diff options
| author | Tom Rini <[email protected]> | 2025-11-24 09:34:29 -0600 |
|---|---|---|
| committer | Tom Rini <[email protected]> | 2025-11-24 09:34:29 -0600 |
| commit | 4a4871e3dc38f3f771d2713b805e79e6191b4297 (patch) | |
| tree | f3cbb63c259f8cce92e87bf1a30b69c02b07c2dc | |
| parent | 6e7d2399c8139f8e2d037e446236b8d8bdbca604 (diff) | |
| parent | c5e6d2ab7eba68cbfb600cdc131c0c375ced2ec9 (diff) | |
Merge tag 'v2026.01-rc3' into next
Prepare v2026.01-rc3
145 files changed, 2503 insertions, 3960 deletions
diff --git a/.azure-pipelines.yml b/.azure-pipelines.yml index dddca4acf17..abbd48d0056 100644 --- a/.azure-pipelines.yml +++ b/.azure-pipelines.yml @@ -515,6 +515,12 @@ stages: qemu_riscv64_spl: TEST_PY_BD: "qemu-riscv64_spl" TEST_PY_TEST_SPEC: "not sleep" + qemu_riscv64_smode: + TEST_PY_BD: "qemu-riscv64_smode" + TEST_PY_TEST_SPEC: "not sleep" + qemu_riscv64_smode_acpi: + TEST_PY_BD: "qemu-riscv64_smode_acpi" + TEST_PY_TEST_SPEC: "not sleep" qemu_x86: TEST_PY_BD: "qemu-x86" TEST_PY_TEST_SPEC: "not sleep" diff --git a/.gitignore b/.gitignore index 1ac737d2718..2bf86a6b5d6 100644 --- a/.gitignore +++ b/.gitignore @@ -73,15 +73,15 @@ fit-dtb.blob* /defconfig /generated_defconfig /Test* -/capsule.*.efi-capsule +/capsule*.efi-capsule /capsule*.map /keep-syms-lto.* /*imx8mimage* /*imx8mcst* /*rcar4-sa0* /drivers/video/u_boot_logo.S -/test/overlay/test-fdt-overlay.dtbo.S -/test/overlay/test-fdt-overlay-stacked.dtbo.S +/test/fdt_overlay/test-fdt-overlay-stacked.dtbo.S +/test/fdt_overlay/test-fdt-overlay.dtbo.S capsule_esl_file # diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 5e9995aed6a..9c2731725e4 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -143,6 +143,7 @@ stages: build all platforms in a single job: stage: world build dependencies: [] + needs: [ "sandbox test.py" ] tags: - ${DEFAULT_FAST_TAG} script: @@ -471,6 +472,18 @@ qemu-riscv64_spl test.py: TEST_PY_TEST_SPEC: "not sleep" <<: *buildman_and_testpy_dfn +qemu-riscv64_smode test.py: + variables: + TEST_PY_BD: "qemu-riscv64_smode" + TEST_PY_TEST_SPEC: "not sleep" + <<: *buildman_and_testpy_dfn + +qemu-riscv64_smode_acpi test.py: + variables: + TEST_PY_BD: "qemu-riscv64_smode_acpi" + TEST_PY_TEST_SPEC: "not sleep" + <<: *buildman_and_testpy_dfn + qemu-x86 test.py: variables: TEST_PY_BD: "qemu-x86" @@ -602,6 +615,7 @@ coreboot test.py: when: manual allow_failure: true dependencies: [] + needs: [ "sandbox test.py" ] tags: [ 'lab' ] script: # Environment: @@ -114,6 +114,7 @@ Radhey Shyam Pandey <[email protected]> <[email protected] Rajeshwari Shinde <[email protected]> Raju Kumar Pothuraju <[email protected]> <[email protected]> Ravi Patel <[email protected]> <[email protected]> +Raymond Mao <[email protected]> <[email protected]> Ricardo Ribalda <[email protected]> <[email protected]> Ricardo Ribalda <[email protected]> <[email protected]> Rohit Visavalia <[email protected]> <[email protected]> @@ -121,6 +122,8 @@ Ruchika Gupta <[email protected]> <[email protected]> Saeed Nowshadi <[email protected]> <[email protected]> Sai Krishna Potthuri <[email protected]> <[email protected]> Sai Pavan Boddu <[email protected]> <[email protected]> +Sam Protsenko <[email protected]> +Sam Protsenko <[email protected]> <[email protected]> Sandeep Gundlupet Raju <[email protected]> <[email protected]> Sandeep Paulraj <[email protected]> Sandeep Reddy Ghanapuram <[email protected]> <[email protected]> diff --git a/MAINTAINERS b/MAINTAINERS index c0c5717f45d..ce1f387928d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -734,6 +734,7 @@ F: drivers/spi/stm32_ospi.c F: drivers/spi/stm32_qspi.c F: drivers/spi/stm32_spi.c F: drivers/video/stm32/stm32_ltdc.c +F: drivers/video/stm32/stm32_lvds.c F: drivers/watchdog/stm32mp_wdt.c F: include/dt-bindings/clock/stm32fx-clock.h F: include/dt-bindings/clock/stm32mp* @@ -3,7 +3,7 @@ VERSION = 2026 PATCHLEVEL = 01 SUBLEVEL = -EXTRAVERSION = -rc2 +EXTRAVERSION = -rc3 NAME = # *DOCUMENTATION* @@ -600,7 +600,7 @@ ifneq ($(shell $(CC) --version 2>&1 | head -n 1 | grep clang),) ifneq ($(CROSS_COMPILE),) CLANG_FLAGS := --target=$(notdir $(CROSS_COMPILE:%-=%)) GCC_TOOLCHAIN_DIR := $(dir $(shell which $(CROSS_COMPILE)elfedit)) -CLANG_FLAGS += --prefix=$(GCC_TOOLCHAIN_DIR) +CLANG_FLAGS += --prefix=$(GCC_TOOLCHAIN_DIR)$(notdir $(CROSS_COMPILE:%-=%))- GCC_TOOLCHAIN := $(realpath $(GCC_TOOLCHAIN_DIR)/..) endif ifneq ($(GCC_TOOLCHAIN),) @@ -1041,7 +1041,6 @@ libs-$(CONFIG_USB_GADGET) += drivers/usb/gadget/ libs-$(CONFIG_USB_GADGET) += drivers/usb/gadget/udc/ libs-y += drivers/usb/host/ libs-y += drivers/usb/mtu3/ -libs-y += drivers/usb/musb/ libs-y += drivers/usb/musb-new/ libs-y += drivers/usb/isp1760/ libs-y += drivers/usb/phy/ diff --git a/arch/arm/config.mk b/arch/arm/config.mk index ba7dd99672a..73fddd50bd7 100644 --- a/arch/arm/config.mk +++ b/arch/arm/config.mk @@ -30,18 +30,19 @@ PLATFORM_RELFLAGS += $(call cc-option,-mgeneral-regs-only) endif # LLVM support -LLVM_RELFLAGS := $(call cc-option,-mllvm,) \ - $(call cc-option,-mno-movt,) -PLATFORM_RELFLAGS += $(LLVM_RELFLAGS) - +LLVM_RELFLAGS := $(call cc-option,-mllvm,) PLATFORM_CPPFLAGS += -D__ARM__ ifdef CONFIG_ARM64 PLATFORM_ELFFLAGS += -B aarch64 -O elf64-littleaarch64 else PLATFORM_ELFFLAGS += -B arm -O elf32-littlearm +# no-movt is only available when targeting AArch32 +LLVM_RELFLAGS += $(call cc-option,-mno-movt,) endif +PLATFORM_RELFLAGS += $(LLVM_RELFLAGS) + # Choose between ARM/Thumb instruction sets ifeq ($(CONFIG_$(PHASE_)SYS_THUMB_BUILD),y) AFLAGS_IMPLICIT_IT := $(call as-option,-Wa$(comma)-mimplicit-it=always) @@ -50,7 +51,7 @@ PF_CPPFLAGS_ARM := $(AFLAGS_IMPLICIT_IT) \ $(call cc-option,-marm,)\ $(call cc-option,-mno-thumb-interwork,)\ ) -else +else ifneq ($(CONFIG_ARM64),y) PF_CPPFLAGS_ARM := $(call cc-option,-marm,) \ $(call cc-option,-mno-thumb-interwork,) endif diff --git a/arch/arm/cpu/armv7/Kconfig b/arch/arm/cpu/armv7/Kconfig index ab86d642eee..3a3c1784e18 100644 --- a/arch/arm/cpu/armv7/Kconfig +++ b/arch/arm/cpu/armv7/Kconfig @@ -28,7 +28,7 @@ config ARMV7_BOOT_SEC_DEFAULT variable to "sec" or "nonsec". config HAS_ARMV7_SECURE_BASE - bool "Enable support for a ahardware secure memory area" + bool "Enable support for a hardware secure memory area" default y if ARCH_LS1021A || ARCH_MX7 || ARCH_MX7ULP || ARCH_STM32MP \ || MACH_SUN6I || MACH_SUN7I || MACH_SUN8I || TEGRA124 diff --git a/arch/arm/dts/en7523-u-boot.dtsi b/arch/arm/dts/en7523-u-boot.dtsi index 90838c00a85..f031f81515a 100644 --- a/arch/arm/dts/en7523-u-boot.dtsi +++ b/arch/arm/dts/en7523-u-boot.dtsi @@ -60,7 +60,7 @@ reg = <0>; spi-max-frequency = <50000000>; spi-tx-bus-width = <1>; - spi-rx-bus-width = <1>; + spi-rx-bus-width = <2>; }; }; }; diff --git a/arch/arm/dts/stm32mp135f-dk-u-boot.dtsi b/arch/arm/dts/stm32mp135f-dk-u-boot.dtsi index f004e9840a2..326a8f8736e 100644 --- a/arch/arm/dts/stm32mp135f-dk-u-boot.dtsi +++ b/arch/arm/dts/stm32mp135f-dk-u-boot.dtsi @@ -14,6 +14,7 @@ u-boot,boot-led = "led-blue"; u-boot,error-led = "led-red"; u-boot,mmc-env-partition = "u-boot-env"; + st,adc_usb_pd = <&adc1 6>, <&adc1 12>; }; gpio-keys { diff --git a/arch/arm/dts/stm32mp13xx-dhcor-u-boot.dtsi b/arch/arm/dts/stm32mp13xx-dhcor-u-boot.dtsi index 699ba15d6ea..bedb7c600d5 100644 --- a/arch/arm/dts/stm32mp13xx-dhcor-u-boot.dtsi +++ b/arch/arm/dts/stm32mp13xx-dhcor-u-boot.dtsi @@ -10,6 +10,7 @@ / { aliases { eeprom0 = &eeprom0; + eeprom0wl = &eeprom0wl; }; config { @@ -186,6 +187,14 @@ }; #endif +®11 { + regulator-always-on; +}; + +®18 { + regulator-always-on; +}; + &sdmmc1 { status = "disabled"; }; diff --git a/arch/arm/dts/stm32mp15xx-dhsom-u-boot.dtsi b/arch/arm/dts/stm32mp15xx-dhsom-u-boot.dtsi index 386c605c07f..ed2629f379a 100644 --- a/arch/arm/dts/stm32mp15xx-dhsom-u-boot.dtsi +++ b/arch/arm/dts/stm32mp15xx-dhsom-u-boot.dtsi @@ -51,3 +51,7 @@ }; }; }; + +&etzpc { + compatible = "simple-bus"; +}; diff --git a/arch/arm/dts/stm32mp23-u-boot.dtsi b/arch/arm/dts/stm32mp23-u-boot.dtsi index 872a8739c54..5a9436dd193 100644 --- a/arch/arm/dts/stm32mp23-u-boot.dtsi +++ b/arch/arm/dts/stm32mp23-u-boot.dtsi @@ -37,6 +37,11 @@ soc@0 { bootph-all; }; + + /* temporary until kernel DT update */ + watchdog { + arm,smc-id = <0xbc000000>; + }; }; &bsec { diff --git a/arch/arm/dts/stm32mp235f-dk-u-boot.dtsi b/arch/arm/dts/stm32mp235f-dk-u-boot.dtsi index 1bc77874050..84279c4712a 100644 --- a/arch/arm/dts/stm32mp235f-dk-u-boot.dtsi +++ b/arch/arm/dts/stm32mp235f-dk-u-boot.dtsi @@ -10,6 +10,14 @@ u-boot,boot-led = "led-blue"; u-boot,mmc-env-partition = "u-boot-env"; }; + + clocks { + txbyteclk { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <0>; + }; + }; }; &usart2 { diff --git a/arch/arm/dts/stm32mp25-u-boot.dtsi b/arch/arm/dts/stm32mp25-u-boot.dtsi index d9aeeb6d510..ee82a0289e2 100644 --- a/arch/arm/dts/stm32mp25-u-boot.dtsi +++ b/arch/arm/dts/stm32mp25-u-boot.dtsi @@ -39,6 +39,11 @@ soc@0 { bootph-all; }; + + /* temporary until kernel DT update */ + watchdog { + arm,smc-id = <0xbc000000>; + }; }; &bsec { diff --git a/arch/arm/dts/stm32mp257f-dk-u-boot.dtsi b/arch/arm/dts/stm32mp257f-dk-u-boot.dtsi new file mode 100644 index 00000000000..fe3fe9c5166 --- /dev/null +++ b/arch/arm/dts/stm32mp257f-dk-u-boot.dtsi @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR BSD-3-Clause +/* + * Copyright (C) STMicroelectronics 2025 - All Rights Reserved + */ + +#include "stm32mp25-u-boot.dtsi" + +/ { + config { + u-boot,mmc-env-partition = "u-boot-env"; + }; +}; + +&usart2 { + bootph-all; +}; + +&usart2_pins_a { + bootph-all; + pins1 { + bootph-all; + }; + pins2 { + bootph-all; + }; +}; diff --git a/arch/arm/dts/zynq-binman-brcp1.dtsi b/arch/arm/dts/zynq-binman-brcp1.dtsi index 3cc8ee8b810..c853e8c7b15 100644 --- a/arch/arm/dts/zynq-binman-brcp1.dtsi +++ b/arch/arm/dts/zynq-binman-brcp1.dtsi @@ -15,7 +15,7 @@ blob@0 { filename = "spl/boot.bin"; - offset = <0x0>; + offset = <0x8000>; }; fit { diff --git a/arch/arm/mach-imx/imx9/scmi/clock_scmi.c b/arch/arm/mach-imx/imx9/scmi/clock_scmi.c index b6be20ec674..9030dbf600d 100644 --- a/arch/arm/mach-imx/imx9/scmi/clock_scmi.c +++ b/arch/arm/mach-imx/imx9/scmi/clock_scmi.c @@ -10,7 +10,7 @@ int imx_clk_scmi_enable(u32 clock_id, bool enable) { - struct scmi_clk_state_in in = { + struct scmi_clk_state_in_v1 in = { .clock_id = clock_id, .attributes = !!enable, }; diff --git a/arch/arm/mach-rockchip/rk3588/rk3588.c b/arch/arm/mach-rockchip/rk3588/rk3588.c index c01a4002089..55d2caab4fe 100644 --- a/arch/arm/mach-rockchip/rk3588/rk3588.c +++ b/arch/arm/mach-rockchip/rk3588/rk3588.c @@ -63,7 +63,20 @@ static struct mm_region rk3588_mem_map[] = { { .virt = 0x0UL, .phys = 0x0UL, - .size = 0xf0000000UL, + .size = 0x10f000UL, + .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | + PTE_BLOCK_INNER_SHARE + }, { + /* SCMI shared memory area must be mapped as non-cacheable. */ + .virt = 0x10f000UL, + .phys = 0x10f000UL, + .size = 0x1000UL, + .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL_NC) | + PTE_BLOCK_INNER_SHARE + }, { + .virt = 0x110000UL, + .phys = 0x110000UL, + .size = 0xefef0000UL, .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_INNER_SHARE }, { diff --git a/arch/arm/mach-stm32mp/Kconfig.13x b/arch/arm/mach-stm32mp/Kconfig.13x index 6a45c4e4132..e9697e34f95 100644 --- a/arch/arm/mach-stm32mp/Kconfig.13x +++ b/arch/arm/mach-stm32mp/Kconfig.13x @@ -17,6 +17,17 @@ config TARGET_ST_STM32MP13X managed by board/st/stm32mp1. The difference between board are managed with devicetree +config TARGET_DH_STM32MP13X + bool "DH electronics STM32MP13x boards" + imply BOOTSTAGE + imply CMD_BOOTSTAGE + imply CMD_CLS if CMD_BMP + imply DISABLE_CONSOLE + imply PRE_CONSOLE_BUFFER + imply SILENT_CONSOLE + help + Target the DH DHSBC development kit with STM32MP13x SoM. + endchoice config TEXT_BASE @@ -50,6 +61,7 @@ config DEBUG_UART_CLOCK default 64000000 endif +source "board/dhelectronics/dh_stm32mp1/Kconfig" source "board/st/stm32mp1/Kconfig" endif diff --git a/arch/arm/mach-stm32mp/stm32mp2/stm32mp25x.c b/arch/arm/mach-stm32mp/stm32mp2/stm32mp25x.c index 12b43ea5cdf..bf1f3d3c5a7 100644 --- a/arch/arm/mach-stm32mp/stm32mp2/stm32mp25x.c +++ b/arch/arm/mach-stm32mp/stm32mp2/stm32mp25x.c @@ -77,6 +77,14 @@ int get_eth_nb(void) case CPU_STM32MP257Axx: nb_eth = 5; /* dual ETH with TSN support */ break; + case CPU_STM32MP255Fxx: + fallthrough; + case CPU_STM32MP255Dxx: + fallthrough; + case CPU_STM32MP255Cxx: + fallthrough; + case CPU_STM32MP255Axx: + fallthrough; case CPU_STM32MP253Fxx: fallthrough; case CPU_STM32MP253Dxx: diff --git a/arch/arm/mach-stm32mp/syscon.c b/arch/arm/mach-stm32mp/syscon.c index 8bcbd979340..b00897e87ec 100644 --- a/arch/arm/mach-stm32mp/syscon.c +++ b/arch/arm/mach-stm32mp/syscon.c @@ -10,6 +10,7 @@ static const struct udevice_id stm32mp_syscon_ids[] = { { .compatible = "st,stm32mp157-syscfg", .data = STM32MP_SYSCON_SYSCFG }, + { .compatible = "st,stm32mp23-syscfg", .data = STM32MP_SYSCON_SYSCFG}, { .compatible = "st,stm32mp25-syscfg", .data = STM32MP_SYSCON_SYSCFG}, { } }; diff --git a/board/dhelectronics/common/dh_common.c b/board/dhelectronics/common/dh_common.c index 6101ecc7ebc..e7ee23aa8ce 100644 --- a/board/dhelectronics/common/dh_common.c +++ b/board/dhelectronics/common/dh_common.c @@ -246,3 +246,40 @@ __weak int dh_setup_mac_address(struct eeprom_id_page *eip) printf("%s: Unable to set mac address!\n", __func__); return -ENXIO; } + +void dh_add_item_number_and_serial_to_env(struct eeprom_id_page *eip) +{ + char *item_number_env; + char item_number[8]; /* String with 7 characters + string termination */ + char *serial_env; + char serial[10]; /* String with 9 characters + string termination */ + int ret; + + ret = dh_get_value_from_eeprom_buffer(DH_ITEM_NUMBER, item_number, sizeof(item_number), + eip); + if (ret) { + printf("%s: Unable to get DHSOM item number from EEPROM ID page! ret = %d\n", + __func__, ret); + } else { + item_number_env = env_get("dh_som_item_number"); + if (!item_number_env) + env_set("dh_som_item_number", item_number); + else if (strcmp(item_number_env, item_number)) + printf("Warning: Environment dh_som_item_number differs from EEPROM ID page value (%s != %s)\n", + item_number_env, item_number); + } + + ret = dh_get_value_from_eeprom_buffer(DH_SERIAL_NUMBER, serial, sizeof(serial), + eip); + if (ret) { + printf("%s: Unable to get DHSOM serial number from EEPROM ID page! ret = %d\n", + __func__, ret); + } else { + serial_env = env_get("dh_som_serial_number"); + if (!serial_env) + env_set("dh_som_serial_number", serial); + else if (strcmp(serial_env, serial)) + printf("Warning: Environment dh_som_serial_number differs from EEPROM ID page value (%s != %s)\n", + serial_env, serial); + } +} diff --git a/board/dhelectronics/common/dh_common.h b/board/dhelectronics/common/dh_common.h index c4693c60618..b4f31bdb88e 100644 --- a/board/dhelectronics/common/dh_common.h +++ b/board/dhelectronics/common/dh_common.h @@ -107,7 +107,16 @@ int dh_get_value_from_eeprom_buffer(enum eip_request_values request, u8 *data, i /* * dh_setup_mac_address - Try to get MAC address from various locations and write it to env + * @eip: ID EEPROM buffer * * Return: 0 if OK, other value on error */ int dh_setup_mac_address(struct eeprom_id_page *eip); + +/* + * dh_add_item_number_and_serial_to_env - Try to get DH IDs from WLP write them to env + * @eip: ID EEPROM buffer + * + * Return: 0 if OK, other value on error + */ +void dh_add_item_number_and_serial_to_env(struct eeprom_id_page *eip); diff --git a/board/dhelectronics/dh_imx8mp/imx8mp_dhcom_pdk2.c b/board/dhelectronics/dh_imx8mp/imx8mp_dhcom_pdk2.c index 3a890c5920c..5c35a5bf447 100644 --- a/board/dhelectronics/dh_imx8mp/imx8mp_dhcom_pdk2.c +++ b/board/dhelectronics/dh_imx8mp/imx8mp_dhcom_pdk2.c @@ -116,43 +116,6 @@ int dh_setup_mac_address(struct eeprom_id_page *eip) return ret; } -void dh_add_item_number_and_serial_to_env(struct eeprom_id_page *eip) -{ - char *item_number_env; - char item_number[8]; /* String with 7 characters + string termination */ - char *serial_env; - char serial[10]; /* String with 9 characters + string termination */ - int ret; - - ret = dh_get_value_from_eeprom_buffer(DH_ITEM_NUMBER, item_number, sizeof(item_number), - eip); - if (ret) { - printf("%s: Unable to get DHSOM item number from EEPROM ID page! ret = %d\n", - __func__, ret); - } else { - item_number_env = env_get("dh_som_item_number"); - if (!item_number_env) - env_set("dh_som_item_number", item_number); - else if (strcmp(item_number_env, item_number)) - printf("Warning: Environment dh_som_item_number differs from EEPROM ID page value (%s != %s)\n", - item_number_env, item_number); - } - - ret = dh_get_value_from_eeprom_buffer(DH_SERIAL_NUMBER, serial, sizeof(serial), - eip); - if (ret) { - printf("%s: Unable to get DHSOM serial number from EEPROM ID page! ret = %d\n", - __func__, ret); - } else { - serial_env = env_get("dh_som_serial_number"); - if (!serial_env) - env_set("dh_som_serial_number", serial); - else if (strcmp(serial_env, serial)) - printf("Warning: Environment dh_som_serial_number differs from EEPROM ID page value (%s != %s)\n", - serial_env, serial); - } -} - int board_late_init(void) { u8 eeprom_buffer[DH_EEPROM_ID_PAGE_MAX_SIZE] = { 0 }; diff --git a/board/dhelectronics/dh_stm32mp1/Kconfig b/board/dhelectronics/dh_stm32mp1/Kconfig index dc707c2753f..05cb97b61e6 100644 --- a/board/dhelectronics/dh_stm32mp1/Kconfig +++ b/board/dhelectronics/dh_stm32mp1/Kconfig @@ -20,3 +20,26 @@ config ENV_OFFSET_REDUND source "board/st/common/Kconfig" endif + +if TARGET_DH_STM32MP13X + +config SYS_BOARD + default "dh_stm32mp1" + +config SYS_VENDOR + default "dhelectronics" + +config SYS_CONFIG_NAME + default "stm32mp13_st_common" + +config ENV_SECT_SIZE + default 0x10000 if ENV_IS_IN_SPI_FLASH + +config ENV_OFFSET + default 0x3E0000 if ENV_IS_IN_SPI_FLASH + +config ENV_OFFSET_REDUND + default 0x3F0000 if ENV_IS_IN_SPI_FLASH + +source "board/st/common/Kconfig" +endif diff --git a/board/dhelectronics/dh_stm32mp1/Makefile b/board/dhelectronics/dh_stm32mp1/Makefile index 30db1dee807..2f4a301d1a0 100644 --- a/board/dhelectronics/dh_stm32mp1/Makefile +++ b/board/dhelectronics/dh_stm32mp1/Makefile @@ -3,6 +3,8 @@ # Copyright (C) 2018, STMicroelectronics - All Rights Reserved # -obj-y += ../../st/common/stpmic1.o board.o +obj-$(CONFIG_PMIC_STPMIC1) += ../../st/common/stpmic1.o +obj-y += board.o obj-$(CONFIG_SET_DFU_ALT_INFO) += ../../st/common/stm32mp_dfu.o +obj-$(CONFIG_$(PHASE_)DFU_VIRT) += ../../st/common/stm32mp_dfu_virt.o diff --git a/board/dhelectronics/dh_stm32mp1/board.c b/board/dhelectronics/dh_stm32mp1/board.c index d98b2c6e809..c18f1911fe4 100644 --- a/board/dhelectronics/dh_stm32mp1/board.c +++ b/board/dhelectronics/dh_stm32mp1/board.c @@ -119,7 +119,30 @@ static bool dh_stm32_mac_is_in_ks8851(void) return false; } -static int dh_stm32_setup_ethaddr(void) +static int dh_stm32_get_mac_from_fuse(unsigned char *enetaddr, int index) +{ + struct udevice *dev; + u8 otp[12]; + int ret; + + ret = uclass_get_device_by_driver(UCLASS_MISC, + DM_DRIVER_GET(stm32mp_bsec), + &dev); + if (ret) + return ret; + + ret = misc_read(dev, STM32_BSEC_SHADOW(BSEC_OTP_MAC), otp, sizeof(otp)); + if (ret < 0) + return ret; + + memcpy(enetaddr, otp + ARP_HLEN * index, ARP_HLEN); + if (!is_valid_ethaddr(enetaddr)) + return -EINVAL; + + return 0; +} + +static int dh_stm32_setup_ethaddr(struct eeprom_id_page *eip) { unsigned char enetaddr[6]; @@ -129,13 +152,22 @@ static int dh_stm32_setup_ethaddr(void) if (dh_get_mac_is_enabled("ethernet0")) return 0; + if (!dh_stm32_get_mac_from_fuse(enetaddr, 0)) + goto out; + + if (!dh_get_value_from_eeprom_buffer(DH_MAC0, enetaddr, sizeof(enetaddr), eip)) + goto out; + if (!dh_get_mac_from_eeprom(enetaddr, "eeprom0")) - return eth_env_set_enetaddr("ethaddr", enetaddr); + goto out; return -ENXIO; + +out: + return eth_env_set_enetaddr("ethaddr", enetaddr); } -static int dh_stm32_setup_eth1addr(void) +static int dh_stm32_setup_eth1addr(struct eeprom_id_page *eip) { unsigned char enetaddr[6]; @@ -148,20 +180,50 @@ static int dh_stm32_setup_eth1addr(void) if (dh_stm32_mac_is_in_ks8851()) return 0; - if (!dh_get_mac_from_eeprom(enetaddr, "eeprom0")) { - enetaddr[5]++; - return eth_env_set_enetaddr("eth1addr", enetaddr); - } + if (!dh_stm32_get_mac_from_fuse(enetaddr, 1)) + goto out; + + if (!dh_get_value_from_eeprom_buffer(DH_MAC1, enetaddr, sizeof(enetaddr), eip)) + goto out; + + if (!dh_get_mac_from_eeprom(enetaddr, "eeprom0")) + goto increment_out; return -ENXIO; + +increment_out: + enetaddr[5]++; + +out: + return eth_env_set_enetaddr("eth1addr", enetaddr); } int setup_mac_address(void) { - if (dh_stm32_setup_ethaddr()) + u8 eeprom_buffer[DH_EEPROM_ID_PAGE_MAX_SIZE] = { 0 }; + struct eeprom_id_page *eip = (struct eeprom_id_page *)eeprom_buffer; + int ret; + + ret = dh_read_eeprom_id_page(eeprom_buffer, "eeprom0wl"); + if (ret) { + /* + * The EEPROM ID page is available on SoM rev. 200 and greater. + * For SoM rev. 100 the return value will be -ENODEV. Suppress + * the error message for that, because the absence cannot be + * treated as an error. + */ + if (ret != -ENODEV) + printf("%s: Cannot read valid data from EEPROM ID page! ret = %d\n", + __func__, ret); + eip = NULL; + } else { + dh_add_item_number_and_serial_to_env(eip); + } + + if (dh_stm32_setup_ethaddr(eip)) log_err("%s: Unable to setup ethaddr!\n", __func__); - if (dh_stm32_setup_eth1addr()) + if (dh_stm32_setup_eth1addr(eip)) log_err("%s: Unable to setup eth1addr!\n", __func__); return 0; @@ -692,6 +754,34 @@ void board_quiesce_devices(void) #endif } +#ifdef CONFIG_TARGET_DH_STM32MP13X +enum env_location env_get_location(enum env_operation op, int prio) +{ + u32 bootmode = get_bootmode(); + + if (prio) + return ENVL_UNKNOWN; + + switch (bootmode & TAMP_BOOT_DEVICE_MASK) { + case BOOT_FLASH_SD: + case BOOT_FLASH_EMMC: + if (CONFIG_IS_ENABLED(ENV_IS_IN_MMC)) + return ENVL_MMC; + else + return ENVL_NOWHERE; + + case BOOT_FLASH_NOR: + if (CONFIG_IS_ENABLED(ENV_IS_IN_SPI_FLASH)) + return ENVL_SPI_FLASH; + else + return ENVL_NOWHERE; + + default: + return ENVL_NOWHERE; + } +} +#endif + static void dh_stm32_ks8851_fixup(void *blob) { struct gpio_desc ks8851intrn; diff --git a/boot/pxe_utils.c b/boot/pxe_utils.c index 038416203fc..836e4eb526c 100644 --- a/boot/pxe_utils.c +++ b/boot/pxe_utils.c @@ -444,7 +444,7 @@ static void label_boot_extension(struct pxe_context *ctx, const struct extension *extension; struct fdt_header *working_fdt; struct alist *extension_list; - int ret, dir_len, len; + int ret, dir_len, len = 0; char *overlay_dir; const char *slash; ulong fdt_addr; @@ -472,18 +472,16 @@ static void label_boot_extension(struct pxe_context *ctx, slash = "/"; else slash = ""; - - dir_len = strlen(label->fdtdir) + strlen(slash) + 1; - overlay_dir = calloc(1, len); - if (!overlay_dir) - return; - - snprintf(overlay_dir, dir_len, "%s%s", label->fdtdir, - slash); } else { - dir_len = 2; - snprintf(overlay_dir, dir_len, "/"); + slash = "/"; } + dir_len = len + strlen(slash) + 1; + + overlay_dir = calloc(1, dir_len); + if (!overlay_dir) + return; + + snprintf(overlay_dir, dir_len, "%s%s", label->fdtdir ?: "", slash); alist_for_each(extension, extension_list) { char *overlay_file; diff --git a/boot/upl_write.c b/boot/upl_write.c index 7d637c15ba0..4185e59becf 100644 --- a/boot/upl_write.c +++ b/boot/upl_write.c @@ -301,7 +301,7 @@ static int add_upl_memory(const struct upl *upl, ofnode root) for (i = 0; i < upl->mem.count; i++) { const struct upl_mem *mem = alist_get(&upl->mem, i, struct upl_mem); - char buf[mem->region.count * sizeof(64) * 2]; + char buf[mem->region.count * sizeof(u64) * 2]; const struct memregion *first; char name[26]; int ret, len; @@ -354,7 +354,7 @@ static int add_upl_memmap(const struct upl *upl, ofnode root) for (i = 0; i < upl->memmap.count; i++) { const struct upl_memmap *memmap = alist_get(&upl->memmap, i, struct upl_memmap); - char buf[memmap->region.count * sizeof(64) * 2]; + char buf[memmap->region.count * sizeof(u64) * 2]; const struct memregion *first; char name[26]; int ret, len; @@ -411,7 +411,7 @@ static int add_upl_memres(const struct upl *upl, ofnode root, for (i = 0; i < upl->memres.count; i++) { const struct upl_memres *memres = alist_get(&upl->memres, i, struct upl_memres); - char buf[memres->region.count * sizeof(64) * 2]; + char buf[memres->region.count * sizeof(u64) * 2]; const struct memregion *first; char name[26]; int ret, len; diff --git a/cmd/mtd.c b/cmd/mtd.c index d0072129659..7f25144098b 100644 --- a/cmd/mtd.c +++ b/cmd/mtd.c @@ -10,6 +10,7 @@ #include <command.h> #include <console.h> +#include <div64.h> #include <led.h> #if CONFIG_IS_ENABLED(CMD_MTD_OTP) #include <hexdump.h> @@ -595,10 +596,10 @@ static int do_mtd_io(struct cmd_tbl *cmdtp, int flag, int argc, if (benchmark && bench_start) { bench_end = timer_get_us(); - speed = (len * 1000000) / (bench_end - bench_start); + speed = lldiv(len * 1000000, bench_end - bench_start); printf("%s speed: %lukiB/s\n", read ? "Read" : "Write", - (unsigned long)(speed / 1024)); + (unsigned long)(speed >> 10)); } led_activity_off(); diff --git a/common/Kconfig b/common/Kconfig index 0c25a8fc866..47d17f4e7c6 100644 --- a/common/Kconfig +++ b/common/Kconfig @@ -26,7 +26,7 @@ config CONSOLE_RECORD_INIT_F config CONSOLE_RECORD_OUT_SIZE hex "Output buffer size" depends on CONSOLE_RECORD - default 0x400 if CONSOLE_RECORD + default 0x6000 help Set the size of the console recording output buffer. When this fills up, no more data will be recorded until some is removed. The buffer diff --git a/common/qfw.c b/common/qfw.c index 45e87d3ae28..14d48952427 100644 --- a/common/qfw.c +++ b/common/qfw.c @@ -109,7 +109,7 @@ int qemu_fwcfg_setup_kernel(struct udevice *qfw_dev, ulong load_addr, ulong initrd_addr) { char *data_addr; - u32 setup_size, kernel_size, cmdline_size, initrd_size; + u32 setup_size = 0, kernel_size = 0, cmdline_size = 0, initrd_size = 0; qfw_read_entry(qfw_dev, FW_CFG_SETUP_SIZE, 4, &setup_size); qfw_read_entry(qfw_dev, FW_CFG_KERNEL_SIZE, 4, &kernel_size); diff --git a/common/spl/spl_nand.c b/common/spl/spl_nand.c index 032f2466278..f449b31f594 100644 --- a/common/spl/spl_nand.c +++ b/common/spl/spl_nand.c @@ -111,7 +111,7 @@ static int spl_nand_load_image_os(struct spl_image_info *spl_image, int *src, *dst; nand_spl_load_image(CONFIG_CMD_SPL_NAND_OFS, CONFIG_CMD_SPL_WRITE_SIZE, (void *)CONFIG_TEXT_BASE); - /* copy to destintion */ + /* copy to destination */ for (dst = (int *)CONFIG_SPL_PAYLOAD_ARGS_ADDR, src = (int *)CONFIG_TEXT_BASE; src < (int *)(CONFIG_TEXT_BASE + CONFIG_CMD_SPL_WRITE_SIZE); diff --git a/configs/am335x_baltos_defconfig b/configs/am335x_baltos_defconfig index 5c43503ff32..e72a2ac2867 100644 --- a/configs/am335x_baltos_defconfig +++ b/configs/am335x_baltos_defconfig @@ -53,7 +53,6 @@ CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y CONFIG_VERSION_VARIABLE=y CONFIG_NET_RETRY_COUNT=10 CONFIG_BOOTP_SEND_HOSTNAME=y -# CONFIG_TI_SYSC is not set CONFIG_BOOTCOUNT_LIMIT=y CONFIG_DM_I2C=y CONFIG_SPL_SYS_I2C_LEGACY=y diff --git a/configs/at91sam9260ek_nandflash_defconfig b/configs/at91sam9260ek_nandflash_defconfig index 02890de8259..8021815749e 100644 --- a/configs/at91sam9260ek_nandflash_defconfig +++ b/configs/at91sam9260ek_nandflash_defconfig @@ -13,8 +13,8 @@ CONFIG_DEFAULT_DEVICE_TREE="at91sam9260ek" CONFIG_SYS_LOAD_ADDR=0x22000000 CONFIG_DEBUG_UART_BASE=0xfffff200 CONFIG_DEBUG_UART_CLOCK=132000000 -CONFIG_DEBUG_UART_BOARD_INIT=y CONFIG_ENV_OFFSET_REDUND=0x100000 +CONFIG_DEBUG_UART_BOARD_INIT=y CONFIG_DEBUG_UART=y CONFIG_NAND_BOOT=y CONFIG_BOOTDELAY=3 diff --git a/configs/at91sam9261ek_nandflash_defconfig b/configs/at91sam9261ek_nandflash_defconfig index 1f62bbf7a81..37ecba5a09e 100644 --- a/configs/at91sam9261ek_nandflash_defconfig +++ b/configs/at91sam9261ek_nandflash_defconfig @@ -12,8 +12,8 @@ CONFIG_DEFAULT_DEVICE_TREE="at91sam9261ek" CONFIG_SYS_LOAD_ADDR=0x22000000 CONFIG_DEBUG_UART_BASE=0xfffff200 CONFIG_DEBUG_UART_CLOCK=100000000 -CONFIG_DEBUG_UART_BOARD_INIT=y CONFIG_ENV_OFFSET_REDUND=0x100000 +CONFIG_DEBUG_UART_BOARD_INIT=y CONFIG_DEBUG_UART=y CONFIG_NAND_BOOT=y CONFIG_BOOTDELAY=3 diff --git a/configs/at91sam9263ek_nandflash_defconfig b/configs/at91sam9263ek_nandflash_defconfig index e860376aa70..6d3b6fbadf4 100644 --- a/configs/at91sam9263ek_nandflash_defconfig +++ b/configs/at91sam9263ek_nandflash_defconfig @@ -12,8 +12,8 @@ CONFIG_DEFAULT_DEVICE_TREE="at91sam9263ek" CONFIG_SYS_LOAD_ADDR=0x22000000 CONFIG_DEBUG_UART_BASE=0xffffee00 CONFIG_DEBUG_UART_CLOCK=100000000 -CONFIG_DEBUG_UART_BOARD_INIT=y CONFIG_ENV_OFFSET_REDUND=0x100000 +CONFIG_DEBUG_UART_BOARD_INIT=y CONFIG_DEBUG_UART=y CONFIG_NAND_BOOT=y CONFIG_BOOTDELAY=3 diff --git a/configs/at91sam9g10ek_nandflash_defconfig b/configs/at91sam9g10ek_nandflash_defconfig index 2e5e38a62b3..3d70d0f6036 100644 --- a/configs/at91sam9g10ek_nandflash_defconfig +++ b/configs/at91sam9g10ek_nandflash_defconfig @@ -12,8 +12,8 @@ CONFIG_DEFAULT_DEVICE_TREE="at91sam9261ek" CONFIG_SYS_LOAD_ADDR=0x22000000 CONFIG_DEBUG_UART_BASE=0xfffff200 CONFIG_DEBUG_UART_CLOCK=100000000 -CONFIG_DEBUG_UART_BOARD_INIT=y CONFIG_ENV_OFFSET_REDUND=0x100000 +CONFIG_DEBUG_UART_BOARD_INIT=y CONFIG_DEBUG_UART=y CONFIG_NAND_BOOT=y CONFIG_BOOTDELAY=3 diff --git a/configs/at91sam9g20ek_2mmc_nandflash_defconfig b/configs/at91sam9g20ek_2mmc_nandflash_defconfig index 719f0b47766..6b73050e036 100644 --- a/configs/at91sam9g20ek_2mmc_nandflash_defconfig +++ b/configs/at91sam9g20ek_2mmc_nandflash_defconfig @@ -14,8 +14,8 @@ CONFIG_DEFAULT_DEVICE_TREE="at91sam9g20ek_2mmc" CONFIG_SYS_LOAD_ADDR=0x22000000 CONFIG_DEBUG_UART_BASE=0xfffff200 CONFIG_DEBUG_UART_CLOCK=132000000 -CONFIG_DEBUG_UART_BOARD_INIT=y CONFIG_ENV_OFFSET_REDUND=0x100000 +CONFIG_DEBUG_UART_BOARD_INIT=y CONFIG_DEBUG_UART=y CONFIG_NAND_BOOT=y CONFIG_BOOTDELAY=3 diff --git a/configs/at91sam9g20ek_nandflash_defconfig b/configs/at91sam9g20ek_nandflash_defconfig index 92972325a75..94a330d3f18 100644 --- a/configs/at91sam9g20ek_nandflash_defconfig +++ b/configs/at91sam9g20ek_nandflash_defconfig @@ -13,8 +13,8 @@ CONFIG_DEFAULT_DEVICE_TREE="at91sam9g20ek" CONFIG_SYS_LOAD_ADDR=0x22000000 CONFIG_DEBUG_UART_BASE=0xfffff200 CONFIG_DEBUG_UART_CLOCK=132000000 -CONFIG_DEBUG_UART_BOARD_INIT=y CONFIG_ENV_OFFSET_REDUND=0x100000 +CONFIG_DEBUG_UART_BOARD_INIT=y CONFIG_DEBUG_UART=y CONFIG_NAND_BOOT=y CONFIG_BOOTDELAY=3 diff --git a/configs/at91sam9m10g45ek_nandflash_defconfig b/configs/at91sam9m10g45ek_nandflash_defconfig index c4fc3d6f882..76daa14f9e9 100644 --- a/configs/at91sam9m10g45ek_nandflash_defconfig +++ b/configs/at91sam9m10g45ek_nandflash_defconfig @@ -14,8 +14,8 @@ CONFIG_SYS_MONITOR_LEN=524288 CONFIG_SYS_LOAD_ADDR=0x22000000 CONFIG_DEBUG_UART_BASE=0xffffee00 CONFIG_DEBUG_UART_CLOCK=132000000 -CONFIG_DEBUG_UART_BOARD_INIT=y CONFIG_ENV_OFFSET_REDUND=0x100000 +CONFIG_DEBUG_UART_BOARD_INIT=y CONFIG_DEBUG_UART=y CONFIG_NAND_BOOT=y CONFIG_BOOTDELAY=3 diff --git a/configs/at91sam9n12ek_nandflash_defconfig b/configs/at91sam9n12ek_nandflash_defconfig index d266e71aa46..68cde1ca5b0 100644 --- a/configs/at91sam9n12ek_nandflash_defconfig +++ b/configs/at91sam9n12ek_nandflash_defconfig @@ -13,8 +13,8 @@ CONFIG_SYS_MONITOR_LEN=524288 CONFIG_SYS_LOAD_ADDR=0x22000000 CONFIG_DEBUG_UART_BASE=0xfffff200 CONFIG_DEBUG_UART_CLOCK=132000000 -CONFIG_DEBUG_UART_BOARD_INIT=y CONFIG_ENV_OFFSET_REDUND=0x100000 +CONFIG_DEBUG_UART_BOARD_INIT=y CONFIG_DEBUG_UART=y CONFIG_NAND_BOOT=y CONFIG_BOOTDELAY=3 diff --git a/configs/at91sam9rlek_nandflash_defconfig b/configs/at91sam9rlek_nandflash_defconfig index 967331fe147..421952668c4 100644 --- a/configs/at91sam9rlek_nandflash_defconfig +++ b/configs/at91sam9rlek_nandflash_defconfig @@ -12,8 +12,8 @@ CONFIG_DEFAULT_DEVICE_TREE="at91sam9rlek" CONFIG_SYS_LOAD_ADDR=0x22000000 CONFIG_DEBUG_UART_BASE=0xfffff200 CONFIG_DEBUG_UART_CLOCK=100000000 -CONFIG_DEBUG_UART_BOARD_INIT=y CONFIG_ENV_OFFSET_REDUND=0x100000 +CONFIG_DEBUG_UART_BOARD_INIT=y CONFIG_DEBUG_UART=y CONFIG_NAND_BOOT=y CONFIG_BOOTDELAY=3 diff --git a/configs/at91sam9x5ek_nandflash_defconfig b/configs/at91sam9x5ek_nandflash_defconfig index ac6feb2857c..6ebbd8b7d8f 100644 --- a/configs/at91sam9x5ek_nandflash_defconfig +++ b/configs/at91sam9x5ek_nandflash_defconfig @@ -15,8 +15,8 @@ CONFIG_SYS_MONITOR_LEN=524288 CONFIG_SYS_LOAD_ADDR=0x22000000 CONFIG_DEBUG_UART_BASE=0xfffff200 CONFIG_DEBUG_UART_CLOCK=132000000 -CONFIG_DEBUG_UART_BOARD_INIT=y CONFIG_ENV_OFFSET_REDUND=0x100000 +CONFIG_DEBUG_UART_BOARD_INIT=y CONFIG_DEBUG_UART=y CONFIG_FIT=y CONFIG_NAND_BOOT=y diff --git a/configs/at91sam9xeek_nandflash_defconfig b/configs/at91sam9xeek_nandflash_defconfig index 02890de8259..8021815749e 100644 --- a/configs/at91sam9xeek_nandflash_defconfig +++ b/configs/at91sam9xeek_nandflash_defconfig @@ -13,8 +13,8 @@ CONFIG_DEFAULT_DEVICE_TREE="at91sam9260ek" CONFIG_SYS_LOAD_ADDR=0x22000000 CONFIG_DEBUG_UART_BASE=0xfffff200 CONFIG_DEBUG_UART_CLOCK=132000000 -CONFIG_DEBUG_UART_BOARD_INIT=y CONFIG_ENV_OFFSET_REDUND=0x100000 +CONFIG_DEBUG_UART_BOARD_INIT=y CONFIG_DEBUG_UART=y CONFIG_NAND_BOOT=y CONFIG_BOOTDELAY=3 diff --git a/configs/mscc_jr2_defconfig b/configs/mscc_jr2_defconfig index 2cef93802f8..ec0f78c42dc 100644 --- a/configs/mscc_jr2_defconfig +++ b/configs/mscc_jr2_defconfig @@ -10,8 +10,8 @@ CONFIG_SYS_BOOTM_LEN=0x1000000 CONFIG_SYS_LOAD_ADDR=0x100000 CONFIG_DEBUG_UART_BASE=0x70100000 CONFIG_DEBUG_UART_CLOCK=250000000 -CONFIG_DEBUG_UART_BOARD_INIT=y CONFIG_ENV_OFFSET_REDUND=0x140000 +CONFIG_DEBUG_UART_BOARD_INIT=y CONFIG_ARCH_MSCC=y CONFIG_SOC_JR2=y CONFIG_SYS_MIPS_TIMER_FREQ=250000000 diff --git a/configs/mscc_luton_defconfig b/configs/mscc_luton_defconfig index 1fcda3f1681..c673dfbaf8d 100644 --- a/configs/mscc_luton_defconfig +++ b/configs/mscc_luton_defconfig @@ -10,8 +10,8 @@ CONFIG_SYS_BOOTM_LEN=0x1000000 CONFIG_SYS_LOAD_ADDR=0x100000 CONFIG_DEBUG_UART_BASE=0x70100000 CONFIG_DEBUG_UART_CLOCK=208333333 -CONFIG_DEBUG_UART_BOARD_INIT=y CONFIG_ENV_OFFSET_REDUND=0x140000 +CONFIG_DEBUG_UART_BOARD_INIT=y CONFIG_ARCH_MSCC=y CONFIG_SOC_LUTON=y CONFIG_DDRTYPE_MT47H128M8HQ=y diff --git a/configs/mscc_ocelot_defconfig b/configs/mscc_ocelot_defconfig index 23d138d03b9..5507513eedb 100644 --- a/configs/mscc_ocelot_defconfig +++ b/configs/mscc_ocelot_defconfig @@ -10,8 +10,8 @@ CONFIG_SYS_BOOTM_LEN=0x1000000 CONFIG_SYS_LOAD_ADDR=0x100000 CONFIG_DEBUG_UART_BASE=0x70100000 CONFIG_DEBUG_UART_CLOCK=250000000 -CONFIG_DEBUG_UART_BOARD_INIT=y CONFIG_ENV_OFFSET_REDUND=0x140000 +CONFIG_DEBUG_UART_BOARD_INIT=y CONFIG_ARCH_MSCC=y CONFIG_SYS_MIPS_TIMER_FREQ=250000000 CONFIG_DEBUG_UART=y diff --git a/configs/omap3_evm_defconfig b/configs/omap3_evm_defconfig index a813d216787..f99798ac1a5 100644 --- a/configs/omap3_evm_defconfig +++ b/configs/omap3_evm_defconfig @@ -78,7 +78,6 @@ CONFIG_OMAP3_SPI=y CONFIG_USB=y # CONFIG_SPL_DM_USB is not set CONFIG_USB_EHCI_HCD=y -CONFIG_USB_OMAP3=y CONFIG_USB_MUSB_GADGET=y CONFIG_USB_MUSB_OMAP2PLUS=y CONFIG_USB_HOST_ETHER=y diff --git a/configs/qemu-riscv64_smode_acpi_defconfig b/configs/qemu-riscv64_smode_acpi_defconfig index e78e5ffb390..11592091443 100644 --- a/configs/qemu-riscv64_smode_acpi_defconfig +++ b/configs/qemu-riscv64_smode_acpi_defconfig @@ -1,2 +1,3 @@ #include <configs/qemu-riscv64_smode_defconfig> #include <board/emulation/configs/acpi.config> +CONFIG_CONSOLE_RECORD=y diff --git a/configs/sam9x60ek_nandflash_defconfig b/configs/sam9x60ek_nandflash_defconfig index 265112580be..22d879a645b 100644 --- a/configs/sam9x60ek_nandflash_defconfig +++ b/configs/sam9x60ek_nandflash_defconfig @@ -17,8 +17,8 @@ CONFIG_DM_RESET=y CONFIG_SYS_LOAD_ADDR=0x22000000 CONFIG_DEBUG_UART_BASE=0xfffff200 CONFIG_DEBUG_UART_CLOCK=200000000 -CONFIG_DEBUG_UART_BOARD_INIT=y CONFIG_ENV_OFFSET_REDUND=0x100000 +CONFIG_DEBUG_UART_BOARD_INIT=y CONFIG_DEBUG_UART=y CONFIG_FIT=y CONFIG_NAND_BOOT=y diff --git a/configs/sama5d2_ptc_ek_nandflash_defconfig b/configs/sama5d2_ptc_ek_nandflash_defconfig index 7945e19bac3..608591ff69a 100644 --- a/configs/sama5d2_ptc_ek_nandflash_defconfig +++ b/configs/sama5d2_ptc_ek_nandflash_defconfig @@ -13,8 +13,8 @@ CONFIG_OF_LIBFDT_OVERLAY=y CONFIG_SYS_LOAD_ADDR=0x22000000 CONFIG_DEBUG_UART_BASE=0xf801c000 CONFIG_DEBUG_UART_CLOCK=82000000 -CONFIG_DEBUG_UART_BOARD_INIT=y CONFIG_ENV_OFFSET_REDUND=0x100000 +CONFIG_DEBUG_UART_BOARD_INIT=y CONFIG_DEBUG_UART=y CONFIG_ENV_VARS_UBOOT_CONFIG=y CONFIG_FIT=y diff --git a/configs/sama5d36ek_cmp_nandflash_defconfig b/configs/sama5d36ek_cmp_nandflash_defconfig index 4478a2405c8..d8ddbc921e0 100644 --- a/configs/sama5d36ek_cmp_nandflash_defconfig +++ b/configs/sama5d36ek_cmp_nandflash_defconfig @@ -14,8 +14,8 @@ CONFIG_SYS_MONITOR_LEN=524288 CONFIG_SYS_LOAD_ADDR=0x22000000 CONFIG_DEBUG_UART_BASE=0xffffee00 CONFIG_DEBUG_UART_CLOCK=132000000 -CONFIG_DEBUG_UART_BOARD_INIT=y CONFIG_ENV_OFFSET_REDUND=0x100000 +CONFIG_DEBUG_UART_BOARD_INIT=y CONFIG_DEBUG_UART=y CONFIG_ENV_VARS_UBOOT_CONFIG=y CONFIG_FIT=y diff --git a/configs/sama5d3_xplained_nandflash_defconfig b/configs/sama5d3_xplained_nandflash_defconfig index a733e2cd9d7..3c0ea0e7032 100644 --- a/configs/sama5d3_xplained_nandflash_defconfig +++ b/configs/sama5d3_xplained_nandflash_defconfig @@ -25,8 +25,8 @@ CONFIG_SYS_LOAD_ADDR=0x22000000 CONFIG_SPL=y CONFIG_DEBUG_UART_BASE=0xffffee00 CONFIG_DEBUG_UART_CLOCK=132000000 -CONFIG_DEBUG_UART_BOARD_INIT=y CONFIG_ENV_OFFSET_REDUND=0x100000 +CONFIG_DEBUG_UART_BOARD_INIT=y CONFIG_DEBUG_UART=y CONFIG_ENV_VARS_UBOOT_CONFIG=y CONFIG_FIT=y diff --git a/configs/sama5d3xek_nandflash_defconfig b/configs/sama5d3xek_nandflash_defconfig index 99280f3c480..237acc181bf 100644 --- a/configs/sama5d3xek_nandflash_defconfig +++ b/configs/sama5d3xek_nandflash_defconfig @@ -25,8 +25,8 @@ CONFIG_SYS_LOAD_ADDR=0x22000000 CONFIG_SPL=y CONFIG_DEBUG_UART_BASE=0xffffee00 CONFIG_DEBUG_UART_CLOCK=132000000 -CONFIG_DEBUG_UART_BOARD_INIT=y CONFIG_ENV_OFFSET_REDUND=0x100000 +CONFIG_DEBUG_UART_BOARD_INIT=y CONFIG_DEBUG_UART=y CONFIG_ENV_VARS_UBOOT_CONFIG=y CONFIG_FIT=y diff --git a/configs/sama5d4_xplained_nandflash_defconfig b/configs/sama5d4_xplained_nandflash_defconfig index 2066cbe4213..3a777bafb91 100644 --- a/configs/sama5d4_xplained_nandflash_defconfig +++ b/configs/sama5d4_xplained_nandflash_defconfig @@ -26,8 +26,8 @@ CONFIG_SYS_LOAD_ADDR=0x22000000 CONFIG_SPL=y CONFIG_DEBUG_UART_BASE=0xfc00c000 CONFIG_DEBUG_UART_CLOCK=100000000 -CONFIG_DEBUG_UART_BOARD_INIT=y CONFIG_ENV_OFFSET_REDUND=0x100000 +CONFIG_DEBUG_UART_BOARD_INIT=y CONFIG_DEBUG_UART=y CONFIG_ENV_VARS_UBOOT_CONFIG=y CONFIG_FIT=y diff --git a/configs/sama5d4ek_nandflash_defconfig b/configs/sama5d4ek_nandflash_defconfig index 230d4015c2e..0ce52b455e7 100644 --- a/configs/sama5d4ek_nandflash_defconfig +++ b/configs/sama5d4ek_nandflash_defconfig @@ -25,8 +25,8 @@ CONFIG_SYS_LOAD_ADDR=0x22000000 CONFIG_SPL=y CONFIG_DEBUG_UART_BASE=0xfc00c000 CONFIG_DEBUG_UART_CLOCK=88000000 -CONFIG_DEBUG_UART_BOARD_INIT=y CONFIG_ENV_OFFSET_REDUND=0x100000 +CONFIG_DEBUG_UART_BOARD_INIT=y CONFIG_DEBUG_UART=y CONFIG_ENV_VARS_UBOOT_CONFIG=y CONFIG_FIT=y diff --git a/configs/sandbox64_defconfig b/configs/sandbox64_defconfig index 1603e86d184..9a2e7e87d07 100644 --- a/configs/sandbox64_defconfig +++ b/configs/sandbox64_defconfig @@ -24,7 +24,6 @@ CONFIG_BOOTSTAGE_FDT=y CONFIG_BOOTSTAGE_STASH=y CONFIG_BOOTSTAGE_STASH_SIZE=0x4096 CONFIG_CONSOLE_RECORD=y -CONFIG_CONSOLE_RECORD_OUT_SIZE=0x6000 CONFIG_PRE_CONSOLE_BUFFER=y CONFIG_DISPLAY_BOARDINFO_LATE=y # CONFIG_BOARD_INIT is not set diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig index 57d5b1f15ca..df6083e605f 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -40,7 +40,6 @@ CONFIG_IMAGE_PRE_LOAD=y CONFIG_IMAGE_PRE_LOAD_SIG=y CONFIG_CEDIT=y CONFIG_CONSOLE_RECORD=y -CONFIG_CONSOLE_RECORD_OUT_SIZE=0x6000 CONFIG_PRE_CONSOLE_BUFFER=y CONFIG_LOG=y CONFIG_LOG_MAX_LEVEL=9 diff --git a/configs/sandbox_flattree_defconfig b/configs/sandbox_flattree_defconfig index e4b5d2e4163..ed70075b135 100644 --- a/configs/sandbox_flattree_defconfig +++ b/configs/sandbox_flattree_defconfig @@ -23,7 +23,6 @@ CONFIG_BOOTSTAGE_FDT=y CONFIG_BOOTSTAGE_STASH=y CONFIG_BOOTSTAGE_STASH_SIZE=0x4096 CONFIG_CONSOLE_RECORD=y -CONFIG_CONSOLE_RECORD_OUT_SIZE=0x6000 CONFIG_DISPLAY_BOARDINFO_LATE=y # CONFIG_BOARD_INIT is not set CONFIG_CMD_CPU=y diff --git a/configs/stm32mp13_defconfig b/configs/stm32mp13_defconfig index 3283e910219..8ef465ac222 100644 --- a/configs/stm32mp13_defconfig +++ b/configs/stm32mp13_defconfig @@ -29,6 +29,7 @@ CONFIG_CMD_NVEDIT_EFI=y CONFIG_CMD_MEMINFO=y CONFIG_CMD_MEMTEST=y CONFIG_CMD_UNZIP=y +CONFIG_CMD_ADC=y CONFIG_CMD_CLK=y CONFIG_CMD_FUSE=y CONFIG_CMD_GPIO=y @@ -56,6 +57,7 @@ CONFIG_ENV_REDUNDANT=y CONFIG_ENV_RELOC_GD_ENV_ADDR=y CONFIG_ENV_MMC_DEVICE_INDEX=-1 CONFIG_ENV_MMC_USE_DT=y +CONFIG_STM32_ADC=y CONFIG_SYS_64BIT_LBA=y CONFIG_BUTTON=y CONFIG_BUTTON_GPIO=y diff --git a/configs/stm32mp13_dhcor_defconfig b/configs/stm32mp13_dhcor_defconfig index c21416459e6..f751deb801f 100644 --- a/configs/stm32mp13_dhcor_defconfig +++ b/configs/stm32mp13_dhcor_defconfig @@ -8,7 +8,7 @@ CONFIG_ENV_OFFSET=0x3E0000 CONFIG_DEFAULT_DEVICE_TREE="st/stm32mp135f-dhcor-dhsbc" CONFIG_STM32MP13X=y CONFIG_DDR_CACHEABLE_SIZE=0x8000000 -CONFIG_TARGET_ST_STM32MP13X=y +CONFIG_TARGET_DH_STM32MP13X=y CONFIG_ENV_OFFSET_REDUND=0x3F0000 CONFIG_STM32MP15_PWR=y CONFIG_ARMV7_NONSEC=y diff --git a/configs/stm32mp15-icore-stm32mp1-ctouch2_defconfig b/configs/stm32mp15-icore-stm32mp1-ctouch2_defconfig index 2c71d36dec0..6e413296a60 100644 --- a/configs/stm32mp15-icore-stm32mp1-ctouch2_defconfig +++ b/configs/stm32mp15-icore-stm32mp1-ctouch2_defconfig @@ -11,8 +11,8 @@ CONFIG_SPL_TEXT_BASE=0x2FFC2500 CONFIG_SYS_BOOTM_LEN=0x2000000 CONFIG_SYS_LOAD_ADDR=0xc2000000 CONFIG_SPL=y -CONFIG_TARGET_ICORE_STM32MP1=y CONFIG_ENV_OFFSET_REDUND=0x2C0000 +CONFIG_TARGET_ICORE_STM32MP1=y # CONFIG_ARMV7_VIRT is not set CONFIG_SYS_MEMTEST_START=0xc0000000 CONFIG_SYS_MEMTEST_END=0xc4000000 diff --git a/configs/stm32mp15-icore-stm32mp1-edimm2.2_defconfig b/configs/stm32mp15-icore-stm32mp1-edimm2.2_defconfig index 69e9ea4b0c7..bd189f6f9dc 100644 --- a/configs/stm32mp15-icore-stm32mp1-edimm2.2_defconfig +++ b/configs/stm32mp15-icore-stm32mp1-edimm2.2_defconfig @@ -11,8 +11,8 @@ CONFIG_SPL_TEXT_BASE=0x2FFC2500 CONFIG_SYS_BOOTM_LEN=0x2000000 CONFIG_SYS_LOAD_ADDR=0xc2000000 CONFIG_SPL=y -CONFIG_TARGET_ICORE_STM32MP1=y CONFIG_ENV_OFFSET_REDUND=0x2C0000 +CONFIG_TARGET_ICORE_STM32MP1=y # CONFIG_ARMV7_VIRT is not set CONFIG_SYS_MEMTEST_START=0xc0000000 CONFIG_SYS_MEMTEST_END=0xc4000000 diff --git a/configs/stm32mp15-microgea-stm32mp1-microdev2-of7_defconfig b/configs/stm32mp15-microgea-stm32mp1-microdev2-of7_defconfig index ea584f5f794..aff5c16d234 100644 --- a/configs/stm32mp15-microgea-stm32mp1-microdev2-of7_defconfig +++ b/configs/stm32mp15-microgea-stm32mp1-microdev2-of7_defconfig @@ -11,8 +11,8 @@ CONFIG_SPL_TEXT_BASE=0x2FFC2500 CONFIG_SYS_BOOTM_LEN=0x2000000 CONFIG_SYS_LOAD_ADDR=0xc2000000 CONFIG_SPL=y -CONFIG_TARGET_MICROGEA_STM32MP1=y CONFIG_ENV_OFFSET_REDUND=0x2C0000 +CONFIG_TARGET_MICROGEA_STM32MP1=y # CONFIG_ARMV7_VIRT is not set CONFIG_SYS_MEMTEST_START=0xc0000000 CONFIG_SYS_MEMTEST_END=0xc4000000 diff --git a/configs/stm32mp15-microgea-stm32mp1-microdev2_defconfig b/configs/stm32mp15-microgea-stm32mp1-microdev2_defconfig index 5b12980f0a4..cd65c2e5b9b 100644 --- a/configs/stm32mp15-microgea-stm32mp1-microdev2_defconfig +++ b/configs/stm32mp15-microgea-stm32mp1-microdev2_defconfig @@ -11,8 +11,8 @@ CONFIG_SPL_TEXT_BASE=0x2FFC2500 CONFIG_SYS_BOOTM_LEN=0x2000000 CONFIG_SYS_LOAD_ADDR=0xc2000000 CONFIG_SPL=y -CONFIG_TARGET_MICROGEA_STM32MP1=y CONFIG_ENV_OFFSET_REDUND=0x2C0000 +CONFIG_TARGET_MICROGEA_STM32MP1=y # CONFIG_ARMV7_VIRT is not set CONFIG_SYS_MEMTEST_START=0xc0000000 CONFIG_SYS_MEMTEST_END=0xc4000000 diff --git a/configs/stm32mp15-odyssey_defconfig b/configs/stm32mp15-odyssey_defconfig index a317a6cae11..868ba1915f7 100644 --- a/configs/stm32mp15-odyssey_defconfig +++ b/configs/stm32mp15-odyssey_defconfig @@ -10,9 +10,9 @@ CONFIG_SYS_BOOTM_LEN=0x2000000 CONFIG_SYS_LOAD_ADDR=0xc2000000 CONFIG_DDR_CACHEABLE_SIZE=0x8000000 CONFIG_CMD_STM32KEY=y +CONFIG_ENV_OFFSET_REDUND=0x940000 CONFIG_TYPEC_STUSB160X=y CONFIG_TARGET_ST_STM32MP15X=y -CONFIG_ENV_OFFSET_REDUND=0x940000 CONFIG_CMD_STM32PROG=y # CONFIG_ARMV7_NONSEC is not set CONFIG_SYS_MEMTEST_START=0xc0000000 diff --git a/configs/stm32mp15_basic_defconfig b/configs/stm32mp15_basic_defconfig index 79593cce9fe..69a180888f9 100644 --- a/configs/stm32mp15_basic_defconfig +++ b/configs/stm32mp15_basic_defconfig @@ -14,9 +14,9 @@ CONFIG_SYS_BOOTM_LEN=0x2000000 CONFIG_SYS_LOAD_ADDR=0xc2000000 CONFIG_SPL=y CONFIG_CMD_STM32KEY=y +CONFIG_ENV_OFFSET_REDUND=0x2C0000 CONFIG_TYPEC_STUSB160X=y CONFIG_TARGET_ST_STM32MP15X=y -CONFIG_ENV_OFFSET_REDUND=0x2C0000 CONFIG_CMD_STM32PROG=y CONFIG_SPL_SPI_FLASH_SUPPORT=y CONFIG_SPL_SPI=y diff --git a/configs/stm32mp15_defconfig b/configs/stm32mp15_defconfig index b3ec3898861..6adc0b252ec 100644 --- a/configs/stm32mp15_defconfig +++ b/configs/stm32mp15_defconfig @@ -10,9 +10,9 @@ CONFIG_SYS_BOOTM_LEN=0x2000000 CONFIG_SYS_LOAD_ADDR=0xc2000000 CONFIG_DDR_CACHEABLE_SIZE=0x8000000 CONFIG_CMD_STM32KEY=y +CONFIG_ENV_OFFSET_REDUND=0x940000 CONFIG_TYPEC_STUSB160X=y CONFIG_TARGET_ST_STM32MP15X=y -CONFIG_ENV_OFFSET_REDUND=0x940000 CONFIG_CMD_STM32PROG=y # CONFIG_ARMV7_NONSEC is not set CONFIG_SYS_MEMTEST_START=0xc0000000 diff --git a/configs/stm32mp15_trusted_defconfig b/configs/stm32mp15_trusted_defconfig index 09383ed4824..3436c5750ec 100644 --- a/configs/stm32mp15_trusted_defconfig +++ b/configs/stm32mp15_trusted_defconfig @@ -10,10 +10,10 @@ CONFIG_SYS_BOOTM_LEN=0x2000000 CONFIG_SYS_LOAD_ADDR=0xc2000000 CONFIG_DDR_CACHEABLE_SIZE=0x10000000 CONFIG_CMD_STM32KEY=y +CONFIG_ENV_OFFSET_REDUND=0x2C0000 CONFIG_TYPEC_STUSB160X=y CONFIG_STM32MP15X_STM32IMAGE=y CONFIG_TARGET_ST_STM32MP15X=y -CONFIG_ENV_OFFSET_REDUND=0x2C0000 CONFIG_CMD_STM32PROG=y # CONFIG_ARMV7_NONSEC is not set CONFIG_SYS_MEMTEST_START=0xc0000000 diff --git a/configs/stm32mp25_defconfig b/configs/stm32mp25_defconfig index a5ee02a09b4..61cee2f354e 100644 --- a/configs/stm32mp25_defconfig +++ b/configs/stm32mp25_defconfig @@ -91,6 +91,9 @@ CONFIG_SPI=y CONFIG_DM_SPI=y CONFIG_STM32_OSPI=y # CONFIG_OPTEE_TA_AVB is not set +CONFIG_VIDEO=y +CONFIG_VIDEO_STM32=y +CONFIG_VIDEO_STM32_LVDS=y CONFIG_WDT=y CONFIG_WDT_STM32MP=y CONFIG_WDT_ARM_SMC=y diff --git a/doc/api/index.rst b/doc/api/index.rst index 40134e4f42c..9a70597c35d 100644 --- a/doc/api/index.rst +++ b/doc/api/index.rst @@ -28,6 +28,7 @@ U-Boot API documentation serial setjmp sysreset + test timer unicode uthread diff --git a/doc/api/test.rst b/doc/api/test.rst new file mode 100644 index 00000000000..359cbd0617d --- /dev/null +++ b/doc/api/test.rst @@ -0,0 +1,11 @@ +.. SPDX-License-Identifier: GPL-2.0-or-later +.. Copyright (c) 2025 Heinrich Schuchardt + +Test Framework +============== + +Assertions and reporting functions +---------------------------------- + +.. kernel-doc:: include/test/ut.h + :internal: diff --git a/doc/board/samsung/e850-96.rst b/doc/board/samsung/e850-96.rst index 2b66e6568fb..3174a7daff9 100644 --- a/doc/board/samsung/e850-96.rst +++ b/doc/board/samsung/e850-96.rst @@ -637,9 +637,14 @@ machine: `-- pxelinux.cfg `-- 01-02-36-f5-1c-81-13 - where ``'01-02-36-f5-1c-81-13'`` file contains extlinux configuration for - TFTP to load and boot. The name of this file is the Ethernet MAC address, - which can be looked up in the ``$ethaddr`` environment variable in U-Boot. + where ``'01-02-36-f5-1c-81-13'`` file contains extlinux configuration for TFTP + to load and boot. The name of this file has to be in the format of + ``'01-MAC-address'``. The Ethernet MAC address in this case is + ``02-36-f5-1c-81-13``, and it can be looked up in the ``$ethaddr`` environment + variable in U-Boot:: + + => env print ethaddr + ethaddr=02:36:f5:1c:81:13 An example of such configuration file is:: @@ -667,11 +672,11 @@ machine: arch/arm64/configs/defconfig ---------------------------- - # Needed for boot from USB storage (mounting rootfs from USB drive) + # Keep USB PHY driver built-in, as the Ethernet controller sits on USB bus CONFIG_PHY_EXYNOS5_USBDRD=y CONFIG_TYPEC=y - # Needed for NFS boot + # Keep Ethernet driver built-in CONFIG_USB_NET_SMSC95XX=y CONFIG_USB_USBNET=y diff --git a/doc/board/st/st-dt.rst b/doc/board/st/st-dt.rst index 2a285c81807..28cada97e72 100644 --- a/doc/board/st/st-dt.rst +++ b/doc/board/st/st-dt.rst @@ -25,6 +25,7 @@ kernel binding directory = Documentation/devicetree/bindings/ * display - display/st,stm32-dsi.yaml - display/st,stm32-ltdc.yaml + - display/st,stm32mp25-lvds.yaml * gpio - pinctrl/st,stm32-pinctrl.yaml * hwlock diff --git a/doc/board/ti/am6254atl_sk.rst b/doc/board/ti/am6254atl_sk.rst index 3219c86385d..cf58ed4c03f 100644 --- a/doc/board/ti/am6254atl_sk.rst +++ b/doc/board/ti/am6254atl_sk.rst @@ -60,7 +60,7 @@ Set the variables corresponding to this platform: export UBOOT_CFG_CORTEXR=am6254atl_evm_r5_defconfig export UBOOT_CFG_CORTEXA=am6254atl_evm_a53_defconfig export TFA_BOARD=lite - export TFA_EXTRA_ARGS="PRELOADED_BL33_BASE=0x81880000 BL32_BASE=0x80080000" + export TFA_EXTRA_ARGS="PRELOADED_BL33_BASE=0x82000000 BL32_BASE=0x80080000" export OPTEE_PLATFORM=k3-am62x export OPTEE_EXTRA_ARGS="CFG_TZDRAM_START=0x80080000" diff --git a/doc/board/ti/k3.rst b/doc/board/ti/k3.rst index fafef239e01..37a66b3c69d 100644 --- a/doc/board/ti/k3.rst +++ b/doc/board/ti/k3.rst @@ -184,7 +184,7 @@ online * **TI Firmware (TIFS, DM, SYSFW)** - | **source:** https://git.ti.com/git/processor-firmware/ti-linux-firmware.git + | **source:** https://github.com/TexasInstruments/ti-linux-firmware | **branch:** ti-linux-firmware .. note:: diff --git a/doc/build/docker.rst b/doc/build/docker.rst index 4974a98d4af..791eb215617 100644 --- a/doc/build/docker.rst +++ b/doc/build/docker.rst @@ -36,7 +36,7 @@ To build the image yourself: .. code-block:: bash - sudo docker buildx build --platform linux/arm64/v8,linux/amd64 -t your-namespace:your-tag . + sudo docker buildx build --platform linux/arm64,linux/amd64 -t your-namespace:your-tag . Or to use an existing container diff --git a/doc/develop/pytest/usage.rst b/doc/develop/pytest/usage.rst index 596b0397379..7335a39b963 100644 --- a/doc/develop/pytest/usage.rst +++ b/doc/develop/pytest/usage.rst @@ -35,21 +35,26 @@ can be installed via the command pip install -r requirements.txt In order to execute certain tests on their supported platforms other tools -will be required. The following is an incomplete list: +will be required. The following packages may be needed: -* gdisk -* dfu-util -* dtc -* openssl -* e2fsprogs -* util-linux +* cgpt * coreutils +* device-tree-compiler +* dfu-util * dosfstools +* e2fsprogs * efitools +* fdisk +* gdisk +* libgnutls28-dev / gnutls-devel * mount * mtools +* openssl * sbsigntool +* swig * udisks2 +* util-linux +* vboot-kernel-utils / vboot-utils Please use the appropriate commands for your distribution to match these tools up with the package that provides them. @@ -63,7 +68,7 @@ The test script supports either: Further details are described later. The usage of the command ``sudo`` is not allowed in tests. Using elevated -priviledges can lead to security concerns. Furthermore not all users may have +privileges can lead to security concerns. Furthermore not all users may have administrator rights. Therefore the command ``sudo`` must not be used in tests. To create disk images we have helper functions located in ``test/py/tests/fs_helper.py`` which shall be used in any tests that require @@ -387,7 +392,7 @@ to flash, pulsing the board's reset signal is likely all this script needs to do. However, in some scenarios, this script may perform other actions. For example, it may call out to some SoC- or board-specific vendor utility in order to download the U-Boot binary directly into RAM and execute it. This would -avoid the need for ``u-boot-test-flash1`` to actually write U-Boot to flash, +avoid the need for ``u-boot-test-flash`` to actually write U-Boot to flash, thus saving wear on the flash chip(s). u-boot-test-release diff --git a/doc/develop/release_cycle.rst b/doc/develop/release_cycle.rst index 8b0a0333863..56cbfcb4b65 100644 --- a/doc/develop/release_cycle.rst +++ b/doc/develop/release_cycle.rst @@ -69,13 +69,13 @@ Future Releases .. The following commented out dates are for when release candidates are planned to be tagged. -For the next scheduled release, release candidates were made on:: +For the next scheduled release, release candidates were made on: * U-Boot |next_ver|-rc1 was released on Mon 27 October 2025. * U-Boot |next_ver|-rc2 was released on Mon 10 November 2025. -.. * U-Boot |next_ver|-rc3 was released on Mon 24 November 2025. +* U-Boot |next_ver|-rc3 was released on Mon 24 November 2025. .. * U-Boot |next_ver|-rc4 was released on Mon 08 December 2025. diff --git a/doc/develop/tests_writing.rst b/doc/develop/tests_writing.rst index 062194659b5..1a020caa411 100644 --- a/doc/develop/tests_writing.rst +++ b/doc/develop/tests_writing.rst @@ -206,8 +206,44 @@ some common test tasks. (there are also UEFI C tests in lib/efi_selftest/ not considered here.) +Add a C test to an existing suite +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Use this when you are adding to or modifying an existing feature outside driver +model. An example is bloblist. + +Add a new function in the same file as the rest of the suite and register it +with the suite. For example, to add a new mem_search test:: + + /* Test 'ms' command with 32-bit values */ + static int mem_test_ms_new_thing(struct unit_test_state *uts) + { + /* test code here */ + + return 0; + } + MEM_TEST(mem_test_ms_new_thing, UTF_CONSOLE); + +Note that the MEM_TEST() macros is defined at the top of the file. + +Example commit: 9fe064646d2 ("bloblist: Support relocating to a larger space") [1] + +* A successful test returns 0. +* A skipped test returns -EAGAIN. +* Any other value signals a failure. + +Include ``test/ut.h`` defines a number of macros to check values and to return +from the test function if the assertion fails. See :doc:`../api/test` +for details. + +[1] https://gitlab.denx.de/u-boot/u-boot/-/commit/9fe064646d2 + + Add a new driver model test -~~~~~~~~~~~~~~~~~~~~~~~~~~~ +''''''''''''''''''''''''''' + +``dm`` is the test suite that contains C tests for U-boot +:doc:`Driver Model <driver-model/index>`. Use this when adding a test for a new or existing uclass, adding new operations or features to a uclass, adding new ofnode or dev_read_() functions, or anything @@ -249,31 +285,6 @@ Example commit: c48cb7ebfb4 ("sandbox: add ADC unit tests") [1] [1] https://gitlab.denx.de/u-boot/u-boot/-/commit/c48cb7ebfb4 -Add a C test to an existing suite -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Use this when you are adding to or modifying an existing feature outside driver -model. An example is bloblist. - -Add a new function in the same file as the rest of the suite and register it -with the suite. For example, to add a new mem_search test:: - - /* Test 'ms' command with 32-bit values */ - static int mem_test_ms_new_thing(struct unit_test_state *uts) - { - /* test code here */ - - return 0; - } - MEM_TEST(mem_test_ms_new_thing, UTF_CONSOLE); - -Note that the MEM_TEST() macros is defined at the top of the file. - -Example commit: 9fe064646d2 ("bloblist: Support relocating to a larger space") [1] - -[1] https://gitlab.denx.de/u-boot/u-boot/-/commit/9fe064646d2 - - Add a new test suite ~~~~~~~~~~~~~~~~~~~~ diff --git a/drivers/adc/stm32-adc-core.c b/drivers/adc/stm32-adc-core.c index af340b8b273..3446e34fa46 100644 --- a/drivers/adc/stm32-adc-core.c +++ b/drivers/adc/stm32-adc-core.c @@ -200,6 +200,7 @@ err_aclk_disable: static const struct udevice_id stm32_adc_core_ids[] = { { .compatible = "st,stm32h7-adc-core" }, { .compatible = "st,stm32mp1-adc-core" }, + { .compatible = "st,stm32mp13-adc-core" }, {} }; diff --git a/drivers/adc/stm32-adc.c b/drivers/adc/stm32-adc.c index d50f00f1233..b11f771b71c 100644 --- a/drivers/adc/stm32-adc.c +++ b/drivers/adc/stm32-adc.c @@ -49,29 +49,68 @@ /* STM32H7_ADC_SQR1 - bit fields */ #define STM32H7_SQ1_SHIFT 6 +/* STM32H7_ADC_DIFSEL - bit fields */ +#define STM32H7_DIFSEL_SHIFT 0 +#define STM32H7_DIFSEL_MASK GENMASK(19, 0) + /* BOOST bit must be set on STM32H7 when ADC clock is above 20MHz */ #define STM32H7_BOOST_CLKRATE 20000000UL +/* STM32MP13 - Registers for each ADC instance */ +#define STM32MP13_ADC_DIFSEL 0xB0 + +/* STM32MP13_ADC_CFGR specific bit fields */ +#define STM32MP13_DMAEN BIT(0) +#define STM32MP13_DMACFG BIT(1) + +/* STM32MP13_ADC_DIFSEL - bit fields */ +#define STM32MP13_DIFSEL_SHIFT 0 +#define STM32MP13_DIFSEL_MASK GENMASK(18, 0) + #define STM32_ADC_CH_MAX 20 /* max number of channels */ #define STM32_ADC_TIMEOUT_US 100000 +struct stm32_adc { + void __iomem *regs; + int active_channel; + const struct stm32_adc_cfg *cfg; +}; + +struct stm32_adc_regs { + int reg; + int mask; + int shift; +}; + +struct stm32_adc_regspec { + const struct stm32_adc_regs difsel; +}; + struct stm32_adc_cfg { + const struct stm32_adc_regspec *regs; unsigned int max_channels; unsigned int num_bits; bool has_vregready; + bool has_boostmode; + bool has_linearcal; + bool has_presel; }; -struct stm32_adc { - void __iomem *regs; - int active_channel; - const struct stm32_adc_cfg *cfg; +static const struct stm32_adc_regspec stm32h7_adc_regspec = { + .difsel = { STM32H7_ADC_DIFSEL, STM32H7_DIFSEL_MASK }, +}; + +static const struct stm32_adc_regspec stm32mp13_adc_regspec = { + .difsel = { STM32MP13_ADC_DIFSEL, STM32MP13_DIFSEL_MASK }, }; static void stm32_adc_enter_pwr_down(struct udevice *dev) { struct stm32_adc *adc = dev_get_priv(dev); - clrbits_le32(adc->regs + STM32H7_ADC_CR, STM32H7_BOOST); + if (adc->cfg->has_boostmode) + clrbits_le32(adc->regs + STM32H7_ADC_CR, STM32H7_BOOST); + /* Setting DEEPPWD disables ADC vreg and clears ADVREGEN */ setbits_le32(adc->regs + STM32H7_ADC_CR, STM32H7_DEEPPWD); } @@ -90,8 +129,7 @@ static int stm32_adc_exit_pwr_down(struct udevice *dev) /* Exit deep power down, then enable ADC voltage regulator */ clrbits_le32(adc->regs + STM32H7_ADC_CR, STM32H7_DEEPPWD); setbits_le32(adc->regs + STM32H7_ADC_CR, STM32H7_ADVREGEN); - - if (common->rate > STM32H7_BOOST_CLKRATE) + if (adc->cfg->has_boostmode && common->rate > STM32H7_BOOST_CLKRATE) setbits_le32(adc->regs + STM32H7_ADC_CR, STM32H7_BOOST); /* Wait for startup time */ @@ -134,7 +172,7 @@ static int stm32_adc_start_channel(struct udevice *dev, int channel) return ret; /* Only use single ended channels */ - writel(0, adc->regs + STM32H7_ADC_DIFSEL); + clrbits_le32(adc->regs + adc->cfg->regs->difsel.reg, adc->cfg->regs->difsel.mask); /* Enable ADC, Poll for ADRDY to be set (after adc startup time) */ setbits_le32(adc->regs + STM32H7_ADC_CR, STM32H7_ADEN); @@ -147,7 +185,8 @@ static int stm32_adc_start_channel(struct udevice *dev, int channel) } /* Preselect channels */ - writel(uc_pdata->channel_mask, adc->regs + STM32H7_ADC_PCSEL); + if (adc->cfg->has_presel) + writel(uc_pdata->channel_mask, adc->regs + STM32H7_ADC_PCSEL); /* Set sampling time to max value by default */ writel(0xffffffff, adc->regs + STM32H7_ADC_SMPR1); @@ -156,9 +195,11 @@ static int stm32_adc_start_channel(struct udevice *dev, int channel) /* Program regular sequence: chan in SQ1 & len = 0 for one channel */ writel(channel << STM32H7_SQ1_SHIFT, adc->regs + STM32H7_ADC_SQR1); - /* Trigger detection disabled (conversion can be launched in SW) */ - clrbits_le32(adc->regs + STM32H7_ADC_CFGR, STM32H7_EXTEN | - STM32H7_DMNGT); + /* + * Trigger detection disabled (conversion can be launched in SW) + * STM32H7_DMNGT is equivalent to STM32MP13_DMAEN & STM32MP13_DMACFG + */ + clrbits_le32(adc->regs + STM32H7_ADC_CFGR, STM32H7_EXTEN | STM32H7_DMNGT); adc->active_channel = channel; return 0; @@ -206,7 +247,7 @@ static int stm32_adc_selfcalib(struct udevice *dev) { struct stm32_adc *adc = dev_get_priv(dev); int ret; - u32 val; + u32 val, mask; /* * Select calibration mode: @@ -231,7 +272,10 @@ static int stm32_adc_selfcalib(struct udevice *dev) * - Linearity calibration (needs to be done only once for single/diff) * will run simultaneously with offset calibration. */ - setbits_le32(adc->regs + STM32H7_ADC_CR, STM32H7_ADCALDIF | STM32H7_ADCALLIN); + mask = STM32H7_ADCALDIF; + if (adc->cfg->has_linearcal) + mask |= STM32H7_ADCALLIN; + setbits_le32(adc->regs + STM32H7_ADC_CR, mask); /* Start calibration, then wait for completion */ setbits_le32(adc->regs + STM32H7_ADC_CR, STM32H7_ADCAL); @@ -394,14 +438,28 @@ static const struct adc_ops stm32_adc_ops = { }; static const struct stm32_adc_cfg stm32h7_adc_cfg = { + .regs = &stm32h7_adc_regspec, .num_bits = 16, .max_channels = STM32_ADC_CH_MAX, + .has_boostmode = true, + .has_linearcal = true, + .has_presel = true, }; static const struct stm32_adc_cfg stm32mp1_adc_cfg = { + .regs = &stm32h7_adc_regspec, .num_bits = 16, .max_channels = STM32_ADC_CH_MAX, .has_vregready = true, + .has_boostmode = true, + .has_linearcal = true, + .has_presel = true, +}; + +static const struct stm32_adc_cfg stm32mp13_adc_cfg = { + .regs = &stm32mp13_adc_regspec, + .num_bits = 12, + .max_channels = STM32_ADC_CH_MAX - 1, }; static const struct udevice_id stm32_adc_ids[] = { @@ -409,6 +467,8 @@ static const struct udevice_id stm32_adc_ids[] = { .data = (ulong)&stm32h7_adc_cfg }, { .compatible = "st,stm32mp1-adc", .data = (ulong)&stm32mp1_adc_cfg }, + { .compatible = "st,stm32mp13-adc", + .data = (ulong)&stm32mp13_adc_cfg }, {} }; diff --git a/drivers/clk/clk_scmi.c b/drivers/clk/clk_scmi.c index a7d89f32cd7..683ac822a01 100644 --- a/drivers/clk/clk_scmi.c +++ b/drivers/clk/clk_scmi.c @@ -8,6 +8,7 @@ #include <clk-uclass.h> #include <dm.h> #include <dm/device_compat.h> +#include <dm/device-internal.h> #include <scmi_agent.h> #include <scmi_agent-uclass.h> #include <scmi_protocols.h> @@ -16,7 +17,9 @@ struct clk_scmi { struct clk clk; + char name[SCMI_CLOCK_NAME_LENGTH_MAX]; u32 ctrl_flags; + bool attrs_resolved; }; struct scmi_clock_priv { @@ -84,7 +87,7 @@ static int scmi_clk_get_num_clock(struct udevice *dev, size_t *num_clocks) return 0; } -static int scmi_clk_get_attibute(struct udevice *dev, int clkid, char **name, +static int scmi_clk_get_attibute(struct udevice *dev, int clkid, char *name, u32 *attr) { struct scmi_clock_priv *priv = dev_get_priv(dev); @@ -108,7 +111,7 @@ static int scmi_clk_get_attibute(struct udevice *dev, int clkid, char **name, if (ret) return ret; - *name = strdup(out.clock_name); + strncpy(name, out.clock_name, SCMI_CLOCK_NAME_LENGTH_MAX); *attr = out.attributes; } else { struct scmi_clk_attribute_out out; @@ -125,7 +128,7 @@ static int scmi_clk_get_attibute(struct udevice *dev, int clkid, char **name, if (ret) return ret; - *name = strdup(out.clock_name); + strncpy(name, out.clock_name, SCMI_CLOCK_NAME_LENGTH_MAX); *attr = out.attributes; } @@ -134,39 +137,93 @@ static int scmi_clk_get_attibute(struct udevice *dev, int clkid, char **name, static int scmi_clk_gate(struct clk *clk, int enable) { - struct scmi_clk_state_in in = { + struct scmi_clock_priv *priv = dev_get_parent_priv(clk->dev); + struct scmi_clk_state_in_v1 in_v1 = { + .clock_id = clk_get_id(clk), + .attributes = enable, + }; + /* Valid only from SCMI clock v2.1 */ + struct scmi_clk_state_in_v2 in_v2 = { .clock_id = clk_get_id(clk), .attributes = enable, }; struct scmi_clk_state_out out; - struct scmi_msg msg = SCMI_MSG_IN(SCMI_PROTOCOL_ID_CLOCK, - SCMI_CLOCK_CONFIG_SET, - in, out); + struct scmi_msg msg_v1 = SCMI_MSG_IN(SCMI_PROTOCOL_ID_CLOCK, + SCMI_CLOCK_CONFIG_SET, + in_v1, out); + struct scmi_msg msg_v2 = SCMI_MSG_IN(SCMI_PROTOCOL_ID_CLOCK, + SCMI_CLOCK_CONFIG_SET, + in_v2, out); int ret; - ret = devm_scmi_process_msg(clk->dev, &msg); + ret = devm_scmi_process_msg(clk->dev, + (priv->version < CLOCK_PROTOCOL_VERSION_2_1) ? + &msg_v1 : &msg_v2); if (ret) return ret; return scmi_to_linux_errno(out.status); } -static int scmi_clk_enable(struct clk *clk) +static int scmi_clk_get_ctrl_flags(struct clk *clk, u32 *ctrl_flags) { struct clk_scmi *clkscmi; + struct udevice *dev; + u32 attributes; struct clk *c; int ret; - if (!CONFIG_IS_ENABLED(CLK_CCF)) - return scmi_clk_gate(clk, 1); - ret = clk_get_by_id(clk->id, &c); if (ret) return ret; + dev = c->dev->parent; + clkscmi = container_of(c, struct clk_scmi, clk); - if (clkscmi->ctrl_flags & SUPPORT_CLK_STAT_CONTROL) + if (!clkscmi->attrs_resolved) { + char name[SCMI_CLOCK_NAME_LENGTH_MAX]; + ret = scmi_clk_get_attibute(dev, clk->id & CLK_ID_MSK, + name, &attributes); + if (ret) + return ret; + + strncpy(clkscmi->name, name, SCMI_CLOCK_NAME_LENGTH_MAX); + if (CLK_HAS_RESTRICTIONS(attributes)) { + u32 perm; + + ret = scmi_clk_get_permissions(dev, clk->id & CLK_ID_MSK, &perm); + if (ret < 0) + clkscmi->ctrl_flags = 0; + else + clkscmi->ctrl_flags = perm; + } else { + clkscmi->ctrl_flags = SUPPORT_CLK_STAT_CONTROL | + SUPPORT_CLK_PARENT_CONTROL | + SUPPORT_CLK_RATE_CONTROL; + } + + clkscmi->attrs_resolved = true; + } + + *ctrl_flags = clkscmi->ctrl_flags; + + return 0; +} + +static int scmi_clk_enable(struct clk *clk) +{ + u32 ctrl_flags; + int ret; + + if (!CONFIG_IS_ENABLED(CLK_CCF)) + return scmi_clk_gate(clk, 1); + + ret = scmi_clk_get_ctrl_flags(clk, &ctrl_flags); + if (ret) + return ret; + + if (ctrl_flags & SUPPORT_CLK_STAT_CONTROL) return scmi_clk_gate(clk, 1); /* Following Linux drivers/clk/clk-scmi.c, directly return 0 if agent has no permission. */ @@ -176,20 +233,17 @@ static int scmi_clk_enable(struct clk *clk) static int scmi_clk_disable(struct clk *clk) { - struct clk_scmi *clkscmi; - struct clk *c; + u32 ctrl_flags; int ret; if (!CONFIG_IS_ENABLED(CLK_CCF)) return scmi_clk_gate(clk, 0); - ret = clk_get_by_id(clk->id, &c); + ret = scmi_clk_get_ctrl_flags(clk, &ctrl_flags); if (ret) return ret; - clkscmi = container_of(c, struct clk_scmi, clk); - - if (clkscmi->ctrl_flags & SUPPORT_CLK_STAT_CONTROL) + if (ctrl_flags & SUPPORT_CLK_STAT_CONTROL) return scmi_clk_gate(clk, 0); /* Following Linux drivers/clk/clk-scmi.c, directly return 0 if agent has no permission. */ @@ -247,20 +301,17 @@ static ulong __scmi_clk_set_rate(struct clk *clk, ulong rate) static ulong scmi_clk_set_rate(struct clk *clk, ulong rate) { - struct clk_scmi *clkscmi; - struct clk *c; + u32 ctrl_flags; int ret; if (!CONFIG_IS_ENABLED(CLK_CCF)) return __scmi_clk_set_rate(clk, rate); - ret = clk_get_by_id(clk->id, &c); + ret = scmi_clk_get_ctrl_flags(clk, &ctrl_flags); if (ret) return ret; - clkscmi = container_of(c, struct clk_scmi, clk); - - if (clkscmi->ctrl_flags & SUPPORT_CLK_RATE_CONTROL) + if (ctrl_flags & SUPPORT_CLK_RATE_CONTROL) return __scmi_clk_set_rate(clk, rate); /* Following Linux drivers/clk/clk-scmi.c, directly return 0 if agent has no permission. */ @@ -271,7 +322,7 @@ static ulong scmi_clk_set_rate(struct clk *clk, ulong rate) static int scmi_clk_probe(struct udevice *dev) { - struct clk_scmi *clk_scmi; + struct clk_scmi *clk_scmi_bulk, *clk_scmi; struct scmi_clock_priv *priv = dev_get_priv(dev); size_t num_clocks, i; int ret; @@ -300,39 +351,23 @@ static int scmi_clk_probe(struct udevice *dev) return ret; } - for (i = 0; i < num_clocks; i++) { - char *clock_name; - u32 attributes; - - if (!scmi_clk_get_attibute(dev, i, &clock_name, &attributes)) { - clk_scmi = kzalloc(sizeof(*clk_scmi), GFP_KERNEL); - if (!clk_scmi || !clock_name) - ret = -ENOMEM; - else - ret = clk_register(&clk_scmi->clk, dev->driver->name, - clock_name, dev->name); + clk_scmi_bulk = kzalloc(num_clocks * sizeof(*clk_scmi), GFP_KERNEL); + if (!clk_scmi_bulk) + return -ENOMEM; - if (ret) { - free(clk_scmi); - free(clock_name); - return ret; - } + for (i = 0; i < num_clocks; i++) { + clk_scmi = clk_scmi_bulk + i; + char *clock_name = clk_scmi->name; - dev_clk_dm(dev, i, &clk_scmi->clk); + snprintf(clock_name, SCMI_CLOCK_NAME_LENGTH_MAX, "scmi-%zu", i); - if (CLK_HAS_RESTRICTIONS(attributes)) { - u32 perm; + ret = clk_register(&clk_scmi->clk, dev->driver->name, + clock_name, dev->name); + if (ret) + return ret; - ret = scmi_clk_get_permissions(dev, i, &perm); - if (ret < 0) - clk_scmi->ctrl_flags = 0; - else - clk_scmi->ctrl_flags = perm; - } else { - clk_scmi->ctrl_flags = SUPPORT_CLK_STAT_CONTROL | SUPPORT_CLK_PARENT_CONTROL | - SUPPORT_CLK_RATE_CONTROL; - } - } + dev_clk_dm(dev, i, &clk_scmi->clk); + dev_set_parent_priv(clk_scmi->clk.dev, priv); } return 0; @@ -359,20 +394,17 @@ static int __scmi_clk_set_parent(struct clk *clk, struct clk *parent) static int scmi_clk_set_parent(struct clk *clk, struct clk *parent) { - struct clk_scmi *clkscmi; - struct clk *c; + u32 ctrl_flags; int ret; if (!CONFIG_IS_ENABLED(CLK_CCF)) - return -ENOTSUPP; + return __scmi_clk_set_parent(clk, parent); - ret = clk_get_by_id(clk->id, &c); + ret = scmi_clk_get_ctrl_flags(clk, &ctrl_flags); if (ret) return ret; - clkscmi = container_of(c, struct clk_scmi, clk); - - if (clkscmi->ctrl_flags & SUPPORT_CLK_PARENT_CONTROL) + if (ctrl_flags & SUPPORT_CLK_PARENT_CONTROL) return __scmi_clk_set_parent(clk, parent); /* Following Linux drivers/clk/clk-scmi.c, directly return 0 if agent has no permission. */ diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c index 071d998a0a5..cf1cf8abfbe 100644 --- a/drivers/core/ofnode.c +++ b/drivers/core/ofnode.c @@ -1221,13 +1221,16 @@ int ofnode_decode_display_timing(ofnode parent, int index, int ret = 0; timings = ofnode_find_subnode(parent, "display-timings"); - if (!ofnode_valid(timings)) - return -EINVAL; - - i = 0; - ofnode_for_each_subnode(node, timings) { - if (i++ == index) - break; + if (ofnode_valid(timings)) { + i = 0; + ofnode_for_each_subnode(node, timings) { + if (i++ == index) + break; + } + } else { + if (index != 0) + return -EINVAL; + node = ofnode_find_subnode(parent, "panel-timing"); } if (!ofnode_valid(node)) diff --git a/drivers/firmware/scmi/sandbox-scmi_agent.c b/drivers/firmware/scmi/sandbox-scmi_agent.c index 74a87832dcb..5b242a039c2 100644 --- a/drivers/firmware/scmi/sandbox-scmi_agent.c +++ b/drivers/firmware/scmi/sandbox-scmi_agent.c @@ -828,7 +828,7 @@ static int sandbox_scmi_clock_rate_get(struct udevice *dev, static int sandbox_scmi_clock_gate(struct udevice *dev, struct scmi_msg *msg) { - struct scmi_clk_state_in *in = NULL; + struct scmi_clk_state_in_v1 *in = NULL; struct scmi_clk_state_out *out = NULL; struct sandbox_scmi_clk *clk_state = NULL; @@ -836,7 +836,7 @@ static int sandbox_scmi_clock_gate(struct udevice *dev, struct scmi_msg *msg) !msg->out_msg || msg->out_msg_sz < sizeof(*out)) return -EINVAL; - in = (struct scmi_clk_state_in *)msg->in_msg; + in = (struct scmi_clk_state_in_v1 *)msg->in_msg; out = (struct scmi_clk_state_out *)msg->out_msg; clk_state = get_scmi_clk_state(in->clock_id); diff --git a/drivers/firmware/scmi/smt.c b/drivers/firmware/scmi/smt.c index 237871559f0..cd1c0801f72 100644 --- a/drivers/firmware/scmi/smt.c +++ b/drivers/firmware/scmi/smt.c @@ -61,20 +61,6 @@ int scmi_dt_get_smt_buffer(struct udevice *dev, struct scmi_smt *smt) if (device_is_compatible(dev, "arm,scmi") && ofnode_has_property(dev_ofnode(dev), "mboxes")) scmi_smt_enable_intr(smt, true); -#ifdef CONFIG_ARM - if (dcache_status()) { - u32 align_size; - - if (IS_ENABLED(CONFIG_ARM64)) - align_size = PAGE_SIZE; - else - align_size = MMU_SECTION_SIZE; - - mmu_set_region_dcache_behaviour(ALIGN_DOWN((uintptr_t)smt->buf, align_size), - ALIGN(smt->size, align_size), DCACHE_OFF); - } -#endif - return 0; } diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index a47c127d98c..142db9e47b8 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -356,6 +356,7 @@ config NPCM_SGPIO config OMAP_GPIO bool "TI OMAP GPIO driver" depends on ARCH_OMAP2PLUS + select TI_SYSC if OF_CONTROL default y help Support GPIO controllers on the TI OMAP3/4/5 and related (such as diff --git a/drivers/i2c/muxes/i2c-mux-uclass.c b/drivers/i2c/muxes/i2c-mux-uclass.c index 012881de05b..7f4eb914af2 100644 --- a/drivers/i2c/muxes/i2c-mux-uclass.c +++ b/drivers/i2c/muxes/i2c-mux-uclass.c @@ -130,7 +130,7 @@ static int i2c_mux_post_probe(struct udevice *mux) return 0; } -int i2c_mux_select(struct udevice *dev) +static int i2c_mux_select(struct udevice *dev) { struct i2c_mux_bus *plat = dev_get_parent_plat(dev); struct udevice *mux = dev->parent; @@ -142,7 +142,7 @@ int i2c_mux_select(struct udevice *dev) return ops->select(mux, dev, plat->channel); } -int i2c_mux_deselect(struct udevice *dev) +static int i2c_mux_deselect(struct udevice *dev) { struct i2c_mux_bus *plat = dev_get_parent_plat(dev); struct udevice *mux = dev->parent; diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig index 754b99bf3eb..c76c10e1ef9 100644 --- a/drivers/mtd/nand/raw/Kconfig +++ b/drivers/mtd/nand/raw/Kconfig @@ -11,7 +11,6 @@ config SYS_NAND_SELF_INIT config SPL_SYS_NAND_SELF_INIT bool - depends on !SPL_NAND_SIMPLE help This option, if enabled, provides more flexible and linux-like NAND initialization process, in SPL. @@ -454,7 +453,6 @@ config NAND_SANDBOX select SYS_NAND_SELF_INIT select SPL_SYS_NAND_SELF_INIT select SPL_NAND_INIT - select SYS_NAND_SOFT_ECC select BCH select NAND_ECC_BCH imply CMD_NAND @@ -671,7 +669,6 @@ config SYS_NAND_PAGE_SIZE MVEBU_SPL_BOOT_DEVICE_NAND || \ (NAND_ATMEL && SPL_NAND_SUPPORT) || \ SPL_GENERATE_ATMEL_PMECC_HEADER || NAND_SANDBOX || NAND_CADENCE - depends on !NAND_MXS && !NAND_DENALI_DT && !NAND_LPC32XX_MLC && !NAND_MT7621 help Number of data bytes in one page for the NAND chip on the board, not including the OOB area. @@ -681,7 +678,6 @@ config SYS_NAND_OOBSIZE depends on ARCH_SUNXI || NAND_OMAP_GPMC || \ SPL_NAND_SIMPLE || (NAND_MXC && SPL_NAND_SUPPORT) || \ (NAND_ATMEL && SPL_NAND_SUPPORT) || SPL_GENERATE_ATMEL_PMECC_HEADER - depends on !NAND_MXS && !NAND_DENALI_DT && !NAND_LPC32XX_MLC help Number of bytes in the Out-Of-Band area for the NAND chip on the board. diff --git a/drivers/mtd/nand/spi/Makefile b/drivers/mtd/nand/spi/Makefile index 152aa1a3783..a7a0b2cb4b9 100644 --- a/drivers/mtd/nand/spi/Makefile +++ b/drivers/mtd/nand/spi/Makefile @@ -1,6 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 spinand-objs := core.o otp.o -spinand-objs += alliancememory.o ato.o esmt.o foresee.o gigadevice.o macronix.o +spinand-objs += alliancememory.o ato.o esmt.o fmsh.o foresee.o gigadevice.o macronix.o spinand-objs += micron.o paragon.o skyhigh.o toshiba.o winbond.o xtx.o obj-$(CONFIG_MTD_SPI_NAND) += spinand.o diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c index 0c435059546..14af4264612 100644 --- a/drivers/mtd/nand/spi/core.c +++ b/drivers/mtd/nand/spi/core.c @@ -1227,6 +1227,7 @@ static const struct spinand_manufacturer *spinand_manufacturers[] = { &alliancememory_spinand_manufacturer, &ato_spinand_manufacturer, &esmt_c8_spinand_manufacturer, + &fmsh_spinand_manufacturer, &foresee_spinand_manufacturer, &gigadevice_spinand_manufacturer, ¯onix_spinand_manufacturer, diff --git a/drivers/mtd/nand/spi/fmsh.c b/drivers/mtd/nand/spi/fmsh.c new file mode 100644 index 00000000000..80837b7dd42 --- /dev/null +++ b/drivers/mtd/nand/spi/fmsh.c @@ -0,0 +1,76 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2020-2021 Rockchip Electronics Co., Ltd. + * + * Author: Dingqiang Lin <[email protected]> + */ + +#ifndef __UBOOT__ +#include <linux/device.h> +#include <linux/kernel.h> +#endif +#include <linux/mtd/spinand.h> + +#define SPINAND_MFR_FMSH 0xA1 + +static SPINAND_OP_VARIANTS(read_cache_variants, + SPINAND_PAGE_READ_FROM_CACHE_1S_4S_4S_OP(0, 2, NULL, 0, 0), + SPINAND_PAGE_READ_FROM_CACHE_1S_1S_4S_OP(0, 1, NULL, 0, 0), + SPINAND_PAGE_READ_FROM_CACHE_1S_2S_2S_OP(0, 1, NULL, 0, 0), + SPINAND_PAGE_READ_FROM_CACHE_1S_1S_2S_OP(0, 1, NULL, 0, 0), + SPINAND_PAGE_READ_FROM_CACHE_FAST_1S_1S_1S_OP(0, 1, NULL, 0, 0), + SPINAND_PAGE_READ_FROM_CACHE_1S_1S_1S_OP(0, 1, NULL, 0, 0)); + +static SPINAND_OP_VARIANTS(write_cache_variants, + SPINAND_PROG_LOAD_1S_1S_4S_OP(true, 0, NULL, 0), + SPINAND_PROG_LOAD_1S_1S_1S_OP(true, 0, NULL, 0)); + +static SPINAND_OP_VARIANTS(update_cache_variants, + SPINAND_PROG_LOAD_1S_1S_4S_OP(false, 0, NULL, 0), + SPINAND_PROG_LOAD_1S_1S_1S_OP(false, 0, NULL, 0)); + +static int fm25s01a_ooblayout_ecc(struct mtd_info *mtd, int section, + struct mtd_oob_region *region) +{ + return -ERANGE; +} + +static int fm25s01a_ooblayout_free(struct mtd_info *mtd, int section, + struct mtd_oob_region *region) +{ + if (section) + return -ERANGE; + + region->offset = 2; + region->length = 62; + + return 0; +} + +static const struct mtd_ooblayout_ops fm25s01a_ooblayout = { + .ecc = fm25s01a_ooblayout_ecc, + .rfree = fm25s01a_ooblayout_free, +}; + +static const struct spinand_info fmsh_spinand_table[] = { + SPINAND_INFO("FM25S01A", + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xE4), + NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1), + NAND_ECCREQ(1, 512), + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, + &write_cache_variants, + &update_cache_variants), + 0, + SPINAND_ECCINFO(&fm25s01a_ooblayout, NULL)), +}; + +static const struct spinand_manufacturer_ops fmsh_spinand_manuf_ops = { +}; + +const struct spinand_manufacturer fmsh_spinand_manufacturer = { + .id = SPINAND_MFR_FMSH, + .name = "Fudan Micro", + .chips = fmsh_spinand_table, + .nchips = ARRAY_SIZE(fmsh_spinand_table), + .ops = &fmsh_spinand_manuf_ops, +}; diff --git a/drivers/mtd/spi/spi-nor-ids.c b/drivers/mtd/spi/spi-nor-ids.c index 0383175beb5..b6a07fa9063 100644 --- a/drivers/mtd/spi/spi-nor-ids.c +++ b/drivers/mtd/spi/spi-nor-ids.c @@ -591,6 +591,12 @@ const struct flash_info spi_nor_ids[] = { { INFO("w25m512jw", 0xef6119, 0, 64 * 1024, 1024, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, { INFO("w25m512jv", 0xef7119, 0, 64 * 1024, 1024, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, { INFO("w25h02jv", 0xef9022, 0, 64 * 1024, 4096, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, + { INFO("w25h512nw-am", 0xefa020, 0, 64 * 1024, 1024, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, + { INFO("w25h01nw-am", 0xefa021, 0, 64 * 1024, 2048, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, + { INFO("w25h02nw-am", 0xefa022, 0, 64 * 1024, 4096, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, + { INFO("w25q01nw-iq", 0xef6021, 0, 64 * 1024, 2048, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, + { INFO("w25q01nw-im", 0xef8021, 0, 64 * 1024, 2048, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, + { INFO("w25q02nw-im", 0xef8022, 0, 64 * 1024, 4096, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, { INFO("w77q51nw", 0xef8a1a, 0, 64 * 1024, 1024, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) }, #endif #ifdef CONFIG_SPI_FLASH_XMC diff --git a/drivers/net/xilinx_axi_emac.c b/drivers/net/xilinx_axi_emac.c index 22e119370c8..fb48feb4469 100644 --- a/drivers/net/xilinx_axi_emac.c +++ b/drivers/net/xilinx_axi_emac.c @@ -619,11 +619,11 @@ static int axiemac_start(struct udevice *dev) #endif rx_bd.cntrl = sizeof(rxframe); /* Flush the last BD so DMA core could see the updates */ - flush_cache((phys_addr_t)&rx_bd, sizeof(rx_bd)); + flush_cache((phys_addr_t)(uintptr_t)&rx_bd, sizeof(rx_bd)); /* It is necessary to flush rxframe because if you don't do it * then cache can contain uninitialized data */ - flush_cache((phys_addr_t)&rxframe, sizeof(rxframe)); + flush_cache((phys_addr_t)(uintptr_t)&rxframe, sizeof(rxframe)); /* Start the hardware */ temp = readl(&priv->dmarx->control); @@ -675,7 +675,7 @@ static int axiemac_send(struct udevice *dev, void *ptr, int len) } /* Flush packet to main memory to be trasfered by DMA */ - flush_cache((phys_addr_t)ptr, len); + flush_cache((phys_addr_t)(uintptr_t)ptr, len); /* Setup Tx BD */ memset(&tx_bd, 0, sizeof(tx_bd)); @@ -691,7 +691,7 @@ static int axiemac_send(struct udevice *dev, void *ptr, int len) XAXIDMA_BD_CTRL_TXEOF_MASK; /* Flush the last BD so DMA core could see the updates */ - flush_cache((phys_addr_t)&tx_bd, sizeof(tx_bd)); + flush_cache((phys_addr_t)(uintptr_t)&tx_bd, sizeof(tx_bd)); if (readl(&priv->dmatx->status) & XAXIDMA_HALTED_MASK) { u32 temp; @@ -791,11 +791,11 @@ static int axiemac_free_pkt(struct udevice *dev, uchar *packet, int length) rx_bd.cntrl = sizeof(rxframe); /* Write bd to HW */ - flush_cache((phys_addr_t)&rx_bd, sizeof(rx_bd)); + flush_cache((phys_addr_t)(uintptr_t)&rx_bd, sizeof(rx_bd)); /* It is necessary to flush rxframe because if you don't do it * then cache will contain previous packet */ - flush_cache((phys_addr_t)&rxframe, sizeof(rxframe)); + flush_cache((phys_addr_t)(uintptr_t)&rxframe, sizeof(rxframe)); /* Rx BD is ready - start again */ axienet_dma_write(&rx_bd, &priv->dmarx->tail); @@ -831,10 +831,10 @@ static int axi_emac_probe(struct udevice *dev) struct axidma_priv *priv = dev_get_priv(dev); int ret; - priv->iobase = (struct axi_regs *)pdata->iobase; + priv->iobase = (struct axi_regs *)(uintptr_t)pdata->iobase; priv->dmatx = plat->dmatx; /* RX channel offset is 0x30 */ - priv->dmarx = (struct axidma_reg *)((phys_addr_t)priv->dmatx + 0x30); + priv->dmarx = (struct axidma_reg *)((uintptr_t)priv->dmatx + 0x30); priv->mactype = plat->mactype; if (priv->mactype == EMAC_1G) { diff --git a/drivers/pinctrl/renesas/pfc-r8a779g0.c b/drivers/pinctrl/renesas/pfc-r8a779g0.c index ad113cd3e5d..c63adedd297 100644 --- a/drivers/pinctrl/renesas/pfc-r8a779g0.c +++ b/drivers/pinctrl/renesas/pfc-r8a779g0.c @@ -354,7 +354,7 @@ #define IP1SR2_3_0 FM(TPU0TO0_A) FM(CANFD6_RX) F_(0, 0) FM(TCLK1_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) #define IP1SR2_7_4 FM(CAN_CLK) FM(FXR_TXENA_N_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) #define IP1SR2_11_8 FM(CANFD0_TX) FM(FXR_TXENB_N_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) -#define IP1SR2_15_12 FM(CANFD0_RX) FM(STPWT_EXTFXR) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP1SR2_15_12 FM(CANFD0_RX) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) #define IP1SR2_19_16 FM(CANFD2_TX) FM(TPU0TO2_A) F_(0, 0) FM(TCLK3_C) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) #define IP1SR2_23_20 FM(CANFD2_RX) FM(TPU0TO3_A) FM(PWM1_B) FM(TCLK4_C) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) #define IP1SR2_27_24 FM(CANFD3_TX) F_(0, 0) FM(PWM2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) @@ -473,55 +473,55 @@ #define IP0SR6_7_4 FM(AVB1_MAGIC) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) #define IP0SR6_11_8 FM(AVB1_MDC) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) #define IP0SR6_15_12 FM(AVB1_PHY_INT) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) -#define IP0SR6_19_16 FM(AVB1_LINK) FM(AVB1_MII_TX_ER) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) -#define IP0SR6_23_20 FM(AVB1_AVTP_MATCH) FM(AVB1_MII_RX_ER) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) -#define IP0SR6_27_24 FM(AVB1_TXC) FM(AVB1_MII_TXC) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) -#define IP0SR6_31_28 FM(AVB1_TX_CTL) FM(AVB1_MII_TX_EN) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP0SR6_19_16 FM(AVB1_LINK) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP0SR6_23_20 FM(AVB1_AVTP_MATCH) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP0SR6_27_24 FM(AVB1_TXC) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP0SR6_31_28 FM(AVB1_TX_CTL) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) /* IP1SR6 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */ -#define IP1SR6_3_0 FM(AVB1_RXC) FM(AVB1_MII_RXC) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) -#define IP1SR6_7_4 FM(AVB1_RX_CTL) FM(AVB1_MII_RX_DV) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) -#define IP1SR6_11_8 FM(AVB1_AVTP_PPS) FM(AVB1_MII_COL) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) -#define IP1SR6_15_12 FM(AVB1_AVTP_CAPTURE) FM(AVB1_MII_CRS) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) -#define IP1SR6_19_16 FM(AVB1_TD1) FM(AVB1_MII_TD1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) -#define IP1SR6_23_20 FM(AVB1_TD0) FM(AVB1_MII_TD0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) -#define IP1SR6_27_24 FM(AVB1_RD1) FM(AVB1_MII_RD1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) -#define IP1SR6_31_28 FM(AVB1_RD0) FM(AVB1_MII_RD0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP1SR6_3_0 FM(AVB1_RXC) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP1SR6_7_4 FM(AVB1_RX_CTL) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP1SR6_11_8 FM(AVB1_AVTP_PPS) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP1SR6_15_12 FM(AVB1_AVTP_CAPTURE) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP1SR6_19_16 FM(AVB1_TD1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP1SR6_23_20 FM(AVB1_TD0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP1SR6_27_24 FM(AVB1_RD1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP1SR6_31_28 FM(AVB1_RD0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) /* IP2SR6 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */ -#define IP2SR6_3_0 FM(AVB1_TD2) FM(AVB1_MII_TD2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) -#define IP2SR6_7_4 FM(AVB1_RD2) FM(AVB1_MII_RD2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) -#define IP2SR6_11_8 FM(AVB1_TD3) FM(AVB1_MII_TD3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) -#define IP2SR6_15_12 FM(AVB1_RD3) FM(AVB1_MII_RD3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP2SR6_3_0 FM(AVB1_TD2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP2SR6_7_4 FM(AVB1_RD2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP2SR6_11_8 FM(AVB1_TD3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP2SR6_15_12 FM(AVB1_RD3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) #define IP2SR6_19_16 FM(AVB1_TXCREFCLK) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) /* SR7 */ /* IP0SR7 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */ -#define IP0SR7_3_0 FM(AVB0_AVTP_PPS) FM(AVB0_MII_COL) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) -#define IP0SR7_7_4 FM(AVB0_AVTP_CAPTURE) FM(AVB0_MII_CRS) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) -#define IP0SR7_11_8 FM(AVB0_AVTP_MATCH) FM(AVB0_MII_RX_ER) FM(CC5_OSCOUT) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) -#define IP0SR7_15_12 FM(AVB0_TD3) FM(AVB0_MII_TD3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) -#define IP0SR7_19_16 FM(AVB0_LINK) FM(AVB0_MII_TX_ER) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP0SR7_3_0 FM(AVB0_AVTP_PPS) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP0SR7_7_4 FM(AVB0_AVTP_CAPTURE) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP0SR7_11_8 FM(AVB0_AVTP_MATCH) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP0SR7_15_12 FM(AVB0_TD3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP0SR7_19_16 FM(AVB0_LINK) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) #define IP0SR7_23_20 FM(AVB0_PHY_INT) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) -#define IP0SR7_27_24 FM(AVB0_TD2) FM(AVB0_MII_TD2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) -#define IP0SR7_31_28 FM(AVB0_TD1) FM(AVB0_MII_TD1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP0SR7_27_24 FM(AVB0_TD2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP0SR7_31_28 FM(AVB0_TD1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) /* IP1SR7 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */ -#define IP1SR7_3_0 FM(AVB0_RD3) FM(AVB0_MII_RD3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP1SR7_3_0 FM(AVB0_RD3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) #define IP1SR7_7_4 FM(AVB0_TXCREFCLK) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) #define IP1SR7_11_8 FM(AVB0_MAGIC) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) -#define IP1SR7_15_12 FM(AVB0_TD0) FM(AVB0_MII_TD0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) -#define IP1SR7_19_16 FM(AVB0_RD2) FM(AVB0_MII_RD2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP1SR7_15_12 FM(AVB0_TD0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP1SR7_19_16 FM(AVB0_RD2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) #define IP1SR7_23_20 FM(AVB0_MDC) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) #define IP1SR7_27_24 FM(AVB0_MDIO) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) -#define IP1SR7_31_28 FM(AVB0_TXC) FM(AVB0_MII_TXC) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP1SR7_31_28 FM(AVB0_TXC) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) /* IP2SR7 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */ -#define IP2SR7_3_0 FM(AVB0_TX_CTL) FM(AVB0_MII_TX_EN) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) -#define IP2SR7_7_4 FM(AVB0_RD1) FM(AVB0_MII_RD1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) -#define IP2SR7_11_8 FM(AVB0_RD0) FM(AVB0_MII_RD0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) -#define IP2SR7_15_12 FM(AVB0_RXC) FM(AVB0_MII_RXC) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) -#define IP2SR7_19_16 FM(AVB0_RX_CTL) FM(AVB0_MII_RX_DV) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP2SR7_3_0 FM(AVB0_TX_CTL) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP2SR7_7_4 FM(AVB0_RD1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP2SR7_11_8 FM(AVB0_RD0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP2SR7_15_12 FM(AVB0_RXC) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP2SR7_19_16 FM(AVB0_RX_CTL) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) /* SR8 */ /* IP0SR8 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */ @@ -927,7 +927,6 @@ static const u16 pinmux_data[] = { PINMUX_IPSR_GPSR(IP1SR2_11_8, FXR_TXENB_N_B), PINMUX_IPSR_GPSR(IP1SR2_15_12, CANFD0_RX), - PINMUX_IPSR_GPSR(IP1SR2_15_12, STPWT_EXTFXR), PINMUX_IPSR_GPSR(IP1SR2_19_16, CANFD2_TX), PINMUX_IPSR_GPSR(IP1SR2_19_16, TPU0TO2_A), @@ -1078,118 +1077,85 @@ static const u16 pinmux_data[] = { PINMUX_IPSR_GPSR(IP0SR6_15_12, AVB1_PHY_INT), PINMUX_IPSR_GPSR(IP0SR6_19_16, AVB1_LINK), - PINMUX_IPSR_GPSR(IP0SR6_19_16, AVB1_MII_TX_ER), PINMUX_IPSR_GPSR(IP0SR6_23_20, AVB1_AVTP_MATCH), - PINMUX_IPSR_GPSR(IP0SR6_23_20, AVB1_MII_RX_ER), PINMUX_IPSR_GPSR(IP0SR6_27_24, AVB1_TXC), - PINMUX_IPSR_GPSR(IP0SR6_27_24, AVB1_MII_TXC), PINMUX_IPSR_GPSR(IP0SR6_31_28, AVB1_TX_CTL), - PINMUX_IPSR_GPSR(IP0SR6_31_28, AVB1_MII_TX_EN), /* IP1SR6 */ PINMUX_IPSR_GPSR(IP1SR6_3_0, AVB1_RXC), - PINMUX_IPSR_GPSR(IP1SR6_3_0, AVB1_MII_RXC), PINMUX_IPSR_GPSR(IP1SR6_7_4, AVB1_RX_CTL), - PINMUX_IPSR_GPSR(IP1SR6_7_4, AVB1_MII_RX_DV), PINMUX_IPSR_GPSR(IP1SR6_11_8, AVB1_AVTP_PPS), - PINMUX_IPSR_GPSR(IP1SR6_11_8, AVB1_MII_COL), PINMUX_IPSR_GPSR(IP1SR6_15_12, AVB1_AVTP_CAPTURE), - PINMUX_IPSR_GPSR(IP1SR6_15_12, AVB1_MII_CRS), PINMUX_IPSR_GPSR(IP1SR6_19_16, AVB1_TD1), - PINMUX_IPSR_GPSR(IP1SR6_19_16, AVB1_MII_TD1), PINMUX_IPSR_GPSR(IP1SR6_23_20, AVB1_TD0), - PINMUX_IPSR_GPSR(IP1SR6_23_20, AVB1_MII_TD0), PINMUX_IPSR_GPSR(IP1SR6_27_24, AVB1_RD1), - PINMUX_IPSR_GPSR(IP1SR6_27_24, AVB1_MII_RD1), PINMUX_IPSR_GPSR(IP1SR6_31_28, AVB1_RD0), - PINMUX_IPSR_GPSR(IP1SR6_31_28, AVB1_MII_RD0), /* IP2SR6 */ PINMUX_IPSR_GPSR(IP2SR6_3_0, AVB1_TD2), - PINMUX_IPSR_GPSR(IP2SR6_3_0, AVB1_MII_TD2), PINMUX_IPSR_GPSR(IP2SR6_7_4, AVB1_RD2), - PINMUX_IPSR_GPSR(IP2SR6_7_4, AVB1_MII_RD2), PINMUX_IPSR_GPSR(IP2SR6_11_8, AVB1_TD3), - PINMUX_IPSR_GPSR(IP2SR6_11_8, AVB1_MII_TD3), PINMUX_IPSR_GPSR(IP2SR6_15_12, AVB1_RD3), - PINMUX_IPSR_GPSR(IP2SR6_15_12, AVB1_MII_RD3), PINMUX_IPSR_GPSR(IP2SR6_19_16, AVB1_TXCREFCLK), /* IP0SR7 */ PINMUX_IPSR_GPSR(IP0SR7_3_0, AVB0_AVTP_PPS), - PINMUX_IPSR_GPSR(IP0SR7_3_0, AVB0_MII_COL), PINMUX_IPSR_GPSR(IP0SR7_7_4, AVB0_AVTP_CAPTURE), - PINMUX_IPSR_GPSR(IP0SR7_7_4, AVB0_MII_CRS), PINMUX_IPSR_GPSR(IP0SR7_11_8, AVB0_AVTP_MATCH), - PINMUX_IPSR_GPSR(IP0SR7_11_8, AVB0_MII_RX_ER), - PINMUX_IPSR_GPSR(IP0SR7_11_8, CC5_OSCOUT), PINMUX_IPSR_GPSR(IP0SR7_15_12, AVB0_TD3), - PINMUX_IPSR_GPSR(IP0SR7_15_12, AVB0_MII_TD3), PINMUX_IPSR_GPSR(IP0SR7_19_16, AVB0_LINK), - PINMUX_IPSR_GPSR(IP0SR7_19_16, AVB0_MII_TX_ER), PINMUX_IPSR_GPSR(IP0SR7_23_20, AVB0_PHY_INT), PINMUX_IPSR_GPSR(IP0SR7_27_24, AVB0_TD2), - PINMUX_IPSR_GPSR(IP0SR7_27_24, AVB0_MII_TD2), PINMUX_IPSR_GPSR(IP0SR7_31_28, AVB0_TD1), - PINMUX_IPSR_GPSR(IP0SR7_31_28, AVB0_MII_TD1), /* IP1SR7 */ PINMUX_IPSR_GPSR(IP1SR7_3_0, AVB0_RD3), - PINMUX_IPSR_GPSR(IP1SR7_3_0, AVB0_MII_RD3), PINMUX_IPSR_GPSR(IP1SR7_7_4, AVB0_TXCREFCLK), PINMUX_IPSR_GPSR(IP1SR7_11_8, AVB0_MAGIC), PINMUX_IPSR_GPSR(IP1SR7_15_12, AVB0_TD0), - PINMUX_IPSR_GPSR(IP1SR7_15_12, AVB0_MII_TD0), PINMUX_IPSR_GPSR(IP1SR7_19_16, AVB0_RD2), - PINMUX_IPSR_GPSR(IP1SR7_19_16, AVB0_MII_RD2), PINMUX_IPSR_GPSR(IP1SR7_23_20, AVB0_MDC), PINMUX_IPSR_GPSR(IP1SR7_27_24, AVB0_MDIO), PINMUX_IPSR_GPSR(IP1SR7_31_28, AVB0_TXC), - PINMUX_IPSR_GPSR(IP1SR7_31_28, AVB0_MII_TXC), /* IP2SR7 */ PINMUX_IPSR_GPSR(IP2SR7_3_0, AVB0_TX_CTL), - PINMUX_IPSR_GPSR(IP2SR7_3_0, AVB0_MII_TX_EN), PINMUX_IPSR_GPSR(IP2SR7_7_4, AVB0_RD1), - PINMUX_IPSR_GPSR(IP2SR7_7_4, AVB0_MII_RD1), PINMUX_IPSR_GPSR(IP2SR7_11_8, AVB0_RD0), - PINMUX_IPSR_GPSR(IP2SR7_11_8, AVB0_MII_RD0), PINMUX_IPSR_GPSR(IP2SR7_15_12, AVB0_RXC), - PINMUX_IPSR_GPSR(IP2SR7_15_12, AVB0_MII_RXC), PINMUX_IPSR_GPSR(IP2SR7_19_16, AVB0_RX_CTL), - PINMUX_IPSR_GPSR(IP2SR7_19_16, AVB0_MII_RX_DV), /* IP0SR8 */ PINMUX_IPSR_MSEL(IP0SR8_3_0, SCL0, SEL_SCL0_0), diff --git a/drivers/pinctrl/renesas/pfc-r8a779h0.c b/drivers/pinctrl/renesas/pfc-r8a779h0.c index d6c2fbcf854..2c6c901f3a4 100644 --- a/drivers/pinctrl/renesas/pfc-r8a779h0.c +++ b/drivers/pinctrl/renesas/pfc-r8a779h0.c @@ -342,7 +342,7 @@ #define IP1SR2_3_0 FM(TPU0TO0_A) F_(0, 0) F_(0, 0) FM(TCLK1_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) #define IP1SR2_7_4 FM(CAN_CLK) FM(FXR_TXENA_N_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) #define IP1SR2_11_8 FM(CANFD0_TX) FM(FXR_TXENB_N_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) -#define IP1SR2_15_12 FM(CANFD0_RX) FM(STPWT_EXTFXR) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP1SR2_15_12 FM(CANFD0_RX) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) #define IP1SR2_19_16 FM(CANFD2_TX) FM(TPU0TO2_A) F_(0, 0) FM(TCLK3_C) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) #define IP1SR2_23_20 FM(CANFD2_RX) FM(TPU0TO3_A) FM(PWM1_B) FM(TCLK4_C) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) #define IP1SR2_27_24 FM(CANFD3_TX) F_(0, 0) FM(PWM2_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) @@ -481,7 +481,7 @@ /* IP0SR7 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */ #define IP0SR7_3_0 FM(AVB0_AVTP_PPS) FM(AVB0_MII_COL) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) #define IP0SR7_7_4 FM(AVB0_AVTP_CAPTURE) FM(AVB0_MII_CRS) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) -#define IP0SR7_11_8 FM(AVB0_AVTP_MATCH) FM(AVB0_MII_RX_ER) FM(CC5_OSCOUT) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP0SR7_11_8 FM(AVB0_AVTP_MATCH) FM(AVB0_MII_RX_ER) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) #define IP0SR7_15_12 FM(AVB0_TD3) FM(AVB0_MII_TD3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) #define IP0SR7_19_16 FM(AVB0_LINK) FM(AVB0_MII_TX_ER) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) #define IP0SR7_23_20 FM(AVB0_PHY_INT) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) @@ -868,7 +868,6 @@ static const u16 pinmux_data[] = { PINMUX_IPSR_GPSR(IP1SR2_11_8, FXR_TXENB_N_B), PINMUX_IPSR_GPSR(IP1SR2_15_12, CANFD0_RX), - PINMUX_IPSR_GPSR(IP1SR2_15_12, STPWT_EXTFXR), PINMUX_IPSR_GPSR(IP1SR2_19_16, CANFD2_TX), PINMUX_IPSR_GPSR(IP1SR2_19_16, TPU0TO2_A), @@ -1126,7 +1125,6 @@ static const u16 pinmux_data[] = { PINMUX_IPSR_GPSR(IP0SR7_11_8, AVB0_AVTP_MATCH), PINMUX_IPSR_GPSR(IP0SR7_11_8, AVB0_MII_RX_ER), - PINMUX_IPSR_GPSR(IP0SR7_11_8, CC5_OSCOUT), PINMUX_IPSR_GPSR(IP0SR7_15_12, AVB0_TD3), PINMUX_IPSR_GPSR(IP0SR7_15_12, AVB0_MII_TD3), diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index 05608399be1..b414d022f3f 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -584,7 +584,7 @@ static int do_scsi_scan_one(struct udevice *dev, int id, int lun, bool verbose) struct udevice *bdev; struct blk_desc bd; struct blk_desc *bdesc; - char str[10], *name; + char str[10]; /* * detect the scsi driver to get information about its geometry (block @@ -600,10 +600,7 @@ 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); - name = strdup(str); - if (!name) - return log_msg_ret("nam", -ENOMEM); - ret = blk_create_devicef(dev, "scsi_blk", name, UCLASS_SCSI, -1, + ret = blk_create_devicef(dev, "scsi_blk", str, UCLASS_SCSI, -1, bd.blksz, bd.lba, &bdev); if (ret) { debug("Can't create device\n"); diff --git a/drivers/spi/airoha_snfi_spi.c b/drivers/spi/airoha_snfi_spi.c index 3ea25b293d1..769ec956793 100644 --- a/drivers/spi/airoha_snfi_spi.c +++ b/drivers/spi/airoha_snfi_spi.c @@ -141,12 +141,15 @@ #define SPI_NFI_CUS_SEC_SIZE_EN BIT(16) #define REG_SPI_NFI_RD_CTL2 0x0510 +#define SPI_NFI_DATA_READ_CMD GENMASK(7, 0) + #define REG_SPI_NFI_RD_CTL3 0x0514 #define REG_SPI_NFI_PG_CTL1 0x0524 #define SPI_NFI_PG_LOAD_CMD GENMASK(15, 8) #define REG_SPI_NFI_PG_CTL2 0x0528 + #define REG_SPI_NFI_NOR_PROG_ADDR 0x052c #define REG_SPI_NFI_NOR_RD_ADDR 0x0534 @@ -173,7 +176,9 @@ #define SPI_NAND_OP_READ_FROM_CACHE_SINGLE 0x03 #define SPI_NAND_OP_READ_FROM_CACHE_SINGLE_FAST 0x0b #define SPI_NAND_OP_READ_FROM_CACHE_DUAL 0x3b +#define SPI_NAND_OP_READ_FROM_CACHE_DUALIO 0xbb #define SPI_NAND_OP_READ_FROM_CACHE_QUAD 0x6b +#define SPI_NAND_OP_READ_FROM_CACHE_QUADIO 0xeb #define SPI_NAND_OP_WRITE_ENABLE 0x06 #define SPI_NAND_OP_WRITE_DISABLE 0x04 #define SPI_NAND_OP_PROGRAM_LOAD_SINGLE 0x02 @@ -186,6 +191,14 @@ #define SPI_NAND_OP_RESET 0xff #define SPI_NAND_OP_DIE_SELECT 0xc2 +/* SNAND FIFO commands */ +#define SNAND_FIFO_TX_BUSWIDTH_SINGLE 0x08 +#define SNAND_FIFO_TX_BUSWIDTH_DUAL 0x09 +#define SNAND_FIFO_TX_BUSWIDTH_QUAD 0x0a +#define SNAND_FIFO_RX_BUSWIDTH_SINGLE 0x0c +#define SNAND_FIFO_RX_BUSWIDTH_DUAL 0x0e +#define SNAND_FIFO_RX_BUSWIDTH_QUAD 0x0f + #define SPI_NAND_CACHE_SIZE (SZ_4K + SZ_256) #define SPI_MAX_TRANSFER_SIZE 511 @@ -205,12 +218,8 @@ struct airoha_snand_priv { struct regmap *regmap_nfi; struct clk *spi_clk; - struct { - size_t page_size; - size_t sec_size; - u8 sec_num; - u8 spare_size; - } nfi_cfg; + u8 *txrx_buf; + int dma; }; static int airoha_snand_set_fifo_op(struct airoha_snand_priv *priv, @@ -380,10 +389,26 @@ static int airoha_snand_set_mode(struct airoha_snand_priv *priv, return regmap_write(priv->regmap_ctrl, REG_SPI_CTRL_DUMMY, 0); } -static int airoha_snand_write_data(struct airoha_snand_priv *priv, u8 cmd, - const u8 *data, int len) +static int airoha_snand_write_data(struct airoha_snand_priv *priv, + const u8 *data, int len, int buswidth) { int i, data_len; + u8 cmd; + + switch (buswidth) { + case 0: + case 1: + cmd = SNAND_FIFO_TX_BUSWIDTH_SINGLE; + break; + case 2: + cmd = SNAND_FIFO_TX_BUSWIDTH_DUAL; + break; + case 4: + cmd = SNAND_FIFO_TX_BUSWIDTH_QUAD; + break; + default: + return -EINVAL; + } for (i = 0; i < len; i += data_len) { int err; @@ -402,16 +427,32 @@ static int airoha_snand_write_data(struct airoha_snand_priv *priv, u8 cmd, return 0; } -static int airoha_snand_read_data(struct airoha_snand_priv *priv, u8 *data, - int len) +static int airoha_snand_read_data(struct airoha_snand_priv *priv, + u8 *data, int len, int buswidth) { int i, data_len; + u8 cmd; + + switch (buswidth) { + case 0: + case 1: + cmd = SNAND_FIFO_RX_BUSWIDTH_SINGLE; + break; + case 2: + cmd = SNAND_FIFO_RX_BUSWIDTH_DUAL; + break; + case 4: + cmd = SNAND_FIFO_RX_BUSWIDTH_QUAD; + break; + default: + return -EINVAL; + } for (i = 0; i < len; i += data_len) { int err; data_len = min(len - i, SPI_MAX_TRANSFER_SIZE); - err = airoha_snand_set_fifo_op(priv, 0xc, data_len); + err = airoha_snand_set_fifo_op(priv, cmd, data_len); if (err) return err; @@ -439,131 +480,498 @@ static int airoha_snand_nfi_init(struct airoha_snand_priv *priv) SPI_NFI_ALL_IRQ_EN, SPI_NFI_AHB_DONE_EN); } -static int airoha_snand_nfi_config(struct airoha_snand_priv *priv) +static bool airoha_snand_is_page_ops(const struct spi_mem_op *op) { + if (op->addr.nbytes != 2) + return false; + + if (op->addr.buswidth != 1 && op->addr.buswidth != 2 && + op->addr.buswidth != 4) + return false; + + switch (op->data.dir) { + case SPI_MEM_DATA_IN: + if (op->dummy.nbytes * BITS_PER_BYTE / op->dummy.buswidth > 0xf) + return false; + + /* quad in / quad out */ + if (op->addr.buswidth == 4) + return op->data.buswidth == 4; + + if (op->addr.buswidth == 2) + return op->data.buswidth == 2; + + /* standard spi */ + return op->data.buswidth == 4 || op->data.buswidth == 2 || + op->data.buswidth == 1; + case SPI_MEM_DATA_OUT: + return !op->dummy.nbytes && op->addr.buswidth == 1 && + (op->data.buswidth == 4 || op->data.buswidth == 1); + default: + return false; + } +} + +static bool airoha_snand_supports_op(struct spi_slave *slave, + const struct spi_mem_op *op) +{ + if (!spi_mem_default_supports_op(slave, op)) + return false; + + if (op->cmd.buswidth != 1) + return false; + + if (airoha_snand_is_page_ops(op)) + return true; + + return (!op->addr.nbytes || op->addr.buswidth == 1) && + (!op->dummy.nbytes || op->dummy.buswidth == 1) && + (!op->data.nbytes || op->data.buswidth == 1); +} + +static int airoha_snand_dirmap_create(struct spi_mem_dirmap_desc *desc) +{ + struct spi_slave *slave = desc->slave; + struct udevice *bus = slave->dev->parent; + struct airoha_snand_priv *priv = dev_get_priv(bus); + + if (!priv->txrx_buf) + return -EINVAL; + + if (desc->info.offset + desc->info.length > U32_MAX) + return -EINVAL; + + /* continuous reading is not supported */ + if (desc->info.length > SPI_NAND_CACHE_SIZE) + return -E2BIG; + + if (!airoha_snand_supports_op(desc->slave, &desc->info.op_tmpl)) + return -EOPNOTSUPP; + + return 0; +} + +static ssize_t airoha_snand_dirmap_read(struct spi_mem_dirmap_desc *desc, + u64 offs, size_t len, void *buf) +{ + struct spi_slave *slave = desc->slave; + struct udevice *bus = slave->dev->parent; + struct airoha_snand_priv *priv = dev_get_priv(bus); + u8 *txrx_buf = priv->txrx_buf; + dma_addr_t dma_addr; + u32 val, rd_mode, opcode; + size_t bytes; int err; - u32 val; + if (!priv->dma) { + /* simplified version of spi_mem_no_dirmap_read() */ + struct spi_mem_op op = desc->info.op_tmpl; + + op.addr.val = desc->info.offset + offs; + op.data.buf.in = buf; + op.data.nbytes = len; + err = spi_mem_exec_op(desc->slave, &op); + if (err) + return err; + + return op.data.nbytes; + } + + /* minimum oob size is 64 */ + bytes = round_up(offs + len, 64); + + /* + * DUALIO and QUADIO opcodes are not supported by the spi controller, + * replace them with supported opcodes. + */ + opcode = desc->info.op_tmpl.cmd.opcode; + switch (opcode) { + case SPI_NAND_OP_READ_FROM_CACHE_SINGLE: + case SPI_NAND_OP_READ_FROM_CACHE_SINGLE_FAST: + rd_mode = 0; + break; + case SPI_NAND_OP_READ_FROM_CACHE_DUAL: + case SPI_NAND_OP_READ_FROM_CACHE_DUALIO: + opcode = SPI_NAND_OP_READ_FROM_CACHE_DUAL; + rd_mode = 1; + break; + case SPI_NAND_OP_READ_FROM_CACHE_QUAD: + case SPI_NAND_OP_READ_FROM_CACHE_QUADIO: + opcode = SPI_NAND_OP_READ_FROM_CACHE_QUAD; + rd_mode = 2; + break; + default: + /* unknown opcode */ + return -EOPNOTSUPP; + } + + err = airoha_snand_set_mode(priv, SPI_MODE_DMA); + if (err < 0) + return err; + + /* NFI reset */ err = regmap_write(priv->regmap_nfi, REG_SPI_NFI_CON, SPI_NFI_FIFO_FLUSH | SPI_NFI_RST); if (err) - return err; + goto error_dma_mode_off; - /* auto FDM */ - err = regmap_clear_bits(priv->regmap_nfi, REG_SPI_NFI_CNFG, - SPI_NFI_AUTO_FDM_EN); + /* NFI configure: + * - No AutoFDM (custom sector size (SECCUS) register will be used) + * - No SoC's hardware ECC (flash internal ECC will be used) + * - Use burst mode (faster, but requires 16 byte alignment for addresses) + * - Setup for reading (SPI_NFI_READ_MODE) + * - Setup reading command: FIELD_PREP(SPI_NFI_OPMODE, 6) + * - Use DMA instead of PIO for data reading + */ + err = regmap_update_bits(priv->regmap_nfi, REG_SPI_NFI_CNFG, + SPI_NFI_DMA_MODE | + SPI_NFI_READ_MODE | + SPI_NFI_DMA_BURST_EN | + SPI_NFI_HW_ECC_EN | + SPI_NFI_AUTO_FDM_EN | + SPI_NFI_OPMODE, + SPI_NFI_DMA_MODE | + SPI_NFI_READ_MODE | + SPI_NFI_DMA_BURST_EN | + FIELD_PREP(SPI_NFI_OPMODE, 6)); if (err) - return err; + goto error_dma_mode_off; - /* HW ECC */ - err = regmap_clear_bits(priv->regmap_nfi, REG_SPI_NFI_CNFG, - SPI_NFI_HW_ECC_EN); + /* Set number of sector will be read */ + err = regmap_update_bits(priv->regmap_nfi, REG_SPI_NFI_CON, + SPI_NFI_SEC_NUM, + FIELD_PREP(SPI_NFI_SEC_NUM, 1)); if (err) - return err; + goto error_dma_mode_off; - /* DMA Burst */ - err = regmap_set_bits(priv->regmap_nfi, REG_SPI_NFI_CNFG, - SPI_NFI_DMA_BURST_EN); + /* Set custom sector size */ + err = regmap_update_bits(priv->regmap_nfi, REG_SPI_NFI_SECCUS_SIZE, + SPI_NFI_CUS_SEC_SIZE | + SPI_NFI_CUS_SEC_SIZE_EN, + FIELD_PREP(SPI_NFI_CUS_SEC_SIZE, bytes) | + SPI_NFI_CUS_SEC_SIZE_EN); if (err) - return err; + goto error_dma_mode_off; - /* page format */ - switch (priv->nfi_cfg.spare_size) { - case 26: - val = FIELD_PREP(SPI_NFI_SPARE_SIZE, 0x1); - break; - case 27: - val = FIELD_PREP(SPI_NFI_SPARE_SIZE, 0x2); - break; - case 28: - val = FIELD_PREP(SPI_NFI_SPARE_SIZE, 0x3); - break; - default: - val = FIELD_PREP(SPI_NFI_SPARE_SIZE, 0x0); - break; - } + dma_addr = dma_map_single(txrx_buf, SPI_NAND_CACHE_SIZE, + DMA_FROM_DEVICE); + + /* set dma addr */ + err = regmap_write(priv->regmap_nfi, REG_SPI_NFI_STRADDR, + dma_addr); + if (err) + goto error_dma_unmap; + + /* + * Setup transfer length + * --------------------- + * The following rule MUST be met: + * transfer_length = + * = NFI_SNF_MISC_CTL2.read_data_byte_number = + * = NFI_CON.sector_number * NFI_SECCUS.custom_sector_size + */ + err = regmap_update_bits(priv->regmap_nfi, + REG_SPI_NFI_SNF_MISC_CTL2, + SPI_NFI_READ_DATA_BYTE_NUM, + FIELD_PREP(SPI_NFI_READ_DATA_BYTE_NUM, bytes)); + if (err) + goto error_dma_unmap; + + /* set read command */ + err = regmap_write(priv->regmap_nfi, REG_SPI_NFI_RD_CTL2, + FIELD_PREP(SPI_NFI_DATA_READ_CMD, opcode)); + if (err) + goto error_dma_unmap; + + /* set read mode */ + err = regmap_write(priv->regmap_nfi, REG_SPI_NFI_SNF_MISC_CTL, + FIELD_PREP(SPI_NFI_DATA_READ_WR_MODE, rd_mode)); + if (err) + goto error_dma_unmap; + + /* set read addr: zero page offset + descriptor read offset */ + err = regmap_write(priv->regmap_nfi, REG_SPI_NFI_RD_CTL3, + desc->info.offset); + if (err) + goto error_dma_unmap; + + err = regmap_write(priv->regmap_nfi, REG_SPI_NFI_CMD, 0x0); + if (err) + goto error_dma_unmap; + + /* trigger dma reading */ + err = regmap_clear_bits(priv->regmap_nfi, REG_SPI_NFI_CON, + SPI_NFI_RD_TRIG); + if (err) + goto error_dma_unmap; - err = regmap_update_bits(priv->regmap_nfi, REG_SPI_NFI_PAGEFMT, - SPI_NFI_SPARE_SIZE, val); + err = regmap_set_bits(priv->regmap_nfi, REG_SPI_NFI_CON, + SPI_NFI_RD_TRIG); if (err) + goto error_dma_unmap; + + err = regmap_read_poll_timeout(priv->regmap_nfi, + REG_SPI_NFI_SNF_STA_CTL1, val, + (val & SPI_NFI_READ_FROM_CACHE_DONE), + 0, 1 * MSEC_PER_SEC); + if (err) + goto error_dma_unmap; + + /* + * SPI_NFI_READ_FROM_CACHE_DONE bit must be written at the end + * of dirmap_read operation even if it is already set. + */ + err = regmap_update_bits(priv->regmap_nfi, REG_SPI_NFI_SNF_STA_CTL1, + SPI_NFI_READ_FROM_CACHE_DONE, + SPI_NFI_READ_FROM_CACHE_DONE); + if (err) + goto error_dma_unmap; + + err = regmap_read_poll_timeout(priv->regmap_nfi, REG_SPI_NFI_INTR, + val, (val & SPI_NFI_AHB_DONE), 0, + 1 * MSEC_PER_SEC); + if (err) + goto error_dma_unmap; + + /* DMA read need delay for data ready from controller to DRAM */ + udelay(1); + + dma_unmap_single(dma_addr, SPI_NAND_CACHE_SIZE, DMA_FROM_DEVICE); + + err = airoha_snand_set_mode(priv, SPI_MODE_MANUAL); + if (err < 0) return err; - switch (priv->nfi_cfg.page_size) { - case 2048: - val = FIELD_PREP(SPI_NFI_PAGE_SIZE, 0x1); + memcpy(buf, txrx_buf + offs, len); + + return len; + +error_dma_unmap: + dma_unmap_single(dma_addr, SPI_NAND_CACHE_SIZE, DMA_FROM_DEVICE); +error_dma_mode_off: + airoha_snand_set_mode(priv, SPI_MODE_MANUAL); + return err; +} + +static ssize_t airoha_snand_dirmap_write(struct spi_mem_dirmap_desc *desc, + u64 offs, size_t len, const void *buf) +{ + struct spi_slave *slave = desc->slave; + struct udevice *bus = slave->dev->parent; + struct airoha_snand_priv *priv = dev_get_priv(bus); + u8 *txrx_buf = priv->txrx_buf; + dma_addr_t dma_addr; + u32 wr_mode, val, opcode; + size_t bytes; + int err; + + if (!priv->dma) { + /* simplified version of spi_mem_no_dirmap_write() */ + struct spi_mem_op op = desc->info.op_tmpl; + + op.addr.val = desc->info.offset + offs; + op.data.buf.out = buf; + op.data.nbytes = len; + err = spi_mem_exec_op(desc->slave, &op); + if (err) + return err; + + return op.data.nbytes; + } + + /* minimum oob size is 64 */ + bytes = round_up(offs + len, 64); + + opcode = desc->info.op_tmpl.cmd.opcode; + switch (opcode) { + case SPI_NAND_OP_PROGRAM_LOAD_SINGLE: + case SPI_NAND_OP_PROGRAM_LOAD_RAMDOM_SINGLE: + wr_mode = 0; break; - case 4096: - val = FIELD_PREP(SPI_NFI_PAGE_SIZE, 0x2); + case SPI_NAND_OP_PROGRAM_LOAD_QUAD: + case SPI_NAND_OP_PROGRAM_LOAD_RAMDON_QUAD: + wr_mode = 2; break; default: - val = FIELD_PREP(SPI_NFI_PAGE_SIZE, 0x0); - break; + /* unknown opcode */ + return -EOPNOTSUPP; } - err = regmap_update_bits(priv->regmap_nfi, REG_SPI_NFI_PAGEFMT, - SPI_NFI_PAGE_SIZE, val); - if (err) + if (offs > 0) + memset(txrx_buf, 0xff, offs); + memcpy(txrx_buf + offs, buf, len); + if (bytes > offs + len) + memset(txrx_buf + offs + len, 0xff, bytes - offs - len); + + err = airoha_snand_set_mode(priv, SPI_MODE_DMA); + if (err < 0) return err; - /* sec num */ - val = FIELD_PREP(SPI_NFI_SEC_NUM, priv->nfi_cfg.sec_num); + /* NFI reset */ + err = regmap_write(priv->regmap_nfi, REG_SPI_NFI_CON, + SPI_NFI_FIFO_FLUSH | SPI_NFI_RST); + if (err) + goto error_dma_mode_off; + + /* + * NFI configure: + * - No AutoFDM (custom sector size (SECCUS) register will be used) + * - No SoC's hardware ECC (flash internal ECC will be used) + * - Use burst mode (faster, but requires 16 byte alignment for addresses) + * - Setup for writing (SPI_NFI_READ_MODE bit is cleared) + * - Setup writing command: FIELD_PREP(SPI_NFI_OPMODE, 3) + * - Use DMA instead of PIO for data writing + */ + err = regmap_update_bits(priv->regmap_nfi, REG_SPI_NFI_CNFG, + SPI_NFI_DMA_MODE | + SPI_NFI_READ_MODE | + SPI_NFI_DMA_BURST_EN | + SPI_NFI_HW_ECC_EN | + SPI_NFI_AUTO_FDM_EN | + SPI_NFI_OPMODE, + SPI_NFI_DMA_MODE | + SPI_NFI_DMA_BURST_EN | + FIELD_PREP(SPI_NFI_OPMODE, 3)); + if (err) + goto error_dma_mode_off; + + /* Set number of sector will be written */ err = regmap_update_bits(priv->regmap_nfi, REG_SPI_NFI_CON, - SPI_NFI_SEC_NUM, val); + SPI_NFI_SEC_NUM, + FIELD_PREP(SPI_NFI_SEC_NUM, 1)); if (err) - return err; + goto error_dma_mode_off; - /* enable cust sec size */ - err = regmap_set_bits(priv->regmap_nfi, REG_SPI_NFI_SECCUS_SIZE, - SPI_NFI_CUS_SEC_SIZE_EN); + /* Set custom sector size */ + err = regmap_update_bits(priv->regmap_nfi, REG_SPI_NFI_SECCUS_SIZE, + SPI_NFI_CUS_SEC_SIZE | + SPI_NFI_CUS_SEC_SIZE_EN, + FIELD_PREP(SPI_NFI_CUS_SEC_SIZE, bytes) | + SPI_NFI_CUS_SEC_SIZE_EN); if (err) - return err; + goto error_dma_mode_off; - /* set cust sec size */ - val = FIELD_PREP(SPI_NFI_CUS_SEC_SIZE, priv->nfi_cfg.sec_size); - return regmap_update_bits(priv->regmap_nfi, - REG_SPI_NFI_SECCUS_SIZE, - SPI_NFI_CUS_SEC_SIZE, val); -} + dma_addr = dma_map_single(txrx_buf, SPI_NAND_CACHE_SIZE, + DMA_TO_DEVICE); -static int airoha_snand_adjust_op_size(struct spi_slave *slave, - struct spi_mem_op *op) -{ - size_t max_len; + /* set dma addr */ + err = regmap_write(priv->regmap_nfi, REG_SPI_NFI_STRADDR, + dma_addr); + if (err) + goto error_dma_unmap; - max_len = 1 + op->addr.nbytes + op->dummy.nbytes; - if (max_len >= 160) - return -EOPNOTSUPP; + /* + * Setup transfer length + * --------------------- + * The following rule MUST be met: + * transfer_length = + * = NFI_SNF_MISC_CTL2.write_data_byte_number = + * = NFI_CON.sector_number * NFI_SECCUS.custom_sector_size + */ + err = regmap_update_bits(priv->regmap_nfi, + REG_SPI_NFI_SNF_MISC_CTL2, + SPI_NFI_PROG_LOAD_BYTE_NUM, + FIELD_PREP(SPI_NFI_PROG_LOAD_BYTE_NUM, bytes)); + if (err) + goto error_dma_unmap; - if (op->data.nbytes > 160 - max_len) - op->data.nbytes = 160 - max_len; + /* set write command */ + err = regmap_write(priv->regmap_nfi, REG_SPI_NFI_PG_CTL1, + FIELD_PREP(SPI_NFI_PG_LOAD_CMD, opcode)); + if (err) + goto error_dma_unmap; - return 0; -} + /* set write mode */ + err = regmap_write(priv->regmap_nfi, REG_SPI_NFI_SNF_MISC_CTL, + FIELD_PREP(SPI_NFI_DATA_READ_WR_MODE, wr_mode)); + if (err) + goto error_dma_unmap; -static bool airoha_snand_supports_op(struct spi_slave *slave, - const struct spi_mem_op *op) -{ - if (!spi_mem_default_supports_op(slave, op)) - return false; + /* set write addr: zero page offset + descriptor write offset */ + err = regmap_write(priv->regmap_nfi, REG_SPI_NFI_PG_CTL2, + desc->info.offset); + if (err) + goto error_dma_unmap; - if (op->cmd.buswidth != 1) - return false; + err = regmap_write(priv->regmap_nfi, REG_SPI_NFI_CMD, 0x80); + if (err) + goto error_dma_unmap; - return (!op->addr.nbytes || op->addr.buswidth == 1) && - (!op->dummy.nbytes || op->dummy.buswidth == 1) && - (!op->data.nbytes || op->data.buswidth == 1); + /* trigger dma writing */ + err = regmap_clear_bits(priv->regmap_nfi, REG_SPI_NFI_CON, + SPI_NFI_WR_TRIG); + if (err) + goto error_dma_unmap; + + err = regmap_set_bits(priv->regmap_nfi, REG_SPI_NFI_CON, + SPI_NFI_WR_TRIG); + if (err) + goto error_dma_unmap; + + err = regmap_read_poll_timeout(priv->regmap_nfi, REG_SPI_NFI_INTR, + val, (val & SPI_NFI_AHB_DONE), 0, + 1 * MSEC_PER_SEC); + if (err) + goto error_dma_unmap; + + err = regmap_read_poll_timeout(priv->regmap_nfi, + REG_SPI_NFI_SNF_STA_CTL1, val, + (val & SPI_NFI_LOAD_TO_CACHE_DONE), + 0, 1 * MSEC_PER_SEC); + if (err) + goto error_dma_unmap; + + /* + * SPI_NFI_LOAD_TO_CACHE_DONE bit must be written at the end + * of dirmap_write operation even if it is already set. + */ + err = regmap_update_bits(priv->regmap_nfi, REG_SPI_NFI_SNF_STA_CTL1, + SPI_NFI_LOAD_TO_CACHE_DONE, + SPI_NFI_LOAD_TO_CACHE_DONE); + if (err) + goto error_dma_unmap; + + dma_unmap_single(dma_addr, SPI_NAND_CACHE_SIZE, DMA_TO_DEVICE); + + err = airoha_snand_set_mode(priv, SPI_MODE_MANUAL); + if (err < 0) + return err; + + return len; + +error_dma_unmap: + dma_unmap_single(dma_addr, SPI_NAND_CACHE_SIZE, DMA_TO_DEVICE); +error_dma_mode_off: + airoha_snand_set_mode(priv, SPI_MODE_MANUAL); + return err; } static int airoha_snand_exec_op(struct spi_slave *slave, const struct spi_mem_op *op) { - u8 data[8], cmd, opcode = op->cmd.opcode; struct udevice *bus = slave->dev->parent; struct airoha_snand_priv *priv; + int op_len, addr_len, dummy_len; + u8 buf[20], *data; int i, err; priv = dev_get_priv(bus); + op_len = op->cmd.nbytes; + addr_len = op->addr.nbytes; + dummy_len = op->dummy.nbytes; + + if (op_len + dummy_len + addr_len > sizeof(buf)) + return -EIO; + + data = buf; + for (i = 0; i < op_len; i++) + *data++ = op->cmd.opcode >> (8 * (op_len - i - 1)); + for (i = 0; i < addr_len; i++) + *data++ = op->addr.val >> (8 * (addr_len - i - 1)); + for (i = 0; i < dummy_len; i++) + *data++ = 0xff; + /* switch to manual mode */ err = airoha_snand_set_mode(priv, SPI_MODE_MANUAL); if (err < 0) @@ -574,40 +982,40 @@ static int airoha_snand_exec_op(struct spi_slave *slave, return err; /* opcode */ - err = airoha_snand_write_data(priv, 0x8, &opcode, sizeof(opcode)); + data = buf; + err = airoha_snand_write_data(priv, data, op_len, + op->cmd.buswidth); if (err) return err; /* addr part */ - cmd = opcode == SPI_NAND_OP_GET_FEATURE ? 0x11 : 0x8; - put_unaligned_be64(op->addr.val, data); - - for (i = ARRAY_SIZE(data) - op->addr.nbytes; - i < ARRAY_SIZE(data); i++) { - err = airoha_snand_write_data(priv, cmd, &data[i], - sizeof(data[0])); + data += op_len; + if (addr_len) { + err = airoha_snand_write_data(priv, data, addr_len, + op->addr.buswidth); if (err) return err; } /* dummy */ - data[0] = 0xff; - for (i = 0; i < op->dummy.nbytes; i++) { - err = airoha_snand_write_data(priv, 0x8, &data[0], - sizeof(data[0])); + data += addr_len; + if (dummy_len) { + err = airoha_snand_write_data(priv, data, dummy_len, + op->dummy.buswidth); if (err) return err; } /* data */ - if (op->data.dir == SPI_MEM_DATA_IN) { - err = airoha_snand_read_data(priv, op->data.buf.in, - op->data.nbytes); - if (err) - return err; - } else { - err = airoha_snand_write_data(priv, 0x8, op->data.buf.out, - op->data.nbytes); + if (op->data.nbytes) { + if (op->data.dir == SPI_MEM_DATA_IN) + err = airoha_snand_read_data(priv, op->data.buf.in, + op->data.nbytes, + op->data.buswidth); + else + err = airoha_snand_write_data(priv, op->data.buf.out, + op->data.nbytes, + op->data.buswidth); if (err) return err; } @@ -619,6 +1027,13 @@ static int airoha_snand_probe(struct udevice *dev) { struct airoha_snand_priv *priv = dev_get_priv(dev); int ret; + u32 sfc_strap; + + priv->txrx_buf = memalign(ARCH_DMA_MINALIGN, SPI_NAND_CACHE_SIZE); + if (!priv->txrx_buf) { + dev_err(dev, "failed to alloacate memory for dirmap\n"); + return -ENOMEM; + } ret = regmap_init_mem_index(dev_ofnode(dev), &priv->regmap_ctrl, 0); if (ret) { @@ -639,6 +1054,25 @@ static int airoha_snand_probe(struct udevice *dev) } clk_enable(priv->spi_clk); + priv->dma = 1; + if (device_is_compatible(dev, "airoha,en7523-snand")){ + ret = regmap_read(priv->regmap_ctrl, REG_SPI_CTRL_SFC_STRAP, &sfc_strap); + if (ret) + return ret; + + if (!(sfc_strap & 0x04)) { + priv->dma = 0; + printf("\n" + "=== WARNING ======================================================\n" + "Detected booting in RESERVED mode (UART_TXD was short to GND).\n" + "This mode is known for incorrect DMA reading of some flashes.\n" + "Usage of DMA for flash operations will be disabled to prevent data\n" + "damage. Unplug your serial console and power cycle the board\n" + "to boot with full performance.\n" + "==================================================================\n\n"); + } + } + return airoha_snand_nfi_init(priv); } @@ -659,48 +1093,18 @@ static int airoha_snand_nfi_set_mode(struct udevice *bus, uint mode) return 0; } -static int airoha_snand_nfi_setup(struct spi_slave *slave, - const struct spinand_info *spinand_info) -{ - struct udevice *bus = slave->dev->parent; - struct airoha_snand_priv *priv; - u32 sec_size, sec_num; - int pagesize, oobsize; - - priv = dev_get_priv(bus); - - pagesize = spinand_info->memorg.pagesize; - oobsize = spinand_info->memorg.oobsize; - - if (pagesize == 2 * 1024) - sec_num = 4; - else if (pagesize == 4 * 1024) - sec_num = 8; - else - sec_num = 1; - - sec_size = (pagesize + oobsize) / sec_num; - - /* init default value */ - priv->nfi_cfg.sec_size = sec_size; - priv->nfi_cfg.sec_num = sec_num; - priv->nfi_cfg.page_size = round_down(sec_size * sec_num, 1024); - priv->nfi_cfg.spare_size = 16; - - return airoha_snand_nfi_config(priv); -} - static const struct spi_controller_mem_ops airoha_snand_mem_ops = { - .adjust_op_size = airoha_snand_adjust_op_size, .supports_op = airoha_snand_supports_op, .exec_op = airoha_snand_exec_op, + .dirmap_create = airoha_snand_dirmap_create, + .dirmap_read = airoha_snand_dirmap_read, + .dirmap_write = airoha_snand_dirmap_write, }; static const struct dm_spi_ops airoha_snfi_spi_ops = { .mem_ops = &airoha_snand_mem_ops, .set_speed = airoha_snand_nfi_set_speed, .set_mode = airoha_snand_nfi_set_mode, - .setup_for_spinand = airoha_snand_nfi_setup, }; static const struct udevice_id airoha_snand_ids[] = { diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c index db44a7b26eb..3fd2353af94 100644 --- a/drivers/spi/spi-mem.c +++ b/drivers/spi/spi-mem.c @@ -499,6 +499,31 @@ int spi_mem_adjust_op_size(struct spi_slave *slave, struct spi_mem_op *op) } EXPORT_SYMBOL_GPL(spi_mem_adjust_op_size); +static inline u64 spi_mem_bytes_to_ncycles(u32 nbytes, u8 buswidth, u8 dtr) +{ + u64 ncycles; + u32 divider = buswidth * (dtr ? 2 : 1); + + /* + * Theoretically + * + * ncycles = (nbytes * 8) / (buswidth * (dtr ? 2 : 1)); + * + * may lead to an integer overflow, if nbytes will be larger than + * 0x1fffffff. Lets split this operation on: + * + * 1) Operation with bits 0..28 (overflow will not happen), + * + * 2) Operation with bits 29..31. Here we'll take into account + * that buswidth is a small power of 2 (so whole divider is + * small power of 2). Hense we may divide first, then multiply. + */ + ncycles = ((nbytes & 0x1fffffff) * 8) / divider; + ncycles += ((u64) ((nbytes & ~0x1fffffff) / divider)) * 8; + + return ncycles; +} + /** * spi_mem_calc_op_duration() - Derives the theoretical length (in cpu cycles) * of an operation. This helps finding the best @@ -518,14 +543,22 @@ u64 spi_mem_calc_op_duration(struct spi_mem_op *op) { u64 ncycles = 0; - ncycles += ((op->cmd.nbytes * 8) / op->cmd.buswidth) / (op->cmd.dtr ? 2 : 1); - ncycles += ((op->addr.nbytes * 8) / op->addr.buswidth) / (op->addr.dtr ? 2 : 1); + ncycles += spi_mem_bytes_to_ncycles(op->cmd.nbytes, + op->cmd.buswidth, + op->cmd.dtr); + ncycles += spi_mem_bytes_to_ncycles(op->addr.nbytes, + op->addr.buswidth, + op->addr.dtr); /* Dummy bytes are optional for some SPI flash memory operations */ if (op->dummy.nbytes) - ncycles += ((op->dummy.nbytes * 8) / op->dummy.buswidth) / (op->dummy.dtr ? 2 : 1); + ncycles += spi_mem_bytes_to_ncycles(op->dummy.nbytes, + op->dummy.buswidth, + op->dummy.dtr); - ncycles += ((op->data.nbytes * 8) / op->data.buswidth) / (op->data.dtr ? 2 : 1); + ncycles += spi_mem_bytes_to_ncycles(op->data.nbytes, + op->data.buswidth, + op->data.dtr); return ncycles; } diff --git a/drivers/ufs/Kconfig b/drivers/ufs/Kconfig index 68693b7d226..445270e8da1 100644 --- a/drivers/ufs/Kconfig +++ b/drivers/ufs/Kconfig @@ -15,20 +15,6 @@ config CADENCE_UFS This selects the platform driver for the Cadence UFS host controller present on present TI's J721e devices. -config UFS_MEDIATEK - tristate "MediaTek UFS Host Controller Driver" - depends on UFS && ARCH_MEDIATEK - select PHY_MTK_UFS - help - This selects the MediaTek specific additions to UFSHCD platform driver. - UFS host on Mediatek needs some vendor specific configuration before - accessing the hardware which includes PHY configuration and vendor - specific registers. - - Select this if you have UFS controller on MediaTek chipset. - - If unsure, say N. - config QCOM_UFS bool "Qualcomm Host Controller driver for UFS" depends on UFS && ARCH_SNAPDRAGON @@ -59,6 +45,20 @@ config UFS_AMD_VERSAL2 UFS host on AMD needs some vendor specific configuration before accessing the hardware. +config UFS_MEDIATEK + tristate "MediaTek UFS Host Controller Driver" + depends on UFS && ARCH_MEDIATEK + select PHY_MTK_UFS + help + This selects the MediaTek specific additions to UFSHCD platform driver. + UFS host on Mediatek needs some vendor specific configuration before + accessing the hardware which includes PHY configuration and vendor + specific registers. + + Select this if you have UFS controller on MediaTek chipset. + + If unsure, say N. + config UFS_PCI bool "PCI bus based UFS Controller support" depends on PCI && UFS diff --git a/drivers/ufs/Makefile b/drivers/ufs/Makefile index 15329b9795a..6b2f2ccc9fc 100644 --- a/drivers/ufs/Makefile +++ b/drivers/ufs/Makefile @@ -5,11 +5,11 @@ obj-$(CONFIG_UFS) += ufs-uclass.o obj-$(CONFIG_CADENCE_UFS) += cdns-platform.o -obj-$(CONFIG_UFS_MEDIATEK) += ufs-mediatek.o obj-$(CONFIG_QCOM_UFS) += ufs-qcom.o +obj-$(CONFIG_ROCKCHIP_UFS) += ufs-rockchip.o obj-$(CONFIG_TI_J721E_UFS) += ti-j721e-ufs.o obj-$(CONFIG_UFS_AMD_VERSAL2) += ufs-amd-versal2.o ufshcd-dwc.o +obj-$(CONFIG_UFS_MEDIATEK) += ufs-mediatek.o obj-$(CONFIG_UFS_PCI) += ufs-pci.o obj-$(CONFIG_UFS_RENESAS) += ufs-renesas.o obj-$(CONFIG_UFS_RENESAS_GEN5) += ufs-renesas-rcar-gen5.o -obj-$(CONFIG_ROCKCHIP_UFS) += ufs-rockchip.o diff --git a/drivers/ufs/ufs-renesas-rcar-gen5.c b/drivers/ufs/ufs-renesas-rcar-gen5.c index 3c66022579f..cc53e91449c 100644 --- a/drivers/ufs/ufs-renesas-rcar-gen5.c +++ b/drivers/ufs/ufs-renesas-rcar-gen5.c @@ -258,7 +258,7 @@ static const struct udevice_id ufs_renesas_pltfm_ids[] = { { /* sentinel */ } }; -U_BOOT_DRIVER(ufs_renesas) = { +U_BOOT_DRIVER(ufs_renesas_gen5) = { .name = "ufs-renesas-gen5", .id = UCLASS_UFS, .of_match = ufs_renesas_pltfm_ids, diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig index daf2240ffd9..93c5ee69b25 100644 --- a/drivers/usb/Kconfig +++ b/drivers/usb/Kconfig @@ -78,8 +78,6 @@ source "drivers/usb/dwc3/Kconfig" source "drivers/usb/mtu3/Kconfig" -source "drivers/usb/musb/Kconfig" - source "drivers/usb/musb-new/Kconfig" source "drivers/usb/emul/Kconfig" diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 008f8c99a58..7e08aeab904 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -39,6 +39,7 @@ menuconfig USB_GADGET config SPL_USB_GADGET bool "USB Gadget Support in SPL" + depends on SPL_FRAMEWORK help Enable USB Gadget API which allows to enable USB device functions in SPL. @@ -107,6 +108,7 @@ config USB_GADGET_AT91 config USB_GADGET_DWC2_OTG bool "DesignWare USB2.0 HS OTG controller (gadget mode)" + depends on ARM select USB_GADGET_DUALSPEED help The Designware USB2.0 high-speed gadget controller @@ -149,6 +151,7 @@ config USB_GADGET_OS_DESCRIPTORS config CI_UDC bool "ChipIdea device controller" + depends on !DM_USB_GADGET select USB_GADGET_DUALSPEED help Say Y here to enable device controller functionality of the diff --git a/drivers/usb/host/xhci-brcm.c b/drivers/usb/host/xhci-brcm.c index 2ffad148dea..595839fac3c 100644 --- a/drivers/usb/host/xhci-brcm.c +++ b/drivers/usb/host/xhci-brcm.c @@ -85,7 +85,7 @@ static const struct udevice_id xhci_brcm_ids[] = { { } }; -U_BOOT_DRIVER(usb_xhci) = { +U_BOOT_DRIVER(xhci_brcm) = { .name = "xhci_brcm", .id = UCLASS_USB, .probe = xhci_brcm_probe, diff --git a/drivers/usb/host/xhci-exynos5.c b/drivers/usb/host/xhci-exynos5.c index c509ce1620a..500696ccae7 100644 --- a/drivers/usb/host/xhci-exynos5.c +++ b/drivers/usb/host/xhci-exynos5.c @@ -246,7 +246,7 @@ static const struct udevice_id xhci_usb_ids[] = { { } }; -U_BOOT_DRIVER(usb_xhci) = { +U_BOOT_DRIVER(xhci_exynos) = { .name = "xhci_exynos", .id = UCLASS_USB, .of_match = xhci_usb_ids, diff --git a/drivers/usb/host/xhci-generic.c b/drivers/usb/host/xhci-generic.c index 355d4883176..8bb4e277423 100644 --- a/drivers/usb/host/xhci-generic.c +++ b/drivers/usb/host/xhci-generic.c @@ -61,7 +61,7 @@ static const struct udevice_id xhci_usb_ids[] = { { } }; -U_BOOT_DRIVER(usb_xhci) = { +U_BOOT_DRIVER(xhci_generic) = { .name = "xhci_generic", .id = UCLASS_USB, .of_match = xhci_usb_ids, diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c index 7e288f0575b..ffe80c0bbdc 100644 --- a/drivers/usb/host/xhci-mtk.c +++ b/drivers/usb/host/xhci-mtk.c @@ -357,7 +357,7 @@ static const struct udevice_id xhci_mtk_ids[] = { { } }; -U_BOOT_DRIVER(usb_xhci) = { +U_BOOT_DRIVER(xhci_mtk) = { .name = "xhci-mtk", .id = UCLASS_USB, .of_match = xhci_mtk_ids, diff --git a/drivers/usb/host/xhci-mvebu.c b/drivers/usb/host/xhci-mvebu.c index 1338b1021c6..12dc61aee9d 100644 --- a/drivers/usb/host/xhci-mvebu.c +++ b/drivers/usb/host/xhci-mvebu.c @@ -87,7 +87,7 @@ static const struct udevice_id xhci_usb_ids[] = { { } }; -U_BOOT_DRIVER(usb_xhci) = { +U_BOOT_DRIVER(xhci_mvebu) = { .name = "xhci_mvebu", .id = UCLASS_USB, .of_match = xhci_usb_ids, diff --git a/drivers/usb/host/xhci-rcar.c b/drivers/usb/host/xhci-rcar.c index b72807053c4..95dfa2c3f87 100644 --- a/drivers/usb/host/xhci-rcar.c +++ b/drivers/usb/host/xhci-rcar.c @@ -149,7 +149,7 @@ static const struct udevice_id xhci_rcar_ids[] = { { } }; -U_BOOT_DRIVER(usb_xhci) = { +U_BOOT_DRIVER(xhci_rcar) = { .name = "xhci_rcar", .id = UCLASS_USB, .probe = xhci_rcar_probe, diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig deleted file mode 100644 index 2508b6ed0d1..00000000000 --- a/drivers/usb/musb/Kconfig +++ /dev/null @@ -1,20 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0+ -# -# (C) Copyright 2017 -# Adam Ford, Logic PD, [email protected] - -comment "Legacy MUSB Support" - -config USB_MUSB_HCD - bool "Legacy MUSB Host Controller" - -config USB_MUSB_UDC - bool "Legacy USB Device Controller" - -config USB_OMAP3 - bool "Legacy MUSB OMAP3 / OMAP4" - depends on ARCH_OMAP2PLUS - -config USB_AM35X - bool"Legacy MUSB AM35x" - depends on ARCH_OMAP2PLUS && !USB_OMAP3 diff --git a/drivers/usb/musb/Makefile b/drivers/usb/musb/Makefile deleted file mode 100644 index 744f2cfaa29..00000000000 --- a/drivers/usb/musb/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0+ -# -# (C) Copyright 2000-2007 -# Wolfgang Denk, DENX Software Engineering, [email protected]. - -obj-$(CONFIG_USB_MUSB_HCD) += musb_hcd.o musb_core.o -obj-$(CONFIG_USB_MUSB_UDC) += musb_udc.o musb_core.o -obj-$(CONFIG_USB_OMAP3) += omap3.o -obj-$(CONFIG_USB_AM35X) += am35x.o diff --git a/drivers/usb/musb/am35x.c b/drivers/usb/musb/am35x.c deleted file mode 100644 index 2c23043d40e..00000000000 --- a/drivers/usb/musb/am35x.c +++ /dev/null @@ -1,138 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * am35x.c - TI's AM35x platform specific usb wrapper functions. - * - * Author: Ajay Kumar Gupta <[email protected]> - * - * Based on drivers/usb/musb/da8xx.c - * - * Copyright (c) 2010 Texas Instruments Incorporated - */ - -#include <linux/delay.h> - -#include "am35x.h" - -/* MUSB platform configuration */ -struct musb_config musb_cfg = { - .regs = (struct musb_regs *)AM35X_USB_OTG_CORE_BASE, - .timeout = AM35X_USB_OTG_TIMEOUT, - .musb_speed = 0, -}; - -/* - * Enable the USB phy - */ -static u8 phy_on(void) -{ - u32 devconf2; - u32 timeout; - - devconf2 = readl(&am35x_scm_general_regs->devconf2); - - devconf2 &= ~(DEVCONF2_RESET | DEVCONF2_PHYPWRDN | DEVCONF2_OTGPWRDN | - DEVCONF2_OTGMODE | DEVCONF2_REFFREQ | - DEVCONF2_PHY_GPIOMODE); - devconf2 |= DEVCONF2_SESENDEN | DEVCONF2_VBDTCTEN | DEVCONF2_PHY_PLLON | - DEVCONF2_REFFREQ_13MHZ | DEVCONF2_DATPOL; - - writel(devconf2, &am35x_scm_general_regs->devconf2); - - /* wait until the USB phy is turned on */ - timeout = musb_cfg.timeout; - while (timeout--) - if (readl(&am35x_scm_general_regs->devconf2) & DEVCONF2_PHYCKGD) - return 1; - - /* USB phy was not turned on */ - return 0; -} - -/* - * Disable the USB phy - */ -static void phy_off(void) -{ - u32 devconf2; - - /* - * Power down the on-chip PHY. - */ - devconf2 = readl(&am35x_scm_general_regs->devconf2); - - devconf2 &= ~DEVCONF2_PHY_PLLON; - devconf2 |= DEVCONF2_PHYPWRDN | DEVCONF2_OTGPWRDN; - writel(devconf2, &am35x_scm_general_regs->devconf2); -} - -/* - * This function performs platform specific initialization for usb0. - */ -int musb_platform_init(void) -{ - u32 revision; - u32 sw_reset; - - /* global usb reset */ - sw_reset = readl(&am35x_scm_general_regs->ip_sw_reset); - sw_reset |= (1 << 0); - writel(sw_reset, &am35x_scm_general_regs->ip_sw_reset); - sw_reset &= ~(1 << 0); - writel(sw_reset, &am35x_scm_general_regs->ip_sw_reset); - - /* reset the controller */ - writel(0x1, &am35x_usb_regs->control); - udelay(5000); - - /* start the on-chip usb phy and its pll */ - if (phy_on() == 0) - return -1; - - /* Returns zero if e.g. not clocked */ - revision = readl(&am35x_usb_regs->revision); - if (revision == 0) - return -1; - - return 0; -} - -/* - * This function performs platform specific deinitialization for usb0. - */ -void musb_platform_deinit(void) -{ - /* Turn off the phy */ - phy_off(); -} - -/* - * This function reads data from endpoint fifo for AM35x - * which supports only 32bit read operation. - * - * ep - endpoint number - * length - number of bytes to read from FIFO - * fifo_data - pointer to data buffer into which data is read - */ -__attribute__((weak)) -void read_fifo(u8 ep, u32 length, void *fifo_data) -{ - u8 *data = (u8 *)fifo_data; - u32 val; - int i; - - /* select the endpoint index */ - writeb(ep, &musbr->index); - - if (length > 4) { - for (i = 0; i < (length >> 2); i++) { - val = readl(&musbr->fifox[ep]); - memcpy(data, &val, 4); - data += 4; - } - length %= 4; - } - if (length > 0) { - val = readl(&musbr->fifox[ep]); - memcpy(data, &val, length); - } -} diff --git a/drivers/usb/musb/am35x.h b/drivers/usb/musb/am35x.h deleted file mode 100644 index 82ad94329cb..00000000000 --- a/drivers/usb/musb/am35x.h +++ /dev/null @@ -1,81 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * am35x.h - TI's AM35x platform specific usb wrapper definitions. - * - * Author: Ajay Kumar Gupta <[email protected]> - * - * Based on drivers/usb/musb/da8xx.h - * - * Copyright (c) 2010 Texas Instruments Incorporated - */ - -#ifndef __AM35X_USB_H__ -#define __AM35X_USB_H__ - -#include <asm/arch/am35x_def.h> -#include "musb_core.h" - -/* Base address of musb wrapper */ -#define AM35X_USB_OTG_BASE 0x5C040000 - -/* Base address of musb core */ -#define AM35X_USB_OTG_CORE_BASE (AM35X_USB_OTG_BASE + 0x400) - -/* Timeout for AM35x usb module */ -#define AM35X_USB_OTG_TIMEOUT 0x3FFFFFF - -/* - * AM35x platform USB wrapper register overlay. - */ -struct am35x_usb_regs { - u32 revision; - u32 control; - u32 status; - u32 emulation; - u32 reserved0[1]; - u32 autoreq; - u32 srpfixtime; - u32 ep_intsrc; - u32 ep_intsrcset; - u32 ep_intsrcclr; - u32 ep_intmsk; - u32 ep_intmskset; - u32 ep_intmskclr; - u32 ep_intsrcmsked; - u32 reserved1[1]; - u32 core_intsrc; - u32 core_intsrcset; - u32 core_intsrcclr; - u32 core_intmsk; - u32 core_intmskset; - u32 core_intmskclr; - u32 core_intsrcmsked; - u32 reserved2[1]; - u32 eoi; - u32 mop_sop_en; - u32 reserved3[2]; - u32 txmode; - u32 rxmode; - u32 epcount_mode; -}; - -#define am35x_usb_regs ((struct am35x_usb_regs *)AM35X_USB_OTG_BASE) - -/* USB 2.0 PHY Control */ -#define DEVCONF2_PHY_GPIOMODE (1 << 23) -#define DEVCONF2_OTGMODE (3 << 14) -#define DEVCONF2_SESENDEN (1 << 13) /* Vsess_end comparator */ -#define DEVCONF2_VBDTCTEN (1 << 12) /* Vbus comparator */ -#define DEVCONF2_REFFREQ_24MHZ (2 << 8) -#define DEVCONF2_REFFREQ_26MHZ (7 << 8) -#define DEVCONF2_REFFREQ_13MHZ (6 << 8) -#define DEVCONF2_REFFREQ (0xf << 8) -#define DEVCONF2_PHYCKGD (1 << 7) -#define DEVCONF2_VBUSSENSE (1 << 6) -#define DEVCONF2_PHY_PLLON (1 << 5) /* override PLL suspend */ -#define DEVCONF2_RESET (1 << 4) -#define DEVCONF2_PHYPWRDN (1 << 3) -#define DEVCONF2_OTGPWRDN (1 << 2) -#define DEVCONF2_DATPOL (1 << 1) - -#endif /* __AM35X_USB_H__ */ diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c deleted file mode 100644 index 260552e4dbd..00000000000 --- a/drivers/usb/musb/musb_core.c +++ /dev/null @@ -1,150 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Mentor USB OTG Core functionality common for both Host and Device - * functionality. - * - * Copyright (c) 2008 Texas Instruments - * - * Author: Thomas Abraham [email protected], Texas Instruments - */ - -#include <linux/bitops.h> - -#include "musb_core.h" -struct musb_regs *musbr; - -/* - * program the mentor core to start (enable interrupts, dma, etc.) - */ -void musb_start(void) -{ -#if defined(CONFIG_USB_MUSB_HCD) - u8 devctl; - u8 busctl; -#endif - - /* disable all interrupts */ - writew(0, &musbr->intrtxe); - writew(0, &musbr->intrrxe); - writeb(0, &musbr->intrusbe); - writeb(0, &musbr->testmode); - - /* put into basic highspeed mode and start session */ - writeb(MUSB_POWER_HSENAB, &musbr->power); -#if defined(CONFIG_USB_MUSB_HCD) - /* Program PHY to use EXT VBUS if required */ - if (musb_cfg.extvbus == 1) { - busctl = musb_read_ulpi_buscontrol(musbr); - musb_write_ulpi_buscontrol(musbr, busctl | ULPI_USE_EXTVBUS); - } - - devctl = readb(&musbr->devctl); - writeb(devctl | MUSB_DEVCTL_SESSION, &musbr->devctl); -#endif -} - -#ifdef MUSB_NO_DYNAMIC_FIFO -# define config_fifo(dir, idx, addr) -#else -# define config_fifo(dir, idx, addr) \ - do { \ - writeb(idx, &musbr->dir##fifosz); \ - writew(addr, &musbr->dir##fifoadd); \ - } while (0) -#endif - -/* - * This function configures the endpoint configuration. The musb hcd or musb - * device implementation can use this function to configure the endpoints - * and set the FIFO sizes. Note: The summation of FIFO sizes of all endpoints - * should not be more than the available FIFO size. - * - * epinfo - Pointer to EP configuration table - * cnt - Number of entries in the EP conf table. - */ -void musb_configure_ep(const struct musb_epinfo *epinfo, u8 cnt) -{ - u16 csr; - u16 fifoaddr = 64 >> 3; /* First 64 bytes of FIFO reserved for EP0 */ - u32 fifosize; - u8 idx; - - while (cnt--) { - /* prepare fifosize to write to register */ - fifosize = epinfo->epsize >> 3; - idx = fifosize ? ((ffs(fifosize) - 1) & 0xF) : 0; - - writeb(epinfo->epnum, &musbr->index); - if (epinfo->epdir) { - /* Configure fifo size and fifo base address */ - config_fifo(tx, idx, fifoaddr); - - csr = readw(&musbr->txcsr); - /* clear the data toggle bit */ - writew(csr | MUSB_TXCSR_CLRDATATOG, &musbr->txcsr); - /* Flush fifo if required */ - if (csr & MUSB_TXCSR_TXPKTRDY) - writew(csr | MUSB_TXCSR_FLUSHFIFO, - &musbr->txcsr); - } else { - /* Configure fifo size and fifo base address */ - config_fifo(rx, idx, fifoaddr); - - csr = readw(&musbr->rxcsr); - /* clear the data toggle bit */ - writew(csr | MUSB_RXCSR_CLRDATATOG, &musbr->rxcsr); - /* Flush fifo if required */ - if (csr & MUSB_RXCSR_RXPKTRDY) - writew(csr | MUSB_RXCSR_FLUSHFIFO, - &musbr->rxcsr); - } - fifoaddr += 1 << idx; - epinfo++; - } -} - -/* - * This function writes data to endpoint fifo - * - * ep - endpoint number - * length - number of bytes to write to FIFO - * fifo_data - Pointer to data buffer that contains the data to write - */ -__attribute__((weak)) -void write_fifo(u8 ep, u32 length, void *fifo_data) -{ - u8 *data = (u8 *)fifo_data; - - /* select the endpoint index */ - writeb(ep, &musbr->index); - - /* write the data to the fifo */ - while (length--) - writeb(*data++, &musbr->fifox[ep]); -} - -/* - * AM35x supports only 32bit read operations so - * use seperate read_fifo() function for it. - */ -#ifndef CONFIG_USB_AM35X -/* - * This function reads data from endpoint fifo - * - * ep - endpoint number - * length - number of bytes to read from FIFO - * fifo_data - pointer to data buffer into which data is read - */ -__attribute__((weak)) -void read_fifo(u8 ep, u32 length, void *fifo_data) -{ - u8 *data = (u8 *)fifo_data; - - /* select the endpoint index */ - writeb(ep, &musbr->index); - - /* read the data to the fifo */ - while (length--) - *data++ = readb(&musbr->fifox[ep]); -} -#endif /* CONFIG_USB_AM35X */ diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h deleted file mode 100644 index 47b839c0835..00000000000 --- a/drivers/usb/musb/musb_core.h +++ /dev/null @@ -1,343 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************** - * Copyright 2008 Mentor Graphics Corporation - * Copyright (C) 2008 by Texas Instruments - * - * This file is part of the Inventra Controller Driver for Linux. - ******************************************************************/ - -#ifndef __MUSB_HDRC_DEFS_H__ -#define __MUSB_HDRC_DEFS_H__ - -#include <usb_defs.h> -#include <asm/io.h> - -#define MUSB_EP0_FIFOSIZE 64 /* This is non-configurable */ - -/* EP0 */ -struct musb_ep0_regs { - u16 reserved4; - u16 csr0; - u16 reserved5; - u16 reserved6; - u16 count0; - u8 host_type0; - u8 host_naklimit0; - u8 reserved7; - u8 reserved8; - u8 reserved9; - u8 configdata; -}; - -/* EP 1-15 */ -struct musb_epN_regs { - u16 txmaxp; - u16 txcsr; - u16 rxmaxp; - u16 rxcsr; - u16 rxcount; - u8 txtype; - u8 txinterval; - u8 rxtype; - u8 rxinterval; - u8 reserved0; - u8 fifosize; -}; - -/* Mentor USB core register overlay structure */ -#ifndef musb_regs -struct musb_regs { - /* common registers */ - u8 faddr; - u8 power; - u16 intrtx; - u16 intrrx; - u16 intrtxe; - u16 intrrxe; - u8 intrusb; - u8 intrusbe; - u16 frame; - u8 index; - u8 testmode; - /* indexed registers */ - u16 txmaxp; - u16 txcsr; - u16 rxmaxp; - u16 rxcsr; - u16 rxcount; - u8 txtype; - u8 txinterval; - u8 rxtype; - u8 rxinterval; - u8 reserved0; - u8 fifosize; - /* fifo */ - u32 fifox[16]; - /* OTG, dynamic FIFO, version & vendor registers */ - u8 devctl; - u8 reserved1; - u8 txfifosz; - u8 rxfifosz; - u16 txfifoadd; - u16 rxfifoadd; - u32 vcontrol; - u16 hwvers; - u16 reserved2a[1]; - u8 ulpi_busctl; - u8 reserved2b[1]; - u16 reserved2[3]; - u8 epinfo; - u8 raminfo; - u8 linkinfo; - u8 vplen; - u8 hseof1; - u8 fseof1; - u8 lseof1; - u8 reserved3; - /* target address registers */ - struct musb_tar_regs { - u8 txfuncaddr; - u8 reserved0; - u8 txhubaddr; - u8 txhubport; - u8 rxfuncaddr; - u8 reserved1; - u8 rxhubaddr; - u8 rxhubport; - } tar[16]; - /* - * endpoint registers - * ep0 elements are valid when array index is 0 - * otherwise epN is valid - */ - union musb_ep_regs { - struct musb_ep0_regs ep0; - struct musb_epN_regs epN; - } ep[16]; - -} __attribute__((packed)); -#endif - -/* - * MUSB Register bits - */ - -/* POWER */ -#define MUSB_POWER_ISOUPDATE 0x80 -#define MUSB_POWER_SOFTCONN 0x40 -#define MUSB_POWER_HSENAB 0x20 -#define MUSB_POWER_HSMODE 0x10 -#define MUSB_POWER_RESET 0x08 -#define MUSB_POWER_RESUME 0x04 -#define MUSB_POWER_SUSPENDM 0x02 -#define MUSB_POWER_ENSUSPEND 0x01 -#define MUSB_POWER_HSMODE_SHIFT 4 - -/* INTRUSB */ -#define MUSB_INTR_SUSPEND 0x01 -#define MUSB_INTR_RESUME 0x02 -#define MUSB_INTR_RESET 0x04 -#define MUSB_INTR_BABBLE 0x04 -#define MUSB_INTR_SOF 0x08 -#define MUSB_INTR_CONNECT 0x10 -#define MUSB_INTR_DISCONNECT 0x20 -#define MUSB_INTR_SESSREQ 0x40 -#define MUSB_INTR_VBUSERROR 0x80 /* For SESSION end */ - -/* DEVCTL */ -#define MUSB_DEVCTL_BDEVICE 0x80 -#define MUSB_DEVCTL_FSDEV 0x40 -#define MUSB_DEVCTL_LSDEV 0x20 -#define MUSB_DEVCTL_VBUS 0x18 -#define MUSB_DEVCTL_VBUS_SHIFT 3 -#define MUSB_DEVCTL_HM 0x04 -#define MUSB_DEVCTL_HR 0x02 -#define MUSB_DEVCTL_SESSION 0x01 - -/* ULPI VBUSCONTROL */ -#define ULPI_USE_EXTVBUS 0x01 -#define ULPI_USE_EXTVBUSIND 0x02 - -/* TESTMODE */ -#define MUSB_TEST_FORCE_HOST 0x80 -#define MUSB_TEST_FIFO_ACCESS 0x40 -#define MUSB_TEST_FORCE_FS 0x20 -#define MUSB_TEST_FORCE_HS 0x10 -#define MUSB_TEST_PACKET 0x08 -#define MUSB_TEST_K 0x04 -#define MUSB_TEST_J 0x02 -#define MUSB_TEST_SE0_NAK 0x01 - -/* Allocate for double-packet buffering (effectively doubles assigned _SIZE) */ -#define MUSB_FIFOSZ_DPB 0x10 -/* Allocation size (8, 16, 32, ... 4096) */ -#define MUSB_FIFOSZ_SIZE 0x0f - -/* CSR0 */ -#define MUSB_CSR0_FLUSHFIFO 0x0100 -#define MUSB_CSR0_TXPKTRDY 0x0002 -#define MUSB_CSR0_RXPKTRDY 0x0001 - -/* CSR0 in Peripheral mode */ -#define MUSB_CSR0_P_SVDSETUPEND 0x0080 -#define MUSB_CSR0_P_SVDRXPKTRDY 0x0040 -#define MUSB_CSR0_P_SENDSTALL 0x0020 -#define MUSB_CSR0_P_SETUPEND 0x0010 -#define MUSB_CSR0_P_DATAEND 0x0008 -#define MUSB_CSR0_P_SENTSTALL 0x0004 - -/* CSR0 in Host mode */ -#define MUSB_CSR0_H_DIS_PING 0x0800 -#define MUSB_CSR0_H_WR_DATATOGGLE 0x0400 /* Set to allow setting: */ -#define MUSB_CSR0_H_DATATOGGLE 0x0200 /* Data toggle control */ -#define MUSB_CSR0_H_NAKTIMEOUT 0x0080 -#define MUSB_CSR0_H_STATUSPKT 0x0040 -#define MUSB_CSR0_H_REQPKT 0x0020 -#define MUSB_CSR0_H_ERROR 0x0010 -#define MUSB_CSR0_H_SETUPPKT 0x0008 -#define MUSB_CSR0_H_RXSTALL 0x0004 - -/* CSR0 bits to avoid zeroing (write zero clears, write 1 ignored) */ -#define MUSB_CSR0_P_WZC_BITS \ - (MUSB_CSR0_P_SENTSTALL) -#define MUSB_CSR0_H_WZC_BITS \ - (MUSB_CSR0_H_NAKTIMEOUT | MUSB_CSR0_H_RXSTALL \ - | MUSB_CSR0_RXPKTRDY) - -/* TxType/RxType */ -#define MUSB_TYPE_SPEED 0xc0 -#define MUSB_TYPE_SPEED_SHIFT 6 -#define MUSB_TYPE_SPEED_HIGH 1 -#define MUSB_TYPE_SPEED_FULL 2 -#define MUSB_TYPE_SPEED_LOW 3 -#define MUSB_TYPE_PROTO 0x30 /* Implicitly zero for ep0 */ -#define MUSB_TYPE_PROTO_SHIFT 4 -#define MUSB_TYPE_REMOTE_END 0xf /* Implicitly zero for ep0 */ -#define MUSB_TYPE_PROTO_BULK 2 -#define MUSB_TYPE_PROTO_INTR 3 - -/* CONFIGDATA */ -#define MUSB_CONFIGDATA_MPRXE 0x80 /* Auto bulk pkt combining */ -#define MUSB_CONFIGDATA_MPTXE 0x40 /* Auto bulk pkt splitting */ -#define MUSB_CONFIGDATA_BIGENDIAN 0x20 -#define MUSB_CONFIGDATA_HBRXE 0x10 /* HB-ISO for RX */ -#define MUSB_CONFIGDATA_HBTXE 0x08 /* HB-ISO for TX */ -#define MUSB_CONFIGDATA_DYNFIFO 0x04 /* Dynamic FIFO sizing */ -#define MUSB_CONFIGDATA_SOFTCONE 0x02 /* SoftConnect */ -#define MUSB_CONFIGDATA_UTMIDW 0x01 /* Data width 0/1 => 8/16bits */ - -/* TXCSR in Peripheral and Host mode */ -#define MUSB_TXCSR_AUTOSET 0x8000 -#define MUSB_TXCSR_MODE 0x2000 -#define MUSB_TXCSR_DMAENAB 0x1000 -#define MUSB_TXCSR_FRCDATATOG 0x0800 -#define MUSB_TXCSR_DMAMODE 0x0400 -#define MUSB_TXCSR_CLRDATATOG 0x0040 -#define MUSB_TXCSR_FLUSHFIFO 0x0008 -#define MUSB_TXCSR_FIFONOTEMPTY 0x0002 -#define MUSB_TXCSR_TXPKTRDY 0x0001 - -/* TXCSR in Peripheral mode */ -#define MUSB_TXCSR_P_ISO 0x4000 -#define MUSB_TXCSR_P_INCOMPTX 0x0080 -#define MUSB_TXCSR_P_SENTSTALL 0x0020 -#define MUSB_TXCSR_P_SENDSTALL 0x0010 -#define MUSB_TXCSR_P_UNDERRUN 0x0004 - -/* TXCSR in Host mode */ -#define MUSB_TXCSR_H_WR_DATATOGGLE 0x0200 -#define MUSB_TXCSR_H_DATATOGGLE 0x0100 -#define MUSB_TXCSR_H_NAKTIMEOUT 0x0080 -#define MUSB_TXCSR_H_RXSTALL 0x0020 -#define MUSB_TXCSR_H_ERROR 0x0004 -#define MUSB_TXCSR_H_DATATOGGLE_SHIFT 8 - -/* TXCSR bits to avoid zeroing (write zero clears, write 1 ignored) */ -#define MUSB_TXCSR_P_WZC_BITS \ - (MUSB_TXCSR_P_INCOMPTX | MUSB_TXCSR_P_SENTSTALL \ - | MUSB_TXCSR_P_UNDERRUN | MUSB_TXCSR_FIFONOTEMPTY) -#define MUSB_TXCSR_H_WZC_BITS \ - (MUSB_TXCSR_H_NAKTIMEOUT | MUSB_TXCSR_H_RXSTALL \ - | MUSB_TXCSR_H_ERROR | MUSB_TXCSR_FIFONOTEMPTY) - -/* RXCSR in Peripheral and Host mode */ -#define MUSB_RXCSR_AUTOCLEAR 0x8000 -#define MUSB_RXCSR_DMAENAB 0x2000 -#define MUSB_RXCSR_DISNYET 0x1000 -#define MUSB_RXCSR_PID_ERR 0x1000 -#define MUSB_RXCSR_DMAMODE 0x0800 -#define MUSB_RXCSR_INCOMPRX 0x0100 -#define MUSB_RXCSR_CLRDATATOG 0x0080 -#define MUSB_RXCSR_FLUSHFIFO 0x0010 -#define MUSB_RXCSR_DATAERROR 0x0008 -#define MUSB_RXCSR_FIFOFULL 0x0002 -#define MUSB_RXCSR_RXPKTRDY 0x0001 - -/* RXCSR in Peripheral mode */ -#define MUSB_RXCSR_P_ISO 0x4000 -#define MUSB_RXCSR_P_SENTSTALL 0x0040 -#define MUSB_RXCSR_P_SENDSTALL 0x0020 -#define MUSB_RXCSR_P_OVERRUN 0x0004 - -/* RXCSR in Host mode */ -#define MUSB_RXCSR_H_AUTOREQ 0x4000 -#define MUSB_RXCSR_H_WR_DATATOGGLE 0x0400 -#define MUSB_RXCSR_H_DATATOGGLE 0x0200 -#define MUSB_RXCSR_H_RXSTALL 0x0040 -#define MUSB_RXCSR_H_REQPKT 0x0020 -#define MUSB_RXCSR_H_ERROR 0x0004 -#define MUSB_S_RXCSR_H_DATATOGGLE 9 - -/* RXCSR bits to avoid zeroing (write zero clears, write 1 ignored) */ -#define MUSB_RXCSR_P_WZC_BITS \ - (MUSB_RXCSR_P_SENTSTALL | MUSB_RXCSR_P_OVERRUN \ - | MUSB_RXCSR_RXPKTRDY) -#define MUSB_RXCSR_H_WZC_BITS \ - (MUSB_RXCSR_H_RXSTALL | MUSB_RXCSR_H_ERROR \ - | MUSB_RXCSR_DATAERROR | MUSB_RXCSR_RXPKTRDY) - -/* HUBADDR */ -#define MUSB_HUBADDR_MULTI_TT 0x80 - -/* Endpoint configuration information. Note: The value of endpoint fifo size - * element should be either 8,16,32,64,128,256,512,1024,2048 or 4096. Other - * values are not supported - */ -struct musb_epinfo { - u8 epnum; /* endpoint number */ - u8 epdir; /* endpoint direction */ - u16 epsize; /* endpoint FIFO size */ -}; - -/* - * Platform specific MUSB configuration. Any platform using the musb - * functionality should create one instance of this structure in the - * platform specific file. - */ -struct musb_config { - struct musb_regs *regs; - u32 timeout; - u8 musb_speed; - u8 extvbus; -}; - -/* externally defined data */ -extern struct musb_config musb_cfg; -extern struct musb_regs *musbr; - -/* exported functions */ -extern void musb_start(void); -extern void musb_configure_ep(const struct musb_epinfo *epinfo, u8 cnt); -extern void write_fifo(u8 ep, u32 length, void *fifo_data); -extern void read_fifo(u8 ep, u32 length, void *fifo_data); - -static inline u8 musb_read_ulpi_buscontrol(struct musb_regs *musbr) -{ - return readb(&musbr->ulpi_busctl); -} -static inline void musb_write_ulpi_buscontrol(struct musb_regs *musbr, u8 val) -{ - writeb(val, &musbr->ulpi_busctl); -} - -#endif /* __MUSB_HDRC_DEFS_H__ */ diff --git a/drivers/usb/musb/musb_debug.h b/drivers/usb/musb/musb_debug.h deleted file mode 100644 index 2c5e192ab21..00000000000 --- a/drivers/usb/musb/musb_debug.h +++ /dev/null @@ -1,191 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Copyright (c) 2009 Wind River Systems, Inc. - * Tom Rix <[email protected]> - */ - -/* Define MUSB_DEBUG before including this file to get debug macros */ -#ifdef MUSB_DEBUG - -#define MUSB_FLAGS_PRINT(v, x, y) \ - if (((v) & MUSB_##x##_##y)) \ - serial_printf("\t\t"#y"\n") - -static inline void musb_print_pwr(u8 b) -{ - serial_printf("\tpower 0x%2.2x\n", b); - MUSB_FLAGS_PRINT(b, POWER, ISOUPDATE); - MUSB_FLAGS_PRINT(b, POWER, SOFTCONN); - MUSB_FLAGS_PRINT(b, POWER, HSENAB); - MUSB_FLAGS_PRINT(b, POWER, HSMODE); - MUSB_FLAGS_PRINT(b, POWER, RESET); - MUSB_FLAGS_PRINT(b, POWER, RESUME); - MUSB_FLAGS_PRINT(b, POWER, SUSPENDM); - MUSB_FLAGS_PRINT(b, POWER, ENSUSPEND); -} - -static inline void musb_print_csr0(u16 w) -{ - serial_printf("\tcsr0 0x%4.4x\n", w); - MUSB_FLAGS_PRINT(w, CSR0, FLUSHFIFO); - MUSB_FLAGS_PRINT(w, CSR0_P, SVDSETUPEND); - MUSB_FLAGS_PRINT(w, CSR0_P, SVDRXPKTRDY); - MUSB_FLAGS_PRINT(w, CSR0_P, SENDSTALL); - MUSB_FLAGS_PRINT(w, CSR0_P, SETUPEND); - MUSB_FLAGS_PRINT(w, CSR0_P, DATAEND); - MUSB_FLAGS_PRINT(w, CSR0_P, SENTSTALL); - MUSB_FLAGS_PRINT(w, CSR0, TXPKTRDY); - MUSB_FLAGS_PRINT(w, CSR0, RXPKTRDY); -} - -static inline void musb_print_intrusb(u8 b) -{ - serial_printf("\tintrusb 0x%2.2x\n", b); - MUSB_FLAGS_PRINT(b, INTR, VBUSERROR); - MUSB_FLAGS_PRINT(b, INTR, SESSREQ); - MUSB_FLAGS_PRINT(b, INTR, DISCONNECT); - MUSB_FLAGS_PRINT(b, INTR, CONNECT); - MUSB_FLAGS_PRINT(b, INTR, SOF); - MUSB_FLAGS_PRINT(b, INTR, RESUME); - MUSB_FLAGS_PRINT(b, INTR, SUSPEND); - - if (b & MUSB_INTR_BABBLE) - serial_printf("\t\tMUSB_INTR_RESET or MUSB_INTR_BABBLE\n"); - -} - -static inline void musb_print_intrtx(u16 w) -{ - serial_printf("\tintrtx 0x%4.4x\n", w); -} - -static inline void musb_print_intrrx(u16 w) -{ - serial_printf("\tintrx 0x%4.4x\n", w); -} - -static inline void musb_print_devctl(u8 b) -{ - serial_printf("\tdevctl 0x%2.2x\n", b); - if (b & MUSB_DEVCTL_BDEVICE) - serial_printf("\t\tB device\n"); - else - serial_printf("\t\tA device\n"); - if (b & MUSB_DEVCTL_FSDEV) - serial_printf("\t\tFast Device -(host mode)\n"); - if (b & MUSB_DEVCTL_LSDEV) - serial_printf("\t\tSlow Device -(host mode)\n"); - if (b & MUSB_DEVCTL_HM) - serial_printf("\t\tHost mode\n"); - else - serial_printf("\t\tPeripherial mode\n"); - if (b & MUSB_DEVCTL_HR) - serial_printf("\t\tHost request started(B device)\n"); - else - serial_printf("\t\tHost request finished(B device)\n"); - if (b & MUSB_DEVCTL_BDEVICE) { - if (b & MUSB_DEVCTL_SESSION) - serial_printf("\t\tStart of session(B device)\n"); - else - serial_printf("\t\tEnd of session(B device)\n"); - } else { - if (b & MUSB_DEVCTL_SESSION) - serial_printf("\t\tStart of session(A device)\n"); - else - serial_printf("\t\tEnd of session(A device)\n"); - } -} - -static inline void musb_print_config(u8 b) -{ - serial_printf("\tconfig 0x%2.2x\n", b); - if (b & MUSB_CONFIGDATA_MPRXE) - serial_printf("\t\tAuto combine rx bulk packets\n"); - if (b & MUSB_CONFIGDATA_MPTXE) - serial_printf("\t\tAuto split tx bulk packets\n"); - if (b & MUSB_CONFIGDATA_BIGENDIAN) - serial_printf("\t\tBig Endian ordering\n"); - else - serial_printf("\t\tLittle Endian ordering\n"); - if (b & MUSB_CONFIGDATA_HBRXE) - serial_printf("\t\tHigh speed rx iso endpoint\n"); - if (b & MUSB_CONFIGDATA_HBTXE) - serial_printf("\t\tHigh speed tx iso endpoint\n"); - if (b & MUSB_CONFIGDATA_DYNFIFO) - serial_printf("\t\tDynamic fifo sizing\n"); - if (b & MUSB_CONFIGDATA_SOFTCONE) - serial_printf("\t\tSoft Connect\n"); - if (b & MUSB_CONFIGDATA_UTMIDW) - serial_printf("\t\t16 bit data width\n"); - else - serial_printf("\t\t8 bit data width\n"); -} - -static inline void musb_print_rxmaxp(u16 w) -{ - serial_printf("\trxmaxp 0x%4.4x\n", w); -} - -static inline void musb_print_rxcsr(u16 w) -{ - serial_printf("\trxcsr 0x%4.4x\n", w); - MUSB_FLAGS_PRINT(w, RXCSR, AUTOCLEAR); - MUSB_FLAGS_PRINT(w, RXCSR, DMAENAB); - MUSB_FLAGS_PRINT(w, RXCSR, DISNYET); - MUSB_FLAGS_PRINT(w, RXCSR, PID_ERR); - MUSB_FLAGS_PRINT(w, RXCSR, DMAMODE); - MUSB_FLAGS_PRINT(w, RXCSR, CLRDATATOG); - MUSB_FLAGS_PRINT(w, RXCSR, FLUSHFIFO); - MUSB_FLAGS_PRINT(w, RXCSR, DATAERROR); - MUSB_FLAGS_PRINT(w, RXCSR, FIFOFULL); - MUSB_FLAGS_PRINT(w, RXCSR, RXPKTRDY); - MUSB_FLAGS_PRINT(w, RXCSR_P, SENTSTALL); - MUSB_FLAGS_PRINT(w, RXCSR_P, SENDSTALL); - MUSB_FLAGS_PRINT(w, RXCSR_P, OVERRUN); - - if (w & MUSB_RXCSR_P_ISO) - serial_printf("\t\tiso mode\n"); - else - serial_printf("\t\tbulk mode\n"); - -} - -static inline void musb_print_txmaxp(u16 w) -{ - serial_printf("\ttxmaxp 0x%4.4x\n", w); -} - -static inline void musb_print_txcsr(u16 w) -{ - serial_printf("\ttxcsr 0x%4.4x\n", w); - MUSB_FLAGS_PRINT(w, TXCSR, TXPKTRDY); - MUSB_FLAGS_PRINT(w, TXCSR, FIFONOTEMPTY); - MUSB_FLAGS_PRINT(w, TXCSR, FLUSHFIFO); - MUSB_FLAGS_PRINT(w, TXCSR, CLRDATATOG); - MUSB_FLAGS_PRINT(w, TXCSR_P, UNDERRUN); - MUSB_FLAGS_PRINT(w, TXCSR_P, SENTSTALL); - MUSB_FLAGS_PRINT(w, TXCSR_P, SENDSTALL); - - if (w & MUSB_TXCSR_MODE) - serial_printf("\t\tTX mode\n"); - else - serial_printf("\t\tRX mode\n"); -} - -#else - -/* stubs */ - -#define musb_print_pwr(b) -#define musb_print_csr0(w) -#define musb_print_intrusb(b) -#define musb_print_intrtx(w) -#define musb_print_intrrx(w) -#define musb_print_devctl(b) -#define musb_print_config(b) -#define musb_print_rxmaxp(w) -#define musb_print_rxcsr(w) -#define musb_print_txmaxp(w) -#define musb_print_txcsr(w) - -#endif /* MUSB_DEBUG */ diff --git a/drivers/usb/musb/musb_hcd.c b/drivers/usb/musb/musb_hcd.c deleted file mode 100644 index c95c6a48281..00000000000 --- a/drivers/usb/musb/musb_hcd.c +++ /dev/null @@ -1,1161 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Mentor USB OTG Core host controller driver. - * - * Copyright (c) 2008 Texas Instruments - * - * Author: Thomas Abraham [email protected], Texas Instruments - */ - -#include <log.h> -#include <usb.h> -#include <linux/delay.h> -#include "musb_hcd.h" - -/* MSC control transfers */ -#define USB_MSC_BBB_RESET 0xFF -#define USB_MSC_BBB_GET_MAX_LUN 0xFE - -/* Endpoint configuration information */ -static const struct musb_epinfo epinfo[3] = { - {MUSB_BULK_EP, 1, 512}, /* EP1 - Bluk Out - 512 Bytes */ - {MUSB_BULK_EP, 0, 512}, /* EP1 - Bluk In - 512 Bytes */ - {MUSB_INTR_EP, 0, 64} /* EP2 - Interrupt IN - 64 Bytes */ -}; - -/* --- Virtual Root Hub ---------------------------------------------------- */ -#ifdef MUSB_NO_MULTIPOINT -static int rh_devnum; -static u32 port_status; - -#include <usbroothubdes.h> - -#endif - -/* - * This function writes the data toggle value. - */ -static void write_toggle(struct usb_device *dev, u8 ep, u8 dir_out) -{ - u16 toggle = usb_gettoggle(dev, ep, dir_out); - u16 csr; - - if (dir_out) { - csr = readw(&musbr->txcsr); - if (!toggle) { - if (csr & MUSB_TXCSR_MODE) - csr = MUSB_TXCSR_CLRDATATOG; - else - csr = 0; - writew(csr, &musbr->txcsr); - } else { - csr |= MUSB_TXCSR_H_WR_DATATOGGLE; - writew(csr, &musbr->txcsr); - csr |= (toggle << MUSB_TXCSR_H_DATATOGGLE_SHIFT); - writew(csr, &musbr->txcsr); - } - } else { - if (!toggle) { - csr = readw(&musbr->txcsr); - if (csr & MUSB_TXCSR_MODE) - csr = MUSB_RXCSR_CLRDATATOG; - else - csr = 0; - writew(csr, &musbr->rxcsr); - } else { - csr = readw(&musbr->rxcsr); - csr |= MUSB_RXCSR_H_WR_DATATOGGLE; - writew(csr, &musbr->rxcsr); - csr |= (toggle << MUSB_S_RXCSR_H_DATATOGGLE); - writew(csr, &musbr->rxcsr); - } - } -} - -/* - * This function checks if RxStall has occurred on the endpoint. If a RxStall - * has occurred, the RxStall is cleared and 1 is returned. If RxStall has - * not occurred, 0 is returned. - */ -static u8 check_stall(u8 ep, u8 dir_out) -{ - u16 csr; - - /* For endpoint 0 */ - if (!ep) { - csr = readw(&musbr->txcsr); - if (csr & MUSB_CSR0_H_RXSTALL) { - csr &= ~MUSB_CSR0_H_RXSTALL; - writew(csr, &musbr->txcsr); - return 1; - } - } else { /* For non-ep0 */ - if (dir_out) { /* is it tx ep */ - csr = readw(&musbr->txcsr); - if (csr & MUSB_TXCSR_H_RXSTALL) { - csr &= ~MUSB_TXCSR_H_RXSTALL; - writew(csr, &musbr->txcsr); - return 1; - } - } else { /* is it rx ep */ - csr = readw(&musbr->rxcsr); - if (csr & MUSB_RXCSR_H_RXSTALL) { - csr &= ~MUSB_RXCSR_H_RXSTALL; - writew(csr, &musbr->rxcsr); - return 1; - } - } - } - return 0; -} - -/* - * waits until ep0 is ready. Returns 0 if ep is ready, -1 for timeout - * error and -2 for stall. - */ -static int wait_until_ep0_ready(struct usb_device *dev, u32 bit_mask) -{ - u16 csr; - int result = 1; - int timeout = MUSB_TIMEOUT; - - while (result > 0) { - csr = readw(&musbr->txcsr); - if (csr & MUSB_CSR0_H_ERROR) { - csr &= ~MUSB_CSR0_H_ERROR; - writew(csr, &musbr->txcsr); - dev->status = USB_ST_CRC_ERR; - result = -1; - break; - } - - switch (bit_mask) { - case MUSB_CSR0_TXPKTRDY: - if (!(csr & MUSB_CSR0_TXPKTRDY)) { - if (check_stall(MUSB_CONTROL_EP, 0)) { - dev->status = USB_ST_STALLED; - result = -2; - } else - result = 0; - } - break; - - case MUSB_CSR0_RXPKTRDY: - if (check_stall(MUSB_CONTROL_EP, 0)) { - dev->status = USB_ST_STALLED; - result = -2; - } else - if (csr & MUSB_CSR0_RXPKTRDY) - result = 0; - break; - - case MUSB_CSR0_H_REQPKT: - if (!(csr & MUSB_CSR0_H_REQPKT)) { - if (check_stall(MUSB_CONTROL_EP, 0)) { - dev->status = USB_ST_STALLED; - result = -2; - } else - result = 0; - } - break; - } - - /* Check the timeout */ - if (--timeout) - udelay(1); - else { - dev->status = USB_ST_CRC_ERR; - result = -1; - break; - } - } - - return result; -} - -/* - * waits until tx ep is ready. Returns 1 when ep is ready and 0 on error. - */ -static int wait_until_txep_ready(struct usb_device *dev, u8 ep) -{ - u16 csr; - int timeout = MUSB_TIMEOUT; - - do { - if (check_stall(ep, 1)) { - dev->status = USB_ST_STALLED; - return 0; - } - - csr = readw(&musbr->txcsr); - if (csr & MUSB_TXCSR_H_ERROR) { - dev->status = USB_ST_CRC_ERR; - return 0; - } - - /* Check the timeout */ - if (--timeout) - udelay(1); - else { - dev->status = USB_ST_CRC_ERR; - return -1; - } - - } while (csr & MUSB_TXCSR_TXPKTRDY); - return 1; -} - -/* - * waits until rx ep is ready. Returns 1 when ep is ready and 0 on error. - */ -static int wait_until_rxep_ready(struct usb_device *dev, u8 ep) -{ - u16 csr; - int timeout = MUSB_TIMEOUT; - - do { - if (check_stall(ep, 0)) { - dev->status = USB_ST_STALLED; - return 0; - } - - csr = readw(&musbr->rxcsr); - if (csr & MUSB_RXCSR_H_ERROR) { - dev->status = USB_ST_CRC_ERR; - return 0; - } - - /* Check the timeout */ - if (--timeout) - udelay(1); - else { - dev->status = USB_ST_CRC_ERR; - return -1; - } - - } while (!(csr & MUSB_RXCSR_RXPKTRDY)); - return 1; -} - -/* - * This function performs the setup phase of the control transfer - */ -static int ctrlreq_setup_phase(struct usb_device *dev, struct devrequest *setup) -{ - int result; - u16 csr; - - /* write the control request to ep0 fifo */ - write_fifo(MUSB_CONTROL_EP, sizeof(struct devrequest), (void *)setup); - - /* enable transfer of setup packet */ - csr = readw(&musbr->txcsr); - csr |= (MUSB_CSR0_TXPKTRDY|MUSB_CSR0_H_SETUPPKT); - writew(csr, &musbr->txcsr); - - /* wait until the setup packet is transmitted */ - result = wait_until_ep0_ready(dev, MUSB_CSR0_TXPKTRDY); - dev->act_len = 0; - return result; -} - -/* - * This function handles the control transfer in data phase - */ -static int ctrlreq_in_data_phase(struct usb_device *dev, u32 len, void *buffer) -{ - u16 csr; - u32 rxlen = 0; - u32 nextlen = 0; - u8 maxpktsize = (1 << dev->maxpacketsize) * 8; - u8 *rxbuff = (u8 *)buffer; - u8 rxedlength; - int result; - - while (rxlen < len) { - /* Determine the next read length */ - nextlen = ((len-rxlen) > maxpktsize) ? maxpktsize : (len-rxlen); - - /* Set the ReqPkt bit */ - csr = readw(&musbr->txcsr); - writew(csr | MUSB_CSR0_H_REQPKT, &musbr->txcsr); - result = wait_until_ep0_ready(dev, MUSB_CSR0_RXPKTRDY); - if (result < 0) - return result; - - /* Actual number of bytes received by usb */ - rxedlength = readb(&musbr->rxcount); - - /* Read the data from the RxFIFO */ - read_fifo(MUSB_CONTROL_EP, rxedlength, &rxbuff[rxlen]); - - /* Clear the RxPktRdy Bit */ - csr = readw(&musbr->txcsr); - csr &= ~MUSB_CSR0_RXPKTRDY; - writew(csr, &musbr->txcsr); - - /* short packet? */ - if (rxedlength != nextlen) { - dev->act_len += rxedlength; - break; - } - rxlen += nextlen; - dev->act_len = rxlen; - } - return 0; -} - -/* - * This function handles the control transfer out data phase - */ -static int ctrlreq_out_data_phase(struct usb_device *dev, u32 len, void *buffer) -{ - u16 csr; - u32 txlen = 0; - u32 nextlen = 0; - u8 maxpktsize = (1 << dev->maxpacketsize) * 8; - u8 *txbuff = (u8 *)buffer; - int result = 0; - - while (txlen < len) { - /* Determine the next write length */ - nextlen = ((len-txlen) > maxpktsize) ? maxpktsize : (len-txlen); - - /* Load the data to send in FIFO */ - write_fifo(MUSB_CONTROL_EP, txlen, &txbuff[txlen]); - - /* Set TXPKTRDY bit */ - csr = readw(&musbr->txcsr); - - csr |= MUSB_CSR0_TXPKTRDY; - csr |= MUSB_CSR0_H_DIS_PING; - writew(csr, &musbr->txcsr); - result = wait_until_ep0_ready(dev, MUSB_CSR0_TXPKTRDY); - if (result < 0) - break; - - txlen += nextlen; - dev->act_len = txlen; - } - return result; -} - -/* - * This function handles the control transfer out status phase - */ -static int ctrlreq_out_status_phase(struct usb_device *dev) -{ - u16 csr; - int result; - - /* Set the StatusPkt bit */ - csr = readw(&musbr->txcsr); - csr |= (MUSB_CSR0_TXPKTRDY | MUSB_CSR0_H_STATUSPKT); - csr |= MUSB_CSR0_H_DIS_PING; - writew(csr, &musbr->txcsr); - - /* Wait until TXPKTRDY bit is cleared */ - result = wait_until_ep0_ready(dev, MUSB_CSR0_TXPKTRDY); - return result; -} - -/* - * This function handles the control transfer in status phase - */ -static int ctrlreq_in_status_phase(struct usb_device *dev) -{ - u16 csr; - int result; - - /* Set the StatusPkt bit and ReqPkt bit */ - csr = MUSB_CSR0_H_REQPKT | MUSB_CSR0_H_STATUSPKT; - csr |= MUSB_CSR0_H_DIS_PING; - writew(csr, &musbr->txcsr); - result = wait_until_ep0_ready(dev, MUSB_CSR0_H_REQPKT); - - /* clear StatusPkt bit and RxPktRdy bit */ - csr = readw(&musbr->txcsr); - csr &= ~(MUSB_CSR0_RXPKTRDY | MUSB_CSR0_H_STATUSPKT); - writew(csr, &musbr->txcsr); - return result; -} - -/* - * determines the speed of the device (High/Full/Slow) - */ -static u8 get_dev_speed(struct usb_device *dev) -{ - return (dev->speed == USB_SPEED_HIGH) ? MUSB_TYPE_SPEED_HIGH : - ((dev->speed == USB_SPEED_LOW) ? MUSB_TYPE_SPEED_LOW : - MUSB_TYPE_SPEED_FULL); -} - -/* - * configure the hub address and the port address. - */ -static void config_hub_port(struct usb_device *dev, u8 ep) -{ - u8 chid; - u8 hub; - - /* Find out the nearest parent which is high speed */ - while (dev->parent->parent != NULL) - if (get_dev_speed(dev->parent) != MUSB_TYPE_SPEED_HIGH) - dev = dev->parent; - else - break; - - /* determine the port address at that hub */ - hub = dev->parent->devnum; - for (chid = 0; chid < USB_MAXCHILDREN; chid++) - if (dev->parent->children[chid] == dev) - break; - -#ifndef MUSB_NO_MULTIPOINT - /* configure the hub address and the port address */ - writeb(hub, &musbr->tar[ep].txhubaddr); - writeb((chid + 1), &musbr->tar[ep].txhubport); - writeb(hub, &musbr->tar[ep].rxhubaddr); - writeb((chid + 1), &musbr->tar[ep].rxhubport); -#endif -} - -#ifdef MUSB_NO_MULTIPOINT - -static void musb_port_reset(int do_reset) -{ - u8 power = readb(&musbr->power); - - if (do_reset) { - power &= 0xf0; - writeb(power | MUSB_POWER_RESET, &musbr->power); - port_status |= USB_PORT_STAT_RESET; - port_status &= ~USB_PORT_STAT_ENABLE; - udelay(30000); - } else { - writeb(power & ~MUSB_POWER_RESET, &musbr->power); - - power = readb(&musbr->power); - if (power & MUSB_POWER_HSMODE) - port_status |= USB_PORT_STAT_HIGH_SPEED; - - port_status &= ~(USB_PORT_STAT_RESET | (USB_PORT_STAT_C_CONNECTION << 16)); - port_status |= USB_PORT_STAT_ENABLE - | (USB_PORT_STAT_C_RESET << 16) - | (USB_PORT_STAT_C_ENABLE << 16); - } -} - -/* - * root hub control - */ -static int musb_submit_rh_msg(struct usb_device *dev, unsigned long pipe, - void *buffer, int transfer_len, - struct devrequest *cmd) -{ - int leni = transfer_len; - int len = 0; - int stat = 0; - u32 datab[4]; - const u8 *data_buf = (u8 *) datab; - u16 bmRType_bReq; - u16 wValue; - u16 wIndex; - u16 wLength; - u16 int_usb; - - if ((pipe & PIPE_INTERRUPT) == PIPE_INTERRUPT) { - debug("Root-Hub submit IRQ: NOT implemented\n"); - return 0; - } - - bmRType_bReq = cmd->requesttype | (cmd->request << 8); - wValue = swap_16(cmd->value); - wIndex = swap_16(cmd->index); - wLength = swap_16(cmd->length); - - debug("--- HUB ----------------------------------------\n"); - debug("submit rh urb, req=%x val=%#x index=%#x len=%d\n", - bmRType_bReq, wValue, wIndex, wLength); - debug("------------------------------------------------\n"); - - switch (bmRType_bReq) { - case RH_GET_STATUS: - debug("RH_GET_STATUS\n"); - - *(__u16 *) data_buf = swap_16(1); - len = 2; - break; - - case RH_GET_STATUS | RH_INTERFACE: - debug("RH_GET_STATUS | RH_INTERFACE\n"); - - *(__u16 *) data_buf = swap_16(0); - len = 2; - break; - - case RH_GET_STATUS | RH_ENDPOINT: - debug("RH_GET_STATUS | RH_ENDPOINT\n"); - - *(__u16 *) data_buf = swap_16(0); - len = 2; - break; - - case RH_GET_STATUS | RH_CLASS: - debug("RH_GET_STATUS | RH_CLASS\n"); - - *(__u32 *) data_buf = swap_32(0); - len = 4; - break; - - case RH_GET_STATUS | RH_OTHER | RH_CLASS: - debug("RH_GET_STATUS | RH_OTHER | RH_CLASS\n"); - - int_usb = readw(&musbr->intrusb); - if (int_usb & MUSB_INTR_CONNECT) { - port_status |= USB_PORT_STAT_CONNECTION - | (USB_PORT_STAT_C_CONNECTION << 16); - port_status |= USB_PORT_STAT_HIGH_SPEED - | USB_PORT_STAT_ENABLE; - } - - if (port_status & USB_PORT_STAT_RESET) - musb_port_reset(0); - - *(__u32 *) data_buf = swap_32(port_status); - len = 4; - break; - - case RH_CLEAR_FEATURE | RH_ENDPOINT: - debug("RH_CLEAR_FEATURE | RH_ENDPOINT\n"); - - switch (wValue) { - case RH_ENDPOINT_STALL: - debug("C_HUB_ENDPOINT_STALL\n"); - len = 0; - break; - } - port_status &= ~(1 << wValue); - break; - - case RH_CLEAR_FEATURE | RH_CLASS: - debug("RH_CLEAR_FEATURE | RH_CLASS\n"); - - switch (wValue) { - case RH_C_HUB_LOCAL_POWER: - debug("C_HUB_LOCAL_POWER\n"); - len = 0; - break; - - case RH_C_HUB_OVER_CURRENT: - debug("C_HUB_OVER_CURRENT\n"); - len = 0; - break; - } - port_status &= ~(1 << wValue); - break; - - case RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS: - debug("RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS\n"); - - switch (wValue) { - case RH_PORT_ENABLE: - len = 0; - break; - - case RH_PORT_SUSPEND: - len = 0; - break; - - case RH_PORT_POWER: - len = 0; - break; - - case RH_C_PORT_CONNECTION: - len = 0; - break; - - case RH_C_PORT_ENABLE: - len = 0; - break; - - case RH_C_PORT_SUSPEND: - len = 0; - break; - - case RH_C_PORT_OVER_CURRENT: - len = 0; - break; - - case RH_C_PORT_RESET: - len = 0; - break; - - default: - debug("invalid wValue\n"); - stat = USB_ST_STALLED; - } - - port_status &= ~(1 << wValue); - break; - - case RH_SET_FEATURE | RH_OTHER | RH_CLASS: - debug("RH_SET_FEATURE | RH_OTHER | RH_CLASS\n"); - - switch (wValue) { - case RH_PORT_SUSPEND: - len = 0; - break; - - case RH_PORT_RESET: - musb_port_reset(1); - len = 0; - break; - - case RH_PORT_POWER: - len = 0; - break; - - case RH_PORT_ENABLE: - len = 0; - break; - - default: - debug("invalid wValue\n"); - stat = USB_ST_STALLED; - } - - port_status |= 1 << wValue; - break; - - case RH_SET_ADDRESS: - debug("RH_SET_ADDRESS\n"); - - rh_devnum = wValue; - len = 0; - break; - - case RH_GET_DESCRIPTOR: - debug("RH_GET_DESCRIPTOR: %x, %d\n", wValue, wLength); - - switch (wValue) { - case (USB_DT_DEVICE << 8): /* device descriptor */ - len = min_t(unsigned int, - leni, min_t(unsigned int, - sizeof(root_hub_dev_des), - wLength)); - data_buf = root_hub_dev_des; - break; - - case (USB_DT_CONFIG << 8): /* configuration descriptor */ - len = min_t(unsigned int, - leni, min_t(unsigned int, - sizeof(root_hub_config_des), - wLength)); - data_buf = root_hub_config_des; - break; - - case ((USB_DT_STRING << 8) | 0x00): /* string 0 descriptors */ - len = min_t(unsigned int, - leni, min_t(unsigned int, - sizeof(root_hub_str_index0), - wLength)); - data_buf = root_hub_str_index0; - break; - - case ((USB_DT_STRING << 8) | 0x01): /* string 1 descriptors */ - len = min_t(unsigned int, - leni, min_t(unsigned int, - sizeof(root_hub_str_index1), - wLength)); - data_buf = root_hub_str_index1; - break; - - default: - debug("invalid wValue\n"); - stat = USB_ST_STALLED; - } - - break; - - case RH_GET_DESCRIPTOR | RH_CLASS: { - u8 *_data_buf = (u8 *) datab; - debug("RH_GET_DESCRIPTOR | RH_CLASS\n"); - - _data_buf[0] = 0x09; /* min length; */ - _data_buf[1] = 0x29; - _data_buf[2] = 0x1; /* 1 port */ - _data_buf[3] = 0x01; /* per-port power switching */ - _data_buf[3] |= 0x10; /* no overcurrent reporting */ - - /* Corresponds to data_buf[4-7] */ - _data_buf[4] = 0; - _data_buf[5] = 5; - _data_buf[6] = 0; - _data_buf[7] = 0x02; - _data_buf[8] = 0xff; - - len = min_t(unsigned int, leni, - min_t(unsigned int, data_buf[0], wLength)); - break; - } - - case RH_GET_CONFIGURATION: - debug("RH_GET_CONFIGURATION\n"); - - *(__u8 *) data_buf = 0x01; - len = 1; - break; - - case RH_SET_CONFIGURATION: - debug("RH_SET_CONFIGURATION\n"); - - len = 0; - break; - - default: - debug("*** *** *** unsupported root hub command *** *** ***\n"); - stat = USB_ST_STALLED; - } - - len = min_t(int, len, leni); - if (buffer != data_buf) - memcpy(buffer, data_buf, len); - - dev->act_len = len; - dev->status = stat; - debug("dev act_len %d, status %lu\n", dev->act_len, dev->status); - - return stat; -} - -static void musb_rh_init(void) -{ - rh_devnum = 0; - port_status = 0; -} - -#else - -static void musb_rh_init(void) {} - -#endif - -/* - * do a control transfer - */ -int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer, - int len, struct devrequest *setup) -{ - int devnum = usb_pipedevice(pipe); - u8 devspeed; - -#ifdef MUSB_NO_MULTIPOINT - /* Control message is for the HUB? */ - if (devnum == rh_devnum) { - int stat = musb_submit_rh_msg(dev, pipe, buffer, len, setup); - if (stat) - return stat; - } -#endif - - /* select control endpoint */ - writeb(MUSB_CONTROL_EP, &musbr->index); - readw(&musbr->txcsr); - -#ifndef MUSB_NO_MULTIPOINT - /* target addr and (for multipoint) hub addr/port */ - writeb(devnum, &musbr->tar[MUSB_CONTROL_EP].txfuncaddr); - writeb(devnum, &musbr->tar[MUSB_CONTROL_EP].rxfuncaddr); -#endif - - /* configure the hub address and the port number as required */ - devspeed = get_dev_speed(dev); - if ((musb_ishighspeed()) && (dev->parent != NULL) && - (devspeed != MUSB_TYPE_SPEED_HIGH)) { - config_hub_port(dev, MUSB_CONTROL_EP); - writeb(devspeed << 6, &musbr->txtype); - } else { - writeb(musb_cfg.musb_speed << 6, &musbr->txtype); -#ifndef MUSB_NO_MULTIPOINT - writeb(0, &musbr->tar[MUSB_CONTROL_EP].txhubaddr); - writeb(0, &musbr->tar[MUSB_CONTROL_EP].txhubport); - writeb(0, &musbr->tar[MUSB_CONTROL_EP].rxhubaddr); - writeb(0, &musbr->tar[MUSB_CONTROL_EP].rxhubport); -#endif - } - - /* Control transfer setup phase */ - if (ctrlreq_setup_phase(dev, setup) < 0) - return 0; - - switch (setup->request) { - case USB_REQ_GET_DESCRIPTOR: - case USB_REQ_GET_CONFIGURATION: - case USB_REQ_GET_INTERFACE: - case USB_REQ_GET_STATUS: - case USB_MSC_BBB_GET_MAX_LUN: - /* control transfer in-data-phase */ - if (ctrlreq_in_data_phase(dev, len, buffer) < 0) - return 0; - /* control transfer out-status-phase */ - if (ctrlreq_out_status_phase(dev) < 0) - return 0; - break; - - case USB_REQ_SET_ADDRESS: - case USB_REQ_SET_CONFIGURATION: - case USB_REQ_SET_FEATURE: - case USB_REQ_SET_INTERFACE: - case USB_REQ_CLEAR_FEATURE: - case USB_MSC_BBB_RESET: - /* control transfer in status phase */ - if (ctrlreq_in_status_phase(dev) < 0) - return 0; - break; - - case USB_REQ_SET_DESCRIPTOR: - /* control transfer out data phase */ - if (ctrlreq_out_data_phase(dev, len, buffer) < 0) - return 0; - /* control transfer in status phase */ - if (ctrlreq_in_status_phase(dev) < 0) - return 0; - break; - - default: - /* unhandled control transfer */ - return -1; - } - - dev->status = 0; - dev->act_len = len; - -#ifdef MUSB_NO_MULTIPOINT - /* Set device address to USB_FADDR register */ - if (setup->request == USB_REQ_SET_ADDRESS) - writeb(dev->devnum, &musbr->faddr); -#endif - - return len; -} - -/* - * do a bulk transfer - */ -int submit_bulk_msg(struct usb_device *dev, unsigned long pipe, - void *buffer, int len) -{ - int dir_out = usb_pipeout(pipe); - int ep = usb_pipeendpoint(pipe); -#ifndef MUSB_NO_MULTIPOINT - int devnum = usb_pipedevice(pipe); -#endif - u8 type; - u16 csr; - u32 txlen = 0; - u32 nextlen = 0; - u8 devspeed; - - /* select bulk endpoint */ - writeb(MUSB_BULK_EP, &musbr->index); - -#ifndef MUSB_NO_MULTIPOINT - /* write the address of the device */ - if (dir_out) - writeb(devnum, &musbr->tar[MUSB_BULK_EP].txfuncaddr); - else - writeb(devnum, &musbr->tar[MUSB_BULK_EP].rxfuncaddr); -#endif - - /* configure the hub address and the port number as required */ - devspeed = get_dev_speed(dev); - if ((musb_ishighspeed()) && (dev->parent != NULL) && - (devspeed != MUSB_TYPE_SPEED_HIGH)) { - /* - * MUSB is in high speed and the destination device is full - * speed device. So configure the hub address and port - * address registers. - */ - config_hub_port(dev, MUSB_BULK_EP); - } else { -#ifndef MUSB_NO_MULTIPOINT - if (dir_out) { - writeb(0, &musbr->tar[MUSB_BULK_EP].txhubaddr); - writeb(0, &musbr->tar[MUSB_BULK_EP].txhubport); - } else { - writeb(0, &musbr->tar[MUSB_BULK_EP].rxhubaddr); - writeb(0, &musbr->tar[MUSB_BULK_EP].rxhubport); - } -#endif - devspeed = musb_cfg.musb_speed; - } - - /* Write the saved toggle bit value */ - write_toggle(dev, ep, dir_out); - - if (dir_out) { /* bulk-out transfer */ - /* Program the TxType register */ - type = (devspeed << MUSB_TYPE_SPEED_SHIFT) | - (MUSB_TYPE_PROTO_BULK << MUSB_TYPE_PROTO_SHIFT) | - (ep & MUSB_TYPE_REMOTE_END); - writeb(type, &musbr->txtype); - - /* Write maximum packet size to the TxMaxp register */ - writew(dev->epmaxpacketout[ep], &musbr->txmaxp); - while (txlen < len) { - nextlen = ((len-txlen) < dev->epmaxpacketout[ep]) ? - (len-txlen) : dev->epmaxpacketout[ep]; - - /* Write the data to the FIFO */ - write_fifo(MUSB_BULK_EP, nextlen, - (void *)(((u8 *)buffer) + txlen)); - - /* Set the TxPktRdy bit */ - csr = readw(&musbr->txcsr); - writew(csr | MUSB_TXCSR_TXPKTRDY, &musbr->txcsr); - - /* Wait until the TxPktRdy bit is cleared */ - if (wait_until_txep_ready(dev, MUSB_BULK_EP) != 1) { - readw(&musbr->txcsr); - usb_settoggle(dev, ep, dir_out, - (csr >> MUSB_TXCSR_H_DATATOGGLE_SHIFT) & 1); - dev->act_len = txlen; - return 0; - } - txlen += nextlen; - } - - /* Keep a copy of the data toggle bit */ - csr = readw(&musbr->txcsr); - usb_settoggle(dev, ep, dir_out, - (csr >> MUSB_TXCSR_H_DATATOGGLE_SHIFT) & 1); - } else { /* bulk-in transfer */ - /* Write the saved toggle bit value */ - write_toggle(dev, ep, dir_out); - - /* Program the RxType register */ - type = (devspeed << MUSB_TYPE_SPEED_SHIFT) | - (MUSB_TYPE_PROTO_BULK << MUSB_TYPE_PROTO_SHIFT) | - (ep & MUSB_TYPE_REMOTE_END); - writeb(type, &musbr->rxtype); - - /* Write the maximum packet size to the RxMaxp register */ - writew(dev->epmaxpacketin[ep], &musbr->rxmaxp); - while (txlen < len) { - nextlen = ((len-txlen) < dev->epmaxpacketin[ep]) ? - (len-txlen) : dev->epmaxpacketin[ep]; - - /* Set the ReqPkt bit */ - csr = readw(&musbr->rxcsr); - writew(csr | MUSB_RXCSR_H_REQPKT, &musbr->rxcsr); - - /* Wait until the RxPktRdy bit is set */ - if (wait_until_rxep_ready(dev, MUSB_BULK_EP) != 1) { - csr = readw(&musbr->rxcsr); - usb_settoggle(dev, ep, dir_out, - (csr >> MUSB_S_RXCSR_H_DATATOGGLE) & 1); - csr &= ~MUSB_RXCSR_RXPKTRDY; - writew(csr, &musbr->rxcsr); - dev->act_len = txlen; - return 0; - } - - /* Read the data from the FIFO */ - read_fifo(MUSB_BULK_EP, nextlen, - (void *)(((u8 *)buffer) + txlen)); - - /* Clear the RxPktRdy bit */ - csr = readw(&musbr->rxcsr); - csr &= ~MUSB_RXCSR_RXPKTRDY; - writew(csr, &musbr->rxcsr); - txlen += nextlen; - } - - /* Keep a copy of the data toggle bit */ - csr = readw(&musbr->rxcsr); - usb_settoggle(dev, ep, dir_out, - (csr >> MUSB_S_RXCSR_H_DATATOGGLE) & 1); - } - - /* bulk transfer is complete */ - dev->status = 0; - dev->act_len = len; - return 0; -} - -/* - * This function initializes the usb controller module. - */ -int usb_lowlevel_init(int index, enum usb_init_type init, void **controller) -{ - u8 power; - u32 timeout; - - musb_rh_init(); - - if (musb_platform_init() == -1) - return -1; - - /* Configure all the endpoint FIFO's and start usb controller */ - musbr = musb_cfg.regs; - musb_configure_ep(&epinfo[0], ARRAY_SIZE(epinfo)); - musb_start(); - - /* - * Wait until musb is enabled in host mode with a timeout. There - * should be a usb device connected. - */ - timeout = musb_cfg.timeout; - while (--timeout) - if (readb(&musbr->devctl) & MUSB_DEVCTL_HM) - break; - - /* if musb core is not in host mode, then return */ - if (!timeout) - return -1; - - /* start usb bus reset */ - power = readb(&musbr->power); - writeb(power | MUSB_POWER_RESET, &musbr->power); - - /* After initiating a usb reset, wait for about 20ms to 30ms */ - udelay(30000); - - /* stop usb bus reset */ - power = readb(&musbr->power); - power &= ~MUSB_POWER_RESET; - writeb(power, &musbr->power); - - /* Determine if the connected device is a high/full/low speed device */ - musb_cfg.musb_speed = (readb(&musbr->power) & MUSB_POWER_HSMODE) ? - MUSB_TYPE_SPEED_HIGH : - ((readb(&musbr->devctl) & MUSB_DEVCTL_FSDEV) ? - MUSB_TYPE_SPEED_FULL : MUSB_TYPE_SPEED_LOW); - return 0; -} - -/* - * This function stops the operation of the davinci usb module. - */ -int usb_lowlevel_stop(int index) -{ - /* Reset the USB module */ - musb_platform_deinit(); - writeb(0, &musbr->devctl); - return 0; -} - -/* - * This function supports usb interrupt transfers. Currently, usb interrupt - * transfers are not supported. - */ -int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer, - int len, int interval, bool nonblock) -{ - int dir_out = usb_pipeout(pipe); - int ep = usb_pipeendpoint(pipe); -#ifndef MUSB_NO_MULTIPOINT - int devnum = usb_pipedevice(pipe); -#endif - u8 type; - u16 csr; - u32 txlen = 0; - u32 nextlen = 0; - u8 devspeed; - - /* select interrupt endpoint */ - writeb(MUSB_INTR_EP, &musbr->index); - -#ifndef MUSB_NO_MULTIPOINT - /* write the address of the device */ - if (dir_out) - writeb(devnum, &musbr->tar[MUSB_INTR_EP].txfuncaddr); - else - writeb(devnum, &musbr->tar[MUSB_INTR_EP].rxfuncaddr); -#endif - - /* configure the hub address and the port number as required */ - devspeed = get_dev_speed(dev); - if ((musb_ishighspeed()) && (dev->parent != NULL) && - (devspeed != MUSB_TYPE_SPEED_HIGH)) { - /* - * MUSB is in high speed and the destination device is full - * speed device. So configure the hub address and port - * address registers. - */ - config_hub_port(dev, MUSB_INTR_EP); - } else { -#ifndef MUSB_NO_MULTIPOINT - if (dir_out) { - writeb(0, &musbr->tar[MUSB_INTR_EP].txhubaddr); - writeb(0, &musbr->tar[MUSB_INTR_EP].txhubport); - } else { - writeb(0, &musbr->tar[MUSB_INTR_EP].rxhubaddr); - writeb(0, &musbr->tar[MUSB_INTR_EP].rxhubport); - } -#endif - devspeed = musb_cfg.musb_speed; - } - - /* Write the saved toggle bit value */ - write_toggle(dev, ep, dir_out); - - if (!dir_out) { /* intrrupt-in transfer */ - /* Write the saved toggle bit value */ - write_toggle(dev, ep, dir_out); - writeb(interval, &musbr->rxinterval); - - /* Program the RxType register */ - type = (devspeed << MUSB_TYPE_SPEED_SHIFT) | - (MUSB_TYPE_PROTO_INTR << MUSB_TYPE_PROTO_SHIFT) | - (ep & MUSB_TYPE_REMOTE_END); - writeb(type, &musbr->rxtype); - - /* Write the maximum packet size to the RxMaxp register */ - writew(dev->epmaxpacketin[ep], &musbr->rxmaxp); - - while (txlen < len) { - nextlen = ((len-txlen) < dev->epmaxpacketin[ep]) ? - (len-txlen) : dev->epmaxpacketin[ep]; - - /* Set the ReqPkt bit */ - csr = readw(&musbr->rxcsr); - writew(csr | MUSB_RXCSR_H_REQPKT, &musbr->rxcsr); - - /* Wait until the RxPktRdy bit is set */ - if (wait_until_rxep_ready(dev, MUSB_INTR_EP) != 1) { - csr = readw(&musbr->rxcsr); - usb_settoggle(dev, ep, dir_out, - (csr >> MUSB_S_RXCSR_H_DATATOGGLE) & 1); - csr &= ~MUSB_RXCSR_RXPKTRDY; - writew(csr, &musbr->rxcsr); - dev->act_len = txlen; - return 0; - } - - /* Read the data from the FIFO */ - read_fifo(MUSB_INTR_EP, nextlen, - (void *)(((u8 *)buffer) + txlen)); - - /* Clear the RxPktRdy bit */ - csr = readw(&musbr->rxcsr); - csr &= ~MUSB_RXCSR_RXPKTRDY; - writew(csr, &musbr->rxcsr); - txlen += nextlen; - } - - /* Keep a copy of the data toggle bit */ - csr = readw(&musbr->rxcsr); - usb_settoggle(dev, ep, dir_out, - (csr >> MUSB_S_RXCSR_H_DATATOGGLE) & 1); - } - - /* interrupt transfer is complete */ - dev->irq_status = 0; - dev->irq_act_len = len; - dev->irq_handle(dev); - dev->status = 0; - dev->act_len = len; - return 0; -} diff --git a/drivers/usb/musb/musb_hcd.h b/drivers/usb/musb/musb_hcd.h deleted file mode 100644 index a492e99ef9d..00000000000 --- a/drivers/usb/musb/musb_hcd.h +++ /dev/null @@ -1,93 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Mentor USB OTG Core host controller driver. - * - * Copyright (c) 2008 Texas Instruments - * - * Author: Thomas Abraham [email protected], Texas Instruments - */ - -#ifndef __MUSB_HCD_H__ -#define __MUSB_HCD_H__ - -#include "musb_core.h" -#ifdef CONFIG_USB_KEYBOARD -#include <stdio_dev.h> -extern unsigned char new[]; -#endif - -#define MUSB_TIMEOUT 100000 - -/* This defines the endpoint number used for control transfers */ -#define MUSB_CONTROL_EP 0 - -/* This defines the endpoint number used for bulk transfer */ -#ifndef MUSB_BULK_EP -# define MUSB_BULK_EP 1 -#endif - -/* This defines the endpoint number used for interrupt transfer */ -#define MUSB_INTR_EP 2 - -/* Determine the operating speed of MUSB core */ -#define musb_ishighspeed() \ - ((readb(&musbr->power) & MUSB_POWER_HSMODE) \ - >> MUSB_POWER_HSMODE_SHIFT) - -/* USB HUB CONSTANTS (not OHCI-specific; see hub.h) */ - -/* destination of request */ -#define RH_INTERFACE 0x01 -#define RH_ENDPOINT 0x02 -#define RH_OTHER 0x03 - -#define RH_CLASS 0x20 -#define RH_VENDOR 0x40 - -/* Requests: bRequest << 8 | bmRequestType */ -#define RH_GET_STATUS 0x0080 -#define RH_CLEAR_FEATURE 0x0100 -#define RH_SET_FEATURE 0x0300 -#define RH_SET_ADDRESS 0x0500 -#define RH_GET_DESCRIPTOR 0x0680 -#define RH_SET_DESCRIPTOR 0x0700 -#define RH_GET_CONFIGURATION 0x0880 -#define RH_SET_CONFIGURATION 0x0900 -#define RH_GET_STATE 0x0280 -#define RH_GET_INTERFACE 0x0A80 -#define RH_SET_INTERFACE 0x0B00 -#define RH_SYNC_FRAME 0x0C80 -/* Our Vendor Specific Request */ -#define RH_SET_EP 0x2000 - -/* Hub port features */ -#define RH_PORT_CONNECTION 0x00 -#define RH_PORT_ENABLE 0x01 -#define RH_PORT_SUSPEND 0x02 -#define RH_PORT_OVER_CURRENT 0x03 -#define RH_PORT_RESET 0x04 -#define RH_PORT_POWER 0x08 -#define RH_PORT_LOW_SPEED 0x09 - -#define RH_C_PORT_CONNECTION 0x10 -#define RH_C_PORT_ENABLE 0x11 -#define RH_C_PORT_SUSPEND 0x12 -#define RH_C_PORT_OVER_CURRENT 0x13 -#define RH_C_PORT_RESET 0x14 - -/* Hub features */ -#define RH_C_HUB_LOCAL_POWER 0x00 -#define RH_C_HUB_OVER_CURRENT 0x01 - -#define RH_DEVICE_REMOTE_WAKEUP 0x00 -#define RH_ENDPOINT_STALL 0x01 - -#define RH_ACK 0x01 -#define RH_REQ_ERR -1 -#define RH_NACK 0x00 - -/* extern functions */ -extern int musb_platform_init(void); -extern void musb_platform_deinit(void); - -#endif /* __MUSB_HCD_H__ */ diff --git a/drivers/usb/musb/musb_udc.c b/drivers/usb/musb/musb_udc.c deleted file mode 100644 index 696855ee3a6..00000000000 --- a/drivers/usb/musb/musb_udc.c +++ /dev/null @@ -1,953 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright (c) 2009 Wind River Systems, Inc. - * Tom Rix <[email protected]> - * - * This file is a rewrite of the usb device part of - * repository git.omapzoom.org/repo/u-boot.git, branch master, - * file cpu/omap3/fastboot.c - * - * This is the unique part of its copyright : - * - * ------------------------------------------------------------------------- - * - * (C) Copyright 2008 - 2009 - * Windriver, <www.windriver.com> - * Tom Rix <[email protected]> - * - * ------------------------------------------------------------------------- - * - * The details of connecting the device to the uboot usb device subsystem - * came from the old omap3 repository www.sakoman.net/u-boot-omap3.git, - * branch omap3-dev-usb, file drivers/usb/usbdcore_musb.c - * - * This is the unique part of its copyright : - * - * ------------------------------------------------------------------------- - * - * (C) Copyright 2008 Texas Instruments Incorporated. - * - * Based on - * u-boot OMAP1510 USB drivers (drivers/usbdcore_omap1510.c) - * twl4030 init based on linux (drivers/i2c/chips/twl4030_usb.c) - * - * Author: Diego Dompe ([email protected]) - * Atin Malaviya ([email protected]) - * - * ------------------------------------------------------------------------- - */ - -#include <hang.h> -#include <serial.h> -#include <usbdevice.h> -#include <linux/delay.h> -#include <usb/udc.h> -#include "../gadget/ep0.h" -#include "musb_core.h" -#if defined(CONFIG_USB_OMAP3) -#include "omap3.h" -#elif defined(CONFIG_USB_AM35X) -#include "am35x.h" -#endif - -/* Define MUSB_DEBUG for debugging */ -/* #define MUSB_DEBUG */ -#include "musb_debug.h" - -#define MAX_ENDPOINT 15 - -#define GET_ENDPOINT(dev,ep) \ -(((struct usb_device_instance *)(dev))->bus->endpoint_array + ep) - -#define SET_EP0_STATE(s) \ -do { \ - if ((0 <= (s)) && (SET_ADDRESS >= (s))) { \ - if ((s) != ep0_state) { \ - if ((debug_setup) && (debug_level > 1)) \ - serial_printf("INFO : Changing state " \ - "from %s to %s in %s at " \ - "line %d\n", \ - ep0_state_strings[ep0_state],\ - ep0_state_strings[s], \ - __PRETTY_FUNCTION__, \ - __LINE__); \ - ep0_state = s; \ - } \ - } else { \ - if (debug_level > 0) \ - serial_printf("Error at %s %d with setting " \ - "state %d is invalid\n", \ - __PRETTY_FUNCTION__, __LINE__, s); \ - } \ -} while (0) - -/* static implies these initialized to 0 or NULL */ -static int debug_setup; -static int debug_level; -static struct musb_epinfo epinfo[MAX_ENDPOINT * 2 + 2]; -static enum ep0_state_enum { - IDLE = 0, - TX, - RX, - SET_ADDRESS -} ep0_state = IDLE; -static char *ep0_state_strings[4] = { - "IDLE", - "TX", - "RX", - "SET_ADDRESS", -}; - -static struct urb *ep0_urb; -struct usb_endpoint_instance *ep0_endpoint; -static struct usb_device_instance *udc_device; -static int enabled; - -static u16 pending_intrrx; - -#ifdef MUSB_DEBUG -static void musb_db_regs(void) -{ - u8 b; - u16 w; - - b = readb(&musbr->faddr); - serial_printf("\tfaddr 0x%2.2x\n", b); - - b = readb(&musbr->power); - musb_print_pwr(b); - - w = readw(&musbr->ep[0].ep0.csr0); - musb_print_csr0(w); - - b = readb(&musbr->devctl); - musb_print_devctl(b); - - b = readb(&musbr->ep[0].ep0.configdata); - musb_print_config(b); - - w = readw(&musbr->frame); - serial_printf("\tframe 0x%4.4x\n", w); - - b = readb(&musbr->index); - serial_printf("\tindex 0x%2.2x\n", b); - - w = readw(&musbr->ep[1].epN.rxmaxp); - musb_print_rxmaxp(w); - - w = readw(&musbr->ep[1].epN.rxcsr); - musb_print_rxcsr(w); - - w = readw(&musbr->ep[1].epN.txmaxp); - musb_print_txmaxp(w); - - w = readw(&musbr->ep[1].epN.txcsr); - musb_print_txcsr(w); -} -#else -#define musb_db_regs() -#endif /* DEBUG_MUSB */ - -static void musb_peri_softconnect(void) -{ - u8 power, devctl; - - /* Power off MUSB */ - power = readb(&musbr->power); - power &= ~MUSB_POWER_SOFTCONN; - writeb(power, &musbr->power); - - /* Read intr to clear */ - readb(&musbr->intrusb); - readw(&musbr->intrrx); - readw(&musbr->intrtx); - - udelay(1000 * 1000); /* 1 sec */ - - /* Power on MUSB */ - power = readb(&musbr->power); - power |= MUSB_POWER_SOFTCONN; - /* - * The usb device interface is usb 1.1 - * Disable 2.0 high speed by clearring the hsenable bit. - */ - power &= ~MUSB_POWER_HSENAB; - writeb(power, &musbr->power); - - /* Check if device is in b-peripheral mode */ - devctl = readb(&musbr->devctl); - if (!(devctl & MUSB_DEVCTL_BDEVICE) || - (devctl & MUSB_DEVCTL_HM)) { - serial_printf("ERROR : Unsupport USB mode\n"); - serial_printf("Check that mini-B USB cable is attached " - "to the device\n"); - } - - if (debug_setup && (debug_level > 1)) - musb_db_regs(); -} - -static void musb_peri_reset(void) -{ - if ((debug_setup) && (debug_level > 1)) - serial_printf("INFO : %s reset\n", __PRETTY_FUNCTION__); - - if (ep0_endpoint) - ep0_endpoint->endpoint_address = 0xff; - - /* Sync sw and hw addresses */ - writeb(udc_device->address, &musbr->faddr); - - SET_EP0_STATE(IDLE); -} - -static void musb_peri_resume(void) -{ - /* noop */ -} - -static void musb_peri_ep0_stall(void) -{ - u16 csr0; - - csr0 = readw(&musbr->ep[0].ep0.csr0); - csr0 |= MUSB_CSR0_P_SENDSTALL; - writew(csr0, &musbr->ep[0].ep0.csr0); - if ((debug_setup) && (debug_level > 1)) - serial_printf("INFO : %s stall\n", __PRETTY_FUNCTION__); -} - -static void musb_peri_ep0_ack_req(void) -{ - u16 csr0; - - csr0 = readw(&musbr->ep[0].ep0.csr0); - csr0 |= MUSB_CSR0_P_SVDRXPKTRDY; - writew(csr0, &musbr->ep[0].ep0.csr0); -} - -static void musb_ep0_tx_ready(void) -{ - u16 csr0; - - csr0 = readw(&musbr->ep[0].ep0.csr0); - csr0 |= MUSB_CSR0_TXPKTRDY; - writew(csr0, &musbr->ep[0].ep0.csr0); -} - -static void musb_ep0_tx_ready_and_last(void) -{ - u16 csr0; - - csr0 = readw(&musbr->ep[0].ep0.csr0); - csr0 |= (MUSB_CSR0_TXPKTRDY | MUSB_CSR0_P_DATAEND); - writew(csr0, &musbr->ep[0].ep0.csr0); -} - -static void musb_peri_ep0_last(void) -{ - u16 csr0; - - csr0 = readw(&musbr->ep[0].ep0.csr0); - csr0 |= MUSB_CSR0_P_DATAEND; - writew(csr0, &musbr->ep[0].ep0.csr0); -} - -static void musb_peri_ep0_set_address(void) -{ - u8 faddr; - writeb(udc_device->address, &musbr->faddr); - - /* Verify */ - faddr = readb(&musbr->faddr); - if (udc_device->address == faddr) { - SET_EP0_STATE(IDLE); - usbd_device_event_irq(udc_device, DEVICE_ADDRESS_ASSIGNED, 0); - if ((debug_setup) && (debug_level > 1)) - serial_printf("INFO : %s Address set to %d\n", - __PRETTY_FUNCTION__, udc_device->address); - } else { - if (debug_level > 0) - serial_printf("ERROR : %s Address mismatch " - "sw %d vs hw %d\n", - __PRETTY_FUNCTION__, - udc_device->address, faddr); - } -} - -static void musb_peri_rx_ack(unsigned int ep) -{ - u16 peri_rxcsr; - - peri_rxcsr = readw(&musbr->ep[ep].epN.rxcsr); - peri_rxcsr &= ~MUSB_RXCSR_RXPKTRDY; - writew(peri_rxcsr, &musbr->ep[ep].epN.rxcsr); -} - -static void musb_peri_tx_ready(unsigned int ep) -{ - u16 peri_txcsr; - - peri_txcsr = readw(&musbr->ep[ep].epN.txcsr); - peri_txcsr |= MUSB_TXCSR_TXPKTRDY; - writew(peri_txcsr, &musbr->ep[ep].epN.txcsr); -} - -static void musb_peri_ep0_zero_data_request(int err) -{ - musb_peri_ep0_ack_req(); - - if (err) { - musb_peri_ep0_stall(); - SET_EP0_STATE(IDLE); - } else { - - musb_peri_ep0_last(); - - /* USBD state */ - switch (ep0_urb->device_request.bRequest) { - case USB_REQ_SET_ADDRESS: - if ((debug_setup) && (debug_level > 1)) - serial_printf("INFO : %s received set " - "address\n", __PRETTY_FUNCTION__); - break; - - case USB_REQ_SET_CONFIGURATION: - if ((debug_setup) && (debug_level > 1)) - serial_printf("INFO : %s Configured\n", - __PRETTY_FUNCTION__); - usbd_device_event_irq(udc_device, DEVICE_CONFIGURED, 0); - break; - } - - /* EP0 state */ - if (USB_REQ_SET_ADDRESS == ep0_urb->device_request.bRequest) { - SET_EP0_STATE(SET_ADDRESS); - } else { - SET_EP0_STATE(IDLE); - } - } -} - -static void musb_peri_ep0_rx_data_request(void) -{ - /* - * This is the completion of the data OUT / RX - * - * Host is sending data to ep0 that is not - * part of setup. This comes from the cdc_recv_setup - * op that is device specific. - * - */ - musb_peri_ep0_ack_req(); - - ep0_endpoint->rcv_urb = ep0_urb; - ep0_urb->actual_length = 0; - SET_EP0_STATE(RX); -} - -static void musb_peri_ep0_tx_data_request(int err) -{ - if (err) { - musb_peri_ep0_stall(); - SET_EP0_STATE(IDLE); - } else { - musb_peri_ep0_ack_req(); - - ep0_endpoint->tx_urb = ep0_urb; - ep0_endpoint->sent = 0; - SET_EP0_STATE(TX); - } -} - -static void musb_peri_ep0_idle(void) -{ - u16 count0; - int err; - u16 csr0; - - /* - * Verify addresses - * A lot of confusion can be caused if the address - * in software, udc layer, does not agree with the - * hardware. Since the setting of the hardware address - * must be set after the set address request, the - * usb state machine is out of sync for a few frame. - * It is a good idea to run this check when changes - * are made to the state machine. - */ - if ((debug_level > 0) && - (ep0_state != SET_ADDRESS)) { - u8 faddr; - - faddr = readb(&musbr->faddr); - if (udc_device->address != faddr) { - serial_printf("ERROR : %s addresses do not" - "match sw %d vs hw %d\n", - __PRETTY_FUNCTION__, - udc_device->address, faddr); - udelay(1000 * 1000); - hang(); - } - } - - csr0 = readw(&musbr->ep[0].ep0.csr0); - - if (!(MUSB_CSR0_RXPKTRDY & csr0)) - goto end; - - count0 = readw(&musbr->ep[0].ep0.count0); - if (count0 == 0) - goto end; - - if (count0 != 8) { - if ((debug_setup) && (debug_level > 1)) - serial_printf("WARN : %s SETUP incorrect size %d\n", - __PRETTY_FUNCTION__, count0); - musb_peri_ep0_stall(); - goto end; - } - - read_fifo(0, count0, &ep0_urb->device_request); - - if (debug_level > 2) - print_usb_device_request(&ep0_urb->device_request); - - if (ep0_urb->device_request.wLength == 0) { - err = ep0_recv_setup(ep0_urb); - - /* Zero data request */ - musb_peri_ep0_zero_data_request(err); - } else { - /* Is data coming or going ? */ - u8 reqType = ep0_urb->device_request.bmRequestType; - - if (USB_REQ_DEVICE2HOST == (reqType & USB_REQ_DIRECTION_MASK)) { - err = ep0_recv_setup(ep0_urb); - /* Device to host */ - musb_peri_ep0_tx_data_request(err); - } else { - /* - * Host to device - * - * The RX routine will call ep0_recv_setup - * when the data packet has arrived. - */ - musb_peri_ep0_rx_data_request(); - } - } - -end: - return; -} - -static void musb_peri_ep0_rx(void) -{ - /* - * This is the completion of the data OUT / RX - * - * Host is sending data to ep0 that is not - * part of setup. This comes from the cdc_recv_setup - * op that is device specific. - * - * Pass the data back to driver ep0_recv_setup which - * should give the cdc_recv_setup the chance to handle - * the rx - */ - u16 csr0; - u16 count0; - - if (debug_level > 3) { - if (0 != ep0_urb->actual_length) { - serial_printf("%s finished ? %d of %d\n", - __PRETTY_FUNCTION__, - ep0_urb->actual_length, - ep0_urb->device_request.wLength); - } - } - - if (ep0_urb->device_request.wLength == ep0_urb->actual_length) { - musb_peri_ep0_last(); - SET_EP0_STATE(IDLE); - ep0_recv_setup(ep0_urb); - return; - } - - csr0 = readw(&musbr->ep[0].ep0.csr0); - if (!(MUSB_CSR0_RXPKTRDY & csr0)) - return; - - count0 = readw(&musbr->ep[0].ep0.count0); - - if (count0) { - struct usb_endpoint_instance *endpoint; - u32 length; - u8 *data; - - endpoint = ep0_endpoint; - if (endpoint && endpoint->rcv_urb) { - struct urb *urb = endpoint->rcv_urb; - unsigned int remaining_space = urb->buffer_length - - urb->actual_length; - - if (remaining_space) { - int urb_bad = 0; /* urb is good */ - - if (count0 > remaining_space) - length = remaining_space; - else - length = count0; - - data = (u8 *) urb->buffer_data; - data += urb->actual_length; - - /* The common musb fifo reader */ - read_fifo(0, length, data); - - musb_peri_ep0_ack_req(); - - /* - * urb's actual_length is updated in - * usbd_rcv_complete - */ - usbd_rcv_complete(endpoint, length, urb_bad); - - } else { - if (debug_level > 0) - serial_printf("ERROR : %s no space in " - "rcv buffer\n", - __PRETTY_FUNCTION__); - } - } else { - if (debug_level > 0) - serial_printf("ERROR : %s problem with " - "endpoint\n", - __PRETTY_FUNCTION__); - } - } else { - if (debug_level > 0) - serial_printf("ERROR : %s with nothing to do\n", - __PRETTY_FUNCTION__); - } -} - -static void musb_peri_ep0_tx(void) -{ - u16 csr0; - int transfer_size = 0; - unsigned int p, pm; - - csr0 = readw(&musbr->ep[0].ep0.csr0); - - /* Check for pending tx */ - if (csr0 & MUSB_CSR0_TXPKTRDY) - goto end; - - /* Check if this is the last packet sent */ - if (ep0_endpoint->sent >= ep0_urb->actual_length) { - SET_EP0_STATE(IDLE); - goto end; - } - - transfer_size = ep0_urb->actual_length - ep0_endpoint->sent; - /* Is the transfer size negative ? */ - if (transfer_size <= 0) { - if (debug_level > 0) - serial_printf("ERROR : %s problem with the" - " transfer size %d\n", - __PRETTY_FUNCTION__, - transfer_size); - SET_EP0_STATE(IDLE); - goto end; - } - - /* Truncate large transfers to the fifo size */ - if (transfer_size > ep0_endpoint->tx_packetSize) - transfer_size = ep0_endpoint->tx_packetSize; - - write_fifo(0, transfer_size, &ep0_urb->buffer[ep0_endpoint->sent]); - ep0_endpoint->sent += transfer_size; - - /* Done or more to send ? */ - if (ep0_endpoint->sent >= ep0_urb->actual_length) - musb_ep0_tx_ready_and_last(); - else - musb_ep0_tx_ready(); - - /* Wait a bit */ - pm = 10; - for (p = 0; p < pm; p++) { - csr0 = readw(&musbr->ep[0].ep0.csr0); - if (!(csr0 & MUSB_CSR0_TXPKTRDY)) - break; - - /* Double the delay. */ - udelay(1 << pm); - } - - if ((ep0_endpoint->sent >= ep0_urb->actual_length) && (p < pm)) - SET_EP0_STATE(IDLE); - -end: - return; -} - -static void musb_peri_ep0(void) -{ - u16 csr0; - - if (SET_ADDRESS == ep0_state) - return; - - csr0 = readw(&musbr->ep[0].ep0.csr0); - - /* Error conditions */ - if (MUSB_CSR0_P_SENTSTALL & csr0) { - csr0 &= ~MUSB_CSR0_P_SENTSTALL; - writew(csr0, &musbr->ep[0].ep0.csr0); - SET_EP0_STATE(IDLE); - } - if (MUSB_CSR0_P_SETUPEND & csr0) { - csr0 |= MUSB_CSR0_P_SVDSETUPEND; - writew(csr0, &musbr->ep[0].ep0.csr0); - SET_EP0_STATE(IDLE); - if ((debug_setup) && (debug_level > 1)) - serial_printf("WARN: %s SETUPEND\n", - __PRETTY_FUNCTION__); - } - - /* Normal states */ - if (IDLE == ep0_state) - musb_peri_ep0_idle(); - - if (TX == ep0_state) - musb_peri_ep0_tx(); - - if (RX == ep0_state) - musb_peri_ep0_rx(); -} - -static void musb_peri_rx_ep(unsigned int ep) -{ - u16 peri_rxcount; - u16 peri_rxcsr = readw(&musbr->ep[ep].epN.rxcsr); - - if (!(peri_rxcsr & MUSB_RXCSR_RXPKTRDY)) { - if (debug_level > 0) - serial_printf("ERROR : %s %d without MUSB_RXCSR_RXPKTRDY set\n", - __PRETTY_FUNCTION__, ep); - return; - } - - peri_rxcount = readw(&musbr->ep[ep].epN.rxcount); - if (peri_rxcount) { - struct usb_endpoint_instance *endpoint; - u32 length; - u8 *data; - - endpoint = GET_ENDPOINT(udc_device, ep); - if (endpoint && endpoint->rcv_urb) { - struct urb *urb = endpoint->rcv_urb; - unsigned int remaining_space = urb->buffer_length - - urb->actual_length; - - if (remaining_space) { - int urb_bad = 0; /* urb is good */ - - if (peri_rxcount > remaining_space) - length = remaining_space; - else - length = peri_rxcount; - - data = (u8 *) urb->buffer_data; - data += urb->actual_length; - - /* The common musb fifo reader */ - read_fifo(ep, length, data); - - if (length == peri_rxcount) - musb_peri_rx_ack(ep); - else - pending_intrrx |= (1 << ep); - - /* - * urb's actual_length is updated in - * usbd_rcv_complete - */ - usbd_rcv_complete(endpoint, length, urb_bad); - - } else { - if (debug_level > 0) - serial_printf("ERROR : %s %d no space " - "in rcv buffer\n", - __PRETTY_FUNCTION__, ep); - - pending_intrrx |= (1 << ep); - } - } else { - if (debug_level > 0) - serial_printf("ERROR : %s %d problem with " - "endpoint\n", - __PRETTY_FUNCTION__, ep); - - pending_intrrx |= (1 << ep); - } - - } else { - if (debug_level > 0) - serial_printf("ERROR : %s %d with nothing to do\n", - __PRETTY_FUNCTION__, ep); - - musb_peri_rx_ack(ep); - } -} - -static void musb_peri_rx(u16 intr) -{ - unsigned int ep; - - /* First bit is reserved and does not indicate interrupt for EP0 */ - - for (ep = 1; ep < 16; ep++) { - if ((1 << ep) & intr) - musb_peri_rx_ep(ep); - } -} - -static void musb_peri_tx(u16 intr) -{ - unsigned int ep; - - /* Check for EP0: first bit indicates interrupt for both RX and TX */ - if (0x01 & intr) - musb_peri_ep0(); - - for (ep = 1; ep < 16; ep++) { - if ((1 << ep) & intr) - udc_endpoint_write(GET_ENDPOINT(udc_device, ep)); - } -} - -void udc_irq(void) -{ - /* This is a high freq called function */ - if (enabled) { - u8 intrusb; - - intrusb = readb(&musbr->intrusb); - - /* - * See drivers/usb/gadget/mpc8xx_udc.c for - * state diagram going from detached through - * configuration. - */ - if (MUSB_INTR_RESUME & intrusb) { - usbd_device_event_irq(udc_device, - DEVICE_BUS_ACTIVITY, 0); - musb_peri_resume(); - } - - if (MUSB_INTR_RESET & intrusb) { - usbd_device_event_irq(udc_device, DEVICE_RESET, 0); - musb_peri_reset(); - } - - if (MUSB_INTR_DISCONNECT & intrusb) { - /* cable unplugged from hub/host */ - usbd_device_event_irq(udc_device, DEVICE_RESET, 0); - musb_peri_reset(); - usbd_device_event_irq(udc_device, DEVICE_HUB_RESET, 0); - } - - if (MUSB_INTR_SOF & intrusb) { - usbd_device_event_irq(udc_device, - DEVICE_BUS_ACTIVITY, 0); - musb_peri_resume(); - } - - if (MUSB_INTR_SUSPEND & intrusb) { - usbd_device_event_irq(udc_device, - DEVICE_BUS_INACTIVE, 0); - } - - if (ep0_state != SET_ADDRESS) { - u16 intrrx, intrtx; - - intrrx = readw(&musbr->intrrx); - intrtx = readw(&musbr->intrtx); - - intrrx |= pending_intrrx; - pending_intrrx = 0; - - if (intrrx) - musb_peri_rx(intrrx); - - if (intrtx) - musb_peri_tx(intrtx); - } else { - if (readw(&musbr->intrtx) & 0x1) { - u8 faddr; - faddr = readb(&musbr->faddr); - /* - * Setting of the address can fail. - * Normally it succeeds the second time. - */ - if (udc_device->address != faddr) - musb_peri_ep0_set_address(); - } - } - } -} - -void udc_set_nak(int ep_num) -{ - /* noop */ -} - -void udc_unset_nak(int ep_num) -{ - /* noop */ -} - -int udc_endpoint_write(struct usb_endpoint_instance *endpoint) -{ - int ret = 0; - - /* Transmit only if the hardware is available */ - if (endpoint->tx_urb && endpoint->state == 0) { - unsigned int ep = endpoint->endpoint_address & - USB_ENDPOINT_NUMBER_MASK; - - u16 peri_txcsr = readw(&musbr->ep[ep].epN.txcsr); - - /* Error conditions */ - if (peri_txcsr & MUSB_TXCSR_P_UNDERRUN) { - peri_txcsr &= ~MUSB_TXCSR_P_UNDERRUN; - writew(peri_txcsr, &musbr->ep[ep].epN.txcsr); - } - - if (debug_level > 1) - musb_print_txcsr(peri_txcsr); - - /* Check if a packet is waiting to be sent */ - if (!(peri_txcsr & MUSB_TXCSR_TXPKTRDY)) { - u32 length; - u8 *data; - struct urb *urb = endpoint->tx_urb; - unsigned int remaining_packet = urb->actual_length - - endpoint->sent; - - if (endpoint->tx_packetSize < remaining_packet) - length = endpoint->tx_packetSize; - else - length = remaining_packet; - - data = (u8 *) urb->buffer; - data += endpoint->sent; - - /* common musb fifo function */ - write_fifo(ep, length, data); - - musb_peri_tx_ready(ep); - - endpoint->last = length; - /* usbd_tx_complete will take care of updating 'sent' */ - usbd_tx_complete(endpoint); - } - } else { - if (debug_level > 0) - serial_printf("ERROR : %s Problem with urb %p " - "or ep state %d\n", - __PRETTY_FUNCTION__, - endpoint->tx_urb, endpoint->state); - } - - return ret; -} - -void udc_setup_ep(struct usb_device_instance *device, unsigned int id, - struct usb_endpoint_instance *endpoint) -{ - if (0 == id) { - /* EP0 */ - ep0_endpoint = endpoint; - ep0_endpoint->endpoint_address = 0xff; - ep0_urb = usbd_alloc_urb(device, endpoint); - } else if (MAX_ENDPOINT >= id) { - epinfo[(id * 2) + 0].epsize = endpoint->rcv_packetSize; - epinfo[(id * 2) + 1].epsize = endpoint->tx_packetSize; - musb_configure_ep(&epinfo[0], ARRAY_SIZE(epinfo)); - } else { - if (debug_level > 0) - serial_printf("ERROR : %s endpoint request %d " - "exceeds maximum %d\n", - __PRETTY_FUNCTION__, id, MAX_ENDPOINT); - } -} - -void udc_connect(void) -{ - /* noop */ -} - -void udc_disconnect(void) -{ - /* noop */ -} - -void udc_enable(struct usb_device_instance *device) -{ - /* Save the device structure pointer */ - udc_device = device; - - enabled = 1; -} - -void udc_disable(void) -{ - enabled = 0; -} - -void udc_startup_events(struct usb_device_instance *device) -{ - /* The DEVICE_INIT event puts the USB device in the state STATE_INIT. */ - usbd_device_event_irq(device, DEVICE_INIT, 0); - - /* - * The DEVICE_CREATE event puts the USB device in the state - * STATE_ATTACHED. - */ - usbd_device_event_irq(device, DEVICE_CREATE, 0); - - /* Resets the address to 0 */ - usbd_device_event_irq(device, DEVICE_RESET, 0); - - udc_enable(device); -} - -int udc_init(void) -{ - int ret; - int ep_loop; - - ret = musb_platform_init(); - if (ret < 0) - goto end; - - /* Configure all the endpoint FIFO's and start usb controller */ - musbr = musb_cfg.regs; - - /* Initialize the endpoints */ - for (ep_loop = 0; ep_loop <= MAX_ENDPOINT * 2; ep_loop++) { - epinfo[ep_loop].epnum = (ep_loop / 2) + 1; - epinfo[ep_loop].epdir = ep_loop % 2; /* OUT, IN */ - epinfo[ep_loop].epsize = 0; - } - - musb_peri_softconnect(); - - ret = 0; -end: - - return ret; -} diff --git a/drivers/usb/musb/omap3.c b/drivers/usb/musb/omap3.c deleted file mode 100644 index e5238bc02f8..00000000000 --- a/drivers/usb/musb/omap3.c +++ /dev/null @@ -1,129 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright (c) 2009 Wind River Systems, Inc. - * Tom Rix <[email protected]> - * - * This is file is based on - * repository git.gitorious.org/u-boot-omap3/mainline.git, - * branch omap3-dev-usb, file drivers/usb/host/omap3530_usb.c - * - * This is the unique part of its copyright : - * - * ------------------------------------------------------------------------ - * - * Copyright (c) 2009 Texas Instruments - * - * ------------------------------------------------------------------------ - */ - -#include <serial.h> -#include <asm/omap_common.h> -#include <twl4030.h> -#include "omap3.h" - -static int platform_needs_initialization = 1; - -struct musb_config musb_cfg = { - .regs = (struct musb_regs *)MENTOR_USB0_BASE, - .timeout = OMAP3_USB_TIMEOUT, - .musb_speed = 0, -}; - -/* - * OMAP3 USB OTG registers. - */ -struct omap3_otg_regs { - u32 revision; - u32 sysconfig; - u32 sysstatus; - u32 interfsel; - u32 simenable; - u32 forcestdby; -}; - -static struct omap3_otg_regs *otg; - -#define OMAP3_OTG_SYSCONFIG_SMART_STANDBY_MODE 0x2000 -#define OMAP3_OTG_SYSCONFIG_NO_STANDBY_MODE 0x1000 -#define OMAP3_OTG_SYSCONFIG_SMART_IDLE_MODE 0x0010 -#define OMAP3_OTG_SYSCONFIG_NO_IDLE_MODE 0x0008 -#define OMAP3_OTG_SYSCONFIG_ENABLEWAKEUP 0x0004 -#define OMAP3_OTG_SYSCONFIG_SOFTRESET 0x0002 -#define OMAP3_OTG_SYSCONFIG_AUTOIDLE 0x0001 - -#define OMAP3_OTG_SYSSTATUS_RESETDONE 0x0001 - -#define OMAP3_OTG_INTERFSEL_OMAP 0x0001 - -#define OMAP3_OTG_FORCESTDBY_STANDBY 0x0001 - -#ifdef DEBUG_MUSB_OMAP3 -static void musb_db_otg_regs(void) -{ - u32 l; - l = readl(&otg->revision); - serial_printf("OTG_REVISION 0x%x\n", l); - l = readl(&otg->sysconfig); - serial_printf("OTG_SYSCONFIG 0x%x\n", l); - l = readl(&otg->sysstatus); - serial_printf("OTG_SYSSTATUS 0x%x\n", l); - l = readl(&otg->interfsel); - serial_printf("OTG_INTERFSEL 0x%x\n", l); - l = readl(&otg->forcestdby); - serial_printf("OTG_FORCESTDBY 0x%x\n", l); -} -#endif - -int musb_platform_init(void) -{ - int ret = -1; - - if (platform_needs_initialization) { - u32 stdby; - - /* - * OMAP3EVM uses ISP1504 phy and so - * twl4030 related init is not required. - */ -#ifdef CONFIG_TWL4030_USB - if (twl4030_usb_ulpi_init()) { - serial_printf("ERROR: %s Could not initialize PHY\n", - __PRETTY_FUNCTION__); - goto end; - } -#endif - - otg = (struct omap3_otg_regs *)OMAP3_OTG_BASE; - - /* Set OTG to always be on */ - writel(OMAP3_OTG_SYSCONFIG_NO_STANDBY_MODE | - OMAP3_OTG_SYSCONFIG_NO_IDLE_MODE, &otg->sysconfig); - - /* Set the interface */ - writel(OMAP3_OTG_INTERFSEL_OMAP, &otg->interfsel); - - /* Clear force standby */ - stdby = readl(&otg->forcestdby); - stdby &= ~OMAP3_OTG_FORCESTDBY_STANDBY; - writel(stdby, &otg->forcestdby); - -#ifdef CONFIG_TARGET_OMAP3_EVM - musb_cfg.extvbus = omap3_evm_need_extvbus(); -#endif - - platform_needs_initialization = 0; - } - - ret = platform_needs_initialization; - -#ifdef CONFIG_TWL4030_USB -end: -#endif - return ret; - -} - -void musb_platform_deinit(void) -{ - /* noop */ -} diff --git a/drivers/usb/musb/omap3.h b/drivers/usb/musb/omap3.h deleted file mode 100644 index 78fdb2959bb..00000000000 --- a/drivers/usb/musb/omap3.h +++ /dev/null @@ -1,38 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Copyright (c) 2009 Wind River Systems, Inc. - * Tom Rix <[email protected]> - * - * This file is based on the file drivers/usb/musb/davinci.h - * - * This is the unique part of its copyright: - * - * -------------------------------------------------------------------- - * - * Copyright (c) 2008 Texas Instruments - * Author: Thomas Abraham [email protected], Texas Instruments - * - * -------------------------------------------------------------------- - */ -#ifndef _MUSB_OMAP3_H_ -#define _MUSB_OMAP3_H_ - -#include <asm/arch/cpu.h> -#include "musb_core.h" - -/* Base address of MUSB registers */ -#define MENTOR_USB0_BASE MUSB_BASE - -/* Base address of OTG registers */ -#define OMAP3_OTG_BASE (MENTOR_USB0_BASE + 0x400) - -/* Timeout for USB module */ -#define OMAP3_USB_TIMEOUT 0x3FFFFFF - -int musb_platform_init(void); - -#ifdef CONFIG_TARGET_OMAP3_EVM -extern u8 omap3_evm_need_extvbus(void); -#endif - -#endif /* _MUSB_OMAP3_H */ diff --git a/drivers/video/simple_panel.c b/drivers/video/simple_panel.c index b6c5b058b2e..0f23df701bc 100644 --- a/drivers/video/simple_panel.c +++ b/drivers/video/simple_panel.c @@ -191,6 +191,7 @@ static const struct mipi_dsi_panel_plat panasonic_vvx10f004b00 = { static const struct udevice_id simple_panel_ids[] = { { .compatible = "simple-panel" }, + { .compatible = "panel-lvds" }, { .compatible = "auo,b133xtn01" }, { .compatible = "auo,b116xw03" }, { .compatible = "auo,b133htn01" }, diff --git a/drivers/video/stm32/Kconfig b/drivers/video/stm32/Kconfig index c354c402c28..4cb8a841caf 100644 --- a/drivers/video/stm32/Kconfig +++ b/drivers/video/stm32/Kconfig @@ -23,6 +23,15 @@ config VIDEO_STM32_DSI This option enables support DSI internal bridge which can be used on devices which have DSI devices connected. +config VIDEO_STM32_LVDS + bool "Enable STM32 LVDS video support" + depends on VIDEO_STM32 + select VIDEO_BRIDGE + select VIDEO_DW_MIPI_DSI + help + This enables Low Voltage Differential Signaling (LVDS) display + support. + config VIDEO_STM32_MAX_XRES int "Maximum horizontal resolution (for memory allocation purposes)" depends on VIDEO_STM32 diff --git a/drivers/video/stm32/Makefile b/drivers/video/stm32/Makefile index f8b42d1a4d1..059d9000c1d 100644 --- a/drivers/video/stm32/Makefile +++ b/drivers/video/stm32/Makefile @@ -7,3 +7,4 @@ obj-${CONFIG_VIDEO_STM32} = stm32_ltdc.o obj-${CONFIG_VIDEO_STM32_DSI} += stm32_dsi.o +obj-${CONFIG_VIDEO_STM32_LVDS} += stm32_lvds.o diff --git a/drivers/video/stm32/stm32_ltdc.c b/drivers/video/stm32/stm32_ltdc.c index 0a062c8939d..834bfb625d2 100644 --- a/drivers/video/stm32/stm32_ltdc.c +++ b/drivers/video/stm32/stm32_ltdc.c @@ -17,6 +17,7 @@ #include <video_bridge.h> #include <asm/io.h> #include <dm/device-internal.h> +#include <dm/uclass-internal.h> #include <dm/device_compat.h> #include <linux/bitops.h> #include <linux/printk.h> @@ -262,6 +263,7 @@ static const u32 layer_regs_a2[] = { #define HWVER_10300 0x010300 #define HWVER_20101 0x020101 #define HWVER_40100 0x040100 +#define HWVER_40101 0x040101 enum stm32_ltdc_pix_fmt { PF_ARGB8888 = 0, /* ARGB [32 bits] */ @@ -494,6 +496,101 @@ static void stm32_ltdc_set_layer1(struct stm32_ltdc_priv *priv, ulong fb_addr) setbits_le32(priv->regs + LTDC_L1CR, LXCR_LEN); } +static int stm32_ltdc_get_remote_device(struct udevice *dev, ofnode ep_node, + enum uclass_id id, struct udevice **remote_dev) +{ + u32 remote_phandle; + ofnode remote; + int ret = 0; + + ret = ofnode_read_u32(ep_node, "remote-endpoint", &remote_phandle); + if (ret) { + dev_err(dev, "%s(%s): Could not find remote-endpoint property\n", + __func__, dev_read_name(dev)); + return ret; + } + + remote = ofnode_get_by_phandle(remote_phandle); + if (!ofnode_valid(remote)) + return -EINVAL; + + while (ofnode_valid(remote)) { + remote = ofnode_get_parent(remote); + if (!ofnode_valid(remote)) { + dev_dbg(dev, "%s(%s): no uclass_id %d for remote-endpoint\n", + __func__, dev_read_name(dev), id); + continue; + } + + ret = uclass_find_device_by_ofnode(id, remote, remote_dev); + if (*remote_dev && !ret) { + ret = uclass_get_device_by_ofnode(id, remote, remote_dev); + if (ret) + dev_dbg(dev, "%s(%s): failed to get remote device %s\n", + __func__, dev_read_name(dev), dev_read_name(*remote_dev)); + break; + } + }; + + return ret; +} + +static int stm32_ltdc_get_panel(struct udevice *dev, struct udevice **panel) +{ + ofnode ep_node, node, ports; + int ret = 0; + + if (!dev) + return -EINVAL; + + ports = ofnode_find_subnode(dev_ofnode(dev), "ports"); + if (!ofnode_valid(ports)) { + dev_err(dev, "Remote bridge subnode\n"); + return ret; + } + + for (node = ofnode_first_subnode(ports); + ofnode_valid(node); + node = dev_read_next_subnode(node)) { + ep_node = ofnode_first_subnode(node); + if (!ofnode_valid(ep_node)) + continue; + + ret = stm32_ltdc_get_remote_device(dev, ep_node, UCLASS_PANEL, panel); + } + + /* Sanity check, we can get out of the loop without having a clean ofnode */ + if (!(*panel)) + ret = -EINVAL; + else + if (!ofnode_valid(dev_ofnode(*panel))) + ret = -EINVAL; + + return ret; +} + +static int stm32_ltdc_display_init(struct udevice *dev, ofnode *ep_node, + struct udevice **panel, struct udevice **bridge) +{ + int ret; + + if (*panel) + return -EINVAL; + + if (IS_ENABLED(CONFIG_VIDEO_BRIDGE)) { + ret = stm32_ltdc_get_remote_device(dev, *ep_node, UCLASS_VIDEO_BRIDGE, bridge); + if (ret) + return ret; + + ret = stm32_ltdc_get_panel(*bridge, panel); + } else { + /* no bridge, search a panel from display controller node */ + ret = stm32_ltdc_get_remote_device(dev, *ep_node, UCLASS_PANEL, panel); + } + + return ret; +} + #if IS_ENABLED(CONFIG_TARGET_STM32F469_DISCOVERY) static int stm32_ltdc_alloc_fb(struct udevice *dev) { @@ -529,8 +626,9 @@ static int stm32_ltdc_probe(struct udevice *dev) struct udevice *bridge = NULL; struct udevice *panel = NULL; struct display_timing timings; - struct clk pclk; + struct clk pclk, bclk; struct reset_ctl rst; + ofnode node, port; ulong rate; int ret; @@ -540,7 +638,21 @@ static int stm32_ltdc_probe(struct udevice *dev) return -EINVAL; } - ret = clk_get_by_index(dev, 0, &pclk); + ret = clk_get_by_name(dev, "bus", &bclk); + if (ret) { + if (ret != -ENODATA) { + dev_err(dev, "bus clock get error %d\n", ret); + return ret; + } + } else { + ret = clk_enable(&bclk); + if (ret) { + dev_err(dev, "bus clock enable error %d\n", ret); + return ret; + } + } + + ret = clk_get_by_name(dev, "lcd", &pclk); if (ret) { dev_err(dev, "peripheral clock get error %d\n", ret); return ret; @@ -553,7 +665,7 @@ static int stm32_ltdc_probe(struct udevice *dev) } priv->hw_version = readl(priv->regs + LTDC_IDR); - debug("%s: LTDC hardware 0x%x\n", __func__, priv->hw_version); + dev_dbg(dev, "%s: LTDC hardware 0x%x\n", __func__, priv->hw_version); switch (priv->hw_version) { case HWVER_10200: @@ -566,6 +678,7 @@ static int stm32_ltdc_probe(struct udevice *dev) priv->pix_fmt_hw = pix_fmt_a1; break; case HWVER_40100: + case HWVER_40101: priv->layer_regs = layer_regs_a2; priv->pix_fmt_hw = pix_fmt_a2; break; @@ -573,13 +686,35 @@ static int stm32_ltdc_probe(struct udevice *dev) return -ENODEV; } - ret = uclass_first_device_err(UCLASS_PANEL, &panel); - if (ret) { - if (ret != -ENODEV) - dev_err(dev, "panel device error %d\n", ret); - return ret; + /* + * Try all the ports until one working. + * + * This is done in two times. First is checks for the + * UCLASS_VIDEO_BRIDGE available, and then for this bridge + * it scans for a UCLASS_PANEL. + */ + + port = dev_read_subnode(dev, "port"); + if (!ofnode_valid(port)) { + dev_err(dev, "%s(%s): 'port' subnode not found\n", + __func__, dev_read_name(dev)); + return -EINVAL; } + for (node = ofnode_first_subnode(port); + ofnode_valid(node); + node = dev_read_next_subnode(node)) { + ret = stm32_ltdc_display_init(dev, &node, &panel, &bridge); + if (ret) + dev_dbg(dev, "Device failed ret=%d\n", ret); + else + break; + } + + /* Sanity check */ + if (ret) + return ret; + ret = panel_get_display_timing(panel, &timings); if (ret) { ret = ofnode_decode_display_timing(dev_ofnode(panel), @@ -608,11 +743,6 @@ static int stm32_ltdc_probe(struct udevice *dev) reset_deassert(&rst); if (IS_ENABLED(CONFIG_VIDEO_BRIDGE)) { - ret = uclass_get_device(UCLASS_VIDEO_BRIDGE, 0, &bridge); - if (ret) - dev_dbg(dev, - "No video bridge, or no backlight on bridge\n"); - if (bridge) { ret = video_bridge_attach(bridge); if (ret) { @@ -688,6 +818,8 @@ static int stm32_ltdc_bind(struct udevice *dev) static const struct udevice_id stm32_ltdc_ids[] = { { .compatible = "st,stm32-ltdc" }, + { .compatible = "st,stm32mp251-ltdc" }, + { .compatible = "st,stm32mp255-ltdc" }, { } }; diff --git a/drivers/video/stm32/stm32_lvds.c b/drivers/video/stm32/stm32_lvds.c new file mode 100644 index 00000000000..bf1393c9e87 --- /dev/null +++ b/drivers/video/stm32/stm32_lvds.c @@ -0,0 +1,693 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR BSD-3-Clause +/* + * Copyright (C) 2025 STMicroelectronics - All Rights Reserved + * Author(s): Raphaël Gallais-Pou <[email protected]> for STMicroelectronics. + * + * This Low Voltage Differential Signal controller driver is based on the Linux Kernel driver from + * drivers/gpu/drm/stm/ltdc.c + */ + +#define LOG_CATEGORY UCLASS_VIDEO_BRIDGE + +#include <clk.h> +#include <dm.h> +#include <log.h> +#include <media_bus_format.h> +#include <panel.h> +#include <reset.h> +#include <video.h> +#include <video_bridge.h> +#include <asm/io.h> +#include <dm/device_compat.h> +#include <dm/ofnode.h> +#include <linux/iopoll.h> + +/* LVDS Host registers */ +#define LVDS_CR 0x0000 /* configuration register */ +#define LVDS_DMLCR0 0x0004 /* data mapping lsb configuration register 0 */ +#define LVDS_DMMCR0 0x0008 /* data mapping msb configuration register 0 */ +#define LVDS_DMLCR1 0x000C /* data mapping lsb configuration register 1 */ +#define LVDS_DMMCR1 0x0010 /* data mapping msb configuration register 1 */ +#define LVDS_DMLCR2 0x0014 /* data mapping lsb configuration register 2 */ +#define LVDS_DMMCR2 0x0018 /* data mapping msb configuration register 2 */ +#define LVDS_DMLCR3 0x001C /* data mapping lsb configuration register 3 */ +#define LVDS_DMMCR3 0x0020 /* data mapping msb configuration register 3 */ +#define LVDS_DMLCR4 0x0024 /* data mapping lsb configuration register 4 */ +#define LVDS_DMMCR4 0x0028 /* data mapping msb configuration register 4 */ +#define LVDS_DMLCR(id) (LVDS_DMLCR0 + 8U * (id)) +#define LVDS_DMMCR(id) (LVDS_DMMCR0 + 8U * (id)) +#define LVDS_CDL1CR 0x002C /* channel distrib link 1 configuration register */ +#define LVDS_CDL2CR 0x0030 /* channel distrib link 2 configuration register */ + +#define CDL1CR_DEFAULT 0x4321 +#define CDL2CR_DEFAULT 0x59876 + +/* LVDS Host registers */ +#define LVDS_PHY_MASTER 0x0 +#define LVDS_PHY_SLAVE 0x100 + +/* phy parameter can only be one of those two above */ +#define LVDS_PXGCR(phy) ((phy) + 0x1000) /* Global Control Register */ +#define LVDS_PXCMCR1(phy) ((phy) + 0x100C) /* Current Mode Control Register 1 */ +#define LVDS_PXCMCR2(phy) ((phy) + 0x1010) /* Current Mode Control Register 2 */ +#define LVDS_PXSCR(phy) ((phy) + 0x1020) /* Serial Control Register */ +#define LVDS_PXBCR1(phy) ((phy) + 0x102C) /* Bias Control Register 1 */ +#define LVDS_PXBCR2(phy) ((phy) + 0x1030) /* Bias Control Register 2 */ +#define LVDS_PXBCR3(phy) ((phy) + 0x1034) /* Bias Control Register 3 */ +#define LVDS_PXMPLCR(phy) ((phy) + 0x1064) /* Monitor PLL Lock Control Register */ +#define LVDS_PXDCR(phy) ((phy) + 0x1084) /* Debug Control Register */ +#define LVDS_PXSSR1(phy) ((phy) + 0x1088) /* Spare Status Register 1 */ +#define LVDS_PXCFGCR(phy) ((phy) + 0x10A0) /* Configuration Control Register */ +#define LVDS_PXPLLCR1(phy) ((phy) + 0x10C0) /* PLL_MODE 1 Control Register */ +#define LVDS_PXPLLCR2(phy) ((phy) + 0x10C4) /* PLL_MODE 2 Control Register */ +#define LVDS_PXPLLSR(phy) ((phy) + 0x10C8) /* PLL Status Register */ +#define LVDS_PXPLLSDCR1(phy) ((phy) + 0x10CC) /* PLL_SD_1 Control Register */ +#define LVDS_PXPLLSDCR2(phy) ((phy) + 0x10D0) /* PLL_SD_2 Control Register */ +#define LVDS_PXPLLTWGCR1(phy) ((phy) + 0x10D4) /* PLL_TWG_1 Control Register */ +#define LVDS_PXPLLTWGCR2(phy) ((phy) + 0x10D8) /* PLL_TWG_2 Control Register */ +#define LVDS_PXPLLCPCR(phy) ((phy) + 0x10E0) /* PLL_CP Control Register */ +#define LVDS_PXPLLTESTCR(phy) ((phy) + 0x10E8) /* PLL_TEST Control Register */ + +/* LVDS Wrapper registers */ +#define LVDS_WCLKCR 0x11B0 /* Wrapper clock control register */ +#define LVDS_HWCFGR 0x1FF0 /* HW configuration register */ +#define LVDS_VERR 0x1FF4 /* Version register */ +#define LVDS_IPIDR 0x1FF8 /* Identification register */ +#define LVDS_SIDR 0x1FFC /* Size Identification register */ + +#define CR_LVDSEN BIT(0) /* LVDS PHY Enable */ +#define CR_HSPOL BIT(1) /* HS Polarity (horizontal sync) */ +#define CR_VSPOL BIT(2) /* VS Polarity (vertical sync) */ +#define CR_DEPOL BIT(3) /* DE Polarity (data enable) */ +#define CR_CI BIT(4) /* Control Internal (software controlled bit) */ +#define CR_LKMOD BIT(5) /* Link Mode, for both Links */ +#define CR_LKPHA BIT(6) /* Link Phase, for both Links */ +#define CR_LK1POL GENMASK(20, 16) /* Link-1 output Polarity */ +#define CR_LK2POL GENMASK(25, 21) /* Link-2 output Polarity */ + +#define DMMCRX_MAP0 GENMASK(4, 0) +#define DMMCRX_MAP1 GENMASK(9, 5) +#define DMMCRX_MAP2 GENMASK(14, 10) +#define DMMCRX_MAP3 GENMASK(19, 15) +#define DMLCRX_MAP4 GENMASK(4, 0) +#define DMLCRX_MAP5 GENMASK(9, 5) +#define DMLCRX_MAP6 GENMASK(14, 10) + +#define CDLCRX_DISTR0 GENMASK(3, 0) +#define CDLCRX_DISTR1 GENMASK(7, 4) +#define CDLCRX_DISTR2 GENMASK(11, 8) +#define CDLCRX_DISTR3 GENMASK(15, 12) +#define CDLCRX_DISTR4 GENMASK(19, 16) + +#define FREF_INDEX 0 +#define NDIV_INDEX 1 +#define FPFD_INDEX 2 +#define MDIV_INDEX 3 +#define FVCO_INDEX 4 +#define BDIV_INDEX 5 +#define FBIT_INDEX 6 +#define FLS_INDEX 7 +#define FDP_INDEX 8 + +#define PXGCR_BIT_CLK_OUT BIT(0) +#define PXGCR_LS_CLK_OUT BIT(4) +#define PXGCR_DP_CLK_OUT BIT(8) +#define PXGCR_RSTZ BIT(24) +#define PXGCR_DIV_RSTN BIT(25) + +#define PXCMCR1_CM_EN_DL (BIT(28) | BIT(20) | BIT(12) | BIT(4)) +#define PXCMCR2_CM_EN_DL4 BIT(4) +#define PXSCR_SER_DATA_OK BIT(16) +#define PXBCR1_EN_BIAS_DL (BIT(16) | BIT(12) | BIT(8) | BIT(4) | BIT(0)) +#define PXBCR2_BIAS_EN BIT(28) +#define PXBCR3_VM_EN_DL (BIT(16) | BIT(12) | BIT(8) | BIT(4) | BIT(0)) +#define PXDCR_POWER_OK BIT(12) +#define PXCFGCR_EN_DIG_DL GENMASK(4, 0) + +#define PXPLLCR1_PLL_EN BIT(0) +#define PxPLLCR1_SD_EN BIT(1) +#define PXPLLCR1_TWG_EN BIT(2) +#define PXPLLCR1_PLL_DIVIDERS_EN BIT(8) +#define PXPLLCR2_NDIV GENMASK(25, 16) +#define PXPLLCR2_BDIV GENMASK(9, 0) +#define PXPLLSR_PLL_LOCK BIT(0) +#define PXPLLSDCR1_MDIV GENMASK(9, 0) +#define PXPLLCPCR_CPCTRL_DEFAULT 0x1 +#define PXPLLTESTCR_PLL_TEST_CLK_EN BIT(0) +#define PXPLLTESTCR_PLL_TDIV_EN BIT(8) +#define PXPLLTESTCR_TDIV GENMASK(25, 16) +#define PXPLLTESTCR_TDIV_VALUE 70 + +#define WCLKCR_SLV_CLKPIX_SEL BIT(0) +#define WCLKCR_SRCSEL BIT(8) + +/* Sleep & timeout for pll lock/unlock */ +#define SLEEP_US 1000 +#define TIMEOUT_US 20000000 + +#define PHY_SLV_OFS 0x100 + +/* PLL parameters */ +#define NDIV_MIN 2 +#define NDIV_MAX 6 +#define BDIV_MIN 2 +#define BDIV_MAX 6 +#define MDIV_MIN 1 +#define MDIV_MAX 1023 + +struct stm32_lvds_plat { + void __iomem *base; + struct udevice *panel; + struct reset_ctl rst; + struct clk pclk; + struct clk refclk; +}; + +struct stm32_lvds_priv { + struct display_timing timings; + u32 refclk_rate; + int dual_link; + int bus_format; +}; + +/* + * enum lvds_pixels_order - Pixel order of an LVDS connection + * @LVDS_DUAL_LINK_EVEN_ODD_PIXELS: Even pixels are expected to be generated + * from the first port, odd pixels from the second port + * @LVDS_DUAL_LINK_ODD_EVEN_PIXELS: Odd pixels are expected to be generated + * from the first port, even pixels from the second port + */ +enum lvds_pixels_order { + LVDS_DUAL_LINK_EVEN_ODD_PIXELS = BIT(0), + LVDS_DUAL_LINK_ODD_EVEN_PIXELS = BIT(1), +}; + +enum lvds_pixel { + PIX_R_0 = 0x00, + PIX_R_1 = 0x01, + PIX_R_2 = 0x02, + PIX_R_3 = 0x03, + PIX_R_4 = 0x04, + PIX_R_5 = 0x05, + PIX_R_6 = 0x06, + PIX_R_7 = 0x07, + PIX_G_0 = 0x08, + PIX_G_1 = 0x09, + PIX_G_2 = 0x0A, + PIX_G_3 = 0x0B, + PIX_G_4 = 0x0C, + PIX_G_5 = 0x0D, + PIX_G_6 = 0x0E, + PIX_G_7 = 0x0F, + PIX_B_0 = 0x10, + PIX_B_1 = 0x11, + PIX_B_2 = 0x12, + PIX_B_3 = 0x13, + PIX_B_4 = 0x14, + PIX_B_5 = 0x15, + PIX_B_6 = 0x16, + PIX_B_7 = 0x17, + PIX_H_S = 0x18, + PIX_V_S = 0x19, + PIX_D_E = 0x1A, + PIX_C_E = 0x1B, + PIX_C_I = 0x1C, + PIX_TOG = 0x1D, + PIX_ONE = 0x1E, + PIX_ZER = 0x1F, +}; + +/* + * Expected JEIDA-RGB888 data to be sent in LSB format + * bit6 ............................bit0 + */ +const enum lvds_pixel lvds_bitmap_jeida_rgb888[5][7] = { + { PIX_ONE, PIX_ONE, PIX_ZER, PIX_ZER, PIX_ZER, PIX_ONE, PIX_ONE }, + { PIX_G_2, PIX_R_7, PIX_R_6, PIX_R_5, PIX_R_4, PIX_R_3, PIX_R_2 }, + { PIX_B_3, PIX_B_2, PIX_G_7, PIX_G_6, PIX_G_5, PIX_G_4, PIX_G_3 }, + { PIX_D_E, PIX_V_S, PIX_H_S, PIX_B_7, PIX_B_6, PIX_B_5, PIX_B_4 }, + { PIX_C_E, PIX_B_1, PIX_B_0, PIX_G_1, PIX_G_0, PIX_R_1, PIX_R_0 } +}; + +/* + * Expected VESA-RGB888 data to be sent in LSB format + * bit6 ............................bit0 + */ +const enum lvds_pixel lvds_bitmap_vesa_rgb888[5][7] = { + { PIX_ONE, PIX_ONE, PIX_ZER, PIX_ZER, PIX_ZER, PIX_ONE, PIX_ONE }, + { PIX_G_0, PIX_R_5, PIX_R_4, PIX_R_3, PIX_R_2, PIX_R_1, PIX_R_0 }, + { PIX_B_1, PIX_B_0, PIX_G_5, PIX_G_4, PIX_G_3, PIX_G_2, PIX_G_1 }, + { PIX_D_E, PIX_V_S, PIX_H_S, PIX_B_5, PIX_B_4, PIX_B_3, PIX_B_2 }, + { PIX_C_E, PIX_B_7, PIX_B_6, PIX_G_7, PIX_G_6, PIX_R_7, PIX_R_6 } +}; + +static inline void lvds_writel(void __iomem *base, u32 reg, u32 val) +{ + writel(val, base + reg); +} + +static inline u32 lvds_readl(void __iomem *base, u32 reg) +{ + return readl(base + reg); +} + +static inline void lvds_set(void __iomem *base, u32 reg, u32 mask) +{ + lvds_writel(base, reg, lvds_readl(base, reg) | mask); +} + +static inline void lvds_clear(void __iomem *base, u32 reg, u32 mask) +{ + lvds_writel(base, reg, lvds_readl(base, reg) & ~mask); +} + +static u32 pll_get_clkout_khz(u32 clkin_khz, u32 bdiv, u32 mdiv, u32 ndiv) +{ + int divisor = ndiv * bdiv; + + /* Prevents from division by 0 */ + if (!divisor) + return 0; + + return clkin_khz * mdiv / divisor; +} + +static int lvds_pll_get_params(u32 clkin_khz, u32 clkout_khz, + u32 *bdiv, u32 *mdiv, u32 *ndiv) +{ + u32 i, o, n; + u32 delta, best_delta; /* all in khz */ + + /* Early checks preventing division by 0 & odd results */ + if (clkin_khz == 0 || clkout_khz == 0) + return -EINVAL; + + best_delta = 1000000; /* big started value (1000000khz) */ + + for (i = NDIV_MIN; i <= NDIV_MAX; i++) { + for (o = BDIV_MIN; o <= BDIV_MAX; o++) { + n = DIV_ROUND_CLOSEST(i * o * clkout_khz, clkin_khz); + /* Check ndiv according to vco range */ + if (n < MDIV_MIN || n > MDIV_MAX) + continue; + /* Check if new delta is better & saves parameters */ + delta = abs(pll_get_clkout_khz(clkin_khz, i, n, o) - clkout_khz); + if (delta < best_delta) { + *ndiv = i; + *mdiv = n; + *bdiv = o; + best_delta = delta; + } + /* fast return in case of "perfect result" */ + if (!delta) + return 0; + } + } + + return 0; +} + +static int stm32_lvds_pll_enable(struct udevice *dev, + int phy) +{ + struct stm32_lvds_plat *plat = dev_get_plat(dev); + struct stm32_lvds_priv *priv = dev_get_priv(dev); + struct display_timing timings = priv->timings; + u32 pll_in_khz, bdiv = 0, mdiv = 0, ndiv = 0; + int ret, val, multiplier; + + /* Release PHY from reset */ + lvds_set(plat->base, LVDS_PXGCR(phy), PXGCR_DIV_RSTN | PXGCR_RSTZ); + + /* lvds_pll_config */ + /* Set PLL Slv & Mst configs and timings */ + pll_in_khz = priv->refclk_rate / 1000; + + if (priv->dual_link) + multiplier = 2; + else + multiplier = 1; + + ret = lvds_pll_get_params(pll_in_khz, timings.pixelclock.typ * 7 / 1000 / multiplier, + &bdiv, &mdiv, &ndiv); + if (ret) + return ret; + + /* Set PLL parameters */ + lvds_writel(plat->base, LVDS_PXPLLCR2(phy), (ndiv << 16) | bdiv); + lvds_writel(plat->base, LVDS_PXPLLSDCR1(phy), mdiv); + lvds_writel(plat->base, LVDS_PXPLLTESTCR(phy), PXPLLTESTCR_TDIV_VALUE << 16); + + /* Disable TWG and SD: for now, PLL just need to be in integer mode */ + lvds_clear(plat->base, LVDS_PXPLLCR1(phy), PXPLLCR1_TWG_EN | PxPLLCR1_SD_EN); + + /* Power up bias and PLL dividers */ + lvds_set(plat->base, LVDS_PXDCR(phy), PXDCR_POWER_OK); + + lvds_set(plat->base, LVDS_PXCMCR1(phy), PXCMCR1_CM_EN_DL); + lvds_set(plat->base, LVDS_PXCMCR2(phy), PXCMCR2_CM_EN_DL4); + + lvds_set(plat->base, LVDS_PXPLLCPCR(phy), PXPLLCPCR_CPCTRL_DEFAULT); + lvds_set(plat->base, LVDS_PXBCR3(phy), PXBCR3_VM_EN_DL); + lvds_set(plat->base, LVDS_PXBCR1(phy), PXBCR1_EN_BIAS_DL); + lvds_set(plat->base, LVDS_PXCFGCR(phy), PXCFGCR_EN_DIG_DL); + + /* lvds_pll_enable */ + /* PLL lock timing control for the monitor unmask after startup (pll_en) */ + /* Adjust the value so that the masking window is opened at start-up */ + /* MST_MON_PLL_LOCK_UNMASK_TUNE */ + lvds_writel(plat->base, LVDS_PXMPLCR(phy), (0x200 - 0x160) << 16); + + lvds_writel(plat->base, LVDS_PXBCR2(phy), PXBCR2_BIAS_EN); + + lvds_set(plat->base, LVDS_PXGCR(phy), + PXGCR_DP_CLK_OUT | PXGCR_LS_CLK_OUT | PXGCR_BIT_CLK_OUT); + + lvds_set(plat->base, LVDS_PXPLLTESTCR(phy), PXPLLTESTCR_PLL_TDIV_EN); + lvds_set(plat->base, LVDS_PXPLLCR1(phy), PXPLLCR1_PLL_DIVIDERS_EN); + lvds_set(plat->base, LVDS_PXSCR(phy), PXSCR_SER_DATA_OK); + + /* Enable the LVDS PLL & wait for its lock */ + lvds_set(plat->base, LVDS_PXPLLCR1(phy), PXPLLCR1_PLL_EN); + ret = readl_poll_sleep_timeout(plat->base + LVDS_PXPLLSR(phy), + val, val & PXPLLSR_PLL_LOCK, SLEEP_US, TIMEOUT_US); + if (ret) + return ret; + + /* Select MST PHY clock as pixel clock for the LDITX instead of FREF */ + /* WCLKCR_SLV_CLKPIX_SEL is for dual link */ + lvds_writel(plat->base, LVDS_WCLKCR, WCLKCR_SLV_CLKPIX_SEL); + + lvds_set(plat->base, LVDS_PXPLLTESTCR(phy), PXPLLTESTCR_PLL_TEST_CLK_EN); + + return 0; +} + +static int stm32_lvds_enable(struct udevice *dev) +{ + struct stm32_lvds_plat *plat = dev_get_plat(dev); + struct stm32_lvds_priv *priv = dev_get_priv(dev); + struct display_timing timings = priv->timings; + u32 lvds_cdl1cr = 0; + u32 lvds_cdl2cr = 0; + u32 lvds_dmlcr = 0; + u32 lvds_dmmcr = 0; + u32 lvds_cr = 0; + int i; + + lvds_clear(plat->base, LVDS_CDL1CR, CDLCRX_DISTR0 | CDLCRX_DISTR1 | CDLCRX_DISTR2 + | CDLCRX_DISTR3 | CDLCRX_DISTR4); + lvds_clear(plat->base, LVDS_CDL2CR, CDLCRX_DISTR0 | CDLCRX_DISTR1 | CDLCRX_DISTR2 + | CDLCRX_DISTR3 | CDLCRX_DISTR4); + + /* Set channel distribution */ + lvds_cr &= ~CR_LKMOD; + lvds_cdl1cr = CDL1CR_DEFAULT; + + if (priv->dual_link) { + lvds_cr |= CR_LKMOD; + lvds_cdl2cr = CDL2CR_DEFAULT; + } + + /* Set signal polarity */ + if (timings.flags & DISPLAY_FLAGS_DE_LOW) + lvds_cr |= CR_DEPOL; + + if (timings.flags & DISPLAY_FLAGS_HSYNC_LOW) + lvds_cr |= CR_HSPOL; + + if (timings.flags & DISPLAY_FLAGS_VSYNC_LOW) + lvds_cr |= CR_VSPOL; + + /* Set link phase */ + switch (priv->dual_link) { + case LVDS_DUAL_LINK_EVEN_ODD_PIXELS: /* LKPHA = 0 */ + lvds_cr &= ~CR_LKPHA; + break; + case LVDS_DUAL_LINK_ODD_EVEN_PIXELS: /* LKPHA = 1 */ + lvds_cr |= CR_LKPHA; + break; + default: + dev_dbg(dev, "No phase precised, setting default\n"); + lvds_cr &= ~CR_LKPHA; + break; + } + + /* Set Data Mapping */ + switch (priv->bus_format) { + case MEDIA_BUS_FMT_RGB888_1X7X4_SPWG: /* VESA-RGB888 */ + for (i = 0; i < 5; i++) { + lvds_dmlcr = ((lvds_bitmap_vesa_rgb888[i][0]) + + (lvds_bitmap_vesa_rgb888[i][1] << 5) + + (lvds_bitmap_vesa_rgb888[i][2] << 10) + + (lvds_bitmap_vesa_rgb888[i][3] << 15)); + lvds_dmmcr = ((lvds_bitmap_vesa_rgb888[i][4]) + + (lvds_bitmap_vesa_rgb888[i][5] << 5) + + (lvds_bitmap_vesa_rgb888[i][6] << 10)); + + /* Write registers at the end of computations */ + lvds_writel(plat->base, LVDS_DMLCR(i), lvds_dmlcr); + lvds_writel(plat->base, LVDS_DMMCR(i), lvds_dmmcr); + } + break; + case MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA: /* JEIDA-RGB888 */ + for (i = 0; i < 5; i++) { + lvds_dmlcr = ((lvds_bitmap_jeida_rgb888[i][0]) + + (lvds_bitmap_jeida_rgb888[i][1] << 5) + + (lvds_bitmap_jeida_rgb888[i][2] << 10) + + (lvds_bitmap_jeida_rgb888[i][3] << 15)); + lvds_dmmcr = ((lvds_bitmap_jeida_rgb888[i][4]) + + (lvds_bitmap_jeida_rgb888[i][5] << 5) + + (lvds_bitmap_jeida_rgb888[i][6] << 10)); + + /* Write registers at the end of computations */ + lvds_writel(plat->base, LVDS_DMLCR(i), lvds_dmlcr); + lvds_writel(plat->base, LVDS_DMMCR(i), lvds_dmmcr); + } + break; + default: + dev_dbg(dev, "Unsupported LVDS bus format 0x%04x\n", priv->bus_format); + } + + /* Turn the output on */ + lvds_cr |= CR_LVDSEN; + + /* Commit config to registers */ + lvds_set(plat->base, LVDS_CR, lvds_cr); + lvds_writel(plat->base, LVDS_CDL1CR, lvds_cdl1cr); + lvds_writel(plat->base, LVDS_CDL2CR, lvds_cdl2cr); + + return 0; +} + +static int stm32_lvds_attach(struct udevice *dev) +{ + struct stm32_lvds_plat *plat = dev_get_plat(dev); + struct stm32_lvds_priv *priv = dev_get_priv(dev); + int ret; + + ret = panel_get_display_timing(plat->panel, &priv->timings); + if (ret) { + ret = ofnode_decode_display_timing(dev_ofnode(plat->panel), + 0, &priv->timings); + if (ret) { + dev_err(dev, "decode display timing error %d\n", ret); + return ret; + } + } + + ret = stm32_lvds_enable(dev); + + return ret; +} + +static int stm32_lvds_set_backlight(struct udevice *dev, int percent) +{ + struct stm32_lvds_plat *plat = dev_get_plat(dev); + int ret; + + ret = panel_enable_backlight(plat->panel); + if (ret) { + dev_err(dev, "panel %s enable backlight error %d\n", + plat->panel->name, ret); + } + + return ret; +} + +static int lvds_handle_pixel_order(struct stm32_lvds_plat *plat) +{ + ofnode parent, panel_port0, panel_port1; + bool even_pixels, odd_pixels; + int port0, port1; + + /* + * In case we are operating in single link, + * there is only one port linked to the LVDS. + * Check whether we are in this case and exit if yes. + */ + parent = ofnode_find_subnode(dev_ofnode(plat->panel), "ports"); + if (!ofnode_valid(parent)) + return 0; + + panel_port0 = ofnode_first_subnode(parent); + if (!ofnode_valid(panel_port0)) + return -EPIPE; + + even_pixels = ofnode_read_bool(panel_port0, "dual-lvds-even-pixels"); + odd_pixels = ofnode_read_bool(panel_port0, "dual-lvds-odd-pixels"); + if (even_pixels && odd_pixels) + return -EINVAL; + + port0 = even_pixels ? LVDS_DUAL_LINK_EVEN_ODD_PIXELS : + LVDS_DUAL_LINK_ODD_EVEN_PIXELS; + + panel_port1 = ofnode_next_subnode(panel_port0); + if (!ofnode_valid(panel_port1)) + return -EPIPE; + + even_pixels = ofnode_read_bool(panel_port1, "dual-lvds-even-pixels"); + odd_pixels = ofnode_read_bool(panel_port1, "dual-lvds-odd-pixels"); + if (even_pixels && odd_pixels) + return -EINVAL; + + port1 = even_pixels ? LVDS_DUAL_LINK_EVEN_ODD_PIXELS : + LVDS_DUAL_LINK_ODD_EVEN_PIXELS; + + /* + * A valid dual-LVDS bus is found when one port is marked with + * "dual-lvds-even-pixels", and the other port is marked with + * "dual-lvds-odd-pixels", bail out if the markers are not right. + */ + if (port0 + port1 != LVDS_DUAL_LINK_EVEN_ODD_PIXELS + LVDS_DUAL_LINK_ODD_EVEN_PIXELS) + return -EINVAL; + + return port0; +} + +static int stm32_lvds_of_to_plat(struct udevice *dev) +{ + struct stm32_lvds_plat *plat = dev_get_plat(dev); + struct stm32_lvds_priv *priv = dev_get_priv(dev); + const char *data_mapping; + int ret; + + plat->base = dev_read_addr_ptr(dev); + if ((fdt_addr_t)plat->base == FDT_ADDR_T_NONE) { + dev_err(dev, "Unable to read LVDS base address\n"); + return -EINVAL; + } + + ret = clk_get_by_name(dev, "pclk", &plat->pclk); + if (ret) { + dev_err(dev, "Unable to get peripheral clock: %d\n", ret); + return ret; + } + + ret = clk_get_by_name(dev, "ref", &plat->refclk); + if (ret) { + dev_err(dev, "Unable to get reference clock: %d\n", ret); + return ret; + } + + ret = reset_get_by_index(dev, 0, &plat->rst); + if (ret) { + dev_err(dev, "Failed to get LVDS reset: %d\n", ret); + return ret; + } + + ret = uclass_get_device_by_driver(UCLASS_PANEL, + DM_DRIVER_GET(simple_panel), &plat->panel); + if (ret) { + dev_err(dev, "panel device error %d\n", ret); + return ret; + } + + ret = panel_get_display_timing(plat->panel, &priv->timings); + if (ret) { + ret = ofnode_decode_display_timing(dev_ofnode(plat->panel), + 0, &priv->timings); + if (ret) { + dev_err(dev, "decode display timing error %d\n", ret); + return ret; + } + } + + data_mapping = ofnode_read_string(dev_ofnode(plat->panel), "data-mapping"); + if (!strcmp(data_mapping, "vesa-24")) + priv->bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG; + else if (!strcmp(data_mapping, "jeida-24")) + priv->bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA; + else + priv->bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG; + + return 0; +} + +static int stm32_lvds_probe(struct udevice *dev) +{ + struct stm32_lvds_plat *plat = dev_get_plat(dev); + struct stm32_lvds_priv *priv = dev_get_priv(dev); + int ret; + + ret = clk_enable(&plat->pclk); + if (ret) { + dev_err(dev, "Failed to enable peripheral clock: %d\n", ret); + return ret; + } + + ret = clk_enable(&plat->refclk); + if (ret) { + dev_err(dev, "Failed to enable reference clock: %d\n", ret); + goto err_clk; + } + + priv->refclk_rate = (unsigned int)clk_get_rate(&plat->refclk); + + reset_deassert(&plat->rst); + + /* Handle dual link config */ + priv->dual_link = lvds_handle_pixel_order(plat); + if (priv->dual_link < 0) + goto err_rst; + + if (priv->dual_link > 0) { + ret = stm32_lvds_pll_enable(dev, LVDS_PHY_SLAVE); + if (ret) + goto err_rst; + } + + ret = stm32_lvds_pll_enable(dev, LVDS_PHY_MASTER); + if (ret) + goto err_rst; + + return 0; + +err_rst: + clk_disable(&plat->refclk); +err_clk: + clk_disable(&plat->pclk); + + return ret; +} + +static const struct video_bridge_ops stm32_lvds_ops = { + .attach = stm32_lvds_attach, + .set_backlight = stm32_lvds_set_backlight, +}; + +static const struct udevice_id stm32_lvds_ids[] = { + {.compatible = "st,stm32mp25-lvds"}, + {} +}; + +U_BOOT_DRIVER(stm32_lvds) = { + .name = "stm32-display-lvds", + .id = UCLASS_VIDEO_BRIDGE, + .of_match = stm32_lvds_ids, + .ops = &stm32_lvds_ops, + .of_to_plat = stm32_lvds_of_to_plat, + .probe = stm32_lvds_probe, + .plat_auto = sizeof(struct stm32_lvds_plat), + .priv_auto = sizeof(struct stm32_lvds_priv), +}; diff --git a/include/dm/root.h b/include/dm/root.h index 286bd9a2ddd..61a61e1ce46 100644 --- a/include/dm/root.h +++ b/include/dm/root.h @@ -114,7 +114,7 @@ int dm_extended_scan(bool pre_reloc_only); * * Some devices may not be visible to Driver Model. This weak function can * be provided by boards which wish to create their own devices - * programmaticaly. They should do this by calling device_bind() on each + * programmatically. They should do this by calling device_bind() on each * device. * * @pre_reloc_only: If true, bind only nodes with special devicetree properties, diff --git a/include/linux/mtd/spinand.h b/include/linux/mtd/spinand.h index cf9b9656d05..e9561c0a395 100644 --- a/include/linux/mtd/spinand.h +++ b/include/linux/mtd/spinand.h @@ -361,6 +361,7 @@ struct spinand_manufacturer { extern const struct spinand_manufacturer alliancememory_spinand_manufacturer; extern const struct spinand_manufacturer ato_spinand_manufacturer; extern const struct spinand_manufacturer esmt_c8_spinand_manufacturer; +extern const struct spinand_manufacturer fmsh_spinand_manufacturer; extern const struct spinand_manufacturer foresee_spinand_manufacturer; extern const struct spinand_manufacturer gigadevice_spinand_manufacturer; extern const struct spinand_manufacturer macronix_spinand_manufacturer; diff --git a/include/scmi_protocols.h b/include/scmi_protocols.h index bb74a57f79a..ecab021b472 100644 --- a/include/scmi_protocols.h +++ b/include/scmi_protocols.h @@ -399,7 +399,7 @@ int scmi_generic_protocol_version(struct udevice *dev, int scmi_base_protocol_version(struct udevice *dev, u32 *version); /** - * scmi_protocol_attrs - get protocol attributes + * scmi_base_protocol_attrs - get protocol attributes * @dev: SCMI protocol device * @num_agents: Number of SCMI agents * @num_protocols: Number of SCMI protocols @@ -414,7 +414,7 @@ int scmi_base_protocol_attrs(struct udevice *dev, u32 *num_agents, u32 *num_protocols); /** - * scmi_protocol_message_attrs - get message-specific attributes + * scmi_base_protocol_message_attrs - get message-specific attributes * @dev: SCMI protocol device * @message_id: SCMI message ID * @attributes: Message-specific attributes @@ -733,6 +733,7 @@ int scmi_pwd_name_get(struct udevice *dev, u32 domain_id, u8 **name); /* * SCMI Clock Protocol */ +#define CLOCK_PROTOCOL_VERSION_2_1 0x20001 #define CLOCK_PROTOCOL_VERSION_3_0 0x30000 enum scmi_clock_message_id { @@ -754,7 +755,7 @@ enum scmi_clock_message_id { #define SCMI_CLOCK_NAME_LENGTH_MAX 16 /** - * struct scmi_clk_get_nb_out - Response for SCMI_PROTOCOL_ATTRIBUTES command + * struct scmi_clk_protocol_attr_out - Response for SCMI_PROTOCOL_ATTRIBUTES command * @status: SCMI command status * @attributes: Attributes of the clock protocol, mainly number of clocks exposed */ @@ -772,7 +773,7 @@ struct scmi_clk_attribute_in { }; /** - * struct scmi_clk_get_nb_out - Response payload for SCMI_CLOCK_ATTRIBUTES command + * struct scmi_clk_attribute_out - Response payload for SCMI_CLOCK_ATTRIBUTES command * @status: SCMI command status * @attributes: clock attributes * @clock_name: name of the clock @@ -785,7 +786,7 @@ struct scmi_clk_attribute_out { }; /** - * struct scmi_clk_get_nb_out_v2 - Response payload for SCMI_CLOCK_ATTRIBUTES command + * struct scmi_clk_attribute_out_v2 - Response payload for SCMI_CLOCK_ATTRIBUTES command * Clock management Protocol 2.0 * @status: SCMI command status * @attributes: clock attributes @@ -800,16 +801,28 @@ struct scmi_clk_attribute_out_v2 { }; /** - * struct scmi_clk_state_in - Message payload for CLOCK_CONFIG_SET command + * struct scmi_clk_state_in_v1 - Message payload for CLOCK_CONFIG_SET command for protocol < 2.1 * @clock_id: SCMI clock ID * @attributes: Attributes of the targets clock state */ -struct scmi_clk_state_in { +struct scmi_clk_state_in_v1 { u32 clock_id; u32 attributes; }; /** + * struct scmi_clk_state_in_v2 - Message payload for CLOCK_CONFIG_SET command for protocol >= 2.1 + * @clock_id: SCMI clock ID + * @attributes: Attributes of the targets clock state + * @extended_config_val: Extended and OEM specific configuration + */ +struct scmi_clk_state_in_v2 { + u32 clock_id; + u32 attributes; + u32 extended_config_val; +}; + +/** * struct scmi_clk_state_out - Response payload for CLOCK_CONFIG_SET command * @status: SCMI command status */ @@ -818,7 +831,7 @@ struct scmi_clk_state_out { }; /** - * struct scmi_clk_state_in - Message payload for CLOCK_RATE_GET command + * struct scmi_clk_rate_get_in - Message payload for CLOCK_RATE_GET command * @clock_id: SCMI clock ID * @attributes: Attributes of the targets clock state */ @@ -839,7 +852,7 @@ struct scmi_clk_rate_get_out { }; /** - * struct scmi_clk_state_in - Message payload for CLOCK_RATE_SET command + * struct scmi_clk_rate_set_in - Message payload for CLOCK_RATE_SET command * @flags: Flags for the clock rate set request * @clock_id: SCMI clock ID * @rate_lsb: 32bit LSB of the clock rate in Hertz @@ -861,7 +874,7 @@ struct scmi_clk_rate_set_out { }; /** - * struct scmi_clk_parent_state_in - Message payload for CLOCK_PARENT_SET command + * struct scmi_clk_parent_set_in - Message payload for CLOCK_PARENT_SET command * @clock_id: SCMI clock ID * @parent_clk: SCMI clock ID */ @@ -879,6 +892,7 @@ struct scmi_clk_parent_set_out { }; /** + * struct scmi_clk_get_permissions_in - Message payload for CLOCK_GET_PERMISSIONS command * @clock_id: Identifier for the clock device. */ struct scmi_clk_get_permissions_in { @@ -886,6 +900,7 @@ struct scmi_clk_get_permissions_in { }; /** + * struct scmi_clk_get_permissions_out - Response payload for CLOCK_GET_PERMISSIONS command * @status: Negative 32-bit integers are used to return error status codes. * @permissions: Bit[31] Clock state control, Bit[30] Clock parent control, * Bit[29] Clock rate control, Bits[28:0] Reserved, must be zero. @@ -1082,7 +1097,7 @@ struct scmi_pin_config { }; /** - * struct scmi_pad_config_set_in - Message payload for PAD_CONFIG_SET command + * struct scmi_pinctrl_config_set_in - Message payload for PAD_CONFIG_SET command * @identifier: Identifier for the pin or group. * @function_id: Identifier for the function selected to be enabled * for the selected pin or group. This field is set to diff --git a/include/smbios.h b/include/smbios.h index b5fed57aba2..f2f7483bce5 100644 --- a/include/smbios.h +++ b/include/smbios.h @@ -204,7 +204,7 @@ struct __packed smbios_type4 { char eos[SMBIOS_STRUCT_EOS_BYTES]; }; -union cache_config { +union __packed cache_config { struct { u16 level:3; u16 bsocketed:1; @@ -217,7 +217,7 @@ union cache_config { u16 data; }; -union cache_size_word { +union __packed cache_size_word { struct { u16 size:15; u16 granu:1; @@ -225,7 +225,7 @@ union cache_size_word { u16 data; }; -union cache_size_dword { +union __packed cache_size_dword { struct { u32 size:31; u32 granu:1; @@ -233,7 +233,7 @@ union cache_size_dword { u32 data; }; -union cache_sram_type { +union __packed cache_sram_type { struct { u16 other:1; u16 unknown:1; diff --git a/include/test/ut.h b/include/test/ut.h index be5502e03a1..6510c35997f 100644 --- a/include/test/ut.h +++ b/include/test/ut.h @@ -130,18 +130,28 @@ int ut_check_console_end(struct unit_test_state *uts); * * This only supports a byte dump. * - * @total_bytes: Size of the expected dump in bytes` - * Return: 0 if OK (looks like a dump and the length matches), other value on - * error + * @uts: Test state + * @total_bytes: Size of the expected dump in bytes + * Return: 0 if OK (looks like a dump and the length matches), + * other value on error */ int ut_check_console_dump(struct unit_test_state *uts, int total_bytes); -/* Report a failure, with printf() string */ +/** + * ut_report() - Report a failure, with printf() string + * + * @fmt: format string + * @args: arguments to be printed + */ #define ut_reportf(fmt, args...) \ ut_failf(uts, __FILE__, __LINE__, __func__, "report", \ fmt, ##args) -/* Assert that a condition is non-zero */ +/** + * ut_assert() - Assert that a condition is true (not 0) + * + * @cond: condition + */ #define ut_assert(cond) ({ \ int __ret = 0; \ \ @@ -152,7 +162,13 @@ int ut_check_console_dump(struct unit_test_state *uts, int total_bytes); __ret; \ }) -/* Assert that a condition is non-zero, with printf() string */ +/** + * ut_assertf() - Assert that a condition is true with printf string + * + * @cond: condition + * @fmt: format string + * @args: arguments to be printed + */ #define ut_assertf(cond, fmt, args...) ({ \ int __ret = 0; \ \ @@ -164,7 +180,12 @@ int ut_check_console_dump(struct unit_test_state *uts, int total_bytes); __ret; \ }) -/* Assert that two int expressions are equal */ +/** + * ut_asserteq() - Assert that two int32 expressions are equal + * + * @expr1: expected value + * @expr2: actual value + */ #define ut_asserteq(expr1, expr2) ({ \ unsigned int _val1 = (expr1), _val2 = (expr2); \ int __ret = 0; \ @@ -179,7 +200,12 @@ int ut_check_console_dump(struct unit_test_state *uts, int total_bytes); __ret; \ }) -/* Assert that two 64 int expressions are equal */ +/** + * ut_asserteq_64() - Assert that two int64 expressions are equal + * + * @expr1: expected value + * @expr2: actual value + */ #define ut_asserteq_64(expr1, expr2) ({ \ u64 _val1 = (expr1), _val2 = (expr2); \ int __ret = 0; \ @@ -197,7 +223,12 @@ int ut_check_console_dump(struct unit_test_state *uts, int total_bytes); __ret; \ }) -/* Assert that two string expressions are equal */ +/** + * ut_asserteq_str() - Assert that two string expressions are equal + * + * @expr1: expected value + * @expr2: actual value + */ #define ut_asserteq_str(expr1, expr2) ({ \ const char *_val1 = (expr1), *_val2 = (expr2); \ int __ret = 0; \ @@ -211,9 +242,12 @@ int ut_check_console_dump(struct unit_test_state *uts, int total_bytes); __ret; \ }) -/* - * Assert that two string expressions are equal, up to length of the - * first +/** + * ut_asserteq_strn() - Assert that two string expressions are equal + * up to the length of the first expression + * + * @expr1: expected value + * @expr2: actual value */ #define ut_asserteq_strn(expr1, expr2) ({ \ const char *_val1 = (expr1), *_val2 = (expr2); \ @@ -230,7 +264,13 @@ int ut_check_console_dump(struct unit_test_state *uts, int total_bytes); __ret; \ }) -/* Assert that two memory areas are equal */ +/** + * ut_asserteq_mem() - Assert that two memory areas are equal + * + * @expr1: expected value + * @expr2: actual value + * @len: length of the memory areas + */ #define ut_asserteq_mem(expr1, expr2, len) ({ \ const u8 *_val1 = (u8 *)(expr1), *_val2 = (u8 *)(expr2); \ const uint __len = len; \ @@ -250,7 +290,12 @@ int ut_check_console_dump(struct unit_test_state *uts, int total_bytes); __ret; \ }) -/* Assert that two pointers are equal */ +/** + * ut_asserteq_ptr() - Assert that two string pointers are equal + * + * @expr1: expected value + * @expr2: actual value + */ #define ut_asserteq_ptr(expr1, expr2) ({ \ const void *_val1 = (expr1), *_val2 = (expr2); \ int __ret = 0; \ @@ -264,7 +309,13 @@ int ut_check_console_dump(struct unit_test_state *uts, int total_bytes); __ret; \ }) -/* Assert that two addresses (converted from pointers) are equal */ +/** + * ut_asserteq_addr() - Assert that two addresses (converted from pointers) + * are equal + * + * @expr1: expected value + * @expr2: actual value + */ #define ut_asserteq_addr(expr1, expr2) ({ \ ulong _val1 = map_to_sysmem(expr1); \ ulong _val2 = map_to_sysmem(expr2); \ @@ -279,7 +330,11 @@ int ut_check_console_dump(struct unit_test_state *uts, int total_bytes); __ret; \ }) -/* Assert that a pointer is NULL */ +/** + * ut_assertnull() - Assert that a pointer is NULL + * + * @expr: pointer + */ #define ut_assertnull(expr) ({ \ const void *_val = (expr); \ int __ret = 0; \ @@ -293,7 +348,11 @@ int ut_check_console_dump(struct unit_test_state *uts, int total_bytes); __ret; \ }) -/* Assert that a pointer is not NULL */ +/** + * ut_assertnonnull() - Assert that a pointer is not NULL + * + * @expr: pointer + */ #define ut_assertnonnull(expr) ({ \ const void *_val = (expr); \ int __ret = 0; \ @@ -307,7 +366,11 @@ int ut_check_console_dump(struct unit_test_state *uts, int total_bytes); __ret; \ }) -/* Assert that a pointer is not an error pointer */ +/** + * ut_assertok_ptr() - Assert that a pointer is not an error pointer + * + * @expr: pointer + */ #define ut_assertok_ptr(expr) ({ \ const void *_val = (expr); \ int __ret = 0; \ @@ -322,10 +385,19 @@ int ut_check_console_dump(struct unit_test_state *uts, int total_bytes); __ret; \ }) -/* Assert that an operation succeeds (returns 0) */ +/** + * ut_assertok() - Assert that an operation succeeds (returns 0) + * + * @cond: expression + */ #define ut_assertok(cond) ut_asserteq(0, cond) -/* Assert that the next console output line matches */ +/** + * ut_assert_nextline() - Assert that the next console output line matches + * + * @fmt: format string + * @args: print arguments + */ #define ut_assert_nextline(fmt, args...) ({ \ int __ret = 0; \ \ @@ -338,7 +410,13 @@ int ut_check_console_dump(struct unit_test_state *uts, int total_bytes); __ret; \ }) -/* Assert that the next console output line matches up to the length */ +/** + * ut_assert_nextlinen() - Assert that the next console output line matches + * up to the length of the expected string. + * + * @fmt: format string + * @args: print arguments + */ #define ut_assert_nextlinen(fmt, args...) ({ \ int __ret = 0; \ \ @@ -351,7 +429,10 @@ int ut_check_console_dump(struct unit_test_state *uts, int total_bytes); __ret; \ }) -/* Assert that there is a 'next' console output line, and skip it */ +/** + * ut_assert_skipline() - Assert that there is a 'next' console output line, + * and skip it + */ #define ut_assert_skipline() ({ \ int __ret = 0; \ \ @@ -363,7 +444,13 @@ int ut_check_console_dump(struct unit_test_state *uts, int total_bytes); __ret; \ }) -/* Assert that a following console output line matches */ +/** + * ut_assert_skip_to_line() - Assert that a following console output line + * matches + * + * @fmt: format string + * @args: print arguments + */ #define ut_assert_skip_to_line(fmt, args...) ({ \ int __ret = 0; \ \ @@ -376,7 +463,13 @@ int ut_check_console_dump(struct unit_test_state *uts, int total_bytes); __ret; \ }) -/* Assert that a following console output line matches */ +/** + * ut_assert_skip_to_linen() - Assert that a following console output line + * matches up to the length of the expected string + * + * @fmt: format string + * @args: print arguments + */ #define ut_assert_skip_to_linen(fmt, args...) ({ \ int __ret = 0; \ \ @@ -389,7 +482,9 @@ int ut_check_console_dump(struct unit_test_state *uts, int total_bytes); __ret; \ }) -/* Assert that there is no more console output */ +/** + * ut_assert_console_end() - Assert that there is no more console output + */ #define ut_assert_console_end() ({ \ int __ret = 0; \ \ @@ -402,7 +497,12 @@ int ut_check_console_dump(struct unit_test_state *uts, int total_bytes); __ret; \ }) -/* Assert that the next lines are print_buffer() dump at an address */ +/** + * ut_assert_nextlines_are_dump - Assert that the next lines are print_buffer() + * dump at an address + * + * @total_bytes: Size of the expected dump in bytes + */ #define ut_assert_nextlines_are_dump(total_bytes) ({ \ int __ret = 0; \ \ @@ -416,7 +516,10 @@ int ut_check_console_dump(struct unit_test_state *uts, int total_bytes); __ret; \ }) -/* Assert that the next console output line is empty */ +/** + * ut_assert_nextline_empty() - Assert that the next console output line is + * empty + */ #define ut_assert_nextline_empty() \ ut_assert_nextline("%s", "") @@ -451,6 +554,8 @@ void ut_silence_console(struct unit_test_state *uts); * * This restarts console output again and turns off console recording. This * happens on all boards, including sandbox. + * + * @uts: Test state */ void ut_unsilence_console(struct unit_test_state *uts); diff --git a/lib/efi_client/efi_app.c b/lib/efi_client/efi_app.c index 9b94a93ee4f..da8e3432859 100644 --- a/lib/efi_client/efi_app.c +++ b/lib/efi_client/efi_app.c @@ -21,7 +21,6 @@ #include <asm/global_data.h> #include <linux/err.h> #include <linux/types.h> -#include <asm/global_data.h> #include <dm/device-internal.h> #include <dm/lists.h> #include <dm/root.h> diff --git a/lib/efi_client/efi_stub.c b/lib/efi_client/efi_stub.c index a083c7f1e9b..da7972444df 100644 --- a/lib/efi_client/efi_stub.c +++ b/lib/efi_client/efi_stub.c @@ -110,7 +110,7 @@ void *memset(void *inptr, int ch, size_t size) while (ptr < end) *ptr++ = ch; - return ptr; + return inptr; } static void jump_to_uboot(ulong cs32, ulong addr, ulong info) diff --git a/lib/efi_loader/efi_firmware.c b/lib/efi_loader/efi_firmware.c index 216df83de67..b41969c70fd 100644 --- a/lib/efi_loader/efi_firmware.c +++ b/lib/efi_loader/efi_firmware.c @@ -651,6 +651,7 @@ efi_status_t EFIAPI efi_firmware_fit_set_image( efi_status_t status; struct fmp_state state = { 0 }; char *orig_dfu_env; + void *img; EFI_ENTRY("%p %d %p %zu %p %p %p\n", this, image_index, image, image_size, vendor_code, progress, abort_reason); @@ -677,7 +678,20 @@ efi_status_t EFIAPI efi_firmware_fit_set_image( return EFI_EXIT(EFI_DEVICE_ERROR); } - ret = fit_update(image); + /* Make sure the update fitImage is properly aligned to 8-bytes */ + if (!IS_ALIGNED((uintptr_t)image, 8)) { + img = memalign(8, image_size); + if (!img) + return EFI_EXIT(EFI_BAD_BUFFER_SIZE); + memcpy(img, image, image_size); + } else { + img = (void *)image; + } + + ret = fit_update(img); + + if (!IS_ALIGNED((uintptr_t)image, 8)) + free(img); if (env_set("dfu_alt_info", orig_dfu_env)) log_warning("Unable to restore env variable \"dfu_alt_info\". Further DFU operations may fail!\n"); diff --git a/lib/efi_loader/efi_ipconfig.c b/lib/efi_loader/efi_ipconfig.c index 9f51f77fa9a..b20de8c3e4b 100644 --- a/lib/efi_loader/efi_ipconfig.c +++ b/lib/efi_loader/efi_ipconfig.c @@ -168,8 +168,8 @@ static efi_status_t EFIAPI efi_ip4_config2_register_notify(struct efi_ip4_config } /* - * efi_ip4_config2_unregister_notify() - Remove a previously registered eventfor - * the specified configuration data + * efi_ip4_config2_unregister_notify() - Remove a previously registered event + * for the specified configuration data * * This function implements EFI_IP4_CONFIG2_PROTOCOL.UnregisterDataNotify() * See the Unified Extensible Firmware Interface diff --git a/lib/efi_selftest/efi_selftest_console.c b/lib/efi_selftest/efi_selftest_console.c index fd2b3d09abc..0f8e9d28ef4 100644 --- a/lib/efi_selftest/efi_selftest_console.c +++ b/lib/efi_selftest/efi_selftest_console.c @@ -12,12 +12,12 @@ struct efi_simple_text_output_protocol *con_out; struct efi_simple_text_input_protocol *con_in; -/* - * Print a MAC address to an u16 string +/** + * mac() - print a MAC address to an u16 string * - * @pointer: mac address - * @buf: pointer to buffer address - * on return position of terminating zero word + * @pointer: mac address + * @buf: pointer to buffer address, + * on return position of terminating zero word */ static void mac(void *pointer, u16 **buf) { @@ -43,7 +43,7 @@ static void mac(void *pointer, u16 **buf) *buf = pos; } -/* +/** * printx() - print hexadecimal number to an u16 string * * @p: value to print @@ -71,7 +71,7 @@ static void printx(u64 p, int prec, u16 **buf) } /** - * print_guid() - print GUID to an u16 string + * print_uuid() - print GUID to an u16 string * * @p: GUID to print * @buf: pointer to buffer address, @@ -92,12 +92,12 @@ static void print_uuid(u8 *p, u16 **buf) } } -/* - * Print an unsigned 32bit value as decimal number to an u16 string +/** + * uint2dec() - print an unsigned 32bit value as decimal number to an u16 string * * @value: value to be printed * @prec: minimum number of digits to display - * @buf: pointer to buffer address + * @buf: pointer to buffer address, * on return position of terminating zero word */ static void uint2dec(u32 value, int prec, u16 **buf) @@ -132,13 +132,13 @@ static void uint2dec(u32 value, int prec, u16 **buf) *buf = pos; } -/* - * Print a signed 32bit value as decimal number to an u16 string +/** + * int2dec() - print a signed 32bit value as decimal number to an u16 string * * @value: value to be printed * @prec: minimum number of digits to display - * @buf: pointer to buffer address - * on return position of terminating zero word + * @buf: pointer to buffer address, + * on return position of terminating zero word */ static void int2dec(s32 value, int prec, u16 **buf) { @@ -155,12 +155,12 @@ static void int2dec(s32 value, int prec, u16 **buf) *buf = pos; } -/* - * Print a colored formatted string to the EFI console +/** + * efi_st_printc() - print a colored message * - * @color color, see constants in efi_api.h, use -1 for no color - * @fmt format string - * @... optional arguments + * @color: color, see constants in efi_api.h, use -1 for no color + * @fmt: printf style format string + * @...: arguments to be printed */ void efi_st_printc(int color, const char *fmt, ...) { @@ -271,10 +271,10 @@ void efi_st_printc(int color, const char *fmt, ...) con_out->set_attribute(con_out, EFI_LIGHTGRAY); } -/* - * Reads an Unicode character from the input device. +/** + * efi_st_get_key() - read an Unicode character from the input device * - * Return: Unicode character + * Return: Unicode character */ u16 efi_st_get_key(void) { diff --git a/lib/efi_selftest/efi_selftest_snp.c b/lib/efi_selftest/efi_selftest_snp.c index b00c76c2f17..290ed3a28f2 100644 --- a/lib/efi_selftest/efi_selftest_snp.c +++ b/lib/efi_selftest/efi_selftest_snp.c @@ -43,7 +43,7 @@ struct dhcp_hdr { u8 chaddr[16]; u8 sname[64]; u8 file[128]; -}; +} __packed; /* * Message type option. diff --git a/lib/optee/Kconfig b/lib/optee/Kconfig index e6834d4d3e1..34b9d8afe67 100644 --- a/lib/optee/Kconfig +++ b/lib/optee/Kconfig @@ -4,6 +4,25 @@ config OPTEE_LIB help Selecting this option will enable the shared OPTEE library code. +config HAS_TEE_IN_BUILD_ENV + def_bool $(success, test -n "$(TEE)") + select OPTEE_LIB if OF_CONTROL + select OF_LIBFDT if OF_CONTROL + help + It is typical whenever OP-TEE OS is loaded before U-Boot proper that + it modifies the FDT passed to U-Boot proper to add reserved-memory + nodes for the RAM it just reserved for itself. + + U-Boot must copy those reserved-nodes in the FDT for the next OS to + boot. + + Failing to do so will incur random crashes or device reboots once the + next OS is running. + + This makes sure that whenever TEE is present in the environment, + meaning a TEE OS will be part of the boot flow, the copy made by the + OP-TEE lib will happen. + config OPTEE_IMAGE bool "Support OPTEE images" help diff --git a/test/cmd/bdinfo.c b/test/cmd/bdinfo.c index 09f44ee41ed..28d448a0866 100644 --- a/test/cmd/bdinfo.c +++ b/test/cmd/bdinfo.c @@ -161,9 +161,9 @@ static int bdinfo_test_all(struct unit_test_state *uts) ut_assertok(bdinfo_check_mem(uts)); /* CONFIG_SYS_HAS_SRAM testing not supported */ - ut_assertok(test_num_l(uts, "flashstart", 0)); - ut_assertok(test_num_l(uts, "flashsize", 0)); - ut_assertok(test_num_l(uts, "flashoffset", 0)); + ut_check_console_linen(uts, "flashstart"); + ut_check_console_linen(uts, "flashsize"); + ut_check_console_linen(uts, "flashoffset"); ut_assert_nextline("baudrate = %lu bps", env_get_ulong("baudrate", 10, 1234)); ut_assertok(test_num_l(uts, "relocaddr", gd->relocaddr)); @@ -215,8 +215,15 @@ static int bdinfo_test_all(struct unit_test_state *uts) ut_assertok(test_num_l(uts, "malloc base", gd_malloc_start())); } + /* Check arch_print_bdinfo() output */ if (IS_ENABLED(CONFIG_X86)) - ut_check_skip_to_linen(uts, " high end ="); + ut_check_skip_to_linen(uts, "tsc"); + +#ifdef CONFIG_RISCV + ut_check_console_linen(uts, "boot hart"); + if (gd->arch.firmware_fdt_addr) + ut_check_console_linen(uts, "firmware fdt"); +#endif return 0; } diff --git a/test/cmd/fdt.c b/test/cmd/fdt.c index 96a8488e172..4c3c6308ab4 100644 --- a/test/cmd/fdt.c +++ b/test/cmd/fdt.c @@ -10,6 +10,7 @@ #include <fdt_support.h> #include <mapmem.h> #include <asm/global_data.h> +#include <dm/uclass.h> #include <linux/libfdt.h> #include <test/ut.h> @@ -264,7 +265,7 @@ FDT_TEST(fdt_test_addr_resize, UTF_CONSOLE); static int fdt_test_move(struct unit_test_state *uts) { char fdt[256]; - ulong addr, newaddr = 0x10000; + ulong addr, newaddr; const int size = sizeof(fdt); uint32_t ts; void *buf; @@ -274,8 +275,10 @@ static int fdt_test_move(struct unit_test_state *uts) ts = fdt_totalsize(fdt); /* Moved target DT location */ - buf = map_sysmem(newaddr, size); + buf = memalign(8, size); + ut_assertnonnull(buf); memset(buf, 0, size); + newaddr = map_to_sysmem(buf); /* Test moving the working FDT to a new location */ ut_assertok(run_commandf("fdt move %08lx %08lx %x", addr, newaddr, ts)); @@ -287,6 +290,8 @@ static int fdt_test_move(struct unit_test_state *uts) ut_assert_nextline("Total of %d byte(s) were the same", ts); ut_assert_console_end(); + free(buf); + return 0; } FDT_TEST(fdt_test_move, UTF_CONSOLE); @@ -1267,6 +1272,7 @@ static int fdt_test_chosen(struct unit_test_state *uts) { const char *env_bootargs = env_get("bootargs"); char fdt[8192]; + struct udevice *dev; ulong addr; ut_assertok(make_test_fdt(uts, fdt, sizeof(fdt), &addr)); @@ -1280,11 +1286,16 @@ static int fdt_test_chosen(struct unit_test_state *uts) /* Test add new chosen node without initrd */ ut_assertok(run_commandf("fdt chosen")); ut_assertok(run_commandf("fdt print /chosen")); - ut_assert_nextline("chosen {"); + ut_assert(0 < console_record_readline(uts->actual_str, + sizeof(uts->actual_str))); + if (!strcmp("No RNG device", uts->actual_str)) + ut_assert(0 < console_record_readline(uts->actual_str, + sizeof(uts->actual_str))); + ut_asserteq_str("chosen {", uts->actual_str); ut_assert_nextlinen("\tu-boot,version = "); /* Ignore the version string */ if (env_bootargs) ut_assert_nextline("\tbootargs = \"%s\";", env_bootargs); - if (IS_ENABLED(CONFIG_DM_RNG) && + if (!uclass_get_device(UCLASS_RNG, 0, &dev) && !IS_ENABLED(CONFIG_MEASURED_BOOT) && !IS_ENABLED(CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT)) ut_assert_nextlinen("\tkaslr-seed = "); @@ -1294,7 +1305,12 @@ static int fdt_test_chosen(struct unit_test_state *uts) /* Test add new chosen node with initrd */ ut_assertok(run_commandf("fdt chosen 0x1234 0x5678")); ut_assertok(run_commandf("fdt print /chosen")); - ut_assert_nextline("chosen {"); + ut_assert(0 < console_record_readline(uts->actual_str, + sizeof(uts->actual_str))); + if (!strcmp("No RNG device", uts->actual_str)) + ut_assert(0 < console_record_readline(uts->actual_str, + sizeof(uts->actual_str))); + ut_asserteq_str("chosen {", uts->actual_str); ut_assert_nextline("\tlinux,initrd-end = <0x%08x 0x%08x>;", upper_32_bits(0x1234 + 0x5678 - 1), lower_32_bits(0x1234 + 0x5678 - 1)); @@ -1303,7 +1319,7 @@ static int fdt_test_chosen(struct unit_test_state *uts) ut_assert_nextlinen("\tu-boot,version = "); /* Ignore the version string */ if (env_bootargs) ut_assert_nextline("\tbootargs = \"%s\";", env_bootargs); - if (IS_ENABLED(CONFIG_DM_RNG) && + if (!uclass_get_device(UCLASS_RNG, 0, &dev) && !IS_ENABLED(CONFIG_MEASURED_BOOT) && !IS_ENABLED(CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT)) ut_assert_nextlinen("\tkaslr-seed = "); @@ -1319,6 +1335,9 @@ static int fdt_test_apply(struct unit_test_state *uts) char fdt[8192], fdto[8192]; ulong addr, addro; + if (!IS_ENABLED(CONFIG_OF_LIBFDT_OVERLAY)) + return -EAGAIN; + /* Create base DT with __symbols__ node */ ut_assertok(fdt_create(fdt, sizeof(fdt))); ut_assertok(fdt_finish_reservemap(fdt)); diff --git a/test/common/print.c b/test/common/print.c index 76ee851fe6a..f33476a36b4 100644 --- a/test/common/print.c +++ b/test/common/print.c @@ -168,12 +168,8 @@ static int print_display_buffer(struct unit_test_state *uts) u8 *buf; int i; - /* This test requires writable memory at zero */ - if (IS_ENABLED(CONFIG_X86)) - return -EAGAIN; - - buf = map_sysmem(0, BUF_SIZE); - memset(buf, '\0', BUF_SIZE); + buf = calloc(1, BUF_SIZE); + ut_assertnonnull(buf); for (i = 0; i < 0x11; i++) buf[i] = i * 0x11; @@ -232,7 +228,7 @@ static int print_display_buffer(struct unit_test_state *uts) ut_assert_nextline("00000000: 00 1f 20 21 7e 7f 80 81 ff 99 .. !~....."); ut_assert_console_end(); - unmap_sysmem(buf); + free(buf); return 0; } @@ -244,13 +240,14 @@ static int print_hexdump_line(struct unit_test_state *uts) u8 *buf; int i; - buf = map_sysmem(0, BUF_SIZE); - memset(buf, '\0', BUF_SIZE); + buf = calloc(1, BUF_SIZE); + ut_assertnonnull(buf); for (i = 0; i < 0x11; i++) buf[i] = i * 0x11; /* Check buffer size calculations */ - linebuf = map_sysmem(0x400, BUF_SIZE); + linebuf = calloc(1, BUF_SIZE); + ut_assertnonnull(buf); memset(linebuf, '\xff', BUF_SIZE); ut_asserteq(-ENOSPC, hexdump_line(0, buf, 1, 0x10, 0, linebuf, 75)); ut_asserteq(0xff, linebuf[0]); @@ -258,7 +255,8 @@ static int print_hexdump_line(struct unit_test_state *uts) ut_asserteq('\0', linebuf[75]); ut_asserteq(0xff, linebuf[76]); - unmap_sysmem(buf); + free(linebuf); + free(buf); return 0; } @@ -268,70 +266,71 @@ static int print_do_hex_dump(struct unit_test_state *uts) { u8 *buf; int i; + ulong addr; - /* This test requires writable memory at zero */ - if (IS_ENABLED(CONFIG_X86)) - return -EAGAIN; - - buf = map_sysmem(0, BUF_SIZE); - memset(buf, '\0', BUF_SIZE); + buf = calloc(1, BUF_SIZE); + ut_assertnonnull(buf); + addr = map_to_sysmem(buf); for (i = 0; i < 0x11; i++) buf[i] = i * 0x11; /* bytes */ print_hex_dump_bytes("", DUMP_PREFIX_ADDRESS, buf, 0x12); ut_assert_nextline("%0*lx: 00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff ..\"3DUfw........", - IS_ENABLED(CONFIG_PHYS_64BIT) ? 16 : 8, 0x0UL); + IS_ENABLED(CONFIG_PHYS_64BIT) ? 16 : 8, addr); ut_assert_nextline("%0*lx: 10 00 ..", - IS_ENABLED(CONFIG_PHYS_64BIT) ? 16 : 8, 0x10UL); + IS_ENABLED(CONFIG_PHYS_64BIT) ? 16 : 8, + addr + 0x10UL); ut_assert_console_end(); /* line length */ print_hex_dump("", DUMP_PREFIX_ADDRESS, 8, 1, buf, 0x12, true); ut_assert_nextline("%0*lx: 00 11 22 33 44 55 66 77 ..\"3DUfw", - IS_ENABLED(CONFIG_PHYS_64BIT) ? 16 : 8, 0x0UL); + IS_ENABLED(CONFIG_PHYS_64BIT) ? 16 : 8, addr); ut_assert_nextline("%0*lx: 88 99 aa bb cc dd ee ff ........", - IS_ENABLED(CONFIG_PHYS_64BIT) ? 16 : 8, 0x8UL); + IS_ENABLED(CONFIG_PHYS_64BIT) ? 16 : 8, + addr + 0x8UL); ut_assert_nextline("%0*lx: 10 00 ..", - IS_ENABLED(CONFIG_PHYS_64BIT) ? 16 : 8, 0x10UL); + IS_ENABLED(CONFIG_PHYS_64BIT) ? 16 : 8, + addr + 0x10UL); ut_assert_console_end(); - unmap_sysmem(buf); /* long line */ buf[0x41] = 0x41; print_hex_dump("", DUMP_PREFIX_ADDRESS, 0x40, 1, buf, 0x42, true); ut_assert_nextline("%0*lx: 00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ..\"3DUfw........................................................", - IS_ENABLED(CONFIG_PHYS_64BIT) ? 16 : 8, 0x0UL); + IS_ENABLED(CONFIG_PHYS_64BIT) ? 16 : 8, addr); ut_assert_nextline("%0*lx: 00 41 .A", - IS_ENABLED(CONFIG_PHYS_64BIT) ? 16 : 8, 0x40UL); + IS_ENABLED(CONFIG_PHYS_64BIT) ? 16 : 8, + addr + 0x40UL); ut_assert_console_end(); /* 16-bit */ print_hex_dump("", DUMP_PREFIX_ADDRESS, 0, 2, buf, 0x12, true); ut_assert_nextline("%0*lx: 1100 3322 5544 7766 9988 bbaa ddcc ffee ..\"3DUfw........", - IS_ENABLED(CONFIG_PHYS_64BIT) ? 16 : 8, 0x0UL); + IS_ENABLED(CONFIG_PHYS_64BIT) ? 16 : 8, addr); ut_assert_nextline("%0*lx: 0010 ..", - IS_ENABLED(CONFIG_PHYS_64BIT) ? 16 : 8, 0x10UL); + IS_ENABLED(CONFIG_PHYS_64BIT) ? 16 : 8, + addr + 0x10UL); ut_assert_console_end(); - unmap_sysmem(buf); /* 32-bit */ print_hex_dump("", DUMP_PREFIX_ADDRESS, 0, 4, buf, 0x14, true); ut_assert_nextline("%0*lx: 33221100 77665544 bbaa9988 ffeeddcc ..\"3DUfw........", - IS_ENABLED(CONFIG_PHYS_64BIT) ? 16 : 8, 0x0UL); + IS_ENABLED(CONFIG_PHYS_64BIT) ? 16 : 8, addr); ut_assert_nextline("%0*lx: 00000010 ....", - IS_ENABLED(CONFIG_PHYS_64BIT) ? 16 : 8, 0x10UL); + IS_ENABLED(CONFIG_PHYS_64BIT) ? 16 : 8, + addr + 0x10UL); ut_assert_console_end(); - unmap_sysmem(buf); /* 64-bit */ print_hex_dump("", DUMP_PREFIX_ADDRESS, 16, 8, buf, 0x18, true); ut_assert_nextline("%0*lx: 7766554433221100 ffeeddccbbaa9988 ..\"3DUfw........", - IS_ENABLED(CONFIG_PHYS_64BIT) ? 16 : 8, 0x0UL); + IS_ENABLED(CONFIG_PHYS_64BIT) ? 16 : 8, addr); ut_assert_nextline("%0*lx: 0000000000000010 ........", - IS_ENABLED(CONFIG_PHYS_64BIT) ? 16 : 8, 0x10UL); + IS_ENABLED(CONFIG_PHYS_64BIT) ? 16 : 8, + addr + 0x10UL); ut_assert_console_end(); - unmap_sysmem(buf); /* ASCII */ buf[1] = 31; @@ -342,9 +341,9 @@ static int print_do_hex_dump(struct unit_test_state *uts) buf[8] = 255; print_hex_dump("", DUMP_PREFIX_ADDRESS, 0, 1, buf, 10, true); ut_assert_nextline("%0*lx: 00 1f 20 21 7e 7f 80 81 ff 99 .. !~.....", - IS_ENABLED(CONFIG_PHYS_64BIT) ? 16 : 8, 0x0UL); + IS_ENABLED(CONFIG_PHYS_64BIT) ? 16 : 8, addr); ut_assert_console_end(); - unmap_sysmem(buf); + free(buf); return 0; } diff --git a/tools/docker/Dockerfile b/tools/docker/Dockerfile index 2dc4bec33bb..630b7f0e141 100644 --- a/tools/docker/Dockerfile +++ b/tools/docker/Dockerfile @@ -6,7 +6,7 @@ FROM ubuntu:noble-20251001 LABEL org.opencontainers.image.authors="Tom Rini <[email protected]>" LABEL org.opencontainers.image.description=" This image is for building U-Boot inside a container" -# Used by docker to set the target platform: valid values are linux/arm64/v8 +# Used by Docker to set the target platform: valid values are linux/arm64 # and linux/amd64 ARG TARGETPLATFORM |
