--- /dev/null
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2023 Toco Technologies <info@toco.ae>
+#
+include $(TOPDIR)/rules.mk
+
+ARCH:=riscv64
+BOARD:=jh71x0
+BOARDNAME:=StarFive JH71x0 (7100/7110)
+FEATURES:=ext4
+KERNELNAME:=Image dtbs
+
+KERNEL_PATCHVER:=6.1
+
+include $(INCLUDE_DIR)/target.mk
+
+define Target/Description
+ Build firmware images for the StarFive JH71x0-based boards
+endef
+
+$(eval $(call BuildTarget))
--- /dev/null
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2022 OpenWrt.org
+#
+
+. /lib/functions/uci-defaults.sh
+
+board_config_update
+
+#case "$(board_name)" in
+#sifive,hifive-unleashed-a00)
+# ucidef_set_led_netdev "lan" "LAN" "green:d3" "eth0"
+# ;;
+#sifive,hifive-unmatched-a00)
+# ucidef_set_led_netdev "lan" "LAN" "green:d2" "eth0"
+# ;;
+#esac
+
+board_config_flush
+
+exit 0
--- /dev/null
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2022 OpenWrt.org
+#
+
+. /lib/functions/uci-defaults.sh
+
+board_config_update
+
+case "$(board_name)" in
+*)
+ ucidef_set_interface_lan 'eth0'
+ ;;
+esac
+
+board_config_flush
+
+exit 0
--- /dev/null
+::sysinit:/etc/init.d/rcS S boot
+::shutdown:/etc/init.d/rcS K shutdown
+ttyS0::askfirst:/usr/libexec/login.sh
+tty1::askfirst:/usr/libexec/login.sh
--- /dev/null
+CONFIG_64BIT=y
+CONFIG_ARCH_CLOCKSOURCE_INIT=y
+CONFIG_ARCH_DMA_ADDR_T_64BIT=y
+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_RV64I=y
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_STACKWALK=y
+CONFIG_ARCH_WANTS_THP_SWAP=y
+CONFIG_ASN1=y
+CONFIG_ASSOCIATIVE_ARRAY=y
+CONFIG_ASYMMETRIC_KEY_TYPE=y
+CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=y
+CONFIG_ATA=y
+CONFIG_AUTOFS4_FS=y
+CONFIG_AUTOFS_FS=y
+CONFIG_AUXILIARY_BUS=y
+# CONFIG_BLK_CGROUP is not set
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_NVME=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_BLK_DEV_SR=y
+CONFIG_BLK_MQ_PCI=y
+CONFIG_BLK_MQ_VIRTIO=y
+CONFIG_BLK_PM=y
+CONFIG_CAN=y
+CONFIG_CC_HAVE_STACKPROTECTOR_TLS=y
+CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5"
+CONFIG_CC_NO_ARRAY_BOUNDS=y
+CONFIG_CDROM=y
+CONFIG_CGROUPS=y
+CONFIG_CGROUP_BPF=y
+# CONFIG_CGROUP_CPUACCT is not set
+# CONFIG_CGROUP_DEBUG is not set
+# CONFIG_CGROUP_DEVICE is not set
+# CONFIG_CGROUP_FREEZER is not set
+# CONFIG_CGROUP_HUGETLB is not set
+# CONFIG_CGROUP_NET_CLASSID is not set
+# CONFIG_CGROUP_NET_PRIO is not set
+# CONFIG_CGROUP_PERF is not set
+# CONFIG_CGROUP_PIDS is not set
+# CONFIG_CGROUP_RDMA is not set
+CONFIG_CGROUP_SCHED=y
+CONFIG_CHECKPOINT_RESTORE=y
+CONFIG_CLKSRC_MMIO=y
+CONFIG_CLK_ANALOGBITS_WRPLL_CLN28HPC=y
+CONFIG_CLK_SIFIVE=y
+CONFIG_CLK_SIFIVE_PRCI=y
+CONFIG_CLK_STARFIVE_JH7100=y
+CONFIG_CLK_STARFIVE_JH7100_AUDIO=y
+CONFIG_CLK_STARFIVE_JH7110_AON=y
+CONFIG_CLK_STARFIVE_JH7110_ISP=y
+CONFIG_CLK_STARFIVE_JH7110_STG=y
+CONFIG_CLK_STARFIVE_JH7110_SYS=y
+CONFIG_CLK_STARFIVE_JH7110_VOUT=y
+CONFIG_CLK_STARFIVE_JH71X0=y
+CONFIG_CLONE_BACKWARDS=y
+CONFIG_CLZ_TAB=y
+CONFIG_CMA=y
+CONFIG_CMA_ALIGNMENT=8
+CONFIG_CMA_AREAS=7
+# CONFIG_CMA_DEBUG is not set
+# CONFIG_CMA_DEBUGFS is not set
+CONFIG_CMA_SIZE_MBYTES=16
+# CONFIG_CMA_SIZE_SEL_MAX is not set
+CONFIG_CMA_SIZE_SEL_MBYTES=y
+# CONFIG_CMA_SIZE_SEL_MIN is not set
+# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set
+# CONFIG_CMA_SYSFS is not set
+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_CONTEXT_TRACKING=y
+CONFIG_CONTEXT_TRACKING_IDLE=y
+CONFIG_CONTIG_ALLOC=y
+# CONFIG_CPUSETS is not set
+CONFIG_CPU_IDLE=y
+CONFIG_CPU_IDLE_GOV_MENU=y
+CONFIG_CPU_IDLE_MULTIPLE_DRIVERS=y
+CONFIG_CPU_PM=y
+CONFIG_CPU_RMAP=y
+CONFIG_CRC16=y
+CONFIG_CRC7=y
+CONFIG_CRC_ITU_T=y
+CONFIG_CRYPTO_CMAC=y
+CONFIG_CRYPTO_CRC32C=y
+CONFIG_CRYPTO_DRBG=y
+CONFIG_CRYPTO_DRBG_HMAC=y
+CONFIG_CRYPTO_DRBG_MENU=y
+CONFIG_CRYPTO_ECB=y
+CONFIG_CRYPTO_ECC=y
+CONFIG_CRYPTO_ECDH=y
+CONFIG_CRYPTO_HASH_INFO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_HW=y
+CONFIG_CRYPTO_JITTERENTROPY=y
+CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
+CONFIG_CRYPTO_LIB_POLY1305_RSIZE=1
+CONFIG_CRYPTO_LIB_SHA1=y
+CONFIG_CRYPTO_LIB_SHA256=y
+CONFIG_CRYPTO_LIB_UTILS=y
+CONFIG_CRYPTO_RNG=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_RNG_DEFAULT=y
+CONFIG_CRYPTO_RSA=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_SM3=y
+CONFIG_CRYPTO_SM3_GENERIC=y
+CONFIG_CRYPTO_USER=y
+CONFIG_CRYPTO_USER_API=y
+CONFIG_CRYPTO_USER_API_AEAD=y
+CONFIG_CRYPTO_USER_API_HASH=y
+CONFIG_CRYPTO_USER_API_RNG=y
+CONFIG_CRYPTO_USER_API_SKCIPHER=y
+CONFIG_DEBUG_ATOMIC_SLEEP=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_RT_MUTEXES=y
+CONFIG_DEBUG_RWSEMS=y
+CONFIG_DEBUG_SG=y
+CONFIG_DEBUG_SPINLOCK=y
+CONFIG_DEBUG_TIMEKEEPING=y
+CONFIG_DEFAULT_HOSTNAME="StarFive"
+# CONFIG_DEVFREQ_GOV_PASSIVE is not set
+# CONFIG_DEVFREQ_GOV_PERFORMANCE is not set
+# CONFIG_DEVFREQ_GOV_POWERSAVE is not set
+# CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND is not set
+# CONFIG_DEVFREQ_GOV_USERSPACE is not set
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# CONFIG_DEVTMPFS_SAFE is not set
+CONFIG_DMADEVICES=y
+CONFIG_DMADEVICES_DEBUG=y
+CONFIG_DMADEVICES_VDEBUG=y
+CONFIG_DMA_CMA=y
+CONFIG_DMA_ENGINE=y
+CONFIG_DMA_OF=y
+CONFIG_DMA_SHARED_BUFFER=y
+CONFIG_DMA_VIRTUAL_CHANNELS=y
+CONFIG_DNS_RESOLVER=y
+CONFIG_DTC=y
+CONFIG_DT_IDLE_GENPD=y
+CONFIG_DT_IDLE_STATES=y
+CONFIG_DVB_CORE=y
+CONFIG_DWMAC_GENERIC=y
+CONFIG_DWMAC_STARFIVE=y
+CONFIG_DW_AXI_DMAC=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_SIFIVE=y
+CONFIG_ERRATA_SIFIVE_CIP_1200=y
+CONFIG_ERRATA_SIFIVE_CIP_453=y
+# CONFIG_ERRATA_THEAD is not set
+CONFIG_EXCLUSIVE_SYSTEM_RAM=y
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXTCON=y
+CONFIG_FAILOVER=y
+CONFIG_FAT_DEFAULT_UTF8=y
+CONFIG_FAT_FS=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_FS_IOMAP=y
+CONFIG_FS_MBCACHE=y
+CONFIG_FS_POSIX_ACL=y
+CONFIG_FWNODE_MDIO=y
+CONFIG_FW_LOADER_PAGED_BUF=y
+CONFIG_FW_LOADER_SYSFS=y
+CONFIG_GCC11_NO_ARRAY_BOUNDS=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_CSUM=y
+CONFIG_GENERIC_EARLY_IOREMAP=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_MIGRATION=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_MSI_IRQ_DOMAIN=y
+CONFIG_GENERIC_PCI_IOMAP=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_TIME_VSYSCALL=y
+CONFIG_GLOB=y
+CONFIG_GOLDFISH=y
+# CONFIG_GOLDFISH_PIPE is not set
+# CONFIG_GOLDFISH_TTY is not set
+CONFIG_GPIOLIB_IRQCHIP=y
+CONFIG_GPIO_CDEV=y
+# CONFIG_GPIO_TPS65086 is not set
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_HAS_DMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT_MAP=y
+CONFIG_HOTPLUG_CPU=y
+CONFIG_HUGETLBFS=y
+CONFIG_HUGETLB_PAGE=y
+CONFIG_HVC_DRIVER=y
+CONFIG_HVC_RISCV_SBI=y
+CONFIG_HWMON=y
+CONFIG_HW_RANDOM=y
+CONFIG_HW_RANDOM_JH7110=y
+CONFIG_HW_RANDOM_STARFIVE_VIC=y
+CONFIG_I2C=y
+CONFIG_I2C_ALGOBIT=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_DESIGNWARE_CORE=y
+CONFIG_I2C_DESIGNWARE_PLATFORM=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_IRQCHIP=y
+CONFIG_IRQ_DOMAIN=y
+CONFIG_IRQ_DOMAIN_HIERARCHY=y
+CONFIG_IRQ_FORCED_THREADING=y
+CONFIG_IRQ_WORK=y
+CONFIG_JBD2=y
+CONFIG_JH71XX_PMU=y
+CONFIG_KCMP=y
+CONFIG_KEYS=y
+# CONFIG_LEDS_PWM_MULTICOLOR is not set
+CONFIG_LIBCRC32C=y
+CONFIG_LIBFDT=y
+CONFIG_LOCKUP_DETECTOR=y
+CONFIG_LOCK_DEBUGGING_SUPPORT=y
+CONFIG_LOCK_SPIN_ON_OWNER=y
+CONFIG_MAILBOX=y
+# CONFIG_MAILBOX_TEST is not set
+CONFIG_MARVELL_PHY=y
+CONFIG_MDIO_BUS=y
+CONFIG_MDIO_DEVICE=y
+CONFIG_MDIO_DEVRES=y
+CONFIG_MEDIA_ANALOG_TV_SUPPORT=y
+CONFIG_MEDIA_ATTACH=y
+CONFIG_MEDIA_CAMERA_SUPPORT=y
+CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y
+CONFIG_MEDIA_PLATFORM_SUPPORT=y
+CONFIG_MEDIA_RADIO_SUPPORT=y
+CONFIG_MEDIA_SDR_SUPPORT=y
+CONFIG_MEDIA_SUPPORT=y
+CONFIG_MEDIA_TEST_SUPPORT=y
+CONFIG_MEDIA_TUNER=y
+# CONFIG_MEMCG is not set
+CONFIG_MEMFD_CREATE=y
+CONFIG_MEMORY_ISOLATION=y
+CONFIG_MEMTEST=y
+CONFIG_MFD_CORE=y
+CONFIG_MFD_SYSCON=y
+CONFIG_MFD_TPS65086=y
+CONFIG_MICREL_PHY=y
+CONFIG_MIGRATION=y
+CONFIG_MMC=y
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_DEBUG=y
+CONFIG_MMC_DW=y
+# CONFIG_MMC_DW_BLUEFIELD is not set
+# CONFIG_MMC_DW_EXYNOS is not set
+# CONFIG_MMC_DW_HI3798CV200 is not set
+# CONFIG_MMC_DW_K3 is not set
+# CONFIG_MMC_DW_PCI is not set
+CONFIG_MMC_DW_PLTFM=y
+CONFIG_MMC_DW_STARFIVE=y
+CONFIG_MMIOWB=y
+CONFIG_MODULES_TREE_LOOKUP=y
+CONFIG_MODULES_USE_ELF_RELA=y
+CONFIG_MODULE_SECTIONS=y
+CONFIG_MOTORCOMM_PHY=y
+CONFIG_MPILIB=y
+CONFIG_MTD_SPI_NOR=y
+CONFIG_MUTEX_SPIN_ON_OWNER=y
+CONFIG_NAMESPACES=y
+CONFIG_NEED_DMA_MAP_STATE=y
+# CONFIG_NET_CLS_CGROUP is not set
+CONFIG_NET_FAILOVER=y
+CONFIG_NET_FLOW_LIMIT=y
+CONFIG_NET_NS=y
+CONFIG_NET_SELFTESTS=y
+CONFIG_NLS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ISO8859_1=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_SYSFS=y
+CONFIG_NVME_CORE=y
+# CONFIG_NVME_HWMON is not set
+# CONFIG_NVME_MULTIPATH is not set
+CONFIG_OF=y
+CONFIG_OF_ADDRESS=y
+CONFIG_OF_DMA_DEFAULT_COHERENT=y
+CONFIG_OF_DYNAMIC=y
+CONFIG_OF_EARLY_FLATTREE=y
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_GPIO=y
+CONFIG_OF_IRQ=y
+CONFIG_OF_KOBJ=y
+CONFIG_OF_MDIO=y
+CONFIG_OF_OVERLAY=y
+CONFIG_OF_RESOLVE=y
+CONFIG_OID_REGISTRY=y
+CONFIG_OVERLAY_FS_INDEX=y
+CONFIG_OVERLAY_FS_METACOPY=y
+CONFIG_OVERLAY_FS_REDIRECT_DIR=y
+CONFIG_PADATA=y
+CONFIG_PAGE_OFFSET=0xff60000000000000
+CONFIG_PAGE_POOL=y
+CONFIG_PAGE_REPORTING=y
+CONFIG_PAGE_SIZE_LESS_THAN_256KB=y
+CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
+CONFIG_PCI=y
+# CONFIG_PCIE_FU740 is not set
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCI_DOMAINS_GENERIC=y
+CONFIG_PCI_MSI=y
+CONFIG_PCI_MSI_IRQ_DOMAIN=y
+CONFIG_PCS_XPCS=y
+CONFIG_PERF_EVENTS=y
+CONFIG_PGTABLE_LEVELS=5
+CONFIG_PHYLIB=y
+CONFIG_PHYLINK=y
+CONFIG_PHYS_ADDR_T_64BIT=y
+# CONFIG_PHY_STARFIVE_JH7110_PCIE is not set
+# CONFIG_PHY_STARFIVE_JH7110_USB is not set
+CONFIG_PINCTRL=y
+CONFIG_PINCTRL_STARFIVE_JH7100=y
+CONFIG_PINCTRL_STARFIVE_JH7110=y
+CONFIG_PINCTRL_STARFIVE_JH7110_AON=y
+CONFIG_PINCTRL_STARFIVE_JH7110_SYS=y
+# CONFIG_PKCS8_PRIVATE_KEY_PARSER is not set
+CONFIG_PM=y
+CONFIG_PM_ADVANCED_DEBUG=y
+CONFIG_PM_CLK=y
+CONFIG_PM_DEBUG=y
+CONFIG_PM_DEVFREQ=y
+# CONFIG_PM_DEVFREQ_EVENT is not set
+CONFIG_PM_GENERIC_DOMAINS=y
+CONFIG_PM_GENERIC_DOMAINS_OF=y
+CONFIG_PM_OPP=y
+CONFIG_PORTABLE=y
+CONFIG_POSIX_CPU_TIMERS_TASK_WORK=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
+CONFIG_POWER_RESET=y
+CONFIG_POWER_RESET_GPIO_RESTART=y
+CONFIG_POWER_RESET_SYSCON=y
+CONFIG_POWER_RESET_SYSCON_POWEROFF=y
+CONFIG_POWER_RESET_TPS65086=y
+CONFIG_PREEMPT_COUNT=y
+CONFIG_PREEMPT_NONE_BUILD=y
+CONFIG_PRINTK_TIME=y
+CONFIG_PROC_CHILDREN=y
+CONFIG_PTP_1588_CLOCK_OPTIONAL=y
+CONFIG_PWM=y
+# CONFIG_PWM_CLK is not set
+# CONFIG_PWM_SIFIVE is not set
+CONFIG_PWM_SIFIVE_PTC=y
+CONFIG_PWM_SYSFS=y
+# CONFIG_PWM_XILINX is not set
+CONFIG_QUEUED_RWLOCKS=y
+CONFIG_R8169=y
+CONFIG_RANDSTRUCT_NONE=y
+CONFIG_RATIONAL=y
+CONFIG_RCU_EQS_DEBUG=y
+CONFIG_REALTEK_PHY=y
+CONFIG_REGMAP=y
+CONFIG_REGMAP_I2C=y
+CONFIG_REGMAP_IRQ=y
+CONFIG_REGMAP_MMIO=y
+CONFIG_REGMAP_SPI=y
+CONFIG_REGULATOR=y
+# CONFIG_REGULATOR_TPS65086 is not set
+# CONFIG_RESET_ATTACK_MITIGATION is not set
+CONFIG_RESET_CONTROLLER=y
+CONFIG_RESET_SIMPLE=y
+CONFIG_RESET_STARFIVE_JH7100=y
+CONFIG_RESET_STARFIVE_JH7110=y
+CONFIG_RESET_STARFIVE_JH71X0=y
+CONFIG_RFS_ACCEL=y
+CONFIG_RISCV=y
+CONFIG_RISCV_ALTERNATIVE=y
+CONFIG_RISCV_BOOT_SPINWAIT=y
+CONFIG_RISCV_DMA_NONCOHERENT=y
+CONFIG_RISCV_INTC=y
+CONFIG_RISCV_ISA_C=y
+CONFIG_RISCV_ISA_SVPBMT=y
+CONFIG_RISCV_ISA_ZICBOM=y
+CONFIG_RISCV_PMU=y
+CONFIG_RISCV_PMU_LEGACY=y
+CONFIG_RISCV_PMU_SBI=y
+CONFIG_RISCV_SBI=y
+CONFIG_RISCV_SBI_CPUIDLE=y
+CONFIG_RISCV_SBI_V01=y
+CONFIG_RISCV_TIMER=y
+CONFIG_RPMSG=y
+CONFIG_RPMSG_CHAR=y
+# CONFIG_RPMSG_CTRL is not set
+CONFIG_RPMSG_NS=y
+# CONFIG_RPMSG_TTY is not set
+CONFIG_RPMSG_VIRTIO=y
+CONFIG_RPS=y
+CONFIG_RTC_CLASS=y
+# CONFIG_RTC_DRV_EFI is not set
+CONFIG_RTC_DRV_GOLDFISH=y
+CONFIG_RTC_I2C_AND_SPI=y
+# CONFIG_RT_GROUP_SCHED is not set
+CONFIG_RWSEM_SPIN_ON_OWNER=y
+CONFIG_SATA_AHCI=y
+CONFIG_SATA_HOST=y
+CONFIG_SCSI=y
+CONFIG_SCSI_COMMON=y
+CONFIG_SCSI_VIRTIO=y
+CONFIG_SENSORS_SFCTEMP=y
+CONFIG_SERIAL_8250_DW=y
+CONFIG_SERIAL_8250_DWLIB=y
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_MANY_PORTS=y
+CONFIG_SERIAL_8250_NR_UARTS=6
+CONFIG_SERIAL_8250_RUNTIME_UARTS=6
+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
+CONFIG_SERIAL_EARLYCON_RISCV_SBI=y
+CONFIG_SERIAL_MCTRL_GPIO=y
+CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_SERIAL_SIFIVE=y
+CONFIG_SERIAL_SIFIVE_CONSOLE=y
+CONFIG_SG_POOL=y
+CONFIG_SIFIVE_CCACHE=y
+CONFIG_SIFIVE_PLIC=y
+CONFIG_SMP=y
+CONFIG_SND=y
+# CONFIG_SND_COMPRESS_OFFLOAD is not set
+CONFIG_SND_DESIGNWARE_I2S=y
+# CONFIG_SND_DESIGNWARE_PCM is not set
+CONFIG_SND_DMAENGINE_PCM=y
+CONFIG_SND_HWDEP=y
+CONFIG_SND_JACK=y
+CONFIG_SND_PCM=y
+CONFIG_SND_RAWMIDI=y
+CONFIG_SND_SIMPLE_CARD=y
+CONFIG_SND_SIMPLE_CARD_UTILS=y
+CONFIG_SND_SOC=y
+CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM=y
+CONFIG_SND_SOC_I2C_AND_SPI=y
+CONFIG_SND_SOC_WM8960=y
+CONFIG_SND_USB_AUDIO=y
+CONFIG_SOCK_CGROUP_DATA=y
+CONFIG_SOCK_RX_QUEUE_MAPPING=y
+# CONFIG_SOC_MICROCHIP_POLARFIRE is not set
+CONFIG_SOC_SIFIVE=y
+CONFIG_SOC_STARFIVE=y
+# CONFIG_SOC_VIRT is not set
+CONFIG_SOFTLOCKUP_DETECTOR=y
+CONFIG_SOUND=y
+CONFIG_SOUND_OSS_CORE=y
+CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
+CONFIG_SPARSE_IRQ=y
+CONFIG_SPI=y
+CONFIG_SPI_CADENCE_QUADSPI=y
+CONFIG_SPI_DYNAMIC=y
+CONFIG_SPI_MASTER=y
+CONFIG_SPI_MEM=y
+CONFIG_SPI_SIFIVE=y
+CONFIG_SPI_SPIDEV=y
+CONFIG_SRCU=y
+CONFIG_STACKTRACE=y
+CONFIG_STARFIVE_TIMER=y
+CONFIG_STARFIVE_WATCHDOG=y
+CONFIG_STMMAC_ETH=y
+CONFIG_STMMAC_PLATFORM=y
+CONFIG_STMMAC_SELFTESTS=y
+CONFIG_SWIOTLB=y
+CONFIG_SWPHY=y
+CONFIG_SYNC_FILE=y
+CONFIG_SYSCTL_EXCEPTION_TRACE=y
+# CONFIG_SYSFB_SIMPLEFB is not set
+CONFIG_THREAD_INFO_IN_TASK=y
+CONFIG_TICK_CPU_ACCOUNTING=y
+CONFIG_TIMER_OF=y
+CONFIG_TIMER_PROBE=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_TOOLCHAIN_HAS_ZICBOM=y
+CONFIG_TOOLCHAIN_HAS_ZIHINTPAUSE=y
+CONFIG_TOOLCHAIN_NEEDS_EXPLICIT_ZICSR_ZIFENCEI=y
+CONFIG_TREE_RCU=y
+CONFIG_TREE_SRCU=y
+CONFIG_TTY_PRINTK=y
+CONFIG_TTY_PRINTK_LEVEL=6
+CONFIG_TUNE_GENERIC=y
+CONFIG_UCS2_STRING=y
+CONFIG_UNINLINE_SPIN_UNLOCK=y
+CONFIG_USB=y
+CONFIG_USB_CDNS3=y
+CONFIG_USB_CDNS3_GADGET=y
+CONFIG_USB_CDNS3_HOST=y
+CONFIG_USB_CDNS3_STARFIVE=y
+CONFIG_USB_CDNS_HOST=y
+CONFIG_USB_CDNS_SUPPORT=y
+CONFIG_USB_COMMON=y
+CONFIG_USB_CONFIGFS=y
+# CONFIG_USB_CONFIGFS_ACM is not set
+# CONFIG_USB_CONFIGFS_ECM is not set
+# CONFIG_USB_CONFIGFS_ECM_SUBSET is not set
+# CONFIG_USB_CONFIGFS_EEM is not set
+CONFIG_USB_CONFIGFS_F_FS=y
+# CONFIG_USB_CONFIGFS_F_HID is not set
+# CONFIG_USB_CONFIGFS_F_LB_SS is not set
+# CONFIG_USB_CONFIGFS_F_MIDI is not set
+# CONFIG_USB_CONFIGFS_F_PRINTER is not set
+# CONFIG_USB_CONFIGFS_F_UAC1 is not set
+# CONFIG_USB_CONFIGFS_F_UAC1_LEGACY is not set
+# CONFIG_USB_CONFIGFS_F_UAC2 is not set
+CONFIG_USB_CONFIGFS_MASS_STORAGE=y
+# CONFIG_USB_CONFIGFS_NCM is not set
+# CONFIG_USB_CONFIGFS_OBEX is not set
+# CONFIG_USB_CONFIGFS_RNDIS is not set
+# CONFIG_USB_CONFIGFS_SERIAL is not set
+CONFIG_USB_F_FS=y
+CONFIG_USB_F_MASS_STORAGE=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_LIBCOMPOSITE=y
+CONFIG_USB_ROLE_SWITCH=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_UAS=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_XHCI_PLATFORM=y
+CONFIG_USELIB=y
+CONFIG_USER_NS=y
+CONFIG_VFAT_FS=y
+# CONFIG_VHOST_MENU is not set
+CONFIG_VIRTIO=y
+CONFIG_VIRTIO_ANCHOR=y
+# CONFIG_VIRTIO_BLK is not set
+CONFIG_VIRTIO_CONSOLE=y
+# CONFIG_VIRTIO_MENU is not set
+CONFIG_VIRTIO_NET=y
+CONFIG_VMAP_STACK=y
+CONFIG_WATCHDOG_CORE=y
+CONFIG_WATCHDOG_SYSFS=y
+CONFIG_WQ_WATCHDOG=y
+CONFIG_XPS=y
+CONFIG_ZONE_DMA32=y
--- /dev/null
+BOARDNAME:=Generic
--- /dev/null
+config JH71X0_SD_BOOT_PARTSIZE
+ int "Boot (SD Card) filesystem partition size (in MB)"
+ depends on TARGET_jh71x0
+ default 32
+
--- /dev/null
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2022 Toco Technologies <info@toco.ae>
+#
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/image.mk
+
+FAT32_BLOCK_SIZE=1024
+FAT32_BLOCKS=$(shell echo $$(($(CONFIG_JH71X0_SD_BOOT_PARTSIZE)*1024*1024/$(FAT32_BLOCK_SIZE))))
+
+#KERNEL_LOADADDR:=0x80200000
+
+define Build/boot-scr
+ rm -f $@-boot.scr
+ mkimage -A riscv -O linux -T script -C none -a 0 -e 0 -d mmc.bootscript.jh7110 $@-boot.scr
+endef
+
+define Build/boot-scr-jh7100
+ rm -f $@-boot.scr
+ mkimage -A riscv -O linux -T script -C none -a 0 -e 0 -d mmc.bootscript.jh7100 $@-boot.scr
+endef
+
+define Build/riscv-sdcard
+ rm -f $@.boot #$(KDIR_TMP)/$(IMG_PREFIX)-$(PROFILE)-boot.img
+ mkfs.fat $@.boot -C $(FAT32_BLOCKS)
+ mcopy -i $@.boot $(LINUX_DIR)/arch/riscv/boot/dts/$(DEVICE_DTS).dtb ::dtb
+ mcopy -i $@.boot $@-boot.scr ::boot.scr.uimg
+ mcopy -i $@.boot $(IMAGE_KERNEL) ::Image
+ ./gen_starfive_sdcard_img.sh \
+ $@ \
+ $@.boot \
+ $(IMAGE_ROOTFS) \
+ $(CONFIG_JH71X0_SD_BOOT_PARTSIZE) \
+ $(CONFIG_TARGET_ROOTFS_PARTSIZE)
+endef
+
+define Device/Default
+ PROFILES := Default
+ KERNEL_NAME := Image
+ KERNEL := kernel-bin
+ IMAGES := sdcard.img.gz
+ IMAGE/sdcard.img.gz := boot-scr | riscv-sdcard | append-metadata | gzip
+endef
+
+define Device/JH7100
+ PROFILES := Default
+ KERNEL_NAME := Image
+ KERNEL := kernel-bin
+ IMAGES := sdcard.img.gz
+ IMAGE/sdcard.img.gz := boot-scr-jh7100 | riscv-sdcard | append-metadata | gzip
+endef
+
+define Device/visionfive2-v1.2a
+ DEVICE_VENDOR := StarFive
+ DEVICE_MODEL := VisionFive2 v1.2a
+ DEVICE_DTS := starfive/jh7110-starfive-visionfive-2-v1.2a
+endef
+TARGET_DEVICES += visionfive2-v1.2a
+
+define Device/visionfive2-v1.3b
+ DEVICE_VENDOR := StarFive
+ DEVICE_MODEL := VisionFive2 v1.3b
+ DEVICE_DTS := starfive/jh7110-starfive-visionfive-2-v1.3b
+endef
+TARGET_DEVICES += visionfive2-v1.3b
+
+define Device/beaglev-starlight
+ $(call Device/JH7100)
+ DEVICE_VENDOR := BeagleV
+ DEVICE_MODEL := Starlight
+ DEVICE_DTS := starfive/jh7100-beaglev-starlight
+endef
+TARGET_DEVICES += beaglev-starlight
+
+define Device/visionfive-v1
+ $(call Device/JH7100)
+ DEVICE_VENDOR := StarFive
+ DEVICE_MODEL := VisionFive v1
+ DEVICE_DTS := starfive/jh7100-starfive-visionfive-v1
+endef
+TARGET_DEVICES += visionfive-v1
+
+$(eval $(call BuildImage))
--- /dev/null
+#!/usr/bin/env bash
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2022 OpenWrt.org
+#
+
+set -ex
+#[ $# -eq 7 ] || {
+[ $# -eq 5 ] || {
+ echo "SYNTAX: $0 <file> <bootfs image> <rootfs image> <bootfs size> <rootfs size>"
+ exit 1
+}
+
+OUTPUT="$1"
+BOOTFS="$2"
+ROOTFS="$3"
+BOOTFSSIZE="$4"
+ROOTFSSIZE="$5"
+#UBOOT="$6"
+#UBOOT_SPL="$7"
+#override UBOOT/UBOOT_SPL with a filler file until u-boot packaging is ready
+UBOOT=`mktemp`
+UBOOT_SPL=`mktemp`
+
+set $(ptgen -o $OUTPUT -v -g -T sifiveu_spl -N loader1 -p 1024 -T sifiveu_uboot -N loader2 -p 4096 -t ef -N boot -p ${BOOTFSSIZE}M -N rootfs -p ${ROOTFSSIZE}M)
+
+ROOTFSOFFSET=$(($7 / 512))
+
+dd bs=512 if="$UBOOT_SPL" of="$OUTPUT" seek=34 conv=notrunc
+dd bs=512 if="$UBOOT" of="$OUTPUT" seek=2082 conv=notrunc
+dd bs=512 if="$BOOTFS" of="$OUTPUT" seek=10274 conv=notrunc
+dd bs=512 if="$ROOTFS" of="$OUTPUT" seek=${ROOTFSOFFSET} conv=notrunc
--- /dev/null
+fatload mmc 0:3 0x84000000 Image
+fatload mmc 0:3 0x88000000 dtb
+setenv bootargs "earlyprintk console=ttyS0,115200 debug rootwait earlycon=sbi root=/dev/mmcblk0p4"
+booti 0x84000000 - 0x88000000
--- /dev/null
+fatload mmc 1:3 0xa0000000 Image
+fatload mmc 1:3 0x46000000 dtb
+run chipa_set_linux
+setenv bootargs "earlyprintk console=ttyS0,115200 debug rootwait earlycon=sbi root=/dev/mmcblk0p4"
+booti 0xa0000000 - 0x46000000
--- /dev/null
+From be4e34a21e5bc403c922d5cd0132b853fbee4e56 Mon Sep 17 00:00:00 2001
+From: Jianlong Huang <jianlong.huang@starfivetech.com>
+Date: Thu, 9 Feb 2023 22:36:59 +0800
+Subject: [PATCH 01/95] dt-bindings: pinctrl: Add StarFive JH7110 sys pinctrl
+
+Add pinctrl bindings for StarFive JH7110 SoC sys pinctrl controller.
+
+Reviewed-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Jianlong Huang <jianlong.huang@starfivetech.com>
+Co-developed-by: Emil Renner Berthing <kernel@esmil.dk>
+Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ .../pinctrl/starfive,jh7110-sys-pinctrl.yaml | 142 ++++++++++++++++++
+ MAINTAINERS | 6 +-
+ .../pinctrl/starfive,jh7110-pinctrl.h | 115 ++++++++++++++
+ 3 files changed, 261 insertions(+), 2 deletions(-)
+ create mode 100644 Documentation/devicetree/bindings/pinctrl/starfive,jh7110-sys-pinctrl.yaml
+ create mode 100644 include/dt-bindings/pinctrl/starfive,jh7110-pinctrl.h
+
+diff --git a/Documentation/devicetree/bindings/pinctrl/starfive,jh7110-sys-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/starfive,jh7110-sys-pinctrl.yaml
+new file mode 100644
+index 000000000000..222b9e240f8a
+--- /dev/null
++++ b/Documentation/devicetree/bindings/pinctrl/starfive,jh7110-sys-pinctrl.yaml
+@@ -0,0 +1,142 @@
++# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/pinctrl/starfive,jh7110-sys-pinctrl.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: StarFive JH7110 SYS Pin Controller
++
++description: |
++ Bindings for the JH7110 RISC-V SoC from StarFive Technology Ltd.
++
++ Out of the SoC's many pins only the ones named PAD_GPIO0 to PAD_GPIO63
++ can be multiplexed and have configurable bias, drive strength,
++ schmitt trigger etc.
++ Some peripherals have their I/O go through the 64 "GPIOs". This also
++ includes a number of other UARTs, I2Cs, SPIs, PWMs etc.
++ All these peripherals are connected to all 64 GPIOs such that
++ any GPIO can be set up to be controlled by any of the peripherals.
++
++maintainers:
++ - Jianlong Huang <jianlong.huang@starfivetech.com>
++
++properties:
++ compatible:
++ const: starfive,jh7110-sys-pinctrl
++
++ reg:
++ maxItems: 1
++
++ clocks:
++ maxItems: 1
++
++ resets:
++ maxItems: 1
++
++ interrupts:
++ maxItems: 1
++
++ interrupt-controller: true
++
++ '#interrupt-cells':
++ const: 2
++
++ gpio-controller: true
++
++ '#gpio-cells':
++ const: 2
++
++patternProperties:
++ '-[0-9]+$':
++ type: object
++ additionalProperties: false
++ patternProperties:
++ '-pins$':
++ type: object
++ description: |
++ A pinctrl node should contain at least one subnode representing the
++ pinctrl groups available on the machine. Each subnode will list the
++ pins it needs, and how they should be configured, with regard to
++ muxer configuration, bias, input enable/disable, input schmitt
++ trigger enable/disable, slew-rate and drive strength.
++ allOf:
++ - $ref: /schemas/pinctrl/pincfg-node.yaml
++ - $ref: /schemas/pinctrl/pinmux-node.yaml
++ additionalProperties: false
++
++ properties:
++ pinmux:
++ description: |
++ The list of GPIOs and their mux settings that properties in the
++ node apply to. This should be set using the GPIOMUX or PINMUX
++ macros.
++
++ bias-disable: true
++
++ bias-pull-up:
++ type: boolean
++
++ bias-pull-down:
++ type: boolean
++
++ drive-strength:
++ enum: [ 2, 4, 8, 12 ]
++
++ input-enable: true
++
++ input-disable: true
++
++ input-schmitt-enable: true
++
++ input-schmitt-disable: true
++
++ slew-rate:
++ maximum: 1
++
++required:
++ - compatible
++ - reg
++ - clocks
++ - interrupts
++ - interrupt-controller
++ - '#interrupt-cells'
++ - gpio-controller
++ - '#gpio-cells'
++
++additionalProperties: false
++
++examples:
++ - |
++ pinctrl@13040000 {
++ compatible = "starfive,jh7110-sys-pinctrl";
++ reg = <0x13040000 0x10000>;
++ clocks = <&syscrg 112>;
++ resets = <&syscrg 2>;
++ interrupts = <86>;
++ interrupt-controller;
++ #interrupt-cells = <2>;
++ gpio-controller;
++ #gpio-cells = <2>;
++
++ uart0-0 {
++ tx-pins {
++ pinmux = <0xff140005>;
++ bias-disable;
++ drive-strength = <12>;
++ input-disable;
++ input-schmitt-disable;
++ slew-rate = <0>;
++ };
++
++ rx-pins {
++ pinmux = <0x0E000406>;
++ bias-pull-up;
++ drive-strength = <2>;
++ input-enable;
++ input-schmitt-enable;
++ slew-rate = <0>;
++ };
++ };
++ };
++
++...
+diff --git a/MAINTAINERS b/MAINTAINERS
+index 350d7e3ba94f..00989e5a66b3 100644
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -19641,13 +19641,15 @@ F: Documentation/devicetree/bindings/clock/starfive,jh7100-*.yaml
+ F: drivers/clk/starfive/clk-starfive-jh7100*
+ F: include/dt-bindings/clock/starfive-jh7100*.h
+
+-STARFIVE JH7100 PINCTRL DRIVER
++STARFIVE JH71X0 PINCTRL DRIVERS
+ M: Emil Renner Berthing <kernel@esmil.dk>
++M: Jianlong Huang <jianlong.huang@starfivetech.com>
+ L: linux-gpio@vger.kernel.org
+ S: Maintained
+-F: Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml
++F: Documentation/devicetree/bindings/pinctrl/starfive,jh71*.yaml
+ F: drivers/pinctrl/starfive/
+ F: include/dt-bindings/pinctrl/pinctrl-starfive-jh7100.h
++F: include/dt-bindings/pinctrl/starfive,jh7110-pinctrl.h
+
+ STARFIVE JH7100 RESET CONTROLLER DRIVER
+ M: Emil Renner Berthing <kernel@esmil.dk>
+diff --git a/include/dt-bindings/pinctrl/starfive,jh7110-pinctrl.h b/include/dt-bindings/pinctrl/starfive,jh7110-pinctrl.h
+new file mode 100644
+index 000000000000..57c1659e4bbf
+--- /dev/null
++++ b/include/dt-bindings/pinctrl/starfive,jh7110-pinctrl.h
+@@ -0,0 +1,115 @@
++/* SPDX-License-Identifier: GPL-2.0 OR MIT */
++/*
++ * Copyright (C) 2022 Emil Renner Berthing <kernel@esmil.dk>
++ * Copyright (C) 2022 StarFive Technology Co., Ltd.
++ */
++
++#ifndef __DT_BINDINGS_PINCTRL_STARFIVE_JH7110_H__
++#define __DT_BINDINGS_PINCTRL_STARFIVE_JH7110_H__
++
++/* sys_iomux pins */
++#define PAD_GPIO0 0
++#define PAD_GPIO1 1
++#define PAD_GPIO2 2
++#define PAD_GPIO3 3
++#define PAD_GPIO4 4
++#define PAD_GPIO5 5
++#define PAD_GPIO6 6
++#define PAD_GPIO7 7
++#define PAD_GPIO8 8
++#define PAD_GPIO9 9
++#define PAD_GPIO10 10
++#define PAD_GPIO11 11
++#define PAD_GPIO12 12
++#define PAD_GPIO13 13
++#define PAD_GPIO14 14
++#define PAD_GPIO15 15
++#define PAD_GPIO16 16
++#define PAD_GPIO17 17
++#define PAD_GPIO18 18
++#define PAD_GPIO19 19
++#define PAD_GPIO20 20
++#define PAD_GPIO21 21
++#define PAD_GPIO22 22
++#define PAD_GPIO23 23
++#define PAD_GPIO24 24
++#define PAD_GPIO25 25
++#define PAD_GPIO26 26
++#define PAD_GPIO27 27
++#define PAD_GPIO28 28
++#define PAD_GPIO29 29
++#define PAD_GPIO30 30
++#define PAD_GPIO31 31
++#define PAD_GPIO32 32
++#define PAD_GPIO33 33
++#define PAD_GPIO34 34
++#define PAD_GPIO35 35
++#define PAD_GPIO36 36
++#define PAD_GPIO37 37
++#define PAD_GPIO38 38
++#define PAD_GPIO39 39
++#define PAD_GPIO40 40
++#define PAD_GPIO41 41
++#define PAD_GPIO42 42
++#define PAD_GPIO43 43
++#define PAD_GPIO44 44
++#define PAD_GPIO45 45
++#define PAD_GPIO46 46
++#define PAD_GPIO47 47
++#define PAD_GPIO48 48
++#define PAD_GPIO49 49
++#define PAD_GPIO50 50
++#define PAD_GPIO51 51
++#define PAD_GPIO52 52
++#define PAD_GPIO53 53
++#define PAD_GPIO54 54
++#define PAD_GPIO55 55
++#define PAD_GPIO56 56
++#define PAD_GPIO57 57
++#define PAD_GPIO58 58
++#define PAD_GPIO59 59
++#define PAD_GPIO60 60
++#define PAD_GPIO61 61
++#define PAD_GPIO62 62
++#define PAD_GPIO63 63
++#define PAD_SD0_CLK 64
++#define PAD_SD0_CMD 65
++#define PAD_SD0_DATA0 66
++#define PAD_SD0_DATA1 67
++#define PAD_SD0_DATA2 68
++#define PAD_SD0_DATA3 69
++#define PAD_SD0_DATA4 70
++#define PAD_SD0_DATA5 71
++#define PAD_SD0_DATA6 72
++#define PAD_SD0_DATA7 73
++#define PAD_SD0_STRB 74
++#define PAD_GMAC1_MDC 75
++#define PAD_GMAC1_MDIO 76
++#define PAD_GMAC1_RXD0 77
++#define PAD_GMAC1_RXD1 78
++#define PAD_GMAC1_RXD2 79
++#define PAD_GMAC1_RXD3 80
++#define PAD_GMAC1_RXDV 81
++#define PAD_GMAC1_RXC 82
++#define PAD_GMAC1_TXD0 83
++#define PAD_GMAC1_TXD1 84
++#define PAD_GMAC1_TXD2 85
++#define PAD_GMAC1_TXD3 86
++#define PAD_GMAC1_TXEN 87
++#define PAD_GMAC1_TXC 88
++#define PAD_QSPI_SCLK 89
++#define PAD_QSPI_CS0 90
++#define PAD_QSPI_DATA0 91
++#define PAD_QSPI_DATA1 92
++#define PAD_QSPI_DATA2 93
++#define PAD_QSPI_DATA3 94
++
++#define GPOUT_LOW 0
++#define GPOUT_HIGH 1
++
++#define GPOEN_ENABLE 0
++#define GPOEN_DISABLE 1
++
++#define GPI_NONE 255
++
++#endif
+--
+2.20.1
+
--- /dev/null
+From f09620d75572d607e87b6340409d64b34b6c2713 Mon Sep 17 00:00:00 2001
+From: Jianlong Huang <jianlong.huang@starfivetech.com>
+Date: Thu, 9 Feb 2023 22:37:00 +0800
+Subject: [PATCH 02/95] dt-bindings: pinctrl: Add StarFive JH7110 aon pinctrl
+
+Add pinctrl bindings for StarFive JH7110 SoC aon pinctrl controller.
+
+Reviewed-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Jianlong Huang <jianlong.huang@starfivetech.com>
+Co-developed-by: Emil Renner Berthing <kernel@esmil.dk>
+Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ .../pinctrl/starfive,jh7110-aon-pinctrl.yaml | 124 ++++++++++++++++++
+ .../pinctrl/starfive,jh7110-pinctrl.h | 22 ++++
+ 2 files changed, 146 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/pinctrl/starfive,jh7110-aon-pinctrl.yaml
+
+diff --git a/Documentation/devicetree/bindings/pinctrl/starfive,jh7110-aon-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/starfive,jh7110-aon-pinctrl.yaml
+new file mode 100644
+index 000000000000..b470901f5f56
+--- /dev/null
++++ b/Documentation/devicetree/bindings/pinctrl/starfive,jh7110-aon-pinctrl.yaml
+@@ -0,0 +1,124 @@
++# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/pinctrl/starfive,jh7110-aon-pinctrl.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: StarFive JH7110 AON Pin Controller
++
++description: |
++ Bindings for the JH7110 RISC-V SoC from StarFive Technology Ltd.
++
++ Out of the SoC's many pins only the ones named PAD_RGPIO0 to PAD_RGPIO3
++ can be multiplexed and have configurable bias, drive strength,
++ schmitt trigger etc.
++ Some peripherals such as PWM have their I/O go through the 4 "GPIOs".
++
++maintainers:
++ - Jianlong Huang <jianlong.huang@starfivetech.com>
++
++properties:
++ compatible:
++ const: starfive,jh7110-aon-pinctrl
++
++ reg:
++ maxItems: 1
++
++ resets:
++ maxItems: 1
++
++ interrupts:
++ maxItems: 1
++
++ interrupt-controller: true
++
++ '#interrupt-cells':
++ const: 2
++
++ gpio-controller: true
++
++ '#gpio-cells':
++ const: 2
++
++patternProperties:
++ '-[0-9]+$':
++ type: object
++ additionalProperties: false
++ patternProperties:
++ '-pins$':
++ type: object
++ description: |
++ A pinctrl node should contain at least one subnode representing the
++ pinctrl groups available on the machine. Each subnode will list the
++ pins it needs, and how they should be configured, with regard to
++ muxer configuration, bias, input enable/disable, input schmitt
++ trigger enable/disable, slew-rate and drive strength.
++ allOf:
++ - $ref: /schemas/pinctrl/pincfg-node.yaml
++ - $ref: /schemas/pinctrl/pinmux-node.yaml
++ additionalProperties: false
++
++ properties:
++ pinmux:
++ description: |
++ The list of GPIOs and their mux settings that properties in the
++ node apply to. This should be set using the GPIOMUX macro.
++
++ bias-disable: true
++
++ bias-pull-up:
++ type: boolean
++
++ bias-pull-down:
++ type: boolean
++
++ drive-strength:
++ enum: [ 2, 4, 8, 12 ]
++
++ input-enable: true
++
++ input-disable: true
++
++ input-schmitt-enable: true
++
++ input-schmitt-disable: true
++
++ slew-rate:
++ maximum: 1
++
++required:
++ - compatible
++ - reg
++ - interrupts
++ - interrupt-controller
++ - '#interrupt-cells'
++ - gpio-controller
++ - '#gpio-cells'
++
++additionalProperties: false
++
++examples:
++ - |
++ pinctrl@17020000 {
++ compatible = "starfive,jh7110-aon-pinctrl";
++ reg = <0x17020000 0x10000>;
++ resets = <&aoncrg 2>;
++ interrupts = <85>;
++ interrupt-controller;
++ #interrupt-cells = <2>;
++ gpio-controller;
++ #gpio-cells = <2>;
++
++ pwm-0 {
++ pwm-pins {
++ pinmux = <0xff030802>;
++ bias-disable;
++ drive-strength = <12>;
++ input-disable;
++ input-schmitt-disable;
++ slew-rate = <0>;
++ };
++ };
++ };
++
++...
+diff --git a/include/dt-bindings/pinctrl/starfive,jh7110-pinctrl.h b/include/dt-bindings/pinctrl/starfive,jh7110-pinctrl.h
+index 57c1659e4bbf..3865f0139639 100644
+--- a/include/dt-bindings/pinctrl/starfive,jh7110-pinctrl.h
++++ b/include/dt-bindings/pinctrl/starfive,jh7110-pinctrl.h
+@@ -104,6 +104,28 @@
+ #define PAD_QSPI_DATA2 93
+ #define PAD_QSPI_DATA3 94
+
++/* aon_iomux pins */
++#define PAD_TESTEN 0
++#define PAD_RGPIO0 1
++#define PAD_RGPIO1 2
++#define PAD_RGPIO2 3
++#define PAD_RGPIO3 4
++#define PAD_RSTN 5
++#define PAD_GMAC0_MDC 6
++#define PAD_GMAC0_MDIO 7
++#define PAD_GMAC0_RXD0 8
++#define PAD_GMAC0_RXD1 9
++#define PAD_GMAC0_RXD2 10
++#define PAD_GMAC0_RXD3 11
++#define PAD_GMAC0_RXDV 12
++#define PAD_GMAC0_RXC 13
++#define PAD_GMAC0_TXD0 14
++#define PAD_GMAC0_TXD1 15
++#define PAD_GMAC0_TXD2 16
++#define PAD_GMAC0_TXD3 17
++#define PAD_GMAC0_TXEN 18
++#define PAD_GMAC0_TXC 19
++
+ #define GPOUT_LOW 0
+ #define GPOUT_HIGH 1
+
+--
+2.20.1
+
--- /dev/null
+From 202052bb19f008468a85d65f59f6a7ce02c8bdea Mon Sep 17 00:00:00 2001
+From: Jianlong Huang <jianlong.huang@starfivetech.com>
+Date: Thu, 9 Feb 2023 22:37:01 +0800
+Subject: [PATCH 03/95] pinctrl: starfive: Add StarFive JH7110 sys controller
+ driver
+
+Add pinctrl driver for StarFive JH7110 SoC sys pinctrl controller.
+
+Co-developed-by: Emil Renner Berthing <kernel@esmil.dk>
+Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
+Signed-off-by: Jianlong Huang <jianlong.huang@starfivetech.com>
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ MAINTAINERS | 2 +-
+ drivers/pinctrl/starfive/Kconfig | 21 +
+ drivers/pinctrl/starfive/Makefile | 3 +
+ .../starfive/pinctrl-starfive-jh7110-sys.c | 449 ++++++++
+ .../starfive/pinctrl-starfive-jh7110.c | 982 ++++++++++++++++++
+ .../starfive/pinctrl-starfive-jh7110.h | 70 ++
+ 6 files changed, 1526 insertions(+), 1 deletion(-)
+ create mode 100644 drivers/pinctrl/starfive/pinctrl-starfive-jh7110-sys.c
+ create mode 100644 drivers/pinctrl/starfive/pinctrl-starfive-jh7110.c
+ create mode 100644 drivers/pinctrl/starfive/pinctrl-starfive-jh7110.h
+
+diff --git a/MAINTAINERS b/MAINTAINERS
+index 00989e5a66b3..99d8fe3a58f4 100644
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -19647,7 +19647,7 @@ M: Jianlong Huang <jianlong.huang@starfivetech.com>
+ L: linux-gpio@vger.kernel.org
+ S: Maintained
+ F: Documentation/devicetree/bindings/pinctrl/starfive,jh71*.yaml
+-F: drivers/pinctrl/starfive/
++F: drivers/pinctrl/starfive/pinctrl-starfive-jh71*
+ F: include/dt-bindings/pinctrl/pinctrl-starfive-jh7100.h
+ F: include/dt-bindings/pinctrl/starfive,jh7110-pinctrl.h
+
+diff --git a/drivers/pinctrl/starfive/Kconfig b/drivers/pinctrl/starfive/Kconfig
+index 55c514e622f9..453c8a0b3118 100644
+--- a/drivers/pinctrl/starfive/Kconfig
++++ b/drivers/pinctrl/starfive/Kconfig
+@@ -16,3 +16,24 @@ config PINCTRL_STARFIVE_JH7100
+ This also provides an interface to the GPIO pins not used by other
+ peripherals supporting inputs, outputs, configuring pull-up/pull-down
+ and interrupts on input changes.
++
++config PINCTRL_STARFIVE_JH7110
++ bool
++ select GENERIC_PINCTRL_GROUPS
++ select GENERIC_PINMUX_FUNCTIONS
++ select GENERIC_PINCONF
++ select GPIOLIB
++ select GPIOLIB_IRQCHIP
++ select OF_GPIO
++
++config PINCTRL_STARFIVE_JH7110_SYS
++ tristate "System pinctrl and GPIO driver for the StarFive JH7110 SoC"
++ depends on SOC_STARFIVE || COMPILE_TEST
++ depends on OF
++ select PINCTRL_STARFIVE_JH7110
++ default SOC_STARFIVE
++ help
++ Say yes here to support system pin control on the StarFive JH7110 SoC.
++ This also provides an interface to the GPIO pins not used by other
++ peripherals supporting inputs, outputs, configuring pull-up/pull-down
++ and interrupts on input changes.
+diff --git a/drivers/pinctrl/starfive/Makefile b/drivers/pinctrl/starfive/Makefile
+index 0293f26a0a99..dc2d1e392314 100644
+--- a/drivers/pinctrl/starfive/Makefile
++++ b/drivers/pinctrl/starfive/Makefile
+@@ -1,3 +1,6 @@
+ # SPDX-License-Identifier: GPL-2.0
+
+ obj-$(CONFIG_PINCTRL_STARFIVE_JH7100) += pinctrl-starfive-jh7100.o
++
++obj-$(CONFIG_PINCTRL_STARFIVE_JH7110) += pinctrl-starfive-jh7110.o
++obj-$(CONFIG_PINCTRL_STARFIVE_JH7110_SYS) += pinctrl-starfive-jh7110-sys.o
+diff --git a/drivers/pinctrl/starfive/pinctrl-starfive-jh7110-sys.c b/drivers/pinctrl/starfive/pinctrl-starfive-jh7110-sys.c
+new file mode 100644
+index 000000000000..bc279a39613f
+--- /dev/null
++++ b/drivers/pinctrl/starfive/pinctrl-starfive-jh7110-sys.c
+@@ -0,0 +1,449 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Pinctrl / GPIO driver for StarFive JH7110 SoC sys controller
++ *
++ * Copyright (C) 2022 Emil Renner Berthing <kernel@esmil.dk>
++ * Copyright (C) 2022 StarFive Technology Co., Ltd.
++ */
++
++#include <linux/bits.h>
++#include <linux/clk.h>
++#include <linux/gpio/driver.h>
++#include <linux/io.h>
++#include <linux/mod_devicetable.h>
++#include <linux/module.h>
++#include <linux/mutex.h>
++#include <linux/of.h>
++#include <linux/of_device.h>
++#include <linux/platform_device.h>
++#include <linux/reset.h>
++#include <linux/spinlock.h>
++
++#include <linux/pinctrl/pinctrl.h>
++#include <linux/pinctrl/pinmux.h>
++
++#include <dt-bindings/pinctrl/starfive,jh7110-pinctrl.h>
++
++#include "../core.h"
++#include "../pinctrl-utils.h"
++#include "../pinmux.h"
++#include "../pinconf.h"
++#include "pinctrl-starfive-jh7110.h"
++
++#define JH7110_SYS_NGPIO 64
++#define JH7110_SYS_GC_BASE 0
++
++/* registers */
++#define JH7110_SYS_DOEN 0x000
++#define JH7110_SYS_DOUT 0x040
++#define JH7110_SYS_GPI 0x080
++#define JH7110_SYS_GPIOIN 0x118
++
++#define JH7110_SYS_GPIOEN 0x0dc
++#define JH7110_SYS_GPIOIS0 0x0e0
++#define JH7110_SYS_GPIOIS1 0x0e4
++#define JH7110_SYS_GPIOIC0 0x0e8
++#define JH7110_SYS_GPIOIC1 0x0ec
++#define JH7110_SYS_GPIOIBE0 0x0f0
++#define JH7110_SYS_GPIOIBE1 0x0f4
++#define JH7110_SYS_GPIOIEV0 0x0f8
++#define JH7110_SYS_GPIOIEV1 0x0fc
++#define JH7110_SYS_GPIOIE0 0x100
++#define JH7110_SYS_GPIOIE1 0x104
++#define JH7110_SYS_GPIORIS0 0x108
++#define JH7110_SYS_GPIORIS1 0x10c
++#define JH7110_SYS_GPIOMIS0 0x110
++#define JH7110_SYS_GPIOMIS1 0x114
++
++#define JH7110_SYS_GPO_PDA_0_74_CFG 0x120
++#define JH7110_SYS_GPO_PDA_89_94_CFG 0x284
++
++static const struct pinctrl_pin_desc jh7110_sys_pins[] = {
++ PINCTRL_PIN(PAD_GPIO0, "GPIO0"),
++ PINCTRL_PIN(PAD_GPIO1, "GPIO1"),
++ PINCTRL_PIN(PAD_GPIO2, "GPIO2"),
++ PINCTRL_PIN(PAD_GPIO3, "GPIO3"),
++ PINCTRL_PIN(PAD_GPIO4, "GPIO4"),
++ PINCTRL_PIN(PAD_GPIO5, "GPIO5"),
++ PINCTRL_PIN(PAD_GPIO6, "GPIO6"),
++ PINCTRL_PIN(PAD_GPIO7, "GPIO7"),
++ PINCTRL_PIN(PAD_GPIO8, "GPIO8"),
++ PINCTRL_PIN(PAD_GPIO9, "GPIO9"),
++ PINCTRL_PIN(PAD_GPIO10, "GPIO10"),
++ PINCTRL_PIN(PAD_GPIO11, "GPIO11"),
++ PINCTRL_PIN(PAD_GPIO12, "GPIO12"),
++ PINCTRL_PIN(PAD_GPIO13, "GPIO13"),
++ PINCTRL_PIN(PAD_GPIO14, "GPIO14"),
++ PINCTRL_PIN(PAD_GPIO15, "GPIO15"),
++ PINCTRL_PIN(PAD_GPIO16, "GPIO16"),
++ PINCTRL_PIN(PAD_GPIO17, "GPIO17"),
++ PINCTRL_PIN(PAD_GPIO18, "GPIO18"),
++ PINCTRL_PIN(PAD_GPIO19, "GPIO19"),
++ PINCTRL_PIN(PAD_GPIO20, "GPIO20"),
++ PINCTRL_PIN(PAD_GPIO21, "GPIO21"),
++ PINCTRL_PIN(PAD_GPIO22, "GPIO22"),
++ PINCTRL_PIN(PAD_GPIO23, "GPIO23"),
++ PINCTRL_PIN(PAD_GPIO24, "GPIO24"),
++ PINCTRL_PIN(PAD_GPIO25, "GPIO25"),
++ PINCTRL_PIN(PAD_GPIO26, "GPIO26"),
++ PINCTRL_PIN(PAD_GPIO27, "GPIO27"),
++ PINCTRL_PIN(PAD_GPIO28, "GPIO28"),
++ PINCTRL_PIN(PAD_GPIO29, "GPIO29"),
++ PINCTRL_PIN(PAD_GPIO30, "GPIO30"),
++ PINCTRL_PIN(PAD_GPIO31, "GPIO31"),
++ PINCTRL_PIN(PAD_GPIO32, "GPIO32"),
++ PINCTRL_PIN(PAD_GPIO33, "GPIO33"),
++ PINCTRL_PIN(PAD_GPIO34, "GPIO34"),
++ PINCTRL_PIN(PAD_GPIO35, "GPIO35"),
++ PINCTRL_PIN(PAD_GPIO36, "GPIO36"),
++ PINCTRL_PIN(PAD_GPIO37, "GPIO37"),
++ PINCTRL_PIN(PAD_GPIO38, "GPIO38"),
++ PINCTRL_PIN(PAD_GPIO39, "GPIO39"),
++ PINCTRL_PIN(PAD_GPIO40, "GPIO40"),
++ PINCTRL_PIN(PAD_GPIO41, "GPIO41"),
++ PINCTRL_PIN(PAD_GPIO42, "GPIO42"),
++ PINCTRL_PIN(PAD_GPIO43, "GPIO43"),
++ PINCTRL_PIN(PAD_GPIO44, "GPIO44"),
++ PINCTRL_PIN(PAD_GPIO45, "GPIO45"),
++ PINCTRL_PIN(PAD_GPIO46, "GPIO46"),
++ PINCTRL_PIN(PAD_GPIO47, "GPIO47"),
++ PINCTRL_PIN(PAD_GPIO48, "GPIO48"),
++ PINCTRL_PIN(PAD_GPIO49, "GPIO49"),
++ PINCTRL_PIN(PAD_GPIO50, "GPIO50"),
++ PINCTRL_PIN(PAD_GPIO51, "GPIO51"),
++ PINCTRL_PIN(PAD_GPIO52, "GPIO52"),
++ PINCTRL_PIN(PAD_GPIO53, "GPIO53"),
++ PINCTRL_PIN(PAD_GPIO54, "GPIO54"),
++ PINCTRL_PIN(PAD_GPIO55, "GPIO55"),
++ PINCTRL_PIN(PAD_GPIO56, "GPIO56"),
++ PINCTRL_PIN(PAD_GPIO57, "GPIO57"),
++ PINCTRL_PIN(PAD_GPIO58, "GPIO58"),
++ PINCTRL_PIN(PAD_GPIO59, "GPIO59"),
++ PINCTRL_PIN(PAD_GPIO60, "GPIO60"),
++ PINCTRL_PIN(PAD_GPIO61, "GPIO61"),
++ PINCTRL_PIN(PAD_GPIO62, "GPIO62"),
++ PINCTRL_PIN(PAD_GPIO63, "GPIO63"),
++ PINCTRL_PIN(PAD_SD0_CLK, "SD0_CLK"),
++ PINCTRL_PIN(PAD_SD0_CMD, "SD0_CMD"),
++ PINCTRL_PIN(PAD_SD0_DATA0, "SD0_DATA0"),
++ PINCTRL_PIN(PAD_SD0_DATA1, "SD0_DATA1"),
++ PINCTRL_PIN(PAD_SD0_DATA2, "SD0_DATA2"),
++ PINCTRL_PIN(PAD_SD0_DATA3, "SD0_DATA3"),
++ PINCTRL_PIN(PAD_SD0_DATA4, "SD0_DATA4"),
++ PINCTRL_PIN(PAD_SD0_DATA5, "SD0_DATA5"),
++ PINCTRL_PIN(PAD_SD0_DATA6, "SD0_DATA6"),
++ PINCTRL_PIN(PAD_SD0_DATA7, "SD0_DATA7"),
++ PINCTRL_PIN(PAD_SD0_STRB, "SD0_STRB"),
++ PINCTRL_PIN(PAD_GMAC1_MDC, "GMAC1_MDC"),
++ PINCTRL_PIN(PAD_GMAC1_MDIO, "GMAC1_MDIO"),
++ PINCTRL_PIN(PAD_GMAC1_RXD0, "GMAC1_RXD0"),
++ PINCTRL_PIN(PAD_GMAC1_RXD1, "GMAC1_RXD1"),
++ PINCTRL_PIN(PAD_GMAC1_RXD2, "GMAC1_RXD2"),
++ PINCTRL_PIN(PAD_GMAC1_RXD3, "GMAC1_RXD3"),
++ PINCTRL_PIN(PAD_GMAC1_RXDV, "GMAC1_RXDV"),
++ PINCTRL_PIN(PAD_GMAC1_RXC, "GMAC1_RXC"),
++ PINCTRL_PIN(PAD_GMAC1_TXD0, "GMAC1_TXD0"),
++ PINCTRL_PIN(PAD_GMAC1_TXD1, "GMAC1_TXD1"),
++ PINCTRL_PIN(PAD_GMAC1_TXD2, "GMAC1_TXD2"),
++ PINCTRL_PIN(PAD_GMAC1_TXD3, "GMAC1_TXD3"),
++ PINCTRL_PIN(PAD_GMAC1_TXEN, "GMAC1_TXEN"),
++ PINCTRL_PIN(PAD_GMAC1_TXC, "GMAC1_TXC"),
++ PINCTRL_PIN(PAD_QSPI_SCLK, "QSPI_SCLK"),
++ PINCTRL_PIN(PAD_QSPI_CS0, "QSPI_CS0"),
++ PINCTRL_PIN(PAD_QSPI_DATA0, "QSPI_DATA0"),
++ PINCTRL_PIN(PAD_QSPI_DATA1, "QSPI_DATA1"),
++ PINCTRL_PIN(PAD_QSPI_DATA2, "QSPI_DATA2"),
++ PINCTRL_PIN(PAD_QSPI_DATA3, "QSPI_DATA3"),
++};
++
++struct jh7110_func_sel {
++ u16 offset;
++ u8 shift;
++ u8 max;
++};
++
++static const struct jh7110_func_sel
++ jh7110_sys_func_sel[ARRAY_SIZE(jh7110_sys_pins)] = {
++ [PAD_GMAC1_RXC] = { 0x29c, 0, 1 },
++ [PAD_GPIO10] = { 0x29c, 2, 3 },
++ [PAD_GPIO11] = { 0x29c, 5, 3 },
++ [PAD_GPIO12] = { 0x29c, 8, 3 },
++ [PAD_GPIO13] = { 0x29c, 11, 3 },
++ [PAD_GPIO14] = { 0x29c, 14, 3 },
++ [PAD_GPIO15] = { 0x29c, 17, 3 },
++ [PAD_GPIO16] = { 0x29c, 20, 3 },
++ [PAD_GPIO17] = { 0x29c, 23, 3 },
++ [PAD_GPIO18] = { 0x29c, 26, 3 },
++ [PAD_GPIO19] = { 0x29c, 29, 3 },
++
++ [PAD_GPIO20] = { 0x2a0, 0, 3 },
++ [PAD_GPIO21] = { 0x2a0, 3, 3 },
++ [PAD_GPIO22] = { 0x2a0, 6, 3 },
++ [PAD_GPIO23] = { 0x2a0, 9, 3 },
++ [PAD_GPIO24] = { 0x2a0, 12, 3 },
++ [PAD_GPIO25] = { 0x2a0, 15, 3 },
++ [PAD_GPIO26] = { 0x2a0, 18, 3 },
++ [PAD_GPIO27] = { 0x2a0, 21, 3 },
++ [PAD_GPIO28] = { 0x2a0, 24, 3 },
++ [PAD_GPIO29] = { 0x2a0, 27, 3 },
++
++ [PAD_GPIO30] = { 0x2a4, 0, 3 },
++ [PAD_GPIO31] = { 0x2a4, 3, 3 },
++ [PAD_GPIO32] = { 0x2a4, 6, 3 },
++ [PAD_GPIO33] = { 0x2a4, 9, 3 },
++ [PAD_GPIO34] = { 0x2a4, 12, 3 },
++ [PAD_GPIO35] = { 0x2a4, 15, 3 },
++ [PAD_GPIO36] = { 0x2a4, 17, 3 },
++ [PAD_GPIO37] = { 0x2a4, 20, 3 },
++ [PAD_GPIO38] = { 0x2a4, 23, 3 },
++ [PAD_GPIO39] = { 0x2a4, 26, 3 },
++ [PAD_GPIO40] = { 0x2a4, 29, 3 },
++
++ [PAD_GPIO41] = { 0x2a8, 0, 3 },
++ [PAD_GPIO42] = { 0x2a8, 3, 3 },
++ [PAD_GPIO43] = { 0x2a8, 6, 3 },
++ [PAD_GPIO44] = { 0x2a8, 9, 3 },
++ [PAD_GPIO45] = { 0x2a8, 12, 3 },
++ [PAD_GPIO46] = { 0x2a8, 15, 3 },
++ [PAD_GPIO47] = { 0x2a8, 18, 3 },
++ [PAD_GPIO48] = { 0x2a8, 21, 3 },
++ [PAD_GPIO49] = { 0x2a8, 24, 3 },
++ [PAD_GPIO50] = { 0x2a8, 27, 3 },
++ [PAD_GPIO51] = { 0x2a8, 30, 3 },
++
++ [PAD_GPIO52] = { 0x2ac, 0, 3 },
++ [PAD_GPIO53] = { 0x2ac, 2, 3 },
++ [PAD_GPIO54] = { 0x2ac, 4, 3 },
++ [PAD_GPIO55] = { 0x2ac, 6, 3 },
++ [PAD_GPIO56] = { 0x2ac, 9, 3 },
++ [PAD_GPIO57] = { 0x2ac, 12, 3 },
++ [PAD_GPIO58] = { 0x2ac, 15, 3 },
++ [PAD_GPIO59] = { 0x2ac, 18, 3 },
++ [PAD_GPIO60] = { 0x2ac, 21, 3 },
++ [PAD_GPIO61] = { 0x2ac, 24, 3 },
++ [PAD_GPIO62] = { 0x2ac, 27, 3 },
++ [PAD_GPIO63] = { 0x2ac, 30, 3 },
++
++ [PAD_GPIO6] = { 0x2b0, 0, 3 },
++ [PAD_GPIO7] = { 0x2b0, 2, 3 },
++ [PAD_GPIO8] = { 0x2b0, 5, 3 },
++ [PAD_GPIO9] = { 0x2b0, 8, 3 },
++};
++
++struct jh7110_vin_group_sel {
++ u16 offset;
++ u8 shift;
++ u8 group;
++};
++
++static const struct jh7110_vin_group_sel
++ jh7110_sys_vin_group_sel[ARRAY_SIZE(jh7110_sys_pins)] = {
++ [PAD_GPIO6] = { 0x2b4, 21, 0 },
++ [PAD_GPIO7] = { 0x2b4, 18, 0 },
++ [PAD_GPIO8] = { 0x2b4, 15, 0 },
++ [PAD_GPIO9] = { 0x2b0, 11, 0 },
++ [PAD_GPIO10] = { 0x2b0, 20, 0 },
++ [PAD_GPIO11] = { 0x2b0, 23, 0 },
++ [PAD_GPIO12] = { 0x2b0, 26, 0 },
++ [PAD_GPIO13] = { 0x2b0, 29, 0 },
++ [PAD_GPIO14] = { 0x2b4, 0, 0 },
++ [PAD_GPIO15] = { 0x2b4, 3, 0 },
++ [PAD_GPIO16] = { 0x2b4, 6, 0 },
++ [PAD_GPIO17] = { 0x2b4, 9, 0 },
++ [PAD_GPIO18] = { 0x2b4, 12, 0 },
++ [PAD_GPIO19] = { 0x2b0, 14, 0 },
++ [PAD_GPIO20] = { 0x2b0, 17, 0 },
++
++ [PAD_GPIO21] = { 0x2b4, 21, 1 },
++ [PAD_GPIO22] = { 0x2b4, 18, 1 },
++ [PAD_GPIO23] = { 0x2b4, 15, 1 },
++ [PAD_GPIO24] = { 0x2b0, 11, 1 },
++ [PAD_GPIO25] = { 0x2b0, 20, 1 },
++ [PAD_GPIO26] = { 0x2b0, 23, 1 },
++ [PAD_GPIO27] = { 0x2b0, 26, 1 },
++ [PAD_GPIO28] = { 0x2b0, 29, 1 },
++ [PAD_GPIO29] = { 0x2b4, 0, 1 },
++ [PAD_GPIO30] = { 0x2b4, 3, 1 },
++ [PAD_GPIO31] = { 0x2b4, 6, 1 },
++ [PAD_GPIO32] = { 0x2b4, 9, 1 },
++ [PAD_GPIO33] = { 0x2b4, 12, 1 },
++ [PAD_GPIO34] = { 0x2b0, 14, 1 },
++ [PAD_GPIO35] = { 0x2b0, 17, 1 },
++
++ [PAD_GPIO36] = { 0x2b4, 21, 2 },
++ [PAD_GPIO37] = { 0x2b4, 18, 2 },
++ [PAD_GPIO38] = { 0x2b4, 15, 2 },
++ [PAD_GPIO39] = { 0x2b0, 11, 2 },
++ [PAD_GPIO40] = { 0x2b0, 20, 2 },
++ [PAD_GPIO41] = { 0x2b0, 23, 2 },
++ [PAD_GPIO42] = { 0x2b0, 26, 2 },
++ [PAD_GPIO43] = { 0x2b0, 29, 2 },
++ [PAD_GPIO44] = { 0x2b4, 0, 2 },
++ [PAD_GPIO45] = { 0x2b4, 3, 2 },
++ [PAD_GPIO46] = { 0x2b4, 6, 2 },
++ [PAD_GPIO47] = { 0x2b4, 9, 2 },
++ [PAD_GPIO48] = { 0x2b4, 12, 2 },
++ [PAD_GPIO49] = { 0x2b0, 14, 2 },
++ [PAD_GPIO50] = { 0x2b0, 17, 2 },
++};
++
++static void jh7110_set_function(struct jh7110_pinctrl *sfp,
++ unsigned int pin, u32 func)
++{
++ const struct jh7110_func_sel *fs = &jh7110_sys_func_sel[pin];
++ unsigned long flags;
++ void __iomem *reg;
++ u32 mask;
++
++ if (!fs->offset)
++ return;
++
++ if (func > fs->max)
++ return;
++
++ reg = sfp->base + fs->offset;
++ func = func << fs->shift;
++ mask = 0x3U << fs->shift;
++
++ raw_spin_lock_irqsave(&sfp->lock, flags);
++ func |= readl_relaxed(reg) & ~mask;
++ writel_relaxed(func, reg);
++ raw_spin_unlock_irqrestore(&sfp->lock, flags);
++}
++
++static void jh7110_set_vin_group(struct jh7110_pinctrl *sfp,
++ unsigned int pin)
++{
++ const struct jh7110_vin_group_sel *gs = &jh7110_sys_vin_group_sel[pin];
++ unsigned long flags;
++ void __iomem *reg;
++ u32 mask;
++ u32 grp;
++
++ if (!gs->offset)
++ return;
++
++ reg = sfp->base + gs->offset;
++ grp = gs->group << gs->shift;
++ mask = 0x3U << gs->shift;
++
++ raw_spin_lock_irqsave(&sfp->lock, flags);
++ grp |= readl_relaxed(reg) & ~mask;
++ writel_relaxed(grp, reg);
++ raw_spin_unlock_irqrestore(&sfp->lock, flags);
++}
++
++static int jh7110_sys_set_one_pin_mux(struct jh7110_pinctrl *sfp,
++ unsigned int pin,
++ unsigned int din, u32 dout,
++ u32 doen, u32 func)
++{
++ if (pin < sfp->gc.ngpio && func == 0)
++ jh7110_set_gpiomux(sfp, pin, din, dout, doen);
++
++ jh7110_set_function(sfp, pin, func);
++
++ if (pin < sfp->gc.ngpio && func == 2)
++ jh7110_set_vin_group(sfp, pin);
++
++ return 0;
++}
++
++static int jh7110_sys_get_padcfg_base(struct jh7110_pinctrl *sfp,
++ unsigned int pin)
++{
++ if (pin < PAD_GMAC1_MDC)
++ return JH7110_SYS_GPO_PDA_0_74_CFG;
++ else if (pin > PAD_GMAC1_TXC && pin <= PAD_QSPI_DATA3)
++ return JH7110_SYS_GPO_PDA_89_94_CFG;
++ else
++ return -1;
++}
++
++static void jh7110_sys_irq_handler(struct irq_desc *desc)
++{
++ struct jh7110_pinctrl *sfp = jh7110_from_irq_desc(desc);
++ struct irq_chip *chip = irq_desc_get_chip(desc);
++ unsigned long mis;
++ unsigned int pin;
++
++ chained_irq_enter(chip, desc);
++
++ mis = readl_relaxed(sfp->base + JH7110_SYS_GPIOMIS0);
++ for_each_set_bit(pin, &mis, 32)
++ generic_handle_domain_irq(sfp->gc.irq.domain, pin);
++
++ mis = readl_relaxed(sfp->base + JH7110_SYS_GPIOMIS1);
++ for_each_set_bit(pin, &mis, 32)
++ generic_handle_domain_irq(sfp->gc.irq.domain, pin + 32);
++
++ chained_irq_exit(chip, desc);
++}
++
++static int jh7110_sys_init_hw(struct gpio_chip *gc)
++{
++ struct jh7110_pinctrl *sfp = container_of(gc,
++ struct jh7110_pinctrl, gc);
++
++ /* mask all GPIO interrupts */
++ writel(0U, sfp->base + JH7110_SYS_GPIOIE0);
++ writel(0U, sfp->base + JH7110_SYS_GPIOIE1);
++ /* clear edge interrupt flags */
++ writel(~0U, sfp->base + JH7110_SYS_GPIOIC0);
++ writel(~0U, sfp->base + JH7110_SYS_GPIOIC1);
++ /* enable GPIO interrupts */
++ writel(1U, sfp->base + JH7110_SYS_GPIOEN);
++ return 0;
++}
++
++static const struct jh7110_gpio_irq_reg jh7110_sys_irq_reg = {
++ .is_reg_base = JH7110_SYS_GPIOIS0,
++ .ic_reg_base = JH7110_SYS_GPIOIC0,
++ .ibe_reg_base = JH7110_SYS_GPIOIBE0,
++ .iev_reg_base = JH7110_SYS_GPIOIEV0,
++ .ie_reg_base = JH7110_SYS_GPIOIE0,
++ .ris_reg_base = JH7110_SYS_GPIORIS0,
++ .mis_reg_base = JH7110_SYS_GPIOMIS0,
++};
++
++static const struct jh7110_pinctrl_soc_info jh7110_sys_pinctrl_info = {
++ .pins = jh7110_sys_pins,
++ .npins = ARRAY_SIZE(jh7110_sys_pins),
++ .ngpios = JH7110_SYS_NGPIO,
++ .gc_base = JH7110_SYS_GC_BASE,
++ .dout_reg_base = JH7110_SYS_DOUT,
++ .dout_mask = GENMASK(6, 0),
++ .doen_reg_base = JH7110_SYS_DOEN,
++ .doen_mask = GENMASK(5, 0),
++ .gpi_reg_base = JH7110_SYS_GPI,
++ .gpi_mask = GENMASK(6, 0),
++ .gpioin_reg_base = JH7110_SYS_GPIOIN,
++ .irq_reg = &jh7110_sys_irq_reg,
++ .jh7110_set_one_pin_mux = jh7110_sys_set_one_pin_mux,
++ .jh7110_get_padcfg_base = jh7110_sys_get_padcfg_base,
++ .jh7110_gpio_irq_handler = jh7110_sys_irq_handler,
++ .jh7110_gpio_init_hw = jh7110_sys_init_hw,
++};
++
++static const struct of_device_id jh7110_sys_pinctrl_of_match[] = {
++ {
++ .compatible = "starfive,jh7110-sys-pinctrl",
++ .data = &jh7110_sys_pinctrl_info,
++ },
++ { /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(of, jh7110_sys_pinctrl_of_match);
++
++static struct platform_driver jh7110_sys_pinctrl_driver = {
++ .probe = jh7110_pinctrl_probe,
++ .driver = {
++ .name = "starfive-jh7110-sys-pinctrl",
++ .of_match_table = jh7110_sys_pinctrl_of_match,
++ },
++};
++module_platform_driver(jh7110_sys_pinctrl_driver);
++
++MODULE_DESCRIPTION("Pinctrl driver for the StarFive JH7110 SoC sys controller");
++MODULE_AUTHOR("Emil Renner Berthing <kernel@esmil.dk>");
++MODULE_AUTHOR("Jianlong Huang <jianlong.huang@starfivetech.com>");
++MODULE_LICENSE("GPL");
+diff --git a/drivers/pinctrl/starfive/pinctrl-starfive-jh7110.c b/drivers/pinctrl/starfive/pinctrl-starfive-jh7110.c
+new file mode 100644
+index 000000000000..5fe729b4a03d
+--- /dev/null
++++ b/drivers/pinctrl/starfive/pinctrl-starfive-jh7110.c
+@@ -0,0 +1,982 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Pinctrl / GPIO driver for StarFive JH7110 SoC
++ *
++ * Copyright (C) 2022 Emil Renner Berthing <kernel@esmil.dk>
++ * Copyright (C) 2022 StarFive Technology Co., Ltd.
++ */
++
++#include <linux/bits.h>
++#include <linux/clk.h>
++#include <linux/gpio/driver.h>
++#include <linux/io.h>
++#include <linux/mod_devicetable.h>
++#include <linux/module.h>
++#include <linux/mutex.h>
++#include <linux/of.h>
++#include <linux/of_device.h>
++#include <linux/platform_device.h>
++#include <linux/reset.h>
++#include <linux/seq_file.h>
++#include <linux/spinlock.h>
++
++#include <linux/pinctrl/consumer.h>
++#include <linux/pinctrl/pinconf.h>
++#include <linux/pinctrl/pinctrl.h>
++#include <linux/pinctrl/pinmux.h>
++
++#include <dt-bindings/pinctrl/starfive,jh7110-pinctrl.h>
++
++#include "../core.h"
++#include "../pinctrl-utils.h"
++#include "../pinmux.h"
++#include "../pinconf.h"
++#include "pinctrl-starfive-jh7110.h"
++
++/* pad control bits */
++#define JH7110_PADCFG_POS BIT(7)
++#define JH7110_PADCFG_SMT BIT(6)
++#define JH7110_PADCFG_SLEW BIT(5)
++#define JH7110_PADCFG_PD BIT(4)
++#define JH7110_PADCFG_PU BIT(3)
++#define JH7110_PADCFG_BIAS (JH7110_PADCFG_PD | JH7110_PADCFG_PU)
++#define JH7110_PADCFG_DS_MASK GENMASK(2, 1)
++#define JH7110_PADCFG_DS_2MA (0U << 1)
++#define JH7110_PADCFG_DS_4MA BIT(1)
++#define JH7110_PADCFG_DS_8MA (2U << 1)
++#define JH7110_PADCFG_DS_12MA (3U << 1)
++#define JH7110_PADCFG_IE BIT(0)
++
++/*
++ * The packed pinmux values from the device tree look like this:
++ *
++ * | 31 - 24 | 23 - 16 | 15 - 10 | 9 - 8 | 7 - 0 |
++ * | din | dout | doen | function | pin |
++ */
++static unsigned int jh7110_pinmux_din(u32 v)
++{
++ return (v & GENMASK(31, 24)) >> 24;
++}
++
++static u32 jh7110_pinmux_dout(u32 v)
++{
++ return (v & GENMASK(23, 16)) >> 16;
++}
++
++static u32 jh7110_pinmux_doen(u32 v)
++{
++ return (v & GENMASK(15, 10)) >> 10;
++}
++
++static u32 jh7110_pinmux_function(u32 v)
++{
++ return (v & GENMASK(9, 8)) >> 8;
++}
++
++static unsigned int jh7110_pinmux_pin(u32 v)
++{
++ return v & GENMASK(7, 0);
++}
++
++static struct jh7110_pinctrl *jh7110_from_irq_data(struct irq_data *d)
++{
++ struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
++
++ return container_of(gc, struct jh7110_pinctrl, gc);
++}
++
++struct jh7110_pinctrl *jh7110_from_irq_desc(struct irq_desc *desc)
++{
++ struct gpio_chip *gc = irq_desc_get_handler_data(desc);
++
++ return container_of(gc, struct jh7110_pinctrl, gc);
++}
++EXPORT_SYMBOL_GPL(jh7110_from_irq_desc);
++
++#ifdef CONFIG_DEBUG_FS
++static void jh7110_pin_dbg_show(struct pinctrl_dev *pctldev,
++ struct seq_file *s, unsigned int pin)
++{
++ struct jh7110_pinctrl *sfp = pinctrl_dev_get_drvdata(pctldev);
++ const struct jh7110_pinctrl_soc_info *info = sfp->info;
++
++ seq_printf(s, "%s", dev_name(pctldev->dev));
++
++ if (pin < sfp->gc.ngpio) {
++ unsigned int offset = 4 * (pin / 4);
++ unsigned int shift = 8 * (pin % 4);
++ u32 dout = readl_relaxed(sfp->base + info->dout_reg_base + offset);
++ u32 doen = readl_relaxed(sfp->base + info->doen_reg_base + offset);
++ u32 gpi = readl_relaxed(sfp->base + info->gpi_reg_base + offset);
++
++ dout = (dout >> shift) & info->dout_mask;
++ doen = (doen >> shift) & info->doen_mask;
++ gpi = ((gpi >> shift) - 2) & info->gpi_mask;
++
++ seq_printf(s, " dout=%u doen=%u din=%u", dout, doen, gpi);
++ }
++}
++#else
++#define jh7110_pin_dbg_show NULL
++#endif
++
++static int jh7110_dt_node_to_map(struct pinctrl_dev *pctldev,
++ struct device_node *np,
++ struct pinctrl_map **maps,
++ unsigned int *num_maps)
++{
++ struct jh7110_pinctrl *sfp = pinctrl_dev_get_drvdata(pctldev);
++ struct device *dev = sfp->gc.parent;
++ struct device_node *child;
++ struct pinctrl_map *map;
++ const char **pgnames;
++ const char *grpname;
++ int ngroups;
++ int nmaps;
++ int ret;
++
++ ngroups = 0;
++ for_each_child_of_node(np, child)
++ ngroups += 1;
++ nmaps = 2 * ngroups;
++
++ pgnames = devm_kcalloc(dev, ngroups, sizeof(*pgnames), GFP_KERNEL);
++ if (!pgnames)
++ return -ENOMEM;
++
++ map = kcalloc(nmaps, sizeof(*map), GFP_KERNEL);
++ if (!map)
++ return -ENOMEM;
++
++ nmaps = 0;
++ ngroups = 0;
++ mutex_lock(&sfp->mutex);
++ for_each_child_of_node(np, child) {
++ int npins = of_property_count_u32_elems(child, "pinmux");
++ int *pins;
++ u32 *pinmux;
++ int i;
++
++ if (npins < 1) {
++ dev_err(dev,
++ "invalid pinctrl group %pOFn.%pOFn: pinmux not set\n",
++ np, child);
++ ret = -EINVAL;
++ goto put_child;
++ }
++
++ grpname = devm_kasprintf(dev, GFP_KERNEL, "%pOFn.%pOFn", np, child);
++ if (!grpname) {
++ ret = -ENOMEM;
++ goto put_child;
++ }
++
++ pgnames[ngroups++] = grpname;
++
++ pins = devm_kcalloc(dev, npins, sizeof(*pins), GFP_KERNEL);
++ if (!pins) {
++ ret = -ENOMEM;
++ goto put_child;
++ }
++
++ pinmux = devm_kcalloc(dev, npins, sizeof(*pinmux), GFP_KERNEL);
++ if (!pinmux) {
++ ret = -ENOMEM;
++ goto put_child;
++ }
++
++ ret = of_property_read_u32_array(child, "pinmux", pinmux, npins);
++ if (ret)
++ goto put_child;
++
++ for (i = 0; i < npins; i++)
++ pins[i] = jh7110_pinmux_pin(pinmux[i]);
++
++ map[nmaps].type = PIN_MAP_TYPE_MUX_GROUP;
++ map[nmaps].data.mux.function = np->name;
++ map[nmaps].data.mux.group = grpname;
++ nmaps += 1;
++
++ ret = pinctrl_generic_add_group(pctldev, grpname,
++ pins, npins, pinmux);
++ if (ret < 0) {
++ dev_err(dev, "error adding group %s: %d\n", grpname, ret);
++ goto put_child;
++ }
++
++ ret = pinconf_generic_parse_dt_config(child, pctldev,
++ &map[nmaps].data.configs.configs,
++ &map[nmaps].data.configs.num_configs);
++ if (ret) {
++ dev_err(dev, "error parsing pin config of group %s: %d\n",
++ grpname, ret);
++ goto put_child;
++ }
++
++ /* don't create a map if there are no pinconf settings */
++ if (map[nmaps].data.configs.num_configs == 0)
++ continue;
++
++ map[nmaps].type = PIN_MAP_TYPE_CONFIGS_GROUP;
++ map[nmaps].data.configs.group_or_pin = grpname;
++ nmaps += 1;
++ }
++
++ ret = pinmux_generic_add_function(pctldev, np->name,
++ pgnames, ngroups, NULL);
++ if (ret < 0) {
++ dev_err(dev, "error adding function %s: %d\n", np->name, ret);
++ goto free_map;
++ }
++ mutex_unlock(&sfp->mutex);
++
++ *maps = map;
++ *num_maps = nmaps;
++ return 0;
++
++put_child:
++ of_node_put(child);
++free_map:
++ pinctrl_utils_free_map(pctldev, map, nmaps);
++ mutex_unlock(&sfp->mutex);
++ return ret;
++}
++
++static const struct pinctrl_ops jh7110_pinctrl_ops = {
++ .get_groups_count = pinctrl_generic_get_group_count,
++ .get_group_name = pinctrl_generic_get_group_name,
++ .get_group_pins = pinctrl_generic_get_group_pins,
++ .pin_dbg_show = jh7110_pin_dbg_show,
++ .dt_node_to_map = jh7110_dt_node_to_map,
++ .dt_free_map = pinctrl_utils_free_map,
++};
++
++void jh7110_set_gpiomux(struct jh7110_pinctrl *sfp, unsigned int pin,
++ unsigned int din, u32 dout, u32 doen)
++{
++ const struct jh7110_pinctrl_soc_info *info = sfp->info;
++
++ unsigned int offset = 4 * (pin / 4);
++ unsigned int shift = 8 * (pin % 4);
++ u32 dout_mask = info->dout_mask << shift;
++ u32 done_mask = info->doen_mask << shift;
++ u32 ival, imask;
++ void __iomem *reg_dout;
++ void __iomem *reg_doen;
++ void __iomem *reg_din;
++ unsigned long flags;
++
++ reg_dout = sfp->base + info->dout_reg_base + offset;
++ reg_doen = sfp->base + info->doen_reg_base + offset;
++ dout <<= shift;
++ doen <<= shift;
++ if (din != GPI_NONE) {
++ unsigned int ioffset = 4 * (din / 4);
++ unsigned int ishift = 8 * (din % 4);
++
++ reg_din = sfp->base + info->gpi_reg_base + ioffset;
++ ival = (pin + 2) << ishift;
++ imask = info->gpi_mask << ishift;
++ } else {
++ reg_din = NULL;
++ }
++
++ raw_spin_lock_irqsave(&sfp->lock, flags);
++ dout |= readl_relaxed(reg_dout) & ~dout_mask;
++ writel_relaxed(dout, reg_dout);
++ doen |= readl_relaxed(reg_doen) & ~done_mask;
++ writel_relaxed(doen, reg_doen);
++ if (reg_din) {
++ ival |= readl_relaxed(reg_din) & ~imask;
++ writel_relaxed(ival, reg_din);
++ }
++ raw_spin_unlock_irqrestore(&sfp->lock, flags);
++}
++EXPORT_SYMBOL_GPL(jh7110_set_gpiomux);
++
++static int jh7110_set_mux(struct pinctrl_dev *pctldev,
++ unsigned int fsel, unsigned int gsel)
++{
++ struct jh7110_pinctrl *sfp = pinctrl_dev_get_drvdata(pctldev);
++ const struct jh7110_pinctrl_soc_info *info = sfp->info;
++ const struct group_desc *group;
++ const u32 *pinmux;
++ unsigned int i;
++
++ group = pinctrl_generic_get_group(pctldev, gsel);
++ if (!group)
++ return -EINVAL;
++
++ pinmux = group->data;
++ for (i = 0; i < group->num_pins; i++) {
++ u32 v = pinmux[i];
++
++ if (info->jh7110_set_one_pin_mux)
++ info->jh7110_set_one_pin_mux(sfp,
++ jh7110_pinmux_pin(v),
++ jh7110_pinmux_din(v),
++ jh7110_pinmux_dout(v),
++ jh7110_pinmux_doen(v),
++ jh7110_pinmux_function(v));
++ }
++
++ return 0;
++}
++
++static const struct pinmux_ops jh7110_pinmux_ops = {
++ .get_functions_count = pinmux_generic_get_function_count,
++ .get_function_name = pinmux_generic_get_function_name,
++ .get_function_groups = pinmux_generic_get_function_groups,
++ .set_mux = jh7110_set_mux,
++ .strict = true,
++};
++
++static const u8 jh7110_drive_strength_mA[4] = { 2, 4, 8, 12 };
++
++static u32 jh7110_padcfg_ds_to_mA(u32 padcfg)
++{
++ return jh7110_drive_strength_mA[(padcfg >> 1) & 3U];
++}
++
++static u32 jh7110_padcfg_ds_from_mA(u32 v)
++{
++ int i;
++
++ for (i = 0; i < 3; i++) {
++ if (v <= jh7110_drive_strength_mA[i])
++ break;
++ }
++ return i << 1;
++}
++
++static void jh7110_padcfg_rmw(struct jh7110_pinctrl *sfp,
++ unsigned int pin, u32 mask, u32 value)
++{
++ const struct jh7110_pinctrl_soc_info *info = sfp->info;
++ void __iomem *reg;
++ unsigned long flags;
++ int padcfg_base;
++
++ if (!info->jh7110_get_padcfg_base)
++ return;
++
++ padcfg_base = info->jh7110_get_padcfg_base(sfp, pin);
++ if (padcfg_base < 0)
++ return;
++
++ reg = sfp->base + padcfg_base + 4 * pin;
++ value &= mask;
++
++ raw_spin_lock_irqsave(&sfp->lock, flags);
++ value |= readl_relaxed(reg) & ~mask;
++ writel_relaxed(value, reg);
++ raw_spin_unlock_irqrestore(&sfp->lock, flags);
++}
++
++static int jh7110_pinconf_get(struct pinctrl_dev *pctldev,
++ unsigned int pin, unsigned long *config)
++{
++ struct jh7110_pinctrl *sfp = pinctrl_dev_get_drvdata(pctldev);
++ const struct jh7110_pinctrl_soc_info *info = sfp->info;
++ int param = pinconf_to_config_param(*config);
++ u32 padcfg, arg;
++ bool enabled;
++ int padcfg_base;
++
++ if (!info->jh7110_get_padcfg_base)
++ return 0;
++
++ padcfg_base = info->jh7110_get_padcfg_base(sfp, pin);
++ if (padcfg_base < 0)
++ return 0;
++
++ padcfg = readl_relaxed(sfp->base + padcfg_base + 4 * pin);
++ switch (param) {
++ case PIN_CONFIG_BIAS_DISABLE:
++ enabled = !(padcfg & JH7110_PADCFG_BIAS);
++ arg = 0;
++ break;
++ case PIN_CONFIG_BIAS_PULL_DOWN:
++ enabled = padcfg & JH7110_PADCFG_PD;
++ arg = 1;
++ break;
++ case PIN_CONFIG_BIAS_PULL_UP:
++ enabled = padcfg & JH7110_PADCFG_PU;
++ arg = 1;
++ break;
++ case PIN_CONFIG_DRIVE_STRENGTH:
++ enabled = true;
++ arg = jh7110_padcfg_ds_to_mA(padcfg);
++ break;
++ case PIN_CONFIG_INPUT_ENABLE:
++ enabled = padcfg & JH7110_PADCFG_IE;
++ arg = enabled;
++ break;
++ case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
++ enabled = padcfg & JH7110_PADCFG_SMT;
++ arg = enabled;
++ break;
++ case PIN_CONFIG_SLEW_RATE:
++ enabled = true;
++ arg = !!(padcfg & JH7110_PADCFG_SLEW);
++ break;
++ default:
++ return -ENOTSUPP;
++ }
++
++ *config = pinconf_to_config_packed(param, arg);
++ return enabled ? 0 : -EINVAL;
++}
++
++static int jh7110_pinconf_group_get(struct pinctrl_dev *pctldev,
++ unsigned int gsel,
++ unsigned long *config)
++{
++ const struct group_desc *group;
++
++ group = pinctrl_generic_get_group(pctldev, gsel);
++ if (!group)
++ return -EINVAL;
++
++ return jh7110_pinconf_get(pctldev, group->pins[0], config);
++}
++
++static int jh7110_pinconf_group_set(struct pinctrl_dev *pctldev,
++ unsigned int gsel,
++ unsigned long *configs,
++ unsigned int num_configs)
++{
++ struct jh7110_pinctrl *sfp = pinctrl_dev_get_drvdata(pctldev);
++ const struct group_desc *group;
++ u16 mask, value;
++ int i;
++
++ group = pinctrl_generic_get_group(pctldev, gsel);
++ if (!group)
++ return -EINVAL;
++
++ mask = 0;
++ value = 0;
++ for (i = 0; i < num_configs; i++) {
++ int param = pinconf_to_config_param(configs[i]);
++ u32 arg = pinconf_to_config_argument(configs[i]);
++
++ switch (param) {
++ case PIN_CONFIG_BIAS_DISABLE:
++ mask |= JH7110_PADCFG_BIAS;
++ value &= ~JH7110_PADCFG_BIAS;
++ break;
++ case PIN_CONFIG_BIAS_PULL_DOWN:
++ if (arg == 0)
++ return -ENOTSUPP;
++ mask |= JH7110_PADCFG_BIAS;
++ value = (value & ~JH7110_PADCFG_BIAS) | JH7110_PADCFG_PD;
++ break;
++ case PIN_CONFIG_BIAS_PULL_UP:
++ if (arg == 0)
++ return -ENOTSUPP;
++ mask |= JH7110_PADCFG_BIAS;
++ value = (value & ~JH7110_PADCFG_BIAS) | JH7110_PADCFG_PU;
++ break;
++ case PIN_CONFIG_DRIVE_STRENGTH:
++ mask |= JH7110_PADCFG_DS_MASK;
++ value = (value & ~JH7110_PADCFG_DS_MASK) |
++ jh7110_padcfg_ds_from_mA(arg);
++ break;
++ case PIN_CONFIG_INPUT_ENABLE:
++ mask |= JH7110_PADCFG_IE;
++ if (arg)
++ value |= JH7110_PADCFG_IE;
++ else
++ value &= ~JH7110_PADCFG_IE;
++ break;
++ case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
++ mask |= JH7110_PADCFG_SMT;
++ if (arg)
++ value |= JH7110_PADCFG_SMT;
++ else
++ value &= ~JH7110_PADCFG_SMT;
++ break;
++ case PIN_CONFIG_SLEW_RATE:
++ mask |= JH7110_PADCFG_SLEW;
++ if (arg)
++ value |= JH7110_PADCFG_SLEW;
++ else
++ value &= ~JH7110_PADCFG_SLEW;
++ break;
++ default:
++ return -ENOTSUPP;
++ }
++ }
++
++ for (i = 0; i < group->num_pins; i++)
++ jh7110_padcfg_rmw(sfp, group->pins[i], mask, value);
++
++ return 0;
++}
++
++#ifdef CONFIG_DEBUG_FS
++static void jh7110_pinconf_dbg_show(struct pinctrl_dev *pctldev,
++ struct seq_file *s, unsigned int pin)
++{
++ struct jh7110_pinctrl *sfp = pinctrl_dev_get_drvdata(pctldev);
++ const struct jh7110_pinctrl_soc_info *info = sfp->info;
++ u32 value;
++ int padcfg_base;
++
++ if (!info->jh7110_get_padcfg_base)
++ return;
++
++ padcfg_base = info->jh7110_get_padcfg_base(sfp, pin);
++ if (padcfg_base < 0)
++ return;
++
++ value = readl_relaxed(sfp->base + padcfg_base + 4 * pin);
++ seq_printf(s, " (0x%02x)", value);
++}
++#else
++#define jh7110_pinconf_dbg_show NULL
++#endif
++
++static const struct pinconf_ops jh7110_pinconf_ops = {
++ .pin_config_get = jh7110_pinconf_get,
++ .pin_config_group_get = jh7110_pinconf_group_get,
++ .pin_config_group_set = jh7110_pinconf_group_set,
++ .pin_config_dbg_show = jh7110_pinconf_dbg_show,
++ .is_generic = true,
++};
++
++static int jh7110_gpio_request(struct gpio_chip *gc, unsigned int gpio)
++{
++ return pinctrl_gpio_request(gc->base + gpio);
++}
++
++static void jh7110_gpio_free(struct gpio_chip *gc, unsigned int gpio)
++{
++ pinctrl_gpio_free(gc->base + gpio);
++}
++
++static int jh7110_gpio_get_direction(struct gpio_chip *gc,
++ unsigned int gpio)
++{
++ struct jh7110_pinctrl *sfp = container_of(gc,
++ struct jh7110_pinctrl, gc);
++ const struct jh7110_pinctrl_soc_info *info = sfp->info;
++ unsigned int offset = 4 * (gpio / 4);
++ unsigned int shift = 8 * (gpio % 4);
++ u32 doen = readl_relaxed(sfp->base + info->doen_reg_base + offset);
++
++ doen = (doen >> shift) & info->doen_mask;
++
++ return doen == GPOEN_ENABLE ?
++ GPIO_LINE_DIRECTION_OUT : GPIO_LINE_DIRECTION_IN;
++}
++
++static int jh7110_gpio_direction_input(struct gpio_chip *gc,
++ unsigned int gpio)
++{
++ struct jh7110_pinctrl *sfp = container_of(gc,
++ struct jh7110_pinctrl, gc);
++ const struct jh7110_pinctrl_soc_info *info = sfp->info;
++
++ /* enable input and schmitt trigger */
++ jh7110_padcfg_rmw(sfp, gpio,
++ JH7110_PADCFG_IE | JH7110_PADCFG_SMT,
++ JH7110_PADCFG_IE | JH7110_PADCFG_SMT);
++
++ if (info->jh7110_set_one_pin_mux)
++ info->jh7110_set_one_pin_mux(sfp, gpio,
++ GPI_NONE, GPOUT_LOW, GPOEN_DISABLE, 0);
++
++ return 0;
++}
++
++static int jh7110_gpio_direction_output(struct gpio_chip *gc,
++ unsigned int gpio, int value)
++{
++ struct jh7110_pinctrl *sfp = container_of(gc,
++ struct jh7110_pinctrl, gc);
++ const struct jh7110_pinctrl_soc_info *info = sfp->info;
++
++ if (info->jh7110_set_one_pin_mux)
++ info->jh7110_set_one_pin_mux(sfp, gpio,
++ GPI_NONE, value ? GPOUT_HIGH : GPOUT_LOW,
++ GPOEN_ENABLE, 0);
++
++ /* disable input, schmitt trigger and bias */
++ jh7110_padcfg_rmw(sfp, gpio,
++ JH7110_PADCFG_IE | JH7110_PADCFG_SMT |
++ JH7110_PADCFG_BIAS, 0);
++ return 0;
++}
++
++static int jh7110_gpio_get(struct gpio_chip *gc, unsigned int gpio)
++{
++ struct jh7110_pinctrl *sfp = container_of(gc,
++ struct jh7110_pinctrl, gc);
++ const struct jh7110_pinctrl_soc_info *info = sfp->info;
++ void __iomem *reg = sfp->base + info->gpioin_reg_base
++ + 4 * (gpio / 32);
++
++ return !!(readl_relaxed(reg) & BIT(gpio % 32));
++}
++
++static void jh7110_gpio_set(struct gpio_chip *gc,
++ unsigned int gpio, int value)
++{
++ struct jh7110_pinctrl *sfp = container_of(gc,
++ struct jh7110_pinctrl, gc);
++ const struct jh7110_pinctrl_soc_info *info = sfp->info;
++ unsigned int offset = 4 * (gpio / 4);
++ unsigned int shift = 8 * (gpio % 4);
++ void __iomem *reg_dout = sfp->base + info->dout_reg_base + offset;
++ u32 dout = (value ? GPOUT_HIGH : GPOUT_LOW) << shift;
++ u32 mask = info->dout_mask << shift;
++ unsigned long flags;
++
++ raw_spin_lock_irqsave(&sfp->lock, flags);
++ dout |= readl_relaxed(reg_dout) & ~mask;
++ writel_relaxed(dout, reg_dout);
++ raw_spin_unlock_irqrestore(&sfp->lock, flags);
++}
++
++static int jh7110_gpio_set_config(struct gpio_chip *gc,
++ unsigned int gpio, unsigned long config)
++{
++ struct jh7110_pinctrl *sfp = container_of(gc,
++ struct jh7110_pinctrl, gc);
++ u32 arg = pinconf_to_config_argument(config);
++ u32 value;
++ u32 mask;
++
++ switch (pinconf_to_config_param(config)) {
++ case PIN_CONFIG_BIAS_DISABLE:
++ mask = JH7110_PADCFG_BIAS;
++ value = 0;
++ break;
++ case PIN_CONFIG_BIAS_PULL_DOWN:
++ if (arg == 0)
++ return -ENOTSUPP;
++ mask = JH7110_PADCFG_BIAS;
++ value = JH7110_PADCFG_PD;
++ break;
++ case PIN_CONFIG_BIAS_PULL_UP:
++ if (arg == 0)
++ return -ENOTSUPP;
++ mask = JH7110_PADCFG_BIAS;
++ value = JH7110_PADCFG_PU;
++ break;
++ case PIN_CONFIG_DRIVE_PUSH_PULL:
++ return 0;
++ case PIN_CONFIG_INPUT_ENABLE:
++ mask = JH7110_PADCFG_IE;
++ value = arg ? JH7110_PADCFG_IE : 0;
++ break;
++ case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
++ mask = JH7110_PADCFG_SMT;
++ value = arg ? JH7110_PADCFG_SMT : 0;
++ break;
++ default:
++ return -ENOTSUPP;
++ }
++
++ jh7110_padcfg_rmw(sfp, gpio, mask, value);
++ return 0;
++}
++
++static int jh7110_gpio_add_pin_ranges(struct gpio_chip *gc)
++{
++ struct jh7110_pinctrl *sfp = container_of(gc,
++ struct jh7110_pinctrl, gc);
++
++ sfp->gpios.name = sfp->gc.label;
++ sfp->gpios.base = sfp->gc.base;
++ sfp->gpios.pin_base = 0;
++ sfp->gpios.npins = sfp->gc.ngpio;
++ sfp->gpios.gc = &sfp->gc;
++ pinctrl_add_gpio_range(sfp->pctl, &sfp->gpios);
++ return 0;
++}
++
++static void jh7110_irq_ack(struct irq_data *d)
++{
++ struct jh7110_pinctrl *sfp = jh7110_from_irq_data(d);
++ const struct jh7110_gpio_irq_reg *irq_reg = sfp->info->irq_reg;
++ irq_hw_number_t gpio = irqd_to_hwirq(d);
++ void __iomem *ic = sfp->base + irq_reg->ic_reg_base
++ + 4 * (gpio / 32);
++ u32 mask = BIT(gpio % 32);
++ unsigned long flags;
++ u32 value;
++
++ raw_spin_lock_irqsave(&sfp->lock, flags);
++ value = readl_relaxed(ic) & ~mask;
++ writel_relaxed(value, ic);
++ writel_relaxed(value | mask, ic);
++ raw_spin_unlock_irqrestore(&sfp->lock, flags);
++}
++
++static void jh7110_irq_mask(struct irq_data *d)
++{
++ struct jh7110_pinctrl *sfp = jh7110_from_irq_data(d);
++ const struct jh7110_gpio_irq_reg *irq_reg = sfp->info->irq_reg;
++ irq_hw_number_t gpio = irqd_to_hwirq(d);
++ void __iomem *ie = sfp->base + irq_reg->ie_reg_base
++ + 4 * (gpio / 32);
++ u32 mask = BIT(gpio % 32);
++ unsigned long flags;
++ u32 value;
++
++ raw_spin_lock_irqsave(&sfp->lock, flags);
++ value = readl_relaxed(ie) & ~mask;
++ writel_relaxed(value, ie);
++ raw_spin_unlock_irqrestore(&sfp->lock, flags);
++
++ gpiochip_disable_irq(&sfp->gc, d->hwirq);
++}
++
++static void jh7110_irq_mask_ack(struct irq_data *d)
++{
++ struct jh7110_pinctrl *sfp = jh7110_from_irq_data(d);
++ const struct jh7110_gpio_irq_reg *irq_reg = sfp->info->irq_reg;
++ irq_hw_number_t gpio = irqd_to_hwirq(d);
++ void __iomem *ie = sfp->base + irq_reg->ie_reg_base
++ + 4 * (gpio / 32);
++ void __iomem *ic = sfp->base + irq_reg->ic_reg_base
++ + 4 * (gpio / 32);
++ u32 mask = BIT(gpio % 32);
++ unsigned long flags;
++ u32 value;
++
++ raw_spin_lock_irqsave(&sfp->lock, flags);
++ value = readl_relaxed(ie) & ~mask;
++ writel_relaxed(value, ie);
++
++ value = readl_relaxed(ic) & ~mask;
++ writel_relaxed(value, ic);
++ writel_relaxed(value | mask, ic);
++ raw_spin_unlock_irqrestore(&sfp->lock, flags);
++}
++
++static void jh7110_irq_unmask(struct irq_data *d)
++{
++ struct jh7110_pinctrl *sfp = jh7110_from_irq_data(d);
++ const struct jh7110_gpio_irq_reg *irq_reg = sfp->info->irq_reg;
++ irq_hw_number_t gpio = irqd_to_hwirq(d);
++ void __iomem *ie = sfp->base + irq_reg->ie_reg_base
++ + 4 * (gpio / 32);
++ u32 mask = BIT(gpio % 32);
++ unsigned long flags;
++ u32 value;
++
++ gpiochip_enable_irq(&sfp->gc, d->hwirq);
++
++ raw_spin_lock_irqsave(&sfp->lock, flags);
++ value = readl_relaxed(ie) | mask;
++ writel_relaxed(value, ie);
++ raw_spin_unlock_irqrestore(&sfp->lock, flags);
++}
++
++static int jh7110_irq_set_type(struct irq_data *d, unsigned int trigger)
++{
++ struct jh7110_pinctrl *sfp = jh7110_from_irq_data(d);
++ const struct jh7110_gpio_irq_reg *irq_reg = sfp->info->irq_reg;
++ irq_hw_number_t gpio = irqd_to_hwirq(d);
++ void __iomem *base = sfp->base + 4 * (gpio / 32);
++ u32 mask = BIT(gpio % 32);
++ u32 irq_type, edge_both, polarity;
++ unsigned long flags;
++
++ switch (trigger) {
++ case IRQ_TYPE_EDGE_RISING:
++ irq_type = mask; /* 1: edge triggered */
++ edge_both = 0; /* 0: single edge */
++ polarity = mask; /* 1: rising edge */
++ break;
++ case IRQ_TYPE_EDGE_FALLING:
++ irq_type = mask; /* 1: edge triggered */
++ edge_both = 0; /* 0: single edge */
++ polarity = 0; /* 0: falling edge */
++ break;
++ case IRQ_TYPE_EDGE_BOTH:
++ irq_type = mask; /* 1: edge triggered */
++ edge_both = mask; /* 1: both edges */
++ polarity = 0; /* 0: ignored */
++ break;
++ case IRQ_TYPE_LEVEL_HIGH:
++ irq_type = 0; /* 0: level triggered */
++ edge_both = 0; /* 0: ignored */
++ polarity = mask; /* 1: high level */
++ break;
++ case IRQ_TYPE_LEVEL_LOW:
++ irq_type = 0; /* 0: level triggered */
++ edge_both = 0; /* 0: ignored */
++ polarity = 0; /* 0: low level */
++ break;
++ default:
++ return -EINVAL;
++ }
++
++ if (trigger & IRQ_TYPE_EDGE_BOTH)
++ irq_set_handler_locked(d, handle_edge_irq);
++ else
++ irq_set_handler_locked(d, handle_level_irq);
++
++ raw_spin_lock_irqsave(&sfp->lock, flags);
++ irq_type |= readl_relaxed(base + irq_reg->is_reg_base) & ~mask;
++ writel_relaxed(irq_type, base + irq_reg->is_reg_base);
++
++ edge_both |= readl_relaxed(base + irq_reg->ibe_reg_base) & ~mask;
++ writel_relaxed(edge_both, base + irq_reg->ibe_reg_base);
++
++ polarity |= readl_relaxed(base + irq_reg->iev_reg_base) & ~mask;
++ writel_relaxed(polarity, base + irq_reg->iev_reg_base);
++ raw_spin_unlock_irqrestore(&sfp->lock, flags);
++ return 0;
++}
++
++static struct irq_chip jh7110_irq_chip = {
++ .irq_ack = jh7110_irq_ack,
++ .irq_mask = jh7110_irq_mask,
++ .irq_mask_ack = jh7110_irq_mask_ack,
++ .irq_unmask = jh7110_irq_unmask,
++ .irq_set_type = jh7110_irq_set_type,
++ .flags = IRQCHIP_IMMUTABLE | IRQCHIP_SET_TYPE_MASKED,
++ GPIOCHIP_IRQ_RESOURCE_HELPERS,
++};
++
++static void jh7110_disable_clock(void *data)
++{
++ clk_disable_unprepare(data);
++}
++
++int jh7110_pinctrl_probe(struct platform_device *pdev)
++{
++ struct device *dev = &pdev->dev;
++ const struct jh7110_pinctrl_soc_info *info;
++ struct jh7110_pinctrl *sfp;
++ struct pinctrl_desc *jh7110_pinctrl_desc;
++ struct reset_control *rst;
++ struct clk *clk;
++ int ret;
++
++ info = of_device_get_match_data(&pdev->dev);
++ if (!info)
++ return -ENODEV;
++
++ if (!info->pins || !info->npins) {
++ dev_err(dev, "wrong pinctrl info\n");
++ return -EINVAL;
++ }
++
++ sfp = devm_kzalloc(dev, sizeof(*sfp), GFP_KERNEL);
++ if (!sfp)
++ return -ENOMEM;
++
++ sfp->base = devm_platform_ioremap_resource(pdev, 0);
++ if (IS_ERR(sfp->base))
++ return PTR_ERR(sfp->base);
++
++ clk = devm_clk_get_optional(dev, NULL);
++ if (IS_ERR(clk))
++ return dev_err_probe(dev, PTR_ERR(clk), "could not get clock\n");
++
++ rst = devm_reset_control_get_exclusive(dev, NULL);
++ if (IS_ERR(rst))
++ return dev_err_probe(dev, PTR_ERR(rst), "could not get reset\n");
++
++ /*
++ * we don't want to assert reset and risk undoing pin muxing for the
++ * early boot serial console, but let's make sure the reset line is
++ * deasserted in case someone runs a really minimal bootloader.
++ */
++ ret = reset_control_deassert(rst);
++ if (ret)
++ return dev_err_probe(dev, ret, "could not deassert reset\n");
++
++ if (clk) {
++ ret = clk_prepare_enable(clk);
++ if (ret)
++ return dev_err_probe(dev, ret, "could not enable clock\n");
++
++ ret = devm_add_action_or_reset(dev, jh7110_disable_clock, clk);
++ if (ret)
++ return ret;
++ }
++
++ jh7110_pinctrl_desc = devm_kzalloc(&pdev->dev,
++ sizeof(*jh7110_pinctrl_desc),
++ GFP_KERNEL);
++ if (!jh7110_pinctrl_desc)
++ return -ENOMEM;
++
++ jh7110_pinctrl_desc->name = dev_name(dev);
++ jh7110_pinctrl_desc->pins = info->pins;
++ jh7110_pinctrl_desc->npins = info->npins;
++ jh7110_pinctrl_desc->pctlops = &jh7110_pinctrl_ops;
++ jh7110_pinctrl_desc->pmxops = &jh7110_pinmux_ops;
++ jh7110_pinctrl_desc->confops = &jh7110_pinconf_ops;
++ jh7110_pinctrl_desc->owner = THIS_MODULE;
++
++ sfp->info = info;
++ sfp->dev = dev;
++ platform_set_drvdata(pdev, sfp);
++ sfp->gc.parent = dev;
++ raw_spin_lock_init(&sfp->lock);
++ mutex_init(&sfp->mutex);
++
++ ret = devm_pinctrl_register_and_init(dev,
++ jh7110_pinctrl_desc,
++ sfp, &sfp->pctl);
++ if (ret)
++ return dev_err_probe(dev, ret,
++ "could not register pinctrl driver\n");
++
++ sfp->gc.label = dev_name(dev);
++ sfp->gc.owner = THIS_MODULE;
++ sfp->gc.request = jh7110_gpio_request;
++ sfp->gc.free = jh7110_gpio_free;
++ sfp->gc.get_direction = jh7110_gpio_get_direction;
++ sfp->gc.direction_input = jh7110_gpio_direction_input;
++ sfp->gc.direction_output = jh7110_gpio_direction_output;
++ sfp->gc.get = jh7110_gpio_get;
++ sfp->gc.set = jh7110_gpio_set;
++ sfp->gc.set_config = jh7110_gpio_set_config;
++ sfp->gc.add_pin_ranges = jh7110_gpio_add_pin_ranges;
++ sfp->gc.base = info->gc_base;
++ sfp->gc.ngpio = info->ngpios;
++
++ jh7110_irq_chip.name = sfp->gc.label;
++ gpio_irq_chip_set_chip(&sfp->gc.irq, &jh7110_irq_chip);
++ sfp->gc.irq.parent_handler = info->jh7110_gpio_irq_handler;
++ sfp->gc.irq.num_parents = 1;
++ sfp->gc.irq.parents = devm_kcalloc(dev, sfp->gc.irq.num_parents,
++ sizeof(*sfp->gc.irq.parents),
++ GFP_KERNEL);
++ if (!sfp->gc.irq.parents)
++ return -ENOMEM;
++ sfp->gc.irq.default_type = IRQ_TYPE_NONE;
++ sfp->gc.irq.handler = handle_bad_irq;
++ sfp->gc.irq.init_hw = info->jh7110_gpio_init_hw;
++
++ ret = platform_get_irq(pdev, 0);
++ if (ret < 0)
++ return ret;
++ sfp->gc.irq.parents[0] = ret;
++
++ ret = devm_gpiochip_add_data(dev, &sfp->gc, sfp);
++ if (ret)
++ return dev_err_probe(dev, ret, "could not register gpiochip\n");
++
++ irq_domain_set_pm_device(sfp->gc.irq.domain, dev);
++
++ dev_info(dev, "StarFive GPIO chip registered %d GPIOs\n", sfp->gc.ngpio);
++
++ return pinctrl_enable(sfp->pctl);
++}
++EXPORT_SYMBOL_GPL(jh7110_pinctrl_probe);
++
++MODULE_DESCRIPTION("Pinctrl driver for the StarFive JH7110 SoC");
++MODULE_AUTHOR("Emil Renner Berthing <kernel@esmil.dk>");
++MODULE_AUTHOR("Jianlong Huang <jianlong.huang@starfivetech.com>");
++MODULE_LICENSE("GPL");
+diff --git a/drivers/pinctrl/starfive/pinctrl-starfive-jh7110.h b/drivers/pinctrl/starfive/pinctrl-starfive-jh7110.h
+new file mode 100644
+index 000000000000..3f20b7ff96dd
+--- /dev/null
++++ b/drivers/pinctrl/starfive/pinctrl-starfive-jh7110.h
+@@ -0,0 +1,70 @@
++/* SPDX-License-Identifier: GPL-2.0 */
++/*
++ * Pinctrl / GPIO driver for StarFive JH7110 SoC
++ *
++ * Copyright (C) 2022 StarFive Technology Co., Ltd.
++ */
++
++#ifndef __PINCTRL_STARFIVE_JH7110_H__
++#define __PINCTRL_STARFIVE_JH7110_H__
++
++#include <linux/pinctrl/pinconf-generic.h>
++#include <linux/pinctrl/pinmux.h>
++
++struct jh7110_pinctrl {
++ struct device *dev;
++ struct gpio_chip gc;
++ struct pinctrl_gpio_range gpios;
++ raw_spinlock_t lock;
++ void __iomem *base;
++ struct pinctrl_dev *pctl;
++ /* register read/write mutex */
++ struct mutex mutex;
++ const struct jh7110_pinctrl_soc_info *info;
++};
++
++struct jh7110_gpio_irq_reg {
++ unsigned int is_reg_base;
++ unsigned int ic_reg_base;
++ unsigned int ibe_reg_base;
++ unsigned int iev_reg_base;
++ unsigned int ie_reg_base;
++ unsigned int ris_reg_base;
++ unsigned int mis_reg_base;
++};
++
++struct jh7110_pinctrl_soc_info {
++ const struct pinctrl_pin_desc *pins;
++ unsigned int npins;
++ unsigned int ngpios;
++ unsigned int gc_base;
++
++ /* gpio dout/doen/din/gpioinput register */
++ unsigned int dout_reg_base;
++ unsigned int dout_mask;
++ unsigned int doen_reg_base;
++ unsigned int doen_mask;
++ unsigned int gpi_reg_base;
++ unsigned int gpi_mask;
++ unsigned int gpioin_reg_base;
++
++ const struct jh7110_gpio_irq_reg *irq_reg;
++
++ /* generic pinmux */
++ int (*jh7110_set_one_pin_mux)(struct jh7110_pinctrl *sfp,
++ unsigned int pin,
++ unsigned int din, u32 dout,
++ u32 doen, u32 func);
++ /* gpio chip */
++ int (*jh7110_get_padcfg_base)(struct jh7110_pinctrl *sfp,
++ unsigned int pin);
++ void (*jh7110_gpio_irq_handler)(struct irq_desc *desc);
++ int (*jh7110_gpio_init_hw)(struct gpio_chip *gc);
++};
++
++void jh7110_set_gpiomux(struct jh7110_pinctrl *sfp, unsigned int pin,
++ unsigned int din, u32 dout, u32 doen);
++int jh7110_pinctrl_probe(struct platform_device *pdev);
++struct jh7110_pinctrl *jh7110_from_irq_desc(struct irq_desc *desc);
++
++#endif /* __PINCTRL_STARFIVE_JH7110_H__ */
+--
+2.20.1
+
--- /dev/null
+From 5aea7c46928566cd8ed5e568e103fad2f12b3582 Mon Sep 17 00:00:00 2001
+From: Jianlong Huang <jianlong.huang@starfivetech.com>
+Date: Thu, 9 Feb 2023 22:37:02 +0800
+Subject: [PATCH 04/95] pinctrl: starfive: Add StarFive JH7110 aon controller
+ driver
+
+Add pinctrl driver for StarFive JH7110 SoC aon pinctrl controller.
+
+Co-developed-by: Emil Renner Berthing <kernel@esmil.dk>
+Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
+Signed-off-by: Jianlong Huang <jianlong.huang@starfivetech.com>
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ drivers/pinctrl/starfive/Kconfig | 12 ++
+ drivers/pinctrl/starfive/Makefile | 1 +
+ .../starfive/pinctrl-starfive-jh7110-aon.c | 177 ++++++++++++++++++
+ 3 files changed, 190 insertions(+)
+ create mode 100644 drivers/pinctrl/starfive/pinctrl-starfive-jh7110-aon.c
+
+diff --git a/drivers/pinctrl/starfive/Kconfig b/drivers/pinctrl/starfive/Kconfig
+index 453c8a0b3118..8192ac2087fc 100644
+--- a/drivers/pinctrl/starfive/Kconfig
++++ b/drivers/pinctrl/starfive/Kconfig
+@@ -37,3 +37,15 @@ config PINCTRL_STARFIVE_JH7110_SYS
+ This also provides an interface to the GPIO pins not used by other
+ peripherals supporting inputs, outputs, configuring pull-up/pull-down
+ and interrupts on input changes.
++
++config PINCTRL_STARFIVE_JH7110_AON
++ tristate "Always-on pinctrl and GPIO driver for the StarFive JH7110 SoC"
++ depends on SOC_STARFIVE || COMPILE_TEST
++ depends on OF
++ select PINCTRL_STARFIVE_JH7110
++ default SOC_STARFIVE
++ help
++ Say yes here to support always-on pin control on the StarFive JH7110 SoC.
++ This also provides an interface to the GPIO pins not used by other
++ peripherals supporting inputs, outputs, configuring pull-up/pull-down
++ and interrupts on input changes.
+diff --git a/drivers/pinctrl/starfive/Makefile b/drivers/pinctrl/starfive/Makefile
+index dc2d1e392314..ee0d32d085cb 100644
+--- a/drivers/pinctrl/starfive/Makefile
++++ b/drivers/pinctrl/starfive/Makefile
+@@ -4,3 +4,4 @@ obj-$(CONFIG_PINCTRL_STARFIVE_JH7100) += pinctrl-starfive-jh7100.o
+
+ obj-$(CONFIG_PINCTRL_STARFIVE_JH7110) += pinctrl-starfive-jh7110.o
+ obj-$(CONFIG_PINCTRL_STARFIVE_JH7110_SYS) += pinctrl-starfive-jh7110-sys.o
++obj-$(CONFIG_PINCTRL_STARFIVE_JH7110_AON) += pinctrl-starfive-jh7110-aon.o
+diff --git a/drivers/pinctrl/starfive/pinctrl-starfive-jh7110-aon.c b/drivers/pinctrl/starfive/pinctrl-starfive-jh7110-aon.c
+new file mode 100644
+index 000000000000..8cf28aaed254
+--- /dev/null
++++ b/drivers/pinctrl/starfive/pinctrl-starfive-jh7110-aon.c
+@@ -0,0 +1,177 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Pinctrl / GPIO driver for StarFive JH7110 SoC aon controller
++ *
++ * Copyright (C) 2022 StarFive Technology Co., Ltd.
++ */
++
++#include <linux/err.h>
++#include <linux/gpio/driver.h>
++#include <linux/init.h>
++#include <linux/interrupt.h>
++#include <linux/io.h>
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/of_device.h>
++#include <linux/of_irq.h>
++#include <linux/of_platform.h>
++#include <linux/pinctrl/pinconf.h>
++#include <linux/pinctrl/pinconf-generic.h>
++#include <linux/pinctrl/pinctrl.h>
++#include <linux/pinctrl/pinmux.h>
++#include <linux/platform_device.h>
++#include <linux/pm_runtime.h>
++#include <linux/regmap.h>
++#include <linux/slab.h>
++
++#include <dt-bindings/pinctrl/starfive,jh7110-pinctrl.h>
++
++#include "../core.h"
++#include "../pinconf.h"
++#include "../pinmux.h"
++#include "pinctrl-starfive-jh7110.h"
++
++#define JH7110_AON_NGPIO 4
++#define JH7110_AON_GC_BASE 64
++
++/* registers */
++#define JH7110_AON_DOEN 0x0
++#define JH7110_AON_DOUT 0x4
++#define JH7110_AON_GPI 0x8
++#define JH7110_AON_GPIOIN 0x2c
++
++#define JH7110_AON_GPIOEN 0xc
++#define JH7110_AON_GPIOIS 0x10
++#define JH7110_AON_GPIOIC 0x14
++#define JH7110_AON_GPIOIBE 0x18
++#define JH7110_AON_GPIOIEV 0x1c
++#define JH7110_AON_GPIOIE 0x20
++#define JH7110_AON_GPIORIS 0x28
++#define JH7110_AON_GPIOMIS 0x28
++
++#define JH7110_AON_GPO_PDA_0_5_CFG 0x30
++
++static const struct pinctrl_pin_desc jh7110_aon_pins[] = {
++ PINCTRL_PIN(PAD_TESTEN, "TESTEN"),
++ PINCTRL_PIN(PAD_RGPIO0, "RGPIO0"),
++ PINCTRL_PIN(PAD_RGPIO1, "RGPIO1"),
++ PINCTRL_PIN(PAD_RGPIO2, "RGPIO2"),
++ PINCTRL_PIN(PAD_RGPIO3, "RGPIO3"),
++ PINCTRL_PIN(PAD_RSTN, "RSTN"),
++ PINCTRL_PIN(PAD_GMAC0_MDC, "GMAC0_MDC"),
++ PINCTRL_PIN(PAD_GMAC0_MDIO, "GMAC0_MDIO"),
++ PINCTRL_PIN(PAD_GMAC0_RXD0, "GMAC0_RXD0"),
++ PINCTRL_PIN(PAD_GMAC0_RXD1, "GMAC0_RXD1"),
++ PINCTRL_PIN(PAD_GMAC0_RXD2, "GMAC0_RXD2"),
++ PINCTRL_PIN(PAD_GMAC0_RXD3, "GMAC0_RXD3"),
++ PINCTRL_PIN(PAD_GMAC0_RXDV, "GMAC0_RXDV"),
++ PINCTRL_PIN(PAD_GMAC0_RXC, "GMAC0_RXC"),
++ PINCTRL_PIN(PAD_GMAC0_TXD0, "GMAC0_TXD0"),
++ PINCTRL_PIN(PAD_GMAC0_TXD1, "GMAC0_TXD1"),
++ PINCTRL_PIN(PAD_GMAC0_TXD2, "GMAC0_TXD2"),
++ PINCTRL_PIN(PAD_GMAC0_TXD3, "GMAC0_TXD3"),
++ PINCTRL_PIN(PAD_GMAC0_TXEN, "GMAC0_TXEN"),
++ PINCTRL_PIN(PAD_GMAC0_TXC, "GMAC0_TXC"),
++};
++
++static int jh7110_aon_set_one_pin_mux(struct jh7110_pinctrl *sfp,
++ unsigned int pin,
++ unsigned int din, u32 dout,
++ u32 doen, u32 func)
++{
++ if (pin < sfp->gc.ngpio && func == 0)
++ jh7110_set_gpiomux(sfp, pin, din, dout, doen);
++
++ return 0;
++}
++
++static int jh7110_aon_get_padcfg_base(struct jh7110_pinctrl *sfp,
++ unsigned int pin)
++{
++ if (pin < PAD_GMAC0_MDC)
++ return JH7110_AON_GPO_PDA_0_5_CFG;
++
++ return -1;
++}
++
++static void jh7110_aon_irq_handler(struct irq_desc *desc)
++{
++ struct jh7110_pinctrl *sfp = jh7110_from_irq_desc(desc);
++ struct irq_chip *chip = irq_desc_get_chip(desc);
++ unsigned long mis;
++ unsigned int pin;
++
++ chained_irq_enter(chip, desc);
++
++ mis = readl_relaxed(sfp->base + JH7110_AON_GPIOMIS);
++ for_each_set_bit(pin, &mis, JH7110_AON_NGPIO)
++ generic_handle_domain_irq(sfp->gc.irq.domain, pin);
++
++ chained_irq_exit(chip, desc);
++}
++
++static int jh7110_aon_init_hw(struct gpio_chip *gc)
++{
++ struct jh7110_pinctrl *sfp = container_of(gc,
++ struct jh7110_pinctrl, gc);
++
++ /* mask all GPIO interrupts */
++ writel_relaxed(0, sfp->base + JH7110_AON_GPIOIE);
++ /* clear edge interrupt flags */
++ writel_relaxed(0, sfp->base + JH7110_AON_GPIOIC);
++ writel_relaxed(0x0f, sfp->base + JH7110_AON_GPIOIC);
++ /* enable GPIO interrupts */
++ writel_relaxed(1, sfp->base + JH7110_AON_GPIOEN);
++ return 0;
++}
++
++static const struct jh7110_gpio_irq_reg jh7110_aon_irq_reg = {
++ .is_reg_base = JH7110_AON_GPIOIS,
++ .ic_reg_base = JH7110_AON_GPIOIC,
++ .ibe_reg_base = JH7110_AON_GPIOIBE,
++ .iev_reg_base = JH7110_AON_GPIOIEV,
++ .ie_reg_base = JH7110_AON_GPIOIE,
++ .ris_reg_base = JH7110_AON_GPIORIS,
++ .mis_reg_base = JH7110_AON_GPIOMIS,
++};
++
++static const struct jh7110_pinctrl_soc_info jh7110_aon_pinctrl_info = {
++ .pins = jh7110_aon_pins,
++ .npins = ARRAY_SIZE(jh7110_aon_pins),
++ .ngpios = JH7110_AON_NGPIO,
++ .gc_base = JH7110_AON_GC_BASE,
++ .dout_reg_base = JH7110_AON_DOUT,
++ .dout_mask = GENMASK(3, 0),
++ .doen_reg_base = JH7110_AON_DOEN,
++ .doen_mask = GENMASK(2, 0),
++ .gpi_reg_base = JH7110_AON_GPI,
++ .gpi_mask = GENMASK(3, 0),
++ .gpioin_reg_base = JH7110_AON_GPIOIN,
++ .irq_reg = &jh7110_aon_irq_reg,
++ .jh7110_set_one_pin_mux = jh7110_aon_set_one_pin_mux,
++ .jh7110_get_padcfg_base = jh7110_aon_get_padcfg_base,
++ .jh7110_gpio_irq_handler = jh7110_aon_irq_handler,
++ .jh7110_gpio_init_hw = jh7110_aon_init_hw,
++};
++
++static const struct of_device_id jh7110_aon_pinctrl_of_match[] = {
++ {
++ .compatible = "starfive,jh7110-aon-pinctrl",
++ .data = &jh7110_aon_pinctrl_info,
++ },
++ { /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(of, jh7110_aon_pinctrl_of_match);
++
++static struct platform_driver jh7110_aon_pinctrl_driver = {
++ .probe = jh7110_pinctrl_probe,
++ .driver = {
++ .name = "starfive-jh7110-aon-pinctrl",
++ .of_match_table = jh7110_aon_pinctrl_of_match,
++ },
++};
++module_platform_driver(jh7110_aon_pinctrl_driver);
++
++MODULE_DESCRIPTION("Pinctrl driver for the StarFive JH7110 SoC aon controller");
++MODULE_AUTHOR("Jianlong Huang <jianlong.huang@starfivetech.com>");
++MODULE_LICENSE("GPL");
+--
+2.20.1
+
--- /dev/null
+From 81065c6f2a19d7b499277e8aebfeb1cc9e357ae0 Mon Sep 17 00:00:00 2001
+From: Emil Renner Berthing <kernel@esmil.dk>
+Date: Sat, 1 Apr 2023 19:19:13 +0800
+Subject: [PATCH 05/95] dt-bindings: clock: Add StarFive JH7110 system clock
+ and reset generator
+
+Add bindings for the system clock and reset generator (SYSCRG) on the
+JH7110 RISC-V SoC by StarFive Ltd.
+
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+Reviewed-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ .../clock/starfive,jh7110-syscrg.yaml | 104 +++++++++
+ .../dt-bindings/clock/starfive,jh7110-crg.h | 203 ++++++++++++++++++
+ .../dt-bindings/reset/starfive,jh7110-crg.h | 142 ++++++++++++
+ 3 files changed, 449 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/clock/starfive,jh7110-syscrg.yaml
+ create mode 100644 include/dt-bindings/clock/starfive,jh7110-crg.h
+ create mode 100644 include/dt-bindings/reset/starfive,jh7110-crg.h
+
+diff --git a/Documentation/devicetree/bindings/clock/starfive,jh7110-syscrg.yaml b/Documentation/devicetree/bindings/clock/starfive,jh7110-syscrg.yaml
+new file mode 100644
+index 000000000000..84373ae31644
+--- /dev/null
++++ b/Documentation/devicetree/bindings/clock/starfive,jh7110-syscrg.yaml
+@@ -0,0 +1,104 @@
++# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/clock/starfive,jh7110-syscrg.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: StarFive JH7110 System Clock and Reset Generator
++
++maintainers:
++ - Emil Renner Berthing <kernel@esmil.dk>
++
++properties:
++ compatible:
++ const: starfive,jh7110-syscrg
++
++ reg:
++ maxItems: 1
++
++ clocks:
++ oneOf:
++ - items:
++ - description: Main Oscillator (24 MHz)
++ - description: GMAC1 RMII reference or GMAC1 RGMII RX
++ - description: External I2S TX bit clock
++ - description: External I2S TX left/right channel clock
++ - description: External I2S RX bit clock
++ - description: External I2S RX left/right channel clock
++ - description: External TDM clock
++ - description: External audio master clock
++
++ - items:
++ - description: Main Oscillator (24 MHz)
++ - description: GMAC1 RMII reference
++ - description: GMAC1 RGMII RX
++ - description: External I2S TX bit clock
++ - description: External I2S TX left/right channel clock
++ - description: External I2S RX bit clock
++ - description: External I2S RX left/right channel clock
++ - description: External TDM clock
++ - description: External audio master clock
++
++ clock-names:
++ oneOf:
++ - items:
++ - const: osc
++ - enum:
++ - gmac1_rmii_refin
++ - gmac1_rgmii_rxin
++ - const: i2stx_bclk_ext
++ - const: i2stx_lrck_ext
++ - const: i2srx_bclk_ext
++ - const: i2srx_lrck_ext
++ - const: tdm_ext
++ - const: mclk_ext
++
++ - items:
++ - const: osc
++ - const: gmac1_rmii_refin
++ - const: gmac1_rgmii_rxin
++ - const: i2stx_bclk_ext
++ - const: i2stx_lrck_ext
++ - const: i2srx_bclk_ext
++ - const: i2srx_lrck_ext
++ - const: tdm_ext
++ - const: mclk_ext
++
++ '#clock-cells':
++ const: 1
++ description:
++ See <dt-bindings/clock/starfive,jh7110-crg.h> for valid indices.
++
++ '#reset-cells':
++ const: 1
++ description:
++ See <dt-bindings/reset/starfive,jh7110-crg.h> for valid indices.
++
++required:
++ - compatible
++ - reg
++ - clocks
++ - clock-names
++ - '#clock-cells'
++ - '#reset-cells'
++
++additionalProperties: false
++
++examples:
++ - |
++ clock-controller@13020000 {
++ compatible = "starfive,jh7110-syscrg";
++ reg = <0x13020000 0x10000>;
++ clocks = <&osc>, <&gmac1_rmii_refin>,
++ <&gmac1_rgmii_rxin>,
++ <&i2stx_bclk_ext>, <&i2stx_lrck_ext>,
++ <&i2srx_bclk_ext>, <&i2srx_lrck_ext>,
++ <&tdm_ext>, <&mclk_ext>;
++ clock-names = "osc", "gmac1_rmii_refin",
++ "gmac1_rgmii_rxin",
++ "i2stx_bclk_ext", "i2stx_lrck_ext",
++ "i2srx_bclk_ext", "i2srx_lrck_ext",
++ "tdm_ext", "mclk_ext";
++ #clock-cells = <1>;
++ #reset-cells = <1>;
++ };
+diff --git a/include/dt-bindings/clock/starfive,jh7110-crg.h b/include/dt-bindings/clock/starfive,jh7110-crg.h
+new file mode 100644
+index 000000000000..fdd1852e34cc
+--- /dev/null
++++ b/include/dt-bindings/clock/starfive,jh7110-crg.h
+@@ -0,0 +1,203 @@
++/* SPDX-License-Identifier: GPL-2.0 OR MIT */
++/*
++ * Copyright 2022 Emil Renner Berthing <kernel@esmil.dk>
++ */
++
++#ifndef __DT_BINDINGS_CLOCK_STARFIVE_JH7110_CRG_H__
++#define __DT_BINDINGS_CLOCK_STARFIVE_JH7110_CRG_H__
++
++/* SYSCRG clocks */
++#define JH7110_SYSCLK_CPU_ROOT 0
++#define JH7110_SYSCLK_CPU_CORE 1
++#define JH7110_SYSCLK_CPU_BUS 2
++#define JH7110_SYSCLK_GPU_ROOT 3
++#define JH7110_SYSCLK_PERH_ROOT 4
++#define JH7110_SYSCLK_BUS_ROOT 5
++#define JH7110_SYSCLK_NOCSTG_BUS 6
++#define JH7110_SYSCLK_AXI_CFG0 7
++#define JH7110_SYSCLK_STG_AXIAHB 8
++#define JH7110_SYSCLK_AHB0 9
++#define JH7110_SYSCLK_AHB1 10
++#define JH7110_SYSCLK_APB_BUS 11
++#define JH7110_SYSCLK_APB0 12
++#define JH7110_SYSCLK_PLL0_DIV2 13
++#define JH7110_SYSCLK_PLL1_DIV2 14
++#define JH7110_SYSCLK_PLL2_DIV2 15
++#define JH7110_SYSCLK_AUDIO_ROOT 16
++#define JH7110_SYSCLK_MCLK_INNER 17
++#define JH7110_SYSCLK_MCLK 18
++#define JH7110_SYSCLK_MCLK_OUT 19
++#define JH7110_SYSCLK_ISP_2X 20
++#define JH7110_SYSCLK_ISP_AXI 21
++#define JH7110_SYSCLK_GCLK0 22
++#define JH7110_SYSCLK_GCLK1 23
++#define JH7110_SYSCLK_GCLK2 24
++#define JH7110_SYSCLK_CORE 25
++#define JH7110_SYSCLK_CORE1 26
++#define JH7110_SYSCLK_CORE2 27
++#define JH7110_SYSCLK_CORE3 28
++#define JH7110_SYSCLK_CORE4 29
++#define JH7110_SYSCLK_DEBUG 30
++#define JH7110_SYSCLK_RTC_TOGGLE 31
++#define JH7110_SYSCLK_TRACE0 32
++#define JH7110_SYSCLK_TRACE1 33
++#define JH7110_SYSCLK_TRACE2 34
++#define JH7110_SYSCLK_TRACE3 35
++#define JH7110_SYSCLK_TRACE4 36
++#define JH7110_SYSCLK_TRACE_COM 37
++#define JH7110_SYSCLK_NOC_BUS_CPU_AXI 38
++#define JH7110_SYSCLK_NOC_BUS_AXICFG0_AXI 39
++#define JH7110_SYSCLK_OSC_DIV2 40
++#define JH7110_SYSCLK_PLL1_DIV4 41
++#define JH7110_SYSCLK_PLL1_DIV8 42
++#define JH7110_SYSCLK_DDR_BUS 43
++#define JH7110_SYSCLK_DDR_AXI 44
++#define JH7110_SYSCLK_GPU_CORE 45
++#define JH7110_SYSCLK_GPU_CORE_CLK 46
++#define JH7110_SYSCLK_GPU_SYS_CLK 47
++#define JH7110_SYSCLK_GPU_APB 48
++#define JH7110_SYSCLK_GPU_RTC_TOGGLE 49
++#define JH7110_SYSCLK_NOC_BUS_GPU_AXI 50
++#define JH7110_SYSCLK_ISP_TOP_CORE 51
++#define JH7110_SYSCLK_ISP_TOP_AXI 52
++#define JH7110_SYSCLK_NOC_BUS_ISP_AXI 53
++#define JH7110_SYSCLK_HIFI4_CORE 54
++#define JH7110_SYSCLK_HIFI4_AXI 55
++#define JH7110_SYSCLK_AXI_CFG1_MAIN 56
++#define JH7110_SYSCLK_AXI_CFG1_AHB 57
++#define JH7110_SYSCLK_VOUT_SRC 58
++#define JH7110_SYSCLK_VOUT_AXI 59
++#define JH7110_SYSCLK_NOC_BUS_DISP_AXI 60
++#define JH7110_SYSCLK_VOUT_TOP_AHB 61
++#define JH7110_SYSCLK_VOUT_TOP_AXI 62
++#define JH7110_SYSCLK_VOUT_TOP_HDMITX0_MCLK 63
++#define JH7110_SYSCLK_VOUT_TOP_MIPIPHY_REF 64
++#define JH7110_SYSCLK_JPEGC_AXI 65
++#define JH7110_SYSCLK_CODAJ12_AXI 66
++#define JH7110_SYSCLK_CODAJ12_CORE 67
++#define JH7110_SYSCLK_CODAJ12_APB 68
++#define JH7110_SYSCLK_VDEC_AXI 69
++#define JH7110_SYSCLK_WAVE511_AXI 70
++#define JH7110_SYSCLK_WAVE511_BPU 71
++#define JH7110_SYSCLK_WAVE511_VCE 72
++#define JH7110_SYSCLK_WAVE511_APB 73
++#define JH7110_SYSCLK_VDEC_JPG 74
++#define JH7110_SYSCLK_VDEC_MAIN 75
++#define JH7110_SYSCLK_NOC_BUS_VDEC_AXI 76
++#define JH7110_SYSCLK_VENC_AXI 77
++#define JH7110_SYSCLK_WAVE420L_AXI 78
++#define JH7110_SYSCLK_WAVE420L_BPU 79
++#define JH7110_SYSCLK_WAVE420L_VCE 80
++#define JH7110_SYSCLK_WAVE420L_APB 81
++#define JH7110_SYSCLK_NOC_BUS_VENC_AXI 82
++#define JH7110_SYSCLK_AXI_CFG0_MAIN_DIV 83
++#define JH7110_SYSCLK_AXI_CFG0_MAIN 84
++#define JH7110_SYSCLK_AXI_CFG0_HIFI4 85
++#define JH7110_SYSCLK_AXIMEM2_AXI 86
++#define JH7110_SYSCLK_QSPI_AHB 87
++#define JH7110_SYSCLK_QSPI_APB 88
++#define JH7110_SYSCLK_QSPI_REF_SRC 89
++#define JH7110_SYSCLK_QSPI_REF 90
++#define JH7110_SYSCLK_SDIO0_AHB 91
++#define JH7110_SYSCLK_SDIO1_AHB 92
++#define JH7110_SYSCLK_SDIO0_SDCARD 93
++#define JH7110_SYSCLK_SDIO1_SDCARD 94
++#define JH7110_SYSCLK_USB_125M 95
++#define JH7110_SYSCLK_NOC_BUS_STG_AXI 96
++#define JH7110_SYSCLK_GMAC1_AHB 97
++#define JH7110_SYSCLK_GMAC1_AXI 98
++#define JH7110_SYSCLK_GMAC_SRC 99
++#define JH7110_SYSCLK_GMAC1_GTXCLK 100
++#define JH7110_SYSCLK_GMAC1_RMII_RTX 101
++#define JH7110_SYSCLK_GMAC1_PTP 102
++#define JH7110_SYSCLK_GMAC1_RX 103
++#define JH7110_SYSCLK_GMAC1_RX_INV 104
++#define JH7110_SYSCLK_GMAC1_TX 105
++#define JH7110_SYSCLK_GMAC1_TX_INV 106
++#define JH7110_SYSCLK_GMAC1_GTXC 107
++#define JH7110_SYSCLK_GMAC0_GTXCLK 108
++#define JH7110_SYSCLK_GMAC0_PTP 109
++#define JH7110_SYSCLK_GMAC_PHY 110
++#define JH7110_SYSCLK_GMAC0_GTXC 111
++#define JH7110_SYSCLK_IOMUX_APB 112
++#define JH7110_SYSCLK_MAILBOX_APB 113
++#define JH7110_SYSCLK_INT_CTRL_APB 114
++#define JH7110_SYSCLK_CAN0_APB 115
++#define JH7110_SYSCLK_CAN0_TIMER 116
++#define JH7110_SYSCLK_CAN0_CAN 117
++#define JH7110_SYSCLK_CAN1_APB 118
++#define JH7110_SYSCLK_CAN1_TIMER 119
++#define JH7110_SYSCLK_CAN1_CAN 120
++#define JH7110_SYSCLK_PWM_APB 121
++#define JH7110_SYSCLK_WDT_APB 122
++#define JH7110_SYSCLK_WDT_CORE 123
++#define JH7110_SYSCLK_TIMER_APB 124
++#define JH7110_SYSCLK_TIMER0 125
++#define JH7110_SYSCLK_TIMER1 126
++#define JH7110_SYSCLK_TIMER2 127
++#define JH7110_SYSCLK_TIMER3 128
++#define JH7110_SYSCLK_TEMP_APB 129
++#define JH7110_SYSCLK_TEMP_CORE 130
++#define JH7110_SYSCLK_SPI0_APB 131
++#define JH7110_SYSCLK_SPI1_APB 132
++#define JH7110_SYSCLK_SPI2_APB 133
++#define JH7110_SYSCLK_SPI3_APB 134
++#define JH7110_SYSCLK_SPI4_APB 135
++#define JH7110_SYSCLK_SPI5_APB 136
++#define JH7110_SYSCLK_SPI6_APB 137
++#define JH7110_SYSCLK_I2C0_APB 138
++#define JH7110_SYSCLK_I2C1_APB 139
++#define JH7110_SYSCLK_I2C2_APB 140
++#define JH7110_SYSCLK_I2C3_APB 141
++#define JH7110_SYSCLK_I2C4_APB 142
++#define JH7110_SYSCLK_I2C5_APB 143
++#define JH7110_SYSCLK_I2C6_APB 144
++#define JH7110_SYSCLK_UART0_APB 145
++#define JH7110_SYSCLK_UART0_CORE 146
++#define JH7110_SYSCLK_UART1_APB 147
++#define JH7110_SYSCLK_UART1_CORE 148
++#define JH7110_SYSCLK_UART2_APB 149
++#define JH7110_SYSCLK_UART2_CORE 150
++#define JH7110_SYSCLK_UART3_APB 151
++#define JH7110_SYSCLK_UART3_CORE 152
++#define JH7110_SYSCLK_UART4_APB 153
++#define JH7110_SYSCLK_UART4_CORE 154
++#define JH7110_SYSCLK_UART5_APB 155
++#define JH7110_SYSCLK_UART5_CORE 156
++#define JH7110_SYSCLK_PWMDAC_APB 157
++#define JH7110_SYSCLK_PWMDAC_CORE 158
++#define JH7110_SYSCLK_SPDIF_APB 159
++#define JH7110_SYSCLK_SPDIF_CORE 160
++#define JH7110_SYSCLK_I2STX0_APB 161
++#define JH7110_SYSCLK_I2STX0_BCLK_MST 162
++#define JH7110_SYSCLK_I2STX0_BCLK_MST_INV 163
++#define JH7110_SYSCLK_I2STX0_LRCK_MST 164
++#define JH7110_SYSCLK_I2STX0_BCLK 165
++#define JH7110_SYSCLK_I2STX0_BCLK_INV 166
++#define JH7110_SYSCLK_I2STX0_LRCK 167
++#define JH7110_SYSCLK_I2STX1_APB 168
++#define JH7110_SYSCLK_I2STX1_BCLK_MST 169
++#define JH7110_SYSCLK_I2STX1_BCLK_MST_INV 170
++#define JH7110_SYSCLK_I2STX1_LRCK_MST 171
++#define JH7110_SYSCLK_I2STX1_BCLK 172
++#define JH7110_SYSCLK_I2STX1_BCLK_INV 173
++#define JH7110_SYSCLK_I2STX1_LRCK 174
++#define JH7110_SYSCLK_I2SRX_APB 175
++#define JH7110_SYSCLK_I2SRX_BCLK_MST 176
++#define JH7110_SYSCLK_I2SRX_BCLK_MST_INV 177
++#define JH7110_SYSCLK_I2SRX_LRCK_MST 178
++#define JH7110_SYSCLK_I2SRX_BCLK 179
++#define JH7110_SYSCLK_I2SRX_BCLK_INV 180
++#define JH7110_SYSCLK_I2SRX_LRCK 181
++#define JH7110_SYSCLK_PDM_DMIC 182
++#define JH7110_SYSCLK_PDM_APB 183
++#define JH7110_SYSCLK_TDM_AHB 184
++#define JH7110_SYSCLK_TDM_APB 185
++#define JH7110_SYSCLK_TDM_INTERNAL 186
++#define JH7110_SYSCLK_TDM_TDM 187
++#define JH7110_SYSCLK_TDM_TDM_INV 188
++#define JH7110_SYSCLK_JTAG_CERTIFICATION_TRNG 189
++
++#define JH7110_SYSCLK_END 190
++
++#endif /* __DT_BINDINGS_CLOCK_STARFIVE_JH7110_CRG_H__ */
+diff --git a/include/dt-bindings/reset/starfive,jh7110-crg.h b/include/dt-bindings/reset/starfive,jh7110-crg.h
+new file mode 100644
+index 000000000000..b88216a4fe40
+--- /dev/null
++++ b/include/dt-bindings/reset/starfive,jh7110-crg.h
+@@ -0,0 +1,142 @@
++/* SPDX-License-Identifier: GPL-2.0 OR MIT */
++/*
++ * Copyright (C) 2022 Emil Renner Berthing <kernel@esmil.dk>
++ */
++
++#ifndef __DT_BINDINGS_RESET_STARFIVE_JH7110_CRG_H__
++#define __DT_BINDINGS_RESET_STARFIVE_JH7110_CRG_H__
++
++/* SYSCRG resets */
++#define JH7110_SYSRST_JTAG_APB 0
++#define JH7110_SYSRST_SYSCON_APB 1
++#define JH7110_SYSRST_IOMUX_APB 2
++#define JH7110_SYSRST_BUS 3
++#define JH7110_SYSRST_DEBUG 4
++#define JH7110_SYSRST_CORE0 5
++#define JH7110_SYSRST_CORE1 6
++#define JH7110_SYSRST_CORE2 7
++#define JH7110_SYSRST_CORE3 8
++#define JH7110_SYSRST_CORE4 9
++#define JH7110_SYSRST_CORE0_ST 10
++#define JH7110_SYSRST_CORE1_ST 11
++#define JH7110_SYSRST_CORE2_ST 12
++#define JH7110_SYSRST_CORE3_ST 13
++#define JH7110_SYSRST_CORE4_ST 14
++#define JH7110_SYSRST_TRACE0 15
++#define JH7110_SYSRST_TRACE1 16
++#define JH7110_SYSRST_TRACE2 17
++#define JH7110_SYSRST_TRACE3 18
++#define JH7110_SYSRST_TRACE4 19
++#define JH7110_SYSRST_TRACE_COM 20
++#define JH7110_SYSRST_GPU_APB 21
++#define JH7110_SYSRST_GPU_DOMA 22
++#define JH7110_SYSRST_NOC_BUS_APB 23
++#define JH7110_SYSRST_NOC_BUS_AXICFG0_AXI 24
++#define JH7110_SYSRST_NOC_BUS_CPU_AXI 25
++#define JH7110_SYSRST_NOC_BUS_DISP_AXI 26
++#define JH7110_SYSRST_NOC_BUS_GPU_AXI 27
++#define JH7110_SYSRST_NOC_BUS_ISP_AXI 28
++#define JH7110_SYSRST_NOC_BUS_DDRC 29
++#define JH7110_SYSRST_NOC_BUS_STG_AXI 30
++#define JH7110_SYSRST_NOC_BUS_VDEC_AXI 31
++
++#define JH7110_SYSRST_NOC_BUS_VENC_AXI 32
++#define JH7110_SYSRST_AXI_CFG1_AHB 33
++#define JH7110_SYSRST_AXI_CFG1_MAIN 34
++#define JH7110_SYSRST_AXI_CFG0_MAIN 35
++#define JH7110_SYSRST_AXI_CFG0_MAIN_DIV 36
++#define JH7110_SYSRST_AXI_CFG0_HIFI4 37
++#define JH7110_SYSRST_DDR_AXI 38
++#define JH7110_SYSRST_DDR_OSC 39
++#define JH7110_SYSRST_DDR_APB 40
++#define JH7110_SYSRST_ISP_TOP 41
++#define JH7110_SYSRST_ISP_TOP_AXI 42
++#define JH7110_SYSRST_VOUT_TOP_SRC 43
++#define JH7110_SYSRST_CODAJ12_AXI 44
++#define JH7110_SYSRST_CODAJ12_CORE 45
++#define JH7110_SYSRST_CODAJ12_APB 46
++#define JH7110_SYSRST_WAVE511_AXI 47
++#define JH7110_SYSRST_WAVE511_BPU 48
++#define JH7110_SYSRST_WAVE511_VCE 49
++#define JH7110_SYSRST_WAVE511_APB 50
++#define JH7110_SYSRST_VDEC_JPG 51
++#define JH7110_SYSRST_VDEC_MAIN 52
++#define JH7110_SYSRST_AXIMEM0_AXI 53
++#define JH7110_SYSRST_WAVE420L_AXI 54
++#define JH7110_SYSRST_WAVE420L_BPU 55
++#define JH7110_SYSRST_WAVE420L_VCE 56
++#define JH7110_SYSRST_WAVE420L_APB 57
++#define JH7110_SYSRST_AXIMEM1_AXI 58
++#define JH7110_SYSRST_AXIMEM2_AXI 59
++#define JH7110_SYSRST_INTMEM 60
++#define JH7110_SYSRST_QSPI_AHB 61
++#define JH7110_SYSRST_QSPI_APB 62
++#define JH7110_SYSRST_QSPI_REF 63
++
++#define JH7110_SYSRST_SDIO0_AHB 64
++#define JH7110_SYSRST_SDIO1_AHB 65
++#define JH7110_SYSRST_GMAC1_AXI 66
++#define JH7110_SYSRST_GMAC1_AHB 67
++#define JH7110_SYSRST_MAILBOX_APB 68
++#define JH7110_SYSRST_SPI0_APB 69
++#define JH7110_SYSRST_SPI1_APB 70
++#define JH7110_SYSRST_SPI2_APB 71
++#define JH7110_SYSRST_SPI3_APB 72
++#define JH7110_SYSRST_SPI4_APB 73
++#define JH7110_SYSRST_SPI5_APB 74
++#define JH7110_SYSRST_SPI6_APB 75
++#define JH7110_SYSRST_I2C0_APB 76
++#define JH7110_SYSRST_I2C1_APB 77
++#define JH7110_SYSRST_I2C2_APB 78
++#define JH7110_SYSRST_I2C3_APB 79
++#define JH7110_SYSRST_I2C4_APB 80
++#define JH7110_SYSRST_I2C5_APB 81
++#define JH7110_SYSRST_I2C6_APB 82
++#define JH7110_SYSRST_UART0_APB 83
++#define JH7110_SYSRST_UART0_CORE 84
++#define JH7110_SYSRST_UART1_APB 85
++#define JH7110_SYSRST_UART1_CORE 86
++#define JH7110_SYSRST_UART2_APB 87
++#define JH7110_SYSRST_UART2_CORE 88
++#define JH7110_SYSRST_UART3_APB 89
++#define JH7110_SYSRST_UART3_CORE 90
++#define JH7110_SYSRST_UART4_APB 91
++#define JH7110_SYSRST_UART4_CORE 92
++#define JH7110_SYSRST_UART5_APB 93
++#define JH7110_SYSRST_UART5_CORE 94
++#define JH7110_SYSRST_SPDIF_APB 95
++
++#define JH7110_SYSRST_PWMDAC_APB 96
++#define JH7110_SYSRST_PDM_DMIC 97
++#define JH7110_SYSRST_PDM_APB 98
++#define JH7110_SYSRST_I2SRX_APB 99
++#define JH7110_SYSRST_I2SRX_BCLK 100
++#define JH7110_SYSRST_I2STX0_APB 101
++#define JH7110_SYSRST_I2STX0_BCLK 102
++#define JH7110_SYSRST_I2STX1_APB 103
++#define JH7110_SYSRST_I2STX1_BCLK 104
++#define JH7110_SYSRST_TDM_AHB 105
++#define JH7110_SYSRST_TDM_CORE 106
++#define JH7110_SYSRST_TDM_APB 107
++#define JH7110_SYSRST_PWM_APB 108
++#define JH7110_SYSRST_WDT_APB 109
++#define JH7110_SYSRST_WDT_CORE 110
++#define JH7110_SYSRST_CAN0_APB 111
++#define JH7110_SYSRST_CAN0_CORE 112
++#define JH7110_SYSRST_CAN0_TIMER 113
++#define JH7110_SYSRST_CAN1_APB 114
++#define JH7110_SYSRST_CAN1_CORE 115
++#define JH7110_SYSRST_CAN1_TIMER 116
++#define JH7110_SYSRST_TIMER_APB 117
++#define JH7110_SYSRST_TIMER0 118
++#define JH7110_SYSRST_TIMER1 119
++#define JH7110_SYSRST_TIMER2 120
++#define JH7110_SYSRST_TIMER3 121
++#define JH7110_SYSRST_INT_CTRL_APB 122
++#define JH7110_SYSRST_TEMP_APB 123
++#define JH7110_SYSRST_TEMP_CORE 124
++#define JH7110_SYSRST_JTAG_CERTIFICATION 125
++
++#define JH7110_SYSRST_END 126
++
++#endif /* __DT_BINDINGS_RESET_STARFIVE_JH7110_CRG_H__ */
+--
+2.20.1
+
--- /dev/null
+From 8359145605e912951246c41722d15b8dd35c6732 Mon Sep 17 00:00:00 2001
+From: Emil Renner Berthing <kernel@esmil.dk>
+Date: Sat, 1 Apr 2023 19:19:14 +0800
+Subject: [PATCH 06/95] dt-bindings: clock: Add StarFive JH7110 always-on clock
+ and reset generator
+
+Add bindings for the always-on clock and reset generator (AONCRG) on the
+JH7110 RISC-V SoC by StarFive Ltd.
+
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+Reviewed-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ .../clock/starfive,jh7110-aoncrg.yaml | 107 ++++++++++++++++++
+ .../dt-bindings/clock/starfive,jh7110-crg.h | 18 +++
+ .../dt-bindings/reset/starfive,jh7110-crg.h | 12 ++
+ 3 files changed, 137 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/clock/starfive,jh7110-aoncrg.yaml
+
+diff --git a/Documentation/devicetree/bindings/clock/starfive,jh7110-aoncrg.yaml b/Documentation/devicetree/bindings/clock/starfive,jh7110-aoncrg.yaml
+new file mode 100644
+index 000000000000..923680a44aef
+--- /dev/null
++++ b/Documentation/devicetree/bindings/clock/starfive,jh7110-aoncrg.yaml
+@@ -0,0 +1,107 @@
++# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/clock/starfive,jh7110-aoncrg.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: StarFive JH7110 Always-On Clock and Reset Generator
++
++maintainers:
++ - Emil Renner Berthing <kernel@esmil.dk>
++
++properties:
++ compatible:
++ const: starfive,jh7110-aoncrg
++
++ reg:
++ maxItems: 1
++
++ clocks:
++ oneOf:
++ - items:
++ - description: Main Oscillator (24 MHz)
++ - description: GMAC0 RMII reference or GMAC0 RGMII RX
++ - description: STG AXI/AHB
++ - description: APB Bus
++ - description: GMAC0 GTX
++
++ - items:
++ - description: Main Oscillator (24 MHz)
++ - description: GMAC0 RMII reference or GMAC0 RGMII RX
++ - description: STG AXI/AHB or GMAC0 RGMII RX
++ - description: APB Bus or STG AXI/AHB
++ - description: GMAC0 GTX or APB Bus
++ - description: RTC Oscillator (32.768 kHz) or GMAC0 GTX
++
++ - items:
++ - description: Main Oscillator (24 MHz)
++ - description: GMAC0 RMII reference
++ - description: GMAC0 RGMII RX
++ - description: STG AXI/AHB
++ - description: APB Bus
++ - description: GMAC0 GTX
++ - description: RTC Oscillator (32.768 kHz)
++
++ clock-names:
++ oneOf:
++ - minItems: 5
++ items:
++ - const: osc
++ - enum:
++ - gmac0_rmii_refin
++ - gmac0_rgmii_rxin
++ - const: stg_axiahb
++ - const: apb_bus
++ - const: gmac0_gtxclk
++ - const: rtc_osc
++
++ - minItems: 6
++ items:
++ - const: osc
++ - const: gmac0_rmii_refin
++ - const: gmac0_rgmii_rxin
++ - const: stg_axiahb
++ - const: apb_bus
++ - const: gmac0_gtxclk
++ - const: rtc_osc
++
++ '#clock-cells':
++ const: 1
++ description:
++ See <dt-bindings/clock/starfive,jh7110-crg.h> for valid indices.
++
++ '#reset-cells':
++ const: 1
++ description:
++ See <dt-bindings/reset/starfive,jh7110-crg.h> for valid indices.
++
++required:
++ - compatible
++ - reg
++ - clocks
++ - clock-names
++ - '#clock-cells'
++ - '#reset-cells'
++
++additionalProperties: false
++
++examples:
++ - |
++ #include <dt-bindings/clock/starfive,jh7110-crg.h>
++
++ clock-controller@17000000 {
++ compatible = "starfive,jh7110-aoncrg";
++ reg = <0x17000000 0x10000>;
++ clocks = <&osc>, <&gmac0_rmii_refin>,
++ <&gmac0_rgmii_rxin>,
++ <&syscrg JH7110_SYSCLK_STG_AXIAHB>,
++ <&syscrg JH7110_SYSCLK_APB_BUS>,
++ <&syscrg JH7110_SYSCLK_GMAC0_GTXCLK>,
++ <&rtc_osc>;
++ clock-names = "osc", "gmac0_rmii_refin",
++ "gmac0_rgmii_rxin", "stg_axiahb",
++ "apb_bus", "gmac0_gtxclk",
++ "rtc_osc";
++ #clock-cells = <1>;
++ #reset-cells = <1>;
++ };
+diff --git a/include/dt-bindings/clock/starfive,jh7110-crg.h b/include/dt-bindings/clock/starfive,jh7110-crg.h
+index fdd1852e34cc..06257bfd9ac1 100644
+--- a/include/dt-bindings/clock/starfive,jh7110-crg.h
++++ b/include/dt-bindings/clock/starfive,jh7110-crg.h
+@@ -200,4 +200,22 @@
+
+ #define JH7110_SYSCLK_END 190
+
++/* AONCRG clocks */
++#define JH7110_AONCLK_OSC_DIV4 0
++#define JH7110_AONCLK_APB_FUNC 1
++#define JH7110_AONCLK_GMAC0_AHB 2
++#define JH7110_AONCLK_GMAC0_AXI 3
++#define JH7110_AONCLK_GMAC0_RMII_RTX 4
++#define JH7110_AONCLK_GMAC0_TX 5
++#define JH7110_AONCLK_GMAC0_TX_INV 6
++#define JH7110_AONCLK_GMAC0_RX 7
++#define JH7110_AONCLK_GMAC0_RX_INV 8
++#define JH7110_AONCLK_OTPC_APB 9
++#define JH7110_AONCLK_RTC_APB 10
++#define JH7110_AONCLK_RTC_INTERNAL 11
++#define JH7110_AONCLK_RTC_32K 12
++#define JH7110_AONCLK_RTC_CAL 13
++
++#define JH7110_AONCLK_END 14
++
+ #endif /* __DT_BINDINGS_CLOCK_STARFIVE_JH7110_CRG_H__ */
+diff --git a/include/dt-bindings/reset/starfive,jh7110-crg.h b/include/dt-bindings/reset/starfive,jh7110-crg.h
+index b88216a4fe40..d78e38690ceb 100644
+--- a/include/dt-bindings/reset/starfive,jh7110-crg.h
++++ b/include/dt-bindings/reset/starfive,jh7110-crg.h
+@@ -139,4 +139,16 @@
+
+ #define JH7110_SYSRST_END 126
+
++/* AONCRG resets */
++#define JH7110_AONRST_GMAC0_AXI 0
++#define JH7110_AONRST_GMAC0_AHB 1
++#define JH7110_AONRST_IOMUX 2
++#define JH7110_AONRST_PMU_APB 3
++#define JH7110_AONRST_PMU_WKUP 4
++#define JH7110_AONRST_RTC_APB 5
++#define JH7110_AONRST_RTC_CAL 6
++#define JH7110_AONRST_RTC_32K 7
++
++#define JH7110_AONRST_END 8
++
+ #endif /* __DT_BINDINGS_RESET_STARFIVE_JH7110_CRG_H__ */
+--
+2.20.1
+
--- /dev/null
+From 83fa668fbb9c5aeafd5ade688f9c0e434792fc1c Mon Sep 17 00:00:00 2001
+From: Hal Feng <hal.feng@starfivetech.com>
+Date: Sat, 1 Apr 2023 19:19:15 +0800
+Subject: [PATCH 07/95] clk: starfive: Replace SOC_STARFIVE with ARCH_STARFIVE
+
+Using ARCH_FOO symbol is preferred than SOC_FOO.
+Set obj-y for starfive/ in Makefile, so the StarFive drivers
+can be compiled with COMPILE_TEST=y but ARCH_STARFIVE=n.
+
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+Reviewed-by: Heiko Stuebner <heiko.stuebner@vrull.eu>
+---
+ drivers/clk/Makefile | 2 +-
+ drivers/clk/starfive/Kconfig | 6 +++---
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
+index e3ca0d058a25..3bed88d67a3a 100644
+--- a/drivers/clk/Makefile
++++ b/drivers/clk/Makefile
+@@ -117,7 +117,7 @@ obj-$(CONFIG_PLAT_SPEAR) += spear/
+ obj-y += sprd/
+ obj-$(CONFIG_ARCH_STI) += st/
+ obj-$(CONFIG_ARCH_STM32) += stm32/
+-obj-$(CONFIG_SOC_STARFIVE) += starfive/
++obj-y += starfive/
+ obj-$(CONFIG_ARCH_SUNXI) += sunxi/
+ obj-y += sunxi-ng/
+ obj-$(CONFIG_ARCH_TEGRA) += tegra/
+diff --git a/drivers/clk/starfive/Kconfig b/drivers/clk/starfive/Kconfig
+index 003bd2d56ce7..ef3517f4a276 100644
+--- a/drivers/clk/starfive/Kconfig
++++ b/drivers/clk/starfive/Kconfig
+@@ -2,8 +2,8 @@
+
+ config CLK_STARFIVE_JH7100
+ bool "StarFive JH7100 clock support"
+- depends on SOC_STARFIVE || COMPILE_TEST
+- default SOC_STARFIVE
++ depends on ARCH_STARFIVE || COMPILE_TEST
++ default ARCH_STARFIVE
+ help
+ Say yes here to support the clock controller on the StarFive JH7100
+ SoC.
+@@ -11,7 +11,7 @@ config CLK_STARFIVE_JH7100
+ config CLK_STARFIVE_JH7100_AUDIO
+ tristate "StarFive JH7100 audio clock support"
+ depends on CLK_STARFIVE_JH7100
+- default m if SOC_STARFIVE
++ default m if ARCH_STARFIVE
+ help
+ Say Y or M here to support the audio clocks on the StarFive JH7100
+ SoC.
+--
+2.20.1
+
--- /dev/null
+From ddc17d7bc56c7330af48d00ac2ef666564746171 Mon Sep 17 00:00:00 2001
+From: Emil Renner Berthing <kernel@esmil.dk>
+Date: Sat, 1 Apr 2023 19:19:16 +0800
+Subject: [PATCH 08/95] clk: starfive: Factor out common JH7100 and JH7110 code
+
+The clock control registers on the StarFive JH7100 and JH7110 work
+identically, so factor out the code then drivers for the two SoCs
+can share it without depending on each other. No functional change.
+
+Tested-by: Tommaso Merciai <tomm.merciai@gmail.com>
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ drivers/clk/starfive/Kconfig | 5 +
+ drivers/clk/starfive/Makefile | 3 +-
+ drivers/clk/starfive/clk-starfive-jh7100.c | 325 --------------------
+ drivers/clk/starfive/clk-starfive-jh7100.h | 2 +
+ drivers/clk/starfive/clk-starfive-jh71x0.c | 333 +++++++++++++++++++++
+ 5 files changed, 342 insertions(+), 326 deletions(-)
+ create mode 100644 drivers/clk/starfive/clk-starfive-jh71x0.c
+
+diff --git a/drivers/clk/starfive/Kconfig b/drivers/clk/starfive/Kconfig
+index ef3517f4a276..3ceeb19b5eda 100644
+--- a/drivers/clk/starfive/Kconfig
++++ b/drivers/clk/starfive/Kconfig
+@@ -1,8 +1,12 @@
+ # SPDX-License-Identifier: GPL-2.0
+
++config CLK_STARFIVE_JH71X0
++ bool
++
+ config CLK_STARFIVE_JH7100
+ bool "StarFive JH7100 clock support"
+ depends on ARCH_STARFIVE || COMPILE_TEST
++ select CLK_STARFIVE_JH71X0
+ default ARCH_STARFIVE
+ help
+ Say yes here to support the clock controller on the StarFive JH7100
+@@ -11,6 +15,7 @@ config CLK_STARFIVE_JH7100
+ config CLK_STARFIVE_JH7100_AUDIO
+ tristate "StarFive JH7100 audio clock support"
+ depends on CLK_STARFIVE_JH7100
++ select CLK_STARFIVE_JH71X0
+ default m if ARCH_STARFIVE
+ help
+ Say Y or M here to support the audio clocks on the StarFive JH7100
+diff --git a/drivers/clk/starfive/Makefile b/drivers/clk/starfive/Makefile
+index 0fa8ecb9ec1c..82edfa9f9cb8 100644
+--- a/drivers/clk/starfive/Makefile
++++ b/drivers/clk/starfive/Makefile
+@@ -1,4 +1,5 @@
+ # SPDX-License-Identifier: GPL-2.0
+-# StarFive Clock
++obj-$(CONFIG_CLK_STARFIVE_JH71X0) += clk-starfive-jh71x0.o
++
+ obj-$(CONFIG_CLK_STARFIVE_JH7100) += clk-starfive-jh7100.o
+ obj-$(CONFIG_CLK_STARFIVE_JH7100_AUDIO) += clk-starfive-jh7100-audio.o
+diff --git a/drivers/clk/starfive/clk-starfive-jh7100.c b/drivers/clk/starfive/clk-starfive-jh7100.c
+index 691aeebc7092..eea52f16af0d 100644
+--- a/drivers/clk/starfive/clk-starfive-jh7100.c
++++ b/drivers/clk/starfive/clk-starfive-jh7100.c
+@@ -7,15 +7,10 @@
+ * Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
+ */
+
+-#include <linux/bits.h>
+ #include <linux/clk-provider.h>
+-#include <linux/debugfs.h>
+ #include <linux/device.h>
+ #include <linux/init.h>
+-#include <linux/io.h>
+-#include <linux/kernel.h>
+ #include <linux/mod_devicetable.h>
+-#include <linux/module.h>
+ #include <linux/platform_device.h>
+
+ #include <dt-bindings/clock/starfive-jh7100.h>
+@@ -269,326 +264,6 @@ static const struct jh7100_clk_data jh7100_clk_data[] __initconst = {
+ JH7100_GATE(JH7100_CLK_SYSERR_APB, "syserr_apb", 0, JH7100_CLK_APB2_BUS),
+ };
+
+-static struct jh7100_clk *jh7100_clk_from(struct clk_hw *hw)
+-{
+- return container_of(hw, struct jh7100_clk, hw);
+-}
+-
+-static struct jh7100_clk_priv *jh7100_priv_from(struct jh7100_clk *clk)
+-{
+- return container_of(clk, struct jh7100_clk_priv, reg[clk->idx]);
+-}
+-
+-static u32 jh7100_clk_reg_get(struct jh7100_clk *clk)
+-{
+- struct jh7100_clk_priv *priv = jh7100_priv_from(clk);
+- void __iomem *reg = priv->base + 4 * clk->idx;
+-
+- return readl_relaxed(reg);
+-}
+-
+-static void jh7100_clk_reg_rmw(struct jh7100_clk *clk, u32 mask, u32 value)
+-{
+- struct jh7100_clk_priv *priv = jh7100_priv_from(clk);
+- void __iomem *reg = priv->base + 4 * clk->idx;
+- unsigned long flags;
+-
+- spin_lock_irqsave(&priv->rmw_lock, flags);
+- value |= readl_relaxed(reg) & ~mask;
+- writel_relaxed(value, reg);
+- spin_unlock_irqrestore(&priv->rmw_lock, flags);
+-}
+-
+-static int jh7100_clk_enable(struct clk_hw *hw)
+-{
+- struct jh7100_clk *clk = jh7100_clk_from(hw);
+-
+- jh7100_clk_reg_rmw(clk, JH7100_CLK_ENABLE, JH7100_CLK_ENABLE);
+- return 0;
+-}
+-
+-static void jh7100_clk_disable(struct clk_hw *hw)
+-{
+- struct jh7100_clk *clk = jh7100_clk_from(hw);
+-
+- jh7100_clk_reg_rmw(clk, JH7100_CLK_ENABLE, 0);
+-}
+-
+-static int jh7100_clk_is_enabled(struct clk_hw *hw)
+-{
+- struct jh7100_clk *clk = jh7100_clk_from(hw);
+-
+- return !!(jh7100_clk_reg_get(clk) & JH7100_CLK_ENABLE);
+-}
+-
+-static unsigned long jh7100_clk_recalc_rate(struct clk_hw *hw,
+- unsigned long parent_rate)
+-{
+- struct jh7100_clk *clk = jh7100_clk_from(hw);
+- u32 div = jh7100_clk_reg_get(clk) & JH7100_CLK_DIV_MASK;
+-
+- return div ? parent_rate / div : 0;
+-}
+-
+-static int jh7100_clk_determine_rate(struct clk_hw *hw,
+- struct clk_rate_request *req)
+-{
+- struct jh7100_clk *clk = jh7100_clk_from(hw);
+- unsigned long parent = req->best_parent_rate;
+- unsigned long rate = clamp(req->rate, req->min_rate, req->max_rate);
+- unsigned long div = min_t(unsigned long, DIV_ROUND_UP(parent, rate), clk->max_div);
+- unsigned long result = parent / div;
+-
+- /*
+- * we want the result clamped by min_rate and max_rate if possible:
+- * case 1: div hits the max divider value, which means it's less than
+- * parent / rate, so the result is greater than rate and min_rate in
+- * particular. we can't do anything about result > max_rate because the
+- * divider doesn't go any further.
+- * case 2: div = DIV_ROUND_UP(parent, rate) which means the result is
+- * always lower or equal to rate and max_rate. however the result may
+- * turn out lower than min_rate, but then the next higher rate is fine:
+- * div - 1 = ceil(parent / rate) - 1 < parent / rate
+- * and thus
+- * min_rate <= rate < parent / (div - 1)
+- */
+- if (result < req->min_rate && div > 1)
+- result = parent / (div - 1);
+-
+- req->rate = result;
+- return 0;
+-}
+-
+-static int jh7100_clk_set_rate(struct clk_hw *hw,
+- unsigned long rate,
+- unsigned long parent_rate)
+-{
+- struct jh7100_clk *clk = jh7100_clk_from(hw);
+- unsigned long div = clamp(DIV_ROUND_CLOSEST(parent_rate, rate),
+- 1UL, (unsigned long)clk->max_div);
+-
+- jh7100_clk_reg_rmw(clk, JH7100_CLK_DIV_MASK, div);
+- return 0;
+-}
+-
+-static unsigned long jh7100_clk_frac_recalc_rate(struct clk_hw *hw,
+- unsigned long parent_rate)
+-{
+- struct jh7100_clk *clk = jh7100_clk_from(hw);
+- u32 reg = jh7100_clk_reg_get(clk);
+- unsigned long div100 = 100 * (reg & JH7100_CLK_INT_MASK) +
+- ((reg & JH7100_CLK_FRAC_MASK) >> JH7100_CLK_FRAC_SHIFT);
+-
+- return (div100 >= JH7100_CLK_FRAC_MIN) ? 100 * parent_rate / div100 : 0;
+-}
+-
+-static int jh7100_clk_frac_determine_rate(struct clk_hw *hw,
+- struct clk_rate_request *req)
+-{
+- unsigned long parent100 = 100 * req->best_parent_rate;
+- unsigned long rate = clamp(req->rate, req->min_rate, req->max_rate);
+- unsigned long div100 = clamp(DIV_ROUND_CLOSEST(parent100, rate),
+- JH7100_CLK_FRAC_MIN, JH7100_CLK_FRAC_MAX);
+- unsigned long result = parent100 / div100;
+-
+- /* clamp the result as in jh7100_clk_determine_rate() above */
+- if (result > req->max_rate && div100 < JH7100_CLK_FRAC_MAX)
+- result = parent100 / (div100 + 1);
+- if (result < req->min_rate && div100 > JH7100_CLK_FRAC_MIN)
+- result = parent100 / (div100 - 1);
+-
+- req->rate = result;
+- return 0;
+-}
+-
+-static int jh7100_clk_frac_set_rate(struct clk_hw *hw,
+- unsigned long rate,
+- unsigned long parent_rate)
+-{
+- struct jh7100_clk *clk = jh7100_clk_from(hw);
+- unsigned long div100 = clamp(DIV_ROUND_CLOSEST(100 * parent_rate, rate),
+- JH7100_CLK_FRAC_MIN, JH7100_CLK_FRAC_MAX);
+- u32 value = ((div100 % 100) << JH7100_CLK_FRAC_SHIFT) | (div100 / 100);
+-
+- jh7100_clk_reg_rmw(clk, JH7100_CLK_DIV_MASK, value);
+- return 0;
+-}
+-
+-static u8 jh7100_clk_get_parent(struct clk_hw *hw)
+-{
+- struct jh7100_clk *clk = jh7100_clk_from(hw);
+- u32 value = jh7100_clk_reg_get(clk);
+-
+- return (value & JH7100_CLK_MUX_MASK) >> JH7100_CLK_MUX_SHIFT;
+-}
+-
+-static int jh7100_clk_set_parent(struct clk_hw *hw, u8 index)
+-{
+- struct jh7100_clk *clk = jh7100_clk_from(hw);
+- u32 value = (u32)index << JH7100_CLK_MUX_SHIFT;
+-
+- jh7100_clk_reg_rmw(clk, JH7100_CLK_MUX_MASK, value);
+- return 0;
+-}
+-
+-static int jh7100_clk_mux_determine_rate(struct clk_hw *hw,
+- struct clk_rate_request *req)
+-{
+- return clk_mux_determine_rate_flags(hw, req, 0);
+-}
+-
+-static int jh7100_clk_get_phase(struct clk_hw *hw)
+-{
+- struct jh7100_clk *clk = jh7100_clk_from(hw);
+- u32 value = jh7100_clk_reg_get(clk);
+-
+- return (value & JH7100_CLK_INVERT) ? 180 : 0;
+-}
+-
+-static int jh7100_clk_set_phase(struct clk_hw *hw, int degrees)
+-{
+- struct jh7100_clk *clk = jh7100_clk_from(hw);
+- u32 value;
+-
+- if (degrees == 0)
+- value = 0;
+- else if (degrees == 180)
+- value = JH7100_CLK_INVERT;
+- else
+- return -EINVAL;
+-
+- jh7100_clk_reg_rmw(clk, JH7100_CLK_INVERT, value);
+- return 0;
+-}
+-
+-#ifdef CONFIG_DEBUG_FS
+-static void jh7100_clk_debug_init(struct clk_hw *hw, struct dentry *dentry)
+-{
+- static const struct debugfs_reg32 jh7100_clk_reg = {
+- .name = "CTRL",
+- .offset = 0,
+- };
+- struct jh7100_clk *clk = jh7100_clk_from(hw);
+- struct jh7100_clk_priv *priv = jh7100_priv_from(clk);
+- struct debugfs_regset32 *regset;
+-
+- regset = devm_kzalloc(priv->dev, sizeof(*regset), GFP_KERNEL);
+- if (!regset)
+- return;
+-
+- regset->regs = &jh7100_clk_reg;
+- regset->nregs = 1;
+- regset->base = priv->base + 4 * clk->idx;
+-
+- debugfs_create_regset32("registers", 0400, dentry, regset);
+-}
+-#else
+-#define jh7100_clk_debug_init NULL
+-#endif
+-
+-static const struct clk_ops jh7100_clk_gate_ops = {
+- .enable = jh7100_clk_enable,
+- .disable = jh7100_clk_disable,
+- .is_enabled = jh7100_clk_is_enabled,
+- .debug_init = jh7100_clk_debug_init,
+-};
+-
+-static const struct clk_ops jh7100_clk_div_ops = {
+- .recalc_rate = jh7100_clk_recalc_rate,
+- .determine_rate = jh7100_clk_determine_rate,
+- .set_rate = jh7100_clk_set_rate,
+- .debug_init = jh7100_clk_debug_init,
+-};
+-
+-static const struct clk_ops jh7100_clk_fdiv_ops = {
+- .recalc_rate = jh7100_clk_frac_recalc_rate,
+- .determine_rate = jh7100_clk_frac_determine_rate,
+- .set_rate = jh7100_clk_frac_set_rate,
+- .debug_init = jh7100_clk_debug_init,
+-};
+-
+-static const struct clk_ops jh7100_clk_gdiv_ops = {
+- .enable = jh7100_clk_enable,
+- .disable = jh7100_clk_disable,
+- .is_enabled = jh7100_clk_is_enabled,
+- .recalc_rate = jh7100_clk_recalc_rate,
+- .determine_rate = jh7100_clk_determine_rate,
+- .set_rate = jh7100_clk_set_rate,
+- .debug_init = jh7100_clk_debug_init,
+-};
+-
+-static const struct clk_ops jh7100_clk_mux_ops = {
+- .determine_rate = jh7100_clk_mux_determine_rate,
+- .set_parent = jh7100_clk_set_parent,
+- .get_parent = jh7100_clk_get_parent,
+- .debug_init = jh7100_clk_debug_init,
+-};
+-
+-static const struct clk_ops jh7100_clk_gmux_ops = {
+- .enable = jh7100_clk_enable,
+- .disable = jh7100_clk_disable,
+- .is_enabled = jh7100_clk_is_enabled,
+- .determine_rate = jh7100_clk_mux_determine_rate,
+- .set_parent = jh7100_clk_set_parent,
+- .get_parent = jh7100_clk_get_parent,
+- .debug_init = jh7100_clk_debug_init,
+-};
+-
+-static const struct clk_ops jh7100_clk_mdiv_ops = {
+- .recalc_rate = jh7100_clk_recalc_rate,
+- .determine_rate = jh7100_clk_determine_rate,
+- .get_parent = jh7100_clk_get_parent,
+- .set_parent = jh7100_clk_set_parent,
+- .set_rate = jh7100_clk_set_rate,
+- .debug_init = jh7100_clk_debug_init,
+-};
+-
+-static const struct clk_ops jh7100_clk_gmd_ops = {
+- .enable = jh7100_clk_enable,
+- .disable = jh7100_clk_disable,
+- .is_enabled = jh7100_clk_is_enabled,
+- .recalc_rate = jh7100_clk_recalc_rate,
+- .determine_rate = jh7100_clk_determine_rate,
+- .get_parent = jh7100_clk_get_parent,
+- .set_parent = jh7100_clk_set_parent,
+- .set_rate = jh7100_clk_set_rate,
+- .debug_init = jh7100_clk_debug_init,
+-};
+-
+-static const struct clk_ops jh7100_clk_inv_ops = {
+- .get_phase = jh7100_clk_get_phase,
+- .set_phase = jh7100_clk_set_phase,
+- .debug_init = jh7100_clk_debug_init,
+-};
+-
+-const struct clk_ops *starfive_jh7100_clk_ops(u32 max)
+-{
+- if (max & JH7100_CLK_DIV_MASK) {
+- if (max & JH7100_CLK_MUX_MASK) {
+- if (max & JH7100_CLK_ENABLE)
+- return &jh7100_clk_gmd_ops;
+- return &jh7100_clk_mdiv_ops;
+- }
+- if (max & JH7100_CLK_ENABLE)
+- return &jh7100_clk_gdiv_ops;
+- if (max == JH7100_CLK_FRAC_MAX)
+- return &jh7100_clk_fdiv_ops;
+- return &jh7100_clk_div_ops;
+- }
+-
+- if (max & JH7100_CLK_MUX_MASK) {
+- if (max & JH7100_CLK_ENABLE)
+- return &jh7100_clk_gmux_ops;
+- return &jh7100_clk_mux_ops;
+- }
+-
+- if (max & JH7100_CLK_ENABLE)
+- return &jh7100_clk_gate_ops;
+-
+- return &jh7100_clk_inv_ops;
+-}
+-EXPORT_SYMBOL_GPL(starfive_jh7100_clk_ops);
+-
+ static struct clk_hw *jh7100_clk_get(struct of_phandle_args *clkspec, void *data)
+ {
+ struct jh7100_clk_priv *priv = data;
+diff --git a/drivers/clk/starfive/clk-starfive-jh7100.h b/drivers/clk/starfive/clk-starfive-jh7100.h
+index f116be5740a5..a8ba6e25b5ce 100644
+--- a/drivers/clk/starfive/clk-starfive-jh7100.h
++++ b/drivers/clk/starfive/clk-starfive-jh7100.h
+@@ -4,6 +4,8 @@
+
+ #include <linux/bits.h>
+ #include <linux/clk-provider.h>
++#include <linux/device.h>
++#include <linux/spinlock.h>
+
+ /* register fields */
+ #define JH7100_CLK_ENABLE BIT(31)
+diff --git a/drivers/clk/starfive/clk-starfive-jh71x0.c b/drivers/clk/starfive/clk-starfive-jh71x0.c
+new file mode 100644
+index 000000000000..6c07b61b4a32
+--- /dev/null
++++ b/drivers/clk/starfive/clk-starfive-jh71x0.c
+@@ -0,0 +1,333 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * StarFive JH7100 Clock Generator Driver
++ *
++ * Copyright (C) 2021-2022 Emil Renner Berthing <kernel@esmil.dk>
++ */
++
++#include <linux/clk-provider.h>
++#include <linux/debugfs.h>
++#include <linux/device.h>
++#include <linux/io.h>
++
++#include "clk-starfive-jh7100.h"
++
++static struct jh7100_clk *jh7100_clk_from(struct clk_hw *hw)
++{
++ return container_of(hw, struct jh7100_clk, hw);
++}
++
++static struct jh7100_clk_priv *jh7100_priv_from(struct jh7100_clk *clk)
++{
++ return container_of(clk, struct jh7100_clk_priv, reg[clk->idx]);
++}
++
++static u32 jh7100_clk_reg_get(struct jh7100_clk *clk)
++{
++ struct jh7100_clk_priv *priv = jh7100_priv_from(clk);
++ void __iomem *reg = priv->base + 4 * clk->idx;
++
++ return readl_relaxed(reg);
++}
++
++static void jh7100_clk_reg_rmw(struct jh7100_clk *clk, u32 mask, u32 value)
++{
++ struct jh7100_clk_priv *priv = jh7100_priv_from(clk);
++ void __iomem *reg = priv->base + 4 * clk->idx;
++ unsigned long flags;
++
++ spin_lock_irqsave(&priv->rmw_lock, flags);
++ value |= readl_relaxed(reg) & ~mask;
++ writel_relaxed(value, reg);
++ spin_unlock_irqrestore(&priv->rmw_lock, flags);
++}
++
++static int jh7100_clk_enable(struct clk_hw *hw)
++{
++ struct jh7100_clk *clk = jh7100_clk_from(hw);
++
++ jh7100_clk_reg_rmw(clk, JH7100_CLK_ENABLE, JH7100_CLK_ENABLE);
++ return 0;
++}
++
++static void jh7100_clk_disable(struct clk_hw *hw)
++{
++ struct jh7100_clk *clk = jh7100_clk_from(hw);
++
++ jh7100_clk_reg_rmw(clk, JH7100_CLK_ENABLE, 0);
++}
++
++static int jh7100_clk_is_enabled(struct clk_hw *hw)
++{
++ struct jh7100_clk *clk = jh7100_clk_from(hw);
++
++ return !!(jh7100_clk_reg_get(clk) & JH7100_CLK_ENABLE);
++}
++
++static unsigned long jh7100_clk_recalc_rate(struct clk_hw *hw,
++ unsigned long parent_rate)
++{
++ struct jh7100_clk *clk = jh7100_clk_from(hw);
++ u32 div = jh7100_clk_reg_get(clk) & JH7100_CLK_DIV_MASK;
++
++ return div ? parent_rate / div : 0;
++}
++
++static int jh7100_clk_determine_rate(struct clk_hw *hw,
++ struct clk_rate_request *req)
++{
++ struct jh7100_clk *clk = jh7100_clk_from(hw);
++ unsigned long parent = req->best_parent_rate;
++ unsigned long rate = clamp(req->rate, req->min_rate, req->max_rate);
++ unsigned long div = min_t(unsigned long, DIV_ROUND_UP(parent, rate), clk->max_div);
++ unsigned long result = parent / div;
++
++ /*
++ * we want the result clamped by min_rate and max_rate if possible:
++ * case 1: div hits the max divider value, which means it's less than
++ * parent / rate, so the result is greater than rate and min_rate in
++ * particular. we can't do anything about result > max_rate because the
++ * divider doesn't go any further.
++ * case 2: div = DIV_ROUND_UP(parent, rate) which means the result is
++ * always lower or equal to rate and max_rate. however the result may
++ * turn out lower than min_rate, but then the next higher rate is fine:
++ * div - 1 = ceil(parent / rate) - 1 < parent / rate
++ * and thus
++ * min_rate <= rate < parent / (div - 1)
++ */
++ if (result < req->min_rate && div > 1)
++ result = parent / (div - 1);
++
++ req->rate = result;
++ return 0;
++}
++
++static int jh7100_clk_set_rate(struct clk_hw *hw,
++ unsigned long rate,
++ unsigned long parent_rate)
++{
++ struct jh7100_clk *clk = jh7100_clk_from(hw);
++ unsigned long div = clamp(DIV_ROUND_CLOSEST(parent_rate, rate),
++ 1UL, (unsigned long)clk->max_div);
++
++ jh7100_clk_reg_rmw(clk, JH7100_CLK_DIV_MASK, div);
++ return 0;
++}
++
++static unsigned long jh7100_clk_frac_recalc_rate(struct clk_hw *hw,
++ unsigned long parent_rate)
++{
++ struct jh7100_clk *clk = jh7100_clk_from(hw);
++ u32 reg = jh7100_clk_reg_get(clk);
++ unsigned long div100 = 100 * (reg & JH7100_CLK_INT_MASK) +
++ ((reg & JH7100_CLK_FRAC_MASK) >> JH7100_CLK_FRAC_SHIFT);
++
++ return (div100 >= JH7100_CLK_FRAC_MIN) ? 100 * parent_rate / div100 : 0;
++}
++
++static int jh7100_clk_frac_determine_rate(struct clk_hw *hw,
++ struct clk_rate_request *req)
++{
++ unsigned long parent100 = 100 * req->best_parent_rate;
++ unsigned long rate = clamp(req->rate, req->min_rate, req->max_rate);
++ unsigned long div100 = clamp(DIV_ROUND_CLOSEST(parent100, rate),
++ JH7100_CLK_FRAC_MIN, JH7100_CLK_FRAC_MAX);
++ unsigned long result = parent100 / div100;
++
++ /* clamp the result as in jh7100_clk_determine_rate() above */
++ if (result > req->max_rate && div100 < JH7100_CLK_FRAC_MAX)
++ result = parent100 / (div100 + 1);
++ if (result < req->min_rate && div100 > JH7100_CLK_FRAC_MIN)
++ result = parent100 / (div100 - 1);
++
++ req->rate = result;
++ return 0;
++}
++
++static int jh7100_clk_frac_set_rate(struct clk_hw *hw,
++ unsigned long rate,
++ unsigned long parent_rate)
++{
++ struct jh7100_clk *clk = jh7100_clk_from(hw);
++ unsigned long div100 = clamp(DIV_ROUND_CLOSEST(100 * parent_rate, rate),
++ JH7100_CLK_FRAC_MIN, JH7100_CLK_FRAC_MAX);
++ u32 value = ((div100 % 100) << JH7100_CLK_FRAC_SHIFT) | (div100 / 100);
++
++ jh7100_clk_reg_rmw(clk, JH7100_CLK_DIV_MASK, value);
++ return 0;
++}
++
++static u8 jh7100_clk_get_parent(struct clk_hw *hw)
++{
++ struct jh7100_clk *clk = jh7100_clk_from(hw);
++ u32 value = jh7100_clk_reg_get(clk);
++
++ return (value & JH7100_CLK_MUX_MASK) >> JH7100_CLK_MUX_SHIFT;
++}
++
++static int jh7100_clk_set_parent(struct clk_hw *hw, u8 index)
++{
++ struct jh7100_clk *clk = jh7100_clk_from(hw);
++ u32 value = (u32)index << JH7100_CLK_MUX_SHIFT;
++
++ jh7100_clk_reg_rmw(clk, JH7100_CLK_MUX_MASK, value);
++ return 0;
++}
++
++static int jh7100_clk_mux_determine_rate(struct clk_hw *hw,
++ struct clk_rate_request *req)
++{
++ return clk_mux_determine_rate_flags(hw, req, 0);
++}
++
++static int jh7100_clk_get_phase(struct clk_hw *hw)
++{
++ struct jh7100_clk *clk = jh7100_clk_from(hw);
++ u32 value = jh7100_clk_reg_get(clk);
++
++ return (value & JH7100_CLK_INVERT) ? 180 : 0;
++}
++
++static int jh7100_clk_set_phase(struct clk_hw *hw, int degrees)
++{
++ struct jh7100_clk *clk = jh7100_clk_from(hw);
++ u32 value;
++
++ if (degrees == 0)
++ value = 0;
++ else if (degrees == 180)
++ value = JH7100_CLK_INVERT;
++ else
++ return -EINVAL;
++
++ jh7100_clk_reg_rmw(clk, JH7100_CLK_INVERT, value);
++ return 0;
++}
++
++#ifdef CONFIG_DEBUG_FS
++static void jh7100_clk_debug_init(struct clk_hw *hw, struct dentry *dentry)
++{
++ static const struct debugfs_reg32 jh7100_clk_reg = {
++ .name = "CTRL",
++ .offset = 0,
++ };
++ struct jh7100_clk *clk = jh7100_clk_from(hw);
++ struct jh7100_clk_priv *priv = jh7100_priv_from(clk);
++ struct debugfs_regset32 *regset;
++
++ regset = devm_kzalloc(priv->dev, sizeof(*regset), GFP_KERNEL);
++ if (!regset)
++ return;
++
++ regset->regs = &jh7100_clk_reg;
++ regset->nregs = 1;
++ regset->base = priv->base + 4 * clk->idx;
++
++ debugfs_create_regset32("registers", 0400, dentry, regset);
++}
++#else
++#define jh7100_clk_debug_init NULL
++#endif
++
++static const struct clk_ops jh7100_clk_gate_ops = {
++ .enable = jh7100_clk_enable,
++ .disable = jh7100_clk_disable,
++ .is_enabled = jh7100_clk_is_enabled,
++ .debug_init = jh7100_clk_debug_init,
++};
++
++static const struct clk_ops jh7100_clk_div_ops = {
++ .recalc_rate = jh7100_clk_recalc_rate,
++ .determine_rate = jh7100_clk_determine_rate,
++ .set_rate = jh7100_clk_set_rate,
++ .debug_init = jh7100_clk_debug_init,
++};
++
++static const struct clk_ops jh7100_clk_fdiv_ops = {
++ .recalc_rate = jh7100_clk_frac_recalc_rate,
++ .determine_rate = jh7100_clk_frac_determine_rate,
++ .set_rate = jh7100_clk_frac_set_rate,
++ .debug_init = jh7100_clk_debug_init,
++};
++
++static const struct clk_ops jh7100_clk_gdiv_ops = {
++ .enable = jh7100_clk_enable,
++ .disable = jh7100_clk_disable,
++ .is_enabled = jh7100_clk_is_enabled,
++ .recalc_rate = jh7100_clk_recalc_rate,
++ .determine_rate = jh7100_clk_determine_rate,
++ .set_rate = jh7100_clk_set_rate,
++ .debug_init = jh7100_clk_debug_init,
++};
++
++static const struct clk_ops jh7100_clk_mux_ops = {
++ .determine_rate = jh7100_clk_mux_determine_rate,
++ .set_parent = jh7100_clk_set_parent,
++ .get_parent = jh7100_clk_get_parent,
++ .debug_init = jh7100_clk_debug_init,
++};
++
++static const struct clk_ops jh7100_clk_gmux_ops = {
++ .enable = jh7100_clk_enable,
++ .disable = jh7100_clk_disable,
++ .is_enabled = jh7100_clk_is_enabled,
++ .determine_rate = jh7100_clk_mux_determine_rate,
++ .set_parent = jh7100_clk_set_parent,
++ .get_parent = jh7100_clk_get_parent,
++ .debug_init = jh7100_clk_debug_init,
++};
++
++static const struct clk_ops jh7100_clk_mdiv_ops = {
++ .recalc_rate = jh7100_clk_recalc_rate,
++ .determine_rate = jh7100_clk_determine_rate,
++ .get_parent = jh7100_clk_get_parent,
++ .set_parent = jh7100_clk_set_parent,
++ .set_rate = jh7100_clk_set_rate,
++ .debug_init = jh7100_clk_debug_init,
++};
++
++static const struct clk_ops jh7100_clk_gmd_ops = {
++ .enable = jh7100_clk_enable,
++ .disable = jh7100_clk_disable,
++ .is_enabled = jh7100_clk_is_enabled,
++ .recalc_rate = jh7100_clk_recalc_rate,
++ .determine_rate = jh7100_clk_determine_rate,
++ .get_parent = jh7100_clk_get_parent,
++ .set_parent = jh7100_clk_set_parent,
++ .set_rate = jh7100_clk_set_rate,
++ .debug_init = jh7100_clk_debug_init,
++};
++
++static const struct clk_ops jh7100_clk_inv_ops = {
++ .get_phase = jh7100_clk_get_phase,
++ .set_phase = jh7100_clk_set_phase,
++ .debug_init = jh7100_clk_debug_init,
++};
++
++const struct clk_ops *starfive_jh7100_clk_ops(u32 max)
++{
++ if (max & JH7100_CLK_DIV_MASK) {
++ if (max & JH7100_CLK_MUX_MASK) {
++ if (max & JH7100_CLK_ENABLE)
++ return &jh7100_clk_gmd_ops;
++ return &jh7100_clk_mdiv_ops;
++ }
++ if (max & JH7100_CLK_ENABLE)
++ return &jh7100_clk_gdiv_ops;
++ if (max == JH7100_CLK_FRAC_MAX)
++ return &jh7100_clk_fdiv_ops;
++ return &jh7100_clk_div_ops;
++ }
++
++ if (max & JH7100_CLK_MUX_MASK) {
++ if (max & JH7100_CLK_ENABLE)
++ return &jh7100_clk_gmux_ops;
++ return &jh7100_clk_mux_ops;
++ }
++
++ if (max & JH7100_CLK_ENABLE)
++ return &jh7100_clk_gate_ops;
++
++ return &jh7100_clk_inv_ops;
++}
++EXPORT_SYMBOL_GPL(starfive_jh7100_clk_ops);
+--
+2.20.1
+
--- /dev/null
+From 7d2690739839b6c3cbf6b534e48b8b5b9169d27e Mon Sep 17 00:00:00 2001
+From: Emil Renner Berthing <kernel@esmil.dk>
+Date: Sat, 1 Apr 2023 19:19:17 +0800
+Subject: [PATCH 09/95] clk: starfive: Rename clk-starfive-jh7100.h to
+ clk-starfive-jh71x0.h
+
+Rename clk-starfive-jh7100.h to clk-starfive-jh71x0.h for making
+the code to be common.
+
+Tested-by: Tommaso Merciai <tomm.merciai@gmail.com>
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ drivers/clk/starfive/clk-starfive-jh7100-audio.c | 2 +-
+ drivers/clk/starfive/clk-starfive-jh7100.c | 2 +-
+ drivers/clk/starfive/clk-starfive-jh71x0.c | 2 +-
+ .../starfive/{clk-starfive-jh7100.h => clk-starfive-jh71x0.h} | 0
+ 4 files changed, 3 insertions(+), 3 deletions(-)
+ rename drivers/clk/starfive/{clk-starfive-jh7100.h => clk-starfive-jh71x0.h} (100%)
+
+diff --git a/drivers/clk/starfive/clk-starfive-jh7100-audio.c b/drivers/clk/starfive/clk-starfive-jh7100-audio.c
+index 8473a65e219b..db0d9533bd9c 100644
+--- a/drivers/clk/starfive/clk-starfive-jh7100-audio.c
++++ b/drivers/clk/starfive/clk-starfive-jh7100-audio.c
+@@ -16,7 +16,7 @@
+
+ #include <dt-bindings/clock/starfive-jh7100-audio.h>
+
+-#include "clk-starfive-jh7100.h"
++#include "clk-starfive-jh71x0.h"
+
+ /* external clocks */
+ #define JH7100_AUDCLK_AUDIO_SRC (JH7100_AUDCLK_END + 0)
+diff --git a/drivers/clk/starfive/clk-starfive-jh7100.c b/drivers/clk/starfive/clk-starfive-jh7100.c
+index eea52f16af0d..662eb8f74c12 100644
+--- a/drivers/clk/starfive/clk-starfive-jh7100.c
++++ b/drivers/clk/starfive/clk-starfive-jh7100.c
+@@ -15,7 +15,7 @@
+
+ #include <dt-bindings/clock/starfive-jh7100.h>
+
+-#include "clk-starfive-jh7100.h"
++#include "clk-starfive-jh71x0.h"
+
+ /* external clocks */
+ #define JH7100_CLK_OSC_SYS (JH7100_CLK_END + 0)
+diff --git a/drivers/clk/starfive/clk-starfive-jh71x0.c b/drivers/clk/starfive/clk-starfive-jh71x0.c
+index 6c07b61b4a32..0140bdf27a01 100644
+--- a/drivers/clk/starfive/clk-starfive-jh71x0.c
++++ b/drivers/clk/starfive/clk-starfive-jh71x0.c
+@@ -10,7 +10,7 @@
+ #include <linux/device.h>
+ #include <linux/io.h>
+
+-#include "clk-starfive-jh7100.h"
++#include "clk-starfive-jh71x0.h"
+
+ static struct jh7100_clk *jh7100_clk_from(struct clk_hw *hw)
+ {
+diff --git a/drivers/clk/starfive/clk-starfive-jh7100.h b/drivers/clk/starfive/clk-starfive-jh71x0.h
+similarity index 100%
+rename from drivers/clk/starfive/clk-starfive-jh7100.h
+rename to drivers/clk/starfive/clk-starfive-jh71x0.h
+--
+2.20.1
+
--- /dev/null
+From 23ddaddf82fe7e91ffd6ae76347147a3dbaa8f72 Mon Sep 17 00:00:00 2001
+From: Emil Renner Berthing <kernel@esmil.dk>
+Date: Sat, 1 Apr 2023 19:19:18 +0800
+Subject: [PATCH 10/95] clk: starfive: Rename "jh7100" to "jh71x0" for the
+ common code
+
+Rename some variables from "jh7100" or "JH7100" to "jh71x0"
+or "JH71X0".
+
+Tested-by: Tommaso Merciai <tomm.merciai@gmail.com>
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ .../clk/starfive/clk-starfive-jh7100-audio.c | 72 ++--
+ drivers/clk/starfive/clk-starfive-jh7100.c | 389 +++++++++---------
+ drivers/clk/starfive/clk-starfive-jh71x0.c | 282 ++++++-------
+ drivers/clk/starfive/clk-starfive-jh71x0.h | 81 ++--
+ 4 files changed, 418 insertions(+), 406 deletions(-)
+
+diff --git a/drivers/clk/starfive/clk-starfive-jh7100-audio.c b/drivers/clk/starfive/clk-starfive-jh7100-audio.c
+index db0d9533bd9c..02aefb7264f8 100644
+--- a/drivers/clk/starfive/clk-starfive-jh7100-audio.c
++++ b/drivers/clk/starfive/clk-starfive-jh7100-audio.c
+@@ -28,66 +28,66 @@
+ #define JH7100_AUDCLK_I2SDAC_LRCLK_IOPAD (JH7100_AUDCLK_END + 6)
+ #define JH7100_AUDCLK_VAD_INTMEM (JH7100_AUDCLK_END + 7)
+
+-static const struct jh7100_clk_data jh7100_audclk_data[] = {
+- JH7100__GMD(JH7100_AUDCLK_ADC_MCLK, "adc_mclk", 0, 15, 2,
++static const struct jh71x0_clk_data jh7100_audclk_data[] = {
++ JH71X0__GMD(JH7100_AUDCLK_ADC_MCLK, "adc_mclk", 0, 15, 2,
+ JH7100_AUDCLK_AUDIO_SRC,
+ JH7100_AUDCLK_AUDIO_12288),
+- JH7100__GMD(JH7100_AUDCLK_I2S1_MCLK, "i2s1_mclk", 0, 15, 2,
++ JH71X0__GMD(JH7100_AUDCLK_I2S1_MCLK, "i2s1_mclk", 0, 15, 2,
+ JH7100_AUDCLK_AUDIO_SRC,
+ JH7100_AUDCLK_AUDIO_12288),
+- JH7100_GATE(JH7100_AUDCLK_I2SADC_APB, "i2sadc_apb", 0, JH7100_AUDCLK_APB0_BUS),
+- JH7100_MDIV(JH7100_AUDCLK_I2SADC_BCLK, "i2sadc_bclk", 31, 2,
++ JH71X0_GATE(JH7100_AUDCLK_I2SADC_APB, "i2sadc_apb", 0, JH7100_AUDCLK_APB0_BUS),
++ JH71X0_MDIV(JH7100_AUDCLK_I2SADC_BCLK, "i2sadc_bclk", 31, 2,
+ JH7100_AUDCLK_ADC_MCLK,
+ JH7100_AUDCLK_I2SADC_BCLK_IOPAD),
+- JH7100__INV(JH7100_AUDCLK_I2SADC_BCLK_N, "i2sadc_bclk_n", JH7100_AUDCLK_I2SADC_BCLK),
+- JH7100_MDIV(JH7100_AUDCLK_I2SADC_LRCLK, "i2sadc_lrclk", 63, 3,
++ JH71X0__INV(JH7100_AUDCLK_I2SADC_BCLK_N, "i2sadc_bclk_n", JH7100_AUDCLK_I2SADC_BCLK),
++ JH71X0_MDIV(JH7100_AUDCLK_I2SADC_LRCLK, "i2sadc_lrclk", 63, 3,
+ JH7100_AUDCLK_I2SADC_BCLK_N,
+ JH7100_AUDCLK_I2SADC_LRCLK_IOPAD,
+ JH7100_AUDCLK_I2SADC_BCLK),
+- JH7100_GATE(JH7100_AUDCLK_PDM_APB, "pdm_apb", 0, JH7100_AUDCLK_APB0_BUS),
+- JH7100__GMD(JH7100_AUDCLK_PDM_MCLK, "pdm_mclk", 0, 15, 2,
++ JH71X0_GATE(JH7100_AUDCLK_PDM_APB, "pdm_apb", 0, JH7100_AUDCLK_APB0_BUS),
++ JH71X0__GMD(JH7100_AUDCLK_PDM_MCLK, "pdm_mclk", 0, 15, 2,
+ JH7100_AUDCLK_AUDIO_SRC,
+ JH7100_AUDCLK_AUDIO_12288),
+- JH7100_GATE(JH7100_AUDCLK_I2SVAD_APB, "i2svad_apb", 0, JH7100_AUDCLK_APB0_BUS),
+- JH7100__GMD(JH7100_AUDCLK_SPDIF, "spdif", 0, 15, 2,
++ JH71X0_GATE(JH7100_AUDCLK_I2SVAD_APB, "i2svad_apb", 0, JH7100_AUDCLK_APB0_BUS),
++ JH71X0__GMD(JH7100_AUDCLK_SPDIF, "spdif", 0, 15, 2,
+ JH7100_AUDCLK_AUDIO_SRC,
+ JH7100_AUDCLK_AUDIO_12288),
+- JH7100_GATE(JH7100_AUDCLK_SPDIF_APB, "spdif_apb", 0, JH7100_AUDCLK_APB0_BUS),
+- JH7100_GATE(JH7100_AUDCLK_PWMDAC_APB, "pwmdac_apb", 0, JH7100_AUDCLK_APB0_BUS),
+- JH7100__GMD(JH7100_AUDCLK_DAC_MCLK, "dac_mclk", 0, 15, 2,
++ JH71X0_GATE(JH7100_AUDCLK_SPDIF_APB, "spdif_apb", 0, JH7100_AUDCLK_APB0_BUS),
++ JH71X0_GATE(JH7100_AUDCLK_PWMDAC_APB, "pwmdac_apb", 0, JH7100_AUDCLK_APB0_BUS),
++ JH71X0__GMD(JH7100_AUDCLK_DAC_MCLK, "dac_mclk", 0, 15, 2,
+ JH7100_AUDCLK_AUDIO_SRC,
+ JH7100_AUDCLK_AUDIO_12288),
+- JH7100_GATE(JH7100_AUDCLK_I2SDAC_APB, "i2sdac_apb", 0, JH7100_AUDCLK_APB0_BUS),
+- JH7100_MDIV(JH7100_AUDCLK_I2SDAC_BCLK, "i2sdac_bclk", 31, 2,
++ JH71X0_GATE(JH7100_AUDCLK_I2SDAC_APB, "i2sdac_apb", 0, JH7100_AUDCLK_APB0_BUS),
++ JH71X0_MDIV(JH7100_AUDCLK_I2SDAC_BCLK, "i2sdac_bclk", 31, 2,
+ JH7100_AUDCLK_DAC_MCLK,
+ JH7100_AUDCLK_I2SDAC_BCLK_IOPAD),
+- JH7100__INV(JH7100_AUDCLK_I2SDAC_BCLK_N, "i2sdac_bclk_n", JH7100_AUDCLK_I2SDAC_BCLK),
+- JH7100_MDIV(JH7100_AUDCLK_I2SDAC_LRCLK, "i2sdac_lrclk", 31, 2,
++ JH71X0__INV(JH7100_AUDCLK_I2SDAC_BCLK_N, "i2sdac_bclk_n", JH7100_AUDCLK_I2SDAC_BCLK),
++ JH71X0_MDIV(JH7100_AUDCLK_I2SDAC_LRCLK, "i2sdac_lrclk", 31, 2,
+ JH7100_AUDCLK_I2S1_MCLK,
+ JH7100_AUDCLK_I2SDAC_BCLK_IOPAD),
+- JH7100_GATE(JH7100_AUDCLK_I2S1_APB, "i2s1_apb", 0, JH7100_AUDCLK_APB0_BUS),
+- JH7100_MDIV(JH7100_AUDCLK_I2S1_BCLK, "i2s1_bclk", 31, 2,
++ JH71X0_GATE(JH7100_AUDCLK_I2S1_APB, "i2s1_apb", 0, JH7100_AUDCLK_APB0_BUS),
++ JH71X0_MDIV(JH7100_AUDCLK_I2S1_BCLK, "i2s1_bclk", 31, 2,
+ JH7100_AUDCLK_I2S1_MCLK,
+ JH7100_AUDCLK_I2SDAC_BCLK_IOPAD),
+- JH7100__INV(JH7100_AUDCLK_I2S1_BCLK_N, "i2s1_bclk_n", JH7100_AUDCLK_I2S1_BCLK),
+- JH7100_MDIV(JH7100_AUDCLK_I2S1_LRCLK, "i2s1_lrclk", 63, 3,
++ JH71X0__INV(JH7100_AUDCLK_I2S1_BCLK_N, "i2s1_bclk_n", JH7100_AUDCLK_I2S1_BCLK),
++ JH71X0_MDIV(JH7100_AUDCLK_I2S1_LRCLK, "i2s1_lrclk", 63, 3,
+ JH7100_AUDCLK_I2S1_BCLK_N,
+ JH7100_AUDCLK_I2SDAC_LRCLK_IOPAD),
+- JH7100_GATE(JH7100_AUDCLK_I2SDAC16K_APB, "i2s1dac16k_apb", 0, JH7100_AUDCLK_APB0_BUS),
+- JH7100__DIV(JH7100_AUDCLK_APB0_BUS, "apb0_bus", 8, JH7100_AUDCLK_DOM7AHB_BUS),
+- JH7100_GATE(JH7100_AUDCLK_DMA1P_AHB, "dma1p_ahb", 0, JH7100_AUDCLK_DOM7AHB_BUS),
+- JH7100_GATE(JH7100_AUDCLK_USB_APB, "usb_apb", CLK_IGNORE_UNUSED, JH7100_AUDCLK_APB_EN),
+- JH7100_GDIV(JH7100_AUDCLK_USB_LPM, "usb_lpm", CLK_IGNORE_UNUSED, 4, JH7100_AUDCLK_USB_APB),
+- JH7100_GDIV(JH7100_AUDCLK_USB_STB, "usb_stb", CLK_IGNORE_UNUSED, 3, JH7100_AUDCLK_USB_APB),
+- JH7100__DIV(JH7100_AUDCLK_APB_EN, "apb_en", 8, JH7100_AUDCLK_DOM7AHB_BUS),
+- JH7100__MUX(JH7100_AUDCLK_VAD_MEM, "vad_mem", 2,
++ JH71X0_GATE(JH7100_AUDCLK_I2SDAC16K_APB, "i2s1dac16k_apb", 0, JH7100_AUDCLK_APB0_BUS),
++ JH71X0__DIV(JH7100_AUDCLK_APB0_BUS, "apb0_bus", 8, JH7100_AUDCLK_DOM7AHB_BUS),
++ JH71X0_GATE(JH7100_AUDCLK_DMA1P_AHB, "dma1p_ahb", 0, JH7100_AUDCLK_DOM7AHB_BUS),
++ JH71X0_GATE(JH7100_AUDCLK_USB_APB, "usb_apb", CLK_IGNORE_UNUSED, JH7100_AUDCLK_APB_EN),
++ JH71X0_GDIV(JH7100_AUDCLK_USB_LPM, "usb_lpm", CLK_IGNORE_UNUSED, 4, JH7100_AUDCLK_USB_APB),
++ JH71X0_GDIV(JH7100_AUDCLK_USB_STB, "usb_stb", CLK_IGNORE_UNUSED, 3, JH7100_AUDCLK_USB_APB),
++ JH71X0__DIV(JH7100_AUDCLK_APB_EN, "apb_en", 8, JH7100_AUDCLK_DOM7AHB_BUS),
++ JH71X0__MUX(JH7100_AUDCLK_VAD_MEM, "vad_mem", 2,
+ JH7100_AUDCLK_VAD_INTMEM,
+ JH7100_AUDCLK_AUDIO_12288),
+ };
+
+ static struct clk_hw *jh7100_audclk_get(struct of_phandle_args *clkspec, void *data)
+ {
+- struct jh7100_clk_priv *priv = data;
++ struct jh71x0_clk_priv *priv = data;
+ unsigned int idx = clkspec->args[0];
+
+ if (idx < JH7100_AUDCLK_END)
+@@ -98,7 +98,7 @@ static struct clk_hw *jh7100_audclk_get(struct of_phandle_args *clkspec, void *d
+
+ static int jh7100_audclk_probe(struct platform_device *pdev)
+ {
+- struct jh7100_clk_priv *priv;
++ struct jh71x0_clk_priv *priv;
+ unsigned int idx;
+ int ret;
+
+@@ -117,12 +117,12 @@ static int jh7100_audclk_probe(struct platform_device *pdev)
+ struct clk_parent_data parents[4] = {};
+ struct clk_init_data init = {
+ .name = jh7100_audclk_data[idx].name,
+- .ops = starfive_jh7100_clk_ops(max),
++ .ops = starfive_jh71x0_clk_ops(max),
+ .parent_data = parents,
+- .num_parents = ((max & JH7100_CLK_MUX_MASK) >> JH7100_CLK_MUX_SHIFT) + 1,
++ .num_parents = ((max & JH71X0_CLK_MUX_MASK) >> JH71X0_CLK_MUX_SHIFT) + 1,
+ .flags = jh7100_audclk_data[idx].flags,
+ };
+- struct jh7100_clk *clk = &priv->reg[idx];
++ struct jh71x0_clk *clk = &priv->reg[idx];
+ unsigned int i;
+
+ for (i = 0; i < init.num_parents; i++) {
+@@ -140,7 +140,7 @@ static int jh7100_audclk_probe(struct platform_device *pdev)
+
+ clk->hw.init = &init;
+ clk->idx = idx;
+- clk->max_div = max & JH7100_CLK_DIV_MASK;
++ clk->max_div = max & JH71X0_CLK_DIV_MASK;
+
+ ret = devm_clk_hw_register(priv->dev, &clk->hw);
+ if (ret)
+diff --git a/drivers/clk/starfive/clk-starfive-jh7100.c b/drivers/clk/starfive/clk-starfive-jh7100.c
+index 662eb8f74c12..69cc11ea7e33 100644
+--- a/drivers/clk/starfive/clk-starfive-jh7100.c
++++ b/drivers/clk/starfive/clk-starfive-jh7100.c
+@@ -23,250 +23,253 @@
+ #define JH7100_CLK_GMAC_RMII_REF (JH7100_CLK_END + 2)
+ #define JH7100_CLK_GMAC_GR_MII_RX (JH7100_CLK_END + 3)
+
+-static const struct jh7100_clk_data jh7100_clk_data[] __initconst = {
+- JH7100__MUX(JH7100_CLK_CPUNDBUS_ROOT, "cpundbus_root", 4,
++static const struct jh71x0_clk_data jh7100_clk_data[] __initconst = {
++ JH71X0__MUX(JH7100_CLK_CPUNDBUS_ROOT, "cpundbus_root", 4,
+ JH7100_CLK_OSC_SYS,
+ JH7100_CLK_PLL0_OUT,
+ JH7100_CLK_PLL1_OUT,
+ JH7100_CLK_PLL2_OUT),
+- JH7100__MUX(JH7100_CLK_DLA_ROOT, "dla_root", 3,
++ JH71X0__MUX(JH7100_CLK_DLA_ROOT, "dla_root", 3,
+ JH7100_CLK_OSC_SYS,
+ JH7100_CLK_PLL1_OUT,
+ JH7100_CLK_PLL2_OUT),
+- JH7100__MUX(JH7100_CLK_DSP_ROOT, "dsp_root", 4,
++ JH71X0__MUX(JH7100_CLK_DSP_ROOT, "dsp_root", 4,
+ JH7100_CLK_OSC_SYS,
+ JH7100_CLK_PLL0_OUT,
+ JH7100_CLK_PLL1_OUT,
+ JH7100_CLK_PLL2_OUT),
+- JH7100__MUX(JH7100_CLK_GMACUSB_ROOT, "gmacusb_root", 3,
++ JH71X0__MUX(JH7100_CLK_GMACUSB_ROOT, "gmacusb_root", 3,
+ JH7100_CLK_OSC_SYS,
+ JH7100_CLK_PLL0_OUT,
+ JH7100_CLK_PLL2_OUT),
+- JH7100__MUX(JH7100_CLK_PERH0_ROOT, "perh0_root", 2,
++ JH71X0__MUX(JH7100_CLK_PERH0_ROOT, "perh0_root", 2,
+ JH7100_CLK_OSC_SYS,
+ JH7100_CLK_PLL0_OUT),
+- JH7100__MUX(JH7100_CLK_PERH1_ROOT, "perh1_root", 2,
++ JH71X0__MUX(JH7100_CLK_PERH1_ROOT, "perh1_root", 2,
+ JH7100_CLK_OSC_SYS,
+ JH7100_CLK_PLL2_OUT),
+- JH7100__MUX(JH7100_CLK_VIN_ROOT, "vin_root", 3,
++ JH71X0__MUX(JH7100_CLK_VIN_ROOT, "vin_root", 3,
+ JH7100_CLK_OSC_SYS,
+ JH7100_CLK_PLL1_OUT,
+ JH7100_CLK_PLL2_OUT),
+- JH7100__MUX(JH7100_CLK_VOUT_ROOT, "vout_root", 3,
++ JH71X0__MUX(JH7100_CLK_VOUT_ROOT, "vout_root", 3,
+ JH7100_CLK_OSC_AUD,
+ JH7100_CLK_PLL0_OUT,
+ JH7100_CLK_PLL2_OUT),
+- JH7100_GDIV(JH7100_CLK_AUDIO_ROOT, "audio_root", 0, 8, JH7100_CLK_PLL0_OUT),
+- JH7100__MUX(JH7100_CLK_CDECHIFI4_ROOT, "cdechifi4_root", 3,
++ JH71X0_GDIV(JH7100_CLK_AUDIO_ROOT, "audio_root", 0, 8, JH7100_CLK_PLL0_OUT),
++ JH71X0__MUX(JH7100_CLK_CDECHIFI4_ROOT, "cdechifi4_root", 3,
+ JH7100_CLK_OSC_SYS,
+ JH7100_CLK_PLL1_OUT,
+ JH7100_CLK_PLL2_OUT),
+- JH7100__MUX(JH7100_CLK_CDEC_ROOT, "cdec_root", 3,
++ JH71X0__MUX(JH7100_CLK_CDEC_ROOT, "cdec_root", 3,
+ JH7100_CLK_OSC_SYS,
+ JH7100_CLK_PLL0_OUT,
+ JH7100_CLK_PLL1_OUT),
+- JH7100__MUX(JH7100_CLK_VOUTBUS_ROOT, "voutbus_root", 3,
++ JH71X0__MUX(JH7100_CLK_VOUTBUS_ROOT, "voutbus_root", 3,
+ JH7100_CLK_OSC_AUD,
+ JH7100_CLK_PLL0_OUT,
+ JH7100_CLK_PLL2_OUT),
+- JH7100__DIV(JH7100_CLK_CPUNBUS_ROOT_DIV, "cpunbus_root_div", 2, JH7100_CLK_CPUNDBUS_ROOT),
+- JH7100__DIV(JH7100_CLK_DSP_ROOT_DIV, "dsp_root_div", 4, JH7100_CLK_DSP_ROOT),
+- JH7100__DIV(JH7100_CLK_PERH0_SRC, "perh0_src", 4, JH7100_CLK_PERH0_ROOT),
+- JH7100__DIV(JH7100_CLK_PERH1_SRC, "perh1_src", 4, JH7100_CLK_PERH1_ROOT),
+- JH7100_GDIV(JH7100_CLK_PLL0_TESTOUT, "pll0_testout", 0, 31, JH7100_CLK_PERH0_SRC),
+- JH7100_GDIV(JH7100_CLK_PLL1_TESTOUT, "pll1_testout", 0, 31, JH7100_CLK_DLA_ROOT),
+- JH7100_GDIV(JH7100_CLK_PLL2_TESTOUT, "pll2_testout", 0, 31, JH7100_CLK_PERH1_SRC),
+- JH7100__MUX(JH7100_CLK_PLL2_REF, "pll2_refclk", 2,
++ JH71X0__DIV(JH7100_CLK_CPUNBUS_ROOT_DIV, "cpunbus_root_div", 2, JH7100_CLK_CPUNDBUS_ROOT),
++ JH71X0__DIV(JH7100_CLK_DSP_ROOT_DIV, "dsp_root_div", 4, JH7100_CLK_DSP_ROOT),
++ JH71X0__DIV(JH7100_CLK_PERH0_SRC, "perh0_src", 4, JH7100_CLK_PERH0_ROOT),
++ JH71X0__DIV(JH7100_CLK_PERH1_SRC, "perh1_src", 4, JH7100_CLK_PERH1_ROOT),
++ JH71X0_GDIV(JH7100_CLK_PLL0_TESTOUT, "pll0_testout", 0, 31, JH7100_CLK_PERH0_SRC),
++ JH71X0_GDIV(JH7100_CLK_PLL1_TESTOUT, "pll1_testout", 0, 31, JH7100_CLK_DLA_ROOT),
++ JH71X0_GDIV(JH7100_CLK_PLL2_TESTOUT, "pll2_testout", 0, 31, JH7100_CLK_PERH1_SRC),
++ JH71X0__MUX(JH7100_CLK_PLL2_REF, "pll2_refclk", 2,
+ JH7100_CLK_OSC_SYS,
+ JH7100_CLK_OSC_AUD),
+- JH7100__DIV(JH7100_CLK_CPU_CORE, "cpu_core", 8, JH7100_CLK_CPUNBUS_ROOT_DIV),
+- JH7100__DIV(JH7100_CLK_CPU_AXI, "cpu_axi", 8, JH7100_CLK_CPU_CORE),
+- JH7100__DIV(JH7100_CLK_AHB_BUS, "ahb_bus", 8, JH7100_CLK_CPUNBUS_ROOT_DIV),
+- JH7100__DIV(JH7100_CLK_APB1_BUS, "apb1_bus", 8, JH7100_CLK_AHB_BUS),
+- JH7100__DIV(JH7100_CLK_APB2_BUS, "apb2_bus", 8, JH7100_CLK_AHB_BUS),
+- JH7100_GATE(JH7100_CLK_DOM3AHB_BUS, "dom3ahb_bus", CLK_IS_CRITICAL, JH7100_CLK_AHB_BUS),
+- JH7100_GATE(JH7100_CLK_DOM7AHB_BUS, "dom7ahb_bus", CLK_IS_CRITICAL, JH7100_CLK_AHB_BUS),
+- JH7100_GATE(JH7100_CLK_U74_CORE0, "u74_core0", CLK_IS_CRITICAL, JH7100_CLK_CPU_CORE),
+- JH7100_GDIV(JH7100_CLK_U74_CORE1, "u74_core1", CLK_IS_CRITICAL, 8, JH7100_CLK_CPU_CORE),
+- JH7100_GATE(JH7100_CLK_U74_AXI, "u74_axi", CLK_IS_CRITICAL, JH7100_CLK_CPU_AXI),
+- JH7100_GATE(JH7100_CLK_U74RTC_TOGGLE, "u74rtc_toggle", CLK_IS_CRITICAL, JH7100_CLK_OSC_SYS),
+- JH7100_GATE(JH7100_CLK_SGDMA2P_AXI, "sgdma2p_axi", 0, JH7100_CLK_CPU_AXI),
+- JH7100_GATE(JH7100_CLK_DMA2PNOC_AXI, "dma2pnoc_axi", 0, JH7100_CLK_CPU_AXI),
+- JH7100_GATE(JH7100_CLK_SGDMA2P_AHB, "sgdma2p_ahb", 0, JH7100_CLK_AHB_BUS),
+- JH7100__DIV(JH7100_CLK_DLA_BUS, "dla_bus", 4, JH7100_CLK_DLA_ROOT),
+- JH7100_GATE(JH7100_CLK_DLA_AXI, "dla_axi", 0, JH7100_CLK_DLA_BUS),
+- JH7100_GATE(JH7100_CLK_DLANOC_AXI, "dlanoc_axi", 0, JH7100_CLK_DLA_BUS),
+- JH7100_GATE(JH7100_CLK_DLA_APB, "dla_apb", 0, JH7100_CLK_APB1_BUS),
+- JH7100_GDIV(JH7100_CLK_VP6_CORE, "vp6_core", 0, 4, JH7100_CLK_DSP_ROOT_DIV),
+- JH7100__DIV(JH7100_CLK_VP6BUS_SRC, "vp6bus_src", 4, JH7100_CLK_DSP_ROOT),
+- JH7100_GDIV(JH7100_CLK_VP6_AXI, "vp6_axi", 0, 4, JH7100_CLK_VP6BUS_SRC),
+- JH7100__DIV(JH7100_CLK_VCDECBUS_SRC, "vcdecbus_src", 4, JH7100_CLK_CDECHIFI4_ROOT),
+- JH7100__DIV(JH7100_CLK_VDEC_BUS, "vdec_bus", 8, JH7100_CLK_VCDECBUS_SRC),
+- JH7100_GATE(JH7100_CLK_VDEC_AXI, "vdec_axi", 0, JH7100_CLK_VDEC_BUS),
+- JH7100_GATE(JH7100_CLK_VDECBRG_MAIN, "vdecbrg_mainclk", 0, JH7100_CLK_VDEC_BUS),
+- JH7100_GDIV(JH7100_CLK_VDEC_BCLK, "vdec_bclk", 0, 8, JH7100_CLK_VCDECBUS_SRC),
+- JH7100_GDIV(JH7100_CLK_VDEC_CCLK, "vdec_cclk", 0, 8, JH7100_CLK_CDEC_ROOT),
+- JH7100_GATE(JH7100_CLK_VDEC_APB, "vdec_apb", 0, JH7100_CLK_APB1_BUS),
+- JH7100_GDIV(JH7100_CLK_JPEG_AXI, "jpeg_axi", 0, 8, JH7100_CLK_CPUNBUS_ROOT_DIV),
+- JH7100_GDIV(JH7100_CLK_JPEG_CCLK, "jpeg_cclk", 0, 8, JH7100_CLK_CPUNBUS_ROOT_DIV),
+- JH7100_GATE(JH7100_CLK_JPEG_APB, "jpeg_apb", 0, JH7100_CLK_APB1_BUS),
+- JH7100_GDIV(JH7100_CLK_GC300_2X, "gc300_2x", 0, 8, JH7100_CLK_CDECHIFI4_ROOT),
+- JH7100_GATE(JH7100_CLK_GC300_AHB, "gc300_ahb", 0, JH7100_CLK_AHB_BUS),
+- JH7100__DIV(JH7100_CLK_JPCGC300_AXIBUS, "jpcgc300_axibus", 8, JH7100_CLK_VCDECBUS_SRC),
+- JH7100_GATE(JH7100_CLK_GC300_AXI, "gc300_axi", 0, JH7100_CLK_JPCGC300_AXIBUS),
+- JH7100_GATE(JH7100_CLK_JPCGC300_MAIN, "jpcgc300_mainclk", 0, JH7100_CLK_JPCGC300_AXIBUS),
+- JH7100__DIV(JH7100_CLK_VENC_BUS, "venc_bus", 8, JH7100_CLK_VCDECBUS_SRC),
+- JH7100_GATE(JH7100_CLK_VENC_AXI, "venc_axi", 0, JH7100_CLK_VENC_BUS),
+- JH7100_GATE(JH7100_CLK_VENCBRG_MAIN, "vencbrg_mainclk", 0, JH7100_CLK_VENC_BUS),
+- JH7100_GDIV(JH7100_CLK_VENC_BCLK, "venc_bclk", 0, 8, JH7100_CLK_VCDECBUS_SRC),
+- JH7100_GDIV(JH7100_CLK_VENC_CCLK, "venc_cclk", 0, 8, JH7100_CLK_CDEC_ROOT),
+- JH7100_GATE(JH7100_CLK_VENC_APB, "venc_apb", 0, JH7100_CLK_APB1_BUS),
+- JH7100_GDIV(JH7100_CLK_DDRPLL_DIV2, "ddrpll_div2", CLK_IS_CRITICAL, 2, JH7100_CLK_PLL1_OUT),
+- JH7100_GDIV(JH7100_CLK_DDRPLL_DIV4, "ddrpll_div4", CLK_IS_CRITICAL, 2, JH7100_CLK_DDRPLL_DIV2),
+- JH7100_GDIV(JH7100_CLK_DDRPLL_DIV8, "ddrpll_div8", CLK_IS_CRITICAL, 2, JH7100_CLK_DDRPLL_DIV4),
+- JH7100_GDIV(JH7100_CLK_DDROSC_DIV2, "ddrosc_div2", CLK_IS_CRITICAL, 2, JH7100_CLK_OSC_SYS),
+- JH7100_GMUX(JH7100_CLK_DDRC0, "ddrc0", CLK_IS_CRITICAL, 4,
++ JH71X0__DIV(JH7100_CLK_CPU_CORE, "cpu_core", 8, JH7100_CLK_CPUNBUS_ROOT_DIV),
++ JH71X0__DIV(JH7100_CLK_CPU_AXI, "cpu_axi", 8, JH7100_CLK_CPU_CORE),
++ JH71X0__DIV(JH7100_CLK_AHB_BUS, "ahb_bus", 8, JH7100_CLK_CPUNBUS_ROOT_DIV),
++ JH71X0__DIV(JH7100_CLK_APB1_BUS, "apb1_bus", 8, JH7100_CLK_AHB_BUS),
++ JH71X0__DIV(JH7100_CLK_APB2_BUS, "apb2_bus", 8, JH7100_CLK_AHB_BUS),
++ JH71X0_GATE(JH7100_CLK_DOM3AHB_BUS, "dom3ahb_bus", CLK_IS_CRITICAL, JH7100_CLK_AHB_BUS),
++ JH71X0_GATE(JH7100_CLK_DOM7AHB_BUS, "dom7ahb_bus", CLK_IS_CRITICAL, JH7100_CLK_AHB_BUS),
++ JH71X0_GATE(JH7100_CLK_U74_CORE0, "u74_core0", CLK_IS_CRITICAL, JH7100_CLK_CPU_CORE),
++ JH71X0_GDIV(JH7100_CLK_U74_CORE1, "u74_core1", CLK_IS_CRITICAL, 8, JH7100_CLK_CPU_CORE),
++ JH71X0_GATE(JH7100_CLK_U74_AXI, "u74_axi", CLK_IS_CRITICAL, JH7100_CLK_CPU_AXI),
++ JH71X0_GATE(JH7100_CLK_U74RTC_TOGGLE, "u74rtc_toggle", CLK_IS_CRITICAL, JH7100_CLK_OSC_SYS),
++ JH71X0_GATE(JH7100_CLK_SGDMA2P_AXI, "sgdma2p_axi", 0, JH7100_CLK_CPU_AXI),
++ JH71X0_GATE(JH7100_CLK_DMA2PNOC_AXI, "dma2pnoc_axi", 0, JH7100_CLK_CPU_AXI),
++ JH71X0_GATE(JH7100_CLK_SGDMA2P_AHB, "sgdma2p_ahb", 0, JH7100_CLK_AHB_BUS),
++ JH71X0__DIV(JH7100_CLK_DLA_BUS, "dla_bus", 4, JH7100_CLK_DLA_ROOT),
++ JH71X0_GATE(JH7100_CLK_DLA_AXI, "dla_axi", 0, JH7100_CLK_DLA_BUS),
++ JH71X0_GATE(JH7100_CLK_DLANOC_AXI, "dlanoc_axi", 0, JH7100_CLK_DLA_BUS),
++ JH71X0_GATE(JH7100_CLK_DLA_APB, "dla_apb", 0, JH7100_CLK_APB1_BUS),
++ JH71X0_GDIV(JH7100_CLK_VP6_CORE, "vp6_core", 0, 4, JH7100_CLK_DSP_ROOT_DIV),
++ JH71X0__DIV(JH7100_CLK_VP6BUS_SRC, "vp6bus_src", 4, JH7100_CLK_DSP_ROOT),
++ JH71X0_GDIV(JH7100_CLK_VP6_AXI, "vp6_axi", 0, 4, JH7100_CLK_VP6BUS_SRC),
++ JH71X0__DIV(JH7100_CLK_VCDECBUS_SRC, "vcdecbus_src", 4, JH7100_CLK_CDECHIFI4_ROOT),
++ JH71X0__DIV(JH7100_CLK_VDEC_BUS, "vdec_bus", 8, JH7100_CLK_VCDECBUS_SRC),
++ JH71X0_GATE(JH7100_CLK_VDEC_AXI, "vdec_axi", 0, JH7100_CLK_VDEC_BUS),
++ JH71X0_GATE(JH7100_CLK_VDECBRG_MAIN, "vdecbrg_mainclk", 0, JH7100_CLK_VDEC_BUS),
++ JH71X0_GDIV(JH7100_CLK_VDEC_BCLK, "vdec_bclk", 0, 8, JH7100_CLK_VCDECBUS_SRC),
++ JH71X0_GDIV(JH7100_CLK_VDEC_CCLK, "vdec_cclk", 0, 8, JH7100_CLK_CDEC_ROOT),
++ JH71X0_GATE(JH7100_CLK_VDEC_APB, "vdec_apb", 0, JH7100_CLK_APB1_BUS),
++ JH71X0_GDIV(JH7100_CLK_JPEG_AXI, "jpeg_axi", 0, 8, JH7100_CLK_CPUNBUS_ROOT_DIV),
++ JH71X0_GDIV(JH7100_CLK_JPEG_CCLK, "jpeg_cclk", 0, 8, JH7100_CLK_CPUNBUS_ROOT_DIV),
++ JH71X0_GATE(JH7100_CLK_JPEG_APB, "jpeg_apb", 0, JH7100_CLK_APB1_BUS),
++ JH71X0_GDIV(JH7100_CLK_GC300_2X, "gc300_2x", 0, 8, JH7100_CLK_CDECHIFI4_ROOT),
++ JH71X0_GATE(JH7100_CLK_GC300_AHB, "gc300_ahb", 0, JH7100_CLK_AHB_BUS),
++ JH71X0__DIV(JH7100_CLK_JPCGC300_AXIBUS, "jpcgc300_axibus", 8, JH7100_CLK_VCDECBUS_SRC),
++ JH71X0_GATE(JH7100_CLK_GC300_AXI, "gc300_axi", 0, JH7100_CLK_JPCGC300_AXIBUS),
++ JH71X0_GATE(JH7100_CLK_JPCGC300_MAIN, "jpcgc300_mainclk", 0, JH7100_CLK_JPCGC300_AXIBUS),
++ JH71X0__DIV(JH7100_CLK_VENC_BUS, "venc_bus", 8, JH7100_CLK_VCDECBUS_SRC),
++ JH71X0_GATE(JH7100_CLK_VENC_AXI, "venc_axi", 0, JH7100_CLK_VENC_BUS),
++ JH71X0_GATE(JH7100_CLK_VENCBRG_MAIN, "vencbrg_mainclk", 0, JH7100_CLK_VENC_BUS),
++ JH71X0_GDIV(JH7100_CLK_VENC_BCLK, "venc_bclk", 0, 8, JH7100_CLK_VCDECBUS_SRC),
++ JH71X0_GDIV(JH7100_CLK_VENC_CCLK, "venc_cclk", 0, 8, JH7100_CLK_CDEC_ROOT),
++ JH71X0_GATE(JH7100_CLK_VENC_APB, "venc_apb", 0, JH7100_CLK_APB1_BUS),
++ JH71X0_GDIV(JH7100_CLK_DDRPLL_DIV2, "ddrpll_div2", CLK_IS_CRITICAL, 2, JH7100_CLK_PLL1_OUT),
++ JH71X0_GDIV(JH7100_CLK_DDRPLL_DIV4, "ddrpll_div4", CLK_IS_CRITICAL, 2,
++ JH7100_CLK_DDRPLL_DIV2),
++ JH71X0_GDIV(JH7100_CLK_DDRPLL_DIV8, "ddrpll_div8", CLK_IS_CRITICAL, 2,
++ JH7100_CLK_DDRPLL_DIV4),
++ JH71X0_GDIV(JH7100_CLK_DDROSC_DIV2, "ddrosc_div2", CLK_IS_CRITICAL, 2, JH7100_CLK_OSC_SYS),
++ JH71X0_GMUX(JH7100_CLK_DDRC0, "ddrc0", CLK_IS_CRITICAL, 4,
+ JH7100_CLK_DDROSC_DIV2,
+ JH7100_CLK_DDRPLL_DIV2,
+ JH7100_CLK_DDRPLL_DIV4,
+ JH7100_CLK_DDRPLL_DIV8),
+- JH7100_GMUX(JH7100_CLK_DDRC1, "ddrc1", CLK_IS_CRITICAL, 4,
++ JH71X0_GMUX(JH7100_CLK_DDRC1, "ddrc1", CLK_IS_CRITICAL, 4,
+ JH7100_CLK_DDROSC_DIV2,
+ JH7100_CLK_DDRPLL_DIV2,
+ JH7100_CLK_DDRPLL_DIV4,
+ JH7100_CLK_DDRPLL_DIV8),
+- JH7100_GATE(JH7100_CLK_DDRPHY_APB, "ddrphy_apb", 0, JH7100_CLK_APB1_BUS),
+- JH7100__DIV(JH7100_CLK_NOC_ROB, "noc_rob", 8, JH7100_CLK_CPUNBUS_ROOT_DIV),
+- JH7100__DIV(JH7100_CLK_NOC_COG, "noc_cog", 8, JH7100_CLK_DLA_ROOT),
+- JH7100_GATE(JH7100_CLK_NNE_AHB, "nne_ahb", 0, JH7100_CLK_AHB_BUS),
+- JH7100__DIV(JH7100_CLK_NNEBUS_SRC1, "nnebus_src1", 4, JH7100_CLK_DSP_ROOT),
+- JH7100__MUX(JH7100_CLK_NNE_BUS, "nne_bus", 2,
++ JH71X0_GATE(JH7100_CLK_DDRPHY_APB, "ddrphy_apb", 0, JH7100_CLK_APB1_BUS),
++ JH71X0__DIV(JH7100_CLK_NOC_ROB, "noc_rob", 8, JH7100_CLK_CPUNBUS_ROOT_DIV),
++ JH71X0__DIV(JH7100_CLK_NOC_COG, "noc_cog", 8, JH7100_CLK_DLA_ROOT),
++ JH71X0_GATE(JH7100_CLK_NNE_AHB, "nne_ahb", 0, JH7100_CLK_AHB_BUS),
++ JH71X0__DIV(JH7100_CLK_NNEBUS_SRC1, "nnebus_src1", 4, JH7100_CLK_DSP_ROOT),
++ JH71X0__MUX(JH7100_CLK_NNE_BUS, "nne_bus", 2,
+ JH7100_CLK_CPU_AXI,
+ JH7100_CLK_NNEBUS_SRC1),
+- JH7100_GATE(JH7100_CLK_NNE_AXI, "nne_axi", 0, JH7100_CLK_NNE_BUS),
+- JH7100_GATE(JH7100_CLK_NNENOC_AXI, "nnenoc_axi", 0, JH7100_CLK_NNE_BUS),
+- JH7100_GATE(JH7100_CLK_DLASLV_AXI, "dlaslv_axi", 0, JH7100_CLK_NNE_BUS),
+- JH7100_GATE(JH7100_CLK_DSPX2C_AXI, "dspx2c_axi", CLK_IS_CRITICAL, JH7100_CLK_NNE_BUS),
+- JH7100__DIV(JH7100_CLK_HIFI4_SRC, "hifi4_src", 4, JH7100_CLK_CDECHIFI4_ROOT),
+- JH7100__DIV(JH7100_CLK_HIFI4_COREFREE, "hifi4_corefree", 8, JH7100_CLK_HIFI4_SRC),
+- JH7100_GATE(JH7100_CLK_HIFI4_CORE, "hifi4_core", 0, JH7100_CLK_HIFI4_COREFREE),
+- JH7100__DIV(JH7100_CLK_HIFI4_BUS, "hifi4_bus", 8, JH7100_CLK_HIFI4_COREFREE),
+- JH7100_GATE(JH7100_CLK_HIFI4_AXI, "hifi4_axi", 0, JH7100_CLK_HIFI4_BUS),
+- JH7100_GATE(JH7100_CLK_HIFI4NOC_AXI, "hifi4noc_axi", 0, JH7100_CLK_HIFI4_BUS),
+- JH7100__DIV(JH7100_CLK_SGDMA1P_BUS, "sgdma1p_bus", 8, JH7100_CLK_CPUNBUS_ROOT_DIV),
+- JH7100_GATE(JH7100_CLK_SGDMA1P_AXI, "sgdma1p_axi", 0, JH7100_CLK_SGDMA1P_BUS),
+- JH7100_GATE(JH7100_CLK_DMA1P_AXI, "dma1p_axi", 0, JH7100_CLK_SGDMA1P_BUS),
+- JH7100_GDIV(JH7100_CLK_X2C_AXI, "x2c_axi", CLK_IS_CRITICAL, 8, JH7100_CLK_CPUNBUS_ROOT_DIV),
+- JH7100__DIV(JH7100_CLK_USB_BUS, "usb_bus", 8, JH7100_CLK_CPUNBUS_ROOT_DIV),
+- JH7100_GATE(JH7100_CLK_USB_AXI, "usb_axi", 0, JH7100_CLK_USB_BUS),
+- JH7100_GATE(JH7100_CLK_USBNOC_AXI, "usbnoc_axi", 0, JH7100_CLK_USB_BUS),
+- JH7100__DIV(JH7100_CLK_USBPHY_ROOTDIV, "usbphy_rootdiv", 4, JH7100_CLK_GMACUSB_ROOT),
+- JH7100_GDIV(JH7100_CLK_USBPHY_125M, "usbphy_125m", 0, 8, JH7100_CLK_USBPHY_ROOTDIV),
+- JH7100_GDIV(JH7100_CLK_USBPHY_PLLDIV25M, "usbphy_plldiv25m", 0, 32, JH7100_CLK_USBPHY_ROOTDIV),
+- JH7100__MUX(JH7100_CLK_USBPHY_25M, "usbphy_25m", 2,
++ JH71X0_GATE(JH7100_CLK_NNE_AXI, "nne_axi", 0, JH7100_CLK_NNE_BUS),
++ JH71X0_GATE(JH7100_CLK_NNENOC_AXI, "nnenoc_axi", 0, JH7100_CLK_NNE_BUS),
++ JH71X0_GATE(JH7100_CLK_DLASLV_AXI, "dlaslv_axi", 0, JH7100_CLK_NNE_BUS),
++ JH71X0_GATE(JH7100_CLK_DSPX2C_AXI, "dspx2c_axi", CLK_IS_CRITICAL, JH7100_CLK_NNE_BUS),
++ JH71X0__DIV(JH7100_CLK_HIFI4_SRC, "hifi4_src", 4, JH7100_CLK_CDECHIFI4_ROOT),
++ JH71X0__DIV(JH7100_CLK_HIFI4_COREFREE, "hifi4_corefree", 8, JH7100_CLK_HIFI4_SRC),
++ JH71X0_GATE(JH7100_CLK_HIFI4_CORE, "hifi4_core", 0, JH7100_CLK_HIFI4_COREFREE),
++ JH71X0__DIV(JH7100_CLK_HIFI4_BUS, "hifi4_bus", 8, JH7100_CLK_HIFI4_COREFREE),
++ JH71X0_GATE(JH7100_CLK_HIFI4_AXI, "hifi4_axi", 0, JH7100_CLK_HIFI4_BUS),
++ JH71X0_GATE(JH7100_CLK_HIFI4NOC_AXI, "hifi4noc_axi", 0, JH7100_CLK_HIFI4_BUS),
++ JH71X0__DIV(JH7100_CLK_SGDMA1P_BUS, "sgdma1p_bus", 8, JH7100_CLK_CPUNBUS_ROOT_DIV),
++ JH71X0_GATE(JH7100_CLK_SGDMA1P_AXI, "sgdma1p_axi", 0, JH7100_CLK_SGDMA1P_BUS),
++ JH71X0_GATE(JH7100_CLK_DMA1P_AXI, "dma1p_axi", 0, JH7100_CLK_SGDMA1P_BUS),
++ JH71X0_GDIV(JH7100_CLK_X2C_AXI, "x2c_axi", CLK_IS_CRITICAL, 8, JH7100_CLK_CPUNBUS_ROOT_DIV),
++ JH71X0__DIV(JH7100_CLK_USB_BUS, "usb_bus", 8, JH7100_CLK_CPUNBUS_ROOT_DIV),
++ JH71X0_GATE(JH7100_CLK_USB_AXI, "usb_axi", 0, JH7100_CLK_USB_BUS),
++ JH71X0_GATE(JH7100_CLK_USBNOC_AXI, "usbnoc_axi", 0, JH7100_CLK_USB_BUS),
++ JH71X0__DIV(JH7100_CLK_USBPHY_ROOTDIV, "usbphy_rootdiv", 4, JH7100_CLK_GMACUSB_ROOT),
++ JH71X0_GDIV(JH7100_CLK_USBPHY_125M, "usbphy_125m", 0, 8, JH7100_CLK_USBPHY_ROOTDIV),
++ JH71X0_GDIV(JH7100_CLK_USBPHY_PLLDIV25M, "usbphy_plldiv25m", 0, 32,
++ JH7100_CLK_USBPHY_ROOTDIV),
++ JH71X0__MUX(JH7100_CLK_USBPHY_25M, "usbphy_25m", 2,
+ JH7100_CLK_OSC_SYS,
+ JH7100_CLK_USBPHY_PLLDIV25M),
+- JH7100_FDIV(JH7100_CLK_AUDIO_DIV, "audio_div", JH7100_CLK_AUDIO_ROOT),
+- JH7100_GATE(JH7100_CLK_AUDIO_SRC, "audio_src", 0, JH7100_CLK_AUDIO_DIV),
+- JH7100_GATE(JH7100_CLK_AUDIO_12288, "audio_12288", 0, JH7100_CLK_OSC_AUD),
+- JH7100_GDIV(JH7100_CLK_VIN_SRC, "vin_src", 0, 4, JH7100_CLK_VIN_ROOT),
+- JH7100__DIV(JH7100_CLK_ISP0_BUS, "isp0_bus", 8, JH7100_CLK_VIN_SRC),
+- JH7100_GATE(JH7100_CLK_ISP0_AXI, "isp0_axi", 0, JH7100_CLK_ISP0_BUS),
+- JH7100_GATE(JH7100_CLK_ISP0NOC_AXI, "isp0noc_axi", 0, JH7100_CLK_ISP0_BUS),
+- JH7100_GATE(JH7100_CLK_ISPSLV_AXI, "ispslv_axi", 0, JH7100_CLK_ISP0_BUS),
+- JH7100__DIV(JH7100_CLK_ISP1_BUS, "isp1_bus", 8, JH7100_CLK_VIN_SRC),
+- JH7100_GATE(JH7100_CLK_ISP1_AXI, "isp1_axi", 0, JH7100_CLK_ISP1_BUS),
+- JH7100_GATE(JH7100_CLK_ISP1NOC_AXI, "isp1noc_axi", 0, JH7100_CLK_ISP1_BUS),
+- JH7100__DIV(JH7100_CLK_VIN_BUS, "vin_bus", 8, JH7100_CLK_VIN_SRC),
+- JH7100_GATE(JH7100_CLK_VIN_AXI, "vin_axi", 0, JH7100_CLK_VIN_BUS),
+- JH7100_GATE(JH7100_CLK_VINNOC_AXI, "vinnoc_axi", 0, JH7100_CLK_VIN_BUS),
+- JH7100_GDIV(JH7100_CLK_VOUT_SRC, "vout_src", 0, 4, JH7100_CLK_VOUT_ROOT),
+- JH7100__DIV(JH7100_CLK_DISPBUS_SRC, "dispbus_src", 4, JH7100_CLK_VOUTBUS_ROOT),
+- JH7100__DIV(JH7100_CLK_DISP_BUS, "disp_bus", 4, JH7100_CLK_DISPBUS_SRC),
+- JH7100_GATE(JH7100_CLK_DISP_AXI, "disp_axi", 0, JH7100_CLK_DISP_BUS),
+- JH7100_GATE(JH7100_CLK_DISPNOC_AXI, "dispnoc_axi", 0, JH7100_CLK_DISP_BUS),
+- JH7100_GATE(JH7100_CLK_SDIO0_AHB, "sdio0_ahb", 0, JH7100_CLK_AHB_BUS),
+- JH7100_GDIV(JH7100_CLK_SDIO0_CCLKINT, "sdio0_cclkint", 0, 24, JH7100_CLK_PERH0_SRC),
+- JH7100__INV(JH7100_CLK_SDIO0_CCLKINT_INV, "sdio0_cclkint_inv", JH7100_CLK_SDIO0_CCLKINT),
+- JH7100_GATE(JH7100_CLK_SDIO1_AHB, "sdio1_ahb", 0, JH7100_CLK_AHB_BUS),
+- JH7100_GDIV(JH7100_CLK_SDIO1_CCLKINT, "sdio1_cclkint", 0, 24, JH7100_CLK_PERH1_SRC),
+- JH7100__INV(JH7100_CLK_SDIO1_CCLKINT_INV, "sdio1_cclkint_inv", JH7100_CLK_SDIO1_CCLKINT),
+- JH7100_GATE(JH7100_CLK_GMAC_AHB, "gmac_ahb", 0, JH7100_CLK_AHB_BUS),
+- JH7100__DIV(JH7100_CLK_GMAC_ROOT_DIV, "gmac_root_div", 8, JH7100_CLK_GMACUSB_ROOT),
+- JH7100_GDIV(JH7100_CLK_GMAC_PTP_REF, "gmac_ptp_refclk", 0, 31, JH7100_CLK_GMAC_ROOT_DIV),
+- JH7100_GDIV(JH7100_CLK_GMAC_GTX, "gmac_gtxclk", 0, 255, JH7100_CLK_GMAC_ROOT_DIV),
+- JH7100_GDIV(JH7100_CLK_GMAC_RMII_TX, "gmac_rmii_txclk", 0, 8, JH7100_CLK_GMAC_RMII_REF),
+- JH7100_GDIV(JH7100_CLK_GMAC_RMII_RX, "gmac_rmii_rxclk", 0, 8, JH7100_CLK_GMAC_RMII_REF),
+- JH7100__MUX(JH7100_CLK_GMAC_TX, "gmac_tx", 3,
++ JH71X0_FDIV(JH7100_CLK_AUDIO_DIV, "audio_div", JH7100_CLK_AUDIO_ROOT),
++ JH71X0_GATE(JH7100_CLK_AUDIO_SRC, "audio_src", 0, JH7100_CLK_AUDIO_DIV),
++ JH71X0_GATE(JH7100_CLK_AUDIO_12288, "audio_12288", 0, JH7100_CLK_OSC_AUD),
++ JH71X0_GDIV(JH7100_CLK_VIN_SRC, "vin_src", 0, 4, JH7100_CLK_VIN_ROOT),
++ JH71X0__DIV(JH7100_CLK_ISP0_BUS, "isp0_bus", 8, JH7100_CLK_VIN_SRC),
++ JH71X0_GATE(JH7100_CLK_ISP0_AXI, "isp0_axi", 0, JH7100_CLK_ISP0_BUS),
++ JH71X0_GATE(JH7100_CLK_ISP0NOC_AXI, "isp0noc_axi", 0, JH7100_CLK_ISP0_BUS),
++ JH71X0_GATE(JH7100_CLK_ISPSLV_AXI, "ispslv_axi", 0, JH7100_CLK_ISP0_BUS),
++ JH71X0__DIV(JH7100_CLK_ISP1_BUS, "isp1_bus", 8, JH7100_CLK_VIN_SRC),
++ JH71X0_GATE(JH7100_CLK_ISP1_AXI, "isp1_axi", 0, JH7100_CLK_ISP1_BUS),
++ JH71X0_GATE(JH7100_CLK_ISP1NOC_AXI, "isp1noc_axi", 0, JH7100_CLK_ISP1_BUS),
++ JH71X0__DIV(JH7100_CLK_VIN_BUS, "vin_bus", 8, JH7100_CLK_VIN_SRC),
++ JH71X0_GATE(JH7100_CLK_VIN_AXI, "vin_axi", 0, JH7100_CLK_VIN_BUS),
++ JH71X0_GATE(JH7100_CLK_VINNOC_AXI, "vinnoc_axi", 0, JH7100_CLK_VIN_BUS),
++ JH71X0_GDIV(JH7100_CLK_VOUT_SRC, "vout_src", 0, 4, JH7100_CLK_VOUT_ROOT),
++ JH71X0__DIV(JH7100_CLK_DISPBUS_SRC, "dispbus_src", 4, JH7100_CLK_VOUTBUS_ROOT),
++ JH71X0__DIV(JH7100_CLK_DISP_BUS, "disp_bus", 4, JH7100_CLK_DISPBUS_SRC),
++ JH71X0_GATE(JH7100_CLK_DISP_AXI, "disp_axi", 0, JH7100_CLK_DISP_BUS),
++ JH71X0_GATE(JH7100_CLK_DISPNOC_AXI, "dispnoc_axi", 0, JH7100_CLK_DISP_BUS),
++ JH71X0_GATE(JH7100_CLK_SDIO0_AHB, "sdio0_ahb", 0, JH7100_CLK_AHB_BUS),
++ JH71X0_GDIV(JH7100_CLK_SDIO0_CCLKINT, "sdio0_cclkint", 0, 24, JH7100_CLK_PERH0_SRC),
++ JH71X0__INV(JH7100_CLK_SDIO0_CCLKINT_INV, "sdio0_cclkint_inv", JH7100_CLK_SDIO0_CCLKINT),
++ JH71X0_GATE(JH7100_CLK_SDIO1_AHB, "sdio1_ahb", 0, JH7100_CLK_AHB_BUS),
++ JH71X0_GDIV(JH7100_CLK_SDIO1_CCLKINT, "sdio1_cclkint", 0, 24, JH7100_CLK_PERH1_SRC),
++ JH71X0__INV(JH7100_CLK_SDIO1_CCLKINT_INV, "sdio1_cclkint_inv", JH7100_CLK_SDIO1_CCLKINT),
++ JH71X0_GATE(JH7100_CLK_GMAC_AHB, "gmac_ahb", 0, JH7100_CLK_AHB_BUS),
++ JH71X0__DIV(JH7100_CLK_GMAC_ROOT_DIV, "gmac_root_div", 8, JH7100_CLK_GMACUSB_ROOT),
++ JH71X0_GDIV(JH7100_CLK_GMAC_PTP_REF, "gmac_ptp_refclk", 0, 31, JH7100_CLK_GMAC_ROOT_DIV),
++ JH71X0_GDIV(JH7100_CLK_GMAC_GTX, "gmac_gtxclk", 0, 255, JH7100_CLK_GMAC_ROOT_DIV),
++ JH71X0_GDIV(JH7100_CLK_GMAC_RMII_TX, "gmac_rmii_txclk", 0, 8, JH7100_CLK_GMAC_RMII_REF),
++ JH71X0_GDIV(JH7100_CLK_GMAC_RMII_RX, "gmac_rmii_rxclk", 0, 8, JH7100_CLK_GMAC_RMII_REF),
++ JH71X0__MUX(JH7100_CLK_GMAC_TX, "gmac_tx", 3,
+ JH7100_CLK_GMAC_GTX,
+ JH7100_CLK_GMAC_TX_INV,
+ JH7100_CLK_GMAC_RMII_TX),
+- JH7100__INV(JH7100_CLK_GMAC_TX_INV, "gmac_tx_inv", JH7100_CLK_GMAC_TX),
+- JH7100__MUX(JH7100_CLK_GMAC_RX_PRE, "gmac_rx_pre", 2,
++ JH71X0__INV(JH7100_CLK_GMAC_TX_INV, "gmac_tx_inv", JH7100_CLK_GMAC_TX),
++ JH71X0__MUX(JH7100_CLK_GMAC_RX_PRE, "gmac_rx_pre", 2,
+ JH7100_CLK_GMAC_GR_MII_RX,
+ JH7100_CLK_GMAC_RMII_RX),
+- JH7100__INV(JH7100_CLK_GMAC_RX_INV, "gmac_rx_inv", JH7100_CLK_GMAC_RX_PRE),
+- JH7100_GATE(JH7100_CLK_GMAC_RMII, "gmac_rmii", 0, JH7100_CLK_GMAC_RMII_REF),
+- JH7100_GDIV(JH7100_CLK_GMAC_TOPHYREF, "gmac_tophyref", 0, 127, JH7100_CLK_GMAC_ROOT_DIV),
+- JH7100_GATE(JH7100_CLK_SPI2AHB_AHB, "spi2ahb_ahb", 0, JH7100_CLK_AHB_BUS),
+- JH7100_GDIV(JH7100_CLK_SPI2AHB_CORE, "spi2ahb_core", 0, 31, JH7100_CLK_PERH0_SRC),
+- JH7100_GATE(JH7100_CLK_EZMASTER_AHB, "ezmaster_ahb", 0, JH7100_CLK_AHB_BUS),
+- JH7100_GATE(JH7100_CLK_E24_AHB, "e24_ahb", 0, JH7100_CLK_AHB_BUS),
+- JH7100_GATE(JH7100_CLK_E24RTC_TOGGLE, "e24rtc_toggle", 0, JH7100_CLK_OSC_SYS),
+- JH7100_GATE(JH7100_CLK_QSPI_AHB, "qspi_ahb", 0, JH7100_CLK_AHB_BUS),
+- JH7100_GATE(JH7100_CLK_QSPI_APB, "qspi_apb", 0, JH7100_CLK_APB1_BUS),
+- JH7100_GDIV(JH7100_CLK_QSPI_REF, "qspi_refclk", 0, 31, JH7100_CLK_PERH0_SRC),
+- JH7100_GATE(JH7100_CLK_SEC_AHB, "sec_ahb", 0, JH7100_CLK_AHB_BUS),
+- JH7100_GATE(JH7100_CLK_AES, "aes_clk", 0, JH7100_CLK_SEC_AHB),
+- JH7100_GATE(JH7100_CLK_SHA, "sha_clk", 0, JH7100_CLK_SEC_AHB),
+- JH7100_GATE(JH7100_CLK_PKA, "pka_clk", 0, JH7100_CLK_SEC_AHB),
+- JH7100_GATE(JH7100_CLK_TRNG_APB, "trng_apb", 0, JH7100_CLK_APB1_BUS),
+- JH7100_GATE(JH7100_CLK_OTP_APB, "otp_apb", 0, JH7100_CLK_APB1_BUS),
+- JH7100_GATE(JH7100_CLK_UART0_APB, "uart0_apb", 0, JH7100_CLK_APB1_BUS),
+- JH7100_GDIV(JH7100_CLK_UART0_CORE, "uart0_core", 0, 63, JH7100_CLK_PERH1_SRC),
+- JH7100_GATE(JH7100_CLK_UART1_APB, "uart1_apb", 0, JH7100_CLK_APB1_BUS),
+- JH7100_GDIV(JH7100_CLK_UART1_CORE, "uart1_core", 0, 63, JH7100_CLK_PERH1_SRC),
+- JH7100_GATE(JH7100_CLK_SPI0_APB, "spi0_apb", 0, JH7100_CLK_APB1_BUS),
+- JH7100_GDIV(JH7100_CLK_SPI0_CORE, "spi0_core", 0, 63, JH7100_CLK_PERH1_SRC),
+- JH7100_GATE(JH7100_CLK_SPI1_APB, "spi1_apb", 0, JH7100_CLK_APB1_BUS),
+- JH7100_GDIV(JH7100_CLK_SPI1_CORE, "spi1_core", 0, 63, JH7100_CLK_PERH1_SRC),
+- JH7100_GATE(JH7100_CLK_I2C0_APB, "i2c0_apb", 0, JH7100_CLK_APB1_BUS),
+- JH7100_GDIV(JH7100_CLK_I2C0_CORE, "i2c0_core", 0, 63, JH7100_CLK_PERH1_SRC),
+- JH7100_GATE(JH7100_CLK_I2C1_APB, "i2c1_apb", 0, JH7100_CLK_APB1_BUS),
+- JH7100_GDIV(JH7100_CLK_I2C1_CORE, "i2c1_core", 0, 63, JH7100_CLK_PERH1_SRC),
+- JH7100_GATE(JH7100_CLK_GPIO_APB, "gpio_apb", 0, JH7100_CLK_APB1_BUS),
+- JH7100_GATE(JH7100_CLK_UART2_APB, "uart2_apb", 0, JH7100_CLK_APB2_BUS),
+- JH7100_GDIV(JH7100_CLK_UART2_CORE, "uart2_core", 0, 63, JH7100_CLK_PERH0_SRC),
+- JH7100_GATE(JH7100_CLK_UART3_APB, "uart3_apb", 0, JH7100_CLK_APB2_BUS),
+- JH7100_GDIV(JH7100_CLK_UART3_CORE, "uart3_core", 0, 63, JH7100_CLK_PERH0_SRC),
+- JH7100_GATE(JH7100_CLK_SPI2_APB, "spi2_apb", 0, JH7100_CLK_APB2_BUS),
+- JH7100_GDIV(JH7100_CLK_SPI2_CORE, "spi2_core", 0, 63, JH7100_CLK_PERH0_SRC),
+- JH7100_GATE(JH7100_CLK_SPI3_APB, "spi3_apb", 0, JH7100_CLK_APB2_BUS),
+- JH7100_GDIV(JH7100_CLK_SPI3_CORE, "spi3_core", 0, 63, JH7100_CLK_PERH0_SRC),
+- JH7100_GATE(JH7100_CLK_I2C2_APB, "i2c2_apb", 0, JH7100_CLK_APB2_BUS),
+- JH7100_GDIV(JH7100_CLK_I2C2_CORE, "i2c2_core", 0, 63, JH7100_CLK_PERH0_SRC),
+- JH7100_GATE(JH7100_CLK_I2C3_APB, "i2c3_apb", 0, JH7100_CLK_APB2_BUS),
+- JH7100_GDIV(JH7100_CLK_I2C3_CORE, "i2c3_core", 0, 63, JH7100_CLK_PERH0_SRC),
+- JH7100_GATE(JH7100_CLK_WDTIMER_APB, "wdtimer_apb", 0, JH7100_CLK_APB2_BUS),
+- JH7100_GDIV(JH7100_CLK_WDT_CORE, "wdt_coreclk", 0, 63, JH7100_CLK_PERH0_SRC),
+- JH7100_GDIV(JH7100_CLK_TIMER0_CORE, "timer0_coreclk", 0, 63, JH7100_CLK_PERH0_SRC),
+- JH7100_GDIV(JH7100_CLK_TIMER1_CORE, "timer1_coreclk", 0, 63, JH7100_CLK_PERH0_SRC),
+- JH7100_GDIV(JH7100_CLK_TIMER2_CORE, "timer2_coreclk", 0, 63, JH7100_CLK_PERH0_SRC),
+- JH7100_GDIV(JH7100_CLK_TIMER3_CORE, "timer3_coreclk", 0, 63, JH7100_CLK_PERH0_SRC),
+- JH7100_GDIV(JH7100_CLK_TIMER4_CORE, "timer4_coreclk", 0, 63, JH7100_CLK_PERH0_SRC),
+- JH7100_GDIV(JH7100_CLK_TIMER5_CORE, "timer5_coreclk", 0, 63, JH7100_CLK_PERH0_SRC),
+- JH7100_GDIV(JH7100_CLK_TIMER6_CORE, "timer6_coreclk", 0, 63, JH7100_CLK_PERH0_SRC),
+- JH7100_GATE(JH7100_CLK_VP6INTC_APB, "vp6intc_apb", 0, JH7100_CLK_APB2_BUS),
+- JH7100_GATE(JH7100_CLK_PWM_APB, "pwm_apb", 0, JH7100_CLK_APB2_BUS),
+- JH7100_GATE(JH7100_CLK_MSI_APB, "msi_apb", 0, JH7100_CLK_APB2_BUS),
+- JH7100_GATE(JH7100_CLK_TEMP_APB, "temp_apb", 0, JH7100_CLK_APB2_BUS),
+- JH7100_GDIV(JH7100_CLK_TEMP_SENSE, "temp_sense", 0, 31, JH7100_CLK_OSC_SYS),
+- JH7100_GATE(JH7100_CLK_SYSERR_APB, "syserr_apb", 0, JH7100_CLK_APB2_BUS),
++ JH71X0__INV(JH7100_CLK_GMAC_RX_INV, "gmac_rx_inv", JH7100_CLK_GMAC_RX_PRE),
++ JH71X0_GATE(JH7100_CLK_GMAC_RMII, "gmac_rmii", 0, JH7100_CLK_GMAC_RMII_REF),
++ JH71X0_GDIV(JH7100_CLK_GMAC_TOPHYREF, "gmac_tophyref", 0, 127, JH7100_CLK_GMAC_ROOT_DIV),
++ JH71X0_GATE(JH7100_CLK_SPI2AHB_AHB, "spi2ahb_ahb", 0, JH7100_CLK_AHB_BUS),
++ JH71X0_GDIV(JH7100_CLK_SPI2AHB_CORE, "spi2ahb_core", 0, 31, JH7100_CLK_PERH0_SRC),
++ JH71X0_GATE(JH7100_CLK_EZMASTER_AHB, "ezmaster_ahb", 0, JH7100_CLK_AHB_BUS),
++ JH71X0_GATE(JH7100_CLK_E24_AHB, "e24_ahb", 0, JH7100_CLK_AHB_BUS),
++ JH71X0_GATE(JH7100_CLK_E24RTC_TOGGLE, "e24rtc_toggle", 0, JH7100_CLK_OSC_SYS),
++ JH71X0_GATE(JH7100_CLK_QSPI_AHB, "qspi_ahb", 0, JH7100_CLK_AHB_BUS),
++ JH71X0_GATE(JH7100_CLK_QSPI_APB, "qspi_apb", 0, JH7100_CLK_APB1_BUS),
++ JH71X0_GDIV(JH7100_CLK_QSPI_REF, "qspi_refclk", 0, 31, JH7100_CLK_PERH0_SRC),
++ JH71X0_GATE(JH7100_CLK_SEC_AHB, "sec_ahb", 0, JH7100_CLK_AHB_BUS),
++ JH71X0_GATE(JH7100_CLK_AES, "aes_clk", 0, JH7100_CLK_SEC_AHB),
++ JH71X0_GATE(JH7100_CLK_SHA, "sha_clk", 0, JH7100_CLK_SEC_AHB),
++ JH71X0_GATE(JH7100_CLK_PKA, "pka_clk", 0, JH7100_CLK_SEC_AHB),
++ JH71X0_GATE(JH7100_CLK_TRNG_APB, "trng_apb", 0, JH7100_CLK_APB1_BUS),
++ JH71X0_GATE(JH7100_CLK_OTP_APB, "otp_apb", 0, JH7100_CLK_APB1_BUS),
++ JH71X0_GATE(JH7100_CLK_UART0_APB, "uart0_apb", 0, JH7100_CLK_APB1_BUS),
++ JH71X0_GDIV(JH7100_CLK_UART0_CORE, "uart0_core", 0, 63, JH7100_CLK_PERH1_SRC),
++ JH71X0_GATE(JH7100_CLK_UART1_APB, "uart1_apb", 0, JH7100_CLK_APB1_BUS),
++ JH71X0_GDIV(JH7100_CLK_UART1_CORE, "uart1_core", 0, 63, JH7100_CLK_PERH1_SRC),
++ JH71X0_GATE(JH7100_CLK_SPI0_APB, "spi0_apb", 0, JH7100_CLK_APB1_BUS),
++ JH71X0_GDIV(JH7100_CLK_SPI0_CORE, "spi0_core", 0, 63, JH7100_CLK_PERH1_SRC),
++ JH71X0_GATE(JH7100_CLK_SPI1_APB, "spi1_apb", 0, JH7100_CLK_APB1_BUS),
++ JH71X0_GDIV(JH7100_CLK_SPI1_CORE, "spi1_core", 0, 63, JH7100_CLK_PERH1_SRC),
++ JH71X0_GATE(JH7100_CLK_I2C0_APB, "i2c0_apb", 0, JH7100_CLK_APB1_BUS),
++ JH71X0_GDIV(JH7100_CLK_I2C0_CORE, "i2c0_core", 0, 63, JH7100_CLK_PERH1_SRC),
++ JH71X0_GATE(JH7100_CLK_I2C1_APB, "i2c1_apb", 0, JH7100_CLK_APB1_BUS),
++ JH71X0_GDIV(JH7100_CLK_I2C1_CORE, "i2c1_core", 0, 63, JH7100_CLK_PERH1_SRC),
++ JH71X0_GATE(JH7100_CLK_GPIO_APB, "gpio_apb", 0, JH7100_CLK_APB1_BUS),
++ JH71X0_GATE(JH7100_CLK_UART2_APB, "uart2_apb", 0, JH7100_CLK_APB2_BUS),
++ JH71X0_GDIV(JH7100_CLK_UART2_CORE, "uart2_core", 0, 63, JH7100_CLK_PERH0_SRC),
++ JH71X0_GATE(JH7100_CLK_UART3_APB, "uart3_apb", 0, JH7100_CLK_APB2_BUS),
++ JH71X0_GDIV(JH7100_CLK_UART3_CORE, "uart3_core", 0, 63, JH7100_CLK_PERH0_SRC),
++ JH71X0_GATE(JH7100_CLK_SPI2_APB, "spi2_apb", 0, JH7100_CLK_APB2_BUS),
++ JH71X0_GDIV(JH7100_CLK_SPI2_CORE, "spi2_core", 0, 63, JH7100_CLK_PERH0_SRC),
++ JH71X0_GATE(JH7100_CLK_SPI3_APB, "spi3_apb", 0, JH7100_CLK_APB2_BUS),
++ JH71X0_GDIV(JH7100_CLK_SPI3_CORE, "spi3_core", 0, 63, JH7100_CLK_PERH0_SRC),
++ JH71X0_GATE(JH7100_CLK_I2C2_APB, "i2c2_apb", 0, JH7100_CLK_APB2_BUS),
++ JH71X0_GDIV(JH7100_CLK_I2C2_CORE, "i2c2_core", 0, 63, JH7100_CLK_PERH0_SRC),
++ JH71X0_GATE(JH7100_CLK_I2C3_APB, "i2c3_apb", 0, JH7100_CLK_APB2_BUS),
++ JH71X0_GDIV(JH7100_CLK_I2C3_CORE, "i2c3_core", 0, 63, JH7100_CLK_PERH0_SRC),
++ JH71X0_GATE(JH7100_CLK_WDTIMER_APB, "wdtimer_apb", 0, JH7100_CLK_APB2_BUS),
++ JH71X0_GDIV(JH7100_CLK_WDT_CORE, "wdt_coreclk", 0, 63, JH7100_CLK_PERH0_SRC),
++ JH71X0_GDIV(JH7100_CLK_TIMER0_CORE, "timer0_coreclk", 0, 63, JH7100_CLK_PERH0_SRC),
++ JH71X0_GDIV(JH7100_CLK_TIMER1_CORE, "timer1_coreclk", 0, 63, JH7100_CLK_PERH0_SRC),
++ JH71X0_GDIV(JH7100_CLK_TIMER2_CORE, "timer2_coreclk", 0, 63, JH7100_CLK_PERH0_SRC),
++ JH71X0_GDIV(JH7100_CLK_TIMER3_CORE, "timer3_coreclk", 0, 63, JH7100_CLK_PERH0_SRC),
++ JH71X0_GDIV(JH7100_CLK_TIMER4_CORE, "timer4_coreclk", 0, 63, JH7100_CLK_PERH0_SRC),
++ JH71X0_GDIV(JH7100_CLK_TIMER5_CORE, "timer5_coreclk", 0, 63, JH7100_CLK_PERH0_SRC),
++ JH71X0_GDIV(JH7100_CLK_TIMER6_CORE, "timer6_coreclk", 0, 63, JH7100_CLK_PERH0_SRC),
++ JH71X0_GATE(JH7100_CLK_VP6INTC_APB, "vp6intc_apb", 0, JH7100_CLK_APB2_BUS),
++ JH71X0_GATE(JH7100_CLK_PWM_APB, "pwm_apb", 0, JH7100_CLK_APB2_BUS),
++ JH71X0_GATE(JH7100_CLK_MSI_APB, "msi_apb", 0, JH7100_CLK_APB2_BUS),
++ JH71X0_GATE(JH7100_CLK_TEMP_APB, "temp_apb", 0, JH7100_CLK_APB2_BUS),
++ JH71X0_GDIV(JH7100_CLK_TEMP_SENSE, "temp_sense", 0, 31, JH7100_CLK_OSC_SYS),
++ JH71X0_GATE(JH7100_CLK_SYSERR_APB, "syserr_apb", 0, JH7100_CLK_APB2_BUS),
+ };
+
+ static struct clk_hw *jh7100_clk_get(struct of_phandle_args *clkspec, void *data)
+ {
+- struct jh7100_clk_priv *priv = data;
++ struct jh71x0_clk_priv *priv = data;
+ unsigned int idx = clkspec->args[0];
+
+ if (idx < JH7100_CLK_PLL0_OUT)
+@@ -280,7 +283,7 @@ static struct clk_hw *jh7100_clk_get(struct of_phandle_args *clkspec, void *data
+
+ static int __init clk_starfive_jh7100_probe(struct platform_device *pdev)
+ {
+- struct jh7100_clk_priv *priv;
++ struct jh71x0_clk_priv *priv;
+ unsigned int idx;
+ int ret;
+
+@@ -314,12 +317,12 @@ static int __init clk_starfive_jh7100_probe(struct platform_device *pdev)
+ struct clk_parent_data parents[4] = {};
+ struct clk_init_data init = {
+ .name = jh7100_clk_data[idx].name,
+- .ops = starfive_jh7100_clk_ops(max),
++ .ops = starfive_jh71x0_clk_ops(max),
+ .parent_data = parents,
+- .num_parents = ((max & JH7100_CLK_MUX_MASK) >> JH7100_CLK_MUX_SHIFT) + 1,
++ .num_parents = ((max & JH71X0_CLK_MUX_MASK) >> JH71X0_CLK_MUX_SHIFT) + 1,
+ .flags = jh7100_clk_data[idx].flags,
+ };
+- struct jh7100_clk *clk = &priv->reg[idx];
++ struct jh71x0_clk *clk = &priv->reg[idx];
+ unsigned int i;
+
+ for (i = 0; i < init.num_parents; i++) {
+@@ -341,7 +344,7 @@ static int __init clk_starfive_jh7100_probe(struct platform_device *pdev)
+
+ clk->hw.init = &init;
+ clk->idx = idx;
+- clk->max_div = max & JH7100_CLK_DIV_MASK;
++ clk->max_div = max & JH71X0_CLK_DIV_MASK;
+
+ ret = devm_clk_hw_register(priv->dev, &clk->hw);
+ if (ret)
+diff --git a/drivers/clk/starfive/clk-starfive-jh71x0.c b/drivers/clk/starfive/clk-starfive-jh71x0.c
+index 0140bdf27a01..b372083d11c3 100644
+--- a/drivers/clk/starfive/clk-starfive-jh71x0.c
++++ b/drivers/clk/starfive/clk-starfive-jh71x0.c
+@@ -1,6 +1,6 @@
+ // SPDX-License-Identifier: GPL-2.0
+ /*
+- * StarFive JH7100 Clock Generator Driver
++ * StarFive JH71X0 Clock Generator Driver
+ *
+ * Copyright (C) 2021-2022 Emil Renner Berthing <kernel@esmil.dk>
+ */
+@@ -12,27 +12,27 @@
+
+ #include "clk-starfive-jh71x0.h"
+
+-static struct jh7100_clk *jh7100_clk_from(struct clk_hw *hw)
++static struct jh71x0_clk *jh71x0_clk_from(struct clk_hw *hw)
+ {
+- return container_of(hw, struct jh7100_clk, hw);
++ return container_of(hw, struct jh71x0_clk, hw);
+ }
+
+-static struct jh7100_clk_priv *jh7100_priv_from(struct jh7100_clk *clk)
++static struct jh71x0_clk_priv *jh71x0_priv_from(struct jh71x0_clk *clk)
+ {
+- return container_of(clk, struct jh7100_clk_priv, reg[clk->idx]);
++ return container_of(clk, struct jh71x0_clk_priv, reg[clk->idx]);
+ }
+
+-static u32 jh7100_clk_reg_get(struct jh7100_clk *clk)
++static u32 jh71x0_clk_reg_get(struct jh71x0_clk *clk)
+ {
+- struct jh7100_clk_priv *priv = jh7100_priv_from(clk);
++ struct jh71x0_clk_priv *priv = jh71x0_priv_from(clk);
+ void __iomem *reg = priv->base + 4 * clk->idx;
+
+ return readl_relaxed(reg);
+ }
+
+-static void jh7100_clk_reg_rmw(struct jh7100_clk *clk, u32 mask, u32 value)
++static void jh71x0_clk_reg_rmw(struct jh71x0_clk *clk, u32 mask, u32 value)
+ {
+- struct jh7100_clk_priv *priv = jh7100_priv_from(clk);
++ struct jh71x0_clk_priv *priv = jh71x0_priv_from(clk);
+ void __iomem *reg = priv->base + 4 * clk->idx;
+ unsigned long flags;
+
+@@ -42,41 +42,41 @@ static void jh7100_clk_reg_rmw(struct jh7100_clk *clk, u32 mask, u32 value)
+ spin_unlock_irqrestore(&priv->rmw_lock, flags);
+ }
+
+-static int jh7100_clk_enable(struct clk_hw *hw)
++static int jh71x0_clk_enable(struct clk_hw *hw)
+ {
+- struct jh7100_clk *clk = jh7100_clk_from(hw);
++ struct jh71x0_clk *clk = jh71x0_clk_from(hw);
+
+- jh7100_clk_reg_rmw(clk, JH7100_CLK_ENABLE, JH7100_CLK_ENABLE);
++ jh71x0_clk_reg_rmw(clk, JH71X0_CLK_ENABLE, JH71X0_CLK_ENABLE);
+ return 0;
+ }
+
+-static void jh7100_clk_disable(struct clk_hw *hw)
++static void jh71x0_clk_disable(struct clk_hw *hw)
+ {
+- struct jh7100_clk *clk = jh7100_clk_from(hw);
++ struct jh71x0_clk *clk = jh71x0_clk_from(hw);
+
+- jh7100_clk_reg_rmw(clk, JH7100_CLK_ENABLE, 0);
++ jh71x0_clk_reg_rmw(clk, JH71X0_CLK_ENABLE, 0);
+ }
+
+-static int jh7100_clk_is_enabled(struct clk_hw *hw)
++static int jh71x0_clk_is_enabled(struct clk_hw *hw)
+ {
+- struct jh7100_clk *clk = jh7100_clk_from(hw);
++ struct jh71x0_clk *clk = jh71x0_clk_from(hw);
+
+- return !!(jh7100_clk_reg_get(clk) & JH7100_CLK_ENABLE);
++ return !!(jh71x0_clk_reg_get(clk) & JH71X0_CLK_ENABLE);
+ }
+
+-static unsigned long jh7100_clk_recalc_rate(struct clk_hw *hw,
++static unsigned long jh71x0_clk_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+ {
+- struct jh7100_clk *clk = jh7100_clk_from(hw);
+- u32 div = jh7100_clk_reg_get(clk) & JH7100_CLK_DIV_MASK;
++ struct jh71x0_clk *clk = jh71x0_clk_from(hw);
++ u32 div = jh71x0_clk_reg_get(clk) & JH71X0_CLK_DIV_MASK;
+
+ return div ? parent_rate / div : 0;
+ }
+
+-static int jh7100_clk_determine_rate(struct clk_hw *hw,
++static int jh71x0_clk_determine_rate(struct clk_hw *hw,
+ struct clk_rate_request *req)
+ {
+- struct jh7100_clk *clk = jh7100_clk_from(hw);
++ struct jh71x0_clk *clk = jh71x0_clk_from(hw);
+ unsigned long parent = req->best_parent_rate;
+ unsigned long rate = clamp(req->rate, req->min_rate, req->max_rate);
+ unsigned long div = min_t(unsigned long, DIV_ROUND_UP(parent, rate), clk->max_div);
+@@ -102,232 +102,232 @@ static int jh7100_clk_determine_rate(struct clk_hw *hw,
+ return 0;
+ }
+
+-static int jh7100_clk_set_rate(struct clk_hw *hw,
++static int jh71x0_clk_set_rate(struct clk_hw *hw,
+ unsigned long rate,
+ unsigned long parent_rate)
+ {
+- struct jh7100_clk *clk = jh7100_clk_from(hw);
++ struct jh71x0_clk *clk = jh71x0_clk_from(hw);
+ unsigned long div = clamp(DIV_ROUND_CLOSEST(parent_rate, rate),
+ 1UL, (unsigned long)clk->max_div);
+
+- jh7100_clk_reg_rmw(clk, JH7100_CLK_DIV_MASK, div);
++ jh71x0_clk_reg_rmw(clk, JH71X0_CLK_DIV_MASK, div);
+ return 0;
+ }
+
+-static unsigned long jh7100_clk_frac_recalc_rate(struct clk_hw *hw,
++static unsigned long jh71x0_clk_frac_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+ {
+- struct jh7100_clk *clk = jh7100_clk_from(hw);
+- u32 reg = jh7100_clk_reg_get(clk);
+- unsigned long div100 = 100 * (reg & JH7100_CLK_INT_MASK) +
+- ((reg & JH7100_CLK_FRAC_MASK) >> JH7100_CLK_FRAC_SHIFT);
++ struct jh71x0_clk *clk = jh71x0_clk_from(hw);
++ u32 reg = jh71x0_clk_reg_get(clk);
++ unsigned long div100 = 100 * (reg & JH71X0_CLK_INT_MASK) +
++ ((reg & JH71X0_CLK_FRAC_MASK) >> JH71X0_CLK_FRAC_SHIFT);
+
+- return (div100 >= JH7100_CLK_FRAC_MIN) ? 100 * parent_rate / div100 : 0;
++ return (div100 >= JH71X0_CLK_FRAC_MIN) ? 100 * parent_rate / div100 : 0;
+ }
+
+-static int jh7100_clk_frac_determine_rate(struct clk_hw *hw,
++static int jh71x0_clk_frac_determine_rate(struct clk_hw *hw,
+ struct clk_rate_request *req)
+ {
+ unsigned long parent100 = 100 * req->best_parent_rate;
+ unsigned long rate = clamp(req->rate, req->min_rate, req->max_rate);
+ unsigned long div100 = clamp(DIV_ROUND_CLOSEST(parent100, rate),
+- JH7100_CLK_FRAC_MIN, JH7100_CLK_FRAC_MAX);
++ JH71X0_CLK_FRAC_MIN, JH71X0_CLK_FRAC_MAX);
+ unsigned long result = parent100 / div100;
+
+- /* clamp the result as in jh7100_clk_determine_rate() above */
+- if (result > req->max_rate && div100 < JH7100_CLK_FRAC_MAX)
++ /* clamp the result as in jh71x0_clk_determine_rate() above */
++ if (result > req->max_rate && div100 < JH71X0_CLK_FRAC_MAX)
+ result = parent100 / (div100 + 1);
+- if (result < req->min_rate && div100 > JH7100_CLK_FRAC_MIN)
++ if (result < req->min_rate && div100 > JH71X0_CLK_FRAC_MIN)
+ result = parent100 / (div100 - 1);
+
+ req->rate = result;
+ return 0;
+ }
+
+-static int jh7100_clk_frac_set_rate(struct clk_hw *hw,
++static int jh71x0_clk_frac_set_rate(struct clk_hw *hw,
+ unsigned long rate,
+ unsigned long parent_rate)
+ {
+- struct jh7100_clk *clk = jh7100_clk_from(hw);
++ struct jh71x0_clk *clk = jh71x0_clk_from(hw);
+ unsigned long div100 = clamp(DIV_ROUND_CLOSEST(100 * parent_rate, rate),
+- JH7100_CLK_FRAC_MIN, JH7100_CLK_FRAC_MAX);
+- u32 value = ((div100 % 100) << JH7100_CLK_FRAC_SHIFT) | (div100 / 100);
++ JH71X0_CLK_FRAC_MIN, JH71X0_CLK_FRAC_MAX);
++ u32 value = ((div100 % 100) << JH71X0_CLK_FRAC_SHIFT) | (div100 / 100);
+
+- jh7100_clk_reg_rmw(clk, JH7100_CLK_DIV_MASK, value);
++ jh71x0_clk_reg_rmw(clk, JH71X0_CLK_DIV_MASK, value);
+ return 0;
+ }
+
+-static u8 jh7100_clk_get_parent(struct clk_hw *hw)
++static u8 jh71x0_clk_get_parent(struct clk_hw *hw)
+ {
+- struct jh7100_clk *clk = jh7100_clk_from(hw);
+- u32 value = jh7100_clk_reg_get(clk);
++ struct jh71x0_clk *clk = jh71x0_clk_from(hw);
++ u32 value = jh71x0_clk_reg_get(clk);
+
+- return (value & JH7100_CLK_MUX_MASK) >> JH7100_CLK_MUX_SHIFT;
++ return (value & JH71X0_CLK_MUX_MASK) >> JH71X0_CLK_MUX_SHIFT;
+ }
+
+-static int jh7100_clk_set_parent(struct clk_hw *hw, u8 index)
++static int jh71x0_clk_set_parent(struct clk_hw *hw, u8 index)
+ {
+- struct jh7100_clk *clk = jh7100_clk_from(hw);
+- u32 value = (u32)index << JH7100_CLK_MUX_SHIFT;
++ struct jh71x0_clk *clk = jh71x0_clk_from(hw);
++ u32 value = (u32)index << JH71X0_CLK_MUX_SHIFT;
+
+- jh7100_clk_reg_rmw(clk, JH7100_CLK_MUX_MASK, value);
++ jh71x0_clk_reg_rmw(clk, JH71X0_CLK_MUX_MASK, value);
+ return 0;
+ }
+
+-static int jh7100_clk_mux_determine_rate(struct clk_hw *hw,
++static int jh71x0_clk_mux_determine_rate(struct clk_hw *hw,
+ struct clk_rate_request *req)
+ {
+ return clk_mux_determine_rate_flags(hw, req, 0);
+ }
+
+-static int jh7100_clk_get_phase(struct clk_hw *hw)
++static int jh71x0_clk_get_phase(struct clk_hw *hw)
+ {
+- struct jh7100_clk *clk = jh7100_clk_from(hw);
+- u32 value = jh7100_clk_reg_get(clk);
++ struct jh71x0_clk *clk = jh71x0_clk_from(hw);
++ u32 value = jh71x0_clk_reg_get(clk);
+
+- return (value & JH7100_CLK_INVERT) ? 180 : 0;
++ return (value & JH71X0_CLK_INVERT) ? 180 : 0;
+ }
+
+-static int jh7100_clk_set_phase(struct clk_hw *hw, int degrees)
++static int jh71x0_clk_set_phase(struct clk_hw *hw, int degrees)
+ {
+- struct jh7100_clk *clk = jh7100_clk_from(hw);
++ struct jh71x0_clk *clk = jh71x0_clk_from(hw);
+ u32 value;
+
+ if (degrees == 0)
+ value = 0;
+ else if (degrees == 180)
+- value = JH7100_CLK_INVERT;
++ value = JH71X0_CLK_INVERT;
+ else
+ return -EINVAL;
+
+- jh7100_clk_reg_rmw(clk, JH7100_CLK_INVERT, value);
++ jh71x0_clk_reg_rmw(clk, JH71X0_CLK_INVERT, value);
+ return 0;
+ }
+
+ #ifdef CONFIG_DEBUG_FS
+-static void jh7100_clk_debug_init(struct clk_hw *hw, struct dentry *dentry)
++static void jh71x0_clk_debug_init(struct clk_hw *hw, struct dentry *dentry)
+ {
+- static const struct debugfs_reg32 jh7100_clk_reg = {
++ static const struct debugfs_reg32 jh71x0_clk_reg = {
+ .name = "CTRL",
+ .offset = 0,
+ };
+- struct jh7100_clk *clk = jh7100_clk_from(hw);
+- struct jh7100_clk_priv *priv = jh7100_priv_from(clk);
++ struct jh71x0_clk *clk = jh71x0_clk_from(hw);
++ struct jh71x0_clk_priv *priv = jh71x0_priv_from(clk);
+ struct debugfs_regset32 *regset;
+
+ regset = devm_kzalloc(priv->dev, sizeof(*regset), GFP_KERNEL);
+ if (!regset)
+ return;
+
+- regset->regs = &jh7100_clk_reg;
++ regset->regs = &jh71x0_clk_reg;
+ regset->nregs = 1;
+ regset->base = priv->base + 4 * clk->idx;
+
+ debugfs_create_regset32("registers", 0400, dentry, regset);
+ }
+ #else
+-#define jh7100_clk_debug_init NULL
++#define jh71x0_clk_debug_init NULL
+ #endif
+
+-static const struct clk_ops jh7100_clk_gate_ops = {
+- .enable = jh7100_clk_enable,
+- .disable = jh7100_clk_disable,
+- .is_enabled = jh7100_clk_is_enabled,
+- .debug_init = jh7100_clk_debug_init,
++static const struct clk_ops jh71x0_clk_gate_ops = {
++ .enable = jh71x0_clk_enable,
++ .disable = jh71x0_clk_disable,
++ .is_enabled = jh71x0_clk_is_enabled,
++ .debug_init = jh71x0_clk_debug_init,
+ };
+
+-static const struct clk_ops jh7100_clk_div_ops = {
+- .recalc_rate = jh7100_clk_recalc_rate,
+- .determine_rate = jh7100_clk_determine_rate,
+- .set_rate = jh7100_clk_set_rate,
+- .debug_init = jh7100_clk_debug_init,
++static const struct clk_ops jh71x0_clk_div_ops = {
++ .recalc_rate = jh71x0_clk_recalc_rate,
++ .determine_rate = jh71x0_clk_determine_rate,
++ .set_rate = jh71x0_clk_set_rate,
++ .debug_init = jh71x0_clk_debug_init,
+ };
+
+-static const struct clk_ops jh7100_clk_fdiv_ops = {
+- .recalc_rate = jh7100_clk_frac_recalc_rate,
+- .determine_rate = jh7100_clk_frac_determine_rate,
+- .set_rate = jh7100_clk_frac_set_rate,
+- .debug_init = jh7100_clk_debug_init,
++static const struct clk_ops jh71x0_clk_fdiv_ops = {
++ .recalc_rate = jh71x0_clk_frac_recalc_rate,
++ .determine_rate = jh71x0_clk_frac_determine_rate,
++ .set_rate = jh71x0_clk_frac_set_rate,
++ .debug_init = jh71x0_clk_debug_init,
+ };
+
+-static const struct clk_ops jh7100_clk_gdiv_ops = {
+- .enable = jh7100_clk_enable,
+- .disable = jh7100_clk_disable,
+- .is_enabled = jh7100_clk_is_enabled,
+- .recalc_rate = jh7100_clk_recalc_rate,
+- .determine_rate = jh7100_clk_determine_rate,
+- .set_rate = jh7100_clk_set_rate,
+- .debug_init = jh7100_clk_debug_init,
++static const struct clk_ops jh71x0_clk_gdiv_ops = {
++ .enable = jh71x0_clk_enable,
++ .disable = jh71x0_clk_disable,
++ .is_enabled = jh71x0_clk_is_enabled,
++ .recalc_rate = jh71x0_clk_recalc_rate,
++ .determine_rate = jh71x0_clk_determine_rate,
++ .set_rate = jh71x0_clk_set_rate,
++ .debug_init = jh71x0_clk_debug_init,
+ };
+
+-static const struct clk_ops jh7100_clk_mux_ops = {
+- .determine_rate = jh7100_clk_mux_determine_rate,
+- .set_parent = jh7100_clk_set_parent,
+- .get_parent = jh7100_clk_get_parent,
+- .debug_init = jh7100_clk_debug_init,
++static const struct clk_ops jh71x0_clk_mux_ops = {
++ .determine_rate = jh71x0_clk_mux_determine_rate,
++ .set_parent = jh71x0_clk_set_parent,
++ .get_parent = jh71x0_clk_get_parent,
++ .debug_init = jh71x0_clk_debug_init,
+ };
+
+-static const struct clk_ops jh7100_clk_gmux_ops = {
+- .enable = jh7100_clk_enable,
+- .disable = jh7100_clk_disable,
+- .is_enabled = jh7100_clk_is_enabled,
+- .determine_rate = jh7100_clk_mux_determine_rate,
+- .set_parent = jh7100_clk_set_parent,
+- .get_parent = jh7100_clk_get_parent,
+- .debug_init = jh7100_clk_debug_init,
++static const struct clk_ops jh71x0_clk_gmux_ops = {
++ .enable = jh71x0_clk_enable,
++ .disable = jh71x0_clk_disable,
++ .is_enabled = jh71x0_clk_is_enabled,
++ .determine_rate = jh71x0_clk_mux_determine_rate,
++ .set_parent = jh71x0_clk_set_parent,
++ .get_parent = jh71x0_clk_get_parent,
++ .debug_init = jh71x0_clk_debug_init,
+ };
+
+-static const struct clk_ops jh7100_clk_mdiv_ops = {
+- .recalc_rate = jh7100_clk_recalc_rate,
+- .determine_rate = jh7100_clk_determine_rate,
+- .get_parent = jh7100_clk_get_parent,
+- .set_parent = jh7100_clk_set_parent,
+- .set_rate = jh7100_clk_set_rate,
+- .debug_init = jh7100_clk_debug_init,
++static const struct clk_ops jh71x0_clk_mdiv_ops = {
++ .recalc_rate = jh71x0_clk_recalc_rate,
++ .determine_rate = jh71x0_clk_determine_rate,
++ .get_parent = jh71x0_clk_get_parent,
++ .set_parent = jh71x0_clk_set_parent,
++ .set_rate = jh71x0_clk_set_rate,
++ .debug_init = jh71x0_clk_debug_init,
+ };
+
+-static const struct clk_ops jh7100_clk_gmd_ops = {
+- .enable = jh7100_clk_enable,
+- .disable = jh7100_clk_disable,
+- .is_enabled = jh7100_clk_is_enabled,
+- .recalc_rate = jh7100_clk_recalc_rate,
+- .determine_rate = jh7100_clk_determine_rate,
+- .get_parent = jh7100_clk_get_parent,
+- .set_parent = jh7100_clk_set_parent,
+- .set_rate = jh7100_clk_set_rate,
+- .debug_init = jh7100_clk_debug_init,
++static const struct clk_ops jh71x0_clk_gmd_ops = {
++ .enable = jh71x0_clk_enable,
++ .disable = jh71x0_clk_disable,
++ .is_enabled = jh71x0_clk_is_enabled,
++ .recalc_rate = jh71x0_clk_recalc_rate,
++ .determine_rate = jh71x0_clk_determine_rate,
++ .get_parent = jh71x0_clk_get_parent,
++ .set_parent = jh71x0_clk_set_parent,
++ .set_rate = jh71x0_clk_set_rate,
++ .debug_init = jh71x0_clk_debug_init,
+ };
+
+-static const struct clk_ops jh7100_clk_inv_ops = {
+- .get_phase = jh7100_clk_get_phase,
+- .set_phase = jh7100_clk_set_phase,
+- .debug_init = jh7100_clk_debug_init,
++static const struct clk_ops jh71x0_clk_inv_ops = {
++ .get_phase = jh71x0_clk_get_phase,
++ .set_phase = jh71x0_clk_set_phase,
++ .debug_init = jh71x0_clk_debug_init,
+ };
+
+-const struct clk_ops *starfive_jh7100_clk_ops(u32 max)
++const struct clk_ops *starfive_jh71x0_clk_ops(u32 max)
+ {
+- if (max & JH7100_CLK_DIV_MASK) {
+- if (max & JH7100_CLK_MUX_MASK) {
+- if (max & JH7100_CLK_ENABLE)
+- return &jh7100_clk_gmd_ops;
+- return &jh7100_clk_mdiv_ops;
++ if (max & JH71X0_CLK_DIV_MASK) {
++ if (max & JH71X0_CLK_MUX_MASK) {
++ if (max & JH71X0_CLK_ENABLE)
++ return &jh71x0_clk_gmd_ops;
++ return &jh71x0_clk_mdiv_ops;
+ }
+- if (max & JH7100_CLK_ENABLE)
+- return &jh7100_clk_gdiv_ops;
+- if (max == JH7100_CLK_FRAC_MAX)
+- return &jh7100_clk_fdiv_ops;
+- return &jh7100_clk_div_ops;
++ if (max & JH71X0_CLK_ENABLE)
++ return &jh71x0_clk_gdiv_ops;
++ if (max == JH71X0_CLK_FRAC_MAX)
++ return &jh71x0_clk_fdiv_ops;
++ return &jh71x0_clk_div_ops;
+ }
+
+- if (max & JH7100_CLK_MUX_MASK) {
+- if (max & JH7100_CLK_ENABLE)
+- return &jh7100_clk_gmux_ops;
+- return &jh7100_clk_mux_ops;
++ if (max & JH71X0_CLK_MUX_MASK) {
++ if (max & JH71X0_CLK_ENABLE)
++ return &jh71x0_clk_gmux_ops;
++ return &jh71x0_clk_mux_ops;
+ }
+
+- if (max & JH7100_CLK_ENABLE)
+- return &jh7100_clk_gate_ops;
++ if (max & JH71X0_CLK_ENABLE)
++ return &jh71x0_clk_gate_ops;
+
+- return &jh7100_clk_inv_ops;
++ return &jh71x0_clk_inv_ops;
+ }
+-EXPORT_SYMBOL_GPL(starfive_jh7100_clk_ops);
++EXPORT_SYMBOL_GPL(starfive_jh71x0_clk_ops);
+diff --git a/drivers/clk/starfive/clk-starfive-jh71x0.h b/drivers/clk/starfive/clk-starfive-jh71x0.h
+index a8ba6e25b5ce..34bb11c72eb7 100644
+--- a/drivers/clk/starfive/clk-starfive-jh71x0.h
++++ b/drivers/clk/starfive/clk-starfive-jh71x0.h
+@@ -1,6 +1,6 @@
+ /* SPDX-License-Identifier: GPL-2.0 */
+-#ifndef __CLK_STARFIVE_JH7100_H
+-#define __CLK_STARFIVE_JH7100_H
++#ifndef __CLK_STARFIVE_JH71X0_H
++#define __CLK_STARFIVE_JH71X0_H
+
+ #include <linux/bits.h>
+ #include <linux/clk-provider.h>
+@@ -8,107 +8,116 @@
+ #include <linux/spinlock.h>
+
+ /* register fields */
+-#define JH7100_CLK_ENABLE BIT(31)
+-#define JH7100_CLK_INVERT BIT(30)
+-#define JH7100_CLK_MUX_MASK GENMASK(27, 24)
+-#define JH7100_CLK_MUX_SHIFT 24
+-#define JH7100_CLK_DIV_MASK GENMASK(23, 0)
+-#define JH7100_CLK_FRAC_MASK GENMASK(15, 8)
+-#define JH7100_CLK_FRAC_SHIFT 8
+-#define JH7100_CLK_INT_MASK GENMASK(7, 0)
++#define JH71X0_CLK_ENABLE BIT(31)
++#define JH71X0_CLK_INVERT BIT(30)
++#define JH71X0_CLK_MUX_MASK GENMASK(27, 24)
++#define JH71X0_CLK_MUX_SHIFT 24
++#define JH71X0_CLK_DIV_MASK GENMASK(23, 0)
++#define JH71X0_CLK_FRAC_MASK GENMASK(15, 8)
++#define JH71X0_CLK_FRAC_SHIFT 8
++#define JH71X0_CLK_INT_MASK GENMASK(7, 0)
+
+ /* fractional divider min/max */
+-#define JH7100_CLK_FRAC_MIN 100UL
+-#define JH7100_CLK_FRAC_MAX 25599UL
++#define JH71X0_CLK_FRAC_MIN 100UL
++#define JH71X0_CLK_FRAC_MAX 25599UL
+
+ /* clock data */
+-struct jh7100_clk_data {
++struct jh71x0_clk_data {
+ const char *name;
+ unsigned long flags;
+ u32 max;
+ u8 parents[4];
+ };
+
+-#define JH7100_GATE(_idx, _name, _flags, _parent) [_idx] = { \
++#define JH71X0_GATE(_idx, _name, _flags, _parent) \
++[_idx] = { \
+ .name = _name, \
+ .flags = CLK_SET_RATE_PARENT | (_flags), \
+- .max = JH7100_CLK_ENABLE, \
++ .max = JH71X0_CLK_ENABLE, \
+ .parents = { [0] = _parent }, \
+ }
+
+-#define JH7100__DIV(_idx, _name, _max, _parent) [_idx] = { \
++#define JH71X0__DIV(_idx, _name, _max, _parent) \
++[_idx] = { \
+ .name = _name, \
+ .flags = 0, \
+ .max = _max, \
+ .parents = { [0] = _parent }, \
+ }
+
+-#define JH7100_GDIV(_idx, _name, _flags, _max, _parent) [_idx] = { \
++#define JH71X0_GDIV(_idx, _name, _flags, _max, _parent) \
++[_idx] = { \
+ .name = _name, \
+ .flags = _flags, \
+- .max = JH7100_CLK_ENABLE | (_max), \
++ .max = JH71X0_CLK_ENABLE | (_max), \
+ .parents = { [0] = _parent }, \
+ }
+
+-#define JH7100_FDIV(_idx, _name, _parent) [_idx] = { \
++#define JH71X0_FDIV(_idx, _name, _parent) \
++[_idx] = { \
+ .name = _name, \
+ .flags = 0, \
+- .max = JH7100_CLK_FRAC_MAX, \
++ .max = JH71X0_CLK_FRAC_MAX, \
+ .parents = { [0] = _parent }, \
+ }
+
+-#define JH7100__MUX(_idx, _name, _nparents, ...) [_idx] = { \
++#define JH71X0__MUX(_idx, _name, _nparents, ...) \
++[_idx] = { \
+ .name = _name, \
+ .flags = 0, \
+- .max = ((_nparents) - 1) << JH7100_CLK_MUX_SHIFT, \
++ .max = ((_nparents) - 1) << JH71X0_CLK_MUX_SHIFT, \
+ .parents = { __VA_ARGS__ }, \
+ }
+
+-#define JH7100_GMUX(_idx, _name, _flags, _nparents, ...) [_idx] = { \
++#define JH71X0_GMUX(_idx, _name, _flags, _nparents, ...) \
++[_idx] = { \
+ .name = _name, \
+ .flags = _flags, \
+- .max = JH7100_CLK_ENABLE | \
+- (((_nparents) - 1) << JH7100_CLK_MUX_SHIFT), \
++ .max = JH71X0_CLK_ENABLE | \
++ (((_nparents) - 1) << JH71X0_CLK_MUX_SHIFT), \
+ .parents = { __VA_ARGS__ }, \
+ }
+
+-#define JH7100_MDIV(_idx, _name, _max, _nparents, ...) [_idx] = { \
++#define JH71X0_MDIV(_idx, _name, _max, _nparents, ...) \
++[_idx] = { \
+ .name = _name, \
+ .flags = 0, \
+- .max = (((_nparents) - 1) << JH7100_CLK_MUX_SHIFT) | (_max), \
++ .max = (((_nparents) - 1) << JH71X0_CLK_MUX_SHIFT) | (_max), \
+ .parents = { __VA_ARGS__ }, \
+ }
+
+-#define JH7100__GMD(_idx, _name, _flags, _max, _nparents, ...) [_idx] = { \
++#define JH71X0__GMD(_idx, _name, _flags, _max, _nparents, ...) \
++[_idx] = { \
+ .name = _name, \
+ .flags = _flags, \
+- .max = JH7100_CLK_ENABLE | \
+- (((_nparents) - 1) << JH7100_CLK_MUX_SHIFT) | (_max), \
++ .max = JH71X0_CLK_ENABLE | \
++ (((_nparents) - 1) << JH71X0_CLK_MUX_SHIFT) | (_max), \
+ .parents = { __VA_ARGS__ }, \
+ }
+
+-#define JH7100__INV(_idx, _name, _parent) [_idx] = { \
++#define JH71X0__INV(_idx, _name, _parent) \
++[_idx] = { \
+ .name = _name, \
+ .flags = CLK_SET_RATE_PARENT, \
+- .max = JH7100_CLK_INVERT, \
++ .max = JH71X0_CLK_INVERT, \
+ .parents = { [0] = _parent }, \
+ }
+
+-struct jh7100_clk {
++struct jh71x0_clk {
+ struct clk_hw hw;
+ unsigned int idx;
+ unsigned int max_div;
+ };
+
+-struct jh7100_clk_priv {
++struct jh71x0_clk_priv {
+ /* protect clk enable and set rate/parent from happening at the same time */
+ spinlock_t rmw_lock;
+ struct device *dev;
+ void __iomem *base;
+ struct clk_hw *pll[3];
+- struct jh7100_clk reg[];
++ struct jh71x0_clk reg[];
+ };
+
+-const struct clk_ops *starfive_jh7100_clk_ops(u32 max);
++const struct clk_ops *starfive_jh71x0_clk_ops(u32 max);
+
+ #endif
+--
+2.20.1
+
--- /dev/null
+From f25e6310f6693cd36338ac298dec8704137a8612 Mon Sep 17 00:00:00 2001
+From: Hal Feng <hal.feng@starfivetech.com>
+Date: Sat, 1 Apr 2023 19:19:19 +0800
+Subject: [PATCH 11/95] reset: starfive: Replace SOC_STARFIVE with
+ ARCH_STARFIVE
+
+Using ARCH_FOO symbol is preferred than SOC_FOO.
+
+Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de>
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ drivers/reset/Kconfig | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
+index 2a52c990d4fe..6ae5aa46a6b2 100644
+--- a/drivers/reset/Kconfig
++++ b/drivers/reset/Kconfig
+@@ -234,8 +234,8 @@ config RESET_SOCFPGA
+
+ config RESET_STARFIVE_JH7100
+ bool "StarFive JH7100 Reset Driver"
+- depends on SOC_STARFIVE || COMPILE_TEST
+- default SOC_STARFIVE
++ depends on ARCH_STARFIVE || COMPILE_TEST
++ default ARCH_STARFIVE
+ help
+ This enables the reset controller driver for the StarFive JH7100 SoC.
+
+--
+2.20.1
+
--- /dev/null
+From 25a44e2d71af99e9f6f243aeea0e36bb4b7766a1 Mon Sep 17 00:00:00 2001
+From: Emil Renner Berthing <kernel@esmil.dk>
+Date: Sat, 1 Apr 2023 19:19:20 +0800
+Subject: [PATCH 12/95] reset: Create subdirectory for StarFive drivers
+
+This moves the StarFive JH7100 reset driver to a new subdirectory in
+preparation for adding more StarFive reset drivers.
+
+Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de>
+Tested-by: Tommaso Merciai <tomm.merciai@gmail.com>
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ drivers/reset/Kconfig | 8 +-------
+ drivers/reset/Makefile | 2 +-
+ drivers/reset/starfive/Kconfig | 8 ++++++++
+ drivers/reset/starfive/Makefile | 2 ++
+ drivers/reset/{ => starfive}/reset-starfive-jh7100.c | 0
+ 5 files changed, 12 insertions(+), 8 deletions(-)
+ create mode 100644 drivers/reset/starfive/Kconfig
+ create mode 100644 drivers/reset/starfive/Makefile
+ rename drivers/reset/{ => starfive}/reset-starfive-jh7100.c (100%)
+
+diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
+index 6ae5aa46a6b2..6aa8f243b30c 100644
+--- a/drivers/reset/Kconfig
++++ b/drivers/reset/Kconfig
+@@ -232,13 +232,6 @@ config RESET_SOCFPGA
+ This enables the reset driver for the SoCFPGA ARMv7 platforms. This
+ driver gets initialized early during platform init calls.
+
+-config RESET_STARFIVE_JH7100
+- bool "StarFive JH7100 Reset Driver"
+- depends on ARCH_STARFIVE || COMPILE_TEST
+- default ARCH_STARFIVE
+- help
+- This enables the reset controller driver for the StarFive JH7100 SoC.
+-
+ config RESET_SUNPLUS
+ bool "Sunplus SoCs Reset Driver" if COMPILE_TEST
+ default ARCH_SUNPLUS
+@@ -320,6 +313,7 @@ config RESET_ZYNQ
+ help
+ This enables the reset controller driver for Xilinx Zynq SoCs.
+
++source "drivers/reset/starfive/Kconfig"
+ source "drivers/reset/sti/Kconfig"
+ source "drivers/reset/hisilicon/Kconfig"
+ source "drivers/reset/tegra/Kconfig"
+diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
+index 3e7e5fd633a8..7fec5af6c964 100644
+--- a/drivers/reset/Makefile
++++ b/drivers/reset/Makefile
+@@ -1,6 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ obj-y += core.o
+ obj-y += hisilicon/
++obj-y += starfive/
+ obj-$(CONFIG_ARCH_STI) += sti/
+ obj-$(CONFIG_ARCH_TEGRA) += tegra/
+ obj-$(CONFIG_RESET_A10SR) += reset-a10sr.o
+@@ -30,7 +31,6 @@ obj-$(CONFIG_RESET_RZG2L_USBPHY_CTRL) += reset-rzg2l-usbphy-ctrl.o
+ obj-$(CONFIG_RESET_SCMI) += reset-scmi.o
+ obj-$(CONFIG_RESET_SIMPLE) += reset-simple.o
+ obj-$(CONFIG_RESET_SOCFPGA) += reset-socfpga.o
+-obj-$(CONFIG_RESET_STARFIVE_JH7100) += reset-starfive-jh7100.o
+ obj-$(CONFIG_RESET_SUNPLUS) += reset-sunplus.o
+ obj-$(CONFIG_RESET_SUNXI) += reset-sunxi.o
+ obj-$(CONFIG_RESET_TI_SCI) += reset-ti-sci.o
+diff --git a/drivers/reset/starfive/Kconfig b/drivers/reset/starfive/Kconfig
+new file mode 100644
+index 000000000000..abbf0c52d03e
+--- /dev/null
++++ b/drivers/reset/starfive/Kconfig
+@@ -0,0 +1,8 @@
++# SPDX-License-Identifier: GPL-2.0-only
++
++config RESET_STARFIVE_JH7100
++ bool "StarFive JH7100 Reset Driver"
++ depends on ARCH_STARFIVE || COMPILE_TEST
++ default ARCH_STARFIVE
++ help
++ This enables the reset controller driver for the StarFive JH7100 SoC.
+diff --git a/drivers/reset/starfive/Makefile b/drivers/reset/starfive/Makefile
+new file mode 100644
+index 000000000000..670d049423f5
+--- /dev/null
++++ b/drivers/reset/starfive/Makefile
+@@ -0,0 +1,2 @@
++# SPDX-License-Identifier: GPL-2.0
++obj-$(CONFIG_RESET_STARFIVE_JH7100) += reset-starfive-jh7100.o
+diff --git a/drivers/reset/reset-starfive-jh7100.c b/drivers/reset/starfive/reset-starfive-jh7100.c
+similarity index 100%
+rename from drivers/reset/reset-starfive-jh7100.c
+rename to drivers/reset/starfive/reset-starfive-jh7100.c
+--
+2.20.1
+
--- /dev/null
+From ccae68e5fe5a3f7fabc16c941f6c14544d1c930e Mon Sep 17 00:00:00 2001
+From: Emil Renner Berthing <kernel@esmil.dk>
+Date: Sat, 1 Apr 2023 19:19:21 +0800
+Subject: [PATCH 13/95] reset: starfive: Factor out common JH71X0 reset code
+
+The StarFive JH7100 SoC has additional reset controllers for audio and
+video, but the registers follow the same structure. On the JH7110 the
+reset registers don't get their own memory range, but instead follow the
+clock control registers. The registers still follow the same structure
+though, so let's factor out the common code to handle all these cases.
+
+Tested-by: Tommaso Merciai <tomm.merciai@gmail.com>
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ drivers/reset/starfive/Kconfig | 4 +
+ drivers/reset/starfive/Makefile | 2 +
+ .../reset/starfive/reset-starfive-jh7100.c | 150 +---------------
+ .../reset/starfive/reset-starfive-jh71x0.c | 162 ++++++++++++++++++
+ .../reset/starfive/reset-starfive-jh71x0.h | 11 ++
+ 5 files changed, 180 insertions(+), 149 deletions(-)
+ create mode 100644 drivers/reset/starfive/reset-starfive-jh71x0.c
+ create mode 100644 drivers/reset/starfive/reset-starfive-jh71x0.h
+
+diff --git a/drivers/reset/starfive/Kconfig b/drivers/reset/starfive/Kconfig
+index abbf0c52d03e..1927a5a3b53a 100644
+--- a/drivers/reset/starfive/Kconfig
++++ b/drivers/reset/starfive/Kconfig
+@@ -1,8 +1,12 @@
+ # SPDX-License-Identifier: GPL-2.0-only
+
++config RESET_STARFIVE_JH71X0
++ bool
++
+ config RESET_STARFIVE_JH7100
+ bool "StarFive JH7100 Reset Driver"
+ depends on ARCH_STARFIVE || COMPILE_TEST
++ select RESET_STARFIVE_JH71X0
+ default ARCH_STARFIVE
+ help
+ This enables the reset controller driver for the StarFive JH7100 SoC.
+diff --git a/drivers/reset/starfive/Makefile b/drivers/reset/starfive/Makefile
+index 670d049423f5..f6aa12466fad 100644
+--- a/drivers/reset/starfive/Makefile
++++ b/drivers/reset/starfive/Makefile
+@@ -1,2 +1,4 @@
+ # SPDX-License-Identifier: GPL-2.0
++obj-$(CONFIG_RESET_STARFIVE_JH71X0) += reset-starfive-jh71x0.o
++
+ obj-$(CONFIG_RESET_STARFIVE_JH7100) += reset-starfive-jh7100.o
+diff --git a/drivers/reset/starfive/reset-starfive-jh7100.c b/drivers/reset/starfive/reset-starfive-jh7100.c
+index fc44b2fb3e03..5a68327c1f6a 100644
+--- a/drivers/reset/starfive/reset-starfive-jh7100.c
++++ b/drivers/reset/starfive/reset-starfive-jh7100.c
+@@ -5,158 +5,10 @@
+ * Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
+ */
+
+-#include <linux/bitmap.h>
+-#include <linux/io.h>
+-#include <linux/io-64-nonatomic-lo-hi.h>
+-#include <linux/iopoll.h>
+ #include <linux/mod_devicetable.h>
+ #include <linux/platform_device.h>
+-#include <linux/reset-controller.h>
+-#include <linux/spinlock.h>
+
+-#include <dt-bindings/reset/starfive-jh7100.h>
+-
+-/* register offsets */
+-#define JH7100_RESET_ASSERT0 0x00
+-#define JH7100_RESET_ASSERT1 0x04
+-#define JH7100_RESET_ASSERT2 0x08
+-#define JH7100_RESET_ASSERT3 0x0c
+-#define JH7100_RESET_STATUS0 0x10
+-#define JH7100_RESET_STATUS1 0x14
+-#define JH7100_RESET_STATUS2 0x18
+-#define JH7100_RESET_STATUS3 0x1c
+-
+-/*
+- * Writing a 1 to the n'th bit of the m'th ASSERT register asserts
+- * line 32m + n, and writing a 0 deasserts the same line.
+- * Most reset lines have their status inverted so a 0 bit in the STATUS
+- * register means the line is asserted and a 1 means it's deasserted. A few
+- * lines don't though, so store the expected value of the status registers when
+- * all lines are asserted.
+- */
+-static const u64 jh7100_reset_asserted[2] = {
+- /* STATUS0 */
+- BIT_ULL_MASK(JH7100_RST_U74) |
+- BIT_ULL_MASK(JH7100_RST_VP6_DRESET) |
+- BIT_ULL_MASK(JH7100_RST_VP6_BRESET) |
+- /* STATUS1 */
+- BIT_ULL_MASK(JH7100_RST_HIFI4_DRESET) |
+- BIT_ULL_MASK(JH7100_RST_HIFI4_BRESET),
+- /* STATUS2 */
+- BIT_ULL_MASK(JH7100_RST_E24) |
+- /* STATUS3 */
+- 0,
+-};
+-
+-struct jh7100_reset {
+- struct reset_controller_dev rcdev;
+- /* protect registers against concurrent read-modify-write */
+- spinlock_t lock;
+- void __iomem *base;
+-};
+-
+-static inline struct jh7100_reset *
+-jh7100_reset_from(struct reset_controller_dev *rcdev)
+-{
+- return container_of(rcdev, struct jh7100_reset, rcdev);
+-}
+-
+-static int jh7100_reset_update(struct reset_controller_dev *rcdev,
+- unsigned long id, bool assert)
+-{
+- struct jh7100_reset *data = jh7100_reset_from(rcdev);
+- unsigned long offset = BIT_ULL_WORD(id);
+- u64 mask = BIT_ULL_MASK(id);
+- void __iomem *reg_assert = data->base + JH7100_RESET_ASSERT0 + offset * sizeof(u64);
+- void __iomem *reg_status = data->base + JH7100_RESET_STATUS0 + offset * sizeof(u64);
+- u64 done = jh7100_reset_asserted[offset] & mask;
+- u64 value;
+- unsigned long flags;
+- int ret;
+-
+- if (!assert)
+- done ^= mask;
+-
+- spin_lock_irqsave(&data->lock, flags);
+-
+- value = readq(reg_assert);
+- if (assert)
+- value |= mask;
+- else
+- value &= ~mask;
+- writeq(value, reg_assert);
+-
+- /* if the associated clock is gated, deasserting might otherwise hang forever */
+- ret = readq_poll_timeout_atomic(reg_status, value, (value & mask) == done, 0, 1000);
+-
+- spin_unlock_irqrestore(&data->lock, flags);
+- return ret;
+-}
+-
+-static int jh7100_reset_assert(struct reset_controller_dev *rcdev,
+- unsigned long id)
+-{
+- return jh7100_reset_update(rcdev, id, true);
+-}
+-
+-static int jh7100_reset_deassert(struct reset_controller_dev *rcdev,
+- unsigned long id)
+-{
+- return jh7100_reset_update(rcdev, id, false);
+-}
+-
+-static int jh7100_reset_reset(struct reset_controller_dev *rcdev,
+- unsigned long id)
+-{
+- int ret;
+-
+- ret = jh7100_reset_assert(rcdev, id);
+- if (ret)
+- return ret;
+-
+- return jh7100_reset_deassert(rcdev, id);
+-}
+-
+-static int jh7100_reset_status(struct reset_controller_dev *rcdev,
+- unsigned long id)
+-{
+- struct jh7100_reset *data = jh7100_reset_from(rcdev);
+- unsigned long offset = BIT_ULL_WORD(id);
+- u64 mask = BIT_ULL_MASK(id);
+- void __iomem *reg_status = data->base + JH7100_RESET_STATUS0 + offset * sizeof(u64);
+- u64 value = readq(reg_status);
+-
+- return !((value ^ jh7100_reset_asserted[offset]) & mask);
+-}
+-
+-static const struct reset_control_ops jh7100_reset_ops = {
+- .assert = jh7100_reset_assert,
+- .deassert = jh7100_reset_deassert,
+- .reset = jh7100_reset_reset,
+- .status = jh7100_reset_status,
+-};
+-
+-static int __init jh7100_reset_probe(struct platform_device *pdev)
+-{
+- struct jh7100_reset *data;
+-
+- data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+- if (!data)
+- return -ENOMEM;
+-
+- data->base = devm_platform_ioremap_resource(pdev, 0);
+- if (IS_ERR(data->base))
+- return PTR_ERR(data->base);
+-
+- data->rcdev.ops = &jh7100_reset_ops;
+- data->rcdev.owner = THIS_MODULE;
+- data->rcdev.nr_resets = JH7100_RSTN_END;
+- data->rcdev.dev = &pdev->dev;
+- data->rcdev.of_node = pdev->dev.of_node;
+- spin_lock_init(&data->lock);
+-
+- return devm_reset_controller_register(&pdev->dev, &data->rcdev);
+-}
++#include "reset-starfive-jh71x0.h"
+
+ static const struct of_device_id jh7100_reset_dt_ids[] = {
+ { .compatible = "starfive,jh7100-reset" },
+diff --git a/drivers/reset/starfive/reset-starfive-jh71x0.c b/drivers/reset/starfive/reset-starfive-jh71x0.c
+new file mode 100644
+index 000000000000..114a13c4b8a6
+--- /dev/null
++++ b/drivers/reset/starfive/reset-starfive-jh71x0.c
+@@ -0,0 +1,162 @@
++// SPDX-License-Identifier: GPL-2.0-or-later
++/*
++ * Reset driver for the StarFive JH7100 SoC
++ *
++ * Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
++ */
++
++#include <linux/bitmap.h>
++#include <linux/device.h>
++#include <linux/io.h>
++#include <linux/io-64-nonatomic-lo-hi.h>
++#include <linux/iopoll.h>
++#include <linux/platform_device.h>
++#include <linux/reset-controller.h>
++#include <linux/spinlock.h>
++
++#include "reset-starfive-jh71x0.h"
++
++#include <dt-bindings/reset/starfive-jh7100.h>
++
++/* register offsets */
++#define JH7100_RESET_ASSERT0 0x00
++#define JH7100_RESET_ASSERT1 0x04
++#define JH7100_RESET_ASSERT2 0x08
++#define JH7100_RESET_ASSERT3 0x0c
++#define JH7100_RESET_STATUS0 0x10
++#define JH7100_RESET_STATUS1 0x14
++#define JH7100_RESET_STATUS2 0x18
++#define JH7100_RESET_STATUS3 0x1c
++
++/*
++ * Writing a 1 to the n'th bit of the m'th ASSERT register asserts
++ * line 32m + n, and writing a 0 deasserts the same line.
++ * Most reset lines have their status inverted so a 0 bit in the STATUS
++ * register means the line is asserted and a 1 means it's deasserted. A few
++ * lines don't though, so store the expected value of the status registers when
++ * all lines are asserted.
++ */
++static const u64 jh7100_reset_asserted[2] = {
++ /* STATUS0 */
++ BIT_ULL_MASK(JH7100_RST_U74) |
++ BIT_ULL_MASK(JH7100_RST_VP6_DRESET) |
++ BIT_ULL_MASK(JH7100_RST_VP6_BRESET) |
++ /* STATUS1 */
++ BIT_ULL_MASK(JH7100_RST_HIFI4_DRESET) |
++ BIT_ULL_MASK(JH7100_RST_HIFI4_BRESET),
++ /* STATUS2 */
++ BIT_ULL_MASK(JH7100_RST_E24) |
++ /* STATUS3 */
++ 0,
++};
++
++struct jh7100_reset {
++ struct reset_controller_dev rcdev;
++ /* protect registers against concurrent read-modify-write */
++ spinlock_t lock;
++ void __iomem *base;
++};
++
++static inline struct jh7100_reset *
++jh7100_reset_from(struct reset_controller_dev *rcdev)
++{
++ return container_of(rcdev, struct jh7100_reset, rcdev);
++}
++
++static int jh7100_reset_update(struct reset_controller_dev *rcdev,
++ unsigned long id, bool assert)
++{
++ struct jh7100_reset *data = jh7100_reset_from(rcdev);
++ unsigned long offset = BIT_ULL_WORD(id);
++ u64 mask = BIT_ULL_MASK(id);
++ void __iomem *reg_assert = data->base + JH7100_RESET_ASSERT0 + offset * sizeof(u64);
++ void __iomem *reg_status = data->base + JH7100_RESET_STATUS0 + offset * sizeof(u64);
++ u64 done = jh7100_reset_asserted[offset] & mask;
++ u64 value;
++ unsigned long flags;
++ int ret;
++
++ if (!assert)
++ done ^= mask;
++
++ spin_lock_irqsave(&data->lock, flags);
++
++ value = readq(reg_assert);
++ if (assert)
++ value |= mask;
++ else
++ value &= ~mask;
++ writeq(value, reg_assert);
++
++ /* if the associated clock is gated, deasserting might otherwise hang forever */
++ ret = readq_poll_timeout_atomic(reg_status, value, (value & mask) == done, 0, 1000);
++
++ spin_unlock_irqrestore(&data->lock, flags);
++ return ret;
++}
++
++static int jh7100_reset_assert(struct reset_controller_dev *rcdev,
++ unsigned long id)
++{
++ return jh7100_reset_update(rcdev, id, true);
++}
++
++static int jh7100_reset_deassert(struct reset_controller_dev *rcdev,
++ unsigned long id)
++{
++ return jh7100_reset_update(rcdev, id, false);
++}
++
++static int jh7100_reset_reset(struct reset_controller_dev *rcdev,
++ unsigned long id)
++{
++ int ret;
++
++ ret = jh7100_reset_assert(rcdev, id);
++ if (ret)
++ return ret;
++
++ return jh7100_reset_deassert(rcdev, id);
++}
++
++static int jh7100_reset_status(struct reset_controller_dev *rcdev,
++ unsigned long id)
++{
++ struct jh7100_reset *data = jh7100_reset_from(rcdev);
++ unsigned long offset = BIT_ULL_WORD(id);
++ u64 mask = BIT_ULL_MASK(id);
++ void __iomem *reg_status = data->base + JH7100_RESET_STATUS0 + offset * sizeof(u64);
++ u64 value = readq(reg_status);
++
++ return !((value ^ jh7100_reset_asserted[offset]) & mask);
++}
++
++static const struct reset_control_ops jh7100_reset_ops = {
++ .assert = jh7100_reset_assert,
++ .deassert = jh7100_reset_deassert,
++ .reset = jh7100_reset_reset,
++ .status = jh7100_reset_status,
++};
++
++int jh7100_reset_probe(struct platform_device *pdev)
++{
++ struct jh7100_reset *data;
++
++ data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
++ if (!data)
++ return -ENOMEM;
++
++ data->base = devm_platform_ioremap_resource(pdev, 0);
++ if (IS_ERR(data->base))
++ return PTR_ERR(data->base);
++
++ data->rcdev.ops = &jh7100_reset_ops;
++ data->rcdev.owner = THIS_MODULE;
++ data->rcdev.nr_resets = JH7100_RSTN_END;
++ data->rcdev.dev = &pdev->dev;
++ data->rcdev.of_node = pdev->dev.of_node;
++ spin_lock_init(&data->lock);
++
++ return devm_reset_controller_register(&pdev->dev, &data->rcdev);
++}
++EXPORT_SYMBOL_GPL(jh7100_reset_probe);
+diff --git a/drivers/reset/starfive/reset-starfive-jh71x0.h b/drivers/reset/starfive/reset-starfive-jh71x0.h
+new file mode 100644
+index 000000000000..318d7a0e096a
+--- /dev/null
++++ b/drivers/reset/starfive/reset-starfive-jh71x0.h
+@@ -0,0 +1,11 @@
++/* SPDX-License-Identifier: GPL-2.0-or-later */
++/*
++ * Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
++ */
++
++#ifndef __RESET_STARFIVE_JH71X0_H
++#define __RESET_STARFIVE_JH71X0_H
++
++int jh7100_reset_probe(struct platform_device *pdev);
++
++#endif /* __RESET_STARFIVE_JH71X0_H */
+--
+2.20.1
+
--- /dev/null
+From 1c701ff38896d91d4bedc9f0ecdd78243b231b24 Mon Sep 17 00:00:00 2001
+From: Emil Renner Berthing <kernel@esmil.dk>
+Date: Sat, 1 Apr 2023 19:19:22 +0800
+Subject: [PATCH 14/95] reset: starfive: Extract the common JH71X0 reset code
+
+Extract the common JH71X0 reset code for reusing them to
+support JH7110 SoC.
+
+Tested-by: Tommaso Merciai <tomm.merciai@gmail.com>
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ .../reset/starfive/reset-starfive-jh7100.c | 49 ++++++++++++
+ .../reset/starfive/reset-starfive-jh71x0.c | 76 ++++++-------------
+ .../reset/starfive/reset-starfive-jh71x0.h | 5 +-
+ 3 files changed, 76 insertions(+), 54 deletions(-)
+
+diff --git a/drivers/reset/starfive/reset-starfive-jh7100.c b/drivers/reset/starfive/reset-starfive-jh7100.c
+index 5a68327c1f6a..9d7cb4ed8869 100644
+--- a/drivers/reset/starfive/reset-starfive-jh7100.c
++++ b/drivers/reset/starfive/reset-starfive-jh7100.c
+@@ -10,6 +10,55 @@
+
+ #include "reset-starfive-jh71x0.h"
+
++#include <dt-bindings/reset/starfive-jh7100.h>
++
++/* register offsets */
++#define JH7100_RESET_ASSERT0 0x00
++#define JH7100_RESET_ASSERT1 0x04
++#define JH7100_RESET_ASSERT2 0x08
++#define JH7100_RESET_ASSERT3 0x0c
++#define JH7100_RESET_STATUS0 0x10
++#define JH7100_RESET_STATUS1 0x14
++#define JH7100_RESET_STATUS2 0x18
++#define JH7100_RESET_STATUS3 0x1c
++
++/*
++ * Writing a 1 to the n'th bit of the m'th ASSERT register asserts
++ * line 32m + n, and writing a 0 deasserts the same line.
++ * Most reset lines have their status inverted so a 0 bit in the STATUS
++ * register means the line is asserted and a 1 means it's deasserted. A few
++ * lines don't though, so store the expected value of the status registers when
++ * all lines are asserted.
++ */
++static const u64 jh7100_reset_asserted[2] = {
++ /* STATUS0 */
++ BIT_ULL_MASK(JH7100_RST_U74) |
++ BIT_ULL_MASK(JH7100_RST_VP6_DRESET) |
++ BIT_ULL_MASK(JH7100_RST_VP6_BRESET) |
++ /* STATUS1 */
++ BIT_ULL_MASK(JH7100_RST_HIFI4_DRESET) |
++ BIT_ULL_MASK(JH7100_RST_HIFI4_BRESET),
++ /* STATUS2 */
++ BIT_ULL_MASK(JH7100_RST_E24) |
++ /* STATUS3 */
++ 0,
++};
++
++static int __init jh7100_reset_probe(struct platform_device *pdev)
++{
++ void __iomem *base = devm_platform_ioremap_resource(pdev, 0);
++
++ if (IS_ERR(base))
++ return PTR_ERR(base);
++
++ return reset_starfive_jh7100_register(&pdev->dev, pdev->dev.of_node,
++ base + JH7100_RESET_ASSERT0,
++ base + JH7100_RESET_STATUS0,
++ jh7100_reset_asserted,
++ JH7100_RSTN_END,
++ THIS_MODULE);
++}
++
+ static const struct of_device_id jh7100_reset_dt_ids[] = {
+ { .compatible = "starfive,jh7100-reset" },
+ { /* sentinel */ }
+diff --git a/drivers/reset/starfive/reset-starfive-jh71x0.c b/drivers/reset/starfive/reset-starfive-jh71x0.c
+index 114a13c4b8a6..3577444a89c6 100644
+--- a/drivers/reset/starfive/reset-starfive-jh71x0.c
++++ b/drivers/reset/starfive/reset-starfive-jh71x0.c
+@@ -10,51 +10,18 @@
+ #include <linux/io.h>
+ #include <linux/io-64-nonatomic-lo-hi.h>
+ #include <linux/iopoll.h>
+-#include <linux/platform_device.h>
+ #include <linux/reset-controller.h>
+ #include <linux/spinlock.h>
+
+ #include "reset-starfive-jh71x0.h"
+
+-#include <dt-bindings/reset/starfive-jh7100.h>
+-
+-/* register offsets */
+-#define JH7100_RESET_ASSERT0 0x00
+-#define JH7100_RESET_ASSERT1 0x04
+-#define JH7100_RESET_ASSERT2 0x08
+-#define JH7100_RESET_ASSERT3 0x0c
+-#define JH7100_RESET_STATUS0 0x10
+-#define JH7100_RESET_STATUS1 0x14
+-#define JH7100_RESET_STATUS2 0x18
+-#define JH7100_RESET_STATUS3 0x1c
+-
+-/*
+- * Writing a 1 to the n'th bit of the m'th ASSERT register asserts
+- * line 32m + n, and writing a 0 deasserts the same line.
+- * Most reset lines have their status inverted so a 0 bit in the STATUS
+- * register means the line is asserted and a 1 means it's deasserted. A few
+- * lines don't though, so store the expected value of the status registers when
+- * all lines are asserted.
+- */
+-static const u64 jh7100_reset_asserted[2] = {
+- /* STATUS0 */
+- BIT_ULL_MASK(JH7100_RST_U74) |
+- BIT_ULL_MASK(JH7100_RST_VP6_DRESET) |
+- BIT_ULL_MASK(JH7100_RST_VP6_BRESET) |
+- /* STATUS1 */
+- BIT_ULL_MASK(JH7100_RST_HIFI4_DRESET) |
+- BIT_ULL_MASK(JH7100_RST_HIFI4_BRESET),
+- /* STATUS2 */
+- BIT_ULL_MASK(JH7100_RST_E24) |
+- /* STATUS3 */
+- 0,
+-};
+-
+ struct jh7100_reset {
+ struct reset_controller_dev rcdev;
+ /* protect registers against concurrent read-modify-write */
+ spinlock_t lock;
+- void __iomem *base;
++ void __iomem *assert;
++ void __iomem *status;
++ const u64 *asserted;
+ };
+
+ static inline struct jh7100_reset *
+@@ -69,9 +36,9 @@ static int jh7100_reset_update(struct reset_controller_dev *rcdev,
+ struct jh7100_reset *data = jh7100_reset_from(rcdev);
+ unsigned long offset = BIT_ULL_WORD(id);
+ u64 mask = BIT_ULL_MASK(id);
+- void __iomem *reg_assert = data->base + JH7100_RESET_ASSERT0 + offset * sizeof(u64);
+- void __iomem *reg_status = data->base + JH7100_RESET_STATUS0 + offset * sizeof(u64);
+- u64 done = jh7100_reset_asserted[offset] & mask;
++ void __iomem *reg_assert = data->assert + offset * sizeof(u64);
++ void __iomem *reg_status = data->status + offset * sizeof(u64);
++ u64 done = data->asserted ? data->asserted[offset] & mask : 0;
+ u64 value;
+ unsigned long flags;
+ int ret;
+@@ -125,10 +92,10 @@ static int jh7100_reset_status(struct reset_controller_dev *rcdev,
+ struct jh7100_reset *data = jh7100_reset_from(rcdev);
+ unsigned long offset = BIT_ULL_WORD(id);
+ u64 mask = BIT_ULL_MASK(id);
+- void __iomem *reg_status = data->base + JH7100_RESET_STATUS0 + offset * sizeof(u64);
++ void __iomem *reg_status = data->status + offset * sizeof(u64);
+ u64 value = readq(reg_status);
+
+- return !((value ^ jh7100_reset_asserted[offset]) & mask);
++ return !((value ^ data->asserted[offset]) & mask);
+ }
+
+ static const struct reset_control_ops jh7100_reset_ops = {
+@@ -138,25 +105,28 @@ static const struct reset_control_ops jh7100_reset_ops = {
+ .status = jh7100_reset_status,
+ };
+
+-int jh7100_reset_probe(struct platform_device *pdev)
++int reset_starfive_jh7100_register(struct device *dev, struct device_node *of_node,
++ void __iomem *assert, void __iomem *status,
++ const u64 *asserted, unsigned int nr_resets,
++ struct module *owner)
+ {
+ struct jh7100_reset *data;
+
+- data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
++ data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+- data->base = devm_platform_ioremap_resource(pdev, 0);
+- if (IS_ERR(data->base))
+- return PTR_ERR(data->base);
+-
+ data->rcdev.ops = &jh7100_reset_ops;
+- data->rcdev.owner = THIS_MODULE;
+- data->rcdev.nr_resets = JH7100_RSTN_END;
+- data->rcdev.dev = &pdev->dev;
+- data->rcdev.of_node = pdev->dev.of_node;
++ data->rcdev.owner = owner;
++ data->rcdev.nr_resets = nr_resets;
++ data->rcdev.dev = dev;
++ data->rcdev.of_node = of_node;
++
+ spin_lock_init(&data->lock);
++ data->assert = assert;
++ data->status = status;
++ data->asserted = asserted;
+
+- return devm_reset_controller_register(&pdev->dev, &data->rcdev);
++ return devm_reset_controller_register(dev, &data->rcdev);
+ }
+-EXPORT_SYMBOL_GPL(jh7100_reset_probe);
++EXPORT_SYMBOL_GPL(reset_starfive_jh7100_register);
+diff --git a/drivers/reset/starfive/reset-starfive-jh71x0.h b/drivers/reset/starfive/reset-starfive-jh71x0.h
+index 318d7a0e096a..1fc5a648c8d8 100644
+--- a/drivers/reset/starfive/reset-starfive-jh71x0.h
++++ b/drivers/reset/starfive/reset-starfive-jh71x0.h
+@@ -6,6 +6,9 @@
+ #ifndef __RESET_STARFIVE_JH71X0_H
+ #define __RESET_STARFIVE_JH71X0_H
+
+-int jh7100_reset_probe(struct platform_device *pdev);
++int reset_starfive_jh7100_register(struct device *dev, struct device_node *of_node,
++ void __iomem *assert, void __iomem *status,
++ const u64 *asserted, unsigned int nr_resets,
++ struct module *owner);
+
+ #endif /* __RESET_STARFIVE_JH71X0_H */
+--
+2.20.1
+
--- /dev/null
+From 269ffc66e3fbcd926407665fb19fc00243f65e08 Mon Sep 17 00:00:00 2001
+From: Emil Renner Berthing <kernel@esmil.dk>
+Date: Sat, 1 Apr 2023 19:19:23 +0800
+Subject: [PATCH 15/95] reset: starfive: Rename "jh7100" to "jh71x0" for the
+ common code
+
+For the common code will be shared with the StarFive JH7110 SoC.
+
+Tested-by: Tommaso Merciai <tomm.merciai@gmail.com>
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ .../reset/starfive/reset-starfive-jh7100.c | 2 +-
+ .../reset/starfive/reset-starfive-jh71x0.c | 50 +++++++++----------
+ .../reset/starfive/reset-starfive-jh71x0.h | 2 +-
+ 3 files changed, 27 insertions(+), 27 deletions(-)
+
+diff --git a/drivers/reset/starfive/reset-starfive-jh7100.c b/drivers/reset/starfive/reset-starfive-jh7100.c
+index 9d7cb4ed8869..5f06e5ae3346 100644
+--- a/drivers/reset/starfive/reset-starfive-jh7100.c
++++ b/drivers/reset/starfive/reset-starfive-jh7100.c
+@@ -51,7 +51,7 @@ static int __init jh7100_reset_probe(struct platform_device *pdev)
+ if (IS_ERR(base))
+ return PTR_ERR(base);
+
+- return reset_starfive_jh7100_register(&pdev->dev, pdev->dev.of_node,
++ return reset_starfive_jh71x0_register(&pdev->dev, pdev->dev.of_node,
+ base + JH7100_RESET_ASSERT0,
+ base + JH7100_RESET_STATUS0,
+ jh7100_reset_asserted,
+diff --git a/drivers/reset/starfive/reset-starfive-jh71x0.c b/drivers/reset/starfive/reset-starfive-jh71x0.c
+index 3577444a89c6..a689f4730ed7 100644
+--- a/drivers/reset/starfive/reset-starfive-jh71x0.c
++++ b/drivers/reset/starfive/reset-starfive-jh71x0.c
+@@ -1,6 +1,6 @@
+ // SPDX-License-Identifier: GPL-2.0-or-later
+ /*
+- * Reset driver for the StarFive JH7100 SoC
++ * Reset driver for the StarFive JH71X0 SoCs
+ *
+ * Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
+ */
+@@ -15,7 +15,7 @@
+
+ #include "reset-starfive-jh71x0.h"
+
+-struct jh7100_reset {
++struct jh71x0_reset {
+ struct reset_controller_dev rcdev;
+ /* protect registers against concurrent read-modify-write */
+ spinlock_t lock;
+@@ -24,16 +24,16 @@ struct jh7100_reset {
+ const u64 *asserted;
+ };
+
+-static inline struct jh7100_reset *
+-jh7100_reset_from(struct reset_controller_dev *rcdev)
++static inline struct jh71x0_reset *
++jh71x0_reset_from(struct reset_controller_dev *rcdev)
+ {
+- return container_of(rcdev, struct jh7100_reset, rcdev);
++ return container_of(rcdev, struct jh71x0_reset, rcdev);
+ }
+
+-static int jh7100_reset_update(struct reset_controller_dev *rcdev,
++static int jh71x0_reset_update(struct reset_controller_dev *rcdev,
+ unsigned long id, bool assert)
+ {
+- struct jh7100_reset *data = jh7100_reset_from(rcdev);
++ struct jh71x0_reset *data = jh71x0_reset_from(rcdev);
+ unsigned long offset = BIT_ULL_WORD(id);
+ u64 mask = BIT_ULL_MASK(id);
+ void __iomem *reg_assert = data->assert + offset * sizeof(u64);
+@@ -62,34 +62,34 @@ static int jh7100_reset_update(struct reset_controller_dev *rcdev,
+ return ret;
+ }
+
+-static int jh7100_reset_assert(struct reset_controller_dev *rcdev,
++static int jh71x0_reset_assert(struct reset_controller_dev *rcdev,
+ unsigned long id)
+ {
+- return jh7100_reset_update(rcdev, id, true);
++ return jh71x0_reset_update(rcdev, id, true);
+ }
+
+-static int jh7100_reset_deassert(struct reset_controller_dev *rcdev,
++static int jh71x0_reset_deassert(struct reset_controller_dev *rcdev,
+ unsigned long id)
+ {
+- return jh7100_reset_update(rcdev, id, false);
++ return jh71x0_reset_update(rcdev, id, false);
+ }
+
+-static int jh7100_reset_reset(struct reset_controller_dev *rcdev,
++static int jh71x0_reset_reset(struct reset_controller_dev *rcdev,
+ unsigned long id)
+ {
+ int ret;
+
+- ret = jh7100_reset_assert(rcdev, id);
++ ret = jh71x0_reset_assert(rcdev, id);
+ if (ret)
+ return ret;
+
+- return jh7100_reset_deassert(rcdev, id);
++ return jh71x0_reset_deassert(rcdev, id);
+ }
+
+-static int jh7100_reset_status(struct reset_controller_dev *rcdev,
++static int jh71x0_reset_status(struct reset_controller_dev *rcdev,
+ unsigned long id)
+ {
+- struct jh7100_reset *data = jh7100_reset_from(rcdev);
++ struct jh71x0_reset *data = jh71x0_reset_from(rcdev);
+ unsigned long offset = BIT_ULL_WORD(id);
+ u64 mask = BIT_ULL_MASK(id);
+ void __iomem *reg_status = data->status + offset * sizeof(u64);
+@@ -98,25 +98,25 @@ static int jh7100_reset_status(struct reset_controller_dev *rcdev,
+ return !((value ^ data->asserted[offset]) & mask);
+ }
+
+-static const struct reset_control_ops jh7100_reset_ops = {
+- .assert = jh7100_reset_assert,
+- .deassert = jh7100_reset_deassert,
+- .reset = jh7100_reset_reset,
+- .status = jh7100_reset_status,
++static const struct reset_control_ops jh71x0_reset_ops = {
++ .assert = jh71x0_reset_assert,
++ .deassert = jh71x0_reset_deassert,
++ .reset = jh71x0_reset_reset,
++ .status = jh71x0_reset_status,
+ };
+
+-int reset_starfive_jh7100_register(struct device *dev, struct device_node *of_node,
++int reset_starfive_jh71x0_register(struct device *dev, struct device_node *of_node,
+ void __iomem *assert, void __iomem *status,
+ const u64 *asserted, unsigned int nr_resets,
+ struct module *owner)
+ {
+- struct jh7100_reset *data;
++ struct jh71x0_reset *data;
+
+ data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+- data->rcdev.ops = &jh7100_reset_ops;
++ data->rcdev.ops = &jh71x0_reset_ops;
+ data->rcdev.owner = owner;
+ data->rcdev.nr_resets = nr_resets;
+ data->rcdev.dev = dev;
+@@ -129,4 +129,4 @@ int reset_starfive_jh7100_register(struct device *dev, struct device_node *of_no
+
+ return devm_reset_controller_register(dev, &data->rcdev);
+ }
+-EXPORT_SYMBOL_GPL(reset_starfive_jh7100_register);
++EXPORT_SYMBOL_GPL(reset_starfive_jh71x0_register);
+diff --git a/drivers/reset/starfive/reset-starfive-jh71x0.h b/drivers/reset/starfive/reset-starfive-jh71x0.h
+index 1fc5a648c8d8..ac9e80dd3f59 100644
+--- a/drivers/reset/starfive/reset-starfive-jh71x0.h
++++ b/drivers/reset/starfive/reset-starfive-jh71x0.h
+@@ -6,7 +6,7 @@
+ #ifndef __RESET_STARFIVE_JH71X0_H
+ #define __RESET_STARFIVE_JH71X0_H
+
+-int reset_starfive_jh7100_register(struct device *dev, struct device_node *of_node,
++int reset_starfive_jh71x0_register(struct device *dev, struct device_node *of_node,
+ void __iomem *assert, void __iomem *status,
+ const u64 *asserted, unsigned int nr_resets,
+ struct module *owner);
+--
+2.20.1
+
--- /dev/null
+From cdd71a453b4b50a59d9afa159a06850108e060cf Mon Sep 17 00:00:00 2001
+From: Emil Renner Berthing <kernel@esmil.dk>
+Date: Sat, 1 Apr 2023 19:19:24 +0800
+Subject: [PATCH 16/95] reset: starfive: jh71x0: Use 32bit I/O on 32bit
+ registers
+
+We currently use 64bit I/O on the 32bit registers. This works because
+there are an even number of assert and status registers, so they're only
+ever accessed in pairs on 64bit boundaries.
+
+There are however other reset controllers for audio and video on the
+JH7100 SoC with only one status register that isn't 64bit aligned so
+64bit I/O results in an unaligned access exception.
+
+Switch to 32bit I/O in preparation for supporting these resets too.
+
+Tested-by: Tommaso Merciai <tomm.merciai@gmail.com>
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ .../reset/starfive/reset-starfive-jh7100.c | 14 ++++-----
+ .../reset/starfive/reset-starfive-jh71x0.c | 31 +++++++++----------
+ .../reset/starfive/reset-starfive-jh71x0.h | 2 +-
+ 3 files changed, 23 insertions(+), 24 deletions(-)
+
+diff --git a/drivers/reset/starfive/reset-starfive-jh7100.c b/drivers/reset/starfive/reset-starfive-jh7100.c
+index 5f06e5ae3346..2a56f7fd4ba7 100644
+--- a/drivers/reset/starfive/reset-starfive-jh7100.c
++++ b/drivers/reset/starfive/reset-starfive-jh7100.c
+@@ -30,16 +30,16 @@
+ * lines don't though, so store the expected value of the status registers when
+ * all lines are asserted.
+ */
+-static const u64 jh7100_reset_asserted[2] = {
++static const u32 jh7100_reset_asserted[4] = {
+ /* STATUS0 */
+- BIT_ULL_MASK(JH7100_RST_U74) |
+- BIT_ULL_MASK(JH7100_RST_VP6_DRESET) |
+- BIT_ULL_MASK(JH7100_RST_VP6_BRESET) |
++ BIT(JH7100_RST_U74 % 32) |
++ BIT(JH7100_RST_VP6_DRESET % 32) |
++ BIT(JH7100_RST_VP6_BRESET % 32),
+ /* STATUS1 */
+- BIT_ULL_MASK(JH7100_RST_HIFI4_DRESET) |
+- BIT_ULL_MASK(JH7100_RST_HIFI4_BRESET),
++ BIT(JH7100_RST_HIFI4_DRESET % 32) |
++ BIT(JH7100_RST_HIFI4_BRESET % 32),
+ /* STATUS2 */
+- BIT_ULL_MASK(JH7100_RST_E24) |
++ BIT(JH7100_RST_E24 % 32),
+ /* STATUS3 */
+ 0,
+ };
+diff --git a/drivers/reset/starfive/reset-starfive-jh71x0.c b/drivers/reset/starfive/reset-starfive-jh71x0.c
+index a689f4730ed7..55bbbd2de52c 100644
+--- a/drivers/reset/starfive/reset-starfive-jh71x0.c
++++ b/drivers/reset/starfive/reset-starfive-jh71x0.c
+@@ -8,7 +8,6 @@
+ #include <linux/bitmap.h>
+ #include <linux/device.h>
+ #include <linux/io.h>
+-#include <linux/io-64-nonatomic-lo-hi.h>
+ #include <linux/iopoll.h>
+ #include <linux/reset-controller.h>
+ #include <linux/spinlock.h>
+@@ -21,7 +20,7 @@ struct jh71x0_reset {
+ spinlock_t lock;
+ void __iomem *assert;
+ void __iomem *status;
+- const u64 *asserted;
++ const u32 *asserted;
+ };
+
+ static inline struct jh71x0_reset *
+@@ -34,12 +33,12 @@ static int jh71x0_reset_update(struct reset_controller_dev *rcdev,
+ unsigned long id, bool assert)
+ {
+ struct jh71x0_reset *data = jh71x0_reset_from(rcdev);
+- unsigned long offset = BIT_ULL_WORD(id);
+- u64 mask = BIT_ULL_MASK(id);
+- void __iomem *reg_assert = data->assert + offset * sizeof(u64);
+- void __iomem *reg_status = data->status + offset * sizeof(u64);
+- u64 done = data->asserted ? data->asserted[offset] & mask : 0;
+- u64 value;
++ unsigned long offset = id / 32;
++ u32 mask = BIT(id % 32);
++ void __iomem *reg_assert = data->assert + offset * sizeof(u32);
++ void __iomem *reg_status = data->status + offset * sizeof(u32);
++ u32 done = data->asserted ? data->asserted[offset] & mask : 0;
++ u32 value;
+ unsigned long flags;
+ int ret;
+
+@@ -48,15 +47,15 @@ static int jh71x0_reset_update(struct reset_controller_dev *rcdev,
+
+ spin_lock_irqsave(&data->lock, flags);
+
+- value = readq(reg_assert);
++ value = readl(reg_assert);
+ if (assert)
+ value |= mask;
+ else
+ value &= ~mask;
+- writeq(value, reg_assert);
++ writel(value, reg_assert);
+
+ /* if the associated clock is gated, deasserting might otherwise hang forever */
+- ret = readq_poll_timeout_atomic(reg_status, value, (value & mask) == done, 0, 1000);
++ ret = readl_poll_timeout_atomic(reg_status, value, (value & mask) == done, 0, 1000);
+
+ spin_unlock_irqrestore(&data->lock, flags);
+ return ret;
+@@ -90,10 +89,10 @@ static int jh71x0_reset_status(struct reset_controller_dev *rcdev,
+ unsigned long id)
+ {
+ struct jh71x0_reset *data = jh71x0_reset_from(rcdev);
+- unsigned long offset = BIT_ULL_WORD(id);
+- u64 mask = BIT_ULL_MASK(id);
+- void __iomem *reg_status = data->status + offset * sizeof(u64);
+- u64 value = readq(reg_status);
++ unsigned long offset = id / 32;
++ u32 mask = BIT(id % 32);
++ void __iomem *reg_status = data->status + offset * sizeof(u32);
++ u32 value = readl(reg_status);
+
+ return !((value ^ data->asserted[offset]) & mask);
+ }
+@@ -107,7 +106,7 @@ static const struct reset_control_ops jh71x0_reset_ops = {
+
+ int reset_starfive_jh71x0_register(struct device *dev, struct device_node *of_node,
+ void __iomem *assert, void __iomem *status,
+- const u64 *asserted, unsigned int nr_resets,
++ const u32 *asserted, unsigned int nr_resets,
+ struct module *owner)
+ {
+ struct jh71x0_reset *data;
+diff --git a/drivers/reset/starfive/reset-starfive-jh71x0.h b/drivers/reset/starfive/reset-starfive-jh71x0.h
+index ac9e80dd3f59..db7d39a87f87 100644
+--- a/drivers/reset/starfive/reset-starfive-jh71x0.h
++++ b/drivers/reset/starfive/reset-starfive-jh71x0.h
+@@ -8,7 +8,7 @@
+
+ int reset_starfive_jh71x0_register(struct device *dev, struct device_node *of_node,
+ void __iomem *assert, void __iomem *status,
+- const u64 *asserted, unsigned int nr_resets,
++ const u32 *asserted, unsigned int nr_resets,
+ struct module *owner);
+
+ #endif /* __RESET_STARFIVE_JH71X0_H */
+--
+2.20.1
+
--- /dev/null
+From 821664474e5e4b8d89de414f759bbffbb5d4bd9c Mon Sep 17 00:00:00 2001
+From: Emil Renner Berthing <kernel@esmil.dk>
+Date: Sat, 1 Apr 2023 19:19:25 +0800
+Subject: [PATCH 17/95] clk: starfive: Add StarFive JH7110 system clock driver
+
+Add driver for the StarFive JH7110 system clock controller and
+register an auxiliary device for system reset controller which
+is named as "reset-sys".
+
+Tested-by: Tommaso Merciai <tomm.merciai@gmail.com>
+Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
+Co-developed-by: Hal Feng <hal.feng@starfivetech.com>
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ drivers/clk/starfive/Kconfig | 11 +
+ drivers/clk/starfive/Makefile | 2 +
+ .../clk/starfive/clk-starfive-jh7110-sys.c | 490 ++++++++++++++++++
+ drivers/clk/starfive/clk-starfive-jh7110.h | 11 +
+ 4 files changed, 514 insertions(+)
+ create mode 100644 drivers/clk/starfive/clk-starfive-jh7110-sys.c
+ create mode 100644 drivers/clk/starfive/clk-starfive-jh7110.h
+
+diff --git a/drivers/clk/starfive/Kconfig b/drivers/clk/starfive/Kconfig
+index 3ceeb19b5eda..670c5084aeb8 100644
+--- a/drivers/clk/starfive/Kconfig
++++ b/drivers/clk/starfive/Kconfig
+@@ -20,3 +20,14 @@ config CLK_STARFIVE_JH7100_AUDIO
+ help
+ Say Y or M here to support the audio clocks on the StarFive JH7100
+ SoC.
++
++config CLK_STARFIVE_JH7110_SYS
++ bool "StarFive JH7110 system clock support"
++ depends on ARCH_STARFIVE || COMPILE_TEST
++ select AUXILIARY_BUS
++ select CLK_STARFIVE_JH71X0
++ select RESET_STARFIVE_JH7110
++ default ARCH_STARFIVE
++ help
++ Say yes here to support the system clock controller on the
++ StarFive JH7110 SoC.
+diff --git a/drivers/clk/starfive/Makefile b/drivers/clk/starfive/Makefile
+index 82edfa9f9cb8..5ca4e887fb9c 100644
+--- a/drivers/clk/starfive/Makefile
++++ b/drivers/clk/starfive/Makefile
+@@ -3,3 +3,5 @@ obj-$(CONFIG_CLK_STARFIVE_JH71X0) += clk-starfive-jh71x0.o
+
+ obj-$(CONFIG_CLK_STARFIVE_JH7100) += clk-starfive-jh7100.o
+ obj-$(CONFIG_CLK_STARFIVE_JH7100_AUDIO) += clk-starfive-jh7100-audio.o
++
++obj-$(CONFIG_CLK_STARFIVE_JH7110_SYS) += clk-starfive-jh7110-sys.o
+diff --git a/drivers/clk/starfive/clk-starfive-jh7110-sys.c b/drivers/clk/starfive/clk-starfive-jh7110-sys.c
+new file mode 100644
+index 000000000000..5ec210644e1d
+--- /dev/null
++++ b/drivers/clk/starfive/clk-starfive-jh7110-sys.c
+@@ -0,0 +1,490 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * StarFive JH7110 System Clock Driver
++ *
++ * Copyright (C) 2022 Emil Renner Berthing <kernel@esmil.dk>
++ * Copyright (C) 2022 StarFive Technology Co., Ltd.
++ */
++
++#include <linux/auxiliary_bus.h>
++#include <linux/clk-provider.h>
++#include <linux/init.h>
++#include <linux/io.h>
++#include <linux/platform_device.h>
++
++#include <dt-bindings/clock/starfive,jh7110-crg.h>
++
++#include "clk-starfive-jh7110.h"
++
++/* external clocks */
++#define JH7110_SYSCLK_OSC (JH7110_SYSCLK_END + 0)
++#define JH7110_SYSCLK_GMAC1_RMII_REFIN (JH7110_SYSCLK_END + 1)
++#define JH7110_SYSCLK_GMAC1_RGMII_RXIN (JH7110_SYSCLK_END + 2)
++#define JH7110_SYSCLK_I2STX_BCLK_EXT (JH7110_SYSCLK_END + 3)
++#define JH7110_SYSCLK_I2STX_LRCK_EXT (JH7110_SYSCLK_END + 4)
++#define JH7110_SYSCLK_I2SRX_BCLK_EXT (JH7110_SYSCLK_END + 5)
++#define JH7110_SYSCLK_I2SRX_LRCK_EXT (JH7110_SYSCLK_END + 6)
++#define JH7110_SYSCLK_TDM_EXT (JH7110_SYSCLK_END + 7)
++#define JH7110_SYSCLK_MCLK_EXT (JH7110_SYSCLK_END + 8)
++#define JH7110_SYSCLK_PLL0_OUT (JH7110_SYSCLK_END + 9)
++#define JH7110_SYSCLK_PLL1_OUT (JH7110_SYSCLK_END + 10)
++#define JH7110_SYSCLK_PLL2_OUT (JH7110_SYSCLK_END + 11)
++
++static const struct jh71x0_clk_data jh7110_sysclk_data[] __initconst = {
++ /* root */
++ JH71X0__MUX(JH7110_SYSCLK_CPU_ROOT, "cpu_root", 2,
++ JH7110_SYSCLK_OSC,
++ JH7110_SYSCLK_PLL0_OUT),
++ JH71X0__DIV(JH7110_SYSCLK_CPU_CORE, "cpu_core", 7, JH7110_SYSCLK_CPU_ROOT),
++ JH71X0__DIV(JH7110_SYSCLK_CPU_BUS, "cpu_bus", 2, JH7110_SYSCLK_CPU_CORE),
++ JH71X0__MUX(JH7110_SYSCLK_GPU_ROOT, "gpu_root", 2,
++ JH7110_SYSCLK_PLL2_OUT,
++ JH7110_SYSCLK_PLL1_OUT),
++ JH71X0_MDIV(JH7110_SYSCLK_PERH_ROOT, "perh_root", 2, 2,
++ JH7110_SYSCLK_PLL0_OUT,
++ JH7110_SYSCLK_PLL2_OUT),
++ JH71X0__MUX(JH7110_SYSCLK_BUS_ROOT, "bus_root", 2,
++ JH7110_SYSCLK_OSC,
++ JH7110_SYSCLK_PLL2_OUT),
++ JH71X0__DIV(JH7110_SYSCLK_NOCSTG_BUS, "nocstg_bus", 3, JH7110_SYSCLK_BUS_ROOT),
++ JH71X0__DIV(JH7110_SYSCLK_AXI_CFG0, "axi_cfg0", 3, JH7110_SYSCLK_BUS_ROOT),
++ JH71X0__DIV(JH7110_SYSCLK_STG_AXIAHB, "stg_axiahb", 2, JH7110_SYSCLK_AXI_CFG0),
++ JH71X0_GATE(JH7110_SYSCLK_AHB0, "ahb0", CLK_IS_CRITICAL, JH7110_SYSCLK_STG_AXIAHB),
++ JH71X0_GATE(JH7110_SYSCLK_AHB1, "ahb1", CLK_IS_CRITICAL, JH7110_SYSCLK_STG_AXIAHB),
++ JH71X0__DIV(JH7110_SYSCLK_APB_BUS, "apb_bus", 8, JH7110_SYSCLK_STG_AXIAHB),
++ JH71X0_GATE(JH7110_SYSCLK_APB0, "apb0", CLK_IS_CRITICAL, JH7110_SYSCLK_APB_BUS),
++ JH71X0__DIV(JH7110_SYSCLK_PLL0_DIV2, "pll0_div2", 2, JH7110_SYSCLK_PLL0_OUT),
++ JH71X0__DIV(JH7110_SYSCLK_PLL1_DIV2, "pll1_div2", 2, JH7110_SYSCLK_PLL1_OUT),
++ JH71X0__DIV(JH7110_SYSCLK_PLL2_DIV2, "pll2_div2", 2, JH7110_SYSCLK_PLL2_OUT),
++ JH71X0__DIV(JH7110_SYSCLK_AUDIO_ROOT, "audio_root", 8, JH7110_SYSCLK_PLL2_OUT),
++ JH71X0__DIV(JH7110_SYSCLK_MCLK_INNER, "mclk_inner", 64, JH7110_SYSCLK_AUDIO_ROOT),
++ JH71X0__MUX(JH7110_SYSCLK_MCLK, "mclk", 2,
++ JH7110_SYSCLK_MCLK_INNER,
++ JH7110_SYSCLK_MCLK_EXT),
++ JH71X0_GATE(JH7110_SYSCLK_MCLK_OUT, "mclk_out", 0, JH7110_SYSCLK_MCLK_INNER),
++ JH71X0_MDIV(JH7110_SYSCLK_ISP_2X, "isp_2x", 8, 2,
++ JH7110_SYSCLK_PLL2_OUT,
++ JH7110_SYSCLK_PLL1_OUT),
++ JH71X0__DIV(JH7110_SYSCLK_ISP_AXI, "isp_axi", 4, JH7110_SYSCLK_ISP_2X),
++ JH71X0_GDIV(JH7110_SYSCLK_GCLK0, "gclk0", 0, 62, JH7110_SYSCLK_PLL0_DIV2),
++ JH71X0_GDIV(JH7110_SYSCLK_GCLK1, "gclk1", 0, 62, JH7110_SYSCLK_PLL1_DIV2),
++ JH71X0_GDIV(JH7110_SYSCLK_GCLK2, "gclk2", 0, 62, JH7110_SYSCLK_PLL2_DIV2),
++ /* cores */
++ JH71X0_GATE(JH7110_SYSCLK_CORE, "core", CLK_IS_CRITICAL, JH7110_SYSCLK_CPU_CORE),
++ JH71X0_GATE(JH7110_SYSCLK_CORE1, "core1", CLK_IS_CRITICAL, JH7110_SYSCLK_CPU_CORE),
++ JH71X0_GATE(JH7110_SYSCLK_CORE2, "core2", CLK_IS_CRITICAL, JH7110_SYSCLK_CPU_CORE),
++ JH71X0_GATE(JH7110_SYSCLK_CORE3, "core3", CLK_IS_CRITICAL, JH7110_SYSCLK_CPU_CORE),
++ JH71X0_GATE(JH7110_SYSCLK_CORE4, "core4", CLK_IS_CRITICAL, JH7110_SYSCLK_CPU_CORE),
++ JH71X0_GATE(JH7110_SYSCLK_DEBUG, "debug", 0, JH7110_SYSCLK_CPU_BUS),
++ JH71X0__DIV(JH7110_SYSCLK_RTC_TOGGLE, "rtc_toggle", 6, JH7110_SYSCLK_OSC),
++ JH71X0_GATE(JH7110_SYSCLK_TRACE0, "trace0", 0, JH7110_SYSCLK_CPU_CORE),
++ JH71X0_GATE(JH7110_SYSCLK_TRACE1, "trace1", 0, JH7110_SYSCLK_CPU_CORE),
++ JH71X0_GATE(JH7110_SYSCLK_TRACE2, "trace2", 0, JH7110_SYSCLK_CPU_CORE),
++ JH71X0_GATE(JH7110_SYSCLK_TRACE3, "trace3", 0, JH7110_SYSCLK_CPU_CORE),
++ JH71X0_GATE(JH7110_SYSCLK_TRACE4, "trace4", 0, JH7110_SYSCLK_CPU_CORE),
++ JH71X0_GATE(JH7110_SYSCLK_TRACE_COM, "trace_com", 0, JH7110_SYSCLK_CPU_BUS),
++ /* noc */
++ JH71X0_GATE(JH7110_SYSCLK_NOC_BUS_CPU_AXI, "noc_bus_cpu_axi", CLK_IS_CRITICAL,
++ JH7110_SYSCLK_CPU_BUS),
++ JH71X0_GATE(JH7110_SYSCLK_NOC_BUS_AXICFG0_AXI, "noc_bus_axicfg0_axi", CLK_IS_CRITICAL,
++ JH7110_SYSCLK_AXI_CFG0),
++ /* ddr */
++ JH71X0__DIV(JH7110_SYSCLK_OSC_DIV2, "osc_div2", 2, JH7110_SYSCLK_OSC),
++ JH71X0__DIV(JH7110_SYSCLK_PLL1_DIV4, "pll1_div4", 2, JH7110_SYSCLK_PLL1_DIV2),
++ JH71X0__DIV(JH7110_SYSCLK_PLL1_DIV8, "pll1_div8", 2, JH7110_SYSCLK_PLL1_DIV4),
++ JH71X0__MUX(JH7110_SYSCLK_DDR_BUS, "ddr_bus", 4,
++ JH7110_SYSCLK_OSC_DIV2,
++ JH7110_SYSCLK_PLL1_DIV2,
++ JH7110_SYSCLK_PLL1_DIV4,
++ JH7110_SYSCLK_PLL1_DIV8),
++ JH71X0_GATE(JH7110_SYSCLK_DDR_AXI, "ddr_axi", CLK_IS_CRITICAL, JH7110_SYSCLK_DDR_BUS),
++ /* gpu */
++ JH71X0__DIV(JH7110_SYSCLK_GPU_CORE, "gpu_core", 7, JH7110_SYSCLK_GPU_ROOT),
++ JH71X0_GATE(JH7110_SYSCLK_GPU_CORE_CLK, "gpu_core_clk", 0, JH7110_SYSCLK_GPU_CORE),
++ JH71X0_GATE(JH7110_SYSCLK_GPU_SYS_CLK, "gpu_sys_clk", 0, JH7110_SYSCLK_ISP_AXI),
++ JH71X0_GATE(JH7110_SYSCLK_GPU_APB, "gpu_apb", 0, JH7110_SYSCLK_APB_BUS),
++ JH71X0_GDIV(JH7110_SYSCLK_GPU_RTC_TOGGLE, "gpu_rtc_toggle", 0, 12, JH7110_SYSCLK_OSC),
++ JH71X0_GATE(JH7110_SYSCLK_NOC_BUS_GPU_AXI, "noc_bus_gpu_axi", 0, JH7110_SYSCLK_GPU_CORE),
++ /* isp */
++ JH71X0_GATE(JH7110_SYSCLK_ISP_TOP_CORE, "isp_top_core", 0, JH7110_SYSCLK_ISP_2X),
++ JH71X0_GATE(JH7110_SYSCLK_ISP_TOP_AXI, "isp_top_axi", 0, JH7110_SYSCLK_ISP_AXI),
++ JH71X0_GATE(JH7110_SYSCLK_NOC_BUS_ISP_AXI, "noc_bus_isp_axi", CLK_IS_CRITICAL,
++ JH7110_SYSCLK_ISP_AXI),
++ /* hifi4 */
++ JH71X0__DIV(JH7110_SYSCLK_HIFI4_CORE, "hifi4_core", 15, JH7110_SYSCLK_BUS_ROOT),
++ JH71X0__DIV(JH7110_SYSCLK_HIFI4_AXI, "hifi4_axi", 2, JH7110_SYSCLK_HIFI4_CORE),
++ /* axi_cfg1 */
++ JH71X0_GATE(JH7110_SYSCLK_AXI_CFG1_MAIN, "axi_cfg1_main", CLK_IS_CRITICAL,
++ JH7110_SYSCLK_ISP_AXI),
++ JH71X0_GATE(JH7110_SYSCLK_AXI_CFG1_AHB, "axi_cfg1_ahb", CLK_IS_CRITICAL,
++ JH7110_SYSCLK_AHB0),
++ /* vout */
++ JH71X0_GATE(JH7110_SYSCLK_VOUT_SRC, "vout_src", 0, JH7110_SYSCLK_PLL2_OUT),
++ JH71X0__DIV(JH7110_SYSCLK_VOUT_AXI, "vout_axi", 7, JH7110_SYSCLK_PLL2_OUT),
++ JH71X0_GATE(JH7110_SYSCLK_NOC_BUS_DISP_AXI, "noc_bus_disp_axi", 0, JH7110_SYSCLK_VOUT_AXI),
++ JH71X0_GATE(JH7110_SYSCLK_VOUT_TOP_AHB, "vout_top_ahb", 0, JH7110_SYSCLK_AHB1),
++ JH71X0_GATE(JH7110_SYSCLK_VOUT_TOP_AXI, "vout_top_axi", 0, JH7110_SYSCLK_VOUT_AXI),
++ JH71X0_GATE(JH7110_SYSCLK_VOUT_TOP_HDMITX0_MCLK, "vout_top_hdmitx0_mclk", 0,
++ JH7110_SYSCLK_MCLK),
++ JH71X0__DIV(JH7110_SYSCLK_VOUT_TOP_MIPIPHY_REF, "vout_top_mipiphy_ref", 2,
++ JH7110_SYSCLK_OSC),
++ /* jpegc */
++ JH71X0__DIV(JH7110_SYSCLK_JPEGC_AXI, "jpegc_axi", 16, JH7110_SYSCLK_PLL2_OUT),
++ JH71X0_GATE(JH7110_SYSCLK_CODAJ12_AXI, "codaj12_axi", 0, JH7110_SYSCLK_JPEGC_AXI),
++ JH71X0_GDIV(JH7110_SYSCLK_CODAJ12_CORE, "codaj12_core", 0, 16, JH7110_SYSCLK_PLL2_OUT),
++ JH71X0_GATE(JH7110_SYSCLK_CODAJ12_APB, "codaj12_apb", 0, JH7110_SYSCLK_APB_BUS),
++ /* vdec */
++ JH71X0__DIV(JH7110_SYSCLK_VDEC_AXI, "vdec_axi", 7, JH7110_SYSCLK_BUS_ROOT),
++ JH71X0_GATE(JH7110_SYSCLK_WAVE511_AXI, "wave511_axi", 0, JH7110_SYSCLK_VDEC_AXI),
++ JH71X0_GDIV(JH7110_SYSCLK_WAVE511_BPU, "wave511_bpu", 0, 7, JH7110_SYSCLK_BUS_ROOT),
++ JH71X0_GDIV(JH7110_SYSCLK_WAVE511_VCE, "wave511_vce", 0, 7, JH7110_SYSCLK_PLL0_OUT),
++ JH71X0_GATE(JH7110_SYSCLK_WAVE511_APB, "wave511_apb", 0, JH7110_SYSCLK_APB_BUS),
++ JH71X0_GATE(JH7110_SYSCLK_VDEC_JPG, "vdec_jpg", 0, JH7110_SYSCLK_JPEGC_AXI),
++ JH71X0_GATE(JH7110_SYSCLK_VDEC_MAIN, "vdec_main", 0, JH7110_SYSCLK_VDEC_AXI),
++ JH71X0_GATE(JH7110_SYSCLK_NOC_BUS_VDEC_AXI, "noc_bus_vdec_axi", 0, JH7110_SYSCLK_VDEC_AXI),
++ /* venc */
++ JH71X0__DIV(JH7110_SYSCLK_VENC_AXI, "venc_axi", 15, JH7110_SYSCLK_PLL2_OUT),
++ JH71X0_GATE(JH7110_SYSCLK_WAVE420L_AXI, "wave420l_axi", 0, JH7110_SYSCLK_VENC_AXI),
++ JH71X0_GDIV(JH7110_SYSCLK_WAVE420L_BPU, "wave420l_bpu", 0, 15, JH7110_SYSCLK_PLL2_OUT),
++ JH71X0_GDIV(JH7110_SYSCLK_WAVE420L_VCE, "wave420l_vce", 0, 15, JH7110_SYSCLK_PLL2_OUT),
++ JH71X0_GATE(JH7110_SYSCLK_WAVE420L_APB, "wave420l_apb", 0, JH7110_SYSCLK_APB_BUS),
++ JH71X0_GATE(JH7110_SYSCLK_NOC_BUS_VENC_AXI, "noc_bus_venc_axi", 0, JH7110_SYSCLK_VENC_AXI),
++ /* axi_cfg0 */
++ JH71X0_GATE(JH7110_SYSCLK_AXI_CFG0_MAIN_DIV, "axi_cfg0_main_div", CLK_IS_CRITICAL,
++ JH7110_SYSCLK_AHB1),
++ JH71X0_GATE(JH7110_SYSCLK_AXI_CFG0_MAIN, "axi_cfg0_main", CLK_IS_CRITICAL,
++ JH7110_SYSCLK_AXI_CFG0),
++ JH71X0_GATE(JH7110_SYSCLK_AXI_CFG0_HIFI4, "axi_cfg0_hifi4", CLK_IS_CRITICAL,
++ JH7110_SYSCLK_HIFI4_AXI),
++ /* intmem */
++ JH71X0_GATE(JH7110_SYSCLK_AXIMEM2_AXI, "aximem2_axi", 0, JH7110_SYSCLK_AXI_CFG0),
++ /* qspi */
++ JH71X0_GATE(JH7110_SYSCLK_QSPI_AHB, "qspi_ahb", 0, JH7110_SYSCLK_AHB1),
++ JH71X0_GATE(JH7110_SYSCLK_QSPI_APB, "qspi_apb", 0, JH7110_SYSCLK_APB_BUS),
++ JH71X0__DIV(JH7110_SYSCLK_QSPI_REF_SRC, "qspi_ref_src", 16, JH7110_SYSCLK_PLL0_OUT),
++ JH71X0_GMUX(JH7110_SYSCLK_QSPI_REF, "qspi_ref", 0, 2,
++ JH7110_SYSCLK_OSC,
++ JH7110_SYSCLK_QSPI_REF_SRC),
++ /* sdio */
++ JH71X0_GATE(JH7110_SYSCLK_SDIO0_AHB, "sdio0_ahb", 0, JH7110_SYSCLK_AHB0),
++ JH71X0_GATE(JH7110_SYSCLK_SDIO1_AHB, "sdio1_ahb", 0, JH7110_SYSCLK_AHB0),
++ JH71X0_GDIV(JH7110_SYSCLK_SDIO0_SDCARD, "sdio0_sdcard", 0, 15, JH7110_SYSCLK_AXI_CFG0),
++ JH71X0_GDIV(JH7110_SYSCLK_SDIO1_SDCARD, "sdio1_sdcard", 0, 15, JH7110_SYSCLK_AXI_CFG0),
++ /* stg */
++ JH71X0__DIV(JH7110_SYSCLK_USB_125M, "usb_125m", 15, JH7110_SYSCLK_PLL0_OUT),
++ JH71X0_GATE(JH7110_SYSCLK_NOC_BUS_STG_AXI, "noc_bus_stg_axi", CLK_IS_CRITICAL,
++ JH7110_SYSCLK_NOCSTG_BUS),
++ /* gmac1 */
++ JH71X0_GATE(JH7110_SYSCLK_GMAC1_AHB, "gmac1_ahb", 0, JH7110_SYSCLK_AHB0),
++ JH71X0_GATE(JH7110_SYSCLK_GMAC1_AXI, "gmac1_axi", 0, JH7110_SYSCLK_STG_AXIAHB),
++ JH71X0__DIV(JH7110_SYSCLK_GMAC_SRC, "gmac_src", 7, JH7110_SYSCLK_PLL0_OUT),
++ JH71X0__DIV(JH7110_SYSCLK_GMAC1_GTXCLK, "gmac1_gtxclk", 15, JH7110_SYSCLK_PLL0_OUT),
++ JH71X0__DIV(JH7110_SYSCLK_GMAC1_RMII_RTX, "gmac1_rmii_rtx", 30,
++ JH7110_SYSCLK_GMAC1_RMII_REFIN),
++ JH71X0_GDIV(JH7110_SYSCLK_GMAC1_PTP, "gmac1_ptp", 0, 31, JH7110_SYSCLK_GMAC_SRC),
++ JH71X0__MUX(JH7110_SYSCLK_GMAC1_RX, "gmac1_rx", 2,
++ JH7110_SYSCLK_GMAC1_RGMII_RXIN,
++ JH7110_SYSCLK_GMAC1_RMII_RTX),
++ JH71X0__INV(JH7110_SYSCLK_GMAC1_RX_INV, "gmac1_rx_inv", JH7110_SYSCLK_GMAC1_RX),
++ JH71X0_GMUX(JH7110_SYSCLK_GMAC1_TX, "gmac1_tx",
++ CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT, 2,
++ JH7110_SYSCLK_GMAC1_GTXCLK,
++ JH7110_SYSCLK_GMAC1_RMII_RTX),
++ JH71X0__INV(JH7110_SYSCLK_GMAC1_TX_INV, "gmac1_tx_inv", JH7110_SYSCLK_GMAC1_TX),
++ JH71X0_GATE(JH7110_SYSCLK_GMAC1_GTXC, "gmac1_gtxc", 0, JH7110_SYSCLK_GMAC1_GTXCLK),
++ /* gmac0 */
++ JH71X0_GDIV(JH7110_SYSCLK_GMAC0_GTXCLK, "gmac0_gtxclk", 0, 15, JH7110_SYSCLK_PLL0_OUT),
++ JH71X0_GDIV(JH7110_SYSCLK_GMAC0_PTP, "gmac0_ptp", 0, 31, JH7110_SYSCLK_GMAC_SRC),
++ JH71X0_GDIV(JH7110_SYSCLK_GMAC_PHY, "gmac_phy", 0, 31, JH7110_SYSCLK_GMAC_SRC),
++ JH71X0_GATE(JH7110_SYSCLK_GMAC0_GTXC, "gmac0_gtxc", 0, JH7110_SYSCLK_GMAC0_GTXCLK),
++ /* apb misc */
++ JH71X0_GATE(JH7110_SYSCLK_IOMUX_APB, "iomux_apb", 0, JH7110_SYSCLK_APB_BUS),
++ JH71X0_GATE(JH7110_SYSCLK_MAILBOX_APB, "mailbox_apb", 0, JH7110_SYSCLK_APB_BUS),
++ JH71X0_GATE(JH7110_SYSCLK_INT_CTRL_APB, "int_ctrl_apb", 0, JH7110_SYSCLK_APB_BUS),
++ /* can0 */
++ JH71X0_GATE(JH7110_SYSCLK_CAN0_APB, "can0_apb", 0, JH7110_SYSCLK_APB_BUS),
++ JH71X0_GDIV(JH7110_SYSCLK_CAN0_TIMER, "can0_timer", 0, 24, JH7110_SYSCLK_OSC),
++ JH71X0_GDIV(JH7110_SYSCLK_CAN0_CAN, "can0_can", 0, 63, JH7110_SYSCLK_PERH_ROOT),
++ /* can1 */
++ JH71X0_GATE(JH7110_SYSCLK_CAN1_APB, "can1_apb", 0, JH7110_SYSCLK_APB_BUS),
++ JH71X0_GDIV(JH7110_SYSCLK_CAN1_TIMER, "can1_timer", 0, 24, JH7110_SYSCLK_OSC),
++ JH71X0_GDIV(JH7110_SYSCLK_CAN1_CAN, "can1_can", 0, 63, JH7110_SYSCLK_PERH_ROOT),
++ /* pwm */
++ JH71X0_GATE(JH7110_SYSCLK_PWM_APB, "pwm_apb", 0, JH7110_SYSCLK_APB_BUS),
++ /* wdt */
++ JH71X0_GATE(JH7110_SYSCLK_WDT_APB, "wdt_apb", 0, JH7110_SYSCLK_APB_BUS),
++ JH71X0_GATE(JH7110_SYSCLK_WDT_CORE, "wdt_core", 0, JH7110_SYSCLK_OSC),
++ /* timer */
++ JH71X0_GATE(JH7110_SYSCLK_TIMER_APB, "timer_apb", 0, JH7110_SYSCLK_APB_BUS),
++ JH71X0_GATE(JH7110_SYSCLK_TIMER0, "timer0", 0, JH7110_SYSCLK_OSC),
++ JH71X0_GATE(JH7110_SYSCLK_TIMER1, "timer1", 0, JH7110_SYSCLK_OSC),
++ JH71X0_GATE(JH7110_SYSCLK_TIMER2, "timer2", 0, JH7110_SYSCLK_OSC),
++ JH71X0_GATE(JH7110_SYSCLK_TIMER3, "timer3", 0, JH7110_SYSCLK_OSC),
++ /* temp sensor */
++ JH71X0_GATE(JH7110_SYSCLK_TEMP_APB, "temp_apb", 0, JH7110_SYSCLK_APB_BUS),
++ JH71X0_GDIV(JH7110_SYSCLK_TEMP_CORE, "temp_core", 0, 24, JH7110_SYSCLK_OSC),
++ /* spi */
++ JH71X0_GATE(JH7110_SYSCLK_SPI0_APB, "spi0_apb", 0, JH7110_SYSCLK_APB0),
++ JH71X0_GATE(JH7110_SYSCLK_SPI1_APB, "spi1_apb", 0, JH7110_SYSCLK_APB0),
++ JH71X0_GATE(JH7110_SYSCLK_SPI2_APB, "spi2_apb", 0, JH7110_SYSCLK_APB0),
++ JH71X0_GATE(JH7110_SYSCLK_SPI3_APB, "spi3_apb", 0, JH7110_SYSCLK_APB_BUS),
++ JH71X0_GATE(JH7110_SYSCLK_SPI4_APB, "spi4_apb", 0, JH7110_SYSCLK_APB_BUS),
++ JH71X0_GATE(JH7110_SYSCLK_SPI5_APB, "spi5_apb", 0, JH7110_SYSCLK_APB_BUS),
++ JH71X0_GATE(JH7110_SYSCLK_SPI6_APB, "spi6_apb", 0, JH7110_SYSCLK_APB_BUS),
++ /* i2c */
++ JH71X0_GATE(JH7110_SYSCLK_I2C0_APB, "i2c0_apb", 0, JH7110_SYSCLK_APB0),
++ JH71X0_GATE(JH7110_SYSCLK_I2C1_APB, "i2c1_apb", 0, JH7110_SYSCLK_APB0),
++ JH71X0_GATE(JH7110_SYSCLK_I2C2_APB, "i2c2_apb", 0, JH7110_SYSCLK_APB0),
++ JH71X0_GATE(JH7110_SYSCLK_I2C3_APB, "i2c3_apb", 0, JH7110_SYSCLK_APB_BUS),
++ JH71X0_GATE(JH7110_SYSCLK_I2C4_APB, "i2c4_apb", 0, JH7110_SYSCLK_APB_BUS),
++ JH71X0_GATE(JH7110_SYSCLK_I2C5_APB, "i2c5_apb", 0, JH7110_SYSCLK_APB_BUS),
++ JH71X0_GATE(JH7110_SYSCLK_I2C6_APB, "i2c6_apb", 0, JH7110_SYSCLK_APB_BUS),
++ /* uart */
++ JH71X0_GATE(JH7110_SYSCLK_UART0_APB, "uart0_apb", 0, JH7110_SYSCLK_APB0),
++ JH71X0_GATE(JH7110_SYSCLK_UART0_CORE, "uart0_core", 0, JH7110_SYSCLK_OSC),
++ JH71X0_GATE(JH7110_SYSCLK_UART1_APB, "uart1_apb", 0, JH7110_SYSCLK_APB0),
++ JH71X0_GATE(JH7110_SYSCLK_UART1_CORE, "uart1_core", 0, JH7110_SYSCLK_OSC),
++ JH71X0_GATE(JH7110_SYSCLK_UART2_APB, "uart2_apb", 0, JH7110_SYSCLK_APB0),
++ JH71X0_GATE(JH7110_SYSCLK_UART2_CORE, "uart2_core", 0, JH7110_SYSCLK_OSC),
++ JH71X0_GATE(JH7110_SYSCLK_UART3_APB, "uart3_apb", 0, JH7110_SYSCLK_APB0),
++ JH71X0_GDIV(JH7110_SYSCLK_UART3_CORE, "uart3_core", 0, 10, JH7110_SYSCLK_PERH_ROOT),
++ JH71X0_GATE(JH7110_SYSCLK_UART4_APB, "uart4_apb", 0, JH7110_SYSCLK_APB0),
++ JH71X0_GDIV(JH7110_SYSCLK_UART4_CORE, "uart4_core", 0, 10, JH7110_SYSCLK_PERH_ROOT),
++ JH71X0_GATE(JH7110_SYSCLK_UART5_APB, "uart5_apb", 0, JH7110_SYSCLK_APB0),
++ JH71X0_GDIV(JH7110_SYSCLK_UART5_CORE, "uart5_core", 0, 10, JH7110_SYSCLK_PERH_ROOT),
++ /* pwmdac */
++ JH71X0_GATE(JH7110_SYSCLK_PWMDAC_APB, "pwmdac_apb", 0, JH7110_SYSCLK_APB0),
++ JH71X0_GDIV(JH7110_SYSCLK_PWMDAC_CORE, "pwmdac_core", 0, 256, JH7110_SYSCLK_AUDIO_ROOT),
++ /* spdif */
++ JH71X0_GATE(JH7110_SYSCLK_SPDIF_APB, "spdif_apb", 0, JH7110_SYSCLK_APB0),
++ JH71X0_GATE(JH7110_SYSCLK_SPDIF_CORE, "spdif_core", 0, JH7110_SYSCLK_MCLK),
++ /* i2stx0 */
++ JH71X0_GATE(JH7110_SYSCLK_I2STX0_APB, "i2stx0_apb", 0, JH7110_SYSCLK_APB0),
++ JH71X0_GDIV(JH7110_SYSCLK_I2STX0_BCLK_MST, "i2stx0_bclk_mst", 0, 32, JH7110_SYSCLK_MCLK),
++ JH71X0__INV(JH7110_SYSCLK_I2STX0_BCLK_MST_INV, "i2stx0_bclk_mst_inv",
++ JH7110_SYSCLK_I2STX0_BCLK_MST),
++ JH71X0_MDIV(JH7110_SYSCLK_I2STX0_LRCK_MST, "i2stx0_lrck_mst", 64, 2,
++ JH7110_SYSCLK_I2STX0_BCLK_MST_INV,
++ JH7110_SYSCLK_I2STX0_BCLK_MST),
++ JH71X0__MUX(JH7110_SYSCLK_I2STX0_BCLK, "i2stx0_bclk", 2,
++ JH7110_SYSCLK_I2STX0_BCLK_MST,
++ JH7110_SYSCLK_I2STX_BCLK_EXT),
++ JH71X0__INV(JH7110_SYSCLK_I2STX0_BCLK_INV, "i2stx0_bclk_inv", JH7110_SYSCLK_I2STX0_BCLK),
++ JH71X0__MUX(JH7110_SYSCLK_I2STX0_LRCK, "i2stx0_lrck", 2,
++ JH7110_SYSCLK_I2STX0_LRCK_MST,
++ JH7110_SYSCLK_I2STX_LRCK_EXT),
++ /* i2stx1 */
++ JH71X0_GATE(JH7110_SYSCLK_I2STX1_APB, "i2stx1_apb", 0, JH7110_SYSCLK_APB0),
++ JH71X0_GDIV(JH7110_SYSCLK_I2STX1_BCLK_MST, "i2stx1_bclk_mst", 0, 32, JH7110_SYSCLK_MCLK),
++ JH71X0__INV(JH7110_SYSCLK_I2STX1_BCLK_MST_INV, "i2stx1_bclk_mst_inv",
++ JH7110_SYSCLK_I2STX1_BCLK_MST),
++ JH71X0_MDIV(JH7110_SYSCLK_I2STX1_LRCK_MST, "i2stx1_lrck_mst", 64, 2,
++ JH7110_SYSCLK_I2STX1_BCLK_MST_INV,
++ JH7110_SYSCLK_I2STX1_BCLK_MST),
++ JH71X0__MUX(JH7110_SYSCLK_I2STX1_BCLK, "i2stx1_bclk", 2,
++ JH7110_SYSCLK_I2STX1_BCLK_MST,
++ JH7110_SYSCLK_I2STX_BCLK_EXT),
++ JH71X0__INV(JH7110_SYSCLK_I2STX1_BCLK_INV, "i2stx1_bclk_inv", JH7110_SYSCLK_I2STX1_BCLK),
++ JH71X0__MUX(JH7110_SYSCLK_I2STX1_LRCK, "i2stx1_lrck", 2,
++ JH7110_SYSCLK_I2STX1_LRCK_MST,
++ JH7110_SYSCLK_I2STX_LRCK_EXT),
++ /* i2srx */
++ JH71X0_GATE(JH7110_SYSCLK_I2SRX_APB, "i2srx_apb", 0, JH7110_SYSCLK_APB0),
++ JH71X0_GDIV(JH7110_SYSCLK_I2SRX_BCLK_MST, "i2srx_bclk_mst", 0, 32, JH7110_SYSCLK_MCLK),
++ JH71X0__INV(JH7110_SYSCLK_I2SRX_BCLK_MST_INV, "i2srx_bclk_mst_inv",
++ JH7110_SYSCLK_I2SRX_BCLK_MST),
++ JH71X0_MDIV(JH7110_SYSCLK_I2SRX_LRCK_MST, "i2srx_lrck_mst", 64, 2,
++ JH7110_SYSCLK_I2SRX_BCLK_MST_INV,
++ JH7110_SYSCLK_I2SRX_BCLK_MST),
++ JH71X0__MUX(JH7110_SYSCLK_I2SRX_BCLK, "i2srx_bclk", 2,
++ JH7110_SYSCLK_I2SRX_BCLK_MST,
++ JH7110_SYSCLK_I2SRX_BCLK_EXT),
++ JH71X0__INV(JH7110_SYSCLK_I2SRX_BCLK_INV, "i2srx_bclk_inv", JH7110_SYSCLK_I2SRX_BCLK),
++ JH71X0__MUX(JH7110_SYSCLK_I2SRX_LRCK, "i2srx_lrck", 2,
++ JH7110_SYSCLK_I2SRX_LRCK_MST,
++ JH7110_SYSCLK_I2SRX_LRCK_EXT),
++ /* pdm */
++ JH71X0_GDIV(JH7110_SYSCLK_PDM_DMIC, "pdm_dmic", 0, 64, JH7110_SYSCLK_MCLK),
++ JH71X0_GATE(JH7110_SYSCLK_PDM_APB, "pdm_apb", 0, JH7110_SYSCLK_APB0),
++ /* tdm */
++ JH71X0_GATE(JH7110_SYSCLK_TDM_AHB, "tdm_ahb", 0, JH7110_SYSCLK_AHB0),
++ JH71X0_GATE(JH7110_SYSCLK_TDM_APB, "tdm_apb", 0, JH7110_SYSCLK_APB0),
++ JH71X0_GDIV(JH7110_SYSCLK_TDM_INTERNAL, "tdm_internal", 0, 64, JH7110_SYSCLK_MCLK),
++ JH71X0__MUX(JH7110_SYSCLK_TDM_TDM, "tdm_tdm", 2,
++ JH7110_SYSCLK_TDM_INTERNAL,
++ JH7110_SYSCLK_TDM_EXT),
++ JH71X0__INV(JH7110_SYSCLK_TDM_TDM_INV, "tdm_tdm_inv", JH7110_SYSCLK_TDM_TDM),
++ /* jtag */
++ JH71X0__DIV(JH7110_SYSCLK_JTAG_CERTIFICATION_TRNG, "jtag_certification_trng", 4,
++ JH7110_SYSCLK_OSC),
++};
++
++static struct clk_hw *jh7110_sysclk_get(struct of_phandle_args *clkspec, void *data)
++{
++ struct jh71x0_clk_priv *priv = data;
++ unsigned int idx = clkspec->args[0];
++
++ if (idx < JH7110_SYSCLK_END)
++ return &priv->reg[idx].hw;
++
++ return ERR_PTR(-EINVAL);
++}
++
++static void jh7110_reset_unregister_adev(void *_adev)
++{
++ struct auxiliary_device *adev = _adev;
++
++ auxiliary_device_delete(adev);
++}
++
++static void jh7110_reset_adev_release(struct device *dev)
++{
++ struct auxiliary_device *adev = to_auxiliary_dev(dev);
++
++ auxiliary_device_uninit(adev);
++}
++
++int jh7110_reset_controller_register(struct jh71x0_clk_priv *priv,
++ const char *adev_name,
++ u32 adev_id)
++{
++ struct auxiliary_device *adev;
++ int ret;
++
++ adev = devm_kzalloc(priv->dev, sizeof(*adev), GFP_KERNEL);
++ if (!adev)
++ return -ENOMEM;
++
++ adev->name = adev_name;
++ adev->dev.parent = priv->dev;
++ adev->dev.release = jh7110_reset_adev_release;
++ adev->id = adev_id;
++
++ ret = auxiliary_device_init(adev);
++ if (ret)
++ return ret;
++
++ ret = auxiliary_device_add(adev);
++ if (ret) {
++ auxiliary_device_uninit(adev);
++ return ret;
++ }
++
++ return devm_add_action_or_reset(priv->dev,
++ jh7110_reset_unregister_adev, adev);
++}
++EXPORT_SYMBOL_GPL(jh7110_reset_controller_register);
++
++static int __init jh7110_syscrg_probe(struct platform_device *pdev)
++{
++ struct jh71x0_clk_priv *priv;
++ unsigned int idx;
++ int ret;
++
++ priv = devm_kzalloc(&pdev->dev,
++ struct_size(priv, reg, JH7110_SYSCLK_END),
++ GFP_KERNEL);
++ if (!priv)
++ return -ENOMEM;
++
++ spin_lock_init(&priv->rmw_lock);
++ priv->dev = &pdev->dev;
++ priv->base = devm_platform_ioremap_resource(pdev, 0);
++ if (IS_ERR(priv->base))
++ return PTR_ERR(priv->base);
++
++ dev_set_drvdata(priv->dev, (void *)(&priv->base));
++
++ /*
++ * These PLL clocks are not actually fixed factor clocks and can be
++ * controlled by the syscon registers of JH7110. They will be dropped
++ * and registered in the PLL clock driver instead.
++ */
++ /* 24MHz -> 1000.0MHz */
++ priv->pll[0] = devm_clk_hw_register_fixed_factor(priv->dev, "pll0_out",
++ "osc", 0, 125, 3);
++ if (IS_ERR(priv->pll[0]))
++ return PTR_ERR(priv->pll[0]);
++
++ /* 24MHz -> 1066.0MHz */
++ priv->pll[1] = devm_clk_hw_register_fixed_factor(priv->dev, "pll1_out",
++ "osc", 0, 533, 12);
++ if (IS_ERR(priv->pll[1]))
++ return PTR_ERR(priv->pll[1]);
++
++ /* 24MHz -> 1188.0MHz */
++ priv->pll[2] = devm_clk_hw_register_fixed_factor(priv->dev, "pll2_out",
++ "osc", 0, 99, 2);
++ if (IS_ERR(priv->pll[2]))
++ return PTR_ERR(priv->pll[2]);
++
++ for (idx = 0; idx < JH7110_SYSCLK_END; idx++) {
++ u32 max = jh7110_sysclk_data[idx].max;
++ struct clk_parent_data parents[4] = {};
++ struct clk_init_data init = {
++ .name = jh7110_sysclk_data[idx].name,
++ .ops = starfive_jh71x0_clk_ops(max),
++ .parent_data = parents,
++ .num_parents =
++ ((max & JH71X0_CLK_MUX_MASK) >> JH71X0_CLK_MUX_SHIFT) + 1,
++ .flags = jh7110_sysclk_data[idx].flags,
++ };
++ struct jh71x0_clk *clk = &priv->reg[idx];
++ unsigned int i;
++
++ for (i = 0; i < init.num_parents; i++) {
++ unsigned int pidx = jh7110_sysclk_data[idx].parents[i];
++
++ if (pidx < JH7110_SYSCLK_END)
++ parents[i].hw = &priv->reg[pidx].hw;
++ else if (pidx == JH7110_SYSCLK_OSC)
++ parents[i].fw_name = "osc";
++ else if (pidx == JH7110_SYSCLK_GMAC1_RMII_REFIN)
++ parents[i].fw_name = "gmac1_rmii_refin";
++ else if (pidx == JH7110_SYSCLK_GMAC1_RGMII_RXIN)
++ parents[i].fw_name = "gmac1_rgmii_rxin";
++ else if (pidx == JH7110_SYSCLK_I2STX_BCLK_EXT)
++ parents[i].fw_name = "i2stx_bclk_ext";
++ else if (pidx == JH7110_SYSCLK_I2STX_LRCK_EXT)
++ parents[i].fw_name = "i2stx_lrck_ext";
++ else if (pidx == JH7110_SYSCLK_I2SRX_BCLK_EXT)
++ parents[i].fw_name = "i2srx_bclk_ext";
++ else if (pidx == JH7110_SYSCLK_I2SRX_LRCK_EXT)
++ parents[i].fw_name = "i2srx_lrck_ext";
++ else if (pidx == JH7110_SYSCLK_TDM_EXT)
++ parents[i].fw_name = "tdm_ext";
++ else if (pidx == JH7110_SYSCLK_MCLK_EXT)
++ parents[i].fw_name = "mclk_ext";
++ else
++ parents[i].hw = priv->pll[pidx - JH7110_SYSCLK_PLL0_OUT];
++ }
++
++ clk->hw.init = &init;
++ clk->idx = idx;
++ clk->max_div = max & JH71X0_CLK_DIV_MASK;
++
++ ret = devm_clk_hw_register(&pdev->dev, &clk->hw);
++ if (ret)
++ return ret;
++ }
++
++ ret = devm_of_clk_add_hw_provider(&pdev->dev, jh7110_sysclk_get, priv);
++ if (ret)
++ return ret;
++
++ return jh7110_reset_controller_register(priv, "rst-sys", 0);
++}
++
++static const struct of_device_id jh7110_syscrg_match[] = {
++ { .compatible = "starfive,jh7110-syscrg" },
++ { /* sentinel */ }
++};
++
++static struct platform_driver jh7110_syscrg_driver = {
++ .driver = {
++ .name = "clk-starfive-jh7110-sys",
++ .of_match_table = jh7110_syscrg_match,
++ .suppress_bind_attrs = true,
++ },
++};
++builtin_platform_driver_probe(jh7110_syscrg_driver, jh7110_syscrg_probe);
+diff --git a/drivers/clk/starfive/clk-starfive-jh7110.h b/drivers/clk/starfive/clk-starfive-jh7110.h
+new file mode 100644
+index 000000000000..f29682b8d400
+--- /dev/null
++++ b/drivers/clk/starfive/clk-starfive-jh7110.h
+@@ -0,0 +1,11 @@
++/* SPDX-License-Identifier: GPL-2.0 */
++#ifndef __CLK_STARFIVE_JH7110_H
++#define __CLK_STARFIVE_JH7110_H
++
++#include "clk-starfive-jh71x0.h"
++
++int jh7110_reset_controller_register(struct jh71x0_clk_priv *priv,
++ const char *adev_name,
++ u32 adev_id);
++
++#endif
+--
+2.20.1
+
--- /dev/null
+From 7d7cd88aae7a25ee9b57402edc936555bcc11d3d Mon Sep 17 00:00:00 2001
+From: Emil Renner Berthing <kernel@esmil.dk>
+Date: Sat, 1 Apr 2023 19:19:26 +0800
+Subject: [PATCH 18/95] clk: starfive: Add StarFive JH7110 always-on clock
+ driver
+
+Add driver for the StarFive JH7110 always-on clock controller
+and register an auxiliary device for always-on reset controller
+which is named as "reset-aon".
+
+Tested-by: Tommaso Merciai <tomm.merciai@gmail.com>
+Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
+Co-developed-by: Hal Feng <hal.feng@starfivetech.com>
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ drivers/clk/starfive/Kconfig | 11 ++
+ drivers/clk/starfive/Makefile | 1 +
+ .../clk/starfive/clk-starfive-jh7110-aon.c | 156 ++++++++++++++++++
+ 3 files changed, 168 insertions(+)
+ create mode 100644 drivers/clk/starfive/clk-starfive-jh7110-aon.c
+
+diff --git a/drivers/clk/starfive/Kconfig b/drivers/clk/starfive/Kconfig
+index 670c5084aeb8..71c1148ee5f6 100644
+--- a/drivers/clk/starfive/Kconfig
++++ b/drivers/clk/starfive/Kconfig
+@@ -31,3 +31,14 @@ config CLK_STARFIVE_JH7110_SYS
+ help
+ Say yes here to support the system clock controller on the
+ StarFive JH7110 SoC.
++
++config CLK_STARFIVE_JH7110_AON
++ tristate "StarFive JH7110 always-on clock support"
++ depends on CLK_STARFIVE_JH7110_SYS
++ select AUXILIARY_BUS
++ select CLK_STARFIVE_JH71X0
++ select RESET_STARFIVE_JH7110
++ default m if ARCH_STARFIVE
++ help
++ Say yes here to support the always-on clock controller on the
++ StarFive JH7110 SoC.
+diff --git a/drivers/clk/starfive/Makefile b/drivers/clk/starfive/Makefile
+index 5ca4e887fb9c..f3df7d957b1e 100644
+--- a/drivers/clk/starfive/Makefile
++++ b/drivers/clk/starfive/Makefile
+@@ -5,3 +5,4 @@ obj-$(CONFIG_CLK_STARFIVE_JH7100) += clk-starfive-jh7100.o
+ obj-$(CONFIG_CLK_STARFIVE_JH7100_AUDIO) += clk-starfive-jh7100-audio.o
+
+ obj-$(CONFIG_CLK_STARFIVE_JH7110_SYS) += clk-starfive-jh7110-sys.o
++obj-$(CONFIG_CLK_STARFIVE_JH7110_AON) += clk-starfive-jh7110-aon.o
+diff --git a/drivers/clk/starfive/clk-starfive-jh7110-aon.c b/drivers/clk/starfive/clk-starfive-jh7110-aon.c
+new file mode 100644
+index 000000000000..a2799fe8a234
+--- /dev/null
++++ b/drivers/clk/starfive/clk-starfive-jh7110-aon.c
+@@ -0,0 +1,156 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * StarFive JH7110 Always-On Clock Driver
++ *
++ * Copyright (C) 2022 Emil Renner Berthing <kernel@esmil.dk>
++ * Copyright (C) 2022 StarFive Technology Co., Ltd.
++ */
++
++#include <linux/clk-provider.h>
++#include <linux/io.h>
++#include <linux/platform_device.h>
++
++#include <dt-bindings/clock/starfive,jh7110-crg.h>
++
++#include "clk-starfive-jh7110.h"
++
++/* external clocks */
++#define JH7110_AONCLK_OSC (JH7110_AONCLK_END + 0)
++#define JH7110_AONCLK_GMAC0_RMII_REFIN (JH7110_AONCLK_END + 1)
++#define JH7110_AONCLK_GMAC0_RGMII_RXIN (JH7110_AONCLK_END + 2)
++#define JH7110_AONCLK_STG_AXIAHB (JH7110_AONCLK_END + 3)
++#define JH7110_AONCLK_APB_BUS (JH7110_AONCLK_END + 4)
++#define JH7110_AONCLK_GMAC0_GTXCLK (JH7110_AONCLK_END + 5)
++#define JH7110_AONCLK_RTC_OSC (JH7110_AONCLK_END + 6)
++
++static const struct jh71x0_clk_data jh7110_aonclk_data[] = {
++ /* source */
++ JH71X0__DIV(JH7110_AONCLK_OSC_DIV4, "osc_div4", 4, JH7110_AONCLK_OSC),
++ JH71X0__MUX(JH7110_AONCLK_APB_FUNC, "apb_func", 2,
++ JH7110_AONCLK_OSC_DIV4,
++ JH7110_AONCLK_OSC),
++ /* gmac0 */
++ JH71X0_GATE(JH7110_AONCLK_GMAC0_AHB, "gmac0_ahb", 0, JH7110_AONCLK_STG_AXIAHB),
++ JH71X0_GATE(JH7110_AONCLK_GMAC0_AXI, "gmac0_axi", 0, JH7110_AONCLK_STG_AXIAHB),
++ JH71X0__DIV(JH7110_AONCLK_GMAC0_RMII_RTX, "gmac0_rmii_rtx", 30,
++ JH7110_AONCLK_GMAC0_RMII_REFIN),
++ JH71X0_GMUX(JH7110_AONCLK_GMAC0_TX, "gmac0_tx",
++ CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT, 2,
++ JH7110_AONCLK_GMAC0_GTXCLK,
++ JH7110_AONCLK_GMAC0_RMII_RTX),
++ JH71X0__INV(JH7110_AONCLK_GMAC0_TX_INV, "gmac0_tx_inv", JH7110_AONCLK_GMAC0_TX),
++ JH71X0__MUX(JH7110_AONCLK_GMAC0_RX, "gmac0_rx", 2,
++ JH7110_AONCLK_GMAC0_RGMII_RXIN,
++ JH7110_AONCLK_GMAC0_RMII_RTX),
++ JH71X0__INV(JH7110_AONCLK_GMAC0_RX_INV, "gmac0_rx_inv", JH7110_AONCLK_GMAC0_RX),
++ /* otpc */
++ JH71X0_GATE(JH7110_AONCLK_OTPC_APB, "otpc_apb", 0, JH7110_AONCLK_APB_BUS),
++ /* rtc */
++ JH71X0_GATE(JH7110_AONCLK_RTC_APB, "rtc_apb", 0, JH7110_AONCLK_APB_BUS),
++ JH71X0__DIV(JH7110_AONCLK_RTC_INTERNAL, "rtc_internal", 1022, JH7110_AONCLK_OSC),
++ JH71X0__MUX(JH7110_AONCLK_RTC_32K, "rtc_32k", 2,
++ JH7110_AONCLK_RTC_OSC,
++ JH7110_AONCLK_RTC_INTERNAL),
++ JH71X0_GATE(JH7110_AONCLK_RTC_CAL, "rtc_cal", 0, JH7110_AONCLK_OSC),
++};
++
++static struct clk_hw *jh7110_aonclk_get(struct of_phandle_args *clkspec, void *data)
++{
++ struct jh71x0_clk_priv *priv = data;
++ unsigned int idx = clkspec->args[0];
++
++ if (idx < JH7110_AONCLK_END)
++ return &priv->reg[idx].hw;
++
++ return ERR_PTR(-EINVAL);
++}
++
++static int jh7110_aoncrg_probe(struct platform_device *pdev)
++{
++ struct jh71x0_clk_priv *priv;
++ unsigned int idx;
++ int ret;
++
++ priv = devm_kzalloc(&pdev->dev,
++ struct_size(priv, reg, JH7110_AONCLK_END),
++ GFP_KERNEL);
++ if (!priv)
++ return -ENOMEM;
++
++ spin_lock_init(&priv->rmw_lock);
++ priv->dev = &pdev->dev;
++ priv->base = devm_platform_ioremap_resource(pdev, 0);
++ if (IS_ERR(priv->base))
++ return PTR_ERR(priv->base);
++
++ dev_set_drvdata(priv->dev, (void *)(&priv->base));
++
++ for (idx = 0; idx < JH7110_AONCLK_END; idx++) {
++ u32 max = jh7110_aonclk_data[idx].max;
++ struct clk_parent_data parents[4] = {};
++ struct clk_init_data init = {
++ .name = jh7110_aonclk_data[idx].name,
++ .ops = starfive_jh71x0_clk_ops(max),
++ .parent_data = parents,
++ .num_parents =
++ ((max & JH71X0_CLK_MUX_MASK) >> JH71X0_CLK_MUX_SHIFT) + 1,
++ .flags = jh7110_aonclk_data[idx].flags,
++ };
++ struct jh71x0_clk *clk = &priv->reg[idx];
++ unsigned int i;
++
++ for (i = 0; i < init.num_parents; i++) {
++ unsigned int pidx = jh7110_aonclk_data[idx].parents[i];
++
++ if (pidx < JH7110_AONCLK_END)
++ parents[i].hw = &priv->reg[pidx].hw;
++ else if (pidx == JH7110_AONCLK_OSC)
++ parents[i].fw_name = "osc";
++ else if (pidx == JH7110_AONCLK_GMAC0_RMII_REFIN)
++ parents[i].fw_name = "gmac0_rmii_refin";
++ else if (pidx == JH7110_AONCLK_GMAC0_RGMII_RXIN)
++ parents[i].fw_name = "gmac0_rgmii_rxin";
++ else if (pidx == JH7110_AONCLK_STG_AXIAHB)
++ parents[i].fw_name = "stg_axiahb";
++ else if (pidx == JH7110_AONCLK_APB_BUS)
++ parents[i].fw_name = "apb_bus";
++ else if (pidx == JH7110_AONCLK_GMAC0_GTXCLK)
++ parents[i].fw_name = "gmac0_gtxclk";
++ else if (pidx == JH7110_AONCLK_RTC_OSC)
++ parents[i].fw_name = "rtc_osc";
++ }
++
++ clk->hw.init = &init;
++ clk->idx = idx;
++ clk->max_div = max & JH71X0_CLK_DIV_MASK;
++
++ ret = devm_clk_hw_register(&pdev->dev, &clk->hw);
++ if (ret)
++ return ret;
++ }
++
++ ret = devm_of_clk_add_hw_provider(&pdev->dev, jh7110_aonclk_get, priv);
++ if (ret)
++ return ret;
++
++ return jh7110_reset_controller_register(priv, "rst-aon", 1);
++}
++
++static const struct of_device_id jh7110_aoncrg_match[] = {
++ { .compatible = "starfive,jh7110-aoncrg" },
++ { /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(of, jh7110_aoncrg_match);
++
++static struct platform_driver jh7110_aoncrg_driver = {
++ .probe = jh7110_aoncrg_probe,
++ .driver = {
++ .name = "clk-starfive-jh7110-aon",
++ .of_match_table = jh7110_aoncrg_match,
++ },
++};
++module_platform_driver(jh7110_aoncrg_driver);
++
++MODULE_AUTHOR("Emil Renner Berthing");
++MODULE_DESCRIPTION("StarFive JH7110 always-on clock driver");
++MODULE_LICENSE("GPL");
+--
+2.20.1
+
--- /dev/null
+From 8491d586d54eb5d42f16d88a515dc179d2d8856a Mon Sep 17 00:00:00 2001
+From: Hal Feng <hal.feng@starfivetech.com>
+Date: Sat, 1 Apr 2023 19:19:27 +0800
+Subject: [PATCH 19/95] reset: starfive: Add StarFive JH7110 reset driver
+
+Add auxiliary driver to support StarFive JH7110 system
+and always-on resets.
+
+Tested-by: Tommaso Merciai <tomm.merciai@gmail.com>
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ drivers/reset/starfive/Kconfig | 8 +++
+ drivers/reset/starfive/Makefile | 1 +
+ .../reset/starfive/reset-starfive-jh7110.c | 70 +++++++++++++++++++
+ 3 files changed, 79 insertions(+)
+ create mode 100644 drivers/reset/starfive/reset-starfive-jh7110.c
+
+diff --git a/drivers/reset/starfive/Kconfig b/drivers/reset/starfive/Kconfig
+index 1927a5a3b53a..1fa706a2c3dc 100644
+--- a/drivers/reset/starfive/Kconfig
++++ b/drivers/reset/starfive/Kconfig
+@@ -10,3 +10,11 @@ config RESET_STARFIVE_JH7100
+ default ARCH_STARFIVE
+ help
+ This enables the reset controller driver for the StarFive JH7100 SoC.
++
++config RESET_STARFIVE_JH7110
++ bool "StarFive JH7110 Reset Driver"
++ depends on AUXILIARY_BUS && CLK_STARFIVE_JH7110_SYS
++ select RESET_STARFIVE_JH71X0
++ default ARCH_STARFIVE
++ help
++ This enables the reset controller driver for the StarFive JH7110 SoC.
+diff --git a/drivers/reset/starfive/Makefile b/drivers/reset/starfive/Makefile
+index f6aa12466fad..7a44b66fb9d5 100644
+--- a/drivers/reset/starfive/Makefile
++++ b/drivers/reset/starfive/Makefile
+@@ -2,3 +2,4 @@
+ obj-$(CONFIG_RESET_STARFIVE_JH71X0) += reset-starfive-jh71x0.o
+
+ obj-$(CONFIG_RESET_STARFIVE_JH7100) += reset-starfive-jh7100.o
++obj-$(CONFIG_RESET_STARFIVE_JH7110) += reset-starfive-jh7110.o
+diff --git a/drivers/reset/starfive/reset-starfive-jh7110.c b/drivers/reset/starfive/reset-starfive-jh7110.c
+new file mode 100644
+index 000000000000..c1b3a490d951
+--- /dev/null
++++ b/drivers/reset/starfive/reset-starfive-jh7110.c
+@@ -0,0 +1,70 @@
++// SPDX-License-Identifier: GPL-2.0-or-later
++/*
++ * Reset driver for the StarFive JH7110 SoC
++ *
++ * Copyright (C) 2022 StarFive Technology Co., Ltd.
++ */
++
++#include <linux/auxiliary_bus.h>
++
++#include "reset-starfive-jh71x0.h"
++
++#include <dt-bindings/reset/starfive,jh7110-crg.h>
++
++struct jh7110_reset_info {
++ unsigned int nr_resets;
++ unsigned int assert_offset;
++ unsigned int status_offset;
++};
++
++static const struct jh7110_reset_info jh7110_sys_info = {
++ .nr_resets = JH7110_SYSRST_END,
++ .assert_offset = 0x2F8,
++ .status_offset = 0x308,
++};
++
++static const struct jh7110_reset_info jh7110_aon_info = {
++ .nr_resets = JH7110_AONRST_END,
++ .assert_offset = 0x38,
++ .status_offset = 0x3C,
++};
++
++static int jh7110_reset_probe(struct auxiliary_device *adev,
++ const struct auxiliary_device_id *id)
++{
++ struct jh7110_reset_info *info = (struct jh7110_reset_info *)(id->driver_data);
++ void __iomem **base = (void __iomem **)dev_get_drvdata(adev->dev.parent);
++
++ if (!info || !base)
++ return -ENODEV;
++
++ return reset_starfive_jh71x0_register(&adev->dev, adev->dev.parent->of_node,
++ *base + info->assert_offset,
++ *base + info->status_offset,
++ NULL,
++ info->nr_resets,
++ NULL);
++}
++
++static const struct auxiliary_device_id jh7110_reset_ids[] = {
++ {
++ .name = "clk_starfive_jh7110_sys.rst-sys",
++ .driver_data = (kernel_ulong_t)&jh7110_sys_info,
++ },
++ {
++ .name = "clk_starfive_jh7110_sys.rst-aon",
++ .driver_data = (kernel_ulong_t)&jh7110_aon_info,
++ },
++ { /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(auxiliary, jh7110_reset_ids);
++
++static struct auxiliary_driver jh7110_reset_driver = {
++ .probe = jh7110_reset_probe,
++ .id_table = jh7110_reset_ids,
++};
++module_auxiliary_driver(jh7110_reset_driver);
++
++MODULE_AUTHOR("Hal Feng <hal.feng@starfivetech.com>");
++MODULE_DESCRIPTION("StarFive JH7110 reset driver");
++MODULE_LICENSE("GPL");
+--
+2.20.1
+
--- /dev/null
+From 5b65e9bc6ba5bca0b78fbf81e601c5a9431e5779 Mon Sep 17 00:00:00 2001
+From: Emil Renner Berthing <kernel@esmil.dk>
+Date: Sat, 1 Apr 2023 19:19:28 +0800
+Subject: [PATCH 20/95] dt-bindings: timer: Add StarFive JH7110 clint
+
+Add compatible string for the StarFive JH7110 clint.
+
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ Documentation/devicetree/bindings/timer/sifive,clint.yaml | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/Documentation/devicetree/bindings/timer/sifive,clint.yaml b/Documentation/devicetree/bindings/timer/sifive,clint.yaml
+index bbad24165837..a9580191f78b 100644
+--- a/Documentation/devicetree/bindings/timer/sifive,clint.yaml
++++ b/Documentation/devicetree/bindings/timer/sifive,clint.yaml
+@@ -27,6 +27,7 @@ properties:
+ - enum:
+ - sifive,fu540-c000-clint
+ - starfive,jh7100-clint
++ - starfive,jh7110-clint
+ - canaan,k210-clint
+ - const: sifive,clint0
+ - items:
+--
+2.20.1
+
--- /dev/null
+From 9b0e4b9e5cd35360b29b6c41afc5f042e3a4268c Mon Sep 17 00:00:00 2001
+From: Emil Renner Berthing <kernel@esmil.dk>
+Date: Sat, 1 Apr 2023 19:19:29 +0800
+Subject: [PATCH 21/95] dt-bindings: interrupt-controller: Add StarFive JH7110
+ plic
+
+Add compatible string for StarFive JH7110 plic.
+
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ .../bindings/interrupt-controller/sifive,plic-1.0.0.yaml | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/Documentation/devicetree/bindings/interrupt-controller/sifive,plic-1.0.0.yaml b/Documentation/devicetree/bindings/interrupt-controller/sifive,plic-1.0.0.yaml
+index 99e01f4d0a69..571700d5cb9e 100644
+--- a/Documentation/devicetree/bindings/interrupt-controller/sifive,plic-1.0.0.yaml
++++ b/Documentation/devicetree/bindings/interrupt-controller/sifive,plic-1.0.0.yaml
+@@ -60,6 +60,7 @@ properties:
+ - enum:
+ - sifive,fu540-c000-plic
+ - starfive,jh7100-plic
++ - starfive,jh7110-plic
+ - canaan,k210-plic
+ - const: sifive,plic-1.0.0
+ - items:
+--
+2.20.1
+
--- /dev/null
+From 044513fa5dd7c0c6bee080bf0e5f978d1436c847 Mon Sep 17 00:00:00 2001
+From: Hal Feng <hal.feng@starfivetech.com>
+Date: Sat, 1 Apr 2023 19:19:30 +0800
+Subject: [PATCH 22/95] dt-bindings: riscv: Add SiFive S7 compatible
+
+Add a new compatible string in cpu.yaml for SiFive S7 CPU
+core which is used on SiFive U74-MC core complex etc.
+
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ Documentation/devicetree/bindings/riscv/cpus.yaml | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/Documentation/devicetree/bindings/riscv/cpus.yaml b/Documentation/devicetree/bindings/riscv/cpus.yaml
+index d4148418350c..1a65c80e4fed 100644
+--- a/Documentation/devicetree/bindings/riscv/cpus.yaml
++++ b/Documentation/devicetree/bindings/riscv/cpus.yaml
+@@ -34,6 +34,7 @@ properties:
+ - sifive,e7
+ - sifive,e71
+ - sifive,u74-mc
++ - sifive,s7
+ - sifive,u54
+ - sifive,u74
+ - sifive,u5
+--
+2.20.1
+
--- /dev/null
+From 939fc7e4be30fe7febea22a8a401e47e4535b1e9 Mon Sep 17 00:00:00 2001
+From: Emil Renner Berthing <kernel@esmil.dk>
+Date: Sat, 1 Apr 2023 19:19:31 +0800
+Subject: [PATCH 23/95] riscv: dts: starfive: Add initial StarFive JH7110
+ device tree
+
+Add initial device tree for the JH7110 RISC-V SoC by StarFive
+Technology Ltd.
+
+Tested-by: Tommaso Merciai <tomm.merciai@gmail.com>
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
+Co-developed-by: Jianlong Huang <jianlong.huang@starfivetech.com>
+Signed-off-by: Jianlong Huang <jianlong.huang@starfivetech.com>
+Co-developed-by: Hal Feng <hal.feng@starfivetech.com>
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ arch/riscv/boot/dts/starfive/jh7110.dtsi | 509 +++++++++++++++++++++++
+ 1 file changed, 509 insertions(+)
+ create mode 100644 arch/riscv/boot/dts/starfive/jh7110.dtsi
+
+diff --git a/arch/riscv/boot/dts/starfive/jh7110.dtsi b/arch/riscv/boot/dts/starfive/jh7110.dtsi
+new file mode 100644
+index 000000000000..d484ecdf93f7
+--- /dev/null
++++ b/arch/riscv/boot/dts/starfive/jh7110.dtsi
+@@ -0,0 +1,509 @@
++// SPDX-License-Identifier: GPL-2.0 OR MIT
++/*
++ * Copyright (C) 2022 StarFive Technology Co., Ltd.
++ * Copyright (C) 2022 Emil Renner Berthing <kernel@esmil.dk>
++ */
++
++/dts-v1/;
++#include <dt-bindings/clock/starfive,jh7110-crg.h>
++#include <dt-bindings/reset/starfive,jh7110-crg.h>
++
++/ {
++ compatible = "starfive,jh7110";
++ #address-cells = <2>;
++ #size-cells = <2>;
++
++ cpus {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ S7_0: cpu@0 {
++ compatible = "sifive,s7", "riscv";
++ reg = <0>;
++ d-cache-block-size = <64>;
++ d-cache-sets = <64>;
++ d-cache-size = <8192>;
++ d-tlb-sets = <1>;
++ d-tlb-size = <40>;
++ device_type = "cpu";
++ i-cache-block-size = <64>;
++ i-cache-sets = <64>;
++ i-cache-size = <16384>;
++ i-tlb-sets = <1>;
++ i-tlb-size = <40>;
++ mmu-type = "riscv,sv39";
++ next-level-cache = <&ccache>;
++ riscv,isa = "rv64imac_zba_zbb";
++ tlb-split;
++ status = "disabled";
++
++ cpu0_intc: interrupt-controller {
++ compatible = "riscv,cpu-intc";
++ interrupt-controller;
++ #interrupt-cells = <1>;
++ };
++ };
++
++ U74_1: cpu@1 {
++ compatible = "sifive,u74-mc", "riscv";
++ reg = <1>;
++ d-cache-block-size = <64>;
++ d-cache-sets = <64>;
++ d-cache-size = <32768>;
++ d-tlb-sets = <1>;
++ d-tlb-size = <40>;
++ device_type = "cpu";
++ i-cache-block-size = <64>;
++ i-cache-sets = <64>;
++ i-cache-size = <32768>;
++ i-tlb-sets = <1>;
++ i-tlb-size = <40>;
++ mmu-type = "riscv,sv39";
++ next-level-cache = <&ccache>;
++ riscv,isa = "rv64imafdc_zba_zbb";
++ tlb-split;
++
++ cpu1_intc: interrupt-controller {
++ compatible = "riscv,cpu-intc";
++ interrupt-controller;
++ #interrupt-cells = <1>;
++ };
++ };
++
++ U74_2: cpu@2 {
++ compatible = "sifive,u74-mc", "riscv";
++ reg = <2>;
++ d-cache-block-size = <64>;
++ d-cache-sets = <64>;
++ d-cache-size = <32768>;
++ d-tlb-sets = <1>;
++ d-tlb-size = <40>;
++ device_type = "cpu";
++ i-cache-block-size = <64>;
++ i-cache-sets = <64>;
++ i-cache-size = <32768>;
++ i-tlb-sets = <1>;
++ i-tlb-size = <40>;
++ mmu-type = "riscv,sv39";
++ next-level-cache = <&ccache>;
++ riscv,isa = "rv64imafdc_zba_zbb";
++ tlb-split;
++
++ cpu2_intc: interrupt-controller {
++ compatible = "riscv,cpu-intc";
++ interrupt-controller;
++ #interrupt-cells = <1>;
++ };
++ };
++
++ U74_3: cpu@3 {
++ compatible = "sifive,u74-mc", "riscv";
++ reg = <3>;
++ d-cache-block-size = <64>;
++ d-cache-sets = <64>;
++ d-cache-size = <32768>;
++ d-tlb-sets = <1>;
++ d-tlb-size = <40>;
++ device_type = "cpu";
++ i-cache-block-size = <64>;
++ i-cache-sets = <64>;
++ i-cache-size = <32768>;
++ i-tlb-sets = <1>;
++ i-tlb-size = <40>;
++ mmu-type = "riscv,sv39";
++ next-level-cache = <&ccache>;
++ riscv,isa = "rv64imafdc_zba_zbb";
++ tlb-split;
++
++ cpu3_intc: interrupt-controller {
++ compatible = "riscv,cpu-intc";
++ interrupt-controller;
++ #interrupt-cells = <1>;
++ };
++ };
++
++ U74_4: cpu@4 {
++ compatible = "sifive,u74-mc", "riscv";
++ reg = <4>;
++ d-cache-block-size = <64>;
++ d-cache-sets = <64>;
++ d-cache-size = <32768>;
++ d-tlb-sets = <1>;
++ d-tlb-size = <40>;
++ device_type = "cpu";
++ i-cache-block-size = <64>;
++ i-cache-sets = <64>;
++ i-cache-size = <32768>;
++ i-tlb-sets = <1>;
++ i-tlb-size = <40>;
++ mmu-type = "riscv,sv39";
++ next-level-cache = <&ccache>;
++ riscv,isa = "rv64imafdc_zba_zbb";
++ tlb-split;
++
++ cpu4_intc: interrupt-controller {
++ compatible = "riscv,cpu-intc";
++ interrupt-controller;
++ #interrupt-cells = <1>;
++ };
++ };
++
++ cpu-map {
++ cluster0 {
++ core0 {
++ cpu = <&S7_0>;
++ };
++
++ core1 {
++ cpu = <&U74_1>;
++ };
++
++ core2 {
++ cpu = <&U74_2>;
++ };
++
++ core3 {
++ cpu = <&U74_3>;
++ };
++
++ core4 {
++ cpu = <&U74_4>;
++ };
++ };
++ };
++ };
++
++ gmac0_rgmii_rxin: gmac0-rgmii-rxin-clock {
++ compatible = "fixed-clock";
++ clock-output-names = "gmac0_rgmii_rxin";
++ #clock-cells = <0>;
++ };
++
++ gmac0_rmii_refin: gmac0-rmii-refin-clock {
++ compatible = "fixed-clock";
++ clock-output-names = "gmac0_rmii_refin";
++ #clock-cells = <0>;
++ };
++
++ gmac1_rgmii_rxin: gmac1-rgmii-rxin-clock {
++ compatible = "fixed-clock";
++ clock-output-names = "gmac1_rgmii_rxin";
++ #clock-cells = <0>;
++ };
++
++ gmac1_rmii_refin: gmac1-rmii-refin-clock {
++ compatible = "fixed-clock";
++ clock-output-names = "gmac1_rmii_refin";
++ #clock-cells = <0>;
++ };
++
++ i2srx_bclk_ext: i2srx-bclk-ext-clock {
++ compatible = "fixed-clock";
++ clock-output-names = "i2srx_bclk_ext";
++ #clock-cells = <0>;
++ };
++
++ i2srx_lrck_ext: i2srx-lrck-ext-clock {
++ compatible = "fixed-clock";
++ clock-output-names = "i2srx_lrck_ext";
++ #clock-cells = <0>;
++ };
++
++ i2stx_bclk_ext: i2stx-bclk-ext-clock {
++ compatible = "fixed-clock";
++ clock-output-names = "i2stx_bclk_ext";
++ #clock-cells = <0>;
++ };
++
++ i2stx_lrck_ext: i2stx-lrck-ext-clock {
++ compatible = "fixed-clock";
++ clock-output-names = "i2stx_lrck_ext";
++ #clock-cells = <0>;
++ };
++
++ mclk_ext: mclk-ext-clock {
++ compatible = "fixed-clock";
++ clock-output-names = "mclk_ext";
++ #clock-cells = <0>;
++ };
++
++ osc: oscillator {
++ compatible = "fixed-clock";
++ clock-output-names = "osc";
++ #clock-cells = <0>;
++ };
++
++ rtc_osc: rtc-oscillator {
++ compatible = "fixed-clock";
++ clock-output-names = "rtc_osc";
++ #clock-cells = <0>;
++ };
++
++ tdm_ext: tdm-ext-clock {
++ compatible = "fixed-clock";
++ clock-output-names = "tdm_ext";
++ #clock-cells = <0>;
++ };
++
++ soc {
++ compatible = "simple-bus";
++ interrupt-parent = <&plic>;
++ #address-cells = <2>;
++ #size-cells = <2>;
++ ranges;
++
++ clint: timer@2000000 {
++ compatible = "starfive,jh7110-clint", "sifive,clint0";
++ reg = <0x0 0x2000000 0x0 0x10000>;
++ interrupts-extended = <&cpu0_intc 3>, <&cpu0_intc 7>,
++ <&cpu1_intc 3>, <&cpu1_intc 7>,
++ <&cpu2_intc 3>, <&cpu2_intc 7>,
++ <&cpu3_intc 3>, <&cpu3_intc 7>,
++ <&cpu4_intc 3>, <&cpu4_intc 7>;
++ };
++
++ ccache: cache-controller@2010000 {
++ compatible = "starfive,jh7110-ccache", "sifive,ccache0", "cache";
++ reg = <0x0 0x2010000 0x0 0x4000>;
++ interrupts = <1>, <3>, <4>, <2>;
++ cache-block-size = <64>;
++ cache-level = <2>;
++ cache-sets = <2048>;
++ cache-size = <2097152>;
++ cache-unified;
++ };
++
++ plic: interrupt-controller@c000000 {
++ compatible = "starfive,jh7110-plic", "sifive,plic-1.0.0";
++ reg = <0x0 0xc000000 0x0 0x4000000>;
++ interrupts-extended = <&cpu0_intc 11>,
++ <&cpu1_intc 11>, <&cpu1_intc 9>,
++ <&cpu2_intc 11>, <&cpu2_intc 9>,
++ <&cpu3_intc 11>, <&cpu3_intc 9>,
++ <&cpu4_intc 11>, <&cpu4_intc 9>;
++ interrupt-controller;
++ #interrupt-cells = <1>;
++ #address-cells = <0>;
++ riscv,ndev = <136>;
++ };
++
++ uart0: serial@10000000 {
++ compatible = "snps,dw-apb-uart";
++ reg = <0x0 0x10000000 0x0 0x10000>;
++ clocks = <&syscrg JH7110_SYSCLK_UART0_CORE>,
++ <&syscrg JH7110_SYSCLK_UART0_APB>;
++ clock-names = "baudclk", "apb_pclk";
++ resets = <&syscrg JH7110_SYSRST_UART0_APB>;
++ interrupts = <32>;
++ reg-io-width = <4>;
++ reg-shift = <2>;
++ status = "disabled";
++ };
++
++ uart1: serial@10010000 {
++ compatible = "snps,dw-apb-uart";
++ reg = <0x0 0x10010000 0x0 0x10000>;
++ clocks = <&syscrg JH7110_SYSCLK_UART1_CORE>,
++ <&syscrg JH7110_SYSCLK_UART1_APB>;
++ clock-names = "baudclk", "apb_pclk";
++ resets = <&syscrg JH7110_SYSRST_UART1_APB>;
++ interrupts = <33>;
++ reg-io-width = <4>;
++ reg-shift = <2>;
++ status = "disabled";
++ };
++
++ uart2: serial@10020000 {
++ compatible = "snps,dw-apb-uart";
++ reg = <0x0 0x10020000 0x0 0x10000>;
++ clocks = <&syscrg JH7110_SYSCLK_UART2_CORE>,
++ <&syscrg JH7110_SYSCLK_UART2_APB>;
++ clock-names = "baudclk", "apb_pclk";
++ resets = <&syscrg JH7110_SYSRST_UART2_APB>;
++ interrupts = <34>;
++ reg-io-width = <4>;
++ reg-shift = <2>;
++ status = "disabled";
++ };
++
++ i2c0: i2c@10030000 {
++ compatible = "snps,designware-i2c";
++ reg = <0x0 0x10030000 0x0 0x10000>;
++ clocks = <&syscrg JH7110_SYSCLK_I2C0_APB>;
++ clock-names = "ref";
++ resets = <&syscrg JH7110_SYSRST_I2C0_APB>;
++ interrupts = <35>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ i2c1: i2c@10040000 {
++ compatible = "snps,designware-i2c";
++ reg = <0x0 0x10040000 0x0 0x10000>;
++ clocks = <&syscrg JH7110_SYSCLK_I2C1_APB>;
++ clock-names = "ref";
++ resets = <&syscrg JH7110_SYSRST_I2C1_APB>;
++ interrupts = <36>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ i2c2: i2c@10050000 {
++ compatible = "snps,designware-i2c";
++ reg = <0x0 0x10050000 0x0 0x10000>;
++ clocks = <&syscrg JH7110_SYSCLK_I2C2_APB>;
++ clock-names = "ref";
++ resets = <&syscrg JH7110_SYSRST_I2C2_APB>;
++ interrupts = <37>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ uart3: serial@12000000 {
++ compatible = "snps,dw-apb-uart";
++ reg = <0x0 0x12000000 0x0 0x10000>;
++ clocks = <&syscrg JH7110_SYSCLK_UART3_CORE>,
++ <&syscrg JH7110_SYSCLK_UART3_APB>;
++ clock-names = "baudclk", "apb_pclk";
++ resets = <&syscrg JH7110_SYSRST_UART3_APB>;
++ interrupts = <45>;
++ reg-io-width = <4>;
++ reg-shift = <2>;
++ status = "disabled";
++ };
++
++ uart4: serial@12010000 {
++ compatible = "snps,dw-apb-uart";
++ reg = <0x0 0x12010000 0x0 0x10000>;
++ clocks = <&syscrg JH7110_SYSCLK_UART4_CORE>,
++ <&syscrg JH7110_SYSCLK_UART4_APB>;
++ clock-names = "baudclk", "apb_pclk";
++ resets = <&syscrg JH7110_SYSRST_UART4_APB>;
++ interrupts = <46>;
++ reg-io-width = <4>;
++ reg-shift = <2>;
++ status = "disabled";
++ };
++
++ uart5: serial@12020000 {
++ compatible = "snps,dw-apb-uart";
++ reg = <0x0 0x12020000 0x0 0x10000>;
++ clocks = <&syscrg JH7110_SYSCLK_UART5_CORE>,
++ <&syscrg JH7110_SYSCLK_UART5_APB>;
++ clock-names = "baudclk", "apb_pclk";
++ resets = <&syscrg JH7110_SYSRST_UART5_APB>;
++ interrupts = <47>;
++ reg-io-width = <4>;
++ reg-shift = <2>;
++ status = "disabled";
++ };
++
++ i2c3: i2c@12030000 {
++ compatible = "snps,designware-i2c";
++ reg = <0x0 0x12030000 0x0 0x10000>;
++ clocks = <&syscrg JH7110_SYSCLK_I2C3_APB>;
++ clock-names = "ref";
++ resets = <&syscrg JH7110_SYSRST_I2C3_APB>;
++ interrupts = <48>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ i2c4: i2c@12040000 {
++ compatible = "snps,designware-i2c";
++ reg = <0x0 0x12040000 0x0 0x10000>;
++ clocks = <&syscrg JH7110_SYSCLK_I2C4_APB>;
++ clock-names = "ref";
++ resets = <&syscrg JH7110_SYSRST_I2C4_APB>;
++ interrupts = <49>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ i2c5: i2c@12050000 {
++ compatible = "snps,designware-i2c";
++ reg = <0x0 0x12050000 0x0 0x10000>;
++ clocks = <&syscrg JH7110_SYSCLK_I2C5_APB>;
++ clock-names = "ref";
++ resets = <&syscrg JH7110_SYSRST_I2C5_APB>;
++ interrupts = <50>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ i2c6: i2c@12060000 {
++ compatible = "snps,designware-i2c";
++ reg = <0x0 0x12060000 0x0 0x10000>;
++ clocks = <&syscrg JH7110_SYSCLK_I2C6_APB>;
++ clock-names = "ref";
++ resets = <&syscrg JH7110_SYSRST_I2C6_APB>;
++ interrupts = <51>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ syscrg: clock-controller@13020000 {
++ compatible = "starfive,jh7110-syscrg";
++ reg = <0x0 0x13020000 0x0 0x10000>;
++ clocks = <&osc>, <&gmac1_rmii_refin>,
++ <&gmac1_rgmii_rxin>,
++ <&i2stx_bclk_ext>, <&i2stx_lrck_ext>,
++ <&i2srx_bclk_ext>, <&i2srx_lrck_ext>,
++ <&tdm_ext>, <&mclk_ext>;
++ clock-names = "osc", "gmac1_rmii_refin",
++ "gmac1_rgmii_rxin",
++ "i2stx_bclk_ext", "i2stx_lrck_ext",
++ "i2srx_bclk_ext", "i2srx_lrck_ext",
++ "tdm_ext", "mclk_ext";
++ #clock-cells = <1>;
++ #reset-cells = <1>;
++ };
++
++ sysgpio: pinctrl@13040000 {
++ compatible = "starfive,jh7110-sys-pinctrl";
++ reg = <0x0 0x13040000 0x0 0x10000>;
++ clocks = <&syscrg JH7110_SYSCLK_IOMUX_APB>;
++ resets = <&syscrg JH7110_SYSRST_IOMUX_APB>;
++ interrupts = <86>;
++ interrupt-controller;
++ #interrupt-cells = <2>;
++ gpio-controller;
++ #gpio-cells = <2>;
++ };
++
++ aoncrg: clock-controller@17000000 {
++ compatible = "starfive,jh7110-aoncrg";
++ reg = <0x0 0x17000000 0x0 0x10000>;
++ clocks = <&osc>, <&gmac0_rmii_refin>,
++ <&gmac0_rgmii_rxin>,
++ <&syscrg JH7110_SYSCLK_STG_AXIAHB>,
++ <&syscrg JH7110_SYSCLK_APB_BUS>,
++ <&syscrg JH7110_SYSCLK_GMAC0_GTXCLK>,
++ <&rtc_osc>;
++ clock-names = "osc", "gmac0_rmii_refin",
++ "gmac0_rgmii_rxin", "stg_axiahb",
++ "apb_bus", "gmac0_gtxclk",
++ "rtc_osc";
++ #clock-cells = <1>;
++ #reset-cells = <1>;
++ };
++
++ aongpio: pinctrl@17020000 {
++ compatible = "starfive,jh7110-aon-pinctrl";
++ reg = <0x0 0x17020000 0x0 0x10000>;
++ resets = <&aoncrg JH7110_AONRST_IOMUX>;
++ interrupts = <85>;
++ interrupt-controller;
++ #interrupt-cells = <2>;
++ gpio-controller;
++ #gpio-cells = <2>;
++ };
++ };
++};
+--
+2.20.1
+
--- /dev/null
+From 5a096c0787c6fde6ddeaf1bab069ec5a0512e9f8 Mon Sep 17 00:00:00 2001
+From: Jianlong Huang <jianlong.huang@starfivetech.com>
+Date: Sat, 1 Apr 2023 19:19:32 +0800
+Subject: [PATCH 24/95] riscv: dts: starfive: Add StarFive JH7110 pin function
+ definitions
+
+Add pin function definitions for StarFive JH7110 SoC.
+
+Tested-by: Tommaso Merciai <tomm.merciai@gmail.com>
+Co-developed-by: Emil Renner Berthing <kernel@esmil.dk>
+Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
+Signed-off-by: Jianlong Huang <jianlong.huang@starfivetech.com>
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ arch/riscv/boot/dts/starfive/jh7110-pinfunc.h | 308 ++++++++++++++++++
+ 1 file changed, 308 insertions(+)
+ create mode 100644 arch/riscv/boot/dts/starfive/jh7110-pinfunc.h
+
+diff --git a/arch/riscv/boot/dts/starfive/jh7110-pinfunc.h b/arch/riscv/boot/dts/starfive/jh7110-pinfunc.h
+new file mode 100644
+index 000000000000..fb0139b56723
+--- /dev/null
++++ b/arch/riscv/boot/dts/starfive/jh7110-pinfunc.h
+@@ -0,0 +1,308 @@
++/* SPDX-License-Identifier: GPL-2.0 OR MIT */
++/*
++ * Copyright (C) 2022 Emil Renner Berthing <kernel@esmil.dk>
++ * Copyright (C) 2022 StarFive Technology Co., Ltd.
++ */
++
++#ifndef __JH7110_PINFUNC_H__
++#define __JH7110_PINFUNC_H__
++
++/*
++ * mux bits:
++ * | 31 - 24 | 23 - 16 | 15 - 10 | 9 - 8 | 7 - 0 |
++ * | din | dout | doen | function | gpio nr |
++ *
++ * dout: output signal
++ * doen: output enable signal
++ * din: optional input signal, 0xff = none
++ * function: function selector
++ * gpio nr: gpio number, 0 - 63
++ */
++#define GPIOMUX(n, dout, doen, din) ( \
++ (((din) & 0xff) << 24) | \
++ (((dout) & 0xff) << 16) | \
++ (((doen) & 0x3f) << 10) | \
++ ((n) & 0x3f))
++
++#define PINMUX(n, func) ((1 << 10) | (((func) & 0x3) << 8) | ((n) & 0xff))
++
++/* sys_iomux dout */
++#define GPOUT_LOW 0
++#define GPOUT_HIGH 1
++#define GPOUT_SYS_WAVE511_UART_TX 2
++#define GPOUT_SYS_CAN0_STBY 3
++#define GPOUT_SYS_CAN0_TST_NEXT_BIT 4
++#define GPOUT_SYS_CAN0_TST_SAMPLE_POINT 5
++#define GPOUT_SYS_CAN0_TXD 6
++#define GPOUT_SYS_USB_DRIVE_VBUS 7
++#define GPOUT_SYS_QSPI_CS1 8
++#define GPOUT_SYS_SPDIF 9
++#define GPOUT_SYS_HDMI_CEC_SDA 10
++#define GPOUT_SYS_HDMI_DDC_SCL 11
++#define GPOUT_SYS_HDMI_DDC_SDA 12
++#define GPOUT_SYS_WATCHDOG 13
++#define GPOUT_SYS_I2C0_CLK 14
++#define GPOUT_SYS_I2C0_DATA 15
++#define GPOUT_SYS_SDIO0_BACK_END_POWER 16
++#define GPOUT_SYS_SDIO0_CARD_POWER_EN 17
++#define GPOUT_SYS_SDIO0_CCMD_OD_PULLUP_EN 18
++#define GPOUT_SYS_SDIO0_RST 19
++#define GPOUT_SYS_UART0_TX 20
++#define GPOUT_SYS_HIFI4_JTAG_TDO 21
++#define GPOUT_SYS_JTAG_TDO 22
++#define GPOUT_SYS_PDM_MCLK 23
++#define GPOUT_SYS_PWM_CHANNEL0 24
++#define GPOUT_SYS_PWM_CHANNEL1 25
++#define GPOUT_SYS_PWM_CHANNEL2 26
++#define GPOUT_SYS_PWM_CHANNEL3 27
++#define GPOUT_SYS_PWMDAC_LEFT 28
++#define GPOUT_SYS_PWMDAC_RIGHT 29
++#define GPOUT_SYS_SPI0_CLK 30
++#define GPOUT_SYS_SPI0_FSS 31
++#define GPOUT_SYS_SPI0_TXD 32
++#define GPOUT_SYS_GMAC_PHYCLK 33
++#define GPOUT_SYS_I2SRX_BCLK 34
++#define GPOUT_SYS_I2SRX_LRCK 35
++#define GPOUT_SYS_I2STX0_BCLK 36
++#define GPOUT_SYS_I2STX0_LRCK 37
++#define GPOUT_SYS_MCLK 38
++#define GPOUT_SYS_TDM_CLK 39
++#define GPOUT_SYS_TDM_SYNC 40
++#define GPOUT_SYS_TDM_TXD 41
++#define GPOUT_SYS_TRACE_DATA0 42
++#define GPOUT_SYS_TRACE_DATA1 43
++#define GPOUT_SYS_TRACE_DATA2 44
++#define GPOUT_SYS_TRACE_DATA3 45
++#define GPOUT_SYS_TRACE_REF 46
++#define GPOUT_SYS_CAN1_STBY 47
++#define GPOUT_SYS_CAN1_TST_NEXT_BIT 48
++#define GPOUT_SYS_CAN1_TST_SAMPLE_POINT 49
++#define GPOUT_SYS_CAN1_TXD 50
++#define GPOUT_SYS_I2C1_CLK 51
++#define GPOUT_SYS_I2C1_DATA 52
++#define GPOUT_SYS_SDIO1_BACK_END_POWER 53
++#define GPOUT_SYS_SDIO1_CARD_POWER_EN 54
++#define GPOUT_SYS_SDIO1_CLK 55
++#define GPOUT_SYS_SDIO1_CMD_OD_PULLUP_EN 56
++#define GPOUT_SYS_SDIO1_CMD 57
++#define GPOUT_SYS_SDIO1_DATA0 58
++#define GPOUT_SYS_SDIO1_DATA1 59
++#define GPOUT_SYS_SDIO1_DATA2 60
++#define GPOUT_SYS_SDIO1_DATA3 61
++#define GPOUT_SYS_SDIO1_DATA4 63
++#define GPOUT_SYS_SDIO1_DATA5 63
++#define GPOUT_SYS_SDIO1_DATA6 64
++#define GPOUT_SYS_SDIO1_DATA7 65
++#define GPOUT_SYS_SDIO1_RST 66
++#define GPOUT_SYS_UART1_RTS 67
++#define GPOUT_SYS_UART1_TX 68
++#define GPOUT_SYS_I2STX1_SDO0 69
++#define GPOUT_SYS_I2STX1_SDO1 70
++#define GPOUT_SYS_I2STX1_SDO2 71
++#define GPOUT_SYS_I2STX1_SDO3 72
++#define GPOUT_SYS_SPI1_CLK 73
++#define GPOUT_SYS_SPI1_FSS 74
++#define GPOUT_SYS_SPI1_TXD 75
++#define GPOUT_SYS_I2C2_CLK 76
++#define GPOUT_SYS_I2C2_DATA 77
++#define GPOUT_SYS_UART2_RTS 78
++#define GPOUT_SYS_UART2_TX 79
++#define GPOUT_SYS_SPI2_CLK 80
++#define GPOUT_SYS_SPI2_FSS 81
++#define GPOUT_SYS_SPI2_TXD 82
++#define GPOUT_SYS_I2C3_CLK 83
++#define GPOUT_SYS_I2C3_DATA 84
++#define GPOUT_SYS_UART3_TX 85
++#define GPOUT_SYS_SPI3_CLK 86
++#define GPOUT_SYS_SPI3_FSS 87
++#define GPOUT_SYS_SPI3_TXD 88
++#define GPOUT_SYS_I2C4_CLK 89
++#define GPOUT_SYS_I2C4_DATA 90
++#define GPOUT_SYS_UART4_RTS 91
++#define GPOUT_SYS_UART4_TX 92
++#define GPOUT_SYS_SPI4_CLK 93
++#define GPOUT_SYS_SPI4_FSS 94
++#define GPOUT_SYS_SPI4_TXD 95
++#define GPOUT_SYS_I2C5_CLK 96
++#define GPOUT_SYS_I2C5_DATA 97
++#define GPOUT_SYS_UART5_RTS 98
++#define GPOUT_SYS_UART5_TX 99
++#define GPOUT_SYS_SPI5_CLK 100
++#define GPOUT_SYS_SPI5_FSS 101
++#define GPOUT_SYS_SPI5_TXD 102
++#define GPOUT_SYS_I2C6_CLK 103
++#define GPOUT_SYS_I2C6_DATA 104
++#define GPOUT_SYS_SPI6_CLK 105
++#define GPOUT_SYS_SPI6_FSS 106
++#define GPOUT_SYS_SPI6_TXD 107
++
++/* aon_iomux dout */
++#define GPOUT_AON_CLK_32K_OUT 2
++#define GPOUT_AON_PTC0_PWM4 3
++#define GPOUT_AON_PTC0_PWM5 4
++#define GPOUT_AON_PTC0_PWM6 5
++#define GPOUT_AON_PTC0_PWM7 6
++#define GPOUT_AON_CLK_GCLK0 7
++#define GPOUT_AON_CLK_GCLK1 8
++#define GPOUT_AON_CLK_GCLK2 9
++
++/* sys_iomux doen */
++#define GPOEN_ENABLE 0
++#define GPOEN_DISABLE 1
++#define GPOEN_SYS_HDMI_CEC_SDA 2
++#define GPOEN_SYS_HDMI_DDC_SCL 3
++#define GPOEN_SYS_HDMI_DDC_SDA 4
++#define GPOEN_SYS_I2C0_CLK 5
++#define GPOEN_SYS_I2C0_DATA 6
++#define GPOEN_SYS_HIFI4_JTAG_TDO 7
++#define GPOEN_SYS_JTAG_TDO 8
++#define GPOEN_SYS_PWM0_CHANNEL0 9
++#define GPOEN_SYS_PWM0_CHANNEL1 10
++#define GPOEN_SYS_PWM0_CHANNEL2 11
++#define GPOEN_SYS_PWM0_CHANNEL3 12
++#define GPOEN_SYS_SPI0_NSSPCTL 13
++#define GPOEN_SYS_SPI0_NSSP 14
++#define GPOEN_SYS_TDM_SYNC 15
++#define GPOEN_SYS_TDM_TXD 16
++#define GPOEN_SYS_I2C1_CLK 17
++#define GPOEN_SYS_I2C1_DATA 18
++#define GPOEN_SYS_SDIO1_CMD 19
++#define GPOEN_SYS_SDIO1_DATA0 20
++#define GPOEN_SYS_SDIO1_DATA1 21
++#define GPOEN_SYS_SDIO1_DATA2 22
++#define GPOEN_SYS_SDIO1_DATA3 23
++#define GPOEN_SYS_SDIO1_DATA4 24
++#define GPOEN_SYS_SDIO1_DATA5 25
++#define GPOEN_SYS_SDIO1_DATA6 26
++#define GPOEN_SYS_SDIO1_DATA7 27
++#define GPOEN_SYS_SPI1_NSSPCTL 28
++#define GPOEN_SYS_SPI1_NSSP 29
++#define GPOEN_SYS_I2C2_CLK 30
++#define GPOEN_SYS_I2C2_DATA 31
++#define GPOEN_SYS_SPI2_NSSPCTL 32
++#define GPOEN_SYS_SPI2_NSSP 33
++#define GPOEN_SYS_I2C3_CLK 34
++#define GPOEN_SYS_I2C3_DATA 35
++#define GPOEN_SYS_SPI3_NSSPCTL 36
++#define GPOEN_SYS_SPI3_NSSP 37
++#define GPOEN_SYS_I2C4_CLK 38
++#define GPOEN_SYS_I2C4_DATA 39
++#define GPOEN_SYS_SPI4_NSSPCTL 40
++#define GPOEN_SYS_SPI4_NSSP 41
++#define GPOEN_SYS_I2C5_CLK 42
++#define GPOEN_SYS_I2C5_DATA 43
++#define GPOEN_SYS_SPI5_NSSPCTL 44
++#define GPOEN_SYS_SPI5_NSSP 45
++#define GPOEN_SYS_I2C6_CLK 46
++#define GPOEN_SYS_I2C6_DATA 47
++#define GPOEN_SYS_SPI6_NSSPCTL 48
++#define GPOEN_SYS_SPI6_NSSP 49
++
++/* aon_iomux doen */
++#define GPOEN_AON_PTC0_OE_N_4 2
++#define GPOEN_AON_PTC0_OE_N_5 3
++#define GPOEN_AON_PTC0_OE_N_6 4
++#define GPOEN_AON_PTC0_OE_N_7 5
++
++/* sys_iomux gin */
++#define GPI_NONE 255
++
++#define GPI_SYS_WAVE511_UART_RX 0
++#define GPI_SYS_CAN0_RXD 1
++#define GPI_SYS_USB_OVERCURRENT 2
++#define GPI_SYS_SPDIF 3
++#define GPI_SYS_JTAG_RST 4
++#define GPI_SYS_HDMI_CEC_SDA 5
++#define GPI_SYS_HDMI_DDC_SCL 6
++#define GPI_SYS_HDMI_DDC_SDA 7
++#define GPI_SYS_HDMI_HPD 8
++#define GPI_SYS_I2C0_CLK 9
++#define GPI_SYS_I2C0_DATA 10
++#define GPI_SYS_SDIO0_CD 11
++#define GPI_SYS_SDIO0_INT 12
++#define GPI_SYS_SDIO0_WP 13
++#define GPI_SYS_UART0_RX 14
++#define GPI_SYS_HIFI4_JTAG_TCK 15
++#define GPI_SYS_HIFI4_JTAG_TDI 16
++#define GPI_SYS_HIFI4_JTAG_TMS 17
++#define GPI_SYS_HIFI4_JTAG_RST 18
++#define GPI_SYS_JTAG_TDI 19
++#define GPI_SYS_JTAG_TMS 20
++#define GPI_SYS_PDM_DMIC0 21
++#define GPI_SYS_PDM_DMIC1 22
++#define GPI_SYS_I2SRX_SDIN0 23
++#define GPI_SYS_I2SRX_SDIN1 24
++#define GPI_SYS_I2SRX_SDIN2 25
++#define GPI_SYS_SPI0_CLK 26
++#define GPI_SYS_SPI0_FSS 27
++#define GPI_SYS_SPI0_RXD 28
++#define GPI_SYS_JTAG_TCK 29
++#define GPI_SYS_MCLK_EXT 30
++#define GPI_SYS_I2SRX_BCLK 31
++#define GPI_SYS_I2SRX_LRCK 32
++#define GPI_SYS_I2STX0_BCLK 33
++#define GPI_SYS_I2STX0_LRCK 34
++#define GPI_SYS_TDM_CLK 35
++#define GPI_SYS_TDM_RXD 36
++#define GPI_SYS_TDM_SYNC 37
++#define GPI_SYS_CAN1_RXD 38
++#define GPI_SYS_I2C1_CLK 39
++#define GPI_SYS_I2C1_DATA 40
++#define GPI_SYS_SDIO1_CD 41
++#define GPI_SYS_SDIO1_INT 42
++#define GPI_SYS_SDIO1_WP 43
++#define GPI_SYS_SDIO1_CMD 44
++#define GPI_SYS_SDIO1_DATA0 45
++#define GPI_SYS_SDIO1_DATA1 46
++#define GPI_SYS_SDIO1_DATA2 47
++#define GPI_SYS_SDIO1_DATA3 48
++#define GPI_SYS_SDIO1_DATA4 49
++#define GPI_SYS_SDIO1_DATA5 50
++#define GPI_SYS_SDIO1_DATA6 51
++#define GPI_SYS_SDIO1_DATA7 52
++#define GPI_SYS_SDIO1_STRB 53
++#define GPI_SYS_UART1_CTS 54
++#define GPI_SYS_UART1_RX 55
++#define GPI_SYS_SPI1_CLK 56
++#define GPI_SYS_SPI1_FSS 57
++#define GPI_SYS_SPI1_RXD 58
++#define GPI_SYS_I2C2_CLK 59
++#define GPI_SYS_I2C2_DATA 60
++#define GPI_SYS_UART2_CTS 61
++#define GPI_SYS_UART2_RX 62
++#define GPI_SYS_SPI2_CLK 63
++#define GPI_SYS_SPI2_FSS 64
++#define GPI_SYS_SPI2_RXD 65
++#define GPI_SYS_I2C3_CLK 66
++#define GPI_SYS_I2C3_DATA 67
++#define GPI_SYS_UART3_RX 68
++#define GPI_SYS_SPI3_CLK 69
++#define GPI_SYS_SPI3_FSS 70
++#define GPI_SYS_SPI3_RXD 71
++#define GPI_SYS_I2C4_CLK 72
++#define GPI_SYS_I2C4_DATA 73
++#define GPI_SYS_UART4_CTS 74
++#define GPI_SYS_UART4_RX 75
++#define GPI_SYS_SPI4_CLK 76
++#define GPI_SYS_SPI4_FSS 77
++#define GPI_SYS_SPI4_RXD 78
++#define GPI_SYS_I2C5_CLK 79
++#define GPI_SYS_I2C5_DATA 80
++#define GPI_SYS_UART5_CTS 81
++#define GPI_SYS_UART5_RX 82
++#define GPI_SYS_SPI5_CLK 83
++#define GPI_SYS_SPI5_FSS 84
++#define GPI_SYS_SPI5_RXD 85
++#define GPI_SYS_I2C6_CLK 86
++#define GPI_SYS_I2C6_DATA 87
++#define GPI_SYS_SPI6_CLK 88
++#define GPI_SYS_SPI6_FSS 89
++#define GPI_SYS_SPI6_RXD 90
++
++/* aon_iomux gin */
++#define GPI_AON_PMU_GPIO_WAKEUP_0 0
++#define GPI_AON_PMU_GPIO_WAKEUP_1 1
++#define GPI_AON_PMU_GPIO_WAKEUP_2 2
++#define GPI_AON_PMU_GPIO_WAKEUP_3 3
++
++#endif
+--
+2.20.1
+
--- /dev/null
+From 91112089c335da57c9f2005e9e70810545f2c971 Mon Sep 17 00:00:00 2001
+From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
+Date: Tue, 18 Oct 2022 00:05:42 +0300
+Subject: [PATCH 25/95] riscv: dts: starfive: Add StarFive VisionFive V1 device
+ tree
+
+Add initial device tree for the StarFive VisionFive V1 SBC, which
+is similar with the already supported BeagleV Starlight Beta board,
+both being based on the StarFive JH7100 SoC.
+
+Link: https://github.com/starfive-tech/VisionFive
+Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+Reviewed-by: Matthias Brugger <mbrugger@suse.com>
+Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
+---
+ arch/riscv/boot/dts/starfive/Makefile | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/riscv/boot/dts/starfive/Makefile b/arch/riscv/boot/dts/starfive/Makefile
+index 0ea1bc15ab30..039c143cba33 100644
+--- a/arch/riscv/boot/dts/starfive/Makefile
++++ b/arch/riscv/boot/dts/starfive/Makefile
+@@ -1,2 +1,2 @@
+ # SPDX-License-Identifier: GPL-2.0
+-dtb-$(CONFIG_SOC_STARFIVE) += jh7100-beaglev-starlight.dtb
++dtb-$(CONFIG_SOC_STARFIVE) += jh7100-beaglev-starlight.dtb jh7100-starfive-visionfive-v1.dtb
+--
+2.20.1
+
--- /dev/null
+From 6e9d0828c3959b0900a08598b4df3c92da82ebf7 Mon Sep 17 00:00:00 2001
+From: Emil Renner Berthing <kernel@esmil.dk>
+Date: Sat, 1 Apr 2023 19:19:33 +0800
+Subject: [PATCH 26/95] riscv: dts: starfive: Add StarFive JH7110 VisionFive 2
+ board device tree
+
+Add a minimal device tree for StarFive JH7110 VisionFive 2 board
+which has version A and version B. Support booting and basic
+clock/reset/pinctrl/uart drivers.
+
+Tested-by: Tommaso Merciai <tomm.merciai@gmail.com>
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+Acked-by: Conor Dooley <conor.dooley@microchip.com>
+Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
+Co-developed-by: Jianlong Huang <jianlong.huang@starfivetech.com>
+Signed-off-by: Jianlong Huang <jianlong.huang@starfivetech.com>
+Co-developed-by: Hal Feng <hal.feng@starfivetech.com>
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ arch/riscv/boot/dts/starfive/Makefile | 6 +-
+ .../jh7110-starfive-visionfive-2-v1.2a.dts | 13 ++
+ .../jh7110-starfive-visionfive-2-v1.3b.dts | 13 ++
+ .../jh7110-starfive-visionfive-2.dtsi | 215 ++++++++++++++++++
+ 4 files changed, 246 insertions(+), 1 deletion(-)
+ create mode 100644 arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-v1.2a.dts
+ create mode 100644 arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-v1.3b.dts
+ create mode 100644 arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
+
+diff --git a/arch/riscv/boot/dts/starfive/Makefile b/arch/riscv/boot/dts/starfive/Makefile
+index 039c143cba33..cd73519b907b 100644
+--- a/arch/riscv/boot/dts/starfive/Makefile
++++ b/arch/riscv/boot/dts/starfive/Makefile
+@@ -1,2 +1,6 @@
+ # SPDX-License-Identifier: GPL-2.0
+-dtb-$(CONFIG_SOC_STARFIVE) += jh7100-beaglev-starlight.dtb jh7100-starfive-visionfive-v1.dtb
++dtb-$(CONFIG_SOC_STARFIVE) += jh7100-beaglev-starlight.dtb
++dtb-$(CONFIG_SOC_STARFIVE) += jh7100-starfive-visionfive-v1.dtb
++
++dtb-$(CONFIG_SOC_STARFIVE) += jh7110-starfive-visionfive-2-v1.2a.dtb
++dtb-$(CONFIG_SOC_STARFIVE) += jh7110-starfive-visionfive-2-v1.3b.dtb
+diff --git a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-v1.2a.dts b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-v1.2a.dts
+new file mode 100644
+index 000000000000..4af3300f3cf3
+--- /dev/null
++++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-v1.2a.dts
+@@ -0,0 +1,13 @@
++// SPDX-License-Identifier: GPL-2.0 OR MIT
++/*
++ * Copyright (C) 2022 StarFive Technology Co., Ltd.
++ * Copyright (C) 2022 Emil Renner Berthing <kernel@esmil.dk>
++ */
++
++/dts-v1/;
++#include "jh7110-starfive-visionfive-2.dtsi"
++
++/ {
++ model = "StarFive VisionFive 2 v1.2A";
++ compatible = "starfive,visionfive-2-v1.2a", "starfive,jh7110";
++};
+diff --git a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-v1.3b.dts b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-v1.3b.dts
+new file mode 100644
+index 000000000000..9230cc3d8946
+--- /dev/null
++++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-v1.3b.dts
+@@ -0,0 +1,13 @@
++// SPDX-License-Identifier: GPL-2.0 OR MIT
++/*
++ * Copyright (C) 2022 StarFive Technology Co., Ltd.
++ * Copyright (C) 2022 Emil Renner Berthing <kernel@esmil.dk>
++ */
++
++/dts-v1/;
++#include "jh7110-starfive-visionfive-2.dtsi"
++
++/ {
++ model = "StarFive VisionFive 2 v1.3B";
++ compatible = "starfive,visionfive-2-v1.3b", "starfive,jh7110";
++};
+diff --git a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
+new file mode 100644
+index 000000000000..2a6d81609284
+--- /dev/null
++++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
+@@ -0,0 +1,215 @@
++// SPDX-License-Identifier: GPL-2.0 OR MIT
++/*
++ * Copyright (C) 2022 StarFive Technology Co., Ltd.
++ * Copyright (C) 2022 Emil Renner Berthing <kernel@esmil.dk>
++ */
++
++/dts-v1/;
++#include "jh7110.dtsi"
++#include "jh7110-pinfunc.h"
++#include <dt-bindings/gpio/gpio.h>
++
++/ {
++ aliases {
++ i2c0 = &i2c0;
++ i2c2 = &i2c2;
++ i2c5 = &i2c5;
++ i2c6 = &i2c6;
++ serial0 = &uart0;
++ };
++
++ chosen {
++ stdout-path = "serial0:115200n8";
++ };
++
++ cpus {
++ timebase-frequency = <4000000>;
++ };
++
++ memory@40000000 {
++ device_type = "memory";
++ reg = <0x0 0x40000000 0x1 0x0>;
++ };
++
++ gpio-restart {
++ compatible = "gpio-restart";
++ gpios = <&sysgpio 35 GPIO_ACTIVE_HIGH>;
++ priority = <224>;
++ };
++};
++
++&gmac0_rgmii_rxin {
++ clock-frequency = <125000000>;
++};
++
++&gmac0_rmii_refin {
++ clock-frequency = <50000000>;
++};
++
++&gmac1_rgmii_rxin {
++ clock-frequency = <125000000>;
++};
++
++&gmac1_rmii_refin {
++ clock-frequency = <50000000>;
++};
++
++&i2srx_bclk_ext {
++ clock-frequency = <12288000>;
++};
++
++&i2srx_lrck_ext {
++ clock-frequency = <192000>;
++};
++
++&i2stx_bclk_ext {
++ clock-frequency = <12288000>;
++};
++
++&i2stx_lrck_ext {
++ clock-frequency = <192000>;
++};
++
++&mclk_ext {
++ clock-frequency = <12288000>;
++};
++
++&osc {
++ clock-frequency = <24000000>;
++};
++
++&rtc_osc {
++ clock-frequency = <32768>;
++};
++
++&tdm_ext {
++ clock-frequency = <49152000>;
++};
++
++&i2c0 {
++ clock-frequency = <100000>;
++ i2c-sda-hold-time-ns = <300>;
++ i2c-sda-falling-time-ns = <510>;
++ i2c-scl-falling-time-ns = <510>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&i2c0_pins>;
++ status = "okay";
++};
++
++&i2c2 {
++ clock-frequency = <100000>;
++ i2c-sda-hold-time-ns = <300>;
++ i2c-sda-falling-time-ns = <510>;
++ i2c-scl-falling-time-ns = <510>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&i2c2_pins>;
++ status = "okay";
++};
++
++&i2c5 {
++ clock-frequency = <100000>;
++ i2c-sda-hold-time-ns = <300>;
++ i2c-sda-falling-time-ns = <510>;
++ i2c-scl-falling-time-ns = <510>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&i2c5_pins>;
++ status = "okay";
++};
++
++&i2c6 {
++ clock-frequency = <100000>;
++ i2c-sda-hold-time-ns = <300>;
++ i2c-sda-falling-time-ns = <510>;
++ i2c-scl-falling-time-ns = <510>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&i2c6_pins>;
++ status = "okay";
++};
++
++&sysgpio {
++ i2c0_pins: i2c0-0 {
++ i2c-pins {
++ pinmux = <GPIOMUX(57, GPOUT_LOW,
++ GPOEN_SYS_I2C0_CLK,
++ GPI_SYS_I2C0_CLK)>,
++ <GPIOMUX(58, GPOUT_LOW,
++ GPOEN_SYS_I2C0_DATA,
++ GPI_SYS_I2C0_DATA)>;
++ bias-disable; /* external pull-up */
++ input-enable;
++ input-schmitt-enable;
++ };
++ };
++
++ i2c2_pins: i2c2-0 {
++ i2c-pins {
++ pinmux = <GPIOMUX(3, GPOUT_LOW,
++ GPOEN_SYS_I2C2_CLK,
++ GPI_SYS_I2C2_CLK)>,
++ <GPIOMUX(2, GPOUT_LOW,
++ GPOEN_SYS_I2C2_DATA,
++ GPI_SYS_I2C2_DATA)>;
++ bias-disable; /* external pull-up */
++ input-enable;
++ input-schmitt-enable;
++ };
++ };
++
++ i2c5_pins: i2c5-0 {
++ i2c-pins {
++ pinmux = <GPIOMUX(19, GPOUT_LOW,
++ GPOEN_SYS_I2C5_CLK,
++ GPI_SYS_I2C5_CLK)>,
++ <GPIOMUX(20, GPOUT_LOW,
++ GPOEN_SYS_I2C5_DATA,
++ GPI_SYS_I2C5_DATA)>;
++ bias-disable; /* external pull-up */
++ input-enable;
++ input-schmitt-enable;
++ };
++ };
++
++ i2c6_pins: i2c6-0 {
++ i2c-pins {
++ pinmux = <GPIOMUX(16, GPOUT_LOW,
++ GPOEN_SYS_I2C6_CLK,
++ GPI_SYS_I2C6_CLK)>,
++ <GPIOMUX(17, GPOUT_LOW,
++ GPOEN_SYS_I2C6_DATA,
++ GPI_SYS_I2C6_DATA)>;
++ bias-disable; /* external pull-up */
++ input-enable;
++ input-schmitt-enable;
++ };
++ };
++
++ uart0_pins: uart0-0 {
++ tx-pins {
++ pinmux = <GPIOMUX(5, GPOUT_SYS_UART0_TX,
++ GPOEN_ENABLE,
++ GPI_NONE)>;
++ bias-disable;
++ drive-strength = <12>;
++ input-disable;
++ input-schmitt-disable;
++ slew-rate = <0>;
++ };
++
++ rx-pins {
++ pinmux = <GPIOMUX(6, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_SYS_UART0_RX)>;
++ bias-disable; /* external pull-up */
++ drive-strength = <2>;
++ input-enable;
++ input-schmitt-enable;
++ slew-rate = <0>;
++ };
++ };
++};
++
++&uart0 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&uart0_pins>;
++ status = "okay";
++};
+--
+2.20.1
+
--- /dev/null
+From d2046085ffd6e77614dd77977809fa604842e1ad Mon Sep 17 00:00:00 2001
+From: Hal Feng <hal.feng@starfivetech.com>
+Date: Sat, 1 Apr 2023 19:19:34 +0800
+Subject: [PATCH 27/95] riscv: dts: starfive: jh7110: Correct the properties of
+ S7 core
+
+The S7 core has no L1 data cache and MMU, so delete some
+related properties.
+
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ arch/riscv/boot/dts/starfive/jh7110.dtsi | 9 ---------
+ 1 file changed, 9 deletions(-)
+
+diff --git a/arch/riscv/boot/dts/starfive/jh7110.dtsi b/arch/riscv/boot/dts/starfive/jh7110.dtsi
+index d484ecdf93f7..4c5fdb905da8 100644
+--- a/arch/riscv/boot/dts/starfive/jh7110.dtsi
++++ b/arch/riscv/boot/dts/starfive/jh7110.dtsi
+@@ -20,21 +20,12 @@
+ S7_0: cpu@0 {
+ compatible = "sifive,s7", "riscv";
+ reg = <0>;
+- d-cache-block-size = <64>;
+- d-cache-sets = <64>;
+- d-cache-size = <8192>;
+- d-tlb-sets = <1>;
+- d-tlb-size = <40>;
+ device_type = "cpu";
+ i-cache-block-size = <64>;
+ i-cache-sets = <64>;
+ i-cache-size = <16384>;
+- i-tlb-sets = <1>;
+- i-tlb-size = <40>;
+- mmu-type = "riscv,sv39";
+ next-level-cache = <&ccache>;
+ riscv,isa = "rv64imac_zba_zbb";
+- tlb-split;
+ status = "disabled";
+
+ cpu0_intc: interrupt-controller {
+--
+2.20.1
+
--- /dev/null
+From 7b1a5c1db1775af5c917937a05ca5e574843d064 Mon Sep 17 00:00:00 2001
+From: Walker Chen <walker.chen@starfivetech.com>
+Date: Thu, 19 Jan 2023 17:44:46 +0800
+Subject: [PATCH 28/95] dt-bindings: power: Add starfive,jh7110-pmu
+
+Add bindings for the Power Management Unit on the StarFive JH7110 SoC.
+
+Signed-off-by: Walker Chen <walker.chen@starfivetech.com>
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+Reviewed-by: Heiko Stuebner <heiko@sntech.de>
+---
+ .../bindings/power/starfive,jh7110-pmu.yaml | 45 +++++++++++++++++++
+ .../dt-bindings/power/starfive,jh7110-pmu.h | 17 +++++++
+ 2 files changed, 62 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/power/starfive,jh7110-pmu.yaml
+ create mode 100644 include/dt-bindings/power/starfive,jh7110-pmu.h
+
+diff --git a/Documentation/devicetree/bindings/power/starfive,jh7110-pmu.yaml b/Documentation/devicetree/bindings/power/starfive,jh7110-pmu.yaml
+new file mode 100644
+index 000000000000..98eb8b4110e7
+--- /dev/null
++++ b/Documentation/devicetree/bindings/power/starfive,jh7110-pmu.yaml
+@@ -0,0 +1,45 @@
++# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/power/starfive,jh7110-pmu.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: StarFive JH7110 Power Management Unit
++
++maintainers:
++ - Walker Chen <walker.chen@starfivetech.com>
++
++description: |
++ StarFive JH7110 SoC includes support for multiple power domains which can be
++ powered on/off by software based on different application scenes to save power.
++
++properties:
++ compatible:
++ enum:
++ - starfive,jh7110-pmu
++
++ reg:
++ maxItems: 1
++
++ interrupts:
++ maxItems: 1
++
++ "#power-domain-cells":
++ const: 1
++
++required:
++ - compatible
++ - reg
++ - interrupts
++ - "#power-domain-cells"
++
++additionalProperties: false
++
++examples:
++ - |
++ pwrc: power-controller@17030000 {
++ compatible = "starfive,jh7110-pmu";
++ reg = <0x17030000 0x10000>;
++ interrupts = <111>;
++ #power-domain-cells = <1>;
++ };
+diff --git a/include/dt-bindings/power/starfive,jh7110-pmu.h b/include/dt-bindings/power/starfive,jh7110-pmu.h
+new file mode 100644
+index 000000000000..132bfe401fc8
+--- /dev/null
++++ b/include/dt-bindings/power/starfive,jh7110-pmu.h
+@@ -0,0 +1,17 @@
++/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
++/*
++ * Copyright (C) 2022 StarFive Technology Co., Ltd.
++ * Author: Walker Chen <walker.chen@starfivetech.com>
++ */
++#ifndef __DT_BINDINGS_POWER_JH7110_POWER_H__
++#define __DT_BINDINGS_POWER_JH7110_POWER_H__
++
++#define JH7110_PD_SYSTOP 0
++#define JH7110_PD_CPU 1
++#define JH7110_PD_GPUA 2
++#define JH7110_PD_VDEC 3
++#define JH7110_PD_VOUT 4
++#define JH7110_PD_ISP 5
++#define JH7110_PD_VENC 6
++
++#endif
+--
+2.20.1
+
--- /dev/null
+From 68c935bd365f8985600c07a8d4deca476942acf0 Mon Sep 17 00:00:00 2001
+From: Walker Chen <walker.chen@starfivetech.com>
+Date: Thu, 19 Jan 2023 17:44:47 +0800
+Subject: [PATCH 29/95] soc: starfive: Add StarFive JH71XX pmu driver
+
+Add pmu driver for the StarFive JH71XX SoC.
+
+As the power domains provider, the Power Management Unit (PMU) is
+designed for including multiple PM domains that can be used for power
+gating of selected IP blocks for power saving by reduced leakage
+current. It accepts software encourage command to switch the power mode
+of SoC.
+
+Signed-off-by: Walker Chen <walker.chen@starfivetech.com>
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+Reviewed-by: Heiko Stuebner <heiko@sntech.de>
+---
+ drivers/soc/Kconfig | 1 +
+ drivers/soc/Makefile | 1 +
+ drivers/soc/starfive/Kconfig | 12 +
+ drivers/soc/starfive/Makefile | 3 +
+ drivers/soc/starfive/jh71xx_pmu.c | 383 ++++++++++++++++++++++++++++++
+ 5 files changed, 400 insertions(+)
+ create mode 100644 drivers/soc/starfive/Kconfig
+ create mode 100644 drivers/soc/starfive/Makefile
+ create mode 100644 drivers/soc/starfive/jh71xx_pmu.c
+
+diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig
+index e461c071189b..628fda4d5ed9 100644
+--- a/drivers/soc/Kconfig
++++ b/drivers/soc/Kconfig
+@@ -21,6 +21,7 @@ source "drivers/soc/renesas/Kconfig"
+ source "drivers/soc/rockchip/Kconfig"
+ source "drivers/soc/samsung/Kconfig"
+ source "drivers/soc/sifive/Kconfig"
++source "drivers/soc/starfive/Kconfig"
+ source "drivers/soc/sunxi/Kconfig"
+ source "drivers/soc/tegra/Kconfig"
+ source "drivers/soc/ti/Kconfig"
+diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile
+index 69ba6508cf2c..464ef482c016 100644
+--- a/drivers/soc/Makefile
++++ b/drivers/soc/Makefile
+@@ -27,6 +27,7 @@ obj-y += renesas/
+ obj-y += rockchip/
+ obj-$(CONFIG_SOC_SAMSUNG) += samsung/
+ obj-$(CONFIG_SOC_SIFIVE) += sifive/
++obj-$(CONFIG_SOC_STARFIVE) += starfive/
+ obj-y += sunxi/
+ obj-$(CONFIG_ARCH_TEGRA) += tegra/
+ obj-y += ti/
+diff --git a/drivers/soc/starfive/Kconfig b/drivers/soc/starfive/Kconfig
+new file mode 100644
+index 000000000000..bdb96dc4c989
+--- /dev/null
++++ b/drivers/soc/starfive/Kconfig
+@@ -0,0 +1,12 @@
++# SPDX-License-Identifier: GPL-2.0
++
++config JH71XX_PMU
++ bool "Support PMU for StarFive JH71XX Soc"
++ depends on PM
++ depends on SOC_STARFIVE || COMPILE_TEST
++ default SOC_STARFIVE
++ select PM_GENERIC_DOMAINS
++ help
++ Say 'y' here to enable support power domain support.
++ In order to meet low power requirements, a Power Management Unit (PMU)
++ is designed for controlling power resources in StarFive JH71XX SoCs.
+diff --git a/drivers/soc/starfive/Makefile b/drivers/soc/starfive/Makefile
+new file mode 100644
+index 000000000000..13b589d6b5f3
+--- /dev/null
++++ b/drivers/soc/starfive/Makefile
+@@ -0,0 +1,3 @@
++# SPDX-License-Identifier: GPL-2.0
++
++obj-$(CONFIG_JH71XX_PMU) += jh71xx_pmu.o
+diff --git a/drivers/soc/starfive/jh71xx_pmu.c b/drivers/soc/starfive/jh71xx_pmu.c
+new file mode 100644
+index 000000000000..7d5f50d71c0d
+--- /dev/null
++++ b/drivers/soc/starfive/jh71xx_pmu.c
+@@ -0,0 +1,383 @@
++// SPDX-License-Identifier: GPL-2.0-or-later
++/*
++ * StarFive JH71XX PMU (Power Management Unit) Controller Driver
++ *
++ * Copyright (C) 2022 StarFive Technology Co., Ltd.
++ */
++
++#include <linux/interrupt.h>
++#include <linux/io.h>
++#include <linux/iopoll.h>
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/of_device.h>
++#include <linux/platform_device.h>
++#include <linux/pm_domain.h>
++#include <dt-bindings/power/starfive,jh7110-pmu.h>
++
++/* register offset */
++#define JH71XX_PMU_SW_TURN_ON_POWER 0x0C
++#define JH71XX_PMU_SW_TURN_OFF_POWER 0x10
++#define JH71XX_PMU_SW_ENCOURAGE 0x44
++#define JH71XX_PMU_TIMER_INT_MASK 0x48
++#define JH71XX_PMU_CURR_POWER_MODE 0x80
++#define JH71XX_PMU_EVENT_STATUS 0x88
++#define JH71XX_PMU_INT_STATUS 0x8C
++
++/* sw encourage cfg */
++#define JH71XX_PMU_SW_ENCOURAGE_EN_LO 0x05
++#define JH71XX_PMU_SW_ENCOURAGE_EN_HI 0x50
++#define JH71XX_PMU_SW_ENCOURAGE_DIS_LO 0x0A
++#define JH71XX_PMU_SW_ENCOURAGE_DIS_HI 0xA0
++#define JH71XX_PMU_SW_ENCOURAGE_ON 0xFF
++
++/* pmu int status */
++#define JH71XX_PMU_INT_SEQ_DONE BIT(0)
++#define JH71XX_PMU_INT_HW_REQ BIT(1)
++#define JH71XX_PMU_INT_SW_FAIL GENMASK(3, 2)
++#define JH71XX_PMU_INT_HW_FAIL GENMASK(5, 4)
++#define JH71XX_PMU_INT_PCH_FAIL GENMASK(8, 6)
++#define JH71XX_PMU_INT_ALL_MASK GENMASK(8, 0)
++
++/*
++ * The time required for switching power status is based on the time
++ * to turn on the largest domain's power, which is at microsecond level
++ */
++#define JH71XX_PMU_TIMEOUT_US 100
++
++struct jh71xx_domain_info {
++ const char * const name;
++ unsigned int flags;
++ u8 bit;
++};
++
++struct jh71xx_pmu_match_data {
++ const struct jh71xx_domain_info *domain_info;
++ int num_domains;
++};
++
++struct jh71xx_pmu {
++ struct device *dev;
++ const struct jh71xx_pmu_match_data *match_data;
++ void __iomem *base;
++ struct generic_pm_domain **genpd;
++ struct genpd_onecell_data genpd_data;
++ int irq;
++ spinlock_t lock; /* protects pmu reg */
++};
++
++struct jh71xx_pmu_dev {
++ const struct jh71xx_domain_info *domain_info;
++ struct jh71xx_pmu *pmu;
++ struct generic_pm_domain genpd;
++};
++
++static int jh71xx_pmu_get_state(struct jh71xx_pmu_dev *pmd, u32 mask, bool *is_on)
++{
++ struct jh71xx_pmu *pmu = pmd->pmu;
++
++ if (!mask)
++ return -EINVAL;
++
++ *is_on = readl(pmu->base + JH71XX_PMU_CURR_POWER_MODE) & mask;
++
++ return 0;
++}
++
++static int jh71xx_pmu_set_state(struct jh71xx_pmu_dev *pmd, u32 mask, bool on)
++{
++ struct jh71xx_pmu *pmu = pmd->pmu;
++ unsigned long flags;
++ u32 val;
++ u32 mode;
++ u32 encourage_lo;
++ u32 encourage_hi;
++ bool is_on;
++ int ret;
++
++ ret = jh71xx_pmu_get_state(pmd, mask, &is_on);
++ if (ret) {
++ dev_dbg(pmu->dev, "unable to get current state for %s\n",
++ pmd->genpd.name);
++ return ret;
++ }
++
++ if (is_on == on) {
++ dev_dbg(pmu->dev, "pm domain [%s] is already %sable status.\n",
++ pmd->genpd.name, on ? "en" : "dis");
++ return 0;
++ }
++
++ spin_lock_irqsave(&pmu->lock, flags);
++
++ /*
++ * The PMU accepts software encourage to switch power mode in the following 2 steps:
++ *
++ * 1.Configure the register SW_TURN_ON_POWER (offset 0x0c) by writing 1 to
++ * the bit corresponding to the power domain that will be turned on
++ * and writing 0 to the others.
++ * Likewise, configure the register SW_TURN_OFF_POWER (offset 0x10) by
++ * writing 1 to the bit corresponding to the power domain that will be
++ * turned off and writing 0 to the others.
++ */
++ if (on) {
++ mode = JH71XX_PMU_SW_TURN_ON_POWER;
++ encourage_lo = JH71XX_PMU_SW_ENCOURAGE_EN_LO;
++ encourage_hi = JH71XX_PMU_SW_ENCOURAGE_EN_HI;
++ } else {
++ mode = JH71XX_PMU_SW_TURN_OFF_POWER;
++ encourage_lo = JH71XX_PMU_SW_ENCOURAGE_DIS_LO;
++ encourage_hi = JH71XX_PMU_SW_ENCOURAGE_DIS_HI;
++ }
++
++ writel(mask, pmu->base + mode);
++
++ /*
++ * 2.Write SW encourage command sequence to the Software Encourage Reg (offset 0x44)
++ * First write SW_MODE_ENCOURAGE_ON to JH71XX_PMU_SW_ENCOURAGE. This will reset
++ * the state machine which parses the command sequence. This register must be
++ * written every time software wants to power on/off a domain.
++ * Then write the lower bits of the command sequence, followed by the upper
++ * bits. The sequence differs between powering on & off a domain.
++ */
++ writel(JH71XX_PMU_SW_ENCOURAGE_ON, pmu->base + JH71XX_PMU_SW_ENCOURAGE);
++ writel(encourage_lo, pmu->base + JH71XX_PMU_SW_ENCOURAGE);
++ writel(encourage_hi, pmu->base + JH71XX_PMU_SW_ENCOURAGE);
++
++ spin_unlock_irqrestore(&pmu->lock, flags);
++
++ /* Wait for the power domain bit to be enabled / disabled */
++ if (on) {
++ ret = readl_poll_timeout_atomic(pmu->base + JH71XX_PMU_CURR_POWER_MODE,
++ val, val & mask,
++ 1, JH71XX_PMU_TIMEOUT_US);
++ } else {
++ ret = readl_poll_timeout_atomic(pmu->base + JH71XX_PMU_CURR_POWER_MODE,
++ val, !(val & mask),
++ 1, JH71XX_PMU_TIMEOUT_US);
++ }
++
++ if (ret) {
++ dev_err(pmu->dev, "%s: failed to power %s\n",
++ pmd->genpd.name, on ? "on" : "off");
++ return -ETIMEDOUT;
++ }
++
++ return 0;
++}
++
++static int jh71xx_pmu_on(struct generic_pm_domain *genpd)
++{
++ struct jh71xx_pmu_dev *pmd = container_of(genpd,
++ struct jh71xx_pmu_dev, genpd);
++ u32 pwr_mask = BIT(pmd->domain_info->bit);
++
++ return jh71xx_pmu_set_state(pmd, pwr_mask, true);
++}
++
++static int jh71xx_pmu_off(struct generic_pm_domain *genpd)
++{
++ struct jh71xx_pmu_dev *pmd = container_of(genpd,
++ struct jh71xx_pmu_dev, genpd);
++ u32 pwr_mask = BIT(pmd->domain_info->bit);
++
++ return jh71xx_pmu_set_state(pmd, pwr_mask, false);
++}
++
++static void jh71xx_pmu_int_enable(struct jh71xx_pmu *pmu, u32 mask, bool enable)
++{
++ u32 val;
++ unsigned long flags;
++
++ spin_lock_irqsave(&pmu->lock, flags);
++ val = readl(pmu->base + JH71XX_PMU_TIMER_INT_MASK);
++
++ if (enable)
++ val &= ~mask;
++ else
++ val |= mask;
++
++ writel(val, pmu->base + JH71XX_PMU_TIMER_INT_MASK);
++ spin_unlock_irqrestore(&pmu->lock, flags);
++}
++
++static irqreturn_t jh71xx_pmu_interrupt(int irq, void *data)
++{
++ struct jh71xx_pmu *pmu = data;
++ u32 val;
++
++ val = readl(pmu->base + JH71XX_PMU_INT_STATUS);
++
++ if (val & JH71XX_PMU_INT_SEQ_DONE)
++ dev_dbg(pmu->dev, "sequence done.\n");
++ if (val & JH71XX_PMU_INT_HW_REQ)
++ dev_dbg(pmu->dev, "hardware encourage requestion.\n");
++ if (val & JH71XX_PMU_INT_SW_FAIL)
++ dev_err(pmu->dev, "software encourage fail.\n");
++ if (val & JH71XX_PMU_INT_HW_FAIL)
++ dev_err(pmu->dev, "hardware encourage fail.\n");
++ if (val & JH71XX_PMU_INT_PCH_FAIL)
++ dev_err(pmu->dev, "p-channel fail event.\n");
++
++ /* clear interrupts */
++ writel(val, pmu->base + JH71XX_PMU_INT_STATUS);
++ writel(val, pmu->base + JH71XX_PMU_EVENT_STATUS);
++
++ return IRQ_HANDLED;
++}
++
++static int jh71xx_pmu_init_domain(struct jh71xx_pmu *pmu, int index)
++{
++ struct jh71xx_pmu_dev *pmd;
++ u32 pwr_mask;
++ int ret;
++ bool is_on = false;
++
++ pmd = devm_kzalloc(pmu->dev, sizeof(*pmd), GFP_KERNEL);
++ if (!pmd)
++ return -ENOMEM;
++
++ pmd->domain_info = &pmu->match_data->domain_info[index];
++ pmd->pmu = pmu;
++ pwr_mask = BIT(pmd->domain_info->bit);
++
++ pmd->genpd.name = pmd->domain_info->name;
++ pmd->genpd.flags = pmd->domain_info->flags;
++
++ ret = jh71xx_pmu_get_state(pmd, pwr_mask, &is_on);
++ if (ret)
++ dev_warn(pmu->dev, "unable to get current state for %s\n",
++ pmd->genpd.name);
++
++ pmd->genpd.power_on = jh71xx_pmu_on;
++ pmd->genpd.power_off = jh71xx_pmu_off;
++ pm_genpd_init(&pmd->genpd, NULL, !is_on);
++
++ pmu->genpd_data.domains[index] = &pmd->genpd;
++
++ return 0;
++}
++
++static int jh71xx_pmu_probe(struct platform_device *pdev)
++{
++ struct device *dev = &pdev->dev;
++ struct device_node *np = dev->of_node;
++ const struct jh71xx_pmu_match_data *match_data;
++ struct jh71xx_pmu *pmu;
++ unsigned int i;
++ int ret;
++
++ pmu = devm_kzalloc(dev, sizeof(*pmu), GFP_KERNEL);
++ if (!pmu)
++ return -ENOMEM;
++
++ pmu->base = devm_platform_ioremap_resource(pdev, 0);
++ if (IS_ERR(pmu->base))
++ return PTR_ERR(pmu->base);
++
++ pmu->irq = platform_get_irq(pdev, 0);
++ if (pmu->irq < 0)
++ return pmu->irq;
++
++ ret = devm_request_irq(dev, pmu->irq, jh71xx_pmu_interrupt,
++ 0, pdev->name, pmu);
++ if (ret)
++ dev_err(dev, "failed to request irq\n");
++
++ match_data = of_device_get_match_data(dev);
++ if (!match_data)
++ return -EINVAL;
++
++ pmu->genpd = devm_kcalloc(dev, match_data->num_domains,
++ sizeof(struct generic_pm_domain *),
++ GFP_KERNEL);
++ if (!pmu->genpd)
++ return -ENOMEM;
++
++ pmu->dev = dev;
++ pmu->match_data = match_data;
++ pmu->genpd_data.domains = pmu->genpd;
++ pmu->genpd_data.num_domains = match_data->num_domains;
++
++ for (i = 0; i < match_data->num_domains; i++) {
++ ret = jh71xx_pmu_init_domain(pmu, i);
++ if (ret) {
++ dev_err(dev, "failed to initialize power domain\n");
++ return ret;
++ }
++ }
++
++ spin_lock_init(&pmu->lock);
++ jh71xx_pmu_int_enable(pmu, JH71XX_PMU_INT_ALL_MASK & ~JH71XX_PMU_INT_PCH_FAIL, true);
++
++ ret = of_genpd_add_provider_onecell(np, &pmu->genpd_data);
++ if (ret) {
++ dev_err(dev, "failed to register genpd driver: %d\n", ret);
++ return ret;
++ }
++
++ dev_dbg(dev, "registered %u power domains\n", i);
++
++ return 0;
++}
++
++static const struct jh71xx_domain_info jh7110_power_domains[] = {
++ [JH7110_PD_SYSTOP] = {
++ .name = "SYSTOP",
++ .bit = 0,
++ .flags = GENPD_FLAG_ALWAYS_ON,
++ },
++ [JH7110_PD_CPU] = {
++ .name = "CPU",
++ .bit = 1,
++ .flags = GENPD_FLAG_ALWAYS_ON,
++ },
++ [JH7110_PD_GPUA] = {
++ .name = "GPUA",
++ .bit = 2,
++ },
++ [JH7110_PD_VDEC] = {
++ .name = "VDEC",
++ .bit = 3,
++ },
++ [JH7110_PD_VOUT] = {
++ .name = "VOUT",
++ .bit = 4,
++ },
++ [JH7110_PD_ISP] = {
++ .name = "ISP",
++ .bit = 5,
++ },
++ [JH7110_PD_VENC] = {
++ .name = "VENC",
++ .bit = 6,
++ },
++};
++
++static const struct jh71xx_pmu_match_data jh7110_pmu = {
++ .num_domains = ARRAY_SIZE(jh7110_power_domains),
++ .domain_info = jh7110_power_domains,
++};
++
++static const struct of_device_id jh71xx_pmu_of_match[] = {
++ {
++ .compatible = "starfive,jh7110-pmu",
++ .data = (void *)&jh7110_pmu,
++ }, {
++ /* sentinel */
++ }
++};
++
++static struct platform_driver jh71xx_pmu_driver = {
++ .probe = jh71xx_pmu_probe,
++ .driver = {
++ .name = "jh71xx-pmu",
++ .of_match_table = jh71xx_pmu_of_match,
++ .suppress_bind_attrs = true,
++ },
++};
++builtin_platform_driver(jh71xx_pmu_driver);
++
++MODULE_AUTHOR("Walker Chen <walker.chen@starfivetech.com>");
++MODULE_DESCRIPTION("StarFive JH71XX PMU Driver");
++MODULE_LICENSE("GPL");
+--
+2.20.1
+
--- /dev/null
+From 4cb9754f2e13003873e40c109e6700619caee7af Mon Sep 17 00:00:00 2001
+From: William Qiu <william.qiu@starfivetech.com>
+Date: Fri, 3 Feb 2023 16:19:11 +0800
+Subject: [PATCH 30/95] dt-bindings: mmc: Add StarFive MMC module
+
+Add documentation to describe StarFive designware mobile storage
+host controller driver.
+
+Signed-off-by: William Qiu <william.qiu@starfivetech.com>
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+---
+ .../bindings/mmc/starfive,jh7110-mmc.yaml | 77 +++++++++++++++++++
+ 1 file changed, 77 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/mmc/starfive,jh7110-mmc.yaml
+
+diff --git a/Documentation/devicetree/bindings/mmc/starfive,jh7110-mmc.yaml b/Documentation/devicetree/bindings/mmc/starfive,jh7110-mmc.yaml
+new file mode 100644
+index 000000000000..deacf8e9cfb2
+--- /dev/null
++++ b/Documentation/devicetree/bindings/mmc/starfive,jh7110-mmc.yaml
+@@ -0,0 +1,77 @@
++# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/mmc/starfive,jh7110-mmc.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: StarFive Designware Mobile Storage Host Controller
++
++description:
++ StarFive uses the Synopsys designware mobile storage host controller
++ to interface a SoC with storage medium such as eMMC or SD/MMC cards.
++
++allOf:
++ - $ref: synopsys-dw-mshc-common.yaml#
++
++maintainers:
++ - William Qiu <william.qiu@starfivetech.com>
++
++properties:
++ compatible:
++ const: starfive,jh7110-mmc
++
++ reg:
++ maxItems: 1
++
++ clocks:
++ items:
++ - description: biu clock
++ - description: ciu clock
++
++ clock-names:
++ items:
++ - const: biu
++ - const: ciu
++
++ interrupts:
++ maxItems: 1
++
++ starfive,sysreg:
++ $ref: /schemas/types.yaml#/definitions/phandle-array
++ items:
++ - items:
++ - description: phandle to System Register Controller syscon node
++ - description: offset of SYS_SYSCONSAIF__SYSCFG register for MMC controller
++ - description: shift of SYS_SYSCONSAIF__SYSCFG register for MMC controller
++ - description: mask of SYS_SYSCONSAIF__SYSCFG register for MMC controller
++ description:
++ Should be four parameters, the phandle to System Register Controller
++ syscon node and the offset/shift/mask of SYS_SYSCONSAIF__SYSCFG register
++ for MMC controller.
++
++required:
++ - compatible
++ - reg
++ - clocks
++ - clock-names
++ - interrupts
++ - starfive,sysreg
++
++unevaluatedProperties: false
++
++examples:
++ - |
++ mmc@16010000 {
++ compatible = "starfive,jh7110-mmc";
++ reg = <0x16010000 0x10000>;
++ clocks = <&syscrg 91>,
++ <&syscrg 93>;
++ clock-names = "biu","ciu";
++ resets = <&syscrg 64>;
++ reset-names = "reset";
++ interrupts = <74>;
++ fifo-depth = <32>;
++ fifo-watermark-aligned;
++ data-addr = <0>;
++ starfive,sysreg = <&sysreg 0x14 0x1a 0x7c000000>;
++ };
+--
+2.20.1
+
--- /dev/null
+From f482010825813e19023f0a231616c78521aef834 Mon Sep 17 00:00:00 2001
+From: William Qiu <william.qiu@starfivetech.com>
+Date: Fri, 3 Feb 2023 16:19:12 +0800
+Subject: [PATCH 31/95] mmc: starfive: Add sdio/emmc driver support
+
+Add sdio/emmc driver support for StarFive JH7110 soc.
+
+Tested-by: Conor Dooley <conor.dooley@microchip.com>
+Signed-off-by: William Qiu <william.qiu@starfivetech.com>
+---
+ drivers/mmc/host/Kconfig | 10 ++
+ drivers/mmc/host/Makefile | 1 +
+ drivers/mmc/host/dw_mmc-starfive.c | 185 +++++++++++++++++++++++++++++
+ 3 files changed, 196 insertions(+)
+ create mode 100644 drivers/mmc/host/dw_mmc-starfive.c
+
+diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
+index fb1062a6394c..b87262503403 100644
+--- a/drivers/mmc/host/Kconfig
++++ b/drivers/mmc/host/Kconfig
+@@ -871,6 +871,16 @@ config MMC_DW_ROCKCHIP
+ Synopsys DesignWare Memory Card Interface driver. Select this option
+ for platforms based on RK3066, RK3188 and RK3288 SoC's.
+
++config MMC_DW_STARFIVE
++ tristate "StarFive specific extensions for Synopsys DW Memory Card Interface"
++ depends on SOC_STARFIVE
++ depends on MMC_DW
++ select MMC_DW_PLTFM
++ help
++ This selects support for StarFive JH7110 SoC specific extensions to the
++ Synopsys DesignWare Memory Card Interface driver. Select this option
++ for platforms based on StarFive JH7110 SoC.
++
+ config MMC_SH_MMCIF
+ tristate "SuperH Internal MMCIF support"
+ depends on SUPERH || ARCH_RENESAS || COMPILE_TEST
+diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
+index 4e4ceb32c4b4..32c0e5564b9a 100644
+--- a/drivers/mmc/host/Makefile
++++ b/drivers/mmc/host/Makefile
+@@ -56,6 +56,7 @@ obj-$(CONFIG_MMC_DW_HI3798CV200) += dw_mmc-hi3798cv200.o
+ obj-$(CONFIG_MMC_DW_K3) += dw_mmc-k3.o
+ obj-$(CONFIG_MMC_DW_PCI) += dw_mmc-pci.o
+ obj-$(CONFIG_MMC_DW_ROCKCHIP) += dw_mmc-rockchip.o
++obj-$(CONFIG_MMC_DW_STARFIVE) += dw_mmc-starfive.o
+ obj-$(CONFIG_MMC_SH_MMCIF) += sh_mmcif.o
+ obj-$(CONFIG_MMC_JZ4740) += jz4740_mmc.o
+ obj-$(CONFIG_MMC_VUB300) += vub300.o
+diff --git a/drivers/mmc/host/dw_mmc-starfive.c b/drivers/mmc/host/dw_mmc-starfive.c
+new file mode 100644
+index 000000000000..e4d0bdb40d12
+--- /dev/null
++++ b/drivers/mmc/host/dw_mmc-starfive.c
+@@ -0,0 +1,185 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * StarFive Designware Mobile Storage Host Controller Driver
++ *
++ * Copyright (c) 2022 StarFive Technology Co., Ltd.
++ */
++
++#include <linux/clk.h>
++#include <linux/delay.h>
++#include <linux/mfd/syscon.h>
++#include <linux/mmc/host.h>
++#include <linux/module.h>
++#include <linux/of_address.h>
++#include <linux/platform_device.h>
++#include <linux/regmap.h>
++
++#include "dw_mmc.h"
++#include "dw_mmc-pltfm.h"
++
++#define ALL_INT_CLR 0x1ffff
++#define MAX_DELAY_CHAIN 32
++
++struct starfive_priv {
++ struct device *dev;
++ struct regmap *reg_syscon;
++ u32 syscon_offset;
++ u32 syscon_shift;
++ u32 syscon_mask;
++};
++
++static void dw_mci_starfive_set_ios(struct dw_mci *host, struct mmc_ios *ios)
++{
++ int ret;
++ unsigned int clock;
++
++ if (ios->timing == MMC_TIMING_MMC_DDR52 || ios->timing == MMC_TIMING_UHS_DDR50) {
++ clock = (ios->clock > 50000000 && ios->clock <= 52000000) ? 100000000 : ios->clock;
++ ret = clk_set_rate(host->ciu_clk, clock);
++ if (ret)
++ dev_dbg(host->dev, "Use an external frequency divider %uHz\n", ios->clock);
++ host->bus_hz = clk_get_rate(host->ciu_clk);
++ } else {
++ dev_dbg(host->dev, "Using the internal divider\n");
++ }
++}
++
++static int dw_mci_starfive_execute_tuning(struct dw_mci_slot *slot,
++ u32 opcode)
++{
++ static const int grade = MAX_DELAY_CHAIN;
++ struct dw_mci *host = slot->host;
++ struct starfive_priv *priv = host->priv;
++ int rise_point = -1, fall_point = -1;
++ int err, prev_err;
++ int i;
++ bool found = 0;
++ u32 regval;
++
++ /* Use grade as the max delay chain, and use the rise_point and
++ * fall_point to ensure the best sampling point of a data input
++ * signals.
++ */
++ for (i = 0; i < grade; i++) {
++ regval = i << priv->syscon_shift;
++ err = regmap_update_bits(priv->reg_syscon, priv->syscon_offset,
++ priv->syscon_mask, regval);
++ if (err)
++ return err;
++ mci_writel(host, RINTSTS, ALL_INT_CLR);
++
++ err = mmc_send_tuning(slot->mmc, opcode, NULL);
++ if (!err)
++ found = 1;
++
++ if (i > 0) {
++ if (err && !prev_err)
++ fall_point = i - 1;
++ if (!err && prev_err)
++ rise_point = i;
++ }
++
++ if (rise_point != -1 && fall_point != -1)
++ goto tuning_out;
++
++ prev_err = err;
++ err = 0;
++ }
++
++tuning_out:
++ if (found) {
++ if (rise_point == -1)
++ rise_point = 0;
++ if (fall_point == -1)
++ fall_point = grade - 1;
++ if (fall_point < rise_point) {
++ if ((rise_point + fall_point) >
++ (grade - 1))
++ i = fall_point / 2;
++ else
++ i = (rise_point + grade - 1) / 2;
++ } else {
++ i = (rise_point + fall_point) / 2;
++ }
++
++ regval = i << priv->syscon_shift;
++ err = regmap_update_bits(priv->reg_syscon, priv->syscon_offset,
++ priv->syscon_mask, regval);
++ if (err)
++ return err;
++ mci_writel(host, RINTSTS, ALL_INT_CLR);
++
++ dev_info(host->dev, "Found valid delay chain! use it [delay=%d]\n", i);
++ } else {
++ dev_err(host->dev, "No valid delay chain! use default\n");
++ err = -EINVAL;
++ }
++
++ mci_writel(host, RINTSTS, ALL_INT_CLR);
++ return err;
++}
++
++static int dw_mci_starfive_parse_dt(struct dw_mci *host)
++{
++ struct of_phandle_args args;
++ struct starfive_priv *priv;
++ int ret;
++
++ priv = devm_kzalloc(host->dev, sizeof(*priv), GFP_KERNEL);
++ if (!priv)
++ return -ENOMEM;
++
++ ret = of_parse_phandle_with_fixed_args(host->dev->of_node,
++ "starfive,syscon", 3, 0, &args);
++ if (ret) {
++ dev_err(host->dev, "Failed to parse starfive,syscon\n");
++ return -EINVAL;
++ }
++
++ priv->reg_syscon = syscon_node_to_regmap(args.np);
++ of_node_put(args.np);
++ if (IS_ERR(priv->reg_syscon))
++ return PTR_ERR(priv->reg_syscon);
++
++ priv->syscon_offset = args.args[0];
++ priv->syscon_shift = args.args[1];
++ priv->syscon_mask = args.args[2];
++
++ host->priv = priv;
++
++ return 0;
++}
++
++static const struct dw_mci_drv_data starfive_data = {
++ .common_caps = MMC_CAP_CMD23,
++ .set_ios = dw_mci_starfive_set_ios,
++ .parse_dt = dw_mci_starfive_parse_dt,
++ .execute_tuning = dw_mci_starfive_execute_tuning,
++};
++
++static const struct of_device_id dw_mci_starfive_match[] = {
++ { .compatible = "starfive,jh7110-mmc",
++ .data = &starfive_data },
++ {},
++};
++MODULE_DEVICE_TABLE(of, dw_mci_starfive_match);
++
++static int dw_mci_starfive_probe(struct platform_device *pdev)
++{
++ return dw_mci_pltfm_register(pdev, &starfive_data);;
++}
++
++static struct platform_driver dw_mci_starfive_driver = {
++ .probe = dw_mci_starfive_probe,
++ .remove = dw_mci_pltfm_remove,
++ .driver = {
++ .name = "dwmmc_starfive",
++ .probe_type = PROBE_PREFER_ASYNCHRONOUS,
++ .of_match_table = dw_mci_starfive_match,
++ },
++};
++module_platform_driver(dw_mci_starfive_driver);
++
++MODULE_DESCRIPTION("StarFive JH7110 Specific DW-MSHC Driver Extension");
++MODULE_LICENSE("GPL");
++MODULE_ALIAS("platform:dwmmc_starfive");
+--
+2.20.1
+
--- /dev/null
+From 56e2aab94ecc9465b08f0e4a0e68a4c5cae3a462 Mon Sep 17 00:00:00 2001
+From: William Qiu <william.qiu@starfivetech.com>
+Date: Fri, 3 Feb 2023 16:19:13 +0800
+Subject: [PATCH 32/95] riscv: dts: starfive: Add mmc node
+
+This adds the mmc node for the StarFive JH7110 SoC.
+Set mmco node to emmc and set mmc1 node to sd.
+
+Signed-off-by: William Qiu <william.qiu@starfivetech.com>
+---
+ .../jh7110-starfive-visionfive-2.dtsi | 23 ++++++++++++
+ arch/riscv/boot/dts/starfive/jh7110.dtsi | 37 +++++++++++++++++++
+ 2 files changed, 60 insertions(+)
+
+diff --git a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
+index 2a6d81609284..a132debb9b53 100644
+--- a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
++++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
+@@ -42,6 +42,29 @@
+ clock-frequency = <125000000>;
+ };
+
++&mmc0 {
++ max-frequency = <100000000>;
++ bus-width = <8>;
++ cap-mmc-highspeed;
++ mmc-ddr-1_8v;
++ mmc-hs200-1_8v;
++ non-removable;
++ cap-mmc-hw-reset;
++ post-power-on-delay-ms = <200>;
++ status = "okay";
++};
++
++&mmc1 {
++ max-frequency = <100000000>;
++ bus-width = <4>;
++ no-sdio;
++ no-mmc;
++ broken-cd;
++ cap-sd-highspeed;
++ post-power-on-delay-ms = <200>;
++ status = "okay";
++};
++
+ &gmac0_rmii_refin {
+ clock-frequency = <50000000>;
+ };
+diff --git a/arch/riscv/boot/dts/starfive/jh7110.dtsi b/arch/riscv/boot/dts/starfive/jh7110.dtsi
+index 4c5fdb905da8..c1fdd0758abf 100644
+--- a/arch/riscv/boot/dts/starfive/jh7110.dtsi
++++ b/arch/riscv/boot/dts/starfive/jh7110.dtsi
+@@ -457,6 +457,11 @@
+ #reset-cells = <1>;
+ };
+
++ sysreg: syscon@13030000 {
++ compatible = "starfive,sysreg", "syscon";
++ reg = <0x0 0x13030000 0x0 0x1000>;
++ };
++
+ sysgpio: pinctrl@13040000 {
+ compatible = "starfive,jh7110-sys-pinctrl";
+ reg = <0x0 0x13040000 0x0 0x10000>;
+@@ -496,5 +501,37 @@
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
++
++ mmc0: mmc@16010000 {
++ compatible = "starfive,jh7110-mmc";
++ reg = <0x0 0x16010000 0x0 0x10000>;
++ clocks = <&syscrg JH7110_SYSCLK_SDIO0_AHB>,
++ <&syscrg JH7110_SYSCLK_SDIO0_SDCARD>;
++ clock-names = "biu","ciu";
++ resets = <&syscrg JH7110_SYSRST_SDIO0_AHB>;
++ reset-names = "reset";
++ interrupts = <74>;
++ fifo-depth = <32>;
++ fifo-watermark-aligned;
++ data-addr = <0>;
++ starfive,sysreg = <&sysreg 0x14 0x1a 0x7c000000>;
++ status = "disabled";
++ };
++
++ mmc1: mmc@16020000 {
++ compatible = "starfive,jh7110-mmc";
++ reg = <0x0 0x16020000 0x0 0x10000>;
++ clocks = <&syscrg JH7110_SYSCLK_SDIO1_AHB>,
++ <&syscrg JH7110_SYSCLK_SDIO1_SDCARD>;
++ clock-names = "biu","ciu";
++ resets = <&syscrg JH7110_SYSRST_SDIO1_AHB>;
++ reset-names = "reset";
++ interrupts = <75>;
++ fifo-depth = <32>;
++ fifo-watermark-aligned;
++ data-addr = <0>;
++ starfive,sysreg = <&sysreg 0x9c 0x1 0x3e>;
++ status = "disabled";
++ };
+ };
+ };
+--
+2.20.1
+
--- /dev/null
+From 079f4ac96f7839ca22d1d8724fd4c1b1acac94d6 Mon Sep 17 00:00:00 2001
+From: Emil Renner Berthing <kernel@esmil.dk>
+Date: Mon, 17 Apr 2023 18:02:46 +0800
+Subject: [PATCH 43/95] dt-bindings: net: snps,dwmac: Add dwmac-5.20 version
+
+Add dwmac-5.20 IP version to snps.dwmac.yaml
+
+Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
+Signed-off-by: Samin Guo <samin.guo@starfivetech.com>
+---
+ Documentation/devicetree/bindings/net/snps,dwmac.yaml | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/Documentation/devicetree/bindings/net/snps,dwmac.yaml b/Documentation/devicetree/bindings/net/snps,dwmac.yaml
+index 13b984076af5..e26c3e76ebb7 100644
+--- a/Documentation/devicetree/bindings/net/snps,dwmac.yaml
++++ b/Documentation/devicetree/bindings/net/snps,dwmac.yaml
+@@ -30,6 +30,7 @@ select:
+ - snps,dwmac-4.10a
+ - snps,dwmac-4.20a
+ - snps,dwmac-5.10a
++ - snps,dwmac-5.20
+ - snps,dwxgmac
+ - snps,dwxgmac-2.10
+
+@@ -87,6 +88,7 @@ properties:
+ - snps,dwmac-4.10a
+ - snps,dwmac-4.20a
+ - snps,dwmac-5.10a
++ - snps,dwmac-5.20
+ - snps,dwxgmac
+ - snps,dwxgmac-2.10
+
+@@ -393,6 +395,7 @@ allOf:
+ - snps,dwmac-3.50a
+ - snps,dwmac-4.10a
+ - snps,dwmac-4.20a
++ - snps,dwmac-5.20
+ - snps,dwxgmac
+ - snps,dwxgmac-2.10
+ - st,spear600-gmac
+@@ -447,6 +450,7 @@ allOf:
+ - snps,dwmac-4.10a
+ - snps,dwmac-4.20a
+ - snps,dwmac-5.10a
++ - snps,dwmac-5.20
+ - snps,dwxgmac
+ - snps,dwxgmac-2.10
+ - st,spear600-gmac
+--
+2.20.1
+
--- /dev/null
+From 4feacd095226d91f4ca6c70a52b9c28a0ff19d81 Mon Sep 17 00:00:00 2001
+From: Emil Renner Berthing <kernel@esmil.dk>
+Date: Mon, 17 Apr 2023 18:02:47 +0800
+Subject: [PATCH 44/95] net: stmmac: platform: Add snps,dwmac-5.20 IP
+ compatible string
+
+Add "snps,dwmac-5.20" compatible string for 5.20 version that can avoid
+to define some platform data in the glue layer.
+
+Tested-by: Tommaso Merciai <tomm.merciai@gmail.com>
+Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
+Signed-off-by: Samin Guo <samin.guo@starfivetech.com>
+---
+ drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+index 0046a4ee6e64..807eca7edf53 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+@@ -519,7 +519,8 @@ stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac)
+ if (of_device_is_compatible(np, "snps,dwmac-4.00") ||
+ of_device_is_compatible(np, "snps,dwmac-4.10a") ||
+ of_device_is_compatible(np, "snps,dwmac-4.20a") ||
+- of_device_is_compatible(np, "snps,dwmac-5.10a")) {
++ of_device_is_compatible(np, "snps,dwmac-5.10a") ||
++ of_device_is_compatible(np, "snps,dwmac-5.20")) {
+ plat->has_gmac4 = 1;
+ plat->has_gmac = 0;
+ plat->pmt = 1;
+--
+2.20.1
+
--- /dev/null
+From b7ddcc414e98b6e7d51d991b456c87020c723bf2 Mon Sep 17 00:00:00 2001
+From: Samin Guo <samin.guo@starfivetech.com>
+Date: Mon, 17 Apr 2023 18:02:48 +0800
+Subject: [PATCH 45/95] dt-bindings: net: snps,dwmac: Add 'ahb'
+ reset/reset-name
+
+According to:
+stmmac_platform.c: stmmac_probe_config_dt
+stmmac_main.c: stmmac_dvr_probe
+
+dwmac controller may require one (stmmaceth) or two (stmmaceth+ahb)
+reset signals, and the maxItems of resets/reset-names is going to be 2.
+
+The gmac of Starfive Jh7110 SOC must have two resets.
+it uses snps,dwmac-5.20 IP.
+
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Samin Guo <samin.guo@starfivetech.com>
+---
+ .../devicetree/bindings/net/snps,dwmac.yaml | 12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+diff --git a/Documentation/devicetree/bindings/net/snps,dwmac.yaml b/Documentation/devicetree/bindings/net/snps,dwmac.yaml
+index e26c3e76ebb7..8fb8a0d24c08 100644
+--- a/Documentation/devicetree/bindings/net/snps,dwmac.yaml
++++ b/Documentation/devicetree/bindings/net/snps,dwmac.yaml
+@@ -133,12 +133,16 @@ properties:
+ - ptp_ref
+
+ resets:
+- maxItems: 1
+- description:
+- MAC Reset signal.
++ minItems: 1
++ items:
++ - description: GMAC stmmaceth reset
++ - description: AHB reset
+
+ reset-names:
+- const: stmmaceth
++ minItems: 1
++ items:
++ - const: stmmaceth
++ - const: ahb
+
+ power-domains:
+ maxItems: 1
+--
+2.20.1
+
--- /dev/null
+From adbeff7de0bffc67b352f6be78690b91d421bca6 Mon Sep 17 00:00:00 2001
+From: Yanhong Wang <yanhong.wang@starfivetech.com>
+Date: Mon, 17 Apr 2023 18:02:49 +0800
+Subject: [PATCH 46/95] dt-bindings: net: Add support StarFive dwmac
+
+Add documentation to describe StarFive dwmac driver(GMAC).
+
+Signed-off-by: Yanhong Wang <yanhong.wang@starfivetech.com>
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Samin Guo <samin.guo@starfivetech.com>
+---
+ .../devicetree/bindings/net/snps,dwmac.yaml | 1 +
+ .../bindings/net/starfive,jh7110-dwmac.yaml | 144 ++++++++++++++++++
+ 2 files changed, 145 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/net/starfive,jh7110-dwmac.yaml
+
+diff --git a/Documentation/devicetree/bindings/net/snps,dwmac.yaml b/Documentation/devicetree/bindings/net/snps,dwmac.yaml
+index 8fb8a0d24c08..0dcaee864a1c 100644
+--- a/Documentation/devicetree/bindings/net/snps,dwmac.yaml
++++ b/Documentation/devicetree/bindings/net/snps,dwmac.yaml
+@@ -91,6 +91,7 @@ properties:
+ - snps,dwmac-5.20
+ - snps,dwxgmac
+ - snps,dwxgmac-2.10
++ - starfive,jh7110-dwmac
+
+ reg:
+ minItems: 1
+diff --git a/Documentation/devicetree/bindings/net/starfive,jh7110-dwmac.yaml b/Documentation/devicetree/bindings/net/starfive,jh7110-dwmac.yaml
+new file mode 100644
+index 000000000000..5e7cfbbebce6
+--- /dev/null
++++ b/Documentation/devicetree/bindings/net/starfive,jh7110-dwmac.yaml
+@@ -0,0 +1,144 @@
++# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
++# Copyright (C) 2022 StarFive Technology Co., Ltd.
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/net/starfive,jh7110-dwmac.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: StarFive JH7110 DWMAC glue layer
++
++maintainers:
++ - Emil Renner Berthing <kernel@esmil.dk>
++ - Samin Guo <samin.guo@starfivetech.com>
++
++select:
++ properties:
++ compatible:
++ contains:
++ enum:
++ - starfive,jh7110-dwmac
++ required:
++ - compatible
++
++properties:
++ compatible:
++ items:
++ - enum:
++ - starfive,jh7110-dwmac
++ - const: snps,dwmac-5.20
++
++ reg:
++ maxItems: 1
++
++ clocks:
++ items:
++ - description: GMAC main clock
++ - description: GMAC AHB clock
++ - description: PTP clock
++ - description: TX clock
++ - description: GTX clock
++
++ clock-names:
++ items:
++ - const: stmmaceth
++ - const: pclk
++ - const: ptp_ref
++ - const: tx
++ - const: gtx
++
++ interrupts:
++ minItems: 3
++ maxItems: 3
++
++ interrupt-names:
++ minItems: 3
++ maxItems: 3
++
++ resets:
++ items:
++ - description: MAC Reset signal.
++ - description: AHB Reset signal.
++
++ reset-names:
++ items:
++ - const: stmmaceth
++ - const: ahb
++
++ starfive,tx-use-rgmii-clk:
++ description:
++ Tx clock is provided by external rgmii clock.
++ type: boolean
++
++ starfive,syscon:
++ $ref: /schemas/types.yaml#/definitions/phandle-array
++ items:
++ - items:
++ - description: phandle to syscon that configures phy mode
++ - description: Offset of phy mode selection
++ - description: Shift of phy mode selection
++ description:
++ A phandle to syscon with two arguments that configure phy mode.
++ The argument one is the offset of phy mode selection, the
++ argument two is the shift of phy mode selection.
++
++required:
++ - compatible
++ - reg
++ - clocks
++ - clock-names
++ - interrupts
++ - interrupt-names
++ - resets
++ - reset-names
++
++allOf:
++ - $ref: snps,dwmac.yaml#
++
++unevaluatedProperties: false
++
++examples:
++ - |
++ ethernet@16030000 {
++ compatible = "starfive,jh7110-dwmac", "snps,dwmac-5.20";
++ reg = <0x16030000 0x10000>;
++ clocks = <&clk 3>, <&clk 2>, <&clk 109>,
++ <&clk 6>, <&clk 111>;
++ clock-names = "stmmaceth", "pclk", "ptp_ref",
++ "tx", "gtx";
++ resets = <&rst 1>, <&rst 2>;
++ reset-names = "stmmaceth", "ahb";
++ interrupts = <7>, <6>, <5>;
++ interrupt-names = "macirq", "eth_wake_irq", "eth_lpi";
++ phy-mode = "rgmii-id";
++ snps,multicast-filter-bins = <64>;
++ snps,perfect-filter-entries = <8>;
++ rx-fifo-depth = <2048>;
++ tx-fifo-depth = <2048>;
++ snps,fixed-burst;
++ snps,no-pbl-x8;
++ snps,tso;
++ snps,force_thresh_dma_mode;
++ snps,axi-config = <&stmmac_axi_setup>;
++ snps,en-tx-lpi-clockgating;
++ snps,txpbl = <16>;
++ snps,rxpbl = <16>;
++ starfive,syscon = <&aon_syscon 0xc 0x12>;
++ phy-handle = <&phy0>;
++
++ mdio {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ compatible = "snps,dwmac-mdio";
++
++ phy0: ethernet-phy@0 {
++ reg = <0>;
++ };
++ };
++
++ stmmac_axi_setup: stmmac-axi-config {
++ snps,lpi_en;
++ snps,wr_osr_lmt = <4>;
++ snps,rd_osr_lmt = <4>;
++ snps,blen = <256 128 64 32 0 0 0>;
++ };
++ };
+--
+2.20.1
+
--- /dev/null
+From 20fa98c6230f05d5c70023828079858437cea919 Mon Sep 17 00:00:00 2001
+From: Samin Guo <samin.guo@starfivetech.com>
+Date: Mon, 17 Apr 2023 18:02:50 +0800
+Subject: [PATCH 47/95] net: stmmac: Add glue layer for StarFive JH7110 SoC
+
+This adds StarFive dwmac driver support on the StarFive JH7110 SoC.
+
+Tested-by: Tommaso Merciai <tomm.merciai@gmail.com>
+Co-developed-by: Emil Renner Berthing <kernel@esmil.dk>
+Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
+Signed-off-by: Samin Guo <samin.guo@starfivetech.com>
+---
+ drivers/net/ethernet/stmicro/stmmac/Kconfig | 12 ++
+ drivers/net/ethernet/stmicro/stmmac/Makefile | 1 +
+ .../ethernet/stmicro/stmmac/dwmac-starfive.c | 123 ++++++++++++++++++
+ 3 files changed, 136 insertions(+)
+ create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwmac-starfive.c
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/Kconfig b/drivers/net/ethernet/stmicro/stmmac/Kconfig
+index 31ff35174034..b5e95e6fc4a4 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/Kconfig
++++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig
+@@ -165,6 +165,18 @@ config DWMAC_SOCFPGA
+ for the stmmac device driver. This driver is used for
+ arria5 and cyclone5 FPGA SoCs.
+
++config DWMAC_STARFIVE
++ tristate "StarFive dwmac support"
++ depends on OF && (ARCH_STARFIVE || COMPILE_TEST)
++ select MFD_SYSCON
++ default m if ARCH_STARFIVE
++ help
++ Support for ethernet controllers on StarFive RISC-V SoCs
++
++ This selects the StarFive platform specific glue layer support for
++ the stmmac device driver. This driver is used for StarFive JH7110
++ ethernet controller.
++
+ config DWMAC_STI
+ tristate "STi GMAC support"
+ default ARCH_STI
+diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile b/drivers/net/ethernet/stmicro/stmmac/Makefile
+index d4e12e9ace4f..09e3c141c2a1 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/Makefile
++++ b/drivers/net/ethernet/stmicro/stmmac/Makefile
+@@ -23,6 +23,7 @@ obj-$(CONFIG_DWMAC_OXNAS) += dwmac-oxnas.o
+ obj-$(CONFIG_DWMAC_QCOM_ETHQOS) += dwmac-qcom-ethqos.o
+ obj-$(CONFIG_DWMAC_ROCKCHIP) += dwmac-rk.o
+ obj-$(CONFIG_DWMAC_SOCFPGA) += dwmac-altr-socfpga.o
++obj-$(CONFIG_DWMAC_STARFIVE) += dwmac-starfive.o
+ obj-$(CONFIG_DWMAC_STI) += dwmac-sti.o
+ obj-$(CONFIG_DWMAC_STM32) += dwmac-stm32.o
+ obj-$(CONFIG_DWMAC_SUNXI) += dwmac-sunxi.o
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-starfive.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-starfive.c
+new file mode 100644
+index 000000000000..4963d4008485
+--- /dev/null
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-starfive.c
+@@ -0,0 +1,123 @@
++// SPDX-License-Identifier: GPL-2.0+
++/*
++ * StarFive DWMAC platform driver
++ *
++ * Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
++ * Copyright (C) 2022 StarFive Technology Co., Ltd.
++ *
++ */
++
++#include <linux/mfd/syscon.h>
++#include <linux/of_device.h>
++#include <linux/regmap.h>
++
++#include "stmmac_platform.h"
++
++struct starfive_dwmac {
++ struct device *dev;
++ struct clk *clk_tx;
++};
++
++static void starfive_dwmac_fix_mac_speed(void *priv, unsigned int speed)
++{
++ struct starfive_dwmac *dwmac = priv;
++ unsigned long rate;
++ int err;
++
++ rate = clk_get_rate(dwmac->clk_tx);
++
++ switch (speed) {
++ case SPEED_1000:
++ rate = 125000000;
++ break;
++ case SPEED_100:
++ rate = 25000000;
++ break;
++ case SPEED_10:
++ rate = 2500000;
++ break;
++ default:
++ dev_err(dwmac->dev, "invalid speed %u\n", speed);
++ break;
++ }
++
++ err = clk_set_rate(dwmac->clk_tx, rate);
++ if (err)
++ dev_err(dwmac->dev, "failed to set tx rate %lu\n", rate);
++}
++
++static int starfive_dwmac_probe(struct platform_device *pdev)
++{
++ struct plat_stmmacenet_data *plat_dat;
++ struct stmmac_resources stmmac_res;
++ struct starfive_dwmac *dwmac;
++ struct clk *clk_gtx;
++ int err;
++
++ err = stmmac_get_platform_resources(pdev, &stmmac_res);
++ if (err)
++ return dev_err_probe(&pdev->dev, err,
++ "failed to get resources\n");
++
++ plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
++ if (IS_ERR(plat_dat))
++ return dev_err_probe(&pdev->dev, PTR_ERR(plat_dat),
++ "dt configuration failed\n");
++
++ dwmac = devm_kzalloc(&pdev->dev, sizeof(*dwmac), GFP_KERNEL);
++ if (!dwmac)
++ return -ENOMEM;
++
++ dwmac->clk_tx = devm_clk_get_enabled(&pdev->dev, "tx");
++ if (IS_ERR(dwmac->clk_tx))
++ return dev_err_probe(&pdev->dev, PTR_ERR(dwmac->clk_tx),
++ "error getting tx clock\n");
++
++ clk_gtx = devm_clk_get_enabled(&pdev->dev, "gtx");
++ if (IS_ERR(clk_gtx))
++ return dev_err_probe(&pdev->dev, PTR_ERR(clk_gtx),
++ "error getting gtx clock\n");
++
++ /* Generally, the rgmii_tx clock is provided by the internal clock,
++ * which needs to match the corresponding clock frequency according
++ * to different speeds. If the rgmii_tx clock is provided by the
++ * external rgmii_rxin, there is no need to configure the clock
++ * internally, because rgmii_rxin will be adaptively adjusted.
++ */
++ if (!device_property_read_bool(&pdev->dev, "starfive,tx-use-rgmii-clk"))
++ plat_dat->fix_mac_speed = starfive_dwmac_fix_mac_speed;
++
++ dwmac->dev = &pdev->dev;
++ plat_dat->bsp_priv = dwmac;
++ plat_dat->dma_cfg->dche = true;
++
++ err = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
++ if (err) {
++ stmmac_remove_config_dt(pdev, plat_dat);
++ return err;
++ }
++
++ return 0;
++}
++
++static const struct of_device_id starfive_dwmac_match[] = {
++ { .compatible = "starfive,jh7110-dwmac" },
++ { /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(of, starfive_dwmac_match);
++
++static struct platform_driver starfive_dwmac_driver = {
++ .probe = starfive_dwmac_probe,
++ .remove = stmmac_pltfr_remove,
++ .driver = {
++ .name = "starfive-dwmac",
++ .pm = &stmmac_pltfr_pm_ops,
++ .of_match_table = starfive_dwmac_match,
++ },
++};
++module_platform_driver(starfive_dwmac_driver);
++
++MODULE_LICENSE("GPL");
++MODULE_DESCRIPTION("StarFive DWMAC platform driver");
++MODULE_AUTHOR("Emil Renner Berthing <kernel@esmil.dk>");
++MODULE_AUTHOR("Samin Guo <samin.guo@starfivetech.com>");
+--
+2.20.1
+
--- /dev/null
+From 1f38e60596bc2eb0e681c7596d815f983bd5f4bf Mon Sep 17 00:00:00 2001
+From: Samin Guo <samin.guo@starfivetech.com>
+Date: Mon, 17 Apr 2023 18:02:51 +0800
+Subject: [PATCH 48/95] net: stmmac: dwmac-starfive: Add phy interface settings
+
+dwmac supports multiple modess. When working under rmii and rgmii,
+you need to set different phy interfaces.
+
+According to the dwmac document, when working in rmii, it needs to be
+set to 0x4, and rgmii needs to be set to 0x1.
+
+The phy interface needs to be set in syscon, the format is as follows:
+starfive,syscon: <&syscon, offset, shift>
+
+Tested-by: Tommaso Merciai <tomm.merciai@gmail.com>
+Signed-off-by: Samin Guo <samin.guo@starfivetech.com>
+---
+ .../ethernet/stmicro/stmmac/dwmac-starfive.c | 48 +++++++++++++++++++
+ 1 file changed, 48 insertions(+)
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-starfive.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-starfive.c
+index 4963d4008485..4f51a7889642 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-starfive.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-starfive.c
+@@ -13,6 +13,10 @@
+
+ #include "stmmac_platform.h"
+
++#define STARFIVE_DWMAC_PHY_INFT_RGMII 0x1
++#define STARFIVE_DWMAC_PHY_INFT_RMII 0x4
++#define STARFIVE_DWMAC_PHY_INFT_FIELD 0x7U
++
+ struct starfive_dwmac {
+ struct device *dev;
+ struct clk *clk_tx;
+@@ -46,6 +50,46 @@ static void starfive_dwmac_fix_mac_speed(void *priv, unsigned int speed)
+ dev_err(dwmac->dev, "failed to set tx rate %lu\n", rate);
+ }
+
++static int starfive_dwmac_set_mode(struct plat_stmmacenet_data *plat_dat)
++{
++ struct starfive_dwmac *dwmac = plat_dat->bsp_priv;
++ struct regmap *regmap;
++ unsigned int args[2];
++ unsigned int mode;
++ int err;
++
++ switch (plat_dat->interface) {
++ case PHY_INTERFACE_MODE_RMII:
++ mode = STARFIVE_DWMAC_PHY_INFT_RMII;
++ break;
++
++ case PHY_INTERFACE_MODE_RGMII:
++ case PHY_INTERFACE_MODE_RGMII_ID:
++ mode = STARFIVE_DWMAC_PHY_INFT_RGMII;
++ break;
++
++ default:
++ dev_err(dwmac->dev, "unsupported interface %d\n",
++ plat_dat->interface);
++ return -EINVAL;
++ }
++
++ regmap = syscon_regmap_lookup_by_phandle_args(dwmac->dev->of_node,
++ "starfive,syscon",
++ 2, args);
++ if (IS_ERR(regmap))
++ return dev_err_probe(dwmac->dev, PTR_ERR(regmap), "getting the regmap failed\n");
++
++ /* args[0]:offset args[1]: shift */
++ err = regmap_update_bits(regmap, args[0],
++ STARFIVE_DWMAC_PHY_INFT_FIELD << args[1],
++ mode << args[1]);
++ if (err)
++ return dev_err_probe(dwmac->dev, err, "error setting phy mode\n");
++
++ return 0;
++}
++
+ static int starfive_dwmac_probe(struct platform_device *pdev)
+ {
+ struct plat_stmmacenet_data *plat_dat;
+@@ -91,6 +135,10 @@ static int starfive_dwmac_probe(struct platform_device *pdev)
+ plat_dat->bsp_priv = dwmac;
+ plat_dat->dma_cfg->dche = true;
+
++ err = starfive_dwmac_set_mode(plat_dat);
++ if (err)
++ return err;
++
+ err = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
+ if (err) {
+ stmmac_remove_config_dt(pdev, plat_dat);
+--
+2.20.1
+
--- /dev/null
+From 098e06fbea88bca7ac1d71d031c5830c99169a15 Mon Sep 17 00:00:00 2001
+From: Xingyu Wu <xingyu.wu@starfivetech.com>
+Date: Tue, 14 Mar 2023 21:24:35 +0800
+Subject: [PATCH 49/95] dt-bindings: watchdog: Add watchdog for StarFive JH7100
+ and JH7110
+
+Add bindings to describe the watchdog for the StarFive JH7100/JH7110 SoC.
+And Use JH7100 as first StarFive SoC with watchdog.
+
+Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Reviewed-by: Guenter Roeck <linux@roeck-us.net>
+---
+ .../watchdog/starfive,jh7100-wdt.yaml | 71 +++++++++++++++++++
+ 1 file changed, 71 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/watchdog/starfive,jh7100-wdt.yaml
+
+diff --git a/Documentation/devicetree/bindings/watchdog/starfive,jh7100-wdt.yaml b/Documentation/devicetree/bindings/watchdog/starfive,jh7100-wdt.yaml
+new file mode 100644
+index 000000000000..68f3f6fd08a6
+--- /dev/null
++++ b/Documentation/devicetree/bindings/watchdog/starfive,jh7100-wdt.yaml
+@@ -0,0 +1,71 @@
++# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/watchdog/starfive,jh7100-wdt.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: StarFive Watchdog for JH7100 and JH7110 SoC
++
++maintainers:
++ - Xingyu Wu <xingyu.wu@starfivetech.com>
++ - Samin Guo <samin.guo@starfivetech.com>
++
++description:
++ The JH7100 and JH7110 watchdog both are 32 bit counters. JH7100 watchdog
++ has only one timeout phase and reboots. And JH7110 watchdog has two
++ timeout phases. At the first phase, the signal of watchdog interrupt
++ output(WDOGINT) will rise when counter is 0. The counter will reload
++ the timeout value. And then, if counter decreases to 0 again and WDOGINT
++ isn't cleared, the watchdog will reset the system unless the watchdog
++ reset is disabled.
++
++allOf:
++ - $ref: watchdog.yaml#
++
++properties:
++ compatible:
++ enum:
++ - starfive,jh7100-wdt
++ - starfive,jh7110-wdt
++
++ reg:
++ maxItems: 1
++
++ interrupts:
++ maxItems: 1
++
++ clocks:
++ items:
++ - description: APB clock
++ - description: Core clock
++
++ clock-names:
++ items:
++ - const: apb
++ - const: core
++
++ resets:
++ items:
++ - description: APB reset
++ - description: Core reset
++
++required:
++ - compatible
++ - reg
++ - clocks
++ - clock-names
++ - resets
++
++unevaluatedProperties: false
++
++examples:
++ - |
++ watchdog@12480000 {
++ compatible = "starfive,jh7100-wdt";
++ reg = <0x12480000 0x10000>;
++ clocks = <&clk 171>,
++ <&clk 172>;
++ clock-names = "apb", "core";
++ resets = <&rst 99>,
++ <&rst 100>;
++ };
+--
+2.20.1
+
--- /dev/null
+From 0a8c3317498474fb7876f5d251f16a2ad8251801 Mon Sep 17 00:00:00 2001
+From: Xingyu Wu <xingyu.wu@starfivetech.com>
+Date: Tue, 14 Mar 2023 21:24:36 +0800
+Subject: [PATCH 50/95] drivers: watchdog: Add StarFive Watchdog driver
+
+Add watchdog driver for the StarFive JH7100 and JH7110 SoC.
+
+Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
+Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
+Reviewed-by: Guenter Roeck <linux@roeck-us.net>
+---
+ drivers/watchdog/Kconfig | 11 +
+ drivers/watchdog/Makefile | 3 +
+ drivers/watchdog/starfive-wdt.c | 606 ++++++++++++++++++++++++++++++++
+ 3 files changed, 620 insertions(+)
+ create mode 100644 drivers/watchdog/starfive-wdt.c
+
+diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
+index b64bc49c7f30..44e0670a76f6 100644
+--- a/drivers/watchdog/Kconfig
++++ b/drivers/watchdog/Kconfig
+@@ -1991,6 +1991,17 @@ config WATCHDOG_RTAS
+ To compile this driver as a module, choose M here. The module
+ will be called wdrtas.
+
++# RISC-V Architecture
++
++config STARFIVE_WATCHDOG
++ tristate "StarFive Watchdog support"
++ depends on ARCH_STARFIVE || COMPILE_TEST
++ select WATCHDOG_CORE
++ default ARCH_STARFIVE
++ help
++ Say Y here to support the watchdog of StarFive JH7100 and JH7110
++ SoC. This driver can also be built as a module if choose M.
++
+ # S390 Architecture
+
+ config DIAG288_WATCHDOG
+diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
+index d41e5f830ae7..78fa3e970816 100644
+--- a/drivers/watchdog/Makefile
++++ b/drivers/watchdog/Makefile
+@@ -191,6 +191,9 @@ obj-$(CONFIG_MEN_A21_WDT) += mena21_wdt.o
+ obj-$(CONFIG_PSERIES_WDT) += pseries-wdt.o
+ obj-$(CONFIG_WATCHDOG_RTAS) += wdrtas.o
+
++# RISC-V Architecture
++obj-$(CONFIG_STARFIVE_WATCHDOG) += starfive-wdt.o
++
+ # S390 Architecture
+ obj-$(CONFIG_DIAG288_WATCHDOG) += diag288_wdt.o
+
+diff --git a/drivers/watchdog/starfive-wdt.c b/drivers/watchdog/starfive-wdt.c
+new file mode 100644
+index 000000000000..1995cceca51e
+--- /dev/null
++++ b/drivers/watchdog/starfive-wdt.c
+@@ -0,0 +1,606 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Starfive Watchdog driver
++ *
++ * Copyright (C) 2022 StarFive Technology Co., Ltd.
++ */
++
++#include <linux/clk.h>
++#include <linux/iopoll.h>
++#include <linux/module.h>
++#include <linux/of_device.h>
++#include <linux/pm_runtime.h>
++#include <linux/reset.h>
++#include <linux/watchdog.h>
++
++/* JH7100 Watchdog register define */
++#define STARFIVE_WDT_JH7100_INTSTAUS 0x000
++#define STARFIVE_WDT_JH7100_CONTROL 0x104
++#define STARFIVE_WDT_JH7100_LOAD 0x108
++#define STARFIVE_WDT_JH7100_EN 0x110
++#define STARFIVE_WDT_JH7100_RELOAD 0x114 /* Write 0 or 1 to reload preset value */
++#define STARFIVE_WDT_JH7100_VALUE 0x118
++#define STARFIVE_WDT_JH7100_INTCLR 0x120 /*
++ * [0]: Write 1 to clear interrupt
++ * [1]: 1 mean clearing and 0 mean complete
++ * [31:2]: reserved.
++ */
++#define STARFIVE_WDT_JH7100_LOCK 0x13c /* write 0x378f0765 to unlock */
++
++/* JH7110 Watchdog register define */
++#define STARFIVE_WDT_JH7110_LOAD 0x000
++#define STARFIVE_WDT_JH7110_VALUE 0x004
++#define STARFIVE_WDT_JH7110_CONTROL 0x008 /*
++ * [0]: reset enable;
++ * [1]: interrupt enable && watchdog enable
++ * [31:2]: reserved.
++ */
++#define STARFIVE_WDT_JH7110_INTCLR 0x00c /* clear intterupt and reload the counter */
++#define STARFIVE_WDT_JH7110_IMS 0x014
++#define STARFIVE_WDT_JH7110_LOCK 0xc00 /* write 0x1ACCE551 to unlock */
++
++/* WDOGCONTROL */
++#define STARFIVE_WDT_ENABLE 0x1
++#define STARFIVE_WDT_EN_SHIFT 0
++#define STARFIVE_WDT_RESET_EN 0x1
++#define STARFIVE_WDT_JH7100_RST_EN_SHIFT 0
++#define STARFIVE_WDT_JH7110_RST_EN_SHIFT 1
++
++/* WDOGLOCK */
++#define STARFIVE_WDT_JH7100_UNLOCK_KEY 0x378f0765
++#define STARFIVE_WDT_JH7110_UNLOCK_KEY 0x1acce551
++
++/* WDOGINTCLR */
++#define STARFIVE_WDT_INTCLR 0x1
++#define STARFIVE_WDT_JH7100_INTCLR_AVA_SHIFT 1 /* Watchdog can clear interrupt when 0 */
++
++#define STARFIVE_WDT_MAXCNT 0xffffffff
++#define STARFIVE_WDT_DEFAULT_TIME (15)
++#define STARFIVE_WDT_DELAY_US 0
++#define STARFIVE_WDT_TIMEOUT_US 10000
++
++/* module parameter */
++#define STARFIVE_WDT_EARLY_ENA 0
++
++static bool nowayout = WATCHDOG_NOWAYOUT;
++static int heartbeat;
++static bool early_enable = STARFIVE_WDT_EARLY_ENA;
++
++module_param(heartbeat, int, 0);
++module_param(early_enable, bool, 0);
++module_param(nowayout, bool, 0);
++
++MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (default="
++ __MODULE_STRING(STARFIVE_WDT_DEFAULT_TIME) ")");
++MODULE_PARM_DESC(early_enable,
++ "Watchdog is started at boot time if set to 1, default="
++ __MODULE_STRING(STARFIVE_WDT_EARLY_ENA));
++MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
++ __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
++
++struct starfive_wdt_variant {
++ unsigned int control; /* Watchdog Control Resgister for reset enable */
++ unsigned int load; /* Watchdog Load register */
++ unsigned int reload; /* Watchdog Reload Control register */
++ unsigned int enable; /* Watchdog Enable Register */
++ unsigned int value; /* Watchdog Counter Value Register */
++ unsigned int int_clr; /* Watchdog Interrupt Clear Register */
++ unsigned int unlock; /* Watchdog Lock Register */
++ unsigned int int_status; /* Watchdog Interrupt Status Register */
++
++ u32 unlock_key;
++ char enrst_shift;
++ char en_shift;
++ bool intclr_check; /* whether need to check it before clearing interrupt */
++ char intclr_ava_shift;
++ bool double_timeout; /* The watchdog need twice timeout to reboot */
++};
++
++struct starfive_wdt {
++ struct watchdog_device wdd;
++ spinlock_t lock; /* spinlock for register handling */
++ void __iomem *base;
++ struct clk *core_clk;
++ struct clk *apb_clk;
++ const struct starfive_wdt_variant *variant;
++ unsigned long freq;
++ u32 count; /* count of timeout */
++ u32 reload; /* restore the count */
++};
++
++/* Register layout and configuration for the JH7100 */
++static const struct starfive_wdt_variant starfive_wdt_jh7100_variant = {
++ .control = STARFIVE_WDT_JH7100_CONTROL,
++ .load = STARFIVE_WDT_JH7100_LOAD,
++ .reload = STARFIVE_WDT_JH7100_RELOAD,
++ .enable = STARFIVE_WDT_JH7100_EN,
++ .value = STARFIVE_WDT_JH7100_VALUE,
++ .int_clr = STARFIVE_WDT_JH7100_INTCLR,
++ .unlock = STARFIVE_WDT_JH7100_LOCK,
++ .unlock_key = STARFIVE_WDT_JH7100_UNLOCK_KEY,
++ .int_status = STARFIVE_WDT_JH7100_INTSTAUS,
++ .enrst_shift = STARFIVE_WDT_JH7100_RST_EN_SHIFT,
++ .en_shift = STARFIVE_WDT_EN_SHIFT,
++ .intclr_check = true,
++ .intclr_ava_shift = STARFIVE_WDT_JH7100_INTCLR_AVA_SHIFT,
++ .double_timeout = false,
++};
++
++/* Register layout and configuration for the JH7110 */
++static const struct starfive_wdt_variant starfive_wdt_jh7110_variant = {
++ .control = STARFIVE_WDT_JH7110_CONTROL,
++ .load = STARFIVE_WDT_JH7110_LOAD,
++ .enable = STARFIVE_WDT_JH7110_CONTROL,
++ .value = STARFIVE_WDT_JH7110_VALUE,
++ .int_clr = STARFIVE_WDT_JH7110_INTCLR,
++ .unlock = STARFIVE_WDT_JH7110_LOCK,
++ .unlock_key = STARFIVE_WDT_JH7110_UNLOCK_KEY,
++ .int_status = STARFIVE_WDT_JH7110_IMS,
++ .enrst_shift = STARFIVE_WDT_JH7110_RST_EN_SHIFT,
++ .en_shift = STARFIVE_WDT_EN_SHIFT,
++ .intclr_check = false,
++ .double_timeout = true,
++};
++
++static int starfive_wdt_enable_clock(struct starfive_wdt *wdt)
++{
++ int ret;
++
++ ret = clk_prepare_enable(wdt->apb_clk);
++ if (ret)
++ return dev_err_probe(wdt->wdd.parent, ret, "failed to enable apb clock\n");
++
++ ret = clk_prepare_enable(wdt->core_clk);
++ if (ret)
++ return dev_err_probe(wdt->wdd.parent, ret, "failed to enable core clock\n");
++
++ return 0;
++}
++
++static void starfive_wdt_disable_clock(struct starfive_wdt *wdt)
++{
++ clk_disable_unprepare(wdt->core_clk);
++ clk_disable_unprepare(wdt->apb_clk);
++}
++
++static inline int starfive_wdt_get_clock(struct starfive_wdt *wdt)
++{
++ struct device *dev = wdt->wdd.parent;
++
++ wdt->apb_clk = devm_clk_get(dev, "apb");
++ if (IS_ERR(wdt->apb_clk))
++ return dev_err_probe(dev, PTR_ERR(wdt->apb_clk), "failed to get apb clock\n");
++
++ wdt->core_clk = devm_clk_get(dev, "core");
++ if (IS_ERR(wdt->core_clk))
++ return dev_err_probe(dev, PTR_ERR(wdt->core_clk), "failed to get core clock\n");
++
++ return 0;
++}
++
++static inline int starfive_wdt_reset_init(struct device *dev)
++{
++ struct reset_control *rsts;
++ int ret;
++
++ rsts = devm_reset_control_array_get_exclusive(dev);
++ if (IS_ERR(rsts))
++ return dev_err_probe(dev, PTR_ERR(rsts), "failed to get resets\n");
++
++ ret = reset_control_deassert(rsts);
++ if (ret)
++ return dev_err_probe(dev, ret, "failed to deassert resets\n");
++
++ return 0;
++}
++
++static u32 starfive_wdt_ticks_to_sec(struct starfive_wdt *wdt, u32 ticks)
++{
++ return DIV_ROUND_CLOSEST(ticks, wdt->freq);
++}
++
++/* Write unlock-key to unlock. Write other value to lock. */
++static void starfive_wdt_unlock(struct starfive_wdt *wdt)
++{
++ spin_lock(&wdt->lock);
++ writel(wdt->variant->unlock_key, wdt->base + wdt->variant->unlock);
++}
++
++static void starfive_wdt_lock(struct starfive_wdt *wdt)
++{
++ writel(~wdt->variant->unlock_key, wdt->base + wdt->variant->unlock);
++ spin_unlock(&wdt->lock);
++}
++
++/* enable watchdog interrupt to reset/reboot */
++static void starfive_wdt_enable_reset(struct starfive_wdt *wdt)
++{
++ u32 val;
++
++ val = readl(wdt->base + wdt->variant->control);
++ val |= STARFIVE_WDT_RESET_EN << wdt->variant->enrst_shift;
++ writel(val, wdt->base + wdt->variant->control);
++}
++
++/* interrupt status whether has been raised from the counter */
++static bool starfive_wdt_raise_irq_status(struct starfive_wdt *wdt)
++{
++ return !!readl(wdt->base + wdt->variant->int_status);
++}
++
++/* waiting interrupt can be free to clear */
++static int starfive_wdt_wait_int_free(struct starfive_wdt *wdt)
++{
++ u32 value;
++
++ return readl_poll_timeout_atomic(wdt->base + wdt->variant->int_clr, value,
++ !(value & BIT(wdt->variant->intclr_ava_shift)),
++ STARFIVE_WDT_DELAY_US, STARFIVE_WDT_TIMEOUT_US);
++}
++
++/* clear interrupt signal before initialization or reload */
++static int starfive_wdt_int_clr(struct starfive_wdt *wdt)
++{
++ int ret;
++
++ if (wdt->variant->intclr_check) {
++ ret = starfive_wdt_wait_int_free(wdt);
++ if (ret)
++ return dev_err_probe(wdt->wdd.parent, ret,
++ "watchdog is not ready to clear interrupt.\n");
++ }
++ writel(STARFIVE_WDT_INTCLR, wdt->base + wdt->variant->int_clr);
++
++ return 0;
++}
++
++static inline void starfive_wdt_set_count(struct starfive_wdt *wdt, u32 val)
++{
++ writel(val, wdt->base + wdt->variant->load);
++}
++
++static inline u32 starfive_wdt_get_count(struct starfive_wdt *wdt)
++{
++ return readl(wdt->base + wdt->variant->value);
++}
++
++/* enable watchdog */
++static inline void starfive_wdt_enable(struct starfive_wdt *wdt)
++{
++ u32 val;
++
++ val = readl(wdt->base + wdt->variant->enable);
++ val |= STARFIVE_WDT_ENABLE << wdt->variant->en_shift;
++ writel(val, wdt->base + wdt->variant->enable);
++}
++
++/* disable watchdog */
++static inline void starfive_wdt_disable(struct starfive_wdt *wdt)
++{
++ u32 val;
++
++ val = readl(wdt->base + wdt->variant->enable);
++ val &= ~(STARFIVE_WDT_ENABLE << wdt->variant->en_shift);
++ writel(val, wdt->base + wdt->variant->enable);
++}
++
++static inline void starfive_wdt_set_reload_count(struct starfive_wdt *wdt, u32 count)
++{
++ starfive_wdt_set_count(wdt, count);
++
++ /* 7100 need set any value to reload register and could reload value to counter */
++ if (wdt->variant->reload)
++ writel(0x1, wdt->base + wdt->variant->reload);
++}
++
++static unsigned int starfive_wdt_max_timeout(struct starfive_wdt *wdt)
++{
++ if (wdt->variant->double_timeout)
++ return DIV_ROUND_UP(STARFIVE_WDT_MAXCNT, (wdt->freq / 2)) - 1;
++
++ return DIV_ROUND_UP(STARFIVE_WDT_MAXCNT, wdt->freq) - 1;
++}
++
++static unsigned int starfive_wdt_get_timeleft(struct watchdog_device *wdd)
++{
++ struct starfive_wdt *wdt = watchdog_get_drvdata(wdd);
++ u32 count;
++
++ /*
++ * If the watchdog takes twice timeout and set half count value,
++ * timeleft value should add the count value before first timeout.
++ */
++ count = starfive_wdt_get_count(wdt);
++ if (wdt->variant->double_timeout && !starfive_wdt_raise_irq_status(wdt))
++ count += wdt->count;
++
++ return starfive_wdt_ticks_to_sec(wdt, count);
++}
++
++static int starfive_wdt_keepalive(struct watchdog_device *wdd)
++{
++ struct starfive_wdt *wdt = watchdog_get_drvdata(wdd);
++ int ret;
++
++ starfive_wdt_unlock(wdt);
++ ret = starfive_wdt_int_clr(wdt);
++ if (ret)
++ goto exit;
++
++ starfive_wdt_set_reload_count(wdt, wdt->count);
++
++exit:
++ /* exit with releasing spinlock and locking registers */
++ starfive_wdt_lock(wdt);
++ return ret;
++}
++
++static int starfive_wdt_start(struct starfive_wdt *wdt)
++{
++ int ret;
++
++ starfive_wdt_unlock(wdt);
++ /* disable watchdog, to be safe */
++ starfive_wdt_disable(wdt);
++
++ starfive_wdt_enable_reset(wdt);
++ ret = starfive_wdt_int_clr(wdt);
++ if (ret)
++ goto exit;
++
++ starfive_wdt_set_count(wdt, wdt->count);
++ starfive_wdt_enable(wdt);
++
++exit:
++ starfive_wdt_lock(wdt);
++ return ret;
++}
++
++static void starfive_wdt_stop(struct starfive_wdt *wdt)
++{
++ starfive_wdt_unlock(wdt);
++ starfive_wdt_disable(wdt);
++ starfive_wdt_lock(wdt);
++}
++
++static int starfive_wdt_pm_start(struct watchdog_device *wdd)
++{
++ struct starfive_wdt *wdt = watchdog_get_drvdata(wdd);
++ int ret = pm_runtime_get_sync(wdd->parent);
++
++ if (ret < 0)
++ return ret;
++
++ return starfive_wdt_start(wdt);
++}
++
++static int starfive_wdt_pm_stop(struct watchdog_device *wdd)
++{
++ struct starfive_wdt *wdt = watchdog_get_drvdata(wdd);
++
++ starfive_wdt_stop(wdt);
++ return pm_runtime_put_sync(wdd->parent);
++}
++
++static int starfive_wdt_set_timeout(struct watchdog_device *wdd,
++ unsigned int timeout)
++{
++ struct starfive_wdt *wdt = watchdog_get_drvdata(wdd);
++ unsigned long count = timeout * wdt->freq;
++
++ /* some watchdogs take two timeouts to reset */
++ if (wdt->variant->double_timeout)
++ count /= 2;
++
++ wdt->count = count;
++ wdd->timeout = timeout;
++
++ starfive_wdt_unlock(wdt);
++ starfive_wdt_disable(wdt);
++ starfive_wdt_set_reload_count(wdt, wdt->count);
++ starfive_wdt_enable(wdt);
++ starfive_wdt_lock(wdt);
++
++ return 0;
++}
++
++#define STARFIVE_WDT_OPTIONS (WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE)
++
++static const struct watchdog_info starfive_wdt_info = {
++ .options = STARFIVE_WDT_OPTIONS,
++ .identity = "StarFive Watchdog",
++};
++
++static const struct watchdog_ops starfive_wdt_ops = {
++ .owner = THIS_MODULE,
++ .start = starfive_wdt_pm_start,
++ .stop = starfive_wdt_pm_stop,
++ .ping = starfive_wdt_keepalive,
++ .set_timeout = starfive_wdt_set_timeout,
++ .get_timeleft = starfive_wdt_get_timeleft,
++};
++
++static int starfive_wdt_probe(struct platform_device *pdev)
++{
++ struct starfive_wdt *wdt;
++ int ret;
++
++ wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL);
++ if (!wdt)
++ return -ENOMEM;
++
++ wdt->base = devm_platform_ioremap_resource(pdev, 0);
++ if (IS_ERR(wdt->base))
++ return dev_err_probe(&pdev->dev, PTR_ERR(wdt->base), "error mapping registers\n");
++
++ wdt->wdd.parent = &pdev->dev;
++ ret = starfive_wdt_get_clock(wdt);
++ if (ret)
++ return ret;
++
++ platform_set_drvdata(pdev, wdt);
++ pm_runtime_enable(&pdev->dev);
++ if (pm_runtime_enabled(&pdev->dev)) {
++ ret = pm_runtime_get_sync(&pdev->dev);
++ if (ret < 0)
++ return ret;
++ } else {
++ /* runtime PM is disabled but clocks need to be enabled */
++ ret = starfive_wdt_enable_clock(wdt);
++ if (ret)
++ return ret;
++ }
++
++ ret = starfive_wdt_reset_init(&pdev->dev);
++ if (ret)
++ goto err_exit;
++
++ watchdog_set_drvdata(&wdt->wdd, wdt);
++ wdt->wdd.info = &starfive_wdt_info;
++ wdt->wdd.ops = &starfive_wdt_ops;
++ wdt->variant = of_device_get_match_data(&pdev->dev);
++ spin_lock_init(&wdt->lock);
++
++ wdt->freq = clk_get_rate(wdt->core_clk);
++ if (!wdt->freq) {
++ dev_err(&pdev->dev, "get clock rate failed.\n");
++ ret = -EINVAL;
++ goto err_exit;
++ }
++
++ wdt->wdd.min_timeout = 1;
++ wdt->wdd.max_timeout = starfive_wdt_max_timeout(wdt);
++ wdt->wdd.timeout = STARFIVE_WDT_DEFAULT_TIME;
++ watchdog_init_timeout(&wdt->wdd, heartbeat, &pdev->dev);
++ starfive_wdt_set_timeout(&wdt->wdd, wdt->wdd.timeout);
++
++ watchdog_set_nowayout(&wdt->wdd, nowayout);
++ watchdog_stop_on_reboot(&wdt->wdd);
++ watchdog_stop_on_unregister(&wdt->wdd);
++
++ if (early_enable) {
++ ret = starfive_wdt_start(wdt);
++ if (ret)
++ goto err_exit;
++ set_bit(WDOG_HW_RUNNING, &wdt->wdd.status);
++ } else {
++ starfive_wdt_stop(wdt);
++ }
++
++ ret = watchdog_register_device(&wdt->wdd);
++ if (ret)
++ goto err_exit;
++
++ if (!early_enable)
++ return pm_runtime_put_sync(&pdev->dev);
++
++ return 0;
++
++err_exit:
++ starfive_wdt_disable_clock(wdt);
++ pm_runtime_disable(&pdev->dev);
++
++ return ret;
++}
++
++static int starfive_wdt_remove(struct platform_device *pdev)
++{
++ struct starfive_wdt *wdt = platform_get_drvdata(pdev);
++
++ starfive_wdt_stop(wdt);
++ watchdog_unregister_device(&wdt->wdd);
++
++ if (pm_runtime_enabled(&pdev->dev))
++ pm_runtime_disable(&pdev->dev);
++ else
++ /* disable clock without PM */
++ starfive_wdt_disable_clock(wdt);
++
++ return 0;
++}
++
++static void starfive_wdt_shutdown(struct platform_device *pdev)
++{
++ struct starfive_wdt *wdt = platform_get_drvdata(pdev);
++
++ starfive_wdt_pm_stop(&wdt->wdd);
++}
++
++#ifdef CONFIG_PM_SLEEP
++static int starfive_wdt_suspend(struct device *dev)
++{
++ struct starfive_wdt *wdt = dev_get_drvdata(dev);
++
++ /* Save watchdog state, and turn it off. */
++ wdt->reload = starfive_wdt_get_count(wdt);
++
++ /* Note that WTCNT doesn't need to be saved. */
++ starfive_wdt_stop(wdt);
++
++ return pm_runtime_force_suspend(dev);
++}
++
++static int starfive_wdt_resume(struct device *dev)
++{
++ struct starfive_wdt *wdt = dev_get_drvdata(dev);
++ int ret;
++
++ ret = pm_runtime_force_resume(dev);
++ if (ret)
++ return ret;
++
++ starfive_wdt_unlock(wdt);
++ /* Restore watchdog state. */
++ starfive_wdt_set_reload_count(wdt, wdt->reload);
++ starfive_wdt_lock(wdt);
++
++ return starfive_wdt_start(wdt);
++}
++#endif /* CONFIG_PM_SLEEP */
++
++#ifdef CONFIG_PM
++static int starfive_wdt_runtime_suspend(struct device *dev)
++{
++ struct starfive_wdt *wdt = dev_get_drvdata(dev);
++
++ starfive_wdt_disable_clock(wdt);
++
++ return 0;
++}
++
++static int starfive_wdt_runtime_resume(struct device *dev)
++{
++ struct starfive_wdt *wdt = dev_get_drvdata(dev);
++
++ return starfive_wdt_enable_clock(wdt);
++}
++#endif /* CONFIG_PM */
++
++static const struct dev_pm_ops starfive_wdt_pm_ops = {
++ SET_RUNTIME_PM_OPS(starfive_wdt_runtime_suspend, starfive_wdt_runtime_resume, NULL)
++ SET_SYSTEM_SLEEP_PM_OPS(starfive_wdt_suspend, starfive_wdt_resume)
++};
++
++static const struct of_device_id starfive_wdt_match[] = {
++ { .compatible = "starfive,jh7100-wdt", .data = &starfive_wdt_jh7100_variant },
++ { .compatible = "starfive,jh7110-wdt", .data = &starfive_wdt_jh7110_variant },
++ { /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(of, starfive_wdt_match);
++
++static struct platform_driver starfive_wdt_driver = {
++ .probe = starfive_wdt_probe,
++ .remove = starfive_wdt_remove,
++ .shutdown = starfive_wdt_shutdown,
++ .driver = {
++ .name = "starfive-wdt",
++ .pm = &starfive_wdt_pm_ops,
++ .of_match_table = of_match_ptr(starfive_wdt_match),
++ },
++};
++module_platform_driver(starfive_wdt_driver);
++
++MODULE_AUTHOR("Xingyu Wu <xingyu.wu@starfivetech.com>");
++MODULE_AUTHOR("Samin Guo <samin.guo@starfivetech.com>");
++MODULE_DESCRIPTION("StarFive Watchdog Device Driver");
++MODULE_LICENSE("GPL");
+--
+2.20.1
+
--- /dev/null
+From 0c7703de753c4ea6387e2323ae0ba828ed33aec7 Mon Sep 17 00:00:00 2001
+From: Xingyu Wu <xingyu.wu@starfivetech.com>
+Date: Tue, 14 Mar 2023 21:24:37 +0800
+Subject: [PATCH 51/95] riscv: dts: starfive: jh7100: Add watchdog node
+
+Add watchdog node for the StarFive JH7100 RISC-V SoC.
+
+Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
+Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
+---
+ arch/riscv/boot/dts/starfive/jh7100.dtsi | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/arch/riscv/boot/dts/starfive/jh7100.dtsi b/arch/riscv/boot/dts/starfive/jh7100.dtsi
+index 000447482aca..4218621ea3b9 100644
+--- a/arch/riscv/boot/dts/starfive/jh7100.dtsi
++++ b/arch/riscv/boot/dts/starfive/jh7100.dtsi
+@@ -238,5 +238,15 @@
+ #size-cells = <0>;
+ status = "disabled";
+ };
++
++ watchdog@12480000 {
++ compatible = "starfive,jh7100-wdt";
++ reg = <0x0 0x12480000 0x0 0x10000>;
++ clocks = <&clkgen JH7100_CLK_WDTIMER_APB>,
++ <&clkgen JH7100_CLK_WDT_CORE>;
++ clock-names = "apb", "core";
++ resets = <&rstgen JH7100_RSTN_WDTIMER_APB>,
++ <&rstgen JH7100_RSTN_WDT>;
++ };
+ };
+ };
+--
+2.20.1
+
--- /dev/null
+From 53349e3f810a298fb96e99d56e13fd8fedd8c510 Mon Sep 17 00:00:00 2001
+From: Jia Jie Ho <jiajie.ho@starfivetech.com>
+Date: Tue, 17 Jan 2023 09:54:43 +0800
+Subject: [PATCH 52/95] dt-bindings: rng: Add StarFive TRNG module
+
+Add documentation to describe Starfive true random number generator
+module.
+
+Co-developed-by: Jenny Zhang <jenny.zhang@starfivetech.com>
+Signed-off-by: Jenny Zhang <jenny.zhang@starfivetech.com>
+Signed-off-by: Jia Jie Ho <jiajie.ho@starfivetech.com>
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+---
+ .../bindings/rng/starfive,jh7110-trng.yaml | 55 +++++++++++++++++++
+ 1 file changed, 55 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/rng/starfive,jh7110-trng.yaml
+
+diff --git a/Documentation/devicetree/bindings/rng/starfive,jh7110-trng.yaml b/Documentation/devicetree/bindings/rng/starfive,jh7110-trng.yaml
+new file mode 100644
+index 000000000000..2b76ce25acc4
+--- /dev/null
++++ b/Documentation/devicetree/bindings/rng/starfive,jh7110-trng.yaml
+@@ -0,0 +1,55 @@
++# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/rng/starfive,jh7110-trng.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: StarFive SoC TRNG Module
++
++maintainers:
++ - Jia Jie Ho <jiajie.ho@starfivetech.com>
++
++properties:
++ compatible:
++ const: starfive,jh7110-trng
++
++ reg:
++ maxItems: 1
++
++ clocks:
++ items:
++ - description: Hardware reference clock
++ - description: AHB reference clock
++
++ clock-names:
++ items:
++ - const: hclk
++ - const: ahb
++
++ resets:
++ maxItems: 1
++
++ interrupts:
++ maxItems: 1
++
++required:
++ - compatible
++ - reg
++ - clocks
++ - clock-names
++ - resets
++ - interrupts
++
++additionalProperties: false
++
++examples:
++ - |
++ rng: rng@1600C000 {
++ compatible = "starfive,jh7110-trng";
++ reg = <0x1600C000 0x4000>;
++ clocks = <&clk 15>, <&clk 16>;
++ clock-names = "hclk", "ahb";
++ resets = <&reset 3>;
++ interrupts = <30>;
++ };
++...
+--
+2.20.1
+
--- /dev/null
+From c8f7b03b59da0d83f95580fdf802463d24cbedc0 Mon Sep 17 00:00:00 2001
+From: Jia Jie Ho <jiajie.ho@starfivetech.com>
+Date: Tue, 17 Jan 2023 09:54:44 +0800
+Subject: [PATCH 53/95] hwrng: starfive - Add TRNG driver for StarFive SoC
+
+This adds driver support for the hardware random number generator in
+Starfive SoCs and adds StarFive TRNG entry to MAINTAINERS.
+
+Co-developed-by: Jenny Zhang <jenny.zhang@starfivetech.com>
+Signed-off-by: Jenny Zhang <jenny.zhang@starfivetech.com>
+Signed-off-by: Jia Jie Ho <jiajie.ho@starfivetech.com>
+---
+ drivers/char/hw_random/Kconfig | 11 +
+ drivers/char/hw_random/Makefile | 1 +
+ drivers/char/hw_random/jh7110-trng.c | 393 +++++++++++++++++++++++++++
+ 3 files changed, 405 insertions(+)
+ create mode 100644 drivers/char/hw_random/jh7110-trng.c
+
+diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig
+index 3da8e85f8aae..be202959efa6 100644
+--- a/drivers/char/hw_random/Kconfig
++++ b/drivers/char/hw_random/Kconfig
+@@ -549,6 +549,17 @@ config HW_RANDOM_CN10K
+ To compile this driver as a module, choose M here.
+ The module will be called cn10k_rng. If unsure, say Y.
+
++config HW_RANDOM_JH7110
++ tristate "StarFive JH7110 Random Number Generator support"
++ depends on SOC_STARFIVE
++ depends on HW_RANDOM
++ help
++ This driver provides support for the True Random Number
++ Generator in StarFive JH7110 SoCs.
++
++ To compile this driver as a module, choose M here.
++ The module will be called jh7110-trng.
++
+ endif # HW_RANDOM
+
+ config UML_RANDOM
+diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile
+index 3e948cf04476..09bde4a0f971 100644
+--- a/drivers/char/hw_random/Makefile
++++ b/drivers/char/hw_random/Makefile
+@@ -47,3 +47,4 @@ obj-$(CONFIG_HW_RANDOM_XIPHERA) += xiphera-trng.o
+ obj-$(CONFIG_HW_RANDOM_ARM_SMCCC_TRNG) += arm_smccc_trng.o
+ obj-$(CONFIG_HW_RANDOM_CN10K) += cn10k-rng.o
+ obj-$(CONFIG_HW_RANDOM_POLARFIRE_SOC) += mpfs-rng.o
++obj-$(CONFIG_HW_RANDOM_JH7110) += jh7110-trng.o
+diff --git a/drivers/char/hw_random/jh7110-trng.c b/drivers/char/hw_random/jh7110-trng.c
+new file mode 100644
+index 000000000000..38474d48a25e
+--- /dev/null
++++ b/drivers/char/hw_random/jh7110-trng.c
+@@ -0,0 +1,393 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * TRNG driver for the StarFive JH7110 SoC
++ *
++ * Copyright (C) 2022 StarFive Technology Co.
++ */
++
++#include <linux/clk.h>
++#include <linux/completion.h>
++#include <linux/delay.h>
++#include <linux/err.h>
++#include <linux/hw_random.h>
++#include <linux/interrupt.h>
++#include <linux/io.h>
++#include <linux/iopoll.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/platform_device.h>
++#include <linux/pm_runtime.h>
++#include <linux/random.h>
++#include <linux/reset.h>
++
++/* trng register offset */
++#define STARFIVE_CTRL 0x00
++#define STARFIVE_STAT 0x04
++#define STARFIVE_MODE 0x08
++#define STARFIVE_SMODE 0x0C
++#define STARFIVE_IE 0x10
++#define STARFIVE_ISTAT 0x14
++#define STARFIVE_RAND0 0x20
++#define STARFIVE_RAND1 0x24
++#define STARFIVE_RAND2 0x28
++#define STARFIVE_RAND3 0x2C
++#define STARFIVE_RAND4 0x30
++#define STARFIVE_RAND5 0x34
++#define STARFIVE_RAND6 0x38
++#define STARFIVE_RAND7 0x3C
++#define STARFIVE_AUTO_RQSTS 0x60
++#define STARFIVE_AUTO_AGE 0x64
++
++/* CTRL CMD */
++#define STARFIVE_CTRL_EXEC_NOP 0x0
++#define STARFIVE_CTRL_GENE_RANDNUM 0x1
++#define STARFIVE_CTRL_EXEC_RANDRESEED 0x2
++
++/* STAT */
++#define STARFIVE_STAT_NONCE_MODE BIT(2)
++#define STARFIVE_STAT_R256 BIT(3)
++#define STARFIVE_STAT_MISSION_MODE BIT(8)
++#define STARFIVE_STAT_SEEDED BIT(9)
++#define STARFIVE_STAT_LAST_RESEED(x) ((x) << 16)
++#define STARFIVE_STAT_SRVC_RQST BIT(27)
++#define STARFIVE_STAT_RAND_GENERATING BIT(30)
++#define STARFIVE_STAT_RAND_SEEDING BIT(31)
++
++/* MODE */
++#define STARFIVE_MODE_R256 BIT(3)
++
++/* SMODE */
++#define STARFIVE_SMODE_NONCE_MODE BIT(2)
++#define STARFIVE_SMODE_MISSION_MODE BIT(8)
++#define STARFIVE_SMODE_MAX_REJECTS(x) ((x) << 16)
++
++/* IE */
++#define STARFIVE_IE_RAND_RDY_EN BIT(0)
++#define STARFIVE_IE_SEED_DONE_EN BIT(1)
++#define STARFIVE_IE_LFSR_LOCKUP_EN BIT(4)
++#define STARFIVE_IE_GLBL_EN BIT(31)
++
++#define STARFIVE_IE_ALL (STARFIVE_IE_GLBL_EN | \
++ STARFIVE_IE_RAND_RDY_EN | \
++ STARFIVE_IE_SEED_DONE_EN | \
++ STARFIVE_IE_LFSR_LOCKUP_EN)
++
++/* ISTAT */
++#define STARFIVE_ISTAT_RAND_RDY BIT(0)
++#define STARFIVE_ISTAT_SEED_DONE BIT(1)
++#define STARFIVE_ISTAT_LFSR_LOCKUP BIT(4)
++
++#define STARFIVE_RAND_LEN sizeof(u32)
++
++#define to_trng(p) container_of(p, struct starfive_trng, rng)
++
++enum reseed {
++ RANDOM_RESEED,
++ NONCE_RESEED,
++};
++
++enum mode {
++ PRNG_128BIT,
++ PRNG_256BIT,
++};
++
++struct starfive_trng {
++ struct device *dev;
++ void __iomem *base;
++ struct clk *hclk;
++ struct clk *ahb;
++ struct reset_control *rst;
++ struct hwrng rng;
++ struct completion random_done;
++ struct completion reseed_done;
++ u32 mode;
++ u32 mission;
++ u32 reseed;
++ /* protects against concurrent write to ctrl register */
++ spinlock_t write_lock;
++};
++
++static u16 autoreq;
++module_param(autoreq, ushort, 0);
++MODULE_PARM_DESC(autoreq, "Auto-reseeding after random number requests by host reaches specified counter:\n"
++ " 0 - disable counter\n"
++ " other - reload value for internal counter");
++
++static u16 autoage;
++module_param(autoage, ushort, 0);
++MODULE_PARM_DESC(autoage, "Auto-reseeding after specified timer countdowns to 0:\n"
++ " 0 - disable timer\n"
++ " other - reload value for internal timer");
++
++static inline int starfive_trng_wait_idle(struct starfive_trng *trng)
++{
++ u32 stat;
++
++ return readl_relaxed_poll_timeout(trng->base + STARFIVE_STAT, stat,
++ !(stat & (STARFIVE_STAT_RAND_GENERATING |
++ STARFIVE_STAT_RAND_SEEDING)),
++ 10, 100000);
++}
++
++static inline void starfive_trng_irq_mask_clear(struct starfive_trng *trng)
++{
++ /* clear register: ISTAT */
++ u32 data = readl(trng->base + STARFIVE_ISTAT);
++
++ writel(data, trng->base + STARFIVE_ISTAT);
++}
++
++static int starfive_trng_cmd(struct starfive_trng *trng, u32 cmd, bool wait)
++{
++ int wait_time = 1000;
++
++ /* allow up to 40 us for wait == 0 */
++ if (!wait)
++ wait_time = 40;
++
++ switch (cmd) {
++ case STARFIVE_CTRL_GENE_RANDNUM:
++ reinit_completion(&trng->random_done);
++ spin_lock_irq(&trng->write_lock);
++ writel(cmd, trng->base + STARFIVE_CTRL);
++ spin_unlock_irq(&trng->write_lock);
++ if (!wait_for_completion_timeout(&trng->random_done, usecs_to_jiffies(wait_time)))
++ return -ETIMEDOUT;
++ break;
++ case STARFIVE_CTRL_EXEC_RANDRESEED:
++ reinit_completion(&trng->reseed_done);
++ spin_lock_irq(&trng->write_lock);
++ writel(cmd, trng->base + STARFIVE_CTRL);
++ spin_unlock_irq(&trng->write_lock);
++ if (!wait_for_completion_timeout(&trng->reseed_done, usecs_to_jiffies(wait_time)))
++ return -ETIMEDOUT;
++ break;
++ default:
++ return -EINVAL;
++ }
++
++ return 0;
++}
++
++static int starfive_trng_init(struct hwrng *rng)
++{
++ struct starfive_trng *trng = to_trng(rng);
++ u32 mode, intr = 0;
++
++ /* setup Auto Request/Age register */
++ writel(autoage, trng->base + STARFIVE_AUTO_AGE);
++ writel(autoreq, trng->base + STARFIVE_AUTO_RQSTS);
++
++ /* clear register: ISTAT */
++ starfive_trng_irq_mask_clear(trng);
++
++ intr |= STARFIVE_IE_ALL;
++ writel(intr, trng->base + STARFIVE_IE);
++
++ mode = readl(trng->base + STARFIVE_MODE);
++
++ switch (trng->mode) {
++ case PRNG_128BIT:
++ mode &= ~STARFIVE_MODE_R256;
++ break;
++ case PRNG_256BIT:
++ mode |= STARFIVE_MODE_R256;
++ break;
++ default:
++ mode |= STARFIVE_MODE_R256;
++ break;
++ }
++
++ writel(mode, trng->base + STARFIVE_MODE);
++
++ return starfive_trng_cmd(trng, STARFIVE_CTRL_EXEC_RANDRESEED, 1);
++}
++
++static irqreturn_t starfive_trng_irq(int irq, void *priv)
++{
++ u32 status;
++ struct starfive_trng *trng = (struct starfive_trng *)priv;
++
++ status = readl(trng->base + STARFIVE_ISTAT);
++ if (status & STARFIVE_ISTAT_RAND_RDY) {
++ writel(STARFIVE_ISTAT_RAND_RDY, trng->base + STARFIVE_ISTAT);
++ complete(&trng->random_done);
++ }
++
++ if (status & STARFIVE_ISTAT_SEED_DONE) {
++ writel(STARFIVE_ISTAT_SEED_DONE, trng->base + STARFIVE_ISTAT);
++ complete(&trng->reseed_done);
++ }
++
++ if (status & STARFIVE_ISTAT_LFSR_LOCKUP) {
++ writel(STARFIVE_ISTAT_LFSR_LOCKUP, trng->base + STARFIVE_ISTAT);
++ /* SEU occurred, reseeding required*/
++ spin_lock(&trng->write_lock);
++ writel(STARFIVE_CTRL_EXEC_RANDRESEED, trng->base + STARFIVE_CTRL);
++ spin_unlock(&trng->write_lock);
++ }
++
++ return IRQ_HANDLED;
++}
++
++static void starfive_trng_cleanup(struct hwrng *rng)
++{
++ struct starfive_trng *trng = to_trng(rng);
++
++ writel(0, trng->base + STARFIVE_CTRL);
++
++ reset_control_assert(trng->rst);
++ clk_disable_unprepare(trng->hclk);
++ clk_disable_unprepare(trng->ahb);
++}
++
++static int starfive_trng_read(struct hwrng *rng, void *buf, size_t max, bool wait)
++{
++ struct starfive_trng *trng = to_trng(rng);
++ int ret;
++
++ pm_runtime_get_sync(trng->dev);
++
++ if (trng->mode == PRNG_256BIT)
++ max = min_t(size_t, max, (STARFIVE_RAND_LEN * 8));
++ else
++ max = min_t(size_t, max, (STARFIVE_RAND_LEN * 4));
++
++ if (wait) {
++ ret = starfive_trng_wait_idle(trng);
++ if (ret)
++ return -ETIMEDOUT;
++ }
++
++ ret = starfive_trng_cmd(trng, STARFIVE_CTRL_GENE_RANDNUM, wait);
++ if (ret)
++ return ret;
++
++ memcpy_fromio(buf, trng->base + STARFIVE_RAND0, max);
++
++ pm_runtime_put_sync_autosuspend(trng->dev);
++
++ return max;
++}
++
++static int starfive_trng_probe(struct platform_device *pdev)
++{
++ int ret;
++ int irq;
++ struct starfive_trng *trng;
++
++ trng = devm_kzalloc(&pdev->dev, sizeof(*trng), GFP_KERNEL);
++ if (!trng)
++ return -ENOMEM;
++
++ platform_set_drvdata(pdev, trng);
++ trng->dev = &pdev->dev;
++
++ trng->base = devm_platform_ioremap_resource(pdev, 0);
++ if (IS_ERR(trng->base))
++ return dev_err_probe(&pdev->dev, PTR_ERR(trng->base),
++ "Error remapping memory for platform device.\n");
++
++ irq = platform_get_irq(pdev, 0);
++ if (irq < 0)
++ return irq;
++
++ init_completion(&trng->random_done);
++ init_completion(&trng->reseed_done);
++ spin_lock_init(&trng->write_lock);
++
++ ret = devm_request_irq(&pdev->dev, irq, starfive_trng_irq, 0, pdev->name,
++ (void *)trng);
++ if (ret)
++ return dev_err_probe(&pdev->dev, irq,
++ "Failed to register interrupt handler\n");
++
++ trng->hclk = devm_clk_get(&pdev->dev, "hclk");
++ if (IS_ERR(trng->hclk))
++ return dev_err_probe(&pdev->dev, PTR_ERR(trng->hclk),
++ "Error getting hardware reference clock\n");
++
++ trng->ahb = devm_clk_get(&pdev->dev, "ahb");
++ if (IS_ERR(trng->ahb))
++ return dev_err_probe(&pdev->dev, PTR_ERR(trng->ahb),
++ "Error getting ahb reference clock\n");
++
++ trng->rst = devm_reset_control_get_shared(&pdev->dev, NULL);
++ if (IS_ERR(trng->rst))
++ return dev_err_probe(&pdev->dev, PTR_ERR(trng->rst),
++ "Error getting hardware reset line\n");
++
++ clk_prepare_enable(trng->hclk);
++ clk_prepare_enable(trng->ahb);
++ reset_control_deassert(trng->rst);
++
++ trng->rng.name = dev_driver_string(&pdev->dev);
++ trng->rng.init = starfive_trng_init;
++ trng->rng.cleanup = starfive_trng_cleanup;
++ trng->rng.read = starfive_trng_read;
++
++ trng->mode = PRNG_256BIT;
++ trng->mission = 1;
++ trng->reseed = RANDOM_RESEED;
++
++ pm_runtime_use_autosuspend(&pdev->dev);
++ pm_runtime_set_autosuspend_delay(&pdev->dev, 100);
++ pm_runtime_enable(&pdev->dev);
++
++ ret = devm_hwrng_register(&pdev->dev, &trng->rng);
++ if (ret) {
++ pm_runtime_disable(&pdev->dev);
++
++ reset_control_assert(trng->rst);
++ clk_disable_unprepare(trng->ahb);
++ clk_disable_unprepare(trng->hclk);
++
++ return dev_err_probe(&pdev->dev, ret, "Failed to register hwrng\n");
++ }
++
++ return 0;
++}
++
++static int __maybe_unused starfive_trng_suspend(struct device *dev)
++{
++ struct starfive_trng *trng = dev_get_drvdata(dev);
++
++ clk_disable_unprepare(trng->hclk);
++ clk_disable_unprepare(trng->ahb);
++
++ return 0;
++}
++
++static int __maybe_unused starfive_trng_resume(struct device *dev)
++{
++ struct starfive_trng *trng = dev_get_drvdata(dev);
++
++ clk_prepare_enable(trng->hclk);
++ clk_prepare_enable(trng->ahb);
++
++ return 0;
++}
++
++static DEFINE_SIMPLE_DEV_PM_OPS(starfive_trng_pm_ops, starfive_trng_suspend,
++ starfive_trng_resume);
++
++static const struct of_device_id trng_dt_ids[] __maybe_unused = {
++ { .compatible = "starfive,jh7110-trng" },
++ { }
++};
++MODULE_DEVICE_TABLE(of, trng_dt_ids);
++
++static struct platform_driver starfive_trng_driver = {
++ .probe = starfive_trng_probe,
++ .driver = {
++ .name = "jh7110-trng",
++ .pm = &starfive_trng_pm_ops,
++ .of_match_table = of_match_ptr(trng_dt_ids),
++ },
++};
++
++module_platform_driver(starfive_trng_driver);
++
++MODULE_LICENSE("GPL");
++MODULE_DESCRIPTION("StarFive True Random Number Generator");
+--
+2.20.1
+
--- /dev/null
+From f9303f0ed1fa28d1d677b260190b1bd4747a787f Mon Sep 17 00:00:00 2001
+From: Jia Jie Ho <jiajie.ho@starfivetech.com>
+Date: Tue, 17 Jan 2023 09:54:45 +0800
+Subject: [PATCH 54/95] riscv: dts: starfive: Add TRNG node for VisionFive 2
+
+Adding StarFive TRNG controller node to VisionFive 2 SoC.
+
+Co-developed-by: Jenny Zhang <jenny.zhang@starfivetech.com>
+Signed-off-by: Jenny Zhang <jenny.zhang@starfivetech.com>
+Signed-off-by: Jia Jie Ho <jiajie.ho@starfivetech.com>
+Acked-by: Palmer Dabbelt <palmer@rivosinc.com>
+---
+ arch/riscv/boot/dts/starfive/jh7110.dtsi | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/arch/riscv/boot/dts/starfive/jh7110.dtsi b/arch/riscv/boot/dts/starfive/jh7110.dtsi
+index c1fdd0758abf..7961c90b293f 100644
+--- a/arch/riscv/boot/dts/starfive/jh7110.dtsi
++++ b/arch/riscv/boot/dts/starfive/jh7110.dtsi
+@@ -392,6 +392,16 @@
+ status = "disabled";
+ };
+
++ rng: rng@1600c000 {
++ compatible = "starfive,jh7110-trng";
++ reg = <0x0 0x1600C000 0x0 0x4000>;
++ clocks = <&stgcrg JH7110_STGCLK_SEC_HCLK>,
++ <&stgcrg JH7110_STGCLK_SEC_MISCAHB>;
++ clock-names = "hclk", "ahb";
++ resets = <&stgcrg JH7110_STGRST_SEC_TOP_HRESETN>;
++ interrupts = <30>;
++ };
++
+ i2c3: i2c@12030000 {
+ compatible = "snps,designware-i2c";
+ reg = <0x0 0x12030000 0x0 0x10000>;
+--
+2.20.1
+
--- /dev/null
+From b39d5efb277a9a5e2833f771f30e083c280a88ee Mon Sep 17 00:00:00 2001
+From: Xingyu Wu <xingyu.wu@starfivetech.com>
+Date: Thu, 18 May 2023 18:12:24 +0800
+Subject: [PATCH 55/95] dt-bindings: clock: Add StarFive JH7110
+ System-Top-Group clock and reset generator
+
+Add bindings for the System-Top-Group clock and reset generator (STGCRG)
+on the JH7110 RISC-V SoC by StarFive Ltd.
+
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
+---
+ .../clock/starfive,jh7110-stgcrg.yaml | 82 +++++++++++++++++++
+ .../dt-bindings/clock/starfive,jh7110-crg.h | 34 ++++++++
+ .../dt-bindings/reset/starfive,jh7110-crg.h | 28 +++++++
+ 3 files changed, 144 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/clock/starfive,jh7110-stgcrg.yaml
+
+diff --git a/Documentation/devicetree/bindings/clock/starfive,jh7110-stgcrg.yaml b/Documentation/devicetree/bindings/clock/starfive,jh7110-stgcrg.yaml
+new file mode 100644
+index 000000000000..b64ccd84200a
+--- /dev/null
++++ b/Documentation/devicetree/bindings/clock/starfive,jh7110-stgcrg.yaml
+@@ -0,0 +1,82 @@
++# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/clock/starfive,jh7110-stgcrg.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: StarFive JH7110 System-Top-Group Clock and Reset Generator
++
++maintainers:
++ - Xingyu Wu <xingyu.wu@starfivetech.com>
++
++properties:
++ compatible:
++ const: starfive,jh7110-stgcrg
++
++ reg:
++ maxItems: 1
++
++ clocks:
++ items:
++ - description: Main Oscillator (24 MHz)
++ - description: HIFI4 core
++ - description: STG AXI/AHB
++ - description: USB (125 MHz)
++ - description: CPU Bus
++ - description: HIFI4 Axi
++ - description: NOC STG Bus
++ - description: APB Bus
++
++ clock-names:
++ items:
++ - const: osc
++ - const: hifi4_core
++ - const: stg_axiahb
++ - const: usb_125m
++ - const: cpu_bus
++ - const: hifi4_axi
++ - const: nocstg_bus
++ - const: apb_bus
++
++ '#clock-cells':
++ const: 1
++ description:
++ See <dt-bindings/clock/starfive,jh7110-crg.h> for valid indices.
++
++ '#reset-cells':
++ const: 1
++ description:
++ See <dt-bindings/reset/starfive,jh7110-crg.h> for valid indices.
++
++required:
++ - compatible
++ - reg
++ - clocks
++ - clock-names
++ - '#clock-cells'
++ - '#reset-cells'
++
++additionalProperties: false
++
++examples:
++ - |
++ #include <dt-bindings/clock/starfive,jh7110-crg.h>
++
++ stgcrg: clock-controller@10230000 {
++ compatible = "starfive,jh7110-stgcrg";
++ reg = <0x10230000 0x10000>;
++ clocks = <&osc>,
++ <&syscrg JH7110_SYSCLK_HIFI4_CORE>,
++ <&syscrg JH7110_SYSCLK_STG_AXIAHB>,
++ <&syscrg JH7110_SYSCLK_USB_125M>,
++ <&syscrg JH7110_SYSCLK_CPU_BUS>,
++ <&syscrg JH7110_SYSCLK_HIFI4_AXI>,
++ <&syscrg JH7110_SYSCLK_NOCSTG_BUS>,
++ <&syscrg JH7110_SYSCLK_APB_BUS>;
++ clock-names = "osc", "hifi4_core",
++ "stg_axiahb", "usb_125m",
++ "cpu_bus", "hifi4_axi",
++ "nocstg_bus", "apb_bus";
++ #clock-cells = <1>;
++ #reset-cells = <1>;
++ };
+diff --git a/include/dt-bindings/clock/starfive,jh7110-crg.h b/include/dt-bindings/clock/starfive,jh7110-crg.h
+index 06257bfd9ac1..6c8e8b4cf1f6 100644
+--- a/include/dt-bindings/clock/starfive,jh7110-crg.h
++++ b/include/dt-bindings/clock/starfive,jh7110-crg.h
+@@ -1,6 +1,7 @@
+ /* SPDX-License-Identifier: GPL-2.0 OR MIT */
+ /*
+ * Copyright 2022 Emil Renner Berthing <kernel@esmil.dk>
++ * Copyright 2022 StarFive Technology Co., Ltd.
+ */
+
+ #ifndef __DT_BINDINGS_CLOCK_STARFIVE_JH7110_CRG_H__
+@@ -218,4 +219,37 @@
+
+ #define JH7110_AONCLK_END 14
+
++/* STGCRG clocks */
++#define JH7110_STGCLK_HIFI4_CLK_CORE 0
++#define JH7110_STGCLK_USB0_APB 1
++#define JH7110_STGCLK_USB0_UTMI_APB 2
++#define JH7110_STGCLK_USB0_AXI 3
++#define JH7110_STGCLK_USB0_LPM 4
++#define JH7110_STGCLK_USB0_STB 5
++#define JH7110_STGCLK_USB0_APP_125 6
++#define JH7110_STGCLK_USB0_REFCLK 7
++#define JH7110_STGCLK_PCIE0_AXI_MST0 8
++#define JH7110_STGCLK_PCIE0_APB 9
++#define JH7110_STGCLK_PCIE0_TL 10
++#define JH7110_STGCLK_PCIE1_AXI_MST0 11
++#define JH7110_STGCLK_PCIE1_APB 12
++#define JH7110_STGCLK_PCIE1_TL 13
++#define JH7110_STGCLK_PCIE_SLV_MAIN 14
++#define JH7110_STGCLK_SEC_AHB 15
++#define JH7110_STGCLK_SEC_MISC_AHB 16
++#define JH7110_STGCLK_GRP0_MAIN 17
++#define JH7110_STGCLK_GRP0_BUS 18
++#define JH7110_STGCLK_GRP0_STG 19
++#define JH7110_STGCLK_GRP1_MAIN 20
++#define JH7110_STGCLK_GRP1_BUS 21
++#define JH7110_STGCLK_GRP1_STG 22
++#define JH7110_STGCLK_GRP1_HIFI 23
++#define JH7110_STGCLK_E2_RTC 24
++#define JH7110_STGCLK_E2_CORE 25
++#define JH7110_STGCLK_E2_DBG 26
++#define JH7110_STGCLK_DMA1P_AXI 27
++#define JH7110_STGCLK_DMA1P_AHB 28
++
++#define JH7110_STGCLK_END 29
++
+ #endif /* __DT_BINDINGS_CLOCK_STARFIVE_JH7110_CRG_H__ */
+diff --git a/include/dt-bindings/reset/starfive,jh7110-crg.h b/include/dt-bindings/reset/starfive,jh7110-crg.h
+index d78e38690ceb..4e96ab81dd8e 100644
+--- a/include/dt-bindings/reset/starfive,jh7110-crg.h
++++ b/include/dt-bindings/reset/starfive,jh7110-crg.h
+@@ -1,6 +1,7 @@
+ /* SPDX-License-Identifier: GPL-2.0 OR MIT */
+ /*
+ * Copyright (C) 2022 Emil Renner Berthing <kernel@esmil.dk>
++ * Copyright (C) 2022 StarFive Technology Co., Ltd.
+ */
+
+ #ifndef __DT_BINDINGS_RESET_STARFIVE_JH7110_CRG_H__
+@@ -151,4 +152,31 @@
+
+ #define JH7110_AONRST_END 8
+
++/* STGCRG resets */
++#define JH7110_STGRST_SYSCON 0
++#define JH7110_STGRST_HIFI4_CORE 1
++#define JH7110_STGRST_HIFI4_AXI 2
++#define JH7110_STGRST_SEC_AHB 3
++#define JH7110_STGRST_E24_CORE 4
++#define JH7110_STGRST_DMA1P_AXI 5
++#define JH7110_STGRST_DMA1P_AHB 6
++#define JH7110_STGRST_USB0_AXI 7
++#define JH7110_STGRST_USB0_APB 8
++#define JH7110_STGRST_USB0_UTMI_APB 9
++#define JH7110_STGRST_USB0_PWRUP 10
++#define JH7110_STGRST_PCIE0_AXI_MST0 11
++#define JH7110_STGRST_PCIE0_AXI_SLV0 12
++#define JH7110_STGRST_PCIE0_AXI_SLV 13
++#define JH7110_STGRST_PCIE0_BRG 14
++#define JH7110_STGRST_PCIE0_CORE 15
++#define JH7110_STGRST_PCIE0_APB 16
++#define JH7110_STGRST_PCIE1_AXI_MST0 17
++#define JH7110_STGRST_PCIE1_AXI_SLV0 18
++#define JH7110_STGRST_PCIE1_AXI_SLV 19
++#define JH7110_STGRST_PCIE1_BRG 20
++#define JH7110_STGRST_PCIE1_CORE 21
++#define JH7110_STGRST_PCIE1_APB 22
++
++#define JH7110_STGRST_END 23
++
+ #endif /* __DT_BINDINGS_RESET_STARFIVE_JH7110_CRG_H__ */
+--
+2.20.1
+
--- /dev/null
+From 520841348b93c0913cdefa5abf46fde033d1d57b Mon Sep 17 00:00:00 2001
+From: Zoltan HERPAI <wigyori@uid0.hu>
+Date: Sun, 28 May 2023 18:22:32 +0200
+Subject: [PATCH 56/95] generic/6.1: change ARCH_STARFIVE to SOC_STARFIVE
+
+Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>
+---
+ drivers/clk/starfive/Kconfig | 12 ++++++------
+ drivers/net/ethernet/stmicro/stmmac/Kconfig | 4 ++--
+ drivers/reset/starfive/Kconfig | 6 +++---
+ drivers/watchdog/Kconfig | 4 ++--
+ 4 files changed, 13 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/clk/starfive/Kconfig b/drivers/clk/starfive/Kconfig
+index 71c1148ee5f6..78305ae54c0e 100644
+--- a/drivers/clk/starfive/Kconfig
++++ b/drivers/clk/starfive/Kconfig
+@@ -5,9 +5,9 @@ config CLK_STARFIVE_JH71X0
+
+ config CLK_STARFIVE_JH7100
+ bool "StarFive JH7100 clock support"
+- depends on ARCH_STARFIVE || COMPILE_TEST
++ depends on SOC_STARFIVE || COMPILE_TEST
+ select CLK_STARFIVE_JH71X0
+- default ARCH_STARFIVE
++ default SOC_STARFIVE
+ help
+ Say yes here to support the clock controller on the StarFive JH7100
+ SoC.
+@@ -16,18 +16,18 @@ config CLK_STARFIVE_JH7100_AUDIO
+ tristate "StarFive JH7100 audio clock support"
+ depends on CLK_STARFIVE_JH7100
+ select CLK_STARFIVE_JH71X0
+- default m if ARCH_STARFIVE
++ default m if SOC_STARFIVE
+ help
+ Say Y or M here to support the audio clocks on the StarFive JH7100
+ SoC.
+
+ config CLK_STARFIVE_JH7110_SYS
+ bool "StarFive JH7110 system clock support"
+- depends on ARCH_STARFIVE || COMPILE_TEST
++ depends on SOC_STARFIVE || COMPILE_TEST
+ select AUXILIARY_BUS
+ select CLK_STARFIVE_JH71X0
+ select RESET_STARFIVE_JH7110
+- default ARCH_STARFIVE
++ default SOC_STARFIVE
+ help
+ Say yes here to support the system clock controller on the
+ StarFive JH7110 SoC.
+@@ -38,7 +38,7 @@ config CLK_STARFIVE_JH7110_AON
+ select AUXILIARY_BUS
+ select CLK_STARFIVE_JH71X0
+ select RESET_STARFIVE_JH7110
+- default m if ARCH_STARFIVE
++ default m if SOC_STARFIVE
+ help
+ Say yes here to support the always-on clock controller on the
+ StarFive JH7110 SoC.
+diff --git a/drivers/net/ethernet/stmicro/stmmac/Kconfig b/drivers/net/ethernet/stmicro/stmmac/Kconfig
+index b5e95e6fc4a4..71bb4d515a19 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/Kconfig
++++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig
+@@ -167,9 +167,9 @@ config DWMAC_SOCFPGA
+
+ config DWMAC_STARFIVE
+ tristate "StarFive dwmac support"
+- depends on OF && (ARCH_STARFIVE || COMPILE_TEST)
++ depends on OF && (SOC_STARFIVE || COMPILE_TEST)
+ select MFD_SYSCON
+- default m if ARCH_STARFIVE
++ default m if SOC_STARFIVE
+ help
+ Support for ethernet controllers on StarFive RISC-V SoCs
+
+diff --git a/drivers/reset/starfive/Kconfig b/drivers/reset/starfive/Kconfig
+index 1fa706a2c3dc..c2bb0a7d38b5 100644
+--- a/drivers/reset/starfive/Kconfig
++++ b/drivers/reset/starfive/Kconfig
+@@ -5,9 +5,9 @@ config RESET_STARFIVE_JH71X0
+
+ config RESET_STARFIVE_JH7100
+ bool "StarFive JH7100 Reset Driver"
+- depends on ARCH_STARFIVE || COMPILE_TEST
++ depends on SOC_STARFIVE || COMPILE_TEST
+ select RESET_STARFIVE_JH71X0
+- default ARCH_STARFIVE
++ default SOC_STARFIVE
+ help
+ This enables the reset controller driver for the StarFive JH7100 SoC.
+
+@@ -15,6 +15,6 @@ config RESET_STARFIVE_JH7110
+ bool "StarFive JH7110 Reset Driver"
+ depends on AUXILIARY_BUS && CLK_STARFIVE_JH7110_SYS
+ select RESET_STARFIVE_JH71X0
+- default ARCH_STARFIVE
++ default SOC_STARFIVE
+ help
+ This enables the reset controller driver for the StarFive JH7110 SoC.
+diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
+index 44e0670a76f6..044a8bd060c5 100644
+--- a/drivers/watchdog/Kconfig
++++ b/drivers/watchdog/Kconfig
+@@ -1995,9 +1995,9 @@ config WATCHDOG_RTAS
+
+ config STARFIVE_WATCHDOG
+ tristate "StarFive Watchdog support"
+- depends on ARCH_STARFIVE || COMPILE_TEST
++ depends on SOC_STARFIVE || COMPILE_TEST
+ select WATCHDOG_CORE
+- default ARCH_STARFIVE
++ default SOC_STARFIVE
+ help
+ Say Y here to support the watchdog of StarFive JH7100 and JH7110
+ SoC. This driver can also be built as a module if choose M.
+--
+2.20.1
+
--- /dev/null
+From 9fff4d59826097f98084865bcdb75c14a449fd2a Mon Sep 17 00:00:00 2001
+From: Emil Renner Berthing <emil.renner.berthing@canonical.com>
+Date: Thu, 18 May 2023 18:12:25 +0800
+Subject: [PATCH 57/95] clk: starfive: Add StarFive JH7110 System-Top-Group
+ clock driver
+
+Add driver for the StarFive JH7110 System-Top-Group clock controller.
+
+Co-developed-by: Xingyu Wu <xingyu.wu@starfivetech.com>
+Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
+Signed-off-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
+---
+ drivers/clk/starfive/Kconfig | 11 ++
+ drivers/clk/starfive/Makefile | 1 +
+ .../clk/starfive/clk-starfive-jh7110-stg.c | 173 ++++++++++++++++++
+ 3 files changed, 185 insertions(+)
+ create mode 100644 drivers/clk/starfive/clk-starfive-jh7110-stg.c
+
+diff --git a/drivers/clk/starfive/Kconfig b/drivers/clk/starfive/Kconfig
+index 78305ae54c0e..00f2a9d84eb6 100644
+--- a/drivers/clk/starfive/Kconfig
++++ b/drivers/clk/starfive/Kconfig
+@@ -42,3 +42,14 @@ config CLK_STARFIVE_JH7110_AON
+ help
+ Say yes here to support the always-on clock controller on the
+ StarFive JH7110 SoC.
++
++config CLK_STARFIVE_JH7110_STG
++ tristate "StarFive JH7110 System-Top-Group clock support"
++ depends on CLK_STARFIVE_JH7110_SYS
++ select AUXILIARY_BUS
++ select CLK_STARFIVE_JH71X0
++ select RESET_STARFIVE_JH7110
++ default m if ARCH_STARFIVE
++ help
++ Say yes here to support the System-Top-Group clock controller
++ on the StarFive JH7110 SoC.
+diff --git a/drivers/clk/starfive/Makefile b/drivers/clk/starfive/Makefile
+index f3df7d957b1e..b81e97ee2659 100644
+--- a/drivers/clk/starfive/Makefile
++++ b/drivers/clk/starfive/Makefile
+@@ -6,3 +6,4 @@ obj-$(CONFIG_CLK_STARFIVE_JH7100_AUDIO) += clk-starfive-jh7100-audio.o
+
+ obj-$(CONFIG_CLK_STARFIVE_JH7110_SYS) += clk-starfive-jh7110-sys.o
+ obj-$(CONFIG_CLK_STARFIVE_JH7110_AON) += clk-starfive-jh7110-aon.o
++obj-$(CONFIG_CLK_STARFIVE_JH7110_STG) += clk-starfive-jh7110-stg.o
+diff --git a/drivers/clk/starfive/clk-starfive-jh7110-stg.c b/drivers/clk/starfive/clk-starfive-jh7110-stg.c
+new file mode 100644
+index 000000000000..dafcb7190592
+--- /dev/null
++++ b/drivers/clk/starfive/clk-starfive-jh7110-stg.c
+@@ -0,0 +1,173 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * StarFive JH7110 System-Top-Group Clock Driver
++ *
++ * Copyright (C) 2022 Emil Renner Berthing <kernel@esmil.dk>
++ * Copyright (C) 2022 StarFive Technology Co., Ltd.
++ */
++
++#include <linux/clk-provider.h>
++#include <linux/io.h>
++#include <linux/platform_device.h>
++
++#include <dt-bindings/clock/starfive,jh7110-crg.h>
++
++#include "clk-starfive-jh7110.h"
++
++/* external clocks */
++#define JH7110_STGCLK_OSC (JH7110_STGCLK_END + 0)
++#define JH7110_STGCLK_HIFI4_CORE (JH7110_STGCLK_END + 1)
++#define JH7110_STGCLK_STG_AXIAHB (JH7110_STGCLK_END + 2)
++#define JH7110_STGCLK_USB_125M (JH7110_STGCLK_END + 3)
++#define JH7110_STGCLK_CPU_BUS (JH7110_STGCLK_END + 4)
++#define JH7110_STGCLK_HIFI4_AXI (JH7110_STGCLK_END + 5)
++#define JH7110_STGCLK_NOCSTG_BUS (JH7110_STGCLK_END + 6)
++#define JH7110_STGCLK_APB_BUS (JH7110_STGCLK_END + 7)
++#define JH7110_STGCLK_EXT_END (JH7110_STGCLK_END + 8)
++
++static const struct jh71x0_clk_data jh7110_stgclk_data[] = {
++ /* hifi4 */
++ JH71X0_GATE(JH7110_STGCLK_HIFI4_CLK_CORE, "hifi4_clk_core", 0,
++ JH7110_STGCLK_HIFI4_CORE),
++ /* usb */
++ JH71X0_GATE(JH7110_STGCLK_USB0_APB, "usb0_apb", 0, JH7110_STGCLK_APB_BUS),
++ JH71X0_GATE(JH7110_STGCLK_USB0_UTMI_APB, "usb0_utmi_apb", 0, JH7110_STGCLK_APB_BUS),
++ JH71X0_GATE(JH7110_STGCLK_USB0_AXI, "usb0_axi", 0, JH7110_STGCLK_STG_AXIAHB),
++ JH71X0_GDIV(JH7110_STGCLK_USB0_LPM, "usb0_lpm", 0, 2, JH7110_STGCLK_OSC),
++ JH71X0_GDIV(JH7110_STGCLK_USB0_STB, "usb0_stb", 0, 4, JH7110_STGCLK_OSC),
++ JH71X0_GATE(JH7110_STGCLK_USB0_APP_125, "usb0_app_125", 0, JH7110_STGCLK_USB_125M),
++ JH71X0__DIV(JH7110_STGCLK_USB0_REFCLK, "usb0_refclk", 2, JH7110_STGCLK_OSC),
++ /* pci-e */
++ JH71X0_GATE(JH7110_STGCLK_PCIE0_AXI_MST0, "pcie0_axi_mst0", 0,
++ JH7110_STGCLK_STG_AXIAHB),
++ JH71X0_GATE(JH7110_STGCLK_PCIE0_APB, "pcie0_apb", 0, JH7110_STGCLK_APB_BUS),
++ JH71X0_GATE(JH7110_STGCLK_PCIE0_TL, "pcie0_tl", 0, JH7110_STGCLK_STG_AXIAHB),
++ JH71X0_GATE(JH7110_STGCLK_PCIE1_AXI_MST0, "pcie1_axi_mst0", 0,
++ JH7110_STGCLK_STG_AXIAHB),
++ JH71X0_GATE(JH7110_STGCLK_PCIE1_APB, "pcie1_apb", 0, JH7110_STGCLK_APB_BUS),
++ JH71X0_GATE(JH7110_STGCLK_PCIE1_TL, "pcie1_tl", 0, JH7110_STGCLK_STG_AXIAHB),
++ JH71X0_GATE(JH7110_STGCLK_PCIE_SLV_MAIN, "pcie_slv_main", CLK_IS_CRITICAL,
++ JH7110_STGCLK_STG_AXIAHB),
++ /* security */
++ JH71X0_GATE(JH7110_STGCLK_SEC_AHB, "sec_ahb", 0, JH7110_STGCLK_STG_AXIAHB),
++ JH71X0_GATE(JH7110_STGCLK_SEC_MISC_AHB, "sec_misc_ahb", 0, JH7110_STGCLK_STG_AXIAHB),
++ /* stg mtrx */
++ JH71X0_GATE(JH7110_STGCLK_GRP0_MAIN, "mtrx_grp0_main", CLK_IS_CRITICAL,
++ JH7110_STGCLK_CPU_BUS),
++ JH71X0_GATE(JH7110_STGCLK_GRP0_BUS, "mtrx_grp0_bus", CLK_IS_CRITICAL,
++ JH7110_STGCLK_NOCSTG_BUS),
++ JH71X0_GATE(JH7110_STGCLK_GRP0_STG, "mtrx_grp0_stg", CLK_IS_CRITICAL,
++ JH7110_STGCLK_STG_AXIAHB),
++ JH71X0_GATE(JH7110_STGCLK_GRP1_MAIN, "mtrx_grp1_main", CLK_IS_CRITICAL,
++ JH7110_STGCLK_CPU_BUS),
++ JH71X0_GATE(JH7110_STGCLK_GRP1_BUS, "mtrx_grp1_bus", CLK_IS_CRITICAL,
++ JH7110_STGCLK_NOCSTG_BUS),
++ JH71X0_GATE(JH7110_STGCLK_GRP1_STG, "mtrx_grp1_stg", CLK_IS_CRITICAL,
++ JH7110_STGCLK_STG_AXIAHB),
++ JH71X0_GATE(JH7110_STGCLK_GRP1_HIFI, "mtrx_grp1_hifi", CLK_IS_CRITICAL,
++ JH7110_STGCLK_HIFI4_AXI),
++ /* e24_rvpi */
++ JH71X0_GDIV(JH7110_STGCLK_E2_RTC, "e2_rtc", 0, 24, JH7110_STGCLK_OSC),
++ JH71X0_GATE(JH7110_STGCLK_E2_CORE, "e2_core", 0, JH7110_STGCLK_STG_AXIAHB),
++ JH71X0_GATE(JH7110_STGCLK_E2_DBG, "e2_dbg", 0, JH7110_STGCLK_STG_AXIAHB),
++ /* dw_sgdma1p */
++ JH71X0_GATE(JH7110_STGCLK_DMA1P_AXI, "dma1p_axi", 0, JH7110_STGCLK_STG_AXIAHB),
++ JH71X0_GATE(JH7110_STGCLK_DMA1P_AHB, "dma1p_ahb", 0, JH7110_STGCLK_STG_AXIAHB),
++};
++
++static struct clk_hw *jh7110_stgclk_get(struct of_phandle_args *clkspec, void *data)
++{
++ struct jh71x0_clk_priv *priv = data;
++ unsigned int idx = clkspec->args[0];
++
++ if (idx < JH7110_STGCLK_END)
++ return &priv->reg[idx].hw;
++
++ return ERR_PTR(-EINVAL);
++}
++
++static int jh7110_stgcrg_probe(struct platform_device *pdev)
++{
++ struct jh71x0_clk_priv *priv;
++ unsigned int idx;
++ int ret;
++
++ priv = devm_kzalloc(&pdev->dev, struct_size(priv, reg, JH7110_STGCLK_END),
++ GFP_KERNEL);
++ if (!priv)
++ return -ENOMEM;
++
++ spin_lock_init(&priv->rmw_lock);
++ priv->dev = &pdev->dev;
++ priv->base = devm_platform_ioremap_resource(pdev, 0);
++ if (IS_ERR(priv->base))
++ return PTR_ERR(priv->base);
++
++ for (idx = 0; idx < JH7110_STGCLK_END; idx++) {
++ u32 max = jh7110_stgclk_data[idx].max;
++ struct clk_parent_data parents[4] = {};
++ struct clk_init_data init = {
++ .name = jh7110_stgclk_data[idx].name,
++ .ops = starfive_jh71x0_clk_ops(max),
++ .parent_data = parents,
++ .num_parents =
++ ((max & JH71X0_CLK_MUX_MASK) >> JH71X0_CLK_MUX_SHIFT) + 1,
++ .flags = jh7110_stgclk_data[idx].flags,
++ };
++ struct jh71x0_clk *clk = &priv->reg[idx];
++ const char *fw_name[JH7110_STGCLK_EXT_END - JH7110_STGCLK_END] = {
++ "osc",
++ "hifi4_core",
++ "stg_axiahb",
++ "usb_125m",
++ "cpu_bus",
++ "hifi4_axi",
++ "nocstg_bus",
++ "apb_bus"
++ };
++ unsigned int i;
++
++ for (i = 0; i < init.num_parents; i++) {
++ unsigned int pidx = jh7110_stgclk_data[idx].parents[i];
++
++ if (pidx < JH7110_STGCLK_END)
++ parents[i].hw = &priv->reg[pidx].hw;
++ else if (pidx < JH7110_STGCLK_EXT_END)
++ parents[i].fw_name = fw_name[pidx - JH7110_STGCLK_END];
++ }
++
++ clk->hw.init = &init;
++ clk->idx = idx;
++ clk->max_div = max & JH71X0_CLK_DIV_MASK;
++
++ ret = devm_clk_hw_register(&pdev->dev, &clk->hw);
++ if (ret)
++ return ret;
++ }
++
++ ret = devm_of_clk_add_hw_provider(&pdev->dev, jh7110_stgclk_get, priv);
++ if (ret)
++ return ret;
++
++ return jh7110_reset_controller_register(priv, "rst-stg", 2);
++}
++
++static const struct of_device_id jh7110_stgcrg_match[] = {
++ { .compatible = "starfive,jh7110-stgcrg" },
++ { /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(of, jh7110_stgcrg_match);
++
++static struct platform_driver jh7110_stgcrg_driver = {
++ .probe = jh7110_stgcrg_probe,
++ .driver = {
++ .name = "clk-starfive-jh7110-stg",
++ .of_match_table = jh7110_stgcrg_match,
++ },
++};
++module_platform_driver(jh7110_stgcrg_driver);
++
++MODULE_AUTHOR("Xingyu Wu <xingyu.wu@starfivetech.com>");
++MODULE_AUTHOR("Emil Renner Berthing <kernel@esmil.dk>");
++MODULE_DESCRIPTION("StarFive JH7110 System-Top-Group clock driver");
++MODULE_LICENSE("GPL");
+--
+2.20.1
+
--- /dev/null
+From 1fb4a879aabe81dfc5ea664870bb19db74c1a6e4 Mon Sep 17 00:00:00 2001
+From: Xingyu Wu <xingyu.wu@starfivetech.com>
+Date: Thu, 18 May 2023 18:12:26 +0800
+Subject: [PATCH 58/95] dt-bindings: clock: Add StarFive JH7110
+ Image-Signal-Process clock and reset generator
+
+Add bindings for the Image-Signal-Process clock and reset
+generator (ISPCRG) on the JH7110 RISC-V SoC by StarFive Ltd.
+
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
+---
+ .../clock/starfive,jh7110-ispcrg.yaml | 87 +++++++++++++++++++
+ .../dt-bindings/clock/starfive,jh7110-crg.h | 18 ++++
+ .../dt-bindings/reset/starfive,jh7110-crg.h | 16 ++++
+ 3 files changed, 121 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/clock/starfive,jh7110-ispcrg.yaml
+
+diff --git a/Documentation/devicetree/bindings/clock/starfive,jh7110-ispcrg.yaml b/Documentation/devicetree/bindings/clock/starfive,jh7110-ispcrg.yaml
+new file mode 100644
+index 000000000000..3b8b85be5cd0
+--- /dev/null
++++ b/Documentation/devicetree/bindings/clock/starfive,jh7110-ispcrg.yaml
+@@ -0,0 +1,87 @@
++# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/clock/starfive,jh7110-ispcrg.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: StarFive JH7110 Image-Signal-Process Clock and Reset Generator
++
++maintainers:
++ - Xingyu Wu <xingyu.wu@starfivetech.com>
++
++properties:
++ compatible:
++ const: starfive,jh7110-ispcrg
++
++ reg:
++ maxItems: 1
++
++ clocks:
++ items:
++ - description: ISP Top core
++ - description: ISP Top Axi
++ - description: NOC ISP Bus
++ - description: external DVP
++
++ clock-names:
++ items:
++ - const: isp_top_core
++ - const: isp_top_axi
++ - const: noc_bus_isp_axi
++ - const: dvp_clk
++
++ resets:
++ items:
++ - description: ISP Top core
++ - description: ISP Top Axi
++ - description: NOC ISP Bus
++
++ '#clock-cells':
++ const: 1
++ description:
++ See <dt-bindings/clock/starfive,jh7110-crg.h> for valid indices.
++
++ '#reset-cells':
++ const: 1
++ description:
++ See <dt-bindings/reset/starfive,jh7110-crg.h> for valid indices.
++
++ power-domains:
++ maxItems: 1
++ description:
++ ISP domain power
++
++required:
++ - compatible
++ - reg
++ - clocks
++ - clock-names
++ - resets
++ - '#clock-cells'
++ - '#reset-cells'
++ - power-domains
++
++additionalProperties: false
++
++examples:
++ - |
++ #include <dt-bindings/clock/starfive,jh7110-crg.h>
++ #include <dt-bindings/power/starfive,jh7110-pmu.h>
++ #include <dt-bindings/reset/starfive,jh7110-crg.h>
++
++ ispcrg: clock-controller@19810000 {
++ compatible = "starfive,jh7110-ispcrg";
++ reg = <0x19810000 0x10000>;
++ clocks = <&syscrg JH7110_SYSCLK_ISP_TOP_CORE>,
++ <&syscrg JH7110_SYSCLK_ISP_TOP_AXI>,
++ <&syscrg JH7110_SYSCLK_NOC_BUS_ISP_AXI>,
++ <&dvp_clk>;
++ clock-names = "isp_top_core", "isp_top_axi",
++ "noc_bus_isp_axi", "dvp_clk";
++ resets = <&syscrg JH7110_SYSRST_ISP_TOP>,
++ <&syscrg JH7110_SYSRST_ISP_TOP_AXI>,
++ <&syscrg JH7110_SYSRST_NOC_BUS_ISP_AXI>;
++ #clock-cells = <1>;
++ #reset-cells = <1>;
++ power-domains = <&pwrc JH7110_PD_ISP>;
++ };
+diff --git a/include/dt-bindings/clock/starfive,jh7110-crg.h b/include/dt-bindings/clock/starfive,jh7110-crg.h
+index 6c8e8b4cf1f6..39acf30db491 100644
+--- a/include/dt-bindings/clock/starfive,jh7110-crg.h
++++ b/include/dt-bindings/clock/starfive,jh7110-crg.h
+@@ -252,4 +252,22 @@
+
+ #define JH7110_STGCLK_END 29
+
++/* ISPCRG clocks */
++#define JH7110_ISPCLK_DOM4_APB_FUNC 0
++#define JH7110_ISPCLK_MIPI_RX0_PXL 1
++#define JH7110_ISPCLK_DVP_INV 2
++#define JH7110_ISPCLK_M31DPHY_CFG_IN 3
++#define JH7110_ISPCLK_M31DPHY_REF_IN 4
++#define JH7110_ISPCLK_M31DPHY_TX_ESC_LAN0 5
++#define JH7110_ISPCLK_VIN_APB 6
++#define JH7110_ISPCLK_VIN_SYS 7
++#define JH7110_ISPCLK_VIN_PIXEL_IF0 8
++#define JH7110_ISPCLK_VIN_PIXEL_IF1 9
++#define JH7110_ISPCLK_VIN_PIXEL_IF2 10
++#define JH7110_ISPCLK_VIN_PIXEL_IF3 11
++#define JH7110_ISPCLK_VIN_P_AXI_WR 12
++#define JH7110_ISPCLK_ISPV2_TOP_WRAPPER_C 13
++
++#define JH7110_ISPCLK_END 14
++
+ #endif /* __DT_BINDINGS_CLOCK_STARFIVE_JH7110_CRG_H__ */
+diff --git a/include/dt-bindings/reset/starfive,jh7110-crg.h b/include/dt-bindings/reset/starfive,jh7110-crg.h
+index 4e96ab81dd8e..2c5d9dcefffa 100644
+--- a/include/dt-bindings/reset/starfive,jh7110-crg.h
++++ b/include/dt-bindings/reset/starfive,jh7110-crg.h
+@@ -179,4 +179,20 @@
+
+ #define JH7110_STGRST_END 23
+
++/* ISPCRG resets */
++#define JH7110_ISPRST_ISPV2_TOP_WRAPPER_P 0
++#define JH7110_ISPRST_ISPV2_TOP_WRAPPER_C 1
++#define JH7110_ISPRST_M31DPHY_HW 2
++#define JH7110_ISPRST_M31DPHY_B09_AON 3
++#define JH7110_ISPRST_VIN_APB 4
++#define JH7110_ISPRST_VIN_PIXEL_IF0 5
++#define JH7110_ISPRST_VIN_PIXEL_IF1 6
++#define JH7110_ISPRST_VIN_PIXEL_IF2 7
++#define JH7110_ISPRST_VIN_PIXEL_IF3 8
++#define JH7110_ISPRST_VIN_SYS 9
++#define JH7110_ISPRST_VIN_P_AXI_RD 10
++#define JH7110_ISPRST_VIN_P_AXI_WR 11
++
++#define JH7110_ISPRST_END 12
++
+ #endif /* __DT_BINDINGS_RESET_STARFIVE_JH7110_CRG_H__ */
+--
+2.20.1
+
--- /dev/null
+From 3a797a3b3c3fda679407b6d056f9f9288632f816 Mon Sep 17 00:00:00 2001
+From: Xingyu Wu <xingyu.wu@starfivetech.com>
+Date: Thu, 18 May 2023 18:12:27 +0800
+Subject: [PATCH 59/95] clk: starfive: Add StarFive JH7110 Image-Signal-Process
+ clock driver
+
+Add driver for the StarFive JH7110 Image-Signal-Process clock controller.
+And these clock controllers should power on and enable the clocks from
+SYSCRG first before registering.
+
+Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
+---
+ drivers/clk/starfive/Kconfig | 11 +
+ drivers/clk/starfive/Makefile | 1 +
+ .../clk/starfive/clk-starfive-jh7110-isp.c | 232 ++++++++++++++++++
+ drivers/clk/starfive/clk-starfive-jh7110.h | 6 +
+ 4 files changed, 250 insertions(+)
+ create mode 100644 drivers/clk/starfive/clk-starfive-jh7110-isp.c
+
+diff --git a/drivers/clk/starfive/Kconfig b/drivers/clk/starfive/Kconfig
+index 00f2a9d84eb6..7f7d0a198d62 100644
+--- a/drivers/clk/starfive/Kconfig
++++ b/drivers/clk/starfive/Kconfig
+@@ -53,3 +53,14 @@ config CLK_STARFIVE_JH7110_STG
+ help
+ Say yes here to support the System-Top-Group clock controller
+ on the StarFive JH7110 SoC.
++
++config CLK_STARFIVE_JH7110_ISP
++ tristate "StarFive JH7110 Image-Signal-Process clock support"
++ depends on CLK_STARFIVE_JH7110_SYS && JH71XX_PMU
++ select AUXILIARY_BUS
++ select CLK_STARFIVE_JH71X0
++ select RESET_STARFIVE_JH7110
++ default m if ARCH_STARFIVE
++ help
++ Say yes here to support the Image-Signal-Process clock controller
++ on the StarFive JH7110 SoC.
+diff --git a/drivers/clk/starfive/Makefile b/drivers/clk/starfive/Makefile
+index b81e97ee2659..76fb9f8d628b 100644
+--- a/drivers/clk/starfive/Makefile
++++ b/drivers/clk/starfive/Makefile
+@@ -7,3 +7,4 @@ obj-$(CONFIG_CLK_STARFIVE_JH7100_AUDIO) += clk-starfive-jh7100-audio.o
+ obj-$(CONFIG_CLK_STARFIVE_JH7110_SYS) += clk-starfive-jh7110-sys.o
+ obj-$(CONFIG_CLK_STARFIVE_JH7110_AON) += clk-starfive-jh7110-aon.o
+ obj-$(CONFIG_CLK_STARFIVE_JH7110_STG) += clk-starfive-jh7110-stg.o
++obj-$(CONFIG_CLK_STARFIVE_JH7110_ISP) += clk-starfive-jh7110-isp.o
+diff --git a/drivers/clk/starfive/clk-starfive-jh7110-isp.c b/drivers/clk/starfive/clk-starfive-jh7110-isp.c
+new file mode 100644
+index 000000000000..7e51447060fe
+--- /dev/null
++++ b/drivers/clk/starfive/clk-starfive-jh7110-isp.c
+@@ -0,0 +1,232 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * StarFive JH7110 Image-Signal-Process Clock Driver
++ *
++ * Copyright (C) 2022-2023 StarFive Technology Co., Ltd.
++ */
++
++#include <linux/clk.h>
++#include <linux/clk-provider.h>
++#include <linux/io.h>
++#include <linux/platform_device.h>
++#include <linux/pm_runtime.h>
++#include <linux/reset.h>
++
++#include <dt-bindings/clock/starfive,jh7110-crg.h>
++
++#include "clk-starfive-jh7110.h"
++
++/* external clocks */
++#define JH7110_ISPCLK_ISP_TOP_CORE (JH7110_ISPCLK_END + 0)
++#define JH7110_ISPCLK_ISP_TOP_AXI (JH7110_ISPCLK_END + 1)
++#define JH7110_ISPCLK_NOC_BUS_ISP_AXI (JH7110_ISPCLK_END + 2)
++#define JH7110_ISPCLK_DVP_CLK (JH7110_ISPCLK_END + 3)
++#define JH7110_ISPCLK_EXT_END (JH7110_ISPCLK_END + 4)
++
++static struct clk_bulk_data jh7110_isp_top_clks[] = {
++ { .id = "isp_top_core" },
++ { .id = "isp_top_axi" }
++};
++
++static const struct jh71x0_clk_data jh7110_ispclk_data[] = {
++ /* syscon */
++ JH71X0__DIV(JH7110_ISPCLK_DOM4_APB_FUNC, "dom4_apb_func", 15,
++ JH7110_ISPCLK_ISP_TOP_AXI),
++ JH71X0__DIV(JH7110_ISPCLK_MIPI_RX0_PXL, "mipi_rx0_pxl", 8,
++ JH7110_ISPCLK_ISP_TOP_CORE),
++ JH71X0__INV(JH7110_ISPCLK_DVP_INV, "dvp_inv", JH7110_ISPCLK_DVP_CLK),
++ /* vin */
++ JH71X0__DIV(JH7110_ISPCLK_M31DPHY_CFG_IN, "m31dphy_cfg_in", 16,
++ JH7110_ISPCLK_ISP_TOP_CORE),
++ JH71X0__DIV(JH7110_ISPCLK_M31DPHY_REF_IN, "m31dphy_ref_in", 16,
++ JH7110_ISPCLK_ISP_TOP_CORE),
++ JH71X0__DIV(JH7110_ISPCLK_M31DPHY_TX_ESC_LAN0, "m31dphy_tx_esc_lan0", 60,
++ JH7110_ISPCLK_ISP_TOP_CORE),
++ JH71X0_GATE(JH7110_ISPCLK_VIN_APB, "vin_apb", 0,
++ JH7110_ISPCLK_DOM4_APB_FUNC),
++ JH71X0__DIV(JH7110_ISPCLK_VIN_SYS, "vin_sys", 8, JH7110_ISPCLK_ISP_TOP_CORE),
++ JH71X0_GATE(JH7110_ISPCLK_VIN_PIXEL_IF0, "vin_pixel_if0", 0,
++ JH7110_ISPCLK_MIPI_RX0_PXL),
++ JH71X0_GATE(JH7110_ISPCLK_VIN_PIXEL_IF1, "vin_pixel_if1", 0,
++ JH7110_ISPCLK_MIPI_RX0_PXL),
++ JH71X0_GATE(JH7110_ISPCLK_VIN_PIXEL_IF2, "vin_pixel_if2", 0,
++ JH7110_ISPCLK_MIPI_RX0_PXL),
++ JH71X0_GATE(JH7110_ISPCLK_VIN_PIXEL_IF3, "vin_pixel_if3", 0,
++ JH7110_ISPCLK_MIPI_RX0_PXL),
++ JH71X0__MUX(JH7110_ISPCLK_VIN_P_AXI_WR, "vin_p_axi_wr", 2,
++ JH7110_ISPCLK_MIPI_RX0_PXL,
++ JH7110_ISPCLK_DVP_INV),
++ /* ispv2_top_wrapper */
++ JH71X0_GMUX(JH7110_ISPCLK_ISPV2_TOP_WRAPPER_C, "ispv2_top_wrapper_c", 0, 2,
++ JH7110_ISPCLK_MIPI_RX0_PXL,
++ JH7110_ISPCLK_DVP_INV),
++};
++
++static inline int jh7110_isp_top_rst_init(struct jh71x0_clk_priv *priv)
++{
++ struct reset_control *top_rsts;
++
++ /* The resets should be shared and other ISP modules will use its. */
++ top_rsts = devm_reset_control_array_get_shared(priv->dev);
++ if (IS_ERR(top_rsts))
++ return dev_err_probe(priv->dev, PTR_ERR(top_rsts),
++ "failed to get top resets\n");
++
++ return reset_control_deassert(top_rsts);
++}
++
++static struct clk_hw *jh7110_ispclk_get(struct of_phandle_args *clkspec, void *data)
++{
++ struct jh71x0_clk_priv *priv = data;
++ unsigned int idx = clkspec->args[0];
++
++ if (idx < JH7110_ISPCLK_END)
++ return &priv->reg[idx].hw;
++
++ return ERR_PTR(-EINVAL);
++}
++
++#ifdef CONFIG_PM
++static int jh7110_ispcrg_suspend(struct device *dev)
++{
++ struct top_sysclk *top = dev_get_drvdata(dev);
++
++ clk_bulk_disable_unprepare(top->top_clks_num, top->top_clks);
++
++ return 0;
++}
++
++static int jh7110_ispcrg_resume(struct device *dev)
++{
++ struct top_sysclk *top = dev_get_drvdata(dev);
++
++ return clk_bulk_prepare_enable(top->top_clks_num, top->top_clks);
++}
++#endif
++
++static const struct dev_pm_ops jh7110_ispcrg_pm_ops = {
++ SET_RUNTIME_PM_OPS(jh7110_ispcrg_suspend, jh7110_ispcrg_resume, NULL)
++};
++
++static int jh7110_ispcrg_probe(struct platform_device *pdev)
++{
++ struct jh71x0_clk_priv *priv;
++ struct top_sysclk *top;
++ unsigned int idx;
++ int ret;
++
++ priv = devm_kzalloc(&pdev->dev,
++ struct_size(priv, reg, JH7110_ISPCLK_END),
++ GFP_KERNEL);
++ if (!priv)
++ return -ENOMEM;
++
++ top = devm_kzalloc(&pdev->dev, sizeof(*top), GFP_KERNEL);
++ if (!top)
++ return -ENOMEM;
++
++ spin_lock_init(&priv->rmw_lock);
++ priv->dev = &pdev->dev;
++ priv->base = devm_platform_ioremap_resource(pdev, 0);
++ if (IS_ERR(priv->base))
++ return PTR_ERR(priv->base);
++
++ top->top_clks = jh7110_isp_top_clks;
++ top->top_clks_num = ARRAY_SIZE(jh7110_isp_top_clks);
++ ret = devm_clk_bulk_get(priv->dev, top->top_clks_num, top->top_clks);
++ if (ret)
++ return dev_err_probe(priv->dev, ret, "failed to get main clocks\n");
++ dev_set_drvdata(priv->dev, top);
++
++ /* enable power domain and clocks */
++ pm_runtime_enable(priv->dev);
++ ret = pm_runtime_get_sync(priv->dev);
++ if (ret < 0)
++ return dev_err_probe(priv->dev, ret, "failed to turn on power\n");
++
++ ret = jh7110_isp_top_rst_init(priv);
++ if (ret)
++ goto err_exit;
++
++ for (idx = 0; idx < JH7110_ISPCLK_END; idx++) {
++ u32 max = jh7110_ispclk_data[idx].max;
++ struct clk_parent_data parents[4] = {};
++ struct clk_init_data init = {
++ .name = jh7110_ispclk_data[idx].name,
++ .ops = starfive_jh71x0_clk_ops(max),
++ .parent_data = parents,
++ .num_parents =
++ ((max & JH71X0_CLK_MUX_MASK) >> JH71X0_CLK_MUX_SHIFT) + 1,
++ .flags = jh7110_ispclk_data[idx].flags,
++ };
++ struct jh71x0_clk *clk = &priv->reg[idx];
++ unsigned int i;
++ const char *fw_name[JH7110_ISPCLK_EXT_END - JH7110_ISPCLK_END] = {
++ "isp_top_core",
++ "isp_top_axi",
++ "noc_bus_isp_axi",
++ "dvp_clk"
++ };
++
++ for (i = 0; i < init.num_parents; i++) {
++ unsigned int pidx = jh7110_ispclk_data[idx].parents[i];
++
++ if (pidx < JH7110_ISPCLK_END)
++ parents[i].hw = &priv->reg[pidx].hw;
++ else
++ parents[i].fw_name = fw_name[pidx - JH7110_ISPCLK_END];
++ }
++
++ clk->hw.init = &init;
++ clk->idx = idx;
++ clk->max_div = max & JH71X0_CLK_DIV_MASK;
++
++ ret = devm_clk_hw_register(&pdev->dev, &clk->hw);
++ if (ret)
++ goto err_exit;
++ }
++
++ ret = devm_of_clk_add_hw_provider(&pdev->dev, jh7110_ispclk_get, priv);
++ if (ret)
++ goto err_exit;
++
++ ret = jh7110_reset_controller_register(priv, "rst-isp", 3);
++ if (ret)
++ goto err_exit;
++
++ return 0;
++
++err_exit:
++ pm_runtime_put_sync(priv->dev);
++ pm_runtime_disable(priv->dev);
++ return ret;
++}
++
++static int jh7110_ispcrg_remove(struct platform_device *pdev)
++{
++ pm_runtime_put_sync(&pdev->dev);
++ pm_runtime_disable(&pdev->dev);
++
++ return 0;
++}
++
++static const struct of_device_id jh7110_ispcrg_match[] = {
++ { .compatible = "starfive,jh7110-ispcrg" },
++ { /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(of, jh7110_ispcrg_match);
++
++static struct platform_driver jh7110_ispcrg_driver = {
++ .probe = jh7110_ispcrg_probe,
++ .remove = jh7110_ispcrg_remove,
++ .driver = {
++ .name = "clk-starfive-jh7110-isp",
++ .of_match_table = jh7110_ispcrg_match,
++ .pm = &jh7110_ispcrg_pm_ops,
++ },
++};
++module_platform_driver(jh7110_ispcrg_driver);
++
++MODULE_AUTHOR("Xingyu Wu <xingyu.wu@starfivetech.com>");
++MODULE_DESCRIPTION("StarFive JH7110 Image-Signal-Process clock driver");
++MODULE_LICENSE("GPL");
+diff --git a/drivers/clk/starfive/clk-starfive-jh7110.h b/drivers/clk/starfive/clk-starfive-jh7110.h
+index f29682b8d400..5425fd89394a 100644
+--- a/drivers/clk/starfive/clk-starfive-jh7110.h
++++ b/drivers/clk/starfive/clk-starfive-jh7110.h
+@@ -4,6 +4,12 @@
+
+ #include "clk-starfive-jh71x0.h"
+
++/* top clocks of ISP/VOUT domain from SYSCRG */
++struct top_sysclk {
++ struct clk_bulk_data *top_clks;
++ int top_clks_num;
++};
++
+ int jh7110_reset_controller_register(struct jh71x0_clk_priv *priv,
+ const char *adev_name,
+ u32 adev_id);
+--
+2.20.1
+
--- /dev/null
+From 4df4c0d830af056f6098fb677cda2013900c9381 Mon Sep 17 00:00:00 2001
+From: Xingyu Wu <xingyu.wu@starfivetech.com>
+Date: Thu, 18 May 2023 18:12:28 +0800
+Subject: [PATCH 60/95] dt-bindings: clock: Add StarFive JH7110 Video-Output
+ clock and reset generator
+
+Add bindings for the Video-Output clock and reset generator (VOUTCRG)
+on the JH7110 RISC-V SoC by StarFive Ltd.
+
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
+---
+ .../clock/starfive,jh7110-voutcrg.yaml | 90 +++++++++++++++++++
+ .../dt-bindings/clock/starfive,jh7110-crg.h | 22 +++++
+ .../dt-bindings/reset/starfive,jh7110-crg.h | 16 ++++
+ 3 files changed, 128 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/clock/starfive,jh7110-voutcrg.yaml
+
+diff --git a/Documentation/devicetree/bindings/clock/starfive,jh7110-voutcrg.yaml b/Documentation/devicetree/bindings/clock/starfive,jh7110-voutcrg.yaml
+new file mode 100644
+index 000000000000..af77bd8c86b1
+--- /dev/null
++++ b/Documentation/devicetree/bindings/clock/starfive,jh7110-voutcrg.yaml
+@@ -0,0 +1,90 @@
++# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/clock/starfive,jh7110-voutcrg.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: StarFive JH7110 Video-Output Clock and Reset Generator
++
++maintainers:
++ - Xingyu Wu <xingyu.wu@starfivetech.com>
++
++properties:
++ compatible:
++ const: starfive,jh7110-voutcrg
++
++ reg:
++ maxItems: 1
++
++ clocks:
++ items:
++ - description: Vout Top core
++ - description: Vout Top Ahb
++ - description: Vout Top Axi
++ - description: Vout Top HDMI MCLK
++ - description: I2STX0 BCLK
++ - description: external HDMI pixel
++
++ clock-names:
++ items:
++ - const: vout_src
++ - const: vout_top_ahb
++ - const: vout_top_axi
++ - const: vout_top_hdmitx0_mclk
++ - const: i2stx0_bclk
++ - const: hdmitx0_pixelclk
++
++ resets:
++ maxItems: 1
++ description: Vout Top core
++
++ '#clock-cells':
++ const: 1
++ description:
++ See <dt-bindings/clock/starfive,jh7110-crg.h> for valid indices.
++
++ '#reset-cells':
++ const: 1
++ description:
++ See <dt-bindings/reset/starfive,jh7110-crg.h> for valid indices.
++
++ power-domains:
++ maxItems: 1
++ description:
++ Vout domain power
++
++required:
++ - compatible
++ - reg
++ - clocks
++ - clock-names
++ - resets
++ - '#clock-cells'
++ - '#reset-cells'
++ - power-domains
++
++additionalProperties: false
++
++examples:
++ - |
++ #include <dt-bindings/clock/starfive,jh7110-crg.h>
++ #include <dt-bindings/power/starfive,jh7110-pmu.h>
++ #include <dt-bindings/reset/starfive,jh7110-crg.h>
++
++ voutcrg: clock-controller@295C0000 {
++ compatible = "starfive,jh7110-voutcrg";
++ reg = <0x295C0000 0x10000>;
++ clocks = <&syscrg JH7110_SYSCLK_VOUT_SRC>,
++ <&syscrg JH7110_SYSCLK_VOUT_TOP_AHB>,
++ <&syscrg JH7110_SYSCLK_VOUT_TOP_AXI>,
++ <&syscrg JH7110_SYSCLK_VOUT_TOP_HDMITX0_MCLK>,
++ <&syscrg JH7110_SYSCLK_I2STX0_BCLK>,
++ <&hdmitx0_pixelclk>;
++ clock-names = "vout_src", "vout_top_ahb",
++ "vout_top_axi", "vout_top_hdmitx0_mclk",
++ "i2stx0_bclk", "hdmitx0_pixelclk";
++ resets = <&syscrg JH7110_SYSRST_VOUT_TOP_SRC>;
++ #clock-cells = <1>;
++ #reset-cells = <1>;
++ power-domains = <&pwrc JH7110_PD_VOUT>;
++ };
+diff --git a/include/dt-bindings/clock/starfive,jh7110-crg.h b/include/dt-bindings/clock/starfive,jh7110-crg.h
+index 39acf30db491..016227c64a27 100644
+--- a/include/dt-bindings/clock/starfive,jh7110-crg.h
++++ b/include/dt-bindings/clock/starfive,jh7110-crg.h
+@@ -270,4 +270,26 @@
+
+ #define JH7110_ISPCLK_END 14
+
++/* VOUTCRG clocks */
++#define JH7110_VOUTCLK_APB 0
++#define JH7110_VOUTCLK_DC8200_PIX 1
++#define JH7110_VOUTCLK_DSI_SYS 2
++#define JH7110_VOUTCLK_TX_ESC 3
++#define JH7110_VOUTCLK_DC8200_AXI 4
++#define JH7110_VOUTCLK_DC8200_CORE 5
++#define JH7110_VOUTCLK_DC8200_AHB 6
++#define JH7110_VOUTCLK_DC8200_PIX0 7
++#define JH7110_VOUTCLK_DC8200_PIX1 8
++#define JH7110_VOUTCLK_DOM_VOUT_TOP_LCD 9
++#define JH7110_VOUTCLK_DSITX_APB 10
++#define JH7110_VOUTCLK_DSITX_SYS 11
++#define JH7110_VOUTCLK_DSITX_DPI 12
++#define JH7110_VOUTCLK_DSITX_TXESC 13
++#define JH7110_VOUTCLK_MIPITX_DPHY_TXESC 14
++#define JH7110_VOUTCLK_HDMI_TX_MCLK 15
++#define JH7110_VOUTCLK_HDMI_TX_BCLK 16
++#define JH7110_VOUTCLK_HDMI_TX_SYS 17
++
++#define JH7110_VOUTCLK_END 18
++
+ #endif /* __DT_BINDINGS_CLOCK_STARFIVE_JH7110_CRG_H__ */
+diff --git a/include/dt-bindings/reset/starfive,jh7110-crg.h b/include/dt-bindings/reset/starfive,jh7110-crg.h
+index 2c5d9dcefffa..eaf4a0d84f6a 100644
+--- a/include/dt-bindings/reset/starfive,jh7110-crg.h
++++ b/include/dt-bindings/reset/starfive,jh7110-crg.h
+@@ -195,4 +195,20 @@
+
+ #define JH7110_ISPRST_END 12
+
++/* VOUTCRG resets */
++#define JH7110_VOUTRST_DC8200_AXI 0
++#define JH7110_VOUTRST_DC8200_AHB 1
++#define JH7110_VOUTRST_DC8200_CORE 2
++#define JH7110_VOUTRST_DSITX_DPI 3
++#define JH7110_VOUTRST_DSITX_APB 4
++#define JH7110_VOUTRST_DSITX_RXESC 5
++#define JH7110_VOUTRST_DSITX_SYS 6
++#define JH7110_VOUTRST_DSITX_TXBYTEHS 7
++#define JH7110_VOUTRST_DSITX_TXESC 8
++#define JH7110_VOUTRST_HDMI_TX_HDMI 9
++#define JH7110_VOUTRST_MIPITX_DPHY_SYS 10
++#define JH7110_VOUTRST_MIPITX_DPHY_TXBYTEHS 11
++
++#define JH7110_VOUTRST_END 12
++
+ #endif /* __DT_BINDINGS_RESET_STARFIVE_JH7110_CRG_H__ */
+--
+2.20.1
+
--- /dev/null
+From c12f84d6c12ffdd50bc55112f6d7cce9e6ae4447 Mon Sep 17 00:00:00 2001
+From: Xingyu Wu <xingyu.wu@starfivetech.com>
+Date: Thu, 18 May 2023 18:12:29 +0800
+Subject: [PATCH 61/95] clk: starfive: Add StarFive JH7110 Video-Output clock
+ driver
+
+Add driver for the StarFive JH7110 Video-Output clock controller.
+And these clock controllers should power on and enable the clocks from
+SYSCRG first before registering.
+
+Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
+---
+ drivers/clk/starfive/Kconfig | 11 +
+ drivers/clk/starfive/Makefile | 1 +
+ .../clk/starfive/clk-starfive-jh7110-vout.c | 239 ++++++++++++++++++
+ 3 files changed, 251 insertions(+)
+ create mode 100644 drivers/clk/starfive/clk-starfive-jh7110-vout.c
+
+diff --git a/drivers/clk/starfive/Kconfig b/drivers/clk/starfive/Kconfig
+index 7f7d0a198d62..42485abea0ce 100644
+--- a/drivers/clk/starfive/Kconfig
++++ b/drivers/clk/starfive/Kconfig
+@@ -64,3 +64,14 @@ config CLK_STARFIVE_JH7110_ISP
+ help
+ Say yes here to support the Image-Signal-Process clock controller
+ on the StarFive JH7110 SoC.
++
++config CLK_STARFIVE_JH7110_VOUT
++ tristate "StarFive JH7110 Video-Output clock support"
++ depends on CLK_STARFIVE_JH7110_SYS && JH71XX_PMU
++ select AUXILIARY_BUS
++ select CLK_STARFIVE_JH71X0
++ select RESET_STARFIVE_JH7110
++ default m if ARCH_STARFIVE
++ help
++ Say yes here to support the Video-Output clock controller
++ on the StarFive JH7110 SoC.
+diff --git a/drivers/clk/starfive/Makefile b/drivers/clk/starfive/Makefile
+index 76fb9f8d628b..841377e45bb6 100644
+--- a/drivers/clk/starfive/Makefile
++++ b/drivers/clk/starfive/Makefile
+@@ -8,3 +8,4 @@ obj-$(CONFIG_CLK_STARFIVE_JH7110_SYS) += clk-starfive-jh7110-sys.o
+ obj-$(CONFIG_CLK_STARFIVE_JH7110_AON) += clk-starfive-jh7110-aon.o
+ obj-$(CONFIG_CLK_STARFIVE_JH7110_STG) += clk-starfive-jh7110-stg.o
+ obj-$(CONFIG_CLK_STARFIVE_JH7110_ISP) += clk-starfive-jh7110-isp.o
++obj-$(CONFIG_CLK_STARFIVE_JH7110_VOUT) += clk-starfive-jh7110-vout.o
+diff --git a/drivers/clk/starfive/clk-starfive-jh7110-vout.c b/drivers/clk/starfive/clk-starfive-jh7110-vout.c
+new file mode 100644
+index 000000000000..743840e03d81
+--- /dev/null
++++ b/drivers/clk/starfive/clk-starfive-jh7110-vout.c
+@@ -0,0 +1,239 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * StarFive JH7110 Video-Output Clock Driver
++ *
++ * Copyright (C) 2022-2023 StarFive Technology Co., Ltd.
++ */
++
++#include <linux/clk.h>
++#include <linux/clk-provider.h>
++#include <linux/io.h>
++#include <linux/platform_device.h>
++#include <linux/pm_runtime.h>
++#include <linux/reset.h>
++
++#include <dt-bindings/clock/starfive,jh7110-crg.h>
++
++#include "clk-starfive-jh7110.h"
++
++/* external clocks */
++#define JH7110_VOUTCLK_VOUT_SRC (JH7110_VOUTCLK_END + 0)
++#define JH7110_VOUTCLK_VOUT_TOP_AHB (JH7110_VOUTCLK_END + 1)
++#define JH7110_VOUTCLK_VOUT_TOP_AXI (JH7110_VOUTCLK_END + 2)
++#define JH7110_VOUTCLK_VOUT_TOP_HDMITX0_MCLK (JH7110_VOUTCLK_END + 3)
++#define JH7110_VOUTCLK_I2STX0_BCLK (JH7110_VOUTCLK_END + 4)
++#define JH7110_VOUTCLK_HDMITX0_PIXELCLK (JH7110_VOUTCLK_END + 5)
++#define JH7110_VOUTCLK_EXT_END (JH7110_VOUTCLK_END + 6)
++
++static struct clk_bulk_data jh7110_vout_top_clks[] = {
++ { .id = "vout_src" },
++ { .id = "vout_top_ahb" }
++};
++
++static const struct jh71x0_clk_data jh7110_voutclk_data[] = {
++ /* divider */
++ JH71X0__DIV(JH7110_VOUTCLK_APB, "apb", 8, JH7110_VOUTCLK_VOUT_TOP_AHB),
++ JH71X0__DIV(JH7110_VOUTCLK_DC8200_PIX, "dc8200_pix", 63, JH7110_VOUTCLK_VOUT_SRC),
++ JH71X0__DIV(JH7110_VOUTCLK_DSI_SYS, "dsi_sys", 31, JH7110_VOUTCLK_VOUT_SRC),
++ JH71X0__DIV(JH7110_VOUTCLK_TX_ESC, "tx_esc", 31, JH7110_VOUTCLK_VOUT_TOP_AHB),
++ /* dc8200 */
++ JH71X0_GATE(JH7110_VOUTCLK_DC8200_AXI, "dc8200_axi", 0, JH7110_VOUTCLK_VOUT_TOP_AXI),
++ JH71X0_GATE(JH7110_VOUTCLK_DC8200_CORE, "dc8200_core", 0, JH7110_VOUTCLK_VOUT_TOP_AXI),
++ JH71X0_GATE(JH7110_VOUTCLK_DC8200_AHB, "dc8200_ahb", 0, JH7110_VOUTCLK_VOUT_TOP_AHB),
++ JH71X0_GMUX(JH7110_VOUTCLK_DC8200_PIX0, "dc8200_pix0", 0, 2,
++ JH7110_VOUTCLK_DC8200_PIX,
++ JH7110_VOUTCLK_HDMITX0_PIXELCLK),
++ JH71X0_GMUX(JH7110_VOUTCLK_DC8200_PIX1, "dc8200_pix1", 0, 2,
++ JH7110_VOUTCLK_DC8200_PIX,
++ JH7110_VOUTCLK_HDMITX0_PIXELCLK),
++ /* LCD */
++ JH71X0_GMUX(JH7110_VOUTCLK_DOM_VOUT_TOP_LCD, "dom_vout_top_lcd", 0, 2,
++ JH7110_VOUTCLK_DC8200_PIX0,
++ JH7110_VOUTCLK_DC8200_PIX1),
++ /* dsiTx */
++ JH71X0_GATE(JH7110_VOUTCLK_DSITX_APB, "dsiTx_apb", 0, JH7110_VOUTCLK_DSI_SYS),
++ JH71X0_GATE(JH7110_VOUTCLK_DSITX_SYS, "dsiTx_sys", 0, JH7110_VOUTCLK_DSI_SYS),
++ JH71X0_GMUX(JH7110_VOUTCLK_DSITX_DPI, "dsiTx_dpi", 0, 2,
++ JH7110_VOUTCLK_DC8200_PIX,
++ JH7110_VOUTCLK_HDMITX0_PIXELCLK),
++ JH71X0_GATE(JH7110_VOUTCLK_DSITX_TXESC, "dsiTx_txesc", 0, JH7110_VOUTCLK_TX_ESC),
++ /* mipitx DPHY */
++ JH71X0_GATE(JH7110_VOUTCLK_MIPITX_DPHY_TXESC, "mipitx_dphy_txesc", 0,
++ JH7110_VOUTCLK_TX_ESC),
++ /* hdmi */
++ JH71X0_GATE(JH7110_VOUTCLK_HDMI_TX_MCLK, "hdmi_tx_mclk", 0,
++ JH7110_VOUTCLK_VOUT_TOP_HDMITX0_MCLK),
++ JH71X0_GATE(JH7110_VOUTCLK_HDMI_TX_BCLK, "hdmi_tx_bclk", 0,
++ JH7110_VOUTCLK_I2STX0_BCLK),
++ JH71X0_GATE(JH7110_VOUTCLK_HDMI_TX_SYS, "hdmi_tx_sys", 0, JH7110_VOUTCLK_APB),
++};
++
++static int jh7110_vout_top_rst_init(struct jh71x0_clk_priv *priv)
++{
++ struct reset_control *top_rst;
++
++ /* The reset should be shared and other Vout modules will use its. */
++ top_rst = devm_reset_control_get_shared(priv->dev, NULL);
++ if (IS_ERR(top_rst))
++ return dev_err_probe(priv->dev, PTR_ERR(top_rst), "failed to get top reset\n");
++
++ return reset_control_deassert(top_rst);
++}
++
++static struct clk_hw *jh7110_voutclk_get(struct of_phandle_args *clkspec, void *data)
++{
++ struct jh71x0_clk_priv *priv = data;
++ unsigned int idx = clkspec->args[0];
++
++ if (idx < JH7110_VOUTCLK_END)
++ return &priv->reg[idx].hw;
++
++ return ERR_PTR(-EINVAL);
++}
++
++#ifdef CONFIG_PM
++static int jh7110_voutcrg_suspend(struct device *dev)
++{
++ struct top_sysclk *top = dev_get_drvdata(dev);
++
++ clk_bulk_disable_unprepare(top->top_clks_num, top->top_clks);
++
++ return 0;
++}
++
++static int jh7110_voutcrg_resume(struct device *dev)
++{
++ struct top_sysclk *top = dev_get_drvdata(dev);
++
++ return clk_bulk_prepare_enable(top->top_clks_num, top->top_clks);
++}
++#endif
++
++static const struct dev_pm_ops jh7110_voutcrg_pm_ops = {
++ SET_RUNTIME_PM_OPS(jh7110_voutcrg_suspend, jh7110_voutcrg_resume, NULL)
++};
++
++static int jh7110_voutcrg_probe(struct platform_device *pdev)
++{
++ struct jh71x0_clk_priv *priv;
++ struct top_sysclk *top;
++ unsigned int idx;
++ int ret;
++
++ priv = devm_kzalloc(&pdev->dev,
++ struct_size(priv, reg, JH7110_VOUTCLK_END),
++ GFP_KERNEL);
++ if (!priv)
++ return -ENOMEM;
++
++ top = devm_kzalloc(&pdev->dev, sizeof(*top), GFP_KERNEL);
++ if (!top)
++ return -ENOMEM;
++
++ spin_lock_init(&priv->rmw_lock);
++ priv->dev = &pdev->dev;
++ priv->base = devm_platform_ioremap_resource(pdev, 0);
++ if (IS_ERR(priv->base))
++ return PTR_ERR(priv->base);
++
++ top->top_clks = jh7110_vout_top_clks;
++ top->top_clks_num = ARRAY_SIZE(jh7110_vout_top_clks);
++ ret = devm_clk_bulk_get(priv->dev, top->top_clks_num, top->top_clks);
++ if (ret)
++ return dev_err_probe(priv->dev, ret, "failed to get top clocks\n");
++ dev_set_drvdata(priv->dev, top);
++
++ /* enable power domain and clocks */
++ pm_runtime_enable(priv->dev);
++ ret = pm_runtime_get_sync(priv->dev);
++ if (ret < 0)
++ return dev_err_probe(priv->dev, ret, "failed to turn on power\n");
++
++ ret = jh7110_vout_top_rst_init(priv);
++ if (ret)
++ goto err_exit;
++
++ for (idx = 0; idx < JH7110_VOUTCLK_END; idx++) {
++ u32 max = jh7110_voutclk_data[idx].max;
++ struct clk_parent_data parents[4] = {};
++ struct clk_init_data init = {
++ .name = jh7110_voutclk_data[idx].name,
++ .ops = starfive_jh71x0_clk_ops(max),
++ .parent_data = parents,
++ .num_parents =
++ ((max & JH71X0_CLK_MUX_MASK) >> JH71X0_CLK_MUX_SHIFT) + 1,
++ .flags = jh7110_voutclk_data[idx].flags,
++ };
++ struct jh71x0_clk *clk = &priv->reg[idx];
++ unsigned int i;
++ const char *fw_name[JH7110_VOUTCLK_EXT_END - JH7110_VOUTCLK_END] = {
++ "vout_src",
++ "vout_top_ahb",
++ "vout_top_axi",
++ "vout_top_hdmitx0_mclk",
++ "i2stx0_bclk",
++ "hdmitx0_pixelclk"
++ };
++
++ for (i = 0; i < init.num_parents; i++) {
++ unsigned int pidx = jh7110_voutclk_data[idx].parents[i];
++
++ if (pidx < JH7110_VOUTCLK_END)
++ parents[i].hw = &priv->reg[pidx].hw;
++ else if (pidx < JH7110_VOUTCLK_EXT_END)
++ parents[i].fw_name = fw_name[pidx - JH7110_VOUTCLK_END];
++ }
++
++ clk->hw.init = &init;
++ clk->idx = idx;
++ clk->max_div = max & JH71X0_CLK_DIV_MASK;
++
++ ret = devm_clk_hw_register(&pdev->dev, &clk->hw);
++ if (ret)
++ goto err_exit;
++ }
++
++ ret = devm_of_clk_add_hw_provider(&pdev->dev, jh7110_voutclk_get, priv);
++ if (ret)
++ goto err_exit;
++
++ ret = jh7110_reset_controller_register(priv, "rst-vo", 4);
++ if (ret)
++ goto err_exit;
++
++ return 0;
++
++err_exit:
++ pm_runtime_put_sync(priv->dev);
++ pm_runtime_disable(priv->dev);
++ return ret;
++}
++
++static int jh7110_voutcrg_remove(struct platform_device *pdev)
++{
++ pm_runtime_put_sync(&pdev->dev);
++ pm_runtime_disable(&pdev->dev);
++
++ return 0;
++}
++
++static const struct of_device_id jh7110_voutcrg_match[] = {
++ { .compatible = "starfive,jh7110-voutcrg" },
++ { /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(of, jh7110_voutcrg_match);
++
++static struct platform_driver jh7110_voutcrg_driver = {
++ .probe = jh7110_voutcrg_probe,
++ .remove = jh7110_voutcrg_remove,
++ .driver = {
++ .name = "clk-starfive-jh7110-vout",
++ .of_match_table = jh7110_voutcrg_match,
++ .pm = &jh7110_voutcrg_pm_ops,
++ },
++};
++module_platform_driver(jh7110_voutcrg_driver);
++
++MODULE_AUTHOR("Xingyu Wu <xingyu.wu@starfivetech.com>");
++MODULE_DESCRIPTION("StarFive JH7110 Video-Output clock driver");
++MODULE_LICENSE("GPL");
+--
+2.20.1
+
--- /dev/null
+From 4367f5439a48015032f91b1c1536fc2bbfa606bd Mon Sep 17 00:00:00 2001
+From: Xingyu Wu <xingyu.wu@starfivetech.com>
+Date: Thu, 18 May 2023 18:12:31 +0800
+Subject: [PATCH 62/95] reset: starfive: jh7110: Add StarFive STG/ISP/VOUT
+ resets support
+
+Add new struct members and auxiliary_device_id of resets to support
+System-Top-Group, Image-Signal-Process and Video-Output on the StarFive
+JH7110 SoC.
+
+Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
+---
+ .../reset/starfive/reset-starfive-jh7110.c | 30 +++++++++++++++++++
+ 1 file changed, 30 insertions(+)
+
+diff --git a/drivers/reset/starfive/reset-starfive-jh7110.c b/drivers/reset/starfive/reset-starfive-jh7110.c
+index c1b3a490d951..c51e78965cc4 100644
+--- a/drivers/reset/starfive/reset-starfive-jh7110.c
++++ b/drivers/reset/starfive/reset-starfive-jh7110.c
+@@ -29,6 +29,12 @@ static const struct jh7110_reset_info jh7110_aon_info = {
+ .status_offset = 0x3C,
+ };
+
++static const struct jh7110_reset_info jh7110_stg_info = {
++ .nr_resets = JH7110_STGRST_END,
++ .assert_offset = 0x74,
++ .status_offset = 0x78,
++};
++
+ static int jh7110_reset_probe(struct auxiliary_device *adev,
+ const struct auxiliary_device_id *id)
+ {
+@@ -55,6 +73,10 @@ static const struct auxiliary_device_id jh7110_reset_ids[] = {
+ .name = "clk_starfive_jh7110_sys.rst-aon",
+ .driver_data = (kernel_ulong_t)&jh7110_aon_info,
+ },
++ {
++ .name = "clk_starfive_jh7110_sys.rst-stg",
++ .driver_data = (kernel_ulong_t)&jh7110_stg_info,
++ },
+ { /* sentinel */ }
+ };
+ MODULE_DEVICE_TABLE(auxiliary, jh7110_reset_ids);
+--
+2.20.1
+
--- /dev/null
+From 98ce972b8459457a1a113ca96184f381552e99d1 Mon Sep 17 00:00:00 2001
+From: Walker Chen <walker.chen@starfivetech.com>
+Date: Thu, 18 May 2023 18:12:32 +0800
+Subject: [PATCH 63/95] riscv: dts: starfive: jh7110: add pmu controller node
+
+Add the pmu controller node for the Starfive JH7110 SoC. The PMU needs
+to be used by other modules such as VPU, ISP, etc.
+
+Signed-off-by: Walker Chen <walker.chen@starfivetech.com>
+---
+ arch/riscv/boot/dts/starfive/jh7110.dtsi | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/arch/riscv/boot/dts/starfive/jh7110.dtsi b/arch/riscv/boot/dts/starfive/jh7110.dtsi
+index 7961c90b293f..f3080e0f7c47 100644
+--- a/arch/riscv/boot/dts/starfive/jh7110.dtsi
++++ b/arch/riscv/boot/dts/starfive/jh7110.dtsi
+@@ -543,5 +543,12 @@
+ starfive,sysreg = <&sysreg 0x9c 0x1 0x3e>;
+ status = "disabled";
+ };
++
++ pwrc: power-controller@17030000 {
++ compatible = "starfive,jh7110-pmu";
++ reg = <0x0 0x17030000 0x0 0x10000>;
++ interrupts = <111>;
++ #power-domain-cells = <1>;
++ };
+ };
+ };
+--
+2.20.1
+
--- /dev/null
+From 1abd74a15e81c05dae7f40f63d070b489a9e8d1d Mon Sep 17 00:00:00 2001
+From: Xingyu Wu <xingyu.wu@starfivetech.com>
+Date: Thu, 18 May 2023 18:12:33 +0800
+Subject: [PATCH 64/95] riscv: dts: starfive: jh7110: Add DVP and HDMI TX pixel
+ external clocks
+
+Add DVP and HDMI TX pixel external fixed clocks and the rates are
+74.25MHz and 297MHz.
+
+Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+---
+ .../dts/starfive/jh7110-starfive-visionfive-2.dtsi | 8 ++++++++
+ arch/riscv/boot/dts/starfive/jh7110.dtsi | 12 ++++++++++++
+ 2 files changed, 20 insertions(+)
+
+diff --git a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
+index a132debb9b53..641888db058c 100644
+--- a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
++++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
+@@ -38,6 +38,10 @@
+ };
+ };
+
++&dvp_clk {
++ clock-frequency = <74250000>;
++};
++
+ &gmac0_rgmii_rxin {
+ clock-frequency = <125000000>;
+ };
+@@ -77,6 +81,10 @@
+ clock-frequency = <50000000>;
+ };
+
++&hdmitx0_pixelclk {
++ clock-frequency = <297000000>;
++};
++
+ &i2srx_bclk_ext {
+ clock-frequency = <12288000>;
+ };
+diff --git a/arch/riscv/boot/dts/starfive/jh7110.dtsi b/arch/riscv/boot/dts/starfive/jh7110.dtsi
+index f3080e0f7c47..74d2483a3c33 100644
+--- a/arch/riscv/boot/dts/starfive/jh7110.dtsi
++++ b/arch/riscv/boot/dts/starfive/jh7110.dtsi
+@@ -164,6 +164,12 @@
+ };
+ };
+
++ dvp_clk: dvp-clock {
++ compatible = "fixed-clock";
++ clock-output-names = "dvp_clk";
++ #clock-cells = <0>;
++ };
++
+ gmac0_rgmii_rxin: gmac0-rgmii-rxin-clock {
+ compatible = "fixed-clock";
+ clock-output-names = "gmac0_rgmii_rxin";
+@@ -188,6 +194,12 @@
+ #clock-cells = <0>;
+ };
+
++ hdmitx0_pixelclk: hdmitx0-pixel-clock {
++ compatible = "fixed-clock";
++ clock-output-names = "hdmitx0_pixelclk";
++ #clock-cells = <0>;
++ };
++
+ i2srx_bclk_ext: i2srx-bclk-ext-clock {
+ compatible = "fixed-clock";
+ clock-output-names = "i2srx_bclk_ext";
+--
+2.20.1
+
--- /dev/null
+From 647d7653de9ce303a42077d31f9324f6bdaebb25 Mon Sep 17 00:00:00 2001
+From: Xingyu Wu <xingyu.wu@starfivetech.com>
+Date: Thu, 18 May 2023 18:12:34 +0800
+Subject: [PATCH 65/95] riscv: dts: starfive: jh7110: Add STGCRG/ISPCRG/VOUTCRG
+ nodes
+
+Add STGCRG/ISPCRG/VOUTCRG new node to support JH7110
+System-Top-Group, Image-Signal-Process and Video-Output
+clock and reset drivers for the JH7110 RISC-V SoC.
+
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
+---
+ arch/riscv/boot/dts/starfive/jh7110.dtsi | 55 ++++++++++++++++++++++++
+ 1 file changed, 55 insertions(+)
+
+diff --git a/arch/riscv/boot/dts/starfive/jh7110.dtsi b/arch/riscv/boot/dts/starfive/jh7110.dtsi
+index 74d2483a3c33..35e459923dc1 100644
+--- a/arch/riscv/boot/dts/starfive/jh7110.dtsi
++++ b/arch/riscv/boot/dts/starfive/jh7110.dtsi
+@@ -6,6 +6,7 @@
+
+ /dts-v1/;
+ #include <dt-bindings/clock/starfive,jh7110-crg.h>
++#include <dt-bindings/power/starfive,jh7110-pmu.h>
+ #include <dt-bindings/reset/starfive,jh7110-crg.h>
+
+ / {
+@@ -365,6 +366,25 @@
+ status = "disabled";
+ };
+
++ stgcrg: clock-controller@10230000 {
++ compatible = "starfive,jh7110-stgcrg";
++ reg = <0x0 0x10230000 0x0 0x10000>;
++ clocks = <&osc>,
++ <&syscrg JH7110_SYSCLK_HIFI4_CORE>,
++ <&syscrg JH7110_SYSCLK_STG_AXIAHB>,
++ <&syscrg JH7110_SYSCLK_USB_125M>,
++ <&syscrg JH7110_SYSCLK_CPU_BUS>,
++ <&syscrg JH7110_SYSCLK_HIFI4_AXI>,
++ <&syscrg JH7110_SYSCLK_NOCSTG_BUS>,
++ <&syscrg JH7110_SYSCLK_APB_BUS>;
++ clock-names = "osc", "hifi4_core",
++ "stg_axiahb", "usb_125m",
++ "cpu_bus", "hifi4_axi",
++ "nocstg_bus", "apb_bus";
++ #clock-cells = <1>;
++ #reset-cells = <1>;
++ };
++
+ uart3: serial@12000000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x0 0x12000000 0x0 0x10000>;
+@@ -562,5 +582,40 @@
+ interrupts = <111>;
+ #power-domain-cells = <1>;
+ };
++
++ ispcrg: clock-controller@19810000 {
++ compatible = "starfive,jh7110-ispcrg";
++ reg = <0x0 0x19810000 0x0 0x10000>;
++ clocks = <&syscrg JH7110_SYSCLK_ISP_TOP_CORE>,
++ <&syscrg JH7110_SYSCLK_ISP_TOP_AXI>,
++ <&syscrg JH7110_SYSCLK_NOC_BUS_ISP_AXI>,
++ <&dvp_clk>;
++ clock-names = "isp_top_core", "isp_top_axi",
++ "noc_bus_isp_axi", "dvp_clk";
++ resets = <&syscrg JH7110_SYSRST_ISP_TOP>,
++ <&syscrg JH7110_SYSRST_ISP_TOP_AXI>,
++ <&syscrg JH7110_SYSRST_NOC_BUS_ISP_AXI>;
++ #clock-cells = <1>;
++ #reset-cells = <1>;
++ power-domains = <&pwrc JH7110_PD_ISP>;
++ };
++
++ voutcrg: clock-controller@295c0000 {
++ compatible = "starfive,jh7110-voutcrg";
++ reg = <0x0 0x295c0000 0x0 0x10000>;
++ clocks = <&syscrg JH7110_SYSCLK_VOUT_SRC>,
++ <&syscrg JH7110_SYSCLK_VOUT_TOP_AHB>,
++ <&syscrg JH7110_SYSCLK_VOUT_TOP_AXI>,
++ <&syscrg JH7110_SYSCLK_VOUT_TOP_HDMITX0_MCLK>,
++ <&syscrg JH7110_SYSCLK_I2STX0_BCLK>,
++ <&hdmitx0_pixelclk>;
++ clock-names = "vout_src", "vout_top_ahb",
++ "vout_top_axi", "vout_top_hdmitx0_mclk",
++ "i2stx0_bclk", "hdmitx0_pixelclk";
++ resets = <&syscrg JH7110_SYSRST_VOUT_TOP_SRC>;
++ #clock-cells = <1>;
++ #reset-cells = <1>;
++ power-domains = <&pwrc JH7110_PD_VOUT>;
++ };
+ };
+ };
+--
+2.20.1
+
--- /dev/null
+From 88b6607482a2fa200036b678293caa12ddd9f772 Mon Sep 17 00:00:00 2001
+From: Zoltan HERPAI <wigyori@uid0.hu>
+Date: Sun, 28 May 2023 18:35:00 +0200
+Subject: [PATCH 66/95] dts/6.1: trng: use correct reset/clock identifiers
+
+Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>
+---
+ arch/riscv/boot/dts/starfive/jh7110.dtsi | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/arch/riscv/boot/dts/starfive/jh7110.dtsi b/arch/riscv/boot/dts/starfive/jh7110.dtsi
+index 35e459923dc1..5e6421851ffa 100644
+--- a/arch/riscv/boot/dts/starfive/jh7110.dtsi
++++ b/arch/riscv/boot/dts/starfive/jh7110.dtsi
+@@ -427,10 +427,10 @@
+ rng: rng@1600c000 {
+ compatible = "starfive,jh7110-trng";
+ reg = <0x0 0x1600C000 0x0 0x4000>;
+- clocks = <&stgcrg JH7110_STGCLK_SEC_HCLK>,
+- <&stgcrg JH7110_STGCLK_SEC_MISCAHB>;
++ clocks = <&stgcrg JH7110_STGCLK_SEC_AHB>,
++ <&stgcrg JH7110_STGCLK_SEC_MISC_AHB>;
+ clock-names = "hclk", "ahb";
+- resets = <&stgcrg JH7110_STGRST_SEC_TOP_HRESETN>;
++ resets = <&stgcrg JH7110_STGRST_SEC_AHB>;
+ interrupts = <30>;
+ };
+
+--
+2.20.1
+
--- /dev/null
+From 9d8287cc4934e7e1596db6da60b8dd8141b5f010 Mon Sep 17 00:00:00 2001
+From: Zoltan HERPAI <wigyori@uid0.hu>
+Date: Sun, 28 May 2023 18:35:30 +0200
+Subject: [PATCH 67/95] generic/6.1: another set of ARCH_STARFIVE to
+ SOC_STARFIVE change
+
+Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>
+---
+ drivers/clk/starfive/Kconfig | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/clk/starfive/Kconfig b/drivers/clk/starfive/Kconfig
+index 42485abea0ce..ac0844a0ac39 100644
+--- a/drivers/clk/starfive/Kconfig
++++ b/drivers/clk/starfive/Kconfig
+@@ -49,7 +49,7 @@ config CLK_STARFIVE_JH7110_STG
+ select AUXILIARY_BUS
+ select CLK_STARFIVE_JH71X0
+ select RESET_STARFIVE_JH7110
+- default m if ARCH_STARFIVE
++ default m if SOC_STARFIVE
+ help
+ Say yes here to support the System-Top-Group clock controller
+ on the StarFive JH7110 SoC.
+@@ -60,7 +60,7 @@ config CLK_STARFIVE_JH7110_ISP
+ select AUXILIARY_BUS
+ select CLK_STARFIVE_JH71X0
+ select RESET_STARFIVE_JH7110
+- default m if ARCH_STARFIVE
++ default m if SOC_STARFIVE
+ help
+ Say yes here to support the Image-Signal-Process clock controller
+ on the StarFive JH7110 SoC.
+@@ -71,7 +71,7 @@ config CLK_STARFIVE_JH7110_VOUT
+ select AUXILIARY_BUS
+ select CLK_STARFIVE_JH71X0
+ select RESET_STARFIVE_JH7110
+- default m if ARCH_STARFIVE
++ default m if SOC_STARFIVE
+ help
+ Say yes here to support the Video-Output clock controller
+ on the StarFive JH7110 SoC.
+--
+2.20.1
+
--- /dev/null
+From 5941747e795176c83553b66742e91384d67600da Mon Sep 17 00:00:00 2001
+From: Walker Chen <walker.chen@starfivetech.com>
+Date: Wed, 22 Mar 2023 17:48:17 +0800
+Subject: [PATCH 68/95] dt-bindings: dma: snps,dw-axi-dmac: constrain the items
+ of resets for JH7110 dma
+
+The DMA controller needs two reset items to work properly on JH7110 SoC,
+so there is need to constrain the items' value to 2, other platforms
+have 1 reset item at most.
+
+Reviewed-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Walker Chen <walker.chen@starfivetech.com>
+---
+ .../bindings/dma/snps,dw-axi-dmac.yaml | 23 ++++++++++++++++++-
+ 1 file changed, 22 insertions(+), 1 deletion(-)
+
+diff --git a/Documentation/devicetree/bindings/dma/snps,dw-axi-dmac.yaml b/Documentation/devicetree/bindings/dma/snps,dw-axi-dmac.yaml
+index 67aa7bb6d36a..e1ec04f65279 100644
+--- a/Documentation/devicetree/bindings/dma/snps,dw-axi-dmac.yaml
++++ b/Documentation/devicetree/bindings/dma/snps,dw-axi-dmac.yaml
+@@ -21,6 +21,7 @@ properties:
+ enum:
+ - snps,axi-dma-1.01a
+ - intel,kmb-axi-dma
++ - starfive,jh7110-axi-dma
+
+ reg:
+ minItems: 1
+@@ -59,7 +60,8 @@ properties:
+ maximum: 8
+
+ resets:
+- maxItems: 1
++ minItems: 1
++ maxItems: 2
+
+ snps,dma-masters:
+ description: |
+@@ -110,6 +112,25 @@ required:
+ - snps,priority
+ - snps,block-size
+
++if:
++ properties:
++ compatible:
++ contains:
++ enum:
++ - starfive,jh7110-axi-dma
++then:
++ properties:
++ resets:
++ minItems: 2
++ items:
++ - description: AXI reset line
++ - description: AHB reset line
++ - description: module reset
++else:
++ properties:
++ resets:
++ maxItems: 1
++
+ additionalProperties: false
+
+ examples:
+--
+2.20.1
+
--- /dev/null
+From 82b76cf5477f1189608f1ab69c855f89e96bebd6 Mon Sep 17 00:00:00 2001
+From: Zoltan HERPAI <wigyori@uid0.hu>
+Date: Sun, 28 May 2023 19:55:44 +0200
+Subject: [PATCH 69/95] dts/6.1: mmc: change starfive,sysreg to starfive,syscon
+
+Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>
+---
+ arch/riscv/boot/dts/starfive/jh7110.dtsi | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/riscv/boot/dts/starfive/jh7110.dtsi b/arch/riscv/boot/dts/starfive/jh7110.dtsi
+index 5e6421851ffa..3adfcd1b710a 100644
+--- a/arch/riscv/boot/dts/starfive/jh7110.dtsi
++++ b/arch/riscv/boot/dts/starfive/jh7110.dtsi
+@@ -556,7 +556,7 @@
+ fifo-depth = <32>;
+ fifo-watermark-aligned;
+ data-addr = <0>;
+- starfive,sysreg = <&sysreg 0x14 0x1a 0x7c000000>;
++ starfive,syscon = <&sysreg 0x14 0x1a 0x7c000000>;
+ status = "disabled";
+ };
+
+@@ -572,7 +572,7 @@
+ fifo-depth = <32>;
+ fifo-watermark-aligned;
+ data-addr = <0>;
+- starfive,sysreg = <&sysreg 0x9c 0x1 0x3e>;
++ starfive,syscon = <&sysreg 0x9c 0x1 0x3e>;
+ status = "disabled";
+ };
+
+--
+2.20.1
+
--- /dev/null
+From 5fbef31ad0ebdb6905d36b2b9e745103e02fb150 Mon Sep 17 00:00:00 2001
+From: Zoltan HERPAI <wigyori@uid0.hu>
+Date: Sun, 28 May 2023 19:58:19 +0200
+Subject: [PATCH 70/95] dts/6.1: disable jh7100-visionfive build for now
+
+Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>
+---
+ arch/riscv/boot/dts/starfive/Makefile | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/riscv/boot/dts/starfive/Makefile b/arch/riscv/boot/dts/starfive/Makefile
+index cd73519b907b..1801cfb7bd95 100644
+--- a/arch/riscv/boot/dts/starfive/Makefile
++++ b/arch/riscv/boot/dts/starfive/Makefile
+@@ -1,6 +1,6 @@
+ # SPDX-License-Identifier: GPL-2.0
+ dtb-$(CONFIG_SOC_STARFIVE) += jh7100-beaglev-starlight.dtb
+-dtb-$(CONFIG_SOC_STARFIVE) += jh7100-starfive-visionfive-v1.dtb
++#dtb-$(CONFIG_SOC_STARFIVE) += jh7100-starfive-visionfive-v1.dtb
+
+ dtb-$(CONFIG_SOC_STARFIVE) += jh7110-starfive-visionfive-2-v1.2a.dtb
+ dtb-$(CONFIG_SOC_STARFIVE) += jh7110-starfive-visionfive-2-v1.3b.dtb
+--
+2.20.1
+
--- /dev/null
+From de6204bc2eeee3f1ae2cc97fd926d281d4094e57 Mon Sep 17 00:00:00 2001
+From: Minda Chen <minda.chen@starfivetech.com>
+Date: Thu, 20 Apr 2023 19:00:46 +0800
+Subject: [PATCH 71/95] dt-bindings: phy: Add StarFive JH7110 USB PHY
+
+Add StarFive JH7110 SoC USB 2.0 PHY dt-binding.
+
+Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
+Reviewed-by: Hal Feng <hal.feng@starfivetech.com>
+Reviewed-by: Rob Herring <robh@kernel.org>
+---
+ .../bindings/phy/starfive,jh7110-usb-phy.yaml | 50 +++++++++++++++++++
+ 1 file changed, 50 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/phy/starfive,jh7110-usb-phy.yaml
+
+diff --git a/Documentation/devicetree/bindings/phy/starfive,jh7110-usb-phy.yaml b/Documentation/devicetree/bindings/phy/starfive,jh7110-usb-phy.yaml
+new file mode 100644
+index 000000000000..269e9f9f12b6
+--- /dev/null
++++ b/Documentation/devicetree/bindings/phy/starfive,jh7110-usb-phy.yaml
+@@ -0,0 +1,50 @@
++# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/phy/starfive,jh7110-usb-phy.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: StarFive JH7110 USB 2.0 PHY
++
++maintainers:
++ - Minda Chen <minda.chen@starfivetech.com>
++
++properties:
++ compatible:
++ const: starfive,jh7110-usb-phy
++
++ reg:
++ maxItems: 1
++
++ "#phy-cells":
++ const: 0
++
++ clocks:
++ items:
++ - description: PHY 125m
++ - description: app 125m
++
++ clock-names:
++ items:
++ - const: 125m
++ - const: app_125m
++
++required:
++ - compatible
++ - reg
++ - clocks
++ - clock-names
++ - "#phy-cells"
++
++additionalProperties: false
++
++examples:
++ - |
++ phy@10200000 {
++ compatible = "starfive,jh7110-usb-phy";
++ reg = <0x10200000 0x10000>;
++ clocks = <&syscrg 95>,
++ <&stgcrg 6>;
++ clock-names = "125m", "app_125m";
++ #phy-cells = <0>;
++ };
+--
+2.20.1
+
--- /dev/null
+From ba04fd4a11d2e12c2f8a34e3de92048b099a8b4e Mon Sep 17 00:00:00 2001
+From: Minda Chen <minda.chen@starfivetech.com>
+Date: Thu, 20 Apr 2023 19:00:47 +0800
+Subject: [PATCH 72/95] dt-bindings: phy: Add StarFive JH7110 PCIe PHY
+
+Add StarFive JH7110 SoC PCIe 2.0 PHY dt-binding.
+PCIe PHY0 (phy@10210000) can be used as USB 3.0 PHY.
+
+Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
+Reviewed-by: Hal Feng <hal.feng@starfivetech.com>
+Reviewed-by: Rob Herring <robh@kernel.org>
+---
+ .../phy/starfive,jh7110-pcie-phy.yaml | 58 +++++++++++++++++++
+ 1 file changed, 58 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/phy/starfive,jh7110-pcie-phy.yaml
+
+diff --git a/Documentation/devicetree/bindings/phy/starfive,jh7110-pcie-phy.yaml b/Documentation/devicetree/bindings/phy/starfive,jh7110-pcie-phy.yaml
+new file mode 100644
+index 000000000000..2e83a6164cd1
+--- /dev/null
++++ b/Documentation/devicetree/bindings/phy/starfive,jh7110-pcie-phy.yaml
+@@ -0,0 +1,58 @@
++# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/phy/starfive,jh7110-pcie-phy.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: StarFive JH7110 PCIe 2.0 PHY
++
++maintainers:
++ - Minda Chen <minda.chen@starfivetech.com>
++
++properties:
++ compatible:
++ const: starfive,jh7110-pcie-phy
++
++ reg:
++ maxItems: 1
++
++ "#phy-cells":
++ const: 0
++
++ starfive,sys-syscon:
++ $ref: /schemas/types.yaml#/definitions/phandle-array
++ items:
++ - items:
++ - description: phandle to System Register Controller sys_syscon node.
++ - description: PHY connect offset of SYS_SYSCONSAIF__SYSCFG register for USB PHY.
++ description:
++ The phandle to System Register Controller syscon node and the PHY connect offset
++ of SYS_SYSCONSAIF__SYSCFG register. Connect PHY to USB3 controller.
++
++ starfive,stg-syscon:
++ $ref: /schemas/types.yaml#/definitions/phandle-array
++ items:
++ - items:
++ - description: phandle to System Register Controller stg_syscon node.
++ - description: PHY mode offset of STG_SYSCONSAIF__SYSCFG register.
++ - description: PHY enable for USB offset of STG_SYSCONSAIF__SYSCFG register.
++ description:
++ The phandle to System Register Controller syscon node and the offset
++ of STG_SYSCONSAIF__SYSCFG register for PCIe PHY. Total 2 regsisters offset.
++
++required:
++ - compatible
++ - reg
++ - "#phy-cells"
++
++additionalProperties: false
++
++examples:
++ - |
++ phy@10210000 {
++ compatible = "starfive,jh7110-pcie-phy";
++ reg = <0x10210000 0x10000>;
++ #phy-cells = <0>;
++ starfive,sys-syscon = <&sys_syscon 0x18>;
++ starfive,stg-syscon = <&stg_syscon 0x148 0x1f4>;
++ };
+--
+2.20.1
+
--- /dev/null
+From d9772afb3f54c241e004e7ed53efd8fcc3b6624f Mon Sep 17 00:00:00 2001
+From: Minda Chen <minda.chen@starfivetech.com>
+Date: Thu, 20 Apr 2023 19:00:48 +0800
+Subject: [PATCH 73/95] phy: starfive: Add JH7110 USB 2.0 PHY driver
+
+Add Starfive JH7110 SoC USB 2.0 PHY driver support.
+USB 2.0 PHY default connect to Cadence USB controller.
+
+Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
+---
+ drivers/phy/starfive/phy-jh7110-usb.c | 162 ++++++++++++++++++++++++++
+ 1 file changed, 162 insertions(+)
+ create mode 100644 drivers/phy/starfive/phy-jh7110-usb.c
+
+diff --git a/drivers/phy/starfive/phy-jh7110-usb.c b/drivers/phy/starfive/phy-jh7110-usb.c
+new file mode 100644
+index 000000000000..4a12df0692cd
+--- /dev/null
++++ b/drivers/phy/starfive/phy-jh7110-usb.c
+@@ -0,0 +1,162 @@
++// SPDX-License-Identifier: GPL-2.0+
++/*
++ * StarFive JH7110 USB 2.0 PHY driver
++ *
++ * Copyright (C) 2023 StarFive Technology Co., Ltd.
++ * Author: Minda Chen <minda.chen@starfivetech.com>
++ */
++
++#include <linux/bits.h>
++#include <linux/clk.h>
++#include <linux/err.h>
++#include <linux/io.h>
++#include <linux/module.h>
++#include <linux/phy/phy.h>
++#include <linux/platform_device.h>
++#include <linux/usb/of.h>
++
++#define USB_125M_CLK_RATE 125000000
++#define USB_LS_KEEPALIVE_OFF 0x4
++#define USB_LS_KEEPALIVE_ENABLE BIT(4)
++
++struct jh7110_usb2_phy {
++ struct phy *phy;
++ void __iomem *regs;
++ struct clk *usb_125m_clk;
++ struct clk *app_125m;
++ enum phy_mode mode;
++};
++
++static void jh7110_usb2_mode_set(struct jh7110_usb2_phy *phy)
++{
++ unsigned int val;
++
++ if (phy->mode != PHY_MODE_USB_HOST) {
++ /* Enable the LS speed keep-alive signal */
++ val = readl(phy->regs + USB_LS_KEEPALIVE_OFF);
++ val |= USB_LS_KEEPALIVE_ENABLE;
++ writel(val, phy->regs + USB_LS_KEEPALIVE_OFF);
++ }
++}
++
++static int jh7110_usb2_phy_set_mode(struct phy *_phy,
++ enum phy_mode mode, int submode)
++{
++ struct jh7110_usb2_phy *phy = phy_get_drvdata(_phy);
++
++ switch (mode) {
++ case PHY_MODE_USB_HOST:
++ case PHY_MODE_USB_DEVICE:
++ case PHY_MODE_USB_OTG:
++ break;
++ default:
++ return -EINVAL;
++ }
++
++ if (mode != phy->mode) {
++ dev_info(&_phy->dev, "Changing phy to %d\n", mode);
++ phy->mode = mode;
++ jh7110_usb2_mode_set(phy);
++ }
++
++ return 0;
++}
++
++static int jh7110_usb2_phy_init(struct phy *_phy)
++{
++ struct jh7110_usb2_phy *phy = phy_get_drvdata(_phy);
++ int ret;
++
++ ret = clk_set_rate(phy->usb_125m_clk, USB_125M_CLK_RATE);
++ if (ret)
++ return ret;
++
++ ret = clk_prepare_enable(phy->app_125m);
++ if (ret)
++ return ret;
++
++ return 0;
++}
++
++static int jh7110_usb2_phy_exit(struct phy *_phy)
++{
++ struct jh7110_usb2_phy *phy = phy_get_drvdata(_phy);
++
++ clk_disable_unprepare(phy->app_125m);
++
++ return 0;
++}
++
++static const struct phy_ops jh7110_usb2_phy_ops = {
++ .init = jh7110_usb2_phy_init,
++ .exit = jh7110_usb2_phy_exit,
++ .set_mode = jh7110_usb2_phy_set_mode,
++ .owner = THIS_MODULE,
++};
++
++static int jh7110_usb_phy_probe(struct platform_device *pdev)
++{
++ struct jh7110_usb2_phy *phy;
++ struct device *dev = &pdev->dev;
++ struct phy_provider *phy_provider;
++
++ phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL);
++ if (!phy)
++ return -ENOMEM;
++
++ phy->usb_125m_clk = devm_clk_get(dev, "125m");
++ if (IS_ERR(phy->usb_125m_clk))
++ return dev_err_probe(dev, PTR_ERR(phy->usb_125m_clk),
++ "Failed to get 125m clock\n");
++
++ phy->app_125m = devm_clk_get(dev, "app_125m");
++ if (IS_ERR(phy->app_125m))
++ return dev_err_probe(dev, PTR_ERR(phy->app_125m),
++ "Failed to get app 125m clock\n");
++
++ phy->regs = devm_platform_ioremap_resource(pdev, 0);
++ if (IS_ERR(phy->regs))
++ return dev_err_probe(dev, PTR_ERR(phy->regs),
++ "Failed to map phy base\n");
++
++ phy->phy = devm_phy_create(dev, NULL, &jh7110_usb2_phy_ops);
++ if (IS_ERR(phy->phy))
++ return dev_err_probe(dev, PTR_ERR(phy->phy),
++ "Failed to create phy\n");
++
++ platform_set_drvdata(pdev, phy);
++ phy_set_drvdata(phy->phy, phy);
++ phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
++
++ return PTR_ERR_OR_ZERO(phy_provider);
++}
++
++static int jh7110_usb_phy_remove(struct platform_device *pdev)
++{
++ struct jh7110_usb2_phy *phy = platform_get_drvdata(pdev);
++
++ clk_disable_unprepare(phy->app_125m);
++ platform_set_drvdata(pdev, NULL);
++
++ return 0;
++}
++
++static const struct of_device_id jh7110_usb_phy_of_match[] = {
++ { .compatible = "starfive,jh7110-usb-phy" },
++ { /* sentinel */ },
++};
++MODULE_DEVICE_TABLE(of, jh7110_usb_phy_of_match);
++
++static struct platform_driver jh7110_usb_phy_driver = {
++ .probe = jh7110_usb_phy_probe,
++ .remove = jh7110_usb_phy_remove,
++ .driver = {
++ .of_match_table = jh7110_usb_phy_of_match,
++ .name = "jh7110-usb-phy",
++ }
++};
++module_platform_driver(jh7110_usb_phy_driver);
++
++MODULE_DESCRIPTION("StarFive JH7110 USB 2.0 PHY driver");
++MODULE_AUTHOR("Minda Chen <minda.chen@starfivetech.com>");
++MODULE_LICENSE("GPL");
+--
+2.20.1
+
--- /dev/null
+From 58521c902a080776fc93fb066533e6f00ebf82ca Mon Sep 17 00:00:00 2001
+From: Minda Chen <minda.chen@starfivetech.com>
+Date: Thu, 20 Apr 2023 19:00:49 +0800
+Subject: [PATCH 74/95] phy: starfive: Add JH7110 PCIE 2.0 PHY driver
+
+Add Starfive JH7110 SoC PCIe 2.0 PHY driver support.
+PCIe 2.0 PHY default connect to PCIe controller.
+But pcie0 PHY can connect to USB 3.0 controlller.
+
+Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
+---
+ drivers/phy/starfive/phy-jh7110-pcie.c | 202 +++++++++++++++++++++++++
+ 1 file changed, 202 insertions(+)
+ create mode 100644 drivers/phy/starfive/phy-jh7110-pcie.c
+
+diff --git a/drivers/phy/starfive/phy-jh7110-pcie.c b/drivers/phy/starfive/phy-jh7110-pcie.c
+new file mode 100644
+index 000000000000..fe029daef62e
+--- /dev/null
++++ b/drivers/phy/starfive/phy-jh7110-pcie.c
+@@ -0,0 +1,202 @@
++// SPDX-License-Identifier: GPL-2.0+
++/*
++ * StarFive JH7110 PCIe 2.0 PHY driver
++ *
++ * Copyright (C) 2023 StarFive Technology Co., Ltd.
++ * Author: Minda Chen <minda.chen@starfivetech.com>
++ */
++
++#include <linux/bits.h>
++#include <linux/clk.h>
++#include <linux/err.h>
++#include <linux/io.h>
++#include <linux/module.h>
++#include <linux/mfd/syscon.h>
++#include <linux/phy/phy.h>
++#include <linux/platform_device.h>
++#include <linux/regmap.h>
++
++#define PCIE_KVCO_LEVEL_OFF (0x28)
++#define PCIE_USB3_PHY_PLL_CTL_OFF (0x7c)
++#define PCIE_KVCO_TUNE_SIGNAL_OFF (0x80)
++#define PCIE_USB3_PHY_ENABLE BIT(4)
++#define PHY_KVCO_FINE_TUNE_LEVEL 0x91
++#define PHY_KVCO_FINE_TUNE_SIGNALS 0xc
++
++#define USB_PDRSTN_SPLIT BIT(17)
++
++#define PCIE_PHY_MODE BIT(20)
++#define PCIE_PHY_MODE_MASK GENMASK(21, 20)
++#define PCIE_USB3_BUS_WIDTH_MASK GENMASK(3, 2)
++#define PCIE_USB3_RATE_MASK GENMASK(6, 5)
++#define PCIE_USB3_RX_STANDBY_MASK BIT(7)
++#define PCIE_USB3_PHY_ENABLE BIT(4)
++
++struct jh7110_pcie_phy {
++ struct phy *phy;
++ struct regmap *stg_syscon;
++ struct regmap *sys_syscon;
++ void __iomem *regs;
++ u32 sys_phy_connect;
++ u32 stg_pcie_mode;
++ u32 stg_pcie_usb;
++ enum phy_mode mode;
++};
++
++static int jh7110_usb3_mode_set(struct jh7110_pcie_phy *data)
++{
++ if (!data->stg_syscon || !data->sys_syscon) {
++ dev_info(&data->phy->dev, "don't support usb3 mode\n");
++ return -EINVAL;
++ }
++
++ regmap_update_bits(data->stg_syscon, data->stg_pcie_mode,
++ PCIE_PHY_MODE_MASK, PCIE_PHY_MODE);
++ regmap_update_bits(data->stg_syscon, data->stg_pcie_usb,
++ PCIE_USB3_BUS_WIDTH_MASK, 0);
++ regmap_update_bits(data->stg_syscon, data->stg_pcie_usb,
++ PCIE_USB3_RATE_MASK, 0);
++ regmap_update_bits(data->stg_syscon, data->stg_pcie_usb,
++ PCIE_USB3_RX_STANDBY_MASK, 0);
++ regmap_update_bits(data->stg_syscon, data->stg_pcie_usb,
++ PCIE_USB3_PHY_ENABLE, PCIE_USB3_PHY_ENABLE);
++
++ /* Connect usb 3.0 phy mode */
++ regmap_update_bits(data->sys_syscon, data->sys_phy_connect,
++ USB_PDRSTN_SPLIT, 0);
++
++ /* Configuare spread-spectrum mode: down-spread-spectrum */
++ writel(PCIE_USB3_PHY_ENABLE, data->regs + PCIE_USB3_PHY_PLL_CTL_OFF);
++
++ return 0;
++}
++
++static void jh7110_pcie_mode_set(struct jh7110_pcie_phy *phy)
++{
++ /* PCIe Multi-PHY PLL KVCO Gain fine tune settings: */
++ writel(PHY_KVCO_FINE_TUNE_LEVEL, phy->regs + PCIE_KVCO_LEVEL_OFF);
++ writel(PHY_KVCO_FINE_TUNE_SIGNALS, phy->regs + PCIE_KVCO_TUNE_SIGNAL_OFF);
++}
++
++static int jh7110_pcie_phy_set_mode(struct phy *_phy,
++ enum phy_mode mode, int submode)
++{
++ struct jh7110_pcie_phy *phy = phy_get_drvdata(_phy);
++ int ret;
++
++ if (mode == phy->mode)
++ return 0;
++
++ switch (mode) {
++ case PHY_MODE_USB_HOST:
++ case PHY_MODE_USB_DEVICE:
++ case PHY_MODE_USB_OTG:
++ ret = jh7110_usb3_mode_set(phy);
++ if (ret)
++ return ret;
++ break;
++ case PHY_MODE_PCIE:
++ jh7110_pcie_mode_set(phy);
++ break;
++ default:
++ return -EINVAL;
++ }
++
++ dev_info(&_phy->dev, "Changing phy mode to %d\n", mode);
++ phy->mode = mode;
++
++ return 0;
++}
++
++static int jh7110_pcie_phy_init(struct phy *_phy)
++{
++ return 0;
++}
++
++static int jh7110_pcie_phy_exit(struct phy *_phy)
++{
++ return 0;
++}
++
++static const struct phy_ops jh7110_pcie_phy_ops = {
++ .init = jh7110_pcie_phy_init,
++ .exit = jh7110_pcie_phy_exit,
++ .set_mode = jh7110_pcie_phy_set_mode,
++ .owner = THIS_MODULE,
++};
++
++static int jh7110_pcie_phy_probe(struct platform_device *pdev)
++{
++ struct jh7110_pcie_phy *phy;
++ struct device *dev = &pdev->dev;
++ struct phy_provider *phy_provider;
++ u32 args[2];
++
++ phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL);
++ if (!phy)
++ return -ENOMEM;
++
++ phy->regs = devm_platform_ioremap_resource(pdev, 0);
++ if (IS_ERR(phy->regs))
++ return PTR_ERR(phy->regs);
++
++ phy->phy = devm_phy_create(dev, NULL, &jh7110_pcie_phy_ops);
++ if (IS_ERR(phy->phy))
++ return dev_err_probe(dev, PTR_ERR(phy->regs),
++ "Failed to map phy base\n");
++
++ phy->sys_syscon =
++ syscon_regmap_lookup_by_phandle_args(pdev->dev.of_node,
++ "starfive,sys-syscon",
++ 1, args);
++
++ if (!IS_ERR_OR_NULL(phy->sys_syscon))
++ phy->sys_phy_connect = args[0];
++ else
++ phy->sys_syscon = NULL;
++
++ phy->stg_syscon =
++ syscon_regmap_lookup_by_phandle_args(pdev->dev.of_node,
++ "starfive,stg-syscon",
++ 2, args);
++
++ if (!IS_ERR_OR_NULL(phy->stg_syscon)) {
++ phy->stg_pcie_mode = args[0];
++ phy->stg_pcie_usb = args[1];
++ } else {
++ phy->stg_syscon = NULL;
++ }
++
++ platform_set_drvdata(pdev, phy);
++ phy_set_drvdata(phy->phy, phy);
++ phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
++
++ return PTR_ERR_OR_ZERO(phy_provider);
++}
++
++static int jh7110_pcie_phy_remove(struct platform_device *pdev)
++{
++ platform_set_drvdata(pdev, NULL);
++
++ return 0;
++}
++
++static const struct of_device_id jh7110_pcie_phy_of_match[] = {
++ { .compatible = "starfive,jh7110-pcie-phy" },
++ { /* sentinel */ },
++};
++MODULE_DEVICE_TABLE(of, jh7110_pcie_phy_of_match);
++
++static struct platform_driver jh7110_pcie_phy_driver = {
++ .probe = jh7110_pcie_phy_probe,
++ .remove = jh7110_pcie_phy_remove,
++ .driver = {
++ .of_match_table = jh7110_pcie_phy_of_match,
++ .name = "jh7110-pcie-phy",
++ }
++};
++module_platform_driver(jh7110_pcie_phy_driver);
++
++MODULE_DESCRIPTION("StarFive JH7110 PCIe 2.0 PHY driver");
++MODULE_AUTHOR("Minda Chen <minda.chen@starfivetech.com>");
++MODULE_LICENSE("GPL");
+--
+2.20.1
+
--- /dev/null
+From ca6592878708d1cc045c55e846cfe6baaf0be06c Mon Sep 17 00:00:00 2001
+From: Minda Chen <minda.chen@starfivetech.com>
+Date: Thu, 20 Apr 2023 19:00:50 +0800
+Subject: [PATCH 75/95] dt-bindings: usb: Add StarFive JH7110 USB controller
+
+StarFive JH7110 platforms USB have a wrapper module around
+the Cadence USBSS-DRD controller. Add binding information doc
+for that.
+
+Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
+Reviewed-by: Peter Chen <peter.chen@kernel.org>
+Reviewed-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ .../bindings/usb/starfive,jh7110-usb.yaml | 131 ++++++++++++++++++
+ 1 file changed, 131 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/usb/starfive,jh7110-usb.yaml
+
+diff --git a/Documentation/devicetree/bindings/usb/starfive,jh7110-usb.yaml b/Documentation/devicetree/bindings/usb/starfive,jh7110-usb.yaml
+new file mode 100644
+index 000000000000..e6bd8a583da3
+--- /dev/null
++++ b/Documentation/devicetree/bindings/usb/starfive,jh7110-usb.yaml
+@@ -0,0 +1,131 @@
++# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/usb/starfive,jh7110-usb.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: StarFive JH7110 Cadence USBSS-DRD SoC controller
++
++maintainers:
++ - Minda Chen <minda.chen@starfivetech.com>
++
++properties:
++ compatible:
++ const: starfive,jh7110-usb
++
++ reg:
++ items:
++ - description: OTG controller registers
++ - description: XHCI Host controller registers
++ - description: DEVICE controller registers
++
++ reg-names:
++ items:
++ - const: otg
++ - const: xhci
++ - const: dev
++
++ interrupts:
++ items:
++ - description: XHCI host controller interrupt
++ - description: Device controller interrupt
++ - description: OTG/DRD controller interrupt
++
++ interrupt-names:
++ items:
++ - const: host
++ - const: peripheral
++ - const: otg
++
++ clocks:
++ items:
++ - description: low power clock
++ - description: STB clock
++ - description: APB clock
++ - description: AXI clock
++ - description: UTMI APB clock
++
++ clock-names:
++ items:
++ - const: lpm
++ - const: stb
++ - const: apb
++ - const: axi
++ - const: utmi_apb
++
++ resets:
++ items:
++ - description: Power up reset
++ - description: APB clock reset
++ - description: AXI clock reset
++ - description: UTMI APB clock reset
++
++ reset-names:
++ items:
++ - const: pwrup
++ - const: apb
++ - const: axi
++ - const: utmi_apb
++
++ starfive,stg-syscon:
++ $ref: /schemas/types.yaml#/definitions/phandle-array
++ items:
++ - items:
++ - description: phandle to System Register Controller stg_syscon node.
++ - description: dr mode register offset of STG_SYSCONSAIF__SYSCFG register for USB.
++ description:
++ The phandle to System Register Controller syscon node and the offset
++ of STG_SYSCONSAIF__SYSCFG register for USB.
++
++ dr_mode:
++ enum: [host, otg, peripheral]
++
++ phys:
++ minItems: 1
++ maxItems: 2
++
++ phy-names:
++ minItems: 1
++ maxItems: 2
++ items:
++ anyOf:
++ - const: usb2
++ - const: usb3
++
++required:
++ - compatible
++ - reg
++ - reg-names
++ - interrupts
++ - interrupt-names
++ - clocks
++ - resets
++ - starfive,stg-syscon
++ - dr_mode
++
++additionalProperties: false
++
++examples:
++ - |
++ usb@10100000 {
++ compatible = "starfive,jh7110-usb";
++ reg = <0x10100000 0x10000>,
++ <0x10110000 0x10000>,
++ <0x10120000 0x10000>;
++ reg-names = "otg", "xhci", "dev";
++ interrupts = <100>, <108>, <110>;
++ interrupt-names = "host", "peripheral", "otg";
++ clocks = <&syscrg 4>,
++ <&stgcrg 5>,
++ <&stgcrg 1>,
++ <&stgcrg 3>,
++ <&stgcrg 2>;
++ clock-names = "lpm", "stb", "apb", "axi", "utmi_apb";
++ resets = <&stgcrg 10>,
++ <&stgcrg 8>,
++ <&stgcrg 7>,
++ <&stgcrg 9>;
++ reset-names = "pwrup", "apb", "axi", "utmi_apb";
++ starfive,stg-syscon = <&stg_syscon 0x4>;
++ dr_mode = "host";
++ };
+--
+2.20.1
+
--- /dev/null
+From 4ba6a9980171ffcd1715c7ad8fc06b21270e8a6d Mon Sep 17 00:00:00 2001
+From: Minda Chen <minda.chen@starfivetech.com>
+Date: Thu, 20 Apr 2023 19:00:51 +0800
+Subject: [PATCH 76/95] usb: cdns3: Add StarFive JH7110 USB driver
+
+Adds Specific Glue layer to support USB peripherals on
+StarFive JH7110 SoC.
+There is a Cadence USB3 core for JH7110 SoCs, the cdns
+core is the child of this USB wrapper module device.
+
+Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
+Acked-by: Peter Chen <peter.chen@kernel.org>
+---
+ drivers/usb/cdns3/Kconfig | 11 +
+ drivers/usb/cdns3/Makefile | 1 +
+ drivers/usb/cdns3/cdns3-starfive.c | 390 +++++++++++++++++++++++++++++
+ drivers/usb/cdns3/core.h | 3 +
+ 4 files changed, 405 insertions(+)
+ create mode 100644 drivers/usb/cdns3/cdns3-starfive.c
+
+diff --git a/drivers/usb/cdns3/Kconfig b/drivers/usb/cdns3/Kconfig
+index b98ca0a1352a..0a514b591527 100644
+--- a/drivers/usb/cdns3/Kconfig
++++ b/drivers/usb/cdns3/Kconfig
+@@ -78,6 +78,17 @@ config USB_CDNS3_IMX
+
+ For example, imx8qm and imx8qxp.
+
++config USB_CDNS3_STARFIVE
++ tristate "Cadence USB3 support on StarFive SoC platforms"
++ depends on ARCH_STARFIVE || COMPILE_TEST
++ help
++ Say 'Y' or 'M' here if you are building for StarFive SoCs
++ platforms that contain Cadence USB3 controller core.
++
++ e.g. JH7110.
++
++ If you choose to build this driver as module it will
++ be dynamically linked and module will be called cdns3-starfive.ko
+ endif
+
+ if USB_CDNS_SUPPORT
+diff --git a/drivers/usb/cdns3/Makefile b/drivers/usb/cdns3/Makefile
+index 61edb2f89276..48dfae75b5aa 100644
+--- a/drivers/usb/cdns3/Makefile
++++ b/drivers/usb/cdns3/Makefile
+@@ -24,6 +24,7 @@ endif
+ obj-$(CONFIG_USB_CDNS3_PCI_WRAP) += cdns3-pci-wrap.o
+ obj-$(CONFIG_USB_CDNS3_TI) += cdns3-ti.o
+ obj-$(CONFIG_USB_CDNS3_IMX) += cdns3-imx.o
++obj-$(CONFIG_USB_CDNS3_STARFIVE) += cdns3-starfive.o
+
+ cdnsp-udc-pci-y := cdnsp-pci.o
+
+diff --git a/drivers/usb/cdns3/cdns3-starfive.c b/drivers/usb/cdns3/cdns3-starfive.c
+new file mode 100644
+index 000000000000..afe1c6652660
+--- /dev/null
++++ b/drivers/usb/cdns3/cdns3-starfive.c
+@@ -0,0 +1,390 @@
++// SPDX-License-Identifier: GPL-2.0
++/**
++ * cdns3-starfive.c - StarFive specific Glue layer for Cadence USB Controller
++ *
++ * Copyright (C) 2023 StarFive Technology Co., Ltd.
++ *
++ * Author: Yanhong Wang <yanhong.wang@starfivetech.com>
++ * Author: Mason Huo <mason.huo@starfivetech.com>
++ * Author: Minda Chen <minda.chen@starfivetech.com>
++ */
++
++#include <linux/bits.h>
++#include <linux/clk.h>
++#include <linux/module.h>
++#include <linux/mfd/syscon.h>
++#include <linux/kernel.h>
++#include <linux/platform_device.h>
++#include <linux/io.h>
++#include <linux/of_platform.h>
++#include <linux/regmap.h>
++#include <linux/reset.h>
++#include <linux/usb/otg.h>
++#include "core.h"
++
++#define USB_STRAP_HOST BIT(17)
++#define USB_STRAP_DEVICE BIT(18)
++#define USB_STRAP_MASK GENMASK(18, 16)
++
++#define USB_SUSPENDM_HOST BIT(19)
++#define USB_SUSPENDM_MASK BIT(19)
++#define CDNS_IRQ_WAKEUP_INDEX 3
++
++struct cdns_starfive {
++ struct device *dev;
++ struct phy *usb2_phy;
++ struct phy *usb3_phy;
++ struct regmap *stg_syscon;
++ struct reset_control *resets;
++ struct clk_bulk_data *clks;
++ int num_clks;
++ enum phy_mode phy_mode;
++ u32 stg_usb_mode;
++};
++
++static int set_phy_power_on(struct cdns_starfive *data)
++{
++ int ret;
++
++ ret = phy_power_on(data->usb2_phy);
++ if (ret)
++ return ret;
++
++ ret = phy_power_on(data->usb3_phy);
++ if (ret)
++ phy_power_off(data->usb2_phy);
++
++ return ret;
++}
++
++static void cdns_mode_init(struct platform_device *pdev,
++ struct cdns_starfive *data)
++{
++ enum usb_dr_mode mode;
++
++ mode = usb_get_dr_mode(&pdev->dev);
++
++ switch (mode) {
++ case USB_DR_MODE_HOST:
++ regmap_update_bits(data->stg_syscon,
++ data->stg_usb_mode,
++ USB_STRAP_MASK,
++ USB_STRAP_HOST);
++ regmap_update_bits(data->stg_syscon,
++ data->stg_usb_mode,
++ USB_SUSPENDM_MASK,
++ USB_SUSPENDM_HOST);
++ data->phy_mode = PHY_MODE_USB_HOST;
++ break;
++
++ case USB_DR_MODE_PERIPHERAL:
++ regmap_update_bits(data->stg_syscon, data->stg_usb_mode,
++ USB_STRAP_MASK, USB_STRAP_DEVICE);
++ regmap_update_bits(data->stg_syscon, data->stg_usb_mode,
++ USB_SUSPENDM_MASK, 0);
++ data->phy_mode = PHY_MODE_USB_DEVICE;
++ break;
++
++ case USB_DR_MODE_OTG:
++ data->phy_mode = PHY_MODE_USB_OTG;
++ default:
++ break;
++ }
++}
++
++static int cdns_clk_rst_init(struct cdns_starfive *data)
++{
++ int ret;
++
++ ret = clk_bulk_prepare_enable(data->num_clks, data->clks);
++ if (ret)
++ return dev_err_probe(data->dev, ret,
++ "failed to enable clocks\n");
++
++ ret = reset_control_deassert(data->resets);
++ if (ret) {
++ dev_err(data->dev, "failed to reset clocks\n");
++ goto err_clk_init;
++ }
++
++ return ret;
++
++err_clk_init:
++ clk_bulk_disable_unprepare(data->num_clks, data->clks);
++ return ret;
++}
++
++static void cdns_clk_rst_deinit(struct cdns_starfive *data)
++{
++ reset_control_assert(data->resets);
++ clk_bulk_disable_unprepare(data->num_clks, data->clks);
++}
++
++static int cdns_starfive_phy_init(struct cdns_starfive *data)
++{
++ int ret;
++
++ ret = phy_init(data->usb2_phy);
++ if (ret)
++ return ret;
++
++ ret = phy_init(data->usb3_phy);
++ if (ret)
++ goto err_phy3_init;
++
++ phy_set_mode(data->usb2_phy, data->phy_mode);
++ phy_set_mode(data->usb3_phy, data->phy_mode);
++
++ ret = set_phy_power_on(data);
++ if (ret)
++ goto err_phy_power_on;
++
++ return 0;
++
++err_phy_power_on:
++ phy_exit(data->usb3_phy);
++err_phy3_init:
++ phy_exit(data->usb2_phy);
++ return ret;
++}
++
++static void cdns_starfive_phy_deinit(struct cdns_starfive *data)
++{
++ phy_power_off(data->usb3_phy);
++ phy_power_off(data->usb2_phy);
++ phy_exit(data->usb3_phy);
++ phy_exit(data->usb2_phy);
++}
++
++static int cdns_starfive_platform_device_add(struct platform_device *pdev,
++ struct cdns_starfive *data)
++{
++ struct platform_device *cdns3;
++ struct resource cdns_res[CDNS_RESOURCES_NUM], *res;
++ struct device *dev = &pdev->dev;
++ const char *reg_name[CDNS_IOMEM_RESOURCES_NUM] = {"otg", "xhci", "dev"};
++ const char *irq_name[CDNS_IRQ_RESOURCES_NUM] = {"host", "peripheral", "otg", "wakeup"};
++ int i, ret, res_idx = 0;
++
++ cdns3 = platform_device_alloc("cdns-usb3", PLATFORM_DEVID_AUTO);
++ if (!cdns3)
++ return dev_err_probe(dev, -ENOMEM,
++ "couldn't alloc cdns3 usb device\n");
++
++ cdns3->dev.parent = dev;
++ memset(cdns_res, 0, sizeof(cdns_res));
++
++ for (i = 0; i < CDNS_IOMEM_RESOURCES_NUM; i++) {
++ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, reg_name[i]);
++ if (!res) {
++ ret = dev_err_probe(dev,
++ -ENXIO,
++ "couldn't get %s reg resource\n",
++ reg_name[i]);
++ goto free_memory;
++ }
++ cdns_res[res_idx] = *res;
++ res_idx++;
++ }
++
++ for (i = 0; i < CDNS_IRQ_RESOURCES_NUM; i++) {
++ if (i == CDNS_IRQ_WAKEUP_INDEX) {
++ ret = platform_get_irq_byname_optional(pdev, irq_name[i]);
++ if (ret < 0)
++ continue;
++ } else {
++ ret = platform_get_irq_byname(pdev, irq_name[i]);
++ if (ret < 0) {
++ dev_err(dev, "couldn't get %s irq\n", irq_name[i]);
++ goto free_memory;
++ }
++ }
++ cdns_res[res_idx].start = ret;
++ cdns_res[res_idx].end = ret;
++ cdns_res[res_idx].flags = IORESOURCE_IRQ;
++ cdns_res[res_idx].name = irq_name[i];
++ res_idx++;
++ }
++
++ ret = platform_device_add_resources(cdns3, cdns_res, res_idx);
++ if (ret) {
++ dev_err(dev, "couldn't add res to cdns3 device\n");
++ goto free_memory;
++ }
++
++ ret = platform_device_add(cdns3);
++ if (ret) {
++ dev_err(dev, "failed to register cdns3 device\n");
++ goto free_memory;
++ }
++
++ return ret;
++free_memory:
++ platform_device_put(cdns3);
++ return ret;
++}
++
++static int cdns_starfive_probe(struct platform_device *pdev)
++{
++ struct device *dev = &pdev->dev;
++ struct cdns_starfive *data;
++ unsigned int args;
++ int ret;
++
++ data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
++ if (!data)
++ return -ENOMEM;
++
++ platform_set_drvdata(pdev, data);
++
++ data->dev = dev;
++
++ data->stg_syscon =
++ syscon_regmap_lookup_by_phandle_args(pdev->dev.of_node,
++ "starfive,stg-syscon", 1, &args);
++
++ if (IS_ERR(data->stg_syscon))
++ return dev_err_probe(dev, PTR_ERR(data->stg_syscon),
++ "Failed to parse starfive,stg-syscon\n");
++
++ data->stg_usb_mode = args;
++
++ data->num_clks = devm_clk_bulk_get_all(data->dev, &data->clks);
++ if (data->num_clks < 0)
++ return dev_err_probe(data->dev, -ENODEV,
++ "Failed to get clocks\n");
++
++ data->resets = devm_reset_control_array_get_exclusive(data->dev);
++ if (IS_ERR(data->resets))
++ return dev_err_probe(data->dev, PTR_ERR(data->resets),
++ "Failed to get resets");
++
++ data->usb2_phy = devm_phy_optional_get(dev, "usb2");
++ if (IS_ERR(data->usb2_phy))
++ return dev_err_probe(dev, PTR_ERR(data->usb2_phy),
++ "Failed to parse usb2 PHY\n");
++
++ data->usb3_phy = devm_phy_optional_get(dev, "usb3");
++ if (IS_ERR(data->usb3_phy))
++ return dev_err_probe(dev, PTR_ERR(data->usb3_phy),
++ "Failed to parse usb3 PHY\n");
++
++ cdns_mode_init(pdev, data);
++
++ ret = cdns_clk_rst_init(data);
++ if (ret)
++ return ret;
++
++ ret = cdns_starfive_phy_init(data);
++ if (ret) {
++ dev_err(dev, "Failed to init PHY\n");
++ goto err_clk_init;
++ }
++
++ ret = cdns_starfive_platform_device_add(pdev, data);
++ if (ret) {
++ dev_err(dev, "Failed to create children\n");
++ goto err_phy_init;
++ }
++
++ device_set_wakeup_capable(dev, true);
++ pm_runtime_set_active(dev);
++ pm_runtime_enable(dev);
++
++ dev_info(dev, "usb mode %d probe success\n", data->phy_mode);
++
++ return 0;
++
++err_phy_init:
++ cdns_starfive_phy_deinit(data);
++err_clk_init:
++ cdns_clk_rst_deinit(data);
++ return ret;
++}
++
++static int cdns_starfive_remove_core(struct device *dev, void *c)
++{
++ struct platform_device *pdev = to_platform_device(dev);
++
++ platform_device_unregister(pdev);
++
++ return 0;
++}
++
++static int cdns_starfive_remove(struct platform_device *pdev)
++{
++ struct device *dev = &pdev->dev;
++ struct cdns_starfive *data = dev_get_drvdata(dev);
++
++ pm_runtime_get_sync(dev);
++ device_for_each_child(dev, NULL, cdns_starfive_remove_core);
++
++ cdns_starfive_phy_deinit(data);
++ cdns_clk_rst_deinit(data);
++ pm_runtime_disable(dev);
++ pm_runtime_put_noidle(dev);
++ platform_set_drvdata(pdev, NULL);
++
++ return 0;
++}
++
++#ifdef CONFIG_PM
++static int cdns_starfive_resume(struct device *dev)
++{
++ struct cdns_starfive *data = dev_get_drvdata(dev);
++ int ret;
++
++ ret = clk_bulk_prepare_enable(data->num_clks, data->clks);
++ if (ret)
++ return ret;
++
++ ret = reset_control_deassert(data->resets);
++ if (ret) {
++ clk_bulk_disable_unprepare(data->num_clks, data->clks);
++ return ret;
++ }
++
++ ret = cdns_starfive_phy_init(data);
++ if (ret)
++ cdns_clk_rst_deinit(data);
++
++ return ret;
++}
++
++static int cdns_starfive_suspend(struct device *dev)
++{
++ struct cdns_starfive *data = dev_get_drvdata(dev);
++
++ cdns_starfive_phy_deinit(data);
++ cdns_clk_rst_deinit(data);
++ return 0;
++}
++#endif
++
++static const struct dev_pm_ops cdns_starfive_pm_ops = {
++ SET_RUNTIME_PM_OPS(cdns_starfive_suspend, cdns_starfive_resume, NULL)
++ SET_SYSTEM_SLEEP_PM_OPS(cdns_starfive_suspend, cdns_starfive_resume)
++};
++
++static const struct of_device_id cdns_starfive_of_match[] = {
++ { .compatible = "starfive,jh7110-usb", },
++ { /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(of, cdns_starfive_of_match);
++
++static struct platform_driver cdns_starfive_driver = {
++ .probe = cdns_starfive_probe,
++ .remove = cdns_starfive_remove,
++ .driver = {
++ .name = "cdns3-starfive",
++ .of_match_table = cdns_starfive_of_match,
++ .pm = &cdns_starfive_pm_ops,
++ },
++};
++module_platform_driver(cdns_starfive_driver);
++
++MODULE_ALIAS("platform:cdns3-starfive");
++MODULE_AUTHOR("YanHong Wang <yanhong.wang@starfivetech.com>");
++MODULE_AUTHOR("Mason Huo <mason.huo@starfivetech.com>");
++MODULE_LICENSE("GPL v2");
++MODULE_DESCRIPTION("Cadence USB3 StarFive Glue Layer");
+diff --git a/drivers/usb/cdns3/core.h b/drivers/usb/cdns3/core.h
+index 2d332a788871..8d44ab504898 100644
+--- a/drivers/usb/cdns3/core.h
++++ b/drivers/usb/cdns3/core.h
+@@ -38,6 +38,9 @@ struct cdns_role_driver {
+ };
+
+ #define CDNS_XHCI_RESOURCES_NUM 2
++#define CDNS_IOMEM_RESOURCES_NUM 3
++#define CDNS_IRQ_RESOURCES_NUM 4
++#define CDNS_RESOURCES_NUM (CDNS_IOMEM_RESOURCES_NUM + CDNS_IRQ_RESOURCES_NUM)
+
+ struct cdns3_platform_data {
+ int (*platform_suspend)(struct device *dev,
+--
+2.20.1
+
--- /dev/null
+From 3129a9165caf563f635e23d1d3c8bdd0b0218c48 Mon Sep 17 00:00:00 2001
+From: Minda Chen <minda.chen@starfivetech.com>
+Date: Thu, 20 Apr 2023 19:00:52 +0800
+Subject: [PATCH 77/95] riscv: dts: starfive: Add USB dts configuration for
+ JH7110
+
+Add USB wrapper layer and Cadence USB3 controller dts
+configuration for StarFive JH7110 SoC and VisionFive2
+Board.
+USB controller connect to PHY, The PHY dts configuration
+are also added.
+
+Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
+---
+ .../jh7110-starfive-visionfive-2.dtsi | 7 +++
+ arch/riscv/boot/dts/starfive/jh7110.dtsi | 44 +++++++++++++++++++
+ 2 files changed, 51 insertions(+)
+
+diff --git a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
+index 641888db058c..41662fee3804 100644
+--- a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
++++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
+@@ -244,3 +244,10 @@
+ pinctrl-0 = <&uart0_pins>;
+ status = "okay";
+ };
++
++&usb0 {
++ phys = <&usbphy0>;
++ phy-names = "usb2";
++ dr_mode = "peripheral";
++ status = "okay";
++};
+diff --git a/arch/riscv/boot/dts/starfive/jh7110.dtsi b/arch/riscv/boot/dts/starfive/jh7110.dtsi
+index 3adfcd1b710a..b6a023b4c23e 100644
+--- a/arch/riscv/boot/dts/starfive/jh7110.dtsi
++++ b/arch/riscv/boot/dts/starfive/jh7110.dtsi
+@@ -366,6 +366,50 @@
+ status = "disabled";
+ };
+
++ usb0: usb@10100000 {
++ compatible = "starfive,jh7110-usb";
++ reg = <0x0 0x10100000 0x0 0x10000>,
++ <0x0 0x10110000 0x0 0x10000>,
++ <0x0 0x10120000 0x0 0x10000>;
++ reg-names = "otg", "xhci", "dev";
++ interrupts = <100>, <108>, <110>;
++ interrupt-names = "host", "peripheral", "otg";
++ clocks = <&stgcrg JH7110_STGCLK_USB0_LPM>,
++ <&stgcrg JH7110_STGCLK_USB0_STB>,
++ <&stgcrg JH7110_STGCLK_USB0_APB>,
++ <&stgcrg JH7110_STGCLK_USB0_AXI>,
++ <&stgcrg JH7110_STGCLK_USB0_UTMI_APB>;
++ clock-names = "lpm", "stb", "apb", "axi", "utmi_apb";
++ resets = <&stgcrg JH7110_STGRST_USB0_PWRUP>,
++ <&stgcrg JH7110_STGRST_USB0_APB>,
++ <&stgcrg JH7110_STGRST_USB0_AXI>,
++ <&stgcrg JH7110_STGRST_USB0_UTMI_APB>;
++ reset-names = "pwrup", "apb", "axi", "utmi_apb";
++ starfive,stg-syscon = <&stg_syscon 0x4>;
++ status = "disabled";
++ };
++
++ usbphy0: phy@10200000 {
++ compatible = "starfive,jh7110-usb-phy";
++ reg = <0x0 0x10200000 0x0 0x10000>;
++ clocks = <&syscrg JH7110_SYSCLK_USB_125M>,
++ <&stgcrg JH7110_STGCLK_USB0_APP_125>;
++ clock-names = "125m", "app_125m";
++ #phy-cells = <0>;
++ };
++
++ pciephy0: phy@10210000 {
++ compatible = "starfive,jh7110-pcie-phy";
++ reg = <0x0 0x10210000 0x0 0x10000>;
++ #phy-cells = <0>;
++ };
++
++ pciephy1: phy@10220000 {
++ compatible = "starfive,jh7110-pcie-phy";
++ reg = <0x0 0x10220000 0x0 0x10000>;
++ #phy-cells = <0>;
++ };
++
+ stgcrg: clock-controller@10230000 {
+ compatible = "starfive,jh7110-stgcrg";
+ reg = <0x0 0x10230000 0x0 0x10000>;
+--
+2.20.1
+
--- /dev/null
+From 14a42b3c35b052436e5cf0e945ecee67d73445d6 Mon Sep 17 00:00:00 2001
+From: Zoltan HERPAI <wigyori@uid0.hu>
+Date: Sun, 28 May 2023 20:11:32 +0200
+Subject: [PATCH 78/95] phy/6.1: add drivers/phy/starfive for USB2.0 and PCIe
+
+Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>
+---
+ drivers/phy/Kconfig | 1 +
+ drivers/phy/Makefile | 1 +
+ drivers/phy/starfive/Kconfig | 26 ++++++++++++++++++++++++++
+ drivers/phy/starfive/Makefile | 3 +++
+ 4 files changed, 31 insertions(+)
+ create mode 100644 drivers/phy/starfive/Kconfig
+ create mode 100644 drivers/phy/starfive/Makefile
+
+diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
+index 7bd00a11d074..c4b2a86e2afb 100644
+--- a/drivers/phy/Kconfig
++++ b/drivers/phy/Kconfig
+@@ -91,6 +91,7 @@ source "drivers/phy/rockchip/Kconfig"
+ source "drivers/phy/samsung/Kconfig"
+ source "drivers/phy/socionext/Kconfig"
+ source "drivers/phy/st/Kconfig"
++source "drivers/phy/starfive/Kconfig"
+ source "drivers/phy/sunplus/Kconfig"
+ source "drivers/phy/tegra/Kconfig"
+ source "drivers/phy/ti/Kconfig"
+diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
+index 54f312c10a40..fb3dc9de6111 100644
+--- a/drivers/phy/Makefile
++++ b/drivers/phy/Makefile
+@@ -31,6 +31,7 @@ obj-y += allwinner/ \
+ samsung/ \
+ socionext/ \
+ st/ \
++ starfive/ \
+ sunplus/ \
+ tegra/ \
+ ti/ \
+diff --git a/drivers/phy/starfive/Kconfig b/drivers/phy/starfive/Kconfig
+new file mode 100644
+index 000000000000..82ed16d05934
+--- /dev/null
++++ b/drivers/phy/starfive/Kconfig
+@@ -0,0 +1,26 @@
++# SPDX-License-Identifier: GPL-2.0-only
++#
++# Phy drivers for StarFive platforms
++#
++
++config PHY_STARFIVE_JH7110_USB
++ tristate "Starfive JH7110 USB 2.0 PHY support"
++ depends on USB_SUPPORT
++ select GENERIC_PHY
++ select USB_PHY
++ help
++ Enable this to support the StarFive USB 2.0 PHY,
++ used with the Cadence USB controller.
++ If M is selected, the module will be called
++ phy-jh7110-usb.ko.
++
++config PHY_STARFIVE_JH7110_PCIE
++ tristate "Starfive JH7110 PCIE 2.0/USB 3.0 PHY support"
++ depends on USB_SUPPORT
++ select GENERIC_PHY
++ select USB_PHY
++ help
++ Enable this to support the StarFive PCIe 2.0 PHY,
++ or used as USB 3.0 PHY.
++ If M is selected, the module will be called
++ phy-jh7110-pcie.ko.
+diff --git a/drivers/phy/starfive/Makefile b/drivers/phy/starfive/Makefile
+new file mode 100644
+index 000000000000..fd81ca844267
+--- /dev/null
++++ b/drivers/phy/starfive/Makefile
+@@ -0,0 +1,3 @@
++# SPDX-License-Identifier: GPL-2.0
++obj-$(CONFIG_PHY_STARFIVE_JH7110_USB) += phy-jh7110-usb.o
++obj-$(CONFIG_PHY_STARFIVE_JH7110_PCIE) += phy-jh7110-pcie.o
+--
+2.20.1
+
--- /dev/null
+From f736e353d759348ea608b4baea75ee1c2ae8a2f6 Mon Sep 17 00:00:00 2001
+From: Zoltan HERPAI <wigyori@uid0.hu>
+Date: Sun, 28 May 2023 20:17:45 +0200
+Subject: [PATCH 79/95] cdns3/6.1: change ARCH_STARFIVE to SOC_STARFIVE
+
+Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>
+---
+ drivers/usb/cdns3/Kconfig | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/usb/cdns3/Kconfig b/drivers/usb/cdns3/Kconfig
+index 0a514b591527..898f497d5e45 100644
+--- a/drivers/usb/cdns3/Kconfig
++++ b/drivers/usb/cdns3/Kconfig
+@@ -80,7 +80,7 @@ config USB_CDNS3_IMX
+
+ config USB_CDNS3_STARFIVE
+ tristate "Cadence USB3 support on StarFive SoC platforms"
+- depends on ARCH_STARFIVE || COMPILE_TEST
++ depends on SOC_STARFIVE || COMPILE_TEST
+ help
+ Say 'Y' or 'M' here if you are building for StarFive SoCs
+ platforms that contain Cadence USB3 controller core.
+--
+2.20.1
+
--- /dev/null
+From 84707813ac114be80eb31244916f3e0bdd3ed15b Mon Sep 17 00:00:00 2001
+From: William Qiu <william.qiu@starfivetech.com>
+Date: Fri, 12 May 2023 10:20:35 +0800
+Subject: [PATCH 87/95] riscv: dts: starfive: jh7110: Add syscon nodes
+
+Add stg_syscon/sys_syscon/aon_syscon nodes for JH7110 Soc.
+
+Co-developed-by: Xingyu Wu <xingyu.wu@starfivetech.com>
+Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
+Signed-off-by: William Qiu <william.qiu@starfivetech.com>
+---
+ arch/riscv/boot/dts/starfive/jh7110.dtsi | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+diff --git a/arch/riscv/boot/dts/starfive/jh7110.dtsi b/arch/riscv/boot/dts/starfive/jh7110.dtsi
+index b6a023b4c23e..d87181cfc09c 100644
+--- a/arch/riscv/boot/dts/starfive/jh7110.dtsi
++++ b/arch/riscv/boot/dts/starfive/jh7110.dtsi
+@@ -429,6 +429,11 @@
+ #reset-cells = <1>;
+ };
+
++ stg_syscon: syscon@10240000 {
++ compatible = "starfive,jh7110-stg-syscon", "syscon";
++ reg = <0x0 0x10240000 0x0 0x1000>;
++ };
++
+ uart3: serial@12000000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x0 0x12000000 0x0 0x10000>;
+@@ -548,6 +553,11 @@
+ reg = <0x0 0x13030000 0x0 0x1000>;
+ };
+
++ sys_syscon: syscon@13030000 {
++ compatible = "starfive,jh7110-sys-syscon", "syscon", "simple-mfd";
++ reg = <0x0 0x13030000 0x0 0x1000>;
++ };
++
+ sysgpio: pinctrl@13040000 {
+ compatible = "starfive,jh7110-sys-pinctrl";
+ reg = <0x0 0x13040000 0x0 0x10000>;
+@@ -577,6 +587,12 @@
+ #reset-cells = <1>;
+ };
+
++ aon_syscon: syscon@17010000 {
++ compatible = "starfive,jh7110-aon-syscon", "syscon";
++ reg = <0x0 0x17010000 0x0 0x1000>;
++ #power-domain-cells = <1>;
++ };
++
+ aongpio: pinctrl@17020000 {
+ compatible = "starfive,jh7110-aon-pinctrl";
+ reg = <0x0 0x17020000 0x0 0x10000>;
+--
+2.20.1
+
--- /dev/null
+From 79c663c8da42f137dd67549eb4c8613e9b7b45df Mon Sep 17 00:00:00 2001
+From: Zoltan HERPAI <wigyori@uid0.hu>
+Date: Mon, 29 May 2023 00:39:44 +0200
+Subject: [PATCH 90/95] dts/6.1: jh7110: syscon updates
+
+Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>
+---
+ arch/riscv/boot/dts/starfive/jh7110.dtsi | 9 ++-------
+ 1 file changed, 2 insertions(+), 7 deletions(-)
+
+diff --git a/arch/riscv/boot/dts/starfive/jh7110.dtsi b/arch/riscv/boot/dts/starfive/jh7110.dtsi
+index 5b3e30ec9618..0fb22d4a860e 100644
+--- a/arch/riscv/boot/dts/starfive/jh7110.dtsi
++++ b/arch/riscv/boot/dts/starfive/jh7110.dtsi
+@@ -552,11 +552,6 @@
+ #reset-cells = <1>;
+ };
+
+- sysreg: syscon@13030000 {
+- compatible = "starfive,sysreg", "syscon";
+- reg = <0x0 0x13030000 0x0 0x1000>;
+- };
+-
+ sys_syscon: syscon@13030000 {
+ compatible = "starfive,jh7110-sys-syscon", "syscon", "simple-mfd";
+ reg = <0x0 0x13030000 0x0 0x1000>;
+@@ -626,7 +621,7 @@
+ fifo-depth = <32>;
+ fifo-watermark-aligned;
+ data-addr = <0>;
+- starfive,syscon = <&sysreg 0x14 0x1a 0x7c000000>;
++ starfive,syscon = <&sys_syscon 0x14 0x1a 0x7c000000>;
+ status = "disabled";
+ };
+
+@@ -642,7 +637,7 @@
+ fifo-depth = <32>;
+ fifo-watermark-aligned;
+ data-addr = <0>;
+- starfive,syscon = <&sysreg 0x9c 0x1 0x3e>;
++ starfive,syscon = <&sys_syscon 0x9c 0x1 0x3e>;
+ status = "disabled";
+ };
+
+--
+2.20.1
+
--- /dev/null
+From 8cce344efbddfcea37a001ce67a652aac02a80d3 Mon Sep 17 00:00:00 2001
+From: Samin Guo <samin.guo@starfivetech.com>
+Date: Fri, 3 Mar 2023 16:49:31 +0800
+Subject: [PATCH 91/95] riscv: dts: starfive: jh7110: Add ethernet device nodes
+
+Add JH7110 ethernet device node to support gmac driver for the JH7110
+RISC-V SoC.
+
+Signed-off-by: Yanhong Wang <yanhong.wang@starfivetech.com>
+Signed-off-by: Samin Guo <samin.guo@starfivetech.com>
+---
+ arch/riscv/boot/dts/starfive/jh7110.dtsi | 91 ++++++++++++++++++++++++
+ 1 file changed, 91 insertions(+)
+
+diff --git a/arch/riscv/boot/dts/starfive/jh7110.dtsi b/arch/riscv/boot/dts/starfive/jh7110.dtsi
+index 0fb22d4a860e..a9e02c88569a 100644
+--- a/arch/riscv/boot/dts/starfive/jh7110.dtsi
++++ b/arch/riscv/boot/dts/starfive/jh7110.dtsi
+@@ -243,6 +243,13 @@
+ #clock-cells = <0>;
+ };
+
++ stmmac_axi_setup: stmmac-axi-config {
++ snps,lpi_en;
++ snps,wr_osr_lmt = <4>;
++ snps,rd_osr_lmt = <4>;
++ snps,blen = <256 128 64 32 0 0 0>;
++ };
++
+ tdm_ext: tdm-ext-clock {
+ compatible = "fixed-clock";
+ clock-output-names = "tdm_ext";
+@@ -682,5 +689,89 @@
+ #reset-cells = <1>;
+ power-domains = <&pwrc JH7110_PD_VOUT>;
+ };
++
++ gmac0: ethernet@16030000 {
++ compatible = "starfive,jh7110-dwmac", "snps,dwmac-5.20";
++ reg = <0x0 0x16030000 0x0 0x10000>;
++ clocks = <&aoncrg JH7110_AONCLK_GMAC0_AXI>,
++ <&aoncrg JH7110_AONCLK_GMAC0_AHB>,
++ <&syscrg JH7110_SYSCLK_GMAC0_PTP>,
++ <&aoncrg JH7110_AONCLK_GMAC0_TX_INV>,
++ <&syscrg JH7110_SYSCLK_GMAC0_GTXC>;
++ clock-names = "stmmaceth", "pclk", "ptp_ref",
++ "tx", "gtx";
++ resets = <&aoncrg JH7110_AONRST_GMAC0_AXI>,
++ <&aoncrg JH7110_AONRST_GMAC0_AHB>;
++ reset-names = "stmmaceth", "ahb";
++ interrupts = <7>, <6>, <5>;
++ interrupt-names = "macirq", "eth_wake_irq", "eth_lpi";
++ phy-mode = "rgmii-id";
++ snps,multicast-filter-bins = <64>;
++ snps,perfect-filter-entries = <8>;
++ rx-fifo-depth = <2048>;
++ tx-fifo-depth = <2048>;
++ snps,fixed-burst;
++ snps,no-pbl-x8;
++ snps,force_thresh_dma_mode;
++ snps,axi-config = <&stmmac_axi_setup>;
++ snps,tso;
++ snps,en-tx-lpi-clockgating;
++ snps,txpbl = <16>;
++ snps,rxpbl = <16>;
++ status = "disabled";
++ phy-handle = <&phy0>;
++
++ mdio {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ compatible = "snps,dwmac-mdio";
++
++ phy0: ethernet-phy@0 {
++ reg = <0>;
++ };
++ };
++ };
++
++ gmac1: ethernet@16040000 {
++ compatible = "starfive,jh7110-dwmac", "snps,dwmac-5.20";
++ reg = <0x0 0x16040000 0x0 0x10000>;
++ clocks = <&syscrg JH7110_SYSCLK_GMAC1_AXI>,
++ <&syscrg JH7110_SYSCLK_GMAC1_AHB>,
++ <&syscrg JH7110_SYSCLK_GMAC1_PTP>,
++ <&syscrg JH7110_SYSCLK_GMAC1_TX_INV>,
++ <&syscrg JH7110_SYSCLK_GMAC1_GTXC>;
++ clock-names = "stmmaceth", "pclk", "ptp_ref",
++ "tx", "gtx";
++ resets = <&syscrg JH7110_SYSRST_GMAC1_AXI>,
++ <&syscrg JH7110_SYSRST_GMAC1_AHB>;
++ reset-names = "stmmaceth", "ahb";
++ interrupts = <78>, <77>, <76>;
++ interrupt-names = "macirq", "eth_wake_irq", "eth_lpi";
++ phy-mode = "rgmii-id";
++ snps,multicast-filter-bins = <64>;
++ snps,perfect-filter-entries = <8>;
++ rx-fifo-depth = <2048>;
++ tx-fifo-depth = <2048>;
++ snps,fixed-burst;
++ snps,no-pbl-x8;
++ snps,force_thresh_dma_mode;
++ snps,axi-config = <&stmmac_axi_setup>;
++ snps,tso;
++ snps,en-tx-lpi-clockgating;
++ snps,txpbl = <16>;
++ snps,rxpbl = <16>;
++ status = "disabled";
++ phy-handle = <&phy1>;
++
++ mdio {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ compatible = "snps,dwmac-mdio";
++
++ phy1: ethernet-phy@1 {
++ reg = <0>;
++ };
++ };
++ };
+ };
+ };
+--
+2.20.1
+
--- /dev/null
+From 735cd14099ccb01555227ac672f1cefe13f3e471 Mon Sep 17 00:00:00 2001
+From: Samin Guo <samin.guo@starfivetech.com>
+Date: Fri, 3 Mar 2023 10:03:35 +0800
+Subject: [PATCH 92/95] riscv: dts: starfive: jh7110: Add syscon to support phy
+ interface settings
+
+The phy interface needs to be set in syscon, the format is as follows:
+starfive,syscon: <&syscon, offset, mask>
+
+Signed-off-by: Samin Guo <samin.guo@starfivetech.com>
+---
+ arch/riscv/boot/dts/starfive/jh7110.dtsi | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/arch/riscv/boot/dts/starfive/jh7110.dtsi b/arch/riscv/boot/dts/starfive/jh7110.dtsi
+index a9e02c88569a..7ffeeded54a7 100644
+--- a/arch/riscv/boot/dts/starfive/jh7110.dtsi
++++ b/arch/riscv/boot/dts/starfive/jh7110.dtsi
+@@ -718,6 +718,7 @@
+ snps,en-tx-lpi-clockgating;
+ snps,txpbl = <16>;
+ snps,rxpbl = <16>;
++ starfive,syscon = <&aon_syscon 0xc 0x1c0000>;
+ status = "disabled";
+ phy-handle = <&phy0>;
+
+@@ -760,6 +761,7 @@
+ snps,en-tx-lpi-clockgating;
+ snps,txpbl = <16>;
+ snps,rxpbl = <16>;
++ starfive,syscon = <&sys_syscon 0x90 0x1c>;
+ status = "disabled";
+ phy-handle = <&phy1>;
+
+--
+2.20.1
+
--- /dev/null
+From 09b1e03df780cc0b75fe714a6bade73691f5911a Mon Sep 17 00:00:00 2001
+From: Samin Guo <samin.guo@starfivetech.com>
+Date: Mon, 20 Feb 2023 17:13:47 +0800
+Subject: [PATCH 93/95] riscv: dts: starfive: visionfive-2-v1.3b: Add
+ gmac+phy's delay configuration
+
+v1.3B uses motorcomm YT8531(rgmii-id phy) x2, need delay and
+inverse configurations.
+
+The tx_clk of v1.3B uses an external clock and needs to be
+switched to an external clock source.
+
+Signed-off-by: Samin Guo <samin.guo@starfivetech.com>
+---
+ .../jh7110-starfive-visionfive-2-v1.3b.dts | 27 +++++++++++++++++++
+ 1 file changed, 27 insertions(+)
+
+diff --git a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-v1.3b.dts b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-v1.3b.dts
+index 9230cc3d8946..32fae0de9a44 100644
+--- a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-v1.3b.dts
++++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-v1.3b.dts
+@@ -11,3 +11,30 @@
+ model = "StarFive VisionFive 2 v1.3B";
+ compatible = "starfive,visionfive-2-v1.3b", "starfive,jh7110";
+ };
++
++&gmac0 {
++ starfive,tx-use-rgmii-clk;
++ assigned-clocks = <&aoncrg JH7110_AONCLK_GMAC0_TX>;
++ assigned-clock-parents = <&aoncrg JH7110_AONCLK_GMAC0_RMII_RTX>;
++};
++
++&gmac1 {
++ starfive,tx-use-rgmii-clk;
++ assigned-clocks = <&syscrg JH7110_SYSCLK_GMAC1_TX>;
++ assigned-clock-parents = <&syscrg JH7110_SYSCLK_GMAC1_RMII_RTX>;
++};
++
++&phy0 {
++ motorcomm,tx-clk-adj-enabled;
++ motorcomm,tx-clk-100-inverted;
++ motorcomm,tx-clk-1000-inverted;
++ rx-internal-delay-ps = <1900>;
++ tx-internal-delay-ps = <1500>;
++};
++
++&phy1 {
++ motorcomm,tx-clk-adj-enabled;
++ motorcomm,tx-clk-100-inverted;
++ rx-internal-delay-ps = <0>;
++ tx-internal-delay-ps = <0>;
++};
+--
+2.20.1
+
--- /dev/null
+From 180f71182595a74e77bb857a482931ce42592d56 Mon Sep 17 00:00:00 2001
+From: Samin Guo <samin.guo@starfivetech.com>
+Date: Mon, 20 Feb 2023 17:18:52 +0800
+Subject: [PATCH 94/95] riscv: dts: starfive: visionfive-2-v1.2a: Add
+ gmac+phy's delay configuration
+
+v1.2A gmac0 uses motorcomm YT8531(rgmii-id) PHY, and needs delay
+configurations.
+
+v1.2A gmac1 uses motorcomm YT8512(rmii) PHY, and needs to
+switch rx and rx to external clock sources.
+
+Signed-off-by: Samin Guo <samin.guo@starfivetech.com>
+---
+ .../starfive/jh7110-starfive-visionfive-2-v1.2a.dts | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+diff --git a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-v1.2a.dts b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-v1.2a.dts
+index 4af3300f3cf3..205a13d8c8b1 100644
+--- a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-v1.2a.dts
++++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-v1.2a.dts
+@@ -11,3 +11,16 @@
+ model = "StarFive VisionFive 2 v1.2A";
+ compatible = "starfive,visionfive-2-v1.2a", "starfive,jh7110";
+ };
++
++&gmac1 {
++ phy-mode = "rmii";
++ assigned-clocks = <&syscrg JH7110_SYSCLK_GMAC1_TX>,
++ <&syscrg JH7110_SYSCLK_GMAC1_RX>;
++ assigned-clock-parents = <&syscrg JH7110_SYSCLK_GMAC1_RMII_RTX>,
++ <&syscrg JH7110_SYSCLK_GMAC1_RMII_RTX>;
++};
++
++&phy0 {
++ rx-internal-delay-ps = <1900>;
++ tx-internal-delay-ps = <1350>;
++};
+--
+2.20.1
+
--- /dev/null
+From 658250d9a81124ba4a63a834eb507660f0a04b1f Mon Sep 17 00:00:00 2001
+From: Yanhong Wang <yanhong.wang@starfivetech.com>
+Date: Tue, 1 Nov 2022 18:11:02 +0800
+Subject: [PATCH 95/95] riscv: dts: starfive: visionfive 2: Enable gmac device
+ tree node
+
+Update gmac device tree node status to okay.
+
+Signed-off-by: Yanhong Wang <yanhong.wang@starfivetech.com>
+Signed-off-by: Samin Guo <samin.guo@starfivetech.com>
+---
+ .../dts/starfive/jh7110-starfive-visionfive-2.dtsi | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
+index 41662fee3804..96f86aece098 100644
+--- a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
++++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
+@@ -11,6 +11,8 @@
+
+ / {
+ aliases {
++ ethernet0 = &gmac0;
++ ethernet1 = &gmac1;
+ i2c0 = &i2c0;
+ i2c2 = &i2c2;
+ i2c5 = &i2c5;
+@@ -117,6 +119,14 @@
+ clock-frequency = <49152000>;
+ };
+
++&gmac0 {
++ status = "okay";
++};
++
++&gmac1 {
++ status = "okay";
++};
++
+ &i2c0 {
+ clock-frequency = <100000>;
+ i2c-sda-hold-time-ns = <300>;
+--
+2.20.1
+
--- /dev/null
+From e3d0d5fea3429218b79b58eb6cc96f5d5ab5dd31 Mon Sep 17 00:00:00 2001
+From: Zoltan HERPAI <wigyori@uid0.hu>
+Date: Mon, 29 May 2023 01:16:50 +0200
+Subject: [PATCH 97/97] riscv/6.1: jh7110: add watchdog node
+
+Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>
+---
+ arch/riscv/boot/dts/starfive/jh7110.dtsi | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/arch/riscv/boot/dts/starfive/jh7110.dtsi b/arch/riscv/boot/dts/starfive/jh7110.dtsi
+index 7ffeeded54a7..f3f563e3c5c2 100644
+--- a/arch/riscv/boot/dts/starfive/jh7110.dtsi
++++ b/arch/riscv/boot/dts/starfive/jh7110.dtsi
+@@ -582,6 +582,16 @@
+ #gpio-cells = <2>;
+ };
+
++ watchdog@13070000 {
++ compatible = "starfive,jh7110-wdt";
++ reg = <0x0 0x13070000 0x0 0x10000>;
++ clocks = <&syscrg JH7110_SYSCLK_WDT_APB>,
++ <&syscrg JH7110_SYSCLK_WDT_CORE>;
++ clock-names = "apb", "core";
++ resets = <&syscrg JH7110_SYSRST_WDT_APB>,
++ <&syscrg JH7110_SYSRST_WDT_CORE>;
++ };
++
+ aoncrg: clock-controller@17000000 {
+ compatible = "starfive,jh7110-aoncrg";
+ reg = <0x0 0x17000000 0x0 0x10000>;
+--
+2.20.1
+
--- /dev/null
+From 2671efe486d958cdbf37e95666eb0c7def6f4c59 Mon Sep 17 00:00:00 2001
+From: Xingyu Wu <xingyu.wu@starfivetech.com>
+Date: Mon, 20 Mar 2023 21:54:32 +0800
+Subject: [PATCH 98/99] clocksource: Add StarFive timer driver
+
+Add timer driver for the StarFive JH7110 SoC.
+
+Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
+---
+ drivers/clocksource/Kconfig | 12 +
+ drivers/clocksource/Makefile | 1 +
+ drivers/clocksource/timer-starfive.c | 390 +++++++++++++++++++++++++++
+ drivers/clocksource/timer-starfive.h | 96 +++++++
+ 4 files changed, 499 insertions(+)
+ create mode 100644 drivers/clocksource/timer-starfive.c
+ create mode 100644 drivers/clocksource/timer-starfive.h
+
+diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
+index 4469e7f555e9..6341128cd71e 100644
+--- a/drivers/clocksource/Kconfig
++++ b/drivers/clocksource/Kconfig
+@@ -630,6 +630,18 @@ config RISCV_TIMER
+ is accessed via both the SBI and the rdcycle instruction. This is
+ required for all RISC-V systems.
+
++config STARFIVE_TIMER
++ bool "Timer for the STARFIVE SoCs"
++ depends on ARCH_STARFIVE || COMPILE_TEST
++ select TIMER_OF
++ select CLKSRC_MMIO
++ default ARCH_STARFIVE
++ help
++ This enables the timer for StarFive SoCs. On RISC-V platform,
++ the system has started RISCV_TIMER. But you can also use this timer
++ to do a lot more on StarFive SoCs. This timer can provide high
++ precision and four channels to use in JH7110 SoC.
++
+ config CLINT_TIMER
+ bool "CLINT Timer for the RISC-V platform" if COMPILE_TEST
+ depends on GENERIC_SCHED_CLOCK && RISCV
+diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
+index 64ab547de97b..276695d95cdc 100644
+--- a/drivers/clocksource/Makefile
++++ b/drivers/clocksource/Makefile
+@@ -80,6 +80,7 @@ obj-$(CONFIG_INGENIC_TIMER) += ingenic-timer.o
+ obj-$(CONFIG_CLKSRC_ST_LPC) += clksrc_st_lpc.o
+ obj-$(CONFIG_X86_NUMACHIP) += numachip.o
+ obj-$(CONFIG_RISCV_TIMER) += timer-riscv.o
++obj-$(CONFIG_STARFIVE_TIMER) += timer-starfive.o
+ obj-$(CONFIG_CLINT_TIMER) += timer-clint.o
+ obj-$(CONFIG_CSKY_MP_TIMER) += timer-mp-csky.o
+ obj-$(CONFIG_GX6605S_TIMER) += timer-gx6605s.o
+diff --git a/drivers/clocksource/timer-starfive.c b/drivers/clocksource/timer-starfive.c
+new file mode 100644
+index 000000000000..53163948ed86
+--- /dev/null
++++ b/drivers/clocksource/timer-starfive.c
+@@ -0,0 +1,390 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Starfive Timer driver
++ *
++ * Copyright (C) 2022 StarFive Technology Co., Ltd.
++ *
++ * Author:
++ * Xingyu Wu <xingyu.wu@starfivetech.com>
++ * Samin Guo <samin.guo@starfivetech.com>
++ */
++
++#include <linux/clk.h>
++#include <linux/clockchips.h>
++#include <linux/clocksource.h>
++#include <linux/err.h>
++#include <linux/interrupt.h>
++#include <linux/io.h>
++#include <linux/iopoll.h>
++#include <linux/irq.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/of_device.h>
++#include <linux/platform_device.h>
++#include <linux/reset.h>
++#include <linux/sched_clock.h>
++
++#include "timer-starfive.h"
++
++static const struct starfive_timer_chan_base starfive_timer_jh7110_base = {
++ .ctrl = STARFIVE_TIMER_JH7110_CTL,
++ .load = STARFIVE_TIMER_JH7110_LOAD,
++ .enable = STARFIVE_TIMER_JH7110_ENABLE,
++ .reload = STARFIVE_TIMER_JH7110_RELOAD,
++ .value = STARFIVE_TIMER_JH7110_VALUE,
++ .intclr = STARFIVE_TIMER_JH7110_INT_CLR,
++ .intmask = STARFIVE_TIMER_JH7110_INT_MASK,
++ .channel_num = STARFIVE_TIMER_CH_4,
++ .channel_base = {STARFIVE_TIMER_CH_BASE(0), STARFIVE_TIMER_CH_BASE(1),
++ STARFIVE_TIMER_CH_BASE(2), STARFIVE_TIMER_CH_BASE(3)},
++};
++
++static inline struct starfive_clkevt *to_starfive_clkevt(struct clock_event_device *evt)
++{
++ return container_of(evt, struct starfive_clkevt, evt);
++}
++
++/* 0:continuous-run mode, 1:single-run mode */
++static inline void starfive_timer_set_mod(struct starfive_clkevt *clkevt, int mod)
++{
++ writel(mod, clkevt->ctrl);
++}
++
++/* Interrupt Mask Register, 0:Unmask, 1:Mask */
++static inline void starfive_timer_int_enable(struct starfive_clkevt *clkevt)
++{
++ writel(STARFIVE_TIMER_INTMASK_DIS, clkevt->intmask);
++}
++
++static inline void starfive_timer_int_disable(struct starfive_clkevt *clkevt)
++{
++ writel(STARFIVE_TIMER_INTMASK_ENA, clkevt->intmask);
++}
++
++/*
++ * BIT(0): Read value represent channel intr status.
++ * Write 1 to this bit to clear interrupt. Write 0 has no effects.
++ * BIT(1): "1" means that it is clearing interrupt. BIT(0) can not be written.
++ */
++static inline int starfive_timer_int_clear(struct starfive_clkevt *clkevt)
++{
++ u32 value;
++ int ret;
++
++ /* waiting interrupt can be to clearing */
++ ret = readl_poll_timeout_atomic(clkevt->intclr, value,
++ !(value & STARFIVE_TIMER_JH7110_INT_CLR_AVA_MASK),
++ STARFIVE_DELAY_US, STARFIVE_TIMEOUT_US);
++ if (!ret)
++ writel(0x1, clkevt->intclr);
++
++ return ret;
++}
++
++/*
++ * The initial value to be loaded into the
++ * counter and is also used as the reload value.
++ * val = clock rate --> 1s
++ */
++static inline void starfive_timer_set_load(struct starfive_clkevt *clkevt, u32 val)
++{
++ writel(val, clkevt->load);
++}
++
++static inline u32 starfive_timer_get_val(struct starfive_clkevt *clkevt)
++{
++ return readl(clkevt->value);
++}
++
++/*
++ * Write RELOAD register to reload preset value to counter.
++ * (Write 0 and write 1 are both ok)
++ */
++static inline void starfive_timer_set_reload(struct starfive_clkevt *clkevt)
++{
++ writel(0, clkevt->reload);
++}
++
++static inline void starfive_timer_enable(struct starfive_clkevt *clkevt)
++{
++ writel(STARFIVE_TIMER_ENA, clkevt->enable);
++}
++
++static inline void starfive_timer_disable(struct starfive_clkevt *clkevt)
++{
++ writel(STARFIVE_TIMER_DIS, clkevt->enable);
++}
++
++static int starfive_timer_int_init_enable(struct starfive_clkevt *clkevt)
++{
++ int ret;
++
++ starfive_timer_int_disable(clkevt);
++ ret = starfive_timer_int_clear(clkevt);
++ if (ret)
++ return ret;
++
++ starfive_timer_int_enable(clkevt);
++ starfive_timer_enable(clkevt);
++
++ return 0;
++}
++
++static int starfive_timer_shutdown(struct clock_event_device *evt)
++{
++ struct starfive_clkevt *clkevt = to_starfive_clkevt(evt);
++
++ starfive_timer_disable(clkevt);
++ return starfive_timer_int_clear(clkevt);
++}
++
++static void starfive_timer_suspend(struct clock_event_device *evt)
++{
++ struct starfive_clkevt *clkevt = to_starfive_clkevt(evt);
++
++ clkevt->reload_val = starfive_timer_get_val(clkevt);
++ starfive_timer_shutdown(evt);
++}
++
++static void starfive_timer_resume(struct clock_event_device *evt)
++{
++ struct starfive_clkevt *clkevt = to_starfive_clkevt(evt);
++
++ starfive_timer_set_load(clkevt, clkevt->reload_val);
++ starfive_timer_set_reload(clkevt);
++ starfive_timer_int_enable(clkevt);
++ starfive_timer_enable(clkevt);
++}
++
++static int starfive_timer_tick_resume(struct clock_event_device *evt)
++{
++ starfive_timer_resume(evt);
++
++ return 0;
++}
++
++static int starfive_clocksource_init(struct starfive_clkevt *clkevt)
++{
++ int ret;
++
++ starfive_timer_set_mod(clkevt, STARFIVE_TIMER_MOD_CONTIN);
++ starfive_timer_set_load(clkevt, STARFIVE_TIMER_MAX_TICKS);
++ ret = starfive_timer_int_init_enable(clkevt);
++ if (ret)
++ return ret;
++
++ return clocksource_mmio_init(clkevt->value, clkevt->name, clkevt->rate,
++ STARFIVE_CLOCK_SOURCE_RATING, STARFIVE_VALID_BITS,
++ clocksource_mmio_readl_down);
++}
++
++/* IRQ handler for the timer */
++static irqreturn_t starfive_timer_interrupt(int irq, void *priv)
++{
++ struct clock_event_device *evt = (struct clock_event_device *)priv;
++ struct starfive_clkevt *clkevt = to_starfive_clkevt(evt);
++
++ if (starfive_timer_int_clear(clkevt))
++ return IRQ_NONE;
++
++ if (evt->event_handler)
++ evt->event_handler(evt);
++
++ return IRQ_HANDLED;
++}
++
++static int starfive_timer_set_periodic(struct clock_event_device *evt)
++{
++ struct starfive_clkevt *clkevt = to_starfive_clkevt(evt);
++
++ starfive_timer_disable(clkevt);
++ starfive_timer_set_mod(clkevt, STARFIVE_TIMER_MOD_CONTIN);
++ starfive_timer_set_load(clkevt, clkevt->periodic);
++
++ return starfive_timer_int_init_enable(clkevt);
++}
++
++static int starfive_timer_set_oneshot(struct clock_event_device *evt)
++{
++ struct starfive_clkevt *clkevt = to_starfive_clkevt(evt);
++
++ starfive_timer_disable(clkevt);
++ starfive_timer_set_mod(clkevt, STARFIVE_TIMER_MOD_SINGLE);
++ starfive_timer_set_load(clkevt, STARFIVE_TIMER_MAX_TICKS);
++
++ return starfive_timer_int_init_enable(clkevt);
++}
++
++static int starfive_timer_set_next_event(unsigned long next,
++ struct clock_event_device *evt)
++{
++ struct starfive_clkevt *clkevt = to_starfive_clkevt(evt);
++
++ starfive_timer_disable(clkevt);
++ starfive_timer_set_mod(clkevt, STARFIVE_TIMER_MOD_SINGLE);
++ starfive_timer_set_load(clkevt, next);
++ starfive_timer_enable(clkevt);
++
++ return 0;
++}
++
++static void starfive_set_clockevent(struct clock_event_device *evt)
++{
++ evt->features = CLOCK_EVT_FEAT_PERIODIC |
++ CLOCK_EVT_FEAT_ONESHOT |
++ CLOCK_EVT_FEAT_DYNIRQ;
++ evt->set_state_shutdown = starfive_timer_shutdown;
++ evt->set_state_periodic = starfive_timer_set_periodic;
++ evt->set_state_oneshot = starfive_timer_set_oneshot;
++ evt->set_state_oneshot_stopped = starfive_timer_shutdown;
++ evt->tick_resume = starfive_timer_tick_resume;
++ evt->set_next_event = starfive_timer_set_next_event;
++ evt->suspend = starfive_timer_suspend;
++ evt->resume = starfive_timer_resume;
++ evt->rating = STARFIVE_CLOCKEVENT_RATING;
++}
++
++static void starfive_clockevents_register(struct starfive_clkevt *clkevt)
++{
++ clkevt->rate = clk_get_rate(clkevt->clk);
++ clkevt->periodic = DIV_ROUND_CLOSEST(clkevt->rate, HZ);
++
++ starfive_set_clockevent(&clkevt->evt);
++ clkevt->evt.name = clkevt->name;
++ clkevt->evt.irq = clkevt->irq;
++ clkevt->evt.cpumask = cpu_possible_mask;
++
++ clockevents_config_and_register(&clkevt->evt, clkevt->rate,
++ STARFIVE_TIMER_MIN_TICKS, STARFIVE_TIMER_MAX_TICKS);
++}
++
++static void __init starfive_clkevt_base_init(const struct starfive_timer_chan_base *timer,
++ struct starfive_clkevt *clkevt,
++ void __iomem *base, int ch)
++{
++ void __iomem *channel_base;
++
++ channel_base = base + timer->channel_base[ch];
++ clkevt->base = channel_base;
++ clkevt->ctrl = channel_base + timer->ctrl;
++ clkevt->load = channel_base + timer->load;
++ clkevt->enable = channel_base + timer->enable;
++ clkevt->reload = channel_base + timer->reload;
++ clkevt->value = channel_base + timer->value;
++ clkevt->intclr = channel_base + timer->intclr;
++ clkevt->intmask = channel_base + timer->intmask;
++}
++
++static int __init starfive_timer_probe(struct platform_device *pdev)
++{
++ const struct starfive_timer_chan_base *timer_base = of_device_get_match_data(&pdev->dev);
++ char name[10];
++ struct starfive_timer_priv *priv;
++ struct starfive_clkevt *clkevt;
++ struct clk *pclk;
++ struct reset_control *rst;
++ int ch;
++ int ret;
++
++ priv = devm_kzalloc(&pdev->dev, struct_size(priv, clkevt, timer_base->channel_num),
++ GFP_KERNEL);
++ if (!priv)
++ return -ENOMEM;
++
++ priv->base = devm_platform_ioremap_resource(pdev, 0);
++ if (IS_ERR(priv->base))
++ return dev_err_probe(&pdev->dev, PTR_ERR(priv->base),
++ "failed to map registers\n");
++
++ rst = devm_reset_control_get_exclusive(&pdev->dev, "apb");
++ if (IS_ERR(rst))
++ return dev_err_probe(&pdev->dev, PTR_ERR(rst), "failed to get apb reset\n");
++
++ pclk = devm_clk_get_enabled(&pdev->dev, "apb");
++ if (IS_ERR(pclk))
++ return dev_err_probe(&pdev->dev, PTR_ERR(pclk),
++ "failed to get & enable apb clock\n");
++
++ ret = reset_control_deassert(rst);
++ if (ret)
++ goto err;
++
++ priv->dev = &pdev->dev;
++ platform_set_drvdata(pdev, priv);
++
++ for (ch = 0; ch < timer_base->channel_num; ch++) {
++ clkevt = &priv->clkevt[ch];
++ snprintf(name, sizeof(name), "ch%d", ch);
++
++ starfive_clkevt_base_init(timer_base, clkevt, priv->base, ch);
++ /* Ensure timers are disabled */
++ starfive_timer_disable(clkevt);
++
++ rst = devm_reset_control_get_exclusive(&pdev->dev, name);
++ if (IS_ERR(rst)) {
++ ret = PTR_ERR(rst);
++ goto err;
++ }
++
++ clkevt->clk = devm_clk_get_enabled(&pdev->dev, name);
++ if (IS_ERR(clkevt->clk)) {
++ ret = PTR_ERR(clkevt->clk);
++ goto err;
++ }
++
++ ret = reset_control_deassert(rst);
++ if (ret)
++ goto ch_err;
++
++ clkevt->irq = platform_get_irq(pdev, ch);
++ if (clkevt->irq < 0) {
++ ret = clkevt->irq;
++ goto ch_err;
++ }
++
++ snprintf(clkevt->name, sizeof(clkevt->name), "%s.ch%d", pdev->name, ch);
++ starfive_clockevents_register(clkevt);
++
++ ret = devm_request_irq(&pdev->dev, clkevt->irq, starfive_timer_interrupt,
++ IRQF_TIMER | IRQF_IRQPOLL,
++ clkevt->name, &clkevt->evt);
++ if (ret)
++ goto ch_err;
++
++ ret = starfive_clocksource_init(clkevt);
++ if (ret)
++ goto ch_err;
++ }
++
++ return 0;
++
++ch_err:
++ /* Only unregister the failed channel and the rest timer channels continue to work. */
++ clk_disable_unprepare(clkevt->clk);
++err:
++ /* If no other channel successfully registers, pclk should be disabled. */
++ if (!ch)
++ clk_disable_unprepare(pclk);
++
++ return ret;
++}
++
++static const struct of_device_id starfive_timer_match[] = {
++ { .compatible = "starfive,jh7110-timer", .data = &starfive_timer_jh7110_base },
++ { /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(of, starfive_timer_match);
++
++static struct platform_driver starfive_timer_driver = {
++ .probe = starfive_timer_probe,
++ .driver = {
++ .name = "starfive-timer",
++ .of_match_table = starfive_timer_match,
++ },
++};
++module_platform_driver(starfive_timer_driver);
++
++MODULE_AUTHOR("Xingyu Wu <xingyu.wu@starfivetech.com>");
++MODULE_DESCRIPTION("StarFive timer driver");
++MODULE_LICENSE("GPL");
+diff --git a/drivers/clocksource/timer-starfive.h b/drivers/clocksource/timer-starfive.h
+new file mode 100644
+index 000000000000..62eb630cc98d
+--- /dev/null
++++ b/drivers/clocksource/timer-starfive.h
+@@ -0,0 +1,96 @@
++/* SPDX-License-Identifier: GPL-2.0 */
++/*
++ * Copyright (C) 2022 StarFive Technology Co., Ltd.
++ */
++
++#ifndef __STARFIVE_TIMER_H__
++#define __STARFIVE_TIMER_H__
++
++/* Bias: Ch0-0x0, Ch1-0x40, Ch2-0x80, and so on. */
++#define STARFIVE_TIMER_CH_LEN 0x40
++#define STARFIVE_TIMER_CH_BASE(x) ((STARFIVE_TIMER_CH_##x) * STARFIVE_TIMER_CH_LEN)
++
++#define STARFIVE_CLOCK_SOURCE_RATING 200
++#define STARFIVE_VALID_BITS 32
++#define STARFIVE_DELAY_US 0
++#define STARFIVE_TIMEOUT_US 10000
++#define STARFIVE_CLOCKEVENT_RATING 300
++#define STARFIVE_TIMER_MAX_TICKS 0xffffffff
++#define STARFIVE_TIMER_MIN_TICKS 0xf
++
++#define STARFIVE_TIMER_JH7110_INT_STATUS 0x00 /* RO[0:4]: Interrupt Status for channel0~4 */
++#define STARFIVE_TIMER_JH7110_CTL 0x04 /* RW[0]: 0-continuous run, 1-single run */
++#define STARFIVE_TIMER_JH7110_LOAD 0x08 /* RW: load value to counter */
++#define STARFIVE_TIMER_JH7110_ENABLE 0x10 /* RW[0]: timer enable register */
++#define STARFIVE_TIMER_JH7110_RELOAD 0x14 /* RW: write 1 or 0 both reload counter */
++#define STARFIVE_TIMER_JH7110_VALUE 0x18 /* RO: timer value register */
++#define STARFIVE_TIMER_JH7110_INT_CLR 0x20 /* RW: timer interrupt clear register */
++#define STARFIVE_TIMER_JH7110_INT_MASK 0x24 /* RW[0]: timer interrupt mask register */
++#define STARFIVE_TIMER_JH7110_INT_CLR_AVA_MASK BIT(1)
++
++enum STARFIVE_TIMER_CH {
++ STARFIVE_TIMER_CH_0 = 0,
++ STARFIVE_TIMER_CH_1,
++ STARFIVE_TIMER_CH_2,
++ STARFIVE_TIMER_CH_3,
++ STARFIVE_TIMER_CH_4,
++ STARFIVE_TIMER_CH_5,
++ STARFIVE_TIMER_CH_6,
++ STARFIVE_TIMER_CH_7,
++ STARFIVE_TIMER_CH_MAX
++};
++
++enum STARFIVE_TIMER_INTMASK {
++ STARFIVE_TIMER_INTMASK_DIS = 0,
++ STARFIVE_TIMER_INTMASK_ENA = 1
++};
++
++enum STARFIVE_TIMER_MOD {
++ STARFIVE_TIMER_MOD_CONTIN = 0,
++ STARFIVE_TIMER_MOD_SINGLE = 1
++};
++
++enum STARFIVE_TIMER_CTL_EN {
++ STARFIVE_TIMER_DIS = 0,
++ STARFIVE_TIMER_ENA = 1
++};
++
++struct starfive_timer_chan_base {
++ /* Resgister */
++ unsigned int ctrl;
++ unsigned int load;
++ unsigned int enable;
++ unsigned int reload;
++ unsigned int value;
++ unsigned int intclr;
++ unsigned int intmask;
++
++ unsigned int channel_num; /* timer channel numbers */
++ unsigned int channel_base[];
++};
++
++struct starfive_clkevt {
++ struct clock_event_device evt;
++ struct clk *clk;
++ char name[20];
++ int irq;
++ u32 periodic;
++ u32 rate;
++ u32 reload_val;
++ void __iomem *base;
++ void __iomem *ctrl;
++ void __iomem *load;
++ void __iomem *enable;
++ void __iomem *reload;
++ void __iomem *value;
++ void __iomem *intclr;
++ void __iomem *intmask;
++};
++
++struct starfive_timer_priv {
++ struct device *dev;
++ void __iomem *base;
++ struct starfive_clkevt clkevt[];
++};
++
++#endif /* __STARFIVE_TIMER_H__ */
+--
+2.20.1
+
--- /dev/null
+From 6ce865e7c0277326d7ce73ff391f31af52696143 Mon Sep 17 00:00:00 2001
+From: Zoltan HERPAI <wigyori@uid0.hu>
+Date: Mon, 29 May 2023 01:18:39 +0200
+Subject: [PATCH 99/99] riscv/6.1: jh7110: add starfive-timer node
+
+Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>
+---
+ arch/riscv/boot/dts/starfive/jh7110.dtsi | 20 ++++++++++++++++++++
+ 1 file changed, 20 insertions(+)
+
+diff --git a/arch/riscv/boot/dts/starfive/jh7110.dtsi b/arch/riscv/boot/dts/starfive/jh7110.dtsi
+index f3f563e3c5c2..141488204ce5 100644
+--- a/arch/riscv/boot/dts/starfive/jh7110.dtsi
++++ b/arch/riscv/boot/dts/starfive/jh7110.dtsi
+@@ -582,6 +582,26 @@
+ #gpio-cells = <2>;
+ };
+
++ timer@13050000 {
++ compatible = "starfive,jh7110-timer";
++ reg = <0x0 0x13050000 0x0 0x10000>;
++ interrupts = <69>, <70>, <71> ,<72>;
++ clocks = <&syscrg JH7110_SYSCLK_TIMER_APB>,
++ <&syscrg JH7110_SYSCLK_TIMER0>,
++ <&syscrg JH7110_SYSCLK_TIMER1>,
++ <&syscrg JH7110_SYSCLK_TIMER2>,
++ <&syscrg JH7110_SYSCLK_TIMER3>;
++ clock-names = "apb", "ch0", "ch1",
++ "ch2", "ch3";
++ resets = <&syscrg JH7110_SYSRST_TIMER_APB>,
++ <&syscrg JH7110_SYSRST_TIMER0>,
++ <&syscrg JH7110_SYSRST_TIMER1>,
++ <&syscrg JH7110_SYSRST_TIMER2>,
++ <&syscrg JH7110_SYSRST_TIMER3>;
++ reset-names = "apb", "ch0", "ch1",
++ "ch2", "ch3";
++ };
++
+ watchdog@13070000 {
+ compatible = "starfive,jh7110-wdt";
+ reg = <0x0 0x13070000 0x0 0x10000>;
+--
+2.20.1
+
--- /dev/null
+From c7794ab272a0ee122463fa85292b80b28a82521c Mon Sep 17 00:00:00 2001
+From: Zoltan HERPAI <wigyori@uid0.hu>
+Date: Mon, 29 May 2023 01:19:34 +0200
+Subject: [PATCH 100/100] starfive-timer/6.1: change ARCH_STARFIVE to
+ SOC_STARFIVE
+
+Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>
+---
+ drivers/clocksource/Kconfig | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
+index 6341128cd71e..47de7c889782 100644
+--- a/drivers/clocksource/Kconfig
++++ b/drivers/clocksource/Kconfig
+@@ -632,10 +632,10 @@ config RISCV_TIMER
+
+ config STARFIVE_TIMER
+ bool "Timer for the STARFIVE SoCs"
+- depends on ARCH_STARFIVE || COMPILE_TEST
++ depends on SOC_STARFIVE || COMPILE_TEST
+ select TIMER_OF
+ select CLKSRC_MMIO
+- default ARCH_STARFIVE
++ default SOC_STARFIVE
+ help
+ This enables the timer for StarFive SoCs. On RISC-V platform,
+ the system has started RISCV_TIMER. But you can also use this timer
+--
+2.20.1
+
--- /dev/null
+From 547192c2eef101412649828d8bd1835884d68d7f Mon Sep 17 00:00:00 2001
+From: William Qiu <william.qiu@starfivetech.com>
+Date: Thu, 2 Mar 2023 18:52:20 +0800
+Subject: [PATCH 105/106] dt-bindings: qspi: cdns,qspi-nor: constrain
+ minItems/maxItems of resets
+
+The QSPI controller needs three reset items to work properly on JH7110 SoC,
+so there is need to change the maxItems's value to 3 and add minItems
+whose value is equal to 2. Other platforms do not have this constraint.
+
+Signed-off-by: William Qiu <william.qiu@starfivetech.com>
+---
+ .../bindings/spi/cdns,qspi-nor.yaml | 37 +++++++++++++++++--
+ 1 file changed, 33 insertions(+), 4 deletions(-)
+
+diff --git a/Documentation/devicetree/bindings/spi/cdns,qspi-nor.yaml b/Documentation/devicetree/bindings/spi/cdns,qspi-nor.yaml
+index 4707294d8f59..14821cb6db48 100644
+--- a/Documentation/devicetree/bindings/spi/cdns,qspi-nor.yaml
++++ b/Documentation/devicetree/bindings/spi/cdns,qspi-nor.yaml
+@@ -19,6 +19,33 @@ allOf:
+ then:
+ required:
+ - power-domains
++ - if:
++ properties:
++ compatible:
++ contains:
++ const: starfive,jh7110-qspi
++ then:
++ properties:
++ resets:
++ minItems: 2
++ maxItems: 3
++
++ reset-names:
++ minItems: 2
++ maxItems: 3
++ items:
++ enum: [ qspi, qspi-ocp, rstc_ref ]
++
++ else:
++ properties:
++ resets:
++ maxItems: 2
++
++ reset-names:
++ minItems: 1
++ maxItems: 2
++ items:
++ enum: [ qspi, qspi-ocp ]
+
+ properties:
+ compatible:
+@@ -30,6 +57,7 @@ properties:
+ - intel,lgm-qspi
+ - xlnx,versal-ospi-1.0
+ - intel,socfpga-qspi
++ - starfive,jh7110-qspi
+ - const: cdns,qspi-nor
+ - const: cdns,qspi-nor
+
+@@ -79,13 +107,14 @@ properties:
+ maxItems: 1
+
+ resets:
+- maxItems: 2
++ minItems: 2
++ maxItems: 3
+
+ reset-names:
+- minItems: 1
+- maxItems: 2
++ minItems: 2
++ maxItems: 3
+ items:
+- enum: [ qspi, qspi-ocp ]
++ enum: [ qspi, qspi-ocp, rstc_ref ]
+
+ required:
+ - compatible
+--
+2.20.1
+
--- /dev/null
+From 4d74cae74f664dcf7d859502e4a971268fa8a695 Mon Sep 17 00:00:00 2001
+From: William Qiu <william.qiu@starfivetech.com>
+Date: Thu, 2 Mar 2023 18:52:21 +0800
+Subject: [PATCH 106/106] spi: cadence-quadspi: Add support for StarFive JH7110
+ QSPI
+
+Add QSPI reset operation in device probe and add RISCV support to
+QUAD SPI Kconfig.
+
+Co-developed-by: Ziv Xu <ziv.xu@starfivetech.com>
+Signed-off-by: Ziv Xu <ziv.xu@starfivetech.com>
+Signed-off-by: William Qiu <william.qiu@starfivetech.com>
+---
+ drivers/spi/Kconfig | 2 +-
+ drivers/spi/spi-cadence-quadspi.c | 21 ++++++++++++++++++++-
+ 2 files changed, 21 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
+index d4b969e68c31..888dffeda902 100644
+--- a/drivers/spi/Kconfig
++++ b/drivers/spi/Kconfig
+@@ -230,7 +230,7 @@ config SPI_CADENCE
+
+ config SPI_CADENCE_QUADSPI
+ tristate "Cadence Quad SPI controller"
+- depends on OF && (ARM || ARM64 || X86 || COMPILE_TEST)
++ depends on OF && (ARM || ARM64 || X86 || RISCV || COMPILE_TEST)
+ help
+ Enable support for the Cadence Quad SPI Flash controller.
+
+diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-quadspi.c
+index 30fd4bc90580..995a737ad8b1 100644
+--- a/drivers/spi/spi-cadence-quadspi.c
++++ b/drivers/spi/spi-cadence-quadspi.c
+@@ -1575,7 +1575,7 @@ static int cqspi_setup_flash(struct cqspi_st *cqspi)
+ static int cqspi_probe(struct platform_device *pdev)
+ {
+ const struct cqspi_driver_platdata *ddata;
+- struct reset_control *rstc, *rstc_ocp;
++ struct reset_control *rstc, *rstc_ocp, *rstc_ref;
+ struct device *dev = &pdev->dev;
+ struct spi_master *master;
+ struct resource *res_ahb;
+@@ -1668,6 +1668,17 @@ static int cqspi_probe(struct platform_device *pdev)
+ goto probe_reset_failed;
+ }
+
++ if (of_device_is_compatible(pdev->dev.of_node, "starfive,jh7110-qspi")) {
++ rstc_ref = devm_reset_control_get_optional_exclusive(dev, "rstc_ref");
++ if (IS_ERR(rstc_ref)) {
++ ret = PTR_ERR(rstc_ref);
++ dev_err(dev, "Cannot get QSPI REF reset.\n");
++ goto probe_reset_failed;
++ }
++ reset_control_assert(rstc_ref);
++ reset_control_deassert(rstc_ref);
++ }
++
+ reset_control_assert(rstc);
+ reset_control_deassert(rstc);
+
+@@ -1824,6 +1835,10 @@ static const struct cqspi_driver_platdata versal_ospi = {
+ .get_dma_status = cqspi_get_versal_dma_status,
+ };
+
++static const struct cqspi_driver_platdata jh7110_qspi = {
++ .quirks = CQSPI_DISABLE_DAC_MODE,
++};
++
+ static const struct of_device_id cqspi_dt_ids[] = {
+ {
+ .compatible = "cdns,qspi-nor",
+@@ -1849,6 +1864,10 @@ static const struct of_device_id cqspi_dt_ids[] = {
+ .compatible = "intel,socfpga-qspi",
+ .data = &socfpga_qspi,
+ },
++ {
++ .compatible = "starfive,jh7110-qspi",
++ .data = &jh7110_qspi,
++ },
+ { /* end of table */ }
+ };
+
+--
+2.20.1
+
--- /dev/null
+From 41ad72ec09488b012f3bbf4ad1566a7d02133884 Mon Sep 17 00:00:00 2001
+From: Tudor Ambarus <tudor.ambarus@microchip.com>
+Date: Thu, 10 Nov 2022 17:25:28 +0200
+Subject: [PATCH 107/111] dmaengine: drivers: Use
+ devm_platform_ioremap_resource()
+
+platform_get_resource() and devm_ioremap_resource() are wrapped up in the
+devm_platform_ioremap_resource() helper. Use the helper and get rid of the
+local variable for struct resource *. We now have a function call less.
+
+Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
+Acked-by: Jernej Skrabec <jernej.skrabec@gmail.com>
+Acked-by: Peter Ujfalusi <peter.ujfalusi@gmail.com>
+---
+ drivers/dma/bcm2835-dma.c | 4 +---
+ drivers/dma/dma-axi-dmac.c | 4 +---
+ drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c | 4 +---
+ drivers/dma/fsl-edma.c | 8 +++-----
+ drivers/dma/fsl-qdma.c | 10 +++-------
+ drivers/dma/idma64.c | 4 +---
+ drivers/dma/img-mdc-dma.c | 4 +---
+ drivers/dma/imx-dma.c | 4 +---
+ drivers/dma/imx-sdma.c | 4 +---
+ drivers/dma/mcf-edma.c | 5 +----
+ drivers/dma/mediatek/mtk-hsdma.c | 4 +---
+ drivers/dma/mmp_pdma.c | 4 +---
+ drivers/dma/mmp_tdma.c | 4 +---
+ drivers/dma/moxart-dma.c | 4 +---
+ drivers/dma/mv_xor_v2.c | 7 ++-----
+ drivers/dma/mxs-dma.c | 4 +---
+ drivers/dma/nbpfaxi.c | 4 +---
+ drivers/dma/pxa_dma.c | 4 +---
+ drivers/dma/qcom/bam_dma.c | 4 +---
+ drivers/dma/sf-pdma/sf-pdma.c | 4 +---
+ drivers/dma/sh/usb-dmac.c | 4 +---
+ drivers/dma/stm32-dmamux.c | 4 +---
+ drivers/dma/stm32-mdma.c | 4 +---
+ drivers/dma/sun4i-dma.c | 4 +---
+ drivers/dma/sun6i-dma.c | 4 +---
+ drivers/dma/tegra210-adma.c | 4 +---
+ drivers/dma/ti/cppi41.c | 10 +++-------
+ drivers/dma/ti/omap-dma.c | 4 +---
+ drivers/dma/xilinx/zynqmp_dma.c | 4 +---
+ 29 files changed, 36 insertions(+), 100 deletions(-)
+
+diff --git a/drivers/dma/bcm2835-dma.c b/drivers/dma/bcm2835-dma.c
+index 630dfbb01a40..0807fb9eb262 100644
+--- a/drivers/dma/bcm2835-dma.c
++++ b/drivers/dma/bcm2835-dma.c
+@@ -878,7 +878,6 @@ static struct dma_chan *bcm2835_dma_xlate(struct of_phandle_args *spec,
+ static int bcm2835_dma_probe(struct platform_device *pdev)
+ {
+ struct bcm2835_dmadev *od;
+- struct resource *res;
+ void __iomem *base;
+ int rc;
+ int i, j;
+@@ -902,8 +901,7 @@ static int bcm2835_dma_probe(struct platform_device *pdev)
+
+ dma_set_max_seg_size(&pdev->dev, 0x3FFFFFFF);
+
+- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+- base = devm_ioremap_resource(&pdev->dev, res);
++ base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(base))
+ return PTR_ERR(base);
+
+diff --git a/drivers/dma/dma-axi-dmac.c b/drivers/dma/dma-axi-dmac.c
+index f30dabc99795..a812b9b00e6b 100644
+--- a/drivers/dma/dma-axi-dmac.c
++++ b/drivers/dma/dma-axi-dmac.c
+@@ -910,7 +910,6 @@ static int axi_dmac_probe(struct platform_device *pdev)
+ {
+ struct dma_device *dma_dev;
+ struct axi_dmac *dmac;
+- struct resource *res;
+ struct regmap *regmap;
+ unsigned int version;
+ int ret;
+@@ -925,8 +924,7 @@ static int axi_dmac_probe(struct platform_device *pdev)
+ if (dmac->irq == 0)
+ return -EINVAL;
+
+- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+- dmac->base = devm_ioremap_resource(&pdev->dev, res);
++ dmac->base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(dmac->base))
+ return PTR_ERR(dmac->base);
+
+diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
+index 152c5d98524d..4169e1d7d5ca 100644
+--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
++++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
+@@ -1369,7 +1369,6 @@ static int dw_probe(struct platform_device *pdev)
+ {
+ struct device_node *node = pdev->dev.of_node;
+ struct axi_dma_chip *chip;
+- struct resource *mem;
+ struct dw_axi_dma *dw;
+ struct dw_axi_dma_hcfg *hdata;
+ u32 i;
+@@ -1395,8 +1394,7 @@ static int dw_probe(struct platform_device *pdev)
+ if (chip->irq < 0)
+ return chip->irq;
+
+- mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+- chip->regs = devm_ioremap_resource(chip->dev, mem);
++ chip->regs = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(chip->regs))
+ return PTR_ERR(chip->regs);
+
+diff --git a/drivers/dma/fsl-edma.c b/drivers/dma/fsl-edma.c
+index 76cbf54aec58..e40769666e39 100644
+--- a/drivers/dma/fsl-edma.c
++++ b/drivers/dma/fsl-edma.c
+@@ -272,7 +272,6 @@ static int fsl_edma_probe(struct platform_device *pdev)
+ const struct fsl_edma_drvdata *drvdata = NULL;
+ struct fsl_edma_chan *fsl_chan;
+ struct edma_regs *regs;
+- struct resource *res;
+ int len, chans;
+ int ret, i;
+
+@@ -298,8 +297,7 @@ static int fsl_edma_probe(struct platform_device *pdev)
+ fsl_edma->n_chans = chans;
+ mutex_init(&fsl_edma->fsl_edma_mutex);
+
+- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+- fsl_edma->membase = devm_ioremap_resource(&pdev->dev, res);
++ fsl_edma->membase = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(fsl_edma->membase))
+ return PTR_ERR(fsl_edma->membase);
+
+@@ -323,8 +321,8 @@ static int fsl_edma_probe(struct platform_device *pdev)
+ for (i = 0; i < fsl_edma->drvdata->dmamuxs; i++) {
+ char clkname[32];
+
+- res = platform_get_resource(pdev, IORESOURCE_MEM, 1 + i);
+- fsl_edma->muxbase[i] = devm_ioremap_resource(&pdev->dev, res);
++ fsl_edma->muxbase[i] = devm_platform_ioremap_resource(pdev,
++ 1 + i);
+ if (IS_ERR(fsl_edma->muxbase[i])) {
+ /* on error: disable all previously enabled clks */
+ fsl_disable_clocks(fsl_edma, i);
+diff --git a/drivers/dma/fsl-qdma.c b/drivers/dma/fsl-qdma.c
+index 045ead46ec8f..eddb2688f234 100644
+--- a/drivers/dma/fsl-qdma.c
++++ b/drivers/dma/fsl-qdma.c
+@@ -1119,7 +1119,6 @@ static int fsl_qdma_probe(struct platform_device *pdev)
+ int ret, i;
+ int blk_num, blk_off;
+ u32 len, chans, queues;
+- struct resource *res;
+ struct fsl_qdma_chan *fsl_chan;
+ struct fsl_qdma_engine *fsl_qdma;
+ struct device_node *np = pdev->dev.of_node;
+@@ -1183,18 +1182,15 @@ static int fsl_qdma_probe(struct platform_device *pdev)
+ if (!fsl_qdma->status[i])
+ return -ENOMEM;
+ }
+- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+- fsl_qdma->ctrl_base = devm_ioremap_resource(&pdev->dev, res);
++ fsl_qdma->ctrl_base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(fsl_qdma->ctrl_base))
+ return PTR_ERR(fsl_qdma->ctrl_base);
+
+- res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+- fsl_qdma->status_base = devm_ioremap_resource(&pdev->dev, res);
++ fsl_qdma->status_base = devm_platform_ioremap_resource(pdev, 1);
+ if (IS_ERR(fsl_qdma->status_base))
+ return PTR_ERR(fsl_qdma->status_base);
+
+- res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
+- fsl_qdma->block_base = devm_ioremap_resource(&pdev->dev, res);
++ fsl_qdma->block_base = devm_platform_ioremap_resource(pdev, 2);
+ if (IS_ERR(fsl_qdma->block_base))
+ return PTR_ERR(fsl_qdma->block_base);
+ fsl_qdma->queue = fsl_qdma_alloc_queue_resources(pdev, fsl_qdma);
+diff --git a/drivers/dma/idma64.c b/drivers/dma/idma64.c
+index f4c07ad3be15..96a33ddfcd2b 100644
+--- a/drivers/dma/idma64.c
++++ b/drivers/dma/idma64.c
+@@ -629,7 +629,6 @@ static int idma64_platform_probe(struct platform_device *pdev)
+ struct idma64_chip *chip;
+ struct device *dev = &pdev->dev;
+ struct device *sysdev = dev->parent;
+- struct resource *mem;
+ int ret;
+
+ chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
+@@ -640,8 +639,7 @@ static int idma64_platform_probe(struct platform_device *pdev)
+ if (chip->irq < 0)
+ return chip->irq;
+
+- mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+- chip->regs = devm_ioremap_resource(dev, mem);
++ chip->regs = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(chip->regs))
+ return PTR_ERR(chip->regs);
+
+diff --git a/drivers/dma/img-mdc-dma.c b/drivers/dma/img-mdc-dma.c
+index e4ea107ce78c..ad084552640f 100644
+--- a/drivers/dma/img-mdc-dma.c
++++ b/drivers/dma/img-mdc-dma.c
+@@ -886,7 +886,6 @@ static int img_mdc_runtime_resume(struct device *dev)
+ static int mdc_dma_probe(struct platform_device *pdev)
+ {
+ struct mdc_dma *mdma;
+- struct resource *res;
+ unsigned int i;
+ u32 val;
+ int ret;
+@@ -898,8 +897,7 @@ static int mdc_dma_probe(struct platform_device *pdev)
+
+ mdma->soc = of_device_get_match_data(&pdev->dev);
+
+- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+- mdma->regs = devm_ioremap_resource(&pdev->dev, res);
++ mdma->regs = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(mdma->regs))
+ return PTR_ERR(mdma->regs);
+
+diff --git a/drivers/dma/imx-dma.c b/drivers/dma/imx-dma.c
+index 65c6094ce063..80086977973f 100644
+--- a/drivers/dma/imx-dma.c
++++ b/drivers/dma/imx-dma.c
+@@ -1038,7 +1038,6 @@ static struct dma_chan *imxdma_xlate(struct of_phandle_args *dma_spec,
+ static int __init imxdma_probe(struct platform_device *pdev)
+ {
+ struct imxdma_engine *imxdma;
+- struct resource *res;
+ int ret, i;
+ int irq, irq_err;
+
+@@ -1049,8 +1048,7 @@ static int __init imxdma_probe(struct platform_device *pdev)
+ imxdma->dev = &pdev->dev;
+ imxdma->devtype = (uintptr_t)of_device_get_match_data(&pdev->dev);
+
+- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+- imxdma->base = devm_ioremap_resource(&pdev->dev, res);
++ imxdma->base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(imxdma->base))
+ return PTR_ERR(imxdma->base);
+
+diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
+index b926abe4fa43..0d0ae1109d9f 100644
+--- a/drivers/dma/imx-sdma.c
++++ b/drivers/dma/imx-sdma.c
+@@ -2169,7 +2169,6 @@ static int sdma_probe(struct platform_device *pdev)
+ const char *fw_name;
+ int ret;
+ int irq;
+- struct resource *iores;
+ struct resource spba_res;
+ int i;
+ struct sdma_engine *sdma;
+@@ -2192,8 +2191,7 @@ static int sdma_probe(struct platform_device *pdev)
+ if (irq < 0)
+ return irq;
+
+- iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+- sdma->regs = devm_ioremap_resource(&pdev->dev, iores);
++ sdma->regs = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(sdma->regs))
+ return PTR_ERR(sdma->regs);
+
+diff --git a/drivers/dma/mcf-edma.c b/drivers/dma/mcf-edma.c
+index e12b754e6398..ebd8733f72ad 100644
+--- a/drivers/dma/mcf-edma.c
++++ b/drivers/dma/mcf-edma.c
+@@ -182,7 +182,6 @@ static int mcf_edma_probe(struct platform_device *pdev)
+ struct fsl_edma_engine *mcf_edma;
+ struct fsl_edma_chan *mcf_chan;
+ struct edma_regs *regs;
+- struct resource *res;
+ int ret, i, len, chans;
+
+ pdata = dev_get_platdata(&pdev->dev);
+@@ -210,9 +209,7 @@ static int mcf_edma_probe(struct platform_device *pdev)
+
+ mutex_init(&mcf_edma->fsl_edma_mutex);
+
+- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+-
+- mcf_edma->membase = devm_ioremap_resource(&pdev->dev, res);
++ mcf_edma->membase = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(mcf_edma->membase))
+ return PTR_ERR(mcf_edma->membase);
+
+diff --git a/drivers/dma/mediatek/mtk-hsdma.c b/drivers/dma/mediatek/mtk-hsdma.c
+index f7717c44b887..69cc61c0b262 100644
+--- a/drivers/dma/mediatek/mtk-hsdma.c
++++ b/drivers/dma/mediatek/mtk-hsdma.c
+@@ -896,7 +896,6 @@ static int mtk_hsdma_probe(struct platform_device *pdev)
+ struct mtk_hsdma_device *hsdma;
+ struct mtk_hsdma_vchan *vc;
+ struct dma_device *dd;
+- struct resource *res;
+ int i, err;
+
+ hsdma = devm_kzalloc(&pdev->dev, sizeof(*hsdma), GFP_KERNEL);
+@@ -905,8 +904,7 @@ static int mtk_hsdma_probe(struct platform_device *pdev)
+
+ dd = &hsdma->ddev;
+
+- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+- hsdma->base = devm_ioremap_resource(&pdev->dev, res);
++ hsdma->base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(hsdma->base))
+ return PTR_ERR(hsdma->base);
+
+diff --git a/drivers/dma/mmp_pdma.c b/drivers/dma/mmp_pdma.c
+index e8d71b35593e..ebdfdcbb4f7a 100644
+--- a/drivers/dma/mmp_pdma.c
++++ b/drivers/dma/mmp_pdma.c
+@@ -1022,7 +1022,6 @@ static int mmp_pdma_probe(struct platform_device *op)
+ struct mmp_pdma_device *pdev;
+ const struct of_device_id *of_id;
+ struct mmp_dma_platdata *pdata = dev_get_platdata(&op->dev);
+- struct resource *iores;
+ int i, ret, irq = 0;
+ int dma_channels = 0, irq_num = 0;
+ const enum dma_slave_buswidth widths =
+@@ -1037,8 +1036,7 @@ static int mmp_pdma_probe(struct platform_device *op)
+
+ spin_lock_init(&pdev->phy_lock);
+
+- iores = platform_get_resource(op, IORESOURCE_MEM, 0);
+- pdev->base = devm_ioremap_resource(pdev->dev, iores);
++ pdev->base = devm_platform_ioremap_resource(op, 0);
+ if (IS_ERR(pdev->base))
+ return PTR_ERR(pdev->base);
+
+diff --git a/drivers/dma/mmp_tdma.c b/drivers/dma/mmp_tdma.c
+index a262e0eb4cc9..e956702932aa 100644
+--- a/drivers/dma/mmp_tdma.c
++++ b/drivers/dma/mmp_tdma.c
+@@ -639,7 +639,6 @@ static int mmp_tdma_probe(struct platform_device *pdev)
+ enum mmp_tdma_type type;
+ const struct of_device_id *of_id;
+ struct mmp_tdma_device *tdev;
+- struct resource *iores;
+ int i, ret;
+ int irq = 0, irq_num = 0;
+ int chan_num = TDMA_CHANNEL_NUM;
+@@ -663,8 +662,7 @@ static int mmp_tdma_probe(struct platform_device *pdev)
+ irq_num++;
+ }
+
+- iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+- tdev->base = devm_ioremap_resource(&pdev->dev, iores);
++ tdev->base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(tdev->base))
+ return PTR_ERR(tdev->base);
+
+diff --git a/drivers/dma/moxart-dma.c b/drivers/dma/moxart-dma.c
+index 7459382a8353..7565ad98ba66 100644
+--- a/drivers/dma/moxart-dma.c
++++ b/drivers/dma/moxart-dma.c
+@@ -563,7 +563,6 @@ static int moxart_probe(struct platform_device *pdev)
+ {
+ struct device *dev = &pdev->dev;
+ struct device_node *node = dev->of_node;
+- struct resource *res;
+ void __iomem *dma_base_addr;
+ int ret, i;
+ unsigned int irq;
+@@ -580,8 +579,7 @@ static int moxart_probe(struct platform_device *pdev)
+ return -EINVAL;
+ }
+
+- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+- dma_base_addr = devm_ioremap_resource(dev, res);
++ dma_base_addr = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(dma_base_addr))
+ return PTR_ERR(dma_base_addr);
+
+diff --git a/drivers/dma/mv_xor_v2.c b/drivers/dma/mv_xor_v2.c
+index d086ff1824f8..0991b8265829 100644
+--- a/drivers/dma/mv_xor_v2.c
++++ b/drivers/dma/mv_xor_v2.c
+@@ -714,7 +714,6 @@ static int mv_xor_v2_resume(struct platform_device *dev)
+ static int mv_xor_v2_probe(struct platform_device *pdev)
+ {
+ struct mv_xor_v2_device *xor_dev;
+- struct resource *res;
+ int i, ret = 0;
+ struct dma_device *dma_dev;
+ struct mv_xor_v2_sw_desc *sw_desc;
+@@ -726,13 +725,11 @@ static int mv_xor_v2_probe(struct platform_device *pdev)
+ if (!xor_dev)
+ return -ENOMEM;
+
+- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+- xor_dev->dma_base = devm_ioremap_resource(&pdev->dev, res);
++ xor_dev->dma_base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(xor_dev->dma_base))
+ return PTR_ERR(xor_dev->dma_base);
+
+- res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+- xor_dev->glob_base = devm_ioremap_resource(&pdev->dev, res);
++ xor_dev->glob_base = devm_platform_ioremap_resource(pdev, 1);
+ if (IS_ERR(xor_dev->glob_base))
+ return PTR_ERR(xor_dev->glob_base);
+
+diff --git a/drivers/dma/mxs-dma.c b/drivers/dma/mxs-dma.c
+index dc147cc2436e..acc4d53e4630 100644
+--- a/drivers/dma/mxs-dma.c
++++ b/drivers/dma/mxs-dma.c
+@@ -746,7 +746,6 @@ static int mxs_dma_probe(struct platform_device *pdev)
+ struct device_node *np = pdev->dev.of_node;
+ const struct mxs_dma_type *dma_type;
+ struct mxs_dma_engine *mxs_dma;
+- struct resource *iores;
+ int ret, i;
+
+ mxs_dma = devm_kzalloc(&pdev->dev, sizeof(*mxs_dma), GFP_KERNEL);
+@@ -763,8 +762,7 @@ static int mxs_dma_probe(struct platform_device *pdev)
+ mxs_dma->type = dma_type->type;
+ mxs_dma->dev_id = dma_type->id;
+
+- iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+- mxs_dma->base = devm_ioremap_resource(&pdev->dev, iores);
++ mxs_dma->base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(mxs_dma->base))
+ return PTR_ERR(mxs_dma->base);
+
+diff --git a/drivers/dma/nbpfaxi.c b/drivers/dma/nbpfaxi.c
+index a7063e9cd551..e72e8c10355e 100644
+--- a/drivers/dma/nbpfaxi.c
++++ b/drivers/dma/nbpfaxi.c
+@@ -1294,7 +1294,6 @@ static int nbpf_probe(struct platform_device *pdev)
+ struct device_node *np = dev->of_node;
+ struct nbpf_device *nbpf;
+ struct dma_device *dma_dev;
+- struct resource *iomem;
+ const struct nbpf_config *cfg;
+ int num_channels;
+ int ret, irq, eirq, i;
+@@ -1318,8 +1317,7 @@ static int nbpf_probe(struct platform_device *pdev)
+ dma_dev = &nbpf->dma_dev;
+ dma_dev->dev = dev;
+
+- iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+- nbpf->base = devm_ioremap_resource(dev, iomem);
++ nbpf->base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(nbpf->base))
+ return PTR_ERR(nbpf->base);
+
+diff --git a/drivers/dma/pxa_dma.c b/drivers/dma/pxa_dma.c
+index 22a392fe6d32..1b046d9a3a26 100644
+--- a/drivers/dma/pxa_dma.c
++++ b/drivers/dma/pxa_dma.c
+@@ -1346,7 +1346,6 @@ static int pxad_probe(struct platform_device *op)
+ const struct of_device_id *of_id;
+ const struct dma_slave_map *slave_map = NULL;
+ struct mmp_dma_platdata *pdata = dev_get_platdata(&op->dev);
+- struct resource *iores;
+ int ret, dma_channels = 0, nb_requestors = 0, slave_map_cnt = 0;
+ const enum dma_slave_buswidth widths =
+ DMA_SLAVE_BUSWIDTH_1_BYTE | DMA_SLAVE_BUSWIDTH_2_BYTES |
+@@ -1358,8 +1357,7 @@ static int pxad_probe(struct platform_device *op)
+
+ spin_lock_init(&pdev->phy_lock);
+
+- iores = platform_get_resource(op, IORESOURCE_MEM, 0);
+- pdev->base = devm_ioremap_resource(&op->dev, iores);
++ pdev->base = devm_platform_ioremap_resource(op, 0);
+ if (IS_ERR(pdev->base))
+ return PTR_ERR(pdev->base);
+
+diff --git a/drivers/dma/qcom/bam_dma.c b/drivers/dma/qcom/bam_dma.c
+index 2ff787df513e..1e47d27e1f81 100644
+--- a/drivers/dma/qcom/bam_dma.c
++++ b/drivers/dma/qcom/bam_dma.c
+@@ -1237,7 +1237,6 @@ static int bam_dma_probe(struct platform_device *pdev)
+ {
+ struct bam_device *bdev;
+ const struct of_device_id *match;
+- struct resource *iores;
+ int ret, i;
+
+ bdev = devm_kzalloc(&pdev->dev, sizeof(*bdev), GFP_KERNEL);
+@@ -1254,8 +1253,7 @@ static int bam_dma_probe(struct platform_device *pdev)
+
+ bdev->layout = match->data;
+
+- iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+- bdev->regs = devm_ioremap_resource(&pdev->dev, iores);
++ bdev->regs = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(bdev->regs))
+ return PTR_ERR(bdev->regs);
+
+diff --git a/drivers/dma/sf-pdma/sf-pdma.c b/drivers/dma/sf-pdma/sf-pdma.c
+index e578ad556949..d1c6956af452 100644
+--- a/drivers/dma/sf-pdma/sf-pdma.c
++++ b/drivers/dma/sf-pdma/sf-pdma.c
+@@ -493,7 +493,6 @@ static void sf_pdma_setup_chans(struct sf_pdma *pdma)
+ static int sf_pdma_probe(struct platform_device *pdev)
+ {
+ struct sf_pdma *pdma;
+- struct resource *res;
+ int ret, n_chans;
+ const enum dma_slave_buswidth widths =
+ DMA_SLAVE_BUSWIDTH_1_BYTE | DMA_SLAVE_BUSWIDTH_2_BYTES |
+@@ -518,8 +517,7 @@ static int sf_pdma_probe(struct platform_device *pdev)
+
+ pdma->n_chans = n_chans;
+
+- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+- pdma->membase = devm_ioremap_resource(&pdev->dev, res);
++ pdma->membase = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(pdma->membase))
+ return PTR_ERR(pdma->membase);
+
+diff --git a/drivers/dma/sh/usb-dmac.c b/drivers/dma/sh/usb-dmac.c
+index 5edaeb89d1e6..b14cf350b669 100644
+--- a/drivers/dma/sh/usb-dmac.c
++++ b/drivers/dma/sh/usb-dmac.c
+@@ -768,7 +768,6 @@ static int usb_dmac_probe(struct platform_device *pdev)
+ const enum dma_slave_buswidth widths = USB_DMAC_SLAVE_BUSWIDTH;
+ struct dma_device *engine;
+ struct usb_dmac *dmac;
+- struct resource *mem;
+ unsigned int i;
+ int ret;
+
+@@ -789,8 +788,7 @@ static int usb_dmac_probe(struct platform_device *pdev)
+ return -ENOMEM;
+
+ /* Request resources. */
+- mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+- dmac->iomem = devm_ioremap_resource(&pdev->dev, mem);
++ dmac->iomem = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(dmac->iomem))
+ return PTR_ERR(dmac->iomem);
+
+diff --git a/drivers/dma/stm32-dmamux.c b/drivers/dma/stm32-dmamux.c
+index ee3cbbf51006..46b884d46188 100644
+--- a/drivers/dma/stm32-dmamux.c
++++ b/drivers/dma/stm32-dmamux.c
+@@ -179,7 +179,6 @@ static int stm32_dmamux_probe(struct platform_device *pdev)
+ const struct of_device_id *match;
+ struct device_node *dma_node;
+ struct stm32_dmamux_data *stm32_dmamux;
+- struct resource *res;
+ void __iomem *iomem;
+ struct reset_control *rst;
+ int i, count, ret;
+@@ -238,8 +237,7 @@ static int stm32_dmamux_probe(struct platform_device *pdev)
+ }
+ pm_runtime_get_noresume(&pdev->dev);
+
+- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+- iomem = devm_ioremap_resource(&pdev->dev, res);
++ iomem = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(iomem))
+ return PTR_ERR(iomem);
+
+diff --git a/drivers/dma/stm32-mdma.c b/drivers/dma/stm32-mdma.c
+index b9d4c843635f..84e7f4f4a800 100644
+--- a/drivers/dma/stm32-mdma.c
++++ b/drivers/dma/stm32-mdma.c
+@@ -1580,7 +1580,6 @@ static int stm32_mdma_probe(struct platform_device *pdev)
+ struct stm32_mdma_device *dmadev;
+ struct dma_device *dd;
+ struct device_node *of_node;
+- struct resource *res;
+ struct reset_control *rst;
+ u32 nr_channels, nr_requests;
+ int i, count, ret;
+@@ -1622,8 +1621,7 @@ static int stm32_mdma_probe(struct platform_device *pdev)
+ count);
+ dmadev->nr_ahb_addr_masks = count;
+
+- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+- dmadev->base = devm_ioremap_resource(&pdev->dev, res);
++ dmadev->base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(dmadev->base))
+ return PTR_ERR(dmadev->base);
+
+diff --git a/drivers/dma/sun4i-dma.c b/drivers/dma/sun4i-dma.c
+index f291b1b4db32..e86c8829513a 100644
+--- a/drivers/dma/sun4i-dma.c
++++ b/drivers/dma/sun4i-dma.c
+@@ -1144,15 +1144,13 @@ static irqreturn_t sun4i_dma_interrupt(int irq, void *dev_id)
+ static int sun4i_dma_probe(struct platform_device *pdev)
+ {
+ struct sun4i_dma_dev *priv;
+- struct resource *res;
+ int i, j, ret;
+
+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+- priv->base = devm_ioremap_resource(&pdev->dev, res);
++ priv->base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(priv->base))
+ return PTR_ERR(priv->base);
+
+diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
+index b7557f437936..2f4bf72e7769 100644
+--- a/drivers/dma/sun6i-dma.c
++++ b/drivers/dma/sun6i-dma.c
+@@ -1283,7 +1283,6 @@ static int sun6i_dma_probe(struct platform_device *pdev)
+ {
+ struct device_node *np = pdev->dev.of_node;
+ struct sun6i_dma_dev *sdc;
+- struct resource *res;
+ int ret, i;
+
+ sdc = devm_kzalloc(&pdev->dev, sizeof(*sdc), GFP_KERNEL);
+@@ -1294,8 +1293,7 @@ static int sun6i_dma_probe(struct platform_device *pdev)
+ if (!sdc->cfg)
+ return -ENODEV;
+
+- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+- sdc->base = devm_ioremap_resource(&pdev->dev, res);
++ sdc->base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(sdc->base))
+ return PTR_ERR(sdc->base);
+
+diff --git a/drivers/dma/tegra210-adma.c b/drivers/dma/tegra210-adma.c
+index 79da93cc77b6..b97004036071 100644
+--- a/drivers/dma/tegra210-adma.c
++++ b/drivers/dma/tegra210-adma.c
+@@ -837,7 +837,6 @@ static int tegra_adma_probe(struct platform_device *pdev)
+ {
+ const struct tegra_adma_chip_data *cdata;
+ struct tegra_adma *tdma;
+- struct resource *res;
+ int ret, i;
+
+ cdata = of_device_get_match_data(&pdev->dev);
+@@ -857,8 +856,7 @@ static int tegra_adma_probe(struct platform_device *pdev)
+ tdma->nr_channels = cdata->nr_channels;
+ platform_set_drvdata(pdev, tdma);
+
+- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+- tdma->base_addr = devm_ioremap_resource(&pdev->dev, res);
++ tdma->base_addr = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(tdma->base_addr))
+ return PTR_ERR(tdma->base_addr);
+
+diff --git a/drivers/dma/ti/cppi41.c b/drivers/dma/ti/cppi41.c
+index 695915dba707..c3555cfb0681 100644
+--- a/drivers/dma/ti/cppi41.c
++++ b/drivers/dma/ti/cppi41.c
+@@ -1039,7 +1039,6 @@ static int cppi41_dma_probe(struct platform_device *pdev)
+ struct cppi41_dd *cdd;
+ struct device *dev = &pdev->dev;
+ const struct cppi_glue_infos *glue_info;
+- struct resource *mem;
+ int index;
+ int irq;
+ int ret;
+@@ -1072,18 +1071,15 @@ static int cppi41_dma_probe(struct platform_device *pdev)
+ if (index < 0)
+ return index;
+
+- mem = platform_get_resource(pdev, IORESOURCE_MEM, index);
+- cdd->ctrl_mem = devm_ioremap_resource(dev, mem);
++ cdd->ctrl_mem = devm_platform_ioremap_resource(pdev, index);
+ if (IS_ERR(cdd->ctrl_mem))
+ return PTR_ERR(cdd->ctrl_mem);
+
+- mem = platform_get_resource(pdev, IORESOURCE_MEM, index + 1);
+- cdd->sched_mem = devm_ioremap_resource(dev, mem);
++ cdd->sched_mem = devm_platform_ioremap_resource(pdev, index + 1);
+ if (IS_ERR(cdd->sched_mem))
+ return PTR_ERR(cdd->sched_mem);
+
+- mem = platform_get_resource(pdev, IORESOURCE_MEM, index + 2);
+- cdd->qmgr_mem = devm_ioremap_resource(dev, mem);
++ cdd->qmgr_mem = devm_platform_ioremap_resource(pdev, index + 2);
+ if (IS_ERR(cdd->qmgr_mem))
+ return PTR_ERR(cdd->qmgr_mem);
+
+diff --git a/drivers/dma/ti/omap-dma.c b/drivers/dma/ti/omap-dma.c
+index 27f5019bdc1e..02e1c08c596d 100644
+--- a/drivers/dma/ti/omap-dma.c
++++ b/drivers/dma/ti/omap-dma.c
+@@ -1658,7 +1658,6 @@ static int omap_dma_probe(struct platform_device *pdev)
+ {
+ const struct omap_dma_config *conf;
+ struct omap_dmadev *od;
+- struct resource *res;
+ int rc, i, irq;
+ u32 val;
+
+@@ -1666,8 +1665,7 @@ static int omap_dma_probe(struct platform_device *pdev)
+ if (!od)
+ return -ENOMEM;
+
+- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+- od->base = devm_ioremap_resource(&pdev->dev, res);
++ od->base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(od->base))
+ return PTR_ERR(od->base);
+
+diff --git a/drivers/dma/xilinx/zynqmp_dma.c b/drivers/dma/xilinx/zynqmp_dma.c
+index 21472a5d7636..ce359058c638 100644
+--- a/drivers/dma/xilinx/zynqmp_dma.c
++++ b/drivers/dma/xilinx/zynqmp_dma.c
+@@ -890,7 +890,6 @@ static int zynqmp_dma_chan_probe(struct zynqmp_dma_device *zdev,
+ struct platform_device *pdev)
+ {
+ struct zynqmp_dma_chan *chan;
+- struct resource *res;
+ struct device_node *node = pdev->dev.of_node;
+ int err;
+
+@@ -900,8 +899,7 @@ static int zynqmp_dma_chan_probe(struct zynqmp_dma_device *zdev,
+ chan->dev = zdev->dev;
+ chan->zdev = zdev;
+
+- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+- chan->regs = devm_ioremap_resource(&pdev->dev, res);
++ chan->regs = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(chan->regs))
+ return PTR_ERR(chan->regs);
+
+--
+2.20.1
+
--- /dev/null
+From 1f58a1e1402d42eb2cb5790ce0bfb5f9f73daa42 Mon Sep 17 00:00:00 2001
+From: Walker Chen <walker.chen@starfivetech.com>
+Date: Wed, 22 Mar 2023 17:48:18 +0800
+Subject: [PATCH 108/111] dmaengine: dw-axi-dmac: Add support for StarFive
+ JH7110 DMA
+
+Add DMA reset operation in device probe and use different configuration
+on CH_CFG registers according to match data. Update all uses of
+of_device_is_compatible with of_device_get_match_data.
+
+Signed-off-by: Walker Chen <walker.chen@starfivetech.com>
+Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
+---
+ .../dma/dw-axi-dmac/dw-axi-dmac-platform.c | 38 ++++++++++++++++---
+ drivers/dma/dw-axi-dmac/dw-axi-dmac.h | 1 +
+ 2 files changed, 34 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
+index 4169e1d7d5ca..6cfcb541d8c3 100644
+--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
++++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
+@@ -21,10 +21,12 @@
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+ #include <linux/of.h>
++#include <linux/of_device.h>
+ #include <linux/of_dma.h>
+ #include <linux/platform_device.h>
+ #include <linux/pm_runtime.h>
+ #include <linux/property.h>
++#include <linux/reset.h>
+ #include <linux/slab.h>
+ #include <linux/types.h>
+
+@@ -46,6 +48,10 @@
+ DMA_SLAVE_BUSWIDTH_32_BYTES | \
+ DMA_SLAVE_BUSWIDTH_64_BYTES)
+
++#define AXI_DMA_FLAG_HAS_APB_REGS BIT(0)
++#define AXI_DMA_FLAG_HAS_RESETS BIT(1)
++#define AXI_DMA_FLAG_USE_CFG2 BIT(2)
++
+ static inline void
+ axi_dma_iowrite32(struct axi_dma_chip *chip, u32 reg, u32 val)
+ {
+@@ -86,7 +92,8 @@ static inline void axi_chan_config_write(struct axi_dma_chan *chan,
+
+ cfg_lo = (config->dst_multblk_type << CH_CFG_L_DST_MULTBLK_TYPE_POS |
+ config->src_multblk_type << CH_CFG_L_SRC_MULTBLK_TYPE_POS);
+- if (chan->chip->dw->hdata->reg_map_8_channels) {
++ if (chan->chip->dw->hdata->reg_map_8_channels &&
++ !chan->chip->dw->hdata->use_cfg2) {
+ cfg_hi = config->tt_fc << CH_CFG_H_TT_FC_POS |
+ config->hs_sel_src << CH_CFG_H_HS_SEL_SRC_POS |
+ config->hs_sel_dst << CH_CFG_H_HS_SEL_DST_POS |
+@@ -1367,10 +1374,11 @@ static int parse_device_properties(struct axi_dma_chip *chip)
+
+ static int dw_probe(struct platform_device *pdev)
+ {
+- struct device_node *node = pdev->dev.of_node;
+ struct axi_dma_chip *chip;
+ struct dw_axi_dma *dw;
+ struct dw_axi_dma_hcfg *hdata;
++ struct reset_control *resets;
++ unsigned int flags;
+ u32 i;
+ int ret;
+
+@@ -1398,12 +1406,25 @@ static int dw_probe(struct platform_device *pdev)
+ if (IS_ERR(chip->regs))
+ return PTR_ERR(chip->regs);
+
+- if (of_device_is_compatible(node, "intel,kmb-axi-dma")) {
++ flags = (uintptr_t)of_device_get_match_data(&pdev->dev);
++ if (flags & AXI_DMA_FLAG_HAS_APB_REGS) {
+ chip->apb_regs = devm_platform_ioremap_resource(pdev, 1);
+ if (IS_ERR(chip->apb_regs))
+ return PTR_ERR(chip->apb_regs);
+ }
+
++ if (flags & AXI_DMA_FLAG_HAS_RESETS) {
++ resets = devm_reset_control_array_get_exclusive(&pdev->dev);
++ if (IS_ERR(resets))
++ return PTR_ERR(resets);
++
++ ret = reset_control_deassert(resets);
++ if (ret)
++ return ret;
++ }
++
++ chip->dw->hdata->use_cfg2 = !!(flags & AXI_DMA_FLAG_USE_CFG2);
++
+ chip->core_clk = devm_clk_get(chip->dev, "core-clk");
+ if (IS_ERR(chip->core_clk))
+ return PTR_ERR(chip->core_clk);
+@@ -1554,8 +1575,15 @@ static const struct dev_pm_ops dw_axi_dma_pm_ops = {
+ };
+
+ static const struct of_device_id dw_dma_of_id_table[] = {
+- { .compatible = "snps,axi-dma-1.01a" },
+- { .compatible = "intel,kmb-axi-dma" },
++ {
++ .compatible = "snps,axi-dma-1.01a"
++ }, {
++ .compatible = "intel,kmb-axi-dma",
++ .data = (void *)AXI_DMA_FLAG_HAS_APB_REGS,
++ }, {
++ .compatible = "starfive,jh7110-axi-dma",
++ .data = (void *)(AXI_DMA_FLAG_HAS_RESETS | AXI_DMA_FLAG_USE_CFG2),
++ },
+ {}
+ };
+ MODULE_DEVICE_TABLE(of, dw_dma_of_id_table);
+diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
+index e9d5eb0fd594..eb267cb24f67 100644
+--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
++++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
+@@ -33,6 +33,7 @@ struct dw_axi_dma_hcfg {
+ /* Register map for DMAX_NUM_CHANNELS <= 8 */
+ bool reg_map_8_channels;
+ bool restrict_axi_burst_len;
++ bool use_cfg2;
+ };
+
+ struct axi_dma_chan {
+--
+2.20.1
+
--- /dev/null
+From bdb353f3e23ff1d541178791ae06c0ef1fa45e53 Mon Sep 17 00:00:00 2001
+From: Walker Chen <walker.chen@starfivetech.com>
+Date: Wed, 22 Mar 2023 17:48:19 +0800
+Subject: [PATCH 109/111] dmaengine: dw-axi-dmac: Increase polling time to DMA
+ transmission completion status
+
+The bit DMAC_CHEN[0] is automatically cleared by hardware to disable the
+channel after the last AMBA transfer of the DMA transfer to the
+destination has completed. Software can therefore poll this bit to
+determine when this channel is free for a new DMA transfer.
+This time requires at least 40 milliseconds on JH7110 SoC, otherwise an
+error message 'failed to stop' will be reported.
+
+Signed-off-by: Walker Chen <walker.chen@starfivetech.com>
+---
+ drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
+index 6cfcb541d8c3..6937cc0c0b65 100644
+--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
++++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
+@@ -1147,7 +1147,7 @@ static int dma_chan_terminate_all(struct dma_chan *dchan)
+ axi_chan_disable(chan);
+
+ ret = readl_poll_timeout_atomic(chan->chip->regs + DMAC_CHEN, val,
+- !(val & chan_active), 1000, 10000);
++ !(val & chan_active), 1000, 50000);
+ if (ret == -ETIMEDOUT)
+ dev_warn(dchan2dev(dchan),
+ "%s failed to stop\n", axi_chan_name(chan));
+--
+2.20.1
+
--- /dev/null
+From 356035bea95c223ae1f923342dfbc3559eaae337 Mon Sep 17 00:00:00 2001
+From: Zoltan HERPAI <wigyori@uid0.hu>
+Date: Mon, 29 May 2023 02:01:08 +0200
+Subject: [PATCH 110/111] dts/6.1: jh7110: add qspi node
+
+Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>
+---
+ arch/riscv/boot/dts/starfive/jh7110.dtsi | 44 ++++++++++++++++++++++++
+ 1 file changed, 44 insertions(+)
+
+diff --git a/arch/riscv/boot/dts/starfive/jh7110.dtsi b/arch/riscv/boot/dts/starfive/jh7110.dtsi
+index 09a3f5162f88..d7ce27623b9e 100644
+--- a/arch/riscv/boot/dts/starfive/jh7110.dtsi
++++ b/arch/riscv/boot/dts/starfive/jh7110.dtsi
+@@ -833,5 +833,49 @@
+ dmas = <&sdma 1 2>, <&sdma 0 2>;
+ dma-names = "tx", "rx";
+ };
++
++ qspi: spi@13010000 {
++ compatible = "starfive,jh7110-qspi", "cdns,qspi-nor";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <0x0 0x13010000 0x0 0x10000
++ 0x0 0x21000000 0x0 0x400000>;
++ interrupts = <25>;
++ clocks = <&syscrg JH7110_SYSCLK_QSPI_REF>;
++ resets = <&syscrg JH7110_SYSRST_QSPI_APB>,
++ <&syscrg JH7110_SYSRST_QSPI_AHB>,
++ <&syscrg JH7110_SYSRST_QSPI_REF>;
++ reset-names = "qspi", "qspi-ocp", "rstc_ref";
++ cdns,fifo-depth = <256>;
++ cdns,fifo-width = <4>;
++ cdns,trigger-address = <0x0>;
++
++ nor_flash: nor-flash@0 {
++ compatible = "jedec,spi-nor";
++ reg=<0>;
++ cdns,read-delay = <5>;
++ spi-max-frequency = <12000000>;
++ cdns,tshsl-ns = <1>;
++ cdns,tsd2d-ns = <1>;
++ cdns,tchsh-ns = <1>;
++ cdns,tslch-ns = <1>;
++
++ partitions {
++ compatible = "fixed-partitions";
++ #address-cells = <1>;
++ #size-cells = <1>;
++
++ spl@0 {
++ reg = <0x0 0x20000>;
++ };
++ uboot@100000 {
++ reg = <0x100000 0x300000>;
++ };
++ data@f00000 {
++ reg = <0xf00000 0x100000>;
++ };
++ };
++ };
++ };
+ };
+ };
+--
+2.20.1
+
--- /dev/null
+From eb5f958d0a591ec1665f70d0b01d8e1e4c3dc617 Mon Sep 17 00:00:00 2001
+From: Zoltan HERPAI <wigyori@uid0.hu>
+Date: Mon, 29 May 2023 02:04:47 +0200
+Subject: [PATCH 111/111] dts/6.1: starfive: add dma controller node
+
+Add the dma controller node for the Starfive JH7110 SoC.
+
+Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>
+---
+ arch/riscv/boot/dts/starfive/jh7110.dtsi | 18 ++++++++++++++++++
+ 1 file changed, 18 insertions(+)
+
+diff --git a/arch/riscv/boot/dts/starfive/jh7110.dtsi b/arch/riscv/boot/dts/starfive/jh7110.dtsi
+index d7ce27623b9e..2a51c3c152f4 100644
+--- a/arch/riscv/boot/dts/starfive/jh7110.dtsi
++++ b/arch/riscv/boot/dts/starfive/jh7110.dtsi
+@@ -612,6 +612,24 @@
+ <&syscrg JH7110_SYSRST_WDT_CORE>;
+ };
+
++ dma: dma-controller@16050000 {
++ compatible = "starfive,jh7110-axi-dma";
++ reg = <0x0 0x16050000 0x0 0x10000>;
++ clocks = <&stgcrg JH7110_STGCLK_DMA1P_AXI>,
++ <&stgcrg JH7110_STGCLK_DMA1P_AHB>;
++ clock-names = "core-clk", "cfgr-clk";
++ resets = <&stgcrg JH7110_STGRST_DMA1P_AXI>,
++ <&stgcrg JH7110_STGRST_DMA1P_AHB>;
++ interrupts = <73>;
++ #dma-cells = <1>;
++ dma-channels = <4>;
++ snps,dma-masters = <1>;
++ snps,data-width = <3>;
++ snps,block-size = <65536 65536 65536 65536>;
++ snps,priority = <0 1 2 3>;
++ snps,axi-max-burst-len = <16>;
++ };
++
+ aoncrg: clock-controller@17000000 {
+ compatible = "starfive,jh7110-aoncrg";
+ reg = <0x0 0x17000000 0x0 0x10000>;
+--
+2.20.1
+
--- /dev/null
+From e7edc9897fe9514a5fa876228bbb55267983f2a9 Mon Sep 17 00:00:00 2001
+From: Zoltan HERPAI <wigyori@uid0.hu>
+Date: Mon, 29 May 2023 18:42:38 +0200
+Subject: [PATCH 112/112] clk/6.1: jh7110-sys updates
+
+Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>
+---
+ drivers/clk/starfive/clk-starfive-jh7110-sys.c | 15 ++++++++++++---
+ include/soc/starfive/reset-starfive-jh71x0.h | 17 +++++++++++++++++
+ 2 files changed, 29 insertions(+), 3 deletions(-)
+ create mode 100644 include/soc/starfive/reset-starfive-jh71x0.h
+
+diff --git a/drivers/clk/starfive/clk-starfive-jh7110-sys.c b/drivers/clk/starfive/clk-starfive-jh7110-sys.c
+index ae72f0149ebb..7fd30c571059 100644
+--- a/drivers/clk/starfive/clk-starfive-jh7110-sys.c
++++ b/drivers/clk/starfive/clk-starfive-jh7110-sys.c
+@@ -11,6 +11,9 @@
+ #include <linux/init.h>
+ #include <linux/io.h>
+ #include <linux/platform_device.h>
++#include <linux/slab.h>
++
++#include <soc/starfive/reset-starfive-jh71x0.h>
+
+ #include <dt-bindings/clock/starfive,jh7110-crg.h>
+
+@@ -335,26 +338,32 @@ static void jh7110_reset_unregister_adev(void *_adev)
+ struct auxiliary_device *adev = _adev;
+
+ auxiliary_device_delete(adev);
++ auxiliary_device_uninit(adev);
+ }
+
+ static void jh7110_reset_adev_release(struct device *dev)
+ {
+ struct auxiliary_device *adev = to_auxiliary_dev(dev);
++ struct jh71x0_reset_adev *rdev = to_jh71x0_reset_adev(adev);
+
+- auxiliary_device_uninit(adev);
++ kfree(rdev);
+ }
+
+ int jh7110_reset_controller_register(struct jh71x0_clk_priv *priv,
+ const char *adev_name,
+ u32 adev_id)
+ {
++ struct jh71x0_reset_adev *rdev;
+ struct auxiliary_device *adev;
+ int ret;
+
+- adev = devm_kzalloc(priv->dev, sizeof(*adev), GFP_KERNEL);
+- if (!adev)
++ rdev = kzalloc(sizeof(*rdev), GFP_KERNEL);
++ if (!rdev)
+ return -ENOMEM;
+
++ rdev->base = priv->base;
++
++ adev = &rdev->adev;
+ adev->name = adev_name;
+ adev->dev.parent = priv->dev;
+ adev->dev.release = jh7110_reset_adev_release;
+diff --git a/include/soc/starfive/reset-starfive-jh71x0.h b/include/soc/starfive/reset-starfive-jh71x0.h
+new file mode 100644
+index 000000000000..47b486ececc5
+--- /dev/null
++++ b/include/soc/starfive/reset-starfive-jh71x0.h
+@@ -0,0 +1,17 @@
++/* SPDX-License-Identifier: GPL-2.0 */
++#ifndef __SOC_STARFIVE_RESET_JH71X0_H
++#define __SOC_STARFIVE_RESET_JH71X0_H
++
++#include <linux/auxiliary_bus.h>
++#include <linux/compiler_types.h>
++#include <linux/container_of.h>
++
++struct jh71x0_reset_adev {
++ void __iomem *base;
++ struct auxiliary_device adev;
++};
++
++#define to_jh71x0_reset_adev(_adev) \
++ container_of((_adev), struct jh71x0_reset_adev, adev)
++
++#endif
+--
+2.20.1
+
--- /dev/null
+From 8c1b977209774d20753d819fa8d94d5b1a126706 Mon Sep 17 00:00:00 2001
+From: Geert Uytterhoeven <geert@linux-m68k.org>
+Date: Thu, 25 Nov 2021 14:21:18 +0100
+Subject: [PATCH 113/121] riscv: dts: starfive: Group tuples in interrupt
+ properties
+
+To improve human readability and enable automatic validation, the tuples
+in the various properties containing interrupt specifiers should be
+grouped.
+
+Fix this by grouping the tuples of "interrupts-extended" properties
+using angle brackets.
+
+Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
+---
+ arch/riscv/boot/dts/starfive/jh7100.dtsi | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/arch/riscv/boot/dts/starfive/jh7100.dtsi b/arch/riscv/boot/dts/starfive/jh7100.dtsi
+index 4218621ea3b9..b3f944c1b5b9 100644
+--- a/arch/riscv/boot/dts/starfive/jh7100.dtsi
++++ b/arch/riscv/boot/dts/starfive/jh7100.dtsi
+@@ -118,15 +118,15 @@
+ clint: clint@2000000 {
+ compatible = "starfive,jh7100-clint", "sifive,clint0";
+ reg = <0x0 0x2000000 0x0 0x10000>;
+- interrupts-extended = <&cpu0_intc 3 &cpu0_intc 7
+- &cpu1_intc 3 &cpu1_intc 7>;
++ interrupts-extended = <&cpu0_intc 3>, <&cpu0_intc 7>,
++ <&cpu1_intc 3>, <&cpu1_intc 7>;
+ };
+
+ plic: interrupt-controller@c000000 {
+ compatible = "starfive,jh7100-plic", "sifive,plic-1.0.0";
+ reg = <0x0 0xc000000 0x0 0x4000000>;
+- interrupts-extended = <&cpu0_intc 11 &cpu0_intc 9
+- &cpu1_intc 11 &cpu1_intc 9>;
++ interrupts-extended = <&cpu0_intc 11>, <&cpu0_intc 9>,
++ <&cpu1_intc 11>, <&cpu1_intc 9>;
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <1>;
+--
+2.20.1
+
--- /dev/null
+From 908d47cb1cb38bb92f95284ed800b1a059cef641 Mon Sep 17 00:00:00 2001
+From: Emil Renner Berthing <kernel@esmil.dk>
+Date: Sat, 20 Nov 2021 17:13:22 +0100
+Subject: [PATCH 114/121] RISC-V: Add StarFive JH7100 audio clock node
+
+Add device tree node for the audio clocks on the StarFive JH7100 RISC-V
+SoC.
+
+Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
+---
+ arch/riscv/boot/dts/starfive/jh7100.dtsi | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/arch/riscv/boot/dts/starfive/jh7100.dtsi b/arch/riscv/boot/dts/starfive/jh7100.dtsi
+index b3f944c1b5b9..930721e87ae8 100644
+--- a/arch/riscv/boot/dts/starfive/jh7100.dtsi
++++ b/arch/riscv/boot/dts/starfive/jh7100.dtsi
+@@ -133,6 +133,16 @@
+ riscv,ndev = <133>;
+ };
+
++ audclk: clock-controller@10480000 {
++ compatible = "starfive,jh7100-audclk";
++ reg = <0x0 0x10480000 0x0 0x10000>;
++ clocks = <&clkgen JH7100_CLK_AUDIO_SRC>,
++ <&clkgen JH7100_CLK_AUDIO_12288>,
++ <&clkgen JH7100_CLK_DOM7AHB_BUS>;
++ clock-names = "audio_src", "audio_12288", "dom7ahb_bus";
++ #clock-cells = <1>;
++ };
++
+ clkgen: clock-controller@11800000 {
+ compatible = "starfive,jh7100-clkgen";
+ reg = <0x0 0x11800000 0x0 0x10000>;
+--
+2.20.1
+
--- /dev/null
+From 9a5847f6f31c61b86e76594a33f549bf3cd52667 Mon Sep 17 00:00:00 2001
+From: Emil Renner Berthing <kernel@esmil.dk>
+Date: Wed, 31 Aug 2022 22:54:07 +0200
+Subject: [PATCH 115/121] RISC-V: Mark StarFive JH7100 as having non-coherent
+ DMAs
+
+Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
+---
+ arch/riscv/boot/dts/starfive/jh7100.dtsi | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/riscv/boot/dts/starfive/jh7100.dtsi b/arch/riscv/boot/dts/starfive/jh7100.dtsi
+index 930721e87ae8..2c67f7344cbe 100644
+--- a/arch/riscv/boot/dts/starfive/jh7100.dtsi
++++ b/arch/riscv/boot/dts/starfive/jh7100.dtsi
+@@ -111,6 +111,7 @@
+ soc {
+ compatible = "simple-bus";
+ interrupt-parent = <&plic>;
++ dma-noncoherent;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+--
+2.20.1
+
--- /dev/null
+From 41cb238de44a75d464d2774436427c4ea98ba978 Mon Sep 17 00:00:00 2001
+From: Emil Renner Berthing <kernel@esmil.dk>
+Date: Thu, 14 Oct 2021 20:56:54 +0200
+Subject: [PATCH 116/121] serial: 8250_dw: Add starfive,jh7100-hsuart
+ compatible
+
+This adds a compatible for the high speed UARTs on the StarFive JH7100
+RISC-V SoC. Just like the regular uarts we also need to keep the input
+clocks at their default rate and rely only on the divisor in the UART.
+
+Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
+---
+ drivers/tty/serial/8250/8250_dw.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c
+index 7db51781289e..b749f2805df7 100644
+--- a/drivers/tty/serial/8250/8250_dw.c
++++ b/drivers/tty/serial/8250/8250_dw.c
+@@ -777,6 +777,7 @@ static const struct of_device_id dw8250_of_match[] = {
+ { .compatible = "cavium,octeon-3860-uart", .data = &dw8250_octeon_3860_data },
+ { .compatible = "marvell,armada-38x-uart", .data = &dw8250_armada_38x_data },
+ { .compatible = "renesas,rzn1-uart", .data = &dw8250_renesas_rzn1_data },
++ { .compatible = "starfive,jh7100-hsuart", .data = &dw8250_starfive_jh7100_data },
+ { .compatible = "starfive,jh7100-uart", .data = &dw8250_starfive_jh7100_data },
+ { /* Sentinel */ }
+ };
+--
+2.20.1
+
--- /dev/null
+From 14290f4e63cdfc8f0bd047361a884cbdb5bb8d1d Mon Sep 17 00:00:00 2001
+From: Samin Guo <samin.guo@starfivetech.com>
+Date: Fri, 8 Jan 2021 03:11:04 +0800
+Subject: [PATCH 117/121] drivers/tty/serial/8250: update driver for JH7100
+
+---
+ drivers/tty/serial/8250/8250_port.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c
+index b8e8a96c3eb6..2a2d7c9b960e 100644
+--- a/drivers/tty/serial/8250/8250_port.c
++++ b/drivers/tty/serial/8250/8250_port.c
+@@ -72,8 +72,16 @@ static const struct serial8250_config uart_config[] = {
+ },
+ [PORT_16550] = {
+ .name = "16550",
++#ifdef CONFIG_SOC_STARFIVE
++ .fifo_size = 16,
++ .tx_loadsz = 16,
++ .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_00,
++ .rxtrig_bytes = {1, 4, 8, 14},
++ .flags = UART_CAP_FIFO,
++#else
+ .fifo_size = 1,
+ .tx_loadsz = 1,
++#endif
+ },
+ [PORT_16550A] = {
+ .name = "16550A",
+--
+2.20.1
+
--- /dev/null
+From d5c72c2a426e059b5b5d9c9b689bf9353605769d Mon Sep 17 00:00:00 2001
+From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
+Date: Tue, 18 Oct 2022 00:05:41 +0300
+Subject: [PATCH 118/121] riscv: dts: starfive: Add common DT for JH7100 based
+ boards
+
+In preparation for adding initial device tree support for the StarFive
+VisionFive board, which is similar with BeagleV Starlight, move most
+of the content from jh7100-beaglev-starlight.dts to a new file, to be
+shared between the two boards.
+
+Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+Reviewed-by: Matthias Brugger <mbrugger@suse.com>
+Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
+---
+ .../dts/starfive/jh7100-beaglev-starlight.dts | 153 +----------------
+ .../boot/dts/starfive/jh7100-common.dtsi | 161 ++++++++++++++++++
+ 2 files changed, 162 insertions(+), 152 deletions(-)
+ create mode 100644 arch/riscv/boot/dts/starfive/jh7100-common.dtsi
+
+diff --git a/arch/riscv/boot/dts/starfive/jh7100-beaglev-starlight.dts b/arch/riscv/boot/dts/starfive/jh7100-beaglev-starlight.dts
+index f7a230110512..7cda3a89020a 100644
+--- a/arch/riscv/boot/dts/starfive/jh7100-beaglev-starlight.dts
++++ b/arch/riscv/boot/dts/starfive/jh7100-beaglev-starlight.dts
+@@ -5,160 +5,9 @@
+ */
+
+ /dts-v1/;
+-#include "jh7100.dtsi"
+-#include <dt-bindings/gpio/gpio.h>
+-#include <dt-bindings/leds/common.h>
+-#include <dt-bindings/pinctrl/pinctrl-starfive-jh7100.h>
++#include "jh7100-common.dtsi"
+
+ / {
+ model = "BeagleV Starlight Beta";
+ compatible = "beagle,beaglev-starlight-jh7100-r0", "starfive,jh7100";
+-
+- aliases {
+- serial0 = &uart3;
+- };
+-
+- chosen {
+- stdout-path = "serial0:115200n8";
+- };
+-
+- cpus {
+- timebase-frequency = <6250000>;
+- };
+-
+- memory@80000000 {
+- device_type = "memory";
+- reg = <0x0 0x80000000 0x2 0x0>;
+- };
+-
+- leds {
+- compatible = "gpio-leds";
+-
+- led-ack {
+- gpios = <&gpio 43 GPIO_ACTIVE_HIGH>;
+- color = <LED_COLOR_ID_GREEN>;
+- function = LED_FUNCTION_HEARTBEAT;
+- linux,default-trigger = "heartbeat";
+- label = "ack";
+- };
+- };
+-};
+-
+-&gpio {
+- i2c0_pins: i2c0-0 {
+- i2c-pins {
+- pinmux = <GPIOMUX(62, GPO_LOW,
+- GPO_I2C0_PAD_SCK_OEN,
+- GPI_I2C0_PAD_SCK_IN)>,
+- <GPIOMUX(61, GPO_LOW,
+- GPO_I2C0_PAD_SDA_OEN,
+- GPI_I2C0_PAD_SDA_IN)>;
+- bias-disable; /* external pull-up */
+- input-enable;
+- input-schmitt-enable;
+- };
+- };
+-
+- i2c1_pins: i2c1-0 {
+- i2c-pins {
+- pinmux = <GPIOMUX(47, GPO_LOW,
+- GPO_I2C1_PAD_SCK_OEN,
+- GPI_I2C1_PAD_SCK_IN)>,
+- <GPIOMUX(48, GPO_LOW,
+- GPO_I2C1_PAD_SDA_OEN,
+- GPI_I2C1_PAD_SDA_IN)>;
+- bias-pull-up;
+- input-enable;
+- input-schmitt-enable;
+- };
+- };
+-
+- i2c2_pins: i2c2-0 {
+- i2c-pins {
+- pinmux = <GPIOMUX(60, GPO_LOW,
+- GPO_I2C2_PAD_SCK_OEN,
+- GPI_I2C2_PAD_SCK_IN)>,
+- <GPIOMUX(59, GPO_LOW,
+- GPO_I2C2_PAD_SDA_OEN,
+- GPI_I2C2_PAD_SDA_IN)>;
+- bias-disable; /* external pull-up */
+- input-enable;
+- input-schmitt-enable;
+- };
+- };
+-
+- uart3_pins: uart3-0 {
+- rx-pins {
+- pinmux = <GPIOMUX(13, GPO_LOW, GPO_DISABLE,
+- GPI_UART3_PAD_SIN)>;
+- bias-pull-up;
+- drive-strength = <14>;
+- input-enable;
+- input-schmitt-enable;
+- slew-rate = <0>;
+- };
+- tx-pins {
+- pinmux = <GPIOMUX(14, GPO_UART3_PAD_SOUT,
+- GPO_ENABLE, GPI_NONE)>;
+- bias-disable;
+- drive-strength = <35>;
+- input-disable;
+- input-schmitt-disable;
+- slew-rate = <0>;
+- };
+- };
+-};
+-
+-&i2c0 {
+- clock-frequency = <100000>;
+- i2c-sda-hold-time-ns = <300>;
+- i2c-sda-falling-time-ns = <500>;
+- i2c-scl-falling-time-ns = <500>;
+- pinctrl-names = "default";
+- pinctrl-0 = <&i2c0_pins>;
+- status = "okay";
+-
+- pmic@5e {
+- compatible = "ti,tps65086";
+- reg = <0x5e>;
+- gpio-controller;
+- #gpio-cells = <2>;
+-
+- regulators {
+- };
+- };
+-};
+-
+-&i2c1 {
+- clock-frequency = <400000>;
+- i2c-sda-hold-time-ns = <300>;
+- i2c-sda-falling-time-ns = <100>;
+- i2c-scl-falling-time-ns = <100>;
+- pinctrl-names = "default";
+- pinctrl-0 = <&i2c1_pins>;
+- status = "okay";
+-};
+-
+-&i2c2 {
+- clock-frequency = <100000>;
+- i2c-sda-hold-time-ns = <300>;
+- i2c-sda-falling-time-ns = <500>;
+- i2c-scl-falling-time-ns = <500>;
+- pinctrl-names = "default";
+- pinctrl-0 = <&i2c2_pins>;
+- status = "okay";
+-};
+-
+-&osc_sys {
+- clock-frequency = <25000000>;
+-};
+-
+-&osc_aud {
+- clock-frequency = <27000000>;
+-};
+-
+-&uart3 {
+- pinctrl-names = "default";
+- pinctrl-0 = <&uart3_pins>;
+- status = "okay";
+ };
+diff --git a/arch/riscv/boot/dts/starfive/jh7100-common.dtsi b/arch/riscv/boot/dts/starfive/jh7100-common.dtsi
+new file mode 100644
+index 000000000000..b93ce351a90f
+--- /dev/null
++++ b/arch/riscv/boot/dts/starfive/jh7100-common.dtsi
+@@ -0,0 +1,161 @@
++// SPDX-License-Identifier: GPL-2.0 OR MIT
++/*
++ * Copyright (C) 2021 StarFive Technology Co., Ltd.
++ * Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
++ */
++
++/dts-v1/;
++#include "jh7100.dtsi"
++#include <dt-bindings/gpio/gpio.h>
++#include <dt-bindings/leds/common.h>
++#include <dt-bindings/pinctrl/pinctrl-starfive-jh7100.h>
++
++/ {
++ aliases {
++ serial0 = &uart3;
++ };
++
++ chosen {
++ stdout-path = "serial0:115200n8";
++ };
++
++ cpus {
++ timebase-frequency = <6250000>;
++ };
++
++ memory@80000000 {
++ device_type = "memory";
++ reg = <0x0 0x80000000 0x2 0x0>;
++ };
++
++ leds {
++ compatible = "gpio-leds";
++
++ led-ack {
++ gpios = <&gpio 43 GPIO_ACTIVE_HIGH>;
++ color = <LED_COLOR_ID_GREEN>;
++ function = LED_FUNCTION_HEARTBEAT;
++ linux,default-trigger = "heartbeat";
++ label = "ack";
++ };
++ };
++};
++
++&gpio {
++ i2c0_pins: i2c0-0 {
++ i2c-pins {
++ pinmux = <GPIOMUX(62, GPO_LOW,
++ GPO_I2C0_PAD_SCK_OEN,
++ GPI_I2C0_PAD_SCK_IN)>,
++ <GPIOMUX(61, GPO_LOW,
++ GPO_I2C0_PAD_SDA_OEN,
++ GPI_I2C0_PAD_SDA_IN)>;
++ bias-disable; /* external pull-up */
++ input-enable;
++ input-schmitt-enable;
++ };
++ };
++
++ i2c1_pins: i2c1-0 {
++ i2c-pins {
++ pinmux = <GPIOMUX(47, GPO_LOW,
++ GPO_I2C1_PAD_SCK_OEN,
++ GPI_I2C1_PAD_SCK_IN)>,
++ <GPIOMUX(48, GPO_LOW,
++ GPO_I2C1_PAD_SDA_OEN,
++ GPI_I2C1_PAD_SDA_IN)>;
++ bias-pull-up;
++ input-enable;
++ input-schmitt-enable;
++ };
++ };
++
++ i2c2_pins: i2c2-0 {
++ i2c-pins {
++ pinmux = <GPIOMUX(60, GPO_LOW,
++ GPO_I2C2_PAD_SCK_OEN,
++ GPI_I2C2_PAD_SCK_IN)>,
++ <GPIOMUX(59, GPO_LOW,
++ GPO_I2C2_PAD_SDA_OEN,
++ GPI_I2C2_PAD_SDA_IN)>;
++ bias-disable; /* external pull-up */
++ input-enable;
++ input-schmitt-enable;
++ };
++ };
++
++ uart3_pins: uart3-0 {
++ rx-pins {
++ pinmux = <GPIOMUX(13, GPO_LOW, GPO_DISABLE,
++ GPI_UART3_PAD_SIN)>;
++ bias-pull-up;
++ drive-strength = <14>;
++ input-enable;
++ input-schmitt-enable;
++ slew-rate = <0>;
++ };
++ tx-pins {
++ pinmux = <GPIOMUX(14, GPO_UART3_PAD_SOUT,
++ GPO_ENABLE, GPI_NONE)>;
++ bias-disable;
++ drive-strength = <35>;
++ input-disable;
++ input-schmitt-disable;
++ slew-rate = <0>;
++ };
++ };
++};
++
++&i2c0 {
++ clock-frequency = <100000>;
++ i2c-sda-hold-time-ns = <300>;
++ i2c-sda-falling-time-ns = <500>;
++ i2c-scl-falling-time-ns = <500>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&i2c0_pins>;
++ status = "okay";
++
++ pmic@5e {
++ compatible = "ti,tps65086";
++ reg = <0x5e>;
++ gpio-controller;
++ #gpio-cells = <2>;
++
++ regulators {
++ };
++ };
++};
++
++&i2c1 {
++ clock-frequency = <400000>;
++ i2c-sda-hold-time-ns = <300>;
++ i2c-sda-falling-time-ns = <100>;
++ i2c-scl-falling-time-ns = <100>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&i2c1_pins>;
++ status = "okay";
++};
++
++&i2c2 {
++ clock-frequency = <100000>;
++ i2c-sda-hold-time-ns = <300>;
++ i2c-sda-falling-time-ns = <500>;
++ i2c-scl-falling-time-ns = <500>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&i2c2_pins>;
++ status = "okay";
++};
++
++&osc_sys {
++ clock-frequency = <25000000>;
++};
++
++&osc_aud {
++ clock-frequency = <27000000>;
++};
++
++&uart3 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&uart3_pins>;
++ status = "okay";
++};
+--
+2.20.1
+
--- /dev/null
+From 91a6c27221580de6a5cf99764ebce820dd1fbd03 Mon Sep 17 00:00:00 2001
+From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
+Date: Tue, 18 Oct 2022 00:05:42 +0300
+Subject: [PATCH 119/121] riscv: dts: starfive: Add StarFive VisionFive V1
+ device tree
+
+Add initial device tree for the StarFive VisionFive V1 SBC, which
+is similar with the already supported BeagleV Starlight Beta board,
+both being based on the StarFive JH7100 SoC.
+
+Link: https://github.com/starfive-tech/VisionFive
+Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+Reviewed-by: Matthias Brugger <mbrugger@suse.com>
+Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
+---
+ arch/riscv/boot/dts/starfive/Makefile | 2 +-
+ .../jh7100-starfive-visionfive-v1.dts | 20 +++++++++++++++++++
+ 2 files changed, 21 insertions(+), 1 deletion(-)
+ create mode 100644 arch/riscv/boot/dts/starfive/jh7100-starfive-visionfive-v1.dts
+
+diff --git a/arch/riscv/boot/dts/starfive/Makefile b/arch/riscv/boot/dts/starfive/Makefile
+index 1801cfb7bd95..cd73519b907b 100644
+--- a/arch/riscv/boot/dts/starfive/Makefile
++++ b/arch/riscv/boot/dts/starfive/Makefile
+@@ -1,6 +1,6 @@
+ # SPDX-License-Identifier: GPL-2.0
+ dtb-$(CONFIG_SOC_STARFIVE) += jh7100-beaglev-starlight.dtb
+-#dtb-$(CONFIG_SOC_STARFIVE) += jh7100-starfive-visionfive-v1.dtb
++dtb-$(CONFIG_SOC_STARFIVE) += jh7100-starfive-visionfive-v1.dtb
+
+ dtb-$(CONFIG_SOC_STARFIVE) += jh7110-starfive-visionfive-2-v1.2a.dtb
+ dtb-$(CONFIG_SOC_STARFIVE) += jh7110-starfive-visionfive-2-v1.3b.dtb
+diff --git a/arch/riscv/boot/dts/starfive/jh7100-starfive-visionfive-v1.dts b/arch/riscv/boot/dts/starfive/jh7100-starfive-visionfive-v1.dts
+new file mode 100644
+index 000000000000..e82af72f1aaf
+--- /dev/null
++++ b/arch/riscv/boot/dts/starfive/jh7100-starfive-visionfive-v1.dts
+@@ -0,0 +1,20 @@
++// SPDX-License-Identifier: GPL-2.0 OR MIT
++/*
++ * Copyright (C) 2021 StarFive Technology Co., Ltd.
++ * Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
++ */
++
++/dts-v1/;
++#include "jh7100-common.dtsi"
++#include <dt-bindings/gpio/gpio.h>
++
++/ {
++ model = "StarFive VisionFive V1";
++ compatible = "starfive,visionfive-v1", "starfive,jh7100";
++
++ gpio-restart {
++ compatible = "gpio-restart";
++ gpios = <&gpio 63 GPIO_ACTIVE_HIGH>;
++ priority = <224>;
++ };
++};
+--
+2.20.1
+
--- /dev/null
+From 72f0b2a09859420f6b20e1a097d2432675467807 Mon Sep 17 00:00:00 2001
+From: Emil Renner Berthing <kernel@esmil.dk>
+Date: Sun, 31 Oct 2021 17:15:58 +0100
+Subject: [PATCH 120/121] riscv: dts: Add full JH7100, Starlight and VisionFive
+ support
+
+Based on the device tree in https://github.com/starfive-tech/u-boot/
+with contributions from:
+yanhong.wang <yanhong.wang@starfivetech.com>
+Huan.Feng <huan.feng@starfivetech.com>
+ke.zhu <ke.zhu@starfivetech.com>
+yiming.li <yiming.li@starfivetech.com>
+jack.zhu <jack.zhu@starfivetech.com>
+Samin Guo <samin.guo@starfivetech.com>
+Chenjieqin <Jessica.Chen@starfivetech.com>
+bo.li <bo.li@starfivetech.com>
+
+Rearranged, cleanups, fixes, pins and resets added by Emil.
+Cleanups, fixes, clocks added by Geert.
+Cleanups and GPIO fixes from Drew.
+Thermal zone added by Stephen.
+PWM pins added by Jianlong.
+cpu-map added by Jonas.
+
+Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
+Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
+Signed-off-by: Stephen L Arnold <nerdboy@gentoo.org>
+Signed-off-by: Drew Fustini <drew@beagleboard.org>
+Signed-off-by: Jianlong Huang <jianlong.huang@starfivetech.com>
+Signed-off-by: Jonas Hahnfeld <hahnjo@hahnjo.de>
+---
+ .../starfive/jh7100-beaglev-starlight-a1.dts | 24 +
+ .../dts/starfive/jh7100-beaglev-starlight.dts | 10 +
+ .../boot/dts/starfive/jh7100-common.dtsi | 426 +++++++++++++
+ .../jh7100-starfive-visionfive-v1.dts | 13 +
+ arch/riscv/boot/dts/starfive/jh7100.dtsi | 568 ++++++++++++++++++
+ 5 files changed, 1041 insertions(+)
+ create mode 100644 arch/riscv/boot/dts/starfive/jh7100-beaglev-starlight-a1.dts
+
+diff --git a/arch/riscv/boot/dts/starfive/jh7100-beaglev-starlight-a1.dts b/arch/riscv/boot/dts/starfive/jh7100-beaglev-starlight-a1.dts
+new file mode 100644
+index 000000000000..d307e44590f3
+--- /dev/null
++++ b/arch/riscv/boot/dts/starfive/jh7100-beaglev-starlight-a1.dts
+@@ -0,0 +1,24 @@
++// SPDX-License-Identifier: GPL-2.0 OR MIT
++/*
++ * Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
++ */
++
++/dts-v1/;
++#include "jh7100-common.dtsi"
++#include <dt-bindings/gpio/gpio.h>
++
++/ {
++ model = "BeagleV Starlight Beta A1";
++ compatible = "beagle,beaglev-starlight-jh7100-a1", "starfive,jh7100";
++
++ gpio-restart {
++ compatible = "gpio-restart";
++ gpios = <&gpio 63 GPIO_ACTIVE_HIGH>;
++ priority = <224>;
++ };
++};
++
++&gpio {
++ /* don't reset gpio mux for serial console and reset gpio */
++ starfive,keep-gpiomux = <13 14 63>;
++};
+diff --git a/arch/riscv/boot/dts/starfive/jh7100-beaglev-starlight.dts b/arch/riscv/boot/dts/starfive/jh7100-beaglev-starlight.dts
+index 7cda3a89020a..92a05c6bf5d6 100644
+--- a/arch/riscv/boot/dts/starfive/jh7100-beaglev-starlight.dts
++++ b/arch/riscv/boot/dts/starfive/jh7100-beaglev-starlight.dts
+@@ -6,8 +6,18 @@
+
+ /dts-v1/;
+ #include "jh7100-common.dtsi"
++#include <dt-bindings/gpio/gpio.h>
+
+ / {
+ model = "BeagleV Starlight Beta";
+ compatible = "beagle,beaglev-starlight-jh7100-r0", "starfive,jh7100";
+ };
++
++&gmac {
++ snps,reset-gpios = <&gpio 63 GPIO_ACTIVE_LOW>;
++};
++
++&gpio {
++ /* don't reset gpio mux for serial console on uart3 */
++ starfive,keep-gpiomux = <13 14>;
++};
+diff --git a/arch/riscv/boot/dts/starfive/jh7100-common.dtsi b/arch/riscv/boot/dts/starfive/jh7100-common.dtsi
+index b93ce351a90f..1a36da546137 100644
+--- a/arch/riscv/boot/dts/starfive/jh7100-common.dtsi
++++ b/arch/riscv/boot/dts/starfive/jh7100-common.dtsi
+@@ -12,7 +12,10 @@
+
+ / {
+ aliases {
++ mmc0 = &sdio0;
++ mmc1 = &sdio1;
+ serial0 = &uart3;
++ serial1 = &uart0;
+ };
+
+ chosen {
+@@ -39,9 +42,166 @@
+ label = "ack";
+ };
+ };
++
++ reserved-memory {
++ #address-cells = <2>;
++ #size-cells = <2>;
++ ranges;
++
++ linux,cma {
++ compatible = "shared-dma-pool";
++ reusable;
++ size = <0x0 0x28000000>;
++ alignment = <0x0 0x1000>;
++ alloc-ranges = <0x0 0xa0000000 0x0 0x28000000>;
++ linux,cma-default;
++ };
++
++ jpu_reserved: framebuffer@c9000000 {
++ reg = <0x0 0xc9000000 0x0 0x4000000>;
++ };
++
++ nvdla_reserved: framebuffer@d0000000 {
++ no-map;
++ reg = <0x0 0xd0000000 0x0 0x28000000>;
++ };
++
++ vin_reserved: framebuffer@f9000000 {
++ compatible = "shared-dma-pool";
++ no-map;
++ reg = <0x0 0xf9000000 0x0 0x1000000>;
++ };
++
++ sffb_reserved: framebuffer@fb000000 {
++ compatible = "shared-dma-pool";
++ no-map;
++ reg = <0x0 0xfb000000 0x0 0x2000000>;
++ };
++ };
++
++ wifi_pwrseq: wifi-pwrseq {
++ compatible = "mmc-pwrseq-simple";
++ reset-gpios = <&gpio 37 GPIO_ACTIVE_LOW>;
++ };
++};
++
++&display {
++ memory-region = <&sffb_reserved>;
++ status = "okay";
++};
++
++&crtc {
++ ddr-format = <4>; //<WIN_FMT_RGB565>;
++ status = "okay";
++
++ port: port@0 {
++ reg = <0>;
++
++ crtc_0_out: endpoint {
++ remote-endpoint = <&hdmi_input0>;
++ };
++ };
++};
++
++&encoder {
++ encoder-type = <2>; // 2-TMDS, 3-LVDS, 6-DSI, 8-DPI
++ status = "okay";
++
++ ports {
++ port@0 {
++ hdmi_out: endpoint {
++ remote-endpoint = <&tda998x_0_input>;
++ };
++ };
++
++ port@1 {
++ hdmi_input0: endpoint {
++ remote-endpoint = <&crtc_0_out>;
++ };
++ };
++
++ };
++};
++
++&gmac {
++ starfive,gtxclk-dlychain = <4>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&gmac_pins>;
++ status = "okay";
+ };
+
+ &gpio {
++ gmac_pins: gmac-0 {
++ gtxclk-pins {
++ pins = <PAD_FUNC_SHARE(115)>;
++ bias-pull-up;
++ drive-strength = <35>;
++ input-enable;
++ input-schmitt-enable;
++ slew-rate = <0>;
++ };
++ miitxclk-pins {
++ pins = <PAD_FUNC_SHARE(116)>;
++ bias-pull-up;
++ drive-strength = <14>;
++ input-enable;
++ input-schmitt-disable;
++ slew-rate = <0>;
++ };
++ tx-pins {
++ pins = <PAD_FUNC_SHARE(117)>,
++ <PAD_FUNC_SHARE(119)>,
++ <PAD_FUNC_SHARE(120)>,
++ <PAD_FUNC_SHARE(121)>,
++ <PAD_FUNC_SHARE(122)>,
++ <PAD_FUNC_SHARE(123)>,
++ <PAD_FUNC_SHARE(124)>,
++ <PAD_FUNC_SHARE(125)>,
++ <PAD_FUNC_SHARE(126)>;
++ bias-pull-up;
++ drive-strength = <35>;
++ input-disable;
++ input-schmitt-disable;
++ slew-rate = <0>;
++ };
++ rxclk-pins {
++ pins = <PAD_FUNC_SHARE(127)>;
++ bias-pull-up;
++ drive-strength = <14>;
++ input-enable;
++ input-schmitt-disable;
++ slew-rate = <6>;
++ };
++ rxer-pins {
++ pins = <PAD_FUNC_SHARE(129)>;
++ bias-pull-up;
++ drive-strength = <14>;
++ input-enable;
++ input-schmitt-disable;
++ slew-rate = <0>;
++ };
++ rx-pins {
++ pins = <PAD_FUNC_SHARE(128)>,
++ <PAD_FUNC_SHARE(130)>,
++ <PAD_FUNC_SHARE(131)>,
++ <PAD_FUNC_SHARE(132)>,
++ <PAD_FUNC_SHARE(133)>,
++ <PAD_FUNC_SHARE(134)>,
++ <PAD_FUNC_SHARE(135)>,
++ <PAD_FUNC_SHARE(136)>,
++ <PAD_FUNC_SHARE(137)>,
++ <PAD_FUNC_SHARE(138)>,
++ <PAD_FUNC_SHARE(139)>,
++ <PAD_FUNC_SHARE(140)>,
++ <PAD_FUNC_SHARE(141)>;
++ bias-pull-up;
++ drive-strength = <14>;
++ input-enable;
++ input-schmitt-enable;
++ slew-rate = <0>;
++ };
++ };
++
+ i2c0_pins: i2c0-0 {
+ i2c-pins {
+ pinmux = <GPIOMUX(62, GPO_LOW,
+@@ -84,6 +244,166 @@
+ };
+ };
+
++ pwmdac_pins: pwmdac-0 {
++ pwmdac-pins {
++ pinmux = <GPIOMUX(23, GPO_PWMDAC_LEFT_OUT,
++ GPO_ENABLE, GPI_NONE)>,
++ <GPIOMUX(24, GPO_PWMDAC_RIGHT_OUT,
++ GPO_ENABLE, GPI_NONE)>;
++ bias-disable;
++ drive-strength = <35>;
++ input-disable;
++ input-schmitt-disable;
++ slew-rate = <0>;
++ };
++ };
++
++ pwm_pins: pwm-0 {
++ pwm-pins {
++ pinmux = <GPIOMUX(7,
++ GPO_PWM_PAD_OUT_BIT0,
++ GPO_PWM_PAD_OE_N_BIT0,
++ GPI_NONE)>,
++ <GPIOMUX(5,
++ GPO_PWM_PAD_OUT_BIT1,
++ GPO_PWM_PAD_OE_N_BIT1,
++ GPI_NONE)>;
++ bias-disable;
++ drive-strength = <35>;
++ input-disable;
++ input-schmitt-disable;
++ slew-rate = <0>;
++ };
++ };
++
++ sdio0_pins: sdio0-0 {
++ clk-pins {
++ pinmux = <GPIOMUX(54, GPO_SDIO0_PAD_CCLK_OUT,
++ GPO_ENABLE, GPI_NONE)>;
++ bias-disable;
++ input-disable;
++ input-schmitt-disable;
++ };
++ sdio-pins {
++ pinmux = <GPIOMUX(55, GPO_LOW, GPO_DISABLE,
++ GPI_SDIO0_PAD_CARD_DETECT_N)>,
++ <GPIOMUX(53,
++ GPO_SDIO0_PAD_CCMD_OUT,
++ GPO_SDIO0_PAD_CCMD_OEN,
++ GPI_SDIO0_PAD_CCMD_IN)>,
++ <GPIOMUX(49,
++ GPO_SDIO0_PAD_CDATA_OUT_BIT0,
++ GPO_SDIO0_PAD_CDATA_OEN_BIT0,
++ GPI_SDIO0_PAD_CDATA_IN_BIT0)>,
++ <GPIOMUX(50,
++ GPO_SDIO0_PAD_CDATA_OUT_BIT1,
++ GPO_SDIO0_PAD_CDATA_OEN_BIT1,
++ GPI_SDIO0_PAD_CDATA_IN_BIT1)>,
++ <GPIOMUX(51,
++ GPO_SDIO0_PAD_CDATA_OUT_BIT2,
++ GPO_SDIO0_PAD_CDATA_OEN_BIT2,
++ GPI_SDIO0_PAD_CDATA_IN_BIT2)>,
++ <GPIOMUX(52,
++ GPO_SDIO0_PAD_CDATA_OUT_BIT3,
++ GPO_SDIO0_PAD_CDATA_OEN_BIT3,
++ GPI_SDIO0_PAD_CDATA_IN_BIT3)>;
++ bias-pull-up;
++ input-enable;
++ input-schmitt-enable;
++ };
++ };
++
++ sdio1_pins: sdio1-0 {
++ clk-pins {
++ pinmux = <GPIOMUX(33, GPO_SDIO1_PAD_CCLK_OUT,
++ GPO_ENABLE, GPI_NONE)>;
++ bias-disable;
++ input-disable;
++ input-schmitt-disable;
++ };
++ sdio-pins {
++ pinmux = <GPIOMUX(29,
++ GPO_SDIO1_PAD_CCMD_OUT,
++ GPO_SDIO1_PAD_CCMD_OEN,
++ GPI_SDIO1_PAD_CCMD_IN)>,
++ <GPIOMUX(36,
++ GPO_SDIO1_PAD_CDATA_OUT_BIT0,
++ GPO_SDIO1_PAD_CDATA_OEN_BIT0,
++ GPI_SDIO1_PAD_CDATA_IN_BIT0)>,
++ <GPIOMUX(30,
++ GPO_SDIO1_PAD_CDATA_OUT_BIT1,
++ GPO_SDIO1_PAD_CDATA_OEN_BIT1,
++ GPI_SDIO1_PAD_CDATA_IN_BIT1)>,
++ <GPIOMUX(34,
++ GPO_SDIO1_PAD_CDATA_OUT_BIT2,
++ GPO_SDIO1_PAD_CDATA_OEN_BIT2,
++ GPI_SDIO1_PAD_CDATA_IN_BIT2)>,
++ <GPIOMUX(31,
++ GPO_SDIO1_PAD_CDATA_OUT_BIT3,
++ GPO_SDIO1_PAD_CDATA_OEN_BIT3,
++ GPI_SDIO1_PAD_CDATA_IN_BIT3)>;
++ bias-pull-up;
++ input-enable;
++ input-schmitt-enable;
++ };
++ };
++
++ spi2_pins: spi2-0 {
++ mosi-pins {
++ pinmux = <GPIOMUX(18, GPO_SPI2_PAD_TXD,
++ GPO_ENABLE, GPI_NONE)>;
++ bias-disable;
++ input-disable;
++ input-schmitt-disable;
++ };
++ miso-pins {
++ pinmux = <GPIOMUX(16, GPO_LOW, GPO_DISABLE,
++ GPI_SPI2_PAD_RXD)>;
++ bias-pull-up;
++ input-enable;
++ input-schmitt-enable;
++ };
++ sck-pins {
++ pinmux = <GPIOMUX(12, GPO_SPI2_PAD_SCK_OUT,
++ GPO_ENABLE, GPI_NONE)>;
++ bias-disable;
++ input-disable;
++ input-schmitt-disable;
++ };
++ ss-pins {
++ pinmux = <GPIOMUX(15, GPO_SPI2_PAD_SS_0_N,
++ GPO_ENABLE, GPI_NONE)>,
++ <GPIOMUX(11, GPO_SPI2_PAD_SS_1_N,
++ GPO_ENABLE, GPI_NONE)>;
++ bias-disable;
++ input-disable;
++ input-schmitt-disable;
++ };
++ };
++
++ uart0_pins: uart0-0 {
++ rx-pins {
++ pinmux = <GPIOMUX(40, GPO_LOW, GPO_DISABLE,
++ GPI_UART0_PAD_SIN)>,
++ <GPIOMUX(39, GPO_LOW, GPO_DISABLE,
++ GPI_UART0_PAD_CTSN)>;
++ bias-pull-up;
++ drive-strength = <14>;
++ input-enable;
++ input-schmitt-enable;
++ };
++ tx-pins {
++ pinmux = <GPIOMUX(41, GPO_UART0_PAD_SOUT,
++ GPO_ENABLE, GPI_NONE)>,
++ <GPIOMUX(42, GPO_UART0_PAD_RTSN,
++ GPO_ENABLE, GPI_NONE)>;
++ bias-disable;
++ drive-strength = <35>;
++ input-disable;
++ input-schmitt-disable;
++ };
++ };
++
+ uart3_pins: uart3-0 {
+ rx-pins {
+ pinmux = <GPIOMUX(13, GPO_LOW, GPO_DISABLE,
+@@ -124,6 +444,17 @@
+ regulators {
+ };
+ };
++
++ tda998x@70 {
++ compatible = "nxp,tda998x";
++ reg = <0x70>;
++
++ port {
++ tda998x_0_input: endpoint {
++ remote-endpoint = <&hdmi_out>;
++ };
++ };
++ };
+ };
+
+ &i2c1 {
+@@ -154,8 +485,103 @@
+ clock-frequency = <27000000>;
+ };
+
++&ptc {
++ pinctrl-names = "default";
++ pinctrl-0 = <&pwm_pins>;
++ status = "okay";
++};
++
++&pwmdac {
++ pinctrl-names = "default";
++ pinctrl-0 = <&pwmdac_pins>;
++ status = "okay";
++};
++
++&qspi {
++ nor_flash: nor-flash@0 {
++ compatible = "spi-flash";
++ reg = <0>;
++ spi-max-frequency = <31250000>;
++ page-size = <256>;
++ block-size = <16>;
++ cdns,read-delay = <4>;
++ cdns,tshsl-ns = <1>;
++ cdns,tsd2d-ns = <1>;
++ cdns,tchsh-ns = <1>;
++ cdns,tslch-ns = <1>;
++ spi-tx-bus-width = <1>;
++ spi-rx-bus-width = <1>;
++ };
++
++ nand_flash: nand-flash@1 {
++ compatible = "spi-flash-nand";
++ reg = <1>;
++ spi-max-frequency = <31250000>;
++ page-size = <2048>;
++ block-size = <17>;
++ cdns,read-delay = <4>;
++ cdns,tshsl-ns = <1>;
++ cdns,tsd2d-ns = <1>;
++ cdns,tchsh-ns = <1>;
++ cdns,tslch-ns = <1>;
++ spi-tx-bus-width = <1>;
++ spi-rx-bus-width = <1>;
++ };
++};
++
++&sdio0 {
++ broken-cd;
++ bus-width = <4>;
++ cap-sd-highspeed;
++ pinctrl-names = "default";
++ pinctrl-0 = <&sdio0_pins>;
++ status = "okay";
++};
++
++&sdio1 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ bus-width = <4>;
++ cap-sd-highspeed;
++ cap-sdio-irq;
++ cap-power-off-card;
++ mmc-pwrseq = <&wifi_pwrseq>;
++ non-removable;
++ pinctrl-names = "default";
++ pinctrl-0 = <&sdio1_pins>;
++ status = "okay";
++
++ wifi@1 {
++ compatible = "brcm,bcm4329-fmac";
++ reg = <1>;
++ };
++};
++
++&spi2 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&spi2_pins>;
++ status = "okay";
++
++ spi_dev0: spi@0 {
++ compatible = "rohm,dh2228fv";
++ spi-max-frequency = <10000000>;
++ reg = <0>;
++ };
++};
++
++&uart0 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&uart0_pins>;
++ status = "okay";
++};
++
+ &uart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart3_pins>;
+ status = "okay";
+ };
++
++&usb3 {
++ dr_mode = "host";
++ status = "okay";
++};
+diff --git a/arch/riscv/boot/dts/starfive/jh7100-starfive-visionfive-v1.dts b/arch/riscv/boot/dts/starfive/jh7100-starfive-visionfive-v1.dts
+index e82af72f1aaf..b73bacb0a6f1 100644
+--- a/arch/riscv/boot/dts/starfive/jh7100-starfive-visionfive-v1.dts
++++ b/arch/riscv/boot/dts/starfive/jh7100-starfive-visionfive-v1.dts
+@@ -18,3 +18,16 @@
+ priority = <224>;
+ };
+ };
++
++&gpio {
++ /* don't reset gpio mux for serial console and reset gpio */
++ starfive,keep-gpiomux = <13 14 63>;
++};
++
++&i2c0 {
++ eeprom@50 {
++ compatible = "atmel,24c04";
++ reg = <0x50>;
++ pagesize = <16>;
++ };
++};
+diff --git a/arch/riscv/boot/dts/starfive/jh7100.dtsi b/arch/riscv/boot/dts/starfive/jh7100.dtsi
+index 2c67f7344cbe..c67688aaaebd 100644
+--- a/arch/riscv/boot/dts/starfive/jh7100.dtsi
++++ b/arch/riscv/boot/dts/starfive/jh7100.dtsi
+@@ -6,7 +6,9 @@
+
+ /dts-v1/;
+ #include <dt-bindings/clock/starfive-jh7100.h>
++#include <dt-bindings/clock/starfive-jh7100-audio.h>
+ #include <dt-bindings/reset/starfive-jh7100.h>
++#include <dt-bindings/reset/starfive-jh7100-audio.h>
+
+ / {
+ compatible = "starfive,jh7100";
+@@ -32,7 +34,9 @@
+ i-tlb-sets = <1>;
+ i-tlb-size = <32>;
+ mmu-type = "riscv,sv39";
++ next-level-cache = <&ccache>;
+ riscv,isa = "rv64imafdc";
++ starfive,itim = <&itim0>;
+ tlb-split;
+
+ cpu0_intc: interrupt-controller {
+@@ -57,7 +61,9 @@
+ i-tlb-sets = <1>;
+ i-tlb-size = <32>;
+ mmu-type = "riscv,sv39";
++ next-level-cache = <&ccache>;
+ riscv,isa = "rv64imafdc";
++ starfive,itim = <&itim1>;
+ tlb-split;
+
+ cpu1_intc: interrupt-controller {
+@@ -116,6 +122,24 @@
+ #size-cells = <2>;
+ ranges;
+
++ dtim: dtim@1000000 {
++ compatible = "starfive,dtim0";
++ reg = <0x0 0x1000000 0x0 0x2000>;
++ reg-names = "mem";
++ };
++
++ itim0: itim@1808000 {
++ compatible = "starfive,itim0";
++ reg = <0x0 0x1808000 0x0 0x8000>;
++ reg-names = "mem";
++ };
++
++ itim1: itim@1820000 {
++ compatible = "starfive,itim0";
++ reg = <0x0 0x1820000 0x0 0x8000>;
++ reg-names = "mem";
++ };
++
+ clint: clint@2000000 {
+ compatible = "starfive,jh7100-clint", "sifive,clint0";
+ reg = <0x0 0x2000000 0x0 0x10000>;
+@@ -123,6 +147,21 @@
+ <&cpu1_intc 3>, <&cpu1_intc 7>;
+ };
+
++ ccache: cache-controller@2010000 {
++ compatible = "starfive,jh7100-ccache", "cache";
++ reg = <0x0 0x2010000 0x0 0x1000>,
++ <0x0 0x8000000 0x0 0x2000000>;
++ reg-names = "control", "sideband";
++ interrupts = <128>, <130>, <131>, <129>;
++ cache-block-size = <64>;
++ cache-level = <2>;
++ cache-sets = <2048>;
++ cache-size = <2097152>;
++ cache-unified;
++ /*next-level-cache = <&L40 &L36>;*/
++ uncached-offset = <0xf 0x80000000>;
++ };
++
+ plic: interrupt-controller@c000000 {
+ compatible = "starfive,jh7100-plic", "sifive,plic-1.0.0";
+ reg = <0x0 0xc000000 0x0 0x4000000>;
+@@ -134,6 +173,182 @@
+ riscv,ndev = <133>;
+ };
+
++ sdio0: mmc@10000000 {
++ compatible = "snps,dw-mshc";
++ reg = <0x0 0x10000000 0x0 0x10000>;
++ clocks = <&clkgen JH7100_CLK_SDIO0_AHB>,
++ <&clkgen JH7100_CLK_SDIO0_CCLKINT_INV>;
++ clock-names = "biu", "ciu";
++ interrupts = <4>;
++ data-addr = <0>;
++ fifo-depth = <32>;
++ fifo-watermark-aligned;
++ status = "disabled";
++ };
++
++ sdio1: mmc@10010000 {
++ compatible = "snps,dw-mshc";
++ reg = <0x0 0x10010000 0x0 0x10000>;
++ clocks = <&clkgen JH7100_CLK_SDIO1_AHB>,
++ <&clkgen JH7100_CLK_SDIO1_CCLKINT_INV>;
++ clock-names = "biu", "ciu";
++ interrupts = <5>;
++ data-addr = <0>;
++ fifo-depth = <32>;
++ fifo-watermark-aligned;
++ status = "disabled";
++ };
++
++ /* gmac device configuration */
++ stmmac_axi_setup: stmmac-axi-config {
++ snps,wr_osr_lmt = <0xf>;
++ snps,rd_osr_lmt = <0xf>;
++ snps,blen = <256 128 64 32 0 0 0>;
++ };
++
++ gmac: ethernet@10020000 {
++ compatible = "starfive,jh7100-gmac", "snps,dwmac";
++ reg = <0x0 0x10020000 0x0 0x10000>;
++ clocks = <&clkgen JH7100_CLK_GMAC_ROOT_DIV>,
++ <&clkgen JH7100_CLK_GMAC_AHB>,
++ <&clkgen JH7100_CLK_GMAC_PTP_REF>,
++ <&clkgen JH7100_CLK_GMAC_GTX>,
++ <&clkgen JH7100_CLK_GMAC_TX_INV>;
++ clock-names = "stmmaceth", "pclk", "ptp_ref", "gtxc", "tx";
++ resets = <&rstgen JH7100_RSTN_GMAC_AHB>;
++ reset-names = "ahb";
++ interrupts = <6>, <7>;
++ interrupt-names = "macirq", "eth_wake_irq";
++ max-frame-size = <9000>;
++ phy-mode = "rgmii-txid";
++ snps,multicast-filter-bins = <32>;
++ snps,perfect-filter-entries = <128>;
++ starfive,syscon = <&sysmain>;
++ rx-fifo-depth = <32768>;
++ tx-fifo-depth = <16384>;
++ snps,axi-config = <&stmmac_axi_setup>;
++ snps,fixed-burst;
++ /*snps,force_sf_dma_mode;*/
++ snps,force_thresh_dma_mode;
++ snps,no-pbl-x8;
++ status = "disabled";
++ };
++
++ dma2p: dma-controller@100b0000 {
++ compatible = "snps,axi-dma-1.01a";
++ reg = <0x0 0x100b0000 0x0 0x10000>;
++ clocks = <&clkgen JH7100_CLK_SGDMA2P_AXI>,
++ <&clkgen JH7100_CLK_SGDMA2P_AHB>;
++ clock-names = "core-clk", "cfgr-clk";
++ interrupts = <2>;
++ #dma-cells = <1>;
++ dma-channels = <4>;
++ snps,dma-masters = <1>;
++ snps,data-width = <4>;
++ snps,block-size = <4096 4096 4096 4096>;
++ snps,priority = <0 1 2 3>;
++ snps,axi-max-burst-len = <128>;
++ dma-coherent;
++ };
++
++ crypto: crypto@100d0000 {
++ compatible = "starfive,vic-sec";
++ reg = <0x0 0x100d0000 0x0 0x20000>,
++ <0x0 0x11800234 0x0 0xc>;
++ reg-names = "secmem", "secclk";
++ clocks = <&clkgen JH7100_CLK_SEC_AHB>;
++ interrupts = <31>;
++ };
++
++ i2sadc0: i2sadc0@10400000 {
++ compatible = "snps,designware-i2sadc0";
++ reg = <0x0 0x10400000 0x0 0x1000>;
++ clocks = <&clkgen JH7100_CLK_APB1_BUS>;
++ clock-names = "i2sclk";
++ interrupt-parent = <&plic>;
++ #sound-dai-cells = <0>;
++ dmas = <&dma2p 28>;
++ dma-names = "rx";
++ };
++
++ i2svad: i2svad@10420000 {
++ compatible = "starfive,sf-i2svad";
++ reg = <0x0 0x10420000 0x0 0x1000> ;
++ clocks = <&audclk JH7100_AUDCLK_I2SVAD_APB>;
++ clock-names = "i2svad_apb";
++ resets = <&audrst JH7100_AUDRSTN_I2SVAD_APB>,
++ <&audrst JH7100_AUDRSTN_I2SVAD_SRST>;
++ reset-names = "apb_i2svad", "i2svad_srst";
++ interrupts = <60>, <61>;
++ interrupt-names = "spintr", "slintr";
++ #sound-dai-cells = <0>;
++ };
++
++ pwmdac: pwmdac@10440000 {
++ compatible = "starfive,pwmdac";
++ reg = <0x0 0x10440000 0x0 0x1000>;
++ clocks = <&clkgen JH7100_CLK_AUDIO_ROOT>,
++ <&clkgen JH7100_CLK_AUDIO_SRC>,
++ <&clkgen JH7100_CLK_AUDIO_12288>,
++ <&audclk JH7100_AUDCLK_DMA1P_AHB>,
++ <&audclk JH7100_AUDCLK_PWMDAC_APB>,
++ <&audclk JH7100_AUDCLK_DAC_MCLK>;
++ clock-names = "audio_root",
++ "audio_src",
++ "audio_12288",
++ "dma1p_ahb",
++ "pwmdac_apb",
++ "dac_mclk";
++ resets = <&audrst JH7100_AUDRSTN_APB_BUS>,
++ <&audrst JH7100_AUDRSTN_DMA1P_AHB>,
++ <&audrst JH7100_AUDRSTN_PWMDAC_APB>;
++ reset-names = "apb_bus", "dma1p_ahb", "apb_pwmdac";
++ dmas = <&dma2p 23>;
++ dma-names = "tx";
++ #sound-dai-cells = <0>;
++ };
++
++ i2sdac0: i2sdac0@10450000 {
++ compatible = "snps,designware-i2sdac0";
++ reg = <0x0 0x10450000 0x0 0x1000>;
++ clocks = <&audclk JH7100_AUDCLK_DAC_MCLK>,
++ <&audclk JH7100_AUDCLK_I2SDAC_BCLK>,
++ <&audclk JH7100_AUDCLK_I2SDAC_LRCLK>,
++ <&audclk JH7100_AUDCLK_I2SDAC_APB>;
++ clock-names = "dac_mclk", "i2sdac0_bclk", "i2sdac0_lrclk", "i2sdac_apb";
++ resets = <&audrst JH7100_AUDRSTN_I2SDAC_APB>,
++ <&audrst JH7100_AUDRSTN_I2SDAC_SRST>;
++ reset-names = "apb_i2sdac", "i2sdac_srst";
++ #sound-dai-cells = <0>;
++ dmas = <&dma2p 30>;
++ dma-names = "tx";
++ };
++
++ i2sdac1: i2sdac1@10460000 {
++ compatible = "snps,designware-i2sdac1";
++ reg = <0x0 0x10460000 0x0 0x1000>;
++ clocks = <&audclk JH7100_AUDCLK_DAC_MCLK>,
++ <&audclk JH7100_AUDCLK_I2S1_BCLK>,
++ <&audclk JH7100_AUDCLK_I2S1_LRCLK>,
++ <&audclk JH7100_AUDCLK_I2S1_APB>;
++ clock-names = "dac_mclk", "i2sdac1_bclk", "i2sdac1_lrclk", "i2s1_apb";
++ resets = <&audrst JH7100_AUDRSTN_I2S1_APB>,
++ <&audrst JH7100_AUDRSTN_I2S1_SRST>;
++ #sound-dai-cells = <0>;
++ dmas = <&dma2p 31>;
++ dma-names = "tx";
++ };
++
++ i2sdac16k: i2sdac16k@10470000 {
++ compatible = "snps,designware-i2sdac16k";
++ reg = <0x0 0x10470000 0x0 0x1000>;
++ clocks = <&clkgen JH7100_CLK_APB1_BUS>;
++ clock-names = "i2sclk";
++ #sound-dai-cells = <0>;
++ dmas = <&dma2p 29>;
++ dma-names = "tx";
++ };
++
+ audclk: clock-controller@10480000 {
+ compatible = "starfive,jh7100-audclk";
+ reg = <0x0 0x10480000 0x0 0x10000>;
+@@ -144,6 +359,79 @@
+ #clock-cells = <1>;
+ };
+
++ spdif_transmitter: spdif-transmitter {
++ compatible = "linux,spdif-dit";
++ #sound-dai-cells = <0>;
++ };
++
++ spdif_receiver: spdif-receiver {
++ compatible = "linux,spdif-dir";
++ #sound-dai-cells = <0>;
++ };
++
++ pwmdac_codec: pwmdac-transmitter {
++ compatible = "linux,pwmdac-dit";
++ #sound-dai-cells = <0>;
++ };
++
++ dmic_codec: dmic {
++ compatible = "dmic-codec";
++ #sound-dai-cells = <0>;
++ };
++
++ sound: snd-card {
++ compatible = "simple-audio-card";
++ simple-audio-card,name = "Starfive-Multi-Sound-Card";
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ /* pwmdac */
++ simple-audio-card,dai-link@0 {
++ reg = <0>;
++ status = "okay";
++ format = "left_j";
++ bitclock-master = <&sndcpu0>;
++ frame-master = <&sndcpu0>;
++
++ sndcpu0: cpu {
++ sound-dai = <&pwmdac>;
++ };
++
++ codec {
++ sound-dai = <&pwmdac_codec>;
++ };
++ };
++ };
++
++ usb3: usb@104c0000 {
++ compatible = "cdns,usb3";
++ reg = <0x0 0x104c0000 0x0 0x10000>, // memory area for HOST registers
++ <0x0 0x104d0000 0x0 0x10000>, // memory area for DEVICE registers
++ <0x0 0x104e0000 0x0 0x10000>; // memory area for OTG/DRD registers
++ reg-names = "otg", "xhci", "dev";
++ interrupts = <44>, <52>, <43>;
++ interrupt-names = "host", "peripheral", "otg";
++ phy-names = "cdns3,usb3-phy", "cdns3,usb2-phy";
++ maximum-speed = "super-speed";
++ status = "disabled";
++ };
++
++ dma1p: dma-controller@10500000 {
++ compatible = "snps,axi-dma-1.01a";
++ reg = <0x0 0x10500000 0x0 0x10000>;
++ clocks = <&clkgen JH7100_CLK_SGDMA1P_AXI>,
++ <&clkgen JH7100_CLK_SGDMA1P_BUS>;
++ clock-names = "core-clk", "cfgr-clk";
++ interrupts = <1>;
++ #dma-cells = <1>;
++ dma-channels = <16>;
++ snps,dma-masters = <1>;
++ snps,data-width = <3>;
++ snps,block-size = <4096 4096 4096 4096 4096 4096 4096 4096 4096 4096 4096 4096 4096 4096 4096 4096>;
++ snps,priority = <0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15>;
++ snps,axi-max-burst-len = <64>;
++ };
++
+ clkgen: clock-controller@11800000 {
+ compatible = "starfive,jh7100-clkgen";
+ reg = <0x0 0x11800000 0x0 0x10000>;
+@@ -152,12 +440,93 @@
+ #clock-cells = <1>;
+ };
+
++ otp: otp@11810000 {
++ compatible = "starfive,fu740-otp";
++ reg = <0x0 0x11810000 0x0 0x10000>;
++ clocks = <&clkgen JH7100_CLK_OTP_APB>;
++ fuse-count = <0x200>;
++ };
++
+ rstgen: reset-controller@11840000 {
+ compatible = "starfive,jh7100-reset";
+ reg = <0x0 0x11840000 0x0 0x10000>;
+ #reset-cells = <1>;
+ };
+
++ sysmain: syscon@11850000 {
++ compatible = "starfive,jh7100-sysmain", "syscon";
++ reg = <0x0 0x11850000 0x0 0x10000>;
++ };
++
++ qspi: spi@11860000 {
++ compatible = "cdns,qspi-nor";
++ reg = <0x0 0x11860000 0x0 0x10000>,
++ <0x0 0x20000000 0x0 0x20000000>;
++ clocks = <&clkgen JH7100_CLK_QSPI_AHB>;
++ interrupts = <3>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ cdns,fifo-depth = <256>;
++ cdns,fifo-width = <4>;
++ cdns,trigger-address = <0x0>;
++ spi-max-frequency = <250000000>;
++ status = "disabled";
++ };
++
++ uart0: serial@11870000 {
++ compatible = "starfive,jh7100-hsuart", "snps,dw-apb-uart";
++ reg = <0x0 0x11870000 0x0 0x10000>;
++ clocks = <&clkgen JH7100_CLK_UART0_CORE>,
++ <&clkgen JH7100_CLK_UART0_APB>;
++ clock-names = "baudclk", "apb_pclk";
++ resets = <&rstgen JH7100_RSTN_UART0_APB>;
++ interrupts = <92>;
++ reg-io-width = <4>;
++ reg-shift = <2>;
++ status = "disabled";
++ };
++
++ uart1: serial@11880000 {
++ compatible = "starfive,jh7100-hsuart", "snps,dw-apb-uart";
++ reg = <0x0 0x11880000 0x0 0x10000>;
++ clocks = <&clkgen JH7100_CLK_UART1_CORE>,
++ <&clkgen JH7100_CLK_UART1_APB>;
++ clock-names = "baudclk", "apb_pclk";
++ resets = <&rstgen JH7100_RSTN_UART1_APB>;
++ interrupts = <93>;
++ reg-io-width = <4>;
++ reg-shift = <2>;
++ status = "disabled";
++ };
++
++ spi0: spi@11890000 {
++ compatible = "snps,dw-apb-ssi";
++ reg = <0x0 0x11890000 0x0 0x10000>;
++ clocks = <&clkgen JH7100_CLK_SPI0_CORE>,
++ <&clkgen JH7100_CLK_SPI0_APB>;
++ clock-names = "ssi_clk", "pclk";
++ resets = <&rstgen JH7100_RSTN_SPI0_APB>;
++ reset-names = "spi";
++ interrupts = <94>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ spi1: spi@118a0000 {
++ compatible = "snps,dw-apb-ssi";
++ reg = <0x0 0x118a0000 0x0 0x10000>;
++ clocks = <&clkgen JH7100_CLK_SPI1_CORE>,
++ <&clkgen JH7100_CLK_SPI1_APB>;
++ clock-names = "ssi_clk", "pclk";
++ resets = <&rstgen JH7100_RSTN_SPI1_APB>;
++ reset-names = "spi";
++ interrupts = <95>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
+ i2c0: i2c@118b0000 {
+ compatible = "snps,designware-i2c";
+ reg = <0x0 0x118b0000 0x0 0x10000>;
+@@ -184,6 +553,41 @@
+ status = "disabled";
+ };
+
++ trng: trng@118d0000 {
++ compatible = "starfive,vic-rng";
++ reg = <0x0 0x118d0000 0x0 0x10000>;
++ clocks = <&clkgen JH7100_CLK_TRNG_APB>;
++ interrupts = <98>;
++ };
++
++ vpu_enc: vpu_enc@118e0000 {
++ compatible = "cm,cm521-vpu";
++ reg = <0x0 0x118e0000 0x0 0x4000>;
++ reg-names = "control";
++ clocks = <&clkgen JH7100_CLK_VP6_CORE>;
++ clock-names = "vcodec";
++ interrupts = <26>;
++ };
++
++ vpu_dec: vpu_dec@118f0000 {
++ compatible = "c&m,cm511-vpu";
++ reg = <0 0x118f0000 0 0x10000>;
++ clocks = <&clkgen JH7100_CLK_VP6_CORE>;
++ clock-names = "vcodec";
++ interrupts = <23>;
++ //memory-region = <&vpu_reserved>;
++ };
++
++ jpu: coadj12@11900000 {
++ compatible = "cm,codaj12-jpu-1";
++ reg = <0x0 0x11900000 0x0 0x300>;
++ reg-names = "control";
++ clocks = <&clkgen JH7100_CLK_JPEG_APB>;
++ clock-names = "jpege";
++ interrupts = <24>;
++ memory-region = <&jpu_reserved>;
++ };
++
+ gpio: pinctrl@11910000 {
+ compatible = "starfive,jh7100-pinctrl";
+ reg = <0x0 0x11910000 0x0 0x10000>,
+@@ -198,6 +602,86 @@
+ #interrupt-cells = <2>;
+ };
+
++ nvdla@11940000 {
++ compatible = "nvidia,nvdla_os_initial";
++ interrupts = <22>;
++ memory-region = <&nvdla_reserved>;
++ reg = <0x0 0x11940000 0x0 0x40000>;
++ status = "okay";
++ };
++
++ display: display-subsystem {
++ compatible = "starfive,display-subsystem";
++ dma-coherent;
++ status = "disabled";
++ };
++
++ encoder: display-encoder {
++ compatible = "starfive,display-encoder";
++ status = "disabled";
++ };
++
++ crtc: crtc@12000000 {
++ compatible = "starfive,jh7100-crtc";
++ reg = <0x0 0x12000000 0x0 0x10000>,
++ <0x0 0x12040000 0x0 0x10000>,
++ <0x0 0x12080000 0x0 0x10000>,
++ <0x0 0x120c0000 0x0 0x10000>,
++ <0x0 0x12240000 0x0 0x10000>,
++ <0x0 0x12250000 0x0 0x10000>,
++ <0x0 0x12260000 0x0 0x10000>;
++ reg-names = "lcdc", "vpp0", "vpp1", "vpp2", "clk", "rst", "sys";
++ clocks = <&clkgen JH7100_CLK_DISP_AXI>, <&clkgen JH7100_CLK_VOUT_SRC>;
++ clock-names = "disp_axi", "vout_src";
++ resets = <&rstgen JH7100_RSTN_DISP_AXI>, <&rstgen JH7100_RSTN_VOUT_SRC>;
++ reset-names = "disp_axi", "vout_src";
++ interrupts = <101>, <103>;
++ interrupt-names = "lcdc_irq", "vpp1_irq";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++
++ pp1 {
++ pp-id = <1>;
++ fifo-out;
++ //sys-bus-out;
++ src-format = <11>; //<COLOR_RGB565>;
++ src-width = <1920>;
++ src-height = <1080>;
++ dst-format = <7>; //<COLOR_RGB888_ARGB>;
++ dst-width = <1920>;
++ dst-height = <1080>;
++ };
++ };
++
++ spi2: spi@12410000 {
++ compatible = "snps,dw-apb-ssi";
++ reg = <0x0 0x12410000 0x0 0x10000>;
++ clocks = <&clkgen JH7100_CLK_SPI2_CORE>,
++ <&clkgen JH7100_CLK_SPI2_APB>;
++ clock-names = "ssi_clk", "pclk";
++ resets = <&rstgen JH7100_RSTN_SPI2_APB>;
++ reset-names = "spi";
++ interrupts = <70>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ spi3: spi@12420000 {
++ compatible = "snps,dw-apb-ssi";
++ reg = <0x0 0x12420000 0x0 0x10000>;
++ clocks = <&clkgen JH7100_CLK_SPI3_CORE>,
++ <&clkgen JH7100_CLK_SPI3_APB>;
++ clock-names = "ssi_clk", "pclk";
++ resets = <&rstgen JH7100_RSTN_SPI3_APB>;
++ reset-names = "spi";
++ interrupts = <71>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
+ uart2: serial@12430000 {
+ compatible = "starfive,jh7100-uart", "snps,dw-apb-uart";
+ reg = <0x0 0x12430000 0x0 0x10000>;
+@@ -259,5 +743,89 @@
+ resets = <&rstgen JH7100_RSTN_WDTIMER_APB>,
+ <&rstgen JH7100_RSTN_WDT>;
+ };
++
++ watchdog@12480000 {
++ compatible = "starfive,si5-wdt";
++ reg = <0x0 0x12480000 0x0 0x10000>;
++ clocks = <&clkgen JH7100_CLK_WDT_CORE>,
++ <&clkgen JH7100_CLK_WDTIMER_APB>;
++ clock-names = "wdt_coreclk", "wdtimer_apb";
++ resets = <&rstgen JH7100_RSTN_WDTIMER_APB>,
++ <&rstgen JH7100_RSTN_WDT>;
++ reset-names = "wdtimer_apb", "wdt";
++ interrupts = <80>;
++ };
++
++ ptc: pwm@12490000 {
++ compatible = "starfive,pwm0";
++ reg = <0x0 0x12490000 0x0 0x10000>;
++ clocks = <&clkgen JH7100_CLK_PWM_APB>;
++ resets = <&rstgen JH7100_RSTN_PWM_APB>;
++ #pwm-cells = <3>;
++ sifive,npwm = <8>;
++ status = "disabled";
++ };
++
++ sfctemp: tmon@124a0000 {
++ compatible = "starfive,jh7100-temp";
++ reg = <0x0 0x124a0000 0x0 0x10000>;
++ clocks = <&clkgen JH7100_CLK_TEMP_SENSE>,
++ <&clkgen JH7100_CLK_TEMP_APB>;
++ clock-names = "sense", "bus";
++ resets = <&rstgen JH7100_RSTN_TEMP_SENSE>,
++ <&rstgen JH7100_RSTN_TEMP_APB>;
++ reset-names = "sense", "bus";
++ interrupts = <122>;
++ #thermal-sensor-cells = <0>;
++ };
++
++ thermal-zones {
++ cpu-thermal {
++ polling-delay-passive = <250>;
++ polling-delay = <15000>;
++
++ thermal-sensors = <&sfctemp>;
++
++ cooling-maps {
++ };
++
++ trips {
++ cpu_alert0: cpu_alert0 {
++ /* milliCelsius */
++ temperature = <75000>;
++ hysteresis = <2000>;
++ type = "passive";
++ };
++
++ cpu_crit: cpu_crit {
++ /* milliCelsius */
++ temperature = <90000>;
++ hysteresis = <2000>;
++ type = "critical";
++ };
++ };
++ };
++ };
++
++ xrp@f0000000 {
++ compatible = "cdns,xrp";
++ reg = <0x0 0xf0000000 0x0 0x01ffffff>,
++ <0x10 0x72000000 0x0 0x00001000>,
++ <0x10 0x72001000 0x0 0x00fff000>,
++ <0x0 0x124b0000 0x0 0x00010000>;
++ clocks = <&clkgen JH7100_CLK_VP6_CORE>;
++ interrupts = <27>, <28>;
++ firmware-name = "vp6_elf";
++ dsp-irq = <19 20>;
++ dsp-irq-src = <0x20 0x21>;
++ intc-irq-mode = <1>;
++ intc-irq = <0 1>;
++ #address-cells = <1>;
++ #size-cells = <1>;
++ ranges = <0x40000000 0x0 0x40000000 0x01000000>,
++ <0xb0000000 0x10 0x70000000 0x3000000>;
++ dsp@0 {
++ };
++ };
+ };
+ };
+--
+2.20.1
+
--- /dev/null
+From ac919b7da7cdc1246990138a1bad3f087cd7cdcd Mon Sep 17 00:00:00 2001
+From: Zoltan HERPAI <wigyori@uid0.hu>
+Date: Tue, 30 May 2023 00:24:18 +0200
+Subject: [PATCH 121/121] dts/6.1: jh7100: fixups, remove audio blocks
+
+Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>
+---
+ .../riscv/boot/dts/starfive/jh7100-common.dtsi | 4 ++--
+ arch/riscv/boot/dts/starfive/jh7100.dtsi | 18 +++++++++---------
+ 2 files changed, 11 insertions(+), 11 deletions(-)
+
+diff --git a/arch/riscv/boot/dts/starfive/jh7100-common.dtsi b/arch/riscv/boot/dts/starfive/jh7100-common.dtsi
+index 1a36da546137..c39ef1f8c1aa 100644
+--- a/arch/riscv/boot/dts/starfive/jh7100-common.dtsi
++++ b/arch/riscv/boot/dts/starfive/jh7100-common.dtsi
+@@ -491,11 +491,11 @@
+ status = "okay";
+ };
+
+-&pwmdac {
++/*&pwmdac {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwmdac_pins>;
+ status = "okay";
+-};
++};*/
+
+ &qspi {
+ nor_flash: nor-flash@0 {
+diff --git a/arch/riscv/boot/dts/starfive/jh7100.dtsi b/arch/riscv/boot/dts/starfive/jh7100.dtsi
+index c67688aaaebd..8c52b3ad05c4 100644
+--- a/arch/riscv/boot/dts/starfive/jh7100.dtsi
++++ b/arch/riscv/boot/dts/starfive/jh7100.dtsi
+@@ -6,9 +6,9 @@
+
+ /dts-v1/;
+ #include <dt-bindings/clock/starfive-jh7100.h>
+-#include <dt-bindings/clock/starfive-jh7100-audio.h>
++//#include <dt-bindings/clock/starfive-jh7100-audio.h>
+ #include <dt-bindings/reset/starfive-jh7100.h>
+-#include <dt-bindings/reset/starfive-jh7100-audio.h>
++//#include <dt-bindings/reset/starfive-jh7100-audio.h>
+
+ / {
+ compatible = "starfive,jh7100";
+@@ -271,7 +271,7 @@
+ dma-names = "rx";
+ };
+
+- i2svad: i2svad@10420000 {
++/* i2svad: i2svad@10420000 {
+ compatible = "starfive,sf-i2svad";
+ reg = <0x0 0x10420000 0x0 0x1000> ;
+ clocks = <&audclk JH7100_AUDCLK_I2SVAD_APB>;
+@@ -358,7 +358,7 @@
+ clock-names = "audio_src", "audio_12288", "dom7ahb_bus";
+ #clock-cells = <1>;
+ };
+-
++*/
+ spdif_transmitter: spdif-transmitter {
+ compatible = "linux,spdif-dit";
+ #sound-dai-cells = <0>;
+@@ -379,14 +379,14 @@
+ #sound-dai-cells = <0>;
+ };
+
+- sound: snd-card {
++/* sound: snd-card {
+ compatible = "simple-audio-card";
+ simple-audio-card,name = "Starfive-Multi-Sound-Card";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ /* pwmdac */
+- simple-audio-card,dai-link@0 {
++/* simple-audio-card,dai-link@0 {
+ reg = <0>;
+ status = "okay";
+ format = "left_j";
+@@ -402,7 +402,7 @@
+ };
+ };
+ };
+-
++*/
+ usb3: usb@104c0000 {
+ compatible = "cdns,usb3";
+ reg = <0x0 0x104c0000 0x0 0x10000>, // memory area for HOST registers
+@@ -734,7 +734,7 @@
+ status = "disabled";
+ };
+
+- watchdog@12480000 {
++/* watchdog@12480000 {
+ compatible = "starfive,jh7100-wdt";
+ reg = <0x0 0x12480000 0x0 0x10000>;
+ clocks = <&clkgen JH7100_CLK_WDTIMER_APB>,
+@@ -743,7 +743,7 @@
+ resets = <&rstgen JH7100_RSTN_WDTIMER_APB>,
+ <&rstgen JH7100_RSTN_WDT>;
+ };
+-
++*/
+ watchdog@12480000 {
+ compatible = "starfive,si5-wdt";
+ reg = <0x0 0x12480000 0x0 0x10000>;
+--
+2.20.1
+
--- /dev/null
+From 9b1fffcb2c1ea9377197b6def49242a62484035b Mon Sep 17 00:00:00 2001
+From: Emil Renner Berthing <kernel@esmil.dk>
+Date: Wed, 6 Apr 2022 00:38:05 +0200
+Subject: [PATCH 122/124] soc: sifive: ccache: Add StarFive JH71x0 support
+
+This adds support for the StarFive JH7100 and JH7110 SoCs which also
+feature this SiFive cache controller.
+
+Unfortunately the interrupt for uncorrected data is broken on the JH7100
+and fires continuously, so add a quirk to not register a handler for it.
+
+Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
+---
+ arch/riscv/Kconfig.socs | 1 +
+ drivers/soc/sifive/Kconfig | 2 +-
+ drivers/soc/sifive/sifive_ccache.c | 12 +++++++++++-
+ 3 files changed, 13 insertions(+), 2 deletions(-)
+
+diff --git a/arch/riscv/Kconfig.socs b/arch/riscv/Kconfig.socs
+index 69774bb362d6..5a40e05f8cab 100644
+--- a/arch/riscv/Kconfig.socs
++++ b/arch/riscv/Kconfig.socs
+@@ -22,6 +22,7 @@ config SOC_STARFIVE
+ bool "StarFive SoCs"
+ select PINCTRL
+ select RESET_CONTROLLER
++ select SIFIVE_CCACHE
+ select SIFIVE_PLIC
+ help
+ This enables support for StarFive SoC platform hardware.
+diff --git a/drivers/soc/sifive/Kconfig b/drivers/soc/sifive/Kconfig
+index ed4c571f8771..e86870be34c9 100644
+--- a/drivers/soc/sifive/Kconfig
++++ b/drivers/soc/sifive/Kconfig
+@@ -1,6 +1,6 @@
+ # SPDX-License-Identifier: GPL-2.0
+
+-if SOC_SIFIVE
++if SOC_SIFIVE || SOC_STARFIVE
+
+ config SIFIVE_CCACHE
+ bool "Sifive Composable Cache controller"
+diff --git a/drivers/soc/sifive/sifive_ccache.c b/drivers/soc/sifive/sifive_ccache.c
+index 3684f5b40a80..fd5f0c7b060f 100644
+--- a/drivers/soc/sifive/sifive_ccache.c
++++ b/drivers/soc/sifive/sifive_ccache.c
+@@ -106,6 +106,8 @@ static void ccache_config_read(void)
+ static const struct of_device_id sifive_ccache_ids[] = {
+ { .compatible = "sifive,fu540-c000-ccache" },
+ { .compatible = "sifive,fu740-c000-ccache" },
++ { .compatible = "starfive,jh7100-ccache", .data = (void *)BIT(DATA_UNCORR) },
++ { .compatible = "starfive,jh7110-ccache" },
+ { .compatible = "sifive,ccache0" },
+ { /* end of table */ }
+ };
+@@ -210,11 +212,15 @@ static int __init sifive_ccache_init(void)
+ struct device_node *np;
+ struct resource res;
+ int i, rc, intr_num;
++ const struct of_device_id *match;
++ unsigned long broken_irqs;
+
+- np = of_find_matching_node(NULL, sifive_ccache_ids);
++ np = of_find_matching_node_and_match(NULL, sifive_ccache_ids, &match);
+ if (!np)
+ return -ENODEV;
+
++ broken_irqs = (uintptr_t)match->data;
++
+ if (of_address_to_resource(np, 0, &res)) {
+ rc = -ENODEV;
+ goto err_node_put;
+@@ -240,6 +246,10 @@ static int __init sifive_ccache_init(void)
+
+ for (i = 0; i < intr_num; i++) {
+ g_irq[i] = irq_of_parse_and_map(np, i);
++
++ if (broken_irqs & BIT(i))
++ continue;
++
+ rc = request_irq(g_irq[i], ccache_int_handler, 0, "ccache_ecc",
+ NULL);
+ if (rc) {
+--
+2.20.1
+
--- /dev/null
+From 00e6213fc9e5102bc4d06aa47795ff716bc3bd00 Mon Sep 17 00:00:00 2001
+From: Emil Renner Berthing <kernel@esmil.dk>
+Date: Sat, 12 Jun 2021 16:48:31 -0700
+Subject: [PATCH 123/124] soc: sifive: ccache: Add non-coherent DMA handling
+
+Add functions to flush the caches and handle non-coherent DMA.
+
+Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
+---
+ drivers/soc/sifive/sifive_ccache.c | 60 +++++++++++++++++++++++++++++-
+ include/soc/sifive/sifive_ccache.h | 21 +++++++++++
+ 2 files changed, 80 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/soc/sifive/sifive_ccache.c b/drivers/soc/sifive/sifive_ccache.c
+index fd5f0c7b060f..4352c203f84d 100644
+--- a/drivers/soc/sifive/sifive_ccache.c
++++ b/drivers/soc/sifive/sifive_ccache.c
+@@ -8,13 +8,16 @@
+
+ #define pr_fmt(fmt) "CCACHE: " fmt
+
++#include <linux/align.h>
+ #include <linux/debugfs.h>
+ #include <linux/interrupt.h>
+ #include <linux/of_irq.h>
+ #include <linux/of_address.h>
+ #include <linux/device.h>
+ #include <linux/bitfield.h>
++#include <asm/cacheflush.h>
+ #include <asm/cacheinfo.h>
++#include <asm/page.h>
+ #include <soc/sifive/sifive_ccache.h>
+
+ #define SIFIVE_CCACHE_DIRECCFIX_LOW 0x100
+@@ -39,10 +42,14 @@
+ #define SIFIVE_CCACHE_CONFIG_SETS_MASK GENMASK_ULL(23, 16)
+ #define SIFIVE_CCACHE_CONFIG_BLKS_MASK GENMASK_ULL(31, 24)
+
++#define SIFIVE_CCACHE_FLUSH64 0x200
++#define SIFIVE_CCACHE_FLUSH32 0x240
++
+ #define SIFIVE_CCACHE_WAYENABLE 0x08
+ #define SIFIVE_CCACHE_ECCINJECTERR 0x40
+
+ #define SIFIVE_CCACHE_MAX_ECCINTR 4
++#define SIFIVE_CCACHE_LINE_SIZE 64
+
+ static void __iomem *ccache_base;
+ static int g_irq[SIFIVE_CCACHE_MAX_ECCINTR];
+@@ -126,6 +133,47 @@ int unregister_sifive_ccache_error_notifier(struct notifier_block *nb)
+ }
+ EXPORT_SYMBOL_GPL(unregister_sifive_ccache_error_notifier);
+
++#ifdef CONFIG_RISCV_DMA_NONCOHERENT
++static phys_addr_t uncached_offset;
++DEFINE_STATIC_KEY_FALSE(sifive_ccache_handle_noncoherent_key);
++
++void sifive_ccache_flush_range(phys_addr_t start, size_t len)
++{
++ phys_addr_t end = start + len;
++ phys_addr_t line;
++
++ if (!len)
++ return;
++
++ mb();
++ for (line = ALIGN_DOWN(start, SIFIVE_CCACHE_LINE_SIZE); line < end;
++ line += SIFIVE_CCACHE_LINE_SIZE) {
++#ifdef CONFIG_32BIT
++ writel(line >> 4, ccache_base + SIFIVE_CCACHE_FLUSH32);
++#else
++ writeq(line, ccache_base + SIFIVE_CCACHE_FLUSH64);
++#endif
++ mb();
++ }
++}
++EXPORT_SYMBOL_GPL(sifive_ccache_flush_range);
++
++void *sifive_ccache_set_uncached(void *addr, size_t size)
++{
++ phys_addr_t phys_addr = __pa(addr) + uncached_offset;
++ void *mem_base;
++
++ mem_base = memremap(phys_addr, size, MEMREMAP_WT);
++ if (!mem_base) {
++ pr_err("%s memremap failed for addr %p\n", __func__, addr);
++ return ERR_PTR(-EINVAL);
++ }
++
++ return mem_base;
++}
++EXPORT_SYMBOL_GPL(sifive_ccache_set_uncached);
++#endif /* CONFIG_RISCV_DMA_NONCOHERENT */
++
+ static int ccache_largest_wayenabled(void)
+ {
+ return readl(ccache_base + SIFIVE_CCACHE_WAYENABLE) & 0xFF;
+@@ -214,6 +262,7 @@ static int __init sifive_ccache_init(void)
+ int i, rc, intr_num;
+ const struct of_device_id *match;
+ unsigned long broken_irqs;
++ u64 __maybe_unused offset;
+
+ np = of_find_matching_node_and_match(NULL, sifive_ccache_ids, &match);
+ if (!np)
+@@ -259,6 +308,15 @@ static int __init sifive_ccache_init(void)
+ }
+ of_node_put(np);
+
++#ifdef CONFIG_RISCV_DMA_NONCOHERENT
++ if (!of_property_read_u64(np, "uncached-offset", &offset)) {
++ uncached_offset = offset;
++ static_branch_enable(&sifive_ccache_handle_noncoherent_key);
++ riscv_cbom_block_size = SIFIVE_CCACHE_LINE_SIZE;
++ riscv_noncoherent_supported();
++ }
++#endif
++
+ ccache_config_read();
+
+ ccache_cache_ops.get_priv_group = ccache_get_priv_group;
+@@ -279,4 +337,4 @@ static int __init sifive_ccache_init(void)
+ return rc;
+ }
+
+-device_initcall(sifive_ccache_init);
++arch_initcall(sifive_ccache_init);
+diff --git a/include/soc/sifive/sifive_ccache.h b/include/soc/sifive/sifive_ccache.h
+index 4d4ed49388a0..d349ccb3969b 100644
+--- a/include/soc/sifive/sifive_ccache.h
++++ b/include/soc/sifive/sifive_ccache.h
+@@ -7,10 +7,31 @@
+ #ifndef __SOC_SIFIVE_CCACHE_H
+ #define __SOC_SIFIVE_CCACHE_H
+
++#include <linux/io.h>
++#include <linux/jump_label.h>
++
+ extern int register_sifive_ccache_error_notifier(struct notifier_block *nb);
+ extern int unregister_sifive_ccache_error_notifier(struct notifier_block *nb);
+
+ #define SIFIVE_CCACHE_ERR_TYPE_CE 0
+ #define SIFIVE_CCACHE_ERR_TYPE_UE 1
+
++DECLARE_STATIC_KEY_FALSE(sifive_ccache_handle_noncoherent_key);
++
++static inline bool sifive_ccache_handle_noncoherent(void)
++{
++#ifdef CONFIG_SIFIVE_CCACHE
++ return static_branch_unlikely(&sifive_ccache_handle_noncoherent_key);
++#else
++ return false;
++#endif
++}
++
++void sifive_ccache_flush_range(phys_addr_t start, size_t len);
++void *sifive_ccache_set_uncached(void *addr, size_t size);
++static inline void sifive_ccache_clear_uncached(void *addr, size_t size)
++{
++ memunmap(addr);
++}
++
+ #endif /* __SOC_SIFIVE_CCACHE_H */
+--
+2.20.1
+
--- /dev/null
+From 5dc44176bed8b29e218490e6f2a0a8e5def97e4c Mon Sep 17 00:00:00 2001
+From: Emil Renner Berthing <kernel@esmil.dk>
+Date: Sat, 12 Jun 2021 16:48:31 -0700
+Subject: [PATCH 124/132] riscv: Implement non-coherent DMA support via SiFive
+ cache flushing
+
+This variant is used on the StarFive JH7100 SoC.
+
+Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
+---
+ arch/riscv/Kconfig | 6 ++++--
+ arch/riscv/mm/dma-noncoherent.c | 37 +++++++++++++++++++++++++++++++--
+ 2 files changed, 39 insertions(+), 4 deletions(-)
+
+diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
+index 06b9b2f60b9f..593db37db622 100644
+--- a/arch/riscv/Kconfig
++++ b/arch/riscv/Kconfig
+@@ -223,12 +223,14 @@ config LOCKDEP_SUPPORT
+ def_bool y
+
+ config RISCV_DMA_NONCOHERENT
+- bool
++ bool "Support non-coherent DMA"
++ default SOC_STARFIVE
+ select ARCH_HAS_DMA_PREP_COHERENT
++ select ARCH_HAS_DMA_SET_UNCACHED
++ select ARCH_HAS_DMA_CLEAR_UNCACHED
+ select ARCH_HAS_SYNC_DMA_FOR_DEVICE
+ select ARCH_HAS_SYNC_DMA_FOR_CPU
+ select ARCH_HAS_SETUP_DMA_OPS
+- select DMA_DIRECT_REMAP
+
+ config AS_HAS_INSN
+ def_bool $(as-instr,.insn r 51$(comma) 0$(comma) 0$(comma) t0$(comma) t0$(comma) zero)
+diff --git a/arch/riscv/mm/dma-noncoherent.c b/arch/riscv/mm/dma-noncoherent.c
+index d919efab6eba..e07e53aea537 100644
+--- a/arch/riscv/mm/dma-noncoherent.c
++++ b/arch/riscv/mm/dma-noncoherent.c
+@@ -9,14 +9,21 @@
+ #include <linux/dma-map-ops.h>
+ #include <linux/mm.h>
+ #include <asm/cacheflush.h>
++#include <soc/sifive/sifive_ccache.h>
+
+ static bool noncoherent_supported;
+
+ void arch_sync_dma_for_device(phys_addr_t paddr, size_t size,
+ enum dma_data_direction dir)
+ {
+- void *vaddr = phys_to_virt(paddr);
++ void *vaddr;
+
++ if (sifive_ccache_handle_noncoherent()) {
++ sifive_ccache_flush_range(paddr, size);
++ return;
++ }
++
++ vaddr = phys_to_virt(paddr);
+ switch (dir) {
+ case DMA_TO_DEVICE:
+ ALT_CMO_OP(clean, vaddr, size, riscv_cbom_block_size);
+@@ -35,8 +42,14 @@ void arch_sync_dma_for_device(phys_addr_t paddr, size_t size,
+ void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size,
+ enum dma_data_direction dir)
+ {
+- void *vaddr = phys_to_virt(paddr);
++ void *vaddr;
++
++ if (sifive_ccache_handle_noncoherent()) {
++ sifive_ccache_flush_range(paddr, size);
++ return;
++ }
+
++ vaddr = phys_to_virt(paddr);
+ switch (dir) {
+ case DMA_TO_DEVICE:
+ break;
+@@ -49,10 +62,30 @@ void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size,
+ }
+ }
+
++void *arch_dma_set_uncached(void *addr, size_t size)
++{
++ if (sifive_ccache_handle_noncoherent())
++ return sifive_ccache_set_uncached(addr, size);
++
++ return addr;
++}
++
++void arch_dma_clear_uncached(void *addr, size_t size)
++{
++ if (sifive_ccache_handle_noncoherent())
++ sifive_ccache_clear_uncached(addr, size);
++}
++
+ void arch_dma_prep_coherent(struct page *page, size_t size)
+ {
+ void *flush_addr = page_address(page);
+
++ if (sifive_ccache_handle_noncoherent()) {
++ memset(flush_addr, 0, size);
++ sifive_ccache_flush_range(__pa(flush_addr), size);
++ return;
++ }
++
+ ALT_CMO_OP(flush, flush_addr, size, riscv_cbom_block_size);
+ }
+
+--
+2.20.1
+
--- /dev/null
+From d9e6d30c49b479adfdaef70e767929b4cb823ffe Mon Sep 17 00:00:00 2001
+From: Zoltan HERPAI <wigyori@uid0.hu>
+Date: Tue, 30 May 2023 01:02:44 +0200
+Subject: [PATCH 125/132] dts/6.1: jh7100: disable USB for now as it's causing
+ hard resets
+
+Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>
+---
+ arch/riscv/boot/dts/starfive/jh7100-common.dtsi | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/arch/riscv/boot/dts/starfive/jh7100-common.dtsi b/arch/riscv/boot/dts/starfive/jh7100-common.dtsi
+index c39ef1f8c1aa..8231e75d08fc 100644
+--- a/arch/riscv/boot/dts/starfive/jh7100-common.dtsi
++++ b/arch/riscv/boot/dts/starfive/jh7100-common.dtsi
+@@ -581,7 +581,8 @@
+ status = "okay";
+ };
+
+-&usb3 {
++/*&usb3 {
+ dr_mode = "host";
+ status = "okay";
+ };
++*/
+--
+2.20.1
+
--- /dev/null
+From f2c0c17058bc06786b4d7d64d4bf1e1a498304c4 Mon Sep 17 00:00:00 2001
+From: Samin Guo <samin.guo@starfivetech.com>
+Date: Wed, 17 Nov 2021 14:50:45 +0800
+Subject: [PATCH 126/132] dmaengine: dw-axi-dmac: Handle xfer start while
+ non-idle
+
+Signed-off-by: Samin Guo <samin.guo@starfivetech.com>
+Signed-off-by: Curry Zhang <curry.zhang@starfivetech.com>
+---
+ drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c | 12 +++++++++++-
+ drivers/dma/dw-axi-dmac/dw-axi-dmac.h | 1 +
+ 2 files changed, 12 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
+index 6937cc0c0b65..f71105de7e65 100644
+--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
++++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
+@@ -382,11 +382,13 @@ static void axi_chan_block_xfer_start(struct axi_dma_chan *chan,
+ u32 irq_mask;
+ u8 lms = 0; /* Select AXI0 master for LLI fetching */
+
++ chan->is_err = false;
+ if (unlikely(axi_chan_is_hw_enable(chan))) {
+ dev_err(chan2dev(chan), "%s is non-idle!\n",
+ axi_chan_name(chan));
+
+- return;
++ axi_chan_disable(chan);
++ chan->is_err = true;
+ }
+
+ axi_dma_enable(chan->chip);
+@@ -1028,6 +1030,14 @@ static noinline void axi_chan_handle_err(struct axi_dma_chan *chan, u32 status)
+ axi_chan_name(chan));
+ goto out;
+ }
++ if (chan->is_err) {
++ struct axi_dma_desc *desc = vd_to_axi_desc(vd);
++
++ axi_chan_block_xfer_start(chan, desc);
++ chan->is_err = false;
++ goto out;
++ }
++
+ /* Remove the completed descriptor from issued list */
+ list_del(&vd->node);
+
+diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
+index eb267cb24f67..10d96a423bb2 100644
+--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
++++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
+@@ -50,6 +50,7 @@ struct axi_dma_chan {
+ struct dma_slave_config config;
+ enum dma_transfer_direction direction;
+ bool cyclic;
++ bool is_err;
+ /* these other elements are all protected by vc.lock */
+ bool is_paused;
+ };
+--
+2.20.1
+
--- /dev/null
+From a1eefda528d9333bb41405631968c99e9c8e8f07 Mon Sep 17 00:00:00 2001
+From: Samin Guo <samin.guo@starfivetech.com>
+Date: Wed, 17 Nov 2021 14:50:45 +0800
+Subject: [PATCH 127/132] dmaengine: dw-axi-dmac: Add StarFive JH7100 support
+
+Signed-off-by: Samin Guo <samin.guo@starfivetech.com>
+Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
+---
+ drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c | 12 ++++++++++++
+ drivers/dma/dw-axi-dmac/dw-axi-dmac.h | 4 ++++
+ 2 files changed, 16 insertions(+)
+
+diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
+index f71105de7e65..10ae58582c66 100644
+--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
++++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
+@@ -677,8 +677,13 @@ static int dw_axi_dma_set_hw_desc(struct axi_dma_chan *chan,
+
+ hw_desc->lli->block_ts_lo = cpu_to_le32(block_ts - 1);
+
++#ifdef CONFIG_SOC_STARFIVE
++ ctllo |= DWAXIDMAC_BURST_TRANS_LEN_16 << CH_CTL_L_DST_MSIZE_POS |
++ DWAXIDMAC_BURST_TRANS_LEN_16 << CH_CTL_L_SRC_MSIZE_POS;
++#else
+ ctllo |= DWAXIDMAC_BURST_TRANS_LEN_4 << CH_CTL_L_DST_MSIZE_POS |
+ DWAXIDMAC_BURST_TRANS_LEN_4 << CH_CTL_L_SRC_MSIZE_POS;
++#endif
+ hw_desc->lli->ctl_lo = cpu_to_le32(ctllo);
+
+ set_desc_src_master(hw_desc);
+@@ -1506,7 +1511,11 @@ static int dw_probe(struct platform_device *pdev)
+ * Therefore, set constraint to 1024 * 4.
+ */
+ dw->dma.dev->dma_parms = &dw->dma_parms;
++#ifdef CONFIG_SOC_STARFIVE
++ dma_set_max_seg_size(&pdev->dev, DMAC_MAX_BLK_SIZE);
++#else
+ dma_set_max_seg_size(&pdev->dev, MAX_BLOCK_SIZE);
++#endif
+ platform_set_drvdata(pdev, chip);
+
+ pm_runtime_enable(chip->dev);
+@@ -1590,6 +1599,9 @@ static const struct of_device_id dw_dma_of_id_table[] = {
+ }, {
+ .compatible = "intel,kmb-axi-dma",
+ .data = (void *)AXI_DMA_FLAG_HAS_APB_REGS,
++ }, {
++ .compatible = "starfive,jh7100-axi-dma",
++ .data = (void *)(AXI_DMA_FLAG_HAS_RESETS | AXI_DMA_FLAG_USE_CFG2),
+ }, {
+ .compatible = "starfive,jh7110-axi-dma",
+ .data = (void *)(AXI_DMA_FLAG_HAS_RESETS | AXI_DMA_FLAG_USE_CFG2),
+diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
+index 10d96a423bb2..0964b0588f95 100644
+--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
++++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
+@@ -283,7 +283,11 @@ enum {
+ #define CH_CTL_L_SRC_MAST BIT(0)
+
+ /* CH_CFG_H */
++#ifdef CONFIG_SOC_STARFIVE
++#define CH_CFG_H_PRIORITY_POS 15
++#else
+ #define CH_CFG_H_PRIORITY_POS 17
++#endif
+ #define CH_CFG_H_DST_PER_POS 12
+ #define CH_CFG_H_SRC_PER_POS 7
+ #define CH_CFG_H_HS_SEL_DST_POS 4
+--
+2.20.1
+
--- /dev/null
+From 5491601f6721df404448cbaefb3a9af6062e2625 Mon Sep 17 00:00:00 2001
+From: Emil Renner Berthing <kernel@esmil.dk>
+Date: Sat, 17 Jul 2021 21:50:38 +0200
+Subject: [PATCH 128/132] pinctrl: starfive: Reset pinmux settings
+
+Current u-boot doesn't seem to take into account that some GPIOs are
+configured as inputs/outputs of certain peripherals on power-up. This
+means it ends up configuring some GPIOs as inputs to more than one
+peripheral which the documentation explicitly says is illegal. Similarly
+it also ends up configuring more than one GPIO as output of the same
+peripheral. While not explicitly mentioned by the documentation this
+also seems like a bad idea.
+
+The easiest way to remedy this mess is to just disconnect all GPIOs from
+peripherals and have our pinmux configuration set everything up
+properly. This, however, means that we'd disconnect the serial console
+from its pins for a while, so add a device tree property to keep
+certain GPIOs from being reset.
+
+Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
+---
+ .../pinctrl/starfive,jh7100-pinctrl.yaml | 4 ++
+ .../starfive/pinctrl-starfive-jh7100.c | 66 +++++++++++++++++++
+ 2 files changed, 70 insertions(+)
+
+diff --git a/Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml
+index 69c0dd9998ea..ba3a664cf2ae 100644
+--- a/Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml
++++ b/Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml
+@@ -88,6 +88,10 @@ properties:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ enum: [0, 1, 2, 3, 4, 5, 6]
+
++ starfive,keep-gpiomux:
++ description: Keep pinmux for these GPIOs from being reset at boot.
++ $ref: /schemas/types.yaml#/definitions/uint32-array
++
+ required:
+ - compatible
+ - reg
+diff --git a/drivers/pinctrl/starfive/pinctrl-starfive-jh7100.c b/drivers/pinctrl/starfive/pinctrl-starfive-jh7100.c
+index 5b544fb7f3d8..4230633dce26 100644
+--- a/drivers/pinctrl/starfive/pinctrl-starfive-jh7100.c
++++ b/drivers/pinctrl/starfive/pinctrl-starfive-jh7100.c
+@@ -200,6 +200,10 @@ static u16 starfive_drive_strength_from_max_mA(u32 i)
+ return (clamp(i, 14U, 63U) - 14) / 7;
+ }
+
++static bool keepmux;
++module_param(keepmux, bool, 0644);
++MODULE_PARM_DESC(keepmux, "Keep pinmux settings from previous boot stage");
++
+ struct starfive_pinctrl {
+ struct gpio_chip gc;
+ struct pinctrl_gpio_range gpios;
+@@ -1222,6 +1226,65 @@ static void starfive_disable_clock(void *data)
+ clk_disable_unprepare(data);
+ }
+
++#define GPI_END (GPI_USB_OVER_CURRENT + 1)
++static void starfive_pinmux_reset(struct starfive_pinctrl *sfp)
++{
++ static const DECLARE_BITMAP(defaults, GPI_END) = {
++ BIT_MASK(GPI_I2C0_PAD_SCK_IN) |
++ BIT_MASK(GPI_I2C0_PAD_SDA_IN) |
++ BIT_MASK(GPI_I2C1_PAD_SCK_IN) |
++ BIT_MASK(GPI_I2C1_PAD_SDA_IN) |
++ BIT_MASK(GPI_I2C2_PAD_SCK_IN) |
++ BIT_MASK(GPI_I2C2_PAD_SDA_IN) |
++ BIT_MASK(GPI_I2C3_PAD_SCK_IN) |
++ BIT_MASK(GPI_I2C3_PAD_SDA_IN) |
++ BIT_MASK(GPI_SDIO0_PAD_CARD_DETECT_N) |
++
++ BIT_MASK(GPI_SDIO1_PAD_CARD_DETECT_N) |
++ BIT_MASK(GPI_SPI0_PAD_SS_IN_N) |
++ BIT_MASK(GPI_SPI1_PAD_SS_IN_N) |
++ BIT_MASK(GPI_SPI2_PAD_SS_IN_N) |
++ BIT_MASK(GPI_SPI2AHB_PAD_SS_N) |
++ BIT_MASK(GPI_SPI3_PAD_SS_IN_N),
++
++ BIT_MASK(GPI_UART0_PAD_SIN) |
++ BIT_MASK(GPI_UART1_PAD_SIN) |
++ BIT_MASK(GPI_UART2_PAD_SIN) |
++ BIT_MASK(GPI_UART3_PAD_SIN) |
++ BIT_MASK(GPI_USB_OVER_CURRENT)
++ };
++ DECLARE_BITMAP(keep, NR_GPIOS) = {};
++ struct device_node *np = sfp->gc.parent->of_node;
++ int len = of_property_count_u32_elems(np, "starfive,keep-gpiomux");
++ int i;
++
++ for (i = 0; i < len; i++) {
++ u32 gpio;
++
++ of_property_read_u32_index(np, "starfive,keep-gpiomux", i, &gpio);
++ if (gpio < NR_GPIOS)
++ set_bit(gpio, keep);
++ }
++
++ for (i = 0; i < NR_GPIOS; i++) {
++ if (test_bit(i, keep))
++ continue;
++
++ writel_relaxed(GPO_DISABLE, sfp->base + GPON_DOEN_CFG + 8 * i);
++ writel_relaxed(GPO_LOW, sfp->base + GPON_DOUT_CFG + 8 * i);
++ }
++
++ for (i = 0; i < GPI_END; i++) {
++ void __iomem *reg = sfp->base + GPI_CFG_OFFSET + 4 * i;
++ u32 din = readl_relaxed(reg);
++
++ if (din >= 2 && din < (NR_GPIOS + 2) && test_bit(din - 2, keep))
++ continue;
++
++ writel_relaxed(test_bit(i, defaults), reg);
++ }
++}
++
+ static int starfive_probe(struct platform_device *pdev)
+ {
+ struct device *dev = &pdev->dev;
+@@ -1283,6 +1346,9 @@ static int starfive_probe(struct platform_device *pdev)
+ writel(value, sfp->padctl + IO_PADSHARE_SEL);
+ }
+
++ if (!keepmux)
++ starfive_pinmux_reset(sfp);
++
+ value = readl(sfp->padctl + IO_PADSHARE_SEL);
+ switch (value) {
+ case 0:
+--
+2.20.1
+
--- /dev/null
+From 661659609aa11708094ce861a39eec7e9cf9831d Mon Sep 17 00:00:00 2001
+From: Emil Renner Berthing <emil.renner.berthing@canonical.com>
+Date: Sat, 25 Mar 2023 22:57:06 +0100
+Subject: [PATCH 129/132] clk: starfive: Add flags argument to JH71X0__MUX
+ macro
+
+This flag is needed to add the CLK_SET_RATE_PARENT flag on the gmac_tx
+clock on the JH7100, which in turn is needed by the dwmac-starfive
+driver to set the clock properly for 1000, 100 and 10 Mbps links.
+
+This change was mostly made using coccinelle:
+
+@ match @
+expression idx, name, nparents;
+@@
+ JH71X0__MUX(
+-idx, name, nparents,
++idx, name, 0, nparents,
+ ...)
+
+Signed-off-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
+---
+ .../clk/starfive/clk-starfive-jh7100-audio.c | 2 +-
+ drivers/clk/starfive/clk-starfive-jh7100.c | 32 +++++++++----------
+ .../clk/starfive/clk-starfive-jh7110-aon.c | 6 ++--
+ .../clk/starfive/clk-starfive-jh7110-isp.c | 2 +-
+ .../clk/starfive/clk-starfive-jh7110-sys.c | 26 +++++++--------
+ drivers/clk/starfive/clk-starfive-jh71x0.h | 4 +--
+ 6 files changed, 36 insertions(+), 36 deletions(-)
+
+diff --git a/drivers/clk/starfive/clk-starfive-jh7100-audio.c b/drivers/clk/starfive/clk-starfive-jh7100-audio.c
+index 02aefb7264f8..7141ed244782 100644
+--- a/drivers/clk/starfive/clk-starfive-jh7100-audio.c
++++ b/drivers/clk/starfive/clk-starfive-jh7100-audio.c
+@@ -80,7 +80,7 @@ static const struct jh71x0_clk_data jh7100_audclk_data[] = {
+ JH71X0_GDIV(JH7100_AUDCLK_USB_LPM, "usb_lpm", CLK_IGNORE_UNUSED, 4, JH7100_AUDCLK_USB_APB),
+ JH71X0_GDIV(JH7100_AUDCLK_USB_STB, "usb_stb", CLK_IGNORE_UNUSED, 3, JH7100_AUDCLK_USB_APB),
+ JH71X0__DIV(JH7100_AUDCLK_APB_EN, "apb_en", 8, JH7100_AUDCLK_DOM7AHB_BUS),
+- JH71X0__MUX(JH7100_AUDCLK_VAD_MEM, "vad_mem", 2,
++ JH71X0__MUX(JH7100_AUDCLK_VAD_MEM, "vad_mem", 0, 2,
+ JH7100_AUDCLK_VAD_INTMEM,
+ JH7100_AUDCLK_AUDIO_12288),
+ };
+diff --git a/drivers/clk/starfive/clk-starfive-jh7100.c b/drivers/clk/starfive/clk-starfive-jh7100.c
+index 69cc11ea7e33..d3b260c01d5c 100644
+--- a/drivers/clk/starfive/clk-starfive-jh7100.c
++++ b/drivers/clk/starfive/clk-starfive-jh7100.c
+@@ -24,48 +24,48 @@
+ #define JH7100_CLK_GMAC_GR_MII_RX (JH7100_CLK_END + 3)
+
+ static const struct jh71x0_clk_data jh7100_clk_data[] __initconst = {
+- JH71X0__MUX(JH7100_CLK_CPUNDBUS_ROOT, "cpundbus_root", 4,
++ JH71X0__MUX(JH7100_CLK_CPUNDBUS_ROOT, "cpundbus_root", 0, 4,
+ JH7100_CLK_OSC_SYS,
+ JH7100_CLK_PLL0_OUT,
+ JH7100_CLK_PLL1_OUT,
+ JH7100_CLK_PLL2_OUT),
+- JH71X0__MUX(JH7100_CLK_DLA_ROOT, "dla_root", 3,
++ JH71X0__MUX(JH7100_CLK_DLA_ROOT, "dla_root", 0, 3,
+ JH7100_CLK_OSC_SYS,
+ JH7100_CLK_PLL1_OUT,
+ JH7100_CLK_PLL2_OUT),
+- JH71X0__MUX(JH7100_CLK_DSP_ROOT, "dsp_root", 4,
++ JH71X0__MUX(JH7100_CLK_DSP_ROOT, "dsp_root", 0, 4,
+ JH7100_CLK_OSC_SYS,
+ JH7100_CLK_PLL0_OUT,
+ JH7100_CLK_PLL1_OUT,
+ JH7100_CLK_PLL2_OUT),
+- JH71X0__MUX(JH7100_CLK_GMACUSB_ROOT, "gmacusb_root", 3,
++ JH71X0__MUX(JH7100_CLK_GMACUSB_ROOT, "gmacusb_root", 0, 3,
+ JH7100_CLK_OSC_SYS,
+ JH7100_CLK_PLL0_OUT,
+ JH7100_CLK_PLL2_OUT),
+- JH71X0__MUX(JH7100_CLK_PERH0_ROOT, "perh0_root", 2,
++ JH71X0__MUX(JH7100_CLK_PERH0_ROOT, "perh0_root", 0, 2,
+ JH7100_CLK_OSC_SYS,
+ JH7100_CLK_PLL0_OUT),
+- JH71X0__MUX(JH7100_CLK_PERH1_ROOT, "perh1_root", 2,
++ JH71X0__MUX(JH7100_CLK_PERH1_ROOT, "perh1_root", 0, 2,
+ JH7100_CLK_OSC_SYS,
+ JH7100_CLK_PLL2_OUT),
+- JH71X0__MUX(JH7100_CLK_VIN_ROOT, "vin_root", 3,
++ JH71X0__MUX(JH7100_CLK_VIN_ROOT, "vin_root", 0, 3,
+ JH7100_CLK_OSC_SYS,
+ JH7100_CLK_PLL1_OUT,
+ JH7100_CLK_PLL2_OUT),
+- JH71X0__MUX(JH7100_CLK_VOUT_ROOT, "vout_root", 3,
++ JH71X0__MUX(JH7100_CLK_VOUT_ROOT, "vout_root", 0, 3,
+ JH7100_CLK_OSC_AUD,
+ JH7100_CLK_PLL0_OUT,
+ JH7100_CLK_PLL2_OUT),
+ JH71X0_GDIV(JH7100_CLK_AUDIO_ROOT, "audio_root", 0, 8, JH7100_CLK_PLL0_OUT),
+- JH71X0__MUX(JH7100_CLK_CDECHIFI4_ROOT, "cdechifi4_root", 3,
++ JH71X0__MUX(JH7100_CLK_CDECHIFI4_ROOT, "cdechifi4_root", 0, 3,
+ JH7100_CLK_OSC_SYS,
+ JH7100_CLK_PLL1_OUT,
+ JH7100_CLK_PLL2_OUT),
+- JH71X0__MUX(JH7100_CLK_CDEC_ROOT, "cdec_root", 3,
++ JH71X0__MUX(JH7100_CLK_CDEC_ROOT, "cdec_root", 0, 3,
+ JH7100_CLK_OSC_SYS,
+ JH7100_CLK_PLL0_OUT,
+ JH7100_CLK_PLL1_OUT),
+- JH71X0__MUX(JH7100_CLK_VOUTBUS_ROOT, "voutbus_root", 3,
++ JH71X0__MUX(JH7100_CLK_VOUTBUS_ROOT, "voutbus_root", 0, 3,
+ JH7100_CLK_OSC_AUD,
+ JH7100_CLK_PLL0_OUT,
+ JH7100_CLK_PLL2_OUT),
+@@ -76,7 +76,7 @@ static const struct jh71x0_clk_data jh7100_clk_data[] __initconst = {
+ JH71X0_GDIV(JH7100_CLK_PLL0_TESTOUT, "pll0_testout", 0, 31, JH7100_CLK_PERH0_SRC),
+ JH71X0_GDIV(JH7100_CLK_PLL1_TESTOUT, "pll1_testout", 0, 31, JH7100_CLK_DLA_ROOT),
+ JH71X0_GDIV(JH7100_CLK_PLL2_TESTOUT, "pll2_testout", 0, 31, JH7100_CLK_PERH1_SRC),
+- JH71X0__MUX(JH7100_CLK_PLL2_REF, "pll2_refclk", 2,
++ JH71X0__MUX(JH7100_CLK_PLL2_REF, "pll2_refclk", 0, 2,
+ JH7100_CLK_OSC_SYS,
+ JH7100_CLK_OSC_AUD),
+ JH71X0__DIV(JH7100_CLK_CPU_CORE, "cpu_core", 8, JH7100_CLK_CPUNBUS_ROOT_DIV),
+@@ -142,7 +142,7 @@ static const struct jh71x0_clk_data jh7100_clk_data[] __initconst = {
+ JH71X0__DIV(JH7100_CLK_NOC_COG, "noc_cog", 8, JH7100_CLK_DLA_ROOT),
+ JH71X0_GATE(JH7100_CLK_NNE_AHB, "nne_ahb", 0, JH7100_CLK_AHB_BUS),
+ JH71X0__DIV(JH7100_CLK_NNEBUS_SRC1, "nnebus_src1", 4, JH7100_CLK_DSP_ROOT),
+- JH71X0__MUX(JH7100_CLK_NNE_BUS, "nne_bus", 2,
++ JH71X0__MUX(JH7100_CLK_NNE_BUS, "nne_bus", 0, 2,
+ JH7100_CLK_CPU_AXI,
+ JH7100_CLK_NNEBUS_SRC1),
+ JH71X0_GATE(JH7100_CLK_NNE_AXI, "nne_axi", 0, JH7100_CLK_NNE_BUS),
+@@ -166,7 +166,7 @@ static const struct jh71x0_clk_data jh7100_clk_data[] __initconst = {
+ JH71X0_GDIV(JH7100_CLK_USBPHY_125M, "usbphy_125m", 0, 8, JH7100_CLK_USBPHY_ROOTDIV),
+ JH71X0_GDIV(JH7100_CLK_USBPHY_PLLDIV25M, "usbphy_plldiv25m", 0, 32,
+ JH7100_CLK_USBPHY_ROOTDIV),
+- JH71X0__MUX(JH7100_CLK_USBPHY_25M, "usbphy_25m", 2,
++ JH71X0__MUX(JH7100_CLK_USBPHY_25M, "usbphy_25m", 0, 2,
+ JH7100_CLK_OSC_SYS,
+ JH7100_CLK_USBPHY_PLLDIV25M),
+ JH71X0_FDIV(JH7100_CLK_AUDIO_DIV, "audio_div", JH7100_CLK_AUDIO_ROOT),
+@@ -200,12 +200,12 @@ static const struct jh71x0_clk_data jh7100_clk_data[] __initconst = {
+ JH71X0_GDIV(JH7100_CLK_GMAC_GTX, "gmac_gtxclk", 0, 255, JH7100_CLK_GMAC_ROOT_DIV),
+ JH71X0_GDIV(JH7100_CLK_GMAC_RMII_TX, "gmac_rmii_txclk", 0, 8, JH7100_CLK_GMAC_RMII_REF),
+ JH71X0_GDIV(JH7100_CLK_GMAC_RMII_RX, "gmac_rmii_rxclk", 0, 8, JH7100_CLK_GMAC_RMII_REF),
+- JH71X0__MUX(JH7100_CLK_GMAC_TX, "gmac_tx", 3,
++ JH71X0__MUX(JH7100_CLK_GMAC_TX, "gmac_tx", 0, 3,
+ JH7100_CLK_GMAC_GTX,
+ JH7100_CLK_GMAC_TX_INV,
+ JH7100_CLK_GMAC_RMII_TX),
+ JH71X0__INV(JH7100_CLK_GMAC_TX_INV, "gmac_tx_inv", JH7100_CLK_GMAC_TX),
+- JH71X0__MUX(JH7100_CLK_GMAC_RX_PRE, "gmac_rx_pre", 2,
++ JH71X0__MUX(JH7100_CLK_GMAC_RX_PRE, "gmac_rx_pre", 0, 2,
+ JH7100_CLK_GMAC_GR_MII_RX,
+ JH7100_CLK_GMAC_RMII_RX),
+ JH71X0__INV(JH7100_CLK_GMAC_RX_INV, "gmac_rx_inv", JH7100_CLK_GMAC_RX_PRE),
+diff --git a/drivers/clk/starfive/clk-starfive-jh7110-aon.c b/drivers/clk/starfive/clk-starfive-jh7110-aon.c
+index a2799fe8a234..3b80394f33f0 100644
+--- a/drivers/clk/starfive/clk-starfive-jh7110-aon.c
++++ b/drivers/clk/starfive/clk-starfive-jh7110-aon.c
+@@ -26,7 +26,7 @@
+ static const struct jh71x0_clk_data jh7110_aonclk_data[] = {
+ /* source */
+ JH71X0__DIV(JH7110_AONCLK_OSC_DIV4, "osc_div4", 4, JH7110_AONCLK_OSC),
+- JH71X0__MUX(JH7110_AONCLK_APB_FUNC, "apb_func", 2,
++ JH71X0__MUX(JH7110_AONCLK_APB_FUNC, "apb_func", 0, 2,
+ JH7110_AONCLK_OSC_DIV4,
+ JH7110_AONCLK_OSC),
+ /* gmac0 */
+@@ -39,7 +39,7 @@ static const struct jh71x0_clk_data jh7110_aonclk_data[] = {
+ JH7110_AONCLK_GMAC0_GTXCLK,
+ JH7110_AONCLK_GMAC0_RMII_RTX),
+ JH71X0__INV(JH7110_AONCLK_GMAC0_TX_INV, "gmac0_tx_inv", JH7110_AONCLK_GMAC0_TX),
+- JH71X0__MUX(JH7110_AONCLK_GMAC0_RX, "gmac0_rx", 2,
++ JH71X0__MUX(JH7110_AONCLK_GMAC0_RX, "gmac0_rx", 0, 2,
+ JH7110_AONCLK_GMAC0_RGMII_RXIN,
+ JH7110_AONCLK_GMAC0_RMII_RTX),
+ JH71X0__INV(JH7110_AONCLK_GMAC0_RX_INV, "gmac0_rx_inv", JH7110_AONCLK_GMAC0_RX),
+@@ -48,7 +48,7 @@ static const struct jh71x0_clk_data jh7110_aonclk_data[] = {
+ /* rtc */
+ JH71X0_GATE(JH7110_AONCLK_RTC_APB, "rtc_apb", 0, JH7110_AONCLK_APB_BUS),
+ JH71X0__DIV(JH7110_AONCLK_RTC_INTERNAL, "rtc_internal", 1022, JH7110_AONCLK_OSC),
+- JH71X0__MUX(JH7110_AONCLK_RTC_32K, "rtc_32k", 2,
++ JH71X0__MUX(JH7110_AONCLK_RTC_32K, "rtc_32k", 0, 2,
+ JH7110_AONCLK_RTC_OSC,
+ JH7110_AONCLK_RTC_INTERNAL),
+ JH71X0_GATE(JH7110_AONCLK_RTC_CAL, "rtc_cal", 0, JH7110_AONCLK_OSC),
+diff --git a/drivers/clk/starfive/clk-starfive-jh7110-isp.c b/drivers/clk/starfive/clk-starfive-jh7110-isp.c
+index 7e51447060fe..686972a0db2f 100644
+--- a/drivers/clk/starfive/clk-starfive-jh7110-isp.c
++++ b/drivers/clk/starfive/clk-starfive-jh7110-isp.c
+@@ -53,7 +53,7 @@ static const struct jh71x0_clk_data jh7110_ispclk_data[] = {
+ JH7110_ISPCLK_MIPI_RX0_PXL),
+ JH71X0_GATE(JH7110_ISPCLK_VIN_PIXEL_IF3, "vin_pixel_if3", 0,
+ JH7110_ISPCLK_MIPI_RX0_PXL),
+- JH71X0__MUX(JH7110_ISPCLK_VIN_P_AXI_WR, "vin_p_axi_wr", 2,
++ JH71X0__MUX(JH7110_ISPCLK_VIN_P_AXI_WR, "vin_p_axi_wr", 0, 2,
+ JH7110_ISPCLK_MIPI_RX0_PXL,
+ JH7110_ISPCLK_DVP_INV),
+ /* ispv2_top_wrapper */
+diff --git a/drivers/clk/starfive/clk-starfive-jh7110-sys.c b/drivers/clk/starfive/clk-starfive-jh7110-sys.c
+index 7fd30c571059..be4ccb9e6323 100644
+--- a/drivers/clk/starfive/clk-starfive-jh7110-sys.c
++++ b/drivers/clk/starfive/clk-starfive-jh7110-sys.c
+@@ -35,18 +35,18 @@
+
+ static const struct jh71x0_clk_data jh7110_sysclk_data[] __initconst = {
+ /* root */
+- JH71X0__MUX(JH7110_SYSCLK_CPU_ROOT, "cpu_root", 2,
++ JH71X0__MUX(JH7110_SYSCLK_CPU_ROOT, "cpu_root", 0, 2,
+ JH7110_SYSCLK_OSC,
+ JH7110_SYSCLK_PLL0_OUT),
+ JH71X0__DIV(JH7110_SYSCLK_CPU_CORE, "cpu_core", 7, JH7110_SYSCLK_CPU_ROOT),
+ JH71X0__DIV(JH7110_SYSCLK_CPU_BUS, "cpu_bus", 2, JH7110_SYSCLK_CPU_CORE),
+- JH71X0__MUX(JH7110_SYSCLK_GPU_ROOT, "gpu_root", 2,
++ JH71X0__MUX(JH7110_SYSCLK_GPU_ROOT, "gpu_root", 0, 2,
+ JH7110_SYSCLK_PLL2_OUT,
+ JH7110_SYSCLK_PLL1_OUT),
+ JH71X0_MDIV(JH7110_SYSCLK_PERH_ROOT, "perh_root", 2, 2,
+ JH7110_SYSCLK_PLL0_OUT,
+ JH7110_SYSCLK_PLL2_OUT),
+- JH71X0__MUX(JH7110_SYSCLK_BUS_ROOT, "bus_root", 2,
++ JH71X0__MUX(JH7110_SYSCLK_BUS_ROOT, "bus_root", 0, 2,
+ JH7110_SYSCLK_OSC,
+ JH7110_SYSCLK_PLL2_OUT),
+ JH71X0__DIV(JH7110_SYSCLK_NOCSTG_BUS, "nocstg_bus", 3, JH7110_SYSCLK_BUS_ROOT),
+@@ -61,7 +61,7 @@ static const struct jh71x0_clk_data jh7110_sysclk_data[] __initconst = {
+ JH71X0__DIV(JH7110_SYSCLK_PLL2_DIV2, "pll2_div2", 2, JH7110_SYSCLK_PLL2_OUT),
+ JH71X0__DIV(JH7110_SYSCLK_AUDIO_ROOT, "audio_root", 8, JH7110_SYSCLK_PLL2_OUT),
+ JH71X0__DIV(JH7110_SYSCLK_MCLK_INNER, "mclk_inner", 64, JH7110_SYSCLK_AUDIO_ROOT),
+- JH71X0__MUX(JH7110_SYSCLK_MCLK, "mclk", 2,
++ JH71X0__MUX(JH7110_SYSCLK_MCLK, "mclk", 0, 2,
+ JH7110_SYSCLK_MCLK_INNER,
+ JH7110_SYSCLK_MCLK_EXT),
+ JH71X0_GATE(JH7110_SYSCLK_MCLK_OUT, "mclk_out", 0, JH7110_SYSCLK_MCLK_INNER),
+@@ -95,7 +95,7 @@ static const struct jh71x0_clk_data jh7110_sysclk_data[] __initconst = {
+ JH71X0__DIV(JH7110_SYSCLK_OSC_DIV2, "osc_div2", 2, JH7110_SYSCLK_OSC),
+ JH71X0__DIV(JH7110_SYSCLK_PLL1_DIV4, "pll1_div4", 2, JH7110_SYSCLK_PLL1_DIV2),
+ JH71X0__DIV(JH7110_SYSCLK_PLL1_DIV8, "pll1_div8", 2, JH7110_SYSCLK_PLL1_DIV4),
+- JH71X0__MUX(JH7110_SYSCLK_DDR_BUS, "ddr_bus", 4,
++ JH71X0__MUX(JH7110_SYSCLK_DDR_BUS, "ddr_bus", 0, 4,
+ JH7110_SYSCLK_OSC_DIV2,
+ JH7110_SYSCLK_PLL1_DIV2,
+ JH7110_SYSCLK_PLL1_DIV4,
+@@ -185,7 +185,7 @@ static const struct jh71x0_clk_data jh7110_sysclk_data[] __initconst = {
+ JH71X0__DIV(JH7110_SYSCLK_GMAC1_RMII_RTX, "gmac1_rmii_rtx", 30,
+ JH7110_SYSCLK_GMAC1_RMII_REFIN),
+ JH71X0_GDIV(JH7110_SYSCLK_GMAC1_PTP, "gmac1_ptp", 0, 31, JH7110_SYSCLK_GMAC_SRC),
+- JH71X0__MUX(JH7110_SYSCLK_GMAC1_RX, "gmac1_rx", 2,
++ JH71X0__MUX(JH7110_SYSCLK_GMAC1_RX, "gmac1_rx", 0, 2,
+ JH7110_SYSCLK_GMAC1_RGMII_RXIN,
+ JH7110_SYSCLK_GMAC1_RMII_RTX),
+ JH71X0__INV(JH7110_SYSCLK_GMAC1_RX_INV, "gmac1_rx_inv", JH7110_SYSCLK_GMAC1_RX),
+@@ -269,11 +269,11 @@ static const struct jh71x0_clk_data jh7110_sysclk_data[] __initconst = {
+ JH71X0_MDIV(JH7110_SYSCLK_I2STX0_LRCK_MST, "i2stx0_lrck_mst", 64, 2,
+ JH7110_SYSCLK_I2STX0_BCLK_MST_INV,
+ JH7110_SYSCLK_I2STX0_BCLK_MST),
+- JH71X0__MUX(JH7110_SYSCLK_I2STX0_BCLK, "i2stx0_bclk", 2,
++ JH71X0__MUX(JH7110_SYSCLK_I2STX0_BCLK, "i2stx0_bclk", 0, 2,
+ JH7110_SYSCLK_I2STX0_BCLK_MST,
+ JH7110_SYSCLK_I2STX_BCLK_EXT),
+ JH71X0__INV(JH7110_SYSCLK_I2STX0_BCLK_INV, "i2stx0_bclk_inv", JH7110_SYSCLK_I2STX0_BCLK),
+- JH71X0__MUX(JH7110_SYSCLK_I2STX0_LRCK, "i2stx0_lrck", 2,
++ JH71X0__MUX(JH7110_SYSCLK_I2STX0_LRCK, "i2stx0_lrck", 0, 2,
+ JH7110_SYSCLK_I2STX0_LRCK_MST,
+ JH7110_SYSCLK_I2STX_LRCK_EXT),
+ /* i2stx1 */
+@@ -284,11 +284,11 @@ static const struct jh71x0_clk_data jh7110_sysclk_data[] __initconst = {
+ JH71X0_MDIV(JH7110_SYSCLK_I2STX1_LRCK_MST, "i2stx1_lrck_mst", 64, 2,
+ JH7110_SYSCLK_I2STX1_BCLK_MST_INV,
+ JH7110_SYSCLK_I2STX1_BCLK_MST),
+- JH71X0__MUX(JH7110_SYSCLK_I2STX1_BCLK, "i2stx1_bclk", 2,
++ JH71X0__MUX(JH7110_SYSCLK_I2STX1_BCLK, "i2stx1_bclk", 0, 2,
+ JH7110_SYSCLK_I2STX1_BCLK_MST,
+ JH7110_SYSCLK_I2STX_BCLK_EXT),
+ JH71X0__INV(JH7110_SYSCLK_I2STX1_BCLK_INV, "i2stx1_bclk_inv", JH7110_SYSCLK_I2STX1_BCLK),
+- JH71X0__MUX(JH7110_SYSCLK_I2STX1_LRCK, "i2stx1_lrck", 2,
++ JH71X0__MUX(JH7110_SYSCLK_I2STX1_LRCK, "i2stx1_lrck", 0, 2,
+ JH7110_SYSCLK_I2STX1_LRCK_MST,
+ JH7110_SYSCLK_I2STX_LRCK_EXT),
+ /* i2srx */
+@@ -299,11 +299,11 @@ static const struct jh71x0_clk_data jh7110_sysclk_data[] __initconst = {
+ JH71X0_MDIV(JH7110_SYSCLK_I2SRX_LRCK_MST, "i2srx_lrck_mst", 64, 2,
+ JH7110_SYSCLK_I2SRX_BCLK_MST_INV,
+ JH7110_SYSCLK_I2SRX_BCLK_MST),
+- JH71X0__MUX(JH7110_SYSCLK_I2SRX_BCLK, "i2srx_bclk", 2,
++ JH71X0__MUX(JH7110_SYSCLK_I2SRX_BCLK, "i2srx_bclk", 0, 2,
+ JH7110_SYSCLK_I2SRX_BCLK_MST,
+ JH7110_SYSCLK_I2SRX_BCLK_EXT),
+ JH71X0__INV(JH7110_SYSCLK_I2SRX_BCLK_INV, "i2srx_bclk_inv", JH7110_SYSCLK_I2SRX_BCLK),
+- JH71X0__MUX(JH7110_SYSCLK_I2SRX_LRCK, "i2srx_lrck", 2,
++ JH71X0__MUX(JH7110_SYSCLK_I2SRX_LRCK, "i2srx_lrck", 0, 2,
+ JH7110_SYSCLK_I2SRX_LRCK_MST,
+ JH7110_SYSCLK_I2SRX_LRCK_EXT),
+ /* pdm */
+@@ -313,7 +313,7 @@ static const struct jh71x0_clk_data jh7110_sysclk_data[] __initconst = {
+ JH71X0_GATE(JH7110_SYSCLK_TDM_AHB, "tdm_ahb", 0, JH7110_SYSCLK_AHB0),
+ JH71X0_GATE(JH7110_SYSCLK_TDM_APB, "tdm_apb", 0, JH7110_SYSCLK_APB0),
+ JH71X0_GDIV(JH7110_SYSCLK_TDM_INTERNAL, "tdm_internal", 0, 64, JH7110_SYSCLK_MCLK),
+- JH71X0__MUX(JH7110_SYSCLK_TDM_TDM, "tdm_tdm", 2,
++ JH71X0__MUX(JH7110_SYSCLK_TDM_TDM, "tdm_tdm", 0, 2,
+ JH7110_SYSCLK_TDM_INTERNAL,
+ JH7110_SYSCLK_TDM_EXT),
+ JH71X0__INV(JH7110_SYSCLK_TDM_TDM_INV, "tdm_tdm_inv", JH7110_SYSCLK_TDM_TDM),
+diff --git a/drivers/clk/starfive/clk-starfive-jh71x0.h b/drivers/clk/starfive/clk-starfive-jh71x0.h
+index 34bb11c72eb7..23e052fc1549 100644
+--- a/drivers/clk/starfive/clk-starfive-jh71x0.h
++++ b/drivers/clk/starfive/clk-starfive-jh71x0.h
+@@ -61,10 +61,10 @@ struct jh71x0_clk_data {
+ .parents = { [0] = _parent }, \
+ }
+
+-#define JH71X0__MUX(_idx, _name, _nparents, ...) \
++#define JH71X0__MUX(_idx, _name, _flags, _nparents, ...) \
+ [_idx] = { \
+ .name = _name, \
+- .flags = 0, \
++ .flags = _flags, \
+ .max = ((_nparents) - 1) << JH71X0_CLK_MUX_SHIFT, \
+ .parents = { __VA_ARGS__ }, \
+ }
+--
+2.20.1
+
--- /dev/null
+From 71c2e72e58bd520e8dac34b32d670e73b1ce6b36 Mon Sep 17 00:00:00 2001
+From: Emil Renner Berthing <emil.renner.berthing@canonical.com>
+Date: Sat, 25 Mar 2023 23:04:31 +0100
+Subject: [PATCH 130/132] clk: starfive: jh7100: Add CLK_SET_RATE_PARENT to
+ gmac_tx
+
+This is needed by the dwmac-starfive ethernet driver to set the clock
+for 1000, 100 and 10 Mbps links properly.
+
+Signed-off-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
+---
+ drivers/clk/starfive/clk-starfive-jh7100.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/clk/starfive/clk-starfive-jh7100.c b/drivers/clk/starfive/clk-starfive-jh7100.c
+index d3b260c01d5c..03f6f26a15d8 100644
+--- a/drivers/clk/starfive/clk-starfive-jh7100.c
++++ b/drivers/clk/starfive/clk-starfive-jh7100.c
+@@ -200,7 +200,7 @@ static const struct jh71x0_clk_data jh7100_clk_data[] __initconst = {
+ JH71X0_GDIV(JH7100_CLK_GMAC_GTX, "gmac_gtxclk", 0, 255, JH7100_CLK_GMAC_ROOT_DIV),
+ JH71X0_GDIV(JH7100_CLK_GMAC_RMII_TX, "gmac_rmii_txclk", 0, 8, JH7100_CLK_GMAC_RMII_REF),
+ JH71X0_GDIV(JH7100_CLK_GMAC_RMII_RX, "gmac_rmii_rxclk", 0, 8, JH7100_CLK_GMAC_RMII_REF),
+- JH71X0__MUX(JH7100_CLK_GMAC_TX, "gmac_tx", 0, 3,
++ JH71X0__MUX(JH7100_CLK_GMAC_TX, "gmac_tx", CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT, 3,
+ JH7100_CLK_GMAC_GTX,
+ JH7100_CLK_GMAC_TX_INV,
+ JH7100_CLK_GMAC_RMII_TX),
+--
+2.20.1
+
--- /dev/null
+From a46e9f1b2d57fa7cd5b1b9185165e755e3145b96 Mon Sep 17 00:00:00 2001
+From: Emil Renner Berthing <kernel@esmil.dk>
+Date: Thu, 14 Oct 2021 20:35:43 +0200
+Subject: [PATCH 131/132] clk: starfive: jh7100: Keep more clocks alive
+
+Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
+---
+ drivers/clk/starfive/clk-starfive-jh7100.c | 37 +++++++++++-----------
+ 1 file changed, 19 insertions(+), 18 deletions(-)
+
+diff --git a/drivers/clk/starfive/clk-starfive-jh7100.c b/drivers/clk/starfive/clk-starfive-jh7100.c
+index 03f6f26a15d8..1ee495a9af52 100644
+--- a/drivers/clk/starfive/clk-starfive-jh7100.c
++++ b/drivers/clk/starfive/clk-starfive-jh7100.c
+@@ -94,9 +94,9 @@ static const struct jh71x0_clk_data jh7100_clk_data[] __initconst = {
+ JH71X0_GATE(JH7100_CLK_DMA2PNOC_AXI, "dma2pnoc_axi", 0, JH7100_CLK_CPU_AXI),
+ JH71X0_GATE(JH7100_CLK_SGDMA2P_AHB, "sgdma2p_ahb", 0, JH7100_CLK_AHB_BUS),
+ JH71X0__DIV(JH7100_CLK_DLA_BUS, "dla_bus", 4, JH7100_CLK_DLA_ROOT),
+- JH71X0_GATE(JH7100_CLK_DLA_AXI, "dla_axi", 0, JH7100_CLK_DLA_BUS),
+- JH71X0_GATE(JH7100_CLK_DLANOC_AXI, "dlanoc_axi", 0, JH7100_CLK_DLA_BUS),
+- JH71X0_GATE(JH7100_CLK_DLA_APB, "dla_apb", 0, JH7100_CLK_APB1_BUS),
++ JH71X0_GATE(JH7100_CLK_DLA_AXI, "dla_axi", CLK_IGNORE_UNUSED, JH7100_CLK_DLA_BUS),
++ JH71X0_GATE(JH7100_CLK_DLANOC_AXI, "dlanoc_axi", CLK_IGNORE_UNUSED, JH7100_CLK_DLA_BUS),
++ JH71X0_GATE(JH7100_CLK_DLA_APB, "dla_apb", CLK_IGNORE_UNUSED, JH7100_CLK_APB1_BUS),
+ JH71X0_GDIV(JH7100_CLK_VP6_CORE, "vp6_core", 0, 4, JH7100_CLK_DSP_ROOT_DIV),
+ JH71X0__DIV(JH7100_CLK_VP6BUS_SRC, "vp6bus_src", 4, JH7100_CLK_DSP_ROOT),
+ JH71X0_GDIV(JH7100_CLK_VP6_AXI, "vp6_axi", 0, 4, JH7100_CLK_VP6BUS_SRC),
+@@ -160,11 +160,12 @@ static const struct jh71x0_clk_data jh7100_clk_data[] __initconst = {
+ JH71X0_GATE(JH7100_CLK_DMA1P_AXI, "dma1p_axi", 0, JH7100_CLK_SGDMA1P_BUS),
+ JH71X0_GDIV(JH7100_CLK_X2C_AXI, "x2c_axi", CLK_IS_CRITICAL, 8, JH7100_CLK_CPUNBUS_ROOT_DIV),
+ JH71X0__DIV(JH7100_CLK_USB_BUS, "usb_bus", 8, JH7100_CLK_CPUNBUS_ROOT_DIV),
+- JH71X0_GATE(JH7100_CLK_USB_AXI, "usb_axi", 0, JH7100_CLK_USB_BUS),
+- JH71X0_GATE(JH7100_CLK_USBNOC_AXI, "usbnoc_axi", 0, JH7100_CLK_USB_BUS),
++ JH71X0_GATE(JH7100_CLK_USB_AXI, "usb_axi", CLK_IGNORE_UNUSED, JH7100_CLK_USB_BUS),
++ JH71X0_GATE(JH7100_CLK_USBNOC_AXI, "usbnoc_axi", CLK_IGNORE_UNUSED, JH7100_CLK_USB_BUS),
+ JH71X0__DIV(JH7100_CLK_USBPHY_ROOTDIV, "usbphy_rootdiv", 4, JH7100_CLK_GMACUSB_ROOT),
+- JH71X0_GDIV(JH7100_CLK_USBPHY_125M, "usbphy_125m", 0, 8, JH7100_CLK_USBPHY_ROOTDIV),
+- JH71X0_GDIV(JH7100_CLK_USBPHY_PLLDIV25M, "usbphy_plldiv25m", 0, 32,
++ JH71X0_GDIV(JH7100_CLK_USBPHY_125M, "usbphy_125m", CLK_IGNORE_UNUSED, 8,
++ JH7100_CLK_USBPHY_ROOTDIV),
++ JH71X0_GDIV(JH7100_CLK_USBPHY_PLLDIV25M, "usbphy_plldiv25m", CLK_IGNORE_UNUSED, 32,
+ JH7100_CLK_USBPHY_ROOTDIV),
+ JH71X0__MUX(JH7100_CLK_USBPHY_25M, "usbphy_25m", 0, 2,
+ JH7100_CLK_OSC_SYS,
+@@ -183,23 +184,23 @@ static const struct jh71x0_clk_data jh7100_clk_data[] __initconst = {
+ JH71X0__DIV(JH7100_CLK_VIN_BUS, "vin_bus", 8, JH7100_CLK_VIN_SRC),
+ JH71X0_GATE(JH7100_CLK_VIN_AXI, "vin_axi", 0, JH7100_CLK_VIN_BUS),
+ JH71X0_GATE(JH7100_CLK_VINNOC_AXI, "vinnoc_axi", 0, JH7100_CLK_VIN_BUS),
+- JH71X0_GDIV(JH7100_CLK_VOUT_SRC, "vout_src", 0, 4, JH7100_CLK_VOUT_ROOT),
++ JH71X0_GDIV(JH7100_CLK_VOUT_SRC, "vout_src", CLK_IGNORE_UNUSED, 4, JH7100_CLK_VOUT_ROOT),
+ JH71X0__DIV(JH7100_CLK_DISPBUS_SRC, "dispbus_src", 4, JH7100_CLK_VOUTBUS_ROOT),
+ JH71X0__DIV(JH7100_CLK_DISP_BUS, "disp_bus", 4, JH7100_CLK_DISPBUS_SRC),
+- JH71X0_GATE(JH7100_CLK_DISP_AXI, "disp_axi", 0, JH7100_CLK_DISP_BUS),
+- JH71X0_GATE(JH7100_CLK_DISPNOC_AXI, "dispnoc_axi", 0, JH7100_CLK_DISP_BUS),
++ JH71X0_GATE(JH7100_CLK_DISP_AXI, "disp_axi", CLK_IGNORE_UNUSED, JH7100_CLK_DISP_BUS),
++ JH71X0_GATE(JH7100_CLK_DISPNOC_AXI, "dispnoc_axi", CLK_IGNORE_UNUSED, JH7100_CLK_DISP_BUS),
+ JH71X0_GATE(JH7100_CLK_SDIO0_AHB, "sdio0_ahb", 0, JH7100_CLK_AHB_BUS),
+ JH71X0_GDIV(JH7100_CLK_SDIO0_CCLKINT, "sdio0_cclkint", 0, 24, JH7100_CLK_PERH0_SRC),
+ JH71X0__INV(JH7100_CLK_SDIO0_CCLKINT_INV, "sdio0_cclkint_inv", JH7100_CLK_SDIO0_CCLKINT),
+ JH71X0_GATE(JH7100_CLK_SDIO1_AHB, "sdio1_ahb", 0, JH7100_CLK_AHB_BUS),
+ JH71X0_GDIV(JH7100_CLK_SDIO1_CCLKINT, "sdio1_cclkint", 0, 24, JH7100_CLK_PERH1_SRC),
+ JH71X0__INV(JH7100_CLK_SDIO1_CCLKINT_INV, "sdio1_cclkint_inv", JH7100_CLK_SDIO1_CCLKINT),
+- JH71X0_GATE(JH7100_CLK_GMAC_AHB, "gmac_ahb", 0, JH7100_CLK_AHB_BUS),
++ JH71X0_GATE(JH7100_CLK_GMAC_AHB, "gmac_ahb", CLK_IGNORE_UNUSED, JH7100_CLK_AHB_BUS),
+ JH71X0__DIV(JH7100_CLK_GMAC_ROOT_DIV, "gmac_root_div", 8, JH7100_CLK_GMACUSB_ROOT),
+- JH71X0_GDIV(JH7100_CLK_GMAC_PTP_REF, "gmac_ptp_refclk", 0, 31, JH7100_CLK_GMAC_ROOT_DIV),
+- JH71X0_GDIV(JH7100_CLK_GMAC_GTX, "gmac_gtxclk", 0, 255, JH7100_CLK_GMAC_ROOT_DIV),
+- JH71X0_GDIV(JH7100_CLK_GMAC_RMII_TX, "gmac_rmii_txclk", 0, 8, JH7100_CLK_GMAC_RMII_REF),
+- JH71X0_GDIV(JH7100_CLK_GMAC_RMII_RX, "gmac_rmii_rxclk", 0, 8, JH7100_CLK_GMAC_RMII_REF),
++ JH71X0_GDIV(JH7100_CLK_GMAC_PTP_REF, "gmac_ptp_refclk", CLK_IGNORE_UNUSED, 31, JH7100_CLK_GMAC_ROOT_DIV),
++ JH71X0_GDIV(JH7100_CLK_GMAC_GTX, "gmac_gtxclk", CLK_IGNORE_UNUSED, 255, JH7100_CLK_GMAC_ROOT_DIV),
++ JH71X0_GDIV(JH7100_CLK_GMAC_RMII_TX, "gmac_rmii_txclk", CLK_IGNORE_UNUSED, 8, JH7100_CLK_GMAC_RMII_REF),
++ JH71X0_GDIV(JH7100_CLK_GMAC_RMII_RX, "gmac_rmii_rxclk", CLK_IGNORE_UNUSED, 8, JH7100_CLK_GMAC_RMII_REF),
+ JH71X0__MUX(JH7100_CLK_GMAC_TX, "gmac_tx", CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT, 3,
+ JH7100_CLK_GMAC_GTX,
+ JH7100_CLK_GMAC_TX_INV,
+@@ -209,8 +210,8 @@ static const struct jh71x0_clk_data jh7100_clk_data[] __initconst = {
+ JH7100_CLK_GMAC_GR_MII_RX,
+ JH7100_CLK_GMAC_RMII_RX),
+ JH71X0__INV(JH7100_CLK_GMAC_RX_INV, "gmac_rx_inv", JH7100_CLK_GMAC_RX_PRE),
+- JH71X0_GATE(JH7100_CLK_GMAC_RMII, "gmac_rmii", 0, JH7100_CLK_GMAC_RMII_REF),
+- JH71X0_GDIV(JH7100_CLK_GMAC_TOPHYREF, "gmac_tophyref", 0, 127, JH7100_CLK_GMAC_ROOT_DIV),
++ JH71X0_GATE(JH7100_CLK_GMAC_RMII, "gmac_rmii", CLK_IGNORE_UNUSED, JH7100_CLK_GMAC_RMII_REF),
++ JH71X0_GDIV(JH7100_CLK_GMAC_TOPHYREF, "gmac_tophyref", CLK_IGNORE_UNUSED, 127, JH7100_CLK_GMAC_ROOT_DIV),
+ JH71X0_GATE(JH7100_CLK_SPI2AHB_AHB, "spi2ahb_ahb", 0, JH7100_CLK_AHB_BUS),
+ JH71X0_GDIV(JH7100_CLK_SPI2AHB_CORE, "spi2ahb_core", 0, 31, JH7100_CLK_PERH0_SRC),
+ JH71X0_GATE(JH7100_CLK_EZMASTER_AHB, "ezmaster_ahb", 0, JH7100_CLK_AHB_BUS),
+@@ -223,7 +224,7 @@ static const struct jh71x0_clk_data jh7100_clk_data[] __initconst = {
+ JH71X0_GATE(JH7100_CLK_AES, "aes_clk", 0, JH7100_CLK_SEC_AHB),
+ JH71X0_GATE(JH7100_CLK_SHA, "sha_clk", 0, JH7100_CLK_SEC_AHB),
+ JH71X0_GATE(JH7100_CLK_PKA, "pka_clk", 0, JH7100_CLK_SEC_AHB),
+- JH71X0_GATE(JH7100_CLK_TRNG_APB, "trng_apb", 0, JH7100_CLK_APB1_BUS),
++ JH71X0_GATE(JH7100_CLK_TRNG_APB, "trng_apb", CLK_IGNORE_UNUSED, JH7100_CLK_APB1_BUS),
+ JH71X0_GATE(JH7100_CLK_OTP_APB, "otp_apb", 0, JH7100_CLK_APB1_BUS),
+ JH71X0_GATE(JH7100_CLK_UART0_APB, "uart0_apb", 0, JH7100_CLK_APB1_BUS),
+ JH71X0_GDIV(JH7100_CLK_UART0_CORE, "uart0_core", 0, 63, JH7100_CLK_PERH1_SRC),
+--
+2.20.1
+
--- /dev/null
+From 5ebc1821dc78d22bdd1f2b3713b6a77823bb063d Mon Sep 17 00:00:00 2001
+From: Matteo Croce <technoboy85@gmail.com>
+Date: Fri, 21 May 2021 03:26:38 +0200
+Subject: [PATCH 132/132] net: stmmac: use GFP_DMA32
+
+Signed-off-by: Matteo Croce <mcroce@microsoft.com>
+---
+ drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+index 490315723062..059f980cb175 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+@@ -1436,7 +1436,7 @@ static int stmmac_init_rx_buffers(struct stmmac_priv *priv,
+ {
+ struct stmmac_rx_queue *rx_q = &dma_conf->rx_queue[queue];
+ struct stmmac_rx_buffer *buf = &rx_q->buf_pool[i];
+- gfp_t gfp = (GFP_ATOMIC | __GFP_NOWARN);
++ gfp_t gfp = (GFP_ATOMIC | __GFP_NOWARN | GFP_DMA32);
+
+ if (priv->dma_cap.host_dma_width <= 32)
+ gfp |= GFP_DMA32;
+@@ -4592,7 +4592,7 @@ static inline void stmmac_rx_refill(struct stmmac_priv *priv, u32 queue)
+ struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue];
+ int dirty = stmmac_rx_dirty(priv, queue);
+ unsigned int entry = rx_q->dirty_rx;
+- gfp_t gfp = (GFP_ATOMIC | __GFP_NOWARN);
++ gfp_t gfp = (GFP_ATOMIC | __GFP_NOWARN | GFP_DMA32);
+
+ if (priv->dma_cap.host_dma_width <= 32)
+ gfp |= GFP_DMA32;
+--
+2.20.1
+
--- /dev/null
+From 7543930bf426a524655b2001d92feb62793dac5a Mon Sep 17 00:00:00 2001
+From: Huan Feng <huan.feng@starfivetech.com>
+Date: Fri, 8 Jan 2021 03:35:42 +0800
+Subject: [PATCH 133/135] hwrng: Add StarFive JH7100 Random Number Generator
+ driver
+
+Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
+---
+ drivers/char/hw_random/Kconfig | 13 ++
+ drivers/char/hw_random/Makefile | 1 +
+ drivers/char/hw_random/starfive-vic-rng.c | 256 ++++++++++++++++++++++
+ drivers/char/hw_random/starfive-vic-rng.h | 167 ++++++++++++++
+ 4 files changed, 437 insertions(+)
+ create mode 100644 drivers/char/hw_random/starfive-vic-rng.c
+ create mode 100644 drivers/char/hw_random/starfive-vic-rng.h
+
+diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig
+index be202959efa6..70df036537db 100644
+--- a/drivers/char/hw_random/Kconfig
++++ b/drivers/char/hw_random/Kconfig
+@@ -322,6 +322,19 @@ config HW_RANDOM_POWERNV
+
+ If unsure, say Y.
+
++config HW_RANDOM_STARFIVE_VIC
++ tristate "Starfive VIC Random Number Generator support"
++ depends on HW_RANDOM && (SOC_STARFIVE || COMPILE_TEST)
++ default SOC_STARFIVE
++ help
++ This driver provides kernel-side support for the Random Number
++ Generator hardware found on Starfive VIC SoC.
++
++ To compile this driver as a module, choose M here: the
++ module will be called starfive-vic-rng.
++
++ If unsure, say Y.
++
+ config HW_RANDOM_HISI
+ tristate "Hisilicon Random Number Generator support"
+ depends on HW_RANDOM && ARCH_HISI
+diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile
+index 09bde4a0f971..c73b28099660 100644
+--- a/drivers/char/hw_random/Makefile
++++ b/drivers/char/hw_random/Makefile
+@@ -28,6 +28,7 @@ obj-$(CONFIG_HW_RANDOM_OCTEON) += octeon-rng.o
+ obj-$(CONFIG_HW_RANDOM_NOMADIK) += nomadik-rng.o
+ obj-$(CONFIG_HW_RANDOM_PSERIES) += pseries-rng.o
+ obj-$(CONFIG_HW_RANDOM_POWERNV) += powernv-rng.o
++obj-$(CONFIG_HW_RANDOM_STARFIVE_VIC) += starfive-vic-rng.o
+ obj-$(CONFIG_HW_RANDOM_HISI) += hisi-rng.o
+ obj-$(CONFIG_HW_RANDOM_BCM2835) += bcm2835-rng.o
+ obj-$(CONFIG_HW_RANDOM_IPROC_RNG200) += iproc-rng200.o
+diff --git a/drivers/char/hw_random/starfive-vic-rng.c b/drivers/char/hw_random/starfive-vic-rng.c
+new file mode 100644
+index 000000000000..1e003b755a52
+--- /dev/null
++++ b/drivers/char/hw_random/starfive-vic-rng.c
+@@ -0,0 +1,256 @@
++/*
++ ******************************************************************************
++ * @file starfive-vic-rng.c
++ * @author StarFive Technology
++ * @version V1.0
++ * @date 08/13/2020
++ * @brief
++ ******************************************************************************
++ * @copy
++ *
++ * THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
++ * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
++ * TIME. AS A RESULT, STARFIVE SHALL NOT BE HELD LIABLE FOR ANY
++ * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
++ * FROM THE CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
++ * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
++ *
++ * COPYRIGHT 2020 Shanghai StarFive Technology Co., Ltd.
++ */
++#include <linux/err.h>
++#include <linux/kernel.h>
++#include <linux/hw_random.h>
++#include <linux/io.h>
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/platform_device.h>
++#include <linux/interrupt.h>
++#include <linux/random.h>
++
++#include "starfive-vic-rng.h"
++
++#define to_vic_rng(p) container_of(p, struct vic_rng, rng)
++
++struct vic_rng {
++ struct device *dev;
++ void __iomem *base;
++ struct hwrng rng;
++};
++
++static inline void vic_wait_till_idle(struct vic_rng *hrng)
++{
++ while(readl(hrng->base + VIC_STAT) & VIC_STAT_BUSY)
++ ;
++}
++
++static inline void vic_rng_irq_mask_clear(struct vic_rng *hrng)
++{
++ // clear register: ISTAT
++ u32 data = readl(hrng->base + VIC_ISTAT);
++ writel(data, hrng->base + VIC_ISTAT);
++ writel(0, hrng->base + VIC_ALARM);
++}
++
++static int vic_trng_cmd(struct vic_rng *hrng, u32 cmd) {
++ int res = 0;
++ // wait till idle
++ vic_wait_till_idle(hrng);
++ switch (cmd) {
++ case VIC_CTRL_CMD_NOP:
++ case VIC_CTRL_CMD_GEN_NOISE:
++ case VIC_CTRL_CMD_GEN_NONCE:
++ case VIC_CTRL_CMD_CREATE_STATE:
++ case VIC_CTRL_CMD_RENEW_STATE:
++ case VIC_CTRL_CMD_REFRESH_ADDIN:
++ case VIC_CTRL_CMD_GEN_RANDOM:
++ case VIC_CTRL_CMD_ADVANCE_STATE:
++ case VIC_CTRL_CMD_KAT:
++ case VIC_CTRL_CMD_ZEROIZE:
++ writel(cmd, hrng->base + VIC_CTRL);
++ break;
++ default:
++ res = -1;
++ break;
++ }
++
++ return res;
++}
++
++static int vic_rng_init(struct hwrng *rng)
++{
++ struct vic_rng *hrng = to_vic_rng(rng);
++
++ // wait till idle
++
++ // clear register: ISTAT
++ vic_rng_irq_mask_clear(hrng);
++
++ // set mission mode
++ writel(VIC_SMODE_SECURE_EN(1), hrng->base + VIC_SMODE);
++
++ vic_trng_cmd(hrng, VIC_CTRL_CMD_GEN_NOISE);
++ vic_wait_till_idle(hrng);
++
++ // set interrupt
++ writel(VIC_IE_ALL, hrng->base + VIC_IE);
++
++ // zeroize
++ vic_trng_cmd(hrng, VIC_CTRL_CMD_ZEROIZE);
++
++ vic_wait_till_idle(hrng);
++
++ return 0;
++}
++
++static irqreturn_t vic_rng_irq(int irq, void *priv)
++{
++ u32 status, val;
++ struct vic_rng *hrng = (struct vic_rng *)priv;
++
++ /*
++ * clearing the interrupt will also clear the error register
++ * read error and status before clearing
++ */
++ status = readl(hrng->base + VIC_ISTAT);
++
++ if (status & VIC_ISTAT_ALARMS) {
++ writel(VIC_ISTAT_ALARMS, hrng->base + VIC_ISTAT);
++ val = readl(hrng->base + VIC_ALARM);
++ if (val & VIC_ALARM_ILLEGAL_CMD_SEQ) {
++ writel(VIC_ALARM_ILLEGAL_CMD_SEQ, hrng->base + VIC_ALARM);
++ //dev_info(hrng->dev, "ILLEGAL CMD SEQ: LAST_CMD=0x%x\r\n",
++ //VIC_STAT_LAST_CMD(readl(hrng->base + VIC_STAT)));
++ } else {
++ dev_info(hrng->dev, "Failed test: %x\r\n", val);
++ }
++ }
++
++ if (status & VIC_ISTAT_ZEROIZE) {
++ writel(VIC_ISTAT_ZEROIZE, hrng->base + VIC_ISTAT);
++ //dev_info(hrng->dev, "zeroized\r\n");
++ }
++
++ if (status & VIC_ISTAT_KAT_COMPLETE) {
++ writel(VIC_ISTAT_KAT_COMPLETE, hrng->base + VIC_ISTAT);
++ //dev_info(hrng->dev, "kat_completed\r\n");
++ }
++
++ if (status & VIC_ISTAT_NOISE_RDY) {
++ writel(VIC_ISTAT_NOISE_RDY, hrng->base + VIC_ISTAT);
++ //dev_info(hrng->dev, "noise_rdy\r\n");
++ }
++
++ if (status & VIC_ISTAT_DONE) {
++ writel(VIC_ISTAT_DONE, hrng->base + VIC_ISTAT);
++ //dev_info(hrng->dev, "done\r\n");
++ /*
++ if (VIC_STAT_LAST_CMD(readl(hrng->base + VIC_STAT)) ==
++ VIC_CTRL_CMD_GEN_RANDOM) {
++ dev_info(hrng->dev, "Need Update Buffer\r\n");
++ }
++ */
++ }
++ vic_rng_irq_mask_clear(hrng);
++
++ return IRQ_HANDLED;
++}
++
++static void vic_rng_cleanup(struct hwrng *rng)
++{
++ struct vic_rng *hrng = to_vic_rng(rng);
++
++ writel(0, hrng->base + VIC_CTRL);
++}
++
++static int vic_rng_read(struct hwrng *rng, void *buf, size_t max, bool wait)
++{
++ struct vic_rng *hrng = to_vic_rng(rng);
++
++ vic_trng_cmd(hrng, VIC_CTRL_CMD_ZEROIZE);
++ vic_trng_cmd(hrng, VIC_CTRL_CMD_GEN_NOISE);
++ vic_trng_cmd(hrng, VIC_CTRL_CMD_CREATE_STATE);
++
++ vic_wait_till_idle(hrng);
++ max = min_t(size_t, max, (VIC_RAND_LEN * 4));
++
++ writel(0x0, hrng->base + VIC_MODE);
++ vic_trng_cmd(hrng, VIC_CTRL_CMD_GEN_RANDOM);
++
++ vic_wait_till_idle(hrng);
++ memcpy_fromio(buf, hrng->base + VIC_RAND0, max);
++ vic_trng_cmd(hrng, VIC_CTRL_CMD_ZEROIZE);
++
++ vic_wait_till_idle(hrng);
++ return max;
++}
++
++static int vic_rng_probe(struct platform_device *pdev)
++{
++ int ret;
++ int irq;
++ struct vic_rng *rng;
++ struct resource *res;
++
++ rng = devm_kzalloc(&pdev->dev, sizeof(*rng), GFP_KERNEL);
++ if (!rng){
++ return -ENOMEM;
++ }
++
++ platform_set_drvdata(pdev, rng);
++
++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ rng->base = devm_ioremap_resource(&pdev->dev, res);
++ if (IS_ERR(rng->base)){
++ return PTR_ERR(rng->base);
++ }
++
++ irq = platform_get_irq(pdev, 0);
++ if (irq <= 0) {
++ dev_err(&pdev->dev, "Couldn't get irq %d\n", irq);
++ return irq;
++ }
++
++ ret = devm_request_irq(&pdev->dev, irq, vic_rng_irq, 0, pdev->name,
++ (void *)rng);
++ if (ret) {
++ dev_err(&pdev->dev, "Can't get interrupt working.\n");
++ return ret;
++ }
++
++ rng->rng.name = pdev->name;
++ rng->rng.init = vic_rng_init;
++ rng->rng.cleanup = vic_rng_cleanup;
++ rng->rng.read = vic_rng_read;
++
++ rng->dev = &pdev->dev;
++
++ ret = devm_hwrng_register(&pdev->dev, &rng->rng);
++ if (ret) {
++ dev_err(&pdev->dev, "failed to register hwrng\n");
++ return ret;
++ }
++
++ dev_info(&pdev->dev, "Initialized\n");
++
++ return 0;
++}
++
++static const struct of_device_id vic_rng_dt_ids[] = {
++ { .compatible = "starfive,vic-rng" },
++ { }
++};
++MODULE_DEVICE_TABLE(of, vic_rng_dt_ids);
++
++static struct platform_driver vic_rng_driver = {
++ .probe = vic_rng_probe,
++ .driver = {
++ .name = "vic-rng",
++ .of_match_table = vic_rng_dt_ids,
++ },
++};
++
++module_platform_driver(vic_rng_driver);
++
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Huan Feng <huan.feng@starfivetech.com>");
++MODULE_DESCRIPTION("Starfive VIC random number generator driver");
+diff --git a/drivers/char/hw_random/starfive-vic-rng.h b/drivers/char/hw_random/starfive-vic-rng.h
+new file mode 100644
+index 000000000000..b3bbabde0cfb
+--- /dev/null
++++ b/drivers/char/hw_random/starfive-vic-rng.h
+@@ -0,0 +1,167 @@
++/*
++ ******************************************************************************
++ * @file starfive-vic-rng.h
++ * @author StarFive Technology
++ * @version V1.0
++ * @date 08/13/2020
++ * @brief
++ ******************************************************************************
++ * @copy
++ *
++ * THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
++ * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
++ * TIME. AS A RESULT, STARFIVE SHALL NOT BE HELD LIABLE FOR ANY
++ * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
++ * FROM THE CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
++ * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
++ *
++ * COPYRIGHT 2020 Shanghai StarFive Technology Co., Ltd.
++ */
++
++#define VIC_CTRL 0x00
++#define VIC_MODE 0x04
++#define VIC_SMODE 0x08
++#define VIC_STAT 0x0C
++#define VIC_IE 0x10
++#define VIC_ISTAT 0x14
++#define VIC_ALARM 0x18
++#define VIC_BUILD_ID 0x1C
++#define VIC_FEATURES 0x20
++#define VIC_RAND0 0x24
++#define VIC_NPA_DATA0 0x34
++#define VIC_SEED0 0x74
++#define VIC_IA_RDATA 0xA4
++#define VIC_IA_WDATA 0xA8
++#define VIC_IA_ADDR 0xAC
++#define VIC_IA_CMD 0xB0
++
++/* CTRL */
++#define VIC_CTRL_CMD_NOP 0
++#define VIC_CTRL_CMD_GEN_NOISE 1
++#define VIC_CTRL_CMD_GEN_NONCE 2
++#define VIC_CTRL_CMD_CREATE_STATE 3
++#define VIC_CTRL_CMD_RENEW_STATE 4
++#define VIC_CTRL_CMD_REFRESH_ADDIN 5
++#define VIC_CTRL_CMD_GEN_RANDOM 6
++#define VIC_CTRL_CMD_ADVANCE_STATE 7
++#define VIC_CTRL_CMD_KAT 8
++#define VIC_CTRL_CMD_ZEROIZE 15
++
++/* MODE */
++#define _VIC_MODE_ADDIN_PRESENT 4
++#define _VIC_MODE_PRED_RESIST 3
++#define _VIC_MODE_KAT_SEL 2
++#define _VIC_MODE_KAT_VEC 1
++#define _VIC_MODE_SEC_ALG 0
++
++#define VIC_MODE_ADDIN_PRESENT (1UL << _VIC_MODE_ADDIN_PRESENT)
++#define VIC_MODE_PRED_RESIST (1UL << _VIC_MODE_PRED_RESIST)
++#define VIC_MODE_KAT_SEL (1UL << _VIC_MODE_KAT_SEL)
++#define VIC_MODE_KAT_VEC (1UL << _VIC_MODE_KAT_VEC)
++#define VIC_MODE_SEC_ALG (1UL << _VIC_MODE_SEC_ALG)
++
++/* SMODE */
++#define _VIC_SMODE_MAX_REJECTS 2
++#define _VIC_SMODE_SECURE_EN 1
++#define _VIC_SMODE_NONCE 0
++
++#define VIC_SMODE_MAX_REJECTS(x) ((x) << _VIC_SMODE_MAX_REJECTS)
++#define VIC_SMODE_SECURE_EN(x) ((x) << _VIC_SMODE_SECURE_EN)
++#define VIC_SMODE_NONCE (1UL << _VIC_SMODE_NONCE)
++
++/* STAT */
++#define _VIC_STAT_BUSY 31
++#define _VIC_STAT_DRBG_STATE 7
++#define _VIC_STAT_SECURE 6
++#define _VIC_STAT_NONCE_MODE 5
++#define _VIC_STAT_SEC_ALG 4
++#define _VIC_STAT_LAST_CMD 0
++
++#define VIC_STAT_BUSY (1UL << _VIC_STAT_BUSY)
++#define VIC_STAT_DRBG_STATE (1UL << _VIC_STAT_DRBG_STATE)
++#define VIC_STAT_SECURE (1UL << _VIC_STAT_SECURE)
++#define VIC_STAT_NONCE_MODE (1UL << _VIC_STAT_NONCE_MODE)
++#define VIC_STAT_SEC_ALG (1UL << _VIC_STAT_SEC_ALG)
++#define VIC_STAT_LAST_CMD(x) (((x) >> _VIC_STAT_LAST_CMD) & 0xF)
++
++/* IE */
++#define _VIC_IE_GLBL 31
++#define _VIC_IE_DONE 4
++#define _VIC_IE_ALARMS 3
++#define _VIC_IE_NOISE_RDY 2
++#define _VIC_IE_KAT_COMPLETE 1
++#define _VIC_IE_ZEROIZE 0
++
++#define VIC_IE_GLBL (1UL << _VIC_IE_GLBL)
++#define VIC_IE_DONE (1UL << _VIC_IE_DONE)
++#define VIC_IE_ALARMS (1UL << _VIC_IE_ALARMS)
++#define VIC_IE_NOISE_RDY (1UL << _VIC_IE_NOISE_RDY)
++#define VIC_IE_KAT_COMPLETE (1UL << _VIC_IE_KAT_COMPLETE)
++#define VIC_IE_ZEROIZE (1UL << _VIC_IE_ZEROIZE)
++#define VIC_IE_ALL (VIC_IE_GLBL | VIC_IE_DONE | VIC_IE_ALARMS | \
++ VIC_IE_NOISE_RDY | VIC_IE_KAT_COMPLETE | VIC_IE_ZEROIZE)
++
++/* ISTAT */
++#define _VIC_ISTAT_DONE 4
++#define _VIC_ISTAT_ALARMS 3
++#define _VIC_ISTAT_NOISE_RDY 2
++#define _VIC_ISTAT_KAT_COMPLETE 1
++#define _VIC_ISTAT_ZEROIZE 0
++
++#define VIC_ISTAT_DONE (1UL << _VIC_ISTAT_DONE)
++#define VIC_ISTAT_ALARMS (1UL << _VIC_ISTAT_ALARMS)
++#define VIC_ISTAT_NOISE_RDY (1UL << _VIC_ISTAT_NOISE_RDY)
++#define VIC_ISTAT_KAT_COMPLETE (1UL << _VIC_ISTAT_KAT_COMPLETE)
++#define VIC_ISTAT_ZEROIZE (1UL << _VIC_ISTAT_ZEROIZE)
++
++/* ALARMS */
++#define VIC_ALARM_ILLEGAL_CMD_SEQ (1UL << 4)
++#define VIC_ALARM_FAILED_TEST_ID_OK 0
++#define VIC_ALARM_FAILED_TEST_ID_KAT_STAT 1
++#define VIC_ALARM_FAILED_TEST_ID_KAT 2
++#define VIC_ALARM_FAILED_TEST_ID_MONOBIT 3
++#define VIC_ALARM_FAILED_TEST_ID_RUN 4
++#define VIC_ALARM_FAILED_TEST_ID_LONGRUN 5
++#define VIC_ALARM_FAILED_TEST_ID_AUTOCORRELATION 6
++#define VIC_ALARM_FAILED_TEST_ID_POKER 7
++#define VIC_ALARM_FAILED_TEST_ID_REPETITION_COUNT 8
++#define VIC_ALARM_FAILED_TEST_ID_ADAPATIVE_PROPORTION 9
++
++/* BUILD_ID */
++#define VIC_BUILD_ID_STEPPING(x) (((x) >> 28) & 0xF)
++#define VIC_BUILD_ID_EPN(x) ((x) & 0xFFFF)
++
++/* FEATURES */
++#define VIC_FEATURES_AES_256(x) (((x) >> 9) & 1)
++#define VIC_FEATURES_EXTRA_PS_PRESENT(x) (((x) >> 8) & 1)
++#define VIC_FEATURES_DIAG_LEVEL_NS(x) (((x) >> 7) & 1)
++#define VIC_FEATURES_DIAG_LEVEL_CLP800(x) (((x) >> 4) & 7)
++#define VIC_FEATURES_DIAG_LEVEL_ST_HLT(x) (((x) >> 1) & 7)
++#define VIC_FEATURES_SECURE_RST_STATE(x) ((x) & 1)
++
++/* IA_CMD */
++#define VIC_IA_CMD_GO (1UL << 31)
++#define VIC_IA_CMD_WR (1)
++
++#define _VIC_SMODE_MAX_REJECTS_MASK 255UL
++#define _VIC_SMODE_SECURE_EN_MASK 1UL
++#define _VIC_SMODE_NONCE_MASK 1UL
++#define _VIC_MODE_SEC_ALG_MASK 1UL
++#define _VIC_MODE_ADDIN_PRESENT_MASK 1UL
++#define _VIC_MODE_PRED_RESIST_MASK 1UL
++
++#define VIC_SMODE_SET_MAX_REJECTS(y, x) (((y) & ~(_VIC_SMODE_MAX_REJECTS_MASK << _VIC_SMODE_MAX_REJECTS)) | ((x) << _VIC_SMODE_MAX_REJECTS))
++#define VIC_SMODE_SET_SECURE_EN(y, x) (((y) & ~(_VIC_SMODE_SECURE_EN_MASK << _VIC_SMODE_SECURE_EN)) | ((x) << _VIC_SMODE_SECURE_EN))
++#define VIC_SMODE_SET_NONCE(y, x) (((y) & ~(_VIC_SMODE_NONCE_MASK << _VIC_SMODE_NONCE)) | ((x) << _VIC_SMODE_NONCE))
++#define VIC_SMODE_GET_MAX_REJECTS(x) (((x) >> _VIC_SMODE_MAX_REJECTS) & _VIC_SMODE_MAX_REJECTS_MASK)
++#define VIC_SMODE_GET_SECURE_EN(x) (((x) >> _VIC_SMODE_SECURE_EN) & _VIC_SMODE_SECURE_EN_MASK)
++#define VIC_SMODE_GET_NONCE(x) (((x) >> _VIC_SMODE_NONCE) & _VIC_SMODE_NONCE_MASK)
++
++#define VIC_MODE_SET_SEC_ALG(y, x) (((y) & ~(_VIC_MODE_SEC_ALG_MASK << _VIC_MODE_SEC_ALG)) | ((x) << _VIC_MODE_SEC_ALG))
++#define VIC_MODE_SET_PRED_RESIST(y, x) (((y) & ~(_VIC_MODE_PRED_RESIST_MASK << _VIC_MODE_PRED_RESIST)) | ((x) << _VIC_MODE_PRED_RESIST))
++#define VIC_MODE_SET_ADDIN_PRESENT(y, x) (((y) & ~(_VIC_MODE_ADDIN_PRESENT_MASK << _VIC_MODE_ADDIN_PRESENT)) | ((x) << _VIC_MODE_ADDIN_PRESENT))
++#define VIC_MODE_GET_SEC_ALG(x) (((x) >> _VIC_MODE_SEC_ALG) & _VIC_MODE_SEC_ALG_MASK)
++#define VIC_MODE_GET_PRED_RESIST(x) (((x) >> _VIC_MODE_PRED_RESIST) & _VIC_MODE_PRED_RESIST_MASK)
++#define VIC_MODE_GET_ADDIN_PRESENT(x) (((x) >> _VIC_MODE_ADDIN_PRESENT) & _VIC_MODE_ADDIN_PRESENT_MASK)
++
++#define VIC_RAND_LEN 4
+--
+2.20.1
+
--- /dev/null
+From 4cccec247776311b3d7274368e890704d2d95c9d Mon Sep 17 00:00:00 2001
+From: Emil Renner Berthing <kernel@esmil.dk>
+Date: Sun, 6 Jun 2021 22:31:18 +0200
+Subject: [PATCH 134/135] hwmon: (sfctemp) Add StarFive JH71x0 temperature
+ sensor
+
+Register definitions and conversion constants based on sfctemp driver by
+Samin in the StarFive 5.10 kernel.
+
+Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
+Signed-off-by: Samin Guo <samin.guo@starfivetech.com>
+---
+ Documentation/hwmon/index.rst | 1 +
+ Documentation/hwmon/sfctemp.rst | 33 +++
+ MAINTAINERS | 8 +
+ drivers/hwmon/Kconfig | 10 +
+ drivers/hwmon/Makefile | 1 +
+ drivers/hwmon/sfctemp.c | 350 ++++++++++++++++++++++++++++++++
+ 6 files changed, 403 insertions(+)
+ create mode 100644 Documentation/hwmon/sfctemp.rst
+ create mode 100644 drivers/hwmon/sfctemp.c
+
+diff --git a/Documentation/hwmon/index.rst b/Documentation/hwmon/index.rst
+index c1d11cf13eef..f7ede608b6e3 100644
+--- a/Documentation/hwmon/index.rst
++++ b/Documentation/hwmon/index.rst
+@@ -179,6 +179,7 @@ Hardware Monitoring Kernel Drivers
+ sch5627
+ sch5636
+ scpi-hwmon
++ sfctemp
+ sht15
+ sht21
+ sht3x
+diff --git a/Documentation/hwmon/sfctemp.rst b/Documentation/hwmon/sfctemp.rst
+new file mode 100644
+index 000000000000..9fbd5bb1f356
+--- /dev/null
++++ b/Documentation/hwmon/sfctemp.rst
+@@ -0,0 +1,33 @@
++.. SPDX-License-Identifier: GPL-2.0
++
++Kernel driver sfctemp
++=====================
++
++Supported chips:
++ - StarFive JH7100
++ - StarFive JH7110
++
++Authors:
++ - Emil Renner Berthing <kernel@esmil.dk>
++
++Description
++-----------
++
++This driver adds support for reading the built-in temperature sensor on the
++JH7100 and JH7110 RISC-V SoCs by StarFive Technology Co. Ltd.
++
++``sysfs`` interface
++-------------------
++
++The temperature sensor can be enabled, disabled and queried via the standard
++hwmon interface in sysfs under ``/sys/class/hwmon/hwmonX`` for some value of
++``X``:
++
++================ ==== =============================================
++Name Perm Description
++================ ==== =============================================
++temp1_enable RW Enable or disable temperature sensor.
++ Automatically enabled by the driver,
++ but may be disabled to save power.
++temp1_input RO Temperature reading in milli-degrees Celsius.
++================ ==== =============================================
+diff --git a/MAINTAINERS b/MAINTAINERS
+index 99d8fe3a58f4..40aa981b3179 100644
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -18663,6 +18663,14 @@ L: netdev@vger.kernel.org
+ S: Supported
+ F: drivers/net/ethernet/sfc/
+
++SFCTEMP HWMON DRIVER
++M: Emil Renner Berthing <kernel@esmil.dk>
++L: linux-hwmon@vger.kernel.org
++S: Maintained
++F: Documentation/devicetree/bindings/hwmon/starfive,jh71x0-temp.yaml
++F: Documentation/hwmon/sfctemp.rst
++F: drivers/hwmon/sfctemp.c
++
+ SFF/SFP/SFP+ MODULE SUPPORT
+ M: Russell King <linux@armlinux.org.uk>
+ L: netdev@vger.kernel.org
+diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
+index a5143d01b95f..ebae09c46639 100644
+--- a/drivers/hwmon/Kconfig
++++ b/drivers/hwmon/Kconfig
+@@ -1911,6 +1911,16 @@ config SENSORS_STTS751
+ This driver can also be built as a module. If so, the module
+ will be called stts751.
+
++config SENSORS_SFCTEMP
++ tristate "Starfive JH71x0 temperature sensor"
++ depends on SOC_STARFIVE || COMPILE_TEST
++ help
++ If you say yes here you get support for temperature sensor
++ on the Starfive JH71x0 SoCs.
++
++ This driver can also be built as a module. If so, the module
++ will be called sfctemp.
++
+ config SENSORS_SMM665
+ tristate "Summit Microelectronics SMM665"
+ depends on I2C
+diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
+index 11d076cad8a2..5a4a02c5535c 100644
+--- a/drivers/hwmon/Makefile
++++ b/drivers/hwmon/Makefile
+@@ -179,6 +179,7 @@ obj-$(CONFIG_SENSORS_SBRMI) += sbrmi.o
+ obj-$(CONFIG_SENSORS_SCH56XX_COMMON)+= sch56xx-common.o
+ obj-$(CONFIG_SENSORS_SCH5627) += sch5627.o
+ obj-$(CONFIG_SENSORS_SCH5636) += sch5636.o
++obj-$(CONFIG_SENSORS_SFCTEMP) += sfctemp.o
+ obj-$(CONFIG_SENSORS_SL28CPLD) += sl28cpld-hwmon.o
+ obj-$(CONFIG_SENSORS_SHT15) += sht15.o
+ obj-$(CONFIG_SENSORS_SHT21) += sht21.o
+diff --git a/drivers/hwmon/sfctemp.c b/drivers/hwmon/sfctemp.c
+new file mode 100644
+index 000000000000..e56716ad9587
+--- /dev/null
++++ b/drivers/hwmon/sfctemp.c
+@@ -0,0 +1,350 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
++ * Copyright (C) 2021 Samin Guo <samin.guo@starfivetech.com>
++ */
++#include <linux/clk.h>
++#include <linux/completion.h>
++#include <linux/delay.h>
++#include <linux/hwmon.h>
++#include <linux/interrupt.h>
++#include <linux/io.h>
++#include <linux/module.h>
++#include <linux/mutex.h>
++#include <linux/of.h>
++#include <linux/platform_device.h>
++#include <linux/reset.h>
++
++/*
++ * TempSensor reset. The RSTN can be de-asserted once the analog core has
++ * powered up. Trst(min 100ns)
++ * 0:reset 1:de-assert
++ */
++#define SFCTEMP_RSTN BIT(0)
++
++/*
++ * TempSensor analog core power down. The analog core will be powered up
++ * Tpu(min 50us) after PD is de-asserted. RSTN should be held low until the
++ * analog core is powered up.
++ * 0:power up 1:power down
++ */
++#define SFCTEMP_PD BIT(1)
++
++/*
++ * TempSensor start conversion enable.
++ * 0:disable 1:enable
++ */
++#define SFCTEMP_RUN BIT(2)
++
++/*
++ * TempSensor conversion value output.
++ * Temp(C)=DOUT*Y/4094 - K
++ */
++#define SFCTEMP_DOUT_POS 16
++#define SFCTEMP_DOUT_MSK GENMASK(27, 16)
++
++/* DOUT to Celcius conversion constants */
++#define SFCTEMP_Y1000 237500L
++#define SFCTEMP_Z 4094L
++#define SFCTEMP_K1000 81100L
++
++struct sfctemp {
++ /* serialize access to hardware register and enabled below */
++ struct mutex lock;
++ struct completion conversion_done;
++ void __iomem *regs;
++ struct clk *clk_sense;
++ struct clk *clk_bus;
++ struct reset_control *rst_sense;
++ struct reset_control *rst_bus;
++ bool enabled;
++};
++
++static irqreturn_t sfctemp_isr(int irq, void *data)
++{
++ struct sfctemp *sfctemp = data;
++
++ complete(&sfctemp->conversion_done);
++ return IRQ_HANDLED;
++}
++
++static void sfctemp_power_up(struct sfctemp *sfctemp)
++{
++ /* make sure we're powered down first */
++ writel(SFCTEMP_PD, sfctemp->regs);
++ udelay(1);
++
++ writel(0, sfctemp->regs);
++ /* wait t_pu(50us) + t_rst(100ns) */
++ usleep_range(60, 200);
++
++ /* de-assert reset */
++ writel(SFCTEMP_RSTN, sfctemp->regs);
++ udelay(1); /* wait t_su(500ps) */
++}
++
++static void sfctemp_power_down(struct sfctemp *sfctemp)
++{
++ writel(SFCTEMP_PD, sfctemp->regs);
++}
++
++static void sfctemp_run_single(struct sfctemp *sfctemp)
++{
++ writel(SFCTEMP_RSTN | SFCTEMP_RUN, sfctemp->regs);
++ udelay(1);
++ writel(SFCTEMP_RSTN, sfctemp->regs);
++}
++
++static int sfctemp_enable(struct sfctemp *sfctemp)
++{
++ int ret = 0;
++
++ mutex_lock(&sfctemp->lock);
++ if (sfctemp->enabled)
++ goto done;
++
++ ret = clk_prepare_enable(sfctemp->clk_bus);
++ if (ret)
++ goto err;
++ ret = reset_control_deassert(sfctemp->rst_bus);
++ if (ret)
++ goto err_disable_bus;
++
++ ret = clk_prepare_enable(sfctemp->clk_sense);
++ if (ret)
++ goto err_assert_bus;
++ ret = reset_control_deassert(sfctemp->rst_sense);
++ if (ret)
++ goto err_disable_sense;
++
++ sfctemp_power_up(sfctemp);
++ sfctemp->enabled = true;
++done:
++ mutex_unlock(&sfctemp->lock);
++ return ret;
++
++err_disable_sense:
++ clk_disable_unprepare(sfctemp->clk_sense);
++err_assert_bus:
++ reset_control_assert(sfctemp->rst_bus);
++err_disable_bus:
++ clk_disable_unprepare(sfctemp->clk_bus);
++err:
++ mutex_unlock(&sfctemp->lock);
++ return ret;
++}
++
++static int sfctemp_disable(struct sfctemp *sfctemp)
++{
++ mutex_lock(&sfctemp->lock);
++ if (!sfctemp->enabled)
++ goto done;
++
++ sfctemp_power_down(sfctemp);
++ reset_control_assert(sfctemp->rst_sense);
++ clk_disable_unprepare(sfctemp->clk_sense);
++ reset_control_assert(sfctemp->rst_bus);
++ clk_disable_unprepare(sfctemp->clk_bus);
++ sfctemp->enabled = false;
++done:
++ mutex_unlock(&sfctemp->lock);
++ return 0;
++}
++
++static void sfctemp_disable_action(void *data)
++{
++ sfctemp_disable(data);
++}
++
++static int sfctemp_convert(struct sfctemp *sfctemp, long *val)
++{
++ int ret;
++
++ mutex_lock(&sfctemp->lock);
++ if (!sfctemp->enabled) {
++ ret = -ENODATA;
++ goto out;
++ }
++
++ sfctemp_run_single(sfctemp);
++
++ ret = wait_for_completion_interruptible_timeout(&sfctemp->conversion_done,
++ msecs_to_jiffies(10));
++ if (ret <= 0) {
++ if (ret == 0)
++ ret = -ETIMEDOUT;
++ goto out;
++ }
++
++ /* calculate temperature in milli Celcius */
++ *val = (long)((readl(sfctemp->regs) & SFCTEMP_DOUT_MSK) >> SFCTEMP_DOUT_POS)
++ * SFCTEMP_Y1000 / SFCTEMP_Z - SFCTEMP_K1000;
++
++ ret = 0;
++out:
++ mutex_unlock(&sfctemp->lock);
++ return ret;
++}
++
++static umode_t sfctemp_is_visible(const void *data, enum hwmon_sensor_types type,
++ u32 attr, int channel)
++{
++ switch (type) {
++ case hwmon_temp:
++ switch (attr) {
++ case hwmon_temp_enable:
++ return 0644;
++ case hwmon_temp_input:
++ return 0444;
++ }
++ return 0;
++ default:
++ return 0;
++ }
++}
++
++static int sfctemp_read(struct device *dev, enum hwmon_sensor_types type,
++ u32 attr, int channel, long *val)
++{
++ struct sfctemp *sfctemp = dev_get_drvdata(dev);
++
++ switch (type) {
++ case hwmon_temp:
++ switch (attr) {
++ case hwmon_temp_enable:
++ *val = sfctemp->enabled;
++ return 0;
++ case hwmon_temp_input:
++ return sfctemp_convert(sfctemp, val);
++ }
++ return -EINVAL;
++ default:
++ return -EINVAL;
++ }
++}
++
++static int sfctemp_write(struct device *dev, enum hwmon_sensor_types type,
++ u32 attr, int channel, long val)
++{
++ struct sfctemp *sfctemp = dev_get_drvdata(dev);
++
++ switch (type) {
++ case hwmon_temp:
++ switch (attr) {
++ case hwmon_temp_enable:
++ if (val == 0)
++ return sfctemp_disable(sfctemp);
++ if (val == 1)
++ return sfctemp_enable(sfctemp);
++ break;
++ }
++ return -EINVAL;
++ default:
++ return -EINVAL;
++ }
++}
++
++static const struct hwmon_channel_info *sfctemp_info[] = {
++ HWMON_CHANNEL_INFO(chip, HWMON_C_REGISTER_TZ),
++ HWMON_CHANNEL_INFO(temp, HWMON_T_ENABLE | HWMON_T_INPUT),
++ NULL
++};
++
++static const struct hwmon_ops sfctemp_hwmon_ops = {
++ .is_visible = sfctemp_is_visible,
++ .read = sfctemp_read,
++ .write = sfctemp_write,
++};
++
++static const struct hwmon_chip_info sfctemp_chip_info = {
++ .ops = &sfctemp_hwmon_ops,
++ .info = sfctemp_info,
++};
++
++static int sfctemp_probe(struct platform_device *pdev)
++{
++ struct device *dev = &pdev->dev;
++ struct device *hwmon_dev;
++ struct sfctemp *sfctemp;
++ int ret;
++
++ sfctemp = devm_kzalloc(dev, sizeof(*sfctemp), GFP_KERNEL);
++ if (!sfctemp)
++ return -ENOMEM;
++
++ dev_set_drvdata(dev, sfctemp);
++ mutex_init(&sfctemp->lock);
++ init_completion(&sfctemp->conversion_done);
++
++ sfctemp->regs = devm_platform_ioremap_resource(pdev, 0);
++ if (IS_ERR(sfctemp->regs))
++ return PTR_ERR(sfctemp->regs);
++
++ sfctemp->clk_sense = devm_clk_get(dev, "sense");
++ if (IS_ERR(sfctemp->clk_sense))
++ return dev_err_probe(dev, PTR_ERR(sfctemp->clk_sense),
++ "error getting sense clock\n");
++
++ sfctemp->clk_bus = devm_clk_get(dev, "bus");
++ if (IS_ERR(sfctemp->clk_bus))
++ return dev_err_probe(dev, PTR_ERR(sfctemp->clk_bus),
++ "error getting bus clock\n");
++
++ sfctemp->rst_sense = devm_reset_control_get_exclusive(dev, "sense");
++ if (IS_ERR(sfctemp->rst_sense))
++ return dev_err_probe(dev, PTR_ERR(sfctemp->rst_sense),
++ "error getting sense reset\n");
++
++ sfctemp->rst_bus = devm_reset_control_get_exclusive(dev, "bus");
++ if (IS_ERR(sfctemp->rst_bus))
++ return dev_err_probe(dev, PTR_ERR(sfctemp->rst_bus),
++ "error getting busreset\n");
++
++ ret = reset_control_assert(sfctemp->rst_sense);
++ if (ret)
++ return dev_err_probe(dev, ret, "error asserting sense reset\n");
++
++ ret = reset_control_assert(sfctemp->rst_bus);
++ if (ret)
++ return dev_err_probe(dev, ret, "error asserting bus reset\n");
++
++ ret = platform_get_irq(pdev, 0);
++ if (ret < 0)
++ return ret;
++
++ ret = devm_request_irq(dev, ret, sfctemp_isr, 0, pdev->name, sfctemp);
++ if (ret)
++ return dev_err_probe(dev, ret, "error requesting irq\n");
++
++ ret = devm_add_action(dev, sfctemp_disable_action, sfctemp);
++ if (ret)
++ return ret;
++
++ ret = sfctemp_enable(sfctemp);
++ if (ret)
++ return dev_err_probe(dev, ret, "error enabling temperature sensor: %d\n", ret);
++
++ hwmon_dev = devm_hwmon_device_register_with_info(dev, pdev->name, sfctemp,
++ &sfctemp_chip_info, NULL);
++ return PTR_ERR_OR_ZERO(hwmon_dev);
++}
++
++static const struct of_device_id sfctemp_of_match[] = {
++ { .compatible = "starfive,jh7100-temp" },
++ { .compatible = "starfive,jh7110-temp" },
++ { /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(of, sfctemp_of_match);
++
++static struct platform_driver sfctemp_driver = {
++ .probe = sfctemp_probe,
++ .driver = {
++ .name = "sfctemp",
++ .of_match_table = sfctemp_of_match,
++ },
++};
++module_platform_driver(sfctemp_driver);
++
++MODULE_AUTHOR("Emil Renner Berthing");
++MODULE_DESCRIPTION("StarFive JH71x0 temperature sensor driver");
++MODULE_LICENSE("GPL");
+--
+2.20.1
+
--- /dev/null
+From ed3579621603c9fa797f8a5d2981c5b8ac6cef7a Mon Sep 17 00:00:00 2001
+From: Chenjieqin <Jessica.Chen@starfivetech.com>
+Date: Fri, 8 Jan 2021 03:56:54 +0800
+Subject: [PATCH 135/135] pwm: sifive-ptc: Add SiFive PWM PTC driver
+
+yiming.li: clear CNTR of PWM after setting period & duty_cycle
+Emil: cleanups, clock, reset and div_u64
+
+Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
+---
+ drivers/pwm/Kconfig | 11 ++
+ drivers/pwm/Makefile | 1 +
+ drivers/pwm/pwm-sifive-ptc.c | 260 +++++++++++++++++++++++++++++++++++
+ 3 files changed, 272 insertions(+)
+ create mode 100644 drivers/pwm/pwm-sifive-ptc.c
+
+diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
+index 60d13a949bc5..89cd8a6406e3 100644
+--- a/drivers/pwm/Kconfig
++++ b/drivers/pwm/Kconfig
+@@ -504,6 +504,17 @@ config PWM_SIFIVE
+ To compile this driver as a module, choose M here: the module
+ will be called pwm-sifive.
+
++config PWM_SIFIVE_PTC
++ tristate "SiFive PWM PTC support"
++ depends on SOC_SIFIVE || SOC_STARFIVE || COMPILE_TEST
++ depends on OF
++ depends on COMMON_CLK
++ help
++ Generic PWM framework driver for SiFive SoCs.
++
++ To compile this driver as a module, choose M here: the module
++ will be called pwm-sifive-ptc.
++
+ config PWM_SL28CPLD
+ tristate "Kontron sl28cpld PWM support"
+ depends on MFD_SL28CPLD || COMPILE_TEST
+diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
+index 7bf1a29f02b8..fbaa279cf540 100644
+--- a/drivers/pwm/Makefile
++++ b/drivers/pwm/Makefile
+@@ -46,6 +46,7 @@ obj-$(CONFIG_PWM_RENESAS_TPU) += pwm-renesas-tpu.o
+ obj-$(CONFIG_PWM_ROCKCHIP) += pwm-rockchip.o
+ obj-$(CONFIG_PWM_SAMSUNG) += pwm-samsung.o
+ obj-$(CONFIG_PWM_SIFIVE) += pwm-sifive.o
++obj-$(CONFIG_PWM_SIFIVE_PTC) += pwm-sifive-ptc.o
+ obj-$(CONFIG_PWM_SL28CPLD) += pwm-sl28cpld.o
+ obj-$(CONFIG_PWM_SPEAR) += pwm-spear.o
+ obj-$(CONFIG_PWM_SPRD) += pwm-sprd.o
+diff --git a/drivers/pwm/pwm-sifive-ptc.c b/drivers/pwm/pwm-sifive-ptc.c
+new file mode 100644
+index 000000000000..2bfc4d9f4932
+--- /dev/null
++++ b/drivers/pwm/pwm-sifive-ptc.c
+@@ -0,0 +1,260 @@
++/*
++ * Copyright (C) 2018 SiFive, Inc
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2, as published by
++ * the Free Software Foundation.
++ */
++
++#include <linux/clk.h>
++#include <linux/io.h>
++#include <linux/math64.h>
++#include <linux/module.h>
++#include <linux/platform_device.h>
++#include <linux/pwm.h>
++#include <linux/reset.h>
++
++#include <dt-bindings/pwm/pwm.h>
++
++/* max channel of pwm */
++#define MAX_PWM 8
++
++/* PTC Register offsets */
++#define REG_RPTC_CNTR 0x0
++#define REG_RPTC_HRC 0x4
++#define REG_RPTC_LRC 0x8
++#define REG_RPTC_CTRL 0xC
++
++/* Bit for PWM clock */
++#define BIT_PWM_CLOCK_EN 31
++
++/* Bit for clock gen soft reset */
++#define BIT_CLK_GEN_SOFT_RESET 13
++
++#define NS_1 1000000000U
++
++/* Access PTC register (cntr hrc lrc and ctrl), need to replace PWM_BASE_ADDR */
++#define REG_PTC_BASE_ADDR_SUB(base, N) \
++ ((base) + (((N) > 3) ? (((N) - 4) * 0x10 + (1 << 15)) : ((N) * 0x10)))
++#define REG_PTC_RPTC_CNTR(base, N) (REG_PTC_BASE_ADDR_SUB(base, N))
++#define REG_PTC_RPTC_HRC(base, N) (REG_PTC_BASE_ADDR_SUB(base, N) + 0x4)
++#define REG_PTC_RPTC_LRC(base, N) (REG_PTC_BASE_ADDR_SUB(base, N) + 0x8)
++#define REG_PTC_RPTC_CTRL(base, N) (REG_PTC_BASE_ADDR_SUB(base, N) + 0xC)
++
++/* pwm ptc device */
++struct sifive_pwm_ptc_device {
++ struct pwm_chip chip;
++ struct clk *clk;
++ void __iomem *regs;
++};
++
++static inline struct sifive_pwm_ptc_device *chip_to_sifive_ptc(struct pwm_chip *c)
++{
++ return container_of(c, struct sifive_pwm_ptc_device, chip);
++}
++
++static int sifive_pwm_ptc_get_state(struct pwm_chip *chip, struct pwm_device *dev,
++ struct pwm_state *state)
++{
++ struct sifive_pwm_ptc_device *pwm = chip_to_sifive_ptc(chip);
++ u32 data_lrc;
++ u32 data_hrc;
++ u32 pwm_clk_ns = 0;
++
++ /* get lrc and hrc data from registe */
++ data_lrc = ioread32(REG_PTC_RPTC_LRC(pwm->regs, dev->hwpwm));
++ data_hrc = ioread32(REG_PTC_RPTC_HRC(pwm->regs, dev->hwpwm));
++
++ /* how many ns does apb clock elapse */
++ pwm_clk_ns = NS_1 / clk_get_rate(pwm->clk);
++
++ /* pwm period(ns) */
++ state->period = data_lrc * pwm_clk_ns;
++
++ /* duty cycle(ns) means high level eclapse ns if it is normal polarity */
++ state->duty_cycle = data_hrc * pwm_clk_ns;
++
++ /* polarity, we don't use it now because it is not in dts */
++ state->polarity = PWM_POLARITY_NORMAL;
++
++ /* enabled or not */
++ state->enabled = 1;
++
++ dev_dbg(pwm->chip.dev, "%s: no:%d\n", __func__, dev->hwpwm);
++ dev_dbg(pwm->chip.dev, "data_hrc:0x%x 0x%x\n", data_hrc, data_lrc);
++ dev_dbg(pwm->chip.dev, "period:%llu\n", state->period);
++ dev_dbg(pwm->chip.dev, "duty_cycle:%llu\n", state->duty_cycle);
++ dev_dbg(pwm->chip.dev, "polarity:%d\n", state->polarity);
++ dev_dbg(pwm->chip.dev, "enabled:%d\n", state->enabled);
++
++ return 0;
++}
++
++static int sifive_pwm_ptc_apply(struct pwm_chip *chip, struct pwm_device *dev,
++ const struct pwm_state *state)
++{
++ struct sifive_pwm_ptc_device *pwm = chip_to_sifive_ptc(chip);
++ void __iomem *reg_addr;
++ u32 pwm_clk_ns = 0;
++ u32 data_hrc = 0;
++ u32 data_lrc = 0;
++ u32 period_data = 0;
++ u32 duty_data = 0;
++
++ dev_dbg(pwm->chip.dev, "%s: no:%d\n", __func__, dev->hwpwm);
++ dev_dbg(pwm->chip.dev, "period:%llu\n", state->period);
++ dev_dbg(pwm->chip.dev, "duty_cycle:%llu\n", state->duty_cycle);
++ dev_dbg(pwm->chip.dev, "polarity:%d\n", state->polarity);
++ dev_dbg(pwm->chip.dev, "enabled:%d\n", state->enabled);
++
++ /* duty_cycle should be less or equal than period */
++ if (state->duty_cycle > state->period)
++ return -EINVAL;
++
++ /* calculate pwm real period (ns) */
++ pwm_clk_ns = NS_1 / clk_get_rate(pwm->clk);
++
++ dev_dbg(pwm->chip.dev, "pwm_clk_ns:%u\n", pwm_clk_ns);
++
++ /* calculate period count */
++ period_data = div_u64(state->period, pwm_clk_ns);
++
++ if (!state->enabled)
++ /* if disabled, just set duty_data to 0, which means low level always */
++ duty_data = 0;
++ else
++ /* calculate duty count */
++ duty_data = div_u64(state->duty_cycle, pwm_clk_ns);
++
++ dev_dbg(pwm->chip.dev, "period_data:%u, duty_data:%u\n",
++ period_data, duty_data);
++
++ if (state->polarity == PWM_POLARITY_NORMAL)
++ /* calculate data_hrc */
++ data_hrc = period_data - duty_data;
++ else
++ /* calculate data_hrc */
++ data_hrc = duty_data;
++
++ data_lrc = period_data;
++
++ /* set hrc */
++ reg_addr = REG_PTC_RPTC_HRC(pwm->regs, dev->hwpwm);
++ dev_dbg(pwm->chip.dev, "%s: reg_addr:%p, data:%u\n",
++ __func__, reg_addr, data_hrc);
++
++ iowrite32(data_hrc, reg_addr);
++
++ dev_dbg(pwm->chip.dev, "%s: hrc ok\n", __func__);
++
++ /* set lrc */
++ reg_addr = REG_PTC_RPTC_LRC(pwm->regs, dev->hwpwm);
++ dev_dbg(pwm->chip.dev, "%s: reg_addr:%p, data:%u\n",
++ __func__, reg_addr, data_lrc);
++
++ iowrite32(data_lrc, reg_addr);
++ dev_dbg(pwm->chip.dev, "%s: lrc ok\n", __func__);
++
++ /* Clear REG_RPTC_CNTR after setting period & duty_cycle */
++ reg_addr = REG_PTC_RPTC_CNTR(pwm->regs, dev->hwpwm);
++ iowrite32(0, reg_addr);
++ return 0;
++}
++
++static const struct pwm_ops sifive_pwm_ptc_ops = {
++ .get_state = sifive_pwm_ptc_get_state,
++ .apply = sifive_pwm_ptc_apply,
++ .owner = THIS_MODULE,
++};
++
++static void sifive_pwm_ptc_disable_action(void *data)
++{
++ clk_disable_unprepare(data);
++}
++
++static int sifive_pwm_ptc_probe(struct platform_device *pdev)
++{
++ struct device *dev = &pdev->dev;
++ struct device_node *node = pdev->dev.of_node;
++ struct sifive_pwm_ptc_device *pwm;
++ struct pwm_chip *chip;
++ struct reset_control *rst;
++ int ret;
++
++ pwm = devm_kzalloc(dev, sizeof(*pwm), GFP_KERNEL);
++ if (!pwm)
++ return -ENOMEM;
++
++ platform_set_drvdata(pdev, pwm);
++
++ chip = &pwm->chip;
++ chip->dev = dev;
++ chip->ops = &sifive_pwm_ptc_ops;
++
++ /* how many parameters can be transferred to ptc, need to fix */
++ chip->of_pwm_n_cells = 3;
++ chip->base = -1;
++
++ /* get pwm channels count, max value is 8 */
++ ret = of_property_read_u32(node, "starfive,npwm", &chip->npwm);
++ if (ret < 0 || chip->npwm > MAX_PWM)
++ chip->npwm = MAX_PWM;
++
++ dev_dbg(dev, "%s: npwm:0x%x\n", __func__, chip->npwm);
++
++ /* get IO base address */
++ pwm->regs = devm_platform_ioremap_resource(pdev, 0);
++ if (IS_ERR(pwm->regs))
++ return dev_err_probe(dev, PTR_ERR(pwm->regs),
++ "Unable to map IO resources\n");
++
++ pwm->clk = devm_clk_get(dev, NULL);
++ if (IS_ERR(pwm->clk))
++ return dev_err_probe(dev, PTR_ERR(pwm->clk),
++ "Unable to get controller clock\n");
++
++ ret = clk_prepare_enable(pwm->clk);
++ if (ret)
++ return dev_err_probe(dev, ret, "Unable to enable clock\n");
++
++ ret = devm_add_action_or_reset(dev, sifive_pwm_ptc_disable_action, pwm->clk);
++ if (ret)
++ return ret;
++
++ rst = devm_reset_control_get_exclusive(dev, NULL);
++ if (IS_ERR(rst))
++ return dev_err_probe(dev, PTR_ERR(rst), "Unable to get reset\n");
++
++ ret = reset_control_deassert(rst);
++ if (ret)
++ return dev_err_probe(dev, ret, "Unable to deassert reset\n");
++
++ /*
++ * after pwmchip_add it will show up as /sys/class/pwm/pwmchip0,
++ * 0 is chip->base, pwm0 can be seen after running echo 0 > export
++ */
++ ret = devm_pwmchip_add(dev, chip);
++ if (ret)
++ return dev_err_probe(dev, ret, "cannot register PTC: %d\n", ret);
++
++ dev_dbg(dev, "SiFive PWM PTC chip registered %d PWMs\n", chip->npwm);
++ return 0;
++}
++
++static const struct of_device_id sifive_pwm_ptc_of_match[] = {
++ { .compatible = "starfive,pwm0" },
++ { /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(of, sifive_pwm_ptc_of_match);
++
++static struct platform_driver sifive_pwm_ptc_driver = {
++ .probe = sifive_pwm_ptc_probe,
++ .driver = {
++ .name = "pwm-sifive-ptc",
++ .of_match_table = sifive_pwm_ptc_of_match,
++ },
++};
++module_platform_driver(sifive_pwm_ptc_driver);
++
++MODULE_DESCRIPTION("SiFive PWM PTC driver");
++MODULE_LICENSE("GPL v2");
+--
+2.20.1
+