diff --git a/config/Config-images.in b/config/Config-images.in index 6b9901b65d0766..543803df6cf018 100644 --- a/config/Config-images.in +++ b/config/Config-images.in @@ -352,6 +352,7 @@ menu "Target Images" int "Root filesystem partition size (in MiB)" depends on USES_ROOTFS_PART || TARGET_ROOTFS_EXT4FS default 232 if TARGET_loongarch64 + default 236 if TARGET_spacemit default 448 if TARGET_mediatek || TARGET_microchipsw default 104 help diff --git a/include/image-commands.mk b/include/image-commands.mk index 443c870a8ec32e..ebaa9b1dda15f5 100644 --- a/include/image-commands.mk +++ b/include/image-commands.mk @@ -450,6 +450,7 @@ define Build/fit-its $(if $(DEVICE_DTS_DELIMITER),-l $(DEVICE_DTS_DELIMITER)) \ $(if $(DEVICE_DTS_LOADADDR),-s $(DEVICE_DTS_LOADADDR)) \ $(if $(DEVICE_DTS_OVERLAY),$(foreach dtso,$(DEVICE_DTS_OVERLAY), -O $(dtso):$(KERNEL_BUILD_DIR)/image-$(dtso).dtbo)) \ + $(if $(DEVICE_DTS_MULTI),$(foreach dtb,$(DEVICE_DTS_MULTI), -m $(dtb))) \ -c $(if $(DEVICE_DTS_CONFIG),$(DEVICE_DTS_CONFIG),"config-1") \ -A $(LINUX_KARCH) -v $(LINUX_VERSION) endef diff --git a/include/u-boot.mk b/include/u-boot.mk index bdf77f1612bd1b..9336e26f8c10eb 100644 --- a/include/u-boot.mk +++ b/include/u-boot.mk @@ -70,8 +70,12 @@ endef TARGET_DEP = TARGET_$(BUILD_TARGET)$(if $(BUILD_SUBTARGET),_$(BUILD_SUBTARGET)) +ifndef UBOOT_USE_INTREE_DTC + DTC=$(wildcard $(LINUX_DIR)/scripts/dtc/dtc) +endif + UBOOT_MAKE_FLAGS = \ - PATH=$(STAGING_DIR_HOST)/bin:$(PATH) \ + PATH=$(STAGING_DIR_HOST)/bin:$(if $(DTC),$(shell dirname $(DTC)):)$(PATH) \ HOSTCC="$(HOSTCC)" \ HOSTCFLAGS="$(HOST_CFLAGS) $(HOST_CPPFLAGS) -std=gnu11" \ HOSTLDFLAGS="$(HOST_LDFLAGS)" \ @@ -123,10 +127,6 @@ define Build/Configure/U-Boot +$(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR) CROSS_COMPILE=$(TARGET_CROSS) $(UBOOT_CONFIGURE_VARS) oldconfig) endef -ifndef UBOOT_USE_INTREE_DTC - DTC=$(wildcard $(LINUX_DIR)/scripts/dtc/dtc) -endif - define Build/Compile/U-Boot +$(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR) \ CROSS_COMPILE=$(TARGET_CROSS) \ diff --git a/package/base-files/files/lib/upgrade/common.sh b/package/base-files/files/lib/upgrade/common.sh index ba2e364775d628..e88c3c11d11494 100644 --- a/package/base-files/files/lib/upgrade/common.sh +++ b/package/base-files/files/lib/upgrade/common.sh @@ -183,7 +183,7 @@ export_bootdevice() { done ;; PARTUUID=????????-????-????-????-??????????0?/PARTNROFF=1 | \ - PARTUUID=????????-????-????-????-??????????02) + PARTUUID=????????-????-????-????-??????????0?) uuid="${rootpart#PARTUUID=}" uuid="${uuid%/PARTNROFF=1}" uuid="${uuid%0?}00" diff --git a/package/base-files/files/sbin/sysupgrade b/package/base-files/files/sbin/sysupgrade index 68ab9c63b3f774..cfc80e2f76bb58 100755 --- a/package/base-files/files/sbin/sysupgrade +++ b/package/base-files/files/sbin/sysupgrade @@ -14,7 +14,6 @@ COMMAND=/lib/upgrade/do_stage2 ADD_PROVISIONING=0 SAVE_OVERLAY=0 SAVE_OVERLAY_PATH= -SAVE_PARTITIONS=1 SAVE_INSTALLED_PKGS=0 SKIP_UNCHANGED=0 CONF_IMAGE= @@ -32,6 +31,7 @@ export MTD_CONFIG_ARGS="" export INTERACTIVE=0 export VERBOSE=1 export SAVE_CONFIG=1 +export SAVE_PARTITIONS=1 export IGNORE_MINOR_COMPAT=0 export FORCE=0 export CONFFILES=/tmp/sysupgrade.conffiles @@ -45,7 +45,7 @@ while [ -n "$1" ]; do -n) export SAVE_CONFIG=0;; -c) SAVE_OVERLAY=1 SAVE_OVERLAY_PATH=/etc;; -o) SAVE_OVERLAY=1 SAVE_OVERLAY_PATH=/;; - -p) SAVE_PARTITIONS=0;; + -p) export SAVE_PARTITIONS=0;; -P) ADD_PROVISIONING=1;; -k) SAVE_INSTALLED_PKGS=1;; -u) SKIP_UNCHANGED=1;; diff --git a/package/boot/opensbi/Makefile b/package/boot/opensbi/Makefile index 58803a97234d7d..552b6355dccb2c 100644 --- a/package/boot/opensbi/Makefile +++ b/package/boot/opensbi/Makefile @@ -6,13 +6,12 @@ include $(TOPDIR)/rules.mk PKG_NAME:=opensbi -PKG_RELEASE:=1.6 +PKG_VERSION:=1.9 PKG_SOURCE_PROTO:=git -PKG_SOURCE_URL=https://github.com/riscv/opensbi -PKG_SOURCE_DATE:=2024-12-24 -PKG_SOURCE_VERSION:=bd613dd92113f683052acfb23d9dc8ba60029e0a -PKG_MIRROR_HASH:=19593a340e4346ed953f17664a15744f9efdc68340a89ec6831c5e0e4dc5656d +PKG_SOURCE_URL:=https://github.com/riscv/opensbi +PKG_SOURCE_VERSION:=v$(PKG_VERSION) +PKG_MIRROR_HASH:=1abb1467ade206dc7880caf6bd994cac43cbb207882b43b63a05322d91ef3902 PKG_BUILD_DIR=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION) @@ -29,7 +28,7 @@ include $(INCLUDE_DIR)/package.mk define Package/opensbi SECTION:=boot CATEGORY:=Boot Loaders - DEPENDS:=@(TARGET_sifiveu||TARGET_d1) + DEPENDS:=@(TARGET_sifiveu||TARGET_d1||TARGET_spacemit) URL:=https://github.com/riscv/opensbi/blob/master/README.md VARIANT:=$(subst _,/,$(subst opensbi_,,$(1))) TITLE:=OpenSBI generic @@ -46,12 +45,15 @@ endef export GCC_HONOUR_COPTS=s -MAKE_VARS = \ - CROSS_COMPILE="$(TARGET_CROSS)" +MAKE_FLAGS = \ + CROSS_COMPILE="$(TARGET_CROSS)" \ + REPRODUCIBLE=y \ + $(if $(findstring c,$(OPENWRT_VERBOSE)),V=1,V='') \ + OPENSBI_VERSION_GIT="v$(PKG_VERSION)-OpenWrt-$(REVISION)" define Build/Compile $(eval $(Package/opensbi_$(BUILD_VARIANT))) \ - +$(MAKE_VARS) $(MAKE) -C $(PKG_BUILD_DIR) \ + +$(MAKE) $(MAKE_FLAGS) -C $(PKG_BUILD_DIR) \ PLATFORM=$(PLAT) endef diff --git a/package/boot/uboot-spacemit/Makefile b/package/boot/uboot-spacemit/Makefile new file mode 100644 index 00000000000000..441a47e3f609cb --- /dev/null +++ b/package/boot/uboot-spacemit/Makefile @@ -0,0 +1,59 @@ +# SPDX-License-Identifier: GPL-2.0-only + +include $(TOPDIR)/rules.mk +include $(INCLUDE_DIR)/kernel.mk + +PKG_NAME:=uboot-spacemit + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_URL:=https://github.com/spacemit-com/uboot-2022.10.git +PKG_SOURCE_DATE:=2026-06-05 +PKG_SOURCE_VERSION:=46a4f510352684407c074b7c0e9114b5443dcc59 +PKG_MIRROR_HASH:=6c52e24dba290ff9f86875e6b5a5c6d9a3fb8a2b80e950c7f4f08a09a3cb99e0 + +PKG_RELEASE:=1 + +include $(INCLUDE_DIR)/u-boot.mk +include $(INCLUDE_DIR)/package.mk +include $(INCLUDE_DIR)/host-build.mk + +# build an user installable package +PKG_TARGETS:= +PKG_BUILD_DEPENDS:=opensbi + +define U-Boot/spacemit_k1 + NAME:=SpacemiT K1 + BUILD_TARGET:=spacemit + BUILD_SUBTARGET:=k1 + UBOOT_CONFIG:=k1 + UBOOT_IMAGE:= \ + FSBL.bin \ + u-boot.itb \ + bootinfo_emmc.bin \ + bootinfo_sd.bin \ + bootinfo_spinand.bin \ + bootinfo_spinor.bin + DEPENDS:=+mtd +endef + +UBOOT_TARGETS:= \ + spacemit_k1 + +UBOOT_MAKE_FLAGS += OPENSBI=$(STAGING_DIR_IMAGE)/fw_dynamic-generic.bin + +define Build/InstallDev + $(INSTALL_DIR) $(STAGING_DIR_IMAGE)/u-boot-$(BUILD_VARIANT) + $(INSTALL_DATA) $(patsubst %,$(PKG_BUILD_DIR)/%,$(UBOOT_IMAGE)) $(STAGING_DIR_IMAGE)/u-boot-$(BUILD_VARIANT)/ + $(INSTALL_BIN) bootstrap.sh $(STAGING_DIR_IMAGE)/u-boot-$(BUILD_VARIANT)/ + $(TAR) -C $(STAGING_DIR_IMAGE) -cvzf $(STAGING_DIR_IMAGE)/u-boot-$(BUILD_VARIANT).tar.gz u-boot-$(BUILD_VARIANT)/ + $(INSTALL_DATA) $(STAGING_DIR_IMAGE)/u-boot-$(BUILD_VARIANT).tar.gz $(BIN_DIR)/ +endef + +define Package/u-boot/install + $(INSTALL_DIR) $(1)/usr/share/bootloader + $(INSTALL_DATA) $(patsubst %,$(PKG_BUILD_DIR)/%,$(UBOOT_IMAGE)) $(1)/usr/share/bootloader/ + $(INSTALL_DIR) $(1)/sbin + $(INSTALL_BIN) update-bootloader.sh $(1)/sbin/ +endef + +$(eval $(call BuildPackage/U-Boot)) diff --git a/package/boot/uboot-spacemit/bootstrap.sh b/package/boot/uboot-spacemit/bootstrap.sh new file mode 100755 index 00000000000000..62be3c4e76c128 --- /dev/null +++ b/package/boot/uboot-spacemit/bootstrap.sh @@ -0,0 +1,46 @@ +#!/bin/sh -e + +# bootstrap SpacemiT K1 boards +# * hold the FDL (Firmware Download) button while powering on +# * run this script without arguments to upload u-boot and drop to its prompt +# * pass the filename of a FIT (*.itb) image to boot it: +# ./u-boot-spacemit_k1/bootstrap.sh openwrt-spacemit-k1-generic-initramfs.itb + +dir="$(dirname "$(readlink -f "$0")")" +stage1="${dir}/FSBL.bin" +stage2="${dir}/u-boot.itb" +stage3="${1}" + +die() { + echo "$(basename "$0"): error: $*" + exit 1 +} + +which fastboot 2>/dev/null 1>&2 || die "the fastboot tool is required" +test -f "${stage1}" || die "missing file: ${stage1}" +test -f "${stage2}" || die "missing file: ${stage2}" +test -n "${stage3}" -a ! -f "${stage3}" && die "not a file: ${stage3}" + +fastboot getvar version-brom +echo "uploading stage1..." +fastboot stage "${stage1}" +fastboot continue +sleep 1 + +echo "uploading stage2..." +fastboot stage "${stage2}" +fastboot continue +sleep 1 + +if test -z "${stage3}"; then + echo "dropping to prompt..." + fastboot oem env:set bootdelay:-1 + fastboot continue + exit 0 +fi + +echo "uploading stage3..." +fastboot oem env:set bootargs:earlycon=sbi console=ttyS0,115200 root=/dev/ram +fastboot stage "${stage3}" +fastboot oem env:set bootdelay:0 +fastboot continue diff --git a/package/boot/uboot-spacemit/patches/0001-SpacemiT-K1X-Fixups.patch b/package/boot/uboot-spacemit/patches/0001-SpacemiT-K1X-Fixups.patch new file mode 100644 index 00000000000000..8b87f04833906f --- /dev/null +++ b/package/boot/uboot-spacemit/patches/0001-SpacemiT-K1X-Fixups.patch @@ -0,0 +1,147 @@ +From 49efbf8f5dd59c50e42b6c77cb56fc000872ef53 Mon Sep 17 00:00:00 2001 +From: Patrick Yavitz +Date: Mon, 16 Feb 2026 09:18:25 -0500 +Subject: [PATCH] SpacemiT K1X Fixups + +a.heider: fix bugs, remove net config + +Signed-off-by: Patrick Yavitz +--- + board/spacemit/k1-x/k1x.c | 33 +++++++++++---------------------- + include/configs/k1-x.h | 27 ++++++++++----------------- + 2 files changed, 21 insertions(+), 39 deletions(-) + +--- a/board/spacemit/k1-x/k1x.c ++++ b/board/spacemit/k1-x/k1x.c +@@ -532,8 +532,8 @@ void _load_env_from_blk(struct blk_desc + if (part > MAX_SEARCH_PARTITIONS) + return; + +- env_set("bootfs_part", simple_itoa(part)); +- env_set("bootfs_devname", dev_name); ++ env_set("distro_bootpart", simple_itoa(part)); ++ env_set("devtype", dev_name); + + /*load env.txt and import to uboot*/ + memset((void *)CONFIG_SPL_LOAD_FIT_ADDRESS, 0, CONFIG_ENV_SIZE); +@@ -739,7 +739,7 @@ void setenv_boot_mode(void) + const char *boot_override = env_get("boot_override"); + + if (boot_override) { +- env_set("boot_device", boot_override); ++ env_set("devtype", boot_override); + env_set("boot_override", NULL); + return; + } +@@ -748,34 +748,23 @@ void setenv_boot_mode(void) + u32 boot_mode = get_boot_mode(); + switch (boot_mode) { + case BOOT_MODE_NAND: +- env_set("boot_device", "nand"); ++ env_set("devtype", "nand"); + break; + case BOOT_MODE_NOR: +- char *blk_name; +- int blk_index; +- +- if (get_available_boot_blk_dev(&blk_name, &blk_index)){ +- printf("can not get available blk dev\n"); +- return; +- } +- +- env_set("boot_device", "nor"); +- env_set("boot_devnum", simple_itoa(blk_index)); +- break; + case BOOT_MODE_EMMC: +- env_set("boot_device", "mmc"); +- env_set("boot_devnum", simple_itoa(MMC_DEV_EMMC)); ++ env_set("devtype", "mmc"); ++ env_set("devnum", simple_itoa(MMC_DEV_EMMC)); + break; + case BOOT_MODE_SD: +- env_set("boot_device", "mmc"); +- env_set("boot_devnum", simple_itoa(MMC_DEV_SD)); ++ env_set("devtype", "mmc"); ++ env_set("devnum", simple_itoa(MMC_DEV_SD)); + break; + case BOOT_MODE_USB: + // for fastboot image download and run test + env_set("bootcmd", CONFIG_BOOTCOMMAND); + break; + default: +- env_set("boot_device", ""); ++ env_set("devtype", ""); + break; + } + } +@@ -1048,9 +1037,9 @@ int board_late_init(void) + setenv_boot_mode(); + + // Resize the last partition for sd +- const char *boot_device = env_get("boot_device"); ++ const char *boot_device = env_get("devtype"); + if (boot_device && strcmp(boot_device, "mmc") == 0) { +- const char *boot_devnum = env_get("boot_devnum"); ++ const char *boot_devnum = env_get("devnum"); + unsigned long devnum = simple_strtoul(boot_devnum, NULL, 10); + if (devnum == MMC_DEV_SD) { + printf("Resize the last partition for boot dev %s devnum %lu\n", boot_device, devnum); +--- a/include/configs/k1-x.h ++++ b/include/configs/k1-x.h +@@ -20,11 +20,6 @@ + #define RISCV_SMODE_TIMER_FREQ 24000000 + #define RISCV_TIMER_FREQ (RISCV_SMODE_TIMER_FREQ) + +-#define CONFIG_IPADDR 10.0.92.253 +-#define CONFIG_SERVERIP 10.0.92.134 +-#define CONFIG_GATEWAYIP 10.0.92.1 +-#define CONFIG_NETMASK 255.255.255.0 +- + #define DEFAULT_PRODUCT_NAME "k1-x_deb1" + + #define DDR_TRAINING_DATA_BASE (0xc0832000) +@@ -108,11 +103,6 @@ + #define TLV_CODE_EEPROM_I2C_INDEX 0x81 + #define TLV_CODE_EEPROM_PIN_GROUP 0x82 + +-// #define RAMDISK_LOAD_ADDR (CONFIG_FASTBOOT_BUF_ADDR + CONFIG_FASTBOOT_BUF_SIZE) +-// #define DTB_LOAD_ADDR (CONFIG_FASTBOOT_BUF_ADDR + CONFIG_FASTBOOT_BUF_SIZE * 2) +-#define RAMDISK_LOAD_ADDR 0x21000000 +-#define DTB_LOAD_ADDR 0x31000000 +- + // for those has NOT been through test procedure(ATE) + #define SVT_DRO_DEFAULT_VALUE (120) + +@@ -217,6 +207,11 @@ enum private_part_offset { + #define BOOT_TARGET_DEVICES(func) \ + func(QEMU, qemu, na) + ++#define KERNEL_ADDR_R __stringify(0x10000000) ++#define RAMDISK_ADDR_R __stringify(0x21000000) ++#define FDT_ADDR_R __stringify(0x31000000) ++#define FDTOVERLAY_ADDR_R __stringify(0x01000000) ++ + #include + + #define BOOTENV_DEV_QEMU(devtypeu, devtypel, instance) \ +@@ -244,15 +239,13 @@ enum private_part_offset { + "stdout_flash=serial,vidconsole\0" \ + "kernel_comp_addr_r=" __stringify(CONFIG_SYS_LOAD_ADDR) "\0" \ + "kernel_comp_size=" __stringify(CONFIG_FASTBOOT_BUF_SIZE) "\0" \ +- "kernel_addr_r=" __stringify(CONFIG_FASTBOOT_BUF_ADDR) "\0" \ +- "ramdisk_addr=" __stringify(RAMDISK_LOAD_ADDR) "\0" \ +- "dtb_addr=" __stringify(DTB_LOAD_ADDR) "\0" \ + "scriptaddr=0x2c100000\0" \ + "pxefile_addr_r=0x0c200000\0" \ +- "splashimage=" __stringify(CONFIG_FASTBOOT_BUF_ADDR) "\0" \ +- "splashpos=m,m\0" \ +- "splashfile=bianbu.bmp\0" \ +- "led0_gpio=" __stringify(STATUS_LED_GPIO0) "\0" \ ++ "fdt_addr_r=" FDT_ADDR_R "\0" \ ++ "kernel_addr_r=" KERNEL_ADDR_R "\0" \ ++ "ramdisk_addr_r=" RAMDISK_ADDR_R "\0" \ ++ "fdtoverlay_addr_r=" FDTOVERLAY_ADDR_R "\0" \ ++ "fdtfile=spacemit/" CONFIG_DEFAULT_DEVICE_TREE ".dtb\0" \ + BOOTENV_DEVICE_CONFIG + + diff --git a/package/boot/uboot-spacemit/patches/0002-efi_loader-Suppress-error-print-message.patch b/package/boot/uboot-spacemit/patches/0002-efi_loader-Suppress-error-print-message.patch new file mode 100644 index 00000000000000..3115d04eaa3d7c --- /dev/null +++ b/package/boot/uboot-spacemit/patches/0002-efi_loader-Suppress-error-print-message.patch @@ -0,0 +1,50 @@ +From f31fc0e84da0fede92a00a47aa09b8b5e8652f27 Mon Sep 17 00:00:00 2001 +From: Tejas Bhumkar +Date: Fri, 7 Jun 2024 06:32:58 -0400 +Subject: [PATCH] efi_loader : Suppress error print message + +Currently, on certain Xilinx platforms, an issue has been +identified, manifesting as follows: + +Starting kernel ... + +efi_free_pool: illegal free 0x0000000077830040 +efi_free_pool: illegal free 0x000000007782d040 +efi_free_pool: illegal free 0x000000007782c040 + +The issue arises when the ramdisk image is relocated, placing +it within the previously allocated EFI memory region( as EFI +is established quite early in U-Boot). Consequently, when +attempting to release memory in the EFI memory region during +the handover process to the kernel,we encounter memory violations. + +Highlighting that EFI remains active primarily during the +booting of an EFI application, and the lmb persists while +configuring images for the boot process. Since we aren't +utilizing the EFI memory region during the boot process, +there is no adverse impact even in the event of a violation. + +Currently, there is an ongoing discussion regarding the handling +strategies of three memory allocators: malloc, lmb, and EFI. This +discussion is documented in the email chain +titled "Proposal: U-Boot memory management." + +Therefore, it is advisable to suppress the print message during +the boot process for now. + +Signed-off-by: Tejas Bhumkar +--- + lib/efi_loader/efi_memory.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/lib/efi_loader/efi_memory.c ++++ b/lib/efi_loader/efi_memory.c +@@ -660,7 +660,7 @@ efi_status_t efi_free_pool(void *buffer) + /* Check that this memory was allocated by efi_allocate_pool() */ + if (((uintptr_t)alloc & EFI_PAGE_MASK) || + alloc->checksum != checksum(alloc)) { +- printf("%s: illegal free 0x%p\n", __func__, buffer); ++ debug("%s: illegal free 0x%p\n", __func__, buffer); + return EFI_INVALID_PARAMETER; + } + /* Avoid double free */ diff --git a/package/boot/uboot-spacemit/patches/0003-Orange-Pi-RV2-u-boot-support-for-XM25QU128C-flash.patch b/package/boot/uboot-spacemit/patches/0003-Orange-Pi-RV2-u-boot-support-for-XM25QU128C-flash.patch new file mode 100644 index 00000000000000..6f5b446ea5ce1b --- /dev/null +++ b/package/boot/uboot-spacemit/patches/0003-Orange-Pi-RV2-u-boot-support-for-XM25QU128C-flash.patch @@ -0,0 +1,33 @@ +From 28f2768c0717beb867f8fdd2b9d5228d324afd25 Mon Sep 17 00:00:00 2001 +From: Sven-Ola Tuecke +Date: Fri, 20 Feb 2026 14:55:43 -0500 +Subject: [PATCH] Orange Pi RV2: u-boot support for XM25QU128C flash + +NOR flash name from u-boot/master, ID from Xunlong Ky-Tree. + +Signed-off-by: Sven-Ola Tuecke +--- + configs/k1_defconfig | 1 + + drivers/mtd/spi/spi-nor-ids.c | 1 + + 2 files changed, 2 insertions(+) + +--- a/configs/k1_defconfig ++++ b/configs/k1_defconfig +@@ -209,6 +209,7 @@ CONFIG_MTD_SPI_NAND=y + CONFIG_SPI_NAND_GIGADEVICE=y + CONFIG_SPI_FLASH_GIGADEVICE=y + CONFIG_SPI_FLASH_WINBOND=y ++CONFIG_SPI_FLASH_XMC=y + CONFIG_SPI_FLASH_FM=y + CONFIG_SPINOR_BLOCK_SUPPORT=y + # CONFIG_SPI_FLASH_USE_4K_SECTORS is not set +--- a/drivers/mtd/spi/spi-nor-ids.c ++++ b/drivers/mtd/spi/spi-nor-ids.c +@@ -455,6 +455,7 @@ const struct flash_info spi_nor_ids[] = + { INFO("XM25QH64A", 0x207017, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, + { INFO("XM25QH64C", 0x204017, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, + { INFO("XM25QH128A", 0x207018, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, ++ { INFO("XM25QU128C", 0x204118, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, + #endif + #ifdef CONFIG_SPI_FLASH_XTX + /* XTX Technology (Shenzhen) Limited */ diff --git a/package/boot/uboot-spacemit/patches/0004-add-ky-x1-boards-orangepi-rv2-and-r2s.patch b/package/boot/uboot-spacemit/patches/0004-add-ky-x1-boards-orangepi-rv2-and-r2s.patch new file mode 100644 index 00000000000000..afd7a9fd23758f --- /dev/null +++ b/package/boot/uboot-spacemit/patches/0004-add-ky-x1-boards-orangepi-rv2-and-r2s.patch @@ -0,0 +1,752 @@ +From e0d40087f3186dec921a6cacde9776c315908f81 Mon Sep 17 00:00:00 2001 +From: Sven-Ola Tuecke +Date: Mon, 12 Jan 2026 21:21:41 +0100 +Subject: [PATCH] add ky x1 boards (orangepi rv2 and r2s) + +Signed-off-by: Sven-Ola Tuecke +--- + arch/riscv/dts/Makefile | 2 +- + arch/riscv/dts/x1_orangepi-r2s.dts | 335 +++++++++++++++++++++ + arch/riscv/dts/x1_orangepi-rv2.dts | 342 ++++++++++++++++++++++ + board/spacemit/k1-x/configs/uboot_fdt.its | 28 ++ + 4 files changed, 706 insertions(+), 1 deletion(-) + create mode 100644 arch/riscv/dts/x1_orangepi-r2s.dts + create mode 100644 arch/riscv/dts/x1_orangepi-rv2.dts + +--- a/arch/riscv/dts/Makefile ++++ b/arch/riscv/dts/Makefile +@@ -16,7 +16,7 @@ dtb-$(CONFIG_TARGET_SPACEMIT_K1X) += k1- + k1-x_MUSE-Paper-mini-4g.dtb k1-x_baton-camera.dtb \ + k1-x_FusionOne.dtb k1-x_InnoBoard-Pi.dtb k1-x_ZT001H.dtb \ + k1-x_uav.dtb k1-x_MUSE-Paper2.dtb k1-x_MUSE-Pi-Pro.dtb k1-x_LX-V10.dtb \ +- k1-x_som.dtb k1-x_ZT_RVOH007.dtb ++ k1-x_som.dtb k1-x_ZT_RVOH007.dtb x1_orangepi-rv2.dtb x1_orangepi-r2s.dtb + + include $(srctree)/scripts/Makefile.dts + +--- /dev/null ++++ b/arch/riscv/dts/x1_orangepi-r2s.dts +@@ -0,0 +1,335 @@ ++// SPDX-License-Identifier: (GPL-2.0 OR MIT) ++/* Copyright (c) 2023 Ky, Inc */ ++ ++/dts-v1/; ++ ++#include "k1-x.dtsi" ++#include "k1-x_pinctrl.dtsi" ++#include "k1-x_spm8821.dtsi" ++ ++/ { ++ model = "ky x1 orangepi-r2s board"; ++ ++ aliases { ++ efuse_power = &ldo_31; ++ }; ++ ++ memory@0 { ++ device_type = "memory"; ++ reg = <0x00000000 0x00000000 0x00000000 0x80000000>; ++ }; ++ ++ chosen { ++ bootargs = "earlycon=sbi console=ttyS0,115200 debug loglevel=8,initcall_debug=1 rdinit=/init.tmp"; ++ stdout-path = "serial0:115200n8"; ++ }; ++ ++ usb2hub: usb2hub { ++ compatible = "spacemit,usb-hub"; ++ vbus-gpios = <&gpio 123 0>; /* for usb2 hub output vbus */ ++ status = "okay"; ++ }; ++ ++ usb3hub: usb3hub { ++ compatible = "spacemit,usb-hub"; ++ vbus-gpios = <&gpio 79 0>; /* gpio_79 for usb3 pwren */ ++ status = "okay"; ++ }; ++ ++ vcc5v_otg: vcc5v-otg-regulator { ++ u-boot,dm-spl; ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc5v_otg"; ++ regulator-always-on; ++ regulator-boot-on; ++ enable-active-high; ++ gpio = <&gpio 126 0>; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ }; ++ ++ vcc3v3_pcie: vcc3v3-pcie-regulator { ++ u-boot,dm-spl; ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc3v3_pcie"; ++ regulator-always-on; ++ regulator-boot-on; ++ enable-active-high; ++ gpio = <&gpio 116 0>; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ }; ++ ++ gpio-leds { ++ //u-boot,dm-pre-reloc; ++ compatible = "gpio-leds"; ++ status = "okay"; ++ ++ act-led { ++ //u-boot,dm-pre-reloc; ++ gpios=<&gpio 96 1>; ++ label = "status_led"; ++ default-state = "on"; ++ }; ++ }; ++}; ++ ++&cpus { ++ timebase-frequency = <24000000>; ++}; ++ ++&uart0 { ++ status = "okay"; ++}; ++ ++&i2c0 { ++ status = "disabled"; ++}; ++ ++&i2c1 { ++ status = "disabled"; ++}; ++ ++&i2c2 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_i2c2_0>; ++ status = "okay"; ++ ++ eeprom@50{ ++ compatible = "atmel,24c02"; ++ reg = <0x50>; ++ vin-supply-names = "eeprom_1v8"; ++ status = "okay"; ++ }; ++}; ++ ++&i2c3 { ++ status = "disabled"; ++}; ++ ++&i2c4 { ++ clock-frequency = <400000>; ++ status = "okay"; ++}; ++ ++&i2c5 { ++ status = "disabled"; ++}; ++ ++&i2c6 { ++ status = "disabled"; ++}; ++ ++&i2c7 { ++ status = "disabled"; ++}; ++ ++&pinctrl { ++ pinctrl-single,gpio-range = < ++ &range GPIO_49 2 (MUX_MODE0 | EDGE_NONE | PULL_UP | PAD_3V_DS4) ++ &range GPIO_58 1 (MUX_MODE0 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2) ++ &range GPIO_63 1 (MUX_MODE0 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2) ++ &range GPIO_64 1 (MUX_MODE1 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2) ++ &range GPIO_65 1 (MUX_MODE0 | EDGE_NONE | PULL_UP | PAD_1V8_DS2) ++ &range GPIO_66 2 (MUX_MODE0 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2) ++ &range PRI_TDI 2 (MUX_MODE1 | EDGE_NONE | PULL_UP | PAD_1V8_DS2) ++ &range PRI_TCK 1 (MUX_MODE1 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2) ++ &range PRI_TDO 1 (MUX_MODE1 | EDGE_NONE | PULL_UP | PAD_1V8_DS2) ++ &range GPIO_74 1 (MUX_MODE0 | EDGE_NONE | PULL_UP | PAD_1V8_DS2) ++ &range GPIO_79 1 (MUX_MODE0 | EDGE_NONE | PULL_UP | PAD_1V8_DS2) ++ &range GPIO_80 1 (MUX_MODE0 | EDGE_NONE | PULL_UP | PAD_3V_DS4) ++ &range GPIO_81 3 (MUX_MODE0 | EDGE_NONE | PULL_UP | PAD_1V8_DS2) ++ &range GPIO_90 1 (MUX_MODE0 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2) ++ &range GPIO_91 2 (MUX_MODE0 | EDGE_NONE | PULL_UP | PAD_1V8_DS2) ++ &range DVL0 2 (MUX_MODE1 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2) ++ &range GPIO_110 1 (MUX_MODE0 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2) ++ &range GPIO_114 1 (MUX_MODE0 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2) ++ &range GPIO_115 2 (MUX_MODE0 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2) ++ &range GPIO_123 1 (MUX_MODE0 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2) ++ &range GPIO_124 1 (MUX_MODE0 | EDGE_NONE | PULL_UP | PAD_1V8_DS2) ++ &range GPIO_125 3 (MUX_MODE0 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2) ++ >; ++ ++ usbp1_vbus: usbp1_vbus { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_66, MUX_MODE0, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) /* drive_vbus1_iso */ ++ >; ++ }; ++ ++ gpio80_pmx_func0: gpio80_pmx_func0 { ++ pinctrl-single,pins = < ++ K1X_PADCONF(GPIO_80, MUX_MODE0, (EDGE_BOTH | PULL_UP | PAD_3V_DS4)) /* mmc cd */ ++ >; ++ }; ++}; ++ ++&gpio{ ++ gpio-ranges = < ++ &pinctrl 49 GPIO_49 2 ++ &pinctrl 58 GPIO_58 1 ++ &pinctrl 63 GPIO_63 1 ++ &pinctrl 65 GPIO_65 3 ++ &pinctrl 70 PRI_TDI 4 ++ &pinctrl 74 GPIO_74 1 ++ &pinctrl 79 GPIO_79 1 ++ &pinctrl 80 GPIO_80 4 ++ &pinctrl 90 GPIO_90 3 ++ &pinctrl 96 DVL0 2 ++ &pinctrl 110 GPIO_110 1 ++ &pinctrl 114 GPIO_114 3 ++ &pinctrl 123 GPIO_123 5 ++ >; ++}; ++ ++&udc { ++ status = "okay"; ++}; ++ ++&usbphy1 { ++ status = "okay"; ++}; ++ ++&ehci1 { ++ vbus-supply = <&usb2hub>; ++ status = "okay"; ++}; ++ ++&usb2phy { ++ status = "okay"; ++}; ++ ++&combphy { ++ status = "okay"; ++}; ++ ++ ++&usbdrd3 { ++ status = "okay"; ++ vbus-supply = <&usb3hub>; ++ dwc3@c0a00000 { ++ dr_mode = "host"; ++ phy_type = "utmi"; ++ snps,dis_enblslpm_quirk; ++ snps,dis_u2_susphy_quirk; ++ snps,dis_u3_susphy_quirk; ++ snps,dis-del-phy-power-chg-quirk; ++ snps,dis-tx-ipgap-linecheck-quirk; ++ }; ++}; ++ ++&sdhci0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_mmc1 &gpio80_pmx_func0>; ++ bus-width = <4>; ++ cd-gpios = <&gpio 80 0>; ++ cd-inverted; ++ cap-sd-highspeed; ++ sdh-phy-module = <0>; ++ clk-src-freq = <204800000>; ++ status = "okay"; ++}; ++ ++/* eMMC */ ++&sdhci2 { ++ bus-width = <8>; ++ non-removable; ++ mmc-hs400-1_8v; ++ mmc-hs400-enhanced-strobe; ++ sdh-phy-module = <1>; ++ clk-src-freq = <375000000>; ++ status = "okay"; ++}; ++ ++ð0 { ++ status = "okay"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_gmac0>; ++ ++ phy-reset-pin = <110>; ++ ++ clk_tuning_enable; ++ clk-tuning-by-delayline; ++ tx-phase = <90>; ++ rx-phase = <73>; ++ ++ phy-mode = "rgmii"; ++ phy-addr = <1>; ++ phy-handle = <&rgmii>; ++ ++ ref-clock-from-phy; ++ ++ mdio { ++ #address-cells = <0x1>; ++ #size-cells = <0x0>; ++ rgmii: phy@0 { ++ compatible = "ethernet-phy-id001c.c916"; ++ device_type = "ethernet-phy"; ++ reg = <0x1>; ++ }; ++ }; ++}; ++ ++&pcie0_rc { ++ status = "disabled"; ++}; ++ ++&pcie1_rc { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_pcie1_3>; ++ status = "disabled"; ++}; ++ ++&qspi { ++ status = "okay"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_qspi>; ++ ++ flash@0 { ++ compatible = "jedec,spi-nor"; ++ reg = <0>; ++ spi-max-frequency = <26500000>; ++ m25p,fast-read; ++ broken-flash-reset; ++ status = "okay"; ++ }; ++}; ++ ++&efuse { ++ status = "okay"; ++}; ++ ++&dpu { ++ status = "okay"; ++}; ++ ++&hdmi { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_hdmi_0>; ++ status = "okay"; ++}; ++ ++&pwm14 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_pwm14_1>; ++ status = "disabled"; ++}; ++ ++&backlight { ++ pwms = <&pwm14 0 2000>; ++ default-brightness-level = <6>; ++ status = "disabled"; ++}; ++ ++&mipi_dsi { ++ status = "disabled"; ++}; ++ ++&panel { ++ dcp-gpios = <&gpio 82 0>; ++ dcn-gpios = <&gpio 83 0>; ++ backlight = <&backlight>; ++ reset-gpios = <&gpio 81 0>; ++ status = "disabled"; ++}; +--- /dev/null ++++ b/arch/riscv/dts/x1_orangepi-rv2.dts +@@ -0,0 +1,342 @@ ++// SPDX-License-Identifier: (GPL-2.0 OR MIT) ++/* Copyright (c) 2023 Ky, Inc */ ++ ++/dts-v1/; ++ ++#include "k1-x.dtsi" ++#include "k1-x_pinctrl.dtsi" ++#include "k1-x_spm8821.dtsi" ++ ++/ { ++ model = "ky x1 orangepi-rv2 board"; ++ ++ aliases { ++ efuse_power = &ldo_31; ++ }; ++ ++ memory@0 { ++ device_type = "memory"; ++ reg = <0x00000000 0x00000000 0x00000000 0x80000000>; ++ }; ++ ++ chosen { ++ bootargs = "earlycon=sbi console=ttyS0,115200 debug loglevel=8,initcall_debug=1 rdinit=/init.tmp"; ++ stdout-path = "serial0:115200n8"; ++ }; ++ ++ usb2hub: usb2hub { ++ compatible = "spacemit,usb-hub"; ++ vbus-gpios = <&gpio 123 0>; /* for usb2 hub output vbus */ ++ status = "okay"; ++ }; ++ ++ usb3hub: usb3hub { ++ compatible = "spacemit,usb-hub"; ++ vbus-gpios = <&gpio 79 0>; /* gpio_79 for usb3 pwren */ ++ status = "okay"; ++ }; ++ ++ vcc5v_otg: vcc5v-otg-regulator { ++ u-boot,dm-spl; ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc5v_otg"; ++ regulator-always-on; ++ regulator-boot-on; ++ enable-active-high; ++ gpio = <&gpio 126 0>; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ }; ++ ++ vcc3v3_pcie: vcc3v3-pcie-regulator { ++ u-boot,dm-spl; ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc3v3_pcie"; ++ regulator-always-on; ++ regulator-boot-on; ++ enable-active-high; ++ gpio = <&gpio 116 0>; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ }; ++ ++ gpio-leds { ++ //u-boot,dm-pre-reloc; ++ compatible = "gpio-leds"; ++ status = "okay"; ++ ++ act-led { ++ //u-boot,dm-pre-reloc; ++ gpios=<&gpio 96 1>; ++ label = "status_led"; ++ default-state = "on"; ++ }; ++ }; ++}; ++ ++&cpus { ++ timebase-frequency = <24000000>; ++}; ++ ++&uart0 { ++ status = "okay"; ++}; ++ ++&i2c0 { ++ status = "disabled"; ++}; ++ ++&i2c1 { ++ status = "disabled"; ++}; ++ ++&i2c2 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_i2c2_0>; ++ status = "okay"; ++ ++ eeprom@50{ ++ compatible = "atmel,24c02"; ++ reg = <0x50>; ++ vin-supply-names = "eeprom_1v8"; ++ status = "okay"; ++ }; ++}; ++ ++&i2c3 { ++ status = "disabled"; ++}; ++ ++&i2c4 { ++ clock-frequency = <400000>; ++ status = "okay"; ++}; ++ ++&i2c5 { ++ status = "disabled"; ++}; ++ ++&i2c6 { ++ status = "disabled"; ++}; ++ ++&i2c7 { ++ status = "disabled"; ++}; ++ ++&pinctrl { ++ pinctrl-single,gpio-range = < ++ &range GPIO_49 2 (MUX_MODE0 | EDGE_NONE | PULL_UP | PAD_3V_DS4) ++ &range GPIO_58 1 (MUX_MODE0 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2) ++ &range GPIO_63 1 (MUX_MODE0 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2) ++ &range GPIO_64 1 (MUX_MODE1 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2) ++ &range GPIO_65 1 (MUX_MODE0 | EDGE_NONE | PULL_UP | PAD_1V8_DS2) ++ &range GPIO_66 2 (MUX_MODE0 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2) ++ &range PRI_TDI 2 (MUX_MODE1 | EDGE_NONE | PULL_UP | PAD_1V8_DS2) ++ &range PRI_TCK 1 (MUX_MODE1 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2) ++ &range PRI_TDO 1 (MUX_MODE1 | EDGE_NONE | PULL_UP | PAD_1V8_DS2) ++ &range GPIO_74 1 (MUX_MODE0 | EDGE_NONE | PULL_UP | PAD_1V8_DS2) ++ &range GPIO_79 1 (MUX_MODE0 | EDGE_NONE | PULL_UP | PAD_1V8_DS2) ++ &range GPIO_80 1 (MUX_MODE0 | EDGE_NONE | PULL_UP | PAD_3V_DS4) ++ &range GPIO_81 3 (MUX_MODE0 | EDGE_NONE | PULL_UP | PAD_1V8_DS2) ++ &range GPIO_90 1 (MUX_MODE0 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2) ++ &range GPIO_91 2 (MUX_MODE0 | EDGE_NONE | PULL_UP | PAD_1V8_DS2) ++ &range DVL0 2 (MUX_MODE1 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2) ++ &range GPIO_110 1 (MUX_MODE0 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2) ++ &range GPIO_114 1 (MUX_MODE0 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2) ++ &range GPIO_115 2 (MUX_MODE0 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2) ++ &range GPIO_123 1 (MUX_MODE0 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2) ++ &range GPIO_124 1 (MUX_MODE0 | EDGE_NONE | PULL_UP | PAD_1V8_DS2) ++ &range GPIO_125 3 (MUX_MODE0 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2) ++ >; ++ ++ usbp1_vbus: usbp1_vbus { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_66, MUX_MODE0, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) /* drive_vbus1_iso */ ++ >; ++ }; ++ ++ gpio80_pmx_func0: gpio80_pmx_func0 { ++ pinctrl-single,pins = < ++ K1X_PADCONF(GPIO_80, MUX_MODE0, (EDGE_BOTH | PULL_UP | PAD_3V_DS4)) /* mmc cd */ ++ >; ++ }; ++}; ++ ++&gpio{ ++ gpio-ranges = < ++ &pinctrl 49 GPIO_49 2 ++ &pinctrl 58 GPIO_58 1 ++ &pinctrl 63 GPIO_63 1 ++ &pinctrl 65 GPIO_65 3 ++ &pinctrl 70 PRI_TDI 4 ++ &pinctrl 74 GPIO_74 1 ++ &pinctrl 79 GPIO_79 1 ++ &pinctrl 80 GPIO_80 4 ++ &pinctrl 90 GPIO_90 3 ++ &pinctrl 96 DVL0 2 ++ &pinctrl 110 GPIO_110 1 ++ &pinctrl 114 GPIO_114 3 ++ &pinctrl 123 GPIO_123 5 ++ >; ++}; ++ ++&udc { ++ status = "okay"; ++}; ++ ++&usbphy1 { ++ status = "okay"; ++}; ++ ++&ehci1 { ++ vbus-supply = <&usb2hub>; ++ status = "okay"; ++}; ++ ++&usb2phy { ++ status = "okay"; ++}; ++ ++&combphy { ++ status = "okay"; ++}; ++ ++ ++&usbdrd3 { ++ status = "okay"; ++ vbus-supply = <&usb3hub>; ++ dwc3@c0a00000 { ++ dr_mode = "host"; ++ phy_type = "utmi"; ++ snps,dis_enblslpm_quirk; ++ snps,dis_u2_susphy_quirk; ++ snps,dis_u3_susphy_quirk; ++ snps,dis-del-phy-power-chg-quirk; ++ snps,dis-tx-ipgap-linecheck-quirk; ++ }; ++}; ++ ++&sdhci0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_mmc1 &gpio80_pmx_func0>; ++ bus-width = <4>; ++ cd-gpios = <&gpio 80 0>; ++ cd-inverted; ++ cap-sd-highspeed; ++ sdh-phy-module = <0>; ++ clk-src-freq = <204800000>; ++ status = "okay"; ++}; ++ ++/* eMMC */ ++&sdhci2 { ++ bus-width = <8>; ++ non-removable; ++ mmc-hs400-1_8v; ++ mmc-hs400-enhanced-strobe; ++ sdh-phy-module = <1>; ++ clk-src-freq = <375000000>; ++ status = "okay"; ++}; ++ ++ð0 { ++ status = "okay"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_gmac0>; ++ ++ phy-reset-pin = <110>; ++ ++ clk_tuning_enable; ++ clk-tuning-by-delayline; ++ tx-phase = <90>; ++ rx-phase = <73>; ++ ++ phy-mode = "rgmii"; ++ phy-addr = <1>; ++ phy-handle = <&rgmii>; ++ ++ ref-clock-from-phy; ++ ++ mdio { ++ #address-cells = <0x1>; ++ #size-cells = <0x0>; ++ rgmii: phy@0 { ++ compatible = "ethernet-phy-id001c.c916"; ++ device_type = "ethernet-phy"; ++ reg = <0x1>; ++ }; ++ }; ++}; ++ ++&pcie0_rc { ++ status = "disabled"; ++}; ++ ++&pcie1_rc { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_pcie1_3>; ++ k1x,pwr_on = <&gpio 116 0>; ++ status = "okay"; ++}; ++ ++&pcie2_rc { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_pcie2_4>; ++ status = "okay"; ++}; ++ ++&qspi { ++ status = "okay"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_qspi>; ++ ++ flash@0 { ++ compatible = "jedec,spi-nor"; ++ reg = <0>; ++ spi-max-frequency = <26500000>; ++ m25p,fast-read; ++ broken-flash-reset; ++ status = "okay"; ++ }; ++}; ++ ++&efuse { ++ status = "okay"; ++}; ++ ++&dpu { ++ status = "okay"; ++}; ++ ++&hdmi { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_hdmi_0>; ++ status = "okay"; ++}; ++ ++&pwm14 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_pwm14_1>; ++ status = "disabled"; ++}; ++ ++&backlight { ++ pwms = <&pwm14 0 2000>; ++ default-brightness-level = <6>; ++ status = "disabled"; ++}; ++ ++&mipi_dsi { ++ status = "disabled"; ++}; ++ ++&panel { ++ dcp-gpios = <&gpio 82 0>; ++ dcn-gpios = <&gpio 83 0>; ++ backlight = <&backlight>; ++ reset-gpios = <&gpio 81 0>; ++ status = "disabled"; ++}; +--- a/board/spacemit/k1-x/configs/uboot_fdt.its ++++ b/board/spacemit/k1-x/configs/uboot_fdt.its +@@ -172,6 +172,24 @@ + algo = "crc32"; + }; + }; ++ fdt_18 { ++ description = "x1_orangepi-rv2"; ++ type = "flat_dt"; ++ compression = "none"; ++ data = /incbin/("../dtb/x1_orangepi-rv2.dtb"); ++ hash-1 { ++ algo = "crc32"; ++ }; ++ }; ++ fdt_19 { ++ description = "x1_orangepi-r2s"; ++ type = "flat_dt"; ++ compression = "none"; ++ data = /incbin/("../dtb/x1_orangepi-r2s.dtb"); ++ hash-1 { ++ algo = "crc32"; ++ }; ++ }; + }; + + configurations { +@@ -261,5 +279,15 @@ + loadables = "uboot"; + fdt = "fdt_17"; + }; ++ conf_18 { ++ description = "x1_orangepi-rv2"; ++ loadables = "uboot"; ++ fdt = "fdt_18"; ++ }; ++ conf_19 { ++ description = "x1_orangepi-r2s"; ++ loadables = "uboot"; ++ fdt = "fdt_19"; ++ }; + }; + }; diff --git a/package/boot/uboot-spacemit/patches/0005-update-k1-defconfig.patch b/package/boot/uboot-spacemit/patches/0005-update-k1-defconfig.patch new file mode 100644 index 00000000000000..37fbcbe410b7db --- /dev/null +++ b/package/boot/uboot-spacemit/patches/0005-update-k1-defconfig.patch @@ -0,0 +1,111 @@ +From 5b9b09e674f866e5851b2d352ce190a757ad8079 Mon Sep 17 00:00:00 2001 +From: Andre Heider +Date: Wed, 29 Apr 2026 13:41:08 +0200 +Subject: [PATCH] update k1 defconfig + +Enable distro defaults, revert to sane defaults and enable +CONFIG_FIT_BEST_MATCH for multi fit images. +--- + configs/k1_defconfig | 22 +++------------------- + 1 file changed, 3 insertions(+), 19 deletions(-) + +--- a/configs/k1_defconfig ++++ b/configs/k1_defconfig +@@ -3,7 +3,7 @@ CONFIG_SYS_TEXT_BASE=0x00200000 + CONFIG_SYS_MALLOC_LEN=0x1000000 + CONFIG_NR_DRAM_BANKS=2 + CONFIG_SPL_LDSCRIPT="arch/$(ARCH)/cpu/x60/u-boot-spl.lds" +-CONFIG_ENV_SIZE=0x4000 ++CONFIG_ENV_SIZE=0x10000 + CONFIG_ENV_OFFSET=0x60000 + CONFIG_DM_GPIO=y + CONFIG_SPL_DM_SPI=y +@@ -24,25 +24,18 @@ CONFIG_K1_X_BOARD_ASIC=y + CONFIG_ARCH_RV64I=y + CONFIG_RISCV_SMODE=y + # CONFIG_SPL_SMP is not set +-CONFIG_LOCALVERSION="spacemit" +-CONFIG_ENV_VARS_UBOOT_CONFIG=y ++CONFIG_DISTRO_DEFAULTS=y + CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y + CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x1000000 + CONFIG_STACK_SIZE=0x100000 + CONFIG_FIT=y ++CONFIG_FIT_BEST_MATCH=y + CONFIG_SPL_FIT_SIGNATURE=y + CONFIG_SPL_LOAD_FIT_ADDRESS=0x08000000 + # CONFIG_BOOTSTD is not set + CONFIG_LEGACY_IMAGE_FORMAT=y +-CONFIG_SUPPORT_RAW_INITRD=y + CONFIG_OF_BOARD_SETUP=y +-CONFIG_BOOTDELAY=0 +-CONFIG_AUTOBOOT_KEYED=y +-CONFIG_AUTOBOOT_STOP_STR="s" +-CONFIG_USE_BOOTCOMMAND=y + CONFIG_BOOTCOMMAND="bootm 0x08000000" +-CONFIG_LOGLEVEL=7 +-CONFIG_SPL_LOGLEVEL=1 + # CONFIG_SYS_DEVICE_NULLDEV is not set + CONFIG_DISPLAY_CPUINFO=y + CONFIG_DISPLAY_BOARDINFO=y +@@ -82,7 +75,6 @@ CONFIG_SPL_FASTBOOT_LOAD=y + CONFIG_SPL_USB_SDP_SUPPORT=y + CONFIG_SPL_OPENSBI_SCRATCH_OPTIONS=0x0 + CONFIG_FDT_SIMPLEFB=y +-CONFIG_HUSH_PARSER=y + CONFIG_SYS_CBSIZE=256 + CONFIG_SYS_PBSIZE=276 + # CONFIG_CMD_CPU is not set +@@ -102,20 +94,16 @@ CONFIG_CMD_I2C=y + CONFIG_CMD_MMC=y + CONFIG_CMD_BKOPS_ENABLE=y + CONFIG_CMD_MTD=y +-CONFIG_CMD_PART=y + # CONFIG_CMD_SCSI is not set + CONFIG_CMD_USB=y + CONFIG_CMD_WDT=y +-CONFIG_CMD_DHCP=y + CONFIG_CMD_TFTPPUT=y + CONFIG_CMD_TFTPSRV=y + CONFIG_SYS_DISABLE_AUTOLOAD=y +-CONFIG_CMD_PXE=y + CONFIG_CMD_BMP=y + CONFIG_CMD_TIME=y + CONFIG_CMD_GETTIME=y + CONFIG_CMD_TIMER=y +-CONFIG_CMD_SYSBOOT=y + CONFIG_CMD_EXT4_WRITE=y + CONFIG_CMD_SQUASHFS=y + CONFIG_CMD_FS_UUID=y +@@ -137,7 +125,6 @@ CONFIG_MULTI_DTB_FIT=y + CONFIG_ENV_OVERWRITE=y + CONFIG_ENV_IS_NOWHERE=y + CONFIG_ENV_IS_IN_MMC=y +-CONFIG_ENV_IS_IN_NFS=y + CONFIG_ENV_IS_IN_MTD=y + CONFIG_SYS_MMC_ENV_DEV=1 + # CONFIG_SPL_ENV_IS_NOWHERE is not set +@@ -149,7 +136,6 @@ CONFIG_IP_DEFRAG=y + CONFIG_NET_MAXDEFRAG=65535 + CONFIG_TFTP_BLOCKSIZE=32768 + CONFIG_KEEP_SERVERADDR=y +-CONFIG_BOOTP_SERVERIP=y + CONFIG_REGMAP=y + CONFIG_DEVRES=y + # CONFIG_SCSI_AHCI is not set +@@ -258,7 +244,6 @@ CONFIG_USB_DWC3=y + # CONFIG_USB_DWC3_GADGET is not set + CONFIG_USB_DWC3_GENERIC=y + CONFIG_TYPEC_HUSB239=y +-CONFIG_USB_STORAGE=y + CONFIG_USB_KEYBOARD=y + CONFIG_SYS_USB_EVENT_POLL_COMPATIBLE=y + CONFIG_USB_GADGET=y +@@ -289,7 +274,6 @@ CONFIG_JFFS2_NOR=y + CONFIG_JFFS2_USE_MTD_READ=y + CONFIG_UBIFS_SILENCE_MSG=y + CONFIG_IMAGE_SPARSE_TRANSFER_BLK_NUM=0x3000 +-CONFIG_PRINT_TIMESTAMP=y + # CONFIG_SPL_USE_TINY_PRINTF is not set + # CONFIG_RSA is not set + # CONFIG_SPL_SHA1 is not set diff --git a/package/boot/uboot-spacemit/patches/0006-replace-the-vendor-env.patch b/package/boot/uboot-spacemit/patches/0006-replace-the-vendor-env.patch new file mode 100644 index 00000000000000..f75b64c9d33805 --- /dev/null +++ b/package/boot/uboot-spacemit/patches/0006-replace-the-vendor-env.patch @@ -0,0 +1,390 @@ +From 43ae86fa6e2e804bfe9df5fb9caeeae28fd82aec Mon Sep 17 00:00:00 2001 +From: Andre Heider +Date: Thu, 30 Apr 2026 16:51:59 +0200 +Subject: [PATCH] replace the vendor env + +Use distro independent extlinux, boot scripts and EFI instead. + +Set the envvar rootfs_uuid to the uuid of the partition 'rootfs', +which can be then be used in extlinux arguments. +--- + board/spacemit/k1-x/k1-x.env | 376 ++++------------------------------- + 1 file changed, 41 insertions(+), 335 deletions(-) + +--- a/board/spacemit/k1-x/k1-x.env ++++ b/board/spacemit/k1-x/k1-x.env +@@ -1,336 +1,42 @@ +-// Common parameter +-earlycon=sbi +-init=/init +-bootdelay=0 +-baudrate=115200 +-stderr=serial ++stderr=serial,vidconsole + stdin=serial,usbkbd,usbkbd1 +-stdout=serial +-workqueue.default_affinity_scope=system ++stdout=serial,vidconsole + +-//partitions/mtdparts/mtdids would set while flashing env.bin ++bootfs_name=bootfs ++rootfs_name=rootfs + +-// Nor flash rootfs device +-nor_root=/dev/mtdblock6 +-nor_rootfstype=squashfs ++set_rootfs_uuid=\ ++ setenv rootfs_uuid; \ ++ part number ${devtype} ${devnum} ${rootfs_name} rootfs_part && \ ++ part uuid ${devtype} ${devnum}:${rootfs_part} rootfs_uuid ++ ++try_boot=\ ++ echo "Trying to boot from ${devtype} ${devnum}:${distro_bootpart} ..."; \ ++ run set_rootfs_uuid && echo "rootfs UUID: ${rootfs_uuid}"; \ ++ if test -e ${devtype} ${devnum}:${distro_bootpart} /extlinux/extlinux.conf; then \ ++ sysboot ${devtype} ${devnum}:${distro_bootpart} any ${pxefile_addr_r} /extlinux/extlinux.conf; \ ++ elif test -e ${devtype} ${devnum}:${distro_bootpart} /boot/extlinux/extlinux.conf; then \ ++ sysboot ${devtype} ${devnum}:${distro_bootpart} any ${pxefile_addr_r} /boot/extlinux/extlinux.conf; \ ++ elif test -e ${devtype} ${devnum}:${distro_bootpart} /boot.scr; then \ ++ load ${devtype} ${devnum}:${distro_bootpart} ${scriptaddr} /boot.scr; source ${scriptaddr}; \ ++ elif test -e ${devtype} ${devnum}:${distro_bootpart} /boot/boot.scr; then \ ++ load ${devtype} ${devnum}:${distro_bootpart} ${scriptaddr} /boot/boot.scr; source ${scriptaddr}; \ ++ elif test -e ${devtype} ${devnum}:${distro_bootpart} EFI/BOOT/BOOTRISCV64.EFI; then \ ++ load ${devtype} ${devnum}:${distro_bootpart} ${kernel_addr_r} EFI/BOOT/BOOTRISCV64.EFI; bootefi ${kernel_addr_r}; \ ++ fi ++ ++set_bootfs_part=\ ++ part number ${devtype} ${devnum} ${bootfs_name} distro_bootpart || setenv distro_bootpart 1 ++ ++try_bootfs=\ ++ setenv devnum 0; \ ++ run set_bootfs_part; \ ++ run try_boot ++ ++autoboot=\ ++ echo; echo "Running on product: ${product_name}"; \ ++ run try_boot; \ ++ nvme scan; setenv devtype nvme; run try_bootfs ; \ ++ usb start; setenv devtype usb; run try_bootfs + +-// eMMC/SDCard rootfs device +-mmc_rootfstype=ext4 +- +-// NAND UBI rootfs device +-nand_rootfstype=ubifs +-nand_ubi_mtd=6 +-nand_ubi_dev=0 +-nand_ubi_bootfs_vol=bootfs +-nand_ubi_rootfs_vol=rootfs +-nand_mtd_name=user +- +-// rootfs part number must less than 99 +-rootfs_part_to_ul=echo "set rootfs_part to ul"; setexpr temp_num_0 ${rootfs_part} / a; \ +- setexpr temp_num_1 ${rootfs_part} % a; \ +- setenv rootfs_part ${temp_num_0}${temp_num_1}; +- +-// Get "rootfs" partition number in decimal, and set var "blk_root" +-// Variable "boot_devnum" is set during board_lat_init() +-set_rootfs_env=if test "${bootfs_devname}" = mmc; then \ +- setenv blk_root "/dev/mmcblk${boot_devnum}p${rootfs_part}"; \ +- elif test "${bootfs_devname}" = nvme; then \ +- setenv blk_root "/dev/nvme${boot_devnum}n1p${rootfs_part}"; \ +- else \ +- echo "not define rootfs part at this blk device, add to env"; \ +- fi; +- +-get_rootfs_env=part number ${bootfs_devname} ${boot_devnum} rootfs rootfs_part; \ +- setexpr rootfs_part ${rootfs_part} + 0; \ +- if test ${rootfs_part} > 9; then run rootfs_part_to_ul; fi; \ +- echo "get rootfs_part index:${rootfs_part}"; +- +-// get "rootfs" partition uuid, and set var "rootfs_uuid" +-get_rootfs_uuid=part number ${bootfs_devname} ${boot_devnum} rootfs rootfs_part; \ +- fsuuid ${bootfs_devname} ${boot_devnum}:${rootfs_part} rootfs_uuid; +- +-set_root_arg=run get_rootfs_uuid; \ +- setenv bootargs "${bootargs}" root=UUID=${rootfs_uuid}; +- +-//override here, otherwise gen random addr and save to eeprom by uboot +-//ethaddr=fe:fe:fe:22:22:01 +-//eth1addr=fe:fe:fe:22:22:02 +- +-ipaddr= +-netmask=255.255.255.0 +-serverip=10.0.92.148 +-gatewayip=10.0.92.1 +-net_data_path=net_flash_file/net_flash_file/ +-mac_mapping_file=/home/it/nfs/bianbu/mac_mapping.txt +- +-//net_flash_protocol=spacemit_tftp +- +-preboot= +-ramdisk_size=- +-ramdisk_combo=- +-knl_name=Image.itb +-ramdisk_name=initramfs-generic.img +-dtb_dir= +-dtb_name=k1-x_evb.dtb +-splashfile=bianbu.bmp +-grub_file=EFI/BOOT/BOOTRISCV64.EFI +-mdio_intf= +-phyaddr0=1 +-phy_link_time=10000 +-netdev=eth0 +- +-uboot_status=IN_UBOOT +- +-// EFI system partition +-esp_name=ESP +-esp_index=5 +-usb_start=true +- +-get_esp_index=env set esp_index ${bootfs_part}; \ +- part number ${bootfs_devname} ${boot_devnum} ${esp_name} esp_index; +- +-// Common boot args +-commonargs=setenv bootargs earlyprintk quiet splash plymouth.ignore-serial-consoles \ +- plymouth.prefer-fbcon clk_ignore_unused swiotlb=65536 \ +- workqueue.default_affinity_scope=${workqueue.default_affinity_scope} +-set_loglevel=if test "${loglevel}" != "";then \ +- setenv bootargs "${bootargs}" loglevel=${loglevel}; +- fi +- +-set_console=if test "${console}" != "";then \ +- setenv bootargs "${bootargs}" console=${console}; +- fi +- +-add_bootarg=run set_console; \ +- run set_loglevel; +- +-set_bootargs_unified=run commonargs; \ +- run add_bootarg; \ +- if test "${boot_device}" = nand; then \ +- run set_nand_args; \ +- elif test "${boot_device}" = nor; then \ +- run set_nor_args; \ +- run set_root_arg; \ +- elif test "${boot_device}" = mmc; then \ +- run set_mmc_args; \ +- run set_root_arg; \ +- elif test "${boot_device}" = nfs; then \ +- setenv bootargs "${bootargs}" root=/dev/nfs net.ifnames=0 nfsroot=${serverip}:${rootfs_path} bootfs=${serverip}:${bootfs_path} ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}::${netdev}:off noipath; \ +- else \ +- echo "Unknown boot_device: ${boot_device}"; \ +- fi; +- +-//detect product_name from env and select dtb file to load +-dtb_env=if test -n "${product_name}"; then \ +- if test "${product_name}" = k1_evb; then \ +- setenv dtb_name ${dtb_dir}/k1-x_evb.dtb; \ +- elif test "${product_name}" = k1_deb1; then \ +- setenv dtb_name ${dtb_dir}/k1-x_deb1.dtb; \ +- elif test "${product_name}" = k1_deb2; then \ +- setenv dtb_name ${dtb_dir}/k1-x_deb2.dtb; \ +- elif test "${product_name}" = k1_hs450; then \ +- setenv dtb_name ${dtb_dir}/k1-x_hs450.dtb; \ +- elif test "${product_name}" = k1_kx312; then \ +- setenv dtb_name ${dtb_dir}/k1-x_kx312.dtb; \ +- elif test "${product_name}" = k1_mingo; then \ +- setenv dtb_name ${dtb_dir}/k1-x_mingo.dtb; \ +- elif test "${product_name}" = k1_MINI-PC; then \ +- setenv dtb_name ${dtb_dir}/k1-x_MINI-PC.dtb; \ +- else \ +- echo "match dtb by product_name: ${dtb_dir}/${product_name}.dtb"; \ +- setenv dtb_name ${dtb_dir}/${product_name}.dtb; \ +- fi; \ +- fi; +- +-detect_dtb=echo "product_name: ${product_name}"; run dtb_env; echo "select ${dtb_name} to load"; +- +-loadknl=echo "Loading kernel..."; \ +- load ${bootfs_devname} ${boot_devnum}:${bootfs_part} ${kernel_addr_r} ${knl_name}; +- +-loadramdisk=echo "Loading ramdisk ..."; \ +- if load ${bootfs_devname} ${boot_devnum}:${bootfs_part} ${ramdisk_addr} ${ramdisk_name}; then \ +- size ${bootfs_devname} ${boot_devnum}:${bootfs_part} ${ramdisk_name}; \ +- setenv ramdisk_size ${filesize}; \ +- setenv ramdisk_combo ${ramdisk_addr}:${ramdisk_size}; \ +- else \ +- echo "load ramdisk from bootfs fail, use built-in ramdisk"; \ +- setenv ramdisk_addr -; \ +- fi; +- +-loaddtb=echo "Loading dtb..."; \ +- if load ${bootfs_devname} ${boot_devnum}:${bootfs_part} ${dtb_addr} ${dtb_name}; then \ +- else \ +- echo "load dtb from bootfs fail, use built-in dtb"; \ +- setenv dtb_addr ""; \ +- fi; +- +-load_grub=echo "Loading grub..."; \ +- load ${bootfs_devname} ${boot_devnum}:${esp_index} ${kernel_addr_r} ${grub_file}; +- +-# bootm command for fit image, booti command for PE or compress PE image +-start_kernel=fdt addr ${kernel_addr_r}; \ +- if fdt list /; then \ +- bootm ${kernel_addr_r} ${ramdisk_combo} ${dtb_addr}; \ +- else \ +- booti ${kernel_addr_r} ${ramdisk_combo} ${dtb_addr}; \ +- fi; +- +-boot_kernel=run set_root_arg; \ +- run detect_dtb; \ +- run loadknl; \ +- run loaddtb; \ +- run loadramdisk; \ +- run start_kernel; +- +-boot_grub=env set -e -bs product_name "${product_name}"; \ +- env set -e -bs bootargs "${bootargs}"; \ +- run usb_start; +- run load_grub; \ +- bootefi ${kernel_addr_r}; +- +-// Nor+ssd boot combo +-set_nor_args=setenv bootargs "${bootargs}" mtdparts=${mtdparts} rootfstype=ext4 +-nor_boot=echo "Try to boot from ${bootfs_devname}${boot_devnum} ..."; \ +- run commonargs; \ +- run add_bootarg; \ +- run set_nor_args; \ +- run get_esp_index; \ +- if test -e ${bootfs_devname} ${boot_devnum}:${esp_index} ${grub_file}; then \ +- run boot_grub; \ +- else \ +- run boot_kernel; \ +- fi; \ +- echo "########### boot failed by default config, check your boot config #############" +- +-//############################################################################## +-# spinand_ubifs boot +-fastboot_ubi_size=16 +-ubifs_list= mtd list; \ +- ubifsls; +-ubifs_loadimg=echo "Loading kernel image..."; \ +- if ubifsload ${kernel_addr_r} Image.itb; then \ +- echo "Loaded Image.itb successfully"; \ +- setenv boot_cmd "bootm"; \ +- elif ubifsload ${kernel_addr_r} Image; then \ +- echo "Loaded Image successfully"; \ +- setenv boot_cmd "booti"; \ +- else \ +- echo "Failed to load kernel image"; \ +- setenv boot_cmd ""; \ +- fi; +- +-ubifs_boot=echo "Trying to boot from UBIFS..."; \ +- run ubifs_loadimg; \ +- if test -n "${boot_cmd}"; then \ +- ${boot_cmd} ${kernel_addr_r}; \ +- else \ +- echo "No valid kernel image found"; \ +- fi; +- +-# Nand boot +-set_nand_args=setenv bootargs "${bootargs}" mtdparts=${mtdparts} root=ubi${nand_ubi_dev}:${nand_ubi_rootfs_vol} rootfstype=${nand_rootfstype} ubi.mtd=${nand_ubi_mtd}; +- +-nand_boot=echo "Try to boot from nand flash..."; \ +- run commonargs; \ +- run add_bootarg; \ +- run set_nand_args; \ +- echo "bootargs: ${bootargs}"; \ +- run detect_dtb; \ +- run ubifs_list; \ +- run ubifs_loadimg; \ +- if test -n "${boot_cmd}"; then \ +- if test "${boot_cmd}" = "bootm"; then \ +- echo "Booting FIT image with embedded DTB and ramdisk..."; \ +- ${boot_cmd} ${kernel_addr_r}; \ +- else \ +- echo "Loading separate DTB and ramdisk for raw kernel..."; \ +- if test -e ${dtb_name}; then \ +- echo "Loading dtb from UBIFS..."; \ +- ubifsload ${dtb_addr} ${dtb_name}; \ +- fi; \ +- if test -e ${ramdisk_name}; then \ +- echo "Loading ramdisk from UBIFS..."; \ +- ubifsload ${ramdisk_addr} ${ramdisk_name}; \ +- setenv ramdisk_size ${filesize}; \ +- setenv ramdisk_combo ${ramdisk_addr}:${ramdisk_size}; \ +- else \ +- setenv ramdisk_combo -; \ +- fi; \ +- echo "Booting with ${boot_cmd} command..."; \ +- ${boot_cmd} ${kernel_addr_r} ${ramdisk_combo} ${dtb_addr}; \ +- fi; \ +- else \ +- echo "No valid kernel image found"; \ +- fi; +- +-// eMMC/SDCard boot +-//############################################################################## +-set_mmc_args=setenv bootargs "${bootargs}" rootwait rootfstype=${mmc_rootfstype}; +- +-mmc_boot=echo "Try to boot from ${bootfs_devname}${boot_devnum} ..."; \ +- run commonargs; \ +- run add_bootarg; \ +- run set_mmc_args; \ +- run get_esp_index; \ +- if test -e ${bootfs_devname} ${boot_devnum}:${esp_index} ${grub_file}; then \ +- run boot_grub; \ +- else \ +- run boot_kernel; \ +- fi; \ +- echo "########### boot failed by default config, check your boot config #############" +- +-nfs_boot=echo "Try to boot from NFS ..."; \ +- run commonargs; \ +- run add_bootarg; \ +- setenv bootargs "${bootargs}" root=/dev/nfs net.ifnames=0 nfsroot=${serverip}:${rootfs_path} bootfs=${serverip}:${bootfs_path} ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}::${netdev}:off noipath; \ +- echo "bootargs: ${bootargs}"; \ +- run detect_dtb; \ +- echo "Loading kernel from NFS..."; \ +- nfs ${kernel_addr_r} ${serverip}:${bootfs_path}/${knl_name}; \ +- echo "Loading dtb from NFS..."; \ +- nfs ${dtb_addr} ${serverip}:${bootfs_path}/${dtb_name}; \ +- if test -n "${ramdisk_name}"; then \ +- echo "Loading ramdisk from NFS..."; \ +- nfs ${ramdisk_addr} ${serverip}:${bootfs_path}/${ramdisk_name}; \ +- setenv ramdisk_size ${filesize}; \ +- setenv ramdisk_combo ${ramdisk_addr}:${ramdisk_size}; \ +- else \ +- setenv ramdisk_combo -; \ +- fi; \ +- run start_kernel; \ +- echo "########### boot kernel failed from NFS, check your boot config #############" +- +-// Variable "boot_device" is set during board_late_init() +-autoboot=if test ${boot_device} = nand; then \ +- run nand_boot; \ +- elif test ${boot_device} = nor; then \ +- run nor_boot; \ +- elif test ${boot_device} = mmc; then \ +- run mmc_boot; \ +- elif test ${boot_device} = nfs; then \ +- run nfs_boot; \ +- fi; +- +-bootcmd=run autoboot; echo "run autoboot" +- +-// Boot menu definitions +-boot_default=echo "Current Boot Device: ${boot_device}" +-flash_default=echo "Returning to Boot Menu..." +-flash_from_usb=echo "recovery from usb...... "; \ +- flash_image usb; +-flash_from_mmc=echo "recovery from mmc...... " \ +- flash_image mmc; +-flash_from_net=echo "recovery from net...... " \ +- flash_image net; +- +-bootmenu_delay=5 +-bootmenu_0="-------- Boot Options --------"=run boot_default +-bootmenu_1="Boot from Nor"=run nor_boot +-bootmenu_2="Boot from Nand"=run nand_boot +-bootmenu_3="Boot from MMC"=run mmc_boot +-bootmenu_4="Autoboot"=run autoboot +-bootmenu_5="Show current Boot Device"=run boot_default +-bootmenu_6="-------- Flash Options --------"=run flash_default +-bootmenu_7="recovery from usb"=run flash_from_usb +-bootmenu_8="recovery from mmc"=run flash_from_mmc +-bootmenu_9="recovery from net"=run flash_from_net ++bootcmd=run autoboot diff --git a/package/boot/uboot-spacemit/patches/0007-disable-automatic-resizing-of-the-last-sdcard-partit.patch b/package/boot/uboot-spacemit/patches/0007-disable-automatic-resizing-of-the-last-sdcard-partit.patch new file mode 100644 index 00000000000000..003cc5cfbc9044 --- /dev/null +++ b/package/boot/uboot-spacemit/patches/0007-disable-automatic-resizing-of-the-last-sdcard-partit.patch @@ -0,0 +1,27 @@ +From 3bf39e8ffbeb5fec00d826504d5540b076905f42 Mon Sep 17 00:00:00 2001 +From: Andre Heider +Date: Sun, 3 May 2026 12:08:16 +0200 +Subject: [PATCH] disable automatic resizing of the last sdcard partition + +--- + board/spacemit/k1-x/k1x.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/board/spacemit/k1-x/k1x.c ++++ b/board/spacemit/k1-x/k1x.c +@@ -1036,6 +1036,7 @@ int board_late_init(void) + + setenv_boot_mode(); + ++#if 0 + // Resize the last partition for sd + const char *boot_device = env_get("devtype"); + if (boot_device && strcmp(boot_device, "mmc") == 0) { +@@ -1049,6 +1050,7 @@ int board_late_init(void) + } + } + } ++#endif + + /*save ram size to env, transfer to MB*/ + sprintf(ram_size_str, "mem=%dMB", (int)(gd->ram_size / SZ_1MB)); diff --git a/package/boot/uboot-spacemit/patches/0008-k1-x_-.dts-add-mainline-compatibles.patch b/package/boot/uboot-spacemit/patches/0008-k1-x_-.dts-add-mainline-compatibles.patch new file mode 100644 index 00000000000000..b9d0cc7cb3f5e6 --- /dev/null +++ b/package/boot/uboot-spacemit/patches/0008-k1-x_-.dts-add-mainline-compatibles.patch @@ -0,0 +1,65 @@ +From 32f8840bbd82b94f302adf107f51371d5f4787e5 Mon Sep 17 00:00:00 2001 +From: Andre Heider +Date: Fri, 1 May 2026 20:45:05 +0200 +Subject: [PATCH] k1-x_*.dts: add mainline compatibles + +This allows the board to identify itself using mainline compatibles. +For OpenSBI and u-boot's CONFIG_FIT_BEST_MATCH. +--- + arch/riscv/dts/k1-x_MUSE-Pi-Pro.dts | 1 + + arch/riscv/dts/k1-x_deb1.dts | 1 + + arch/riscv/dts/k1-x_milkv-jupiter.dts | 1 + + arch/riscv/dts/x1_orangepi-r2s.dts | 1 + + arch/riscv/dts/x1_orangepi-rv2.dts | 1 + + 5 files changed, 5 insertions(+) + +--- a/arch/riscv/dts/k1-x_MUSE-Pi-Pro.dts ++++ b/arch/riscv/dts/k1-x_MUSE-Pi-Pro.dts +@@ -9,6 +9,7 @@ + + / { + model = "spacemit k1-x MUSE-Pi-Pro board"; ++ compatible = "spacemit,musepi-pro", "spacemit,k1x", "spacemit,k1", "riscv"; + + aliases { + efuse_power = &ldo_31; +--- a/arch/riscv/dts/k1-x_deb1.dts ++++ b/arch/riscv/dts/k1-x_deb1.dts +@@ -9,6 +9,7 @@ + + / { + model = "spacemit k1-x deb1 board"; ++ compatible = "bananapi,bpi-f3", "spacemit,k1x", "spacemit,k1", "riscv"; + + aliases { + efuse_power = &ldo_31; +--- a/arch/riscv/dts/k1-x_milkv-jupiter.dts ++++ b/arch/riscv/dts/k1-x_milkv-jupiter.dts +@@ -9,6 +9,7 @@ + + / { + model = "Milk-V Jupiter"; ++ compatible = "milkv,jupiter", "spacemit,k1x", "spacemit,k1", "riscv"; + + aliases { + efuse_power = &ldo_31; +--- a/arch/riscv/dts/x1_orangepi-r2s.dts ++++ b/arch/riscv/dts/x1_orangepi-r2s.dts +@@ -9,6 +9,7 @@ + + / { + model = "ky x1 orangepi-r2s board"; ++ compatible = "xunlong,orangepi-r2s", "spacemit,k1x", "spacemit,k1", "riscv"; + + aliases { + efuse_power = &ldo_31; +--- a/arch/riscv/dts/x1_orangepi-rv2.dts ++++ b/arch/riscv/dts/x1_orangepi-rv2.dts +@@ -9,6 +9,7 @@ + + / { + model = "ky x1 orangepi-rv2 board"; ++ compatible = "xunlong,orangepi-rv2", "spacemit,k1x", "spacemit,k1", "riscv"; + + aliases { + efuse_power = &ldo_31; diff --git a/package/boot/uboot-spacemit/patches/0009-serial-ns16550-Add-Intel-XScale-support.patch b/package/boot/uboot-spacemit/patches/0009-serial-ns16550-Add-Intel-XScale-support.patch new file mode 100644 index 00000000000000..b5df15d6cb82c3 --- /dev/null +++ b/package/boot/uboot-spacemit/patches/0009-serial-ns16550-Add-Intel-XScale-support.patch @@ -0,0 +1,27 @@ +From 32c6ee580875a27a0ffd6620e57e704c5b294684 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Duje=20Mihanovi=C4=87?= +Date: Fri, 24 Jan 2025 16:47:48 +0100 +Subject: [PATCH] serial: ns16550: Add Intel XScale support +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Add compatible string for the Intel XScale variant of the 16550. Needed +to match upstream. + +Signed-off-by: Duje Mihanović +Reviewed-by: Stefan Roese +--- + drivers/serial/ns16550.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/serial/ns16550.c ++++ b/drivers/serial/ns16550.c +@@ -626,6 +626,7 @@ static const struct udevice_id ns16550_s + { .compatible = "ingenic,jz4780-uart", .data = PORT_JZ4780 }, + { .compatible = "nvidia,tegra20-uart", .data = PORT_NS16550 }, + { .compatible = "snps,dw-apb-uart", .data = PORT_NS16550 }, ++ { .compatible = "intel,xscale-uart", .data = PORT_NS16550 }, + {} + }; + #endif /* OF_REAL */ diff --git a/package/boot/uboot-spacemit/patches/0010-k1-x.dtsi-replace-uart-compatible-property-to-match-.patch b/package/boot/uboot-spacemit/patches/0010-k1-x.dtsi-replace-uart-compatible-property-to-match-.patch new file mode 100644 index 00000000000000..84d00fe419da58 --- /dev/null +++ b/package/boot/uboot-spacemit/patches/0010-k1-x.dtsi-replace-uart-compatible-property-to-match-.patch @@ -0,0 +1,21 @@ +From 1a65c2b4ae841bea8abeadacad120766d6c777e1 Mon Sep 17 00:00:00 2001 +From: Aurelien Jarno +Date: Fri, 10 Apr 2026 23:41:18 +0200 +Subject: [PATCH] k1-x.dtsi: replace uart compatible property to match upstream + Linux and OpenSBI + +--- + arch/riscv/dts/k1-x.dtsi | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/riscv/dts/k1-x.dtsi ++++ b/arch/riscv/dts/k1-x.dtsi +@@ -290,7 +290,7 @@ + }; + + uart0: uart@d4017000 { +- compatible = "ns16550"; ++ compatible = "spacemit,k1-uart", "intel,xscale-uart"; + reg = <0x00000000 0xD4017000 0x00000000 0x00000100>; + reg-shift = <2>; + reg-io-width = <4>; diff --git a/package/boot/uboot-spacemit/patches/0011-k1-x.dtsi-update-riscv-isa-properties-to-match-the-u.patch b/package/boot/uboot-spacemit/patches/0011-k1-x.dtsi-update-riscv-isa-properties-to-match-the-u.patch new file mode 100644 index 00000000000000..d784adbfa28340 --- /dev/null +++ b/package/boot/uboot-spacemit/patches/0011-k1-x.dtsi-update-riscv-isa-properties-to-match-the-u.patch @@ -0,0 +1,162 @@ +From 2c48bd3874f689599d10bf497757e356e0322430 Mon Sep 17 00:00:00 2001 +From: Aurelien Jarno +Date: Sat, 11 Apr 2026 21:27:55 +0200 +Subject: [PATCH] k1-x.dtsi: update riscv,isa properties to match the upstream + kernel + +It seems that zicbom and zicboz are very important for upstream version +of OpenSBI. +--- + arch/riscv/dts/k1-x.dtsi | 92 ++++++++++++++++++++++++++++++++++------ + 1 file changed, 80 insertions(+), 12 deletions(-) + +--- a/arch/riscv/dts/k1-x.dtsi ++++ b/arch/riscv/dts/k1-x.dtsi +@@ -28,7 +28,16 @@ + device_type = "cpu"; + reg = <0>; + status = "okay"; +- riscv,isa = "rv64imafdcv"; ++ riscv,isa = "rv64imafdcv_zicbom_zicbop_zicboz_zicntr_zicond_zicsr_zifencei_zihintpause_zihpm_zfh_zba_zbb_zbc_zbs_zkt_zvfh_zvkt_sscofpmf_sstc_svinval_svnapot_svpbmt"; ++ riscv,isa-base = "rv64i"; ++ riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "v", "zicbom", ++ "zicbop", "zicboz", "zicntr", "zicond", "zicsr", ++ "zifencei", "zihintpause", "zihpm", "zfh", "zba", ++ "zbb", "zbc", "zbs", "zkt", "zvfh", "zvkt", ++ "sscofpmf", "sstc", "svinval", "svnapot", "svpbmt"; ++ riscv,cbom-block-size = <64>; ++ riscv,cbop-block-size = <64>; ++ riscv,cboz-block-size = <64>; + mmu-type = "riscv,sv39"; + + cpu0_intc: interrupt-controller { +@@ -42,7 +51,16 @@ + device_type = "cpu"; + reg = <1>; + status = "okay"; +- riscv,isa = "rv64imafdcv"; ++ riscv,isa = "rv64imafdcv_zicbom_zicbop_zicboz_zicntr_zicond_zicsr_zifencei_zihintpause_zihpm_zfh_zba_zbb_zbc_zbs_zkt_zvfh_zvkt_sscofpmf_sstc_svinval_svnapot_svpbmt"; ++ riscv,isa-base = "rv64i"; ++ riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "v", "zicbom", ++ "zicbop", "zicboz", "zicntr", "zicond", "zicsr", ++ "zifencei", "zihintpause", "zihpm", "zfh", "zba", ++ "zbb", "zbc", "zbs", "zkt", "zvfh", "zvkt", ++ "sscofpmf", "sstc", "svinval", "svnapot", "svpbmt"; ++ riscv,cbom-block-size = <64>; ++ riscv,cbop-block-size = <64>; ++ riscv,cboz-block-size = <64>; + mmu-type = "riscv,sv39"; + + cpu1_intc: interrupt-controller { +@@ -56,7 +74,16 @@ + device_type = "cpu"; + reg = <2>; + status = "okay"; +- riscv,isa = "rv64imafdcv"; ++ riscv,isa = "rv64imafdcv_zicbom_zicbop_zicboz_zicntr_zicond_zicsr_zifencei_zihintpause_zihpm_zfh_zba_zbb_zbc_zbs_zkt_zvfh_zvkt_sscofpmf_sstc_svinval_svnapot_svpbmt"; ++ riscv,isa-base = "rv64i"; ++ riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "v", "zicbom", ++ "zicbop", "zicboz", "zicntr", "zicond", "zicsr", ++ "zifencei", "zihintpause", "zihpm", "zfh", "zba", ++ "zbb", "zbc", "zbs", "zkt", "zvfh", "zvkt", ++ "sscofpmf", "sstc", "svinval", "svnapot", "svpbmt"; ++ riscv,cbom-block-size = <64>; ++ riscv,cbop-block-size = <64>; ++ riscv,cboz-block-size = <64>; + mmu-type = "riscv,sv39"; + + cpu2_intc: interrupt-controller { +@@ -69,8 +96,16 @@ + compatible = "riscv"; + device_type = "cpu"; + reg = <3>; +- status = "okay"; +- riscv,isa = "rv64imafdcv"; ++ riscv,isa = "rv64imafdcv_zicbom_zicbop_zicboz_zicntr_zicond_zicsr_zifencei_zihintpause_zihpm_zfh_zba_zbb_zbc_zbs_zkt_zvfh_zvkt_sscofpmf_sstc_svinval_svnapot_svpbmt"; ++ riscv,isa-base = "rv64i"; ++ riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "v", "zicbom", ++ "zicbop", "zicboz", "zicntr", "zicond", "zicsr", ++ "zifencei", "zihintpause", "zihpm", "zfh", "zba", ++ "zbb", "zbc", "zbs", "zkt", "zvfh", "zvkt", ++ "sscofpmf", "sstc", "svinval", "svnapot", "svpbmt"; ++ riscv,cbom-block-size = <64>; ++ riscv,cbop-block-size = <64>; ++ riscv,cboz-block-size = <64>; + mmu-type = "riscv,sv39"; + + cpu3_intc: interrupt-controller { +@@ -83,8 +118,16 @@ + compatible = "riscv"; + device_type = "cpu"; + reg = <4>; +- status = "okay"; +- riscv,isa = "rv64imafdcv"; ++ riscv,isa = "rv64imafdcv_zicbom_zicbop_zicboz_zicntr_zicond_zicsr_zifencei_zihintpause_zihpm_zfh_zba_zbb_zbc_zbs_zkt_zvfh_zvkt_sscofpmf_sstc_svinval_svnapot_svpbmt"; ++ riscv,isa-base = "rv64i"; ++ riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "v", "zicbom", ++ "zicbop", "zicboz", "zicntr", "zicond", "zicsr", ++ "zifencei", "zihintpause", "zihpm", "zfh", "zba", ++ "zbb", "zbc", "zbs", "zkt", "zvfh", "zvkt", ++ "sscofpmf", "sstc", "svinval", "svnapot", "svpbmt"; ++ riscv,cbom-block-size = <64>; ++ riscv,cbop-block-size = <64>; ++ riscv,cboz-block-size = <64>; + mmu-type = "riscv,sv39"; + + cpu4_intc: interrupt-controller { +@@ -97,8 +140,16 @@ + compatible = "riscv"; + device_type = "cpu"; + reg = <5>; +- status = "okay"; +- riscv,isa = "rv64imafdcv"; ++ riscv,isa = "rv64imafdcv_zicbom_zicbop_zicboz_zicntr_zicond_zicsr_zifencei_zihintpause_zihpm_zfh_zba_zbb_zbc_zbs_zkt_zvfh_zvkt_sscofpmf_sstc_svinval_svnapot_svpbmt"; ++ riscv,isa-base = "rv64i"; ++ riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "v", "zicbom", ++ "zicbop", "zicboz", "zicntr", "zicond", "zicsr", ++ "zifencei", "zihintpause", "zihpm", "zfh", "zba", ++ "zbb", "zbc", "zbs", "zkt", "zvfh", "zvkt", ++ "sscofpmf", "sstc", "svinval", "svnapot", "svpbmt"; ++ riscv,cbom-block-size = <64>; ++ riscv,cbop-block-size = <64>; ++ riscv,cboz-block-size = <64>; + mmu-type = "riscv,sv39"; + + cpu5_intc: interrupt-controller { +@@ -111,8 +162,16 @@ + compatible = "riscv"; + device_type = "cpu"; + reg = <6>; +- status = "okay"; +- riscv,isa = "rv64imafdcv"; ++ riscv,isa = "rv64imafdcv_zicbom_zicbop_zicboz_zicntr_zicond_zicsr_zifencei_zihintpause_zihpm_zfh_zba_zbb_zbc_zbs_zkt_zvfh_zvkt_sscofpmf_sstc_svinval_svnapot_svpbmt"; ++ riscv,isa-base = "rv64i"; ++ riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "v", "zicbom", ++ "zicbop", "zicboz", "zicntr", "zicond", "zicsr", ++ "zifencei", "zihintpause", "zihpm", "zfh", "zba", ++ "zbb", "zbc", "zbs", "zkt", "zvfh", "zvkt", ++ "sscofpmf", "sstc", "svinval", "svnapot", "svpbmt"; ++ riscv,cbom-block-size = <64>; ++ riscv,cbop-block-size = <64>; ++ riscv,cboz-block-size = <64>; + mmu-type = "riscv,sv39"; + + cpu6_intc: interrupt-controller { +@@ -126,7 +185,16 @@ + device_type = "cpu"; + reg = <7>; + status = "okay"; +- riscv,isa = "rv64imafdcv"; ++ riscv,isa = "rv64imafdcv_zicbom_zicbop_zicboz_zicntr_zicond_zicsr_zifencei_zihintpause_zihpm_zfh_zba_zbb_zbc_zbs_zkt_zvfh_zvkt_sscofpmf_sstc_svinval_svnapot_svpbmt"; ++ riscv,isa-base = "rv64i"; ++ riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "v", "zicbom", ++ "zicbop", "zicboz", "zicntr", "zicond", "zicsr", ++ "zifencei", "zihintpause", "zihpm", "zfh", "zba", ++ "zbb", "zbc", "zbs", "zkt", "zvfh", "zvkt", ++ "sscofpmf", "sstc", "svinval", "svnapot", "svpbmt"; ++ riscv,cbom-block-size = <64>; ++ riscv,cbop-block-size = <64>; ++ riscv,cboz-block-size = <64>; + mmu-type = "riscv,sv39"; + + cpu7_intc: interrupt-controller { diff --git a/package/boot/uboot-spacemit/patches/0012-k1-x.dtsi-add-a-second-compatible-entry-matching-ups.patch b/package/boot/uboot-spacemit/patches/0012-k1-x.dtsi-add-a-second-compatible-entry-matching-ups.patch new file mode 100644 index 00000000000000..ffb2652905f31f --- /dev/null +++ b/package/boot/uboot-spacemit/patches/0012-k1-x.dtsi-add-a-second-compatible-entry-matching-ups.patch @@ -0,0 +1,93 @@ +From f12728c531eca8d51c86736e2471c0c056a814cd Mon Sep 17 00:00:00 2001 +From: Aurelien Jarno +Date: Sat, 11 Apr 2026 21:41:39 +0200 +Subject: [PATCH] k1-x.dtsi: add a second compatible entry matching upstream + Linux and OpenSBI for the i2c controllers + +--- + arch/riscv/dts/k1-x.dtsi | 18 +++++++++--------- + 1 file changed, 9 insertions(+), 9 deletions(-) + +--- a/arch/riscv/dts/k1-x.dtsi ++++ b/arch/riscv/dts/k1-x.dtsi +@@ -500,7 +500,7 @@ + }; + + i2c0: twsi0@d4010800 { +- compatible = "spacemit,i2c"; ++ compatible = "spacemit,i2c", "spacemit,k1-i2c"; + reg = <0x0 0xd4010800 0x0 0x38>; + clocks = <&ccu CLK_TWSI0>; + resets = <&reset RESET_TWSI0>; +@@ -510,7 +510,7 @@ + }; + + i2c1: twsi1@d4011000 { +- compatible = "spacemit,i2c"; ++ compatible = "spacemit,i2c", "spacemit,k1-i2c"; + reg = <0x0 0xd4011000 0x0 0x38>; + clocks = <&ccu CLK_TWSI1>; + resets = <&reset RESET_TWSI1>; +@@ -520,7 +520,7 @@ + }; + + i2c2: twsi2@d4012000 { +- compatible = "spacemit,i2c"; ++ compatible = "spacemit,i2c", "spacemit,k1-i2c"; + reg = <0x0 0xd4012000 0x0 0x38>; + clocks = <&ccu CLK_TWSI2>; + resets = <&reset RESET_TWSI2>; +@@ -530,7 +530,7 @@ + }; + + i2c3: twsi3@f0614000 { +- compatible = "spacemit,i2c"; ++ compatible = "spacemit,i2c", "spacemit,k1-i2c"; + reg = <0x0 0xf0614000 0x0 0x38>; + #address-cells = <1>; + #size-cells = <0>; +@@ -538,7 +538,7 @@ + }; + + i2c4: twsi4@d4012800 { +- compatible = "spacemit,i2c"; ++ compatible = "spacemit,i2c", "spacemit,k1-i2c"; + reg = <0x0 0xd4012800 0x0 0x38>; + clocks = <&ccu CLK_TWSI4>; + resets = <&reset RESET_TWSI4>; +@@ -548,7 +548,7 @@ + }; + + i2c5: twsi5@d4013800 { +- compatible = "spacemit,i2c"; ++ compatible = "spacemit,i2c", "spacemit,k1-i2c"; + reg = <0x0 0xd4013800 0x0 0x38>; + clocks = <&ccu CLK_TWSI5>; + resets = <&reset RESET_TWSI5>; +@@ -558,7 +558,7 @@ + }; + + i2c6: twsi6@d4018800 { +- compatible = "spacemit,i2c"; ++ compatible = "spacemit,i2c", "spacemit,k1-i2c"; + reg = <0x0 0xd4018800 0x0 0x38>; + clocks = <&ccu CLK_TWSI6>; + resets = <&reset RESET_TWSI6>; +@@ -568,7 +568,7 @@ + }; + + i2c7: twsi7@d401d000 { +- compatible = "spacemit,i2c"; ++ compatible = "spacemit,i2c", "spacemit,k1-i2c"; + reg = <0x0 0xd401d000 0x0 0x38>; + clocks = <&ccu CLK_TWSI7>; + resets = <&reset RESET_TWSI7>; +@@ -578,7 +578,7 @@ + }; + + i2c8: twsi8@d401d800 { +- compatible = "spacemit,i2c"; ++ compatible = "spacemit,i2c", "spacemit,k1-i2c"; + reg = <0x0 0xd401d800 0x0 0x38>; + clocks = <&ccu CLK_TWSI8>; + resets = <&reset RESET_TWSI8>; diff --git a/package/boot/uboot-spacemit/patches/0013-k1-x_spm8821.dtsi-add-a-second-compatible-entry-matc.patch b/package/boot/uboot-spacemit/patches/0013-k1-x_spm8821.dtsi-add-a-second-compatible-entry-matc.patch new file mode 100644 index 00000000000000..35eb159954f18f --- /dev/null +++ b/package/boot/uboot-spacemit/patches/0013-k1-x_spm8821.dtsi-add-a-second-compatible-entry-matc.patch @@ -0,0 +1,21 @@ +From c8eb20c278a99c818c9e3d1d07a6395dc6df721d Mon Sep 17 00:00:00 2001 +From: Andre Heider +Date: Sun, 3 May 2026 16:12:03 +0200 +Subject: [PATCH] k1-x_spm8821.dtsi: add a second compatible entry matching + upstream Linux and OpenSBI for the PMIC + +--- + arch/riscv/dts/k1-x_spm8821.dtsi | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/riscv/dts/k1-x_spm8821.dtsi ++++ b/arch/riscv/dts/k1-x_spm8821.dtsi +@@ -7,7 +7,7 @@ + status = "okay"; + + spm8821: pmic@41 { +- compatible = "spacemit,spm8821"; ++ compatible = "spacemit,spm8821", "spacemit,p1"; + reg = <0x41>; + bus = <8>; + u-boot,dm-spl; diff --git a/package/boot/uboot-spacemit/patches/0014-Add-support-to-embed-OpenSBI-firmware-into-the-u-boo.patch b/package/boot/uboot-spacemit/patches/0014-Add-support-to-embed-OpenSBI-firmware-into-the-u-boo.patch new file mode 100644 index 00000000000000..25701c38882c1a --- /dev/null +++ b/package/boot/uboot-spacemit/patches/0014-Add-support-to-embed-OpenSBI-firmware-into-the-u-boo.patch @@ -0,0 +1,183 @@ +From 101885c7840c3d58dc1150fa5fcfb7e6ecbcd026 Mon Sep 17 00:00:00 2001 +From: Aurelien Jarno +Date: Sun, 19 Apr 2026 16:30:17 +0000 +Subject: [PATCH] Add support to embed OpenSBI firmware into the u-boot.itb + image + +This is how upstream u-boot is typically configured. + +On the Milk-V Jupiter board the dedicated "opensbi" NOR flash partition +is too small to fit the upstream OpenSBI build. Embedding the firmware +in u-boot.itb enables the use of the upstream OpenSBI version on this +board. + +a.heider: orangepi rv2 and r2s too +--- + board/spacemit/k1-x/config.mk | 1 + + board/spacemit/k1-x/configs/uboot_fdt.its | 33 +++++++++++++++++++++++ + configs/k1_defconfig | 5 ++-- + 3 files changed, 36 insertions(+), 3 deletions(-) + +--- a/board/spacemit/k1-x/config.mk ++++ b/board/spacemit/k1-x/config.mk +@@ -33,6 +33,7 @@ cmd_build_itb = \ + $(srctree)/board/$(CONFIG_SYS_VENDOR)/$(CONFIG_SYS_BOARD)/dtb/ && \ + cp $(srctree)/u-boot-nodtb.bin \ + $(srctree)/board/$(CONFIG_SYS_VENDOR)/$(CONFIG_SYS_BOARD)/ && \ ++ cp $(OPENSBI) $(srctree)/board/$(CONFIG_SYS_VENDOR)/$(CONFIG_SYS_BOARD)/fw_dynamic.bin && \ + $(srctree)/tools/mkimage -f \ + $(srctree)/board/$(CONFIG_SYS_VENDOR)/$(CONFIG_SYS_BOARD)/configs/uboot_fdt.its \ + -r $(srctree)/$2;\ +--- a/board/spacemit/k1-x/configs/uboot_fdt.its ++++ b/board/spacemit/k1-x/configs/uboot_fdt.its +@@ -19,6 +19,20 @@ + }; + }; + ++ opensbi { ++ description = "OpenSBI fw_dynamic Firmware"; ++ type = "firmware"; ++ os = "opensbi"; ++ arch = "riscv"; ++ compression = "none"; ++ load = <0x0 0x0>; ++ entry = <0x0 0x0>; ++ data = /incbin/("../fw_dynamic.bin"); ++ hash-1 { ++ algo = "crc32"; ++ }; ++ }; ++ + fdt_1 { + description = "k1-x_deb1"; + type = "flat_dt"; +@@ -197,96 +211,115 @@ + conf_1 { + description = "k1-x_deb1"; + loadables = "uboot"; ++ firmware = "opensbi"; + fdt = "fdt_1"; + }; + conf_2 { + description = "k1-x_MINI-PC"; + loadables = "uboot"; ++ firmware = "opensbi"; + fdt = "fdt_2"; + }; + conf_3 { + description = "k1-x_MUSE-N1"; + loadables = "uboot"; ++ firmware = "opensbi"; + fdt = "fdt_3"; + }; + conf_4 { + description = "k1-x_MUSE-Pi"; + loadables = "uboot"; ++ firmware = "opensbi"; + fdt = "fdt_4"; + }; + conf_5 { + description = "k1-x_milkv-jupiter"; + loadables = "uboot"; ++ firmware = "opensbi"; + fdt = "fdt_5"; + }; + conf_6 { + description = "k1-x_MUSE-Book"; + loadables = "uboot"; ++ firmware = "opensbi"; + fdt = "fdt_6"; + }; + conf_7 { + description = "m1-x_milkv-jupiter"; + loadables = "uboot"; ++ firmware = "opensbi"; + fdt = "fdt_7"; + }; + conf_8 { + description = "k1-x_lpi3a"; + loadables = "uboot"; ++ firmware = "opensbi"; + fdt = "fdt_8"; + }; + conf_9 { + description = "k1-x_MUSE-Card"; + loadables = "uboot"; ++ firmware = "opensbi"; + fdt = "fdt_9"; + }; + conf_10 { + description = "k1-x_MUSE-Paper-mini-4g"; + loadables = "uboot"; ++ firmware = "opensbi"; + fdt = "fdt_10"; + }; + conf_11 { + description = "k1-x_ZT001H"; + loadables = "uboot"; ++ firmware = "opensbi"; + fdt = "fdt_11"; + }; + conf_12 { + description = "k1-x_uav"; + loadables = "uboot"; ++ firmware = "opensbi"; + fdt = "fdt_12"; + }; + conf_13 { + description = "k1-x_MUSE-Paper2"; + loadables = "uboot"; ++ firmware = "opensbi"; + fdt = "fdt_13"; + }; + conf_14 { + description = "k1-x_MUSE-Pi-Pro"; + loadables = "uboot"; ++ firmware = "opensbi"; + fdt = "fdt_14"; + }; + conf_15 { + description = "k1-x_LX-V10"; + loadables = "uboot"; ++ firmware = "opensbi"; + fdt = "fdt_15"; + }; + conf_16 { + description = "k1-x_som"; + loadables = "uboot"; ++ firmware = "opensbi"; + fdt = "fdt_16"; + }; + conf_17 { + description = "k1-x_ZT_RVOH007"; + loadables = "uboot"; ++ firmware = "opensbi"; + fdt = "fdt_17"; + }; + conf_18 { + description = "x1_orangepi-rv2"; + loadables = "uboot"; ++ firmware = "opensbi"; + fdt = "fdt_18"; + }; + conf_19 { + description = "x1_orangepi-r2s"; + loadables = "uboot"; ++ firmware = "opensbi"; + fdt = "fdt_19"; + }; + }; +--- a/configs/k1_defconfig ++++ b/configs/k1_defconfig +@@ -67,9 +67,8 @@ CONFIG_SPL_POWER=y + # CONFIG_SPL_SPI_FLASH_TINY is not set + CONFIG_SPL_SPI_FLASH_MTD=y + CONFIG_SPL_MTD_LOAD=y +-CONFIG_SYS_LOAD_IMAGE_PARTITION_NAME="opensbi" +-CONFIG_SYS_LOAD_IMAGE_SEC_PARTITION=y +-CONFIG_SYS_LOAD_IMAGE_SEC_PARTITION_NAME="uboot" ++CONFIG_SYS_LOAD_IMAGE_PARTITION_NAME="uboot" ++CONFIG_SYS_LOAD_IMAGE_SEC_PARTITION=n + CONFIG_SPL_USB_GADGET=y + CONFIG_SPL_FASTBOOT_LOAD=y + CONFIG_SPL_USB_SDP_SUPPORT=y diff --git a/package/boot/uboot-spacemit/update-bootloader.sh b/package/boot/uboot-spacemit/update-bootloader.sh new file mode 100755 index 00000000000000..a24f548a27025d --- /dev/null +++ b/package/boot/uboot-spacemit/update-bootloader.sh @@ -0,0 +1,73 @@ +#!/bin/sh + +dir="/usr/share/bootloader" +bootinfo_emmc="${dir}/bootinfo_emmc.bin" +stage1="${dir}/FSBL.bin" +stage2="${dir}/u-boot.itb" +nor= +emmc= + +die() { + echo "$(basename "$0"): error: $*" + exit 1 +} + +test -f "${bootinfo_emmc}" || die "missing file: ${bootinfo_emmc}" +test -f "${stage1}" || die "missing file: ${stage1}" +test -f "${stage2}" || die "missing file: ${stage2}" + +usage() { + printf "Usage: %s [-e] [-n]" "$(basename "$0")" + + printf "\n\t-e\tinstall first stage bootloader to eMMC" + printf "\n\t-n\tinstall bootloader to NOR\n" + exit 1 +} + +while getopts "en" OPTION +do + case $OPTION in + e) emmc=1;; + n) nor=1;; + *) echo "Invalid option passed to '$0' (options:$*)" + usage;; + esac +done + +test -z "${emmc}" -a -z "${nor}" && usage + +if test "${emmc}" = "1"; then + if test -b "/dev/mmcblk0boot0"; then + dev="mmcblk0boot0" + elif test -b "/dev/mmcblk1boot0"; then + dev="mmcblk1boot0" + else + die "no eMMC found" + fi + + echo "installing first stage bootloader to eMMC ${dev}" + echo 0 > /sys/block/${dev}/force_ro + sleep 1 + dd if="${bootinfo_emmc}" of="/dev/${dev}" bs=512 conv=notrunc + dd if="${stage1}" of="/dev/${dev}" bs=512 seek=1 conv=notrunc + sync + echo 1 > /sys/block/${dev}/force_ro +fi + +check_mtdpart() { + test -c /dev/mtd${1} || die "/dev/mtd${1} is not a MTD device" + name=$(cat "/sys/class/mtd/mtd${1}/name") + test "$name" = "$2" || die "/dev/mtd${1} name mismatch: \"${name}\", expected \"${2}\"" +} + +if test "${nor}" = "1"; then + check_mtdpart 2 "fsbl" + check_mtdpart 3 "env" + check_mtdpart 4 "opensbi" + check_mtdpart 5 "uboot" + echo "installing bootloader to NOR" + mtd write "${stage1}" /dev/mtd2 + mtd erase /dev/mtd3 + mtd erase /dev/mtd4 + mtd write "${stage2}" /dev/mtd5 +fi diff --git a/scripts/mkits.sh b/scripts/mkits.sh index fc2b580ee20281..43827b67e3fd45 100755 --- a/scripts/mkits.sh +++ b/scripts/mkits.sh @@ -28,6 +28,7 @@ usage() { printf "\n\t-v ==> set kernel version to 'version'" printf "\n\t-k ==> include kernel image 'kernel'" printf "\n\t-D ==> human friendly Device Tree Blob 'name'" + printf "\n\t-m ==> include multiple Device Tree Blobs 'name:dtb'" printf "\n\t-n ==> fdt unit-address 'address'" printf "\n\t-d ==> include Device Tree Blob 'dtb'" printf "\n\t-r ==> include RootFS blob 'rootfs'" @@ -46,10 +47,11 @@ ROOTFSNUM=1 INITRDNUM=1 HASH=sha1 LOADABLES= +MULTI_DTB= DTOVERLAY= DTADDR= -while getopts ":A:a:c:C:D:d:e:f:i:k:l:n:o:O:v:r:s:H:" OPTION +while getopts ":A:a:c:C:D:d:e:f:i:k:l:m:n:o:O:v:r:s:H:" OPTION do case $OPTION in A ) ARCH=$OPTARG;; @@ -63,6 +65,7 @@ do i ) INITRD=$OPTARG;; k ) KERNEL=$OPTARG;; l ) REFERENCE_CHAR=$OPTARG;; + m ) MULTI_DTB="$MULTI_DTB ${OPTARG}";; n ) FDTNUM=$OPTARG;; o ) OUTPUT=$OPTARG;; O ) DTOVERLAY="$DTOVERLAY ${OPTARG}";; @@ -82,6 +85,11 @@ if [ -z "${ARCH}" ] || [ -z "${COMPRESS}" ] || [ -z "${LOAD_ADDR}" ] || \ usage fi +if [ -n "${DTB}" ] && [ -n "${MULTI_DTB}" ]; then + echo "Either -d or -m can be passed, but not both" + exit 1 +fi + if [ -n "${ROOTFS}" ] && [ ! -f "${ROOTFS}".pagesync ]; then echo "Missing .pagesync blob for RootFS blob '${ROOTFS}'" exit 1 @@ -98,7 +106,29 @@ fi } # Conditionally create fdt information -if [ -n "${DTB}" ]; then +if [ -n "${MULTI_DTB}" ]; then + FDT_NODE="" + for mdtb in ${MULTI_DTB}; do + mdtb_dtb=${mdtb%%:*} + mdtb_name=${mdtb##*:} + FDT_NODE=${FDT_NODE}" + fdt${REFERENCE_CHAR}${mdtb_name} { + description = \"${ARCH_UPPER} OpenWrt ${mdtb_name} device tree blob\"; + data = /incbin/(\"${mdtb_dtb}\"); + type = \"flat_dt\"; + ${DTADDR:+load = <${DTADDR}>;} + arch = \"${ARCH}\"; + compression = \"none\"; + hash${REFERENCE_CHAR}1 { + algo = \"crc32\"; + }; + hash${REFERENCE_CHAR}2 { + algo = \"${HASH}\"; + }; + }; + " + done +elif [ -n "${DTB}" ]; then FDT_NODE=" fdt${REFERENCE_CHAR}$FDTNUM { description = \"${ARCH_UPPER} OpenWrt ${DEVICE} device tree blob\"; @@ -196,6 +226,35 @@ OVCONFIGS="" " done +if [ -n "${MULTI_DTB}" ]; then + CONFIGURATIONS_NODE="" + for mdtb in ${MULTI_DTB}; do + mdtb_name=${mdtb##*:} + CONFIGURATIONS_NODE=${CONFIGURATIONS_NODE}" + config${REFERENCE_CHAR}${mdtb_name} { + description = \"OpenWrt ${mdtb_name}\"; + compatible = \"${mdtb_name}\"; + kernel = \"kernel${REFERENCE_CHAR}1\"; + fdt = \"fdt${REFERENCE_CHAR}${mdtb_name}\"; + ${LOADABLES:+loadables = ${LOADABLES};} + ${INITRD_PROP} + }; +" + done +else + CONFIGURATIONS_NODE=" + default = \"${CONFIG}\"; + ${CONFIG} { + description = \"OpenWrt ${DEVICE}\"; + kernel = \"kernel${REFERENCE_CHAR}1\"; + ${FDT_PROP} + ${LOADABLES:+loadables = ${LOADABLES};} + ${COMPATIBLE_PROP} + ${INITRD_PROP} + }; +" +fi + # Create a default, fully populated DTS file DATA="/dts-v1/; @@ -227,16 +286,8 @@ ${ROOTFS_NODE} }; configurations { - default = \"${CONFIG}\"; - ${CONFIG} { - description = \"OpenWrt ${DEVICE}\"; - kernel = \"kernel${REFERENCE_CHAR}1\"; - ${FDT_PROP} - ${LOADABLES:+loadables = ${LOADABLES};} - ${COMPATIBLE_PROP} - ${INITRD_PROP} - }; - ${OVCONFIGS} +${CONFIGURATIONS_NODE} +${OVCONFIGS} }; };" diff --git a/target/linux/spacemit/Makefile b/target/linux/spacemit/Makefile new file mode 100644 index 00000000000000..e3040b8b02c52d --- /dev/null +++ b/target/linux/spacemit/Makefile @@ -0,0 +1,21 @@ +# SPDX-License-Identifier: GPL-2.0-only + +include $(TOPDIR)/rules.mk + +ARCH:=riscv64 +BOARD:=spacemit +BOARDNAME:=SpacemiT RISC-V +SUBTARGETS:=k1 +FEATURES:=boot-part dt emmc erofs fpu gpio pci pcie pinctrl regulator rootfs-part rtc separate_ramdisk usb + +KERNEL_PATCHVER:=6.18 + +include $(INCLUDE_DIR)/target.mk + +DEFAULT_PACKAGES += \ + kmod-leds-gpio \ + kmod-gpio-button-hotplug \ + mkf2fs \ + partx-utils + +$(eval $(call BuildTarget)) diff --git a/target/linux/spacemit/base-files/etc/inittab b/target/linux/spacemit/base-files/etc/inittab new file mode 100644 index 00000000000000..9820e7144bed61 --- /dev/null +++ b/target/linux/spacemit/base-files/etc/inittab @@ -0,0 +1,3 @@ +::sysinit:/etc/init.d/rcS S boot +::shutdown:/etc/init.d/rcS K shutdown +::askconsole:/usr/libexec/login.sh diff --git a/target/linux/spacemit/config-6.18 b/target/linux/spacemit/config-6.18 new file mode 100644 index 00000000000000..d02b9ad2116740 --- /dev/null +++ b/target/linux/spacemit/config-6.18 @@ -0,0 +1,466 @@ +CONFIG_64BIT=y +# CONFIG_ACLINT_SSWI is not set +# CONFIG_ACPI is not set +# CONFIG_ARCH_CANAAN is not set +CONFIG_ARCH_DMA_ADDR_T_64BIT=y +CONFIG_ARCH_DMA_DEFAULT_COHERENT=y +CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE=y +# CONFIG_ARCH_MICROCHIP is not set +CONFIG_ARCH_MMAP_RND_BITS=18 +CONFIG_ARCH_MMAP_RND_BITS_MAX=24 +CONFIG_ARCH_MMAP_RND_BITS_MIN=18 +CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=17 +CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y +CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y +CONFIG_ARCH_PROC_KCORE_TEXT=y +CONFIG_ARCH_RV64I=y +CONFIG_ARCH_SELECT_MEMORY_MODEL=y +# CONFIG_ARCH_SIFIVE is not set +CONFIG_ARCH_SPACEMIT=y +CONFIG_ARCH_SPARSEMEM_ENABLE=y +CONFIG_ARCH_STACKWALK=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +# CONFIG_ARCH_THEAD is not set +CONFIG_ARCH_VMLINUX_NEEDS_RELOCS=y +CONFIG_ARCH_WANTS_NO_INSTR=y +CONFIG_ARCH_WANTS_THP_SWAP=y +CONFIG_ARCH_WEAK_RELEASE_ACQUIRE=y +CONFIG_AUXILIARY_BUS=y +# CONFIG_AX45MP_L2_CACHE is not set +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_NVME=y +CONFIG_BLK_DEV_SD=y +CONFIG_BLK_PM=y +CONFIG_BLOCK_NOTIFIERS=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +CONFIG_CC_HAVE_STACKPROTECTOR_TLS=y +CONFIG_CLONE_BACKWARDS=y +CONFIG_CMODEL_MEDANY=y +# CONFIG_CMODEL_MEDLOW is not set +CONFIG_COMMON_CLK=y +CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1 +# CONFIG_COMPAT_32BIT_TIME is not set +CONFIG_CONFIGFS_FS=y +CONFIG_CONSOLE_LOGLEVEL_DEFAULT=15 +CONFIG_CONTEXT_TRACKING=y +CONFIG_CONTEXT_TRACKING_IDLE=y +CONFIG_CPUFREQ_DT=y +CONFIG_CPUFREQ_DT_PLATDEV=y +CONFIG_CPU_FREQ=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL=y +CONFIG_CPU_FREQ_GOV_ATTR_SET=y +CONFIG_CPU_FREQ_GOV_COMMON=y +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y +CONFIG_CPU_FREQ_GOV_USERSPACE=y +CONFIG_CPU_FREQ_STAT=y +CONFIG_CPU_IDLE=y +CONFIG_CPU_IDLE_GOV_LADDER=y +CONFIG_CPU_IDLE_GOV_MENU=y +CONFIG_CPU_IDLE_MULTIPLE_DRIVERS=y +CONFIG_CPU_MITIGATIONS=y +CONFIG_CPU_PM=y +CONFIG_CPU_RMAP=y +CONFIG_CPU_THERMAL=y +CONFIG_CRC32_ARCH=y +CONFIG_CRYPTO_DRBG=y +CONFIG_CRYPTO_DRBG_HMAC=y +CONFIG_CRYPTO_DRBG_MENU=y +CONFIG_CRYPTO_ECB=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_JITTERENTROPY=y +CONFIG_CRYPTO_JITTERENTROPY_MEMORY_BLOCKS=64 +CONFIG_CRYPTO_JITTERENTROPY_MEMORY_BLOCKSIZE=32 +CONFIG_CRYPTO_JITTERENTROPY_OSR=1 +CONFIG_CRYPTO_LIB_GF128MUL=y +CONFIG_CRYPTO_LIB_POLY1305_RSIZE=2 +CONFIG_CRYPTO_LIB_SHA512=y +CONFIG_CRYPTO_LIB_UTILS=y +CONFIG_CRYPTO_RNG=y +CONFIG_CRYPTO_SHA3=y +CONFIG_CRYPTO_SHA512=y +CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_MISC=y +CONFIG_DMADEVICES=y +CONFIG_DMA_BOUNCE_UNALIGNED_KMALLOC=y +CONFIG_DMA_DIRECT_REMAP=y +CONFIG_DMA_ENGINE=y +CONFIG_DMA_NEED_SYNC=y +CONFIG_DMA_OF=y +CONFIG_DMI=y +CONFIG_DMIID=y +# CONFIG_DMI_SYSFS is not set +CONFIG_DTC=y +CONFIG_DT_IDLE_STATES=y +CONFIG_DYNAMIC_SIGFRAME=y +CONFIG_EDAC_SUPPORT=y +CONFIG_EEPROM_AT24=y +CONFIG_EFI=y +CONFIG_EFIVAR_FS=m +# CONFIG_EFI_BOOTLOADER_CONTROL is not set +# CONFIG_EFI_CAPSULE_LOADER is not set +# CONFIG_EFI_COCO_SECRET is not set +# CONFIG_EFI_DISABLE_PCI_DMA is not set +# CONFIG_EFI_DISABLE_RUNTIME is not set +CONFIG_EFI_EARLYCON=y +CONFIG_EFI_ESRT=y +CONFIG_EFI_GENERIC_STUB=y +CONFIG_EFI_PARAMS_FROM_FDT=y +CONFIG_EFI_RUNTIME_WRAPPERS=y +CONFIG_EFI_STUB=y +# CONFIG_EFI_TEST is not set +# CONFIG_EFI_ZBOOT is not set +# CONFIG_ERRATA_ANDES is not set +# CONFIG_ERRATA_SIFIVE is not set +# CONFIG_ERRATA_THEAD is not set +CONFIG_EXCLUSIVE_SYSTEM_RAM=y +CONFIG_FIXED_PHY=y +CONFIG_FIX_EARLYCON_MEM=y +CONFIG_FONT_8x16=y +CONFIG_FONT_AUTOSELECT=y +CONFIG_FONT_SUPPORT=y +CONFIG_FPU=y +CONFIG_FRAME_POINTER=y +CONFIG_FS_IOMAP=y +CONFIG_FUNCTION_ALIGNMENT=4 +CONFIG_FUNCTION_ALIGNMENT_4B=y +CONFIG_FWNODE_MDIO=y +CONFIG_FW_LOADER_PAGED_BUF=y +CONFIG_FW_LOADER_SYSFS=y +CONFIG_GCC_SUPPORTS_DYNAMIC_FTRACE=y +CONFIG_GENERIC_ALLOCATOR=y +CONFIG_GENERIC_ARCH_TOPOLOGY=y +CONFIG_GENERIC_BUG=y +CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y +CONFIG_GENERIC_CPU_DEVICES=y +CONFIG_GENERIC_CPU_VULNERABILITIES=y +CONFIG_GENERIC_CSUM=y +CONFIG_GENERIC_EARLY_IOREMAP=y +CONFIG_GENERIC_ENTRY=y +CONFIG_GENERIC_GETTIMEOFDAY=y +CONFIG_GENERIC_IDLE_POLL_SETUP=y +CONFIG_GENERIC_IOREMAP=y +CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y +CONFIG_GENERIC_IRQ_ENTRY=y +CONFIG_GENERIC_IRQ_IPI_MUX=y +CONFIG_GENERIC_IRQ_MATRIX_ALLOCATOR=y +CONFIG_GENERIC_IRQ_MULTI_HANDLER=y +CONFIG_GENERIC_IRQ_SHOW=y +CONFIG_GENERIC_IRQ_SHOW_LEVEL=y +CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED=y +CONFIG_GENERIC_MSI_IRQ=y +CONFIG_GENERIC_PCI_IOMAP=y +CONFIG_GENERIC_PENDING_IRQ=y +CONFIG_GENERIC_PHY=y +CONFIG_GENERIC_PINCONF=y +CONFIG_GENERIC_PINCTRL_GROUPS=y +CONFIG_GENERIC_PINMUX_FUNCTIONS=y +CONFIG_GENERIC_SCHED_CLOCK=y +CONFIG_GENERIC_SMP_IDLE_THREAD=y +CONFIG_GENERIC_STRNCPY_FROM_USER=y +CONFIG_GENERIC_STRNLEN_USER=y +CONFIG_GENERIC_SYSCALL=y +CONFIG_GENERIC_TIME_VSYSCALL=y +CONFIG_GPIOLIB_IRQCHIP=y +CONFIG_GPIO_CDEV=y +CONFIG_GPIO_GENERIC=y +CONFIG_GPIO_SPACEMIT_K1=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_HAS_DMA=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_IOPORT_MAP=y +CONFIG_HWMON=y +CONFIG_HW_RANDOM=y +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_K1=y +CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000 +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_IOMMUFD is not set +CONFIG_IOMMU_API=y +# CONFIG_IOMMU_DEBUGFS is not set +# CONFIG_IOMMU_DEFAULT_DMA_LAZY is not set +CONFIG_IOMMU_DEFAULT_DMA_STRICT=y +# CONFIG_IOMMU_DEFAULT_PASSTHROUGH is not set +CONFIG_IOMMU_SUPPORT=y +CONFIG_IRQCHIP=y +CONFIG_IRQ_DOMAIN=y +CONFIG_IRQ_DOMAIN_HIERARCHY=y +CONFIG_IRQ_FORCED_THREADING=y +CONFIG_IRQ_MSI_LIB=y +CONFIG_IRQ_STACKS=y +CONFIG_IRQ_TIME_ACCOUNTING=y +CONFIG_IRQ_WORK=y +# CONFIG_KERNEL_UNCOMPRESSED is not set +CONFIG_LEDS_PWM=y +CONFIG_LEDS_TRIGGER_PATTERN=y +CONFIG_LIBFDT=y +CONFIG_LOCK_DEBUGGING_SUPPORT=y +CONFIG_LOCK_SPIN_ON_OWNER=y +CONFIG_LRU_GEN_WALKS_MMU=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_MDIO_BUS=y +CONFIG_MESSAGE_LOGLEVEL_DEFAULT=7 +CONFIG_MFD_CORE=y +CONFIG_MFD_SIMPLE_MFD_I2C=y +CONFIG_MFD_SPACEMIT_P1=y +CONFIG_MFD_SYSCON=y +CONFIG_MIGRATION=y +CONFIG_MMC=y +CONFIG_MMC_BLOCK=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_OF_K1=y +CONFIG_MMC_SDHCI_PLTFM=y +CONFIG_MMIOWB=y +# CONFIG_MMP_PDMA is not set +CONFIG_MMU_LAZY_TLB_REFCOUNT=y +CONFIG_MODULES_TREE_LOOKUP=y +CONFIG_MODULES_USE_ELF_RELA=y +CONFIG_MODULE_SECTIONS=y +CONFIG_MOTORCOMM_PHY=y +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_ROOTFS_ROOT_DEV is not set +CONFIG_MTD_SPI_NOR=y +# CONFIG_MTD_SPLIT_SQUASHFS_ROOT is not set +CONFIG_MUTEX_SPIN_ON_OWNER=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_NET_EGRESS=y +CONFIG_NET_FLOW_LIMIT=y +CONFIG_NET_INGRESS=y +CONFIG_NET_SELFTESTS=y +CONFIG_NET_VENDOR_SPACEMIT=y +CONFIG_NET_XGRESS=y +CONFIG_NLS=y +# CONFIG_NONPORTABLE is not set +CONFIG_NO_HZ_COMMON=y +CONFIG_NO_HZ_IDLE=y +CONFIG_NR_CPUS=8 +CONFIG_NVMEM=y +CONFIG_NVMEM_LAYOUTS=y +CONFIG_NVMEM_LAYOUT_ONIE_TLV=y +CONFIG_NVMEM_SYSFS=y +CONFIG_NVME_CORE=y +CONFIG_NVME_HWMON=y +# CONFIG_NVME_MULTIPATH is not set +CONFIG_OF=y +CONFIG_OF_ADDRESS=y +CONFIG_OF_EARLY_FLATTREE=y +CONFIG_OF_FLATTREE=y +CONFIG_OF_GPIO=y +CONFIG_OF_IOMMU=y +CONFIG_OF_IRQ=y +CONFIG_OF_KOBJ=y +CONFIG_OF_MDIO=y +CONFIG_PADATA=y +CONFIG_PAGE_BLOCK_MAX_ORDER=10 +CONFIG_PAGE_POOL=y +CONFIG_PAGE_SIZE_LESS_THAN_256KB=y +CONFIG_PAGE_SIZE_LESS_THAN_64KB=y +CONFIG_PCI=y +CONFIG_PCIEAER=y +CONFIG_PCIEASPM=y +# CONFIG_PCIEASPM_DEFAULT is not set +CONFIG_PCIEASPM_PERFORMANCE=y +# CONFIG_PCIEASPM_POWERSAVE is not set +# CONFIG_PCIEASPM_POWER_SUPERSAVE is not set +CONFIG_PCIEPORTBUS=y +CONFIG_PCIE_DW=y +# CONFIG_PCIE_DW_DEBUGFS is not set +CONFIG_PCIE_DW_HOST=y +CONFIG_PCIE_PME=y +CONFIG_PCIE_SPACEMIT_K1=y +CONFIG_PCI_DOMAINS=y +CONFIG_PCI_DOMAINS_GENERIC=y +CONFIG_PCI_ECAM=y +CONFIG_PCI_HOST_COMMON=y +CONFIG_PCI_LABEL=y +CONFIG_PCI_MSI=y +CONFIG_PCI_PWRCTRL=y +CONFIG_PCI_PWRCTRL_SLOT=y +CONFIG_PERF_EVENTS=y +CONFIG_PER_VMA_LOCK=y +CONFIG_PGTABLE_LEVELS=5 +CONFIG_PHYLIB=y +CONFIG_PHYLIB_LEDS=y +CONFIG_PHYS_ADDR_T_64BIT=y +CONFIG_PHY_COMMON_PROPS=y +CONFIG_PHY_SPACEMIT_K1_PCIE=y +CONFIG_PHY_SPACEMIT_K1_USB2=y +CONFIG_PINCTRL=y +# CONFIG_PINCTRL_SINGLE is not set +CONFIG_PINCTRL_SPACEMIT_K1=y +CONFIG_PM=y +CONFIG_PM_CLK=y +CONFIG_PM_OPP=y +CONFIG_PORTABLE=y +CONFIG_POSIX_CPU_TIMERS_TASK_WORK=y +CONFIG_POWER_RESET=y +CONFIG_POWER_RESET_SPACEMIT_P1=y +CONFIG_POWER_SUPPLY=y +CONFIG_PRINTK_TIME=y +CONFIG_PTP_1588_CLOCK_OPTIONAL=y +CONFIG_PWM=y +# CONFIG_PWM_PXA is not set +CONFIG_QUEUED_RWLOCKS=y +CONFIG_QUEUED_SPINLOCKS=y +CONFIG_RANDOMIZE_BASE=y +CONFIG_RANDSTRUCT_NONE=y +CONFIG_RAS=y +CONFIG_RATIONAL=y +# CONFIG_RAVE_SP_CORE is not set +CONFIG_REALTEK_PHY=y +CONFIG_REALTEK_PHY_HWMON=y +CONFIG_REGMAP=y +CONFIG_REGMAP_I2C=y +CONFIG_REGMAP_MMIO=y +CONFIG_REGULATOR=y +CONFIG_REGULATOR_FIXED_VOLTAGE=y +CONFIG_REGULATOR_SPACEMIT_P1=y +CONFIG_RELOCATABLE=y +# CONFIG_RESET_ATTACK_MITIGATION is not set +CONFIG_RESET_CONTROLLER=y +CONFIG_RESET_SPACEMIT=y +CONFIG_RFS_ACCEL=y +CONFIG_RISCV=y +CONFIG_RISCV_ALTERNATIVE=y +CONFIG_RISCV_APLIC=y +CONFIG_RISCV_APLIC_MSI=y +# CONFIG_RISCV_BOOT_SPINWAIT is not set +CONFIG_RISCV_COMBO_SPINLOCKS=y +CONFIG_RISCV_DMA_NONCOHERENT=y +# CONFIG_RISCV_EMULATED_UNALIGNED_ACCESS is not set +CONFIG_RISCV_IMSIC=y +CONFIG_RISCV_INTC=y +CONFIG_RISCV_IOMMU=y +CONFIG_RISCV_IOMMU_PCI=y +CONFIG_RISCV_ISA_C=y +CONFIG_RISCV_ISA_FALLBACK=y +CONFIG_RISCV_ISA_SUPM=y +CONFIG_RISCV_ISA_SVNAPOT=y +CONFIG_RISCV_ISA_SVPBMT=y +CONFIG_RISCV_ISA_V=y +# CONFIG_RISCV_ISA_VENDOR_EXT_ANDES is not set +# CONFIG_RISCV_ISA_VENDOR_EXT_MIPS is not set +# CONFIG_RISCV_ISA_VENDOR_EXT_SIFIVE is not set +# CONFIG_RISCV_ISA_VENDOR_EXT_THEAD is not set +CONFIG_RISCV_ISA_V_DEFAULT_ENABLE=y +CONFIG_RISCV_ISA_V_UCOPY_THRESHOLD=768 +CONFIG_RISCV_ISA_ZABHA=y +CONFIG_RISCV_ISA_ZACAS=y +CONFIG_RISCV_ISA_ZAWRS=y +CONFIG_RISCV_ISA_ZBA=y +CONFIG_RISCV_ISA_ZBB=y +CONFIG_RISCV_ISA_ZBC=y +CONFIG_RISCV_ISA_ZBKB=y +CONFIG_RISCV_ISA_ZICBOM=y +CONFIG_RISCV_ISA_ZICBOP=y +CONFIG_RISCV_ISA_ZICBOZ=y +CONFIG_RISCV_MISALIGNED=y +CONFIG_RISCV_PROBE_UNALIGNED_ACCESS=y +CONFIG_RISCV_PROBE_VECTOR_UNALIGNED_ACCESS=y +CONFIG_RISCV_SBI=y +CONFIG_RISCV_SBI_CPUIDLE=y +# CONFIG_RISCV_SBI_V01 is not set +CONFIG_RISCV_SCALAR_MISALIGNED=y +# CONFIG_RISCV_TICKET_SPINLOCKS is not set +CONFIG_RISCV_TIMER=y +CONFIG_RISCV_VECTOR_MISALIGNED=y +CONFIG_RPS=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_SPACEMIT_P1=y +CONFIG_RTC_I2C_AND_SPI=y +CONFIG_RUNTIME_KERNEL_TESTING_MENU=y +CONFIG_RWSEM_SPIN_ON_OWNER=y +CONFIG_SCHED_MC=y +CONFIG_SCSI=y +CONFIG_SCSI_COMMON=y +# CONFIG_SECTION_MISMATCH_WARN_ONLY is not set +CONFIG_SERIAL_8250_NR_UARTS=3 +CONFIG_SERIAL_8250_RUNTIME_UARTS=3 +CONFIG_SERIAL_DEV_BUS=y +CONFIG_SERIAL_DEV_CTRL_TTYPORT=y +CONFIG_SERIAL_EARLYCON_RISCV_SBI=y +CONFIG_SERIAL_MCTRL_GPIO=y +CONFIG_SERIAL_OF_PLATFORM=y +CONFIG_SG_POOL=y +CONFIG_SIFIVE_PLIC=y +CONFIG_SMP=y +CONFIG_SOCK_RX_QUEUE_MAPPING=y +# CONFIG_SOC_STARFIVE is not set +CONFIG_SOFTIRQ_ON_OWN_STACK=y +CONFIG_SPACEMIT_CCU=y +CONFIG_SPACEMIT_K1_CCU=y +CONFIG_SPACEMIT_K1_EMAC=y +CONFIG_SPACEMIT_K1_TSENSOR=y +CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y +CONFIG_SPARSE_IRQ=y +CONFIG_SPI=y +CONFIG_SPI_FSL_QUADSPI=y +CONFIG_SPI_MASTER=y +CONFIG_SPI_MEM=y +CONFIG_SPI_SPACEMIT_K1=y +CONFIG_SPLIT_PMD_PTLOCKS=y +CONFIG_SPLIT_PTE_PTLOCKS=y +# CONFIG_SQUASHFS_XZ is not set +CONFIG_SQUASHFS_ZLIB=y +CONFIG_SWIOTLB=y +CONFIG_SWPHY=y +CONFIG_SYSCTL_ARCH_UNALIGN_ALLOW=y +CONFIG_SYSCTL_EXCEPTION_TRACE=y +# CONFIG_SYSFB_SIMPLEFB is not set +CONFIG_THERMAL=y +CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y +CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0 +CONFIG_THERMAL_GOV_BANG_BANG=y +CONFIG_THERMAL_GOV_FAIR_SHARE=y +CONFIG_THERMAL_GOV_STEP_WISE=y +CONFIG_THERMAL_GOV_USER_SPACE=y +CONFIG_THERMAL_HWMON=y +CONFIG_THERMAL_OF=y +CONFIG_THREAD_INFO_IN_TASK=y +CONFIG_THREAD_SIZE_ORDER=2 +CONFIG_TICK_CPU_ACCOUNTING=y +CONFIG_TIMER_OF=y +CONFIG_TIMER_PROBE=y +CONFIG_TOOLCHAIN_HAS_V=y +CONFIG_TOOLCHAIN_HAS_VECTOR_CRYPTO=y +CONFIG_TOOLCHAIN_HAS_ZABHA=y +CONFIG_TOOLCHAIN_HAS_ZACAS=y +CONFIG_TOOLCHAIN_HAS_ZBA=y +CONFIG_TOOLCHAIN_HAS_ZBB=y +CONFIG_TOOLCHAIN_HAS_ZBC=y +CONFIG_TOOLCHAIN_HAS_ZBKB=y +CONFIG_TOOLCHAIN_NEEDS_EXPLICIT_ZICSR_ZIFENCEI=y +CONFIG_TREE_RCU=y +CONFIG_TREE_SRCU=y +CONFIG_TUNE_GENERIC=y +# CONFIG_UCLAMP_TASK is not set +CONFIG_UCS2_STRING=y +CONFIG_USB=y +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y +CONFIG_USB_COMMON=y +CONFIG_USB_DWC3=y +CONFIG_USB_DWC3_GENERIC_PLAT=y +CONFIG_USB_DWC3_HOST=y +CONFIG_USB_ONBOARD_DEV=y +# CONFIG_USB_ONBOARD_DEV_USB5744 is not set +CONFIG_USB_STORAGE=y +CONFIG_USB_SUPPORT=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_XHCI_PLATFORM=y +CONFIG_USER_STACKTRACE_SUPPORT=y +CONFIG_VDSO_GETRANDOM=y +CONFIG_VMAP_STACK=y +CONFIG_XPS=y +CONFIG_ZLIB_INFLATE=y +CONFIG_ZONE_DMA32=y diff --git a/target/linux/spacemit/image/Makefile b/target/linux/spacemit/image/Makefile new file mode 100644 index 00000000000000..fcaf0179b4f6c8 --- /dev/null +++ b/target/linux/spacemit/image/Makefile @@ -0,0 +1,26 @@ +# SPDX-License-Identifier: GPL-2.0-only + +include $(TOPDIR)/rules.mk +include $(INCLUDE_DIR)/image.mk + +loadaddr-$(CONFIG_TARGET_spacemit_k1) := 0x200000 + +define Device/Default + PROFILES = Default $$(DEVICE_NAME) + KERNEL_NAME := Image + KERNEL = kernel-bin | lzma | fit lzma + KERNEL_SUFFIX := .itb + KERNEL_INITRAMFS = kernel-bin | lzma | fit lzma "" with-initrd + KERNEL_INITRAMFS_SUFFIX := .itb + KERNEL_LOADADDR = $(loadaddr-y) + DEVICE_VENDOR := SpacemiT + DEVICE_DTS_DIR := $(DTS_DIR)/spacemit +endef + +include $(SUBTARGET).mk + +define Image/Build + $(call Image/Build/$(1),$(1)) +endef + +$(eval $(call BuildImage)) diff --git a/target/linux/spacemit/image/extlinux.conf b/target/linux/spacemit/image/extlinux.conf new file mode 100644 index 00000000000000..e067663ff10a10 --- /dev/null +++ b/target/linux/spacemit/image/extlinux.conf @@ -0,0 +1,4 @@ +label OpenWrt + kernel /Image.itb + devicetree /Image.itb + append earlycon=sbi console=ttyS0,115200 root=PARTUUID=${rootfs_uuid} rootwait diff --git a/target/linux/spacemit/image/k1.mk b/target/linux/spacemit/image/k1.mk new file mode 100644 index 00000000000000..cc5a6e2ab3483a --- /dev/null +++ b/target/linux/spacemit/image/k1.mk @@ -0,0 +1,121 @@ +# SPDX-License-Identifier: GPL-2.0-only + +# TODO +# check-size + +ifeq ($(DUMP),) +GUID_SD:=$(shell echo $(SOURCE_DATE_EPOCH)$(LINUX_VERMAGIC)sd | $(MKHASH) md5 | sed -E 's/(.{8})(.{4})(.{4})(.{4})(.{10})../\1-\2-\3-\4-\500/') +GUID_EMMC:=$(shell echo $(SOURCE_DATE_EPOCH)$(LINUX_VERMAGIC)emmc | $(MKHASH) md5 | sed -E 's/(.{8})(.{4})(.{4})(.{4})(.{10})../\1-\2-\3-\4-\500/') +GUID_OTHER:=$(shell echo $(SOURCE_DATE_EPOCH)$(LINUX_VERMAGIC)other | $(MKHASH) md5 | sed -E 's/(.{8})(.{4})(.{4})(.{4})(.{10})../\1-\2-\3-\4-\500/') + +FAT32_BLOCK_SIZE=1024 +FAT32_BLOCKS=$(shell echo $$(($(CONFIG_TARGET_KERNEL_PARTSIZE)*1024*1024/$(FAT32_BLOCK_SIZE)))) + +ROOTFS_OFFSET_SD=$(shell echo $$(($(CONFIG_TARGET_KERNEL_PARTSIZE)*1024+3520))) +ROOTFS_OFFSET_EMMC=$(shell echo $$(($(CONFIG_TARGET_KERNEL_PARTSIZE)*1024+3264))) +ROOTFS_OFFSET_OTHER=$(shell echo $$(($(CONFIG_TARGET_KERNEL_PARTSIZE)*1024+128))) +endif + +define Build/k1-gpt-sd + rm -f $@.gpt-sd + ptgen -o $@.gpt-sd -g -l 1024 -D -H -G "${GUID_SD}" \ + -t 0x83 -N fsbl -r -p 256k@128k \ + -t 0x83 -N env -r -p 64k@384k \ + -t 0x83 -N uboot -r -p 3072k@448k \ + -t 0x0b -N bootfs -B -p $(CONFIG_TARGET_KERNEL_PARTSIZE)M@3520k \ + -t 0x83 -N rootfs -p $(CONFIG_TARGET_ROOTFS_PARTSIZE)M@$(ROOTFS_OFFSET_SD)k + dd if=$(STAGING_DIR_IMAGE)/u-boot-spacemit_k1/bootinfo_sd.bin of=$@.gpt-sd conv=notrunc + cat $@.gpt-sd >> $@ +endef + +define Build/k1-gpt-emmc + rm -f $@.gpt-emmc + ptgen -o $@.gpt-emmc -g -l 1024 -D -H -G "${GUID_EMMC}" \ + -t 0x83 -N env -r -p 64k@128k \ + -t 0x83 -N uboot -r -p 3072k@192k \ + -t 0x0b -N bootfs -B -p $(CONFIG_TARGET_KERNEL_PARTSIZE)M@3264k \ + -t 0x83 -N rootfs -p $(CONFIG_TARGET_ROOTFS_PARTSIZE)M@$(ROOTFS_OFFSET_EMMC)k + cat $@.gpt-emmc >> $@ +endef + +define Build/k1-gpt-other + rm -f $@.gpt-other + ptgen -o $@.gpt-other -g -l 1024 -D -H -G "${GUID_OTHER}" \ + -t 0x0b -N bootfs -B -p $(CONFIG_TARGET_KERNEL_PARTSIZE)M@128k \ + -t 0x83 -N rootfs -p $(CONFIG_TARGET_ROOTFS_PARTSIZE)M@$(ROOTFS_OFFSET_OTHER)k + cat $@.gpt-other >> $@ +endef + +define Build/k1-fsbl + cat $(STAGING_DIR_IMAGE)/u-boot-spacemit_k1/FSBL.bin >> $@ +endef + +define Build/k1-uboot + cat $(STAGING_DIR_IMAGE)/u-boot-spacemit_k1/u-boot.itb >> $@ +endef + +define Build/k1-bootfs + rm -f $@.bootfs + mkfs.fat -n bootfs -C $@.bootfs $(FAT32_BLOCKS) + mcopy -i $@.bootfs $(KDIR)/generic.itb ::/Image.itb + mmd -i $@.bootfs ::/extlinux + mcopy -i $@.bootfs extlinux.conf ::/extlinux/extlinux.conf + cat $@.bootfs >> $@ +endef + +define Device/generic + DEVICE_MODEL := K1 + DEVICE_TITLE := Generic + DEVICE_DESCRIPTION = \ + Generate images for \ + Banana Pi BPI-F3, \ + Milk-V Jupiter, \ + SpacemiT MusePi Pro, \ + OrangePi R2S and \ + OrangePi RV2 + DEVICE_DTS := \ + k1-bananapi-f3 \ + k1-milkv-jupiter \ + k1-musepi-pro \ + k1-orangepi-r2s \ + k1-orangepi-rv2 + DEVICE_DTS_MULTI := \ + $(KDIR)/image-k1-bananapi-f3.dtb:bananapi,bpi-f3 \ + $(KDIR)/image-k1-milkv-jupiter.dtb:milkv,jupiter \ + $(KDIR)/image-k1-musepi-pro.dtb:spacemit,musepi-pro \ + $(KDIR)/image-k1-orangepi-r2s.dtb:xunlong,orangepi-r2s \ + $(KDIR)/image-k1-orangepi-rv2.dtb:xunlong,orangepi-rv2 + SUPPORTED_DEVICES := \ + bananapi,bpi-f3 \ + milkv,jupiter \ + spacemit,musepi-pro \ + xunlong,orangepi-r2s \ + xunlong,orangepi-rv2 + DEVICE_PACKAGES := \ + u-boot-spacemit_k1 \ + kmod-fs-vfat \ + kmod-r8169 + IMAGES := \ + sdcard.img.gz \ + emmc.img.gz \ + other.img.gz + IMAGE/sdcard.img.gz := \ + k1-gpt-sd |\ + pad-to 128k | k1-fsbl |\ + pad-to 448k | k1-uboot |\ + pad-to 3520k | k1-bootfs |\ + pad-to $(ROOTFS_OFFSET_SD)k | append-rootfs |\ + libdeflate-gzip | append-metadata + IMAGE/emmc.img.gz := \ + k1-gpt-emmc |\ + pad-to 192k | k1-uboot |\ + pad-to 3264k | k1-bootfs |\ + pad-to $(ROOTFS_OFFSET_EMMC)k | append-rootfs |\ + libdeflate-gzip | append-metadata + IMAGE/other.img.gz := \ + k1-gpt-other |\ + pad-to 128k | k1-bootfs |\ + pad-to $(ROOTFS_OFFSET_OTHER)k | append-rootfs |\ + libdeflate-gzip | append-metadata +endef +TARGET_DEVICES += generic diff --git a/target/linux/spacemit/k1/base-files/etc/board.d/02_network b/target/linux/spacemit/k1/base-files/etc/board.d/02_network new file mode 100644 index 00000000000000..ea56d05c727ddd --- /dev/null +++ b/target/linux/spacemit/k1/base-files/etc/board.d/02_network @@ -0,0 +1,26 @@ +#!/bin/sh + +. /lib/functions/uci-defaults.sh + +board_config_update + +case "$(board_name)" in +bananapi,bpi-f3|\ +milkv,jupiter|\ +xunlong,orangepi-rv2) + ucidef_set_interface_lan 'eth0 eth1' + ;; +xunlong,orangepi-r2s) + ucidef_set_interface_lan 'eth0 eth1 eth2 eth3' + ;; +spacemit,musepi-pro) + ucidef_set_interface_lan 'eth0' + ;; +*) + echo "Unsupported hardware. Network interfaces not initialized" + ;; +esac + +board_config_flush + +exit 0 diff --git a/target/linux/spacemit/k1/base-files/lib/preinit/79_move_config b/target/linux/spacemit/k1/base-files/lib/preinit/79_move_config new file mode 100644 index 00000000000000..62490b1da806e3 --- /dev/null +++ b/target/linux/spacemit/k1/base-files/lib/preinit/79_move_config @@ -0,0 +1,39 @@ +#iterate over each partition from the bootdisk and find 'bootfs' +find_partn_by_name() { + local name="$1" var="$2" part start size partdev + + while read part start size; do + if export_partdevice partdev $part; then + . "/sys/class/block/$partdev/uevent" + if [ "$PARTNAME" = "$name" ]; then + export "$var=$PARTN" + return 0 + fi + fi + done < /tmp/partmap.bootdisk + + return 1 +} + +move_config() { + local diskdev partdev + + . /lib/upgrade/common.sh + + if export_bootdevice && export_partdevice diskdev 0; then + get_partitions "/dev/$diskdev" bootdisk + + if find_partn_by_name "bootfs" bootn && export_partdevice partdev "$bootn"; then + if mount -o rw,noatime "/dev/$partdev" /mnt; then + if [ -f "/mnt/$BACKUP_FILE" ]; then + mv -f "/mnt/$BACKUP_FILE" / + fi + umount /mnt + fi + fi + + rm -f /tmp/partmap.bootdisk + fi +} + +boot_hook_add preinit_mount_root move_config diff --git a/target/linux/spacemit/k1/base-files/lib/upgrade/platform.sh b/target/linux/spacemit/k1/base-files/lib/upgrade/platform.sh new file mode 100644 index 00000000000000..1d432597495305 --- /dev/null +++ b/target/linux/spacemit/k1/base-files/lib/upgrade/platform.sh @@ -0,0 +1,133 @@ +REQUIRE_IMAGE_METADATA=1 + +#iterate over each partition from the bootdisk and find 'bootfs' +find_partn_by_name() { + local name="$1" var="$2" part start size partdev + + while read part start size; do + if export_partdevice partdev $part; then + . "/sys/class/block/$partdev/uevent" + if [ "$PARTNAME" = "$name" ]; then + export "$var=$PARTN" + return 0 + fi + fi + done < /tmp/partmap.bootdisk + + return 1 +} + +platform_check_image() { + local diskdev diff bootn partdev + local board=$(board_name) + [ "$#" -gt 1 ] && return 1 + + v "Running on board: ${board}" + + export_bootdevice && export_partdevice diskdev 0 || { + v "ERROR: Unable to determine upgrade device" + return 1 + } + + get_partitions "/dev/$diskdev" bootdisk + + v "Extracting the boot sector from the image" + get_image_dd "$1" of=/tmp/image.bs count=63 bs=512b + + get_partitions /tmp/image.bs image + rm -f /tmp/image.bs + + if [ "$SAVE_PARTITIONS" = "1" ]; then + #compare tables + diff="$(grep -F -x -v -f /tmp/partmap.bootdisk /tmp/partmap.image)" + + if [ -n "$diff" ]; then + v "The partition layout has changed!" + v "The full image needs to be written and additional partitions will be lost!" + v "Please confirm with '-p'." + ask_bool 1 "Abort" && exit 1 + return 0 + fi + else + v "The full image will be written to /dev/$diskdev" + fi + + if [ "$SAVE_CONFIG" = "1" ]; then + find_partn_by_name "bootfs" bootn && export_partdevice partdev "$bootn" + if [ -z "$partdev" ]; then + v "The bootfs partition is missing, can't store the configuration" + return 1 + fi + v "The configuration will be stored on /dev/$partdev" + fi + + rm -f /tmp/partmap.bootdisk /tmp/partmap.image +} + +platform_copy_config() { + local bootn partdev + + if find_partn_by_name "bootfs" bootn && export_partdevice partdev "$bootn"; then + v "Storing the configuration on /dev/$partdev" + mount -o rw,noatime "/dev/$partdev" /mnt + cp -af "$UPGRADE_BACKUP" "/mnt/$BACKUP_FILE" + umount /mnt + else + v "ERROR: Unable to find the partition to store the configuration on" + fi +} + +platform_do_upgrade() { + local diskdev partdev diff + + export_bootdevice && export_partdevice diskdev 0 || { + v "ERROR: Unable to determine upgrade device" + return 1 + } + + sync + + if [ "$UPGRADE_OPT_SAVE_PARTITIONS" = "1" ]; then + get_partitions "/dev/$diskdev" bootdisk + + v "Extracting the boot sector from the image" + get_image_dd "$1" of=/tmp/image.bs count=63 bs=512b + + get_partitions /tmp/image.bs image + + #compare tables + diff="$(grep -F -x -v -f /tmp/partmap.bootdisk /tmp/partmap.image)" + else + diff=1 + fi + + # Only change the partition table if sysupgrade -p is set, + # otherwise doing so could interfere with embedded "single storage" + # (e.g SoC boot from SD card) setups, as well as other user + # created storage (like uvol) + if [ -n "$diff" ]; then + # Need to remove partitions before dd, otherwise the partitions + # that are added after will have minor numbers offset + partx -d - "/dev/$diskdev" + + v "Writing full image to /dev/$diskdev ..." + get_image_dd "$1" of="/dev/$diskdev" bs=4096 conv=fsync + + # Separate removal and addtion is necessary; otherwise, partition 1 + # will be missing if it overlaps with the old partition 2 + partx -a - "/dev/$diskdev" + + return 0 + fi + + #iterate over each partition from the image and write it to the boot disk + while read part start size; do + if export_partdevice partdev $part; then + v "Writing image partition to /dev/$partdev ..." + get_image_dd "$1" of="/dev/$partdev" ibs=512 obs=1M skip="$start" \ + count="$size" conv=fsync + else + v "Unable to find partition $part device, skipped." + fi + done < /tmp/partmap.image +} diff --git a/target/linux/spacemit/k1/target.mk b/target/linux/spacemit/k1/target.mk new file mode 100644 index 00000000000000..47348336fa274f --- /dev/null +++ b/target/linux/spacemit/k1/target.mk @@ -0,0 +1,8 @@ +SUBTARGET:=k1 +BOARDNAME:=SpacemiT K1 +CPU_TYPE:=generic +KERNELNAME:=Image dtbs + +define Target/Description + Build firmware images for SpacemiT K1 based boards +endef diff --git a/target/linux/spacemit/patches-6.18/0001-riscv-dts-spacemit-add-UART-pinctrl-combinations.patch b/target/linux/spacemit/patches-6.18/0001-riscv-dts-spacemit-add-UART-pinctrl-combinations.patch new file mode 100644 index 00000000000000..ae44259df28bda --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0001-riscv-dts-spacemit-add-UART-pinctrl-combinations.patch @@ -0,0 +1,463 @@ +From 218156c82ed0bb22573ecffa1caa1c9398fc8ec1 Mon Sep 17 00:00:00 2001 +From: Hendrik Hamerlinck +Date: Wed, 17 Sep 2025 08:59:07 +0200 +Subject: [PATCH] riscv: dts: spacemit: add UART pinctrl combinations + +Add UART pinctrl configurations based on the SoC datasheet and the +downstream Bianbu Linux tree. The drive strength values were taken from +the downstream implementation, which uses medium drive strength. +CTS/RTS are moved to separate *-cts-rts-cfg states so boards can enable +hardware flow control conditionally. + +Signed-off-by: Hendrik Hamerlinck +Reviewed-by: Yixun Lan +Reviewed-by: Troy Mitchell +Link: https://lore.kernel.org/r/20250917065907.160615-1-hendrik.hamerlinck@hammernet.be +Signed-off-by: Yixun Lan +(cherry picked from commit 1187f9b3f6ebde806289877fa710ffd58f950104) +--- + arch/riscv/boot/dts/spacemit/k1-pinctrl.dtsi | 430 ++++++++++++++++++- + 1 file changed, 428 insertions(+), 2 deletions(-) + +--- a/arch/riscv/boot/dts/spacemit/k1-pinctrl.dtsi ++++ b/arch/riscv/boot/dts/spacemit/k1-pinctrl.dtsi +@@ -59,11 +59,437 @@ + }; + }; + ++ /omit-if-no-ref/ ++ uart0_0_cfg: uart0-0-cfg { ++ uart0-0-pins { ++ pinmux = , /* uart0_txd */ ++ ; /* uart0_rxd */ ++ power-source = <3300>; ++ bias-pull-up = <0>; ++ drive-strength = <19>; ++ }; ++ }; ++ ++ /omit-if-no-ref/ ++ uart0_1_cfg: uart0-1-cfg { ++ uart0-1-pins { ++ pinmux = , /* uart0_txd */ ++ ; /* uart0_rxd */ ++ power-source = <3300>; ++ bias-pull-up = <0>; ++ drive-strength = <19>; ++ }; ++ }; ++ ++ /omit-if-no-ref/ + uart0_2_cfg: uart0-2-cfg { + uart0-2-pins { +- pinmux = , +- ; ++ pinmux = , /* uart0_txd */ ++ ; /* uart0_rxd */ ++ bias-pull-up = <0>; ++ drive-strength = <32>; ++ }; ++ }; ++ ++ /omit-if-no-ref/ ++ uart2_0_cfg: uart2-0-cfg { ++ uart2-0-pins { ++ pinmux = , /* uart2_txd */ ++ ; /* uart2_rxd */ ++ bias-pull-up = <0>; ++ drive-strength = <32>; ++ }; ++ }; ++ ++ /omit-if-no-ref/ ++ uart2_0_cts_rts_cfg: uart2-0-cts-rts-cfg { ++ uart2-0-pins { ++ pinmux = , /* uart2_cts */ ++ ; /* uart2_rts */ ++ bias-pull-up = <0>; ++ drive-strength = <32>; ++ }; ++ }; ++ ++ /omit-if-no-ref/ ++ uart3_0_cfg: uart3-0-cfg { ++ uart3-0-pins { ++ pinmux = , /* uart3_txd */ ++ ; /* uart3_rxd */ ++ bias-pull-up = <0>; ++ drive-strength = <32>; ++ }; ++ }; ++ ++ /omit-if-no-ref/ ++ uart3_0_cts_rts_cfg: uart3-0-cts-rts-cfg { ++ uart3-0-pins { ++ pinmux = , /* uart3_cts */ ++ ; /* uart3_rts */ ++ bias-pull-up = <0>; ++ drive-strength = <32>; ++ }; ++ }; ++ ++ /omit-if-no-ref/ ++ uart3_1_cfg: uart3-1-cfg { ++ uart3-1-pins { ++ pinmux = , /* uart3_txd */ ++ ; /* uart3_rxd */ ++ bias-pull-up = <0>; ++ drive-strength = <32>; ++ }; ++ }; ++ ++ /omit-if-no-ref/ ++ uart3_1_cts_rts_cfg: uart3-1-cts-rts-cfg { ++ uart3-1-pins { ++ pinmux = , /* uart3_cts */ ++ ; /* uart3_rts */ ++ bias-pull-up = <0>; ++ drive-strength = <32>; ++ }; ++ }; ++ ++ /omit-if-no-ref/ ++ uart3_2_cfg: uart3-2-cfg { ++ uart3-2-pins { ++ pinmux = , /* uart3_txd */ ++ ; /* uart3_rxd */ ++ bias-pull-up = <0>; ++ drive-strength = <32>; ++ }; ++ }; ++ ++ /omit-if-no-ref/ ++ uart3_2_cts_rts_cfg: uart3-2-cts-rts-cfg { ++ uart3-2-pins { ++ pinmux = , /* uart3_cts */ ++ ; /* uart3_rts */ ++ bias-pull-up = <0>; ++ drive-strength = <32>; ++ }; ++ }; ++ ++ /omit-if-no-ref/ ++ uart4_0_cfg: uart4-0-cfg { ++ uart4-0-pins { ++ pinmux = , /* uart4_txd */ ++ ; /* uart4_rxd */ ++ power-source = <3300>; ++ bias-pull-up = <0>; ++ drive-strength = <19>; ++ }; ++ }; ++ ++ /omit-if-no-ref/ ++ uart4_1_cfg: uart4-1-cfg { ++ uart4-1-pins { ++ pinmux = , /* uart4_txd */ ++ ; /* uart4_rxd */ ++ bias-pull-up = <0>; ++ drive-strength = <32>; ++ }; ++ }; ++ ++ /omit-if-no-ref/ ++ uart4_1_cts_rts_cfg: uart4-1-cts-rts-cfg { ++ uart4-1-pins { ++ pinmux = , /* uart4_cts */ ++ ; /* uart4_rts */ ++ bias-pull-up = <0>; ++ drive-strength = <32>; ++ }; ++ }; ++ ++ /omit-if-no-ref/ ++ uart4_2_cfg: uart4-2-cfg { ++ uart4-2-pins { ++ pinmux = , /* uart4_txd */ ++ ; /* uart4_rxd */ ++ bias-pull-up = <0>; ++ drive-strength = <32>; ++ }; ++ }; ++ ++ /omit-if-no-ref/ ++ uart4_3_cfg: uart4-3-cfg { ++ uart4-3-pins { ++ pinmux = , /* uart4_txd */ ++ ; /* uart4_rxd */ ++ bias-pull-up = <0>; ++ drive-strength = <32>; ++ }; ++ }; ++ ++ /omit-if-no-ref/ ++ uart4_3_cts_rts_cfg: uart4-3-cts-rts-cfg { ++ uart4-3-pins { ++ pinmux = , /* uart4_cts */ ++ ; /* uart4_rts */ ++ bias-pull-up = <0>; ++ drive-strength = <32>; ++ }; ++ }; ++ ++ /omit-if-no-ref/ ++ uart4_4_cfg: uart4-4-cfg { ++ uart4-4-pins { ++ pinmux = , /* uart4_txd */ ++ ; /* uart4_rxd */ ++ bias-pull-up = <0>; ++ drive-strength = <32>; ++ }; ++ }; ++ ++ /omit-if-no-ref/ ++ uart4_4_cts_rts_cfg: uart4-4-cts-rts-cfg { ++ uart4-4-pins { ++ pinmux = , /* uart4_cts */ ++ ; /* uart4_rts */ ++ bias-pull-up = <0>; ++ drive-strength = <32>; ++ }; ++ }; ++ ++ /omit-if-no-ref/ ++ uart5_0_cfg: uart5-0-cfg { ++ uart5-0-pins { ++ pinmux = , /* uart5_txd */ ++ ; /* uart5_rxd */ ++ power-source = <3300>; ++ bias-pull-up = <0>; ++ drive-strength = <19>; ++ }; ++ }; ++ ++ /omit-if-no-ref/ ++ uart5_1_cfg: uart5-1-cfg { ++ uart5-1-pins { ++ pinmux = , /* uart5_txd */ ++ ; /* uart5_rxd */ ++ bias-pull-up = <0>; ++ drive-strength = <32>; ++ }; ++ }; ++ ++ /omit-if-no-ref/ ++ uart5_1_cts_rts_cfg: uart5-1-cts-rts-cfg { ++ uart5-1-pins { ++ pinmux = , /* uart5_cts */ ++ ; /* uart5_rts */ ++ bias-pull-up = <0>; ++ drive-strength = <32>; ++ }; ++ }; ++ ++ /omit-if-no-ref/ ++ uart5_2_cfg: uart5-2-cfg { ++ uart5-2-pins { ++ pinmux = , /* uart5_txd */ ++ ; /* uart5_rxd */ ++ bias-pull-up = <0>; ++ drive-strength = <32>; ++ }; ++ }; ++ ++ /omit-if-no-ref/ ++ uart5_2_cts_rts_cfg: uart5-2-cts-rts-cfg { ++ uart5-2-pins { ++ pinmux = , /* uart5_cts */ ++ ; /* uart5_rts */ ++ bias-pull-up = <0>; ++ drive-strength = <32>; ++ }; ++ }; ++ ++ /omit-if-no-ref/ ++ uart5_3_cfg: uart5-3-cfg { ++ uart5-3-pins { ++ pinmux = , /* uart5_txd */ ++ ; /* uart5_rxd */ ++ bias-pull-up = <0>; ++ drive-strength = <32>; ++ }; ++ }; ++ ++ /omit-if-no-ref/ ++ uart5_3_cts_rts_cfg: uart5-3-cts-rts-cfg { ++ uart5-3-pins { ++ pinmux = , /* uart5_cts */ ++ ; /* uart5_rts */ ++ bias-pull-up = <0>; ++ drive-strength = <32>; ++ }; ++ }; ++ ++ /omit-if-no-ref/ ++ uart6_0_cfg: uart6-0-cfg { ++ uart6-0-pins { ++ pinmux = , /* uart6_txd */ ++ ; /* uart6_rxd */ ++ bias-pull-up = <0>; ++ drive-strength = <32>; ++ }; ++ }; ++ ++ /omit-if-no-ref/ ++ uart6_0_cts_rts_cfg: uart6-0-cts-rts-cfg { ++ uart6-0-pins { ++ pinmux = , /* uart6_cts */ ++ ; /* uart6_rts */ ++ bias-pull-up = <0>; ++ drive-strength = <32>; ++ }; ++ }; ++ ++ /omit-if-no-ref/ ++ uart6_1_cfg: uart6-1-cfg { ++ uart6-1-pins { ++ pinmux = , /* uart6_txd */ ++ ; /* uart6_rxd */ ++ bias-pull-up = <0>; ++ drive-strength = <32>; ++ }; ++ }; ++ ++ /omit-if-no-ref/ ++ uart6_1_cts_rts_cfg: uart6-1-cts-rts-cfg { ++ uart6-1-pins { ++ pinmux = , /* uart6_cts */ ++ ; /* uart6_rts */ ++ bias-pull-up = <0>; ++ drive-strength = <32>; ++ }; ++ }; ++ ++ /omit-if-no-ref/ ++ uart6_2_cfg: uart6-2-cfg { ++ uart6-2-pins { ++ pinmux = , /* uart6_txd */ ++ ; /* uart6_rxd */ ++ bias-pull-up = <0>; ++ drive-strength = <32>; ++ }; ++ }; ++ ++ /omit-if-no-ref/ ++ uart7_0_cfg: uart7-0-cfg { ++ uart7-0-pins { ++ pinmux = , /* uart7_txd */ ++ ; /* uart7_rxd */ ++ bias-pull-up = <0>; ++ drive-strength = <32>; ++ }; ++ }; ++ ++ /omit-if-no-ref/ ++ uart7_1_cfg: uart7-1-cfg { ++ uart7-1-pins { ++ pinmux = , /* uart7_txd */ ++ ; /* uart7_rxd */ ++ bias-pull-up = <0>; ++ drive-strength = <32>; ++ }; ++ }; ++ ++ /omit-if-no-ref/ ++ uart7_1_cts_rts_cfg: uart7-1-cts-rts-cfg { ++ uart7-1-pins { ++ pinmux = , /* uart7_cts */ ++ ; /* uart7_rts */ ++ bias-pull-up = <0>; ++ drive-strength = <32>; ++ }; ++ }; ++ ++ /omit-if-no-ref/ ++ uart8_0_cfg: uart8-0-cfg { ++ uart8-0-pins { ++ pinmux = , /* uart8_txd */ ++ ; /* uart8_rxd */ ++ bias-pull-up = <0>; ++ drive-strength = <32>; ++ }; ++ }; ++ ++ /omit-if-no-ref/ ++ uart8_1_cfg: uart8-1-cfg { ++ uart8-1-pins { ++ pinmux = , /* uart8_txd */ ++ ; /* uart8_rxd */ ++ bias-pull-up = <0>; ++ drive-strength = <32>; ++ }; ++ }; ++ ++ /omit-if-no-ref/ ++ uart8_1_cts_rts_cfg: uart8-1-cts-rts-cfg { ++ uart8-1-pins { ++ pinmux = , /* uart8_cts */ ++ ; /* uart8_rts */ ++ bias-pull-up = <0>; ++ drive-strength = <32>; ++ }; ++ }; ++ ++ /omit-if-no-ref/ ++ uart8_2_cfg: uart8-2-cfg { ++ uart8-2-pins { ++ pinmux = , /* uart8_txd */ ++ ; /* uart8_rxd */ ++ power-source = <3300>; ++ bias-pull-up = <0>; ++ drive-strength = <19>; ++ }; ++ }; ++ ++ /omit-if-no-ref/ ++ uart8_2_cts_rts_cfg: uart8-2-cts-rts-cfg { ++ uart8-2-pins { ++ pinmux = , /* uart8_cts */ ++ ; /* uart8_rts */ ++ power-source = <3300>; ++ bias-pull-up = <0>; ++ drive-strength = <19>; ++ }; ++ }; ++ ++ /omit-if-no-ref/ ++ uart9_0_cfg: uart9-0-cfg { ++ uart9-0-pins { ++ pinmux = , /* uart9_txd */ ++ ; /* uart9_rxd */ ++ bias-pull-up = <0>; ++ drive-strength = <32>; ++ }; ++ }; ++ ++ /omit-if-no-ref/ ++ uart9_1_cfg: uart9-1-cfg { ++ uart9-1-pins { ++ pinmux = , /* uart9_txd */ ++ ; /* uart9_rxd */ ++ bias-pull-up = <0>; ++ drive-strength = <32>; ++ }; ++ }; ++ ++ /omit-if-no-ref/ ++ uart9_1_cts_rts_cfg: uart9-1-cts-rts-cfg { ++ uart9-1-pins { ++ pinmux = , /* uart9_cts */ ++ ; /* uart9_rts */ ++ bias-pull-up = <0>; ++ drive-strength = <32>; ++ }; ++ }; + ++ /omit-if-no-ref/ ++ uart9_2_cfg: uart9-2-cfg { ++ uart9-2-pins { ++ pinmux = , /* uart9_txd */ ++ ; /* uart9_rxd */ + bias-pull-up = <0>; + drive-strength = <32>; + }; diff --git a/target/linux/spacemit/patches-6.18/0002-riscv-dts-spacemit-enable-the-i2c8-adapter.patch b/target/linux/spacemit/patches-6.18/0002-riscv-dts-spacemit-enable-the-i2c8-adapter.patch new file mode 100644 index 00000000000000..5e788e8eb85ab2 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0002-riscv-dts-spacemit-enable-the-i2c8-adapter.patch @@ -0,0 +1,77 @@ +From 30c530bb61204f41f5a8c3d1235a22268b94a97f Mon Sep 17 00:00:00 2001 +From: Alex Elder +Date: Mon, 25 Aug 2025 12:20:54 -0500 +Subject: [PATCH] riscv: dts: spacemit: enable the i2c8 adapter + +Define properties for the I2C adapter that provides access to the +SpacemiT P1 PMIC. Enable this adapter on the Banana Pi BPI-F3. + +Signed-off-by: Alex Elder +Link: https://lore.kernel.org/r/20250825172057.163883-6-elder@riscstar.com +Signed-off-by: Yixun Lan +(cherry picked from commit 3e8d7309e6260b1d066e733bf3e2e1b6a0d3f82b) +--- + arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts | 12 ++++++++++++ + arch/riscv/boot/dts/spacemit/k1-pinctrl.dtsi | 7 +++++++ + arch/riscv/boot/dts/spacemit/k1.dtsi | 13 +++++++++++++ + 3 files changed, 32 insertions(+) + +--- a/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts ++++ b/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts +@@ -92,6 +92,18 @@ + status = "okay"; + }; + ++&i2c8 { ++ pinctrl-0 = <&i2c8_cfg>; ++ pinctrl-names = "default"; ++ status = "okay"; ++ ++ pmic@41 { ++ compatible = "spacemit,p1"; ++ reg = <0x41>; ++ interrupts = <64>; ++ }; ++}; ++ + &uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_2_cfg>; +--- a/arch/riscv/boot/dts/spacemit/k1-pinctrl.dtsi ++++ b/arch/riscv/boot/dts/spacemit/k1-pinctrl.dtsi +@@ -59,6 +59,13 @@ + }; + }; + ++ i2c8_cfg: i2c8-cfg { ++ i2c8-0-pins { ++ pinmux = , /* PWR_SCL */ ++ ; /* PWR_SDA */ ++ }; ++ }; ++ + /omit-if-no-ref/ + uart0_0_cfg: uart0-0-cfg { + uart0-0-pins { +--- a/arch/riscv/boot/dts/spacemit/k1.dtsi ++++ b/arch/riscv/boot/dts/spacemit/k1.dtsi +@@ -459,6 +459,19 @@ + status = "disabled"; + }; + ++ i2c8: i2c@d401d800 { ++ compatible = "spacemit,k1-i2c"; ++ reg = <0x0 0xd401d800 0x0 0x38>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ clocks = <&syscon_apbc CLK_TWSI8>, ++ <&syscon_apbc CLK_TWSI8_BUS>; ++ clock-names = "func", "bus"; ++ clock-frequency = <400000>; ++ interrupts = <19>; ++ status = "disabled"; ++ }; ++ + pinctrl: pinctrl@d401e000 { + compatible = "spacemit,k1-pinctrl"; + reg = <0x0 0xd401e000 0x0 0x400>; diff --git a/target/linux/spacemit/patches-6.18/0003-riscv-dts-spacemit-define-fixed-regulators.patch b/target/linux/spacemit/patches-6.18/0003-riscv-dts-spacemit-define-fixed-regulators.patch new file mode 100644 index 00000000000000..e2a0ab7d8b9558 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0003-riscv-dts-spacemit-define-fixed-regulators.patch @@ -0,0 +1,44 @@ +From 70ca7e4361e9de8f8f34b00893cb0d5bf537b188 Mon Sep 17 00:00:00 2001 +From: Alex Elder +Date: Mon, 25 Aug 2025 12:20:55 -0500 +Subject: [PATCH] riscv: dts: spacemit: define fixed regulators + +Define the DC power input and the 4v power as fixed supplies in the +Banana Pi BPI-F3. + +Signed-off-by: Alex Elder +Link: https://lore.kernel.org/r/20250825172057.163883-7-elder@riscstar.com +Signed-off-by: Yixun Lan +(cherry picked from commit 1df07a40453fd652132051419140950d47941fe9) +--- + .../boot/dts/spacemit/k1-bananapi-f3.dts | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +--- a/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts ++++ b/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts +@@ -30,6 +30,25 @@ + default-state = "on"; + }; + }; ++ ++ reg_dc_in: dc-in-12v { ++ compatible = "regulator-fixed"; ++ regulator-name = "dc_in_12v"; ++ regulator-min-microvolt = <12000000>; ++ regulator-max-microvolt = <12000000>; ++ regulator-boot-on; ++ regulator-always-on; ++ }; ++ ++ reg_vcc_4v: vcc-4v { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc_4v"; ++ regulator-min-microvolt = <4000000>; ++ regulator-max-microvolt = <4000000>; ++ regulator-boot-on; ++ regulator-always-on; ++ vin-supply = <®_dc_in>; ++ }; + }; + + &emmc { diff --git a/target/linux/spacemit/patches-6.18/0004-riscv-dts-spacemit-define-regulator-constraints.patch b/target/linux/spacemit/patches-6.18/0004-riscv-dts-spacemit-define-regulator-constraints.patch new file mode 100644 index 00000000000000..5669186944d348 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0004-riscv-dts-spacemit-define-regulator-constraints.patch @@ -0,0 +1,129 @@ +From cf7eb12f17efee4e41d21fe281e72f32129d52fa Mon Sep 17 00:00:00 2001 +From: Alex Elder +Date: Mon, 25 Aug 2025 12:20:56 -0500 +Subject: [PATCH] riscv: dts: spacemit: define regulator constraints + +Define basic constraints for the regulators in the SpacemiT P1 PMIC, +as implemented in the Banana Pi BPI-F3. + +Signed-off-by: Alex Elder +Link: https://lore.kernel.org/r/20250825172057.163883-8-elder@riscstar.com +Signed-off-by: Yixun Lan +(cherry picked from commit 09a412d397484e76588707d85ccc37f71e491091) +--- + .../boot/dts/spacemit/k1-bananapi-f3.dts | 104 ++++++++++++++++++ + 1 file changed, 104 insertions(+) + +--- a/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts ++++ b/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts +@@ -120,6 +120,110 @@ + compatible = "spacemit,p1"; + reg = <0x41>; + interrupts = <64>; ++ vin-supply = <®_vcc_4v>; ++ ++ regulators { ++ buck1 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <3450000>; ++ regulator-ramp-delay = <5000>; ++ regulator-always-on; ++ }; ++ ++ buck2 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <3450000>; ++ regulator-ramp-delay = <5000>; ++ regulator-always-on; ++ }; ++ ++ buck3 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-ramp-delay = <5000>; ++ regulator-always-on; ++ }; ++ ++ buck4 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-ramp-delay = <5000>; ++ regulator-always-on; ++ }; ++ ++ buck5 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <3450000>; ++ regulator-ramp-delay = <5000>; ++ regulator-always-on; ++ }; ++ ++ buck6 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <3450000>; ++ regulator-ramp-delay = <5000>; ++ regulator-always-on; ++ }; ++ ++ aldo1 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <3400000>; ++ regulator-boot-on; ++ }; ++ ++ aldo2 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <3400000>; ++ }; ++ ++ aldo3 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <3400000>; ++ }; ++ ++ aldo4 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <3400000>; ++ }; ++ ++ dldo1 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <3400000>; ++ regulator-boot-on; ++ }; ++ ++ dldo2 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <3400000>; ++ }; ++ ++ dldo3 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <3400000>; ++ }; ++ ++ dldo4 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <3400000>; ++ regulator-always-on; ++ }; ++ ++ dldo5 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <3400000>; ++ }; ++ ++ dldo6 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <3400000>; ++ regulator-always-on; ++ }; ++ ++ dldo7 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <3400000>; ++ }; ++ }; + }; + }; + diff --git a/target/linux/spacemit/patches-6.18/0005-riscv-dts-spacemit-enable-the-i2c2-adapter-on-BPI-F3.patch b/target/linux/spacemit/patches-6.18/0005-riscv-dts-spacemit-enable-the-i2c2-adapter-on-BPI-F3.patch new file mode 100644 index 00000000000000..e5a04934602870 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0005-riscv-dts-spacemit-enable-the-i2c2-adapter-on-BPI-F3.patch @@ -0,0 +1,74 @@ +From 0cba925ad59dfaac9689169c21d82c82c35093f3 Mon Sep 17 00:00:00 2001 +From: Aurelien Jarno +Date: Fri, 26 Sep 2025 19:54:37 +0200 +Subject: [PATCH] riscv: dts: spacemit: enable the i2c2 adapter on BPI-F3 + +Define properties for the I2C adapter, and enable it on the BPI-F3. It +will be used by the 24c02 eeprom. + +Signed-off-by: Aurelien Jarno +Reviewed-by: Troy Mitchell +Reviewed-by: Vivian Wang +Reviewed-by: Yixun Lan +Link: https://lore.kernel.org/r/20250926175833.3048516-2-aurelien@aurel32.net +Signed-off-by: Yixun Lan +(cherry picked from commit dcca2287773b69201b756723e8d45b6b8ad81b34) +--- + arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts | 6 ++++++ + arch/riscv/boot/dts/spacemit/k1-pinctrl.dtsi | 7 +++++++ + arch/riscv/boot/dts/spacemit/k1.dtsi | 13 +++++++++++++ + 3 files changed, 26 insertions(+) + +--- a/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts ++++ b/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts +@@ -111,6 +111,12 @@ + status = "okay"; + }; + ++&i2c2 { ++ pinctrl-0 = <&i2c2_0_cfg>; ++ pinctrl-names = "default"; ++ status = "okay"; ++}; ++ + &i2c8 { + pinctrl-0 = <&i2c8_cfg>; + pinctrl-names = "default"; +--- a/arch/riscv/boot/dts/spacemit/k1-pinctrl.dtsi ++++ b/arch/riscv/boot/dts/spacemit/k1-pinctrl.dtsi +@@ -59,6 +59,13 @@ + }; + }; + ++ i2c2_0_cfg: i2c2-0-cfg { ++ i2c2-0-pins { ++ pinmux = , /* I2C2_SCL */ ++ ; /* I2C2_SDA */ ++ }; ++ }; ++ + i2c8_cfg: i2c8-cfg { + i2c8-0-pins { + pinmux = , /* PWR_SCL */ +--- a/arch/riscv/boot/dts/spacemit/k1.dtsi ++++ b/arch/riscv/boot/dts/spacemit/k1.dtsi +@@ -459,6 +459,19 @@ + status = "disabled"; + }; + ++ i2c2: i2c@d4012000 { ++ compatible = "spacemit,k1-i2c"; ++ reg = <0x0 0xd4012000 0x0 0x38>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ clocks = <&syscon_apbc CLK_TWSI2>, ++ <&syscon_apbc CLK_TWSI2_BUS>; ++ clock-names = "func", "bus"; ++ clock-frequency = <400000>; ++ interrupts = <38>; ++ status = "disabled"; ++ }; ++ + i2c8: i2c@d401d800 { + compatible = "spacemit,k1-i2c"; + reg = <0x0 0xd401d800 0x0 0x38>; diff --git a/target/linux/spacemit/patches-6.18/0006-riscv-dts-spacemit-add-24c02-eeprom-on-BPI-F3.patch b/target/linux/spacemit/patches-6.18/0006-riscv-dts-spacemit-add-24c02-eeprom-on-BPI-F3.patch new file mode 100644 index 00000000000000..00bec61d25d81d --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0006-riscv-dts-spacemit-add-24c02-eeprom-on-BPI-F3.patch @@ -0,0 +1,64 @@ +From 675ca5ae624877b3b5cb2759e62708ca31c3ec9d Mon Sep 17 00:00:00 2001 +From: Aurelien Jarno +Date: Fri, 26 Sep 2025 19:54:38 +0200 +Subject: [PATCH] riscv: dts: spacemit: add 24c02 eeprom on BPI-F3 + +The BPI-F3 board includes a 24c02 eeprom, that stores the MAC addresses +of the two network interfaces and the board's serial number. These +values are also exposed via an onie,tlv-layout nvmem layout. + +The eeprom is marked as read-only since its contents are not supposed to +be modified. + +Signed-off-by: Aurelien Jarno +Reviewed-by: Troy Mitchell +Reviewed-by: Vivian Wang +Reviewed-by: Yixun Lan +Link: https://lore.kernel.org/r/20250926175833.3048516-3-aurelien@aurel32.net +Signed-off-by: Yixun Lan +(cherry picked from commit bfce75e2345fa1ecbf046e696994132f56d6db1c) +--- + .../boot/dts/spacemit/k1-bananapi-f3.dts | 25 ++++++++++++++++++- + 1 file changed, 24 insertions(+), 1 deletion(-) + +--- a/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts ++++ b/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts +@@ -115,6 +115,29 @@ + pinctrl-0 = <&i2c2_0_cfg>; + pinctrl-names = "default"; + status = "okay"; ++ ++ eeprom@50 { ++ compatible = "atmel,24c02"; ++ reg = <0x50>; ++ vcc-supply = <&buck3_1v8>; /* EEPROM_VCC1V8 */ ++ pagesize = <16>; ++ read-only; ++ size = <256>; ++ ++ nvmem-layout { ++ compatible = "onie,tlv-layout"; ++ ++ mac-address { ++ #nvmem-cell-cells = <1>; ++ }; ++ ++ num-macs { ++ }; ++ ++ serial-number { ++ }; ++ }; ++ }; + }; + + &i2c8 { +@@ -143,7 +166,7 @@ + regulator-always-on; + }; + +- buck3 { ++ buck3_1v8: buck3 { + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <1800000>; + regulator-ramp-delay = <5000>; diff --git a/target/linux/spacemit/patches-6.18/0007-riscv-dts-spacemit-add-i2c-aliases-on-BPI-F3.patch b/target/linux/spacemit/patches-6.18/0007-riscv-dts-spacemit-add-i2c-aliases-on-BPI-F3.patch new file mode 100644 index 00000000000000..7d05f36df1938a --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0007-riscv-dts-spacemit-add-i2c-aliases-on-BPI-F3.patch @@ -0,0 +1,30 @@ +From 6d930878d6bd32113a684856387d939076d0d657 Mon Sep 17 00:00:00 2001 +From: Aurelien Jarno +Date: Fri, 26 Sep 2025 19:54:39 +0200 +Subject: [PATCH] riscv: dts: spacemit: add i2c aliases on BPI-F3 + +Add i2c aliases for i2c2 and i2c8 on BPI-F3. This is useful to keep a +stable number for the /dev entries after loading the i2c-dev module. + +Signed-off-by: Aurelien Jarno +Reviewed-by: Troy Mitchell +Reviewed-by: Vivian Wang +Reviewed-by: Yixun Lan +Link: https://lore.kernel.org/r/20250926175833.3048516-4-aurelien@aurel32.net +Signed-off-by: Yixun Lan +(cherry picked from commit 859ce3828f0b462e991c24224390def4c8fea673) +--- + arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts ++++ b/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts +@@ -14,6 +14,8 @@ + ethernet0 = ð0; + ethernet1 = ð1; + serial0 = &uart0; ++ i2c2 = &i2c2; ++ i2c8 = &i2c8; + }; + + chosen { diff --git a/target/linux/spacemit/patches-6.18/0008-net-spacemit-Avoid-Wflex-array-member-not-at-end-war.patch b/target/linux/spacemit/patches-6.18/0008-net-spacemit-Avoid-Wflex-array-member-not-at-end-war.patch new file mode 100644 index 00000000000000..2b353e4d940243 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0008-net-spacemit-Avoid-Wflex-array-member-not-at-end-war.patch @@ -0,0 +1,61 @@ +From bc43dc38efa4f029d98a4da04228187011c33535 Mon Sep 17 00:00:00 2001 +From: "Gustavo A. R. Silva" +Date: Tue, 21 Oct 2025 12:54:10 +0100 +Subject: [PATCH] net: spacemit: Avoid -Wflex-array-member-not-at-end warnings + +-Wflex-array-member-not-at-end was introduced in GCC-14, and we are +getting ready to enable it, globally. + +Use regular arrays instead of flexible-array members (they're not +really needed in this case) in a couple of unions, and fix the +following warnings: + + 1 drivers/net/ethernet/spacemit/k1_emac.c:122:42: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end] + 1 drivers/net/ethernet/spacemit/k1_emac.c:122:32: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end] + 1 drivers/net/ethernet/spacemit/k1_emac.c:121:42: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end] + 1 drivers/net/ethernet/spacemit/k1_emac.c:121:32: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end] + +Signed-off-by: Gustavo A. R. Silva +Reviewed-by: Simon Horman +Acked-by: Vivian Wang +Link: https://patch.msgid.link/aPd0YjO-oP60Lgvj@kspp +Signed-off-by: Jakub Kicinski +(cherry picked from commit 10e0378f05d2b89c4f88f04ec56b2a5b9a116648) +--- + drivers/net/ethernet/spacemit/k1_emac.h | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/net/ethernet/spacemit/k1_emac.h ++++ b/drivers/net/ethernet/spacemit/k1_emac.h +@@ -363,7 +363,7 @@ struct emac_desc { + /* Keep stats in this order, index used for accessing hardware */ + + union emac_hw_tx_stats { +- struct { ++ struct individual_tx_stats { + u64 tx_ok_pkts; + u64 tx_total_pkts; + u64 tx_ok_bytes; +@@ -378,11 +378,11 @@ union emac_hw_tx_stats { + u64 tx_pause_pkts; + } stats; + +- DECLARE_FLEX_ARRAY(u64, array); ++ u64 array[sizeof(struct individual_tx_stats) / sizeof(u64)]; + }; + + union emac_hw_rx_stats { +- struct { ++ struct individual_rx_stats { + u64 rx_ok_pkts; + u64 rx_total_pkts; + u64 rx_crc_err_pkts; +@@ -410,7 +410,7 @@ union emac_hw_rx_stats { + u64 rx_truncate_fifo_full_pkts; + } stats; + +- DECLARE_FLEX_ARRAY(u64, array); ++ u64 array[sizeof(struct individual_rx_stats) / sizeof(u64)]; + }; + + #endif /* _K1_EMAC_H_ */ diff --git a/target/linux/spacemit/patches-6.18/0009-riscv-dts-spacemit-add-Ethernet-and-PDMA-to-OrangePi.patch b/target/linux/spacemit/patches-6.18/0009-riscv-dts-spacemit-add-Ethernet-and-PDMA-to-OrangePi.patch new file mode 100644 index 00000000000000..b824daf4376849 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0009-riscv-dts-spacemit-add-Ethernet-and-PDMA-to-OrangePi.patch @@ -0,0 +1,88 @@ +From a3d676d6310122f9551f1726e7c192d4de951916 Mon Sep 17 00:00:00 2001 +From: Michael Opdenacker +Date: Wed, 22 Oct 2025 20:18:38 +0000 +Subject: [PATCH] riscv: dts: spacemit: add Ethernet and PDMA to OrangePi RV2 + +The OrangePi RV2 board ships two RGMII ethernet ports. +Each has an external Motorcomm YT8531C PHY attached, the PHY uses GPIO +for reset pin control. + +Enable PDMA for the SpacemiT K1-based SoC in the OrangePi RV2 board. + +Signed-off-by: Michael Opdenacker +Reviewed-by: Yixun Lan +Link: https://lore.kernel.org/r/20251022201807.1474789-2-michael.opdenacker@rootcommit.com +Signed-off-by: Yixun Lan +(cherry picked from commit 9813395078352fed03c88742bd39b9c4a0e40c15) +--- + .../boot/dts/spacemit/k1-orangepi-rv2.dts | 52 +++++++++++++++++++ + 1 file changed, 52 insertions(+) + +--- a/arch/riscv/boot/dts/spacemit/k1-orangepi-rv2.dts ++++ b/arch/riscv/boot/dts/spacemit/k1-orangepi-rv2.dts +@@ -15,6 +15,8 @@ + + aliases { + serial0 = &uart0; ++ ethernet0 = ð0; ++ ethernet1 = ð1; + }; + + chosen { +@@ -33,6 +35,56 @@ + }; + }; + ++ð0 { ++ phy-handle = <&rgmii0>; ++ phy-mode = "rgmii-id"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&gmac0_cfg>; ++ rx-internal-delay-ps = <0>; ++ tx-internal-delay-ps = <0>; ++ status = "okay"; ++ ++ mdio-bus { ++ #address-cells = <0x1>; ++ #size-cells = <0x0>; ++ ++ reset-gpios = <&gpio K1_GPIO(110) GPIO_ACTIVE_LOW>; ++ reset-delay-us = <10000>; ++ reset-post-delay-us = <100000>; ++ ++ rgmii0: phy@1 { ++ reg = <0x1>; ++ }; ++ }; ++}; ++ ++ð1 { ++ phy-handle = <&rgmii1>; ++ phy-mode = "rgmii-id"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&gmac1_cfg>; ++ rx-internal-delay-ps = <0>; ++ tx-internal-delay-ps = <250>; ++ status = "okay"; ++ ++ mdio-bus { ++ #address-cells = <0x1>; ++ #size-cells = <0x0>; ++ ++ reset-gpios = <&gpio K1_GPIO(115) GPIO_ACTIVE_LOW>; ++ reset-delay-us = <10000>; ++ reset-post-delay-us = <100000>; ++ ++ rgmii1: phy@1 { ++ reg = <0x1>; ++ }; ++ }; ++}; ++ ++&pdma { ++ status = "okay"; ++}; ++ + &uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_2_cfg>; diff --git a/target/linux/spacemit/patches-6.18/0010-driver-reset-spacemit-p1-add-driver-for-poweroff-reb.patch b/target/linux/spacemit/patches-6.18/0010-driver-reset-spacemit-p1-add-driver-for-poweroff-reb.patch new file mode 100644 index 00000000000000..837185fd02f270 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0010-driver-reset-spacemit-p1-add-driver-for-poweroff-reb.patch @@ -0,0 +1,143 @@ +From 55a5ed1ad68ea82b0ddeb76fa253b41afa64f43f Mon Sep 17 00:00:00 2001 +From: Aurelien Jarno +Date: Mon, 3 Nov 2025 00:01:59 +0100 +Subject: [PATCH] driver: reset: spacemit-p1: add driver for poweroff/reboot + +This driver implements poweroff/reboot support for the SpacemiT P1 PMIC +chip, which is commonly paired with the SpacemiT K1 SoC. + +The SpacemiT P1 support is implemented as a MFD driver, so the access is +done directly through the regmap interface. Reboot or poweroff is +triggered by setting a specific bit in a control register, which is +automatically cleared by the hardware afterwards. + +Signed-off-by: Aurelien Jarno +Link: https://patch.msgid.link/20251102230352.914421-2-aurelien@aurel32.net +Signed-off-by: Sebastian Reichel +(cherry picked from commit 28124cc0fb8c7dc01a6834d227351e25d9a92c58) +--- + drivers/power/reset/Kconfig | 9 +++ + drivers/power/reset/Makefile | 1 + + drivers/power/reset/spacemit-p1-reboot.c | 88 ++++++++++++++++++++++++ + 3 files changed, 98 insertions(+) + create mode 100644 drivers/power/reset/spacemit-p1-reboot.c + +--- a/drivers/power/reset/Kconfig ++++ b/drivers/power/reset/Kconfig +@@ -283,6 +283,15 @@ config POWER_RESET_KEYSTONE + help + Reboot support for the KEYSTONE SoCs. + ++config POWER_RESET_SPACEMIT_P1 ++ tristate "SpacemiT P1 poweroff and reset driver" ++ depends on ARCH_SPACEMIT || COMPILE_TEST ++ depends on MFD_SPACEMIT_P1 ++ default MFD_SPACEMIT_P1 ++ help ++ This driver supports power-off and reset operations for the SpacemiT ++ P1 PMIC. ++ + config POWER_RESET_SYSCON + bool "Generic SYSCON regmap reset driver" + depends on OF +--- a/drivers/power/reset/Makefile ++++ b/drivers/power/reset/Makefile +@@ -24,6 +24,7 @@ obj-$(CONFIG_POWER_RESET_LTC2952) += ltc + obj-$(CONFIG_POWER_RESET_QNAP) += qnap-poweroff.o + obj-$(CONFIG_POWER_RESET_REGULATOR) += regulator-poweroff.o + obj-$(CONFIG_POWER_RESET_RESTART) += restart-poweroff.o ++obj-$(CONFIG_POWER_RESET_SPACEMIT_P1) += spacemit-p1-reboot.o + obj-$(CONFIG_POWER_RESET_ST) += st-poweroff.o + obj-$(CONFIG_POWER_RESET_TH1520_AON) += th1520-aon-reboot.o + obj-$(CONFIG_POWER_RESET_TORADEX_EC) += tdx-ec-poweroff.o +--- /dev/null ++++ b/drivers/power/reset/spacemit-p1-reboot.c +@@ -0,0 +1,88 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright (C) 2025 by Aurelien Jarno ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++/* Power Control Register 2 */ ++#define PWR_CTRL2 0x7e ++#define PWR_CTRL2_SHUTDOWN BIT(2) /* Shutdown request */ ++#define PWR_CTRL2_RST BIT(1) /* Reset request */ ++ ++static int spacemit_p1_pwroff_handler(struct sys_off_data *data) ++{ ++ struct regmap *regmap = data->cb_data; ++ int ret; ++ ++ /* Put the PMIC into shutdown state */ ++ ret = regmap_set_bits(regmap, PWR_CTRL2, PWR_CTRL2_SHUTDOWN); ++ if (ret) { ++ dev_err(data->dev, "shutdown failed: %d\n", ret); ++ return notifier_from_errno(ret); ++ } ++ ++ return NOTIFY_DONE; ++} ++ ++static int spacemit_p1_restart_handler(struct sys_off_data *data) ++{ ++ struct regmap *regmap = data->cb_data; ++ int ret; ++ ++ /* Put the PMIC into reset state */ ++ ret = regmap_set_bits(regmap, PWR_CTRL2, PWR_CTRL2_RST); ++ if (ret) { ++ dev_err(data->dev, "restart failed: %d\n", ret); ++ return notifier_from_errno(ret); ++ } ++ ++ return NOTIFY_DONE; ++} ++ ++static int spacemit_p1_reboot_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct regmap *regmap; ++ int ret; ++ ++ regmap = dev_get_regmap(dev->parent, NULL); ++ if (!regmap) ++ return -ENODEV; ++ ++ ret = devm_register_power_off_handler(dev, &spacemit_p1_pwroff_handler, ++ regmap); ++ if (ret) ++ return dev_err_probe(dev, ret, ++ "Failed to register power off handler\n"); ++ ++ ret = devm_register_restart_handler(dev, spacemit_p1_restart_handler, ++ regmap); ++ if (ret) ++ return dev_err_probe(dev, ret, ++ "Failed to register restart handler\n"); ++ ++ return 0; ++} ++ ++static const struct platform_device_id spacemit_p1_reboot_id_table[] = { ++ { "spacemit-p1-reboot", }, ++ { /* sentinel */ }, ++}; ++MODULE_DEVICE_TABLE(platform, spacemit_p1_reboot_id_table); ++ ++static struct platform_driver spacemit_p1_reboot_driver = { ++ .driver = { ++ .name = "spacemit-p1-reboot", ++ }, ++ .probe = spacemit_p1_reboot_probe, ++ .id_table = spacemit_p1_reboot_id_table, ++}; ++module_platform_driver(spacemit_p1_reboot_driver); ++ ++MODULE_DESCRIPTION("SpacemiT P1 reboot/poweroff driver"); ++MODULE_LICENSE("GPL"); diff --git a/target/linux/spacemit/patches-6.18/0011-dt-bindings-riscv-spacemit-add-MusePi-Pro-board.patch b/target/linux/spacemit/patches-6.18/0011-dt-bindings-riscv-spacemit-add-MusePi-Pro-board.patch new file mode 100644 index 00000000000000..2c07efd1dc7194 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0011-dt-bindings-riscv-spacemit-add-MusePi-Pro-board.patch @@ -0,0 +1,43 @@ +From 2729eac34f35adb03b5b958d5a579d1762623986 Mon Sep 17 00:00:00 2001 +From: Troy Mitchell +Date: Thu, 23 Oct 2025 15:28:29 +0800 +Subject: [PATCH] dt-bindings: riscv: spacemit: add MusePi Pro board + +Document the compatible string for the MusePi Pro [1]. It is a 1.8-inch +single board computer based on the SpacemiT K1/M1 RISC-V SoC [2]. + +Here's a refined list of its core features: + - SoC: SpacemiT M1/K1, 8-core 64-bit RISC-V. + - Memory: LPDDR4X @ 2400MT/s, available in 8GB & 16GB options. + - Storage: Onboard eMMC 5.1 (64GB/128GB options), M.2 M-Key for NVMe + SSD (2230 size), and a microSD slot (UHS-II) for expansion. + - Display: HDMI 1.4 (1080P@60Hz) and 2-lane MIPI DSI FPC (1080P@60Hz). + - Connectivity: Onboard Wi-Fi 6 & Bluetooth 5.2, single Gigabit Ethernet + port (RJ45). + - USB: 4x USB 3.0 Type-A (host) and 1x USB 2.0 Type-C (device/OTG). + - Expansion: Full-size miniPCIe slot and a second M.2 M-Key (2230). + - GPIO: Standard 40-pin GPIO interface. + - MIPI: 1x 4-lane MIPI CSI FPC and 2x MIPI DSI FPC interfaces. + - Clock: Onboard RTC with battery support. + +Link: https://developer.spacemit.com/documentation?token=YJtdwnvvViPVcmkoPDpcvwfVnrh&type=pdf [1] +Link: https://www.spacemit.com/en/key-stone-k1 [2] +Acked-by: Conor Dooley +Signed-off-by: Troy Mitchell +Link: https://lore.kernel.org/r/20251023-k1-musepi-pro-dts-v4-1-01836303e10f@linux.spacemit.com +Signed-off-by: Yixun Lan +(cherry picked from commit 2cc22890635ded33856e2761b780688f54a49393) +--- + Documentation/devicetree/bindings/riscv/spacemit.yaml | 1 + + 1 file changed, 1 insertion(+) + +--- a/Documentation/devicetree/bindings/riscv/spacemit.yaml ++++ b/Documentation/devicetree/bindings/riscv/spacemit.yaml +@@ -22,6 +22,7 @@ properties: + - enum: + - bananapi,bpi-f3 + - milkv,jupiter ++ - spacemit,musepi-pro + - xunlong,orangepi-rv2 + - const: spacemit,k1 + diff --git a/target/linux/spacemit/patches-6.18/0012-riscv-dts-spacemit-add-MusePi-Pro-board-device-tree.patch b/target/linux/spacemit/patches-6.18/0012-riscv-dts-spacemit-add-MusePi-Pro-board-device-tree.patch new file mode 100644 index 00000000000000..2a506e68fd6d00 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0012-riscv-dts-spacemit-add-MusePi-Pro-board-device-tree.patch @@ -0,0 +1,114 @@ +From 4f54b16f169df8616f0868e02ca9963855e91e4e Mon Sep 17 00:00:00 2001 +From: Troy Mitchell +Date: Thu, 23 Oct 2025 15:28:30 +0800 +Subject: [PATCH] riscv: dts: spacemit: add MusePi Pro board device tree + +Add initial device tree support for the MusePi Pro board [1]. +The board is using the SpacemiT K1/M1 SoC. + +This device tree is adapted from the SpacemiT vendor tree [2] and +enables basic board functionality, including UART console, LED, eMMC, +Ethernet, and PDMA. + +Link: https://developer.spacemit.com/documentation?token=YJtdwnvvViPVcmkoPDpcvwfVnrh&type=pdf [1] +Link: https://gitee.com/bianbu-linux/linux-6.6/blob/k1-bl-v2.2.y/arch/riscv/boot/dts/spacemit/k1-x_MUSE-Pi-Pro.dts [2] +Signed-off-by: Troy Mitchell +Link: https://lore.kernel.org/r/20251023-k1-musepi-pro-dts-v4-2-01836303e10f@linux.spacemit.com +Signed-off-by: Yixun Lan +(cherry picked from commit 0ee59934662dfb89b43a8392e64ac4880c2fca88) +--- + arch/riscv/boot/dts/spacemit/Makefile | 1 + + .../riscv/boot/dts/spacemit/k1-musepi-pro.dts | 79 +++++++++++++++++++ + 2 files changed, 80 insertions(+) + create mode 100644 arch/riscv/boot/dts/spacemit/k1-musepi-pro.dts + +--- a/arch/riscv/boot/dts/spacemit/Makefile ++++ b/arch/riscv/boot/dts/spacemit/Makefile +@@ -1,4 +1,5 @@ + # SPDX-License-Identifier: GPL-2.0 + dtb-$(CONFIG_ARCH_SPACEMIT) += k1-bananapi-f3.dtb + dtb-$(CONFIG_ARCH_SPACEMIT) += k1-milkv-jupiter.dtb ++dtb-$(CONFIG_ARCH_SPACEMIT) += k1-musepi-pro.dtb + dtb-$(CONFIG_ARCH_SPACEMIT) += k1-orangepi-rv2.dtb +--- /dev/null ++++ b/arch/riscv/boot/dts/spacemit/k1-musepi-pro.dts +@@ -0,0 +1,79 @@ ++// SPDX-License-Identifier: (GPL-2.0 OR MIT) ++/* ++ * Copyright (C) 2024 Yangyu Chen ++ * Copyright (C) 2025 SpacemiT, Inc ++ * Copyright (C) 2025 Troy Mitchell ++ */ ++ ++/dts-v1/; ++ ++#include "k1.dtsi" ++#include "k1-pinctrl.dtsi" ++ ++/ { ++ model = "SpacemiT MusePi Pro"; ++ compatible = "spacemit,musepi-pro", "spacemit,k1"; ++ ++ aliases { ++ ethernet0 = ð0; ++ serial0 = &uart0; ++ }; ++ ++ chosen { ++ stdout-path = "serial0"; ++ }; ++ ++ leds { ++ compatible = "gpio-leds"; ++ ++ led1 { ++ label = "sys-led"; ++ gpios = <&gpio K1_GPIO(96) GPIO_ACTIVE_HIGH>; ++ linux,default-trigger = "heartbeat"; ++ default-state = "on"; ++ }; ++ }; ++}; ++ ++&emmc { ++ bus-width = <8>; ++ mmc-hs400-1_8v; ++ mmc-hs400-enhanced-strobe; ++ non-removable; ++ no-sd; ++ no-sdio; ++ status = "okay"; ++}; ++ ++ð0 { ++ phy-handle = <&rgmii0>; ++ phy-mode = "rgmii-id"; ++ pinctrl-0 = <&gmac0_cfg>; ++ pinctrl-names = "default"; ++ rx-internal-delay-ps = <0>; ++ tx-internal-delay-ps = <0>; ++ status = "okay"; ++ ++ mdio-bus { ++ #address-cells = <0x1>; ++ #size-cells = <0x0>; ++ ++ reset-gpios = <&gpio K1_GPIO(110) GPIO_ACTIVE_LOW>; ++ reset-delay-us = <10000>; ++ reset-post-delay-us = <100000>; ++ ++ rgmii0: phy@1 { ++ reg = <0x1>; ++ }; ++ }; ++}; ++ ++&pdma { ++ status = "okay"; ++}; ++ ++&uart0 { ++ pinctrl-0 = <&uart0_2_cfg>; ++ pinctrl-names = "default"; ++ status = "okay"; ++}; diff --git a/target/linux/spacemit/patches-6.18/0013-mfd-simple-mfd-i2c-Remove-select-I2C_K1-from-MFD_SPA.patch b/target/linux/spacemit/patches-6.18/0013-mfd-simple-mfd-i2c-Remove-select-I2C_K1-from-MFD_SPA.patch new file mode 100644 index 00000000000000..69fff9ba873c66 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0013-mfd-simple-mfd-i2c-Remove-select-I2C_K1-from-MFD_SPA.patch @@ -0,0 +1,35 @@ +From 395366c887da0d2e92af1a7d12a4b358a2b51f1a Mon Sep 17 00:00:00 2001 +From: Troy Mitchell +Date: Mon, 27 Oct 2025 13:48:05 +0800 +Subject: [PATCH] mfd: simple-mfd-i2c: Remove select I2C_K1 from + MFD_SPACEMIT_P1 + +select will force a symbol to a specific value without considering +its dependencies. As a result, the i2c-k1 driver will fail to build +when OF or COMMON_CLK are disabled. + +The reason for removing I2C_K1 instead of adding a depends on condition +is to keep the possibility for other SoCs to use this PMIC. + +Reported-by: kernel test robot +Closes: https://lore.kernel.org/oe-kbuild-all/202510211523.sSEVqPUQ-lkp@intel.com/ +Acked-by: Alex Elder +Signed-off-by: Troy Mitchell +Link: https://lore.kernel.org/all/20251022004830-GYB1522542@gentoo.org/ [1] +Link: https://patch.msgid.link/20251027-p1-kconfig-fix-v2-1-49688f30bae8@linux.spacemit.com +Signed-off-by: Lee Jones +(cherry picked from commit ecf6bc474ae97c404e2125b413eb0ef3627b03c5) +--- + drivers/mfd/Kconfig | 1 - + 1 file changed, 1 deletion(-) + +--- a/drivers/mfd/Kconfig ++++ b/drivers/mfd/Kconfig +@@ -1269,7 +1269,6 @@ config MFD_SPACEMIT_P1 + tristate "SpacemiT P1 PMIC" + depends on ARCH_SPACEMIT || COMPILE_TEST + depends on I2C +- select I2C_K1 + select MFD_SIMPLE_MFD_I2C + help + This option supports the I2C-based SpacemiT P1 PMIC, which diff --git a/target/linux/spacemit/patches-6.18/0014-spi-dt-bindings-fsl-qspi-support-SpacemiT-K1.patch b/target/linux/spacemit/patches-6.18/0014-spi-dt-bindings-fsl-qspi-support-SpacemiT-K1.patch new file mode 100644 index 00000000000000..b30f52caff3408 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0014-spi-dt-bindings-fsl-qspi-support-SpacemiT-K1.patch @@ -0,0 +1,29 @@ +From c46740878b51e5e589c3d2d21cbb837c5ffc31b1 Mon Sep 17 00:00:00 2001 +From: Alex Elder +Date: Mon, 27 Oct 2025 08:29:59 -0500 +Subject: [PATCH] spi: dt-bindings: fsl-qspi: support SpacemiT K1 + +Add the SpacemiT K1 SoC QSPI IP to the list of supported hardware. This +is the first non-Freescale device represented here. It has a nearly +identidal register set, and this binding correctly describes the hardware. + +Acked-by: Conor Dooley +Reviewed-by: Frank Li +Signed-off-by: Alex Elder +Link: https://patch.msgid.link/20251027133008.360237-2-elder@riscstar.com +Signed-off-by: Mark Brown +(cherry picked from commit bd352547df647be8a1e6c9d4ca2b54b459f3abc1) +--- + Documentation/devicetree/bindings/spi/fsl,spi-fsl-qspi.yaml | 1 + + 1 file changed, 1 insertion(+) + +--- a/Documentation/devicetree/bindings/spi/fsl,spi-fsl-qspi.yaml ++++ b/Documentation/devicetree/bindings/spi/fsl,spi-fsl-qspi.yaml +@@ -22,6 +22,7 @@ properties: + - fsl,imx6ul-qspi + - fsl,ls1021a-qspi + - fsl,ls2080a-qspi ++ - spacemit,k1-qspi + - items: + - enum: + - fsl,ls1043a-qspi diff --git a/target/linux/spacemit/patches-6.18/0015-spi-dt-bindings-fsl-qspi-add-optional-resets.patch b/target/linux/spacemit/patches-6.18/0015-spi-dt-bindings-fsl-qspi-add-optional-resets.patch new file mode 100644 index 00000000000000..97280d9e5ac0ae --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0015-spi-dt-bindings-fsl-qspi-add-optional-resets.patch @@ -0,0 +1,61 @@ +From e7b37f4b5aae4120f1fe034fa4b16e41d2d05498 Mon Sep 17 00:00:00 2001 +From: Alex Elder +Date: Mon, 27 Oct 2025 08:30:00 -0500 +Subject: [PATCH] spi: dt-bindings: fsl-qspi: add optional resets + +Allow two resets to be defined to support the SpacemiT K1 SoC QSPI IP. +Move the allOf block down, below the required section. + +Reviewed-by: Frank Li +Acked-by: Conor Dooley +Signed-off-by: Alex Elder +Link: https://patch.msgid.link/20251027133008.360237-3-elder@riscstar.com +Signed-off-by: Mark Brown +(cherry picked from commit 873a46141460d209bb62eaa0dc9e7b67bff924a6) +--- + .../bindings/spi/fsl,spi-fsl-qspi.yaml | 20 ++++++++++++++++--- + 1 file changed, 17 insertions(+), 3 deletions(-) + +--- a/Documentation/devicetree/bindings/spi/fsl,spi-fsl-qspi.yaml ++++ b/Documentation/devicetree/bindings/spi/fsl,spi-fsl-qspi.yaml +@@ -9,9 +9,6 @@ title: Freescale Quad Serial Peripheral + maintainers: + - Han Xu + +-allOf: +- - $ref: spi-controller.yaml# +- + properties: + compatible: + oneOf: +@@ -55,6 +52,11 @@ properties: + - const: qspi_en + - const: qspi + ++ resets: ++ items: ++ - description: SoC QSPI reset ++ - description: SoC QSPI bus reset ++ + required: + - compatible + - reg +@@ -63,6 +65,18 @@ required: + - clocks + - clock-names + ++allOf: ++ - $ref: spi-controller.yaml# ++ - if: ++ properties: ++ compatible: ++ not: ++ contains: ++ const: spacemit,k1-qspi ++ then: ++ properties: ++ resets: false ++ + unevaluatedProperties: false + + examples: diff --git a/target/linux/spacemit/patches-6.18/0016-spi-fsl-qspi-add-a-clock-disable-quirk.patch b/target/linux/spacemit/patches-6.18/0016-spi-fsl-qspi-add-a-clock-disable-quirk.patch new file mode 100644 index 00000000000000..f193fb9027bd7f --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0016-spi-fsl-qspi-add-a-clock-disable-quirk.patch @@ -0,0 +1,67 @@ +From 5292bab09e0a3343c6884277100bee9624a6c0e2 Mon Sep 17 00:00:00 2001 +From: Alex Elder +Date: Mon, 27 Oct 2025 08:30:03 -0500 +Subject: [PATCH] spi: fsl-qspi: add a clock disable quirk + +The SpacemiT K1 SoC QSPI implementation needs to avoid shutting off the +clock when changing its rate. Add a new quirk to indicate that disabling +and enabling the clock should be skipped when changing its rate. + +Reviewed-by: Frank Li +Signed-off-by: Alex Elder +Link: https://patch.msgid.link/20251027133008.360237-6-elder@riscstar.com +Signed-off-by: Mark Brown +(cherry picked from commit 1797d254f5c4b46b295527a635af7321a3fe1318) +--- + drivers/spi/spi-fsl-qspi.c | 21 +++++++++++++++++---- + 1 file changed, 17 insertions(+), 4 deletions(-) + +--- a/drivers/spi/spi-fsl-qspi.c ++++ b/drivers/spi/spi-fsl-qspi.c +@@ -196,6 +196,11 @@ + */ + #define QUADSPI_QUIRK_USE_TDH_SETTING BIT(5) + ++/* ++ * Do not disable the "qspi" clock when changing its rate. ++ */ ++#define QUADSPI_QUIRK_SKIP_CLK_DISABLE BIT(6) ++ + struct fsl_qspi_devtype_data { + unsigned int rxfifo; + unsigned int txfifo; +@@ -304,6 +309,11 @@ static inline int needs_tdh_setting(stru + return q->devtype_data->quirks & QUADSPI_QUIRK_USE_TDH_SETTING; + } + ++static bool needs_clk_disable(struct fsl_qspi *q) ++{ ++ return !(q->devtype_data->quirks & QUADSPI_QUIRK_SKIP_CLK_DISABLE); ++} ++ + /* + * An IC bug makes it necessary to rearrange the 32-bit data. + * Later chips, such as IMX6SLX, have fixed this bug. +@@ -534,15 +544,18 @@ static void fsl_qspi_select_mem(struct f + if (needs_4x_clock(q)) + rate *= 4; + +- fsl_qspi_clk_disable_unprep(q); ++ if (needs_clk_disable(q)) ++ fsl_qspi_clk_disable_unprep(q); + + ret = clk_set_rate(q->clk, rate); + if (ret) + return; + +- ret = fsl_qspi_clk_prep_enable(q); +- if (ret) +- return; ++ if (needs_clk_disable(q)) { ++ ret = fsl_qspi_clk_prep_enable(q); ++ if (ret) ++ return; ++ } + + q->selected = spi_get_chipselect(spi, 0); + diff --git a/target/linux/spacemit/patches-6.18/0017-spi-fsl-qspi-introduce-sfa_size-devtype-data.patch b/target/linux/spacemit/patches-6.18/0017-spi-fsl-qspi-introduce-sfa_size-devtype-data.patch new file mode 100644 index 00000000000000..4e9cd816106ca1 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0017-spi-fsl-qspi-introduce-sfa_size-devtype-data.patch @@ -0,0 +1,71 @@ +From e2e53160d128015c895a56bd31bdca327a10a6e0 Mon Sep 17 00:00:00 2001 +From: Alex Elder +Date: Mon, 27 Oct 2025 08:30:04 -0500 +Subject: [PATCH] spi: fsl-qspi: introduce sfa_size devtype data + +In fsl_qspi_default_setup(), four registers define the size of blocks of +data to written to each of four chips that comprise SPI NOR flash storage. +They are currently defined to be the same as the AHB buffer size. + +The SpacemiT QSPI has an AHB buffer size of 512 bytes, but requires these +four sizes to be multiples of 1024 bytes. + +Define a new field sfa_size in the fsl_qspi_devtype_data structure that, if +non-zero, will be used instead of the AHB buffer size to define the size of +these chip regions. + +Reviewed-by: Frank Li +Signed-off-by: Alex Elder +Link: https://patch.msgid.link/20251027133008.360237-7-elder@riscstar.com +Signed-off-by: Mark Brown +(cherry picked from commit 56931105074fe7e5fc9d54e3163df3b95075643c) +--- + drivers/spi/spi-fsl-qspi.c | 22 ++++++++++++---------- + 1 file changed, 12 insertions(+), 10 deletions(-) + +--- a/drivers/spi/spi-fsl-qspi.c ++++ b/drivers/spi/spi-fsl-qspi.c +@@ -206,6 +206,7 @@ struct fsl_qspi_devtype_data { + unsigned int txfifo; + int invalid_mstrid; + unsigned int ahb_buf_size; ++ unsigned int sfa_size; + unsigned int quirks; + bool little_endian; + }; +@@ -735,6 +736,7 @@ static int fsl_qspi_default_setup(struct + { + void __iomem *base = q->iobase; + u32 reg, addr_offset = 0; ++ u32 sfa_size; + int ret; + + /* disable and unprepare clock to avoid glitch pass to controller */ +@@ -793,17 +795,17 @@ static int fsl_qspi_default_setup(struct + * In HW there can be a maximum of four chips on two buses with + * two chip selects on each bus. We use four chip selects in SW + * to differentiate between the four chips. +- * We use ahb_buf_size for each chip and set SFA1AD, SFA2AD, SFB1AD, +- * SFB2AD accordingly. ++ * ++ * By default we write the AHB buffer size to each chip, but ++ * a different size can be specified with devtype_data->sfa_size. ++ * The SFA1AD, SFA2AD, SFB1AD, and SFB2AD registers define the ++ * top (end) of these four regions. + */ +- qspi_writel(q, q->devtype_data->ahb_buf_size + addr_offset, +- base + QUADSPI_SFA1AD); +- qspi_writel(q, q->devtype_data->ahb_buf_size * 2 + addr_offset, +- base + QUADSPI_SFA2AD); +- qspi_writel(q, q->devtype_data->ahb_buf_size * 3 + addr_offset, +- base + QUADSPI_SFB1AD); +- qspi_writel(q, q->devtype_data->ahb_buf_size * 4 + addr_offset, +- base + QUADSPI_SFB2AD); ++ sfa_size = q->devtype_data->sfa_size ? : q->devtype_data->ahb_buf_size; ++ qspi_writel(q, addr_offset + 1 * sfa_size, base + QUADSPI_SFA1AD); ++ qspi_writel(q, addr_offset + 2 * sfa_size, base + QUADSPI_SFA2AD); ++ qspi_writel(q, addr_offset + 3 * sfa_size, base + QUADSPI_SFB1AD); ++ qspi_writel(q, addr_offset + 4 * sfa_size, base + QUADSPI_SFB2AD); + + q->selected = -1; + diff --git a/target/linux/spacemit/patches-6.18/0018-spi-fsl-qspi-support-the-SpacemiT-K1-SoC.patch b/target/linux/spacemit/patches-6.18/0018-spi-fsl-qspi-support-the-SpacemiT-K1-SoC.patch new file mode 100644 index 00000000000000..52963e8abdd4a6 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0018-spi-fsl-qspi-support-the-SpacemiT-K1-SoC.patch @@ -0,0 +1,59 @@ +From 8355d0377a96e71e9ba95a2b06663e60e9d2031d Mon Sep 17 00:00:00 2001 +From: Alex Elder +Date: Mon, 27 Oct 2025 08:30:05 -0500 +Subject: [PATCH] spi: fsl-qspi: support the SpacemiT K1 SoC + +Allow the SPI_FSL_QUADSPI Kconfig option to be selected if ARCH_SPACEMIT +enabled. + +Add support for the SpacemiT K1 SoC in the Freescale QSPI driver by +defining the device type data for its QSPI implementation. + +Signed-off-by: Alex Elder +Link: https://patch.msgid.link/20251027133008.360237-8-elder@riscstar.com +Signed-off-by: Mark Brown +(cherry picked from commit abc9a349b87ac0fd3ba8787ca00971b59c2e1257) +--- + drivers/spi/Kconfig | 3 ++- + drivers/spi/spi-fsl-qspi.c | 11 +++++++++++ + 2 files changed, 13 insertions(+), 1 deletion(-) + +--- a/drivers/spi/Kconfig ++++ b/drivers/spi/Kconfig +@@ -435,7 +435,8 @@ config SPI_FSL_LPSPI + + config SPI_FSL_QUADSPI + tristate "Freescale QSPI controller" +- depends on ARCH_MXC || SOC_LS1021A || ARCH_LAYERSCAPE || COMPILE_TEST ++ depends on ARCH_MXC || SOC_LS1021A || ARCH_LAYERSCAPE || \ ++ ARCH_SPACEMIT || COMPILE_TEST + depends on HAS_IOMEM + help + This enables support for the Quad SPI controller in master mode. +--- a/drivers/spi/spi-fsl-qspi.c ++++ b/drivers/spi/spi-fsl-qspi.c +@@ -267,6 +267,16 @@ static const struct fsl_qspi_devtype_dat + .little_endian = true, + }; + ++static const struct fsl_qspi_devtype_data spacemit_k1_data = { ++ .rxfifo = SZ_128, ++ .txfifo = SZ_256, ++ .ahb_buf_size = SZ_512, ++ .sfa_size = SZ_1K, ++ .invalid_mstrid = QUADSPI_BUFXCR_INVALID_MSTRID, ++ .quirks = QUADSPI_QUIRK_TKT253890 | QUADSPI_QUIRK_SKIP_CLK_DISABLE, ++ .little_endian = true, ++}; ++ + struct fsl_qspi { + void __iomem *iobase; + void __iomem *ahb_addr; +@@ -992,6 +1002,7 @@ static const struct of_device_id fsl_qsp + { .compatible = "fsl,imx6ul-qspi", .data = &imx6ul_data, }, + { .compatible = "fsl,ls1021a-qspi", .data = &ls1021a_data, }, + { .compatible = "fsl,ls2080a-qspi", .data = &ls2080a_data, }, ++ { .compatible = "spacemit,k1-qspi", .data = &spacemit_k1_data, }, + { /* sentinel */ } + }; + MODULE_DEVICE_TABLE(of, fsl_qspi_dt_ids); diff --git a/target/linux/spacemit/patches-6.18/0019-riscv-dts-spacemit-enable-K1-SoC-QSPI-on-BPI-F3.patch b/target/linux/spacemit/patches-6.18/0019-riscv-dts-spacemit-enable-K1-SoC-QSPI-on-BPI-F3.patch new file mode 100644 index 00000000000000..2f0231e68a1919 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0019-riscv-dts-spacemit-enable-K1-SoC-QSPI-on-BPI-F3.patch @@ -0,0 +1,88 @@ +From 9907d0c199c262cc9c29ead8b2ef45e7519b738a Mon Sep 17 00:00:00 2001 +From: Alex Elder +Date: Mon, 27 Oct 2025 08:30:06 -0500 +Subject: [PATCH] riscv: dts: spacemit: enable K1 SoC QSPI on BPI-F3 + +Define DTS nodes to enable support for QSPI on the K1 SoC, including the +pin control configuration used. Enable QSPI on the Banana Pi BPI-F3 board. + +Signed-off-by: Alex Elder +Link: https://lore.kernel.org/r/20251027133008.360237-9-elder@riscstar.com +Signed-off-by: Yixun Lan +(cherry picked from commit 41d34e0b5497f919229d32580fbe34386087458f) +--- + .../boot/dts/spacemit/k1-bananapi-f3.dts | 6 ++++++ + arch/riscv/boot/dts/spacemit/k1-pinctrl.dtsi | 21 +++++++++++++++++++ + arch/riscv/boot/dts/spacemit/k1.dtsi | 16 ++++++++++++++ + 3 files changed, 43 insertions(+) + +--- a/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts ++++ b/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts +@@ -113,6 +113,12 @@ + status = "okay"; + }; + ++&qspi { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&qspi_cfg>; ++ status = "okay"; ++}; ++ + &i2c2 { + pinctrl-0 = <&i2c2_0_cfg>; + pinctrl-names = "default"; +--- a/arch/riscv/boot/dts/spacemit/k1-pinctrl.dtsi ++++ b/arch/riscv/boot/dts/spacemit/k1-pinctrl.dtsi +@@ -73,6 +73,27 @@ + }; + }; + ++ qspi_cfg: qspi-cfg { ++ qspi-pins { ++ pinmux = , /* QSPI_DATA3 */ ++ , /* QSPI_DATA2 */ ++ , /* QSPI_DATA1 */ ++ , /* QSPI_DATA0 */ ++ ; /* QSPI_CLK */ ++ ++ bias-disable; ++ drive-strength = <19>; ++ power-source = <3300>; ++ }; ++ ++ qspi-cs1-pins { ++ pinmux = ; /* QSPI_CS1 */ ++ bias-pull-up = <0>; ++ drive-strength = <19>; ++ power-source = <3300>; ++ }; ++ }; ++ + /omit-if-no-ref/ + uart0_0_cfg: uart0-0-cfg { + uart0-0-pins { +--- a/arch/riscv/boot/dts/spacemit/k1.dtsi ++++ b/arch/riscv/boot/dts/spacemit/k1.dtsi +@@ -823,6 +823,22 @@ + status = "disabled"; + }; + ++ qspi: spi@d420c000 { ++ compatible = "spacemit,k1-qspi"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ reg = <0x0 0xd420c000 0x0 0x1000>, ++ <0x0 0xb8000000 0x0 0xc00000>; ++ reg-names = "QuadSPI", "QuadSPI-memory"; ++ clocks = <&syscon_apmu CLK_QSPI_BUS>, ++ <&syscon_apmu CLK_QSPI>; ++ clock-names = "qspi_en", "qspi"; ++ resets = <&syscon_apmu RESET_QSPI>, ++ <&syscon_apmu RESET_QSPI_BUS>; ++ interrupts = <117>; ++ status = "disabled"; ++ }; ++ + /* sec_uart1: 0xf0612000, not available from Linux */ + }; + diff --git a/target/linux/spacemit/patches-6.18/0020-dt-bindings-riscv-spacemit-Add-OrangePi-R2S-board.patch b/target/linux/spacemit/patches-6.18/0020-dt-bindings-riscv-spacemit-Add-OrangePi-R2S-board.patch new file mode 100644 index 00000000000000..78bd4caa73ff77 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0020-dt-bindings-riscv-spacemit-Add-OrangePi-R2S-board.patch @@ -0,0 +1,31 @@ +From d78e635d94b0d4492b1747ca8d7c3e9a857fa4a3 Mon Sep 17 00:00:00 2001 +From: Michael Opdenacker +Date: Wed, 12 Nov 2025 04:44:40 +0000 +Subject: [PATCH] dt-bindings: riscv: spacemit: Add OrangePi R2S board + +Document the compatible string for the OrangePi R2S board [1], which +is marketed as using the Ky X1 SoC but is in fact identical in die +and package to the SpacemiT K1 SoC [2]. + +Link: http://www.orangepi.org/html/hardWare/computerAndMicrocontrollers/details/Orange-Pi-R2S.html [1] +Link: https://www.spacemit.com/en/key-stone-k1 [2] +Signed-off-by: Michael Opdenacker +Acked-by: Krzysztof Kozlowski +Reviewed-by: Yixun Lan +Link: https://lore.kernel.org/r/20251112044426.2351999-2-michael.opdenacker@rootcommit.com +Signed-off-by: Yixun Lan +(cherry picked from commit 323256d11e01d5ee2a0a2e7b682890498b90b212) +--- + Documentation/devicetree/bindings/riscv/spacemit.yaml | 1 + + 1 file changed, 1 insertion(+) + +--- a/Documentation/devicetree/bindings/riscv/spacemit.yaml ++++ b/Documentation/devicetree/bindings/riscv/spacemit.yaml +@@ -23,6 +23,7 @@ properties: + - bananapi,bpi-f3 + - milkv,jupiter + - spacemit,musepi-pro ++ - xunlong,orangepi-r2s + - xunlong,orangepi-rv2 + - const: spacemit,k1 + diff --git a/target/linux/spacemit/patches-6.18/0021-riscv-dts-spacemit-Add-OrangePi-R2S-board-device-tre.patch b/target/linux/spacemit/patches-6.18/0021-riscv-dts-spacemit-Add-OrangePi-R2S-board-device-tre.patch new file mode 100644 index 00000000000000..b9f3b66dedeea0 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0021-riscv-dts-spacemit-Add-OrangePi-R2S-board-device-tre.patch @@ -0,0 +1,133 @@ +From 74fce52c4ce59054e474ad6d21737c95524f3432 Mon Sep 17 00:00:00 2001 +From: Michael Opdenacker +Date: Wed, 12 Nov 2025 04:44:42 +0000 +Subject: [PATCH] riscv: dts: spacemit: Add OrangePi R2S board device tree + +Add initial device tree support for the OrangePi RV2 board [1], which is +marketed as using the Ky X1 SoC but is identical in die and package +to the SpacemiT K1 SoC [2]. + +Enable UART0, to boot into a serial console + +Two Gigabit Ethernet ports with RGMII interface standard support +are enabled, each port is connected to an external +Motorcomm YT8531C PHY chip which uses the GPIO for reset control. + +Enable PDMA. + +Enable 8 GB eMMC chip for storage. + +Link: http://www.orangepi.org/html/hardWare/computerAndMicrocontrollers/details/Orange-Pi-R2S.html [1] +Link: https://www.spacemit.com/en/key-stone-k1 [2] +Signed-off-by: Michael Opdenacker +Reviewed-by: Yixun Lan +Link: https://lore.kernel.org/r/20251112044426.2351999-3-michael.opdenacker@rootcommit.com +Signed-off-by: Yixun Lan +(cherry picked from commit 63e572b11464a233f45ad469ba64b8b9e68a9cd1) +--- + arch/riscv/boot/dts/spacemit/Makefile | 1 + + .../boot/dts/spacemit/k1-orangepi-r2s.dts | 90 +++++++++++++++++++ + 2 files changed, 91 insertions(+) + create mode 100644 arch/riscv/boot/dts/spacemit/k1-orangepi-r2s.dts + +--- a/arch/riscv/boot/dts/spacemit/Makefile ++++ b/arch/riscv/boot/dts/spacemit/Makefile +@@ -2,4 +2,5 @@ + dtb-$(CONFIG_ARCH_SPACEMIT) += k1-bananapi-f3.dtb + dtb-$(CONFIG_ARCH_SPACEMIT) += k1-milkv-jupiter.dtb + dtb-$(CONFIG_ARCH_SPACEMIT) += k1-musepi-pro.dtb ++dtb-$(CONFIG_ARCH_SPACEMIT) += k1-orangepi-r2s.dtb + dtb-$(CONFIG_ARCH_SPACEMIT) += k1-orangepi-rv2.dtb +--- /dev/null ++++ b/arch/riscv/boot/dts/spacemit/k1-orangepi-r2s.dts +@@ -0,0 +1,90 @@ ++// SPDX-License-Identifier: (GPL-2.0 OR MIT) ++/* ++ * Copyright (C) 2025 Michael Opdenacker ++ */ ++ ++/dts-v1/; ++ ++#include "k1.dtsi" ++#include "k1-pinctrl.dtsi" ++ ++/ { ++ model = "OrangePi R2S"; ++ compatible = "xunlong,orangepi-r2s", "spacemit,k1"; ++ ++ aliases { ++ serial0 = &uart0; ++ ethernet0 = ð0; ++ ethernet1 = ð1; ++ }; ++ ++ chosen { ++ stdout-path = "serial0"; ++ }; ++}; ++ ++&emmc { ++ bus-width = <8>; ++ mmc-hs400-1_8v; ++ mmc-hs400-enhanced-strobe; ++ non-removable; ++ no-sd; ++ no-sdio; ++ status = "okay"; ++}; ++ ++ð0 { ++ phy-handle = <&rgmii0>; ++ phy-mode = "rgmii-id"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&gmac0_cfg>; ++ rx-internal-delay-ps = <0>; ++ tx-internal-delay-ps = <0>; ++ status = "okay"; ++ ++ mdio-bus { ++ #address-cells = <0x1>; ++ #size-cells = <0x0>; ++ ++ reset-gpios = <&gpio K1_GPIO(110) GPIO_ACTIVE_LOW>; ++ reset-delay-us = <10000>; ++ reset-post-delay-us = <100000>; ++ ++ rgmii0: phy@1 { ++ reg = <0x1>; ++ }; ++ }; ++}; ++ ++ð1 { ++ phy-handle = <&rgmii1>; ++ phy-mode = "rgmii-id"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&gmac1_cfg>; ++ rx-internal-delay-ps = <0>; ++ tx-internal-delay-ps = <250>; ++ status = "okay"; ++ ++ mdio-bus { ++ #address-cells = <0x1>; ++ #size-cells = <0x0>; ++ ++ reset-gpios = <&gpio K1_GPIO(115) GPIO_ACTIVE_LOW>; ++ reset-delay-us = <10000>; ++ reset-post-delay-us = <100000>; ++ ++ rgmii1: phy@1 { ++ reg = <0x1>; ++ }; ++ }; ++}; ++ ++&pdma { ++ status = "okay"; ++}; ++ ++&uart0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart0_2_cfg>; ++ status = "okay"; ++}; diff --git a/target/linux/spacemit/patches-6.18/0022-riscv-dts-spacemit-reorder-i2c2-node.patch b/target/linux/spacemit/patches-6.18/0022-riscv-dts-spacemit-reorder-i2c2-node.patch new file mode 100644 index 00000000000000..a37ba54552886d --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0022-riscv-dts-spacemit-reorder-i2c2-node.patch @@ -0,0 +1,61 @@ +From 2442f70d4605e1ecea317b856e1fb83f1495b3b6 Mon Sep 17 00:00:00 2001 +From: Troy Mitchell +Date: Wed, 5 Nov 2025 11:37:43 +0800 +Subject: [PATCH] riscv: dts: spacemit: reorder i2c2 node + +Reorder the i2c2 node to its correct position according to its +register address.This improves the readability and maintainability +of the device tree file by adhering to the established ordering convention. + +No functional change is introduced by this reordering. + +Signed-off-by: Troy Mitchell +Link: https://lore.kernel.org/r/20251105-k1-add-i2c-node-v1-1-d18dae246137@linux.spacemit.com +Signed-off-by: Yixun Lan +(cherry picked from commit 3b70f972b6fb769bdee780b5b4639585845d6af4) +--- + arch/riscv/boot/dts/spacemit/k1.dtsi | 26 +++++++++++++------------- + 1 file changed, 13 insertions(+), 13 deletions(-) + +--- a/arch/riscv/boot/dts/spacemit/k1.dtsi ++++ b/arch/riscv/boot/dts/spacemit/k1.dtsi +@@ -358,6 +358,19 @@ + #reset-cells = <1>; + }; + ++ i2c2: i2c@d4012000 { ++ compatible = "spacemit,k1-i2c"; ++ reg = <0x0 0xd4012000 0x0 0x38>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ clocks = <&syscon_apbc CLK_TWSI2>, ++ <&syscon_apbc CLK_TWSI2_BUS>; ++ clock-names = "func", "bus"; ++ clock-frequency = <400000>; ++ interrupts = <38>; ++ status = "disabled"; ++ }; ++ + syscon_apbc: system-controller@d4015000 { + compatible = "spacemit,k1-syscon-apbc"; + reg = <0x0 0xd4015000 0x0 0x1000>; +@@ -459,19 +472,6 @@ + status = "disabled"; + }; + +- i2c2: i2c@d4012000 { +- compatible = "spacemit,k1-i2c"; +- reg = <0x0 0xd4012000 0x0 0x38>; +- #address-cells = <1>; +- #size-cells = <0>; +- clocks = <&syscon_apbc CLK_TWSI2>, +- <&syscon_apbc CLK_TWSI2_BUS>; +- clock-names = "func", "bus"; +- clock-frequency = <400000>; +- interrupts = <38>; +- status = "disabled"; +- }; +- + i2c8: i2c@d401d800 { + compatible = "spacemit,k1-i2c"; + reg = <0x0 0xd401d800 0x0 0x38>; diff --git a/target/linux/spacemit/patches-6.18/0023-riscv-dts-spacemit-define-all-missing-I2C-controller.patch b/target/linux/spacemit/patches-6.18/0023-riscv-dts-spacemit-define-all-missing-I2C-controller.patch new file mode 100644 index 00000000000000..f9aed75a27f834 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0023-riscv-dts-spacemit-define-all-missing-I2C-controller.patch @@ -0,0 +1,143 @@ +From d8e473a69355ade0a3d1e3dd3382ddcec190bbbe Mon Sep 17 00:00:00 2001 +From: Troy Mitchell +Date: Wed, 5 Nov 2025 11:37:44 +0800 +Subject: [PATCH] riscv: dts: spacemit: define all missing I2C controller nodes + +SpacemiT K1 SoC is equipped with a total of nine I2C controllers, +ranging from I2C0 to I2C8. + +Prior to this change, only I2C2 and I2C8 were explicitly defined +within the device tree. This patch comprehensively adds the +device tree node definitions for I2C controller 0, 1, 4 to 7. + +The I2C3 node is not added because it belongs exclusively to the +secure domain which not used in the linux realm. + +All newly added I2C nodes are set to "disabled" status by default, +allowing future board-specific device tree to enable and configure. + +Signed-off-by: Troy Mitchell +Link: https://lore.kernel.org/r/20251105-k1-add-i2c-node-v1-2-d18dae246137@linux.spacemit.com +Signed-off-by: Yixun Lan +(cherry picked from commit 5a97a38c22799a802f33001dcb022d2942fe4a41) +--- + arch/riscv/boot/dts/spacemit/k1.dtsi | 80 ++++++++++++++++++++++++++++ + 1 file changed, 80 insertions(+) + +--- a/arch/riscv/boot/dts/spacemit/k1.dtsi ++++ b/arch/riscv/boot/dts/spacemit/k1.dtsi +@@ -358,6 +358,32 @@ + #reset-cells = <1>; + }; + ++ i2c0: i2c@d4010800 { ++ compatible = "spacemit,k1-i2c"; ++ reg = <0x0 0xd4010800 0x0 0x38>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ clocks = <&syscon_apbc CLK_TWSI0>, ++ <&syscon_apbc CLK_TWSI0_BUS>; ++ clock-names = "func", "bus"; ++ clock-frequency = <400000>; ++ interrupts = <36>; ++ status = "disabled"; ++ }; ++ ++ i2c1: i2c@d4011000 { ++ compatible = "spacemit,k1-i2c"; ++ reg = <0x0 0xd4011000 0x0 0x38>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ clocks = <&syscon_apbc CLK_TWSI1>, ++ <&syscon_apbc CLK_TWSI1_BUS>; ++ clock-names = "func", "bus"; ++ clock-frequency = <400000>; ++ interrupts = <37>; ++ status = "disabled"; ++ }; ++ + i2c2: i2c@d4012000 { + compatible = "spacemit,k1-i2c"; + reg = <0x0 0xd4012000 0x0 0x38>; +@@ -371,6 +397,32 @@ + status = "disabled"; + }; + ++ i2c4: i2c@d4012800 { ++ compatible = "spacemit,k1-i2c"; ++ reg = <0x0 0xd4012800 0x0 0x38>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ clocks = <&syscon_apbc CLK_TWSI4>, ++ <&syscon_apbc CLK_TWSI4_BUS>; ++ clock-names = "func", "bus"; ++ clock-frequency = <400000>; ++ interrupts = <40>; ++ status = "disabled"; ++ }; ++ ++ i2c5: i2c@d4013800 { ++ compatible = "spacemit,k1-i2c"; ++ reg = <0x0 0xd4013800 0x0 0x38>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ clocks = <&syscon_apbc CLK_TWSI5>, ++ <&syscon_apbc CLK_TWSI5_BUS>; ++ clock-names = "func", "bus"; ++ clock-frequency = <400000>; ++ interrupts = <41>; ++ status = "disabled"; ++ }; ++ + syscon_apbc: system-controller@d4015000 { + compatible = "spacemit,k1-syscon-apbc"; + reg = <0x0 0xd4015000 0x0 0x1000>; +@@ -382,6 +434,19 @@ + #reset-cells = <1>; + }; + ++ i2c6: i2c@d4018800 { ++ compatible = "spacemit,k1-i2c"; ++ reg = <0x0 0xd4018800 0x0 0x38>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ clocks = <&syscon_apbc CLK_TWSI6>, ++ <&syscon_apbc CLK_TWSI6_BUS>; ++ clock-names = "func", "bus"; ++ clock-frequency = <400000>; ++ interrupts = <70>; ++ status = "disabled"; ++ }; ++ + gpio: gpio@d4019000 { + compatible = "spacemit,k1-gpio"; + reg = <0x0 0xd4019000 0x0 0x100>; +@@ -472,6 +537,19 @@ + status = "disabled"; + }; + ++ i2c7: i2c@d401d000 { ++ compatible = "spacemit,k1-i2c"; ++ reg = <0x0 0xd401d000 0x0 0x38>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ clocks = <&syscon_apbc CLK_TWSI7>, ++ <&syscon_apbc CLK_TWSI7_BUS>; ++ clock-names = "func", "bus"; ++ clock-frequency = <400000>; ++ interrupts = <18>; ++ status = "disabled"; ++ }; ++ + i2c8: i2c@d401d800 { + compatible = "spacemit,k1-i2c"; + reg = <0x0 0xd401d800 0x0 0x38>; +@@ -669,6 +747,8 @@ + #reset-cells = <1>; + }; + ++ /* sec_i2c3: 0xf0614000, not available from Linux */ ++ + camera-bus { + compatible = "simple-bus"; + ranges; diff --git a/target/linux/spacemit/patches-6.18/0024-riscv-defconfig-enable-SPI_FSL_QUADSPI-as-a-module.patch b/target/linux/spacemit/patches-6.18/0024-riscv-defconfig-enable-SPI_FSL_QUADSPI-as-a-module.patch new file mode 100644 index 00000000000000..56952b50dcc308 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0024-riscv-defconfig-enable-SPI_FSL_QUADSPI-as-a-module.patch @@ -0,0 +1,26 @@ +From 57f516904152020443a90be4959478f1c39bcecf Mon Sep 17 00:00:00 2001 +From: Alex Elder +Date: Mon, 27 Oct 2025 08:30:07 -0500 +Subject: [PATCH] riscv: defconfig: enable SPI_FSL_QUADSPI as a module + +The SpacemiT K1 SoC QSPI IP uses the Freescale driver. Enable it as a +module in the default kernel configuration for RISC-V. + +Acked-by: Paul Walmsley # for arch/riscv +Signed-off-by: Alex Elder +Signed-off-by: Conor Dooley +(cherry picked from commit 3187e25eb2705dec9f0509f6e42da7e018718c74) +--- + arch/riscv/configs/defconfig | 1 + + 1 file changed, 1 insertion(+) + +--- a/arch/riscv/configs/defconfig ++++ b/arch/riscv/configs/defconfig +@@ -158,6 +158,7 @@ CONFIG_I2C_DESIGNWARE_CORE=y + CONFIG_I2C_MV64XXX=m + CONFIG_SPI=y + CONFIG_SPI_CADENCE_QUADSPI=m ++CONFIG_SPI_FSL_QUADSPI=m + CONFIG_SPI_PL022=m + CONFIG_SPI_SIFIVE=y + CONFIG_SPI_SUN6I=y diff --git a/target/linux/spacemit/patches-6.18/0025-clk-spacemit-fix-comment-typo.patch b/target/linux/spacemit/patches-6.18/0025-clk-spacemit-fix-comment-typo.patch new file mode 100644 index 00000000000000..d68a783699b187 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0025-clk-spacemit-fix-comment-typo.patch @@ -0,0 +1,24 @@ +From 0a8ad918769ec093dc83107e9bc77be583487c22 Mon Sep 17 00:00:00 2001 +From: Encrow Thorne +Date: Tue, 11 Nov 2025 23:50:09 +0800 +Subject: [PATCH] clk: spacemit: fix comment typo + +Fix incorrect comment to match the filename. + +Reviewd-by: Troy Mitchell +Signed-off-by: Encrow Thorne +Reviewed-by: Yixun Lan +Signed-off-by: Stephen Boyd +(cherry picked from commit 2e12d91cbf3d0105fc58d07b8a0548ebd7bb619b) +--- + drivers/clk/spacemit/ccu_mix.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/clk/spacemit/ccu_mix.h ++++ b/drivers/clk/spacemit/ccu_mix.h +@@ -220,4 +220,4 @@ extern const struct clk_ops spacemit_ccu + extern const struct clk_ops spacemit_ccu_mux_gate_ops; + extern const struct clk_ops spacemit_ccu_mux_div_ops; + extern const struct clk_ops spacemit_ccu_mux_div_gate_ops; +-#endif /* _CCU_DIV_H_ */ ++#endif /* _CCU_MIX_H_ */ diff --git a/target/linux/spacemit/patches-6.18/0026-dt-bindings-pci-spacemit-Introduce-PCIe-host-control.patch b/target/linux/spacemit/patches-6.18/0026-dt-bindings-pci-spacemit-Introduce-PCIe-host-control.patch new file mode 100644 index 00000000000000..290223b11a816a --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0026-dt-bindings-pci-spacemit-Introduce-PCIe-host-control.patch @@ -0,0 +1,184 @@ +From bf329ca0081b7c94b9d5c9efc10478b75cbb6413 Mon Sep 17 00:00:00 2001 +From: Alex Elder +Date: Thu, 13 Nov 2025 15:45:35 -0600 +Subject: [PATCH] dt-bindings: pci: spacemit: Introduce PCIe host controller + +Add the Devicetree binding for the PCIe Root Complex found on the SpacemiT +K1 SoC. This Root Complex is derived from the Synopsys Designware PCIe IP. +It supports up to three PCIe ports operating at PCIe link speed up to 5 +GT/sec. One of the ports uses a combo PHY, which is typically used to +support a USB3 port. + +Signed-off-by: Alex Elder +Signed-off-by: Manivannan Sadhasivam +Tested-by: Jason Montleon +Tested-by: Johannes Erdfelt +Tested-by: Aurelien Jarno +Reviewed-by: Rob Herring (Arm) +Link: https://patch.msgid.link/20251113214540.2623070-4-elder@riscstar.com +(cherry picked from commit a812b09a6b599ea80ec1065a9a635724a235843d) +--- + .../bindings/pci/spacemit,k1-pcie-host.yaml | 157 ++++++++++++++++++ + 1 file changed, 157 insertions(+) + create mode 100644 Documentation/devicetree/bindings/pci/spacemit,k1-pcie-host.yaml + +--- /dev/null ++++ b/Documentation/devicetree/bindings/pci/spacemit,k1-pcie-host.yaml +@@ -0,0 +1,157 @@ ++# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) ++%YAML 1.2 ++--- ++$id: http://devicetree.org/schemas/pci/spacemit,k1-pcie-host.yaml# ++$schema: http://devicetree.org/meta-schemas/core.yaml# ++ ++title: SpacemiT K1 PCI Express Host Controller ++ ++maintainers: ++ - Alex Elder ++ ++description: > ++ The SpacemiT K1 SoC PCIe host controller is based on the Synopsys DesignWare ++ PCIe IP. The controller uses the DesignWare built-in MSI interrupt ++ controller, and supports 256 MSIs. ++ ++allOf: ++ - $ref: /schemas/pci/snps,dw-pcie.yaml# ++ ++properties: ++ compatible: ++ const: spacemit,k1-pcie ++ ++ reg: ++ items: ++ - description: DesignWare PCIe registers ++ - description: ATU address space ++ - description: PCIe configuration space ++ - description: Link control registers ++ ++ reg-names: ++ items: ++ - const: dbi ++ - const: atu ++ - const: config ++ - const: link ++ ++ clocks: ++ items: ++ - description: DWC PCIe Data Bus Interface (DBI) clock ++ - description: DWC PCIe application AXI-bus master interface clock ++ - description: DWC PCIe application AXI-bus slave interface clock ++ ++ clock-names: ++ items: ++ - const: dbi ++ - const: mstr ++ - const: slv ++ ++ resets: ++ items: ++ - description: DWC PCIe Data Bus Interface (DBI) reset ++ - description: DWC PCIe application AXI-bus master interface reset ++ - description: DWC PCIe application AXI-bus slave interface reset ++ ++ reset-names: ++ items: ++ - const: dbi ++ - const: mstr ++ - const: slv ++ ++ interrupts: ++ items: ++ - description: Interrupt used for MSIs ++ ++ interrupt-names: ++ const: msi ++ ++ spacemit,apmu: ++ $ref: /schemas/types.yaml#/definitions/phandle-array ++ description: ++ A phandle that refers to the APMU system controller, whose regmap is ++ used in managing resets and link state, along with and offset of its ++ reset control register. ++ items: ++ - items: ++ - description: phandle to APMU system controller ++ - description: register offset ++ ++patternProperties: ++ '^pcie@': ++ type: object ++ $ref: /schemas/pci/pci-pci-bridge.yaml# ++ ++ properties: ++ phys: ++ maxItems: 1 ++ ++ vpcie3v3-supply: ++ description: ++ A phandle for 3.3v regulator to use for PCIe ++ ++ required: ++ - phys ++ - vpcie3v3-supply ++ ++ unevaluatedProperties: false ++ ++required: ++ - clocks ++ - clock-names ++ - resets ++ - reset-names ++ - interrupts ++ - interrupt-names ++ - spacemit,apmu ++ ++unevaluatedProperties: false ++ ++examples: ++ - | ++ #include ++ pcie@ca400000 { ++ device_type = "pci"; ++ compatible = "spacemit,k1-pcie"; ++ reg = <0xca400000 0x00001000>, ++ <0xca700000 0x0001ff24>, ++ <0x9f000000 0x00002000>, ++ <0xc0c20000 0x00001000>; ++ reg-names = "dbi", ++ "atu", ++ "config", ++ "link"; ++ #address-cells = <3>; ++ #size-cells = <2>; ++ ranges = <0x01000000 0x0 0x00000000 0x9f002000 0x0 0x00100000>, ++ <0x02000000 0x0 0x90000000 0x90000000 0x0 0x0f000000>; ++ interrupts = <142>; ++ interrupt-names = "msi"; ++ clocks = <&syscon_apmu CLK_PCIE1_DBI>, ++ <&syscon_apmu CLK_PCIE1_MASTER>, ++ <&syscon_apmu CLK_PCIE1_SLAVE>; ++ clock-names = "dbi", ++ "mstr", ++ "slv"; ++ resets = <&syscon_apmu RESET_PCIE1_DBI>, ++ <&syscon_apmu RESET_PCIE1_MASTER>, ++ <&syscon_apmu RESET_PCIE1_SLAVE>; ++ reset-names = "dbi", ++ "mstr", ++ "slv"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pcie1_3_cfg>; ++ spacemit,apmu = <&syscon_apmu 0x3d4>; ++ ++ pcie@0 { ++ device_type = "pci"; ++ compatible = "pciclass,0604"; ++ reg = <0x0 0x0 0x0 0x0 0x0>; ++ bus-range = <0x01 0xff>; ++ #address-cells = <3>; ++ #size-cells = <2>; ++ ranges; ++ phys = <&pcie1_phy>; ++ vpcie3v3-supply = <&pcie_vcc_3v3>; ++ }; ++ }; diff --git a/target/linux/spacemit/patches-6.18/0027-PCI-spacemit-Add-SpacemiT-PCIe-host-driver.patch b/target/linux/spacemit/patches-6.18/0027-PCI-spacemit-Add-SpacemiT-PCIe-host-driver.patch new file mode 100644 index 00000000000000..265f7b3e2ae8c5 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0027-PCI-spacemit-Add-SpacemiT-PCIe-host-driver.patch @@ -0,0 +1,418 @@ +From 0b76fa6d7ea88d8014e9d9e2f0a141f59c802750 Mon Sep 17 00:00:00 2001 +From: Alex Elder +Date: Thu, 13 Nov 2025 15:45:37 -0600 +Subject: [PATCH] PCI: spacemit: Add SpacemiT PCIe host driver + +Introduce a driver for the PCIe host controller found in the SpacemiT K1 +SoC. The hardware is derived from the Synopsys DesignWare PCIe IP. The +driver supports up to three PCIe ports operating at PCIe link speed up to +5 GT/s. The first port uses a combo PHY, which may be configured for use +for USB3 instead. + +Signed-off-by: Alex Elder +[mani: added FIXME to the comment on disabling ASPM L1] +Signed-off-by: Manivannan Sadhasivam +Tested-by: Jason Montleon +Tested-by: Johannes Erdfelt +Tested-by: Aurelien Jarno +Link: https://patch.msgid.link/20251113214540.2623070-6-elder@riscstar.com +(cherry picked from commit ff64e078e45faee50cc6ca7900a3520e8ff1c79e) +--- + drivers/pci/controller/dwc/Kconfig | 13 + + drivers/pci/controller/dwc/Makefile | 1 + + drivers/pci/controller/dwc/pcie-spacemit-k1.c | 357 ++++++++++++++++++ + 3 files changed, 371 insertions(+) + create mode 100644 drivers/pci/controller/dwc/pcie-spacemit-k1.c + +--- a/drivers/pci/controller/dwc/Kconfig ++++ b/drivers/pci/controller/dwc/Kconfig +@@ -416,6 +416,19 @@ config PCIE_SOPHGO_DW + Say Y here if you want PCIe host controller support on + Sophgo SoCs. + ++config PCIE_SPACEMIT_K1 ++ tristate "SpacemiT K1 PCIe controller (host mode)" ++ depends on ARCH_SPACEMIT || COMPILE_TEST ++ depends on HAS_IOMEM ++ select PCIE_DW_HOST ++ select PCI_PWRCTRL_SLOT ++ default ARCH_SPACEMIT ++ help ++ Enables support for the DesignWare based PCIe controller in ++ the SpacemiT K1 SoC operating in host mode. Three controllers ++ are available on the K1 SoC; the first of these shares a PHY ++ with a USB 3.0 host controller (one or the other can be used). ++ + config PCIE_SPEAR13XX + bool "STMicroelectronics SPEAr PCIe controller" + depends on ARCH_SPEAR13XX || COMPILE_TEST +--- a/drivers/pci/controller/dwc/Makefile ++++ b/drivers/pci/controller/dwc/Makefile +@@ -31,6 +31,7 @@ obj-$(CONFIG_PCIE_UNIPHIER) += pcie-unip + obj-$(CONFIG_PCIE_UNIPHIER_EP) += pcie-uniphier-ep.o + obj-$(CONFIG_PCIE_VISCONTI_HOST) += pcie-visconti.o + obj-$(CONFIG_PCIE_RCAR_GEN4) += pcie-rcar-gen4.o ++obj-$(CONFIG_PCIE_SPACEMIT_K1) += pcie-spacemit-k1.o + obj-$(CONFIG_PCIE_STM32_HOST) += pcie-stm32.o + obj-$(CONFIG_PCIE_STM32_EP) += pcie-stm32-ep.o + +--- /dev/null ++++ b/drivers/pci/controller/dwc/pcie-spacemit-k1.c +@@ -0,0 +1,357 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * SpacemiT K1 PCIe host driver ++ * ++ * Copyright (C) 2025 by RISCstar Solutions Corporation. All rights reserved. ++ * Copyright (c) 2023, spacemit Corporation. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "pcie-designware.h" ++ ++#define PCI_VENDOR_ID_SPACEMIT 0x201f ++#define PCI_DEVICE_ID_SPACEMIT_K1 0x0001 ++ ++/* Offsets and field definitions for link management registers */ ++#define K1_PHY_AHB_IRQ_EN 0x0000 ++#define PCIE_INTERRUPT_EN BIT(0) ++ ++#define K1_PHY_AHB_LINK_STS 0x0004 ++#define SMLH_LINK_UP BIT(1) ++#define RDLH_LINK_UP BIT(12) ++ ++#define INTR_ENABLE 0x0014 ++#define MSI_CTRL_INT BIT(11) ++ ++/* Some controls require APMU regmap access */ ++#define SYSCON_APMU "spacemit,apmu" ++ ++/* Offsets and field definitions for APMU registers */ ++#define PCIE_CLK_RESET_CONTROL 0x0000 ++#define LTSSM_EN BIT(6) ++#define PCIE_AUX_PWR_DET BIT(9) ++#define PCIE_RC_PERST BIT(12) /* 1: assert PERST# */ ++#define APP_HOLD_PHY_RST BIT(30) ++#define DEVICE_TYPE_RC BIT(31) /* 0: endpoint; 1: RC */ ++ ++#define PCIE_CONTROL_LOGIC 0x0004 ++#define PCIE_SOFT_RESET BIT(0) ++ ++struct k1_pcie { ++ struct dw_pcie pci; ++ struct phy *phy; ++ void __iomem *link; ++ struct regmap *pmu; /* Errors ignored; MMIO-backed regmap */ ++ u32 pmu_off; ++}; ++ ++#define to_k1_pcie(dw_pcie) \ ++ platform_get_drvdata(to_platform_device((dw_pcie)->dev)) ++ ++static void k1_pcie_toggle_soft_reset(struct k1_pcie *k1) ++{ ++ u32 offset; ++ u32 val; ++ ++ /* ++ * Write, then read back to guarantee it has reached the device ++ * before we start the delay. ++ */ ++ offset = k1->pmu_off + PCIE_CONTROL_LOGIC; ++ regmap_set_bits(k1->pmu, offset, PCIE_SOFT_RESET); ++ regmap_read(k1->pmu, offset, &val); ++ ++ mdelay(2); ++ ++ regmap_clear_bits(k1->pmu, offset, PCIE_SOFT_RESET); ++} ++ ++/* Enable app clocks, deassert resets */ ++static int k1_pcie_enable_resources(struct k1_pcie *k1) ++{ ++ struct dw_pcie *pci = &k1->pci; ++ int ret; ++ ++ ret = clk_bulk_prepare_enable(ARRAY_SIZE(pci->app_clks), pci->app_clks); ++ if (ret) ++ return ret; ++ ++ ret = reset_control_bulk_deassert(ARRAY_SIZE(pci->app_rsts), ++ pci->app_rsts); ++ if (ret) ++ goto err_disable_clks; ++ ++ return 0; ++ ++err_disable_clks: ++ clk_bulk_disable_unprepare(ARRAY_SIZE(pci->app_clks), pci->app_clks); ++ ++ return ret; ++} ++ ++/* Assert resets, disable app clocks */ ++static void k1_pcie_disable_resources(struct k1_pcie *k1) ++{ ++ struct dw_pcie *pci = &k1->pci; ++ ++ reset_control_bulk_assert(ARRAY_SIZE(pci->app_rsts), pci->app_rsts); ++ clk_bulk_disable_unprepare(ARRAY_SIZE(pci->app_clks), pci->app_clks); ++} ++ ++/* FIXME: Disable ASPM L1 to avoid errors reported on some NVMe drives */ ++static void k1_pcie_disable_aspm_l1(struct k1_pcie *k1) ++{ ++ struct dw_pcie *pci = &k1->pci; ++ u8 offset; ++ u32 val; ++ ++ offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP); ++ offset += PCI_EXP_LNKCAP; ++ ++ dw_pcie_dbi_ro_wr_en(pci); ++ val = dw_pcie_readl_dbi(pci, offset); ++ val &= ~PCI_EXP_LNKCAP_ASPM_L1; ++ dw_pcie_writel_dbi(pci, offset, val); ++ dw_pcie_dbi_ro_wr_dis(pci); ++} ++ ++static int k1_pcie_init(struct dw_pcie_rp *pp) ++{ ++ struct dw_pcie *pci = to_dw_pcie_from_pp(pp); ++ struct k1_pcie *k1 = to_k1_pcie(pci); ++ u32 reset_ctrl; ++ u32 val; ++ int ret; ++ ++ k1_pcie_toggle_soft_reset(k1); ++ ++ ret = k1_pcie_enable_resources(k1); ++ if (ret) ++ return ret; ++ ++ /* Set the PCI vendor and device ID */ ++ dw_pcie_dbi_ro_wr_en(pci); ++ dw_pcie_writew_dbi(pci, PCI_VENDOR_ID, PCI_VENDOR_ID_SPACEMIT); ++ dw_pcie_writew_dbi(pci, PCI_DEVICE_ID, PCI_DEVICE_ID_SPACEMIT_K1); ++ dw_pcie_dbi_ro_wr_dis(pci); ++ ++ /* ++ * Start by asserting fundamental reset (drive PERST# low). The ++ * PCI CEM spec says that PERST# should be deasserted at least ++ * 100ms after the power becomes stable, so we'll insert that ++ * delay first. Write, then read it back to guarantee the write ++ * reaches the device before we start the delay. ++ */ ++ reset_ctrl = k1->pmu_off + PCIE_CLK_RESET_CONTROL; ++ regmap_set_bits(k1->pmu, reset_ctrl, PCIE_RC_PERST); ++ regmap_read(k1->pmu, reset_ctrl, &val); ++ mdelay(PCIE_T_PVPERL_MS); ++ ++ /* ++ * Put the controller in root complex mode, and indicate that ++ * Vaux (3.3v) is present. ++ */ ++ regmap_set_bits(k1->pmu, reset_ctrl, DEVICE_TYPE_RC | PCIE_AUX_PWR_DET); ++ ++ ret = phy_init(k1->phy); ++ if (ret) { ++ k1_pcie_disable_resources(k1); ++ ++ return ret; ++ } ++ ++ /* Deassert fundamental reset (drive PERST# high) */ ++ regmap_clear_bits(k1->pmu, reset_ctrl, PCIE_RC_PERST); ++ ++ /* Finally, as a workaround, disable ASPM L1 */ ++ k1_pcie_disable_aspm_l1(k1); ++ ++ return 0; ++} ++ ++static void k1_pcie_deinit(struct dw_pcie_rp *pp) ++{ ++ struct dw_pcie *pci = to_dw_pcie_from_pp(pp); ++ struct k1_pcie *k1 = to_k1_pcie(pci); ++ ++ /* Assert fundamental reset (drive PERST# low) */ ++ regmap_set_bits(k1->pmu, k1->pmu_off + PCIE_CLK_RESET_CONTROL, ++ PCIE_RC_PERST); ++ ++ phy_exit(k1->phy); ++ ++ k1_pcie_disable_resources(k1); ++} ++ ++static const struct dw_pcie_host_ops k1_pcie_host_ops = { ++ .init = k1_pcie_init, ++ .deinit = k1_pcie_deinit, ++}; ++ ++static bool k1_pcie_link_up(struct dw_pcie *pci) ++{ ++ struct k1_pcie *k1 = to_k1_pcie(pci); ++ u32 val; ++ ++ val = readl_relaxed(k1->link + K1_PHY_AHB_LINK_STS); ++ ++ return (val & RDLH_LINK_UP) && (val & SMLH_LINK_UP); ++} ++ ++static int k1_pcie_start_link(struct dw_pcie *pci) ++{ ++ struct k1_pcie *k1 = to_k1_pcie(pci); ++ u32 val; ++ ++ /* Stop holding the PHY in reset, and enable link training */ ++ regmap_update_bits(k1->pmu, k1->pmu_off + PCIE_CLK_RESET_CONTROL, ++ APP_HOLD_PHY_RST | LTSSM_EN, LTSSM_EN); ++ ++ /* Enable the MSI interrupt */ ++ writel_relaxed(MSI_CTRL_INT, k1->link + INTR_ENABLE); ++ ++ /* Top-level interrupt enable */ ++ val = readl_relaxed(k1->link + K1_PHY_AHB_IRQ_EN); ++ val |= PCIE_INTERRUPT_EN; ++ writel_relaxed(val, k1->link + K1_PHY_AHB_IRQ_EN); ++ ++ return 0; ++} ++ ++static void k1_pcie_stop_link(struct dw_pcie *pci) ++{ ++ struct k1_pcie *k1 = to_k1_pcie(pci); ++ u32 val; ++ ++ /* Disable interrupts */ ++ val = readl_relaxed(k1->link + K1_PHY_AHB_IRQ_EN); ++ val &= ~PCIE_INTERRUPT_EN; ++ writel_relaxed(val, k1->link + K1_PHY_AHB_IRQ_EN); ++ ++ writel_relaxed(0, k1->link + INTR_ENABLE); ++ ++ /* Disable the link and hold the PHY in reset */ ++ regmap_update_bits(k1->pmu, k1->pmu_off + PCIE_CLK_RESET_CONTROL, ++ APP_HOLD_PHY_RST | LTSSM_EN, APP_HOLD_PHY_RST); ++} ++ ++static const struct dw_pcie_ops k1_pcie_ops = { ++ .link_up = k1_pcie_link_up, ++ .start_link = k1_pcie_start_link, ++ .stop_link = k1_pcie_stop_link, ++}; ++ ++static int k1_pcie_parse_port(struct k1_pcie *k1) ++{ ++ struct device *dev = k1->pci.dev; ++ struct device_node *root_port; ++ struct phy *phy; ++ ++ /* We assume only one root port */ ++ root_port = of_get_next_available_child(dev_of_node(dev), NULL); ++ if (!root_port) ++ return -EINVAL; ++ ++ phy = devm_of_phy_get(dev, root_port, NULL); ++ ++ of_node_put(root_port); ++ ++ if (IS_ERR(phy)) ++ return PTR_ERR(phy); ++ ++ k1->phy = phy; ++ ++ return 0; ++} ++ ++static int k1_pcie_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct k1_pcie *k1; ++ int ret; ++ ++ k1 = devm_kzalloc(dev, sizeof(*k1), GFP_KERNEL); ++ if (!k1) ++ return -ENOMEM; ++ ++ k1->pmu = syscon_regmap_lookup_by_phandle_args(dev_of_node(dev), ++ SYSCON_APMU, 1, ++ &k1->pmu_off); ++ if (IS_ERR(k1->pmu)) ++ return dev_err_probe(dev, PTR_ERR(k1->pmu), ++ "failed to lookup PMU registers\n"); ++ ++ k1->link = devm_platform_ioremap_resource_byname(pdev, "link"); ++ if (IS_ERR(k1->link)) ++ return dev_err_probe(dev, PTR_ERR(k1->link), ++ "failed to map \"link\" registers\n"); ++ ++ k1->pci.dev = dev; ++ k1->pci.ops = &k1_pcie_ops; ++ k1->pci.pp.num_vectors = MAX_MSI_IRQS; ++ dw_pcie_cap_set(&k1->pci, REQ_RES); ++ ++ k1->pci.pp.ops = &k1_pcie_host_ops; ++ ++ /* Hold the PHY in reset until we start the link */ ++ regmap_set_bits(k1->pmu, k1->pmu_off + PCIE_CLK_RESET_CONTROL, ++ APP_HOLD_PHY_RST); ++ ++ ret = devm_regulator_get_enable(dev, "vpcie3v3"); ++ if (ret) ++ return dev_err_probe(dev, ret, ++ "failed to get \"vpcie3v3\" supply\n"); ++ ++ pm_runtime_set_active(dev); ++ pm_runtime_no_callbacks(dev); ++ devm_pm_runtime_enable(dev); ++ ++ platform_set_drvdata(pdev, k1); ++ ++ ret = k1_pcie_parse_port(k1); ++ if (ret) ++ return dev_err_probe(dev, ret, "failed to parse root port\n"); ++ ++ ret = dw_pcie_host_init(&k1->pci.pp); ++ if (ret) ++ return dev_err_probe(dev, ret, "failed to initialize host\n"); ++ ++ return 0; ++} ++ ++static void k1_pcie_remove(struct platform_device *pdev) ++{ ++ struct k1_pcie *k1 = platform_get_drvdata(pdev); ++ ++ dw_pcie_host_deinit(&k1->pci.pp); ++} ++ ++static const struct of_device_id k1_pcie_of_match_table[] = { ++ { .compatible = "spacemit,k1-pcie", }, ++ { } ++}; ++ ++static struct platform_driver k1_pcie_driver = { ++ .probe = k1_pcie_probe, ++ .remove = k1_pcie_remove, ++ .driver = { ++ .name = "spacemit-k1-pcie", ++ .of_match_table = k1_pcie_of_match_table, ++ .probe_type = PROBE_PREFER_ASYNCHRONOUS, ++ }, ++}; ++module_platform_driver(k1_pcie_driver); ++MODULE_LICENSE("GPL"); ++MODULE_DESCRIPTION("SpacemiT K1 PCIe host driver"); diff --git a/target/linux/spacemit/patches-6.18/0028-rtc-spacemit-MFD_SPACEMIT_P1-as-dependencies.patch b/target/linux/spacemit/patches-6.18/0028-rtc-spacemit-MFD_SPACEMIT_P1-as-dependencies.patch new file mode 100644 index 00000000000000..db486a38127f06 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0028-rtc-spacemit-MFD_SPACEMIT_P1-as-dependencies.patch @@ -0,0 +1,35 @@ +From 01f33b07d3eb6402df6803e7703a3011b7c8f772 Mon Sep 17 00:00:00 2001 +From: Troy Mitchell +Date: Tue, 18 Nov 2025 14:08:06 +0800 +Subject: [PATCH] rtc: spacemit: MFD_SPACEMIT_P1 as dependencies + +RTC_DRV_SPACEMIT_P1 is a subdevice of P1 and should depend on +MFD_SPACEMIT_P1 rather than selecting it directly. Using 'select' +does not always respect the parent's dependencies, so 'depends on' +is the safer and more correct choice. + +Additionally, the default value depends on MFD_SPACEMIT_P1 rather +than ARCH_SPACEMIT. + +Signed-off-by: Troy Mitchell +Acked-by: Alex Elder +Link: https://patch.msgid.link/20251118-p1-kconfig-fix-v3-2-8839c5ac5db3@linux.spacemit.com +Signed-off-by: Alexandre Belloni +(cherry picked from commit 16bd954c93360145bc77cc601e350913fc28182d) +--- + drivers/rtc/Kconfig | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/rtc/Kconfig ++++ b/drivers/rtc/Kconfig +@@ -409,8 +409,8 @@ config RTC_DRV_MAX77686 + config RTC_DRV_SPACEMIT_P1 + tristate "SpacemiT P1 RTC" + depends on ARCH_SPACEMIT || COMPILE_TEST +- select MFD_SPACEMIT_P1 +- default ARCH_SPACEMIT ++ depends on MFD_SPACEMIT_P1 ++ default MFD_SPACEMIT_P1 + help + Enable support for the RTC function in the SpacemiT P1 PMIC. + This driver can also be built as a module, which will be called diff --git a/target/linux/spacemit/patches-6.18/0029-riscv-dts-spacemit-Enable-i2c8-adapter-for-Milk-V-Ju.patch b/target/linux/spacemit/patches-6.18/0029-riscv-dts-spacemit-Enable-i2c8-adapter-for-Milk-V-Ju.patch new file mode 100644 index 00000000000000..79fa76fd89cbd4 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0029-riscv-dts-spacemit-Enable-i2c8-adapter-for-Milk-V-Ju.patch @@ -0,0 +1,31 @@ +From 62524eaf8b0c09ed3e11ad8cfcae5a73f8e8abe9 Mon Sep 17 00:00:00 2001 +From: Javier Martinez Canillas +Date: Sat, 6 Dec 2025 14:44:53 +0100 +Subject: [PATCH] riscv: dts: spacemit: Enable i2c8 adapter for Milk-V Jupiter + +The adapter is used to access the SpacemiT P1 PMIC present in this board. + +Signed-off-by: Javier Martinez Canillas +Reviewed-by: Yixun Lan +Link: https://lore.kernel.org/r/20251206134532.1741648-2-javierm@redhat.com +Signed-off-by: Yixun Lan +(cherry picked from commit f33ccc2316304f3a71e40e53f1568e75042b0a4b) +--- + arch/riscv/boot/dts/spacemit/k1-milkv-jupiter.dts | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/arch/riscv/boot/dts/spacemit/k1-milkv-jupiter.dts ++++ b/arch/riscv/boot/dts/spacemit/k1-milkv-jupiter.dts +@@ -72,6 +72,12 @@ + status = "okay"; + }; + ++&i2c8 { ++ pinctrl-0 = <&i2c8_cfg>; ++ pinctrl-names = "default"; ++ status = "okay"; ++}; ++ + &uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_2_cfg>; diff --git a/target/linux/spacemit/patches-6.18/0030-riscv-dts-spacemit-Define-fixed-regulators-for-Milk-.patch b/target/linux/spacemit/patches-6.18/0030-riscv-dts-spacemit-Define-fixed-regulators-for-Milk-.patch new file mode 100644 index 00000000000000..bee4d3908eb0fa --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0030-riscv-dts-spacemit-Define-fixed-regulators-for-Milk-.patch @@ -0,0 +1,45 @@ +From 55965334a67d9a97963f2ccbb93bc41dc1357692 Mon Sep 17 00:00:00 2001 +From: Javier Martinez Canillas +Date: Sat, 6 Dec 2025 14:44:54 +0100 +Subject: [PATCH] riscv: dts: spacemit: Define fixed regulators for Milk-V + Jupiter + +Define the DC power input and the 4v power as fixed regulator supplies. + +Signed-off-by: Javier Martinez Canillas +Reviewed-by: Yixun Lan +Link: https://lore.kernel.org/r/20251206134532.1741648-3-javierm@redhat.com +Signed-off-by: Yixun Lan +(cherry picked from commit ae9d03f8aec76c1bff21083b67c211238d7c57b1) +--- + .../boot/dts/spacemit/k1-milkv-jupiter.dts | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +--- a/arch/riscv/boot/dts/spacemit/k1-milkv-jupiter.dts ++++ b/arch/riscv/boot/dts/spacemit/k1-milkv-jupiter.dts +@@ -20,6 +20,25 @@ + chosen { + stdout-path = "serial0"; + }; ++ ++ reg_dc_in: dc-in-12v { ++ compatible = "regulator-fixed"; ++ regulator-name = "dc_in_12v"; ++ regulator-min-microvolt = <12000000>; ++ regulator-max-microvolt = <12000000>; ++ regulator-boot-on; ++ regulator-always-on; ++ }; ++ ++ reg_vcc_4v: vcc-4v { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc_4v"; ++ regulator-min-microvolt = <4000000>; ++ regulator-max-microvolt = <4000000>; ++ regulator-boot-on; ++ regulator-always-on; ++ vin-supply = <®_dc_in>; ++ }; + }; + + ð0 { diff --git a/target/linux/spacemit/patches-6.18/0031-riscv-dts-spacemit-Define-the-P1-PMIC-regulators-for.patch b/target/linux/spacemit/patches-6.18/0031-riscv-dts-spacemit-Define-the-P1-PMIC-regulators-for.patch new file mode 100644 index 00000000000000..3624e86cc863f0 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0031-riscv-dts-spacemit-Define-the-P1-PMIC-regulators-for.patch @@ -0,0 +1,139 @@ +From 4b69c76e361b64b65b9ebb98135edcbd842b1572 Mon Sep 17 00:00:00 2001 +From: Javier Martinez Canillas +Date: Sat, 6 Dec 2025 14:44:55 +0100 +Subject: [PATCH] riscv: dts: spacemit: Define the P1 PMIC regulators for + Milk-V Jupiter + +Define the SpacemiT P1 PMIC voltage regulators and their constraints. + +The power management hardware design on the Milk-V Jupiter is identical to +the Banana Pi BPI-F3, so the DT Nodes were taken from k1-bananapi-f3.dts. + +Signed-off-by: Javier Martinez Canillas +Reviewed-by: Yixun Lan +Link: https://lore.kernel.org/r/20251206134532.1741648-4-javierm@redhat.com +Signed-off-by: Yixun Lan +(cherry picked from commit 7d307daa12b15a97269f577d5dcf50518758b568) +--- + .../boot/dts/spacemit/k1-milkv-jupiter.dts | 110 ++++++++++++++++++ + 1 file changed, 110 insertions(+) + +--- a/arch/riscv/boot/dts/spacemit/k1-milkv-jupiter.dts ++++ b/arch/riscv/boot/dts/spacemit/k1-milkv-jupiter.dts +@@ -95,6 +95,116 @@ + pinctrl-0 = <&i2c8_cfg>; + pinctrl-names = "default"; + status = "okay"; ++ ++ pmic@41 { ++ compatible = "spacemit,p1"; ++ reg = <0x41>; ++ interrupts = <64>; ++ vin-supply = <®_vcc_4v>; ++ ++ regulators { ++ buck1 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <3450000>; ++ regulator-ramp-delay = <5000>; ++ regulator-always-on; ++ }; ++ ++ buck2 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <3450000>; ++ regulator-ramp-delay = <5000>; ++ regulator-always-on; ++ }; ++ ++ buck3_1v8: buck3 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-ramp-delay = <5000>; ++ regulator-always-on; ++ }; ++ ++ buck4 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-ramp-delay = <5000>; ++ regulator-always-on; ++ }; ++ ++ buck5 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <3450000>; ++ regulator-ramp-delay = <5000>; ++ regulator-always-on; ++ }; ++ ++ buck6 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <3450000>; ++ regulator-ramp-delay = <5000>; ++ regulator-always-on; ++ }; ++ ++ aldo1 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <3400000>; ++ regulator-boot-on; ++ }; ++ ++ aldo2 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <3400000>; ++ }; ++ ++ aldo3 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <3400000>; ++ }; ++ ++ aldo4 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <3400000>; ++ }; ++ ++ dldo1 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <3400000>; ++ regulator-boot-on; ++ }; ++ ++ dldo2 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <3400000>; ++ }; ++ ++ dldo3 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <3400000>; ++ }; ++ ++ dldo4 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <3400000>; ++ regulator-always-on; ++ }; ++ ++ dldo5 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <3400000>; ++ }; ++ ++ dldo6 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <3400000>; ++ regulator-always-on; ++ }; ++ ++ dldo7 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <3400000>; ++ }; ++ }; ++ }; + }; + + &uart0 { diff --git a/target/linux/spacemit/patches-6.18/0032-clk-spacemit-Hide-common-clock-driver-from-user-cont.patch b/target/linux/spacemit/patches-6.18/0032-clk-spacemit-Hide-common-clock-driver-from-user-cont.patch new file mode 100644 index 00000000000000..558b9b13c48998 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0032-clk-spacemit-Hide-common-clock-driver-from-user-cont.patch @@ -0,0 +1,46 @@ +From 897846c40c04a8c14e85bb0f92adc05158195c15 Mon Sep 17 00:00:00 2001 +From: Inochi Amaoto +Date: Fri, 19 Dec 2025 09:28:18 +0800 +Subject: [PATCH] clk: spacemit: Hide common clock driver from user controller + +Since the common clock driver is only a dependency for other spacemit +clock driver, it should not be enabled individually, so hide this in +the Kconfig UI and let other spacemit clock driver select it. + +Signed-off-by: Inochi Amaoto +Reviewed-by: Yixun Lan +Link: https://lore.kernel.org/r/20251219012819.440972-3-inochiama@gmail.com +Signed-off-by: Yixun Lan +(cherry picked from commit 99735a742f7e9a3e7f4cb6c58edf1b38101e7657) +--- + drivers/clk/spacemit/Kconfig | 14 ++++++-------- + 1 file changed, 6 insertions(+), 8 deletions(-) + +--- a/drivers/clk/spacemit/Kconfig ++++ b/drivers/clk/spacemit/Kconfig +@@ -1,19 +1,17 @@ + # SPDX-License-Identifier: GPL-2.0-only + +-config SPACEMIT_CCU +- tristate "Clock support for SpacemiT SoCs" ++menu "Clock support for SpacemiT platforms" + depends on ARCH_SPACEMIT || COMPILE_TEST ++ ++config SPACEMIT_CCU ++ tristate + select AUXILIARY_BUS + select MFD_SYSCON +- help +- Say Y to enable clock controller unit support for SpacemiT SoCs. +- +-if SPACEMIT_CCU + + config SPACEMIT_K1_CCU + tristate "Support for SpacemiT K1 SoC" +- depends on ARCH_SPACEMIT || COMPILE_TEST ++ select SPACEMIT_CCU + help + Support for clock controller unit in SpacemiT K1 SoC. + +-endif ++endmenu diff --git a/target/linux/spacemit/patches-6.18/0033-dt-bindings-phy-spacemit-Add-SpacemiT-PCIe-combo-PHY.patch b/target/linux/spacemit/patches-6.18/0033-dt-bindings-phy-spacemit-Add-SpacemiT-PCIe-combo-PHY.patch new file mode 100644 index 00000000000000..10fd259c074582 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0033-dt-bindings-phy-spacemit-Add-SpacemiT-PCIe-combo-PHY.patch @@ -0,0 +1,144 @@ +From 030fb883f114d0a2d15cae8f12fc9020de773de5 Mon Sep 17 00:00:00 2001 +From: Alex Elder +Date: Thu, 18 Dec 2025 09:12:27 -0600 +Subject: [PATCH] dt-bindings: phy: spacemit: Add SpacemiT PCIe/combo PHY + +Add the Device Tree binding for the PCIe/USB 3.0 combo PHY found in +the SpacemiT K1 SoC. This is one of three PCIe PHYs, and is unusual +in that only the combo PHY can perform a calibration step needed to +determine settings used by the other two PCIe PHYs. + +Calibration must be done with the combo PHY in PCIe mode, and to allow +this to occur independent of the eventual use for the PHY (PCIe or USB) +some PCIe-related properties must be supplied: clocks; resets; and a +syscon phandle. + +Reviewed-by: Rob Herring (Arm) +Signed-off-by: Alex Elder +Link: https://lore.kernel.org/all/ba532f8d-a452-40e5-af46-b58b89f70a92@linaro.org/ [1] +Tested-by: Yixun Lan +Link: https://patch.msgid.link/20251218151235.454997-2-elder@riscstar.com +Signed-off-by: Vinod Koul +(cherry picked from commit f6194de7df023ecfd5156caf8e2762487be07ef7) +--- + .../bindings/phy/spacemit,k1-combo-phy.yaml | 114 ++++++++++++++++++ + 1 file changed, 114 insertions(+) + create mode 100644 Documentation/devicetree/bindings/phy/spacemit,k1-combo-phy.yaml + +--- /dev/null ++++ b/Documentation/devicetree/bindings/phy/spacemit,k1-combo-phy.yaml +@@ -0,0 +1,114 @@ ++# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) ++%YAML 1.2 ++--- ++$id: http://devicetree.org/schemas/phy/spacemit,k1-combo-phy.yaml# ++$schema: http://devicetree.org/meta-schemas/core.yaml# ++ ++title: SpacemiT K1 PCIe/USB3 Combo PHY ++ ++maintainers: ++ - Alex Elder ++ ++description: > ++ Of the three PHYs on the SpacemiT K1 SoC capable of being used for ++ PCIe, one is a combo PHY that can also be configured for use by a ++ USB 3 controller. Using PCIe or USB 3 is a board design decision. ++ ++ The combo PHY is also the only PCIe PHY that is able to determine ++ PCIe calibration values to use, and this must be determined before ++ the other two PCIe PHYs can be used. This calibration must be ++ performed with the combo PHY in PCIe mode, and is this is done ++ when the combo PHY is probed. ++ ++ The combo PHY uses an external oscillator as a reference clock. ++ During normal operation, the PCIe or USB port driver is responsible ++ for ensuring all other clocks needed by a PHY are enabled, and all ++ resets affecting the PHY are deasserted. However, for the combo ++ PHY to perform calibration independent of whether it's later used ++ for PCIe or USB, all PCIe mode clocks and resets must be defined. ++ ++properties: ++ compatible: ++ const: spacemit,k1-combo-phy ++ ++ reg: ++ items: ++ - description: PHY control registers ++ ++ clocks: ++ items: ++ - description: External oscillator used by the PHY PLL ++ - description: DWC PCIe Data Bus Interface (DBI) clock ++ - description: DWC PCIe application AXI-bus Master interface clock ++ - description: DWC PCIe application AXI-bus slave interface clock ++ ++ clock-names: ++ items: ++ - const: refclk ++ - const: dbi ++ - const: mstr ++ - const: slv ++ ++ resets: ++ items: ++ - description: PHY reset; remains deasserted after initialization ++ - description: DWC PCIe Data Bus Interface (DBI) reset ++ - description: DWC PCIe application AXI-bus Master interface reset ++ - description: DWC PCIe application AXI-bus slave interface reset ++ ++ reset-names: ++ items: ++ - const: phy ++ - const: dbi ++ - const: mstr ++ - const: slv ++ ++ spacemit,apmu: ++ description: ++ A phandle that refers to the APMU system controller, whose ++ regmap is used in setting the mode ++ $ref: /schemas/types.yaml#/definitions/phandle ++ ++ "#phy-cells": ++ const: 1 ++ description: ++ The argument value (PHY_TYPE_PCIE or PHY_TYPE_USB3) determines ++ whether the PHY operates in PCIe or USB3 mode. ++ ++required: ++ - compatible ++ - reg ++ - clocks ++ - clock-names ++ - resets ++ - reset-names ++ - spacemit,apmu ++ - "#phy-cells" ++ ++additionalProperties: false ++ ++examples: ++ - | ++ #include ++ phy@c0b10000 { ++ compatible = "spacemit,k1-combo-phy"; ++ reg = <0xc0b10000 0x1000>; ++ clocks = <&vctcxo_24m>, ++ <&syscon_apmu CLK_PCIE0_DBI>, ++ <&syscon_apmu CLK_PCIE0_MASTER>, ++ <&syscon_apmu CLK_PCIE0_SLAVE>; ++ clock-names = "refclk", ++ "dbi", ++ "mstr", ++ "slv"; ++ resets = <&syscon_apmu RESET_PCIE0_GLOBAL>, ++ <&syscon_apmu RESET_PCIE0_DBI>, ++ <&syscon_apmu RESET_PCIE0_MASTER>, ++ <&syscon_apmu RESET_PCIE0_SLAVE>; ++ reset-names = "phy", ++ "dbi", ++ "mstr", ++ "slv"; ++ spacemit,apmu = <&syscon_apmu>; ++ #phy-cells = <1>; ++ }; diff --git a/target/linux/spacemit/patches-6.18/0034-dt-bindings-phy-spacemit-Introduce-PCIe-PHY.patch b/target/linux/spacemit/patches-6.18/0034-dt-bindings-phy-spacemit-Introduce-PCIe-PHY.patch new file mode 100644 index 00000000000000..c6c6f171b28cfb --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0034-dt-bindings-phy-spacemit-Introduce-PCIe-PHY.patch @@ -0,0 +1,96 @@ +From 62d544244436e8f525e31d32c573fe20115aee5f Mon Sep 17 00:00:00 2001 +From: Alex Elder +Date: Thu, 18 Dec 2025 09:12:28 -0600 +Subject: [PATCH] dt-bindings: phy: spacemit: Introduce PCIe PHY + +Add the Device Tree binding for two PCIe PHYs present on the SpacemiT +K1 SoC. These PHYs are dependent on a separate combo PHY, which +determines at probe time the calibration values used by the PCIe-only +PHYs. + +Reviewed-by: Rob Herring (Arm) +Signed-off-by: Alex Elder +Link: https://lore.kernel.org/all/ba532f8d-a452-40e5-af46-b58b89f70a92@linaro.org/ [1] +Tested-by: Yixun Lan +Link: https://patch.msgid.link/20251218151235.454997-3-elder@riscstar.com +Signed-off-by: Vinod Koul +(cherry picked from commit 326a278a3682d390269699f68e597b5ef5a57d26) +--- + .../bindings/phy/spacemit,k1-pcie-phy.yaml | 71 +++++++++++++++++++ + 1 file changed, 71 insertions(+) + create mode 100644 Documentation/devicetree/bindings/phy/spacemit,k1-pcie-phy.yaml + +--- /dev/null ++++ b/Documentation/devicetree/bindings/phy/spacemit,k1-pcie-phy.yaml +@@ -0,0 +1,71 @@ ++# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) ++%YAML 1.2 ++--- ++$id: http://devicetree.org/schemas/phy/spacemit,k1-pcie-phy.yaml# ++$schema: http://devicetree.org/meta-schemas/core.yaml# ++ ++title: SpacemiT K1 PCIe PHY ++ ++maintainers: ++ - Alex Elder ++ ++description: > ++ Two PHYs on the SpacemiT K1 SoC used for only for PCIe. These ++ PHYs must be configured using calibration values that are ++ determined by a third "combo PHY". The combo PHY determines ++ these calibration values during probe so they can be used for ++ the two PCIe-only PHYs. ++ ++ The PHY uses an external oscillator as a reference clock. During ++ normal operation, the PCIe host driver is responsible for ensuring ++ all other clocks needed by a PHY are enabled, and all resets ++ affecting the PHY are deasserted. ++ ++properties: ++ compatible: ++ const: spacemit,k1-pcie-phy ++ ++ reg: ++ items: ++ - description: PHY control registers ++ ++ clocks: ++ items: ++ - description: External oscillator used by the PHY PLL ++ ++ clock-names: ++ const: refclk ++ ++ resets: ++ items: ++ - description: PHY reset; remains deasserted after initialization ++ ++ reset-names: ++ const: phy ++ ++ "#phy-cells": ++ const: 0 ++ ++required: ++ - compatible ++ - reg ++ - clocks ++ - clock-names ++ - resets ++ - reset-names ++ - "#phy-cells" ++ ++additionalProperties: false ++ ++examples: ++ - | ++ #include ++ phy@c0c10000 { ++ compatible = "spacemit,k1-pcie-phy"; ++ reg = <0xc0c10000 0x1000>; ++ clocks = <&vctcxo_24m>; ++ clock-names = "refclk"; ++ resets = <&syscon_apmu RESET_PCIE1_GLOBAL>; ++ reset-names = "phy"; ++ #phy-cells = <0>; ++ }; diff --git a/target/linux/spacemit/patches-6.18/0035-phy-spacemit-Introduce-PCIe-combo-PHY.patch b/target/linux/spacemit/patches-6.18/0035-phy-spacemit-Introduce-PCIe-combo-PHY.patch new file mode 100644 index 00000000000000..7d42bf575bff5e --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0035-phy-spacemit-Introduce-PCIe-combo-PHY.patch @@ -0,0 +1,747 @@ +From a7034b903f07fc2a2a3c3ab327702e4e3443b350 Mon Sep 17 00:00:00 2001 +From: Alex Elder +Date: Thu, 18 Dec 2025 09:12:29 -0600 +Subject: [PATCH] phy: spacemit: Introduce PCIe/combo PHY + +Introduce a driver that supports three PHYs found on the SpacemiT +K1 SoC. The first PHY is a combo PHY that can be configured for +use for either USB 3 or PCIe. The other two PHYs support PCIe +only. + +All three PHYs must be programmed with an 8 bit receiver termination +value, which must be determined dynamically. Only the combo PHY is +able to determine this value. The combo PHY performs a special +calibration step at probe time to discover this, and that value is +used to program each PHY that operates in PCIe mode. The combo +PHY must therefore be probed before either of the PCIe-only PHYs +will be used. + +Each PHY has an internal PLL driven from an external oscillator. +This PLL started when the PHY is first initialized, and stays +on thereafter. + +During normal operation, the USB or PCIe driver using the PHY must +ensure (other) clocks and resets are set up properly. + +However PCIe mode clocks are enabled and resets are de-asserted +temporarily by this driver to perform the calibration step on the +combo PHY. + +Tested-by: Junzhong Pan +Signed-off-by: Alex Elder +Reviewed-by: Neil Armstrong +Link: https://lore.kernel.org/all/ba532f8d-a452-40e5-af46-b58b89f70a92@linaro.org/ [1] +Tested-by: Yixun Lan +Link: https://patch.msgid.link/20251218151235.454997-4-elder@riscstar.com +Signed-off-by: Vinod Koul +(cherry picked from commit 57e920b92724dd568526990c04e79ed54241c5fc) +--- + drivers/phy/Kconfig | 11 + + drivers/phy/Makefile | 1 + + drivers/phy/phy-spacemit-k1-pcie.c | 670 +++++++++++++++++++++++++++++ + 3 files changed, 682 insertions(+) + create mode 100644 drivers/phy/phy-spacemit-k1-pcie.c + +--- a/drivers/phy/Kconfig ++++ b/drivers/phy/Kconfig +@@ -123,6 +123,17 @@ config PHY_NXP_PTN3222 + schemes. It supports all three USB 2.0 data rates: Low Speed, Full + Speed and High Speed. + ++config PHY_SPACEMIT_K1_PCIE ++ tristate "PCIe and combo PHY driver for the SpacemiT K1 SoC" ++ depends on ARCH_SPACEMIT || COMPILE_TEST ++ depends on HAS_IOMEM ++ depends on OF ++ select GENERIC_PHY ++ default ARCH_SPACEMIT ++ help ++ Enable support for the PCIe and USB 3 combo PHY and two ++ PCIe-only PHYs used in the SpacemiT K1 SoC. ++ + source "drivers/phy/allwinner/Kconfig" + source "drivers/phy/amlogic/Kconfig" + source "drivers/phy/broadcom/Kconfig" +--- a/drivers/phy/Makefile ++++ b/drivers/phy/Makefile +@@ -15,6 +15,7 @@ obj-$(CONFIG_PHY_SNPS_EUSB2) += phy-snp + obj-$(CONFIG_USB_LGM_PHY) += phy-lgm-usb.o + obj-$(CONFIG_PHY_AIROHA_PCIE) += phy-airoha-pcie.o + obj-$(CONFIG_PHY_NXP_PTN3222) += phy-nxp-ptn3222.o ++obj-$(CONFIG_PHY_SPACEMIT_K1_PCIE) += phy-spacemit-k1-pcie.o + obj-$(CONFIG_GENERIC_PHY) += allwinner/ \ + amlogic/ \ + broadcom/ \ +--- /dev/null ++++ b/drivers/phy/phy-spacemit-k1-pcie.c +@@ -0,0 +1,670 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * SpacemiT K1 PCIe and PCIe/USB 3 combo PHY driver ++ * ++ * Copyright (C) 2025 by RISCstar Solutions Corporation. All rights reserved. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++/* ++ * Three PCIe ports are supported in the SpacemiT K1 SoC, and this driver ++ * supports their PHYs. ++ * ++ * The PHY for PCIe port A is different from the PHYs for ports B and C: ++ * - It has one lane, while ports B and C have two ++ * - It is a combo PHY can be used for PCIe or USB 3 ++ * - It can automatically calibrate PCIe TX and RX termination settings ++ * ++ * The PHY functionality for PCIe ports B and C is identical: ++ * - They have two PCIe lanes (but can be restricted to 1 via device tree) ++ * - They are used for PCIe only ++ * - They are configured using TX and RX values computed for port A ++ * ++ * A given board is designed to use the combo PHY for either PCIe or USB 3. ++ * Whether the combo PHY is configured for PCIe or USB 3 is specified in ++ * device tree using a phandle plus an argument. The argument indicates ++ * the type (either PHY_TYPE_PCIE or PHY_TYPE_USB3). ++ * ++ * Each PHY has a reset that it gets and deasserts during initialization. ++ * Each depends also on other clocks and resets provided by the controller ++ * hardware (PCIe or USB) it is associated with. The controller drivers ++ * are required to enable any clocks and de-assert any resets that affect ++ * PHY operation. In addition each PHY implements an internal PLL, driven ++ * by an external (24 MHz) oscillator. ++ * ++ * PCIe PHYs must be programmed with RX and TX calibration values. The ++ * combo PHY is the only one that can determine these values. They are ++ * determined by temporarily enabling the combo PHY in PCIe mode at probe ++ * time (if necessary). This calibration only needs to be done once, and ++ * when it has completed the TX and RX values are saved. ++ * ++ * To allow the combo PHY to be enabled for calibration, the resets and ++ * clocks it uses in PCIe mode must be supplied. ++ */ ++ ++struct k1_pcie_phy { ++ struct device *dev; /* PHY provider device */ ++ struct phy *phy; ++ void __iomem *regs; ++ u32 pcie_lanes; /* Max (1 or 2) unless limited by DT */ ++ struct clk *pll; ++ struct clk_hw pll_hw; /* Private PLL clock */ ++ ++ /* The remaining fields are only used for the combo PHY */ ++ u32 type; /* PHY_TYPE_PCIE or PHY_TYPE_USB3 */ ++ struct regmap *pmu; /* MMIO regmap (no errors) */ ++}; ++ ++#define CALIBRATION_TIMEOUT 500000 /* For combo PHY (usec) */ ++#define PLL_TIMEOUT 500000 /* For PHY PLL lock (usec) */ ++#define POLL_DELAY 500 /* Time between polls (usec) */ ++ ++/* Selecting the combo PHY operating mode requires APMU regmap access */ ++#define SYSCON_APMU "spacemit,apmu" ++ ++/* PMU space, for selecting between PCIe and USB 3 mode (combo PHY only) */ ++ ++#define PMUA_USB_PHY_CTRL0 0x0110 ++#define COMBO_PHY_SEL BIT(3) /* 0: PCIe; 1: USB 3 */ ++ ++#define PCIE_CLK_RES_CTRL 0x03cc ++#define PCIE_APP_HOLD_PHY_RST BIT(30) ++ ++/* PHY register space */ ++ ++/* Offset between lane 0 and lane 1 registers when there are two */ ++#define PHY_LANE_OFFSET 0x0400 ++ ++/* PHY PLL configuration */ ++#define PCIE_PU_ADDR_CLK_CFG 0x0008 ++#define PLL_READY BIT(0) /* read-only */ ++#define CFG_INTERNAL_TIMER_ADJ GENMASK(10, 7) ++#define TIMER_ADJ_USB 0x2 ++#define TIMER_ADJ_PCIE 0x6 ++#define CFG_SW_PHY_INIT_DONE BIT(11) /* We set after PLL config */ ++ ++#define PCIE_RC_DONE_STATUS 0x0018 ++#define CFG_FORCE_RCV_RETRY BIT(10) /* Used for PCIe */ ++ ++/* PCIe PHY lane calibration; assumes 24MHz input clock */ ++#define PCIE_RC_CAL_REG2 0x0020 ++#define RC_CAL_TOGGLE BIT(22) ++#define CLKSEL GENMASK(31, 29) ++#define CLKSEL_24M 0x3 ++ ++/* Additional PHY PLL configuration (USB 3 and PCIe) */ ++#define PCIE_PU_PLL_1 0x0048 ++#define REF_100_WSSC BIT(12) /* 1: input is 100MHz, SSC */ ++#define FREF_SEL GENMASK(15, 13) ++#define FREF_24M 0x1 ++#define SSC_DEP_SEL GENMASK(19, 16) ++#define SSC_DEP_NONE 0x0 ++#define SSC_DEP_5000PPM 0xa ++ ++/* PCIe PHY configuration */ ++#define PCIE_PU_PLL_2 0x004c ++#define GEN_REF100 BIT(4) /* 1: generate 100MHz clk */ ++ ++#define PCIE_RX_REG1 0x0050 ++#define EN_RTERM BIT(3) ++#define AFE_RTERM_REG GENMASK(11, 8) ++ ++#define PCIE_RX_REG2 0x0054 ++#define RX_RTERM_SEL BIT(5) /* 0: use AFE_RTERM_REG value */ ++ ++#define PCIE_LTSSM_DIS_ENTRY 0x005c ++#define CFG_REFCLK_MODE GENMASK(9, 8) ++#define RFCLK_MODE_DRIVER 0x1 ++#define OVRD_REFCLK_MODE BIT(10) /* 1: use CFG_RFCLK_MODE */ ++ ++#define PCIE_TX_REG1 0x0064 ++#define TX_RTERM_REG GENMASK(15, 12) ++#define TX_RTERM_SEL BIT(25) /* 1: use TX_RTERM_REG */ ++ ++/* Zeroed for the combo PHY operating in USB mode */ ++#define USB3_TEST_CTRL 0x0068 ++ ++/* PHY calibration values, determined by the combo PHY at probe time */ ++#define PCIE_RCAL_RESULT 0x0084 /* Port A PHY only */ ++#define RTERM_VALUE_RX GENMASK(3, 0) ++#define RTERM_VALUE_TX GENMASK(7, 4) ++#define R_TUNE_DONE BIT(10) ++ ++static u32 k1_phy_rterm = ~0; /* Invalid initial value */ ++ ++/* Save the RX and TX receiver termination values */ ++static void k1_phy_rterm_set(u32 val) ++{ ++ k1_phy_rterm = val & (RTERM_VALUE_RX | RTERM_VALUE_TX); ++} ++ ++static bool k1_phy_rterm_valid(void) ++{ ++ /* Valid if no bits outside those we care about are set */ ++ return !(k1_phy_rterm & ~(RTERM_VALUE_RX | RTERM_VALUE_TX)); ++} ++ ++static u32 k1_phy_rterm_rx(void) ++{ ++ return FIELD_GET(RTERM_VALUE_RX, k1_phy_rterm); ++} ++ ++static u32 k1_phy_rterm_tx(void) ++{ ++ return FIELD_GET(RTERM_VALUE_TX, k1_phy_rterm); ++} ++ ++/* Only the combo PHY has a PMU pointer defined */ ++static bool k1_phy_port_a(struct k1_pcie_phy *k1_phy) ++{ ++ return !!k1_phy->pmu; ++} ++ ++/* The PLL clocks are driven by the external oscillator */ ++static const struct clk_parent_data k1_pcie_phy_data[] = { ++ { .fw_name = "refclk", }, ++}; ++ ++static struct k1_pcie_phy *clk_hw_to_k1_phy(struct clk_hw *clk_hw) ++{ ++ return container_of(clk_hw, struct k1_pcie_phy, pll_hw); ++} ++ ++/* USB mode only works on the combo PHY, which has only one lane */ ++static void k1_pcie_phy_pll_prepare_usb(struct k1_pcie_phy *k1_phy) ++{ ++ void __iomem *regs = k1_phy->regs; ++ u32 val; ++ ++ val = readl(regs + PCIE_PU_ADDR_CLK_CFG); ++ val &= ~CFG_INTERNAL_TIMER_ADJ; ++ val |= FIELD_PREP(CFG_INTERNAL_TIMER_ADJ, TIMER_ADJ_USB); ++ writel(val, regs + PCIE_PU_ADDR_CLK_CFG); ++ ++ val = readl(regs + PCIE_PU_PLL_1); ++ val &= ~SSC_DEP_SEL; ++ val |= FIELD_PREP(SSC_DEP_SEL, SSC_DEP_5000PPM); ++ writel(val, regs + PCIE_PU_PLL_1); ++} ++ ++/* Perform PCIe-specific register updates before starting the PLL clock */ ++static void k1_pcie_phy_pll_prepare_pcie(struct k1_pcie_phy *k1_phy) ++{ ++ void __iomem *regs = k1_phy->regs; ++ u32 val; ++ u32 i; ++ ++ for (i = 0; i < k1_phy->pcie_lanes; i++) { ++ val = readl(regs + PCIE_PU_ADDR_CLK_CFG); ++ val &= ~CFG_INTERNAL_TIMER_ADJ; ++ val |= FIELD_PREP(CFG_INTERNAL_TIMER_ADJ, TIMER_ADJ_PCIE); ++ writel(val, regs + PCIE_PU_ADDR_CLK_CFG); ++ ++ regs += PHY_LANE_OFFSET; /* Next lane */ ++ } ++ ++ regs = k1_phy->regs; ++ val = readl(regs + PCIE_RC_DONE_STATUS); ++ val |= CFG_FORCE_RCV_RETRY; ++ writel(val, regs + PCIE_RC_DONE_STATUS); ++ ++ val = readl(regs + PCIE_PU_PLL_1); ++ val &= ~SSC_DEP_SEL; ++ val |= FIELD_PREP(SSC_DEP_SEL, SSC_DEP_NONE); ++ writel(val, regs + PCIE_PU_PLL_1); ++ ++ val = readl(regs + PCIE_PU_PLL_2); ++ val |= GEN_REF100; /* Enable 100 MHz PLL output clock */ ++ writel(val, regs + PCIE_PU_PLL_2); ++} ++ ++static int k1_pcie_phy_pll_prepare(struct clk_hw *clk_hw) ++{ ++ struct k1_pcie_phy *k1_phy = clk_hw_to_k1_phy(clk_hw); ++ void __iomem *regs = k1_phy->regs; ++ u32 val; ++ u32 i; ++ ++ if (k1_phy_port_a(k1_phy) && k1_phy->type == PHY_TYPE_USB3) ++ k1_pcie_phy_pll_prepare_usb(k1_phy); ++ else ++ k1_pcie_phy_pll_prepare_pcie(k1_phy); ++ ++ /* ++ * Disable 100 MHz input reference with spread-spectrum ++ * clocking and select the 24 MHz clock input frequency ++ */ ++ val = readl(regs + PCIE_PU_PLL_1); ++ val &= ~REF_100_WSSC; ++ val &= ~FREF_SEL; ++ val |= FIELD_PREP(FREF_SEL, FREF_24M); ++ writel(val, regs + PCIE_PU_PLL_1); ++ ++ /* Mark PLL configuration done on all lanes */ ++ for (i = 0; i < k1_phy->pcie_lanes; i++) { ++ val = readl(regs + PCIE_PU_ADDR_CLK_CFG); ++ val |= CFG_SW_PHY_INIT_DONE; ++ writel(val, regs + PCIE_PU_ADDR_CLK_CFG); ++ ++ regs += PHY_LANE_OFFSET; /* Next lane */ ++ } ++ ++ /* ++ * Wait for indication the PHY PLL is locked. Lanes for ports ++ * B and C share a PLL, so it's enough to sample just lane 0. ++ */ ++ return readl_poll_timeout(k1_phy->regs + PCIE_PU_ADDR_CLK_CFG, ++ val, val & PLL_READY, ++ POLL_DELAY, PLL_TIMEOUT); ++} ++ ++/* Prepare implies enable, and once enabled, it's always on */ ++static const struct clk_ops k1_pcie_phy_pll_ops = { ++ .prepare = k1_pcie_phy_pll_prepare, ++}; ++ ++/* We represent the PHY PLL as a private clock */ ++static int k1_pcie_phy_pll_setup(struct k1_pcie_phy *k1_phy) ++{ ++ struct clk_hw *hw = &k1_phy->pll_hw; ++ struct device *dev = k1_phy->dev; ++ struct clk_init_data init = { }; ++ char *name; ++ int ret; ++ ++ name = kasprintf(GFP_KERNEL, "pcie%u_phy_pll", k1_phy->phy->id); ++ if (!name) ++ return -ENOMEM; ++ ++ init.name = name; ++ init.ops = &k1_pcie_phy_pll_ops; ++ init.parent_data = k1_pcie_phy_data; ++ init.num_parents = ARRAY_SIZE(k1_pcie_phy_data); ++ ++ hw->init = &init; ++ ++ ret = devm_clk_hw_register(dev, hw); ++ ++ kfree(name); /* __clk_register() duplicates the name we provide */ ++ ++ if (ret) ++ return ret; ++ ++ k1_phy->pll = devm_clk_hw_get_clk(dev, hw, "pll"); ++ if (IS_ERR(k1_phy->pll)) ++ return PTR_ERR(k1_phy->pll); ++ ++ return 0; ++} ++ ++/* Select PCIe or USB 3 mode for the combo PHY. */ ++static void k1_combo_phy_sel(struct k1_pcie_phy *k1_phy, bool usb) ++{ ++ struct regmap *pmu = k1_phy->pmu; ++ ++ /* Only change it if it's not already in the desired state */ ++ if (!regmap_test_bits(pmu, PMUA_USB_PHY_CTRL0, COMBO_PHY_SEL) == usb) ++ regmap_assign_bits(pmu, PMUA_USB_PHY_CTRL0, COMBO_PHY_SEL, usb); ++} ++ ++static void k1_pcie_phy_init_pcie(struct k1_pcie_phy *k1_phy) ++{ ++ u32 rx_rterm = k1_phy_rterm_rx(); ++ u32 tx_rterm = k1_phy_rterm_tx(); ++ void __iomem *regs; ++ u32 val; ++ int i; ++ ++ /* For the combo PHY, set PHY to PCIe mode */ ++ if (k1_phy_port_a(k1_phy)) ++ k1_combo_phy_sel(k1_phy, false); ++ ++ regs = k1_phy->regs; ++ for (i = 0; i < k1_phy->pcie_lanes; i++) { ++ val = readl(regs + PCIE_RX_REG1); ++ ++ /* Set RX analog front-end receiver termination value */ ++ val &= ~AFE_RTERM_REG; ++ val |= FIELD_PREP(AFE_RTERM_REG, rx_rterm); ++ ++ /* And enable refclock receiver termination */ ++ val |= EN_RTERM; ++ writel(val, regs + PCIE_RX_REG1); ++ ++ val = readl(regs + PCIE_RX_REG2); ++ /* Use PCIE_RX_REG1 AFE_RTERM_REG value */ ++ val &= ~RX_RTERM_SEL; ++ writel(val, regs + PCIE_RX_REG2); ++ ++ val = readl(regs + PCIE_TX_REG1); ++ ++ /* Set TX driver termination value */ ++ val &= ~TX_RTERM_REG; ++ val |= FIELD_PREP(TX_RTERM_REG, tx_rterm); ++ ++ /* Use PCIE_TX_REG1 TX_RTERM_REG value */ ++ val |= TX_RTERM_SEL; ++ writel(val, regs + PCIE_TX_REG1); ++ ++ /* Set the input clock to 24 MHz, and clear RC_CAL_TOGGLE */ ++ val = readl(regs + PCIE_RC_CAL_REG2); ++ val &= CLKSEL; ++ val |= FIELD_PREP(CLKSEL, CLKSEL_24M); ++ val &= ~RC_CAL_TOGGLE; ++ writel(val, regs + PCIE_RC_CAL_REG2); ++ ++ /* Now trigger recalibration by setting RC_CAL_TOGGLE again */ ++ val |= RC_CAL_TOGGLE; ++ writel(val, regs + PCIE_RC_CAL_REG2); ++ ++ val = readl(regs + PCIE_LTSSM_DIS_ENTRY); ++ /* Override the reference clock; set to refclk driver mode */ ++ val |= OVRD_REFCLK_MODE; ++ val &= ~CFG_REFCLK_MODE; ++ val |= FIELD_PREP(CFG_REFCLK_MODE, RFCLK_MODE_DRIVER); ++ writel(val, regs + PCIE_LTSSM_DIS_ENTRY); ++ ++ regs += PHY_LANE_OFFSET; /* Next lane */ ++ } ++} ++ ++/* Only called for combo PHY */ ++static void k1_pcie_phy_init_usb(struct k1_pcie_phy *k1_phy) ++{ ++ k1_combo_phy_sel(k1_phy, true); ++ ++ /* We're not doing any testing */ ++ writel(0, k1_phy->regs + USB3_TEST_CTRL); ++} ++ ++static int k1_pcie_phy_init(struct phy *phy) ++{ ++ struct k1_pcie_phy *k1_phy = phy_get_drvdata(phy); ++ ++ /* Note: port type is only valid for port A (both checks needed) */ ++ if (k1_phy_port_a(k1_phy) && k1_phy->type == PHY_TYPE_USB3) ++ k1_pcie_phy_init_usb(k1_phy); ++ else ++ k1_pcie_phy_init_pcie(k1_phy); ++ ++ ++ return clk_prepare_enable(k1_phy->pll); ++} ++ ++static int k1_pcie_phy_exit(struct phy *phy) ++{ ++ struct k1_pcie_phy *k1_phy = phy_get_drvdata(phy); ++ ++ clk_disable_unprepare(k1_phy->pll); ++ ++ return 0; ++} ++ ++static const struct phy_ops k1_pcie_phy_ops = { ++ .init = k1_pcie_phy_init, ++ .exit = k1_pcie_phy_exit, ++ .owner = THIS_MODULE, ++}; ++ ++/* ++ * Get values needed for calibrating PHYs operating in PCIe mode. Only ++ * the combo PHY is able to do this, and its calibration values are used ++ * for configuring all PCIe PHYs. ++ * ++ * We always need to de-assert the "global" reset on the combo PHY, ++ * because the USB driver depends on it. If used for PCIe, that driver ++ * will (also) de-assert this, but by leaving it de-asserted for the ++ * combo PHY, the USB driver doesn't have to do this. Note: although ++ * SpacemiT refers to this as the global reset, we name the "phy" reset. ++ * ++ * In addition, we guarantee the APP_HOLD_PHY_RESET bit is clear for the ++ * combo PHY, so the USB driver doesn't have to manage that either. The ++ * PCIe driver is free to change this bit for normal operation. ++ * ++ * Calibration only needs to be done once. It's possible calibration has ++ * already completed (e.g., it might have happened in the boot loader, or ++ * -EPROBE_DEFER might result in this function being called again). So we ++ * check that early too, to avoid doing it more than once. ++ * ++ * Otherwise we temporarily power up the PHY using the PCIe app clocks ++ * and resets, wait for the hardware to indicate calibration is done, ++ * grab the value, then shut the PHY down again. ++ */ ++static int k1_pcie_combo_phy_calibrate(struct k1_pcie_phy *k1_phy) ++{ ++ struct reset_control_bulk_data resets[] = { ++ { .id = "dbi", }, ++ { .id = "mstr", }, ++ { .id = "slv", }, ++ }; ++ struct clk_bulk_data clocks[] = { ++ { .id = "dbi", }, ++ { .id = "mstr", }, ++ { .id = "slv", }, ++ }; ++ struct device *dev = k1_phy->dev; ++ int ret = 0; ++ int val; ++ ++ /* Nothing to do if we already set the receiver termination value */ ++ if (k1_phy_rterm_valid()) ++ return 0; ++ ++ /* ++ * We also guarantee the APP_HOLD_PHY_RESET bit is clear. We can ++ * leave this bit clear even if an error happens below. ++ */ ++ regmap_assign_bits(k1_phy->pmu, PCIE_CLK_RES_CTRL, ++ PCIE_APP_HOLD_PHY_RST, false); ++ ++ /* If the calibration already completed (e.g. by U-Boot), we're done */ ++ val = readl(k1_phy->regs + PCIE_RCAL_RESULT); ++ if (val & R_TUNE_DONE) ++ goto out_tune_done; ++ ++ /* Put the PHY into PCIe mode */ ++ k1_combo_phy_sel(k1_phy, false); ++ ++ /* Get and enable the PCIe app clocks */ ++ ret = clk_bulk_get(dev, ARRAY_SIZE(clocks), clocks); ++ if (ret < 0) ++ goto out_tune_done; ++ ret = clk_bulk_prepare_enable(ARRAY_SIZE(clocks), clocks); ++ if (ret) ++ goto out_put_clocks; ++ ++ /* Get the PCIe application resets (not the PHY reset) */ ++ ret = reset_control_bulk_get_shared(dev, ARRAY_SIZE(resets), resets); ++ if (ret) ++ goto out_disable_clocks; ++ ++ /* De-assert the PCIe application resets */ ++ ret = reset_control_bulk_deassert(ARRAY_SIZE(resets), resets); ++ if (ret) ++ goto out_put_resets; ++ ++ /* ++ * This is the core activity here. Wait for the hardware to ++ * signal that it has completed calibration/tuning. Once it ++ * has, the register value will contain the values we'll ++ * use to configure PCIe PHYs. ++ */ ++ ret = readl_poll_timeout(k1_phy->regs + PCIE_RCAL_RESULT, ++ val, val & R_TUNE_DONE, ++ POLL_DELAY, CALIBRATION_TIMEOUT); ++ ++ /* Clean up. We're done with the resets and clocks */ ++ reset_control_bulk_assert(ARRAY_SIZE(resets), resets); ++out_put_resets: ++ reset_control_bulk_put(ARRAY_SIZE(resets), resets); ++out_disable_clocks: ++ clk_bulk_disable_unprepare(ARRAY_SIZE(clocks), clocks); ++out_put_clocks: ++ clk_bulk_put(ARRAY_SIZE(clocks), clocks); ++out_tune_done: ++ /* If we got the value without timing out, set k1_phy_rterm */ ++ if (!ret) ++ k1_phy_rterm_set(val); ++ ++ return ret; ++} ++ ++static struct phy * ++k1_pcie_combo_phy_xlate(struct device *dev, const struct of_phandle_args *args) ++{ ++ struct k1_pcie_phy *k1_phy = dev_get_drvdata(dev); ++ u32 type; ++ ++ /* The argument specifying the PHY mode is required */ ++ if (args->args_count != 1) ++ return ERR_PTR(-EINVAL); ++ ++ /* We only support PCIe and USB 3 mode */ ++ type = args->args[0]; ++ if (type != PHY_TYPE_PCIE && type != PHY_TYPE_USB3) ++ return ERR_PTR(-EINVAL); ++ ++ /* This PHY can only be used once */ ++ if (k1_phy->type != PHY_NONE) ++ return ERR_PTR(-EBUSY); ++ ++ k1_phy->type = type; ++ ++ return k1_phy->phy; ++} ++ ++/* Use the maximum number of PCIe lanes unless limited by device tree */ ++static u32 k1_pcie_num_lanes(struct k1_pcie_phy *k1_phy, bool port_a) ++{ ++ struct device *dev = k1_phy->dev; ++ u32 count = 0; ++ u32 max; ++ int ret; ++ ++ ret = of_property_read_u32(dev_of_node(dev), "num-lanes", &count); ++ if (count == 1) ++ return 1; ++ ++ if (count == 2 && !port_a) ++ return 2; ++ ++ max = port_a ? 1 : 2; ++ if (ret != -EINVAL) ++ dev_warn(dev, "bad lane count %u for port; using %u\n", ++ count, max); ++ ++ return max; ++} ++ ++static int k1_pcie_combo_phy_probe(struct k1_pcie_phy *k1_phy) ++{ ++ struct device *dev = k1_phy->dev; ++ struct regmap *regmap; ++ int ret; ++ ++ /* Setting the PHY mode requires access to the PMU regmap */ ++ regmap = syscon_regmap_lookup_by_phandle(dev_of_node(dev), SYSCON_APMU); ++ if (IS_ERR(regmap)) ++ return dev_err_probe(dev, PTR_ERR(regmap), "failed to get PMU\n"); ++ k1_phy->pmu = regmap; ++ ++ ret = k1_pcie_combo_phy_calibrate(k1_phy); ++ if (ret) ++ return dev_err_probe(dev, ret, "calibration failed\n"); ++ ++ /* Needed by k1_pcie_combo_phy_xlate(), which also sets k1_phy->type */ ++ dev_set_drvdata(dev, k1_phy); ++ ++ return 0; ++} ++ ++static int k1_pcie_phy_probe(struct platform_device *pdev) ++{ ++ struct phy *(*xlate)(struct device *dev, ++ const struct of_phandle_args *args); ++ struct device *dev = &pdev->dev; ++ struct reset_control *phy_reset; ++ struct phy_provider *provider; ++ struct k1_pcie_phy *k1_phy; ++ bool probing_port_a; ++ int ret; ++ ++ xlate = of_device_get_match_data(dev); ++ probing_port_a = xlate == k1_pcie_combo_phy_xlate; ++ ++ /* Only the combo PHY can calibrate, so it must probe first */ ++ if (!k1_phy_rterm_valid() && !probing_port_a) ++ return -EPROBE_DEFER; ++ ++ k1_phy = devm_kzalloc(dev, sizeof(*k1_phy), GFP_KERNEL); ++ if (!k1_phy) ++ return -ENOMEM; ++ k1_phy->dev = dev; ++ ++ k1_phy->regs = devm_platform_ioremap_resource(pdev, 0); ++ if (IS_ERR(k1_phy->regs)) ++ return dev_err_probe(dev, PTR_ERR(k1_phy->regs), ++ "error mapping registers\n"); ++ ++ /* De-assert the PHY (global) reset and leave it that way */ ++ phy_reset = devm_reset_control_get_exclusive_deasserted(dev, "phy"); ++ if (IS_ERR(phy_reset)) ++ return PTR_ERR(phy_reset); ++ ++ if (probing_port_a) { ++ ret = k1_pcie_combo_phy_probe(k1_phy); ++ if (ret) ++ return dev_err_probe(dev, ret, ++ "error probing combo phy\n"); ++ } ++ ++ k1_phy->pcie_lanes = k1_pcie_num_lanes(k1_phy, probing_port_a); ++ ++ k1_phy->phy = devm_phy_create(dev, NULL, &k1_pcie_phy_ops); ++ if (IS_ERR(k1_phy->phy)) ++ return dev_err_probe(dev, PTR_ERR(k1_phy->phy), ++ "error creating phy\n"); ++ phy_set_drvdata(k1_phy->phy, k1_phy); ++ ++ ret = k1_pcie_phy_pll_setup(k1_phy); ++ if (ret) ++ return dev_err_probe(dev, ret, "error initializing clock\n"); ++ ++ provider = devm_of_phy_provider_register(dev, xlate); ++ if (IS_ERR(provider)) ++ return dev_err_probe(dev, PTR_ERR(provider), ++ "error registering provider\n"); ++ return 0; ++} ++ ++static const struct of_device_id k1_pcie_phy_of_match[] = { ++ { .compatible = "spacemit,k1-combo-phy", k1_pcie_combo_phy_xlate, }, ++ { .compatible = "spacemit,k1-pcie-phy", of_phy_simple_xlate, }, ++ { }, ++}; ++MODULE_DEVICE_TABLE(of, k1_pcie_phy_of_match); ++ ++static struct platform_driver k1_pcie_phy_driver = { ++ .probe = k1_pcie_phy_probe, ++ .driver = { ++ .of_match_table = k1_pcie_phy_of_match, ++ .name = "spacemit-k1-pcie-phy", ++ } ++}; ++module_platform_driver(k1_pcie_phy_driver); ++ ++MODULE_DESCRIPTION("SpacemiT K1 PCIe and USB 3 PHY driver"); ++MODULE_LICENSE("GPL"); diff --git a/target/linux/spacemit/patches-6.18/0036-riscv-dts-spacemit-Add-a-PCIe-regulator.patch b/target/linux/spacemit/patches-6.18/0036-riscv-dts-spacemit-Add-a-PCIe-regulator.patch new file mode 100644 index 00000000000000..1c946c5341ef66 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0036-riscv-dts-spacemit-Add-a-PCIe-regulator.patch @@ -0,0 +1,35 @@ +From cdece45548091e2886ba5e8864056dd2a3a904e8 Mon Sep 17 00:00:00 2001 +From: Alex Elder +Date: Thu, 18 Dec 2025 09:12:30 -0600 +Subject: [PATCH] riscv: dts: spacemit: Add a PCIe regulator + +Define a 3.3v fixed voltage regulator to be used by PCIe on the +Banana Pi BPI-F3. On this platform, this regulator is always on. + +Signed-off-by: Alex Elder +Reviewed-by: Yixun Lan +Tested-by: Yixun Lan +Link: https://lore.kernel.org/r/20251218151235.454997-5-elder@riscstar.com +Signed-off-by: Yixun Lan +(cherry picked from commit 73a6c811fa0d07078c9e1eaecea76ce26fb5f10e) +--- + arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts ++++ b/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts +@@ -33,6 +33,14 @@ + }; + }; + ++ pcie_vcc_3v3: pcie-vcc3v3 { ++ compatible = "regulator-fixed"; ++ regulator-name = "PCIE_VCC3V3"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-always-on; ++ }; ++ + reg_dc_in: dc-in-12v { + compatible = "regulator-fixed"; + regulator-name = "dc_in_12v"; diff --git a/target/linux/spacemit/patches-6.18/0037-riscv-dts-spacemit-PCIe-and-PHY-related-updates.patch b/target/linux/spacemit/patches-6.18/0037-riscv-dts-spacemit-PCIe-and-PHY-related-updates.patch new file mode 100644 index 00000000000000..99fcf99b50828a --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0037-riscv-dts-spacemit-PCIe-and-PHY-related-updates.patch @@ -0,0 +1,320 @@ +From 8e74fe87fd27b2d7013144a271459a6049acd125 Mon Sep 17 00:00:00 2001 +From: Alex Elder +Date: Thu, 18 Dec 2025 09:12:31 -0600 +Subject: [PATCH] riscv: dts: spacemit: PCIe and PHY-related updates + +Define PCIe and PHY-related Device Tree nodes for the SpacemiT K1 SoC. + +Enable the combo PHY and the two PCIe-only PHYs on the Banana Pi BPI-F3 +board. The combo PHY is used for USB on this board, and that will be +enabled when USB 3 support is accepted. + +The combo PHY must perform a calibration step to determine configuration +values used by the PCIe-only PHYs. As a result, it must be enabled if +either of the other two PHYs is enabled. + +Signed-off-by: Alex Elder +Reviewed-by: Yixun Lan +Tested-by: Yixun Lan +Link: https://lore.kernel.org/r/20251218151235.454997-6-elder@riscstar.com +Signed-off-by: Yixun Lan +(cherry picked from commit 0be016a4b5d1b927de04e2e7a0a2bce51aacbfff) +--- + .../boot/dts/spacemit/k1-bananapi-f3.dts | 36 ++++ + arch/riscv/boot/dts/spacemit/k1-pinctrl.dtsi | 33 ++++ + arch/riscv/boot/dts/spacemit/k1.dtsi | 176 ++++++++++++++++++ + 3 files changed, 245 insertions(+) + +--- a/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts ++++ b/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts +@@ -61,6 +61,12 @@ + }; + }; + ++&combo_phy { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pcie0_3_cfg>; ++ status = "okay"; ++}; ++ + &emmc { + bus-width = <8>; + mmc-hs400-1_8v; +@@ -272,6 +278,36 @@ + }; + }; + ++&pcie1_phy { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pcie1_3_cfg>; ++ status = "okay"; ++}; ++ ++&pcie1_port { ++ phys = <&pcie1_phy>; ++}; ++ ++&pcie1 { ++ vpcie3v3-supply = <&pcie_vcc_3v3>; ++ status = "okay"; ++}; ++ ++&pcie2_phy { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pcie2_4_cfg>; ++ status = "okay"; ++}; ++ ++&pcie2_port { ++ phys = <&pcie2_phy>; ++}; ++ ++&pcie2 { ++ vpcie3v3-supply = <&pcie_vcc_3v3>; ++ status = "okay"; ++}; ++ + &uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_2_cfg>; +--- a/arch/riscv/boot/dts/spacemit/k1-pinctrl.dtsi ++++ b/arch/riscv/boot/dts/spacemit/k1-pinctrl.dtsi +@@ -530,6 +530,39 @@ + }; + }; + ++ pcie0_3_cfg: pcie0-3-cfg { ++ pcie0-3-pins { ++ pinmux = , /* PERST# */ ++ , /* WAKE# */ ++ ; /* CLKREQ# */ ++ ++ bias-pull-up = <0>; ++ drive-strength = <21>; ++ }; ++ }; ++ ++ pcie1_3_cfg: pcie1-3-cfg { ++ pcie1-3-pins { ++ pinmux = , /* PERST# */ ++ , /* WAKE# */ ++ ; /* CLKREQ# */ ++ ++ bias-pull-up = <0>; ++ drive-strength = <21>; ++ }; ++ }; ++ ++ pcie2_4_cfg: pcie2-4-cfg { ++ pcie2-4-pins { ++ pinmux = , /* PERST# */ ++ , /* WAKE# */ ++ ; /* CLKREQ# */ ++ ++ bias-pull-up = <0>; ++ drive-strength = <21>; ++ }; ++ }; ++ + pwm14_1_cfg: pwm14-1-cfg { + pwm14-1-pins { + pinmux = ; +--- a/arch/riscv/boot/dts/spacemit/k1.dtsi ++++ b/arch/riscv/boot/dts/spacemit/k1.dtsi +@@ -4,6 +4,7 @@ + */ + + #include ++#include + + /dts-v1/; + / { +@@ -423,6 +424,52 @@ + status = "disabled"; + }; + ++ combo_phy: phy@c0b10000 { ++ compatible = "spacemit,k1-combo-phy"; ++ reg = <0x0 0xc0b10000 0x0 0x1000>; ++ clocks = <&vctcxo_24m>, ++ <&syscon_apmu CLK_PCIE0_DBI>, ++ <&syscon_apmu CLK_PCIE0_MASTER>, ++ <&syscon_apmu CLK_PCIE0_SLAVE>; ++ clock-names = "refclk", ++ "dbi", ++ "mstr", ++ "slv"; ++ resets = <&syscon_apmu RESET_PCIE0_GLOBAL>, ++ <&syscon_apmu RESET_PCIE0_DBI>, ++ <&syscon_apmu RESET_PCIE0_MASTER>, ++ <&syscon_apmu RESET_PCIE0_SLAVE>; ++ reset-names = "phy", ++ "dbi", ++ "mstr", ++ "slv"; ++ #phy-cells = <1>; ++ spacemit,apmu = <&syscon_apmu>; ++ status = "disabled"; ++ }; ++ ++ pcie1_phy: phy@c0c10000 { ++ compatible = "spacemit,k1-pcie-phy"; ++ reg = <0x0 0xc0c10000 0x0 0x1000>; ++ clocks = <&vctcxo_24m>; ++ clock-names = "refclk"; ++ resets = <&syscon_apmu RESET_PCIE1_GLOBAL>; ++ reset-names = "phy"; ++ #phy-cells = <0>; ++ status = "disabled"; ++ }; ++ ++ pcie2_phy: phy@c0d10000 { ++ compatible = "spacemit,k1-pcie-phy"; ++ reg = <0x0 0xc0d10000 0x0 0x1000>; ++ clocks = <&vctcxo_24m>; ++ clock-names = "refclk"; ++ resets = <&syscon_apmu RESET_PCIE2_GLOBAL>; ++ reset-names = "phy"; ++ #phy-cells = <0>; ++ status = "disabled"; ++ }; ++ + syscon_apbc: system-controller@d4015000 { + compatible = "spacemit,k1-syscon-apbc"; + reg = <0x0 0xd4015000 0x0 0x1000>; +@@ -969,6 +1016,135 @@ + #size-cells = <2>; + dma-ranges = <0x0 0x00000000 0x0 0x00000000 0x0 0x80000000>, + <0x0 0xb8000000 0x1 0x38000000 0x3 0x48000000>; ++ pcie0: pcie@ca000000 { ++ device_type = "pci"; ++ compatible = "spacemit,k1-pcie"; ++ reg = <0x0 0xca000000 0x0 0x00001000>, ++ <0x0 0xca300000 0x0 0x0001ff24>, ++ <0x0 0x8f000000 0x0 0x00002000>, ++ <0x0 0xc0b20000 0x0 0x00001000>; ++ reg-names = "dbi", ++ "atu", ++ "config", ++ "link"; ++ #address-cells = <3>; ++ #size-cells = <2>; ++ ranges = <0x01000000 0x0 0x00000000 0x0 0x8f002000 0x0 0x00100000>, ++ <0x02000000 0x0 0x80000000 0x0 0x80000000 0x0 0x0f000000>; ++ interrupts = <141>; ++ interrupt-names = "msi"; ++ clocks = <&syscon_apmu CLK_PCIE0_DBI>, ++ <&syscon_apmu CLK_PCIE0_MASTER>, ++ <&syscon_apmu CLK_PCIE0_SLAVE>; ++ clock-names = "dbi", ++ "mstr", ++ "slv"; ++ resets = <&syscon_apmu RESET_PCIE0_DBI>, ++ <&syscon_apmu RESET_PCIE0_MASTER>, ++ <&syscon_apmu RESET_PCIE0_SLAVE>; ++ reset-names = "dbi", ++ "mstr", ++ "slv"; ++ spacemit,apmu = <&syscon_apmu 0x03cc>; ++ status = "disabled"; ++ ++ pcie0_port: pcie@0 { ++ device_type = "pci"; ++ compatible = "pciclass,0604"; ++ reg = <0x0 0x0 0x0 0x0 0x0>; ++ bus-range = <0x01 0xff>; ++ #address-cells = <3>; ++ #size-cells = <2>; ++ ranges; ++ }; ++ }; ++ ++ pcie1: pcie@ca400000 { ++ device_type = "pci"; ++ compatible = "spacemit,k1-pcie"; ++ reg = <0x0 0xca400000 0x0 0x00001000>, ++ <0x0 0xca700000 0x0 0x0001ff24>, ++ <0x0 0x9f000000 0x0 0x00002000>, ++ <0x0 0xc0c20000 0x0 0x00001000>; ++ reg-names = "dbi", ++ "atu", ++ "config", ++ "link"; ++ #address-cells = <3>; ++ #size-cells = <2>; ++ ranges = <0x01000000 0x0 0x00000000 0x0 0x9f002000 0x0 0x00100000>, ++ <0x02000000 0x0 0x90000000 0x0 0x90000000 0x0 0x0f000000>; ++ interrupts = <142>; ++ interrupt-names = "msi"; ++ clocks = <&syscon_apmu CLK_PCIE1_DBI>, ++ <&syscon_apmu CLK_PCIE1_MASTER>, ++ <&syscon_apmu CLK_PCIE1_SLAVE>; ++ clock-names = "dbi", ++ "mstr", ++ "slv"; ++ resets = <&syscon_apmu RESET_PCIE1_DBI>, ++ <&syscon_apmu RESET_PCIE1_MASTER>, ++ <&syscon_apmu RESET_PCIE1_SLAVE>; ++ reset-names = "dbi", ++ "mstr", ++ "slv"; ++ spacemit,apmu = <&syscon_apmu 0x3d4>; ++ status = "disabled"; ++ ++ pcie1_port: pcie@0 { ++ device_type = "pci"; ++ compatible = "pciclass,0604"; ++ reg = <0x0 0x0 0x0 0x0 0x0>; ++ bus-range = <0x01 0xff>; ++ #address-cells = <3>; ++ #size-cells = <2>; ++ ranges; ++ }; ++ }; ++ ++ pcie2: pcie@ca800000 { ++ device_type = "pci"; ++ compatible = "spacemit,k1-pcie"; ++ reg = <0x0 0xca800000 0x0 0x00001000>, ++ <0x0 0xcab00000 0x0 0x0001ff24>, ++ <0x0 0xb7000000 0x0 0x00002000>, ++ <0x0 0xc0d20000 0x0 0x00001000>; ++ reg-names = "dbi", ++ "atu", ++ "config", ++ "link"; ++ #address-cells = <3>; ++ #size-cells = <2>; ++ ranges = <0x01000000 0x0 0x00000000 0x0 0xb7002000 0x0 0x00100000>, ++ <0x42000000 0x0 0xa0000000 0x0 0xa0000000 0x0 0x10000000>, ++ <0x02000000 0x0 0xb0000000 0x0 0xb0000000 0x0 0x07000000>; ++ interrupts = <143>; ++ interrupt-names = "msi"; ++ clocks = <&syscon_apmu CLK_PCIE2_DBI>, ++ <&syscon_apmu CLK_PCIE2_MASTER>, ++ <&syscon_apmu CLK_PCIE2_SLAVE>; ++ clock-names = "dbi", ++ "mstr", ++ "slv"; ++ resets = <&syscon_apmu RESET_PCIE2_DBI>, ++ <&syscon_apmu RESET_PCIE2_MASTER>, ++ <&syscon_apmu RESET_PCIE2_SLAVE>; ++ reset-names = "dbi", ++ "mstr", ++ "slv"; ++ spacemit,apmu = <&syscon_apmu 0x3dc>; ++ status = "disabled"; ++ ++ pcie2_port: pcie@0 { ++ device_type = "pci"; ++ compatible = "pciclass,0604"; ++ reg = <0x0 0x0 0x0 0x0 0x0>; ++ bus-range = <0x01 0xff>; ++ #address-cells = <3>; ++ #size-cells = <2>; ++ ranges; ++ }; ++ }; + }; + + storage-bus { diff --git a/target/linux/spacemit/patches-6.18/0038-phy-Kconfig-spacemit-add-COMMON_CLK-dependency.patch b/target/linux/spacemit/patches-6.18/0038-phy-Kconfig-spacemit-add-COMMON_CLK-dependency.patch new file mode 100644 index 00000000000000..81323280259b03 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0038-phy-Kconfig-spacemit-add-COMMON_CLK-dependency.patch @@ -0,0 +1,30 @@ +From 296019157347fb90c203e09c6762651f3339e2b8 Mon Sep 17 00:00:00 2001 +From: Alex Elder +Date: Fri, 26 Dec 2025 11:32:27 -0600 +Subject: [PATCH] phy: Kconfig: spacemit: add COMMON_CLK dependency + +The SpacemiT PCIe PHY driver depends on the common clock framework. +Not specifying that led to a failure when doing a COMPILE_TEST build +for the SPARC architecture. + +Reported-by: kernel test robot +Closes: https://lore.kernel.org/oe-kbuild-all/202512251903.sTVZgg6c-lkp@intel.com/ +Signed-off-by: Alex Elder +Reviewed-by: Javier Martinez Canillas +Link: https://patch.msgid.link/20251226173228.2020411-1-elder@riscstar.com +Signed-off-by: Vinod Koul +(cherry picked from commit 8df20813eb01fe29b4507fd470d73675bda3e1dd) +--- + drivers/phy/Kconfig | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/phy/Kconfig ++++ b/drivers/phy/Kconfig +@@ -126,6 +126,7 @@ config PHY_NXP_PTN3222 + config PHY_SPACEMIT_K1_PCIE + tristate "PCIe and combo PHY driver for the SpacemiT K1 SoC" + depends on ARCH_SPACEMIT || COMPILE_TEST ++ depends on COMMON_CLK + depends on HAS_IOMEM + depends on OF + select GENERIC_PHY diff --git a/target/linux/spacemit/patches-6.18/0039-dt-bindings-phy-spacemit-add-K1-USB2-PHY.patch b/target/linux/spacemit/patches-6.18/0039-dt-bindings-phy-spacemit-add-K1-USB2-PHY.patch new file mode 100644 index 00000000000000..11d71e31b5f490 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0039-dt-bindings-phy-spacemit-add-K1-USB2-PHY.patch @@ -0,0 +1,62 @@ +From e8ae87679f1ad1340896080a2577f617210f6a1d Mon Sep 17 00:00:00 2001 +From: Ze Huang +Date: Fri, 17 Oct 2025 22:49:52 +0800 +Subject: [PATCH] dt-bindings: phy: spacemit: add K1 USB2 PHY + +Add support for USB2 PHY found on SpacemiT K1 SoC. + +Reviewed-by: Rob Herring (Arm) +Signed-off-by: Ze Huang +Tested-by: Aurelien Jarno +Tested-by: Junzhong Pan +Link: https://patch.msgid.link/20251017-k1-usb2phy-v6-1-7cf9ea2477a1@linux.dev +Signed-off-by: Vinod Koul +(cherry picked from commit 61b84d5b20af2a4c9944972202c1386026598928) +--- + .../bindings/phy/spacemit,usb2-phy.yaml | 40 +++++++++++++++++++ + 1 file changed, 40 insertions(+) + create mode 100644 Documentation/devicetree/bindings/phy/spacemit,usb2-phy.yaml + +--- /dev/null ++++ b/Documentation/devicetree/bindings/phy/spacemit,usb2-phy.yaml +@@ -0,0 +1,40 @@ ++# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) ++%YAML 1.2 ++--- ++$id: http://devicetree.org/schemas/phy/spacemit,usb2-phy.yaml# ++$schema: http://devicetree.org/meta-schemas/core.yaml# ++ ++title: SpacemiT K1 SoC USB 2.0 PHY ++ ++maintainers: ++ - Ze Huang ++ ++properties: ++ compatible: ++ const: spacemit,k1-usb2-phy ++ ++ reg: ++ maxItems: 1 ++ ++ clocks: ++ maxItems: 1 ++ ++ "#phy-cells": ++ const: 0 ++ ++required: ++ - compatible ++ - reg ++ - clocks ++ - "#phy-cells" ++ ++additionalProperties: false ++ ++examples: ++ - | ++ usb-phy@c09c0000 { ++ compatible = "spacemit,k1-usb2-phy"; ++ reg = <0xc09c0000 0x200>; ++ clocks = <&syscon_apmu 15>; ++ #phy-cells = <0>; ++ }; diff --git a/target/linux/spacemit/patches-6.18/0040-phy-spacemit-support-K1-USB2.0-PHY-controller.patch b/target/linux/spacemit/patches-6.18/0040-phy-spacemit-support-K1-USB2.0-PHY-controller.patch new file mode 100644 index 00000000000000..08571890c2c344 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0040-phy-spacemit-support-K1-USB2.0-PHY-controller.patch @@ -0,0 +1,279 @@ +From 65f1cf3b3d2cd28a482a785cb51ae37038ee84a2 Mon Sep 17 00:00:00 2001 +From: Ze Huang +Date: Fri, 17 Oct 2025 22:49:53 +0800 +Subject: [PATCH] phy: spacemit: support K1 USB2.0 PHY controller + +The SpacemiT K1 SoC includes three USB ports: + +- One USB2.0 OTG port +- One USB2.0 host-only port +- One USB3.0 port with an integrated USB2.0 DRD interface + +Each of these ports is connected to a USB2.0 PHY responsible for USB2 +transmission. + +This commit adds support for the SpacemiT K1 USB2.0 PHY, which is +compliant with the USB 2.0 specification and supports both 8-bit 60MHz +and 16-bit 30MHz parallel interfaces. + +Signed-off-by: Ze Huang +Tested-by: Aurelien Jarno +Tested-by: Junzhong Pan +Link: https://patch.msgid.link/20251017-k1-usb2phy-v6-2-7cf9ea2477a1@linux.dev +Signed-off-by: Vinod Koul +(cherry picked from commit fe4bc1a08638309b6be1af37210930b856908eb7) +--- + drivers/phy/Kconfig | 1 + + drivers/phy/Makefile | 1 + + drivers/phy/spacemit/Kconfig | 13 ++ + drivers/phy/spacemit/Makefile | 2 + + drivers/phy/spacemit/phy-k1-usb2.c | 200 +++++++++++++++++++++++++++++ + 5 files changed, 217 insertions(+) + create mode 100644 drivers/phy/spacemit/Kconfig + create mode 100644 drivers/phy/spacemit/Makefile + create mode 100644 drivers/phy/spacemit/phy-k1-usb2.c + +--- a/drivers/phy/Kconfig ++++ b/drivers/phy/Kconfig +@@ -157,6 +157,7 @@ source "drivers/phy/rockchip/Kconfig" + source "drivers/phy/samsung/Kconfig" + source "drivers/phy/socionext/Kconfig" + source "drivers/phy/sophgo/Kconfig" ++source "drivers/phy/spacemit/Kconfig" + source "drivers/phy/st/Kconfig" + source "drivers/phy/starfive/Kconfig" + source "drivers/phy/sunplus/Kconfig" +--- a/drivers/phy/Makefile ++++ b/drivers/phy/Makefile +@@ -39,6 +39,7 @@ obj-$(CONFIG_GENERIC_PHY) += allwinner/ + samsung/ \ + socionext/ \ + sophgo/ \ ++ spacemit/ \ + st/ \ + starfive/ \ + sunplus/ \ +--- /dev/null ++++ b/drivers/phy/spacemit/Kconfig +@@ -0,0 +1,13 @@ ++# SPDX-License-Identifier: GPL-2.0-only ++# ++# Phy drivers for SpacemiT platforms ++# ++config PHY_SPACEMIT_K1_USB2 ++ tristate "SpacemiT K1 USB 2.0 PHY support" ++ depends on (ARCH_SPACEMIT || COMPILE_TEST) && OF ++ depends on COMMON_CLK ++ depends on USB_COMMON ++ select GENERIC_PHY ++ help ++ Enable this to support K1 USB 2.0 PHY driver. This driver takes care of ++ enabling and clock setup and will be used by K1 udc/ehci/otg/xhci driver. +--- /dev/null ++++ b/drivers/phy/spacemit/Makefile +@@ -0,0 +1,2 @@ ++# SPDX-License-Identifier: GPL-2.0-only ++obj-$(CONFIG_PHY_SPACEMIT_K1_USB2) += phy-k1-usb2.o +--- /dev/null ++++ b/drivers/phy/spacemit/phy-k1-usb2.c +@@ -0,0 +1,200 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * SpacemiT K1 USB 2.0 PHY driver ++ * ++ * Copyright (C) 2025 SpacemiT (Hangzhou) Technology Co. Ltd ++ * Copyright (C) 2025 Ze Huang ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define PHY_RST_MODE_CTRL 0x04 ++#define PHY_PLL_RDY BIT(0) ++#define PHY_CLK_CDR_EN BIT(1) ++#define PHY_CLK_PLL_EN BIT(2) ++#define PHY_CLK_MAC_EN BIT(3) ++#define PHY_MAC_RSTN BIT(5) ++#define PHY_CDR_RSTN BIT(6) ++#define PHY_PLL_RSTN BIT(7) ++/* ++ * hs line state sel (Bit 13): ++ * - 1 (Default): Internal HS line state is set to 01 when usb_hs_tx_en is valid. ++ * - 0: Internal HS line state is always driven by usb_hs_lstate. ++ * ++ * fs line state sel (Bit 14): ++ * - 1 (Default): FS line state is determined by the output data ++ * (usb_fs_datain/b). ++ * - 0: FS line state is always determined by the input data (dmo/dpo). ++ */ ++#define PHY_HS_LINE_TX_MODE BIT(13) ++#define PHY_FS_LINE_TX_MODE BIT(14) ++ ++#define PHY_INIT_MODE_BITS (PHY_FS_LINE_TX_MODE | PHY_HS_LINE_TX_MODE) ++#define PHY_CLK_ENABLE_BITS (PHY_CLK_PLL_EN | PHY_CLK_CDR_EN | \ ++ PHY_CLK_MAC_EN) ++#define PHY_DEASSERT_RST_BITS (PHY_PLL_RSTN | PHY_CDR_RSTN | \ ++ PHY_MAC_RSTN) ++ ++#define PHY_TX_HOST_CTRL 0x10 ++#define PHY_HST_DISC_AUTO_CLR BIT(2) /* autoclear hs host disc when re-connect */ ++ ++#define PHY_HSTXP_HW_CTRL 0x34 ++#define PHY_HSTXP_RSTN BIT(2) /* generate reset for clock hstxp */ ++#define PHY_CLK_HSTXP_EN BIT(3) /* clock hstxp enable */ ++#define PHY_HSTXP_MODE BIT(4) /* 0: force en_txp to be 1; 1: no force */ ++ ++#define PHY_PLL_DIV_CFG 0x98 ++#define PHY_FDIV_FRACT_8_15 GENMASK(7, 0) ++#define PHY_FDIV_FRACT_16_19 GENMASK(11, 8) ++#define PHY_FDIV_FRACT_20_21 BIT(12) /* fdiv_reg<21>, <20>, bit21 == bit20 */ ++/* ++ * freq_sel<1:0> ++ * if ref clk freq=24.0MHz-->freq_sel<2:0> == 3b'001, then internal divider value == 80 ++ */ ++#define PHY_FDIV_FRACT_0_1 GENMASK(14, 13) ++/* ++ * pll divider value selection ++ * 1: divider value will choose internal default value ,dependent on freq_sel<1:0> ++ * 0: divider value will be over ride by fdiv_reg<21:0> ++ */ ++#define PHY_DIV_LOCAL_EN BIT(15) ++ ++#define PHY_SEL_FREQ_24MHZ 0x01 ++#define FDIV_REG_MASK (PHY_FDIV_FRACT_20_21 | PHY_FDIV_FRACT_16_19 | \ ++ PHY_FDIV_FRACT_8_15) ++#define FDIV_REG_VAL 0x1ec4 /* 0x100 selects 24MHz, rest are default */ ++ ++#define K1_USB2PHY_RESET_TIME_MS 50 ++ ++struct spacemit_usb2phy { ++ struct phy *phy; ++ struct clk *clk; ++ struct regmap *regmap_base; ++}; ++ ++static const struct regmap_config phy_regmap_config = { ++ .reg_bits = 32, ++ .val_bits = 32, ++ .reg_stride = 4, ++ .max_register = 0x200, ++}; ++ ++static int spacemit_usb2phy_init(struct phy *phy) ++{ ++ struct spacemit_usb2phy *sphy = phy_get_drvdata(phy); ++ struct regmap *map = sphy->regmap_base; ++ u32 val; ++ int ret; ++ ++ ret = clk_enable(sphy->clk); ++ if (ret) { ++ dev_err(&phy->dev, "failed to enable clock\n"); ++ clk_disable(sphy->clk); ++ return ret; ++ } ++ ++ /* ++ * make sure the usb controller is not under reset process before ++ * any configuration ++ */ ++ usleep_range(150, 200); ++ ++ /* 24M ref clk */ ++ val = FIELD_PREP(FDIV_REG_MASK, FDIV_REG_VAL) | ++ FIELD_PREP(PHY_FDIV_FRACT_0_1, PHY_SEL_FREQ_24MHZ) | ++ PHY_DIV_LOCAL_EN; ++ regmap_write(map, PHY_PLL_DIV_CFG, val); ++ ++ ret = regmap_read_poll_timeout(map, PHY_RST_MODE_CTRL, val, ++ (val & PHY_PLL_RDY), ++ 500, K1_USB2PHY_RESET_TIME_MS * 1000); ++ if (ret) { ++ dev_err(&phy->dev, "wait PLLREADY timeout\n"); ++ clk_disable(sphy->clk); ++ return ret; ++ } ++ ++ /* release usb2 phy internal reset and enable clock gating */ ++ val = (PHY_INIT_MODE_BITS | PHY_CLK_ENABLE_BITS | PHY_DEASSERT_RST_BITS); ++ regmap_write(map, PHY_RST_MODE_CTRL, val); ++ ++ val = (PHY_HSTXP_RSTN | PHY_CLK_HSTXP_EN | PHY_HSTXP_MODE); ++ regmap_write(map, PHY_HSTXP_HW_CTRL, val); ++ ++ /* auto clear host disc */ ++ regmap_update_bits(map, PHY_TX_HOST_CTRL, PHY_HST_DISC_AUTO_CLR, ++ PHY_HST_DISC_AUTO_CLR); ++ ++ return 0; ++} ++ ++static int spacemit_usb2phy_exit(struct phy *phy) ++{ ++ struct spacemit_usb2phy *sphy = phy_get_drvdata(phy); ++ ++ clk_disable(sphy->clk); ++ ++ return 0; ++} ++ ++static const struct phy_ops spacemit_usb2phy_ops = { ++ .init = spacemit_usb2phy_init, ++ .exit = spacemit_usb2phy_exit, ++ .owner = THIS_MODULE, ++}; ++ ++static int spacemit_usb2phy_probe(struct platform_device *pdev) ++{ ++ struct phy_provider *phy_provider; ++ struct device *dev = &pdev->dev; ++ struct spacemit_usb2phy *sphy; ++ void __iomem *base; ++ ++ sphy = devm_kzalloc(dev, sizeof(*sphy), GFP_KERNEL); ++ if (!sphy) ++ return -ENOMEM; ++ ++ sphy->clk = devm_clk_get_prepared(&pdev->dev, NULL); ++ if (IS_ERR(sphy->clk)) ++ return dev_err_probe(dev, PTR_ERR(sphy->clk), "Failed to get clock\n"); ++ ++ base = devm_platform_ioremap_resource(pdev, 0); ++ if (IS_ERR(base)) ++ return PTR_ERR(base); ++ ++ sphy->regmap_base = devm_regmap_init_mmio(dev, base, &phy_regmap_config); ++ if (IS_ERR(sphy->regmap_base)) ++ return dev_err_probe(dev, PTR_ERR(sphy->regmap_base), "Failed to init regmap\n"); ++ ++ sphy->phy = devm_phy_create(dev, NULL, &spacemit_usb2phy_ops); ++ if (IS_ERR(sphy->phy)) ++ return dev_err_probe(dev, PTR_ERR(sphy->phy), "Failed to create phy\n"); ++ ++ phy_set_drvdata(sphy->phy, sphy); ++ phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); ++ ++ return PTR_ERR_OR_ZERO(phy_provider); ++} ++ ++static const struct of_device_id spacemit_usb2phy_dt_match[] = { ++ { .compatible = "spacemit,k1-usb2-phy", }, ++ { /* sentinel */ } ++}; ++MODULE_DEVICE_TABLE(of, spacemit_usb2phy_dt_match); ++ ++static struct platform_driver spacemit_usb2_phy_driver = { ++ .probe = spacemit_usb2phy_probe, ++ .driver = { ++ .name = "spacemit-usb2-phy", ++ .of_match_table = spacemit_usb2phy_dt_match, ++ }, ++}; ++module_platform_driver(spacemit_usb2_phy_driver); ++ ++MODULE_DESCRIPTION("Spacemit USB 2.0 PHY driver"); ++MODULE_LICENSE("GPL"); diff --git a/target/linux/spacemit/patches-6.18/0041-gpio-spacemit-Add-GPIO-support-for-K3-SoC.patch b/target/linux/spacemit/patches-6.18/0041-gpio-spacemit-Add-GPIO-support-for-K3-SoC.patch new file mode 100644 index 00000000000000..ee22fd57e83863 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0041-gpio-spacemit-Add-GPIO-support-for-K3-SoC.patch @@ -0,0 +1,310 @@ +From 40e0ed63f54d1ebea9ccb75194b0d69333274597 Mon Sep 17 00:00:00 2001 +From: Yixun Lan +Date: Tue, 6 Jan 2026 11:09:33 +0800 +Subject: [PATCH] gpio: spacemit: Add GPIO support for K3 SoC + +SpacemiT K3 SoC has changed gpio register layout while comparing +with previous generation, the register offset and bank offset +need to be adjusted, introduce a compatible data to extend the +driver to support this. + +Signed-off-by: Yixun Lan +Link: https://lore.kernel.org/r/20260106-02-k3-gpio-v3-2-4800c214810b@gentoo.org +Signed-off-by: Bartosz Golaszewski +(cherry picked from commit da64eb51595bc6073b2fb69c2a3859bba93ed75a) +--- + drivers/gpio/gpio-spacemit-k1.c | 163 +++++++++++++++++++++++--------- + 1 file changed, 117 insertions(+), 46 deletions(-) + +--- a/drivers/gpio/gpio-spacemit-k1.c ++++ b/drivers/gpio/gpio-spacemit-k1.c +@@ -15,29 +15,37 @@ + #include + #include + +-/* register offset */ +-#define SPACEMIT_GPLR 0x00 /* port level - R */ +-#define SPACEMIT_GPDR 0x0c /* port direction - R/W */ +-#define SPACEMIT_GPSR 0x18 /* port set - W */ +-#define SPACEMIT_GPCR 0x24 /* port clear - W */ +-#define SPACEMIT_GRER 0x30 /* port rising edge R/W */ +-#define SPACEMIT_GFER 0x3c /* port falling edge R/W */ +-#define SPACEMIT_GEDR 0x48 /* edge detect status - R/W1C */ +-#define SPACEMIT_GSDR 0x54 /* (set) direction - W */ +-#define SPACEMIT_GCDR 0x60 /* (clear) direction - W */ +-#define SPACEMIT_GSRER 0x6c /* (set) rising edge detect enable - W */ +-#define SPACEMIT_GCRER 0x78 /* (clear) rising edge detect enable - W */ +-#define SPACEMIT_GSFER 0x84 /* (set) falling edge detect enable - W */ +-#define SPACEMIT_GCFER 0x90 /* (clear) falling edge detect enable - W */ +-#define SPACEMIT_GAPMASK 0x9c /* interrupt mask , 0 disable, 1 enable - R/W */ +- + #define SPACEMIT_NR_BANKS 4 + #define SPACEMIT_NR_GPIOS_PER_BANK 32 + + #define to_spacemit_gpio_bank(x) container_of((x), struct spacemit_gpio_bank, gc) ++#define to_spacemit_gpio_regs(gb) ((gb)->sg->data->offsets) ++ ++enum spacemit_gpio_registers { ++ SPACEMIT_GPLR, /* port level - R */ ++ SPACEMIT_GPDR, /* port direction - R/W */ ++ SPACEMIT_GPSR, /* port set - W */ ++ SPACEMIT_GPCR, /* port clear - W */ ++ SPACEMIT_GRER, /* port rising edge R/W */ ++ SPACEMIT_GFER, /* port falling edge R/W */ ++ SPACEMIT_GEDR, /* edge detect status - R/W1C */ ++ SPACEMIT_GSDR, /* (set) direction - W */ ++ SPACEMIT_GCDR, /* (clear) direction - W */ ++ SPACEMIT_GSRER, /* (set) rising edge detect enable - W */ ++ SPACEMIT_GCRER, /* (clear) rising edge detect enable - W */ ++ SPACEMIT_GSFER, /* (set) falling edge detect enable - W */ ++ SPACEMIT_GCFER, /* (clear) falling edge detect enable - W */ ++ SPACEMIT_GAPMASK, /* interrupt mask , 0 disable, 1 enable - R/W */ ++ SPACEMIT_GCPMASK, /* interrupt mask for K3 */ ++}; + + struct spacemit_gpio; + ++struct spacemit_gpio_data { ++ const unsigned int *offsets; ++ u32 bank_offsets[SPACEMIT_NR_BANKS]; ++}; ++ + struct spacemit_gpio_bank { + struct gpio_generic_chip chip; + struct spacemit_gpio *sg; +@@ -49,9 +57,22 @@ struct spacemit_gpio_bank { + + struct spacemit_gpio { + struct device *dev; ++ const struct spacemit_gpio_data *data; + struct spacemit_gpio_bank sgb[SPACEMIT_NR_BANKS]; + }; + ++static u32 spacemit_gpio_read(struct spacemit_gpio_bank *gb, ++ enum spacemit_gpio_registers reg) ++{ ++ return readl(gb->base + to_spacemit_gpio_regs(gb)[reg]); ++} ++ ++static void spacemit_gpio_write(struct spacemit_gpio_bank *gb, ++ enum spacemit_gpio_registers reg, u32 val) ++{ ++ writel(val, gb->base + to_spacemit_gpio_regs(gb)[reg]); ++} ++ + static u32 spacemit_gpio_bank_index(struct spacemit_gpio_bank *gb) + { + return (u32)(gb - gb->sg->sgb); +@@ -63,10 +84,10 @@ static irqreturn_t spacemit_gpio_irq_han + unsigned long pending; + u32 n, gedr; + +- gedr = readl(gb->base + SPACEMIT_GEDR); ++ gedr = spacemit_gpio_read(gb, SPACEMIT_GEDR); + if (!gedr) + return IRQ_NONE; +- writel(gedr, gb->base + SPACEMIT_GEDR); ++ spacemit_gpio_write(gb, SPACEMIT_GEDR, gedr); + + pending = gedr & gb->irq_mask; + if (!pending) +@@ -82,7 +103,7 @@ static void spacemit_gpio_irq_ack(struct + { + struct spacemit_gpio_bank *gb = irq_data_get_irq_chip_data(d); + +- writel(BIT(irqd_to_hwirq(d)), gb->base + SPACEMIT_GEDR); ++ spacemit_gpio_write(gb, SPACEMIT_GEDR, BIT(irqd_to_hwirq(d))); + } + + static void spacemit_gpio_irq_mask(struct irq_data *d) +@@ -91,13 +112,13 @@ static void spacemit_gpio_irq_mask(struc + u32 bit = BIT(irqd_to_hwirq(d)); + + gb->irq_mask &= ~bit; +- writel(gb->irq_mask, gb->base + SPACEMIT_GAPMASK); ++ spacemit_gpio_write(gb, SPACEMIT_GAPMASK, gb->irq_mask); + + if (bit & gb->irq_rising_edge) +- writel(bit, gb->base + SPACEMIT_GCRER); ++ spacemit_gpio_write(gb, SPACEMIT_GCRER, bit); + + if (bit & gb->irq_falling_edge) +- writel(bit, gb->base + SPACEMIT_GCFER); ++ spacemit_gpio_write(gb, SPACEMIT_GCFER, bit); + } + + static void spacemit_gpio_irq_unmask(struct irq_data *d) +@@ -108,12 +129,12 @@ static void spacemit_gpio_irq_unmask(str + gb->irq_mask |= bit; + + if (bit & gb->irq_rising_edge) +- writel(bit, gb->base + SPACEMIT_GSRER); ++ spacemit_gpio_write(gb, SPACEMIT_GSRER, bit); + + if (bit & gb->irq_falling_edge) +- writel(bit, gb->base + SPACEMIT_GSFER); ++ spacemit_gpio_write(gb, SPACEMIT_GSFER, bit); + +- writel(gb->irq_mask, gb->base + SPACEMIT_GAPMASK); ++ spacemit_gpio_write(gb, SPACEMIT_GAPMASK, gb->irq_mask); + } + + static int spacemit_gpio_irq_set_type(struct irq_data *d, unsigned int type) +@@ -123,18 +144,18 @@ static int spacemit_gpio_irq_set_type(st + + if (type & IRQ_TYPE_EDGE_RISING) { + gb->irq_rising_edge |= bit; +- writel(bit, gb->base + SPACEMIT_GSRER); ++ spacemit_gpio_write(gb, SPACEMIT_GSRER, bit); + } else { + gb->irq_rising_edge &= ~bit; +- writel(bit, gb->base + SPACEMIT_GCRER); ++ spacemit_gpio_write(gb, SPACEMIT_GCRER, bit); + } + + if (type & IRQ_TYPE_EDGE_FALLING) { + gb->irq_falling_edge |= bit; +- writel(bit, gb->base + SPACEMIT_GSFER); ++ spacemit_gpio_write(gb, SPACEMIT_GSFER, bit); + } else { + gb->irq_falling_edge &= ~bit; +- writel(bit, gb->base + SPACEMIT_GCFER); ++ spacemit_gpio_write(gb, SPACEMIT_GCFER, bit); + } + + return 0; +@@ -179,15 +200,16 @@ static int spacemit_gpio_add_bank(struct + struct device *dev = sg->dev; + struct gpio_irq_chip *girq; + void __iomem *dat, *set, *clr, *dirin, *dirout; +- int ret, bank_base[] = { 0x0, 0x4, 0x8, 0x100 }; ++ int ret; + +- gb->base = regs + bank_base[index]; ++ gb->base = regs + sg->data->bank_offsets[index]; ++ gb->sg = sg; + +- dat = gb->base + SPACEMIT_GPLR; +- set = gb->base + SPACEMIT_GPSR; +- clr = gb->base + SPACEMIT_GPCR; +- dirin = gb->base + SPACEMIT_GCDR; +- dirout = gb->base + SPACEMIT_GSDR; ++ dat = gb->base + to_spacemit_gpio_regs(gb)[SPACEMIT_GPLR]; ++ set = gb->base + to_spacemit_gpio_regs(gb)[SPACEMIT_GPSR]; ++ clr = gb->base + to_spacemit_gpio_regs(gb)[SPACEMIT_GPCR]; ++ dirin = gb->base + to_spacemit_gpio_regs(gb)[SPACEMIT_GCDR]; ++ dirout = gb->base + to_spacemit_gpio_regs(gb)[SPACEMIT_GSDR]; + + config = (struct gpio_generic_chip_config) { + .dev = dev, +@@ -206,8 +228,6 @@ static int spacemit_gpio_add_bank(struct + if (ret) + return dev_err_probe(dev, ret, "failed to init gpio chip\n"); + +- gb->sg = sg; +- + gc->label = dev_name(dev); + gc->request = gpiochip_generic_request; + gc->free = gpiochip_generic_free; +@@ -223,13 +243,13 @@ static int spacemit_gpio_add_bank(struct + gpio_irq_chip_set_chip(girq, &spacemit_gpio_chip); + + /* Disable Interrupt */ +- writel(0, gb->base + SPACEMIT_GAPMASK); ++ spacemit_gpio_write(gb, SPACEMIT_GAPMASK, 0); + /* Disable Edge Detection Settings */ +- writel(0x0, gb->base + SPACEMIT_GRER); +- writel(0x0, gb->base + SPACEMIT_GFER); ++ spacemit_gpio_write(gb, SPACEMIT_GRER, 0x0); ++ spacemit_gpio_write(gb, SPACEMIT_GFER, 0x0); + /* Clear Interrupt */ +- writel(0xffffffff, gb->base + SPACEMIT_GCRER); +- writel(0xffffffff, gb->base + SPACEMIT_GCFER); ++ spacemit_gpio_write(gb, SPACEMIT_GCRER, 0xffffffff); ++ spacemit_gpio_write(gb, SPACEMIT_GCFER, 0xffffffff); + + ret = devm_request_threaded_irq(dev, irq, NULL, + spacemit_gpio_irq_handler, +@@ -260,6 +280,10 @@ static int spacemit_gpio_probe(struct pl + if (!sg) + return -ENOMEM; + ++ sg->data = of_device_get_match_data(dev); ++ if (!sg->data) ++ return dev_err_probe(dev, -EINVAL, "No available compatible data."); ++ + regs = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(regs)) + return PTR_ERR(regs); +@@ -287,8 +311,55 @@ static int spacemit_gpio_probe(struct pl + return 0; + } + ++static const unsigned int spacemit_gpio_k1_offsets[] = { ++ [SPACEMIT_GPLR] = 0x00, ++ [SPACEMIT_GPDR] = 0x0c, ++ [SPACEMIT_GPSR] = 0x18, ++ [SPACEMIT_GPCR] = 0x24, ++ [SPACEMIT_GRER] = 0x30, ++ [SPACEMIT_GFER] = 0x3c, ++ [SPACEMIT_GEDR] = 0x48, ++ [SPACEMIT_GSDR] = 0x54, ++ [SPACEMIT_GCDR] = 0x60, ++ [SPACEMIT_GSRER] = 0x6c, ++ [SPACEMIT_GCRER] = 0x78, ++ [SPACEMIT_GSFER] = 0x84, ++ [SPACEMIT_GCFER] = 0x90, ++ [SPACEMIT_GAPMASK] = 0x9c, ++ [SPACEMIT_GCPMASK] = 0xA8, ++}; ++ ++static const unsigned int spacemit_gpio_k3_offsets[] = { ++ [SPACEMIT_GPLR] = 0x0, ++ [SPACEMIT_GPDR] = 0x4, ++ [SPACEMIT_GPSR] = 0x8, ++ [SPACEMIT_GPCR] = 0xc, ++ [SPACEMIT_GRER] = 0x10, ++ [SPACEMIT_GFER] = 0x14, ++ [SPACEMIT_GEDR] = 0x18, ++ [SPACEMIT_GSDR] = 0x1c, ++ [SPACEMIT_GCDR] = 0x20, ++ [SPACEMIT_GSRER] = 0x24, ++ [SPACEMIT_GCRER] = 0x28, ++ [SPACEMIT_GSFER] = 0x2c, ++ [SPACEMIT_GCFER] = 0x30, ++ [SPACEMIT_GAPMASK] = 0x34, ++ [SPACEMIT_GCPMASK] = 0x38, ++}; ++ ++static const struct spacemit_gpio_data k1_gpio_data = { ++ .offsets = spacemit_gpio_k1_offsets, ++ .bank_offsets = { 0x0, 0x4, 0x8, 0x100 }, ++}; ++ ++static const struct spacemit_gpio_data k3_gpio_data = { ++ .offsets = spacemit_gpio_k3_offsets, ++ .bank_offsets = { 0x0, 0x40, 0x80, 0x100 }, ++}; ++ + static const struct of_device_id spacemit_gpio_dt_ids[] = { +- { .compatible = "spacemit,k1-gpio" }, ++ { .compatible = "spacemit,k1-gpio", .data = &k1_gpio_data }, ++ { .compatible = "spacemit,k3-gpio", .data = &k3_gpio_data }, + { /* sentinel */ } + }; + MODULE_DEVICE_TABLE(of, spacemit_gpio_dt_ids); +@@ -296,12 +367,12 @@ MODULE_DEVICE_TABLE(of, spacemit_gpio_dt + static struct platform_driver spacemit_gpio_driver = { + .probe = spacemit_gpio_probe, + .driver = { +- .name = "k1-gpio", ++ .name = "spacemit-gpio", + .of_match_table = spacemit_gpio_dt_ids, + }, + }; + module_platform_driver(spacemit_gpio_driver); + + MODULE_AUTHOR("Yixun Lan "); +-MODULE_DESCRIPTION("GPIO driver for SpacemiT K1 SoC"); ++MODULE_DESCRIPTION("GPIO driver for SpacemiT K1/K3 SoC"); + MODULE_LICENSE("GPL"); diff --git a/target/linux/spacemit/patches-6.18/0042-net-spacemit-Remove-broken-flow-control-support.patch b/target/linux/spacemit/patches-6.18/0042-net-spacemit-Remove-broken-flow-control-support.patch new file mode 100644 index 00000000000000..f450cb6abef66d --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0042-net-spacemit-Remove-broken-flow-control-support.patch @@ -0,0 +1,201 @@ +From 0ecbc5563ea39b1df662d1e817d903da9134bf25 Mon Sep 17 00:00:00 2001 +From: Vivian Wang +Date: Sun, 4 Jan 2026 14:00:04 +0800 +Subject: [PATCH] net: spacemit: Remove broken flow control support + +The current flow control implementation doesn't handle autonegotiation +and ethtool operations properly. Remove it for now so we don't claim +support for something that doesn't really work. A better implementation +will be sent in future patches. + +Signed-off-by: Vivian Wang +Reviewed-by: Andrew Lunn +Link: https://patch.msgid.link/20260104-k1-ethernet-actually-remove-fc-v3-1-3871b055064c@iscas.ac.cn +Signed-off-by: Jakub Kicinski +(cherry picked from commit f66086798f91f095ce377ca4f3d2765e305a842e) +--- + drivers/net/ethernet/spacemit/k1_emac.c | 109 ------------------------ + 1 file changed, 109 deletions(-) + +--- a/drivers/net/ethernet/spacemit/k1_emac.c ++++ b/drivers/net/ethernet/spacemit/k1_emac.c +@@ -47,8 +47,6 @@ + #define EMAC_RX_FRAMES 64 + #define EMAC_RX_COAL_TIMEOUT (600 * 312) + +-#define DEFAULT_FC_PAUSE_TIME 0xffff +-#define DEFAULT_FC_FIFO_HIGH 1600 + #define DEFAULT_TX_ALMOST_FULL 0x1f8 + #define DEFAULT_TX_THRESHOLD 1518 + #define DEFAULT_RX_THRESHOLD 12 +@@ -133,9 +131,6 @@ struct emac_priv { + u32 tx_delay; + u32 rx_delay; + +- bool flow_control_autoneg; +- u8 flow_control; +- + /* Softirq-safe, hold while touching hardware statistics */ + spinlock_t stats_lock; + }; +@@ -180,9 +175,7 @@ static void emac_set_mac_addr_reg(struct + + static void emac_set_mac_addr(struct emac_priv *priv, const unsigned char *addr) + { +- /* We use only one address, so set the same for flow control as well */ + emac_set_mac_addr_reg(priv, addr, MAC_ADDRESS1_HIGH); +- emac_set_mac_addr_reg(priv, addr, MAC_FC_SOURCE_ADDRESS_HIGH); + } + + static void emac_reset_hw(struct emac_priv *priv) +@@ -201,8 +194,6 @@ static void emac_reset_hw(struct emac_pr + + static void emac_init_hw(struct emac_priv *priv) + { +- /* Destination address for 802.3x Ethernet flow control */ +- u8 fc_dest_addr[ETH_ALEN] = { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x01 }; + u32 rxirq = 0, dma = 0, frame_sz; + + regmap_set_bits(priv->regmap_apmu, +@@ -237,12 +228,6 @@ static void emac_init_hw(struct emac_pri + emac_wr(priv, MAC_TRANSMIT_JABBER_SIZE, frame_sz); + emac_wr(priv, MAC_RECEIVE_JABBER_SIZE, frame_sz); + +- /* Configure flow control (enabled in emac_adjust_link() later) */ +- emac_set_mac_addr_reg(priv, fc_dest_addr, MAC_FC_SOURCE_ADDRESS_HIGH); +- emac_wr(priv, MAC_FC_PAUSE_HIGH_THRESHOLD, DEFAULT_FC_FIFO_HIGH); +- emac_wr(priv, MAC_FC_HIGH_PAUSE_TIME, DEFAULT_FC_PAUSE_TIME); +- emac_wr(priv, MAC_FC_PAUSE_LOW_THRESHOLD, 0); +- + /* RX IRQ mitigation */ + rxirq = FIELD_PREP(MREGBIT_RECEIVE_IRQ_FRAME_COUNTER_MASK, + EMAC_RX_FRAMES); +@@ -1034,57 +1019,6 @@ static int emac_mdio_init(struct emac_pr + return ret; + } + +-static void emac_set_tx_fc(struct emac_priv *priv, bool enable) +-{ +- u32 val; +- +- val = emac_rd(priv, MAC_FC_CONTROL); +- +- FIELD_MODIFY(MREGBIT_FC_GENERATION_ENABLE, &val, enable); +- FIELD_MODIFY(MREGBIT_AUTO_FC_GENERATION_ENABLE, &val, enable); +- +- emac_wr(priv, MAC_FC_CONTROL, val); +-} +- +-static void emac_set_rx_fc(struct emac_priv *priv, bool enable) +-{ +- u32 val = emac_rd(priv, MAC_FC_CONTROL); +- +- FIELD_MODIFY(MREGBIT_FC_DECODE_ENABLE, &val, enable); +- +- emac_wr(priv, MAC_FC_CONTROL, val); +-} +- +-static void emac_set_fc(struct emac_priv *priv, u8 fc) +-{ +- emac_set_tx_fc(priv, fc & FLOW_CTRL_TX); +- emac_set_rx_fc(priv, fc & FLOW_CTRL_RX); +- priv->flow_control = fc; +-} +- +-static void emac_set_fc_autoneg(struct emac_priv *priv) +-{ +- struct phy_device *phydev = priv->ndev->phydev; +- u32 local_adv, remote_adv; +- u8 fc; +- +- local_adv = linkmode_adv_to_lcl_adv_t(phydev->advertising); +- +- remote_adv = 0; +- +- if (phydev->pause) +- remote_adv |= LPA_PAUSE_CAP; +- +- if (phydev->asym_pause) +- remote_adv |= LPA_PAUSE_ASYM; +- +- fc = mii_resolve_flowctrl_fdx(local_adv, remote_adv); +- +- priv->flow_control_autoneg = true; +- +- emac_set_fc(priv, fc); +-} +- + /* + * Even though this MAC supports gigabit operation, it only provides 32-bit + * statistics counters. The most overflow-prone counters are the "bytes" ones, +@@ -1455,42 +1389,6 @@ static void emac_ethtool_get_regs(struct + emac_rd(priv, MAC_GLOBAL_CONTROL + i * 4); + } + +-static void emac_get_pauseparam(struct net_device *dev, +- struct ethtool_pauseparam *pause) +-{ +- struct emac_priv *priv = netdev_priv(dev); +- +- pause->autoneg = priv->flow_control_autoneg; +- pause->tx_pause = !!(priv->flow_control & FLOW_CTRL_TX); +- pause->rx_pause = !!(priv->flow_control & FLOW_CTRL_RX); +-} +- +-static int emac_set_pauseparam(struct net_device *dev, +- struct ethtool_pauseparam *pause) +-{ +- struct emac_priv *priv = netdev_priv(dev); +- u8 fc = 0; +- +- if (!netif_running(dev)) +- return -ENETDOWN; +- +- priv->flow_control_autoneg = pause->autoneg; +- +- if (pause->autoneg) { +- emac_set_fc_autoneg(priv); +- } else { +- if (pause->tx_pause) +- fc |= FLOW_CTRL_TX; +- +- if (pause->rx_pause) +- fc |= FLOW_CTRL_RX; +- +- emac_set_fc(priv, fc); +- } +- +- return 0; +-} +- + static void emac_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) + { +@@ -1665,8 +1563,6 @@ static void emac_adjust_link(struct net_ + + emac_wr(priv, MAC_GLOBAL_CONTROL, ctrl); + +- emac_set_fc_autoneg(priv); +- + /* + * Reschedule stats updates now that link is up. See comments in + * emac_stats_update(). +@@ -1751,8 +1647,6 @@ static int emac_phy_connect(struct net_d + goto err_node_put; + } + +- phy_support_asym_pause(phydev); +- + phydev->mac_managed_pm = true; + + emac_update_delay_line(priv); +@@ -1922,9 +1816,6 @@ static const struct ethtool_ops emac_eth + .get_sset_count = emac_get_sset_count, + .get_strings = emac_get_strings, + .get_ethtool_stats = emac_get_ethtool_stats, +- +- .get_pauseparam = emac_get_pauseparam, +- .set_pauseparam = emac_set_pauseparam, + }; + + static const struct net_device_ops emac_netdev_ops = { diff --git a/target/linux/spacemit/patches-6.18/0043-dt-bindings-pinctrl-spacemit-convert-drive-strength-.patch b/target/linux/spacemit/patches-6.18/0043-dt-bindings-pinctrl-spacemit-convert-drive-strength-.patch new file mode 100644 index 00000000000000..fbdaddd66601cc --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0043-dt-bindings-pinctrl-spacemit-convert-drive-strength-.patch @@ -0,0 +1,38 @@ +From fd476d8960fb4da8c3a1da1826eda52fdb2ab3f9 Mon Sep 17 00:00:00 2001 +From: Yixun Lan +Date: Fri, 2 Jan 2026 15:00:22 +0800 +Subject: [PATCH] dt-bindings: pinctrl: spacemit: convert drive strength to + schema format + +In order to better extend the pinctrl support for future new SoC, convert +drive strength setting from free form text to more standard schema format. + +Signed-off-by: Yixun Lan +Reviewed-by: Krzysztof Kozlowski +Signed-off-by: Linus Walleij +(cherry picked from commit c3efac0592f88ab48c8eef028268e6514908be51) +--- + .../bindings/pinctrl/spacemit,k1-pinctrl.yaml | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +--- a/Documentation/devicetree/bindings/pinctrl/spacemit,k1-pinctrl.yaml ++++ b/Documentation/devicetree/bindings/pinctrl/spacemit,k1-pinctrl.yaml +@@ -72,10 +72,14 @@ patternProperties: + enum: [ 0, 1 ] + + drive-strength: +- description: | +- typical current when output high level. +- 1.8V output: 11, 21, 32, 42 (mA) +- 3.3V output: 7, 10, 13, 16, 19, 23, 26, 29 (mA) ++ description: ++ typical current (in mA) when the output at high level. ++ oneOf: ++ - enum: [ 11, 21, 32, 42 ] ++ description: For K1 SoC, 1.8V voltage output ++ ++ - enum: [ 7, 10, 13, 16, 19, 23, 26, 29 ] ++ description: For K1 SoC, 3.3V voltage output + + input-schmitt: + description: | diff --git a/target/linux/spacemit/patches-6.18/0044-pinctrl-spacemit-k3-add-initial-pin-support.patch b/target/linux/spacemit/patches-6.18/0044-pinctrl-spacemit-k3-add-initial-pin-support.patch new file mode 100644 index 00000000000000..cd812c146bf017 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0044-pinctrl-spacemit-k3-add-initial-pin-support.patch @@ -0,0 +1,440 @@ +From 9b68eafad19664b7fd59a694326c82f653de8d10 Mon Sep 17 00:00:00 2001 +From: Yixun Lan +Date: Fri, 2 Jan 2026 15:00:24 +0800 +Subject: [PATCH] pinctrl: spacemit: k3: add initial pin support + +For the pinctrl IP of SpacemiT's K3 SoC, it has different register offset +comparing with previous SoC generation, so introduce a function to do the +pin to offset mapping. Also add all the pinctrl data. + +Signed-off-by: Yixun Lan +Signed-off-by: Linus Walleij +(cherry picked from commit 7412311c4655497b6ab6dd7b802f9390f0f57dc7) +--- + drivers/pinctrl/spacemit/Kconfig | 4 +- + drivers/pinctrl/spacemit/pinctrl-k1.c | 354 +++++++++++++++++++++++++- + 2 files changed, 352 insertions(+), 6 deletions(-) + +--- a/drivers/pinctrl/spacemit/Kconfig ++++ b/drivers/pinctrl/spacemit/Kconfig +@@ -4,7 +4,7 @@ + # + + config PINCTRL_SPACEMIT_K1 +- bool "SpacemiT K1 SoC Pinctrl driver" ++ bool "SpacemiT K1/K3 SoC Pinctrl driver" + depends on ARCH_SPACEMIT || COMPILE_TEST + depends on OF + default ARCH_SPACEMIT +@@ -12,7 +12,7 @@ config PINCTRL_SPACEMIT_K1 + select GENERIC_PINMUX_FUNCTIONS + select GENERIC_PINCONF + help +- Say Y to select the pinctrl driver for K1 SoC. ++ Say Y to select the pinctrl driver for K1/K3 SoC. + This pin controller allows selecting the mux function for + each pin. This driver can also be built as a module called + pinctrl-k1. +--- a/drivers/pinctrl/spacemit/pinctrl-k1.c ++++ b/drivers/pinctrl/spacemit/pinctrl-k1.c +@@ -66,6 +66,7 @@ struct spacemit_pinctrl_data { + const struct pinctrl_pin_desc *pins; + const struct spacemit_pin *data; + u16 npins; ++ unsigned int (*pin_to_offset)(unsigned int pin); + }; + + struct spacemit_pin_mux_config { +@@ -79,7 +80,7 @@ struct spacemit_pin_drv_strength { + }; + + /* map pin id to pinctrl register offset, refer MFPR definition */ +-static unsigned int spacemit_pin_to_offset(unsigned int pin) ++static unsigned int spacemit_k1_pin_to_offset(unsigned int pin) + { + unsigned int offset = 0; + +@@ -124,10 +125,17 @@ static unsigned int spacemit_pin_to_offs + return offset << 2; + } + ++static unsigned int spacemit_k3_pin_to_offset(unsigned int pin) ++{ ++ unsigned int offset = pin > 130 ? (pin + 2) : pin; ++ ++ return offset << 2; ++} ++ + static inline void __iomem *spacemit_pin_to_reg(struct spacemit_pinctrl *pctrl, + unsigned int pin) + { +- return pctrl->regs + spacemit_pin_to_offset(pin); ++ return pctrl->regs + pctrl->data->pin_to_offset(pin); + } + + static u16 spacemit_dt_get_pin(u32 value) +@@ -177,7 +185,7 @@ static void spacemit_pctrl_dbg_show(stru + void __iomem *reg; + u32 value; + +- seq_printf(seq, "offset: 0x%04x ", spacemit_pin_to_offset(pin)); ++ seq_printf(seq, "offset: 0x%04x ", pctrl->data->pin_to_offset(pin)); + seq_printf(seq, "type: %s ", io_type_desc[type]); + + reg = spacemit_pin_to_reg(pctrl, pin); +@@ -1042,10 +1050,348 @@ static const struct spacemit_pinctrl_dat + .pins = k1_pin_desc, + .data = k1_pin_data, + .npins = ARRAY_SIZE(k1_pin_desc), ++ .pin_to_offset = spacemit_k1_pin_to_offset, ++}; ++ ++static const struct pinctrl_pin_desc k3_pin_desc[] = { ++ PINCTRL_PIN(0, "GPIO_00"), ++ PINCTRL_PIN(1, "GPIO_01"), ++ PINCTRL_PIN(2, "GPIO_02"), ++ PINCTRL_PIN(3, "GPIO_03"), ++ PINCTRL_PIN(4, "GPIO_04"), ++ PINCTRL_PIN(5, "GPIO_05"), ++ PINCTRL_PIN(6, "GPIO_06"), ++ PINCTRL_PIN(7, "GPIO_07"), ++ PINCTRL_PIN(8, "GPIO_08"), ++ PINCTRL_PIN(9, "GPIO_09"), ++ PINCTRL_PIN(10, "GPIO_10"), ++ PINCTRL_PIN(11, "GPIO_11"), ++ PINCTRL_PIN(12, "GPIO_12"), ++ PINCTRL_PIN(13, "GPIO_13"), ++ PINCTRL_PIN(14, "GPIO_14"), ++ PINCTRL_PIN(15, "GPIO_15"), ++ PINCTRL_PIN(16, "GPIO_16"), ++ PINCTRL_PIN(17, "GPIO_17"), ++ PINCTRL_PIN(18, "GPIO_18"), ++ PINCTRL_PIN(19, "GPIO_19"), ++ PINCTRL_PIN(20, "GPIO_20"), ++ PINCTRL_PIN(21, "GPIO_21"), ++ PINCTRL_PIN(22, "GPIO_22"), ++ PINCTRL_PIN(23, "GPIO_23"), ++ PINCTRL_PIN(24, "GPIO_24"), ++ PINCTRL_PIN(25, "GPIO_25"), ++ PINCTRL_PIN(26, "GPIO_26"), ++ PINCTRL_PIN(27, "GPIO_27"), ++ PINCTRL_PIN(28, "GPIO_28"), ++ PINCTRL_PIN(29, "GPIO_29"), ++ PINCTRL_PIN(30, "GPIO_30"), ++ PINCTRL_PIN(31, "GPIO_31"), ++ PINCTRL_PIN(32, "GPIO_32"), ++ PINCTRL_PIN(33, "GPIO_33"), ++ PINCTRL_PIN(34, "GPIO_34"), ++ PINCTRL_PIN(35, "GPIO_35"), ++ PINCTRL_PIN(36, "GPIO_36"), ++ PINCTRL_PIN(37, "GPIO_37"), ++ PINCTRL_PIN(38, "GPIO_38"), ++ PINCTRL_PIN(39, "GPIO_39"), ++ PINCTRL_PIN(40, "GPIO_40"), ++ PINCTRL_PIN(41, "GPIO_41"), ++ PINCTRL_PIN(42, "GPIO_42"), ++ PINCTRL_PIN(43, "GPIO_43"), ++ PINCTRL_PIN(44, "GPIO_44"), ++ PINCTRL_PIN(45, "GPIO_45"), ++ PINCTRL_PIN(46, "GPIO_46"), ++ PINCTRL_PIN(47, "GPIO_47"), ++ PINCTRL_PIN(48, "GPIO_48"), ++ PINCTRL_PIN(49, "GPIO_49"), ++ PINCTRL_PIN(50, "GPIO_50"), ++ PINCTRL_PIN(51, "GPIO_51"), ++ PINCTRL_PIN(52, "GPIO_52"), ++ PINCTRL_PIN(53, "GPIO_53"), ++ PINCTRL_PIN(54, "GPIO_54"), ++ PINCTRL_PIN(55, "GPIO_55"), ++ PINCTRL_PIN(56, "GPIO_56"), ++ PINCTRL_PIN(57, "GPIO_57"), ++ PINCTRL_PIN(58, "GPIO_58"), ++ PINCTRL_PIN(59, "GPIO_59"), ++ PINCTRL_PIN(60, "GPIO_60"), ++ PINCTRL_PIN(61, "GPIO_61"), ++ PINCTRL_PIN(62, "GPIO_62"), ++ PINCTRL_PIN(63, "GPIO_63"), ++ PINCTRL_PIN(64, "GPIO_64"), ++ PINCTRL_PIN(65, "GPIO_65"), ++ PINCTRL_PIN(66, "GPIO_66"), ++ PINCTRL_PIN(67, "GPIO_67"), ++ PINCTRL_PIN(68, "GPIO_68"), ++ PINCTRL_PIN(69, "GPIO_69"), ++ PINCTRL_PIN(70, "GPIO_70"), ++ PINCTRL_PIN(71, "GPIO_71"), ++ PINCTRL_PIN(72, "GPIO_72"), ++ PINCTRL_PIN(73, "GPIO_73"), ++ PINCTRL_PIN(74, "GPIO_74"), ++ PINCTRL_PIN(75, "GPIO_75"), ++ PINCTRL_PIN(76, "GPIO_76"), ++ PINCTRL_PIN(77, "GPIO_77"), ++ PINCTRL_PIN(78, "GPIO_78"), ++ PINCTRL_PIN(79, "GPIO_79"), ++ PINCTRL_PIN(80, "GPIO_80"), ++ PINCTRL_PIN(81, "GPIO_81"), ++ PINCTRL_PIN(82, "GPIO_82"), ++ PINCTRL_PIN(83, "GPIO_83"), ++ PINCTRL_PIN(84, "GPIO_84"), ++ PINCTRL_PIN(85, "GPIO_85"), ++ PINCTRL_PIN(86, "GPIO_86"), ++ PINCTRL_PIN(87, "GPIO_87"), ++ PINCTRL_PIN(88, "GPIO_88"), ++ PINCTRL_PIN(89, "GPIO_89"), ++ PINCTRL_PIN(90, "GPIO_90"), ++ PINCTRL_PIN(91, "GPIO_91"), ++ PINCTRL_PIN(92, "GPIO_92"), ++ PINCTRL_PIN(93, "GPIO_93"), ++ PINCTRL_PIN(94, "GPIO_94"), ++ PINCTRL_PIN(95, "GPIO_95"), ++ PINCTRL_PIN(96, "GPIO_96"), ++ PINCTRL_PIN(97, "GPIO_97"), ++ PINCTRL_PIN(98, "GPIO_98"), ++ PINCTRL_PIN(99, "GPIO_99"), ++ PINCTRL_PIN(100, "GPIO_100"), ++ PINCTRL_PIN(101, "GPIO_101"), ++ PINCTRL_PIN(102, "GPIO_102"), ++ PINCTRL_PIN(103, "GPIO_103"), ++ PINCTRL_PIN(104, "GPIO_104"), ++ PINCTRL_PIN(105, "GPIO_105"), ++ PINCTRL_PIN(106, "GPIO_106"), ++ PINCTRL_PIN(107, "GPIO_107"), ++ PINCTRL_PIN(108, "GPIO_108"), ++ PINCTRL_PIN(109, "GPIO_109"), ++ PINCTRL_PIN(110, "GPIO_110"), ++ PINCTRL_PIN(111, "GPIO_111"), ++ PINCTRL_PIN(112, "GPIO_112"), ++ PINCTRL_PIN(113, "GPIO_113"), ++ PINCTRL_PIN(114, "GPIO_114"), ++ PINCTRL_PIN(115, "GPIO_115"), ++ PINCTRL_PIN(116, "GPIO_116"), ++ PINCTRL_PIN(117, "GPIO_117"), ++ PINCTRL_PIN(118, "GPIO_118"), ++ PINCTRL_PIN(119, "GPIO_119"), ++ PINCTRL_PIN(120, "GPIO_120"), ++ PINCTRL_PIN(121, "GPIO_121"), ++ PINCTRL_PIN(122, "GPIO_122"), ++ PINCTRL_PIN(123, "GPIO_123"), ++ PINCTRL_PIN(124, "GPIO_124"), ++ PINCTRL_PIN(125, "GPIO_125"), ++ PINCTRL_PIN(126, "GPIO_126"), ++ PINCTRL_PIN(127, "GPIO_127"), ++ PINCTRL_PIN(128, "PWR_SCL"), ++ PINCTRL_PIN(129, "PWR_SDA"), ++ PINCTRL_PIN(130, "VCXO_EN"), ++ PINCTRL_PIN(131, "PMIC_INT_N"), ++ PINCTRL_PIN(132, "MMC1_DAT3"), ++ PINCTRL_PIN(133, "MMC1_DAT2"), ++ PINCTRL_PIN(134, "MMC1_DAT1"), ++ PINCTRL_PIN(135, "MMC1_DAT0"), ++ PINCTRL_PIN(136, "MMC1_CMD"), ++ PINCTRL_PIN(137, "MMC1_CLK"), ++ PINCTRL_PIN(138, "QSPI_DAT0"), ++ PINCTRL_PIN(139, "QSPI_DAT1"), ++ PINCTRL_PIN(140, "QSPI_DAT2"), ++ PINCTRL_PIN(141, "QSPI_DAT3"), ++ PINCTRL_PIN(142, "QSPI_CS0"), ++ PINCTRL_PIN(143, "QSPI_CS1"), ++ PINCTRL_PIN(144, "QSPI_CLK"), ++ PINCTRL_PIN(145, "PRI_TDI"), ++ PINCTRL_PIN(146, "PRI_TMS"), ++ PINCTRL_PIN(147, "PRI_TCK"), ++ PINCTRL_PIN(148, "PRI_TDO"), ++ PINCTRL_PIN(149, "PWR_SSP_SCLK"), ++ PINCTRL_PIN(150, "PWR_SSP_FRM"), ++ PINCTRL_PIN(151, "PWR_SSP_TXD"), ++ PINCTRL_PIN(152, "PWR_SSP_RXD"), ++}; ++ ++static const struct spacemit_pin k3_pin_data[ARRAY_SIZE(k3_pin_desc)] = { ++ /* GPIO1 bank */ ++ K1_FUNC_PIN(0, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(1, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(2, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(3, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(4, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(5, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(6, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(7, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(8, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(9, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(10, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(11, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(12, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(13, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(14, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(15, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(16, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(17, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(18, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(19, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(20, 0, IO_TYPE_EXTERNAL), ++ ++ /* GPIO2 bank */ ++ K1_FUNC_PIN(21, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(22, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(23, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(24, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(25, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(26, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(27, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(28, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(29, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(30, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(31, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(32, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(33, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(34, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(35, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(36, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(37, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(38, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(39, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(40, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(41, 0, IO_TYPE_EXTERNAL), ++ ++ /* GPIO3 bank */ ++ K1_FUNC_PIN(42, 0, IO_TYPE_1V8), ++ K1_FUNC_PIN(43, 0, IO_TYPE_1V8), ++ K1_FUNC_PIN(44, 0, IO_TYPE_1V8), ++ K1_FUNC_PIN(45, 0, IO_TYPE_1V8), ++ K1_FUNC_PIN(46, 0, IO_TYPE_1V8), ++ K1_FUNC_PIN(47, 0, IO_TYPE_1V8), ++ K1_FUNC_PIN(48, 0, IO_TYPE_1V8), ++ K1_FUNC_PIN(49, 0, IO_TYPE_1V8), ++ K1_FUNC_PIN(50, 0, IO_TYPE_1V8), ++ K1_FUNC_PIN(51, 0, IO_TYPE_1V8), ++ K1_FUNC_PIN(52, 0, IO_TYPE_1V8), ++ K1_FUNC_PIN(53, 0, IO_TYPE_1V8), ++ K1_FUNC_PIN(54, 0, IO_TYPE_1V8), ++ K1_FUNC_PIN(55, 0, IO_TYPE_1V8), ++ K1_FUNC_PIN(56, 0, IO_TYPE_1V8), ++ K1_FUNC_PIN(57, 0, IO_TYPE_1V8), ++ K1_FUNC_PIN(58, 0, IO_TYPE_1V8), ++ K1_FUNC_PIN(59, 0, IO_TYPE_1V8), ++ K1_FUNC_PIN(60, 0, IO_TYPE_1V8), ++ K1_FUNC_PIN(61, 0, IO_TYPE_1V8), ++ K1_FUNC_PIN(62, 0, IO_TYPE_1V8), ++ K1_FUNC_PIN(63, 0, IO_TYPE_1V8), ++ K1_FUNC_PIN(64, 0, IO_TYPE_1V8), ++ K1_FUNC_PIN(65, 0, IO_TYPE_1V8), ++ K1_FUNC_PIN(66, 0, IO_TYPE_1V8), ++ K1_FUNC_PIN(67, 0, IO_TYPE_1V8), ++ K1_FUNC_PIN(68, 0, IO_TYPE_1V8), ++ K1_FUNC_PIN(69, 0, IO_TYPE_1V8), ++ K1_FUNC_PIN(70, 0, IO_TYPE_1V8), ++ K1_FUNC_PIN(71, 0, IO_TYPE_1V8), ++ K1_FUNC_PIN(72, 0, IO_TYPE_1V8), ++ K1_FUNC_PIN(73, 0, IO_TYPE_1V8), ++ K1_FUNC_PIN(74, 0, IO_TYPE_1V8), ++ K1_FUNC_PIN(75, 0, IO_TYPE_1V8), ++ ++ /* GPIO4 bank */ ++ K1_FUNC_PIN(76, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(77, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(78, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(79, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(80, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(81, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(82, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(83, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(84, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(85, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(86, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(87, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(88, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(89, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(90, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(91, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(92, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(93, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(94, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(95, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(96, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(97, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(98, 0, IO_TYPE_EXTERNAL), ++ ++ /* GPIO5 bank */ ++ K1_FUNC_PIN(99, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(100, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(101, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(102, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(103, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(104, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(105, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(106, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(107, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(108, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(109, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(110, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(111, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(112, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(113, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(114, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(115, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(116, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(117, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(118, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(119, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(120, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(121, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(122, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(123, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(124, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(125, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(126, 0, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(127, 0, IO_TYPE_EXTERNAL), ++ ++ /* PMIC */ ++ K1_FUNC_PIN(128, 0, IO_TYPE_1V8), ++ K1_FUNC_PIN(129, 0, IO_TYPE_1V8), ++ K1_FUNC_PIN(130, 0, IO_TYPE_1V8), ++ K1_FUNC_PIN(131, 0, IO_TYPE_1V8), ++ ++ /* SD/MMC1 */ ++ K1_FUNC_PIN(132, 1, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(133, 1, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(134, 1, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(135, 1, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(136, 1, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(137, 1, IO_TYPE_EXTERNAL), ++ ++ /* QSPI */ ++ K1_FUNC_PIN(138, 1, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(139, 1, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(140, 1, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(141, 1, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(142, 1, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(143, 1, IO_TYPE_EXTERNAL), ++ K1_FUNC_PIN(144, 1, IO_TYPE_EXTERNAL), ++ ++ /* PMIC */ ++ K1_FUNC_PIN(145, 1, IO_TYPE_1V8), ++ K1_FUNC_PIN(146, 1, IO_TYPE_1V8), ++ K1_FUNC_PIN(147, 1, IO_TYPE_1V8), ++ K1_FUNC_PIN(148, 1, IO_TYPE_1V8), ++ K1_FUNC_PIN(149, 1, IO_TYPE_1V8), ++ K1_FUNC_PIN(150, 1, IO_TYPE_1V8), ++ K1_FUNC_PIN(151, 1, IO_TYPE_1V8), ++ K1_FUNC_PIN(152, 1, IO_TYPE_1V8), ++}; ++ ++static const struct spacemit_pinctrl_data k3_pinctrl_data = { ++ .pins = k3_pin_desc, ++ .data = k3_pin_data, ++ .npins = ARRAY_SIZE(k3_pin_desc), ++ .pin_to_offset = spacemit_k3_pin_to_offset, + }; + + static const struct of_device_id k1_pinctrl_ids[] = { + { .compatible = "spacemit,k1-pinctrl", .data = &k1_pinctrl_data }, ++ { .compatible = "spacemit,k3-pinctrl", .data = &k3_pinctrl_data }, + { /* sentinel */ } + }; + MODULE_DEVICE_TABLE(of, k1_pinctrl_ids); +@@ -1061,5 +1407,5 @@ static struct platform_driver k1_pinctrl + builtin_platform_driver(k1_pinctrl_driver); + + MODULE_AUTHOR("Yixun Lan "); +-MODULE_DESCRIPTION("Pinctrl driver for the SpacemiT K1 SoC"); ++MODULE_DESCRIPTION("Pinctrl driver for the SpacemiT K1/K3 SoC"); + MODULE_LICENSE("GPL"); diff --git a/target/linux/spacemit/patches-6.18/0045-pinctrl-spacemit-k3-adjust-drive-strength-and-schmit.patch b/target/linux/spacemit/patches-6.18/0045-pinctrl-spacemit-k3-adjust-drive-strength-and-schmit.patch new file mode 100644 index 00000000000000..9c073489039595 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0045-pinctrl-spacemit-k3-adjust-drive-strength-and-schmit.patch @@ -0,0 +1,319 @@ +From c43fcf1561ebb5dfa07e55e21fe224b5124cfe58 Mon Sep 17 00:00:00 2001 +From: Yixun Lan +Date: Fri, 2 Jan 2026 15:00:25 +0800 +Subject: [PATCH] pinctrl: spacemit: k3: adjust drive strength and schmitter + trigger + +K3 SoC expand drive strength to 4 bits which support even larger +settings table comparing to old SoC generation. Also schmitter trigger +setting is changed to 1 bit. + +Signed-off-by: Yixun Lan +Signed-off-by: Linus Walleij +(cherry picked from commit 3f20bdf7151834547a85231c28538f49601481ee) +--- + drivers/pinctrl/spacemit/pinctrl-k1.c | 163 ++++++++++++++++++-------- + 1 file changed, 116 insertions(+), 47 deletions(-) + +--- a/drivers/pinctrl/spacemit/pinctrl-k1.c ++++ b/drivers/pinctrl/spacemit/pinctrl-k1.c +@@ -24,11 +24,12 @@ + #include "pinctrl-k1.h" + + /* +- * +---------+----------+-----------+--------+--------+----------+--------+ +- * | pull | drive | schmitter | slew | edge | strong | mux | +- * | up/down | strength | trigger | rate | detect | pull | mode | +- * +---------+----------+-----------+--------+--------+----------+--------+ +- * 3 bits 3 bits 2 bits 1 bit 3 bits 1 bit 3 bits ++ * | pull | drive | schmitter | slew | edge | strong | mux | ++ * SoC | up/down | strength | trigger | rate | detect | pull | mode | ++ *-----+---------+----------+-----------+-------+--------+--------+--------+ ++ * K1 | 3 bits | 3 bits | 2 bits | 1 bit | 3 bits | 1 bit | 3 bits | ++ *-----+---------+----------+-----------+-------+--------+--------+--------+ ++ * K3 | 3 bits | 4 bits | 1 bits | 1 bit | 3 bits | 1 bit | 3 bits | + */ + + #define PAD_MUX GENMASK(2, 0) +@@ -38,12 +39,29 @@ + #define PAD_EDGE_CLEAR BIT(6) + #define PAD_SLEW_RATE GENMASK(12, 11) + #define PAD_SLEW_RATE_EN BIT(7) +-#define PAD_SCHMITT GENMASK(9, 8) +-#define PAD_DRIVE GENMASK(12, 10) ++#define PAD_SCHMITT_K1 GENMASK(9, 8) ++#define PAD_DRIVE_K1 GENMASK(12, 10) ++#define PAD_SCHMITT_K3 BIT(8) ++#define PAD_DRIVE_K3 GENMASK(12, 9) + #define PAD_PULLDOWN BIT(13) + #define PAD_PULLUP BIT(14) + #define PAD_PULL_EN BIT(15) + ++struct spacemit_pin_drv_strength { ++ u8 val; ++ u32 mA; ++}; ++ ++struct spacemit_pinctrl_dconf { ++ u64 schmitt_mask; ++ u64 drive_mask; ++ ++ struct spacemit_pin_drv_strength *ds_1v8_tbl; ++ size_t ds_1v8_tbl_num; ++ struct spacemit_pin_drv_strength *ds_3v3_tbl; ++ size_t ds_3v3_tbl_num; ++}; ++ + struct spacemit_pin { + u16 pin; + u16 flags; +@@ -67,6 +85,7 @@ struct spacemit_pinctrl_data { + const struct spacemit_pin *data; + u16 npins; + unsigned int (*pin_to_offset)(unsigned int pin); ++ const struct spacemit_pinctrl_dconf *dconf; + }; + + struct spacemit_pin_mux_config { +@@ -74,11 +93,6 @@ struct spacemit_pin_mux_config { + u32 config; + }; + +-struct spacemit_pin_drv_strength { +- u8 val; +- u32 mA; +-}; +- + /* map pin id to pinctrl register offset, refer MFPR definition */ + static unsigned int spacemit_k1_pin_to_offset(unsigned int pin) + { +@@ -193,23 +207,70 @@ static void spacemit_pctrl_dbg_show(stru + seq_printf(seq, "mux: %ld reg: 0x%04x", (value & PAD_MUX), value); + } + +-/* use IO high level output current as the table */ +-static struct spacemit_pin_drv_strength spacemit_ds_1v8_tbl[4] = { +- { 0, 11 }, +- { 2, 21 }, +- { 4, 32 }, +- { 6, 42 }, ++static const struct spacemit_pinctrl_dconf k1_drive_conf = { ++ .drive_mask = PAD_DRIVE_K1, ++ .schmitt_mask = PAD_SCHMITT_K1, ++ .ds_1v8_tbl = (struct spacemit_pin_drv_strength[]) { ++ { 0, 11 }, ++ { 2, 21 }, ++ { 4, 32 }, ++ { 6, 42 }, ++ }, ++ .ds_1v8_tbl_num = 4, ++ .ds_3v3_tbl = (struct spacemit_pin_drv_strength[]) { ++ { 0, 7 }, ++ { 2, 10 }, ++ { 4, 13 }, ++ { 6, 16 }, ++ { 1, 19 }, ++ { 3, 23 }, ++ { 5, 26 }, ++ { 7, 29 }, ++ }, ++ .ds_3v3_tbl_num = 8, + }; + +-static struct spacemit_pin_drv_strength spacemit_ds_3v3_tbl[8] = { +- { 0, 7 }, +- { 2, 10 }, +- { 4, 13 }, +- { 6, 16 }, +- { 1, 19 }, +- { 3, 23 }, +- { 5, 26 }, +- { 7, 29 }, ++static const struct spacemit_pinctrl_dconf k3_drive_conf = { ++ .drive_mask = PAD_DRIVE_K3, ++ .schmitt_mask = PAD_SCHMITT_K3, ++ .ds_1v8_tbl = (struct spacemit_pin_drv_strength[]) { ++ { 0, 2 }, ++ { 1, 4 }, ++ { 2, 6 }, ++ { 3, 7 }, ++ { 4, 9 }, ++ { 5, 11 }, ++ { 6, 13 }, ++ { 7, 14 }, ++ { 8, 21 }, ++ { 9, 23 }, ++ { 10, 25 }, ++ { 11, 26 }, ++ { 12, 28 }, ++ { 13, 30 }, ++ { 14, 31 }, ++ { 15, 33 }, ++ }, ++ .ds_1v8_tbl_num = 16, ++ .ds_3v3_tbl = (struct spacemit_pin_drv_strength[]) { ++ { 0, 3 }, ++ { 1, 5 }, ++ { 2, 7 }, ++ { 3, 9 }, ++ { 4, 11 }, ++ { 5, 13 }, ++ { 6, 15 }, ++ { 7, 17 }, ++ { 8, 25 }, ++ { 9, 27 }, ++ { 10, 29 }, ++ { 11, 31 }, ++ { 12, 33 }, ++ { 13, 35 }, ++ { 14, 37 }, ++ { 15, 38 }, ++ }, ++ .ds_3v3_tbl_num = 16, + }; + + static inline u8 spacemit_get_ds_value(struct spacemit_pin_drv_strength *tbl, +@@ -237,16 +298,17 @@ static inline u32 spacemit_get_ds_mA(str + } + + static inline u8 spacemit_get_driver_strength(enum spacemit_pin_io_type type, ++ const struct spacemit_pinctrl_dconf *dconf, + u32 mA) + { + switch (type) { + case IO_TYPE_1V8: +- return spacemit_get_ds_value(spacemit_ds_1v8_tbl, +- ARRAY_SIZE(spacemit_ds_1v8_tbl), ++ return spacemit_get_ds_value(dconf->ds_1v8_tbl, ++ dconf->ds_1v8_tbl_num, + mA); + case IO_TYPE_3V3: +- return spacemit_get_ds_value(spacemit_ds_3v3_tbl, +- ARRAY_SIZE(spacemit_ds_3v3_tbl), ++ return spacemit_get_ds_value(dconf->ds_3v3_tbl, ++ dconf->ds_3v3_tbl_num, + mA); + default: + return 0; +@@ -254,16 +316,17 @@ static inline u8 spacemit_get_driver_str + } + + static inline u32 spacemit_get_drive_strength_mA(enum spacemit_pin_io_type type, ++ const struct spacemit_pinctrl_dconf *dconf, + u32 value) + { + switch (type) { + case IO_TYPE_1V8: +- return spacemit_get_ds_mA(spacemit_ds_1v8_tbl, +- ARRAY_SIZE(spacemit_ds_1v8_tbl), +- value & 0x6); ++ return spacemit_get_ds_mA(dconf->ds_1v8_tbl, ++ dconf->ds_1v8_tbl_num, ++ value); + case IO_TYPE_3V3: +- return spacemit_get_ds_mA(spacemit_ds_3v3_tbl, +- ARRAY_SIZE(spacemit_ds_3v3_tbl), ++ return spacemit_get_ds_mA(dconf->ds_3v3_tbl, ++ dconf->ds_3v3_tbl_num, + value); + default: + return 0; +@@ -510,6 +573,7 @@ static int spacemit_pinconf_get(struct p + #define ENABLE_DRV_STRENGTH BIT(1) + #define ENABLE_SLEW_RATE BIT(2) + static int spacemit_pinconf_generate_config(const struct spacemit_pin *spin, ++ const struct spacemit_pinctrl_dconf *dconf, + unsigned long *configs, + unsigned int num_configs, + u32 *value) +@@ -547,8 +611,8 @@ static int spacemit_pinconf_generate_con + drv_strength = arg; + break; + case PIN_CONFIG_INPUT_SCHMITT: +- v &= ~PAD_SCHMITT; +- v |= FIELD_PREP(PAD_SCHMITT, arg); ++ v &= ~dconf->schmitt_mask; ++ v |= (arg << __ffs(dconf->schmitt_mask)) & dconf->schmitt_mask; + break; + case PIN_CONFIG_POWER_SOURCE: + voltage = arg; +@@ -584,10 +648,10 @@ static int spacemit_pinconf_generate_con + } + } + +- val = spacemit_get_driver_strength(type, drv_strength); ++ val = spacemit_get_driver_strength(type, dconf, drv_strength); + +- v &= ~PAD_DRIVE; +- v |= FIELD_PREP(PAD_DRIVE, val); ++ v &= ~dconf->drive_mask; ++ v |= (val << __ffs(dconf->drive_mask)) & dconf->drive_mask; + } + + if (flag & ENABLE_SLEW_RATE) { +@@ -637,7 +701,8 @@ static int spacemit_pinconf_set(struct p + const struct spacemit_pin *spin = spacemit_get_pin(pctrl, pin); + u32 value; + +- if (spacemit_pinconf_generate_config(spin, configs, num_configs, &value)) ++ if (spacemit_pinconf_generate_config(spin, pctrl->data->dconf, ++ configs, num_configs, &value)) + return -EINVAL; + + return spacemit_pin_set_config(pctrl, pin, value); +@@ -659,7 +724,8 @@ static int spacemit_pinconf_group_set(st + return -EINVAL; + + spin = spacemit_get_pin(pctrl, group->grp.pins[0]); +- if (spacemit_pinconf_generate_config(spin, configs, num_configs, &value)) ++ if (spacemit_pinconf_generate_config(spin, pctrl->data->dconf, ++ configs, num_configs, &value)) + return -EINVAL; + + for (i = 0; i < group->grp.npins; i++) +@@ -693,6 +759,7 @@ static void spacemit_pinconf_dbg_show(st + struct seq_file *seq, unsigned int pin) + { + struct spacemit_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); ++ const struct spacemit_pinctrl_dconf *dconf = pctrl->data->dconf; + const struct spacemit_pin *spin = spacemit_get_pin(pctrl, pin); + enum spacemit_pin_io_type type = spacemit_to_pin_io_type(spin); + void __iomem *reg = spacemit_pin_to_reg(pctrl, pin); +@@ -703,17 +770,17 @@ static void spacemit_pinconf_dbg_show(st + + seq_printf(seq, ", io type (%s)", io_type_desc[type]); + +- tmp = FIELD_GET(PAD_DRIVE, value); ++ tmp = (value & dconf->drive_mask) >> __ffs(dconf->drive_mask); + if (type == IO_TYPE_1V8 || type == IO_TYPE_3V3) { +- mA = spacemit_get_drive_strength_mA(type, tmp); ++ mA = spacemit_get_drive_strength_mA(type, dconf, tmp); + seq_printf(seq, ", drive strength (%d mA)", mA); + } + + /* drive strength depend on power source, so show all values */ + if (type == IO_TYPE_EXTERNAL) + seq_printf(seq, ", drive strength (%d or %d mA)", +- spacemit_get_drive_strength_mA(IO_TYPE_1V8, tmp), +- spacemit_get_drive_strength_mA(IO_TYPE_3V3, tmp)); ++ spacemit_get_drive_strength_mA(IO_TYPE_1V8, dconf, tmp), ++ spacemit_get_drive_strength_mA(IO_TYPE_3V3, dconf, tmp)); + + seq_printf(seq, ", register (0x%04x)", value); + } +@@ -1051,6 +1118,7 @@ static const struct spacemit_pinctrl_dat + .data = k1_pin_data, + .npins = ARRAY_SIZE(k1_pin_desc), + .pin_to_offset = spacemit_k1_pin_to_offset, ++ .dconf = &k1_drive_conf, + }; + + static const struct pinctrl_pin_desc k3_pin_desc[] = { +@@ -1387,6 +1455,7 @@ static const struct spacemit_pinctrl_dat + .data = k3_pin_data, + .npins = ARRAY_SIZE(k3_pin_desc), + .pin_to_offset = spacemit_k3_pin_to_offset, ++ .dconf = &k3_drive_conf, + }; + + static const struct of_device_id k1_pinctrl_ids[] = { diff --git a/target/linux/spacemit/patches-6.18/0046-dt-bindings-i2c-spacemit-add-optional-resets.patch b/target/linux/spacemit/patches-6.18/0046-dt-bindings-i2c-spacemit-add-optional-resets.patch new file mode 100644 index 00000000000000..1d84f46a87b0cb --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0046-dt-bindings-i2c-spacemit-add-optional-resets.patch @@ -0,0 +1,31 @@ +From 51c03ee30147ab5bb006a4ac1567b54f844f2a75 Mon Sep 17 00:00:00 2001 +From: Encrow Thorne +Date: Tue, 30 Dec 2025 23:06:51 +0800 +Subject: [PATCH] dt-bindings: i2c: spacemit: add optional resets + +The I2C controller requires a reset to ensure it starts from a clean state. + +Add the 'resets' property to support this hardware requirement. + +Signed-off-by: Encrow Thorne +Reviewed-by: Troy Mitchell +Acked-by: Rob Herring (Arm) +Signed-off-by: Andi Shyti +Link: https://lore.kernel.org/r/20251230150653.42097-1-jyc0019@gmail.com +(cherry picked from commit ad0876a84631fee7b0ad4cd8118b9696aa566671) +--- + Documentation/devicetree/bindings/i2c/spacemit,k1-i2c.yaml | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/Documentation/devicetree/bindings/i2c/spacemit,k1-i2c.yaml ++++ b/Documentation/devicetree/bindings/i2c/spacemit,k1-i2c.yaml +@@ -41,6 +41,9 @@ properties: + default: 400000 + maximum: 3300000 + ++ resets: ++ maxItems: 1 ++ + required: + - compatible + - reg diff --git a/target/linux/spacemit/patches-6.18/0047-i2c-k1-add-reset-support.patch b/target/linux/spacemit/patches-6.18/0047-i2c-k1-add-reset-support.patch new file mode 100644 index 00000000000000..c6c10ff929b6bb --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0047-i2c-k1-add-reset-support.patch @@ -0,0 +1,50 @@ +From 498f122e1ccba999d60514536504de4ec1f00feb Mon Sep 17 00:00:00 2001 +From: Encrow Thorne +Date: Tue, 30 Dec 2025 23:06:52 +0800 +Subject: [PATCH] i2c: k1: add reset support + +The K1 I2C controller provides a reset line that needs to be deasserted +before the controller can be accessed. + +Add reset support to the driver to ensure the controller starts in the +required state. + +Signed-off-by: Encrow Thorne +Reviewed-by: Troy Mitchell +Signed-off-by: Andi Shyti +Link: https://lore.kernel.org/r/20251230150653.42097-2-jyc0019@gmail.com +(cherry picked from commit b96259551b337225bb0e7afb3452b98435dd8b81) +--- + drivers/i2c/busses/i2c-k1.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/drivers/i2c/busses/i2c-k1.c ++++ b/drivers/i2c/busses/i2c-k1.c +@@ -10,6 +10,7 @@ + #include + #include + #include ++ #include + + /* spacemit i2c registers */ + #define SPACEMIT_ICR 0x0 /* Control register */ +@@ -534,6 +535,7 @@ static int spacemit_i2c_probe(struct pla + struct device *dev = &pdev->dev; + struct device_node *of_node = pdev->dev.of_node; + struct spacemit_i2c_dev *i2c; ++ struct reset_control *rst; + int ret; + + i2c = devm_kzalloc(dev, sizeof(*i2c), GFP_KERNEL); +@@ -578,6 +580,11 @@ static int spacemit_i2c_probe(struct pla + if (IS_ERR(clk)) + return dev_err_probe(dev, PTR_ERR(clk), "failed to enable bus clock"); + ++ rst = devm_reset_control_get_optional_exclusive_deasserted(dev, NULL); ++ if (IS_ERR(rst)) ++ return dev_err_probe(dev, PTR_ERR(rst), ++ "failed to acquire deasserted reset\n"); ++ + spacemit_i2c_reset(i2c); + + i2c_set_adapdata(&i2c->adapt, i2c); diff --git a/target/linux/spacemit/patches-6.18/0048-mfd-syscon-Return-EPROBE_DEFER-if-the-syscon-is-not-.patch b/target/linux/spacemit/patches-6.18/0048-mfd-syscon-Return-EPROBE_DEFER-if-the-syscon-is-not-.patch new file mode 100644 index 00000000000000..f1ff0d622c0d89 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0048-mfd-syscon-Return-EPROBE_DEFER-if-the-syscon-is-not-.patch @@ -0,0 +1,32 @@ +From aa81ed81c5f001a4d4755a75364a8e98ffecc1b9 Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Sun, 2 Nov 2025 14:59:22 +0300 +Subject: [PATCH] mfd: syscon: Return -EPROBE_DEFER if the syscon is not found + +These days we can register syscons with of_syscon_register_regmap() so +when we can't find the syscon that probably means it hasn't been +registered yet. Return -EPROBE_DEFER so the driver will try probing +again. + +Signed-off-by: Dan Carpenter +Reviewed-by: Arnd Bergmann +Reviewed-by: Chen-Yu Tsai +Acked-by: Rob Herring (Arm) +Link: https://patch.msgid.link/aQdHmrchkmOr34r3@stanley.mountain +Signed-off-by: Lee Jones +(cherry picked from commit b73d5593bfde6bf570d55bcff3576e35cdf4ec9a) +--- + drivers/mfd/syscon.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/mfd/syscon.c ++++ b/drivers/mfd/syscon.c +@@ -183,7 +183,7 @@ static struct regmap *device_node_get_re + if (create_regmap) + syscon = of_syscon_register(np, check_res); + else +- syscon = ERR_PTR(-EINVAL); ++ syscon = ERR_PTR(-EPROBE_DEFER); + } + mutex_unlock(&syscon_list_lock); + diff --git a/target/linux/spacemit/patches-6.18/0049-dt-bindings-pinctrl-spacemit-add-syscon-property.patch b/target/linux/spacemit/patches-6.18/0049-dt-bindings-pinctrl-spacemit-add-syscon-property.patch new file mode 100644 index 00000000000000..0dfdbeb3ce838f --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0049-dt-bindings-pinctrl-spacemit-add-syscon-property.patch @@ -0,0 +1,42 @@ +From 2f1b09df81cef270b6d2ead36f741b6030c0d31c Mon Sep 17 00:00:00 2001 +From: Troy Mitchell +Date: Thu, 8 Jan 2026 14:42:38 +0800 +Subject: [PATCH] dt-bindings: pinctrl: spacemit: add syscon property + +In order to access the protected IO power domain registers, a valid +unlock sequence must be performed by writing the required keys to the +AIB Secure Access Register (ASAR). + +The ASAR register resides within the APBC register address space. +A corresponding syscon property is added to allow the pinctrl driver +to access this register. + +Signed-off-by: Troy Mitchell +Reviewed-by: Rob Herring (Arm) +Signed-off-by: Linus Walleij +(cherry picked from commit e817f0223d78818cd6c0e3480355c9a9cfbc0096) +--- + .../devicetree/bindings/pinctrl/spacemit,k1-pinctrl.yaml | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/Documentation/devicetree/bindings/pinctrl/spacemit,k1-pinctrl.yaml ++++ b/Documentation/devicetree/bindings/pinctrl/spacemit,k1-pinctrl.yaml +@@ -30,6 +30,10 @@ properties: + resets: + maxItems: 1 + ++ spacemit,apbc: ++ $ref: /schemas/types.yaml#/definitions/phandle ++ description: Phandle to syscon that access the protected register ++ + patternProperties: + '-cfg$': + type: object +@@ -130,6 +134,7 @@ examples: + clocks = <&syscon_apbc 42>, + <&syscon_apbc 94>; + clock-names = "func", "bus"; ++ spacemit,apbc = <&syscon_apbc>; + + uart0_2_cfg: uart0-2-cfg { + uart0-2-pins { diff --git a/target/linux/spacemit/patches-6.18/0050-pinctrl-spacemit-support-I-O-power-domain-configurat.patch b/target/linux/spacemit/patches-6.18/0050-pinctrl-spacemit-support-I-O-power-domain-configurat.patch new file mode 100644 index 00000000000000..9422ff22c8cf38 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0050-pinctrl-spacemit-support-I-O-power-domain-configurat.patch @@ -0,0 +1,256 @@ +From d4e9fbdb2d04ea77c47b0c83707591e81d58437a Mon Sep 17 00:00:00 2001 +From: Troy Mitchell +Date: Thu, 8 Jan 2026 14:42:39 +0800 +Subject: [PATCH] pinctrl: spacemit: support I/O power domain configuration + +Dual-voltage GPIO banks default to 3.3V operation. Even when a bank is +externally supplied with 1.8V, the internal logic remains in the 3.3V +domain, leading to functional failures. + +Add support for programming the IO domain power control registers to +allow explicit configuration for 1.8V operation. + +These registers are secure due to hardware safety constraints. +Specifically, configuring the domain for 1.8V while externally supplying +3.3V causes back-powering and potential pin damage. Consequently, access +requires unlocking the AIB Secure Access Register (ASAR) in the APBC +block before any read or write operation. + +Signed-off-by: Troy Mitchell +Signed-off-by: Linus Walleij +(cherry picked from commit 450e2487d5a28260f70ad7fbf3060e7f8304203d) +--- + drivers/pinctrl/spacemit/pinctrl-k1.c | 129 +++++++++++++++++++++++++- + 1 file changed, 126 insertions(+), 3 deletions(-) + +--- a/drivers/pinctrl/spacemit/pinctrl-k1.c ++++ b/drivers/pinctrl/spacemit/pinctrl-k1.c +@@ -7,8 +7,10 @@ + #include + #include + #include ++#include + #include + #include ++#include + #include + #include + +@@ -47,6 +49,27 @@ + #define PAD_PULLUP BIT(14) + #define PAD_PULL_EN BIT(15) + ++#define IO_PWR_DOMAIN_OFFSET 0x800 ++ ++#define IO_PWR_DOMAIN_GPIO2_Kx 0x0c ++#define IO_PWR_DOMAIN_MMC_Kx 0x1c ++ ++#define IO_PWR_DOMAIN_GPIO3_K1 0x10 ++#define IO_PWR_DOMAIN_QSPI_K1 0x20 ++ ++#define IO_PWR_DOMAIN_GPIO1_K3 0x04 ++#define IO_PWR_DOMAIN_GPIO5_K3 0x10 ++#define IO_PWR_DOMAIN_GPIO4_K3 0x20 ++#define IO_PWR_DOMAIN_QSPI_K3 0x2c ++ ++#define IO_PWR_DOMAIN_V18EN BIT(2) ++ ++#define APBC_ASFAR 0x50 ++#define APBC_ASSAR 0x54 ++ ++#define APBC_ASFAR_AKEY 0xbaba ++#define APBC_ASSAR_AKEY 0xeb10 ++ + struct spacemit_pin_drv_strength { + u8 val; + u32 mA; +@@ -78,6 +101,8 @@ struct spacemit_pinctrl { + raw_spinlock_t lock; + + void __iomem *regs; ++ ++ struct regmap *regmap_apbc; + }; + + struct spacemit_pinctrl_data { +@@ -85,6 +110,7 @@ struct spacemit_pinctrl_data { + const struct spacemit_pin *data; + u16 npins; + unsigned int (*pin_to_offset)(unsigned int pin); ++ unsigned int (*pin_to_io_pd_offset)(unsigned int pin); + const struct spacemit_pinctrl_dconf *dconf; + }; + +@@ -146,6 +172,56 @@ static unsigned int spacemit_k3_pin_to_o + return offset << 2; + } + ++static unsigned int spacemit_k1_pin_to_io_pd_offset(unsigned int pin) ++{ ++ unsigned int offset = 0; ++ ++ switch (pin) { ++ case 47 ... 52: ++ offset = IO_PWR_DOMAIN_GPIO3_K1; ++ break; ++ case 75 ... 80: ++ offset = IO_PWR_DOMAIN_GPIO2_Kx; ++ break; ++ case 98 ... 103: ++ offset = IO_PWR_DOMAIN_QSPI_K1; ++ break; ++ case 104 ... 109: ++ offset = IO_PWR_DOMAIN_MMC_Kx; ++ break; ++ } ++ ++ return offset; ++} ++ ++static unsigned int spacemit_k3_pin_to_io_pd_offset(unsigned int pin) ++{ ++ unsigned int offset = 0; ++ ++ switch (pin) { ++ case 0 ... 20: ++ offset = IO_PWR_DOMAIN_GPIO1_K3; ++ break; ++ case 21 ... 41: ++ offset = IO_PWR_DOMAIN_GPIO2_Kx; ++ break; ++ case 76 ... 98: ++ offset = IO_PWR_DOMAIN_GPIO4_K3; ++ break; ++ case 99 ... 127: ++ offset = IO_PWR_DOMAIN_GPIO5_K3; ++ break; ++ case 132 ... 137: ++ offset = IO_PWR_DOMAIN_MMC_Kx; ++ break; ++ case 138 ... 144: ++ offset = IO_PWR_DOMAIN_QSPI_K3; ++ break; ++ } ++ ++ return offset; ++} ++ + static inline void __iomem *spacemit_pin_to_reg(struct spacemit_pinctrl *pctrl, + unsigned int pin) + { +@@ -365,6 +441,42 @@ static int spacemit_pctrl_check_power(st + return 0; + } + ++static void spacemit_set_io_pwr_domain(struct spacemit_pinctrl *pctrl, ++ const struct spacemit_pin *spin, ++ const enum spacemit_pin_io_type type) ++{ ++ u32 offset, val = 0; ++ ++ if (!pctrl->regmap_apbc) ++ return; ++ ++ offset = pctrl->data->pin_to_io_pd_offset(spin->pin); ++ ++ /* Other bits are reserved so don't need to save them */ ++ if (type == IO_TYPE_1V8) ++ val = IO_PWR_DOMAIN_V18EN; ++ ++ /* ++ * IO power domain registers are protected and cannot be accessed ++ * directly. Before performing any read or write to the IO power ++ * domain registers, an explicit unlock sequence must be issued ++ * via the AIB Secure Access Register (ASAR). ++ * ++ * The unlock sequence allows exactly one subsequent access to the ++ * IO power domain registers. After that access completes, the ASAR ++ * keys are automatically cleared, and the registers become locked ++ * again. ++ * ++ * This mechanism ensures that IO power domain configuration is ++ * performed intentionally, as incorrect voltage settings may ++ * result in functional failures or hardware damage. ++ */ ++ regmap_write(pctrl->regmap_apbc, APBC_ASFAR, APBC_ASFAR_AKEY); ++ regmap_write(pctrl->regmap_apbc, APBC_ASSAR, APBC_ASSAR_AKEY); ++ ++ writel_relaxed(val, pctrl->regs + IO_PWR_DOMAIN_OFFSET + offset); ++} ++ + static int spacemit_pctrl_dt_node_to_map(struct pinctrl_dev *pctldev, + struct device_node *np, + struct pinctrl_map **maps, +@@ -572,7 +684,8 @@ static int spacemit_pinconf_get(struct p + + #define ENABLE_DRV_STRENGTH BIT(1) + #define ENABLE_SLEW_RATE BIT(2) +-static int spacemit_pinconf_generate_config(const struct spacemit_pin *spin, ++static int spacemit_pinconf_generate_config(struct spacemit_pinctrl *pctrl, ++ const struct spacemit_pin *spin, + const struct spacemit_pinctrl_dconf *dconf, + unsigned long *configs, + unsigned int num_configs, +@@ -646,6 +759,7 @@ static int spacemit_pinconf_generate_con + default: + return -EINVAL; + } ++ spacemit_set_io_pwr_domain(pctrl, spin, type); + } + + val = spacemit_get_driver_strength(type, dconf, drv_strength); +@@ -701,7 +815,7 @@ static int spacemit_pinconf_set(struct p + const struct spacemit_pin *spin = spacemit_get_pin(pctrl, pin); + u32 value; + +- if (spacemit_pinconf_generate_config(spin, pctrl->data->dconf, ++ if (spacemit_pinconf_generate_config(pctrl, spin, pctrl->data->dconf, + configs, num_configs, &value)) + return -EINVAL; + +@@ -724,7 +838,7 @@ static int spacemit_pinconf_group_set(st + return -EINVAL; + + spin = spacemit_get_pin(pctrl, group->grp.pins[0]); +- if (spacemit_pinconf_generate_config(spin, pctrl->data->dconf, ++ if (spacemit_pinconf_generate_config(pctrl, spin, pctrl->data->dconf, + configs, num_configs, &value)) + return -EINVAL; + +@@ -795,6 +909,7 @@ static const struct pinconf_ops spacemit + + static int spacemit_pinctrl_probe(struct platform_device *pdev) + { ++ struct device_node *np = pdev->dev.of_node; + struct device *dev = &pdev->dev; + struct spacemit_pinctrl *pctrl; + struct clk *func_clk, *bus_clk; +@@ -816,6 +931,12 @@ static int spacemit_pinctrl_probe(struct + if (IS_ERR(pctrl->regs)) + return PTR_ERR(pctrl->regs); + ++ pctrl->regmap_apbc = syscon_regmap_lookup_by_phandle(np, "spacemit,apbc"); ++ if (IS_ERR(pctrl->regmap_apbc)) { ++ dev_warn(dev, "no syscon found, disable power voltage switch functionality\n"); ++ pctrl->regmap_apbc = NULL; ++ } ++ + func_clk = devm_clk_get_enabled(dev, "func"); + if (IS_ERR(func_clk)) + return dev_err_probe(dev, PTR_ERR(func_clk), "failed to get func clock\n"); +@@ -1118,6 +1239,7 @@ static const struct spacemit_pinctrl_dat + .data = k1_pin_data, + .npins = ARRAY_SIZE(k1_pin_desc), + .pin_to_offset = spacemit_k1_pin_to_offset, ++ .pin_to_io_pd_offset = spacemit_k1_pin_to_io_pd_offset, + .dconf = &k1_drive_conf, + }; + +@@ -1455,6 +1577,7 @@ static const struct spacemit_pinctrl_dat + .data = k3_pin_data, + .npins = ARRAY_SIZE(k3_pin_desc), + .pin_to_offset = spacemit_k3_pin_to_offset, ++ .pin_to_io_pd_offset = spacemit_k3_pin_to_io_pd_offset, + .dconf = &k3_drive_conf, + }; + diff --git a/target/linux/spacemit/patches-6.18/0051-riscv-dts-spacemit-add-reset-property.patch b/target/linux/spacemit/patches-6.18/0051-riscv-dts-spacemit-add-reset-property.patch new file mode 100644 index 00000000000000..abed8c70d69142 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0051-riscv-dts-spacemit-add-reset-property.patch @@ -0,0 +1,81 @@ +From 2ab91e9fd8d036591c94475322c4ffc999508196 Mon Sep 17 00:00:00 2001 +From: Encrow Thorne +Date: Tue, 30 Dec 2025 23:06:53 +0800 +Subject: [PATCH] riscv: dts: spacemit: add reset property + +Add resets property to K1 I2C node. + +Signed-off-by: Encrow Thorne +Link: https://lore.kernel.org/r/20251230150653.42097-3-jyc0019@gmail.com +Signed-off-by: Yixun Lan +(cherry picked from commit 7d6fe7e381d2912300df06e1a7e7a6f6a9269af0) +--- + arch/riscv/boot/dts/spacemit/k1.dtsi | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/arch/riscv/boot/dts/spacemit/k1.dtsi ++++ b/arch/riscv/boot/dts/spacemit/k1.dtsi +@@ -368,6 +368,7 @@ + <&syscon_apbc CLK_TWSI0_BUS>; + clock-names = "func", "bus"; + clock-frequency = <400000>; ++ resets = <&syscon_apbc RESET_TWSI0>; + interrupts = <36>; + status = "disabled"; + }; +@@ -381,6 +382,7 @@ + <&syscon_apbc CLK_TWSI1_BUS>; + clock-names = "func", "bus"; + clock-frequency = <400000>; ++ resets = <&syscon_apbc RESET_TWSI1>; + interrupts = <37>; + status = "disabled"; + }; +@@ -394,6 +396,7 @@ + <&syscon_apbc CLK_TWSI2_BUS>; + clock-names = "func", "bus"; + clock-frequency = <400000>; ++ resets = <&syscon_apbc RESET_TWSI2>; + interrupts = <38>; + status = "disabled"; + }; +@@ -407,6 +410,7 @@ + <&syscon_apbc CLK_TWSI4_BUS>; + clock-names = "func", "bus"; + clock-frequency = <400000>; ++ resets = <&syscon_apbc RESET_TWSI4>; + interrupts = <40>; + status = "disabled"; + }; +@@ -420,6 +424,7 @@ + <&syscon_apbc CLK_TWSI5_BUS>; + clock-names = "func", "bus"; + clock-frequency = <400000>; ++ resets = <&syscon_apbc RESET_TWSI5>; + interrupts = <41>; + status = "disabled"; + }; +@@ -490,6 +495,7 @@ + <&syscon_apbc CLK_TWSI6_BUS>; + clock-names = "func", "bus"; + clock-frequency = <400000>; ++ resets = <&syscon_apbc RESET_TWSI6>; + interrupts = <70>; + status = "disabled"; + }; +@@ -593,6 +599,7 @@ + <&syscon_apbc CLK_TWSI7_BUS>; + clock-names = "func", "bus"; + clock-frequency = <400000>; ++ resets = <&syscon_apbc RESET_TWSI7>; + interrupts = <18>; + status = "disabled"; + }; +@@ -606,6 +613,7 @@ + <&syscon_apbc CLK_TWSI8_BUS>; + clock-names = "func", "bus"; + clock-frequency = <400000>; ++ resets = <&syscon_apbc RESET_TWSI8>; + interrupts = <19>; + status = "disabled"; + }; diff --git a/target/linux/spacemit/patches-6.18/0052-riscv-dts-spacemit-sdhci-add-reset-support.patch b/target/linux/spacemit/patches-6.18/0052-riscv-dts-spacemit-sdhci-add-reset-support.patch new file mode 100644 index 00000000000000..784a42edb9324e --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0052-riscv-dts-spacemit-sdhci-add-reset-support.patch @@ -0,0 +1,27 @@ +From 60be857da65c381c612d727398f5bcde78228e4e Mon Sep 17 00:00:00 2001 +From: Yixun Lan +Date: Tue, 23 Dec 2025 10:24:51 +0800 +Subject: [PATCH] riscv: dts: spacemit: sdhci: add reset support + +Request two reset line explicitly for SDHCI controller. + +Reviewed-by: Javier Martinez Canillas +Link: https://lore.kernel.org/r/20251223-07-k1-sdhci-reset-v2-3-5b8248cfc522@gentoo.org +Signed-off-by: Yixun Lan +(cherry picked from commit 7689c2d1bb1f53b170af79007d0611b43f232f05) +--- + arch/riscv/boot/dts/spacemit/k1.dtsi | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/arch/riscv/boot/dts/spacemit/k1.dtsi ++++ b/arch/riscv/boot/dts/spacemit/k1.dtsi +@@ -1168,6 +1168,9 @@ + clocks = <&syscon_apmu CLK_SDH_AXI>, + <&syscon_apmu CLK_SDH2>; + clock-names = "core", "io"; ++ resets = <&syscon_apmu RESET_SDH_AXI>, ++ <&syscon_apmu RESET_SDH2>; ++ reset-names = "axi", "sdh"; + interrupts = <101>; + status = "disabled"; + }; diff --git a/target/linux/spacemit/patches-6.18/0053-riscv-dts-spacemit-Add-USB2-PHY-node-for-K1.patch b/target/linux/spacemit/patches-6.18/0053-riscv-dts-spacemit-Add-USB2-PHY-node-for-K1.patch new file mode 100644 index 00000000000000..95cabee4b299e1 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0053-riscv-dts-spacemit-Add-USB2-PHY-node-for-K1.patch @@ -0,0 +1,38 @@ +From 0da8428a31fbf301fd648d012d344ce3bce298fa Mon Sep 17 00:00:00 2001 +From: Ze Huang +Date: Sun, 11 Jan 2026 14:41:02 +0800 +Subject: [PATCH] riscv: dts: spacemit: Add USB2 PHY node for K1 + +K1's DWC3 USB 3.0 controller requires two separate PHYs to function: +the USB 3.0 combophy (for SuperSpeed) and a USB 2.0 PHY (for High-Speed, +Full-Speed, etc.). + +Add node for this second USB 2.0 PHY (usbphy2). + +Tested-by: Aurelien Jarno +Signed-off-by: Ze Huang +Reviewed-by: Yixun Lan +Link: https://lore.kernel.org/r/20260111-k1-usb3dts-v2-v3-1-f5ebd546e904@linux.dev +Signed-off-by: Yixun Lan +(cherry picked from commit 9d591fef025d5008f23ab339a10006b151150578) +--- + arch/riscv/boot/dts/spacemit/k1.dtsi | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/arch/riscv/boot/dts/spacemit/k1.dtsi ++++ b/arch/riscv/boot/dts/spacemit/k1.dtsi +@@ -429,6 +429,14 @@ + status = "disabled"; + }; + ++ usbphy2: phy@c0a30000 { ++ compatible = "spacemit,k1-usb2-phy"; ++ reg = <0x0 0xc0a30000 0x0 0x200>; ++ clocks = <&syscon_apmu CLK_USB30>; ++ #phy-cells = <0>; ++ status = "disabled"; ++ }; ++ + combo_phy: phy@c0b10000 { + compatible = "spacemit,k1-combo-phy"; + reg = <0x0 0xc0b10000 0x0 0x1000>; diff --git a/target/linux/spacemit/patches-6.18/0054-riscv-dts-spacemit-Add-DWC3-USB-3.0-controller-node-.patch b/target/linux/spacemit/patches-6.18/0054-riscv-dts-spacemit-Add-DWC3-USB-3.0-controller-node-.patch new file mode 100644 index 00000000000000..756cb26a981741 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0054-riscv-dts-spacemit-Add-DWC3-USB-3.0-controller-node-.patch @@ -0,0 +1,52 @@ +From 29e42f2229ff01832013019779d651789c9afb69 Mon Sep 17 00:00:00 2001 +From: Ze Huang +Date: Sun, 11 Jan 2026 14:41:03 +0800 +Subject: [PATCH] riscv: dts: spacemit: Add DWC3 USB 3.0 controller node for K1 + +Add node for the Synopsys DWC3 USB 3.0 host controller on the K1 SoC. +The controller resides on the 'storage-bus' and uses its DMA +translations. + +Tested-by: Aurelien Jarno +Signed-off-by: Ze Huang +Reviewed-by: Yixun Lan +Link: https://lore.kernel.org/r/20260111-k1-usb3dts-v2-v3-2-f5ebd546e904@linux.dev +Signed-off-by: Yixun Lan +(cherry picked from commit 6e8dcd141833a23d7117fe16896f6d5dfdb2e112) +--- + arch/riscv/boot/dts/spacemit/k1.dtsi | 24 ++++++++++++++++++++++++ + 1 file changed, 24 insertions(+) + +--- a/arch/riscv/boot/dts/spacemit/k1.dtsi ++++ b/arch/riscv/boot/dts/spacemit/k1.dtsi +@@ -1170,6 +1170,30 @@ + #size-cells = <2>; + dma-ranges = <0x0 0x00000000 0x0 0x00000000 0x0 0x80000000>; + ++ usb_dwc3: usb@c0a00000 { ++ compatible = "spacemit,k1-dwc3"; ++ reg = <0x0 0xc0a00000 0x0 0x10000>; ++ clocks = <&syscon_apmu CLK_USB30>; ++ clock-names = "usbdrd30"; ++ interrupts = <125>; ++ phys = <&usbphy2>, <&combo_phy PHY_TYPE_USB3>; ++ phy-names = "usb2-phy", "usb3-phy"; ++ phy_type = "utmi"; ++ resets = <&syscon_apmu RESET_USB30_AHB>, ++ <&syscon_apmu RESET_USB30_VCC>, ++ <&syscon_apmu RESET_USB30_PHY>; ++ reset-names = "ahb", "vcc", "phy"; ++ reset-delay = <2>; ++ snps,hsphy_interface = "utmi"; ++ snps,dis_enblslpm_quirk; ++ snps,dis-u2-freeclk-exists-quirk; ++ snps,dis-del-phy-power-chg-quirk; ++ snps,dis_u2_susphy_quirk; ++ snps,dis_u3_susphy_quirk; ++ snps,dis_rxdet_inp3_quirk; ++ status = "disabled"; ++ }; ++ + emmc: mmc@d4281000 { + compatible = "spacemit,k1-sdhci"; + reg = <0x0 0xd4281000 0x0 0x200>; diff --git a/target/linux/spacemit/patches-6.18/0055-riscv-dts-spacemit-Enable-USB3.0-on-BananaPi-F3.patch b/target/linux/spacemit/patches-6.18/0055-riscv-dts-spacemit-Enable-USB3.0-on-BananaPi-F3.patch new file mode 100644 index 00000000000000..baa3427d0b4902 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0055-riscv-dts-spacemit-Enable-USB3.0-on-BananaPi-F3.patch @@ -0,0 +1,81 @@ +From ff53b3518e0bf2b93ca1d7c1534f0ffa3b4c0123 Mon Sep 17 00:00:00 2001 +From: Ze Huang +Date: Sun, 11 Jan 2026 14:41:04 +0800 +Subject: [PATCH] riscv: dts: spacemit: Enable USB3.0 on BananaPi-F3 + +Enable the DWC3 USB 3.0 controller and its associated usbphy2 on the +Banana Pi F3 board. + +The board utilizes a VLI VL817 hub, which requires two separate power +supplies: one VBUS and one for hub itself. Add two GPIO-controlled +fixed-regulators to manage this. + +Tested-by: Aurelien Jarno +Signed-off-by: Ze Huang +Reviewed-by: Yixun Lan +Link: https://lore.kernel.org/r/20260111-k1-usb3dts-v2-v3-3-f5ebd546e904@linux.dev +Signed-off-by: Yixun Lan +(cherry picked from commit c7e62c4eea026d42d192a0b86ce7313086ef2093) +--- + .../boot/dts/spacemit/k1-bananapi-f3.dts | 46 +++++++++++++++++++ + 1 file changed, 46 insertions(+) + +--- a/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts ++++ b/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts +@@ -59,6 +59,25 @@ + regulator-always-on; + vin-supply = <®_dc_in>; + }; ++ ++ usb3-vbus-5v { ++ compatible = "regulator-fixed"; ++ regulator-name = "USB30_VBUS"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ regulator-always-on; ++ gpio = <&gpio K1_GPIO(97) GPIO_ACTIVE_HIGH>; ++ enable-active-high; ++ }; ++ ++ usb3_hub_5v: usb3-hub-5v { ++ compatible = "regulator-fixed"; ++ regulator-name = "USB30_HUB"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ gpio = <&gpio K1_GPIO(123) GPIO_ACTIVE_HIGH>; ++ enable-active-high; ++ }; + }; + + &combo_phy { +@@ -313,3 +332,30 @@ + pinctrl-0 = <&uart0_2_cfg>; + status = "okay"; + }; ++ ++&usbphy2 { ++ status = "okay"; ++}; ++ ++&usb_dwc3 { ++ dr_mode = "host"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ hub_2_0: hub@1 { ++ compatible = "usb2109,2817"; ++ reg = <0x1>; ++ vdd-supply = <&usb3_hub_5v>; ++ peer-hub = <&hub_3_0>; ++ reset-gpios = <&gpio K1_GPIO(124) GPIO_ACTIVE_LOW>; ++ }; ++ ++ hub_3_0: hub@2 { ++ compatible = "usb2109,817"; ++ reg = <0x2>; ++ vdd-supply = <&usb3_hub_5v>; ++ peer-hub = <&hub_2_0>; ++ reset-gpios = <&gpio K1_GPIO(124) GPIO_ACTIVE_LOW>; ++ }; ++}; diff --git a/target/linux/spacemit/patches-6.18/0056-riscv-dts-spacemit-k1-Add-b-ISA-extension.patch b/target/linux/spacemit/patches-6.18/0056-riscv-dts-spacemit-k1-Add-b-ISA-extension.patch new file mode 100644 index 00000000000000..60ee4a2f68a5db --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0056-riscv-dts-spacemit-k1-Add-b-ISA-extension.patch @@ -0,0 +1,123 @@ +From a9afc90d158cc326e794180edf1eaec920846b42 Mon Sep 17 00:00:00 2001 +From: Guodong Xu +Date: Thu, 15 Jan 2026 07:19:00 +0800 +Subject: [PATCH] riscv: dts: spacemit: k1: Add "b" ISA extension + +"b" is ratified (Apr/2024) much later than its components zba/zbb/zbs +(Jun/2021). With "b" added into riscv/extensions.yaml, a dependency +checking rule is now enforced, which requires that when zba, zbb, and zbs +are all specified, "b" must be added as well. Failing to do this will +cause dtbs_check schema check warnings. + +According to uabi.rst, as a single-letter extension, "b" should be added +after "c" in canonical order. + +Update k1.dtsi to conform to this rule. + +Signed-off-by: Guodong Xu +Reviewed-by: Yixun Lan +Link: https://lore.kernel.org/r/20260115-adding-b-dtsi-v2-4-254dd61cf947@riscstar.com +Signed-off-by: Yixun Lan +(cherry picked from commit 4168630825f95bf57729dad46d2a097096e73e4d) +--- + arch/riscv/boot/dts/spacemit/k1.dtsi | 32 ++++++++++++++-------------- + 1 file changed, 16 insertions(+), 16 deletions(-) + +--- a/arch/riscv/boot/dts/spacemit/k1.dtsi ++++ b/arch/riscv/boot/dts/spacemit/k1.dtsi +@@ -54,9 +54,9 @@ + compatible = "spacemit,x60", "riscv"; + device_type = "cpu"; + reg = <0>; +- riscv,isa = "rv64imafdcv_zicbom_zicbop_zicboz_zicntr_zicond_zicsr_zifencei_zihintpause_zihpm_zfh_zba_zbb_zbc_zbs_zkt_zvfh_zvkt_sscofpmf_sstc_svinval_svnapot_svpbmt"; ++ riscv,isa = "rv64imafdcbv_zicbom_zicbop_zicboz_zicntr_zicond_zicsr_zifencei_zihintpause_zihpm_zfh_zba_zbb_zbc_zbs_zkt_zvfh_zvkt_sscofpmf_sstc_svinval_svnapot_svpbmt"; + riscv,isa-base = "rv64i"; +- riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "v", "zicbom", ++ riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "b", "v", "zicbom", + "zicbop", "zicboz", "zicntr", "zicond", "zicsr", + "zifencei", "zihintpause", "zihpm", "zfh", "zba", + "zbb", "zbc", "zbs", "zkt", "zvfh", "zvkt", +@@ -84,9 +84,9 @@ + compatible = "spacemit,x60", "riscv"; + device_type = "cpu"; + reg = <1>; +- riscv,isa = "rv64imafdcv_zicbom_zicbop_zicboz_zicntr_zicond_zicsr_zifencei_zihintpause_zihpm_zfh_zba_zbb_zbc_zbs_zkt_zvfh_zvkt_sscofpmf_sstc_svinval_svnapot_svpbmt"; ++ riscv,isa = "rv64imafdcbv_zicbom_zicbop_zicboz_zicntr_zicond_zicsr_zifencei_zihintpause_zihpm_zfh_zba_zbb_zbc_zbs_zkt_zvfh_zvkt_sscofpmf_sstc_svinval_svnapot_svpbmt"; + riscv,isa-base = "rv64i"; +- riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "v", "zicbom", ++ riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "b", "v", "zicbom", + "zicbop", "zicboz", "zicntr", "zicond", "zicsr", + "zifencei", "zihintpause", "zihpm", "zfh", "zba", + "zbb", "zbc", "zbs", "zkt", "zvfh", "zvkt", +@@ -114,9 +114,9 @@ + compatible = "spacemit,x60", "riscv"; + device_type = "cpu"; + reg = <2>; +- riscv,isa = "rv64imafdcv_zicbom_zicbop_zicboz_zicntr_zicond_zicsr_zifencei_zihintpause_zihpm_zfh_zba_zbb_zbc_zbs_zkt_zvfh_zvkt_sscofpmf_sstc_svinval_svnapot_svpbmt"; ++ riscv,isa = "rv64imafdcbv_zicbom_zicbop_zicboz_zicntr_zicond_zicsr_zifencei_zihintpause_zihpm_zfh_zba_zbb_zbc_zbs_zkt_zvfh_zvkt_sscofpmf_sstc_svinval_svnapot_svpbmt"; + riscv,isa-base = "rv64i"; +- riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "v", "zicbom", ++ riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "b", "v", "zicbom", + "zicbop", "zicboz", "zicntr", "zicond", "zicsr", + "zifencei", "zihintpause", "zihpm", "zfh", "zba", + "zbb", "zbc", "zbs", "zkt", "zvfh", "zvkt", +@@ -144,9 +144,9 @@ + compatible = "spacemit,x60", "riscv"; + device_type = "cpu"; + reg = <3>; +- riscv,isa = "rv64imafdcv_zicbom_zicbop_zicboz_zicntr_zicond_zicsr_zifencei_zihintpause_zihpm_zfh_zba_zbb_zbc_zbs_zkt_zvfh_zvkt_sscofpmf_sstc_svinval_svnapot_svpbmt"; ++ riscv,isa = "rv64imafdcbv_zicbom_zicbop_zicboz_zicntr_zicond_zicsr_zifencei_zihintpause_zihpm_zfh_zba_zbb_zbc_zbs_zkt_zvfh_zvkt_sscofpmf_sstc_svinval_svnapot_svpbmt"; + riscv,isa-base = "rv64i"; +- riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "v", "zicbom", ++ riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "b", "v", "zicbom", + "zicbop", "zicboz", "zicntr", "zicond", "zicsr", + "zifencei", "zihintpause", "zihpm", "zfh", "zba", + "zbb", "zbc", "zbs", "zkt", "zvfh", "zvkt", +@@ -174,9 +174,9 @@ + compatible = "spacemit,x60", "riscv"; + device_type = "cpu"; + reg = <4>; +- riscv,isa = "rv64imafdcv_zicbom_zicbop_zicboz_zicntr_zicond_zicsr_zifencei_zihintpause_zihpm_zfh_zba_zbb_zbc_zbs_zkt_zvfh_zvkt_sscofpmf_sstc_svinval_svnapot_svpbmt"; ++ riscv,isa = "rv64imafdcbv_zicbom_zicbop_zicboz_zicntr_zicond_zicsr_zifencei_zihintpause_zihpm_zfh_zba_zbb_zbc_zbs_zkt_zvfh_zvkt_sscofpmf_sstc_svinval_svnapot_svpbmt"; + riscv,isa-base = "rv64i"; +- riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "v", "zicbom", ++ riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "b", "v", "zicbom", + "zicbop", "zicboz", "zicntr", "zicond", "zicsr", + "zifencei", "zihintpause", "zihpm", "zfh", "zba", + "zbb", "zbc", "zbs", "zkt", "zvfh", "zvkt", +@@ -204,9 +204,9 @@ + compatible = "spacemit,x60", "riscv"; + device_type = "cpu"; + reg = <5>; +- riscv,isa = "rv64imafdcv_zicbom_zicbop_zicboz_zicntr_zicond_zicsr_zifencei_zihintpause_zihpm_zfh_zba_zbb_zbc_zbs_zkt_zvfh_zvkt_sscofpmf_sstc_svinval_svnapot_svpbmt"; ++ riscv,isa = "rv64imafdcbv_zicbom_zicbop_zicboz_zicntr_zicond_zicsr_zifencei_zihintpause_zihpm_zfh_zba_zbb_zbc_zbs_zkt_zvfh_zvkt_sscofpmf_sstc_svinval_svnapot_svpbmt"; + riscv,isa-base = "rv64i"; +- riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "v", "zicbom", ++ riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "b", "v", "zicbom", + "zicbop", "zicboz", "zicntr", "zicond", "zicsr", + "zifencei", "zihintpause", "zihpm", "zfh", "zba", + "zbb", "zbc", "zbs", "zkt", "zvfh", "zvkt", +@@ -234,9 +234,9 @@ + compatible = "spacemit,x60", "riscv"; + device_type = "cpu"; + reg = <6>; +- riscv,isa = "rv64imafdcv_zicbom_zicbop_zicboz_zicntr_zicond_zicsr_zifencei_zihintpause_zihpm_zfh_zba_zbb_zbc_zbs_zkt_zvfh_zvkt_sscofpmf_sstc_svinval_svnapot_svpbmt"; ++ riscv,isa = "rv64imafdcbv_zicbom_zicbop_zicboz_zicntr_zicond_zicsr_zifencei_zihintpause_zihpm_zfh_zba_zbb_zbc_zbs_zkt_zvfh_zvkt_sscofpmf_sstc_svinval_svnapot_svpbmt"; + riscv,isa-base = "rv64i"; +- riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "v", "zicbom", ++ riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "b", "v", "zicbom", + "zicbop", "zicboz", "zicntr", "zicond", "zicsr", + "zifencei", "zihintpause", "zihpm", "zfh", "zba", + "zbb", "zbc", "zbs", "zkt", "zvfh", "zvkt", +@@ -264,9 +264,9 @@ + compatible = "spacemit,x60", "riscv"; + device_type = "cpu"; + reg = <7>; +- riscv,isa = "rv64imafdcv_zicbom_zicbop_zicboz_zicntr_zicond_zicsr_zifencei_zihintpause_zihpm_zfh_zba_zbb_zbc_zbs_zkt_zvfh_zvkt_sscofpmf_sstc_svinval_svnapot_svpbmt"; ++ riscv,isa = "rv64imafdcbv_zicbom_zicbop_zicboz_zicntr_zicond_zicsr_zifencei_zihintpause_zihpm_zfh_zba_zbb_zbc_zbs_zkt_zvfh_zvkt_sscofpmf_sstc_svinval_svnapot_svpbmt"; + riscv,isa-base = "rv64i"; +- riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "v", "zicbom", ++ riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "b", "v", "zicbom", + "zicbop", "zicboz", "zicntr", "zicond", "zicsr", + "zifencei", "zihintpause", "zihpm", "zfh", "zba", + "zbb", "zbc", "zbs", "zkt", "zvfh", "zvkt", diff --git a/target/linux/spacemit/patches-6.18/0057-riscv-dts-spacemit-pinctrl-update-register-and-IO-po.patch b/target/linux/spacemit/patches-6.18/0057-riscv-dts-spacemit-pinctrl-update-register-and-IO-po.patch new file mode 100644 index 00000000000000..9c0596c1cdcab6 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0057-riscv-dts-spacemit-pinctrl-update-register-and-IO-po.patch @@ -0,0 +1,41 @@ +From 87e64277bf6b200b1b26491b10407496321277fe Mon Sep 17 00:00:00 2001 +From: Troy Mitchell +Date: Thu, 8 Jan 2026 14:42:40 +0800 +Subject: [PATCH] riscv: dts: spacemit: pinctrl: update register and IO power + +Change the size of the reg register to 0x1000 to match the hardware. +This register range covers the IO power domain's register addresses. + +The IO power domain registers are protected. In order to access the +protected IO power domain registers, a valid unlock sequence must be +performed by writing the required keys to the AIB Secure Access Register +(ASAR). + +The ASAR register resides within the APBC register address space. +A corresponding syscon property `spacemit,apbc` is added to allow +the pinctrl driver to access this register. + +Signed-off-by: Troy Mitchell +Acked-by: Linus Walleij +Link: https://lore.kernel.org/r/20260108-kx-pinctrl-aib-io-pwr-domain-v2-3-6bcb46146e53@linux.spacemit.com +Signed-off-by: Yixun Lan +(cherry picked from commit 4083d8d6c0aa445fc440d70a5258351c47547ee2) +--- + arch/riscv/boot/dts/spacemit/k1.dtsi | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/arch/riscv/boot/dts/spacemit/k1.dtsi ++++ b/arch/riscv/boot/dts/spacemit/k1.dtsi +@@ -628,10 +628,11 @@ + + pinctrl: pinctrl@d401e000 { + compatible = "spacemit,k1-pinctrl"; +- reg = <0x0 0xd401e000 0x0 0x400>; ++ reg = <0x0 0xd401e000 0x0 0x1000>; + clocks = <&syscon_apbc CLK_AIB>, + <&syscon_apbc CLK_AIB_BUS>; + clock-names = "func", "bus"; ++ spacemit,apbc = <&syscon_apbc>; + }; + + pwm8: pwm@d4020000 { diff --git a/target/linux/spacemit/patches-6.18/0058-riscv-dts-spacemit-Disable-ETH-PHY-sleep-mode-for-Or.patch b/target/linux/spacemit/patches-6.18/0058-riscv-dts-spacemit-Disable-ETH-PHY-sleep-mode-for-Or.patch new file mode 100644 index 00000000000000..b2cc3b4c731dbb --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0058-riscv-dts-spacemit-Disable-ETH-PHY-sleep-mode-for-Or.patch @@ -0,0 +1,55 @@ +From 614d5a17b8391a84bd9841ff6252a51c53d34ba4 Mon Sep 17 00:00:00 2001 +From: Chukun Pan +Date: Tue, 20 Jan 2026 18:00:01 +0800 +Subject: [PATCH] riscv: dts: spacemit: Disable ETH PHY sleep mode for OrangePi + +On the SpacemiT K1 platform, the MAC can't read statistics when the PHY +clock stops. Disable Link Down Power Saving Mode for the YT8531C PHY on +OrangePi R2S and RV2 boards to avoid reading statistics timeout logs. + +Signed-off-by: Chukun Pan +Reviewed-by: Yixun Lan +Link: https://lore.kernel.org/r/20260120100001.1285624-2-amadeus@jmu.edu.cn +Signed-off-by: Yixun Lan +(cherry picked from commit 5164e95565d3fd508ca8a95351323f5716dfb695) +--- + arch/riscv/boot/dts/spacemit/k1-orangepi-r2s.dts | 2 ++ + arch/riscv/boot/dts/spacemit/k1-orangepi-rv2.dts | 2 ++ + 2 files changed, 4 insertions(+) + +--- a/arch/riscv/boot/dts/spacemit/k1-orangepi-r2s.dts ++++ b/arch/riscv/boot/dts/spacemit/k1-orangepi-r2s.dts +@@ -52,6 +52,7 @@ + + rgmii0: phy@1 { + reg = <0x1>; ++ motorcomm,auto-sleep-disabled; + }; + }; + }; +@@ -75,6 +76,7 @@ + + rgmii1: phy@1 { + reg = <0x1>; ++ motorcomm,auto-sleep-disabled; + }; + }; + }; +--- a/arch/riscv/boot/dts/spacemit/k1-orangepi-rv2.dts ++++ b/arch/riscv/boot/dts/spacemit/k1-orangepi-rv2.dts +@@ -54,6 +54,7 @@ + + rgmii0: phy@1 { + reg = <0x1>; ++ motorcomm,auto-sleep-disabled; + }; + }; + }; +@@ -77,6 +78,7 @@ + + rgmii1: phy@1 { + reg = <0x1>; ++ motorcomm,auto-sleep-disabled; + }; + }; + }; diff --git a/target/linux/spacemit/patches-6.18/0059-mfd-Kconfig-Default-MFD_SPACEMIT_P1-to-m-if-ARCH_SPA.patch b/target/linux/spacemit/patches-6.18/0059-mfd-Kconfig-Default-MFD_SPACEMIT_P1-to-m-if-ARCH_SPA.patch new file mode 100644 index 00000000000000..6cf0709998c4b6 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0059-mfd-Kconfig-Default-MFD_SPACEMIT_P1-to-m-if-ARCH_SPA.patch @@ -0,0 +1,27 @@ +From 1b632a9cf6ef3cf0c9876399bddf8ebd199391cb Mon Sep 17 00:00:00 2001 +From: Troy Mitchell +Date: Thu, 25 Dec 2025 15:46:32 +0800 +Subject: [PATCH] mfd: Kconfig: Default MFD_SPACEMIT_P1 to 'm' if ARCH_SPACEMIT + +The default value of the P1 sub-device depends on the value +of P1, so P1 should have a default value here. + +Signed-off-by: Troy Mitchell +Acked-by: Alex Elder +Link: https://patch.msgid.link/20251225-p1-kconfig-fix-v4-2-44b6728117c1@linux.spacemit.com +Signed-off-by: Lee Jones +(cherry picked from commit 9d1e2d5f2b24a24b32aca451d6a7feb081ad5a62) +--- + drivers/mfd/Kconfig | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/mfd/Kconfig ++++ b/drivers/mfd/Kconfig +@@ -1270,6 +1270,7 @@ config MFD_SPACEMIT_P1 + depends on ARCH_SPACEMIT || COMPILE_TEST + depends on I2C + select MFD_SIMPLE_MFD_I2C ++ default m if ARCH_SPACEMIT + help + This option supports the I2C-based SpacemiT P1 PMIC, which + contains regulators, a power switch, GPIOs, an RTC, and more. diff --git a/target/linux/spacemit/patches-6.18/0060-gpio-spacemit-k1-Use-PDR-for-pin-direction-not-SDR-C.patch b/target/linux/spacemit/patches-6.18/0060-gpio-spacemit-k1-Use-PDR-for-pin-direction-not-SDR-C.patch new file mode 100644 index 00000000000000..180ba6b7b53ef6 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0060-gpio-spacemit-k1-Use-PDR-for-pin-direction-not-SDR-C.patch @@ -0,0 +1,66 @@ +From 1fc267fa1355da50cad175aef2fd1fb0efa8c076 Mon Sep 17 00:00:00 2001 +From: Vivian Wang +Date: Tue, 27 Jan 2026 10:58:49 +0800 +Subject: [PATCH] gpio: spacemit-k1: Use PDR for pin direction, not SDR/CDR + +On the SpacemiT GPIO controller, the direction control register PDR is +readable and writable [1]. Therefore, implement direction control by +using PDR as dirout, and don't mark it as unreadable. + +The original implementation, using SDR as dirout and CDR as dirin, is +not actually a supported configuration by gpio-mmio. The hardware +supports changing the direction of some pins atomically by writing a +value with the corresponding bits set to SDR (set as output) or to CDR +(set as input). However, gpio-mmio does not actually handle this. + +Using only PDR as dirout to match the expectations of gpio-mmio. This +also allows us to avoid clobbering potentially important GPIO direction +configurations set by pre-Linux boot stages. + +Found while trying to add PCIe support to OrangePi RV2, where the +regulator (controlled by GPIO 116) turns off on boot while some other +GPIO pin in the same bank is touched, which is not desirable. + +Link: https://developer.spacemit.com/documentation?token=Rn9Kw3iFHirAMgkIpTAcV2Arnkf#18.4-gpio # [1] +Fixes: d00553240ef8 ("gpio: spacemit: add support for K1 SoC") +Signed-off-by: Vivian Wang +Reviewed-by: Troy Mitchell +Link: https://patch.msgid.link/20260127-gpio-spacemit-k1-pdr-v1-1-bb868a517dbc@iscas.ac.cn +Signed-off-by: Bartosz Golaszewski +(cherry picked from commit aa7e37fd770bafaaf856ab77735296955b93e377) +--- + drivers/gpio/gpio-spacemit-k1.c | 9 +++------ + 1 file changed, 3 insertions(+), 6 deletions(-) + +--- a/drivers/gpio/gpio-spacemit-k1.c ++++ b/drivers/gpio/gpio-spacemit-k1.c +@@ -199,7 +199,7 @@ static int spacemit_gpio_add_bank(struct + struct gpio_chip *gc = &gb->chip.gc; + struct device *dev = sg->dev; + struct gpio_irq_chip *girq; +- void __iomem *dat, *set, *clr, *dirin, *dirout; ++ void __iomem *dat, *set, *clr, *dirout; + int ret; + + gb->base = regs + sg->data->bank_offsets[index]; +@@ -208,8 +208,7 @@ static int spacemit_gpio_add_bank(struct + dat = gb->base + to_spacemit_gpio_regs(gb)[SPACEMIT_GPLR]; + set = gb->base + to_spacemit_gpio_regs(gb)[SPACEMIT_GPSR]; + clr = gb->base + to_spacemit_gpio_regs(gb)[SPACEMIT_GPCR]; +- dirin = gb->base + to_spacemit_gpio_regs(gb)[SPACEMIT_GCDR]; +- dirout = gb->base + to_spacemit_gpio_regs(gb)[SPACEMIT_GSDR]; ++ dirout = gb->base + to_spacemit_gpio_regs(gb)[SPACEMIT_GPDR]; + + config = (struct gpio_generic_chip_config) { + .dev = dev, +@@ -218,9 +217,7 @@ static int spacemit_gpio_add_bank(struct + .set = set, + .clr = clr, + .dirout = dirout, +- .dirin = dirin, +- .flags = GPIO_GENERIC_UNREADABLE_REG_SET | +- GPIO_GENERIC_UNREADABLE_REG_DIR, ++ .flags = GPIO_GENERIC_UNREADABLE_REG_SET, + }; + + /* This registers 32 GPIO lines per bank */ diff --git a/target/linux/spacemit/patches-6.18/0061-dt-bindings-pinctrl-spacemit-fix-drive-strength-chec.patch b/target/linux/spacemit/patches-6.18/0061-dt-bindings-pinctrl-spacemit-fix-drive-strength-chec.patch new file mode 100644 index 00000000000000..8d713673ddb137 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0061-dt-bindings-pinctrl-spacemit-fix-drive-strength-chec.patch @@ -0,0 +1,31 @@ +From c4e2c8c30694ee3ce6ba7aef452ea950f0a6cd07 Mon Sep 17 00:00:00 2001 +From: Yixun Lan +Date: Fri, 30 Jan 2026 19:22:15 +0800 +Subject: [PATCH] dt-bindings: pinctrl: spacemit: fix drive-strength check + warning + +The problem is that one value from drive-strength may match to more than +two different enum groups which lead to DT complaint, switch to use 'anyOf' +to fix this kind warning. + +Fixes: c3efac0592f8 ("dt-bindings: pinctrl: spacemit: convert drive strength to schema format") +Signed-off-by: Yixun Lan +Acked-by: Conor Dooley +Reported-by: Conor Dooley +Signed-off-by: Linus Walleij +(cherry picked from commit 0a4614fe85ef130ab3769afdf9d174cc9e645dea) +--- + .../devicetree/bindings/pinctrl/spacemit,k1-pinctrl.yaml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/Documentation/devicetree/bindings/pinctrl/spacemit,k1-pinctrl.yaml ++++ b/Documentation/devicetree/bindings/pinctrl/spacemit,k1-pinctrl.yaml +@@ -78,7 +78,7 @@ patternProperties: + drive-strength: + description: + typical current (in mA) when the output at high level. +- oneOf: ++ anyOf: + - enum: [ 11, 21, 32, 42 ] + description: For K1 SoC, 1.8V voltage output + diff --git a/target/linux/spacemit/patches-6.18/0062-net-spacemit-display-phy-driver-information.patch b/target/linux/spacemit/patches-6.18/0062-net-spacemit-display-phy-driver-information.patch new file mode 100644 index 00000000000000..a2765b7e1a867b --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0062-net-spacemit-display-phy-driver-information.patch @@ -0,0 +1,27 @@ +From 55bbc26b790d9e30d894beeb43325bc00e71b4e5 Mon Sep 17 00:00:00 2001 +From: Chukun Pan +Date: Sun, 1 Feb 2026 18:00:01 +0800 +Subject: [PATCH] net: spacemit: display phy driver information + +Print the PHY driver used and interrupt status after connection. + +Signed-off-by: Chukun Pan +Reviewed-by: Andrew Lunn +Link: https://patch.msgid.link/20260201100001.33102-1-amadeus@jmu.edu.cn +Signed-off-by: Jakub Kicinski +(cherry picked from commit fd102acfd362de60a941d24f0836278d839b9391) +--- + drivers/net/ethernet/spacemit/k1_emac.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/net/ethernet/spacemit/k1_emac.c ++++ b/drivers/net/ethernet/spacemit/k1_emac.c +@@ -1651,6 +1651,8 @@ static int emac_phy_connect(struct net_d + + emac_update_delay_line(priv); + ++ phy_attached_info(phydev); ++ + err_node_put: + of_node_put(np); + return ret; diff --git a/target/linux/spacemit/patches-6.18/0063-dt-bindings-mfd-spacemit-p1-Add-individual-regulator.patch b/target/linux/spacemit/patches-6.18/0063-dt-bindings-mfd-spacemit-p1-Add-individual-regulator.patch new file mode 100644 index 00000000000000..69ca6d387c33a9 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0063-dt-bindings-mfd-spacemit-p1-Add-individual-regulator.patch @@ -0,0 +1,97 @@ +From 150eba3de1a384fc5d80d5a9d7164b34be501186 Mon Sep 17 00:00:00 2001 +From: Guodong Xu +Date: Fri, 6 Feb 2026 10:32:02 +0800 +Subject: [PATCH] dt-bindings: mfd: spacemit,p1: Add individual regulator + supply properties + +Add supply properties that match the P1 PMIC's actual hardware topology +where each buck converter has its own VIN pin and LDO groups share +common input pins. Supply names are defined according to the pinout +names in the P1 datasheet. + +The existing "vin-supply" is dropped from the binding document as the +updated spacemit P1 driver no longer parses it. Only the per-rail names +("vin1-supply", "vin2-supply", ...) are supported. + +Signed-off-by: Guodong Xu +Acked-by: Conor Dooley +Reviewed-by: Alex Elder +Link: https://patch.msgid.link/20260206-spacemit-p1-v4-1-8f695d93811e@riscstar.com +Signed-off-by: Mark Brown +(cherry picked from commit 82ffa9610ba39d3628a9bec968ddc68fe2fe6612) +--- + .../devicetree/bindings/mfd/spacemit,p1.yaml | 49 ++++++++++++++++++- + 1 file changed, 47 insertions(+), 2 deletions(-) + +--- a/Documentation/devicetree/bindings/mfd/spacemit,p1.yaml ++++ b/Documentation/devicetree/bindings/mfd/spacemit,p1.yaml +@@ -27,8 +27,41 @@ properties: + interrupts: + maxItems: 1 + +- vin-supply: +- description: Input supply phandle. ++ vin1-supply: ++ description: ++ Power supply for BUCK1. Required if BUCK1 is defined. ++ ++ vin2-supply: ++ description: ++ Power supply for BUCK2. Required if BUCK2 is defined. ++ ++ vin3-supply: ++ description: ++ Power supply for BUCK3. Required if BUCK3 is defined. ++ ++ vin4-supply: ++ description: ++ Power supply for BUCK4. Required if BUCK4 is defined. ++ ++ vin5-supply: ++ description: ++ Power supply for BUCK5. Required if BUCK5 is defined. ++ ++ vin6-supply: ++ description: ++ Power supply for BUCK6. Required if BUCK6 is defined. ++ ++ aldoin-supply: ++ description: ++ Power supply for ALDO1-4. Required if any are defined. ++ ++ dldoin1-supply: ++ description: ++ Power supply for DLDO1-4. Required if any are defined. ++ ++ dldoin2-supply: ++ description: ++ Power supply for DLDO5-7. Required if any are defined. + + regulators: + type: object +@@ -58,6 +91,10 @@ examples: + compatible = "spacemit,p1"; + reg = <0x41>; + interrupts = <64>; ++ vin1-supply = <®_vcc_5v>; ++ vin5-supply = <®_vcc_5v>; ++ aldoin-supply = <®_vcc_5v>; ++ dldoin1-supply = <&buck5>; + + regulators { + buck1 { +@@ -65,6 +102,14 @@ examples: + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <3450000>; + regulator-ramp-delay = <5000>; ++ regulator-always-on; ++ }; ++ ++ buck5: buck5 { ++ regulator-name = "buck5"; ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <3450000>; ++ regulator-ramp-delay = <5000>; + regulator-always-on; + }; + diff --git a/target/linux/spacemit/patches-6.18/0064-regulator-spacemit-p1-Update-supply-names.patch b/target/linux/spacemit/patches-6.18/0064-regulator-spacemit-p1-Update-supply-names.patch new file mode 100644 index 00000000000000..ec583cad58f2ab --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0064-regulator-spacemit-p1-Update-supply-names.patch @@ -0,0 +1,69 @@ +From 57742e618a4e0f539c4518d093be152cc5e2c197 Mon Sep 17 00:00:00 2001 +From: Guodong Xu +Date: Fri, 6 Feb 2026 10:32:03 +0800 +Subject: [PATCH] regulator: spacemit-p1: Update supply names + +Update supply names to match the P1 PMIC's actual hardware pinout where +each buck has an individual VIN pin (vin1-vin6) and LDO groups have +dedicated input pins (aldoin, dldoin1, dldoin2). + +This is an ABI change from the original "vin" and "buck5" supplies. +The P1/PMIC regulator has no consumers in the DTS tree yet. For the two +K1 boards in-tree (BPI-F3 and Jupiter), power settings come from +boot firmware, so a probe failure has minimal impact. + +Signed-off-by: Guodong Xu +Link: https://developer.spacemit.com/documentation?token=T1Btw2BdiiSlSXkAdibcoMetnag +[1] +Reviewed-by: Alex Elder +Link: https://patch.msgid.link/20260206-spacemit-p1-v4-2-8f695d93811e@riscstar.com +Signed-off-by: Mark Brown +(cherry picked from commit fbb4c52ccdcb4a612d2b7f800aa57090eeee16d7) +--- + drivers/regulator/spacemit-p1.c | 25 ++++++++++++++----------- + 1 file changed, 14 insertions(+), 11 deletions(-) + +--- a/drivers/regulator/spacemit-p1.c ++++ b/drivers/regulator/spacemit-p1.c +@@ -87,13 +87,16 @@ static const struct linear_range p1_ldo_ + } + + #define P1_BUCK_DESC(_n) \ +- P1_REG_DESC(BUCK, buck, _n, "vin", 0x47, BUCK_MASK, 255, p1_buck_ranges) ++ P1_REG_DESC(BUCK, buck, _n, "vin" #_n, 0x47, BUCK_MASK, 255, p1_buck_ranges) + + #define P1_ALDO_DESC(_n) \ +- P1_REG_DESC(ALDO, aldo, _n, "vin", 0x5b, LDO_MASK, 128, p1_ldo_ranges) ++ P1_REG_DESC(ALDO, aldo, _n, "aldoin", 0x5b, LDO_MASK, 128, p1_ldo_ranges) + +-#define P1_DLDO_DESC(_n) \ +- P1_REG_DESC(DLDO, dldo, _n, "buck5", 0x67, LDO_MASK, 128, p1_ldo_ranges) ++#define P1_DLDO1_DESC(_n) \ ++ P1_REG_DESC(DLDO, dldo, _n, "dldoin1", 0x67, LDO_MASK, 128, p1_ldo_ranges) ++ ++#define P1_DLDO2_DESC(_n) \ ++ P1_REG_DESC(DLDO, dldo, _n, "dldoin2", 0x67, LDO_MASK, 128, p1_ldo_ranges) + + static const struct regulator_desc p1_regulator_desc[] = { + P1_BUCK_DESC(1), +@@ -108,13 +111,13 @@ static const struct regulator_desc p1_re + P1_ALDO_DESC(3), + P1_ALDO_DESC(4), + +- P1_DLDO_DESC(1), +- P1_DLDO_DESC(2), +- P1_DLDO_DESC(3), +- P1_DLDO_DESC(4), +- P1_DLDO_DESC(5), +- P1_DLDO_DESC(6), +- P1_DLDO_DESC(7), ++ P1_DLDO1_DESC(1), ++ P1_DLDO1_DESC(2), ++ P1_DLDO1_DESC(3), ++ P1_DLDO1_DESC(4), ++ P1_DLDO2_DESC(5), ++ P1_DLDO2_DESC(6), ++ P1_DLDO2_DESC(7), + }; + + static int p1_regulator_probe(struct platform_device *pdev) diff --git a/target/linux/spacemit/patches-6.18/0065-dt-bindings-mmc-spacemit-sdhci-add-reset-support.patch b/target/linux/spacemit/patches-6.18/0065-dt-bindings-mmc-spacemit-sdhci-add-reset-support.patch new file mode 100644 index 00000000000000..5f3b9a871232eb --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0065-dt-bindings-mmc-spacemit-sdhci-add-reset-support.patch @@ -0,0 +1,37 @@ +From b50ca0a0fecebc9e9473f623ff75d7509f3426d3 Mon Sep 17 00:00:00 2001 +From: Yixun Lan +Date: Tue, 23 Dec 2025 10:24:49 +0800 +Subject: [PATCH] dt-bindings: mmc: spacemit,sdhci: add reset support + +The SpacemiT SDHCI controller has two reset lines, one connect to AXI bus +which shared by all controllers, while another one connect to individual +controller separately. + +Signed-off-by: Yixun Lan +Reviewed-by: Javier Martinez Canillas +Reviewed-by: Krzysztof Kozlowski +Signed-off-by: Ulf Hansson +(cherry picked from commit 4231325cfb87f712fcbe1fcbeea4186d18c78513) +--- + .../devicetree/bindings/mmc/spacemit,sdhci.yaml | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +--- a/Documentation/devicetree/bindings/mmc/spacemit,sdhci.yaml ++++ b/Documentation/devicetree/bindings/mmc/spacemit,sdhci.yaml +@@ -32,6 +32,16 @@ properties: + - const: core + - const: io + ++ resets: ++ items: ++ - description: axi reset, connect to AXI bus, shared by all controllers ++ - description: sdh reset, connect to individual controller separately ++ ++ reset-names: ++ items: ++ - const: axi ++ - const: sdh ++ + required: + - compatible + - reg diff --git a/target/linux/spacemit/patches-6.18/0066-mmc-sdhci-of-k1-add-reset-support.patch b/target/linux/spacemit/patches-6.18/0066-mmc-sdhci-of-k1-add-reset-support.patch new file mode 100644 index 00000000000000..5ec227cb3fe053 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0066-mmc-sdhci-of-k1-add-reset-support.patch @@ -0,0 +1,61 @@ +From 05337b230f7484c5570f8f6a351c411c34b17abd Mon Sep 17 00:00:00 2001 +From: Yixun Lan +Date: Tue, 23 Dec 2025 10:24:50 +0800 +Subject: [PATCH] mmc: sdhci-of-k1: add reset support + +The SDHCI controller of SpacemiT K1 SoC requires two resets, add +support to explicitly request the reset line and deassert during +initialization phase. Still using devm_xx_get_optional() API to +make the request optional. + +Signed-off-by: Yixun Lan +Reviewed-by: Javier Martinez Canillas +Signed-off-by: Ulf Hansson +(cherry picked from commit 658b716c048684ad13d78280d69b883f181251da) +--- + drivers/mmc/host/sdhci-of-k1.c | 20 ++++++++++++++++++++ + 1 file changed, 20 insertions(+) + +--- a/drivers/mmc/host/sdhci-of-k1.c ++++ b/drivers/mmc/host/sdhci-of-k1.c +@@ -15,6 +15,7 @@ + #include + #include + #include ++#include + #include + + #include "sdhci.h" +@@ -223,6 +224,21 @@ static inline int spacemit_sdhci_get_clo + return 0; + } + ++static inline int spacemit_sdhci_get_resets(struct device *dev) ++{ ++ struct reset_control *rst; ++ ++ rst = devm_reset_control_get_optional_shared_deasserted(dev, "axi"); ++ if (IS_ERR(rst)) ++ return PTR_ERR(rst); ++ ++ rst = devm_reset_control_get_optional_exclusive_deasserted(dev, "sdh"); ++ if (IS_ERR(rst)) ++ return PTR_ERR(rst); ++ ++ return 0; ++} ++ + static const struct sdhci_ops spacemit_sdhci_ops = { + .get_max_clock = spacemit_sdhci_clk_get_max_clock, + .reset = spacemit_sdhci_reset, +@@ -284,6 +300,10 @@ static int spacemit_sdhci_probe(struct p + if (ret) + goto err_pltfm; + ++ ret = spacemit_sdhci_get_resets(dev); ++ if (ret) ++ goto err_pltfm; ++ + ret = sdhci_add_host(host); + if (ret) + goto err_pltfm; diff --git a/target/linux/spacemit/patches-6.18/0067-riscv-dts-spacemit-pcie-fix-missing-power-regulator.patch b/target/linux/spacemit/patches-6.18/0067-riscv-dts-spacemit-pcie-fix-missing-power-regulator.patch new file mode 100644 index 00000000000000..0f1ba3cf5d62a7 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0067-riscv-dts-spacemit-pcie-fix-missing-power-regulator.patch @@ -0,0 +1,38 @@ +From c1a84cb9d7907d853feb7f739b85456009564a49 Mon Sep 17 00:00:00 2001 +From: Yixun Lan +Date: Thu, 26 Feb 2026 08:17:55 +0000 +Subject: [PATCH] riscv: dts: spacemit: pcie: fix missing power regulator + +The PCIe port require 3.3v power regulator for device to work properly, So +explicitly add it to fix the DT warning: + +arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dtb: pcie@ca400000 (spacemit,k1-pcie): pcie@0: 'vpcie3v3-supply' is a required property + from schema $id: http://devicetree.org/schemas/pci/spacemit,k1-pcie-host.yaml + +Fixes: 0be016a4b5d1 ("riscv: dts: spacemit: PCIe and PHY-related updates") +Reported-by: Conor Dooley +Link: https://lore.kernel.org/r/20260226-k1-pcie-fix-pwr-v1-1-94b493cd27e5@kernel.org +Signed-off-by: Yixun Lan +(cherry picked from commit 8a9071299dec817a544c0fb48f7302396fafdc4b) +--- + arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts ++++ b/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts +@@ -305,6 +305,7 @@ + + &pcie1_port { + phys = <&pcie1_phy>; ++ vpcie3v3-supply = <&pcie_vcc_3v3>; + }; + + &pcie1 { +@@ -320,6 +321,7 @@ + + &pcie2_port { + phys = <&pcie2_phy>; ++ vpcie3v3-supply = <&pcie_vcc_3v3>; + }; + + &pcie2 { diff --git a/target/linux/spacemit/patches-6.18/0068-riscv-dts-spacemit-Update-PMIC-supply-properties-for.patch b/target/linux/spacemit/patches-6.18/0068-riscv-dts-spacemit-Update-PMIC-supply-properties-for.patch new file mode 100644 index 00000000000000..5f9471540ee183 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0068-riscv-dts-spacemit-Update-PMIC-supply-properties-for.patch @@ -0,0 +1,75 @@ +From fbc0d09059438c5d51a0ee34abe0919468a6225c Mon Sep 17 00:00:00 2001 +From: Guodong Xu +Date: Fri, 6 Feb 2026 10:32:04 +0800 +Subject: [PATCH] riscv: dts: spacemit: Update PMIC supply properties for + BPI-F3 and Jupiter + +Use per-regulator supply names in pmic "spacemit,p1" node to specify +each board's power tree topology and match the updated dt-binding. + +Signed-off-by: Guodong Xu +Reviewed-by: Alex Elder +Link: https://lore.kernel.org/r/20260206-spacemit-p1-v4-3-8f695d93811e@riscstar.com +Signed-off-by: Yixun Lan +(cherry picked from commit 108c77b34b929e6bdb7ac9613ed65c90da8bcb9f) +--- + arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts | 12 ++++++++++-- + arch/riscv/boot/dts/spacemit/k1-milkv-jupiter.dts | 12 ++++++++++-- + 2 files changed, 20 insertions(+), 4 deletions(-) + +--- a/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts ++++ b/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts +@@ -190,7 +190,15 @@ + compatible = "spacemit,p1"; + reg = <0x41>; + interrupts = <64>; +- vin-supply = <®_vcc_4v>; ++ vin1-supply = <®_vcc_4v>; ++ vin2-supply = <®_vcc_4v>; ++ vin3-supply = <®_vcc_4v>; ++ vin4-supply = <®_vcc_4v>; ++ vin5-supply = <®_vcc_4v>; ++ vin6-supply = <®_vcc_4v>; ++ aldoin-supply = <®_vcc_4v>; ++ dldoin1-supply = <&buck5>; ++ dldoin2-supply = <&buck5>; + + regulators { + buck1 { +@@ -221,7 +229,7 @@ + regulator-always-on; + }; + +- buck5 { ++ buck5: buck5 { + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <3450000>; + regulator-ramp-delay = <5000>; +--- a/arch/riscv/boot/dts/spacemit/k1-milkv-jupiter.dts ++++ b/arch/riscv/boot/dts/spacemit/k1-milkv-jupiter.dts +@@ -100,7 +100,15 @@ + compatible = "spacemit,p1"; + reg = <0x41>; + interrupts = <64>; +- vin-supply = <®_vcc_4v>; ++ vin1-supply = <®_vcc_4v>; ++ vin2-supply = <®_vcc_4v>; ++ vin3-supply = <®_vcc_4v>; ++ vin4-supply = <®_vcc_4v>; ++ vin5-supply = <®_vcc_4v>; ++ vin6-supply = <®_vcc_4v>; ++ aldoin-supply = <®_vcc_4v>; ++ dldoin1-supply = <&buck5>; ++ dldoin2-supply = <&buck5>; + + regulators { + buck1 { +@@ -131,7 +139,7 @@ + regulator-always-on; + }; + +- buck5 { ++ buck5: buck5 { + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <3450000>; + regulator-ramp-delay = <5000>; diff --git a/target/linux/spacemit/patches-6.18/0069-phy-k1-usb-add-disconnect-function-support.patch b/target/linux/spacemit/patches-6.18/0069-phy-k1-usb-add-disconnect-function-support.patch new file mode 100644 index 00000000000000..68ba54e93726e7 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0069-phy-k1-usb-add-disconnect-function-support.patch @@ -0,0 +1,52 @@ +From d4042d7c282e2f5210e7d348c9f4670a779ec3a2 Mon Sep 17 00:00:00 2001 +From: Yixun Lan +Date: Mon, 16 Feb 2026 23:26:53 +0800 +Subject: [PATCH] phy: k1-usb: add disconnect function support + +A disconnect status BIT of USB2 PHY need to be cleared, otherwise +it will fail to work properly during next connection when devices +connect to roothub directly. + +Fixes: fe4bc1a08638 ("phy: spacemit: support K1 USB2.0 PHY controller") +Signed-off-by: Yixun Lan +Reviewed-by: Vladimir Oltean +Link: https://patch.msgid.link/20260216152653.25244-1-dlan@kernel.org +Signed-off-by: Vinod Koul +(cherry picked from commit f0cf0a882a02dcf28547f32264f6fd37e9a7b147) +--- + drivers/phy/spacemit/phy-k1-usb2.c | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +--- a/drivers/phy/spacemit/phy-k1-usb2.c ++++ b/drivers/phy/spacemit/phy-k1-usb2.c +@@ -48,6 +48,9 @@ + #define PHY_CLK_HSTXP_EN BIT(3) /* clock hstxp enable */ + #define PHY_HSTXP_MODE BIT(4) /* 0: force en_txp to be 1; 1: no force */ + ++#define PHY_K1_HS_HOST_DISC 0x40 ++#define PHY_K1_HS_HOST_DISC_CLR BIT(0) ++ + #define PHY_PLL_DIV_CFG 0x98 + #define PHY_FDIV_FRACT_8_15 GENMASK(7, 0) + #define PHY_FDIV_FRACT_16_19 GENMASK(11, 8) +@@ -142,9 +145,20 @@ static int spacemit_usb2phy_exit(struct + return 0; + } + ++static int spacemit_usb2phy_disconnect(struct phy *phy, int port) ++{ ++ struct spacemit_usb2phy *sphy = phy_get_drvdata(phy); ++ ++ regmap_update_bits(sphy->regmap_base, PHY_K1_HS_HOST_DISC, ++ PHY_K1_HS_HOST_DISC_CLR, PHY_K1_HS_HOST_DISC_CLR); ++ ++ return 0; ++} ++ + static const struct phy_ops spacemit_usb2phy_ops = { + .init = spacemit_usb2phy_init, + .exit = spacemit_usb2phy_exit, ++ .disconnect = spacemit_usb2phy_disconnect, + .owner = THIS_MODULE, + }; + diff --git a/target/linux/spacemit/patches-6.18/0070-riscv-dts-spacemit-adapt-regulator-node-name-to-pref.patch b/target/linux/spacemit/patches-6.18/0070-riscv-dts-spacemit-adapt-regulator-node-name-to-pref.patch new file mode 100644 index 00000000000000..42948af3ed2748 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0070-riscv-dts-spacemit-adapt-regulator-node-name-to-pref.patch @@ -0,0 +1,88 @@ +From 2a27927f599b3140af40be2883e7ddfef1c10fec Mon Sep 17 00:00:00 2001 +From: Yixun Lan +Date: Thu, 26 Feb 2026 09:35:00 +0000 +Subject: [PATCH] riscv: dts: spacemit: adapt regulator node name to preferred + form + +The preferred node name for fixed-regulators has changed to pattern [1]: + '^regulator(-[0-9]+v[0-9]+|-[0-9a-z-]+)?$' + +Adjust all SpacemiT DT regulator node names to fix this. + +Reviewed-by: Javier Martinez Canillas +Link: https://lore.kernel.org/r/20240426215147.3138211-1-robh@kernel.org [1] +Link: https://lore.kernel.org/r/20260226-02-k1-regulator-names-v1-1-e87695d50159@kernel.org +Signed-off-by: Yixun Lan +(cherry picked from commit ec1fb4e55df47ed043ab2ccc6787e39b9d67e49b) +--- + arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts | 10 +++++----- + arch/riscv/boot/dts/spacemit/k1-milkv-jupiter.dts | 4 ++-- + 2 files changed, 7 insertions(+), 7 deletions(-) + +--- a/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts ++++ b/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts +@@ -33,7 +33,7 @@ + }; + }; + +- pcie_vcc_3v3: pcie-vcc3v3 { ++ pcie_vcc_3v3: regulator-pcie-vcc3v3 { + compatible = "regulator-fixed"; + regulator-name = "PCIE_VCC3V3"; + regulator-min-microvolt = <3300000>; +@@ -41,7 +41,7 @@ + regulator-always-on; + }; + +- reg_dc_in: dc-in-12v { ++ reg_dc_in: regulator-dc-in-12v { + compatible = "regulator-fixed"; + regulator-name = "dc_in_12v"; + regulator-min-microvolt = <12000000>; +@@ -50,7 +50,7 @@ + regulator-always-on; + }; + +- reg_vcc_4v: vcc-4v { ++ reg_vcc_4v: regulator-vcc-4v { + compatible = "regulator-fixed"; + regulator-name = "vcc_4v"; + regulator-min-microvolt = <4000000>; +@@ -60,7 +60,7 @@ + vin-supply = <®_dc_in>; + }; + +- usb3-vbus-5v { ++ regulator-usb3-vbus-5v { + compatible = "regulator-fixed"; + regulator-name = "USB30_VBUS"; + regulator-min-microvolt = <5000000>; +@@ -70,7 +70,7 @@ + enable-active-high; + }; + +- usb3_hub_5v: usb3-hub-5v { ++ usb3_hub_5v: regulator-usb3-hub-5v { + compatible = "regulator-fixed"; + regulator-name = "USB30_HUB"; + regulator-min-microvolt = <5000000>; +--- a/arch/riscv/boot/dts/spacemit/k1-milkv-jupiter.dts ++++ b/arch/riscv/boot/dts/spacemit/k1-milkv-jupiter.dts +@@ -21,7 +21,7 @@ + stdout-path = "serial0"; + }; + +- reg_dc_in: dc-in-12v { ++ reg_dc_in: regulator-dc-in-12v { + compatible = "regulator-fixed"; + regulator-name = "dc_in_12v"; + regulator-min-microvolt = <12000000>; +@@ -30,7 +30,7 @@ + regulator-always-on; + }; + +- reg_vcc_4v: vcc-4v { ++ reg_vcc_4v: regulator-vcc-4v { + compatible = "regulator-fixed"; + regulator-name = "vcc_4v"; + regulator-min-microvolt = <4000000>; diff --git a/target/linux/spacemit/patches-6.18/0071-riscv-dts-spacemit-Add-linux-pci-domain-to-PCIe-node.patch b/target/linux/spacemit/patches-6.18/0071-riscv-dts-spacemit-Add-linux-pci-domain-to-PCIe-node.patch new file mode 100644 index 00000000000000..49fd8dc88f674c --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0071-riscv-dts-spacemit-Add-linux-pci-domain-to-PCIe-node.patch @@ -0,0 +1,56 @@ +From 8e508921a7cddf292155d2b6f4c5c14171708ebf Mon Sep 17 00:00:00 2001 +From: Chukun Pan +Date: Mon, 9 Mar 2026 11:00:00 +0800 +Subject: [PATCH] riscv: dts: spacemit: Add 'linux,pci-domain' to PCIe nodes + for K1 + +The SpacemiT K1 SoC has 3 PCIe EP controller nodes. Add the +'linux,pci-domain' property to assign a PCI domain number to +each of the controllers instead of assigning it randomly. + +This creates a stable sysfs path, allowing userspace scripts +to reliably target specific PCIe devices (such as PCIe NICs). + +Signed-off-by: Chukun Pan +Reviewed-by: Yixun Lan +Link: https://lore.kernel.org/r/20260309030000.1157040-1-amadeus@jmu.edu.cn +Signed-off-by: Yixun Lan +(cherry picked from commit 86314111f654310a69c9775e35e263c036031675) +--- + arch/riscv/boot/dts/spacemit/k1.dtsi | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/arch/riscv/boot/dts/spacemit/k1.dtsi ++++ b/arch/riscv/boot/dts/spacemit/k1.dtsi +@@ -1033,6 +1033,7 @@ + #size-cells = <2>; + dma-ranges = <0x0 0x00000000 0x0 0x00000000 0x0 0x80000000>, + <0x0 0xb8000000 0x1 0x38000000 0x3 0x48000000>; ++ + pcie0: pcie@ca000000 { + device_type = "pci"; + compatible = "spacemit,k1-pcie"; +@@ -1044,6 +1045,7 @@ + "atu", + "config", + "link"; ++ linux,pci-domain = <0>; + #address-cells = <3>; + #size-cells = <2>; + ranges = <0x01000000 0x0 0x00000000 0x0 0x8f002000 0x0 0x00100000>, +@@ -1087,6 +1089,7 @@ + "atu", + "config", + "link"; ++ linux,pci-domain = <1>; + #address-cells = <3>; + #size-cells = <2>; + ranges = <0x01000000 0x0 0x00000000 0x0 0x9f002000 0x0 0x00100000>, +@@ -1130,6 +1133,7 @@ + "atu", + "config", + "link"; ++ linux,pci-domain = <2>; + #address-cells = <3>; + #size-cells = <2>; + ranges = <0x01000000 0x0 0x00000000 0x0 0xb7002000 0x0 0x00100000>, diff --git a/target/linux/spacemit/patches-6.18/0072-riscv-dts-spacemit-reorder-phy-nodes-for-K1.patch b/target/linux/spacemit/patches-6.18/0072-riscv-dts-spacemit-reorder-phy-nodes-for-K1.patch new file mode 100644 index 00000000000000..42431843999c13 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0072-riscv-dts-spacemit-reorder-phy-nodes-for-K1.patch @@ -0,0 +1,142 @@ +From 3164c05ecf1f9ab008d66f140db8d6b044283eab Mon Sep 17 00:00:00 2001 +From: Chukun Pan +Date: Wed, 18 Mar 2026 18:00:00 +0800 +Subject: [PATCH] riscv: dts: spacemit: reorder phy nodes for K1 + +Reorder the PHY nodes of USB and PCIe to the correct positions based on +the register address. This improves the readability and maintainability +of the DT. No functional change is introduced by this reordering. + +Signed-off-by: Chukun Pan +Reviewed-by: Yixun Lan +Link: https://lore.kernel.org/r/20260318100000.3934516-1-amadeus@jmu.edu.cn +Signed-off-by: Yixun Lan +(cherry picked from commit eac600d5cc42b04e799fb65169b8f4060773381b) +--- + arch/riscv/boot/dts/spacemit/k1.dtsi | 108 +++++++++++++-------------- + 1 file changed, 54 insertions(+), 54 deletions(-) + +--- a/arch/riscv/boot/dts/spacemit/k1.dtsi ++++ b/arch/riscv/boot/dts/spacemit/k1.dtsi +@@ -359,6 +359,60 @@ + #reset-cells = <1>; + }; + ++ usbphy2: phy@c0a30000 { ++ compatible = "spacemit,k1-usb2-phy"; ++ reg = <0x0 0xc0a30000 0x0 0x200>; ++ clocks = <&syscon_apmu CLK_USB30>; ++ #phy-cells = <0>; ++ status = "disabled"; ++ }; ++ ++ combo_phy: phy@c0b10000 { ++ compatible = "spacemit,k1-combo-phy"; ++ reg = <0x0 0xc0b10000 0x0 0x1000>; ++ clocks = <&vctcxo_24m>, ++ <&syscon_apmu CLK_PCIE0_DBI>, ++ <&syscon_apmu CLK_PCIE0_MASTER>, ++ <&syscon_apmu CLK_PCIE0_SLAVE>; ++ clock-names = "refclk", ++ "dbi", ++ "mstr", ++ "slv"; ++ resets = <&syscon_apmu RESET_PCIE0_GLOBAL>, ++ <&syscon_apmu RESET_PCIE0_DBI>, ++ <&syscon_apmu RESET_PCIE0_MASTER>, ++ <&syscon_apmu RESET_PCIE0_SLAVE>; ++ reset-names = "phy", ++ "dbi", ++ "mstr", ++ "slv"; ++ #phy-cells = <1>; ++ spacemit,apmu = <&syscon_apmu>; ++ status = "disabled"; ++ }; ++ ++ pcie1_phy: phy@c0c10000 { ++ compatible = "spacemit,k1-pcie-phy"; ++ reg = <0x0 0xc0c10000 0x0 0x1000>; ++ clocks = <&vctcxo_24m>; ++ clock-names = "refclk"; ++ resets = <&syscon_apmu RESET_PCIE1_GLOBAL>; ++ reset-names = "phy"; ++ #phy-cells = <0>; ++ status = "disabled"; ++ }; ++ ++ pcie2_phy: phy@c0d10000 { ++ compatible = "spacemit,k1-pcie-phy"; ++ reg = <0x0 0xc0d10000 0x0 0x1000>; ++ clocks = <&vctcxo_24m>; ++ clock-names = "refclk"; ++ resets = <&syscon_apmu RESET_PCIE2_GLOBAL>; ++ reset-names = "phy"; ++ #phy-cells = <0>; ++ status = "disabled"; ++ }; ++ + i2c0: i2c@d4010800 { + compatible = "spacemit,k1-i2c"; + reg = <0x0 0xd4010800 0x0 0x38>; +@@ -429,60 +483,6 @@ + status = "disabled"; + }; + +- usbphy2: phy@c0a30000 { +- compatible = "spacemit,k1-usb2-phy"; +- reg = <0x0 0xc0a30000 0x0 0x200>; +- clocks = <&syscon_apmu CLK_USB30>; +- #phy-cells = <0>; +- status = "disabled"; +- }; +- +- combo_phy: phy@c0b10000 { +- compatible = "spacemit,k1-combo-phy"; +- reg = <0x0 0xc0b10000 0x0 0x1000>; +- clocks = <&vctcxo_24m>, +- <&syscon_apmu CLK_PCIE0_DBI>, +- <&syscon_apmu CLK_PCIE0_MASTER>, +- <&syscon_apmu CLK_PCIE0_SLAVE>; +- clock-names = "refclk", +- "dbi", +- "mstr", +- "slv"; +- resets = <&syscon_apmu RESET_PCIE0_GLOBAL>, +- <&syscon_apmu RESET_PCIE0_DBI>, +- <&syscon_apmu RESET_PCIE0_MASTER>, +- <&syscon_apmu RESET_PCIE0_SLAVE>; +- reset-names = "phy", +- "dbi", +- "mstr", +- "slv"; +- #phy-cells = <1>; +- spacemit,apmu = <&syscon_apmu>; +- status = "disabled"; +- }; +- +- pcie1_phy: phy@c0c10000 { +- compatible = "spacemit,k1-pcie-phy"; +- reg = <0x0 0xc0c10000 0x0 0x1000>; +- clocks = <&vctcxo_24m>; +- clock-names = "refclk"; +- resets = <&syscon_apmu RESET_PCIE1_GLOBAL>; +- reset-names = "phy"; +- #phy-cells = <0>; +- status = "disabled"; +- }; +- +- pcie2_phy: phy@c0d10000 { +- compatible = "spacemit,k1-pcie-phy"; +- reg = <0x0 0xc0d10000 0x0 0x1000>; +- clocks = <&vctcxo_24m>; +- clock-names = "refclk"; +- resets = <&syscon_apmu RESET_PCIE2_GLOBAL>; +- reset-names = "phy"; +- #phy-cells = <0>; +- status = "disabled"; +- }; +- + syscon_apbc: system-controller@d4015000 { + compatible = "spacemit,k1-syscon-apbc"; + reg = <0x0 0xd4015000 0x0 0x1000>; diff --git a/target/linux/spacemit/patches-6.18/0073-pinctrl-spacemit-return-ENOTSUPP-for-unsupported-pin.patch b/target/linux/spacemit/patches-6.18/0073-pinctrl-spacemit-return-ENOTSUPP-for-unsupported-pin.patch new file mode 100644 index 00000000000000..d8dcd80683e5f4 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0073-pinctrl-spacemit-return-ENOTSUPP-for-unsupported-pin.patch @@ -0,0 +1,80 @@ +From afed68c93c80b3f40dacd7950d56bd01bd1690dd Mon Sep 17 00:00:00 2001 +From: Junhui Liu +Date: Thu, 12 Mar 2026 16:42:42 +0800 +Subject: [PATCH] pinctrl: spacemit: return -ENOTSUPP for unsupported pin + configurations + +Return -ENOTSUPP instead of -EINVAL when encountering unsupported pin +configuration parameters. This is more logical and allows the GPIO +subsystem to gracefully handle unsupported parameters via functions like +gpio_set_config_with_argument_optional(), which specifically ignores +-ENOTSUPP but treats others as failure. + +Signed-off-by: Junhui Liu +Reviewed-by: Anand Moon +Reviewed-by: Bartosz Golaszewski +Reviewed-by: Yixun Lan +Signed-off-by: Linus Walleij +(cherry picked from commit c3b0c06b73974d75c640a4ebc8678f8538654e5a) +--- + drivers/pinctrl/spacemit/pinctrl-k1.c | 21 ++++++++++++--------- + 1 file changed, 12 insertions(+), 9 deletions(-) + +--- a/drivers/pinctrl/spacemit/pinctrl-k1.c ++++ b/drivers/pinctrl/spacemit/pinctrl-k1.c +@@ -674,7 +674,7 @@ static int spacemit_pinconf_get(struct p + arg = 0; + break; + default: +- return -EINVAL; ++ return -ENOTSUPP; + } + + *config = pinconf_to_config_packed(param, arg); +@@ -740,7 +740,7 @@ static int spacemit_pinconf_generate_con + } + break; + default: +- return -EINVAL; ++ return -ENOTSUPP; + } + } + +@@ -814,10 +814,12 @@ static int spacemit_pinconf_set(struct p + struct spacemit_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); + const struct spacemit_pin *spin = spacemit_get_pin(pctrl, pin); + u32 value; ++ int ret; + +- if (spacemit_pinconf_generate_config(pctrl, spin, pctrl->data->dconf, +- configs, num_configs, &value)) +- return -EINVAL; ++ ret = spacemit_pinconf_generate_config(pctrl, spin, pctrl->data->dconf, ++ configs, num_configs, &value); ++ if (ret) ++ return ret; + + return spacemit_pin_set_config(pctrl, pin, value); + } +@@ -831,16 +833,17 @@ static int spacemit_pinconf_group_set(st + const struct spacemit_pin *spin; + const struct group_desc *group; + u32 value; +- int i; ++ int i, ret; + + group = pinctrl_generic_get_group(pctldev, gsel); + if (!group) + return -EINVAL; + + spin = spacemit_get_pin(pctrl, group->grp.pins[0]); +- if (spacemit_pinconf_generate_config(pctrl, spin, pctrl->data->dconf, +- configs, num_configs, &value)) +- return -EINVAL; ++ ret = spacemit_pinconf_generate_config(pctrl, spin, pctrl->data->dconf, ++ configs, num_configs, &value); ++ if (ret) ++ return ret; + + for (i = 0; i < group->grp.npins; i++) + spacemit_pin_set_config(pctrl, group->grp.pins[i], value); diff --git a/target/linux/spacemit/patches-6.18/0074-gpio-spacemit-k1-Add-set_config-callback-support.patch b/target/linux/spacemit/patches-6.18/0074-gpio-spacemit-k1-Add-set_config-callback-support.patch new file mode 100644 index 00000000000000..90b15c4b0cf453 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0074-gpio-spacemit-k1-Add-set_config-callback-support.patch @@ -0,0 +1,30 @@ +From c6b3cee654fa48a07216aa8b50083e4b2eef03dc Mon Sep 17 00:00:00 2001 +From: Junhui Liu +Date: Thu, 12 Mar 2026 16:42:43 +0800 +Subject: [PATCH] gpio: spacemit-k1: Add set_config callback support + +Assign gpiochip_generic_config() to the set_config() callback to support +pin configuration through the GPIO subsystem. This allows users to +configure GPIO pin attributes like pull-up/down when specifying a GPIO +line in the Device Tree. + +Signed-off-by: Junhui Liu +Reviewed-by: Anand Moon +Acked-by: Bartosz Golaszewski +Reviewed-by: Yixun Lan +Signed-off-by: Linus Walleij +(cherry picked from commit 47a9050e678c7929ada33c3f1f28ac4403423181) +--- + drivers/gpio/gpio-spacemit-k1.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/gpio/gpio-spacemit-k1.c ++++ b/drivers/gpio/gpio-spacemit-k1.c +@@ -228,6 +228,7 @@ static int spacemit_gpio_add_bank(struct + gc->label = dev_name(dev); + gc->request = gpiochip_generic_request; + gc->free = gpiochip_generic_free; ++ gc->set_config = gpiochip_generic_config; + gc->ngpio = SPACEMIT_NR_GPIOS_PER_BANK; + gc->base = -1; + gc->of_gpio_n_cells = 3; diff --git a/target/linux/spacemit/patches-6.18/0075-riscv-dts-spacemit-drop-incorrect-pinctrl-for-combo-.patch b/target/linux/spacemit/patches-6.18/0075-riscv-dts-spacemit-drop-incorrect-pinctrl-for-combo-.patch new file mode 100644 index 00000000000000..5e09fc5a163e36 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0075-riscv-dts-spacemit-drop-incorrect-pinctrl-for-combo-.patch @@ -0,0 +1,35 @@ +From 97a375fdd421fd0c4548565163574b857c035d11 Mon Sep 17 00:00:00 2001 +From: Aurelien Jarno +Date: Sun, 22 Mar 2026 21:25:01 +0100 +Subject: [PATCH] riscv: dts: spacemit: drop incorrect pinctrl for combo PHY + +The combo PHY on the Banana Pi F3 is used for the USB 3.0 port. The high +speed differential lanes are always configured as such, and do not +require a pinctrl entry. + +The existing pinctrl entry only configures PCIe secondary pins, which +are unused for USB and instead routed to the MIPI CSI1 connector. + +Remove this incorrect pinctrl entry. + +Fixes: 0be016a4b5d1b9 ("riscv: dts: spacemit: PCIe and PHY-related updates") +Signed-off-by: Aurelien Jarno +Reviewed-by: Yixun Lan +Link: https://lore.kernel.org/r/20260322202502.2205755-1-aurelien@aurel32.net +Signed-off-by: Yixun Lan +(cherry picked from commit c68360c0d636dae71f766b7b296ddfcf2827ccc7) +--- + arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts | 2 -- + 1 file changed, 2 deletions(-) + +--- a/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts ++++ b/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts +@@ -81,8 +81,6 @@ + }; + + &combo_phy { +- pinctrl-names = "default"; +- pinctrl-0 = <&pcie0_3_cfg>; + status = "okay"; + }; + diff --git a/target/linux/spacemit/patches-6.18/0076-riscv-dts-spacemit-add-LEDs-for-Milk-V-Jupiter-board.patch b/target/linux/spacemit/patches-6.18/0076-riscv-dts-spacemit-add-LEDs-for-Milk-V-Jupiter-board.patch new file mode 100644 index 00000000000000..cd21ebce980c4b --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0076-riscv-dts-spacemit-add-LEDs-for-Milk-V-Jupiter-board.patch @@ -0,0 +1,53 @@ +From 2223303b88e1265d09fa56d2c6c8504a176eee82 Mon Sep 17 00:00:00 2001 +From: Aurelien Jarno +Date: Thu, 26 Mar 2026 19:35:29 +0100 +Subject: [PATCH] riscv: dts: spacemit: add LEDs for Milk-V Jupiter board + +The Milk-V Jupiter board provides support for two LEDs through the front +panel header. The "Power LED" indicates the system is running, and the +"HDD LED" shows disk activity. Configure the corresponding LED triggers +accordingly. + +Caveats: +- The LEDs are driven through a 4.7k series resistor, making them + quite faint. +- The disk activity trigger requires a storage controller on the M.2 or + PCIe interface. That said, it matches the purpose and the vendor + kernel. + +Signed-off-by: Aurelien Jarno +Reviewed-by: Javier Martinez Canillas +Reviewed-by: Yixun Lan +Link: https://lore.kernel.org/r/20260326183745.1370642-2-aurelien@aurel32.net +Signed-off-by: Yixun Lan +(cherry picked from commit 334e64abacd3df4005de80b082d0dbf02b453c76) +--- + .../boot/dts/spacemit/k1-milkv-jupiter.dts | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + +--- a/arch/riscv/boot/dts/spacemit/k1-milkv-jupiter.dts ++++ b/arch/riscv/boot/dts/spacemit/k1-milkv-jupiter.dts +@@ -21,6 +21,23 @@ + stdout-path = "serial0"; + }; + ++ leds { ++ compatible = "gpio-leds"; ++ ++ led1 { ++ label = "pwr-led"; ++ gpios = <&gpio K1_GPIO(96) GPIO_ACTIVE_HIGH>; ++ linux,default-trigger = "default-on"; ++ default-state = "on"; ++ }; ++ ++ led2 { ++ label = "hdd-led"; ++ gpios = <&gpio K1_GPIO(92) GPIO_ACTIVE_HIGH>; ++ linux,default-trigger = "disk-activity"; ++ }; ++ }; ++ + reg_dc_in: regulator-dc-in-12v { + compatible = "regulator-fixed"; + regulator-name = "dc_in_12v"; diff --git a/target/linux/spacemit/patches-6.18/0077-riscv-dts-spacemit-add-24c04-eeprom-on-Milk-V-Jupite.patch b/target/linux/spacemit/patches-6.18/0077-riscv-dts-spacemit-add-24c04-eeprom-on-Milk-V-Jupite.patch new file mode 100644 index 00000000000000..787d353bec8443 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0077-riscv-dts-spacemit-add-24c04-eeprom-on-Milk-V-Jupite.patch @@ -0,0 +1,54 @@ +From cc6d5c1d4bd2ed04b2a3b8761284878968dd9be1 Mon Sep 17 00:00:00 2001 +From: Aurelien Jarno +Date: Thu, 26 Mar 2026 19:35:30 +0100 +Subject: [PATCH] riscv: dts: spacemit: add 24c04 eeprom on Milk-V Jupiter + +The Milk-V Jupiter board includes a 24c04 eeprom on the i2c2 bus. The +eeprom contains an ONIE TLV table, which on the board I tested only +provides a product-name entry. Expose it via an onie,tlv-layout nvmem +layout. + +The eeprom is marked as read-only since its contents are not supposed to +be modified. + +Signed-off-by: Aurelien Jarno +Reviewed-by: Javier Martinez Canillas +Reviewed-by: Yixun Lan +Link: https://lore.kernel.org/r/20260326183745.1370642-3-aurelien@aurel32.net +Signed-off-by: Yixun Lan +(cherry picked from commit 77156216f1d0f57e1cfce3452410db20468edca4) +--- + .../boot/dts/spacemit/k1-milkv-jupiter.dts | 22 +++++++++++++++++++ + 1 file changed, 22 insertions(+) + +--- a/arch/riscv/boot/dts/spacemit/k1-milkv-jupiter.dts ++++ b/arch/riscv/boot/dts/spacemit/k1-milkv-jupiter.dts +@@ -108,6 +108,28 @@ + status = "okay"; + }; + ++&i2c2 { ++ pinctrl-0 = <&i2c2_0_cfg>; ++ pinctrl-names = "default"; ++ status = "okay"; ++ ++ eeprom@50 { ++ compatible = "atmel,24c04"; ++ reg = <0x50>; ++ vcc-supply = <&buck3_1v8>; /* EEPROM_VCC18 */ ++ pagesize = <16>; ++ read-only; ++ size = <512>; ++ ++ nvmem-layout { ++ compatible = "onie,tlv-layout"; ++ ++ product-name { ++ }; ++ }; ++ }; ++}; ++ + &i2c8 { + pinctrl-0 = <&i2c8_cfg>; + pinctrl-names = "default"; diff --git a/target/linux/spacemit/patches-6.18/0078-riscv-dts-spacemit-add-i2c-aliases-on-Milk-V-Jupiter.patch b/target/linux/spacemit/patches-6.18/0078-riscv-dts-spacemit-add-i2c-aliases-on-Milk-V-Jupiter.patch new file mode 100644 index 00000000000000..033cf451937115 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0078-riscv-dts-spacemit-add-i2c-aliases-on-Milk-V-Jupiter.patch @@ -0,0 +1,30 @@ +From f3170ec2c0ba3f96adcc1ae033a43747f05022d0 Mon Sep 17 00:00:00 2001 +From: Aurelien Jarno +Date: Thu, 26 Mar 2026 19:35:31 +0100 +Subject: [PATCH] riscv: dts: spacemit: add i2c aliases on Milk-V Jupiter + +Add i2c aliases for i2c2 and i2c8 on Milk-V Jupiter. This is useful to +keep a stable number for the /dev entries after loading the i2c-dev +module. + +Signed-off-by: Aurelien Jarno +Reviewed-by: Javier Martinez Canillas +Reviewed-by: Yixun Lan +Link: https://lore.kernel.org/r/20260326183745.1370642-4-aurelien@aurel32.net +Signed-off-by: Yixun Lan +(cherry picked from commit 7af5edec73d5d69618541f91600adeb6f35b7d17) +--- + arch/riscv/boot/dts/spacemit/k1-milkv-jupiter.dts | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/arch/riscv/boot/dts/spacemit/k1-milkv-jupiter.dts ++++ b/arch/riscv/boot/dts/spacemit/k1-milkv-jupiter.dts +@@ -15,6 +15,8 @@ + ethernet0 = ð0; + ethernet1 = ð1; + serial0 = &uart0; ++ i2c2 = &i2c2; ++ i2c8 = &i2c8; + }; + + chosen { diff --git a/target/linux/spacemit/patches-6.18/0079-riscv-dts-spacemit-enable-QSPI-and-add-SPI-NOR-on-Mi.patch b/target/linux/spacemit/patches-6.18/0079-riscv-dts-spacemit-enable-QSPI-and-add-SPI-NOR-on-Mi.patch new file mode 100644 index 00000000000000..1f06937b7b2b5b --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0079-riscv-dts-spacemit-enable-QSPI-and-add-SPI-NOR-on-Mi.patch @@ -0,0 +1,89 @@ +From ddeeaf321f06a96a833e0a462101acda3cd292ed Mon Sep 17 00:00:00 2001 +From: Aurelien Jarno +Date: Thu, 26 Mar 2026 19:35:32 +0100 +Subject: [PATCH] riscv: dts: spacemit: enable QSPI and add SPI NOR on Milk-V + Jupiter + +Add the QSPI controller node for the Milk-V Jupiter board and describe +the attached SPI NOR flash (GD25Q64E). + +The flash supports a frequency up to 133MHz (80 MHz for reads), and the +SoC supports a frequency up to 104 MHz. However tests have shown that +the flash is not reliably detected above 26.5 MHz, consistent with +frequency used in the vendor kernel. Therefore, use this frequency. + +The m25p,fast-read properties is taken from the vendor kernel, and the +GD25Q64E datasheet confirms tha the fast read opcodes are supported. + +Add a corresponding flash partition layout, matching the layout and the +names used in the vendor U-Boot. + +Signed-off-by: Aurelien Jarno +Reviewed-by: Javier Martinez Canillas +Reviewed-by: Yixun Lan +Link: https://lore.kernel.org/r/20260326183745.1370642-5-aurelien@aurel32.net +Signed-off-by: Yixun Lan +(cherry picked from commit 2829823956f0f590f5c6b4eafed2dab7a96f69b3) +--- + .../boot/dts/spacemit/k1-milkv-jupiter.dts | 43 ++++++++++++++++++- + 1 file changed, 42 insertions(+), 1 deletion(-) + +--- a/arch/riscv/boot/dts/spacemit/k1-milkv-jupiter.dts ++++ b/arch/riscv/boot/dts/spacemit/k1-milkv-jupiter.dts +@@ -173,7 +173,7 @@ + regulator-always-on; + }; + +- buck4 { ++ buck4_3v3: buck4 { + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <3300000>; + regulator-ramp-delay = <5000>; +@@ -254,6 +254,47 @@ + }; + }; + }; ++}; ++ ++&qspi { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&qspi_cfg>; ++ status = "okay"; ++ ++ flash@0 { ++ compatible = "jedec,spi-nor"; ++ reg = <0>; ++ spi-max-frequency = <26500000>; ++ spi-rx-bus-width = <4>; ++ spi-tx-bus-width = <4>; ++ vcc-supply = <&buck4_3v3>; /* QSPI_VCC1833 */ ++ m25p,fast-read; ++ ++ partitions { ++ compatible = "fixed-partitions"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ bootinfo@0 { ++ reg = <0x0 0x10000>; ++ }; ++ private@10000 { ++ reg = <0x10000 0x10000>; ++ }; ++ fsbl@20000 { ++ reg = <0x20000 0x40000>; ++ }; ++ env@60000 { ++ reg = <0x60000 0x10000>; ++ }; ++ opensbi@70000 { ++ reg = <0x70000 0x30000>; ++ }; ++ uboot@a00000 { ++ reg = <0xa0000 0x760000>; ++ }; ++ }; ++ }; + }; + + &uart0 { diff --git a/target/linux/spacemit/patches-6.18/0080-riscv-dts-spacemit-enable-USB-3-ports-on-Milk-V-Jupi.patch b/target/linux/spacemit/patches-6.18/0080-riscv-dts-spacemit-enable-USB-3-ports-on-Milk-V-Jupi.patch new file mode 100644 index 00000000000000..ad15f46fe09bef --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0080-riscv-dts-spacemit-enable-USB-3-ports-on-Milk-V-Jupi.patch @@ -0,0 +1,105 @@ +From 4bc33146d82834cc8785415f9e6b99e2919eea02 Mon Sep 17 00:00:00 2001 +From: Aurelien Jarno +Date: Thu, 26 Mar 2026 19:35:33 +0100 +Subject: [PATCH] riscv: dts: spacemit: enable USB 3 ports on Milk-V Jupiter + +Enable the DWC3 USB 3.0 controller (USB#2 port in the K1 datasheet) and +its associated combo_phy (USB 3 PHY) and usbphy2 (USB 2 PHY) on the +Milk-V Jupiter board. + +The board uses a VLI VL817 hub, providing four ports. Two are routed to +the 3.0 type-A connectors, and two to the F_USB3 front USB header. The +hub requires two separate 5V power supplies: one for the hub itself and +one for the USB connectors. Add an always-on regulator sourcing 5V from +the DC-IN input, along with two GPIO-controlled fixed regulators to +manage the hub and connectors power supplies. + +Note that the board also provides four USB 2.0 ports (two via type-A +connectors and two via the F_USB2 front USB header), but these are +handled by a different controller (USB#1 port in the K1 datasheet). + +Signed-off-by: Aurelien Jarno +Reviewed-by: Javier Martinez Canillas +Reviewed-by: Yixun Lan +Link: https://lore.kernel.org/r/20260326183745.1370642-6-aurelien@aurel32.net +Signed-off-by: Yixun Lan +(cherry picked from commit dce01d8585a22f708b5f1eb621cacd9878258ac8) +--- + .../boot/dts/spacemit/k1-milkv-jupiter.dts | 62 +++++++++++++++++++ + 1 file changed, 62 insertions(+) + +--- a/arch/riscv/boot/dts/spacemit/k1-milkv-jupiter.dts ++++ b/arch/riscv/boot/dts/spacemit/k1-milkv-jupiter.dts +@@ -58,6 +58,41 @@ + regulator-always-on; + vin-supply = <®_dc_in>; + }; ++ ++ reg_vcc_5v: regulator-vcc-5v { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc_5v"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ regulator-boot-on; ++ regulator-always-on; ++ vin-supply = <®_dc_in>; ++ }; ++ ++ regulator-usb3-vbus-5v { ++ compatible = "regulator-fixed"; ++ regulator-name = "USB30_VBUS"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ regulator-always-on; ++ vin-supply = <®_vcc_5v>; ++ gpio = <&gpio K1_GPIO(97) GPIO_ACTIVE_HIGH>; ++ enable-active-high; ++ }; ++ ++ usb3_hub_5v: regulator-usb3-hub-5v { ++ compatible = "regulator-fixed"; ++ regulator-name = "USB30_HUB"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ vin-supply = <®_vcc_5v>; ++ gpio = <&gpio K1_GPIO(123) GPIO_ACTIVE_HIGH>; ++ enable-active-high; ++ }; ++}; ++ ++&combo_phy { ++ status = "okay"; + }; + + ð0 { +@@ -302,3 +337,30 @@ + pinctrl-0 = <&uart0_2_cfg>; + status = "okay"; + }; ++ ++&usbphy2 { ++ status = "okay"; ++}; ++ ++&usb_dwc3 { ++ dr_mode = "host"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ hub_2_0: hub@1 { ++ compatible = "usb2109,2817"; ++ reg = <0x1>; ++ vdd-supply = <&usb3_hub_5v>; ++ peer-hub = <&hub_3_0>; ++ reset-gpios = <&gpio K1_GPIO(124) GPIO_ACTIVE_LOW>; ++ }; ++ ++ hub_3_0: hub@2 { ++ compatible = "usb2109,817"; ++ reg = <0x2>; ++ vdd-supply = <&usb3_hub_5v>; ++ peer-hub = <&hub_2_0>; ++ reset-gpios = <&gpio K1_GPIO(124) GPIO_ACTIVE_LOW>; ++ }; ++}; diff --git a/target/linux/spacemit/patches-6.18/0081-riscv-dts-spacemit-enable-PCIe-ports-on-Milk-V-Jupit.patch b/target/linux/spacemit/patches-6.18/0081-riscv-dts-spacemit-enable-PCIe-ports-on-Milk-V-Jupit.patch new file mode 100644 index 00000000000000..278f594bef8e5c --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0081-riscv-dts-spacemit-enable-PCIe-ports-on-Milk-V-Jupit.patch @@ -0,0 +1,79 @@ +From 055d3b8fb33259af68f67e599fe4f04a365f3873 Mon Sep 17 00:00:00 2001 +From: Aurelien Jarno +Date: Thu, 26 Mar 2026 19:35:34 +0100 +Subject: [PATCH] riscv: dts: spacemit: enable PCIe ports on Milk-V Jupiter + +Enable the two PCIe controller along with and their associated PHY. They +are routed to the M.2 M-key connector and to the PCIe x8 slot. + +Add an always-on regulator sourcing 3.3V from the DC-IN input, to power +the PCIe ports. + +Signed-off-by: Aurelien Jarno +Reviewed-by: Javier Martinez Canillas +Reviewed-by: Yixun Lan +Link: https://lore.kernel.org/r/20260326183745.1370642-7-aurelien@aurel32.net +Signed-off-by: Yixun Lan +(cherry picked from commit 2b8bd26bbfcdeb1a06127dcd8f9101080133f2a1) +--- + .../boot/dts/spacemit/k1-milkv-jupiter.dts | 42 +++++++++++++++++++ + 1 file changed, 42 insertions(+) + +--- a/arch/riscv/boot/dts/spacemit/k1-milkv-jupiter.dts ++++ b/arch/riscv/boot/dts/spacemit/k1-milkv-jupiter.dts +@@ -40,6 +40,16 @@ + }; + }; + ++ pcie_vcc_3v3: regulator-pcie-vcc3v3 { ++ compatible = "regulator-fixed"; ++ regulator-name = "pcie_vcc3v3"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-boot-on; ++ regulator-always-on; ++ vin-supply = <®_dc_in>; ++ }; ++ + reg_dc_in: regulator-dc-in-12v { + compatible = "regulator-fixed"; + regulator-name = "dc_in_12v"; +@@ -291,6 +301,38 @@ + }; + }; + ++&pcie1_phy { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pcie1_3_cfg>; ++ status = "okay"; ++}; ++ ++&pcie1_port { ++ phys = <&pcie1_phy>; ++ vpcie3v3-supply = <&pcie_vcc_3v3>; ++}; ++ ++&pcie1 { ++ vpcie3v3-supply = <&pcie_vcc_3v3>; ++ status = "okay"; ++}; ++ ++&pcie2_phy { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pcie2_4_cfg>; ++ status = "okay"; ++}; ++ ++&pcie2_port { ++ phys = <&pcie2_phy>; ++ vpcie3v3-supply = <&pcie_vcc_3v3>; ++}; ++ ++&pcie2 { ++ vpcie3v3-supply = <&pcie_vcc_3v3>; ++ status = "okay"; ++}; ++ + &qspi { + pinctrl-names = "default"; + pinctrl-0 = <&qspi_cfg>; diff --git a/target/linux/spacemit/patches-6.18/0082-i2c-spacemit-move-i2c_xfer_msg.patch b/target/linux/spacemit/patches-6.18/0082-i2c-spacemit-move-i2c_xfer_msg.patch new file mode 100644 index 00000000000000..a588f6d5fec745 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0082-i2c-spacemit-move-i2c_xfer_msg.patch @@ -0,0 +1,101 @@ +From 14708675e682e359ea52c94c78a61855a2d90c3e Mon Sep 17 00:00:00 2001 +From: Troy Mitchell +Date: Sat, 7 Feb 2026 23:08:21 +0800 +Subject: [PATCH] i2c: spacemit: move i2c_xfer_msg() + +The upcoming PIO support requires a wait_pio_xfer() helper, which is +invoked from xfer_msg(). + +Since wait_pio_xfer() depends on err_check(), move the definition of +xfer_msg() after err_check() to avoid a forward declaration of +err_check(). + +Reviewed-by: Aurelien Jarno +Reviewed-by: Alex Elder +Signed-off-by: Troy Mitchell +Tested-by: Aurelien Jarno +Signed-off-by: Andi Shyti +Link: https://lore.kernel.org/r/20260207-b4-k3-i2c-pio-v7-1-626942d94d91@linux.spacemit.com +(cherry picked from commit 5b74da8e6cf7e2b5aed0836c733238c0fd7235af) +--- + drivers/i2c/busses/i2c-k1.c | 62 ++++++++++++++++++------------------- + 1 file changed, 31 insertions(+), 31 deletions(-) + +--- a/drivers/i2c/busses/i2c-k1.c ++++ b/drivers/i2c/busses/i2c-k1.c +@@ -305,37 +305,6 @@ static void spacemit_i2c_start(struct sp + writel(val, i2c->base + SPACEMIT_ICR); + } + +-static int spacemit_i2c_xfer_msg(struct spacemit_i2c_dev *i2c) +-{ +- unsigned long time_left; +- struct i2c_msg *msg; +- +- for (i2c->msg_idx = 0; i2c->msg_idx < i2c->msg_num; i2c->msg_idx++) { +- msg = &i2c->msgs[i2c->msg_idx]; +- i2c->msg_buf = msg->buf; +- i2c->unprocessed = msg->len; +- i2c->status = 0; +- +- reinit_completion(&i2c->complete); +- +- spacemit_i2c_start(i2c); +- +- time_left = wait_for_completion_timeout(&i2c->complete, +- i2c->adapt.timeout); +- if (!time_left) { +- dev_err(i2c->dev, "msg completion timeout\n"); +- spacemit_i2c_conditionally_reset_bus(i2c); +- spacemit_i2c_reset(i2c); +- return -ETIMEDOUT; +- } +- +- if (i2c->status & SPACEMIT_SR_ERR) +- return spacemit_i2c_handle_err(i2c); +- } +- +- return 0; +-} +- + static bool spacemit_i2c_is_last_msg(struct spacemit_i2c_dev *i2c) + { + if (i2c->msg_idx != i2c->msg_num - 1) +@@ -419,6 +388,37 @@ static void spacemit_i2c_err_check(struc + complete(&i2c->complete); + } + ++static int spacemit_i2c_xfer_msg(struct spacemit_i2c_dev *i2c) ++{ ++ unsigned long time_left; ++ struct i2c_msg *msg; ++ ++ for (i2c->msg_idx = 0; i2c->msg_idx < i2c->msg_num; i2c->msg_idx++) { ++ msg = &i2c->msgs[i2c->msg_idx]; ++ i2c->msg_buf = msg->buf; ++ i2c->unprocessed = msg->len; ++ i2c->status = 0; ++ ++ reinit_completion(&i2c->complete); ++ ++ spacemit_i2c_start(i2c); ++ ++ time_left = wait_for_completion_timeout(&i2c->complete, ++ i2c->adapt.timeout); ++ if (!time_left) { ++ dev_err(i2c->dev, "msg completion timeout\n"); ++ spacemit_i2c_conditionally_reset_bus(i2c); ++ spacemit_i2c_reset(i2c); ++ return -ETIMEDOUT; ++ } ++ ++ if (i2c->status & SPACEMIT_SR_ERR) ++ return spacemit_i2c_handle_err(i2c); ++ } ++ ++ return 0; ++} ++ + static irqreturn_t spacemit_i2c_irq_handler(int irq, void *devid) + { + struct spacemit_i2c_dev *i2c = devid; diff --git a/target/linux/spacemit/patches-6.18/0083-i2c-spacemit-introduce-pio-for-k1.patch b/target/linux/spacemit/patches-6.18/0083-i2c-spacemit-introduce-pio-for-k1.patch new file mode 100644 index 00000000000000..18cea237575e36 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0083-i2c-spacemit-introduce-pio-for-k1.patch @@ -0,0 +1,480 @@ +From 96dffc55831497bd4a5740c461b05a612051a93f Mon Sep 17 00:00:00 2001 +From: Troy Mitchell +Date: Sat, 7 Feb 2026 23:08:22 +0800 +Subject: [PATCH] i2c: spacemit: introduce pio for k1 + +This patch introduces I2C PIO functionality for the Spacemit K1 SoC, +enabling the use of I2C in atomic context. + +When i2c xfer_atomic is invoked, use_pio is set accordingly. + +Since an atomic context is required, all interrupts are disabled when +operating in PIO mode. Even with interrupts disabled, the bits in the +ISR (Interrupt Status Register) will still be set, so error handling can +be performed by polling the relevant status bits in the ISR. + +Signed-off-by: Troy Mitchell +Tested-by: Aurelien Jarno +Reviewed-by: Aurelien Jarno +Signed-off-by: Andi Shyti +Link: https://lore.kernel.org/r/20260207-b4-k3-i2c-pio-v7-2-626942d94d91@linux.spacemit.com +(cherry picked from commit 5dd75dac1b35e5b24f5051d01fc85105adcc2e15) +--- + drivers/i2c/busses/i2c-k1.c | 300 +++++++++++++++++++++++++++--------- + 1 file changed, 228 insertions(+), 72 deletions(-) + +--- a/drivers/i2c/busses/i2c-k1.c ++++ b/drivers/i2c/busses/i2c-k1.c +@@ -98,6 +98,10 @@ + + #define SPACEMIT_BUS_RESET_CLK_CNT_MAX 9 + ++#define SPACEMIT_WAIT_TIMEOUT 1000 /* ms */ ++#define SPACEMIT_POLL_TIMEOUT 1000 /* us */ ++#define SPACEMIT_POLL_INTERVAL 30 /* us */ ++ + enum spacemit_i2c_state { + SPACEMIT_STATE_IDLE, + SPACEMIT_STATE_START, +@@ -126,6 +130,7 @@ struct spacemit_i2c_dev { + + enum spacemit_i2c_state state; + bool read; ++ bool use_pio; + struct completion complete; + u32 status; + }; +@@ -172,6 +177,14 @@ static int spacemit_i2c_handle_err(struc + return i2c->status & SPACEMIT_SR_ACKNAK ? -ENXIO : -EIO; + } + ++static inline void spacemit_i2c_delay(struct spacemit_i2c_dev *i2c, unsigned int us) ++{ ++ if (i2c->use_pio) ++ udelay(us); ++ else ++ fsleep(us); ++} ++ + static void spacemit_i2c_conditionally_reset_bus(struct spacemit_i2c_dev *i2c) + { + u32 status; +@@ -183,7 +196,8 @@ static void spacemit_i2c_conditionally_r + return; + + spacemit_i2c_reset(i2c); +- usleep_range(10, 20); ++ ++ spacemit_i2c_delay(i2c, 10); + + for (clk_cnt = 0; clk_cnt < SPACEMIT_BUS_RESET_CLK_CNT_MAX; clk_cnt++) { + status = readl(i2c->base + SPACEMIT_IBMR); +@@ -212,9 +226,15 @@ static int spacemit_i2c_wait_bus_idle(st + if (!(val & (SPACEMIT_SR_UB | SPACEMIT_SR_IBB))) + return 0; + +- ret = readl_poll_timeout(i2c->base + SPACEMIT_ISR, +- val, !(val & (SPACEMIT_SR_UB | SPACEMIT_SR_IBB)), +- 1500, SPACEMIT_I2C_BUS_BUSY_TIMEOUT); ++ if (i2c->use_pio) ++ ret = readl_poll_timeout_atomic(i2c->base + SPACEMIT_ISR, ++ val, !(val & (SPACEMIT_SR_UB | SPACEMIT_SR_IBB)), ++ 1500, SPACEMIT_I2C_BUS_BUSY_TIMEOUT); ++ else ++ ret = readl_poll_timeout(i2c->base + SPACEMIT_ISR, ++ val, !(val & (SPACEMIT_SR_UB | SPACEMIT_SR_IBB)), ++ 1500, SPACEMIT_I2C_BUS_BUSY_TIMEOUT); ++ + if (ret) + spacemit_i2c_reset(i2c); + +@@ -226,7 +246,7 @@ static void spacemit_i2c_check_bus_relea + /* in case bus is not released after transfer completes */ + if (readl(i2c->base + SPACEMIT_ISR) & SPACEMIT_SR_EBB) { + spacemit_i2c_conditionally_reset_bus(i2c); +- usleep_range(90, 150); ++ spacemit_i2c_delay(i2c, 90); + } + } + +@@ -238,25 +258,33 @@ spacemit_i2c_clear_int_status(struct spa + + static void spacemit_i2c_init(struct spacemit_i2c_dev *i2c) + { +- u32 val; +- +- /* +- * Unmask interrupt bits for all xfer mode: +- * bus error, arbitration loss detected. +- * For transaction complete signal, we use master stop +- * interrupt, so we don't need to unmask SPACEMIT_CR_TXDONEIE. +- */ +- val = SPACEMIT_CR_BEIE | SPACEMIT_CR_ALDIE; ++ u32 val = 0; + +- /* +- * Unmask interrupt bits for interrupt xfer mode: +- * When IDBR receives a byte, an interrupt is triggered. +- * +- * For the tx empty interrupt, it will be enabled in the +- * i2c_start function. +- * Otherwise, it will cause an erroneous empty interrupt before i2c_start. +- */ +- val |= SPACEMIT_CR_DRFIE; ++ if (!i2c->use_pio) { ++ /* ++ * Enable interrupt bits for all xfer mode: ++ * bus error, arbitration loss detected. ++ */ ++ val |= SPACEMIT_CR_BEIE | SPACEMIT_CR_ALDIE; ++ ++ /* ++ * Unmask interrupt bits for interrupt xfer mode: ++ * When IDBR receives a byte, an interrupt is triggered. ++ * ++ * For the tx empty interrupt, it will be enabled in the ++ * i2c_start(). ++ * We don't want a TX empty interrupt until we start ++ * a transfer in i2c_start(). ++ */ ++ val |= SPACEMIT_CR_DRFIE; ++ ++ /* ++ * Enable master stop interrupt bit. ++ * For transaction complete signal, we use master stop ++ * interrupt, so we don't need to unmask SPACEMIT_CR_TXDONEIE. ++ */ ++ val |= SPACEMIT_CR_MSDIE; ++ } + + if (i2c->clock_freq == SPACEMIT_I2C_MAX_FAST_MODE_FREQ) + val |= SPACEMIT_CR_MODE_FAST; +@@ -268,7 +296,7 @@ static void spacemit_i2c_init(struct spa + val |= SPACEMIT_CR_SCLE; + + /* enable master stop detected */ +- val |= SPACEMIT_CR_MSDE | SPACEMIT_CR_MSDIE; ++ val |= SPACEMIT_CR_MSDE; + + writel(val, i2c->base + SPACEMIT_ICR); + +@@ -301,7 +329,12 @@ static void spacemit_i2c_start(struct sp + /* send start pulse */ + val = readl(i2c->base + SPACEMIT_ICR); + val &= ~SPACEMIT_CR_STOP; +- val |= SPACEMIT_CR_START | SPACEMIT_CR_TB | SPACEMIT_CR_DTEIE; ++ val |= SPACEMIT_CR_START | SPACEMIT_CR_TB; ++ ++ /* Enable the TX empty interrupt */ ++ if (!i2c->use_pio) ++ val |= SPACEMIT_CR_DTEIE; ++ + writel(val, i2c->base + SPACEMIT_ICR); + } + +@@ -316,8 +349,23 @@ static bool spacemit_i2c_is_last_msg(str + return !i2c->unprocessed; + } + ++static inline void spacemit_i2c_complete(struct spacemit_i2c_dev *i2c) ++{ ++ /* SPACEMIT_STATE_IDLE avoids triggering the next byte */ ++ i2c->state = SPACEMIT_STATE_IDLE; ++ ++ if (i2c->use_pio) ++ return; ++ ++ complete(&i2c->complete); ++} ++ + static void spacemit_i2c_handle_write(struct spacemit_i2c_dev *i2c) + { ++ /* If there's no space in the IDBR, we're done */ ++ if (!(i2c->status & SPACEMIT_SR_ITE)) ++ return; ++ + /* if transfer completes, SPACEMIT_ISR will handle it */ + if (i2c->status & SPACEMIT_SR_MSD) + return; +@@ -328,16 +376,19 @@ static void spacemit_i2c_handle_write(st + return; + } + +- /* SPACEMIT_STATE_IDLE avoids trigger next byte */ +- i2c->state = SPACEMIT_STATE_IDLE; +- complete(&i2c->complete); ++ spacemit_i2c_complete(i2c); + } + + static void spacemit_i2c_handle_read(struct spacemit_i2c_dev *i2c) + { ++ /* If there's nothing in the IDBR, we're done */ ++ if (!(i2c->status & SPACEMIT_SR_IRF)) ++ return; ++ + if (i2c->unprocessed) { + *i2c->msg_buf++ = readl(i2c->base + SPACEMIT_IDBR); + i2c->unprocessed--; ++ return; + } + + /* if transfer completes, SPACEMIT_ISR will handle it */ +@@ -348,9 +399,7 @@ static void spacemit_i2c_handle_read(str + if (i2c->unprocessed) + return; + +- /* SPACEMIT_STATE_IDLE avoids trigger next byte */ +- i2c->state = SPACEMIT_STATE_IDLE; +- complete(&i2c->complete); ++ spacemit_i2c_complete(i2c); + } + + static void spacemit_i2c_handle_start(struct spacemit_i2c_dev *i2c) +@@ -384,8 +433,129 @@ static void spacemit_i2c_err_check(struc + + spacemit_i2c_clear_int_status(i2c, SPACEMIT_I2C_INT_STATUS_MASK); + +- i2c->state = SPACEMIT_STATE_IDLE; +- complete(&i2c->complete); ++ spacemit_i2c_complete(i2c); ++} ++ ++static void spacemit_i2c_handle_state(struct spacemit_i2c_dev *i2c) ++{ ++ u32 val; ++ ++ if (i2c->status & SPACEMIT_SR_ERR) ++ goto err_out; ++ ++ switch (i2c->state) { ++ case SPACEMIT_STATE_START: ++ spacemit_i2c_handle_start(i2c); ++ break; ++ case SPACEMIT_STATE_READ: ++ spacemit_i2c_handle_read(i2c); ++ break; ++ case SPACEMIT_STATE_WRITE: ++ spacemit_i2c_handle_write(i2c); ++ break; ++ default: ++ break; ++ } ++ ++ if (i2c->state != SPACEMIT_STATE_IDLE) { ++ val = readl(i2c->base + SPACEMIT_ICR); ++ val &= ~(SPACEMIT_CR_TB | SPACEMIT_CR_ACKNAK | ++ SPACEMIT_CR_STOP | SPACEMIT_CR_START); ++ val |= SPACEMIT_CR_TB; ++ if (!i2c->use_pio) ++ val |= SPACEMIT_CR_ALDIE; ++ ++ if (spacemit_i2c_is_last_msg(i2c)) { ++ /* trigger next byte with stop */ ++ val |= SPACEMIT_CR_STOP; ++ ++ if (i2c->read) ++ val |= SPACEMIT_CR_ACKNAK; ++ } ++ writel(val, i2c->base + SPACEMIT_ICR); ++ } ++ ++err_out: ++ spacemit_i2c_err_check(i2c); ++} ++ ++/* ++ * In PIO mode, this function is used as a replacement for ++ * wait_for_completion_timeout(), whose return value indicates ++ * the remaining time. ++ * ++ * We do not have a meaningful remaining-time value here, so ++ * return a non-zero value on success to indicate "not timed out". ++ * Returning 1 ensures callers treating the return value as ++ * time_left will not incorrectly report a timeout. ++ */ ++static int spacemit_i2c_wait_pio_xfer(struct spacemit_i2c_dev *i2c) ++{ ++ u32 mask, msec = jiffies_to_msecs(i2c->adapt.timeout); ++ ktime_t timeout = ktime_add_ms(ktime_get(), msec); ++ int ret; ++ ++ mask = SPACEMIT_SR_IRF | SPACEMIT_SR_ITE; ++ ++ do { ++ i2c->status = readl(i2c->base + SPACEMIT_ISR); ++ ++ spacemit_i2c_clear_int_status(i2c, i2c->status); ++ ++ if (i2c->status & mask) ++ spacemit_i2c_handle_state(i2c); ++ else ++ udelay(SPACEMIT_POLL_INTERVAL); ++ } while (i2c->unprocessed && ktime_compare(ktime_get(), timeout) < 0); ++ ++ if (i2c->unprocessed) ++ return 0; ++ ++ if (i2c->read) ++ return 1; ++ ++ /* ++ * If this is the last byte to write of the current message, ++ * we have to wait here. Otherwise, control will proceed directly ++ * to start(), which would overwrite the current data. ++ */ ++ ret = readl_poll_timeout_atomic(i2c->base + SPACEMIT_ISR, ++ i2c->status, i2c->status & SPACEMIT_SR_ITE, ++ SPACEMIT_POLL_INTERVAL, SPACEMIT_POLL_TIMEOUT); ++ if (ret) ++ return 0; ++ ++ /* ++ * For writes: in interrupt mode, an ITE (write-empty) interrupt is triggered ++ * after the last byte, and the MSD-related handling takes place there. ++ * In PIO mode, however, we need to explicitly call err_check() to emulate this ++ * step, otherwise the next transfer will fail. ++ */ ++ if (i2c->msg_idx == i2c->msg_num - 1) { ++ mask = SPACEMIT_SR_MSD | SPACEMIT_SR_ERR; ++ /* ++ * In some cases, MSD may not arrive immediately; ++ * wait here to handle that. ++ */ ++ ret = readl_poll_timeout_atomic(i2c->base + SPACEMIT_ISR, ++ i2c->status, i2c->status & mask, ++ SPACEMIT_POLL_INTERVAL, SPACEMIT_POLL_TIMEOUT); ++ if (ret) ++ return 0; ++ ++ spacemit_i2c_err_check(i2c); ++ } ++ ++ return 1; ++} ++ ++static int spacemit_i2c_wait_xfer_complete(struct spacemit_i2c_dev *i2c) ++{ ++ if (i2c->use_pio) ++ return spacemit_i2c_wait_pio_xfer(i2c); ++ ++ return wait_for_completion_timeout(&i2c->complete, ++ i2c->adapt.timeout); + } + + static int spacemit_i2c_xfer_msg(struct spacemit_i2c_dev *i2c) +@@ -403,8 +573,8 @@ static int spacemit_i2c_xfer_msg(struct + + spacemit_i2c_start(i2c); + +- time_left = wait_for_completion_timeout(&i2c->complete, +- i2c->adapt.timeout); ++ time_left = spacemit_i2c_wait_xfer_complete(i2c); ++ + if (!time_left) { + dev_err(i2c->dev, "msg completion timeout\n"); + spacemit_i2c_conditionally_reset_bus(i2c); +@@ -422,7 +592,7 @@ static int spacemit_i2c_xfer_msg(struct + static irqreturn_t spacemit_i2c_irq_handler(int irq, void *devid) + { + struct spacemit_i2c_dev *i2c = devid; +- u32 status, val; ++ u32 status; + + status = readl(i2c->base + SPACEMIT_ISR); + if (!status) +@@ -432,41 +602,8 @@ static irqreturn_t spacemit_i2c_irq_hand + + spacemit_i2c_clear_int_status(i2c, status); + +- if (i2c->status & SPACEMIT_SR_ERR) +- goto err_out; +- +- val = readl(i2c->base + SPACEMIT_ICR); +- val &= ~(SPACEMIT_CR_TB | SPACEMIT_CR_ACKNAK | SPACEMIT_CR_STOP | SPACEMIT_CR_START); +- +- switch (i2c->state) { +- case SPACEMIT_STATE_START: +- spacemit_i2c_handle_start(i2c); +- break; +- case SPACEMIT_STATE_READ: +- spacemit_i2c_handle_read(i2c); +- break; +- case SPACEMIT_STATE_WRITE: +- spacemit_i2c_handle_write(i2c); +- break; +- default: +- break; +- } +- +- if (i2c->state != SPACEMIT_STATE_IDLE) { +- val |= SPACEMIT_CR_TB | SPACEMIT_CR_ALDIE; +- +- if (spacemit_i2c_is_last_msg(i2c)) { +- /* trigger next byte with stop */ +- val |= SPACEMIT_CR_STOP; +- +- if (i2c->read) +- val |= SPACEMIT_CR_ACKNAK; +- } +- writel(val, i2c->base + SPACEMIT_ICR); +- } ++ spacemit_i2c_handle_state(i2c); + +-err_out: +- spacemit_i2c_err_check(i2c); + return IRQ_HANDLED; + } + +@@ -475,6 +612,11 @@ static void spacemit_i2c_calc_timeout(st + unsigned long timeout; + int idx = 0, cnt = 0; + ++ if (i2c->use_pio) { ++ i2c->adapt.timeout = msecs_to_jiffies(SPACEMIT_WAIT_TIMEOUT); ++ return; ++ } ++ + for (; idx < i2c->msg_num; idx++) + cnt += (i2c->msgs + idx)->len + 1; + +@@ -487,11 +629,14 @@ static void spacemit_i2c_calc_timeout(st + i2c->adapt.timeout = usecs_to_jiffies(timeout + USEC_PER_SEC / 10) / i2c->msg_num; + } + +-static int spacemit_i2c_xfer(struct i2c_adapter *adapt, struct i2c_msg *msgs, int num) ++static inline int ++spacemit_i2c_xfer_common(struct i2c_adapter *adapt, struct i2c_msg *msgs, int num, bool use_pio) + { + struct spacemit_i2c_dev *i2c = i2c_get_adapdata(adapt); + int ret; + ++ i2c->use_pio = use_pio; ++ + i2c->msgs = msgs; + i2c->msg_num = num; + +@@ -519,6 +664,16 @@ static int spacemit_i2c_xfer(struct i2c_ + return ret < 0 ? ret : num; + } + ++static int spacemit_i2c_xfer(struct i2c_adapter *adapt, struct i2c_msg *msgs, int num) ++{ ++ return spacemit_i2c_xfer_common(adapt, msgs, num, false); ++} ++ ++static int spacemit_i2c_pio_xfer_atomic(struct i2c_adapter *adapt, struct i2c_msg *msgs, int num) ++{ ++ return spacemit_i2c_xfer_common(adapt, msgs, num, true); ++} ++ + static u32 spacemit_i2c_func(struct i2c_adapter *adap) + { + return I2C_FUNC_I2C | (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK); +@@ -526,6 +681,7 @@ static u32 spacemit_i2c_func(struct i2c_ + + static const struct i2c_algorithm spacemit_i2c_algo = { + .xfer = spacemit_i2c_xfer, ++ .xfer_atomic = spacemit_i2c_pio_xfer_atomic, + .functionality = spacemit_i2c_func, + }; + diff --git a/target/linux/spacemit/patches-6.18/0084-riscv-dts-spacemit-Enable-i2c8-adapter-for-OrangePi-.patch b/target/linux/spacemit/patches-6.18/0084-riscv-dts-spacemit-Enable-i2c8-adapter-for-OrangePi-.patch new file mode 100644 index 00000000000000..ece65249219e15 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0084-riscv-dts-spacemit-Enable-i2c8-adapter-for-OrangePi-.patch @@ -0,0 +1,32 @@ +From c087087031d80e9a7eafab865092c639cd21c443 Mon Sep 17 00:00:00 2001 +From: Han Gao +Date: Tue, 7 Apr 2026 23:28:14 +0800 +Subject: [PATCH] riscv: dts: spacemit: Enable i2c8 adapter for OrangePi RV2 + +The adapter is used to access the SpacemiT P1 PMIC present in this board. + +Tested-by: Vincent Legoll # OrangePi-RV2 +Signed-off-by: Han Gao +Reviewed-by: Yixun Lan +Link: https://lore.kernel.org/r/d66f897b179271f508ac5352e52b1223f3bca5fb.1775575436.git.gaohan@iscas.ac.cn +Signed-off-by: Yixun Lan +(cherry picked from commit ece83d42785e12ab7690c0c13b416baf46a74063) +--- + arch/riscv/boot/dts/spacemit/k1-orangepi-rv2.dts | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/arch/riscv/boot/dts/spacemit/k1-orangepi-rv2.dts ++++ b/arch/riscv/boot/dts/spacemit/k1-orangepi-rv2.dts +@@ -87,6 +87,12 @@ + status = "okay"; + }; + ++&i2c8 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c8_cfg>; ++ status = "okay"; ++}; ++ + &uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_2_cfg>; diff --git a/target/linux/spacemit/patches-6.18/0085-riscv-dts-spacemit-Define-the-P1-PMIC-regulators-for.patch b/target/linux/spacemit/patches-6.18/0085-riscv-dts-spacemit-Define-the-P1-PMIC-regulators-for.patch new file mode 100644 index 00000000000000..7527d70303b1f9 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0085-riscv-dts-spacemit-Define-the-P1-PMIC-regulators-for.patch @@ -0,0 +1,169 @@ +From 99cfb26f7fbe421aa9bccb8788797dbe16a89f78 Mon Sep 17 00:00:00 2001 +From: Han Gao +Date: Tue, 7 Apr 2026 23:28:15 +0800 +Subject: [PATCH] riscv: dts: spacemit: Define the P1 PMIC regulators for + OrangePi RV2 + +Define the DC power input and the 4v power as fixed regulator supplies. + +Define the SpacemiT P1 PMIC voltage regulators and their constraints. + +Co-developed-by: Chukun Pan +Signed-off-by: Chukun Pan +Tested-by: Vincent Legoll # OrangePi-RV2 +Signed-off-by: Han Gao +Reviewed-by: Yixun Lan +Link: https://lore.kernel.org/r/193370a69e1cc3e4d8c4eb57bfea208e29ac75d8.1775575436.git.gaohan@iscas.ac.cn +Signed-off-by: Yixun Lan +(cherry picked from commit c02c047b925c0ed101ec6834e1c07a53a45f98d4) +--- + .../boot/dts/spacemit/k1-orangepi-rv2.dts | 131 ++++++++++++++++++ + 1 file changed, 131 insertions(+) + +--- a/arch/riscv/boot/dts/spacemit/k1-orangepi-rv2.dts ++++ b/arch/riscv/boot/dts/spacemit/k1-orangepi-rv2.dts +@@ -23,6 +23,25 @@ + stdout-path = "serial0"; + }; + ++ vcc_5v0: regulator-vcc-5v0 { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc_5v0"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ }; ++ ++ vcc4v0: regulator-vcc4v0 { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc4v0"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <4000000>; ++ regulator-max-microvolt = <4000000>; ++ vin-supply = <&vcc_5v0>; ++ }; ++ + leds { + compatible = "gpio-leds"; + +@@ -91,6 +110,118 @@ + pinctrl-names = "default"; + pinctrl-0 = <&i2c8_cfg>; + status = "okay"; ++ ++ pmic@41 { ++ compatible = "spacemit,p1"; ++ reg = <0x41>; ++ interrupts = <64>; ++ vin1-supply = <&vcc4v0>; ++ vin2-supply = <&vcc4v0>; ++ vin3-supply = <&vcc4v0>; ++ vin4-supply = <&vcc4v0>; ++ vin5-supply = <&vcc4v0>; ++ vin6-supply = <&vcc4v0>; ++ aldoin-supply = <&vcc4v0>; ++ dldoin1-supply = <&buck5>; ++ dldoin2-supply = <&buck5>; ++ ++ regulators { ++ buck1 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <3450000>; ++ regulator-ramp-delay = <5000>; ++ regulator-always-on; ++ }; ++ ++ buck2 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <3450000>; ++ regulator-ramp-delay = <5000>; ++ regulator-always-on; ++ }; ++ ++ buck3_1v8: buck3 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-ramp-delay = <5000>; ++ regulator-always-on; ++ }; ++ ++ buck4_3v3: buck4 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-ramp-delay = <5000>; ++ regulator-always-on; ++ }; ++ ++ buck5: buck5 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <3450000>; ++ regulator-ramp-delay = <5000>; ++ regulator-always-on; ++ }; ++ ++ buck6 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <3450000>; ++ regulator-ramp-delay = <5000>; ++ regulator-always-on; ++ }; ++ ++ aldo1 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <3400000>; ++ regulator-boot-on; ++ }; ++ ++ aldo2 { ++ /* not connected */ ++ }; ++ ++ aldo3 { ++ /* not connected */ ++ }; ++ ++ aldo4 { ++ /* not connected */ ++ }; ++ ++ dldo1 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <3400000>; ++ regulator-boot-on; ++ }; ++ ++ dldo2 { ++ /* not connected */ ++ }; ++ ++ dldo3 { ++ /* not connected */ ++ }; ++ ++ dldo4 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <3400000>; ++ regulator-always-on; ++ }; ++ ++ dldo5 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <3400000>; ++ }; ++ ++ dldo6 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <3400000>; ++ regulator-always-on; ++ }; ++ ++ dldo7 { ++ /* not connected */ ++ }; ++ }; ++ }; + }; + + &uart0 { diff --git a/target/linux/spacemit/patches-6.18/0086-riscv-dts-spacemit-Enable-USB3.0-PCIe-on-OrangePi-RV.patch b/target/linux/spacemit/patches-6.18/0086-riscv-dts-spacemit-Enable-USB3.0-PCIe-on-OrangePi-RV.patch new file mode 100644 index 00000000000000..971b1a0a1f2a9f --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0086-riscv-dts-spacemit-Enable-USB3.0-PCIe-on-OrangePi-RV.patch @@ -0,0 +1,137 @@ +From d2b3ed59c7e14f9253cc7761789eb9d24e82c257 Mon Sep 17 00:00:00 2001 +From: Han Gao +Date: Tue, 7 Apr 2026 23:28:16 +0800 +Subject: [PATCH] riscv: dts: spacemit: Enable USB3.0/PCIe on OrangePi RV2 + +Enable the DWC3 USB 3.0 controller and its associated usbphy2 on the +OrangePi RV2 board. + +The board utilizes a Genesys Logic GL3523 USB3.0 hub. + +Define a 3.3v fixed voltage regulator for PCIe and enable PCIe and +PHY-related Device Tree nodes for the OrangePi RV2. + +Co-developed-by: Chukun Pan +Signed-off-by: Chukun Pan +Tested-by: Vincent Legoll # OrangePi-RV2 +Signed-off-by: Han Gao +Reviewed-by: Yixun Lan +Link: https://lore.kernel.org/r/8e397efb06efd9b02788df07f435ce153de05cd5.1775575436.git.gaohan@iscas.ac.cn +Signed-off-by: Yixun Lan +(cherry picked from commit e3e433dd9aa04448f8f98d59359cab1340d994a3) +--- + .../boot/dts/spacemit/k1-orangepi-rv2.dts | 80 +++++++++++++++++++ + 1 file changed, 80 insertions(+) + +--- a/arch/riscv/boot/dts/spacemit/k1-orangepi-rv2.dts ++++ b/arch/riscv/boot/dts/spacemit/k1-orangepi-rv2.dts +@@ -23,6 +23,16 @@ + stdout-path = "serial0"; + }; + ++ pcie_vcc3v3: regulator-pcie-vcc3v3 { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpios = <&gpio K1_GPIO(116) GPIO_ACTIVE_HIGH>; ++ regulator-name = "pcie_vcc3v3"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ vin-supply = <&vcc_5v0>; ++ }; ++ + vcc_5v0: regulator-vcc-5v0 { + compatible = "regulator-fixed"; + regulator-name = "vcc_5v0"; +@@ -42,6 +52,16 @@ + vin-supply = <&vcc_5v0>; + }; + ++ vcc5v0_usb30: regulator-vcc5v0-usb30 { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpios = <&gpio K1_GPIO(123) GPIO_ACTIVE_HIGH>; ++ regulator-name = "vcc5v0_usb30"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ vin-supply = <&vcc_5v0>; ++ }; ++ + leds { + compatible = "gpio-leds"; + +@@ -54,6 +74,10 @@ + }; + }; + ++&combo_phy { ++ status = "okay"; ++}; ++ + ð0 { + phy-handle = <&rgmii0>; + phy-mode = "rgmii-id"; +@@ -224,8 +248,64 @@ + }; + }; + ++&pcie1_phy { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pcie1_3_cfg>; ++ status = "okay"; ++}; ++ ++&pcie1_port { ++ phys = <&pcie1_phy>; ++ vpcie3v3-supply = <&pcie_vcc3v3>; ++}; ++ ++&pcie1 { ++ status = "okay"; ++}; ++ ++&pcie2_phy { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pcie2_4_cfg>; ++ status = "okay"; ++}; ++ ++&pcie2_port { ++ phys = <&pcie2_phy>; ++ vpcie3v3-supply = <&pcie_vcc3v3>; ++}; ++ ++&pcie2 { ++ status = "okay"; ++}; ++ + &uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_2_cfg>; + status = "okay"; + }; ++ ++&usbphy2 { ++ status = "okay"; ++}; ++ ++&usb_dwc3 { ++ dr_mode = "host"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ vbus-supply = <&vcc5v0_usb30>; ++ status = "okay"; ++ ++ hub_2_0: hub@1 { ++ compatible = "usb5e3,610"; ++ reg = <0x1>; ++ peer-hub = <&hub_3_0>; ++ vdd-supply = <&vcc_5v0>; ++ }; ++ ++ hub_3_0: hub@2 { ++ compatible = "usb5e3,620"; ++ reg = <0x2>; ++ peer-hub = <&hub_2_0>; ++ vdd-supply = <&vcc_5v0>; ++ }; ++}; diff --git a/target/linux/spacemit/patches-6.18/0087-dts-spacemit-set-console-baud-rate-on-bpif3.patch b/target/linux/spacemit/patches-6.18/0087-dts-spacemit-set-console-baud-rate-on-bpif3.patch new file mode 100644 index 00000000000000..bc30faf491cf34 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0087-dts-spacemit-set-console-baud-rate-on-bpif3.patch @@ -0,0 +1,31 @@ +From 1c95d3d0467aba0700fa4fa292bca016a13a2f69 Mon Sep 17 00:00:00 2001 +From: Conor Dooley +Date: Thu, 30 Apr 2026 19:52:12 +0100 +Subject: [PATCH] dts: spacemit: set console baud rate on bpif3 + +Because the default console's baud rate is not set, defconfig kernels do +not have any serial output on this platform. Set the baud rate to +115200, matching what is used by U-Boot etc on this platform. + +Suggested-by: Vivian Wang +Fixes: d60d57ab6b2a8 ("riscv: dts: spacemit: add Banana Pi BPI-F3 board device tree") +Signed-off-by: Conor Dooley +Reviewed-by: Yixun Lan +Link: https://lore.kernel.org/r/20260430-reword-overstep-3be08b7eab25@spud +Signed-off-by: Yixun Lan +(cherry picked from commit 24c12ca43b12c104389d9a159207d0b25779d0af) +--- + arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts ++++ b/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts +@@ -19,7 +19,7 @@ + }; + + chosen { +- stdout-path = "serial0"; ++ stdout-path = "serial0:115200n8"; + }; + + leds { diff --git a/target/linux/spacemit/patches-6.18/0088-spi-dt-bindings-add-SpacemiT-K1-SPI-support.patch b/target/linux/spacemit/patches-6.18/0088-spi-dt-bindings-add-SpacemiT-K1-SPI-support.patch new file mode 100644 index 00000000000000..c9285e0965e06a --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0088-spi-dt-bindings-add-SpacemiT-K1-SPI-support.patch @@ -0,0 +1,107 @@ +From f9df1fed456dfad7b5ad9816de4f7073953a992b Mon Sep 17 00:00:00 2001 +From: Alex Elder +Date: Sat, 2 May 2026 21:30:51 -0400 +Subject: [PATCH] spi: dt-bindings: add SpacemiT K1 SPI support + +Add support for the SPI controller implemented by the SpacemiT K1 SoC. + +Acked-by: Conor Dooley +Acked-by: Troy Mitchell +Reviewed-by: Rob Herring (Arm) +Signed-off-by: Alex Elder +Signed-off-by: Guodong Xu +Link: https://patch.msgid.link/20260502-spi-spacemit-k1-v10-1-f412e1ae8a34@riscstar.com +Signed-off-by: Mark Brown +(cherry picked from commit b610d5333c4b93389240b62d1b6299e7e2ee2e65) +--- + .../bindings/spi/spacemit,k1-spi.yaml | 84 +++++++++++++++++++ + 1 file changed, 84 insertions(+) + create mode 100644 Documentation/devicetree/bindings/spi/spacemit,k1-spi.yaml + +--- /dev/null ++++ b/Documentation/devicetree/bindings/spi/spacemit,k1-spi.yaml +@@ -0,0 +1,84 @@ ++# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) ++%YAML 1.2 ++--- ++$id: http://devicetree.org/schemas/spi/spacemit,k1-spi.yaml# ++$schema: http://devicetree.org/meta-schemas/core.yaml# ++ ++title: SpacemiT K1 SoC Serial Peripheral Interface (SPI) ++ ++maintainers: ++ - Alex Elder ++ ++description: ++ The SpacemiT K1 SoC implements a SPI controller that has two 32-entry ++ FIFOs, for transmit and receive. Details are currently available in ++ section 18.2.1 of the K1 User Manual, found in the SpacemiT Keystone ++ K1 Documentation[1]. The controller transfers words using PIO. DMA ++ transfers are supported as well, if both TX and RX DMA channels are ++ specified, ++ ++ [1] https://developer.spacemit.com/documentation ++ ++allOf: ++ - $ref: /schemas/spi/spi-controller.yaml# ++ ++properties: ++ compatible: ++ const: spacemit,k1-spi ++ ++ reg: ++ maxItems: 1 ++ ++ clocks: ++ items: ++ - description: Core clock ++ - description: Bus clock ++ ++ clock-names: ++ items: ++ - const: core ++ - const: bus ++ ++ resets: ++ maxItems: 1 ++ ++ interrupts: ++ maxItems: 1 ++ ++ dmas: ++ items: ++ - description: RX DMA channel ++ - description: TX DMA channel ++ ++ dma-names: ++ items: ++ - const: rx ++ - const: tx ++ ++required: ++ - compatible ++ - reg ++ - clocks ++ - clock-names ++ - resets ++ - interrupts ++ ++unevaluatedProperties: false ++ ++examples: ++ - | ++ ++ #include ++ spi@d401c000 { ++ compatible = "spacemit,k1-spi"; ++ reg = <0xd401c000 0x30>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ clocks = <&syscon_apbc CLK_SSP3>, ++ <&syscon_apbc CLK_SSP3_BUS>; ++ clock-names = "core", "bus"; ++ resets = <&syscon_apbc RESET_SSP3>; ++ interrupts = <55>; ++ dmas = <&pdma 20>, <&pdma 19>; ++ dma-names = "rx", "tx"; ++ }; diff --git a/target/linux/spacemit/patches-6.18/0089-spi-spacemit-introduce-SpacemiT-K1-SPI-controller-dr.patch b/target/linux/spacemit/patches-6.18/0089-spi-spacemit-introduce-SpacemiT-K1-SPI-controller-dr.patch new file mode 100644 index 00000000000000..d1ef219d8ef4a2 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0089-spi-spacemit-introduce-SpacemiT-K1-SPI-controller-dr.patch @@ -0,0 +1,842 @@ +From 25a9369325a62284883b67c1080af63ec4cbba86 Mon Sep 17 00:00:00 2001 +From: Alex Elder +Date: Sat, 2 May 2026 21:30:52 -0400 +Subject: [PATCH] spi: spacemit: introduce SpacemiT K1 SPI controller driver + +This patch introduces the driver for the SPI controller found in the +SpacemiT K1 SoC. Currently the driver supports master mode only. +The SPI hardware implements RX and TX FIFOs, 32 entries each, and +supports both PIO and DMA mode transfers. + +Signed-off-by: Alex Elder +Signed-off-by: Guodong Xu +Link: https://patch.msgid.link/20260502-spi-spacemit-k1-v10-2-f412e1ae8a34@riscstar.com +Signed-off-by: Mark Brown +(cherry picked from commit efcd8b9d111177d48c841d09beca43b15d5b9e5f) +--- + drivers/spi/Kconfig | 9 + + drivers/spi/Makefile | 1 + + drivers/spi/spi-spacemit-k1.c | 789 ++++++++++++++++++++++++++++++++++ + 3 files changed, 799 insertions(+) + create mode 100644 drivers/spi/spi-spacemit-k1.c + +--- a/drivers/spi/Kconfig ++++ b/drivers/spi/Kconfig +@@ -1073,6 +1073,15 @@ config SPI_SG2044_NOR + also supporting 3Byte address devices and 4Byte address + devices. + ++config SPI_SPACEMIT_K1 ++ tristate "K1 SPI Controller" ++ depends on ARCH_SPACEMIT || COMPILE_TEST ++ depends on OF ++ imply MMP_PDMA if ARCH_SPACEMIT ++ default m if ARCH_SPACEMIT ++ help ++ Enable support for the SpacemiT K1 SPI controller. ++ + config SPI_SPRD + tristate "Spreadtrum SPI controller" + depends on ARCH_SPRD || COMPILE_TEST +--- a/drivers/spi/Makefile ++++ b/drivers/spi/Makefile +@@ -140,6 +140,7 @@ obj-$(CONFIG_SPI_SIFIVE) += spi-sifive. + obj-$(CONFIG_SPI_SLAVE_MT27XX) += spi-slave-mt27xx.o + obj-$(CONFIG_SPI_SN_F_OSPI) += spi-sn-f-ospi.o + obj-$(CONFIG_SPI_SG2044_NOR) += spi-sg2044-nor.o ++obj-$(CONFIG_SPI_SPACEMIT_K1) += spi-spacemit-k1.o + obj-$(CONFIG_SPI_SPRD) += spi-sprd.o + obj-$(CONFIG_SPI_SPRD_ADI) += spi-sprd-adi.o + obj-$(CONFIG_SPI_STM32) += spi-stm32.o +--- /dev/null ++++ b/drivers/spi/spi-spacemit-k1.c +@@ -0,0 +1,789 @@ ++// SPDX-License-Identifier: GPL-2.0 ++// ++// SpacemiT K1 SPI controller driver ++// ++// Copyright (C) 2026, RISCstar Solutions Corporation ++// Copyright (C) 2023, SpacemiT Corporation ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "internals.h" ++ ++/* This is the range of transfer rates supported by the K1 SoC */ ++#define K1_SPI_MIN_SPEED_HZ 6250 ++#define K1_SPI_MAX_SPEED_HZ 51200000 ++ ++/* DMA constraints */ ++#define K1_SPI_DMA_ALIGNMENT 64 ++#define K1_SPI_MAX_DMA_LEN SZ_512K ++ ++/* SSP Top Control Register */ ++#define SSP_TOP_CTRL 0x00 ++#define TOP_SSE BIT(0) /* Enable port */ ++#define TOP_FRF_MASK GENMASK(2, 1) /* Frame format */ ++#define TOP_FRF_MOTOROLA 0 /* Motorola SPI */ ++#define TOP_DSS_MASK GENMASK(9, 5) /* Data size (1-32) */ ++#define TOP_SPO BIT(10) /* Polarity: 0=low */ ++#define TOP_SPH BIT(11) /* Half-cycle phase */ ++#define TOP_LBM BIT(12) /* Loopback mode */ ++#define TOP_TRAIL BIT(13) /* Trailing bytes */ ++#define TOP_HOLD_FRAME_LOW BIT(14) /* Chip select */ ++ ++/* SSP FIFO Control Register */ ++#define SSP_FIFO_CTRL 0x04 ++#define FIFO_TFT_MASK GENMASK(4, 0) /* TX FIFO threshold */ ++#define FIFO_RFT_MASK GENMASK(9, 5) /* RX FIFO threshold */ ++#define FIFO_TSRE BIT(10) /* TX service request */ ++#define FIFO_RSRE BIT(11) /* RX service request */ ++ ++/* SSP Interrupt Enable Register */ ++#define SSP_INT_EN 0x08 ++#define SSP_INT_EN_TINTE BIT(1) /* RX timeout */ ++#define SSP_INT_EN_RIE BIT(2) /* RX FIFO */ ++#define SSP_INT_EN_TIE BIT(3) /* TX FIFO */ ++#define SSP_INT_EN_RIM BIT(4) /* RX FIFO overrun */ ++#define SSP_INT_EN_TIM BIT(5) /* TX FIFO underrun */ ++#define SSP_INT_EN_EBCEI BIT(6) /* Bit count error */ ++ ++/* TX interrupts, RX interrupts, and error interrupts */ ++#define SSP_INT_EN_TX SSP_INT_EN_TIE ++#define SSP_INT_EN_RX \ ++ (SSP_INT_EN_TINTE | SSP_INT_EN_RIE) ++#define SSP_INT_EN_ERROR \ ++ (SSP_INT_EN_RIM | SSP_INT_EN_TIM | SSP_INT_EN_EBCEI) ++ ++/* SSP Time Out Register */ ++#define SSP_TIMEOUT 0x0c ++#define SSP_TIMEOUT_MASK GENMASK(23, 0) ++ ++/* SSP Data Register */ ++#define SSP_DATAR 0x10 ++ ++/* SSP Status Register */ ++#define SSP_STATUS 0x14 ++#define SSP_STATUS_BSY BIT(0) /* SPI/I2S busy */ ++#define SSP_STATUS_TNF BIT(6) /* TX FIFO not full */ ++#define SSP_STATUS_TFL GENMASK(11, 7) /* TX FIFO level */ ++#define SSP_STATUS_TUR BIT(12) /* TX FIFO underrun */ ++#define SSP_STATUS_RNE BIT(14) /* RX FIFO not empty */ ++#define SSP_STATUS_RFL GENMASK(19, 15) /* RX FIFO level */ ++#define SSP_STATUS_ROR BIT(20) /* RX FIFO overrun */ ++#define SSP_STATUS_BCE BIT(21) /* Bit count error */ ++ ++/* Error status mask */ ++#define SSP_STATUS_ERROR \ ++ (SSP_STATUS_TUR | SSP_STATUS_ROR | SSP_STATUS_BCE) ++ ++/* The FIFO sizes and thresholds are the same for RX and TX */ ++#define K1_SPI_FIFO_SIZE 32 ++#define K1_SPI_THRESH (K1_SPI_FIFO_SIZE / 2) ++ ++struct k1_spi_driver_data { ++ struct spi_controller *host; ++ void __iomem *base; ++ phys_addr_t base_addr; ++ unsigned long bus_rate; ++ struct clk *clk; ++ unsigned long rate; ++ int irq; ++ ++ /* Current transfer information; not valid if message is null */ ++ u32 bytes; /* Bytes used for bits_per_word */ ++ unsigned int rx_resid; /* RX bytes left in transfer */ ++ unsigned int tx_resid; /* TX bytes left in transfer */ ++ struct spi_transfer *transfer; /* Current transfer */ ++ ++ bool dma_enabled; ++}; ++ ++/* Set our registers to a known initial state */ ++static void ++k1_spi_register_reset(struct k1_spi_driver_data *drv_data, bool initial) ++{ ++ u32 val = 0; ++ ++ writel(0, drv_data->base + SSP_TOP_CTRL); ++ ++ if (initial) { ++ /* ++ * The TX and RX FIFO thresholds are the same no matter ++ * what the speed or bits per word, so we can just set ++ * them once. The thresholds are one more than the values ++ * in the register. ++ */ ++ val = FIELD_PREP(FIFO_RFT_MASK, K1_SPI_THRESH - 1); ++ val |= FIELD_PREP(FIFO_TFT_MASK, K1_SPI_THRESH - 1); ++ } ++ writel(val, drv_data->base + SSP_FIFO_CTRL); ++ ++ writel(0, drv_data->base + SSP_INT_EN); ++ writel(0, drv_data->base + SSP_TIMEOUT); ++ ++ /* Clear any pending interrupt conditions */ ++ writel(~0, drv_data->base + SSP_STATUS); ++} ++ ++/* ++ * The client can call the setup function multiple times, and each call ++ * can specify a different SPI mode (and transfer speed). Each transfer ++ * can specify its own speed though, and the core code ensures each ++ * transfer's speed is set to something nonzero and supported by both ++ * the controller and the device. We just set the speed for each transfer. ++ */ ++static int k1_spi_setup(struct spi_device *spi) ++{ ++ struct k1_spi_driver_data *drv_data; ++ u32 val; ++ ++ drv_data = spi_controller_get_devdata(spi->controller); ++ ++ /* ++ * Configure the message format for this device. We only ++ * support Motorola SPI format in master mode. ++ */ ++ val = FIELD_PREP(TOP_FRF_MASK, TOP_FRF_MOTOROLA); ++ ++ /* Translate the mode into the value used to program the hardware. */ ++ if (spi->mode & SPI_CPHA) ++ val |= TOP_SPH; /* 1/2 cycle */ ++ if (spi->mode & SPI_CPOL) ++ val |= TOP_SPO; /* active low */ ++ if (spi->mode & SPI_LOOP) ++ val |= TOP_LBM; /* enable loopback */ ++ writel(val, drv_data->base + SSP_TOP_CTRL); ++ ++ return 0; ++} ++ ++static void k1_spi_cleanup(struct spi_device *spi) ++{ ++ struct k1_spi_driver_data *drv_data; ++ ++ drv_data = spi_controller_get_devdata(spi->controller); ++ k1_spi_register_reset(drv_data, false); ++} ++ ++static bool k1_spi_can_dma(struct spi_controller *host, struct spi_device *spi, ++ struct spi_transfer *transfer) ++{ ++ struct k1_spi_driver_data *drv_data = spi_controller_get_devdata(host); ++ u32 burst_size; ++ ++ if (!drv_data->dma_enabled) ++ return false; ++ ++ if (transfer->len > SZ_2K) ++ return false; ++ ++ /* Don't bother with DMA if we can't do even a single burst */ ++ burst_size = K1_SPI_THRESH * spi_bpw_to_bytes(transfer->bits_per_word); ++ ++ return transfer->len >= burst_size; ++} ++ ++static void k1_spi_dma_callback(void *param) ++{ ++ struct k1_spi_driver_data *drv_data = param; ++ u32 val; ++ ++ val = readl(drv_data->base + SSP_FIFO_CTRL); ++ val &= ~(FIFO_TSRE | FIFO_RSRE); ++ writel(val, drv_data->base + SSP_FIFO_CTRL); ++ ++ val = readl(drv_data->base + SSP_TOP_CTRL); ++ val &= ~TOP_TRAIL; ++ writel(val, drv_data->base + SSP_TOP_CTRL); ++ ++ /* Check for any error conditions */ ++ val = readl(drv_data->base + SSP_STATUS); ++ if (val & SSP_STATUS_ERROR) ++ drv_data->transfer->error |= SPI_TRANS_FAIL_IO; ++ ++ /* Disable the port */ ++ val = readl(drv_data->base + SSP_TOP_CTRL); ++ val &= ~TOP_SSE; ++ writel(val, drv_data->base + SSP_TOP_CTRL); ++ ++ drv_data->transfer = NULL; ++ ++ spi_finalize_current_transfer(drv_data->host); ++} ++ ++/* Prepare a descriptor for TX or RX DMA */ ++static struct dma_async_tx_descriptor * ++k1_spi_dma_prep(struct k1_spi_driver_data *drv_data, ++ struct spi_transfer *transfer, bool tx) ++{ ++ phys_addr_t addr = drv_data->base_addr + SSP_DATAR; ++ u32 burst_size = K1_SPI_THRESH * drv_data->bytes; ++ struct dma_slave_config cfg = { }; ++ enum dma_transfer_direction dir; ++ enum dma_slave_buswidth width; ++ struct dma_chan *chan; ++ struct sg_table *sgt; ++ ++ switch (drv_data->bytes) { ++ case 1: ++ width = DMA_SLAVE_BUSWIDTH_1_BYTE; ++ break; ++ case 2: ++ width = DMA_SLAVE_BUSWIDTH_2_BYTES; ++ break; ++ default: /* bytes == 4 */ ++ width = DMA_SLAVE_BUSWIDTH_4_BYTES; ++ break; ++ } ++ ++ if (tx) { ++ chan = drv_data->host->dma_tx; ++ sgt = &transfer->tx_sg; ++ dir = DMA_MEM_TO_DEV; ++ ++ cfg.dst_addr = addr; ++ cfg.dst_addr_width = width; ++ cfg.dst_maxburst = burst_size; ++ } else { ++ chan = drv_data->host->dma_rx; ++ sgt = &transfer->rx_sg; ++ dir = DMA_DEV_TO_MEM; ++ ++ cfg.src_addr = addr; ++ cfg.src_addr_width = width; ++ cfg.src_maxburst = burst_size; ++ } ++ cfg.direction = dir; ++ ++ if (dmaengine_slave_config(chan, &cfg)) ++ return NULL; ++ ++ return dmaengine_prep_slave_sg(chan, sgt->sgl, sgt->nents, dir, ++ DMA_PREP_INTERRUPT | DMA_CTRL_ACK); ++ ++} ++ ++static int k1_spi_dma_one(struct spi_controller *host, struct spi_device *spi, ++ struct spi_transfer *transfer) ++{ ++ struct k1_spi_driver_data *drv_data = spi_controller_get_devdata(host); ++ struct dma_async_tx_descriptor *desc; ++ u32 val; ++ ++ /* Prepare the TX descriptor and submit it */ ++ desc = k1_spi_dma_prep(drv_data, transfer, true); ++ if (!desc) ++ goto fallback; ++ dmaengine_submit(desc); ++ ++ /* Prepare the RX descriptor and submit it */ ++ desc = k1_spi_dma_prep(drv_data, transfer, false); ++ if (!desc) ++ goto fallback; ++ ++ /* When RX is complete we also know TX has completed */ ++ desc->callback = k1_spi_dma_callback; ++ desc->callback_param = drv_data; ++ ++ dmaengine_submit(desc); ++ ++ val = readl(drv_data->base + SSP_TOP_CTRL); ++ val |= TOP_TRAIL; /* Trailing bytes handled by DMA */ ++ writel(val, drv_data->base + SSP_TOP_CTRL); ++ ++ val = readl(drv_data->base + SSP_FIFO_CTRL); ++ val |= FIFO_TSRE | FIFO_RSRE; ++ writel(val, drv_data->base + SSP_FIFO_CTRL); ++ ++ /* Start RX first so we're ready the instant we start transmitting */ ++ dma_async_issue_pending(host->dma_rx); ++ dma_async_issue_pending(host->dma_tx); ++ ++ return 1; ++fallback: ++ transfer->error |= SPI_TRANS_FAIL_NO_START; ++ ++ return -EAGAIN; ++} ++ ++/* Flush the RX FIFO of any leftover data before processing a message */ ++static int k1_spi_prepare_message(struct spi_controller *host, ++ struct spi_message *message) ++{ ++ struct k1_spi_driver_data *drv_data = spi_controller_get_devdata(host); ++ u32 val = readl(drv_data->base + SSP_STATUS); ++ u32 count; ++ ++ /* If there's nothing in the FIFO, we're done */ ++ if (!(val & SSP_STATUS_RNE)) ++ return 0; ++ ++ /* Read and discard what's there (one more than what the field says) */ ++ count = FIELD_GET(SSP_STATUS_RFL, val) + 1; ++ do ++ (void)readl(drv_data->base + SSP_DATAR); ++ while (--count); ++ ++ return 0; ++} ++ ++/* Set logic level of chip select line (high=true means CS deasserted) */ ++static void k1_spi_set_cs(struct spi_device *spi, bool high) ++{ ++ struct k1_spi_driver_data *drv_data; ++ u32 val; ++ ++ drv_data = spi_controller_get_devdata(spi->controller); ++ ++ val = readl(drv_data->base + SSP_TOP_CTRL); ++ if (high) ++ val &= ~TOP_HOLD_FRAME_LOW; ++ else ++ val |= TOP_HOLD_FRAME_LOW; ++ writel(val, drv_data->base + SSP_TOP_CTRL); ++} ++ ++/* Set the transfer speed; the SPI core code ensures it is supported */ ++static int k1_spi_set_speed(struct k1_spi_driver_data *drv_data, ++ struct spi_transfer *transfer) ++{ ++ struct clk *clk = drv_data->clk; ++ u64 nsec_per_word; ++ u64 bus_ticks; ++ u32 timeout; ++ u32 val; ++ int ret; ++ ++ ret = clk_set_rate(clk, transfer->speed_hz); ++ if (ret) ++ return ret; ++ ++ drv_data->rate = clk_get_rate(clk); ++ ++ /* No need for RX FIFO timeout if we're not receiving anything */ ++ if (!transfer->rx_buf) ++ return 0; ++ ++ /* ++ * Compute the RX FIFO inactivity timeout value that should be used. ++ * The inactivity timer restarts with each word that lands in the ++ * FIFO. If several "word transfer times" pass without any new data ++ * in the RX FIFO, we might as well read what's there. ++ * ++ * The rate at which words land in the FIFO is determined by the ++ * word size and the transfer rate. One bit is transferred per ++ * clock tick, and 8 (or 16 or 32) bits are transferred per word. ++ * ++ * So we can get word transfer time (in nanoseconds) from: ++ * nsec_per_tick = NSEC_PER_SEC / drv_data->rate; ++ * ticks_per_word = BITS_PER_BYTE * drv_data->bytes; ++ * We do the divide last for better accuracy. ++ */ ++ nsec_per_word = NSEC_PER_SEC * BITS_PER_BYTE * drv_data->bytes; ++ nsec_per_word = DIV_ROUND_UP_ULL(nsec_per_word, drv_data->rate); ++ ++ /* ++ * The timeout (which we'll set to three word transfer times) is ++ * expressed as a number of APB clock ticks. ++ * bus_ticks = 3 * nsec * (drv_data->bus_rate / NSEC_PER_SEC) ++ */ ++ bus_ticks = 3 * nsec_per_word * drv_data->bus_rate; ++ timeout = DIV_ROUND_UP_ULL(bus_ticks, NSEC_PER_SEC); ++ ++ /* Set the RX timeout period (required for both DMA and PIO) */ ++ val = FIELD_PREP(SSP_TIMEOUT_MASK, timeout); ++ writel(val, drv_data->base + SSP_TIMEOUT); ++ ++ return 0; ++} ++ ++static int k1_spi_transfer_one(struct spi_controller *host, ++ struct spi_device *spi, ++ struct spi_transfer *transfer) ++{ ++ struct k1_spi_driver_data *drv_data = spi_controller_get_devdata(host); ++ u32 ctrl; ++ u32 val; ++ int ret; ++ ++ /* Bits per word can change on a per-transfer basis */ ++ drv_data->bytes = spi_bpw_to_bytes(transfer->bits_per_word); ++ ++ /* Each transfer can also specify a different rate */ ++ ret = k1_spi_set_speed(drv_data, transfer); ++ if (ret) { ++ dev_err(&host->dev, ++ "failed to set transfer speed: %d\n", ret); ++ return ret; ++ } ++ ++ drv_data->rx_resid = transfer->len; ++ drv_data->tx_resid = transfer->len; ++ ++ drv_data->transfer = transfer; ++ ++ /* Clear any existing interrupt conditions */ ++ writel(~0, drv_data->base + SSP_STATUS); ++ ++ /* Set the data (word) size, and enable the port */ ++ ctrl = readl(drv_data->base + SSP_TOP_CTRL); ++ ctrl &= ~TOP_DSS_MASK; ++ ctrl |= FIELD_PREP(TOP_DSS_MASK, transfer->bits_per_word - 1); ++ ctrl |= TOP_SSE; ++ writel(ctrl, drv_data->base + SSP_TOP_CTRL); ++ ++ if (spi_xfer_is_dma_mapped(host, spi, transfer)) ++ return k1_spi_dma_one(host, spi, transfer); ++ ++ /* An interrupt will initiate the transfer */ ++ val = SSP_INT_EN_TX | SSP_INT_EN_RX | SSP_INT_EN_ERROR; ++ writel(val, drv_data->base + SSP_INT_EN); ++ ++ return 1; /* We will call spi_finalize_current_transfer() */ ++} ++ ++static void ++k1_spi_handle_err(struct spi_controller *host, struct spi_message *message) ++{ ++ struct k1_spi_driver_data *drv_data = spi_controller_get_devdata(host); ++ ++ if (drv_data->dma_enabled) { ++ dmaengine_terminate_sync(host->dma_rx); ++ dmaengine_terminate_sync(host->dma_tx); ++ } ++} ++ ++static void k1_spi_write_word(struct k1_spi_driver_data *drv_data) ++{ ++ struct spi_transfer *transfer = drv_data->transfer; ++ u32 bytes = drv_data->bytes; ++ u32 val; ++ ++ if (transfer->tx_buf) { ++ const void *buf; ++ ++ buf = transfer->tx_buf + (transfer->len - drv_data->tx_resid); ++ if (bytes == 1) ++ val = *(u8 *)buf; ++ else if (bytes == 2) ++ val = *(u16 *)buf; ++ else /* bytes == 4 */ ++ val = *(u32 *)buf; ++ } else { ++ val = 0; /* Null writer; write 1, 2, or 4 zero bytes */ ++ } ++ /* Fill the next TX FIFO entry */ ++ writel(val, drv_data->base + SSP_DATAR); ++ ++ drv_data->tx_resid -= bytes; ++} ++ ++/* The last-read status value is provided; we know SSP_STATUS_TNF is set */ ++static bool k1_spi_write(struct k1_spi_driver_data *drv_data, u32 val) ++{ ++ unsigned int count; ++ ++ /* Get the number of open slots in the FIFO; zero means all */ ++ count = FIELD_GET(SSP_STATUS_TFL, val) ? : K1_SPI_FIFO_SIZE; ++ ++ /* ++ * Limit how much we try to send at a time, to reduce the ++ * chance the other side can overrun our RX FIFO. ++ */ ++ count = min3(count, K1_SPI_THRESH, drv_data->tx_resid / drv_data->bytes); ++ do ++ k1_spi_write_word(drv_data); ++ while (--count); ++ ++ return !drv_data->tx_resid; ++} ++ ++static void k1_spi_read_word(struct k1_spi_driver_data *drv_data) ++{ ++ struct spi_transfer *transfer = drv_data->transfer; ++ u32 bytes = drv_data->bytes; ++ u32 val; ++ ++ /* Consume the next RX FIFO entry */ ++ val = readl(drv_data->base + SSP_DATAR); ++ if (transfer->rx_buf) { ++ void *buf; ++ ++ buf = transfer->rx_buf + (transfer->len - drv_data->rx_resid); ++ ++ if (bytes == 1) ++ *(u8 *)buf = val; ++ else if (bytes == 2) ++ *(u16 *)buf = val; ++ else /* bytes == 4 */ ++ *(u32 *)buf = val; ++ } /* Otherwise null reader: discard the data */ ++ ++ drv_data->rx_resid -= bytes; ++} ++ ++/* The last-read status value is provided; we know SSP_STATUS_RNE is set */ ++static bool k1_spi_read(struct k1_spi_driver_data *drv_data, u32 val) ++{ ++ do { ++ unsigned int count = FIELD_GET(SSP_STATUS_RFL, val) + 1; ++ ++ /* Only read what we need */ ++ count = min(count, drv_data->rx_resid / drv_data->bytes); ++ do ++ k1_spi_read_word(drv_data); ++ while (--count); ++ ++ /* If there's no more to read, we're done */ ++ if (!drv_data->rx_resid) ++ return true; ++ ++ /* Check again in case more became available to read */ ++ val = readl(drv_data->base + SSP_STATUS); ++ if (val & SSP_STATUS_RNE) ++ writel(SSP_STATUS_RNE, drv_data->base + SSP_STATUS); ++ else ++ return false; ++ } while (true); ++} ++ ++static irqreturn_t k1_spi_ssp_isr(int irq, void *dev_id) ++{ ++ struct k1_spi_driver_data *drv_data = dev_id; ++ u32 status; ++ u32 top_ctrl; ++ ++ /* Get status and clear pending interrupts */ ++ status = readl(drv_data->base + SSP_STATUS); ++ writel(status, drv_data->base + SSP_STATUS); ++ ++ /* If no actionable status bits are set, this is not our interrupt */ ++ if (!(status & (SSP_STATUS_ERROR | SSP_STATUS_TNF | SSP_STATUS_RNE))) ++ return IRQ_NONE; ++ ++ /* Check for any error conditions first */ ++ if (status & SSP_STATUS_ERROR) { ++ if (drv_data->transfer) ++ drv_data->transfer->error |= SPI_TRANS_FAIL_IO; ++ goto done; ++ } ++ ++ /* ++ * For SPI, bytes are transferred in both directions equally, and ++ * RX always follows TX. Start by writing if there is anything to ++ * write, then read. Once there's no more to read, we're done. ++ */ ++ if (drv_data->tx_resid && (status & SSP_STATUS_TNF)) { ++ /* If we finish writing, disable TX interrupts */ ++ if (k1_spi_write(drv_data, status)) ++ writel(SSP_INT_EN_RX | SSP_INT_EN_ERROR, ++ drv_data->base + SSP_INT_EN); ++ } ++ ++ /* We're not done unless we've read all that was requested */ ++ if (drv_data->rx_resid) { ++ /* Read more if the FIFO is not empty */ ++ if (status & SSP_STATUS_RNE) ++ if (k1_spi_read(drv_data, status)) ++ goto done; ++ ++ return IRQ_HANDLED; ++ } ++done: ++ /* Disable the port */ ++ top_ctrl = readl(drv_data->base + SSP_TOP_CTRL); ++ top_ctrl &= ~TOP_SSE; ++ writel(top_ctrl, drv_data->base + SSP_TOP_CTRL); ++ ++ /* Disable all interrupts */ ++ writel(0, drv_data->base + SSP_INT_EN); ++ ++ if (drv_data->transfer) { ++ drv_data->transfer = NULL; ++ spi_finalize_current_transfer(drv_data->host); ++ } ++ ++ return IRQ_HANDLED; ++} ++ ++static int ++k1_spi_dma_setup(struct k1_spi_driver_data *drv_data, struct device *dev) ++{ ++ struct spi_controller *host = drv_data->host; ++ struct dma_chan *chan; ++ ++ chan = dma_request_chan(dev, "tx"); ++ if (IS_ERR(chan)) ++ return PTR_ERR(chan); ++ host->dma_tx = chan; ++ ++ chan = dma_request_chan(dev, "rx"); ++ if (IS_ERR(chan)) { ++ dma_release_channel(host->dma_tx); ++ host->dma_tx = NULL; ++ return PTR_ERR(chan); ++ } ++ host->dma_rx = chan; ++ ++ drv_data->dma_enabled = true; ++ ++ return 0; ++} ++ ++static void k1_spi_dma_cleanup(struct device *dev, void *res) ++{ ++ struct k1_spi_driver_data **ptr = res; ++ struct k1_spi_driver_data *drv_data = *ptr; ++ struct spi_controller *host = drv_data->host; ++ ++ if (!drv_data->dma_enabled) ++ return; ++ ++ drv_data->dma_enabled = false; ++ ++ dma_release_channel(host->dma_rx); ++ host->dma_rx = NULL; ++ dma_release_channel(host->dma_tx); ++ host->dma_tx = NULL; ++} ++ ++static int ++devm_k1_spi_dma_setup(struct k1_spi_driver_data *drv_data, struct device *dev) ++{ ++ struct k1_spi_driver_data **ptr; ++ int ret; ++ ++ if (!IS_ENABLED(CONFIG_MMP_PDMA)) { ++ dev_info(dev, "DMA not available; using PIO\n"); ++ return 0; ++ } ++ ++ ptr = devres_alloc(k1_spi_dma_cleanup, sizeof(*ptr), GFP_KERNEL); ++ if (!ptr) ++ return -ENOMEM; ++ ++ ret = k1_spi_dma_setup(drv_data, dev); ++ if (ret) { ++ devres_free(ptr); ++ return ret; ++ } ++ ++ *ptr = drv_data; ++ devres_add(dev, ptr); ++ ++ return 0; ++} ++ ++static int k1_spi_probe(struct platform_device *pdev) ++{ ++ struct k1_spi_driver_data *drv_data; ++ struct device *dev = &pdev->dev; ++ struct reset_control *reset; ++ struct spi_controller *host; ++ struct resource *iores; ++ struct clk *clk_bus; ++ int ret; ++ ++ host = devm_spi_alloc_host(dev, sizeof(*drv_data)); ++ if (!host) ++ return -ENOMEM; ++ drv_data = spi_controller_get_devdata(host); ++ drv_data->host = host; ++ platform_set_drvdata(pdev, drv_data); ++ ++ ret = devm_k1_spi_dma_setup(drv_data, dev); ++ if (ret == -EPROBE_DEFER) ++ return ret; ++ if (ret) ++ dev_warn(dev, "DMA setup failed (%d), falling back to PIO\n", ret); ++ ++ drv_data->base = devm_platform_get_and_ioremap_resource(pdev, 0, ++ &iores); ++ if (IS_ERR(drv_data->base)) ++ return dev_err_probe(dev, PTR_ERR(drv_data->base), ++ "error mapping memory\n"); ++ drv_data->base_addr = iores->start; ++ ++ clk_bus = devm_clk_get_enabled(dev, "bus"); ++ if (IS_ERR(clk_bus)) ++ return dev_err_probe(dev, PTR_ERR(clk_bus), ++ "error getting/enabling bus clock\n"); ++ drv_data->bus_rate = clk_get_rate(clk_bus); ++ ++ drv_data->clk = devm_clk_get_enabled(dev, "core"); ++ if (IS_ERR(drv_data->clk)) ++ return dev_err_probe(dev, PTR_ERR(drv_data->clk), ++ "error getting/enabling core clock\n"); ++ ++ reset = devm_reset_control_get_exclusive_deasserted(dev, NULL); ++ if (IS_ERR(reset)) ++ return dev_err_probe(dev, PTR_ERR(reset), ++ "error getting/deasserting reset\n"); ++ ++ k1_spi_register_reset(drv_data, true); ++ ++ drv_data->irq = platform_get_irq(pdev, 0); ++ if (drv_data->irq < 0) ++ return dev_err_probe(dev, drv_data->irq, "error getting IRQ\n"); ++ ++ ret = devm_request_irq(dev, drv_data->irq, k1_spi_ssp_isr, ++ IRQF_SHARED, dev_name(dev), drv_data); ++ if (ret < 0) ++ return dev_err_probe(dev, ret, "error requesting IRQ\n"); ++ ++ /* Initialize the host structure, then register it */ ++ host->dev.of_node = dev_of_node(dev); ++ host->dev.parent = dev; ++ host->num_chipselect = 1; ++ if (drv_data->dma_enabled) ++ host->dma_alignment = K1_SPI_DMA_ALIGNMENT; ++ host->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LOOP; ++ host->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32); ++ host->min_speed_hz = K1_SPI_MIN_SPEED_HZ; ++ host->max_speed_hz = K1_SPI_MAX_SPEED_HZ; ++ host->flags = SPI_CONTROLLER_MUST_RX | SPI_CONTROLLER_MUST_TX; ++ host->max_dma_len = K1_SPI_MAX_DMA_LEN; ++ ++ host->setup = k1_spi_setup; ++ host->cleanup = k1_spi_cleanup; ++ host->can_dma = k1_spi_can_dma; ++ host->prepare_message = k1_spi_prepare_message; ++ host->set_cs = k1_spi_set_cs; ++ host->transfer_one = k1_spi_transfer_one; ++ host->handle_err = k1_spi_handle_err; ++ ++ ret = devm_spi_register_controller(dev, host); ++ if (ret) ++ dev_err(dev, "error registering controller\n"); ++ ++ return ret; ++} ++ ++static const struct of_device_id k1_spi_dt_ids[] = { ++ { .compatible = "spacemit,k1-spi", }, ++ {} ++}; ++MODULE_DEVICE_TABLE(of, k1_spi_dt_ids); ++ ++static struct platform_driver k1_spi_driver = { ++ .probe = k1_spi_probe, ++ .driver = { ++ .name = "k1-spi", ++ .of_match_table = k1_spi_dt_ids, ++ }, ++}; ++module_platform_driver(k1_spi_driver); ++ ++MODULE_DESCRIPTION("SpacemiT K1 SPI controller driver"); ++MODULE_LICENSE("GPL"); diff --git a/target/linux/spacemit/patches-6.18/0090-riscv-dts-spacemit-define-a-SPI-controller-node.patch b/target/linux/spacemit/patches-6.18/0090-riscv-dts-spacemit-define-a-SPI-controller-node.patch new file mode 100644 index 00000000000000..4a977f57a7b343 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0090-riscv-dts-spacemit-define-a-SPI-controller-node.patch @@ -0,0 +1,105 @@ +From c947e8f96dfc565c37635ba5aeda1c69a836ed43 Mon Sep 17 00:00:00 2001 +From: Alex Elder +Date: Sat, 2 May 2026 21:30:53 -0400 +Subject: [PATCH] riscv: dts: spacemit: define a SPI controller node + +Define a node for the fourth SoC SPI controller (number 3) on the +SpacemiT K1 SoC. + +Enable it on the Banana Pi BPI-F3 board, which exposes this feature +via its GPIO block: + GPIO PIN 19: MOSI + GPIO PIN 21: MISO + GPIO PIN 23: SCLK + GPIO PIN 24: SS (inverted) + +Define pincontrol configurations for the pins as used on that board. + +(This was tested using a GigaDevice GD25Q64E SPI NOR chip.) + +Reviewed-by: Yixun Lan +Signed-off-by: Alex Elder +Signed-off-by: Guodong Xu +Link: https://lore.kernel.org/r/20260502-spi-spacemit-k1-v10-3-f412e1ae8a34@riscstar.com +Signed-off-by: Yixun Lan +(cherry picked from commit c580774185426ea316396b1dc3f1737a3ad3800a) +--- + .../boot/dts/spacemit/k1-bananapi-f3.dts | 7 +++++++ + arch/riscv/boot/dts/spacemit/k1-pinctrl.dtsi | 20 +++++++++++++++++++ + arch/riscv/boot/dts/spacemit/k1.dtsi | 15 ++++++++++++++ + 3 files changed, 42 insertions(+) + +--- a/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts ++++ b/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts +@@ -14,6 +14,7 @@ + ethernet0 = ð0; + ethernet1 = ð1; + serial0 = &uart0; ++ spi3 = &spi3; + i2c2 = &i2c2; + i2c8 = &i2c8; + }; +@@ -335,6 +336,12 @@ + status = "okay"; + }; + ++&spi3 { ++ pinctrl-0 = <&ssp3_0_cfg>; ++ pinctrl-names = "default"; ++ status = "okay"; ++}; ++ + &uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_2_cfg>; +--- a/arch/riscv/boot/dts/spacemit/k1-pinctrl.dtsi ++++ b/arch/riscv/boot/dts/spacemit/k1-pinctrl.dtsi +@@ -570,4 +570,24 @@ + drive-strength = <32>; + }; + }; ++ ++ ssp3_0_cfg: ssp3-0-cfg { ++ ssp3-0-pins { ++ pinmux = , /* SCLK */ ++ , /* MOSI */ ++ ; /* MISO */ ++ ++ bias-disable; ++ drive-strength = <19>; ++ power-source = <3300>; ++ }; ++ ++ ssp3-0-frm-pins { ++ pinmux = ; /* FRM (frame) */ ++ ++ bias-pull-up = <0>; ++ drive-strength = <19>; ++ power-source = <3300>; ++ }; ++ }; + }; +--- a/arch/riscv/boot/dts/spacemit/k1.dtsi ++++ b/arch/riscv/boot/dts/spacemit/k1.dtsi +@@ -983,6 +983,21 @@ + status = "disabled"; + }; + ++ spi3: spi@d401c000 { ++ compatible = "spacemit,k1-spi"; ++ reg = <0x0 0xd401c000 0x0 0x30>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ clocks = <&syscon_apbc CLK_SSP3>, ++ <&syscon_apbc CLK_SSP3_BUS>; ++ clock-names = "core", "bus"; ++ resets = <&syscon_apbc RESET_SSP3>; ++ interrupts = <55>; ++ dmas = <&pdma 20>, <&pdma 19>; ++ dma-names = "rx", "tx"; ++ status = "disabled"; ++ }; ++ + /* sec_uart1: 0xf0612000, not available from Linux */ + }; + diff --git a/target/linux/spacemit/patches-6.18/0091-dts-riscv-spacemit-correct-32k-clock-frequency.patch b/target/linux/spacemit/patches-6.18/0091-dts-riscv-spacemit-correct-32k-clock-frequency.patch new file mode 100644 index 00000000000000..15d294cde44572 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0091-dts-riscv-spacemit-correct-32k-clock-frequency.patch @@ -0,0 +1,27 @@ +From c44ce8e58743d471fb3d19e31c95abe39148e326 Mon Sep 17 00:00:00 2001 +From: Yixun Lan +Date: Tue, 28 Apr 2026 10:57:29 +0000 +Subject: [PATCH] dts: riscv: spacemit: correct 32k clock frequency + +The 32k oscillator's clock frequency is actually 32768Hz, so correct it. + +Fixes: 67072c8cd48c ("riscv: dts: spacemit: k3: add clock tree") +Fixes: a6fafa64b03a ("riscv: dts: spacemit: Add clock tree for SpacemiT K1") +Link: https://patch.msgid.link/20260428-06-k3-clk-osc32k-v1-1-e2378da7cb9b@kernel.org +Signed-off-by: Yixun Lan +(cherry picked from commit 3c350f6284d8ea5e7a9648241b2e9604f2262d42) +--- + arch/riscv/boot/dts/spacemit/k1.dtsi | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/riscv/boot/dts/spacemit/k1.dtsi ++++ b/arch/riscv/boot/dts/spacemit/k1.dtsi +@@ -333,7 +333,7 @@ + + osc_32k: clock-32k { + compatible = "fixed-clock"; +- clock-frequency = <32000>; ++ clock-frequency = <32768>; + clock-output-names = "osc_32k"; + #clock-cells = <0>; + }; diff --git a/target/linux/spacemit/patches-6.18/0092-riscv-dts-spacemit-enable-eMMC-for-OrangePi-RV2.patch b/target/linux/spacemit/patches-6.18/0092-riscv-dts-spacemit-enable-eMMC-for-OrangePi-RV2.patch new file mode 100644 index 00000000000000..8d58fd7b1d2fc9 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0092-riscv-dts-spacemit-enable-eMMC-for-OrangePi-RV2.patch @@ -0,0 +1,36 @@ +From d2cee02a35525b7a870381ba7e72d2a96e47d38e Mon Sep 17 00:00:00 2001 +From: Chukun Pan +Date: Sat, 9 May 2026 18:00:00 +0800 +Subject: [PATCH] riscv: dts: spacemit: enable eMMC for OrangePi RV2 + +The OrangePi RV2 board has one eMMC slot, so enable eMMC. +Tested using a 16 GiB AJTD4R eMMC module. + +Signed-off-by: Chukun Pan +Reviewed-by: Yixun Lan +Link: https://patch.msgid.link/20260509100000.3315109-1-amadeus@jmu.edu.cn +Signed-off-by: Yixun Lan +(cherry picked from commit f068b204555ad62d6a841a49feb4ea8c4f45b25c) +--- + arch/riscv/boot/dts/spacemit/k1-orangepi-rv2.dts | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +--- a/arch/riscv/boot/dts/spacemit/k1-orangepi-rv2.dts ++++ b/arch/riscv/boot/dts/spacemit/k1-orangepi-rv2.dts +@@ -78,6 +78,16 @@ + status = "okay"; + }; + ++&emmc { ++ bus-width = <8>; ++ mmc-hs400-1_8v; ++ mmc-hs400-enhanced-strobe; ++ no-sd; ++ no-sdio; ++ non-removable; ++ status = "okay"; ++}; ++ + ð0 { + phy-handle = <&rgmii0>; + phy-mode = "rgmii-id"; diff --git a/target/linux/spacemit/patches-6.18/0093-usb-dwc3-Add-software-managed-properties-for-flatten.patch b/target/linux/spacemit/patches-6.18/0093-usb-dwc3-Add-software-managed-properties-for-flatten.patch new file mode 100644 index 00000000000000..fa49a2b4bd4f57 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0093-usb-dwc3-Add-software-managed-properties-for-flatten.patch @@ -0,0 +1,122 @@ +From 47b1bcf85a6c54f1cc95b24ed0e39535088efaf7 Mon Sep 17 00:00:00 2001 +From: Frank Li +Date: Mon, 29 Sep 2025 10:24:15 -0400 +Subject: [PATCH] usb: dwc3: Add software-managed properties for flattened + model + +Add software-managed properties for the flattened model, which does not +need to use device tree properties to pass down information to the +common DWC3 core. + +Add 'properties' in dwc3_probe_data and set default values for existing +users (dwc3-qcom, dwc3-generic-plat). + +No functional changes. + +Acked-by: Thinh Nguyen +Signed-off-by: Frank Li +Link: https://lore.kernel.org/r/20250929-ls_dma_coherence-v5-2-2ebee578eb7e@nxp.com +Signed-off-by: Greg Kroah-Hartman +(cherry picked from commit 7298c06d58e23c1c6e60180ab1ce069087ae38e2) +--- + drivers/usb/dwc3/core.c | 12 ++++++++++-- + drivers/usb/dwc3/dwc3-generic-plat.c | 1 + + drivers/usb/dwc3/dwc3-qcom.c | 1 + + drivers/usb/dwc3/glue.h | 14 ++++++++++++++ + 4 files changed, 26 insertions(+), 2 deletions(-) + +--- a/drivers/usb/dwc3/core.c ++++ b/drivers/usb/dwc3/core.c +@@ -1669,7 +1669,8 @@ static void dwc3_core_exit_mode(struct d + dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_DEVICE, true); + } + +-static void dwc3_get_software_properties(struct dwc3 *dwc) ++static void dwc3_get_software_properties(struct dwc3 *dwc, ++ const struct dwc3_properties *properties) + { + struct device *tmpdev; + u16 gsbuscfg0_reqinfo; +@@ -1677,6 +1678,12 @@ static void dwc3_get_software_properties + + dwc->gsbuscfg0_reqinfo = DWC3_GSBUSCFG0_REQINFO_UNSPECIFIED; + ++ if (properties->gsbuscfg0_reqinfo != ++ DWC3_GSBUSCFG0_REQINFO_UNSPECIFIED) { ++ dwc->gsbuscfg0_reqinfo = properties->gsbuscfg0_reqinfo; ++ return; ++ } ++ + /* + * Iterate over all parent nodes for finding swnode properties + * and non-DT (non-ABI) properties. +@@ -2224,7 +2231,7 @@ int dwc3_core_probe(const struct dwc3_pr + + dwc3_get_properties(dwc); + +- dwc3_get_software_properties(dwc); ++ dwc3_get_software_properties(dwc, &data->properties); + + dwc->usb_psy = dwc3_get_usb_power_supply(dwc); + if (IS_ERR(dwc->usb_psy)) +@@ -2374,6 +2381,7 @@ static int dwc3_probe(struct platform_de + + probe_data.dwc = dwc; + probe_data.res = res; ++ probe_data.properties = DWC3_DEFAULT_PROPERTIES; + + return dwc3_core_probe(&probe_data); + } +--- a/drivers/usb/dwc3/dwc3-generic-plat.c ++++ b/drivers/usb/dwc3/dwc3-generic-plat.c +@@ -75,6 +75,7 @@ static int dwc3_generic_probe(struct pla + probe_data.dwc = &dwc3g->dwc; + probe_data.res = res; + probe_data.ignore_clocks_and_resets = true; ++ probe_data.properties = DWC3_DEFAULT_PROPERTIES; + ret = dwc3_core_probe(&probe_data); + if (ret) + return dev_err_probe(dev, ret, "failed to register DWC3 Core\n"); +--- a/drivers/usb/dwc3/dwc3-qcom.c ++++ b/drivers/usb/dwc3/dwc3-qcom.c +@@ -704,6 +704,7 @@ static int dwc3_qcom_probe(struct platfo + probe_data.dwc = &qcom->dwc; + probe_data.res = &res; + probe_data.ignore_clocks_and_resets = true; ++ probe_data.properties = DWC3_DEFAULT_PROPERTIES; + ret = dwc3_core_probe(&probe_data); + if (ret) { + ret = dev_err_probe(dev, ret, "failed to register DWC3 Core\n"); +--- a/drivers/usb/dwc3/glue.h ++++ b/drivers/usb/dwc3/glue.h +@@ -10,16 +10,30 @@ + #include "core.h" + + /** ++ * dwc3_properties: DWC3 core properties ++ * @gsbuscfg0_reqinfo: Value to be programmed in the GSBUSCFG0.REQINFO field ++ */ ++struct dwc3_properties { ++ u32 gsbuscfg0_reqinfo; ++}; ++ ++#define DWC3_DEFAULT_PROPERTIES ((struct dwc3_properties){ \ ++ .gsbuscfg0_reqinfo = DWC3_GSBUSCFG0_REQINFO_UNSPECIFIED, \ ++ }) ++ ++/** + * dwc3_probe_data: Initialization parameters passed to dwc3_core_probe() + * @dwc: Reference to dwc3 context structure + * @res: resource for the DWC3 core mmio region + * @ignore_clocks_and_resets: clocks and resets defined for the device should + * be ignored by the DWC3 core, as they are managed by the glue ++ * @properties: dwc3 software manage properties + */ + struct dwc3_probe_data { + struct dwc3 *dwc; + struct resource *res; + bool ignore_clocks_and_resets; ++ struct dwc3_properties properties; + }; + + int dwc3_core_probe(const struct dwc3_probe_data *data); diff --git a/target/linux/spacemit/patches-6.18/0094-usb-dwc3-dwc3-generic-plat-Add-layerscape-dwc3-suppo.patch b/target/linux/spacemit/patches-6.18/0094-usb-dwc3-dwc3-generic-plat-Add-layerscape-dwc3-suppo.patch new file mode 100644 index 00000000000000..567a1f4eaa8716 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0094-usb-dwc3-dwc3-generic-plat-Add-layerscape-dwc3-suppo.patch @@ -0,0 +1,56 @@ +From 4bb83afb0d8abbd12c7ebf7070a5f640dabd607d Mon Sep 17 00:00:00 2001 +From: Frank Li +Date: Mon, 29 Sep 2025 10:24:16 -0400 +Subject: [PATCH] usb: dwc3: dwc3-generic-plat: Add layerscape dwc3 support + +Add layerscape dwc3 support by using flatten dwc3 core library. Layerscape +dwc3 need set gsbuscfg0-reqinfo as 0x2222 when dma-coherence set. + +Signed-off-by: Frank Li +Acked-by: Thinh Nguyen +Link: https://lore.kernel.org/r/20250929-ls_dma_coherence-v5-3-2ebee578eb7e@nxp.com +Signed-off-by: Greg Kroah-Hartman +(cherry picked from commit 1c97fc901fb6318aca0160da96736d0bc136ddcd) +--- + drivers/usb/dwc3/dwc3-generic-plat.c | 14 +++++++++++++- + 1 file changed, 13 insertions(+), 1 deletion(-) + +--- a/drivers/usb/dwc3/dwc3-generic-plat.c ++++ b/drivers/usb/dwc3/dwc3-generic-plat.c +@@ -29,6 +29,7 @@ static void dwc3_generic_reset_control_a + + static int dwc3_generic_probe(struct platform_device *pdev) + { ++ const struct dwc3_properties *properties; + struct dwc3_probe_data probe_data = {}; + struct device *dev = &pdev->dev; + struct dwc3_generic *dwc3g; +@@ -75,7 +76,13 @@ static int dwc3_generic_probe(struct pla + probe_data.dwc = &dwc3g->dwc; + probe_data.res = res; + probe_data.ignore_clocks_and_resets = true; +- probe_data.properties = DWC3_DEFAULT_PROPERTIES; ++ ++ properties = of_device_get_match_data(dev); ++ if (properties) ++ probe_data.properties = *properties; ++ else ++ probe_data.properties = DWC3_DEFAULT_PROPERTIES; ++ + ret = dwc3_core_probe(&probe_data); + if (ret) + return dev_err_probe(dev, ret, "failed to register DWC3 Core\n"); +@@ -143,8 +150,13 @@ static const struct dev_pm_ops dwc3_gene + dwc3_generic_runtime_idle) + }; + ++static const struct dwc3_properties fsl_ls1028_dwc3 = { ++ .gsbuscfg0_reqinfo = 0x2222, ++}; ++ + static const struct of_device_id dwc3_generic_of_match[] = { + { .compatible = "spacemit,k1-dwc3", }, ++ { .compatible = "fsl,ls1028a-dwc3", &fsl_ls1028_dwc3}, + { /* sentinel */ } + }; + MODULE_DEVICE_TABLE(of, dwc3_generic_of_match); diff --git a/target/linux/spacemit/patches-6.18/0095-usb-dwc3-eic7700-Add-EIC7700-USB-driver.patch b/target/linux/spacemit/patches-6.18/0095-usb-dwc3-eic7700-Add-EIC7700-USB-driver.patch new file mode 100644 index 00000000000000..d91babf366d73b --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0095-usb-dwc3-eic7700-Add-EIC7700-USB-driver.patch @@ -0,0 +1,143 @@ +From 6cb2ee49ffd66a5b29d047a4c9cddcf694d0ca34 Mon Sep 17 00:00:00 2001 +From: Hang Cao +Date: Wed, 12 Nov 2025 13:53:45 +0800 +Subject: [PATCH] usb: dwc3: eic7700: Add EIC7700 USB driver + +The EIC7700 instantiates two USB 3.0 DWC3 IPs, each of which is backward +compatible with USB interfaces. It supports Super-speed (5Gb/s), DRD mode, +and compatible with xHCI 1.1, etc. Each of instances supports 16 endpoints +in device's mode and max 64 devices in host's mode. + +This module needs to interact with the NOC via the AXI master bus, thus +requiring some HSP configuration operations to achieve this. Ops include +bus filter, pm signal or status to usb bus and so on. + +Acked-by: Thinh Nguyen +Signed-off-by: Senchuan Zhang +Signed-off-by: Hang Cao +Link: https://patch.msgid.link/20251112055346.1655-1-caohang@eswincomputing.com +Signed-off-by: Greg Kroah-Hartman +(cherry picked from commit e05d28b759c28660c28a36bf0add178edcc3466e) +--- + drivers/usb/dwc3/dwc3-generic-plat.c | 71 +++++++++++++++++++++++++--- + 1 file changed, 64 insertions(+), 7 deletions(-) + +--- a/drivers/usb/dwc3/dwc3-generic-plat.c ++++ b/drivers/usb/dwc3/dwc3-generic-plat.c +@@ -10,8 +10,16 @@ + #include + #include + #include ++#include ++#include + #include "glue.h" + ++#define EIC7700_HSP_BUS_FILTER_EN BIT(0) ++#define EIC7700_HSP_BUS_CLKEN_GM BIT(9) ++#define EIC7700_HSP_BUS_CLKEN_GS BIT(16) ++#define EIC7700_HSP_AXI_LP_XM_CSYSREQ BIT(0) ++#define EIC7700_HSP_AXI_LP_XS_CSYSREQ BIT(16) ++ + struct dwc3_generic { + struct device *dev; + struct dwc3 dwc; +@@ -20,6 +28,11 @@ struct dwc3_generic { + struct reset_control *resets; + }; + ++struct dwc3_generic_config { ++ int (*init)(struct dwc3_generic *dwc3g); ++ struct dwc3_properties properties; ++}; ++ + #define to_dwc3_generic(d) container_of((d), struct dwc3_generic, dwc) + + static void dwc3_generic_reset_control_assert(void *data) +@@ -27,9 +40,38 @@ static void dwc3_generic_reset_control_a + reset_control_assert(data); + } + ++static int dwc3_eic7700_init(struct dwc3_generic *dwc3g) ++{ ++ struct device *dev = dwc3g->dev; ++ struct regmap *regmap; ++ u32 hsp_usb_axi_lp; ++ u32 hsp_usb_bus; ++ u32 args[2]; ++ u32 val; ++ ++ regmap = syscon_regmap_lookup_by_phandle_args(dev->of_node, ++ "eswin,hsp-sp-csr", ++ ARRAY_SIZE(args), args); ++ if (IS_ERR(regmap)) { ++ dev_err(dev, "No hsp-sp-csr phandle specified\n"); ++ return PTR_ERR(regmap); ++ } ++ ++ hsp_usb_bus = args[0]; ++ hsp_usb_axi_lp = args[1]; ++ ++ regmap_read(regmap, hsp_usb_bus, &val); ++ regmap_write(regmap, hsp_usb_bus, val | EIC7700_HSP_BUS_FILTER_EN | ++ EIC7700_HSP_BUS_CLKEN_GM | EIC7700_HSP_BUS_CLKEN_GS); ++ ++ regmap_write(regmap, hsp_usb_axi_lp, EIC7700_HSP_AXI_LP_XM_CSYSREQ | ++ EIC7700_HSP_AXI_LP_XS_CSYSREQ); ++ return 0; ++} ++ + static int dwc3_generic_probe(struct platform_device *pdev) + { +- const struct dwc3_properties *properties; ++ const struct dwc3_generic_config *plat_config; + struct dwc3_probe_data probe_data = {}; + struct device *dev = &pdev->dev; + struct dwc3_generic *dwc3g; +@@ -77,12 +119,21 @@ static int dwc3_generic_probe(struct pla + probe_data.res = res; + probe_data.ignore_clocks_and_resets = true; + +- properties = of_device_get_match_data(dev); +- if (properties) +- probe_data.properties = *properties; +- else ++ plat_config = of_device_get_match_data(dev); ++ if (!plat_config) { + probe_data.properties = DWC3_DEFAULT_PROPERTIES; ++ goto core_probe; ++ } + ++ probe_data.properties = plat_config->properties; ++ if (plat_config->init) { ++ ret = plat_config->init(dwc3g); ++ if (ret) ++ return dev_err_probe(dev, ret, ++ "failed to init platform\n"); ++ } ++ ++core_probe: + ret = dwc3_core_probe(&probe_data); + if (ret) + return dev_err_probe(dev, ret, "failed to register DWC3 Core\n"); +@@ -150,13 +201,19 @@ static const struct dev_pm_ops dwc3_gene + dwc3_generic_runtime_idle) + }; + +-static const struct dwc3_properties fsl_ls1028_dwc3 = { +- .gsbuscfg0_reqinfo = 0x2222, ++static const struct dwc3_generic_config fsl_ls1028_dwc3 = { ++ .properties.gsbuscfg0_reqinfo = 0x2222, ++}; ++ ++static const struct dwc3_generic_config eic7700_dwc3 = { ++ .init = dwc3_eic7700_init, ++ .properties = DWC3_DEFAULT_PROPERTIES, + }; + + static const struct of_device_id dwc3_generic_of_match[] = { + { .compatible = "spacemit,k1-dwc3", }, + { .compatible = "fsl,ls1028a-dwc3", &fsl_ls1028_dwc3}, ++ { .compatible = "eswin,eic7700-dwc3", &eic7700_dwc3}, + { /* sentinel */ } + }; + MODULE_DEVICE_TABLE(of, dwc3_generic_of_match); diff --git a/target/linux/spacemit/patches-6.18/0096-usb-dwc3-dwc3-generic-plat-spacemit-add-support-for-.patch b/target/linux/spacemit/patches-6.18/0096-usb-dwc3-dwc3-generic-plat-spacemit-add-support-for-.patch new file mode 100644 index 00000000000000..8ebd10508da766 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0096-usb-dwc3-dwc3-generic-plat-spacemit-add-support-for-.patch @@ -0,0 +1,27 @@ +From 083efc556862348e8c0291cfc3d1817a9b998daa Mon Sep 17 00:00:00 2001 +From: Yixun Lan +Date: Fri, 20 Mar 2026 07:15:38 +0000 +Subject: [PATCH] usb: dwc3: dwc3-generic-plat: spacemit: add support for K3 + SoC + +Add support for the DWC3 USB controller which found in SpacemiT K3 SoC. + +Acked-by: Thinh Nguyen +Signed-off-by: Yixun Lan +Link: https://patch.msgid.link/20260320-02-k3-usb20-support-v2-2-308ea0e44038@kernel.org +Signed-off-by: Greg Kroah-Hartman +(cherry picked from commit c05cf9d274daf72dc7e433480cf2e0e888f6bd89) +--- + drivers/usb/dwc3/dwc3-generic-plat.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/usb/dwc3/dwc3-generic-plat.c ++++ b/drivers/usb/dwc3/dwc3-generic-plat.c +@@ -212,6 +212,7 @@ static const struct dwc3_generic_config + + static const struct of_device_id dwc3_generic_of_match[] = { + { .compatible = "spacemit,k1-dwc3", }, ++ { .compatible = "spacemit,k3-dwc3", }, + { .compatible = "fsl,ls1028a-dwc3", &fsl_ls1028_dwc3}, + { .compatible = "eswin,eic7700-dwc3", &eic7700_dwc3}, + { /* sentinel */ } diff --git a/target/linux/spacemit/patches-6.18/0097-usb-dwc3-Add-optional-VBUS-regulator-support-to-Spac.patch b/target/linux/spacemit/patches-6.18/0097-usb-dwc3-Add-optional-VBUS-regulator-support-to-Spac.patch new file mode 100644 index 00000000000000..599e82b91ebd61 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0097-usb-dwc3-Add-optional-VBUS-regulator-support-to-Spac.patch @@ -0,0 +1,77 @@ +From cea66c89dac3f3d742a0f3577145e3c15fc5439f Mon Sep 17 00:00:00 2001 +From: Chukun Pan +Date: Thu, 26 Mar 2026 18:00:10 +0800 +Subject: [PATCH] usb: dwc3: Add optional VBUS regulator support to SpacemiT K1 + +Some SpacemiT K1 boards (like OrangePi R2S) provide USB VBUS +through a controllable regulator. Add support for the optional +vbus-supply property so the regulator can be properly managed +in host mode instead of left always-on. Note that this doesn't +apply to USB Hub downstream ports with different VBUS supplies. + +The enabled and disabled actions of the regulator are handled +automatically by devm_regulator_get_enable_optional(). + +Signed-off-by: Chukun Pan +Acked-by: Thinh Nguyen +Reviewed-by: Anand Moon +Link: https://patch.msgid.link/20260326100010.3588454-2-amadeus@jmu.edu.cn +Signed-off-by: Greg Kroah-Hartman +(cherry picked from commit 764c2e6e60bf17910d84e7179fee14129e053b96) +--- + drivers/usb/dwc3/dwc3-generic-plat.c | 23 ++++++++++++++++++++++- + 1 file changed, 22 insertions(+), 1 deletion(-) + +--- a/drivers/usb/dwc3/dwc3-generic-plat.c ++++ b/drivers/usb/dwc3/dwc3-generic-plat.c +@@ -12,6 +12,8 @@ + #include + #include + #include ++#include ++#include + #include "glue.h" + + #define EIC7700_HSP_BUS_FILTER_EN BIT(0) +@@ -69,6 +71,20 @@ static int dwc3_eic7700_init(struct dwc3 + return 0; + } + ++static int dwc3_spacemit_k1_init(struct dwc3_generic *dwc3g) ++{ ++ struct device *dev = dwc3g->dev; ++ ++ if (usb_get_dr_mode(dev) == USB_DR_MODE_HOST) { ++ int ret = devm_regulator_get_enable_optional(dev, "vbus"); ++ ++ if (ret && ret != -ENODEV) ++ return dev_err_probe(dev, ret, "failed to enable VBUS\n"); ++ } ++ ++ return 0; ++} ++ + static int dwc3_generic_probe(struct platform_device *pdev) + { + const struct dwc3_generic_config *plat_config; +@@ -201,6 +217,11 @@ static const struct dev_pm_ops dwc3_gene + dwc3_generic_runtime_idle) + }; + ++static const struct dwc3_generic_config spacemit_k1_dwc3 = { ++ .init = dwc3_spacemit_k1_init, ++ .properties = DWC3_DEFAULT_PROPERTIES, ++}; ++ + static const struct dwc3_generic_config fsl_ls1028_dwc3 = { + .properties.gsbuscfg0_reqinfo = 0x2222, + }; +@@ -211,7 +232,7 @@ static const struct dwc3_generic_config + }; + + static const struct of_device_id dwc3_generic_of_match[] = { +- { .compatible = "spacemit,k1-dwc3", }, ++ { .compatible = "spacemit,k1-dwc3", &spacemit_k1_dwc3}, + { .compatible = "spacemit,k3-dwc3", }, + { .compatible = "fsl,ls1028a-dwc3", &fsl_ls1028_dwc3}, + { .compatible = "eswin,eic7700-dwc3", &eic7700_dwc3}, diff --git a/target/linux/spacemit/patches-6.18/0098-dt-bindings-mmc-spacemit-sdhci-add-pinctrl-support-f.patch b/target/linux/spacemit/patches-6.18/0098-dt-bindings-mmc-spacemit-sdhci-add-pinctrl-support-f.patch new file mode 100644 index 00000000000000..69a961fb847322 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0098-dt-bindings-mmc-spacemit-sdhci-add-pinctrl-support-f.patch @@ -0,0 +1,54 @@ +From 9b7646ece9148b042ac120baec6c9808f8e63023 Mon Sep 17 00:00:00 2001 +From: Iker Pedrosa +Date: Mon, 11 May 2026 10:53:56 +0200 +Subject: [PATCH] dt-bindings: mmc: spacemit,sdhci: add pinctrl support for + voltage switching + +Document pinctrl properties to support voltage-dependent pin +configuration switching for UHS-I SD card modes. + +Add optional pinctrl-names property with two states: +- "default": For 3.3V operation with standard drive strength +- "state_uhs": For 1.8V operation with optimized drive strength + +These pinctrl states allow the SDHCI driver to coordinate voltage +switching with pin configuration changes, ensuring proper signal +integrity during UHS-I mode transitions. + +Acked-by: Conor Dooley +Signed-off-by: Iker Pedrosa +Signed-off-by: Ulf Hansson +(cherry picked from commit 04a8ddc39e5cfebffb06f383350a6ee393ba89a6) +--- + .../devicetree/bindings/mmc/spacemit,sdhci.yaml | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +--- a/Documentation/devicetree/bindings/mmc/spacemit,sdhci.yaml ++++ b/Documentation/devicetree/bindings/mmc/spacemit,sdhci.yaml +@@ -42,6 +42,18 @@ properties: + - const: axi + - const: sdh + ++ pinctrl-names: ++ minItems: 1 ++ items: ++ - const: default ++ - const: uhs ++ ++ pinctrl-0: ++ description: Default pinctrl state for 3.3V operation ++ ++ pinctrl-1: ++ description: Optional pinctrl state for 1.8V UHS operation with "uhs" name ++ + required: + - compatible + - reg +@@ -60,4 +72,7 @@ examples: + interrupt-parent = <&plic>; + clocks = <&clk_apmu 10>, <&clk_apmu 13>; + clock-names = "core", "io"; ++ pinctrl-names = "default", "uhs"; ++ pinctrl-0 = <&sdhci_default_cfg>; ++ pinctrl-1 = <&sdhci_uhs_cfg>; + }; diff --git a/target/linux/spacemit/patches-6.18/0099-mmc-sdhci-of-k1-enable-essential-clock-infrastructur.patch b/target/linux/spacemit/patches-6.18/0099-mmc-sdhci-of-k1-enable-essential-clock-infrastructur.patch new file mode 100644 index 00000000000000..f0f7be43ab8e6d --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0099-mmc-sdhci-of-k1-enable-essential-clock-infrastructur.patch @@ -0,0 +1,60 @@ +From dfec85567e76c7697a830ebe169557de6a38ac10 Mon Sep 17 00:00:00 2001 +From: Iker Pedrosa +Date: Mon, 11 May 2026 10:53:57 +0200 +Subject: [PATCH] mmc: sdhci-of-k1: enable essential clock infrastructure for + SD operation + +Ensure SD card pins receive clock signals by enabling pad clock +generation and overriding automatic clock gating. Required for all SD +operation modes. + +The SDHC_GEN_PAD_CLK_ON setting in LEGACY_CTRL_REG is safe for both SD +and eMMC operation as both protocols use the same physical MMC interface +pins and require proper clock signal generation at the hardware level +for signal integrity and timing. + +Additional SD-specific clock overrides (SDHC_OVRRD_CLK_OEN and +SDHC_FORCE_CLK_ON) are conditionally applied only for SD-only +controllers to handle removable card scenarios. + +Tested-by: Anand Moon +Acked-by: Adrian Hunter +Tested-by: Trevor Gamblin +Reviewed-by: Troy Mitchell +Tested-by: Vincent Legoll +Signed-off-by: Iker Pedrosa +Signed-off-by: Ulf Hansson +(cherry picked from commit f87b273e4b6dfe57dcd63c24cbe3764d1f6954ae) +--- + drivers/mmc/host/sdhci-of-k1.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +--- a/drivers/mmc/host/sdhci-of-k1.c ++++ b/drivers/mmc/host/sdhci-of-k1.c +@@ -21,6 +21,13 @@ + #include "sdhci.h" + #include "sdhci-pltfm.h" + ++#define SPACEMIT_SDHC_OP_EXT_REG 0x108 ++#define SDHC_OVRRD_CLK_OEN BIT(11) ++#define SDHC_FORCE_CLK_ON BIT(12) ++ ++#define SPACEMIT_SDHC_LEGACY_CTRL_REG 0x10C ++#define SDHC_GEN_PAD_CLK_ON BIT(6) ++ + #define SPACEMIT_SDHC_MMC_CTRL_REG 0x114 + #define SDHC_MISC_INT_EN BIT(1) + #define SDHC_MISC_INT BIT(2) +@@ -101,6 +108,12 @@ static void spacemit_sdhci_reset(struct + + if (!(host->mmc->caps2 & MMC_CAP2_NO_MMC)) + spacemit_sdhci_setbits(host, SDHC_MMC_CARD_MODE, SPACEMIT_SDHC_MMC_CTRL_REG); ++ ++ spacemit_sdhci_setbits(host, SDHC_GEN_PAD_CLK_ON, SPACEMIT_SDHC_LEGACY_CTRL_REG); ++ ++ if (host->mmc->caps2 & MMC_CAP2_NO_MMC) ++ spacemit_sdhci_setbits(host, SDHC_OVRRD_CLK_OEN | SDHC_FORCE_CLK_ON, ++ SPACEMIT_SDHC_OP_EXT_REG); + } + + static void spacemit_sdhci_set_uhs_signaling(struct sdhci_host *host, unsigned int timing) diff --git a/target/linux/spacemit/patches-6.18/0100-mmc-sdhci-of-k1-add-regulator-and-pinctrl-voltage-sw.patch b/target/linux/spacemit/patches-6.18/0100-mmc-sdhci-of-k1-add-regulator-and-pinctrl-voltage-sw.patch new file mode 100644 index 00000000000000..601e3181698fdc --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0100-mmc-sdhci-of-k1-add-regulator-and-pinctrl-voltage-sw.patch @@ -0,0 +1,139 @@ +From 145a0e57deadedc830259be0f722cb05fbbf81fa Mon Sep 17 00:00:00 2001 +From: Iker Pedrosa +Date: Mon, 11 May 2026 10:53:58 +0200 +Subject: [PATCH] mmc: sdhci-of-k1: add regulator and pinctrl voltage switching + support + +Add voltage switching infrastructure for UHS-I modes by integrating both +regulator framework (for supply voltage control) and pinctrl state +switching (for pin drive strength optimization). + +- Add regulator supply parsing and voltage switching callback +- Add optional pinctrl state switching between "default" (3.3V) and + "state_uhs" (1.8V) configurations +- Enable coordinated voltage and pin configuration changes for UHS modes + +This provides complete voltage switching support while maintaining +backward compatibility when pinctrl states are not defined. + +Tested-by: Anand Moon +Tested-by: Trevor Gamblin +Acked-by: Adrian Hunter +Reviewed-by: Troy Mitchell +Tested-by: Vincent Legoll +Signed-off-by: Iker Pedrosa +Signed-off-by: Ulf Hansson +(cherry picked from commit 00a97fc57c09ff1cf71107753d9b5629caeb8c8a) +--- + drivers/mmc/host/sdhci-of-k1.c | 72 ++++++++++++++++++++++++++++++++++ + 1 file changed, 72 insertions(+) + +--- a/drivers/mmc/host/sdhci-of-k1.c ++++ b/drivers/mmc/host/sdhci-of-k1.c +@@ -16,6 +16,7 @@ + #include + #include + #include ++#include + #include + + #include "sdhci.h" +@@ -71,6 +72,9 @@ + struct spacemit_sdhci_host { + struct clk *clk_core; + struct clk *clk_io; ++ struct pinctrl *pinctrl; ++ struct pinctrl_state *pinctrl_default; ++ struct pinctrl_state *pinctrl_uhs; + }; + + /* All helper functions will update clr/set while preserve rest bits */ +@@ -219,6 +223,46 @@ static void spacemit_sdhci_pre_hs400_to_ + SPACEMIT_SDHC_PHY_CTRL_REG); + } + ++static int spacemit_sdhci_start_signal_voltage_switch(struct mmc_host *mmc, ++ struct mmc_ios *ios) ++{ ++ struct sdhci_host *host = mmc_priv(mmc); ++ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); ++ struct spacemit_sdhci_host *sdhst = sdhci_pltfm_priv(pltfm_host); ++ struct pinctrl_state *state; ++ int ret; ++ ++ ret = sdhci_start_signal_voltage_switch(mmc, ios); ++ if (ret) ++ return ret; ++ ++ if (!sdhst->pinctrl) ++ return 0; ++ ++ /* Select appropriate pinctrl state based on signal voltage */ ++ switch (ios->signal_voltage) { ++ case MMC_SIGNAL_VOLTAGE_330: ++ state = sdhst->pinctrl_default; ++ break; ++ case MMC_SIGNAL_VOLTAGE_180: ++ state = sdhst->pinctrl_uhs; ++ break; ++ default: ++ dev_warn(mmc_dev(mmc), "unsupported voltage %d\n", ios->signal_voltage); ++ return 0; ++ } ++ ++ ret = pinctrl_select_state(sdhst->pinctrl, state); ++ if (ret) { ++ dev_warn(mmc_dev(mmc), "failed to select pinctrl state: %d\n", ret); ++ return 0; ++ } ++ dev_dbg(mmc_dev(mmc), "switched to %s pinctrl state\n", ++ ios->signal_voltage == MMC_SIGNAL_VOLTAGE_180 ? "UHS" : "default"); ++ ++ return 0; ++} ++ + static inline int spacemit_sdhci_get_clocks(struct device *dev, + struct sdhci_pltfm_host *pltfm_host) + { +@@ -252,6 +296,30 @@ static inline int spacemit_sdhci_get_res + return 0; + } + ++static inline void spacemit_sdhci_get_pins(struct device *dev, ++ struct sdhci_pltfm_host *pltfm_host) ++{ ++ struct spacemit_sdhci_host *sdhst = sdhci_pltfm_priv(pltfm_host); ++ ++ sdhst->pinctrl = devm_pinctrl_get(dev); ++ if (IS_ERR(sdhst->pinctrl)) { ++ sdhst->pinctrl = NULL; ++ dev_dbg(dev, "pinctrl not available, voltage switching will work without it\n"); ++ return; ++ } ++ ++ sdhst->pinctrl_default = pinctrl_lookup_state(sdhst->pinctrl, "default"); ++ if (IS_ERR(sdhst->pinctrl_default)) ++ sdhst->pinctrl_default = NULL; ++ ++ sdhst->pinctrl_uhs = pinctrl_lookup_state(sdhst->pinctrl, "uhs"); ++ if (IS_ERR(sdhst->pinctrl_uhs)) ++ sdhst->pinctrl_uhs = NULL; ++ ++ dev_dbg(dev, "pinctrl setup: default=%p, uhs=%p\n", ++ sdhst->pinctrl_default, sdhst->pinctrl_uhs); ++} ++ + static const struct sdhci_ops spacemit_sdhci_ops = { + .get_max_clock = spacemit_sdhci_clk_get_max_clock, + .reset = spacemit_sdhci_reset, +@@ -309,6 +377,10 @@ static int spacemit_sdhci_probe(struct p + + host->mmc->caps |= MMC_CAP_NEED_RSP_BUSY; + ++ spacemit_sdhci_get_pins(dev, pltfm_host); ++ ++ host->mmc_host_ops.start_signal_voltage_switch = spacemit_sdhci_start_signal_voltage_switch; ++ + ret = spacemit_sdhci_get_clocks(dev, pltfm_host); + if (ret) + goto err_pltfm; diff --git a/target/linux/spacemit/patches-6.18/0101-mmc-sdhci-of-k1-add-comprehensive-SDR-tuning-support.patch b/target/linux/spacemit/patches-6.18/0101-mmc-sdhci-of-k1-add-comprehensive-SDR-tuning-support.patch new file mode 100644 index 00000000000000..4c3b325dbd8b05 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0101-mmc-sdhci-of-k1-add-comprehensive-SDR-tuning-support.patch @@ -0,0 +1,235 @@ +From 253f04182c6eff82b33b2ae0ba8c50035c68458f Mon Sep 17 00:00:00 2001 +From: Iker Pedrosa +Date: Mon, 11 May 2026 10:53:59 +0200 +Subject: [PATCH] mmc: sdhci-of-k1: add comprehensive SDR tuning support +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Implement software tuning algorithm to enable UHS-I SDR modes for SD +card operation and HS200 mode for eMMC. This adds both TX and RX delay +line tuning based on the SpacemiT K1 controller capabilities. + +Algorithm features: +- Add tuning register definitions (RX_CFG, DLINE_CTRL, DLINE_CFG) +- Conditional tuning: only for high-speed modes (≥100MHz) +- TX tuning: configure transmit delay line with optimal values + (dline_reg=0, delaycode=127) to ensure optimal signal output timing +- RX tuning: single-pass window detection algorithm testing full + delay range (0-255) to find optimal receive timing window +- Retry mechanism: multiple fallback delays within optimal window + for improved reliability + +Tested-by: Anand Moon +Acked-by: Adrian Hunter +Tested-by: Trevor Gamblin +Tested-by: Vincent Legoll +Signed-off-by: Iker Pedrosa +Signed-off-by: Ulf Hansson +(cherry picked from commit e9cb83c10071808aa7db4582e007a650aa6aa183) +--- + drivers/mmc/host/sdhci-of-k1.c | 172 +++++++++++++++++++++++++++++++++ + 1 file changed, 172 insertions(+) + +--- a/drivers/mmc/host/sdhci-of-k1.c ++++ b/drivers/mmc/host/sdhci-of-k1.c +@@ -69,6 +69,28 @@ + #define SDHC_PHY_DRIVE_SEL GENMASK(2, 0) + #define SDHC_RX_BIAS_CTRL BIT(5) + ++#define SPACEMIT_SDHC_RX_CFG_REG 0x118 ++#define SDHC_RX_SDCLK_SEL0_MASK GENMASK(1, 0) ++#define SDHC_RX_SDCLK_SEL1_MASK GENMASK(3, 2) ++#define SDHC_RX_SDCLK_SEL1 FIELD_PREP(SDHC_RX_SDCLK_SEL1_MASK, 1) ++ ++#define SPACEMIT_SDHC_DLINE_CTRL_REG 0x130 ++#define SDHC_DLINE_PU BIT(0) ++#define SDHC_RX_DLINE_CODE_MASK GENMASK(23, 16) ++#define SDHC_TX_DLINE_CODE_MASK GENMASK(31, 24) ++ ++#define SPACEMIT_SDHC_DLINE_CFG_REG 0x134 ++#define SDHC_RX_DLINE_REG_MASK GENMASK(7, 0) ++#define SDHC_RX_DLINE_GAIN BIT(8) ++#define SDHC_TX_DLINE_REG_MASK GENMASK(23, 16) ++ ++#define SPACEMIT_RX_DLINE_REG 9 ++#define SPACEMIT_RX_TUNE_DELAY_MIN 0x0 ++#define SPACEMIT_RX_TUNE_DELAY_MAX 0xFF ++ ++#define SPACEMIT_TX_TUNING_DLINE_REG 0x00 ++#define SPACEMIT_TX_TUNING_DELAYCODE 127 ++ + struct spacemit_sdhci_host { + struct clk *clk_core; + struct clk *clk_io; +@@ -96,6 +118,50 @@ static inline void spacemit_sdhci_clrset + sdhci_writel(host, val, reg); + } + ++static void spacemit_sdhci_set_rx_delay(struct sdhci_host *host, u8 delay) ++{ ++ spacemit_sdhci_clrsetbits(host, SDHC_RX_DLINE_CODE_MASK, ++ FIELD_PREP(SDHC_RX_DLINE_CODE_MASK, delay), ++ SPACEMIT_SDHC_DLINE_CTRL_REG); ++} ++ ++static void spacemit_sdhci_set_tx_delay(struct sdhci_host *host, u8 delay) ++{ ++ spacemit_sdhci_clrsetbits(host, SDHC_TX_DLINE_CODE_MASK, ++ FIELD_PREP(SDHC_TX_DLINE_CODE_MASK, delay), ++ SPACEMIT_SDHC_DLINE_CTRL_REG); ++} ++ ++static void spacemit_sdhci_set_tx_dline_reg(struct sdhci_host *host, u8 dline_reg) ++{ ++ spacemit_sdhci_clrsetbits(host, SDHC_TX_DLINE_REG_MASK, ++ FIELD_PREP(SDHC_TX_DLINE_REG_MASK, dline_reg), ++ SPACEMIT_SDHC_DLINE_CFG_REG); ++} ++ ++static void spacemit_sdhci_tx_tuning_prepare(struct sdhci_host *host) ++{ ++ spacemit_sdhci_setbits(host, SDHC_TX_MUX_SEL, SPACEMIT_SDHC_TX_CFG_REG); ++ spacemit_sdhci_setbits(host, SDHC_DLINE_PU, SPACEMIT_SDHC_DLINE_CTRL_REG); ++ udelay(5); ++} ++ ++static void spacemit_sdhci_prepare_tuning(struct sdhci_host *host) ++{ ++ spacemit_sdhci_clrsetbits(host, SDHC_RX_DLINE_REG_MASK, ++ FIELD_PREP(SDHC_RX_DLINE_REG_MASK, SPACEMIT_RX_DLINE_REG), ++ SPACEMIT_SDHC_DLINE_CFG_REG); ++ ++ spacemit_sdhci_setbits(host, SDHC_DLINE_PU, SPACEMIT_SDHC_DLINE_CTRL_REG); ++ udelay(5); ++ ++ spacemit_sdhci_clrsetbits(host, SDHC_RX_SDCLK_SEL1_MASK, SDHC_RX_SDCLK_SEL1, ++ SPACEMIT_SDHC_RX_CFG_REG); ++ ++ if (host->mmc->ios.timing == MMC_TIMING_MMC_HS200) ++ spacemit_sdhci_setbits(host, SDHC_HS200_USE_RFIFO, SPACEMIT_SDHC_PHY_FUNC_REG); ++} ++ + static void spacemit_sdhci_reset(struct sdhci_host *host, u8 mask) + { + sdhci_reset(host, mask); +@@ -191,6 +257,111 @@ static unsigned int spacemit_sdhci_clk_g + return clk_get_rate(pltfm_host->clk); + } + ++static int spacemit_sdhci_execute_tuning(struct sdhci_host *host, u32 opcode) ++{ ++ int current_len = 0, current_start = 0; ++ int max_pass_len = 0, max_pass_start = 0; ++ struct mmc_host *mmc = host->mmc; ++ struct mmc_ios ios = mmc->ios; ++ u8 final_delay; ++ int ret = 0; ++ int i; ++ ++ /* ++ * Tuning is required for SDR50/SDR104, HS200/HS400 cards and ++ * if clock frequency is greater than 100MHz in these modes. ++ */ ++ if (host->clock < 100 * 1000 * 1000 || ++ !(ios.timing == MMC_TIMING_MMC_HS200 || ++ ios.timing == MMC_TIMING_UHS_SDR50 || ++ ios.timing == MMC_TIMING_UHS_SDR104)) ++ return 0; ++ ++ if (mmc->caps2 & MMC_CAP2_NO_MMC) { ++ spacemit_sdhci_set_tx_dline_reg(host, SPACEMIT_TX_TUNING_DLINE_REG); ++ spacemit_sdhci_set_tx_delay(host, SPACEMIT_TX_TUNING_DELAYCODE); ++ spacemit_sdhci_tx_tuning_prepare(host); ++ ++ dev_dbg(mmc_dev(host->mmc), "TX tuning: dline_reg=%d, delaycode=%d\n", ++ SPACEMIT_TX_TUNING_DLINE_REG, SPACEMIT_TX_TUNING_DELAYCODE); ++ } ++ ++ spacemit_sdhci_prepare_tuning(host); ++ ++ for (i = SPACEMIT_RX_TUNE_DELAY_MIN; i <= SPACEMIT_RX_TUNE_DELAY_MAX; i++) { ++ spacemit_sdhci_set_rx_delay(host, i); ++ ret = mmc_send_tuning(host->mmc, opcode, NULL); ++ ++ dev_dbg(mmc_dev(host->mmc), "RX delay %d: %s\n", ++ i, ret == 0 ? "pass" : "fail"); ++ ++ if (ret == 0) { ++ /* Test passed - extend current window */ ++ if (current_len == 0) ++ current_start = i; ++ current_len++; ++ } else { ++ /* Test failed - check if current window is best so far */ ++ if (current_len > max_pass_len) { ++ max_pass_len = current_len; ++ max_pass_start = current_start; ++ } ++ current_len = 0; ++ } ++ } ++ ++ if (current_len > max_pass_len) { ++ max_pass_len = current_len; ++ max_pass_start = current_start; ++ } ++ ++ if (max_pass_len < 3) { ++ dev_err(mmc_dev(host->mmc), "Tuning failed: no stable window found\n"); ++ return -EIO; ++ } ++ ++ final_delay = max_pass_start + max_pass_len / 2; ++ spacemit_sdhci_set_rx_delay(host, final_delay); ++ ret = mmc_send_tuning(host->mmc, opcode, NULL); ++ if (ret) { ++ u8 retry_delays[] = { ++ max_pass_start + max_pass_len / 4, ++ max_pass_start + (3 * max_pass_len) / 4, ++ max_pass_start, ++ max_pass_start + max_pass_len - 1 ++ }; ++ int retry_count = ARRAY_SIZE(retry_delays); ++ ++ dev_warn(mmc_dev(mmc), "Primary delay %d failed, trying alternatives\n", ++ final_delay); ++ ++ for (i = 0; i < retry_count; i++) { ++ if (retry_delays[i] >= SPACEMIT_RX_TUNE_DELAY_MIN && ++ retry_delays[i] <= SPACEMIT_RX_TUNE_DELAY_MAX) { ++ spacemit_sdhci_set_rx_delay(host, retry_delays[i]); ++ ret = mmc_send_tuning(host->mmc, opcode, NULL); ++ if (!ret) { ++ final_delay = retry_delays[i]; ++ dev_info(mmc_dev(mmc), "Retry successful with delay %d\n", ++ final_delay); ++ break; ++ } ++ } ++ } ++ ++ if (ret) { ++ dev_err(mmc_dev(mmc), "All retry attempts failed\n"); ++ return -EIO; ++ } ++ } ++ ++ dev_dbg(mmc_dev(host->mmc), ++ "Tuning successful: window %d-%d, using delay %d\n", ++ max_pass_start, max_pass_start + max_pass_len - 1, final_delay); ++ ++ return 0; ++} ++ + static int spacemit_sdhci_pre_select_hs400(struct mmc_host *mmc) + { + struct sdhci_host *host = mmc_priv(mmc); +@@ -326,6 +497,7 @@ static const struct sdhci_ops spacemit_s + .set_bus_width = sdhci_set_bus_width, + .set_clock = spacemit_sdhci_set_clock, + .set_uhs_signaling = spacemit_sdhci_set_uhs_signaling, ++ .platform_execute_tuning = spacemit_sdhci_execute_tuning, + }; + + static const struct sdhci_pltfm_data spacemit_sdhci_k1_pdata = { diff --git a/target/linux/spacemit/patches-6.18/0102-riscv-dts-spacemit-k1-add-SD-card-controller-and-pin.patch b/target/linux/spacemit/patches-6.18/0102-riscv-dts-spacemit-k1-add-SD-card-controller-and-pin.patch new file mode 100644 index 00000000000000..2d48db021132c2 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0102-riscv-dts-spacemit-k1-add-SD-card-controller-and-pin.patch @@ -0,0 +1,99 @@ +From 62f87531b321504edcdc87acd68e8ff3bc472c47 Mon Sep 17 00:00:00 2001 +From: Iker Pedrosa +Date: Fri, 15 May 2026 12:48:59 +0200 +Subject: [PATCH] riscv: dts: spacemit: k1: add SD card controller and pinctrl + support + +Add SD card controller infrastructure for SpacemiT K1 SoC with complete +pinctrl support for both standard and UHS modes. + +- Add sdhci0 controller definition with clocks, resets and interrupts +- Add mmc1_cfg pinctrl for 3.3V standard SD operation +- Add mmc1_uhs_cfg pinctrl for 1.8V UHS high-speed operation +- Configure appropriate drive strength and power-source properties + +This provides complete SD card infrastructure that K1-based boards can +enable. + +Tested-by: Anand Moon +Tested-by: Trevor Gamblin +Tested-by: Vincent Legoll +Reviewed-by: Troy Mitchell +Signed-off-by: Iker Pedrosa +Link: https://patch.msgid.link/20260515-orangepi-sd-card-uhs-v10-1-094af27e310d@gmail.com +Signed-off-by: Yixun Lan +(cherry picked from commit 2d77e577109967ef65f269c1fc1d6a659d4260fb) +--- + arch/riscv/boot/dts/spacemit/k1-pinctrl.dtsi | 40 ++++++++++++++++++++ + arch/riscv/boot/dts/spacemit/k1.dtsi | 13 +++++++ + 2 files changed, 53 insertions(+) + +--- a/arch/riscv/boot/dts/spacemit/k1-pinctrl.dtsi ++++ b/arch/riscv/boot/dts/spacemit/k1-pinctrl.dtsi +@@ -590,4 +590,44 @@ + power-source = <3300>; + }; + }; ++ ++ mmc1_cfg: mmc1-cfg { ++ mmc1-data-cmd-pins { ++ pinmux = , /* mmc1_d3 */ ++ , /* mmc1_d2 */ ++ , /* mmc1_d1 */ ++ , /* mmc1_d0 */ ++ ; /* mmc1_cmd */ ++ bias-pull-up = <1>; ++ drive-strength = <19>; ++ power-source = <3300>; ++ }; ++ ++ mmc1-clk-pins { ++ pinmux = ; /* mmc1_clk */ ++ bias-pull-down = <1>; ++ drive-strength = <19>; ++ power-source = <3300>; ++ }; ++ }; ++ ++ mmc1_uhs_cfg: mmc1-uhs-cfg { ++ mmc1-data-cmd-pins { ++ pinmux = , /* mmc1_d3 */ ++ , /* mmc1_d2 */ ++ , /* mmc1_d1 */ ++ , /* mmc1_d0 */ ++ ; /* mmc1_cmd */ ++ bias-pull-up = <1>; ++ drive-strength = <42>; ++ power-source = <1800>; ++ }; ++ ++ mmc1-clk-pins { ++ pinmux = ; /* mmc1_clk */ ++ bias-pull-down = <1>; ++ drive-strength = <42>; ++ power-source = <1800>; ++ }; ++ }; + }; +--- a/arch/riscv/boot/dts/spacemit/k1.dtsi ++++ b/arch/riscv/boot/dts/spacemit/k1.dtsi +@@ -1214,6 +1214,19 @@ + status = "disabled"; + }; + ++ sdhci0: mmc@d4280000 { ++ compatible = "spacemit,k1-sdhci"; ++ reg = <0x0 0xd4280000 0x0 0x200>; ++ clocks = <&syscon_apmu CLK_SDH_AXI>, ++ <&syscon_apmu CLK_SDH0>; ++ clock-names = "core", "io"; ++ resets = <&syscon_apmu RESET_SDH_AXI>, ++ <&syscon_apmu RESET_SDH0>; ++ reset-names = "axi", "sdh"; ++ interrupts = <99>; ++ status = "disabled"; ++ }; ++ + emmc: mmc@d4281000 { + compatible = "spacemit,k1-sdhci"; + reg = <0x0 0xd4281000 0x0 0x200>; diff --git a/target/linux/spacemit/patches-6.18/0103-riscv-dts-spacemit-k1-orangepi-rv2-add-SD-card-suppo.patch b/target/linux/spacemit/patches-6.18/0103-riscv-dts-spacemit-k1-orangepi-rv2-add-SD-card-suppo.patch new file mode 100644 index 00000000000000..dc28901bf14f64 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0103-riscv-dts-spacemit-k1-orangepi-rv2-add-SD-card-suppo.patch @@ -0,0 +1,73 @@ +From bc14a36e0e4115832803185489b83e5936f8021f Mon Sep 17 00:00:00 2001 +From: Iker Pedrosa +Date: Fri, 15 May 2026 12:49:00 +0200 +Subject: [PATCH] riscv: dts: spacemit: k1-orangepi-rv2: add SD card support + with UHS modes + +Add complete SD card controller support with UHS high-speed modes. + +- Enable sdhci0 controller with 4-bit bus width +- Configure card detect GPIO with GPIO_ACTIVE_LOW logic +- Connect vmmc-supply to buck4 for 3.3V card power +- Connect vqmmc-supply to aldo1 for 1.8V/3.3V I/O switching +- Add dual pinctrl states for voltage-dependent pin configuration +- Support UHS-I SDR25, SDR50, and SDR104 modes +- Add stable MMC device aliases (mmc0 = eMMC, mmc1 = SD card) + +This enables full SD card functionality including high-speed UHS modes +for improved performance. + +Tested-by: Anand Moon +Tested-by: Trevor Gamblin +Tested-by: Michael Opdenacker +Tested-by: Vincent Legoll +Signed-off-by: Iker Pedrosa +Link: https://patch.msgid.link/20260515-orangepi-sd-card-uhs-v10-2-094af27e310d@gmail.com +Signed-off-by: Yixun Lan +(cherry picked from commit 2585c60ce2f977b13f14a67d1e3ed9c73fd7f381) +--- + .../boot/dts/spacemit/k1-orangepi-rv2.dts | 22 ++++++++++++++++++- + 1 file changed, 21 insertions(+), 1 deletion(-) + +--- a/arch/riscv/boot/dts/spacemit/k1-orangepi-rv2.dts ++++ b/arch/riscv/boot/dts/spacemit/k1-orangepi-rv2.dts +@@ -17,6 +17,8 @@ + serial0 = &uart0; + ethernet0 = ð0; + ethernet1 = ð1; ++ mmc0 = &emmc; ++ mmc1 = &sdhci0; + }; + + chosen { +@@ -202,7 +204,7 @@ + regulator-always-on; + }; + +- aldo1 { ++ aldo1: aldo1 { + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <3400000>; + regulator-boot-on; +@@ -319,3 +321,21 @@ + vdd-supply = <&vcc_5v0>; + }; + }; ++ ++&sdhci0 { ++ pinctrl-names = "default", "uhs"; ++ pinctrl-0 = <&mmc1_cfg>; ++ pinctrl-1 = <&mmc1_uhs_cfg>; ++ bus-width = <4>; ++ cd-gpios = <&gpio K1_GPIO(80) GPIO_ACTIVE_LOW>; ++ no-mmc; ++ no-sdio; ++ disable-wp; ++ cap-sd-highspeed; ++ vmmc-supply = <&buck4_3v3>; ++ vqmmc-supply = <&aldo1>; ++ sd-uhs-sdr25; ++ sd-uhs-sdr50; ++ sd-uhs-sdr104; ++ status = "okay"; ++}; diff --git a/target/linux/spacemit/patches-6.18/0104-riscv-dts-spacemit-k1-bananapi-f3-add-SD-card-suppor.patch b/target/linux/spacemit/patches-6.18/0104-riscv-dts-spacemit-k1-bananapi-f3-add-SD-card-suppor.patch new file mode 100644 index 00000000000000..a355102a5a803f --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0104-riscv-dts-spacemit-k1-bananapi-f3-add-SD-card-suppor.patch @@ -0,0 +1,84 @@ +From 54ca0db6df346d176fc0209f2034bb946f263709 Mon Sep 17 00:00:00 2001 +From: Iker Pedrosa +Date: Fri, 15 May 2026 12:49:01 +0200 +Subject: [PATCH] riscv: dts: spacemit: k1-bananapi-f3: add SD card support + with UHS modes + +Add complete SD card controller support with UHS high-speed modes. + +- Enable sdhci0 controller with 4-bit bus width +- Configure card detect GPIO with GPIO_ACTIVE_LOW and internal pull-up + support +- Connect vmmc-supply to buck4 for 3.3V card power +- Connect vqmmc-supply to aldo1 for 1.8V/3.3V I/O switching +- Add dual pinctrl states for voltage-dependent pin configuration +- Support UHS-I SDR25, SDR50, and SDR104 modes +- Add stable MMC device aliases (mmc0 = eMMC, mmc1 = SD card) + +This enables full SD card functionality including high-speed UHS modes +for improved performance. + +Suggested-by: Anand Moon +Tested-by: Anand Moon +Tested-by: Margherita Milani +Tested-by: Aurelien Jarno +Reviewed-by: Aurelien Jarno +Signed-off-by: Iker Pedrosa +Link: https://patch.msgid.link/20260515-orangepi-sd-card-uhs-v10-3-094af27e310d@gmail.com +Signed-off-by: Yixun Lan +(cherry picked from commit c76e2f058cbcab84e4a703f26857a58bdf6a0042) +--- + .../boot/dts/spacemit/k1-bananapi-f3.dts | 24 +++++++++++++++++-- + 1 file changed, 22 insertions(+), 2 deletions(-) + +--- a/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts ++++ b/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts +@@ -17,6 +17,8 @@ + spi3 = &spi3; + i2c2 = &i2c2; + i2c8 = &i2c8; ++ mmc0 = &emmc; ++ mmc1 = &sdhci0; + }; + + chosen { +@@ -221,7 +223,7 @@ + regulator-always-on; + }; + +- buck4 { ++ buck4: buck4 { + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <3300000>; + regulator-ramp-delay = <5000>; +@@ -242,7 +244,7 @@ + regulator-always-on; + }; + +- aldo1 { ++ aldo1: aldo1 { + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <3400000>; + regulator-boot-on; +@@ -374,3 +376,21 @@ + reset-gpios = <&gpio K1_GPIO(124) GPIO_ACTIVE_LOW>; + }; + }; ++ ++&sdhci0 { ++ pinctrl-names = "default", "uhs"; ++ pinctrl-0 = <&mmc1_cfg>; ++ pinctrl-1 = <&mmc1_uhs_cfg>; ++ bus-width = <4>; ++ cd-gpios = <&gpio K1_GPIO(80) (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; ++ no-mmc; ++ no-sdio; ++ disable-wp; ++ cap-sd-highspeed; ++ vmmc-supply = <&buck4>; ++ vqmmc-supply = <&aldo1>; ++ sd-uhs-sdr25; ++ sd-uhs-sdr50; ++ sd-uhs-sdr104; ++ status = "okay"; ++}; diff --git a/target/linux/spacemit/patches-6.18/0105-riscv-dts-spacemit-k1-musepi-pro-add-PMIC-and-power-.patch b/target/linux/spacemit/patches-6.18/0105-riscv-dts-spacemit-k1-musepi-pro-add-PMIC-and-power-.patch new file mode 100644 index 00000000000000..948c2882a68a51 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0105-riscv-dts-spacemit-k1-musepi-pro-add-PMIC-and-power-.patch @@ -0,0 +1,175 @@ +From 228d64ddc6b4ee6b2008a368fadfeff794838948 Mon Sep 17 00:00:00 2001 +From: Andre Heider +Date: Wed, 13 May 2026 09:19:49 +0200 +Subject: [PATCH] riscv: dts: spacemit: k1-musepi-pro: add PMIC and power + infrastructure + +Enable i2c8 and add the connected SpacemiT P1 PMIC with its related +regulators for the board's power infrastructure and voltage regulation +support. + +Signed-off-by: Andre Heider +Link: https://patch.msgid.link/20260513071958.29574-2-a.heider@gmail.com +Signed-off-by: Yixun Lan +(cherry picked from commit e2dac7c7a3a8970feeeb758f782ce86b89625ebd) +--- + .../riscv/boot/dts/spacemit/k1-musepi-pro.dts | 134 ++++++++++++++++++ + 1 file changed, 134 insertions(+) + +--- a/arch/riscv/boot/dts/spacemit/k1-musepi-pro.dts ++++ b/arch/riscv/boot/dts/spacemit/k1-musepi-pro.dts +@@ -17,6 +17,7 @@ + aliases { + ethernet0 = ð0; + serial0 = &uart0; ++ i2c8 = &i2c8; + }; + + chosen { +@@ -33,6 +34,15 @@ + default-state = "on"; + }; + }; ++ ++ reg_vcc_4v: regulator-vcc-4v { ++ compatible = "regulator-fixed"; ++ regulator-name = "VCC4V0"; ++ regulator-min-microvolt = <4000000>; ++ regulator-max-microvolt = <4000000>; ++ regulator-boot-on; ++ regulator-always-on; ++ }; + }; + + &emmc { +@@ -72,6 +82,130 @@ + status = "okay"; + }; + ++&i2c8 { ++ pinctrl-0 = <&i2c8_cfg>; ++ pinctrl-names = "default"; ++ status = "okay"; ++ ++ pmic@41 { ++ compatible = "spacemit,p1"; ++ reg = <0x41>; ++ interrupts = <64>; ++ vin1-supply = <®_vcc_4v>; ++ vin2-supply = <®_vcc_4v>; ++ vin3-supply = <®_vcc_4v>; ++ vin4-supply = <®_vcc_4v>; ++ vin5-supply = <®_vcc_4v>; ++ vin6-supply = <®_vcc_4v>; ++ aldoin-supply = <®_vcc_4v>; ++ dldoin1-supply = <&buck5>; ++ dldoin2-supply = <&buck5>; ++ ++ regulators { ++ buck1 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <3450000>; ++ regulator-ramp-delay = <5000>; ++ regulator-always-on; ++ }; ++ ++ buck2 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <3450000>; ++ regulator-ramp-delay = <5000>; ++ regulator-always-on; ++ }; ++ ++ buck3_1v8: buck3 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-ramp-delay = <5000>; ++ regulator-always-on; ++ }; ++ ++ buck4_3v3: buck4 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-ramp-delay = <5000>; ++ regulator-always-on; ++ }; ++ ++ buck5: buck5 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <3450000>; ++ regulator-ramp-delay = <5000>; ++ regulator-always-on; ++ }; ++ ++ buck6 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <3450000>; ++ regulator-ramp-delay = <5000>; ++ regulator-always-on; ++ }; ++ ++ aldo1 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <3400000>; ++ regulator-boot-on; ++ }; ++ ++ aldo2 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <3400000>; ++ }; ++ ++ aldo3 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <3400000>; ++ }; ++ ++ aldo4 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <3400000>; ++ }; ++ ++ dldo1 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <3400000>; ++ regulator-boot-on; ++ }; ++ ++ dldo2 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <3400000>; ++ }; ++ ++ dldo3 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <3400000>; ++ }; ++ ++ dldo4 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <3400000>; ++ regulator-always-on; ++ }; ++ ++ dldo5 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <3400000>; ++ }; ++ ++ dldo6 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <3400000>; ++ regulator-always-on; ++ }; ++ ++ dldo7 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <3400000>; ++ }; ++ }; ++ }; ++}; ++ + &uart0 { + pinctrl-0 = <&uart0_2_cfg>; + pinctrl-names = "default"; diff --git a/target/linux/spacemit/patches-6.18/0106-riscv-dts-spacemit-k1-musepi-pro-add-24c02-eeprom.patch b/target/linux/spacemit/patches-6.18/0106-riscv-dts-spacemit-k1-musepi-pro-add-24c02-eeprom.patch new file mode 100644 index 00000000000000..58a853400be13c --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0106-riscv-dts-spacemit-k1-musepi-pro-add-24c02-eeprom.patch @@ -0,0 +1,83 @@ +From 50353880f87b7f511f41fd455df4ad0f3ab85127 Mon Sep 17 00:00:00 2001 +From: Andre Heider +Date: Wed, 13 May 2026 09:19:50 +0200 +Subject: [PATCH] riscv: dts: spacemit: k1-musepi-pro: add 24c02 eeprom + +Enable i2c2 and add the connected GT24C02B EEPROM. + +It contains an ONIE TLV table: +=> tlv_eeprom +TLV: 0 +[ 12.162] TlvInfo Header: +[ 12.162] Id String: TlvInfo +[ 12.165] Version: 1 +[ 12.168] Total Length: 58 +[ 12.171] TLV Name Code Len Value +[ 12.175] -------------------- ---- --- ----- +[ 12.179] Product Name 0x21 16 k1-x_MUSE-Pi-Pro +[ 12.184] Serial Number 0x23 17 BPMIMXXXXXXXXXXXX +[ 12.189] Unknown 0x41 1 0x02 +[ 12.194] Base MAC Address 0x24 6 FE:FE:FE:XX:XX:XX +[ 12.199] MAC Addresses 0x2A 2 2 +[ 12.203] CRC-32 0xFE 4 0x395ECD34 +[ 12.207] Checksum is valid. + +(With 0x41 as TLV_CODE_DDR_CSNUM) + +Signed-off-by: Andre Heider +Link: https://patch.msgid.link/20260513071958.29574-3-a.heider@gmail.com +Signed-off-by: Yixun Lan +(cherry picked from commit 6bc75cfa56e885c2eab80e215f0a610075505846) +--- + .../riscv/boot/dts/spacemit/k1-musepi-pro.dts | 33 +++++++++++++++++++ + 1 file changed, 33 insertions(+) + +--- a/arch/riscv/boot/dts/spacemit/k1-musepi-pro.dts ++++ b/arch/riscv/boot/dts/spacemit/k1-musepi-pro.dts +@@ -17,6 +17,7 @@ + aliases { + ethernet0 = ð0; + serial0 = &uart0; ++ i2c2 = &i2c2; + i2c8 = &i2c8; + }; + +@@ -82,6 +83,38 @@ + status = "okay"; + }; + ++&i2c2 { ++ pinctrl-0 = <&i2c2_0_cfg>; ++ pinctrl-names = "default"; ++ status = "okay"; ++ ++ eeprom@50 { ++ compatible = "atmel,24c02"; ++ reg = <0x50>; ++ vcc-supply = <&buck3_1v8>; /* EEPROM_VCC1V8 */ ++ pagesize = <8>; ++ read-only; ++ size = <256>; ++ ++ nvmem-layout { ++ compatible = "onie,tlv-layout"; ++ ++ product-name { ++ }; ++ ++ serial-number { ++ }; ++ ++ mac-address { ++ #nvmem-cell-cells = <1>; ++ }; ++ ++ num-macs { ++ }; ++ }; ++ }; ++}; ++ + &i2c8 { + pinctrl-0 = <&i2c8_cfg>; + pinctrl-names = "default"; diff --git a/target/linux/spacemit/patches-6.18/0107-riscv-dts-spacemit-k1-musepi-pro-enable-QSPI-and-add.patch b/target/linux/spacemit/patches-6.18/0107-riscv-dts-spacemit-k1-musepi-pro-enable-QSPI-and-add.patch new file mode 100644 index 00000000000000..46d60dbb006799 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0107-riscv-dts-spacemit-k1-musepi-pro-enable-QSPI-and-add.patch @@ -0,0 +1,85 @@ +From 62956d8028e4a4d99bb5990deb392ea77928802b Mon Sep 17 00:00:00 2001 +From: Andre Heider +Date: Wed, 13 May 2026 09:19:51 +0200 +Subject: [PATCH] riscv: dts: spacemit: k1-musepi-pro: enable QSPI and add SPI + NOR + +Add the QSPI controller node and describe the attached SPI NOR flash +(Winbond W25Q64FWSSAQ). + +Add a corresponding vendor flash partition layout. + +Signed-off-by: Andre Heider +Link: https://patch.msgid.link/20260513071958.29574-4-a.heider@gmail.com +Signed-off-by: Yixun Lan +(cherry picked from commit 735b1b205d07bf7bfa55b1f50f5485b9cc42a251) +--- + .../riscv/boot/dts/spacemit/k1-musepi-pro.dts | 50 +++++++++++++++++++ + 1 file changed, 50 insertions(+) + +--- a/arch/riscv/boot/dts/spacemit/k1-musepi-pro.dts ++++ b/arch/riscv/boot/dts/spacemit/k1-musepi-pro.dts +@@ -44,6 +44,15 @@ + regulator-boot-on; + regulator-always-on; + }; ++ ++ reg_qspi_vcc1v833: regulator-qspi-vcc1v833 { ++ compatible = "regulator-fixed"; ++ regulator-name = "QSPI_VCC1833"; ++ regulator-min-microvolt = <1833000>; ++ regulator-max-microvolt = <1833000>; ++ regulator-always-on; ++ vin-supply = <&buck4_3v3>; ++ }; + }; + + &emmc { +@@ -237,6 +246,47 @@ + }; + }; + }; ++}; ++ ++&qspi { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&qspi_cfg>; ++ status = "okay"; ++ ++ flash@0 { ++ compatible = "jedec,spi-nor"; ++ reg = <0>; ++ spi-max-frequency = <26500000>; ++ spi-rx-bus-width = <4>; ++ spi-tx-bus-width = <4>; ++ vcc-supply = <®_qspi_vcc1v833>; ++ m25p,fast-read; ++ ++ partitions { ++ compatible = "fixed-partitions"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ bootinfo@0 { ++ reg = <0x0 0x10000>; ++ }; ++ private@10000 { ++ reg = <0x10000 0x10000>; ++ }; ++ fsbl@20000 { ++ reg = <0x20000 0x40000>; ++ }; ++ env@60000 { ++ reg = <0x60000 0x10000>; ++ }; ++ opensbi@70000 { ++ reg = <0x70000 0x30000>; ++ }; ++ uboot@a0000 { ++ reg = <0xa0000 0x760000>; ++ }; ++ }; ++ }; + }; + + &uart0 { diff --git a/target/linux/spacemit/patches-6.18/0108-riscv-dts-spacemit-k1-musepi-pro-enable-USB-3-ports.patch b/target/linux/spacemit/patches-6.18/0108-riscv-dts-spacemit-k1-musepi-pro-enable-USB-3-ports.patch new file mode 100644 index 00000000000000..caa29ad3eba4f2 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0108-riscv-dts-spacemit-k1-musepi-pro-enable-USB-3-ports.patch @@ -0,0 +1,90 @@ +From 77e56d90f5a38c5cfe707ef57ea60fee8ed8f620 Mon Sep 17 00:00:00 2001 +From: Andre Heider +Date: Wed, 13 May 2026 09:19:52 +0200 +Subject: [PATCH] riscv: dts: spacemit: k1-musepi-pro: enable USB 3 ports + +Enable the DWC3 USB 3.0 controller, its associated combo_phy (USB 3 PHY) +and usbphy2 (USB 2 PHY) on the MusePi Pro board. + +The board uses a VLI VL817 hub, providing four ports. + +Signed-off-by: Andre Heider +Link: https://patch.msgid.link/20260513071958.29574-5-a.heider@gmail.com +Signed-off-by: Yixun Lan +(cherry picked from commit 83c658c7a82304a2bc944cdd4a5b4f98d19322f0) +--- + .../riscv/boot/dts/spacemit/k1-musepi-pro.dts | 52 +++++++++++++++++++ + 1 file changed, 52 insertions(+) + +--- a/arch/riscv/boot/dts/spacemit/k1-musepi-pro.dts ++++ b/arch/riscv/boot/dts/spacemit/k1-musepi-pro.dts +@@ -53,6 +53,26 @@ + regulator-always-on; + vin-supply = <&buck4_3v3>; + }; ++ ++ reg_5v_vbus: regulator-5v-vbus { ++ compatible = "regulator-fixed"; ++ regulator-name = "5V_VBUS"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ regulator-always-on; ++ gpio = <&gpio K1_GPIO(79) GPIO_ACTIVE_HIGH>; /* USB3_PWREN */ ++ enable-active-high; ++ }; ++ ++ reg_vcc5v_hub: regulator-vcc5v-hub { ++ compatible = "regulator-fixed"; ++ regulator-name = "VCC5V0_HUB"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ regulator-always-on; ++ gpio = <&gpio K1_GPIO(127) GPIO_ACTIVE_HIGH>; /* HUB_PWREN */ ++ enable-active-high; ++ }; + }; + + &emmc { +@@ -65,6 +85,10 @@ + status = "okay"; + }; + ++&combo_phy { ++ status = "okay"; ++}; ++ + ð0 { + phy-handle = <&rgmii0>; + phy-mode = "rgmii-id"; +@@ -294,3 +318,31 @@ + pinctrl-names = "default"; + status = "okay"; + }; ++ ++&usbphy2 { ++ status = "okay"; ++}; ++ ++&usb_dwc3 { ++ dr_mode = "host"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ vbus-supply = <®_5v_vbus>; ++ status = "okay"; ++ ++ hub_2_0: hub@1 { ++ compatible = "usb2109,2817"; ++ reg = <0x1>; ++ vdd-supply = <®_vcc5v_hub>; ++ peer-hub = <&hub_3_0>; ++ reset-gpios = <&gpio K1_GPIO(123) GPIO_ACTIVE_LOW>; /* HUB_RST */ ++ }; ++ ++ hub_3_0: hub@2 { ++ compatible = "usb2109,817"; ++ reg = <0x2>; ++ vdd-supply = <®_vcc5v_hub>; ++ peer-hub = <&hub_2_0>; ++ reset-gpios = <&gpio K1_GPIO(123) GPIO_ACTIVE_LOW>; /* HUB_RST */ ++ }; ++}; diff --git a/target/linux/spacemit/patches-6.18/0109-riscv-dts-spacemit-k1-musepi-pro-enable-PCIe-ports.patch b/target/linux/spacemit/patches-6.18/0109-riscv-dts-spacemit-k1-musepi-pro-enable-PCIe-ports.patch new file mode 100644 index 00000000000000..2f26c2bb114b27 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0109-riscv-dts-spacemit-k1-musepi-pro-enable-PCIe-ports.patch @@ -0,0 +1,70 @@ +From 3ff4950c15fe848367c937ec760b1fed80432b47 Mon Sep 17 00:00:00 2001 +From: Andre Heider +Date: Wed, 13 May 2026 09:19:53 +0200 +Subject: [PATCH] riscv: dts: spacemit: k1-musepi-pro: enable PCIe ports + +Enable the two PCIe controllers along with their associated PHYs. They +are routed to the M.2 M-key connector and to the PCIe slot. + +Signed-off-by: Andre Heider +Link: https://patch.msgid.link/20260513071958.29574-6-a.heider@gmail.com +Signed-off-by: Yixun Lan +(cherry picked from commit d9ab0a855ba13f1db3ae16539348714c74010a22) +--- + .../riscv/boot/dts/spacemit/k1-musepi-pro.dts | 38 +++++++++++++++++++ + 1 file changed, 38 insertions(+) + +--- a/arch/riscv/boot/dts/spacemit/k1-musepi-pro.dts ++++ b/arch/riscv/boot/dts/spacemit/k1-musepi-pro.dts +@@ -36,6 +36,14 @@ + }; + }; + ++ reg_pcie_vcc_3v3: regulator-pcie-vcc3v3 { ++ compatible = "regulator-fixed"; ++ regulator-name = "PCIE_VCC3V3"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-always-on; ++ }; ++ + reg_vcc_4v: regulator-vcc-4v { + compatible = "regulator-fixed"; + regulator-name = "VCC4V0"; +@@ -272,6 +280,36 @@ + }; + }; + ++&pcie1_phy { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pcie1_3_cfg>; ++ status = "okay"; ++}; ++ ++&pcie1_port { ++ phys = <&pcie1_phy>; ++ vpcie3v3-supply = <®_pcie_vcc_3v3>; ++}; ++ ++&pcie1 { ++ status = "okay"; ++}; ++ ++&pcie2_phy { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pcie2_4_cfg>; ++ status = "okay"; ++}; ++ ++&pcie2_port { ++ phys = <&pcie2_phy>; ++ vpcie3v3-supply = <®_pcie_vcc_3v3>; ++}; ++ ++&pcie2 { ++ status = "okay"; ++}; ++ + &qspi { + pinctrl-names = "default"; + pinctrl-0 = <&qspi_cfg>; diff --git a/target/linux/spacemit/patches-6.18/0110-riscv-dts-spacemit-k1-musepi-pro-set-default-console.patch b/target/linux/spacemit/patches-6.18/0110-riscv-dts-spacemit-k1-musepi-pro-set-default-console.patch new file mode 100644 index 00000000000000..b0da2812e055f9 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0110-riscv-dts-spacemit-k1-musepi-pro-set-default-console.patch @@ -0,0 +1,29 @@ +From c115c5f9ed12ed60fab4a1bf13be92e72a4d6a59 Mon Sep 17 00:00:00 2001 +From: Andre Heider +Date: Wed, 13 May 2026 09:19:54 +0200 +Subject: [PATCH] riscv: dts: spacemit: k1-musepi-pro: set default console baud + rate + +Allow serial output with the same uboot/opensbi settings so the +console works without providing a cmdline. + +Signed-off-by: Andre Heider +Reviewed-by: Yixun Lan +Link: https://patch.msgid.link/20260513071958.29574-7-a.heider@gmail.com +Signed-off-by: Yixun Lan +(cherry picked from commit f125c6085fd775f09a316f61cc89a0ae86826895) +--- + arch/riscv/boot/dts/spacemit/k1-musepi-pro.dts | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/riscv/boot/dts/spacemit/k1-musepi-pro.dts ++++ b/arch/riscv/boot/dts/spacemit/k1-musepi-pro.dts +@@ -22,7 +22,7 @@ + }; + + chosen { +- stdout-path = "serial0"; ++ stdout-path = "serial0:115200n8"; + }; + + leds { diff --git a/target/linux/spacemit/patches-6.18/0111-riscv-dts-spacemit-enable-QSPI-for-OrangePi-RV2.patch b/target/linux/spacemit/patches-6.18/0111-riscv-dts-spacemit-enable-QSPI-for-OrangePi-RV2.patch new file mode 100644 index 00000000000000..a4e49d2db64e03 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0111-riscv-dts-spacemit-enable-QSPI-for-OrangePi-RV2.patch @@ -0,0 +1,71 @@ +From d3411540ea5b0fb1551a7f452622872e327bd521 Mon Sep 17 00:00:00 2001 +From: Chukun Pan +Date: Sat, 16 May 2026 16:00:30 +0800 +Subject: [PATCH] riscv: dts: spacemit: enable QSPI for OrangePi RV2 + +Enable the QSPI controller and the XM25QU128C SPI NOR flash on the +OrangePi RV2 board. Add a flash partition layout from vendor UBoot. + +Signed-off-by: Chukun Pan +Reviewed-by: Yixun Lan +Link: https://patch.msgid.link/20260516080030.1736836-1-amadeus@jmu.edu.cn +Signed-off-by: Yixun Lan +(cherry picked from commit e2518e8cb1dde64af2d1bb246639bb7ef7523f7a) +--- + .../boot/dts/spacemit/k1-orangepi-rv2.dts | 45 +++++++++++++++++++ + 1 file changed, 45 insertions(+) + +--- a/arch/riscv/boot/dts/spacemit/k1-orangepi-rv2.dts ++++ b/arch/riscv/boot/dts/spacemit/k1-orangepi-rv2.dts +@@ -290,6 +290,51 @@ + status = "okay"; + }; + ++&qspi { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&qspi_cfg>; ++ status = "okay"; ++ ++ flash@0 { ++ compatible = "jedec,spi-nor"; ++ reg = <0>; ++ spi-max-frequency = <26500000>; ++ spi-rx-bus-width = <4>; ++ spi-tx-bus-width = <4>; ++ vcc-supply = <&buck3_1v8>; ++ ++ partitions { ++ compatible = "fixed-partitions"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ bootinfo@0 { ++ reg = <0x00000 0x010000>; ++ }; ++ ++ private@10000 { ++ reg = <0x10000 0x010000>; ++ }; ++ ++ fsbl@20000 { ++ reg = <0x20000 0x040000>; ++ }; ++ ++ env@60000 { ++ reg = <0x60000 0x010000>; ++ }; ++ ++ opensbi@70000 { ++ reg = <0x70000 0x030000>; ++ }; ++ ++ uboot@a0000 { ++ reg = <0xa0000 0x760000>; ++ }; ++ }; ++ }; ++}; ++ + &uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_2_cfg>; diff --git a/target/linux/spacemit/patches-6.18/0112-mfd-simple-mfd-i2c-Add-a-reboot-cell-for-the-Spacemi.patch b/target/linux/spacemit/patches-6.18/0112-mfd-simple-mfd-i2c-Add-a-reboot-cell-for-the-Spacemi.patch new file mode 100644 index 00000000000000..954e059272dd6f --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0112-mfd-simple-mfd-i2c-Add-a-reboot-cell-for-the-Spacemi.patch @@ -0,0 +1,28 @@ +From 4ce086811c96608cf42f85b2a16459fbca4b7bee Mon Sep 17 00:00:00 2001 +From: Aurelien Jarno +Date: Mon, 3 Nov 2025 00:02:00 +0100 +Subject: [PATCH] mfd: simple-mfd-i2c: Add a reboot cell for the SpacemiT P1 + chip + +Add a "spacemit-p1-reboot" cell for the SpacemiT P1 chip. + +Signed-off-by: Aurelien Jarno +Reviewed-by: Troy Mitchell +Tested-by: Vincent Legoll # OrangePi-RV2 +Link: https://patch.msgid.link/20251102230352.914421-3-aurelien@aurel32.net +Signed-off-by: Lee Jones +(cherry picked from commit aa3fd533697108ec233bff3271d24865373ec5bf) +--- + drivers/mfd/simple-mfd-i2c.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/mfd/simple-mfd-i2c.c ++++ b/drivers/mfd/simple-mfd-i2c.c +@@ -99,6 +99,7 @@ static const struct regmap_config spacem + }; + + static const struct mfd_cell spacemit_p1_cells[] = { ++ { .name = "spacemit-p1-reboot", }, + { .name = "spacemit-p1-regulator", }, + { .name = "spacemit-p1-rtc", }, + }; diff --git a/target/linux/spacemit/patches-6.18/0113-riscv-dts-spacemit-enable-USB3-on-OrangePi-R2S.patch b/target/linux/spacemit/patches-6.18/0113-riscv-dts-spacemit-enable-USB3-on-OrangePi-R2S.patch new file mode 100644 index 00000000000000..dc69ff25bf0142 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0113-riscv-dts-spacemit-enable-USB3-on-OrangePi-R2S.patch @@ -0,0 +1,54 @@ +From 981bb6236f90d491ba4cc4e072f26d30907d5597 Mon Sep 17 00:00:00 2001 +From: Chukun Pan +Date: Mon, 18 May 2026 18:00:30 +0800 +Subject: [PATCH] riscv: dts: spacemit: enable USB3 on OrangePi R2S + +Enable the DWC3 USB3.0 controller and its associated PHY on the +OrangePi R2S. The USB regulator provides VBUS for USB2 and USB3 +ports, but the USB2 ports are handled by a separate controller. + +Signed-off-by: Chukun Pan +Reviewed-by: Yixun Lan +Link: https://patch.msgid.link/20260518100030.2354606-1-amadeus@jmu.edu.cn +Signed-off-by: Yixun Lan +(cherry picked from commit c5ad6737df88bd3c3e83145edb25737cb19f9a1f) +--- + .../boot/dts/spacemit/k1-orangepi-r2s.dts | 23 +++++++++++++++++++ + 1 file changed, 23 insertions(+) + +--- a/arch/riscv/boot/dts/spacemit/k1-orangepi-r2s.dts ++++ b/arch/riscv/boot/dts/spacemit/k1-orangepi-r2s.dts +@@ -21,6 +21,19 @@ + chosen { + stdout-path = "serial0"; + }; ++ ++ vcc5v0_usb: regulator-vcc5v0-usb { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpios = <&gpio K1_GPIO(126) GPIO_ACTIVE_HIGH>; ++ regulator-name = "vcc5v0_usb"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ }; ++}; ++ ++&combo_phy { ++ status = "okay"; + }; + + &emmc { +@@ -90,3 +103,13 @@ + pinctrl-0 = <&uart0_2_cfg>; + status = "okay"; + }; ++ ++&usbphy2 { ++ status = "okay"; ++}; ++ ++&usb_dwc3 { ++ dr_mode = "host"; ++ vbus-supply = <&vcc5v0_usb>; ++ status = "okay"; ++}; diff --git a/target/linux/spacemit/patches-6.18/0114-riscv-dts-spacemit-set-console-baud-rate-on-Milk-V-J.patch b/target/linux/spacemit/patches-6.18/0114-riscv-dts-spacemit-set-console-baud-rate-on-Milk-V-J.patch new file mode 100644 index 00000000000000..10d0f18b49e8de --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0114-riscv-dts-spacemit-set-console-baud-rate-on-Milk-V-J.patch @@ -0,0 +1,31 @@ +From 3266f146cf9f41bc7b61eb2fb6526a28b43ddc22 Mon Sep 17 00:00:00 2001 +From: Aurelien Jarno +Date: Tue, 19 May 2026 06:12:35 +0200 +Subject: [PATCH] riscv: dts: spacemit: set console baud rate on Milk-V Jupiter + +Because the default console's baud rate is not set, defconfig kernels do +not have any serial output on this platform. Set the baud rate to +115200, matching what is used by U-Boot etc on this platform. + +See-also: 24c12ca43b12c ("dts: spacemit: set console baud rate on bpif3") +Fixes: 5b90a3d6092d9 ("riscv: dts: spacemit: Add Milk-V Jupiter board device tree") +Signed-off-by: Aurelien Jarno +Reviewed-by: Yixun Lan +Link: https://patch.msgid.link/20260519041458.3287843-2-aurelien@aurel32.net +Signed-off-by: Yixun Lan +(cherry picked from commit 4f97acb4f744f516bbe976da8282c0fe213216ff) +--- + arch/riscv/boot/dts/spacemit/k1-milkv-jupiter.dts | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/riscv/boot/dts/spacemit/k1-milkv-jupiter.dts ++++ b/arch/riscv/boot/dts/spacemit/k1-milkv-jupiter.dts +@@ -20,7 +20,7 @@ + }; + + chosen { +- stdout-path = "serial0"; ++ stdout-path = "serial0:115200n8"; + }; + + leds { diff --git a/target/linux/spacemit/patches-6.18/0115-riscv-dts-spacemit-sort-aliases-on-Milk-V-Jupiter.patch b/target/linux/spacemit/patches-6.18/0115-riscv-dts-spacemit-sort-aliases-on-Milk-V-Jupiter.patch new file mode 100644 index 00000000000000..2a881251b9cfd2 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0115-riscv-dts-spacemit-sort-aliases-on-Milk-V-Jupiter.patch @@ -0,0 +1,29 @@ +From 2f75bb8799c425ce8c0834f0cc3e447f29233a0c Mon Sep 17 00:00:00 2001 +From: Aurelien Jarno +Date: Tue, 19 May 2026 06:12:36 +0200 +Subject: [PATCH] riscv: dts: spacemit: sort aliases on Milk-V Jupiter + +Before adding more aliases, just sort them. + +Signed-off-by: Aurelien Jarno +Reviewed-by: Yixun Lan +Link: https://patch.msgid.link/20260519041458.3287843-3-aurelien@aurel32.net +Signed-off-by: Yixun Lan +(cherry picked from commit 9cdeba29d65b10e7bdb1491167141ff2df238ab8) +--- + arch/riscv/boot/dts/spacemit/k1-milkv-jupiter.dts | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/riscv/boot/dts/spacemit/k1-milkv-jupiter.dts ++++ b/arch/riscv/boot/dts/spacemit/k1-milkv-jupiter.dts +@@ -14,9 +14,9 @@ + aliases { + ethernet0 = ð0; + ethernet1 = ð1; +- serial0 = &uart0; + i2c2 = &i2c2; + i2c8 = &i2c8; ++ serial0 = &uart0; + }; + + chosen { diff --git a/target/linux/spacemit/patches-6.18/0116-riscv-dts-spacemit-enable-eMMC-on-Milk-V-Jupiter.patch b/target/linux/spacemit/patches-6.18/0116-riscv-dts-spacemit-enable-eMMC-on-Milk-V-Jupiter.patch new file mode 100644 index 00000000000000..55c3dff3c158cc --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0116-riscv-dts-spacemit-enable-eMMC-on-Milk-V-Jupiter.patch @@ -0,0 +1,52 @@ +From c2dc721d9db6343c96b9afc1829e86b610676a16 Mon Sep 17 00:00:00 2001 +From: Aurelien Jarno +Date: Tue, 19 May 2026 06:12:37 +0200 +Subject: [PATCH] riscv: dts: spacemit: enable eMMC on Milk-V Jupiter + +The Milk-V Jupiter board has a connector for an eMMC module. Add an +entry for it in the device tree and alias it mmc0. + +Mark the device as non-removable as eMMC modules have no CD pin and are +not supposed to be inserted or removed while the system is running. On +systems without an eMMC module installed, the kernel emits the following +informational message during boot: + +mmc0: SDHCI controller on d4281000.mmc [d4281000.mmc] using ADMA +mmc0: Failed to initialize a non-removable card + +Signed-off-by: Aurelien Jarno +Reviewed-by: Yixun Lan +Link: https://patch.msgid.link/20260519041458.3287843-4-aurelien@aurel32.net +Signed-off-by: Yixun Lan +(cherry picked from commit 4bc9f44d581be66718cf7cf6e649fb92b3c2e6c6) +--- + arch/riscv/boot/dts/spacemit/k1-milkv-jupiter.dts | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +--- a/arch/riscv/boot/dts/spacemit/k1-milkv-jupiter.dts ++++ b/arch/riscv/boot/dts/spacemit/k1-milkv-jupiter.dts +@@ -16,6 +16,7 @@ + ethernet1 = ð1; + i2c2 = &i2c2; + i2c8 = &i2c8; ++ mmc0 = &emmc; + serial0 = &uart0; + }; + +@@ -105,6 +106,16 @@ + status = "okay"; + }; + ++&emmc { ++ bus-width = <8>; ++ mmc-hs400-1_8v; ++ mmc-hs400-enhanced-strobe; ++ non-removable; ++ no-sd; ++ no-sdio; ++ status = "okay"; ++}; ++ + ð0 { + phy-handle = <&rgmii0>; + phy-mode = "rgmii-id"; diff --git a/target/linux/spacemit/patches-6.18/0117-riscv-dts-spacemit-enable-SD-card-support-on-Milk-V-.patch b/target/linux/spacemit/patches-6.18/0117-riscv-dts-spacemit-enable-SD-card-support-on-Milk-V-.patch new file mode 100644 index 00000000000000..5d23caa2a86cdd --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0117-riscv-dts-spacemit-enable-SD-card-support-on-Milk-V-.patch @@ -0,0 +1,69 @@ +From 7cf1e87f0859f41404fa9a5a04a1df76cb1d06ed Mon Sep 17 00:00:00 2001 +From: Aurelien Jarno +Date: Tue, 19 May 2026 06:12:38 +0200 +Subject: [PATCH] riscv: dts: spacemit: enable SD card support on Milk-V + Jupiter + +Add complete SD card controller support with UHS high-speed modes. + +- Enable sdhci0 controller with 4-bit bus width +- Configure card detect GPIO with pull-up +- Connect vmmc-supply to buck4 for 3.3V card power +- Connect vqmmc-supply to aldo1 for 1.8V/3.3V I/O switching +- Add dual pinctrl states for voltage-dependent pin configuration +- Support UHS-I SDR25, SDR50, and SDR104 modes +- Alias it as mmc1 + +Signed-off-by: Aurelien Jarno +Reviewed-by: Yixun Lan +Link: https://patch.msgid.link/20260519041458.3287843-5-aurelien@aurel32.net +Signed-off-by: Yixun Lan +(cherry picked from commit 60b5e027c8c8cab69ad9cc7cab71ee795963e7b1) +--- + .../boot/dts/spacemit/k1-milkv-jupiter.dts | 21 ++++++++++++++++++- + 1 file changed, 20 insertions(+), 1 deletion(-) + +--- a/arch/riscv/boot/dts/spacemit/k1-milkv-jupiter.dts ++++ b/arch/riscv/boot/dts/spacemit/k1-milkv-jupiter.dts +@@ -17,6 +17,7 @@ + i2c2 = &i2c2; + i2c8 = &i2c8; + mmc0 = &emmc; ++ mmc1 = &sdhci0; + serial0 = &uart0; + }; + +@@ -250,7 +251,7 @@ + regulator-always-on; + }; + +- aldo1 { ++ aldo1: aldo1 { + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <3400000>; + regulator-boot-on; +@@ -385,6 +386,24 @@ + }; + }; + ++&sdhci0 { ++ pinctrl-names = "default", "uhs"; ++ pinctrl-0 = <&mmc1_cfg>; ++ pinctrl-1 = <&mmc1_uhs_cfg>; ++ bus-width = <4>; ++ cd-gpios = <&gpio K1_GPIO(80) (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; ++ no-mmc; ++ no-sdio; ++ disable-wp; ++ cap-sd-highspeed; ++ vmmc-supply = <&buck4_3v3>; ++ vqmmc-supply = <&aldo1>; ++ sd-uhs-sdr25; ++ sd-uhs-sdr50; ++ sd-uhs-sdr104; ++ status = "okay"; ++}; ++ + &uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_2_cfg>; diff --git a/target/linux/spacemit/patches-6.18/0118-riscv-dts-spacemit-fix-uboot-partition-offset-on-Mil.patch b/target/linux/spacemit/patches-6.18/0118-riscv-dts-spacemit-fix-uboot-partition-offset-on-Mil.patch new file mode 100644 index 00000000000000..3cd4a4afa3f2f7 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0118-riscv-dts-spacemit-fix-uboot-partition-offset-on-Mil.patch @@ -0,0 +1,29 @@ +From 84f1519a20cdd873301501e85d0c30aeefa96aed Mon Sep 17 00:00:00 2001 +From: Aurelien Jarno +Date: Tue, 19 May 2026 06:12:39 +0200 +Subject: [PATCH] riscv: dts: spacemit: fix uboot partition offset on Milk-V + Jupiter + +Correct the uboot partition node name to match its actual offset. + +Fixes: 2829823956f0 ("riscv: dts: spacemit: enable QSPI and add SPI NOR on Milk-V Jupiter") +Signed-off-by: Aurelien Jarno +Reviewed-by: Yixun Lan +Link: https://patch.msgid.link/20260519041458.3287843-6-aurelien@aurel32.net +Signed-off-by: Yixun Lan +(cherry picked from commit 6edd9a0d32e1ef81133b8cb5b3bb3157a44da4d1) +--- + arch/riscv/boot/dts/spacemit/k1-milkv-jupiter.dts | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/riscv/boot/dts/spacemit/k1-milkv-jupiter.dts ++++ b/arch/riscv/boot/dts/spacemit/k1-milkv-jupiter.dts +@@ -379,7 +379,7 @@ + opensbi@70000 { + reg = <0x70000 0x30000>; + }; +- uboot@a00000 { ++ uboot@a0000 { + reg = <0xa0000 0x760000>; + }; + }; diff --git a/target/linux/spacemit/patches-6.18/0119-dt-bindings-thermal-Add-SpacemiT-K1-thermal-sensor.patch b/target/linux/spacemit/patches-6.18/0119-dt-bindings-thermal-Add-SpacemiT-K1-thermal-sensor.patch new file mode 100644 index 00000000000000..a04f385aedef5e --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0119-dt-bindings-thermal-Add-SpacemiT-K1-thermal-sensor.patch @@ -0,0 +1,98 @@ +From 23c7ef70c773cdfb45d2f8269cdac35bb397ae10 Mon Sep 17 00:00:00 2001 +From: Shuwei Wu +Date: Mon, 27 Apr 2026 15:15:15 +0800 +Subject: [PATCH] dt-bindings: thermal: Add SpacemiT K1 thermal sensor + +Document the SpacemiT K1 Thermal Sensor, which supports +monitoring temperatures for five zones: soc, package, gpu, cluster0, +and cluster1. + +Reviewed-by: Krzysztof Kozlowski +Signed-off-by: Shuwei Wu +Signed-off-by: Daniel Lezcano +Link: https://patch.msgid.link/20260427-k1-thermal-v5-1-df39187480ed@mailbox.org +(cherry picked from commit c5c2d94c72982db7d2394d2604cec3a2af824d0e) +--- + .../bindings/thermal/spacemit,k1-tsensor.yaml | 76 +++++++++++++++++++ + 1 file changed, 76 insertions(+) + create mode 100644 Documentation/devicetree/bindings/thermal/spacemit,k1-tsensor.yaml + +--- /dev/null ++++ b/Documentation/devicetree/bindings/thermal/spacemit,k1-tsensor.yaml +@@ -0,0 +1,76 @@ ++# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) ++%YAML 1.2 ++--- ++$id: http://devicetree.org/schemas/thermal/spacemit,k1-tsensor.yaml# ++$schema: http://devicetree.org/meta-schemas/core.yaml# ++ ++title: SpacemiT K1 Thermal Sensor ++ ++description: ++ The SpacemiT K1 Thermal Sensor monitors the temperature of the SoC ++ using multiple internal sensors (e.g., soc, package, gpu, clusters). ++ ++maintainers: ++ - Shuwei Wu ++ ++$ref: thermal-sensor.yaml# ++ ++properties: ++ compatible: ++ const: spacemit,k1-tsensor ++ ++ reg: ++ maxItems: 1 ++ ++ clocks: ++ items: ++ - description: Core clock for thermal sensor ++ - description: Bus clock for thermal sensor ++ ++ clock-names: ++ items: ++ - const: core ++ - const: bus ++ ++ interrupts: ++ maxItems: 1 ++ ++ resets: ++ items: ++ - description: Reset for the thermal sensor ++ ++ "#thermal-sensor-cells": ++ const: 1 ++ description: ++ The first cell indicates the sensor ID. ++ 0 = soc ++ 1 = package ++ 2 = gpu ++ 3 = cluster0 ++ 4 = cluster1 ++ ++required: ++ - compatible ++ - reg ++ - clocks ++ - clock-names ++ - interrupts ++ - resets ++ - "#thermal-sensor-cells" ++ ++additionalProperties: false ++ ++examples: ++ - | ++ #include ++ ++ thermal@d4018000 { ++ compatible = "spacemit,k1-tsensor"; ++ reg = <0xd4018000 0x100>; ++ clocks = <&syscon_apbc CLK_TSEN>, ++ <&syscon_apbc CLK_TSEN_BUS>; ++ clock-names = "core", "bus"; ++ interrupts = <61>; ++ resets = <&syscon_apbc RESET_TSEN>; ++ #thermal-sensor-cells = <1>; ++ }; diff --git a/target/linux/spacemit/patches-6.18/0120-thermal-drivers-spacemit-k1-Add-thermal-sensor-suppo.patch b/target/linux/spacemit/patches-6.18/0120-thermal-drivers-spacemit-k1-Add-thermal-sensor-suppo.patch new file mode 100644 index 00000000000000..1975054678c47f --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0120-thermal-drivers-spacemit-k1-Add-thermal-sensor-suppo.patch @@ -0,0 +1,364 @@ +From 121c7f93dafe98389187523cc708ec95319d4507 Mon Sep 17 00:00:00 2001 +From: Shuwei Wu +Date: Mon, 27 Apr 2026 15:15:16 +0800 +Subject: [PATCH] thermal/drivers/spacemit/k1: Add thermal sensor support + +The thermal sensor on K1 supports monitoring five temperature zones. +The driver registers these sensors with the thermal framework +and supports standard operations: +- Reading temperature (millidegree Celsius) +- Setting high/low thresholds for interrupts + +Signed-off-by: Shuwei Wu +Signed-off-by: Daniel Lezcano +Reviewed-by: Anand Moon +Reviewed-by: Troy Mitchell +Reviewed-by: Yao Zi +Tested-by: Anand Moon +Tested-by: Vincent Legoll # OrangePi-RV2 +Tested-by: Gong Shuai +Link: https://patch.msgid.link/20260427-k1-thermal-v5-2-df39187480ed@mailbox.org +(cherry picked from commit 0352b10a34eebfb0d474808c73cc076e6910206e) +--- + drivers/thermal/Kconfig | 2 + + drivers/thermal/Makefile | 1 + + drivers/thermal/spacemit/Kconfig | 19 ++ + drivers/thermal/spacemit/Makefile | 3 + + drivers/thermal/spacemit/k1_tsensor.c | 280 ++++++++++++++++++++++++++ + 5 files changed, 305 insertions(+) + create mode 100644 drivers/thermal/spacemit/Kconfig + create mode 100644 drivers/thermal/spacemit/Makefile + create mode 100644 drivers/thermal/spacemit/k1_tsensor.c + +--- a/drivers/thermal/Kconfig ++++ b/drivers/thermal/Kconfig +@@ -462,6 +462,8 @@ endmenu + + source "drivers/thermal/renesas/Kconfig" + ++source "drivers/thermal/spacemit/Kconfig" ++ + source "drivers/thermal/tegra/Kconfig" + + config GENERIC_ADC_THERMAL +--- a/drivers/thermal/Makefile ++++ b/drivers/thermal/Makefile +@@ -64,6 +64,7 @@ obj-y += mediatek/ + obj-$(CONFIG_GENERIC_ADC_THERMAL) += thermal-generic-adc.o + obj-$(CONFIG_UNIPHIER_THERMAL) += uniphier_thermal.o + obj-$(CONFIG_AMLOGIC_THERMAL) += amlogic_thermal.o ++obj-y += spacemit/ + obj-$(CONFIG_SPRD_THERMAL) += sprd_thermal.o + obj-$(CONFIG_KHADAS_MCU_FAN_THERMAL) += khadas_mcu_fan.o + obj-$(CONFIG_LOONGSON2_THERMAL) += loongson2_thermal.o +--- /dev/null ++++ b/drivers/thermal/spacemit/Kconfig +@@ -0,0 +1,19 @@ ++# SPDX-License-Identifier: GPL-2.0-only ++menu "SpacemiT thermal drivers" ++depends on ARCH_SPACEMIT || COMPILE_TEST ++ ++config SPACEMIT_K1_TSENSOR ++ tristate "SpacemiT K1 thermal sensor driver" ++ depends on THERMAL_OF ++ help ++ This driver provides support for the thermal sensor ++ integrated in the SpacemiT K1 SoC. ++ ++ The thermal sensor monitors temperatures for five thermal zones: ++ soc, package, gpu, cluster0, and cluster1. It supports reporting ++ temperature values and handling high/low threshold interrupts. ++ ++ Say Y here if you want to enable thermal monitoring on SpacemiT K1. ++ If compiled as a module, it will be called k1_tsensor. ++ ++endmenu +--- /dev/null ++++ b/drivers/thermal/spacemit/Makefile +@@ -0,0 +1,3 @@ ++# SPDX-License-Identifier: GPL-2.0-only ++ ++obj-$(CONFIG_SPACEMIT_K1_TSENSOR) += k1_tsensor.o +--- /dev/null ++++ b/drivers/thermal/spacemit/k1_tsensor.c +@@ -0,0 +1,280 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Thermal sensor driver for SpacemiT K1 SoC ++ * ++ * Copyright (C) 2026 Shuwei Wu ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "../thermal_hwmon.h" ++ ++#define K1_TSENSOR_PCTRL_REG 0x00 ++#define K1_TSENSOR_PCTRL_ENABLE BIT(0) ++#define K1_TSENSOR_PCTRL_TEMP_MODE BIT(3) ++#define K1_TSENSOR_PCTRL_RAW_SEL BIT(7) ++ ++#define K1_TSENSOR_PCTRL_CTUNE GENMASK(11, 8) ++#define K1_TSENSOR_PCTRL_SW_CTRL GENMASK(21, 18) ++#define K1_TSENSOR_PCTRL_HW_AUTO_MODE BIT(23) ++ ++#define K1_TSENSOR_EN_REG 0x08 ++#define K1_TSENSOR_EN_ALL GENMASK(MAX_SENSOR_NUMBER - 1, 0) ++ ++#define K1_TSENSOR_TIME_REG 0x0C ++#define K1_TSENSOR_TIME_WAIT_REF_CNT GENMASK(3, 0) ++#define K1_TSENSOR_TIME_ADC_CNT_RST GENMASK(7, 4) ++#define K1_TSENSOR_TIME_FILTER_PERIOD GENMASK(21, 20) ++#define K1_TSENSOR_TIME_MASK GENMASK(23, 0) ++ ++#define K1_TSENSOR_INT_CLR_REG 0x10 ++#define K1_TSENSOR_INT_EN_REG 0x14 ++#define K1_TSENSOR_INT_STA_REG 0x18 ++ ++#define K1_TSENSOR_INT_EN_MASK BIT(0) ++#define K1_TSENSOR_INT_MASK(x) (GENMASK(2, 1) << ((x) * 2)) ++ ++#define K1_TSENSOR_DATA_BASE_REG 0x20 ++#define K1_TSENSOR_DATA_REG(x) (K1_TSENSOR_DATA_BASE_REG + ((x) / 2) * 4) ++#define K1_TSENSOR_DATA_LOW_MASK GENMASK(15, 0) ++#define K1_TSENSOR_DATA_HIGH_MASK GENMASK(31, 16) ++ ++#define K1_TSENSOR_THRSH_BASE_REG 0x40 ++#define K1_TSENSOR_THRSH_REG(x) (K1_TSENSOR_THRSH_BASE_REG + ((x) * 4)) ++#define K1_TSENSOR_THRSH_LOW_MASK GENMASK(15, 0) ++#define K1_TSENSOR_THRSH_HIGH_MASK GENMASK(31, 16) ++ ++#define MAX_SENSOR_NUMBER 5 ++ ++/* Hardware offset value required for temperature calculation */ ++#define TEMPERATURE_OFFSET 278 ++ ++struct k1_tsensor_channel { ++ struct k1_tsensor *ts; ++ struct thermal_zone_device *tzd; ++ int id; ++}; ++ ++struct k1_tsensor { ++ void __iomem *base; ++ struct k1_tsensor_channel ch[MAX_SENSOR_NUMBER]; ++}; ++ ++static void k1_tsensor_init(struct k1_tsensor *ts) ++{ ++ u32 val; ++ ++ /* Disable all the interrupts */ ++ writel(0xffffffff, ts->base + K1_TSENSOR_INT_EN_REG); ++ ++ /* Configure ADC sampling time and filter period */ ++ val = readl(ts->base + K1_TSENSOR_TIME_REG); ++ val &= ~K1_TSENSOR_TIME_MASK; ++ val |= K1_TSENSOR_TIME_FILTER_PERIOD | ++ K1_TSENSOR_TIME_ADC_CNT_RST | ++ K1_TSENSOR_TIME_WAIT_REF_CNT; ++ writel(val, ts->base + K1_TSENSOR_TIME_REG); ++ ++ /* ++ * Enable all sensors' auto mode, enable dither control, ++ * consecutive mode, and power up sensor. ++ */ ++ val = readl(ts->base + K1_TSENSOR_PCTRL_REG); ++ val &= ~K1_TSENSOR_PCTRL_SW_CTRL; ++ val &= ~K1_TSENSOR_PCTRL_CTUNE; ++ val |= K1_TSENSOR_PCTRL_RAW_SEL | ++ K1_TSENSOR_PCTRL_TEMP_MODE | ++ K1_TSENSOR_PCTRL_HW_AUTO_MODE | ++ K1_TSENSOR_PCTRL_ENABLE; ++ writel(val, ts->base + K1_TSENSOR_PCTRL_REG); ++ ++ /* Enable each sensor */ ++ val = readl(ts->base + K1_TSENSOR_EN_REG); ++ val |= K1_TSENSOR_EN_ALL; ++ writel(val, ts->base + K1_TSENSOR_EN_REG); ++} ++ ++static void k1_tsensor_enable_irq(struct k1_tsensor_channel *ch) ++{ ++ struct k1_tsensor *ts = ch->ts; ++ u32 val; ++ ++ val = readl(ts->base + K1_TSENSOR_INT_CLR_REG); ++ val |= K1_TSENSOR_INT_MASK(ch->id); ++ writel(val, ts->base + K1_TSENSOR_INT_CLR_REG); ++ ++ val = readl(ts->base + K1_TSENSOR_INT_EN_REG); ++ val &= ~K1_TSENSOR_INT_MASK(ch->id); ++ writel(val, ts->base + K1_TSENSOR_INT_EN_REG); ++ ++ /* Enable thermal interrupt */ ++ val = readl(ts->base + K1_TSENSOR_INT_EN_REG); ++ val |= K1_TSENSOR_INT_EN_MASK; ++ writel(val, ts->base + K1_TSENSOR_INT_EN_REG); ++} ++ ++/* ++ * The conversion formula used is: ++ * T(m°C) = (((raw_value & mask) >> shift) - TEMPERATURE_OFFSET) * 1000 ++ */ ++static int k1_tsensor_get_temp(struct thermal_zone_device *tz, int *temp) ++{ ++ struct k1_tsensor_channel *ch = thermal_zone_device_priv(tz); ++ struct k1_tsensor *ts = ch->ts; ++ u32 val; ++ ++ val = readl(ts->base + K1_TSENSOR_DATA_REG(ch->id)); ++ if (ch->id % 2) ++ *temp = FIELD_GET(K1_TSENSOR_DATA_HIGH_MASK, val); ++ else ++ *temp = FIELD_GET(K1_TSENSOR_DATA_LOW_MASK, val); ++ ++ *temp -= TEMPERATURE_OFFSET; ++ *temp *= 1000; ++ ++ return 0; ++} ++ ++/* ++ * For each sensor, the hardware threshold register is 32 bits: ++ * - Lower 16 bits [15:0] configure the low threshold temperature. ++ * - Upper 16 bits [31:16] configure the high threshold temperature. ++ */ ++static int k1_tsensor_set_trips(struct thermal_zone_device *tz, int low, int high) ++{ ++ struct k1_tsensor_channel *ch = thermal_zone_device_priv(tz); ++ struct k1_tsensor *ts = ch->ts; ++ u32 val; ++ ++ if (low >= high) ++ return -EINVAL; ++ ++ low = clamp_val(low / 1000 + TEMPERATURE_OFFSET, TEMPERATURE_OFFSET, ++ FIELD_MAX(K1_TSENSOR_THRSH_LOW_MASK)); ++ high = clamp_val(high / 1000 + TEMPERATURE_OFFSET, TEMPERATURE_OFFSET, ++ FIELD_MAX(K1_TSENSOR_THRSH_HIGH_MASK)); ++ ++ val = readl(ts->base + K1_TSENSOR_THRSH_REG(ch->id)); ++ ++ val &= ~(K1_TSENSOR_THRSH_LOW_MASK | K1_TSENSOR_THRSH_HIGH_MASK); ++ val |= FIELD_PREP(K1_TSENSOR_THRSH_LOW_MASK, low); ++ val |= FIELD_PREP(K1_TSENSOR_THRSH_HIGH_MASK, high); ++ ++ writel(val, ts->base + K1_TSENSOR_THRSH_REG(ch->id)); ++ ++ return 0; ++} ++ ++static const struct thermal_zone_device_ops k1_tsensor_ops = { ++ .get_temp = k1_tsensor_get_temp, ++ .set_trips = k1_tsensor_set_trips, ++}; ++ ++static irqreturn_t k1_tsensor_irq_thread(int irq, void *data) ++{ ++ struct k1_tsensor *ts = (struct k1_tsensor *)data; ++ int mask, status, i; ++ ++ status = readl(ts->base + K1_TSENSOR_INT_STA_REG); ++ ++ for (i = 0; i < MAX_SENSOR_NUMBER; i++) { ++ if (status & K1_TSENSOR_INT_MASK(i)) { ++ mask = readl(ts->base + K1_TSENSOR_INT_CLR_REG); ++ mask |= K1_TSENSOR_INT_MASK(i); ++ writel(mask, ts->base + K1_TSENSOR_INT_CLR_REG); ++ thermal_zone_device_update(ts->ch[i].tzd, THERMAL_EVENT_UNSPECIFIED); ++ } ++ } ++ ++ return IRQ_HANDLED; ++} ++ ++static int k1_tsensor_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct k1_tsensor *ts; ++ struct reset_control *reset; ++ struct clk *clk; ++ int i, irq, ret; ++ ++ ts = devm_kzalloc(dev, sizeof(*ts), GFP_KERNEL); ++ if (!ts) ++ return -ENOMEM; ++ ++ ts->base = devm_platform_ioremap_resource(pdev, 0); ++ if (IS_ERR(ts->base)) ++ return dev_err_probe(dev, PTR_ERR(ts->base), "Failed to get reg\n"); ++ ++ reset = devm_reset_control_get_exclusive_deasserted(dev, NULL); ++ if (IS_ERR(reset)) ++ return dev_err_probe(dev, PTR_ERR(reset), "Failed to get/deassert reset control\n"); ++ ++ clk = devm_clk_get_enabled(dev, "core"); ++ if (IS_ERR(clk)) ++ return dev_err_probe(dev, PTR_ERR(clk), "Failed to get core clock\n"); ++ ++ clk = devm_clk_get_enabled(dev, "bus"); ++ if (IS_ERR(clk)) ++ return dev_err_probe(dev, PTR_ERR(clk), "Failed to get bus clock\n"); ++ ++ k1_tsensor_init(ts); ++ ++ irq = platform_get_irq(pdev, 0); ++ if (irq < 0) ++ return irq; ++ ++ ret = devm_request_threaded_irq(dev, irq, NULL, ++ k1_tsensor_irq_thread, ++ IRQF_ONESHOT, "k1_tsensor", ts); ++ if (ret < 0) ++ return ret; ++ ++ for (i = 0; i < MAX_SENSOR_NUMBER; ++i) { ++ ts->ch[i].id = i; ++ ts->ch[i].ts = ts; ++ ts->ch[i].tzd = devm_thermal_of_zone_register(dev, i, ts->ch + i, &k1_tsensor_ops); ++ if (IS_ERR(ts->ch[i].tzd)) ++ return PTR_ERR(ts->ch[i].tzd); ++ ++ /* Attach sysfs hwmon attributes for userspace monitoring */ ++ ret = devm_thermal_add_hwmon_sysfs(dev, ts->ch[i].tzd); ++ if (ret) ++ dev_warn(dev, "Failed to add hwmon sysfs attributes\n"); ++ ++ k1_tsensor_enable_irq(ts->ch + i); ++ } ++ ++ platform_set_drvdata(pdev, ts); ++ ++ return 0; ++} ++ ++static const struct of_device_id k1_tsensor_dt_ids[] = { ++ { .compatible = "spacemit,k1-tsensor" }, ++ { /* sentinel */ } ++}; ++ ++MODULE_DEVICE_TABLE(of, k1_tsensor_dt_ids); ++ ++static struct platform_driver k1_tsensor_driver = { ++ .driver = { ++ .name = "k1_tsensor", ++ .of_match_table = k1_tsensor_dt_ids, ++ }, ++ .probe = k1_tsensor_probe, ++}; ++module_platform_driver(k1_tsensor_driver); ++ ++MODULE_DESCRIPTION("SpacemiT K1 Thermal Sensor Driver"); ++MODULE_AUTHOR("Shuwei Wu "); ++MODULE_LICENSE("GPL"); diff --git a/target/linux/spacemit/patches-6.18/0121-riscv-dts-spacemit-Add-thermal-sensor-for-K1-SoC.patch b/target/linux/spacemit/patches-6.18/0121-riscv-dts-spacemit-Add-thermal-sensor-for-K1-SoC.patch new file mode 100644 index 00000000000000..305bae4d6e6dd7 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0121-riscv-dts-spacemit-Add-thermal-sensor-for-K1-SoC.patch @@ -0,0 +1,138 @@ +From 5ed6dab481805ccc4b76ecabb43e289f2cade5de Mon Sep 17 00:00:00 2001 +From: Shuwei Wu +Date: Mon, 27 Apr 2026 15:15:17 +0800 +Subject: [PATCH] riscv: dts: spacemit: Add thermal sensor for K1 SoC + +Include the Thermal Sensor node in the SpacemiT K1 dtsi +with definitions for registers, clocks, and interrupts. +Additionally, configure thermal zones for the soc, package, gpu, and +clusters to enable temperature monitoring via the thermal framework. + +Tested-by: Vincent Legoll # OrangePi-RV2 +Tested-by: Gong Shuai +Signed-off-by: Shuwei Wu +Reviewed-by: Yixun Lan +Link: https://patch.msgid.link/20260427-k1-thermal-v5-3-df39187480ed@mailbox.org +Signed-off-by: Yixun Lan +(cherry picked from commit 247c77ff5806bcd6a5ff802718de1f0aa2bcba6c) +--- + arch/riscv/boot/dts/spacemit/k1.dtsi | 101 +++++++++++++++++++++++++++ + 1 file changed, 101 insertions(+) + +--- a/arch/riscv/boot/dts/spacemit/k1.dtsi ++++ b/arch/riscv/boot/dts/spacemit/k1.dtsi +@@ -339,6 +339,96 @@ + }; + }; + ++ thermal-zones { ++ soc-thermal { ++ polling-delay-passive = <0>; ++ polling-delay = <0>; ++ thermal-sensors = <&thermal 0>; ++ ++ trips { ++ soc-crit { ++ temperature = <115000>; ++ hysteresis = <0>; ++ type = "critical"; ++ }; ++ }; ++ }; ++ ++ package-thermal { ++ polling-delay-passive = <0>; ++ polling-delay = <0>; ++ thermal-sensors = <&thermal 1>; ++ ++ trips { ++ package-crit { ++ temperature = <115000>; ++ hysteresis = <0>; ++ type = "critical"; ++ }; ++ }; ++ }; ++ ++ gpu-thermal { ++ polling-delay-passive = <100>; ++ polling-delay = <0>; ++ thermal-sensors = <&thermal 2>; ++ ++ trips { ++ gpu-alert { ++ temperature = <85000>; ++ hysteresis = <2000>; ++ type = "passive"; ++ }; ++ ++ gpu-crit { ++ temperature = <115000>; ++ hysteresis = <0>; ++ type = "critical"; ++ }; ++ }; ++ }; ++ ++ cluster0-thermal { ++ polling-delay-passive = <100>; ++ polling-delay = <0>; ++ thermal-sensors = <&thermal 3>; ++ ++ trips { ++ cluster0-alert { ++ temperature = <85000>; ++ hysteresis = <2000>; ++ type = "passive"; ++ }; ++ ++ cluster0-crit { ++ temperature = <115000>; ++ hysteresis = <0>; ++ type = "critical"; ++ }; ++ }; ++ }; ++ ++ cluster1-thermal { ++ polling-delay-passive = <100>; ++ polling-delay = <0>; ++ thermal-sensors = <&thermal 4>; ++ ++ trips { ++ cluster1-alert { ++ temperature = <85000>; ++ hysteresis = <2000>; ++ type = "passive"; ++ }; ++ ++ cluster1-crit { ++ temperature = <115000>; ++ hysteresis = <0>; ++ type = "critical"; ++ }; ++ }; ++ }; ++ }; ++ + soc { + compatible = "simple-bus"; + interrupt-parent = <&plic>; +@@ -494,6 +584,17 @@ + #reset-cells = <1>; + }; + ++ thermal: thermal@d4018000 { ++ compatible = "spacemit,k1-tsensor"; ++ reg = <0x0 0xd4018000 0x0 0x100>; ++ clocks = <&syscon_apbc CLK_TSEN>, ++ <&syscon_apbc CLK_TSEN_BUS>; ++ clock-names = "core", "bus"; ++ interrupts = <61>; ++ resets = <&syscon_apbc RESET_TSEN>; ++ #thermal-sensor-cells = <1>; ++ }; ++ + i2c6: i2c@d4018800 { + compatible = "spacemit,k1-i2c"; + reg = <0x0 0xd4018800 0x0 0x38>; diff --git a/target/linux/spacemit/patches-6.18/0122-riscv-dts-spacemit-k1-musepi-pro-add-SD-card-support.patch b/target/linux/spacemit/patches-6.18/0122-riscv-dts-spacemit-k1-musepi-pro-add-SD-card-support.patch new file mode 100644 index 00000000000000..1bf5a9a055323e --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0122-riscv-dts-spacemit-k1-musepi-pro-add-SD-card-support.patch @@ -0,0 +1,73 @@ +From 93e81bb2ca1c3013845c5ae63a4e875ac38e21a3 Mon Sep 17 00:00:00 2001 +From: Trevor Gamblin +Date: Wed, 20 May 2026 15:06:23 +0200 +Subject: [PATCH] riscv: dts: spacemit: k1-musepi-pro: add SD card support with + UHS modes + +Update the Muse Pi Pro devicetree with SD card support to match what +was done for the OrangePi RV2 in [1]. More precisely: + +- Enable sdhci0 controller with 4-bit bus width +- Configure card detect GPIO with internal pull-up support +- Connect vmmc-supply to buck4 for 3.3V card power +- Connect vqmmc-supply to aldo1 for 1.8V/3.3V I/O switching +- Add dual pinctrl states for voltage-dependent pin configuration +- Support UHS-I SDR25, SDR50, and SDR104 modes +- Add stable MMC device aliases (mmc0 = eMMC, mmc1 = SD card) + +[1] https://lore.kernel.org/linux-riscv/20260316-orangepi-sd-card-uhs-v3-0-aefd3b7832df@gmail.com/T/# + +Tested-by: Andre Heider +Signed-off-by: Trevor Gamblin +Signed-off-by: Iker Pedrosa +Signed-off-by: Andre Heider +Link: https://lore.kernel.org/linux-riscv/20260316-orangepi-sd-card-uhs-v3-0-aefd3b7832df@gmail.com/T/# +Link: https://patch.msgid.link/20260520130624.1763487-1-a.heider@gmail.com +Signed-off-by: Yixun Lan +(cherry picked from commit 85e4c5733cd7efa39f10d7200095c016ce4a2815) +--- + .../riscv/boot/dts/spacemit/k1-musepi-pro.dts | 22 ++++++++++++++++++- + 1 file changed, 21 insertions(+), 1 deletion(-) + +--- a/arch/riscv/boot/dts/spacemit/k1-musepi-pro.dts ++++ b/arch/riscv/boot/dts/spacemit/k1-musepi-pro.dts +@@ -19,6 +19,8 @@ + serial0 = &uart0; + i2c2 = &i2c2; + i2c8 = &i2c8; ++ mmc0 = &emmc; ++ mmc1 = &sdhci0; + }; + + chosen { +@@ -218,7 +220,7 @@ + regulator-always-on; + }; + +- aldo1 { ++ aldo1: aldo1 { + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <3400000>; + regulator-boot-on; +@@ -384,3 +386,21 @@ + reset-gpios = <&gpio K1_GPIO(123) GPIO_ACTIVE_LOW>; /* HUB_RST */ + }; + }; ++ ++&sdhci0 { ++ pinctrl-names = "default", "uhs"; ++ pinctrl-0 = <&mmc1_cfg>; ++ pinctrl-1 = <&mmc1_uhs_cfg>; ++ bus-width = <4>; ++ cd-gpios = <&gpio K1_GPIO(80) (GPIO_ACTIVE_HIGH | GPIO_PULL_UP)>; ++ no-mmc; ++ no-sdio; ++ disable-wp; ++ cap-sd-highspeed; ++ vmmc-supply = <&buck4_3v3>; ++ vqmmc-supply = <&aldo1>; ++ sd-uhs-sdr25; ++ sd-uhs-sdr50; ++ sd-uhs-sdr104; ++ status = "okay"; ++}; diff --git a/target/linux/spacemit/patches-6.18/0123-riscv-dts-spacemit-enable-PMIC-on-OrangePi-R2S.patch b/target/linux/spacemit/patches-6.18/0123-riscv-dts-spacemit-enable-PMIC-on-OrangePi-R2S.patch new file mode 100644 index 00000000000000..4b9b3ca0a6b386 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0123-riscv-dts-spacemit-enable-PMIC-on-OrangePi-R2S.patch @@ -0,0 +1,174 @@ +From 42524fcc38d8a03b66bf373c10b38889311f9927 Mon Sep 17 00:00:00 2001 +From: Chukun Pan +Date: Wed, 20 May 2026 18:00:00 +0800 +Subject: [PATCH] riscv: dts: spacemit: enable PMIC on OrangePi R2S + +Enable the i2c8 interface and add the connected SpacemiT P1 PMIC and +its associated regulators to support voltage regulation on the board. + +Signed-off-by: Chukun Pan +Reviewed-by: Yixun lan +Link: https://patch.msgid.link/20260520100000.575719-1-amadeus@jmu.edu.cn +Signed-off-by: Yixun Lan +(cherry picked from commit 793cc54475b49b5b558902b5c13e4bfe66530a50) +--- + .../boot/dts/spacemit/k1-orangepi-r2s.dts | 134 ++++++++++++++++++ + 1 file changed, 134 insertions(+) + +--- a/arch/riscv/boot/dts/spacemit/k1-orangepi-r2s.dts ++++ b/arch/riscv/boot/dts/spacemit/k1-orangepi-r2s.dts +@@ -13,6 +13,7 @@ + compatible = "xunlong,orangepi-r2s", "spacemit,k1"; + + aliases { ++ i2c8 = &i2c8; + serial0 = &uart0; + ethernet0 = ð0; + ethernet1 = ð1; +@@ -22,6 +23,15 @@ + stdout-path = "serial0"; + }; + ++ vcc4v0: regulator-vcc4v0 { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc4v0"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <4000000>; ++ regulator-max-microvolt = <4000000>; ++ }; ++ + vcc5v0_usb: regulator-vcc5v0-usb { + compatible = "regulator-fixed"; + enable-active-high; +@@ -93,6 +103,130 @@ + }; + }; + }; ++ ++&i2c8 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c8_cfg>; ++ status = "okay"; ++ ++ pmic@41 { ++ compatible = "spacemit,p1"; ++ reg = <0x41>; ++ interrupts = <64>; ++ vin1-supply = <&vcc4v0>; ++ vin2-supply = <&vcc4v0>; ++ vin3-supply = <&vcc4v0>; ++ vin4-supply = <&vcc4v0>; ++ vin5-supply = <&vcc4v0>; ++ vin6-supply = <&vcc4v0>; ++ aldoin-supply = <&vcc4v0>; ++ dldoin1-supply = <&buck5>; ++ dldoin2-supply = <&buck5>; ++ ++ regulators { ++ buck1 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <3450000>; ++ regulator-ramp-delay = <5000>; ++ regulator-always-on; ++ }; ++ ++ buck2 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <3450000>; ++ regulator-ramp-delay = <5000>; ++ regulator-always-on; ++ }; ++ ++ buck3_1v8: buck3 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-ramp-delay = <5000>; ++ regulator-always-on; ++ }; ++ ++ buck4_3v3: buck4 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-ramp-delay = <5000>; ++ regulator-always-on; ++ }; ++ ++ buck5: buck5 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <3450000>; ++ regulator-ramp-delay = <5000>; ++ regulator-always-on; ++ }; ++ ++ buck6 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <3450000>; ++ regulator-ramp-delay = <5000>; ++ regulator-always-on; ++ }; ++ ++ aldo1_3v3: aldo1 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <3400000>; ++ regulator-boot-on; ++ }; ++ ++ aldo2 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <3400000>; ++ }; ++ ++ aldo3 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <3400000>; ++ }; ++ ++ aldo4 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <3400000>; ++ }; ++ ++ dldo1 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <3400000>; ++ regulator-boot-on; ++ }; ++ ++ dldo2 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <3400000>; ++ }; ++ ++ dldo3 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <3400000>; ++ }; ++ ++ dldo4 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <3400000>; ++ regulator-always-on; ++ }; ++ ++ dldo5 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <3400000>; ++ }; ++ ++ dldo6 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <3400000>; ++ regulator-always-on; ++ }; ++ ++ dldo7 { ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <3400000>; ++ }; ++ }; ++ }; ++}; + + &pdma { + status = "okay"; diff --git a/target/linux/spacemit/patches-6.18/0124-riscv-disable-local-interrupts-and-stop-other-CPUs-b.patch b/target/linux/spacemit/patches-6.18/0124-riscv-disable-local-interrupts-and-stop-other-CPUs-b.patch new file mode 100644 index 00000000000000..f4c49d1b6af784 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0124-riscv-disable-local-interrupts-and-stop-other-CPUs-b.patch @@ -0,0 +1,77 @@ +From 1f31f5295464c4a679a75911fab81e852100a2a7 Mon Sep 17 00:00:00 2001 +From: Troy Mitchell +Date: Mon, 30 Mar 2026 17:58:53 +0800 +Subject: [PATCH] riscv: disable local interrupts and stop other CPUs before + reboot/shutdown + +Currently, the RISC-V implementation of machine_restart(), machine_halt(), +and machine_power_off() invokes the kernel teardown chains (e.g., +do_kernel_restart()) with local interrupts enabled and other CPUs still +running. + +This implementation fails to provide a deterministic execution environment +for registered handlers in the restart or power-off notifier chains. These +chains are intended to be executed in a strict atomic and single-threaded +context. + +Specifically, under CONFIG_PREEMPT_RCU, rcu_read_lock() does not increment +the preempt_count. If local interrupts remain enabled, the environment +is not guaranteed to be atomic. This can lead to a context misidentification +within generic kernel teardown code, causing it to incorrectly enter +non-atomic paths (such as attempting to acquire sleeping locks), which +results in fatal "scheduling while atomic" splats or system hangs. + +Additionally, stopping other CPUs ensures the primary CPU has exclusive +access to the hardware state during the final teardown phase, preventing +unpredictable interference from other active cores. + +Align RISC-V with other major architectures by disabling local interrupts +and stopping other CPUs at the beginning of the shutdown sequences. This +guarantees the architectural expectations of the kernel's restart and +power-off handlers are met. + +Signed-off-by: Troy Mitchell +Tested-by: Aurelien Jarno +Link: https://lore.kernel.org/all/abEP80FoCn4S4-WG@aurel32.net/ [1] +--- + arch/riscv/kernel/reset.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +--- a/arch/riscv/kernel/reset.c ++++ b/arch/riscv/kernel/reset.c +@@ -5,6 +5,7 @@ + + #include + #include ++#include + + static void default_power_off(void) + { +@@ -17,18 +18,27 @@ EXPORT_SYMBOL(pm_power_off); + + void machine_restart(char *cmd) + { ++ local_irq_disable(); ++ smp_send_stop(); ++ + do_kernel_restart(cmd); + while (1); + } + + void machine_halt(void) + { ++ local_irq_disable(); ++ smp_send_stop(); ++ + do_kernel_power_off(); + default_power_off(); + } + + void machine_power_off(void) + { ++ local_irq_disable(); ++ smp_send_stop(); ++ + do_kernel_power_off(); + default_power_off(); + } diff --git a/target/linux/spacemit/patches-6.18/0125-riscv-dts-spacemit-enable-PCIe-on-OrangePi-R2S.patch b/target/linux/spacemit/patches-6.18/0125-riscv-dts-spacemit-enable-PCIe-on-OrangePi-R2S.patch new file mode 100644 index 00000000000000..7cebeb7433698e --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0125-riscv-dts-spacemit-enable-PCIe-on-OrangePi-R2S.patch @@ -0,0 +1,67 @@ +From ae1dd50fb9ea1a38ede352ca940d07be41a46d73 Mon Sep 17 00:00:00 2001 +From: Chukun Pan +Date: Tue, 2 Jun 2026 18:00:00 +0800 +Subject: [PATCH] riscv: dts: spacemit: enable PCIe on OrangePi R2S + +Enable the two RTL8125 network controllers and corresponding +PHYs connected via the PCIe controllers on the OrangePi R2S. + +Signed-off-by: Chukun Pan +--- + .../boot/dts/spacemit/k1-orangepi-r2s.dts | 38 +++++++++++++++++++ + 1 file changed, 38 insertions(+) + +--- a/arch/riscv/boot/dts/spacemit/k1-orangepi-r2s.dts ++++ b/arch/riscv/boot/dts/spacemit/k1-orangepi-r2s.dts +@@ -23,6 +23,14 @@ + stdout-path = "serial0"; + }; + ++ pcie_vcc3v3: regulator-pcie-vcc3v3 { ++ compatible = "regulator-fixed"; ++ regulator-name = "pcie_vcc3v3"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-always-on; ++ }; ++ + vcc4v0: regulator-vcc4v0 { + compatible = "regulator-fixed"; + regulator-name = "vcc4v0"; +@@ -228,6 +236,36 @@ + }; + }; + ++&pcie1_phy { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pcie1_3_cfg>; ++ status = "okay"; ++}; ++ ++&pcie1_port { ++ phys = <&pcie1_phy>; ++ vpcie3v3-supply = <&pcie_vcc3v3>; ++}; ++ ++&pcie1 { ++ status = "okay"; ++}; ++ ++&pcie2_phy { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pcie2_4_cfg>; ++ status = "okay"; ++}; ++ ++&pcie2_port { ++ phys = <&pcie2_phy>; ++ vpcie3v3-supply = <&pcie_vcc3v3>; ++}; ++ ++&pcie2 { ++ status = "okay"; ++}; ++ + &pdma { + status = "okay"; + }; diff --git a/target/linux/spacemit/patches-6.18/0126-cpufreq-dt-platdev-Add-SpacemiT-K1-SoC-to-the-allowl.patch b/target/linux/spacemit/patches-6.18/0126-cpufreq-dt-platdev-Add-SpacemiT-K1-SoC-to-the-allowl.patch new file mode 100644 index 00000000000000..3deae0edd22d40 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0126-cpufreq-dt-platdev-Add-SpacemiT-K1-SoC-to-the-allowl.patch @@ -0,0 +1,24 @@ +From 736c71c8cbcf513bb4909aa428870c37f78e59f1 Mon Sep 17 00:00:00 2001 +From: Shuwei Wu +Date: Fri, 26 Jun 2026 16:10:23 +0800 +Subject: [PATCH] cpufreq: dt-platdev: Add SpacemiT K1 SoC to the allowlist + +Add the compatible string for supporting the generic +cpufreq driver on the SpacemiT K1 SoC. + +Signed-off-by: Shuwei Wu +--- + drivers/cpufreq/cpufreq-dt-platdev.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/cpufreq/cpufreq-dt-platdev.c ++++ b/drivers/cpufreq/cpufreq-dt-platdev.c +@@ -81,6 +81,8 @@ static const struct of_device_id allowli + { .have_governor_per_policy = true, }, + }, + ++ { .compatible = "spacemit,k1", }, ++ + { .compatible = "st-ericsson,u8500", }, + { .compatible = "st-ericsson,u8540", }, + { .compatible = "st-ericsson,u9500", }, diff --git a/target/linux/spacemit/patches-6.18/0127-riscv-dts-spacemit-Add-cpu-scaling-for-K1-SoC.patch b/target/linux/spacemit/patches-6.18/0127-riscv-dts-spacemit-Add-cpu-scaling-for-K1-SoC.patch new file mode 100644 index 00000000000000..214b1a43772d1e --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0127-riscv-dts-spacemit-Add-cpu-scaling-for-K1-SoC.patch @@ -0,0 +1,252 @@ +From 60eab9fabc73bea9f3cdcc793d2d90654bb6fca1 Mon Sep 17 00:00:00 2001 +From: Shuwei Wu +Date: Fri, 26 Jun 2026 16:10:24 +0800 +Subject: [PATCH] riscv: dts: spacemit: Add cpu scaling for K1 SoC + +Add CPU clock properties and OPP tables for the two CPU clusters in the +SpacemiT K1 SoC. The OPP entries use voltage ranges because the CPU +supply is shared by both clusters. + +Enable CPU DVFS on Banana Pi BPI-F3 by including the OPP tables and +wiring the CPU nodes to the CPU regulator supply. + +Signed-off-by: Shuwei Wu +--- + .../boot/dts/spacemit/k1-bananapi-f3.dts | 35 +++++- + arch/riscv/boot/dts/spacemit/k1-opp.dtsi | 105 ++++++++++++++++++ + arch/riscv/boot/dts/spacemit/k1.dtsi | 8 ++ + 3 files changed, 147 insertions(+), 1 deletion(-) + create mode 100644 arch/riscv/boot/dts/spacemit/k1-opp.dtsi + +--- a/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts ++++ b/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts +@@ -4,6 +4,7 @@ + */ + + #include "k1.dtsi" ++#include "k1-opp.dtsi" + #include "k1-pinctrl.dtsi" + + / { +@@ -87,6 +88,38 @@ + status = "okay"; + }; + ++&cpu_0 { ++ cpu-supply = <&buck1_0v9>; ++}; ++ ++&cpu_1 { ++ cpu-supply = <&buck1_0v9>; ++}; ++ ++&cpu_2 { ++ cpu-supply = <&buck1_0v9>; ++}; ++ ++&cpu_3 { ++ cpu-supply = <&buck1_0v9>; ++}; ++ ++&cpu_4 { ++ cpu-supply = <&buck1_0v9>; ++}; ++ ++&cpu_5 { ++ cpu-supply = <&buck1_0v9>; ++}; ++ ++&cpu_6 { ++ cpu-supply = <&buck1_0v9>; ++}; ++ ++&cpu_7 { ++ cpu-supply = <&buck1_0v9>; ++}; ++ + &emmc { + bus-width = <8>; + mmc-hs400-1_8v; +@@ -202,7 +235,7 @@ + dldoin2-supply = <&buck5>; + + regulators { +- buck1 { ++ buck1_0v9: buck1 { + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <3450000>; + regulator-ramp-delay = <5000>; +--- /dev/null ++++ b/arch/riscv/boot/dts/spacemit/k1-opp.dtsi +@@ -0,0 +1,105 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++ ++/ { ++ cluster0_opp_table: opp-table-cluster0 { ++ compatible = "operating-points-v2"; ++ opp-shared; ++ ++ opp-614400000 { ++ opp-hz = /bits/ 64 <614400000>; ++ opp-microvolt = <950000 950000 1050000>; ++ clock-latency-ns = <200000>; ++ }; ++ ++ opp-819000000 { ++ opp-hz = /bits/ 64 <819000000>; ++ opp-microvolt = <950000 950000 1050000>; ++ clock-latency-ns = <200000>; ++ }; ++ ++ opp-1000000000 { ++ opp-hz = /bits/ 64 <1000000000>; ++ opp-microvolt = <950000 950000 1050000>; ++ clock-latency-ns = <200000>; ++ }; ++ ++ opp-1228800000 { ++ opp-hz = /bits/ 64 <1228800000>; ++ opp-microvolt = <950000 950000 1050000>; ++ clock-latency-ns = <200000>; ++ }; ++ ++ opp-1600000000 { ++ opp-hz = /bits/ 64 <1600000000>; ++ opp-microvolt = <1050000 1050000 1050000>; ++ clock-latency-ns = <200000>; ++ }; ++ }; ++ ++ cluster1_opp_table: opp-table-cluster1 { ++ compatible = "operating-points-v2"; ++ opp-shared; ++ ++ opp-614400000 { ++ opp-hz = /bits/ 64 <614400000>; ++ opp-microvolt = <950000 950000 1050000>; ++ clock-latency-ns = <200000>; ++ }; ++ ++ opp-819000000 { ++ opp-hz = /bits/ 64 <819000000>; ++ opp-microvolt = <950000 950000 1050000>; ++ clock-latency-ns = <200000>; ++ }; ++ ++ opp-1000000000 { ++ opp-hz = /bits/ 64 <1000000000>; ++ opp-microvolt = <950000 950000 1050000>; ++ clock-latency-ns = <200000>; ++ }; ++ ++ opp-1228800000 { ++ opp-hz = /bits/ 64 <1228800000>; ++ opp-microvolt = <950000 950000 1050000>; ++ clock-latency-ns = <200000>; ++ }; ++ ++ opp-1600000000 { ++ opp-hz = /bits/ 64 <1600000000>; ++ opp-microvolt = <1050000 1050000 1050000>; ++ clock-latency-ns = <200000>; ++ }; ++ }; ++}; ++ ++&cpu_0 { ++ operating-points-v2 = <&cluster0_opp_table>; ++}; ++ ++&cpu_1 { ++ operating-points-v2 = <&cluster0_opp_table>; ++}; ++ ++&cpu_2 { ++ operating-points-v2 = <&cluster0_opp_table>; ++}; ++ ++&cpu_3 { ++ operating-points-v2 = <&cluster0_opp_table>; ++}; ++ ++&cpu_4 { ++ operating-points-v2 = <&cluster1_opp_table>; ++}; ++ ++&cpu_5 { ++ operating-points-v2 = <&cluster1_opp_table>; ++}; ++ ++&cpu_6 { ++ operating-points-v2 = <&cluster1_opp_table>; ++}; ++ ++&cpu_7 { ++ operating-points-v2 = <&cluster1_opp_table>; ++}; +--- a/arch/riscv/boot/dts/spacemit/k1.dtsi ++++ b/arch/riscv/boot/dts/spacemit/k1.dtsi +@@ -54,6 +54,7 @@ + compatible = "spacemit,x60", "riscv"; + device_type = "cpu"; + reg = <0>; ++ clocks = <&syscon_apmu CLK_CPU_C0_CORE>; + riscv,isa = "rv64imafdcbv_zicbom_zicbop_zicboz_zicntr_zicond_zicsr_zifencei_zihintpause_zihpm_zfh_zba_zbb_zbc_zbs_zkt_zvfh_zvkt_sscofpmf_sstc_svinval_svnapot_svpbmt"; + riscv,isa-base = "rv64i"; + riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "b", "v", "zicbom", +@@ -84,6 +85,7 @@ + compatible = "spacemit,x60", "riscv"; + device_type = "cpu"; + reg = <1>; ++ clocks = <&syscon_apmu CLK_CPU_C0_CORE>; + riscv,isa = "rv64imafdcbv_zicbom_zicbop_zicboz_zicntr_zicond_zicsr_zifencei_zihintpause_zihpm_zfh_zba_zbb_zbc_zbs_zkt_zvfh_zvkt_sscofpmf_sstc_svinval_svnapot_svpbmt"; + riscv,isa-base = "rv64i"; + riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "b", "v", "zicbom", +@@ -114,6 +116,7 @@ + compatible = "spacemit,x60", "riscv"; + device_type = "cpu"; + reg = <2>; ++ clocks = <&syscon_apmu CLK_CPU_C0_CORE>; + riscv,isa = "rv64imafdcbv_zicbom_zicbop_zicboz_zicntr_zicond_zicsr_zifencei_zihintpause_zihpm_zfh_zba_zbb_zbc_zbs_zkt_zvfh_zvkt_sscofpmf_sstc_svinval_svnapot_svpbmt"; + riscv,isa-base = "rv64i"; + riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "b", "v", "zicbom", +@@ -144,6 +147,7 @@ + compatible = "spacemit,x60", "riscv"; + device_type = "cpu"; + reg = <3>; ++ clocks = <&syscon_apmu CLK_CPU_C0_CORE>; + riscv,isa = "rv64imafdcbv_zicbom_zicbop_zicboz_zicntr_zicond_zicsr_zifencei_zihintpause_zihpm_zfh_zba_zbb_zbc_zbs_zkt_zvfh_zvkt_sscofpmf_sstc_svinval_svnapot_svpbmt"; + riscv,isa-base = "rv64i"; + riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "b", "v", "zicbom", +@@ -174,6 +178,7 @@ + compatible = "spacemit,x60", "riscv"; + device_type = "cpu"; + reg = <4>; ++ clocks = <&syscon_apmu CLK_CPU_C1_CORE>; + riscv,isa = "rv64imafdcbv_zicbom_zicbop_zicboz_zicntr_zicond_zicsr_zifencei_zihintpause_zihpm_zfh_zba_zbb_zbc_zbs_zkt_zvfh_zvkt_sscofpmf_sstc_svinval_svnapot_svpbmt"; + riscv,isa-base = "rv64i"; + riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "b", "v", "zicbom", +@@ -204,6 +209,7 @@ + compatible = "spacemit,x60", "riscv"; + device_type = "cpu"; + reg = <5>; ++ clocks = <&syscon_apmu CLK_CPU_C1_CORE>; + riscv,isa = "rv64imafdcbv_zicbom_zicbop_zicboz_zicntr_zicond_zicsr_zifencei_zihintpause_zihpm_zfh_zba_zbb_zbc_zbs_zkt_zvfh_zvkt_sscofpmf_sstc_svinval_svnapot_svpbmt"; + riscv,isa-base = "rv64i"; + riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "b", "v", "zicbom", +@@ -234,6 +240,7 @@ + compatible = "spacemit,x60", "riscv"; + device_type = "cpu"; + reg = <6>; ++ clocks = <&syscon_apmu CLK_CPU_C1_CORE>; + riscv,isa = "rv64imafdcbv_zicbom_zicbop_zicboz_zicntr_zicond_zicsr_zifencei_zihintpause_zihpm_zfh_zba_zbb_zbc_zbs_zkt_zvfh_zvkt_sscofpmf_sstc_svinval_svnapot_svpbmt"; + riscv,isa-base = "rv64i"; + riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "b", "v", "zicbom", +@@ -264,6 +271,7 @@ + compatible = "spacemit,x60", "riscv"; + device_type = "cpu"; + reg = <7>; ++ clocks = <&syscon_apmu CLK_CPU_C1_CORE>; + riscv,isa = "rv64imafdcbv_zicbom_zicbop_zicboz_zicntr_zicond_zicsr_zifencei_zihintpause_zihpm_zfh_zba_zbb_zbc_zbs_zkt_zvfh_zvkt_sscofpmf_sstc_svinval_svnapot_svpbmt"; + riscv,isa-base = "rv64i"; + riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "b", "v", "zicbom", diff --git a/target/linux/spacemit/patches-6.18/0128-riscv-dts-spacemit-k1-musepi-pro-add-cpu-scaling.patch b/target/linux/spacemit/patches-6.18/0128-riscv-dts-spacemit-k1-musepi-pro-add-cpu-scaling.patch new file mode 100644 index 00000000000000..4cfcf499fb38cc --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0128-riscv-dts-spacemit-k1-musepi-pro-add-cpu-scaling.patch @@ -0,0 +1,71 @@ +From db17af4940aad2bf5f14d160e182b05723417b7b Mon Sep 17 00:00:00 2001 +From: Andre Heider +Date: Sat, 13 Jun 2026 09:27:58 +0200 +Subject: [PATCH] riscv: dts: spacemit: k1-musepi-pro: add cpu scaling + +Enable CPU DVFS by including the OPP table and wiring the CPU nodes to the +CPU regulator supply. + +Signed-off-by: Andre Heider +--- + .../riscv/boot/dts/spacemit/k1-musepi-pro.dts | 35 ++++++++++++++++++- + 1 file changed, 34 insertions(+), 1 deletion(-) + +--- a/arch/riscv/boot/dts/spacemit/k1-musepi-pro.dts ++++ b/arch/riscv/boot/dts/spacemit/k1-musepi-pro.dts +@@ -9,6 +9,7 @@ + + #include "k1.dtsi" + #include "k1-pinctrl.dtsi" ++#include "k1-opp.dtsi" + + / { + model = "SpacemiT MusePi Pro"; +@@ -99,6 +100,38 @@ + status = "okay"; + }; + ++&cpu_0 { ++ cpu-supply = <&buck1_0v9>; ++}; ++ ++&cpu_1 { ++ cpu-supply = <&buck1_0v9>; ++}; ++ ++&cpu_2 { ++ cpu-supply = <&buck1_0v9>; ++}; ++ ++&cpu_3 { ++ cpu-supply = <&buck1_0v9>; ++}; ++ ++&cpu_4 { ++ cpu-supply = <&buck1_0v9>; ++}; ++ ++&cpu_5 { ++ cpu-supply = <&buck1_0v9>; ++}; ++ ++&cpu_6 { ++ cpu-supply = <&buck1_0v9>; ++}; ++ ++&cpu_7 { ++ cpu-supply = <&buck1_0v9>; ++}; ++ + ð0 { + phy-handle = <&rgmii0>; + phy-mode = "rgmii-id"; +@@ -178,7 +211,7 @@ + dldoin2-supply = <&buck5>; + + regulators { +- buck1 { ++ buck1_0v9: buck1 { + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <3450000>; + regulator-ramp-delay = <5000>; diff --git a/target/linux/spacemit/patches-6.18/0129-riscv-dts-spacemit-orangepi-rv2-Add-cpu-scaling-for-.patch b/target/linux/spacemit/patches-6.18/0129-riscv-dts-spacemit-orangepi-rv2-Add-cpu-scaling-for-.patch new file mode 100644 index 00000000000000..cb7bfd1f853f35 --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0129-riscv-dts-spacemit-orangepi-rv2-Add-cpu-scaling-for-.patch @@ -0,0 +1,73 @@ +From f18544dbbfccb8678f39bf7c4f0dc19c61e65399 Mon Sep 17 00:00:00 2001 +From: Vincent Legoll +Date: Sat, 13 Jun 2026 10:49:34 +0200 +Subject: [PATCH] riscv: dts: spacemit: orangepi-rv2: Add cpu scaling for K1 + SoC + +Enable CPU DVFS on OrangePi RV2 + +This is a copy/paste from Shuwei Wu's BPI-F3 DTS modifications + +Signed-off-by: Vincent Legoll +--- + .../boot/dts/spacemit/k1-orangepi-rv2.dts | 35 ++++++++++++++++++- + 1 file changed, 34 insertions(+), 1 deletion(-) + +--- a/arch/riscv/boot/dts/spacemit/k1-orangepi-rv2.dts ++++ b/arch/riscv/boot/dts/spacemit/k1-orangepi-rv2.dts +@@ -8,6 +8,7 @@ + + #include "k1.dtsi" + #include "k1-pinctrl.dtsi" ++#include "k1-opp.dtsi" + + / { + model = "OrangePi RV2"; +@@ -80,6 +81,38 @@ + status = "okay"; + }; + ++&cpu_0 { ++ cpu-supply = <&buck1_0v9>; ++}; ++ ++&cpu_1 { ++ cpu-supply = <&buck1_0v9>; ++}; ++ ++&cpu_2 { ++ cpu-supply = <&buck1_0v9>; ++}; ++ ++&cpu_3 { ++ cpu-supply = <&buck1_0v9>; ++}; ++ ++&cpu_4 { ++ cpu-supply = <&buck1_0v9>; ++}; ++ ++&cpu_5 { ++ cpu-supply = <&buck1_0v9>; ++}; ++ ++&cpu_6 { ++ cpu-supply = <&buck1_0v9>; ++}; ++ ++&cpu_7 { ++ cpu-supply = <&buck1_0v9>; ++}; ++ + &emmc { + bus-width = <8>; + mmc-hs400-1_8v; +@@ -162,7 +195,7 @@ + dldoin2-supply = <&buck5>; + + regulators { +- buck1 { ++ buck1_0v9: buck1 { + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <3450000>; + regulator-ramp-delay = <5000>; diff --git a/target/linux/spacemit/patches-6.18/0130-riscv-dts-spacemit-orangepi-r2s-add-cpu-scaling.patch b/target/linux/spacemit/patches-6.18/0130-riscv-dts-spacemit-orangepi-r2s-add-cpu-scaling.patch new file mode 100644 index 00000000000000..e5b28befade34b --- /dev/null +++ b/target/linux/spacemit/patches-6.18/0130-riscv-dts-spacemit-orangepi-r2s-add-cpu-scaling.patch @@ -0,0 +1,76 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Jonatan Hazell +Date: Sat, 12 Jul 2026 12:00:00 +0200 +Subject: [PATCH] riscv: dts: spacemit: orangepi-r2s: Add cpu scaling for K1 + SoC + +Enable CPU DVFS on OrangePi R2S by including the shared K1 OPP tables +and wiring the CPU cores to the P1 PMIC's buck1 rail. + +This mirrors the existing cpu-scaling support for the Banana Pi BPI-F3 +and OrangePi RV2. Tested on the R2S hardware. + +Signed-off-by: Jonatan Hazell +--- + arch/riscv/boot/dts/spacemit/k1-orangepi-r2s.dts | 35 +++++++++++++++++++++++- + 1 file changed, 34 insertions(+), 1 deletion(-) + +diff --git a/arch/riscv/boot/dts/spacemit/k1-orangepi-r2s.dts b/arch/riscv/boot/dts/spacemit/k1-orangepi-r2s.dts +--- a/arch/riscv/boot/dts/spacemit/k1-orangepi-r2s.dts ++++ b/arch/riscv/boot/dts/spacemit/k1-orangepi-r2s.dts +@@ -6,6 +6,7 @@ + + #include "k1.dtsi" + #include "k1-pinctrl.dtsi" ++#include "k1-opp.dtsi" + + / { + model = "OrangePi R2S"; +@@ -50,6 +51,38 @@ + }; + }; + ++&cpu_0 { ++ cpu-supply = <&buck1_0v9>; ++}; ++ ++&cpu_1 { ++ cpu-supply = <&buck1_0v9>; ++}; ++ ++&cpu_2 { ++ cpu-supply = <&buck1_0v9>; ++}; ++ ++&cpu_3 { ++ cpu-supply = <&buck1_0v9>; ++}; ++ ++&cpu_4 { ++ cpu-supply = <&buck1_0v9>; ++}; ++ ++&cpu_5 { ++ cpu-supply = <&buck1_0v9>; ++}; ++ ++&cpu_6 { ++ cpu-supply = <&buck1_0v9>; ++}; ++ ++&cpu_7 { ++ cpu-supply = <&buck1_0v9>; ++}; ++ + &combo_phy { + status = "okay"; + }; +@@ -132,7 +165,7 @@ + dldoin2-supply = <&buck5>; + + regulators { +- buck1 { ++ buck1_0v9: buck1 { + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <3450000>; + regulator-ramp-delay = <5000>;