KERNELNAME:=Image dtbs
MAINTAINER:=Zoltan HERPAI <wigyori@uid0.hu>
-KERNEL_PATCHVER:=5.10
+KERNEL_PATCHVER:=5.15
include $(INCLUDE_DIR)/target.mk
+++ /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_OPTIONAL_KERNEL_RWX=y
-CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y
-# CONFIG_ARCH_RV32I is not set
-CONFIG_ARCH_RV64I=y
-CONFIG_ARCH_SELECT_MEMORY_MODEL=y
-CONFIG_ARCH_SPARSEMEM_ENABLE=y
-CONFIG_ASN1=y
-CONFIG_ASSOCIATIVE_ARRAY=y
-CONFIG_ASYMMETRIC_KEY_TYPE=y
-CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=y
-CONFIG_ASYMMETRIC_TPM_KEY_SUBTYPE=y
-CONFIG_ATA=y
-CONFIG_ATA_VERBOSE_ERROR=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_BLK_MQ_PCI=y
-CONFIG_BLK_MQ_VIRTIO=y
-CONFIG_BLK_SCSI_REQUEST=y
-CONFIG_CAVIUM_PTP=y
-CONFIG_CLKDEV_LOOKUP=y
-CONFIG_CLK_ANALOGBITS_WRPLL_CLN28HPC=y
-CONFIG_CLK_SIFIVE=y
-CONFIG_CLK_SIFIVE_FU540_PRCI=y
-CONFIG_CLONE_BACKWARDS=y
-CONFIG_CLZ_TAB=y
-CONFIG_CMODEL_MEDANY=y
-# CONFIG_CMODEL_MEDLOW is not set
-CONFIG_COMMON_CLK=y
-# CONFIG_COMPAT_32BIT_TIME is not set
-CONFIG_COMPAT_BRK=y
-CONFIG_COREDUMP=y
-CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
-CONFIG_CPU_ISOLATION=y
-CONFIG_CPU_RMAP=y
-CONFIG_CRC16=y
-# CONFIG_CRC32_SARWATE is not set
-CONFIG_CRC32_SLICEBY8=y
-CONFIG_CRC7=y
-CONFIG_CRC_ITU_T=y
-CONFIG_CRYPTO_CRC32C=y
-CONFIG_CRYPTO_DRBG=y
-CONFIG_CRYPTO_DRBG_HMAC=y
-CONFIG_CRYPTO_DRBG_MENU=y
-CONFIG_CRYPTO_ECHAINIV=y
-CONFIG_CRYPTO_GF128MUL=y
-CONFIG_CRYPTO_HASH_INFO=y
-CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_JITTERENTROPY=y
-CONFIG_CRYPTO_LIB_POLY1305_RSIZE=1
-CONFIG_CRYPTO_LIB_SHA256=y
-CONFIG_CRYPTO_NULL2=y
-CONFIG_CRYPTO_RNG=y
-CONFIG_CRYPTO_RNG2=y
-CONFIG_CRYPTO_RNG_DEFAULT=y
-CONFIG_CRYPTO_RSA=y
-CONFIG_CRYPTO_SHA256=y
-CONFIG_DA9063_WATCHDOG=y
-CONFIG_DEBUG_BUGVERBOSE=y
-CONFIG_DECOMPRESS_GZIP=y
-CONFIG_DEVMEM=y
-CONFIG_DEVTMPFS=y
-CONFIG_DEVTMPFS_MOUNT=y
-CONFIG_DNOTIFY=y
-CONFIG_DTC=y
-CONFIG_EDAC=y
-# CONFIG_EDAC_DEBUG is not set
-CONFIG_EDAC_LEGACY_SYSFS=y
-CONFIG_EDAC_SUPPORT=y
-CONFIG_EDAC_SIFIVE=y
-CONFIG_ELF_CORE=y
-CONFIG_ENABLE_MUST_CHECK=y
-CONFIG_ERRATA_SIFIVE_CIP_453=y
-CONFIG_ERRATA_SIFIVE_CIP_1200=y
-CONFIG_EXT4_FS=y
-CONFIG_FAILOVER=y
-CONFIG_FHANDLE=y
-CONFIG_FIXED_PHY=y
-CONFIG_FIX_EARLYCON_MEM=y
-CONFIG_FPU=y
-CONFIG_FRAME_POINTER=y
-CONFIG_FRAME_WARN=2048
-CONFIG_FS_IOMAP=y
-CONFIG_FS_MBCACHE=y
-CONFIG_FW_LOADER_PAGED_BUF=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_CSUM=y
-CONFIG_GENERIC_EARLY_IOREMAP=y
-CONFIG_GENERIC_GETTIMEOFDAY=y
-CONFIG_GENERIC_IOREMAP=y
-CONFIG_GENERIC_IRQ_MULTI_HANDLER=y
-CONFIG_GENERIC_IRQ_SHOW=y
-CONFIG_GENERIC_MSI_IRQ=y
-CONFIG_GENERIC_MSI_IRQ_DOMAIN=y
-CONFIG_GENERIC_PCI_IOMAP=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_AUDIO is not set
-# CONFIG_GOLDFISH_PIPE is not set
-# CONFIG_GOLDFISH_TTY is not set
-CONFIG_GPIOLIB=y
-CONFIG_GPIO_SIFIVE=y
-CONFIG_HANDLE_DOMAIN_IRQ=y
-CONFIG_HAS_DMA=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT_MAP=y
-CONFIG_HID=y
-CONFIG_HID_GENERIC=y
-CONFIG_HOTPLUG_PCI=y
-# CONFIG_HOTPLUG_PCI_CPCI is not set
-CONFIG_HOTPLUG_PCI_PCIE=y
-CONFIG_HOTPLUG_PCI_SHPC=y
-CONFIG_HVC_DRIVER=y
-CONFIG_HVC_RISCV_SBI=y
-CONFIG_HZ=250
-# CONFIG_HZ_100 is not set
-CONFIG_HZ_250=y
-CONFIG_HZ_PERIODIC=y
-CONFIG_I2C=y
-CONFIG_I2C_BOARDINFO=y
-CONFIG_I2C_COMPAT=y
-CONFIG_I2C_HELPER_AUTO=y
-CONFIG_I2C_OCORES=y
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_INPUT=y
-# CONFIG_INPUT_DA9063_ONKEY is not set
-CONFIG_IO_URING=y
-CONFIG_IRQCHIP=y
-CONFIG_IRQ_DOMAIN=y
-CONFIG_IRQ_DOMAIN_HIERARCHY=y
-CONFIG_IRQ_WORK=y
-CONFIG_JBD2=y
-CONFIG_KALLSYMS=y
-CONFIG_KEYS=y
-# CONFIG_KEYBOARD_GOLDFISH_EVENTS is not set
-CONFIG_LEDS_PWM=y
-CONFIG_LEDS_TRIGGER_DISK=y
-CONFIG_LEGACY_PTYS=y
-CONFIG_LEGACY_PTY_COUNT=256
-CONFIG_LIBFDT=y
-CONFIG_LLD_VERSION=0
-CONFIG_LOCALVERSION_AUTO=y
-CONFIG_LOCK_DEBUGGING_SUPPORT=y
-CONFIG_LOCK_SPIN_ON_OWNER=y
-CONFIG_MACB=y
-# CONFIG_MACB_PCI is not set
-CONFIG_MACB_USE_HWSTAMP=y
-CONFIG_MANDATORY_FILE_LOCKING=y
-CONFIG_MAXPHYSMEM_128GB=y
-CONFIG_MDIO_BUS=y
-CONFIG_MDIO_DEVICE=y
-CONFIG_MDIO_DEVRES=y
-CONFIG_MEMFD_CREATE=y
-CONFIG_MFD_SYSCON=y
-CONFIG_MFD_DA9063=y
-CONFIG_MICROSEMI_PHY=y
-CONFIG_MIGRATION=y
-CONFIG_MMC=y
-CONFIG_MMC_BLOCK=y
-# CONFIG_MMC_GOLDFISH is not set
-CONFIG_MMC_SPI=y
-CONFIG_MMIOWB=y
-CONFIG_MODULES_USE_ELF_RELA=y
-CONFIG_MODULE_SECTIONS=y
-CONFIG_MPILIB=y
-CONFIG_MQ_IOSCHED_DEADLINE=y
-CONFIG_MQ_IOSCHED_KYBER=y
-CONFIG_MTD_SPI_NOR=y
-CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y
-CONFIG_MUTEX_SPIN_ON_OWNER=y
-CONFIG_NAMESPACES=y
-CONFIG_NEED_DMA_MAP_STATE=y
-CONFIG_NET_FAILOVER=y
-CONFIG_NET_FLOW_LIMIT=y
-CONFIG_NET_NS=y
-CONFIG_NET_PTP_CLASSIFY=y
-CONFIG_NLS=y
-CONFIG_NR_CPUS=8
-CONFIG_NVMEM=y
-CONFIG_NVMEM_SYSFS=y
-CONFIG_OF=y
-CONFIG_OF_ADDRESS=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_NET=y
-CONFIG_OID_REGISTRY=y
-CONFIG_PADATA=y
-CONFIG_PAGE_OFFSET=0xffffffe000000000
-CONFIG_PANIC_TIMEOUT=0
-CONFIG_PA_BITS=56
-CONFIG_PCI=y
-CONFIG_PCI_DEBUG=y
-CONFIG_PCI_DOMAINS=y
-CONFIG_PCI_DOMAINS_GENERIC=y
-CONFIG_PCI_ECAM=y
-CONFIG_PCI_HOST_COMMON=y
-CONFIG_PCI_HOST_GENERIC=y
-CONFIG_PCI_MSI=y
-CONFIG_PCI_MSI_IRQ_DOMAIN=y
-CONFIG_PCI_SW_SWITCHTEC=y
-CONFIG_PCIEPORTBUS=y
-CONFIG_PCIEAER=y
-CONFIG_PCIEAER_INJECT=m
-CONFIG_PCIE_ECRC=y
-CONFIG_PCIEASPM=y
-CONFIG_PCIEASPM_DEFAULT=y
-# CONFIG_PCIEASPM_POWERSAVE is not set
-# CONFIG_PCIEASPM_POWER_SUPERSAVE is not set
-# CONFIG_PCIEASPM_PERFORMANCE is not set
-CONFIG_PCIE_PME=y
-CONFIG_PCIE_DPC=y
-CONFIG_PCIE_PTM=y
-# CONFIG_PCIE_BW is not set
-CONFIG_PCIE_EDR=y
-CONFIG_PCIE_FU740=y
-CONFIG_PCIE_XILINX=y
-CONFIG_PGTABLE_LEVELS=3
-CONFIG_PHYLIB=y
-CONFIG_PHYLINK=y
-CONFIG_PHYS_ADDR_T_64BIT=y
-CONFIG_PID_NS=y
-CONFIG_PKCS7_MESSAGE_PARSER=y
-# CONFIG_PKCS8_PRIVATE_KEY_PARSER is not set
-CONFIG_POWER_RESET=y
-CONFIG_POWER_RESET_RESTART=y
-CONFIG_POWER_RESET_GPIO=y
-CONFIG_POWER_RESET_GPIO_RESTART=y
-CONFIG_POWER_RESET_SYSCON=y
-CONFIG_POWER_RESET_SYSCON_POWEROFF=y
-CONFIG_PPS=y
-CONFIG_PRINTK_TIME=y
-CONFIG_PTP_1588_CLOCK=y
-CONFIG_PWM=y
-CONFIG_PWM_SIFIVE=y
-CONFIG_PWM_SYSFS=y
-CONFIG_R8169=y
-CONFIG_RATIONAL=y
-CONFIG_RCU_TRACE=y
-CONFIG_RD_GZIP=y
-CONFIG_REALTEK_PHY=y
-CONFIG_REGMAP=y
-CONFIG_REGMAP_MMIO=y
-CONFIG_RFS_ACCEL=y
-CONFIG_RISCV=y
-CONFIG_RISCV_ERRATA_ALTERNATIVE=y
-CONFIG_RISCV_INTC=y
-CONFIG_RISCV_ISA_C=y
-CONFIG_RISCV_SBI=y
-CONFIG_RISCV_SBI_V01=y
-CONFIG_RISCV_TIMER=y
-CONFIG_RPS=y
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_DA9063=y
-CONFIG_RTC_DRV_GOLDFISH=y
-CONFIG_RTC_I2C_AND_SPI=y
-CONFIG_RWSEM_SPIN_ON_OWNER=y
-CONFIG_SCHED_DEBUG=y
-CONFIG_SCSI=y
-CONFIG_SENSORS_DA9063=y
-CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=y
-CONFIG_SERIAL_8250_NR_UARTS=4
-CONFIG_SERIAL_8250_RUNTIME_UARTS=4
-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_SERIO=y
-CONFIG_SERIO_SERPORT=y
-CONFIG_SG_POOL=y
-CONFIG_SIFIVE_L2=y
-CONFIG_SIFIVE_PLIC=y
-CONFIG_SLUB_DEBUG=y
-CONFIG_SMP=y
-CONFIG_SOC_SIFIVE=y
-CONFIG_SOC_VIRT=y
-CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
-CONFIG_SPARSE_IRQ=y
-CONFIG_SPI=y
-CONFIG_SPI_BITBANG=y
-CONFIG_SPI_MASTER=y
-CONFIG_SPI_MEM=y
-CONFIG_SPI_SIFIVE=y
-CONFIG_SRCU=y
-CONFIG_STACKTRACE=y
-CONFIG_SWIOTLB=y
-CONFIG_SWPHY=y
-CONFIG_SYSCTL_EXCEPTION_TRACE=y
-CONFIG_SYSFS_SYSCALL=y
-CONFIG_SYS_SUPPORTS_HUGETLBFS=y
-CONFIG_THREAD_INFO_IN_TASK=y
-CONFIG_TICK_CPU_ACCOUNTING=y
-CONFIG_TIMER_OF=y
-CONFIG_TIMER_PROBE=y
-# CONFIG_TPM_KEY_PARSER is not set
-CONFIG_TRACE_CLOCK=y
-CONFIG_TREE_RCU=y
-CONFIG_TREE_SRCU=y
-CONFIG_TUNE_GENERIC=y
-CONFIG_UEVENT_HELPER_PATH=""
-CONFIG_USB=y
-CONFIG_USB_COMMON=y
-CONFIG_USB_EHCI_HCD=y
-# CONFIG_USB_EHCI_HCD_PLATFORM is not set
-CONFIG_USB_EHCI_PCI=y
-CONFIG_USB_HID=y
-CONFIG_USB_NET_DRIVERS=y
-CONFIG_USB_PCI=y
-CONFIG_USB_STORAGE=y
-CONFIG_USB_SUPPORT=y
-# CONFIG_USB_UHCI_HCD is not set
-CONFIG_USB_XHCI_HCD=y
-CONFIG_USB_XHCI_PCI=y
-# CONFIG_USB_XHCI_PLATFORM is not set
-# CONFIG_USER_NS is not set
-CONFIG_UTS_NS=y
-CONFIG_VA_BITS=39
-CONFIG_VGA_ARB=y
-CONFIG_VGA_ARB_MAX_GPUS=16
-CONFIG_VIRTIO=y
-CONFIG_VIRTIO_BLK=y
-CONFIG_VIRTIO_CONSOLE=y
-CONFIG_VIRTIO_MMIO=y
-CONFIG_VIRTIO_NET=y
-CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_X509_CERTIFICATE_PARSER=y
-CONFIG_XPS=y
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZONE_DMA32=y
--- /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_OPTIONAL_KERNEL_RWX=y
+CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y
+# CONFIG_ARCH_RV32I is not set
+CONFIG_ARCH_RV64I=y
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ASN1=y
+CONFIG_ASSOCIATIVE_ARRAY=y
+CONFIG_ASYMMETRIC_KEY_TYPE=y
+CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=y
+CONFIG_ASYMMETRIC_TPM_KEY_SUBTYPE=y
+CONFIG_ATA=y
+CONFIG_ATA_VERBOSE_ERROR=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_BLK_MQ_PCI=y
+CONFIG_BLK_MQ_VIRTIO=y
+CONFIG_BLK_SCSI_REQUEST=y
+CONFIG_CAVIUM_PTP=y
+CONFIG_CLKDEV_LOOKUP=y
+CONFIG_CLK_ANALOGBITS_WRPLL_CLN28HPC=y
+CONFIG_CLK_SIFIVE=y
+CONFIG_CLK_SIFIVE_FU540_PRCI=y
+CONFIG_CLONE_BACKWARDS=y
+CONFIG_CLZ_TAB=y
+CONFIG_CMODEL_MEDANY=y
+# CONFIG_CMODEL_MEDLOW is not set
+CONFIG_COMMON_CLK=y
+# CONFIG_COMPAT_32BIT_TIME is not set
+CONFIG_COMPAT_BRK=y
+CONFIG_COREDUMP=y
+CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
+CONFIG_CPU_ISOLATION=y
+CONFIG_CPU_RMAP=y
+CONFIG_CRC16=y
+# CONFIG_CRC32_SARWATE is not set
+CONFIG_CRC32_SLICEBY8=y
+CONFIG_CRC7=y
+CONFIG_CRC_ITU_T=y
+CONFIG_CRYPTO_CRC32C=y
+CONFIG_CRYPTO_DRBG=y
+CONFIG_CRYPTO_DRBG_HMAC=y
+CONFIG_CRYPTO_DRBG_MENU=y
+CONFIG_CRYPTO_ECHAINIV=y
+CONFIG_CRYPTO_GF128MUL=y
+CONFIG_CRYPTO_HASH_INFO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_JITTERENTROPY=y
+CONFIG_CRYPTO_LIB_POLY1305_RSIZE=1
+CONFIG_CRYPTO_LIB_SHA256=y
+CONFIG_CRYPTO_NULL2=y
+CONFIG_CRYPTO_RNG=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_RNG_DEFAULT=y
+CONFIG_CRYPTO_RSA=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_DA9063_WATCHDOG=y
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DEVMEM=y
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_DNOTIFY=y
+CONFIG_DTC=y
+CONFIG_EDAC=y
+# CONFIG_EDAC_DEBUG is not set
+CONFIG_EDAC_LEGACY_SYSFS=y
+CONFIG_EDAC_SUPPORT=y
+CONFIG_EDAC_SIFIVE=y
+CONFIG_ELF_CORE=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_ERRATA_SIFIVE_CIP_453=y
+CONFIG_ERRATA_SIFIVE_CIP_1200=y
+CONFIG_EXT4_FS=y
+CONFIG_FAILOVER=y
+CONFIG_FHANDLE=y
+CONFIG_FIXED_PHY=y
+CONFIG_FIX_EARLYCON_MEM=y
+CONFIG_FPU=y
+CONFIG_FRAME_POINTER=y
+CONFIG_FRAME_WARN=2048
+CONFIG_FS_IOMAP=y
+CONFIG_FS_MBCACHE=y
+CONFIG_FW_LOADER_PAGED_BUF=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_CSUM=y
+CONFIG_GENERIC_EARLY_IOREMAP=y
+CONFIG_GENERIC_GETTIMEOFDAY=y
+CONFIG_GENERIC_IOREMAP=y
+CONFIG_GENERIC_IRQ_MULTI_HANDLER=y
+CONFIG_GENERIC_IRQ_SHOW=y
+CONFIG_GENERIC_MSI_IRQ=y
+CONFIG_GENERIC_MSI_IRQ_DOMAIN=y
+CONFIG_GENERIC_PCI_IOMAP=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_AUDIO is not set
+# CONFIG_GOLDFISH_PIPE is not set
+# CONFIG_GOLDFISH_TTY is not set
+CONFIG_GPIOLIB=y
+CONFIG_GPIO_SIFIVE=y
+CONFIG_HANDLE_DOMAIN_IRQ=y
+CONFIG_HAS_DMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT_MAP=y
+CONFIG_HID=y
+CONFIG_HID_GENERIC=y
+CONFIG_HOTPLUG_PCI=y
+# CONFIG_HOTPLUG_PCI_CPCI is not set
+CONFIG_HOTPLUG_PCI_PCIE=y
+CONFIG_HOTPLUG_PCI_SHPC=y
+CONFIG_HVC_DRIVER=y
+CONFIG_HVC_RISCV_SBI=y
+CONFIG_HZ=250
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+CONFIG_HZ_PERIODIC=y
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
+CONFIG_I2C_HELPER_AUTO=y
+CONFIG_I2C_OCORES=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_INPUT=y
+# CONFIG_INPUT_DA9063_ONKEY is not set
+CONFIG_IO_URING=y
+CONFIG_IRQCHIP=y
+CONFIG_IRQ_DOMAIN=y
+CONFIG_IRQ_DOMAIN_HIERARCHY=y
+CONFIG_IRQ_WORK=y
+CONFIG_JBD2=y
+CONFIG_KALLSYMS=y
+CONFIG_KEYS=y
+# CONFIG_KEYBOARD_GOLDFISH_EVENTS is not set
+CONFIG_LEDS_PWM=y
+CONFIG_LEDS_TRIGGER_DISK=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+CONFIG_LIBFDT=y
+CONFIG_LLD_VERSION=0
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_LOCK_DEBUGGING_SUPPORT=y
+CONFIG_LOCK_SPIN_ON_OWNER=y
+CONFIG_MACB=y
+# CONFIG_MACB_PCI is not set
+CONFIG_MACB_USE_HWSTAMP=y
+CONFIG_MANDATORY_FILE_LOCKING=y
+CONFIG_MAXPHYSMEM_128GB=y
+CONFIG_MDIO_BUS=y
+CONFIG_MDIO_DEVICE=y
+CONFIG_MDIO_DEVRES=y
+CONFIG_MEMFD_CREATE=y
+CONFIG_MFD_SYSCON=y
+CONFIG_MFD_DA9063=y
+CONFIG_MICROSEMI_PHY=y
+CONFIG_MIGRATION=y
+CONFIG_MMC=y
+CONFIG_MMC_BLOCK=y
+# CONFIG_MMC_GOLDFISH is not set
+CONFIG_MMC_SPI=y
+CONFIG_MMIOWB=y
+CONFIG_MODULES_USE_ELF_RELA=y
+CONFIG_MODULE_SECTIONS=y
+CONFIG_MPILIB=y
+CONFIG_MQ_IOSCHED_DEADLINE=y
+CONFIG_MQ_IOSCHED_KYBER=y
+CONFIG_MTD_SPI_NOR=y
+CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y
+CONFIG_MUTEX_SPIN_ON_OWNER=y
+CONFIG_NAMESPACES=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_NET_FAILOVER=y
+CONFIG_NET_FLOW_LIMIT=y
+CONFIG_NET_NS=y
+CONFIG_NET_PTP_CLASSIFY=y
+CONFIG_NLS=y
+CONFIG_NR_CPUS=8
+CONFIG_NVMEM=y
+CONFIG_NVMEM_SYSFS=y
+CONFIG_OF=y
+CONFIG_OF_ADDRESS=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_NET=y
+CONFIG_OID_REGISTRY=y
+CONFIG_PADATA=y
+CONFIG_PAGE_OFFSET=0xffffffe000000000
+CONFIG_PANIC_TIMEOUT=0
+CONFIG_PA_BITS=56
+CONFIG_PCI=y
+CONFIG_PCI_DEBUG=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCI_DOMAINS_GENERIC=y
+CONFIG_PCI_ECAM=y
+CONFIG_PCI_HOST_COMMON=y
+CONFIG_PCI_HOST_GENERIC=y
+CONFIG_PCI_MSI=y
+CONFIG_PCI_MSI_IRQ_DOMAIN=y
+CONFIG_PCI_SW_SWITCHTEC=y
+CONFIG_PCIEPORTBUS=y
+CONFIG_PCIEAER=y
+CONFIG_PCIEAER_INJECT=m
+CONFIG_PCIE_ECRC=y
+CONFIG_PCIEASPM=y
+CONFIG_PCIEASPM_DEFAULT=y
+# CONFIG_PCIEASPM_POWERSAVE is not set
+# CONFIG_PCIEASPM_POWER_SUPERSAVE is not set
+# CONFIG_PCIEASPM_PERFORMANCE is not set
+CONFIG_PCIE_PME=y
+CONFIG_PCIE_DPC=y
+CONFIG_PCIE_PTM=y
+# CONFIG_PCIE_BW is not set
+CONFIG_PCIE_EDR=y
+CONFIG_PCIE_FU740=y
+CONFIG_PCIE_XILINX=y
+CONFIG_PGTABLE_LEVELS=3
+CONFIG_PHYLIB=y
+CONFIG_PHYLINK=y
+CONFIG_PHYS_ADDR_T_64BIT=y
+CONFIG_PID_NS=y
+CONFIG_PKCS7_MESSAGE_PARSER=y
+# CONFIG_PKCS8_PRIVATE_KEY_PARSER is not set
+CONFIG_POWER_RESET=y
+CONFIG_POWER_RESET_RESTART=y
+CONFIG_POWER_RESET_GPIO=y
+CONFIG_POWER_RESET_GPIO_RESTART=y
+CONFIG_POWER_RESET_SYSCON=y
+CONFIG_POWER_RESET_SYSCON_POWEROFF=y
+CONFIG_PPS=y
+CONFIG_PRINTK_TIME=y
+CONFIG_PTP_1588_CLOCK=y
+CONFIG_PWM=y
+CONFIG_PWM_SIFIVE=y
+CONFIG_PWM_SYSFS=y
+CONFIG_R8169=y
+CONFIG_RATIONAL=y
+CONFIG_RCU_TRACE=y
+CONFIG_RD_GZIP=y
+CONFIG_REALTEK_PHY=y
+CONFIG_REGMAP=y
+CONFIG_REGMAP_MMIO=y
+CONFIG_RFS_ACCEL=y
+CONFIG_RISCV=y
+CONFIG_RISCV_ERRATA_ALTERNATIVE=y
+CONFIG_RISCV_INTC=y
+CONFIG_RISCV_ISA_C=y
+CONFIG_RISCV_SBI=y
+CONFIG_RISCV_SBI_V01=y
+CONFIG_RISCV_TIMER=y
+CONFIG_RPS=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_DA9063=y
+CONFIG_RTC_DRV_GOLDFISH=y
+CONFIG_RTC_I2C_AND_SPI=y
+CONFIG_RWSEM_SPIN_ON_OWNER=y
+CONFIG_SCHED_DEBUG=y
+CONFIG_SCSI=y
+CONFIG_SENSORS_DA9063=y
+CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+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_SERIO=y
+CONFIG_SERIO_SERPORT=y
+CONFIG_SG_POOL=y
+CONFIG_SIFIVE_L2=y
+CONFIG_SIFIVE_PLIC=y
+CONFIG_SLUB_DEBUG=y
+CONFIG_SMP=y
+CONFIG_SOC_SIFIVE=y
+CONFIG_SOC_VIRT=y
+CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
+CONFIG_SPARSE_IRQ=y
+CONFIG_SPI=y
+CONFIG_SPI_BITBANG=y
+CONFIG_SPI_MASTER=y
+CONFIG_SPI_MEM=y
+CONFIG_SPI_SIFIVE=y
+CONFIG_SRCU=y
+CONFIG_STACKTRACE=y
+CONFIG_SWIOTLB=y
+CONFIG_SWPHY=y
+CONFIG_SYSCTL_EXCEPTION_TRACE=y
+CONFIG_SYSFS_SYSCALL=y
+CONFIG_SYS_SUPPORTS_HUGETLBFS=y
+CONFIG_THREAD_INFO_IN_TASK=y
+CONFIG_TICK_CPU_ACCOUNTING=y
+CONFIG_TIMER_OF=y
+CONFIG_TIMER_PROBE=y
+# CONFIG_TPM_KEY_PARSER is not set
+CONFIG_TRACE_CLOCK=y
+CONFIG_TREE_RCU=y
+CONFIG_TREE_SRCU=y
+CONFIG_TUNE_GENERIC=y
+CONFIG_UEVENT_HELPER_PATH=""
+CONFIG_USB=y
+CONFIG_USB_COMMON=y
+CONFIG_USB_EHCI_HCD=y
+# CONFIG_USB_EHCI_HCD_PLATFORM is not set
+CONFIG_USB_EHCI_PCI=y
+CONFIG_USB_HID=y
+CONFIG_USB_NET_DRIVERS=y
+CONFIG_USB_PCI=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_SUPPORT=y
+# CONFIG_USB_UHCI_HCD is not set
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_XHCI_PCI=y
+# CONFIG_USB_XHCI_PLATFORM is not set
+# CONFIG_USER_NS is not set
+CONFIG_UTS_NS=y
+CONFIG_VA_BITS=39
+CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
+CONFIG_VIRTIO=y
+CONFIG_VIRTIO_BLK=y
+CONFIG_VIRTIO_CONSOLE=y
+CONFIG_VIRTIO_MMIO=y
+CONFIG_VIRTIO_NET=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_X509_CERTIFICATE_PARSER=y
+CONFIG_XPS=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZONE_DMA32=y
+++ /dev/null
-From fe033b899ca3461c0439d6cd775476ae7595e327 Mon Sep 17 00:00:00 2001
-From: Zong Li <zong.li@sifive.com>
-Date: Wed, 9 Dec 2020 17:49:12 +0800
-Subject: [PATCH 01/29] clk: sifive: Extract prci core to common base
-
-Extract common core of prci driver to an independent file, it could
-allow other chips to reuse it. Separate SoCs-dependent code 'fu540'
-from prci core, then we can easily add 'fu740' later.
-
-Almost these changes are code movement. The different is adding the
-private data for each SoC use, so it needs to get match data in probe
-callback function, then use the data for initialization.
-
-Signed-off-by: Zong Li <zong.li@sifive.com>
-Reviewed-by: Pragnesh Patel <Pragnesh.patel@sifive.com>
-Acked-by: Palmer Dabbelt <palmerdabbelt@google.com>
----
- drivers/clk/sifive/Makefile | 2 +-
- drivers/clk/sifive/fu540-prci.c | 592 ++-------------------------------------
- drivers/clk/sifive/fu540-prci.h | 21 ++
- drivers/clk/sifive/sifive-prci.c | 395 ++++++++++++++++++++++++++
- drivers/clk/sifive/sifive-prci.h | 201 +++++++++++++
- 5 files changed, 639 insertions(+), 572 deletions(-)
- create mode 100644 drivers/clk/sifive/fu540-prci.h
- create mode 100644 drivers/clk/sifive/sifive-prci.c
- create mode 100644 drivers/clk/sifive/sifive-prci.h
-
-diff --git a/drivers/clk/sifive/Makefile b/drivers/clk/sifive/Makefile
-index 0797f14..51b6ebc 100644
---- a/drivers/clk/sifive/Makefile
-+++ b/drivers/clk/sifive/Makefile
-@@ -1,2 +1,2 @@
- # SPDX-License-Identifier: GPL-2.0-only
--obj-$(CONFIG_CLK_SIFIVE_FU540_PRCI) += fu540-prci.o
-+obj-$(CONFIG_CLK_SIFIVE_FU540_PRCI) += sifive-prci.o fu540-prci.o
-diff --git a/drivers/clk/sifive/fu540-prci.c b/drivers/clk/sifive/fu540-prci.c
-index a8901f9..e2353de 100644
---- a/drivers/clk/sifive/fu540-prci.c
-+++ b/drivers/clk/sifive/fu540-prci.c
-@@ -1,17 +1,9 @@
- // SPDX-License-Identifier: GPL-2.0
- /*
- * Copyright (C) 2018-2019 SiFive, Inc.
-- * Wesley Terpstra
-- * Paul Walmsley
-- *
-- * 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.
-- *
-- * This program is distributed in the hope that it will be useful,
-- * but WITHOUT ANY WARRANTY; without even the implied warranty of
-- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- * GNU General Public License for more details.
-+ * Copyright (C) 2018-2019 Wesley Terpstra
-+ * Copyright (C) 2018-2019 Paul Walmsley
-+ * Copyright (C) 2020 Zong Li
- *
- * The FU540 PRCI implements clock and reset control for the SiFive
- * FU540-C000 chip. This driver assumes that it has sole control
-@@ -25,463 +17,43 @@
- */
-
- #include <dt-bindings/clock/sifive-fu540-prci.h>
--#include <linux/clkdev.h>
--#include <linux/clk-provider.h>
--#include <linux/clk/analogbits-wrpll-cln28hpc.h>
--#include <linux/delay.h>
--#include <linux/err.h>
--#include <linux/io.h>
- #include <linux/module.h>
--#include <linux/of.h>
--#include <linux/of_clk.h>
--#include <linux/platform_device.h>
--#include <linux/slab.h>
--
--/*
-- * EXPECTED_CLK_PARENT_COUNT: how many parent clocks this driver expects:
-- * hfclk and rtcclk
-- */
--#define EXPECTED_CLK_PARENT_COUNT 2
--
--/*
-- * Register offsets and bitmasks
-- */
--
--/* COREPLLCFG0 */
--#define PRCI_COREPLLCFG0_OFFSET 0x4
--# define PRCI_COREPLLCFG0_DIVR_SHIFT 0
--# define PRCI_COREPLLCFG0_DIVR_MASK (0x3f << PRCI_COREPLLCFG0_DIVR_SHIFT)
--# define PRCI_COREPLLCFG0_DIVF_SHIFT 6
--# define PRCI_COREPLLCFG0_DIVF_MASK (0x1ff << PRCI_COREPLLCFG0_DIVF_SHIFT)
--# define PRCI_COREPLLCFG0_DIVQ_SHIFT 15
--# define PRCI_COREPLLCFG0_DIVQ_MASK (0x7 << PRCI_COREPLLCFG0_DIVQ_SHIFT)
--# define PRCI_COREPLLCFG0_RANGE_SHIFT 18
--# define PRCI_COREPLLCFG0_RANGE_MASK (0x7 << PRCI_COREPLLCFG0_RANGE_SHIFT)
--# define PRCI_COREPLLCFG0_BYPASS_SHIFT 24
--# define PRCI_COREPLLCFG0_BYPASS_MASK (0x1 << PRCI_COREPLLCFG0_BYPASS_SHIFT)
--# define PRCI_COREPLLCFG0_FSE_SHIFT 25
--# define PRCI_COREPLLCFG0_FSE_MASK (0x1 << PRCI_COREPLLCFG0_FSE_SHIFT)
--# define PRCI_COREPLLCFG0_LOCK_SHIFT 31
--# define PRCI_COREPLLCFG0_LOCK_MASK (0x1 << PRCI_COREPLLCFG0_LOCK_SHIFT)
--
--/* DDRPLLCFG0 */
--#define PRCI_DDRPLLCFG0_OFFSET 0xc
--# define PRCI_DDRPLLCFG0_DIVR_SHIFT 0
--# define PRCI_DDRPLLCFG0_DIVR_MASK (0x3f << PRCI_DDRPLLCFG0_DIVR_SHIFT)
--# define PRCI_DDRPLLCFG0_DIVF_SHIFT 6
--# define PRCI_DDRPLLCFG0_DIVF_MASK (0x1ff << PRCI_DDRPLLCFG0_DIVF_SHIFT)
--# define PRCI_DDRPLLCFG0_DIVQ_SHIFT 15
--# define PRCI_DDRPLLCFG0_DIVQ_MASK (0x7 << PRCI_DDRPLLCFG0_DIVQ_SHIFT)
--# define PRCI_DDRPLLCFG0_RANGE_SHIFT 18
--# define PRCI_DDRPLLCFG0_RANGE_MASK (0x7 << PRCI_DDRPLLCFG0_RANGE_SHIFT)
--# define PRCI_DDRPLLCFG0_BYPASS_SHIFT 24
--# define PRCI_DDRPLLCFG0_BYPASS_MASK (0x1 << PRCI_DDRPLLCFG0_BYPASS_SHIFT)
--# define PRCI_DDRPLLCFG0_FSE_SHIFT 25
--# define PRCI_DDRPLLCFG0_FSE_MASK (0x1 << PRCI_DDRPLLCFG0_FSE_SHIFT)
--# define PRCI_DDRPLLCFG0_LOCK_SHIFT 31
--# define PRCI_DDRPLLCFG0_LOCK_MASK (0x1 << PRCI_DDRPLLCFG0_LOCK_SHIFT)
-+#include "sifive-prci.h"
-
--/* DDRPLLCFG1 */
--#define PRCI_DDRPLLCFG1_OFFSET 0x10
--# define PRCI_DDRPLLCFG1_CKE_SHIFT 24
--# define PRCI_DDRPLLCFG1_CKE_MASK (0x1 << PRCI_DDRPLLCFG1_CKE_SHIFT)
-+/* PRCI integration data for each WRPLL instance */
-
--/* GEMGXLPLLCFG0 */
--#define PRCI_GEMGXLPLLCFG0_OFFSET 0x1c
--# define PRCI_GEMGXLPLLCFG0_DIVR_SHIFT 0
--# define PRCI_GEMGXLPLLCFG0_DIVR_MASK (0x3f << PRCI_GEMGXLPLLCFG0_DIVR_SHIFT)
--# define PRCI_GEMGXLPLLCFG0_DIVF_SHIFT 6
--# define PRCI_GEMGXLPLLCFG0_DIVF_MASK (0x1ff << PRCI_GEMGXLPLLCFG0_DIVF_SHIFT)
--# define PRCI_GEMGXLPLLCFG0_DIVQ_SHIFT 15
--# define PRCI_GEMGXLPLLCFG0_DIVQ_MASK (0x7 << PRCI_GEMGXLPLLCFG0_DIVQ_SHIFT)
--# define PRCI_GEMGXLPLLCFG0_RANGE_SHIFT 18
--# define PRCI_GEMGXLPLLCFG0_RANGE_MASK (0x7 << PRCI_GEMGXLPLLCFG0_RANGE_SHIFT)
--# define PRCI_GEMGXLPLLCFG0_BYPASS_SHIFT 24
--# define PRCI_GEMGXLPLLCFG0_BYPASS_MASK (0x1 << PRCI_GEMGXLPLLCFG0_BYPASS_SHIFT)
--# define PRCI_GEMGXLPLLCFG0_FSE_SHIFT 25
--# define PRCI_GEMGXLPLLCFG0_FSE_MASK (0x1 << PRCI_GEMGXLPLLCFG0_FSE_SHIFT)
--# define PRCI_GEMGXLPLLCFG0_LOCK_SHIFT 31
--# define PRCI_GEMGXLPLLCFG0_LOCK_MASK (0x1 << PRCI_GEMGXLPLLCFG0_LOCK_SHIFT)
--
--/* GEMGXLPLLCFG1 */
--#define PRCI_GEMGXLPLLCFG1_OFFSET 0x20
--# define PRCI_GEMGXLPLLCFG1_CKE_SHIFT 24
--# define PRCI_GEMGXLPLLCFG1_CKE_MASK (0x1 << PRCI_GEMGXLPLLCFG1_CKE_SHIFT)
--
--/* CORECLKSEL */
--#define PRCI_CORECLKSEL_OFFSET 0x24
--# define PRCI_CORECLKSEL_CORECLKSEL_SHIFT 0
--# define PRCI_CORECLKSEL_CORECLKSEL_MASK (0x1 << PRCI_CORECLKSEL_CORECLKSEL_SHIFT)
--
--/* DEVICESRESETREG */
--#define PRCI_DEVICESRESETREG_OFFSET 0x28
--# define PRCI_DEVICESRESETREG_DDR_CTRL_RST_N_SHIFT 0
--# define PRCI_DEVICESRESETREG_DDR_CTRL_RST_N_MASK (0x1 << PRCI_DEVICESRESETREG_DDR_CTRL_RST_N_SHIFT)
--# define PRCI_DEVICESRESETREG_DDR_AXI_RST_N_SHIFT 1
--# define PRCI_DEVICESRESETREG_DDR_AXI_RST_N_MASK (0x1 << PRCI_DEVICESRESETREG_DDR_AXI_RST_N_SHIFT)
--# define PRCI_DEVICESRESETREG_DDR_AHB_RST_N_SHIFT 2
--# define PRCI_DEVICESRESETREG_DDR_AHB_RST_N_MASK (0x1 << PRCI_DEVICESRESETREG_DDR_AHB_RST_N_SHIFT)
--# define PRCI_DEVICESRESETREG_DDR_PHY_RST_N_SHIFT 3
--# define PRCI_DEVICESRESETREG_DDR_PHY_RST_N_MASK (0x1 << PRCI_DEVICESRESETREG_DDR_PHY_RST_N_SHIFT)
--# define PRCI_DEVICESRESETREG_GEMGXL_RST_N_SHIFT 5
--# define PRCI_DEVICESRESETREG_GEMGXL_RST_N_MASK (0x1 << PRCI_DEVICESRESETREG_GEMGXL_RST_N_SHIFT)
--
--/* CLKMUXSTATUSREG */
--#define PRCI_CLKMUXSTATUSREG_OFFSET 0x2c
--# define PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_SHIFT 1
--# define PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_MASK (0x1 << PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_SHIFT)
--
--/*
-- * Private structures
-- */
--
--/**
-- * struct __prci_data - per-device-instance data
-- * @va: base virtual address of the PRCI IP block
-- * @hw_clks: encapsulates struct clk_hw records
-- *
-- * PRCI per-device instance data
-- */
--struct __prci_data {
-- void __iomem *va;
-- struct clk_hw_onecell_data hw_clks;
-+static struct __prci_wrpll_data __prci_corepll_data = {
-+ .cfg0_offs = PRCI_COREPLLCFG0_OFFSET,
-+ .enable_bypass = sifive_prci_coreclksel_use_hfclk,
-+ .disable_bypass = sifive_prci_coreclksel_use_corepll,
- };
-
--/**
-- * struct __prci_wrpll_data - WRPLL configuration and integration data
-- * @c: WRPLL current configuration record
-- * @enable_bypass: fn ptr to code to bypass the WRPLL (if applicable; else NULL)
-- * @disable_bypass: fn ptr to code to not bypass the WRPLL (or NULL)
-- * @cfg0_offs: WRPLL CFG0 register offset (in bytes) from the PRCI base address
-- *
-- * @enable_bypass and @disable_bypass are used for WRPLL instances
-- * that contain a separate external glitchless clock mux downstream
-- * from the PLL. The WRPLL internal bypass mux is not glitchless.
-- */
--struct __prci_wrpll_data {
-- struct wrpll_cfg c;
-- void (*enable_bypass)(struct __prci_data *pd);
-- void (*disable_bypass)(struct __prci_data *pd);
-- u8 cfg0_offs;
-+static struct __prci_wrpll_data __prci_ddrpll_data = {
-+ .cfg0_offs = PRCI_DDRPLLCFG0_OFFSET,
- };
-
--/**
-- * struct __prci_clock - describes a clock device managed by PRCI
-- * @name: user-readable clock name string - should match the manual
-- * @parent_name: parent name for this clock
-- * @ops: struct clk_ops for the Linux clock framework to use for control
-- * @hw: Linux-private clock data
-- * @pwd: WRPLL-specific data, associated with this clock (if not NULL)
-- * @pd: PRCI-specific data associated with this clock (if not NULL)
-- *
-- * PRCI clock data. Used by the PRCI driver to register PRCI-provided
-- * clocks to the Linux clock infrastructure.
-- */
--struct __prci_clock {
-- const char *name;
-- const char *parent_name;
-- const struct clk_ops *ops;
-- struct clk_hw hw;
-- struct __prci_wrpll_data *pwd;
-- struct __prci_data *pd;
-+static struct __prci_wrpll_data __prci_gemgxlpll_data = {
-+ .cfg0_offs = PRCI_GEMGXLPLLCFG0_OFFSET,
- };
-
--#define clk_hw_to_prci_clock(pwd) container_of(pwd, struct __prci_clock, hw)
--
--/*
-- * Private functions
-- */
--
--/**
-- * __prci_readl() - read from a PRCI register
-- * @pd: PRCI context
-- * @offs: register offset to read from (in bytes, from PRCI base address)
-- *
-- * Read the register located at offset @offs from the base virtual
-- * address of the PRCI register target described by @pd, and return
-- * the value to the caller.
-- *
-- * Context: Any context.
-- *
-- * Return: the contents of the register described by @pd and @offs.
-- */
--static u32 __prci_readl(struct __prci_data *pd, u32 offs)
--{
-- return readl_relaxed(pd->va + offs);
--}
--
--static void __prci_writel(u32 v, u32 offs, struct __prci_data *pd)
--{
-- writel_relaxed(v, pd->va + offs);
--}
--
--/* WRPLL-related private functions */
--
--/**
-- * __prci_wrpll_unpack() - unpack WRPLL configuration registers into parameters
-- * @c: ptr to a struct wrpll_cfg record to write config into
-- * @r: value read from the PRCI PLL configuration register
-- *
-- * Given a value @r read from an FU540 PRCI PLL configuration register,
-- * split it into fields and populate it into the WRPLL configuration record
-- * pointed to by @c.
-- *
-- * The COREPLLCFG0 macros are used below, but the other *PLLCFG0 macros
-- * have the same register layout.
-- *
-- * Context: Any context.
-- */
--static void __prci_wrpll_unpack(struct wrpll_cfg *c, u32 r)
--{
-- u32 v;
--
-- v = r & PRCI_COREPLLCFG0_DIVR_MASK;
-- v >>= PRCI_COREPLLCFG0_DIVR_SHIFT;
-- c->divr = v;
--
-- v = r & PRCI_COREPLLCFG0_DIVF_MASK;
-- v >>= PRCI_COREPLLCFG0_DIVF_SHIFT;
-- c->divf = v;
--
-- v = r & PRCI_COREPLLCFG0_DIVQ_MASK;
-- v >>= PRCI_COREPLLCFG0_DIVQ_SHIFT;
-- c->divq = v;
--
-- v = r & PRCI_COREPLLCFG0_RANGE_MASK;
-- v >>= PRCI_COREPLLCFG0_RANGE_SHIFT;
-- c->range = v;
--
-- c->flags &= (WRPLL_FLAGS_INT_FEEDBACK_MASK |
-- WRPLL_FLAGS_EXT_FEEDBACK_MASK);
--
-- /* external feedback mode not supported */
-- c->flags |= WRPLL_FLAGS_INT_FEEDBACK_MASK;
--}
--
--/**
-- * __prci_wrpll_pack() - pack PLL configuration parameters into a register value
-- * @c: pointer to a struct wrpll_cfg record containing the PLL's cfg
-- *
-- * Using a set of WRPLL configuration values pointed to by @c,
-- * assemble a PRCI PLL configuration register value, and return it to
-- * the caller.
-- *
-- * Context: Any context. Caller must ensure that the contents of the
-- * record pointed to by @c do not change during the execution
-- * of this function.
-- *
-- * Returns: a value suitable for writing into a PRCI PLL configuration
-- * register
-- */
--static u32 __prci_wrpll_pack(const struct wrpll_cfg *c)
--{
-- u32 r = 0;
--
-- r |= c->divr << PRCI_COREPLLCFG0_DIVR_SHIFT;
-- r |= c->divf << PRCI_COREPLLCFG0_DIVF_SHIFT;
-- r |= c->divq << PRCI_COREPLLCFG0_DIVQ_SHIFT;
-- r |= c->range << PRCI_COREPLLCFG0_RANGE_SHIFT;
--
-- /* external feedback mode not supported */
-- r |= PRCI_COREPLLCFG0_FSE_MASK;
--
-- return r;
--}
--
--/**
-- * __prci_wrpll_read_cfg() - read the WRPLL configuration from the PRCI
-- * @pd: PRCI context
-- * @pwd: PRCI WRPLL metadata
-- *
-- * Read the current configuration of the PLL identified by @pwd from
-- * the PRCI identified by @pd, and store it into the local configuration
-- * cache in @pwd.
-- *
-- * Context: Any context. Caller must prevent the records pointed to by
-- * @pd and @pwd from changing during execution.
-- */
--static void __prci_wrpll_read_cfg(struct __prci_data *pd,
-- struct __prci_wrpll_data *pwd)
--{
-- __prci_wrpll_unpack(&pwd->c, __prci_readl(pd, pwd->cfg0_offs));
--}
--
--/**
-- * __prci_wrpll_write_cfg() - write WRPLL configuration into the PRCI
-- * @pd: PRCI context
-- * @pwd: PRCI WRPLL metadata
-- * @c: WRPLL configuration record to write
-- *
-- * Write the WRPLL configuration described by @c into the WRPLL
-- * configuration register identified by @pwd in the PRCI instance
-- * described by @c. Make a cached copy of the WRPLL's current
-- * configuration so it can be used by other code.
-- *
-- * Context: Any context. Caller must prevent the records pointed to by
-- * @pd and @pwd from changing during execution.
-- */
--static void __prci_wrpll_write_cfg(struct __prci_data *pd,
-- struct __prci_wrpll_data *pwd,
-- struct wrpll_cfg *c)
--{
-- __prci_writel(__prci_wrpll_pack(c), pwd->cfg0_offs, pd);
--
-- memcpy(&pwd->c, c, sizeof(*c));
--}
--
--/* Core clock mux control */
--
--/**
-- * __prci_coreclksel_use_hfclk() - switch the CORECLK mux to output HFCLK
-- * @pd: struct __prci_data * for the PRCI containing the CORECLK mux reg
-- *
-- * Switch the CORECLK mux to the HFCLK input source; return once complete.
-- *
-- * Context: Any context. Caller must prevent concurrent changes to the
-- * PRCI_CORECLKSEL_OFFSET register.
-- */
--static void __prci_coreclksel_use_hfclk(struct __prci_data *pd)
--{
-- u32 r;
--
-- r = __prci_readl(pd, PRCI_CORECLKSEL_OFFSET);
-- r |= PRCI_CORECLKSEL_CORECLKSEL_MASK;
-- __prci_writel(r, PRCI_CORECLKSEL_OFFSET, pd);
--
-- r = __prci_readl(pd, PRCI_CORECLKSEL_OFFSET); /* barrier */
--}
--
--/**
-- * __prci_coreclksel_use_corepll() - switch the CORECLK mux to output COREPLL
-- * @pd: struct __prci_data * for the PRCI containing the CORECLK mux reg
-- *
-- * Switch the CORECLK mux to the PLL output clock; return once complete.
-- *
-- * Context: Any context. Caller must prevent concurrent changes to the
-- * PRCI_CORECLKSEL_OFFSET register.
-- */
--static void __prci_coreclksel_use_corepll(struct __prci_data *pd)
--{
-- u32 r;
--
-- r = __prci_readl(pd, PRCI_CORECLKSEL_OFFSET);
-- r &= ~PRCI_CORECLKSEL_CORECLKSEL_MASK;
-- __prci_writel(r, PRCI_CORECLKSEL_OFFSET, pd);
--
-- r = __prci_readl(pd, PRCI_CORECLKSEL_OFFSET); /* barrier */
--}
--
--/*
-- * Linux clock framework integration
-- *
-- * See the Linux clock framework documentation for more information on
-- * these functions.
-- */
--
--static unsigned long sifive_fu540_prci_wrpll_recalc_rate(struct clk_hw *hw,
-- unsigned long parent_rate)
--{
-- struct __prci_clock *pc = clk_hw_to_prci_clock(hw);
-- struct __prci_wrpll_data *pwd = pc->pwd;
--
-- return wrpll_calc_output_rate(&pwd->c, parent_rate);
--}
--
--static long sifive_fu540_prci_wrpll_round_rate(struct clk_hw *hw,
-- unsigned long rate,
-- unsigned long *parent_rate)
--{
-- struct __prci_clock *pc = clk_hw_to_prci_clock(hw);
-- struct __prci_wrpll_data *pwd = pc->pwd;
-- struct wrpll_cfg c;
--
-- memcpy(&c, &pwd->c, sizeof(c));
--
-- wrpll_configure_for_rate(&c, rate, *parent_rate);
--
-- return wrpll_calc_output_rate(&c, *parent_rate);
--}
--
--static int sifive_fu540_prci_wrpll_set_rate(struct clk_hw *hw,
-- unsigned long rate,
-- unsigned long parent_rate)
--{
-- struct __prci_clock *pc = clk_hw_to_prci_clock(hw);
-- struct __prci_wrpll_data *pwd = pc->pwd;
-- struct __prci_data *pd = pc->pd;
-- int r;
--
-- r = wrpll_configure_for_rate(&pwd->c, rate, parent_rate);
-- if (r)
-- return r;
--
-- if (pwd->enable_bypass)
-- pwd->enable_bypass(pd);
--
-- __prci_wrpll_write_cfg(pd, pwd, &pwd->c);
--
-- udelay(wrpll_calc_max_lock_us(&pwd->c));
--
-- if (pwd->disable_bypass)
-- pwd->disable_bypass(pd);
--
-- return 0;
--}
-+/* Linux clock framework integration */
-
- static const struct clk_ops sifive_fu540_prci_wrpll_clk_ops = {
-- .set_rate = sifive_fu540_prci_wrpll_set_rate,
-- .round_rate = sifive_fu540_prci_wrpll_round_rate,
-- .recalc_rate = sifive_fu540_prci_wrpll_recalc_rate,
-+ .set_rate = sifive_prci_wrpll_set_rate,
-+ .round_rate = sifive_prci_wrpll_round_rate,
-+ .recalc_rate = sifive_prci_wrpll_recalc_rate,
- };
-
- static const struct clk_ops sifive_fu540_prci_wrpll_ro_clk_ops = {
-- .recalc_rate = sifive_fu540_prci_wrpll_recalc_rate,
-+ .recalc_rate = sifive_prci_wrpll_recalc_rate,
- };
-
--/* TLCLKSEL clock integration */
--
--static unsigned long sifive_fu540_prci_tlclksel_recalc_rate(struct clk_hw *hw,
-- unsigned long parent_rate)
--{
-- struct __prci_clock *pc = clk_hw_to_prci_clock(hw);
-- struct __prci_data *pd = pc->pd;
-- u32 v;
-- u8 div;
--
-- v = __prci_readl(pd, PRCI_CLKMUXSTATUSREG_OFFSET);
-- v &= PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_MASK;
-- div = v ? 1 : 2;
--
-- return div_u64(parent_rate, div);
--}
--
- static const struct clk_ops sifive_fu540_prci_tlclksel_clk_ops = {
-- .recalc_rate = sifive_fu540_prci_tlclksel_recalc_rate,
--};
--
--/*
-- * PRCI integration data for each WRPLL instance
-- */
--
--static struct __prci_wrpll_data __prci_corepll_data = {
-- .cfg0_offs = PRCI_COREPLLCFG0_OFFSET,
-- .enable_bypass = __prci_coreclksel_use_hfclk,
-- .disable_bypass = __prci_coreclksel_use_corepll,
--};
--
--static struct __prci_wrpll_data __prci_ddrpll_data = {
-- .cfg0_offs = PRCI_DDRPLLCFG0_OFFSET,
-+ .recalc_rate = sifive_prci_tlclksel_recalc_rate,
- };
-
--static struct __prci_wrpll_data __prci_gemgxlpll_data = {
-- .cfg0_offs = PRCI_GEMGXLPLLCFG0_OFFSET,
--};
--
--/*
-- * List of clock controls provided by the PRCI
-- */
--
--static struct __prci_clock __prci_init_clocks[] = {
-+/* List of clock controls provided by the PRCI */
-+struct __prci_clock __prci_init_clocks_fu540[] = {
- [PRCI_CLK_COREPLL] = {
- .name = "corepll",
- .parent_name = "hfclk",
-@@ -506,125 +78,3 @@ static struct __prci_clock __prci_init_clocks[] = {
- .ops = &sifive_fu540_prci_tlclksel_clk_ops,
- },
- };
--
--/**
-- * __prci_register_clocks() - register clock controls in the PRCI with Linux
-- * @dev: Linux struct device *
-- *
-- * Register the list of clock controls described in __prci_init_plls[] with
-- * the Linux clock framework.
-- *
-- * Return: 0 upon success or a negative error code upon failure.
-- */
--static int __prci_register_clocks(struct device *dev, struct __prci_data *pd)
--{
-- struct clk_init_data init = { };
-- struct __prci_clock *pic;
-- int parent_count, i, r;
--
-- parent_count = of_clk_get_parent_count(dev->of_node);
-- if (parent_count != EXPECTED_CLK_PARENT_COUNT) {
-- dev_err(dev, "expected only two parent clocks, found %d\n",
-- parent_count);
-- return -EINVAL;
-- }
--
-- /* Register PLLs */
-- for (i = 0; i < ARRAY_SIZE(__prci_init_clocks); ++i) {
-- pic = &__prci_init_clocks[i];
--
-- init.name = pic->name;
-- init.parent_names = &pic->parent_name;
-- init.num_parents = 1;
-- init.ops = pic->ops;
-- pic->hw.init = &init;
--
-- pic->pd = pd;
--
-- if (pic->pwd)
-- __prci_wrpll_read_cfg(pd, pic->pwd);
--
-- r = devm_clk_hw_register(dev, &pic->hw);
-- if (r) {
-- dev_warn(dev, "Failed to register clock %s: %d\n",
-- init.name, r);
-- return r;
-- }
--
-- r = clk_hw_register_clkdev(&pic->hw, pic->name, dev_name(dev));
-- if (r) {
-- dev_warn(dev, "Failed to register clkdev for %s: %d\n",
-- init.name, r);
-- return r;
-- }
--
-- pd->hw_clks.hws[i] = &pic->hw;
-- }
--
-- pd->hw_clks.num = i;
--
-- r = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
-- &pd->hw_clks);
-- if (r) {
-- dev_err(dev, "could not add hw_provider: %d\n", r);
-- return r;
-- }
--
-- return 0;
--}
--
--/*
-- * Linux device model integration
-- *
-- * See the Linux device model documentation for more information about
-- * these functions.
-- */
--static int sifive_fu540_prci_probe(struct platform_device *pdev)
--{
-- struct device *dev = &pdev->dev;
-- struct resource *res;
-- struct __prci_data *pd;
-- int r;
--
-- pd = devm_kzalloc(dev,
-- struct_size(pd, hw_clks.hws,
-- ARRAY_SIZE(__prci_init_clocks)),
-- GFP_KERNEL);
-- if (!pd)
-- return -ENOMEM;
--
-- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-- pd->va = devm_ioremap_resource(dev, res);
-- if (IS_ERR(pd->va))
-- return PTR_ERR(pd->va);
--
-- r = __prci_register_clocks(dev, pd);
-- if (r) {
-- dev_err(dev, "could not register clocks: %d\n", r);
-- return r;
-- }
--
-- dev_dbg(dev, "SiFive FU540 PRCI probed\n");
--
-- return 0;
--}
--
--static const struct of_device_id sifive_fu540_prci_of_match[] = {
-- { .compatible = "sifive,fu540-c000-prci", },
-- {}
--};
--MODULE_DEVICE_TABLE(of, sifive_fu540_prci_of_match);
--
--static struct platform_driver sifive_fu540_prci_driver = {
-- .driver = {
-- .name = "sifive-fu540-prci",
-- .of_match_table = sifive_fu540_prci_of_match,
-- },
-- .probe = sifive_fu540_prci_probe,
--};
--
--static int __init sifive_fu540_prci_init(void)
--{
-- return platform_driver_register(&sifive_fu540_prci_driver);
--}
--core_initcall(sifive_fu540_prci_init);
-diff --git a/drivers/clk/sifive/fu540-prci.h b/drivers/clk/sifive/fu540-prci.h
-new file mode 100644
-index 00000000..c8271ef
---- /dev/null
-+++ b/drivers/clk/sifive/fu540-prci.h
-@@ -0,0 +1,21 @@
-+/* SPDX-License-Identifier: GPL-2.0 */
-+/*
-+ * Copyright (C) 2020 SiFive, Inc.
-+ * Zong Li
-+ */
-+
-+#ifndef __SIFIVE_CLK_FU540_PRCI_H
-+#define __SIFIVE_CLK_FU540_PRCI_H
-+
-+#include "sifive-prci.h"
-+
-+#define NUM_CLOCK_FU540 4
-+
-+extern struct __prci_clock __prci_init_clocks_fu540[NUM_CLOCK_FU540];
-+
-+static const struct prci_clk_desc prci_clk_fu540 = {
-+ .clks = __prci_init_clocks_fu540,
-+ .num_clks = ARRAY_SIZE(__prci_init_clocks_fu540),
-+};
-+
-+#endif /* __SIFIVE_CLK_FU540_PRCI_H */
-diff --git a/drivers/clk/sifive/sifive-prci.c b/drivers/clk/sifive/sifive-prci.c
-new file mode 100644
-index 00000000..70653d3
---- /dev/null
-+++ b/drivers/clk/sifive/sifive-prci.c
-@@ -0,0 +1,395 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * Copyright (C) 2020 SiFive, Inc.
-+ * Copyright (C) 2020 Zong Li
-+ */
-+
-+#include <linux/clkdev.h>
-+#include <linux/delay.h>
-+#include <linux/io.h>
-+#include <linux/of_device.h>
-+#include "sifive-prci.h"
-+#include "fu540-prci.h"
-+
-+/*
-+ * Private functions
-+ */
-+
-+/**
-+ * __prci_readl() - read from a PRCI register
-+ * @pd: PRCI context
-+ * @offs: register offset to read from (in bytes, from PRCI base address)
-+ *
-+ * Read the register located at offset @offs from the base virtual
-+ * address of the PRCI register target described by @pd, and return
-+ * the value to the caller.
-+ *
-+ * Context: Any context.
-+ *
-+ * Return: the contents of the register described by @pd and @offs.
-+ */
-+static u32 __prci_readl(struct __prci_data *pd, u32 offs)
-+{
-+ return readl_relaxed(pd->va + offs);
-+}
-+
-+static void __prci_writel(u32 v, u32 offs, struct __prci_data *pd)
-+{
-+ writel_relaxed(v, pd->va + offs);
-+}
-+
-+/* WRPLL-related private functions */
-+
-+/**
-+ * __prci_wrpll_unpack() - unpack WRPLL configuration registers into parameters
-+ * @c: ptr to a struct wrpll_cfg record to write config into
-+ * @r: value read from the PRCI PLL configuration register
-+ *
-+ * Given a value @r read from an FU740 PRCI PLL configuration register,
-+ * split it into fields and populate it into the WRPLL configuration record
-+ * pointed to by @c.
-+ *
-+ * The COREPLLCFG0 macros are used below, but the other *PLLCFG0 macros
-+ * have the same register layout.
-+ *
-+ * Context: Any context.
-+ */
-+static void __prci_wrpll_unpack(struct wrpll_cfg *c, u32 r)
-+{
-+ u32 v;
-+
-+ v = r & PRCI_COREPLLCFG0_DIVR_MASK;
-+ v >>= PRCI_COREPLLCFG0_DIVR_SHIFT;
-+ c->divr = v;
-+
-+ v = r & PRCI_COREPLLCFG0_DIVF_MASK;
-+ v >>= PRCI_COREPLLCFG0_DIVF_SHIFT;
-+ c->divf = v;
-+
-+ v = r & PRCI_COREPLLCFG0_DIVQ_MASK;
-+ v >>= PRCI_COREPLLCFG0_DIVQ_SHIFT;
-+ c->divq = v;
-+
-+ v = r & PRCI_COREPLLCFG0_RANGE_MASK;
-+ v >>= PRCI_COREPLLCFG0_RANGE_SHIFT;
-+ c->range = v;
-+
-+ c->flags &=
-+ (WRPLL_FLAGS_INT_FEEDBACK_MASK | WRPLL_FLAGS_EXT_FEEDBACK_MASK);
-+
-+ /* external feedback mode not supported */
-+ c->flags |= WRPLL_FLAGS_INT_FEEDBACK_MASK;
-+}
-+
-+/**
-+ * __prci_wrpll_pack() - pack PLL configuration parameters into a register value
-+ * @c: pointer to a struct wrpll_cfg record containing the PLL's cfg
-+ *
-+ * Using a set of WRPLL configuration values pointed to by @c,
-+ * assemble a PRCI PLL configuration register value, and return it to
-+ * the caller.
-+ *
-+ * Context: Any context. Caller must ensure that the contents of the
-+ * record pointed to by @c do not change during the execution
-+ * of this function.
-+ *
-+ * Returns: a value suitable for writing into a PRCI PLL configuration
-+ * register
-+ */
-+static u32 __prci_wrpll_pack(const struct wrpll_cfg *c)
-+{
-+ u32 r = 0;
-+
-+ r |= c->divr << PRCI_COREPLLCFG0_DIVR_SHIFT;
-+ r |= c->divf << PRCI_COREPLLCFG0_DIVF_SHIFT;
-+ r |= c->divq << PRCI_COREPLLCFG0_DIVQ_SHIFT;
-+ r |= c->range << PRCI_COREPLLCFG0_RANGE_SHIFT;
-+
-+ /* external feedback mode not supported */
-+ r |= PRCI_COREPLLCFG0_FSE_MASK;
-+
-+ return r;
-+}
-+
-+/**
-+ * __prci_wrpll_read_cfg() - read the WRPLL configuration from the PRCI
-+ * @pd: PRCI context
-+ * @pwd: PRCI WRPLL metadata
-+ *
-+ * Read the current configuration of the PLL identified by @pwd from
-+ * the PRCI identified by @pd, and store it into the local configuration
-+ * cache in @pwd.
-+ *
-+ * Context: Any context. Caller must prevent the records pointed to by
-+ * @pd and @pwd from changing during execution.
-+ */
-+static void __prci_wrpll_read_cfg(struct __prci_data *pd,
-+ struct __prci_wrpll_data *pwd)
-+{
-+ __prci_wrpll_unpack(&pwd->c, __prci_readl(pd, pwd->cfg0_offs));
-+}
-+
-+/**
-+ * __prci_wrpll_write_cfg() - write WRPLL configuration into the PRCI
-+ * @pd: PRCI context
-+ * @pwd: PRCI WRPLL metadata
-+ * @c: WRPLL configuration record to write
-+ *
-+ * Write the WRPLL configuration described by @c into the WRPLL
-+ * configuration register identified by @pwd in the PRCI instance
-+ * described by @c. Make a cached copy of the WRPLL's current
-+ * configuration so it can be used by other code.
-+ *
-+ * Context: Any context. Caller must prevent the records pointed to by
-+ * @pd and @pwd from changing during execution.
-+ */
-+static void __prci_wrpll_write_cfg(struct __prci_data *pd,
-+ struct __prci_wrpll_data *pwd,
-+ struct wrpll_cfg *c)
-+{
-+ __prci_writel(__prci_wrpll_pack(c), pwd->cfg0_offs, pd);
-+
-+ memcpy(&pwd->c, c, sizeof(*c));
-+}
-+
-+/*
-+ * Linux clock framework integration
-+ *
-+ * See the Linux clock framework documentation for more information on
-+ * these functions.
-+ */
-+
-+unsigned long sifive_prci_wrpll_recalc_rate(struct clk_hw *hw,
-+ unsigned long parent_rate)
-+{
-+ struct __prci_clock *pc = clk_hw_to_prci_clock(hw);
-+ struct __prci_wrpll_data *pwd = pc->pwd;
-+
-+ return wrpll_calc_output_rate(&pwd->c, parent_rate);
-+}
-+
-+long sifive_prci_wrpll_round_rate(struct clk_hw *hw,
-+ unsigned long rate,
-+ unsigned long *parent_rate)
-+{
-+ struct __prci_clock *pc = clk_hw_to_prci_clock(hw);
-+ struct __prci_wrpll_data *pwd = pc->pwd;
-+ struct wrpll_cfg c;
-+
-+ memcpy(&c, &pwd->c, sizeof(c));
-+
-+ wrpll_configure_for_rate(&c, rate, *parent_rate);
-+
-+ return wrpll_calc_output_rate(&c, *parent_rate);
-+}
-+
-+int sifive_prci_wrpll_set_rate(struct clk_hw *hw,
-+ unsigned long rate, unsigned long parent_rate)
-+{
-+ struct __prci_clock *pc = clk_hw_to_prci_clock(hw);
-+ struct __prci_wrpll_data *pwd = pc->pwd;
-+ struct __prci_data *pd = pc->pd;
-+ int r;
-+
-+ r = wrpll_configure_for_rate(&pwd->c, rate, parent_rate);
-+ if (r)
-+ return r;
-+
-+ if (pwd->enable_bypass)
-+ pwd->enable_bypass(pd);
-+
-+ __prci_wrpll_write_cfg(pd, pwd, &pwd->c);
-+
-+ udelay(wrpll_calc_max_lock_us(&pwd->c));
-+
-+ if (pwd->disable_bypass)
-+ pwd->disable_bypass(pd);
-+
-+ return 0;
-+}
-+
-+/* TLCLKSEL clock integration */
-+
-+unsigned long sifive_prci_tlclksel_recalc_rate(struct clk_hw *hw,
-+ unsigned long parent_rate)
-+{
-+ struct __prci_clock *pc = clk_hw_to_prci_clock(hw);
-+ struct __prci_data *pd = pc->pd;
-+ u32 v;
-+ u8 div;
-+
-+ v = __prci_readl(pd, PRCI_CLKMUXSTATUSREG_OFFSET);
-+ v &= PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_MASK;
-+ div = v ? 1 : 2;
-+
-+ return div_u64(parent_rate, div);
-+}
-+
-+/*
-+ * Core clock mux control
-+ */
-+
-+/**
-+ * sifive_prci_coreclksel_use_hfclk() - switch the CORECLK mux to output HFCLK
-+ * @pd: struct __prci_data * for the PRCI containing the CORECLK mux reg
-+ *
-+ * Switch the CORECLK mux to the HFCLK input source; return once complete.
-+ *
-+ * Context: Any context. Caller must prevent concurrent changes to the
-+ * PRCI_CORECLKSEL_OFFSET register.
-+ */
-+void sifive_prci_coreclksel_use_hfclk(struct __prci_data *pd)
-+{
-+ u32 r;
-+
-+ r = __prci_readl(pd, PRCI_CORECLKSEL_OFFSET);
-+ r |= PRCI_CORECLKSEL_CORECLKSEL_MASK;
-+ __prci_writel(r, PRCI_CORECLKSEL_OFFSET, pd);
-+
-+ r = __prci_readl(pd, PRCI_CORECLKSEL_OFFSET); /* barrier */
-+}
-+
-+/**
-+ * sifive_prci_coreclksel_use_corepll() - switch the CORECLK mux to output
-+ * COREPLL
-+ * @pd: struct __prci_data * for the PRCI containing the CORECLK mux reg
-+ *
-+ * Switch the CORECLK mux to the COREPLL output clock; return once complete.
-+ *
-+ * Context: Any context. Caller must prevent concurrent changes to the
-+ * PRCI_CORECLKSEL_OFFSET register.
-+ */
-+void sifive_prci_coreclksel_use_corepll(struct __prci_data *pd)
-+{
-+ u32 r;
-+
-+ r = __prci_readl(pd, PRCI_CORECLKSEL_OFFSET);
-+ r &= ~PRCI_CORECLKSEL_CORECLKSEL_MASK;
-+ __prci_writel(r, PRCI_CORECLKSEL_OFFSET, pd);
-+
-+ r = __prci_readl(pd, PRCI_CORECLKSEL_OFFSET); /* barrier */
-+}
-+
-+/**
-+ * __prci_register_clocks() - register clock controls in the PRCI
-+ * @dev: Linux struct device
-+ * @pd: The pointer for PRCI per-device instance data
-+ * @desc: The pointer for the information of clocks of each SoCs
-+ *
-+ * Register the list of clock controls described in __prci_init_clocks[] with
-+ * the Linux clock framework.
-+ *
-+ * Return: 0 upon success or a negative error code upon failure.
-+ */
-+static int __prci_register_clocks(struct device *dev, struct __prci_data *pd,
-+ const struct prci_clk_desc *desc)
-+{
-+ struct clk_init_data init = { };
-+ struct __prci_clock *pic;
-+ int parent_count, i, r;
-+
-+ parent_count = of_clk_get_parent_count(dev->of_node);
-+ if (parent_count != EXPECTED_CLK_PARENT_COUNT) {
-+ dev_err(dev, "expected only two parent clocks, found %d\n",
-+ parent_count);
-+ return -EINVAL;
-+ }
-+
-+ /* Register PLLs */
-+ for (i = 0; i < desc->num_clks; ++i) {
-+ pic = &(desc->clks[i]);
-+
-+ init.name = pic->name;
-+ init.parent_names = &pic->parent_name;
-+ init.num_parents = 1;
-+ init.ops = pic->ops;
-+ pic->hw.init = &init;
-+
-+ pic->pd = pd;
-+
-+ if (pic->pwd)
-+ __prci_wrpll_read_cfg(pd, pic->pwd);
-+
-+ r = devm_clk_hw_register(dev, &pic->hw);
-+ if (r) {
-+ dev_warn(dev, "Failed to register clock %s: %d\n",
-+ init.name, r);
-+ return r;
-+ }
-+
-+ r = clk_hw_register_clkdev(&pic->hw, pic->name, dev_name(dev));
-+ if (r) {
-+ dev_warn(dev, "Failed to register clkdev for %s: %d\n",
-+ init.name, r);
-+ return r;
-+ }
-+
-+ pd->hw_clks.hws[i] = &pic->hw;
-+ }
-+
-+ pd->hw_clks.num = i;
-+
-+ r = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
-+ &pd->hw_clks);
-+ if (r) {
-+ dev_err(dev, "could not add hw_provider: %d\n", r);
-+ return r;
-+ }
-+
-+ return 0;
-+}
-+
-+/**
-+ * sifive_prci_init() - initialize prci data and check parent count
-+ * @pdev: platform device pointer for the prci
-+ *
-+ * Return: 0 upon success or a negative error code upon failure.
-+ */
-+static int sifive_prci_probe(struct platform_device *pdev)
-+{
-+ struct device *dev = &pdev->dev;
-+ struct resource *res;
-+ struct __prci_data *pd;
-+ const struct prci_clk_desc *desc;
-+ int r;
-+
-+ desc = of_device_get_match_data(&pdev->dev);
-+
-+ pd = devm_kzalloc(dev, struct_size(pd, hw_clks.hws, desc->num_clks), GFP_KERNEL);
-+ if (!pd)
-+ return -ENOMEM;
-+
-+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+ pd->va = devm_ioremap_resource(dev, res);
-+ if (IS_ERR(pd->va))
-+ return PTR_ERR(pd->va);
-+
-+ r = __prci_register_clocks(dev, pd, desc);
-+ if (r) {
-+ dev_err(dev, "could not register clocks: %d\n", r);
-+ return r;
-+ }
-+
-+ dev_dbg(dev, "SiFive PRCI probed\n");
-+
-+ return 0;
-+}
-+
-+static const struct of_device_id sifive_prci_of_match[] = {
-+ {.compatible = "sifive,fu540-c000-prci", .data = &prci_clk_fu540},
-+ {}
-+};
-+
-+static struct platform_driver sifive_prci_driver = {
-+ .driver = {
-+ .name = "sifive-clk-prci",
-+ .of_match_table = sifive_prci_of_match,
-+ },
-+ .probe = sifive_prci_probe,
-+};
-+
-+static int __init sifive_prci_init(void)
-+{
-+ return platform_driver_register(&sifive_prci_driver);
-+}
-+core_initcall(sifive_prci_init);
-diff --git a/drivers/clk/sifive/sifive-prci.h b/drivers/clk/sifive/sifive-prci.h
-new file mode 100644
-index 00000000..280df63
---- /dev/null
-+++ b/drivers/clk/sifive/sifive-prci.h
-@@ -0,0 +1,201 @@
-+/* SPDX-License-Identifier: GPL-2.0 */
-+/*
-+ * Copyright (C) 2018-2019 SiFive, Inc.
-+ * Wesley Terpstra
-+ * Paul Walmsley
-+ * Zong Li
-+ */
-+
-+#ifndef __SIFIVE_CLK_SIFIVE_PRCI_H
-+#define __SIFIVE_CLK_SIFIVE_PRCI_H
-+
-+#include <linux/clk/analogbits-wrpll-cln28hpc.h>
-+#include <linux/clk-provider.h>
-+#include <linux/platform_device.h>
-+
-+/*
-+ * EXPECTED_CLK_PARENT_COUNT: how many parent clocks this driver expects:
-+ * hfclk and rtcclk
-+ */
-+#define EXPECTED_CLK_PARENT_COUNT 2
-+
-+/*
-+ * Register offsets and bitmasks
-+ */
-+
-+/* COREPLLCFG0 */
-+#define PRCI_COREPLLCFG0_OFFSET 0x4
-+#define PRCI_COREPLLCFG0_DIVR_SHIFT 0
-+#define PRCI_COREPLLCFG0_DIVR_MASK (0x3f << PRCI_COREPLLCFG0_DIVR_SHIFT)
-+#define PRCI_COREPLLCFG0_DIVF_SHIFT 6
-+#define PRCI_COREPLLCFG0_DIVF_MASK (0x1ff << PRCI_COREPLLCFG0_DIVF_SHIFT)
-+#define PRCI_COREPLLCFG0_DIVQ_SHIFT 15
-+#define PRCI_COREPLLCFG0_DIVQ_MASK (0x7 << PRCI_COREPLLCFG0_DIVQ_SHIFT)
-+#define PRCI_COREPLLCFG0_RANGE_SHIFT 18
-+#define PRCI_COREPLLCFG0_RANGE_MASK (0x7 << PRCI_COREPLLCFG0_RANGE_SHIFT)
-+#define PRCI_COREPLLCFG0_BYPASS_SHIFT 24
-+#define PRCI_COREPLLCFG0_BYPASS_MASK (0x1 << PRCI_COREPLLCFG0_BYPASS_SHIFT)
-+#define PRCI_COREPLLCFG0_FSE_SHIFT 25
-+#define PRCI_COREPLLCFG0_FSE_MASK (0x1 << PRCI_COREPLLCFG0_FSE_SHIFT)
-+#define PRCI_COREPLLCFG0_LOCK_SHIFT 31
-+#define PRCI_COREPLLCFG0_LOCK_MASK (0x1 << PRCI_COREPLLCFG0_LOCK_SHIFT)
-+
-+/* DDRPLLCFG0 */
-+#define PRCI_DDRPLLCFG0_OFFSET 0xc
-+#define PRCI_DDRPLLCFG0_DIVR_SHIFT 0
-+#define PRCI_DDRPLLCFG0_DIVR_MASK (0x3f << PRCI_DDRPLLCFG0_DIVR_SHIFT)
-+#define PRCI_DDRPLLCFG0_DIVF_SHIFT 6
-+#define PRCI_DDRPLLCFG0_DIVF_MASK (0x1ff << PRCI_DDRPLLCFG0_DIVF_SHIFT)
-+#define PRCI_DDRPLLCFG0_DIVQ_SHIFT 15
-+#define PRCI_DDRPLLCFG0_DIVQ_MASK (0x7 << PRCI_DDRPLLCFG0_DIVQ_SHIFT)
-+#define PRCI_DDRPLLCFG0_RANGE_SHIFT 18
-+#define PRCI_DDRPLLCFG0_RANGE_MASK (0x7 << PRCI_DDRPLLCFG0_RANGE_SHIFT)
-+#define PRCI_DDRPLLCFG0_BYPASS_SHIFT 24
-+#define PRCI_DDRPLLCFG0_BYPASS_MASK (0x1 << PRCI_DDRPLLCFG0_BYPASS_SHIFT)
-+#define PRCI_DDRPLLCFG0_FSE_SHIFT 25
-+#define PRCI_DDRPLLCFG0_FSE_MASK (0x1 << PRCI_DDRPLLCFG0_FSE_SHIFT)
-+#define PRCI_DDRPLLCFG0_LOCK_SHIFT 31
-+#define PRCI_DDRPLLCFG0_LOCK_MASK (0x1 << PRCI_DDRPLLCFG0_LOCK_SHIFT)
-+
-+/* DDRPLLCFG1 */
-+#define PRCI_DDRPLLCFG1_OFFSET 0x10
-+#define PRCI_DDRPLLCFG1_CKE_SHIFT 24
-+#define PRCI_DDRPLLCFG1_CKE_MASK (0x1 << PRCI_DDRPLLCFG1_CKE_SHIFT)
-+
-+/* GEMGXLPLLCFG0 */
-+#define PRCI_GEMGXLPLLCFG0_OFFSET 0x1c
-+#define PRCI_GEMGXLPLLCFG0_DIVR_SHIFT 0
-+#define PRCI_GEMGXLPLLCFG0_DIVR_MASK (0x3f << PRCI_GEMGXLPLLCFG0_DIVR_SHIFT)
-+#define PRCI_GEMGXLPLLCFG0_DIVF_SHIFT 6
-+#define PRCI_GEMGXLPLLCFG0_DIVF_MASK (0x1ff << PRCI_GEMGXLPLLCFG0_DIVF_SHIFT)
-+#define PRCI_GEMGXLPLLCFG0_DIVQ_SHIFT 15
-+#define PRCI_GEMGXLPLLCFG0_DIVQ_MASK (0x7 << PRCI_GEMGXLPLLCFG0_DIVQ_SHIFT)
-+#define PRCI_GEMGXLPLLCFG0_RANGE_SHIFT 18
-+#define PRCI_GEMGXLPLLCFG0_RANGE_MASK (0x7 << PRCI_GEMGXLPLLCFG0_RANGE_SHIFT)
-+#define PRCI_GEMGXLPLLCFG0_BYPASS_SHIFT 24
-+#define PRCI_GEMGXLPLLCFG0_BYPASS_MASK (0x1 << PRCI_GEMGXLPLLCFG0_BYPASS_SHIFT)
-+#define PRCI_GEMGXLPLLCFG0_FSE_SHIFT 25
-+#define PRCI_GEMGXLPLLCFG0_FSE_MASK (0x1 << PRCI_GEMGXLPLLCFG0_FSE_SHIFT)
-+#define PRCI_GEMGXLPLLCFG0_LOCK_SHIFT 31
-+#define PRCI_GEMGXLPLLCFG0_LOCK_MASK (0x1 << PRCI_GEMGXLPLLCFG0_LOCK_SHIFT)
-+
-+/* GEMGXLPLLCFG1 */
-+#define PRCI_GEMGXLPLLCFG1_OFFSET 0x20
-+#define PRCI_GEMGXLPLLCFG1_CKE_SHIFT 24
-+#define PRCI_GEMGXLPLLCFG1_CKE_MASK (0x1 << PRCI_GEMGXLPLLCFG1_CKE_SHIFT)
-+
-+/* CORECLKSEL */
-+#define PRCI_CORECLKSEL_OFFSET 0x24
-+#define PRCI_CORECLKSEL_CORECLKSEL_SHIFT 0
-+#define PRCI_CORECLKSEL_CORECLKSEL_MASK \
-+ (0x1 << PRCI_CORECLKSEL_CORECLKSEL_SHIFT)
-+
-+/* DEVICESRESETREG */
-+#define PRCI_DEVICESRESETREG_OFFSET 0x28
-+#define PRCI_DEVICESRESETREG_DDR_CTRL_RST_N_SHIFT 0
-+#define PRCI_DEVICESRESETREG_DDR_CTRL_RST_N_MASK \
-+ (0x1 << PRCI_DEVICESRESETREG_DDR_CTRL_RST_N_SHIFT)
-+#define PRCI_DEVICESRESETREG_DDR_AXI_RST_N_SHIFT 1
-+#define PRCI_DEVICESRESETREG_DDR_AXI_RST_N_MASK \
-+ (0x1 << PRCI_DEVICESRESETREG_DDR_AXI_RST_N_SHIFT)
-+#define PRCI_DEVICESRESETREG_DDR_AHB_RST_N_SHIFT 2
-+#define PRCI_DEVICESRESETREG_DDR_AHB_RST_N_MASK \
-+ (0x1 << PRCI_DEVICESRESETREG_DDR_AHB_RST_N_SHIFT)
-+#define PRCI_DEVICESRESETREG_DDR_PHY_RST_N_SHIFT 3
-+#define PRCI_DEVICESRESETREG_DDR_PHY_RST_N_MASK \
-+ (0x1 << PRCI_DEVICESRESETREG_DDR_PHY_RST_N_SHIFT)
-+#define PRCI_DEVICESRESETREG_GEMGXL_RST_N_SHIFT 5
-+#define PRCI_DEVICESRESETREG_GEMGXL_RST_N_MASK \
-+ (0x1 << PRCI_DEVICESRESETREG_GEMGXL_RST_N_SHIFT)
-+#define PRCI_DEVICESRESETREG_CHIPLINK_RST_N_SHIFT 6
-+#define PRCI_DEVICESRESETREG_CHIPLINK_RST_N_MASK \
-+ (0x1 << PRCI_DEVICESRESETREG_CHIPLINK_RST_N_SHIFT)
-+
-+/* CLKMUXSTATUSREG */
-+#define PRCI_CLKMUXSTATUSREG_OFFSET 0x2c
-+#define PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_SHIFT 1
-+#define PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_MASK \
-+ (0x1 << PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_SHIFT)
-+
-+/*
-+ * Private structures
-+ */
-+
-+/**
-+ * struct __prci_data - per-device-instance data
-+ * @va: base virtual address of the PRCI IP block
-+ * @hw_clks: encapsulates struct clk_hw records
-+ *
-+ * PRCI per-device instance data
-+ */
-+struct __prci_data {
-+ void __iomem *va;
-+ struct clk_hw_onecell_data hw_clks;
-+};
-+
-+/**
-+ * struct __prci_wrpll_data - WRPLL configuration and integration data
-+ * @c: WRPLL current configuration record
-+ * @enable_bypass: fn ptr to code to bypass the WRPLL (if applicable; else NULL)
-+ * @disable_bypass: fn ptr to code to not bypass the WRPLL (or NULL)
-+ * @cfg0_offs: WRPLL CFG0 register offset (in bytes) from the PRCI base address
-+ *
-+ * @enable_bypass and @disable_bypass are used for WRPLL instances
-+ * that contain a separate external glitchless clock mux downstream
-+ * from the PLL. The WRPLL internal bypass mux is not glitchless.
-+ */
-+struct __prci_wrpll_data {
-+ struct wrpll_cfg c;
-+ void (*enable_bypass)(struct __prci_data *pd);
-+ void (*disable_bypass)(struct __prci_data *pd);
-+ u8 cfg0_offs;
-+};
-+
-+/**
-+ * struct __prci_clock - describes a clock device managed by PRCI
-+ * @name: user-readable clock name string - should match the manual
-+ * @parent_name: parent name for this clock
-+ * @ops: struct clk_ops for the Linux clock framework to use for control
-+ * @hw: Linux-private clock data
-+ * @pwd: WRPLL-specific data, associated with this clock (if not NULL)
-+ * @pd: PRCI-specific data associated with this clock (if not NULL)
-+ *
-+ * PRCI clock data. Used by the PRCI driver to register PRCI-provided
-+ * clocks to the Linux clock infrastructure.
-+ */
-+struct __prci_clock {
-+ const char *name;
-+ const char *parent_name;
-+ const struct clk_ops *ops;
-+ struct clk_hw hw;
-+ struct __prci_wrpll_data *pwd;
-+ struct __prci_data *pd;
-+};
-+
-+#define clk_hw_to_prci_clock(pwd) container_of(pwd, struct __prci_clock, hw)
-+
-+/*
-+ * struct prci_clk_desc - describes the information of clocks of each SoCs
-+ * @clks: point to a array of __prci_clock
-+ * @num_clks: the number of element of clks
-+ */
-+struct prci_clk_desc {
-+ struct __prci_clock *clks;
-+ size_t num_clks;
-+};
-+
-+/* Core clock mux control */
-+void sifive_prci_coreclksel_use_hfclk(struct __prci_data *pd);
-+void sifive_prci_coreclksel_use_corepll(struct __prci_data *pd);
-+
-+/* Linux clock framework integration */
-+long sifive_prci_wrpll_round_rate(struct clk_hw *hw, unsigned long rate,
-+ unsigned long *parent_rate);
-+int sifive_prci_wrpll_set_rate(struct clk_hw *hw, unsigned long rate,
-+ unsigned long parent_rate);
-+unsigned long sifive_prci_wrpll_recalc_rate(struct clk_hw *hw,
-+ unsigned long parent_rate);
-+unsigned long sifive_prci_tlclksel_recalc_rate(struct clk_hw *hw,
-+ unsigned long parent_rate);
-+
-+#endif /* __SIFIVE_CLK_SIFIVE_PRCI_H */
---
-2.7.4
-
+++ /dev/null
-From df86ca5b9416ebeacb5ecee63118170c7ea20035 Mon Sep 17 00:00:00 2001
-From: Zong Li <zong.li@sifive.com>
-Date: Wed, 9 Dec 2020 17:49:13 +0800
-Subject: [PATCH 02/29] clk: sifive: Use common name for prci configuration
-
-Use generic name CLK_SIFIVE_PRCI instead of CLK_SIFIVE_FU540_PRCI. This
-patch is prepared for fu740 support.
-
-Signed-off-by: Zong Li <zong.li@sifive.com>
-Reviewed-by: Palmer Dabbelt <palmerdabbelt@google.com>
-Acked-by: Palmer Dabbelt <palmerdabbelt@google.com>
-Reviewed-by: Pragnesh Patel <Pragnesh.patel@sifive.com>
----
- arch/riscv/Kconfig.socs | 2 +-
- drivers/clk/sifive/Kconfig | 6 +++---
- drivers/clk/sifive/Makefile | 2 +-
- 3 files changed, 5 insertions(+), 5 deletions(-)
-
-diff --git a/arch/riscv/Kconfig.socs b/arch/riscv/Kconfig.socs
-index 8a55f61..3284d5c 100644
---- a/arch/riscv/Kconfig.socs
-+++ b/arch/riscv/Kconfig.socs
-@@ -5,7 +5,7 @@ config SOC_SIFIVE
- select SERIAL_SIFIVE if TTY
- select SERIAL_SIFIVE_CONSOLE if TTY
- select CLK_SIFIVE
-- select CLK_SIFIVE_FU540_PRCI
-+ select CLK_SIFIVE_PRCI
- select SIFIVE_PLIC
- help
- This enables support for SiFive SoC platform hardware.
-diff --git a/drivers/clk/sifive/Kconfig b/drivers/clk/sifive/Kconfig
-index f3b4eb9..ab48cf7 100644
---- a/drivers/clk/sifive/Kconfig
-+++ b/drivers/clk/sifive/Kconfig
-@@ -8,12 +8,12 @@ menuconfig CLK_SIFIVE
-
- if CLK_SIFIVE
-
--config CLK_SIFIVE_FU540_PRCI
-- bool "PRCI driver for SiFive FU540 SoCs"
-+config CLK_SIFIVE_PRCI
-+ bool "PRCI driver for SiFive SoCs"
- select CLK_ANALOGBITS_WRPLL_CLN28HPC
- help
- Supports the Power Reset Clock interface (PRCI) IP block found in
-- FU540 SoCs. If this kernel is meant to run on a SiFive FU540 SoC,
-+ FU540 SoCs. If this kernel is meant to run on a SiFive FU540 SoC,
- enable this driver.
-
- endif
-diff --git a/drivers/clk/sifive/Makefile b/drivers/clk/sifive/Makefile
-index 51b6ebc..3074cdb 100644
---- a/drivers/clk/sifive/Makefile
-+++ b/drivers/clk/sifive/Makefile
-@@ -1,2 +1,2 @@
- # SPDX-License-Identifier: GPL-2.0-only
--obj-$(CONFIG_CLK_SIFIVE_FU540_PRCI) += sifive-prci.o fu540-prci.o
-+obj-$(CONFIG_CLK_SIFIVE_PRCI) += sifive-prci.o fu540-prci.o
---
-2.7.4
-
+++ /dev/null
-From c5d3ecfcbdcf2e2d24b636fb739501e1a3e85f14 Mon Sep 17 00:00:00 2001
-From: Zong Li <zong.li@sifive.com>
-Date: Wed, 9 Dec 2020 17:49:14 +0800
-Subject: [PATCH 03/29] clk: sifive: Add a driver for the SiFive FU740 PRCI IP
- block
-
-Add driver code for the SiFive FU740 PRCI IP block. This IP block
-handles reset and clock control for the SiFive FU740 device and
-implements SoC-level clock tree controls and dividers.
-
-The link of unmatched as follow, and the U740-C000 manual would
-be present in the same page as soon.
-https://www.sifive.com/boards/hifive-unmatched
-
-This driver contains bug fixes and contributions from
-Henry Styles <hes@sifive.com>
-Erik Danie <erik.danie@sifive.com>
-Pragnesh Patel <pragnesh.patel@sifive.com>
-
-Signed-off-by: Zong Li <zong.li@sifive.com>
-Reviewed-by: Pragnesh Patel <Pragnesh.patel@sifive.com>
-Acked-by: Palmer Dabbelt <palmerdabbelt@google.com>
-Cc: Henry Styles <hes@sifive.com>
-Cc: Erik Danie <erik.danie@sifive.com>
-Cc: Pragnesh Patel <pragnesh.patel@sifive.com>
----
- drivers/clk/sifive/Kconfig | 4 +-
- drivers/clk/sifive/Makefile | 2 +-
- drivers/clk/sifive/fu740-prci.c | 111 ++++++++++++++++++++++++
- drivers/clk/sifive/fu740-prci.h | 21 +++++
- drivers/clk/sifive/sifive-prci.c | 120 ++++++++++++++++++++++++++
- drivers/clk/sifive/sifive-prci.h | 88 +++++++++++++++++++
- include/dt-bindings/clock/sifive-fu740-prci.h | 23 +++++
- 7 files changed, 366 insertions(+), 3 deletions(-)
- create mode 100644 drivers/clk/sifive/fu740-prci.c
- create mode 100644 drivers/clk/sifive/fu740-prci.h
- create mode 100644 include/dt-bindings/clock/sifive-fu740-prci.h
-
-diff --git a/drivers/clk/sifive/Kconfig b/drivers/clk/sifive/Kconfig
-index ab48cf7..1c14eb2 100644
---- a/drivers/clk/sifive/Kconfig
-+++ b/drivers/clk/sifive/Kconfig
-@@ -13,7 +13,7 @@ config CLK_SIFIVE_PRCI
- select CLK_ANALOGBITS_WRPLL_CLN28HPC
- help
- Supports the Power Reset Clock interface (PRCI) IP block found in
-- FU540 SoCs. If this kernel is meant to run on a SiFive FU540 SoC,
-- enable this driver.
-+ FU540/FU740 SoCs. If this kernel is meant to run on a SiFive FU540/
-+ FU740 SoCs, enable this driver.
-
- endif
-diff --git a/drivers/clk/sifive/Makefile b/drivers/clk/sifive/Makefile
-index 3074cdb..7b06fc0 100644
---- a/drivers/clk/sifive/Makefile
-+++ b/drivers/clk/sifive/Makefile
-@@ -1,2 +1,2 @@
- # SPDX-License-Identifier: GPL-2.0-only
--obj-$(CONFIG_CLK_SIFIVE_PRCI) += sifive-prci.o fu540-prci.o
-+obj-$(CONFIG_CLK_SIFIVE_PRCI) += sifive-prci.o fu540-prci.o fu740-prci.o
-diff --git a/drivers/clk/sifive/fu740-prci.c b/drivers/clk/sifive/fu740-prci.c
-new file mode 100644
-index 00000000..41ddd44
---- /dev/null
-+++ b/drivers/clk/sifive/fu740-prci.c
-@@ -0,0 +1,111 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * Copyright (C) 2020 SiFive, Inc.
-+ * Copyright (C) 2020 Zong Li
-+ */
-+
-+#include <dt-bindings/clock/sifive-fu740-prci.h>
-+#include <linux/module.h>
-+#include "sifive-prci.h"
-+
-+/* PRCI integration data for each WRPLL instance */
-+
-+static struct __prci_wrpll_data __prci_corepll_data = {
-+ .cfg0_offs = PRCI_COREPLLCFG0_OFFSET,
-+ .enable_bypass = sifive_prci_coreclksel_use_hfclk,
-+ .disable_bypass = sifive_prci_coreclksel_use_final_corepll,
-+};
-+
-+static struct __prci_wrpll_data __prci_ddrpll_data = {
-+ .cfg0_offs = PRCI_DDRPLLCFG0_OFFSET,
-+};
-+
-+static struct __prci_wrpll_data __prci_gemgxlpll_data = {
-+ .cfg0_offs = PRCI_GEMGXLPLLCFG0_OFFSET,
-+};
-+
-+static struct __prci_wrpll_data __prci_dvfscorepll_data = {
-+ .cfg0_offs = PRCI_DVFSCOREPLLCFG0_OFFSET,
-+ .enable_bypass = sifive_prci_corepllsel_use_corepll,
-+ .disable_bypass = sifive_prci_corepllsel_use_dvfscorepll,
-+};
-+
-+static struct __prci_wrpll_data __prci_hfpclkpll_data = {
-+ .cfg0_offs = PRCI_HFPCLKPLLCFG0_OFFSET,
-+ .enable_bypass = sifive_prci_hfpclkpllsel_use_hfclk,
-+ .disable_bypass = sifive_prci_hfpclkpllsel_use_hfpclkpll,
-+};
-+
-+static struct __prci_wrpll_data __prci_cltxpll_data = {
-+ .cfg0_offs = PRCI_CLTXPLLCFG0_OFFSET,
-+};
-+
-+/* Linux clock framework integration */
-+
-+static const struct clk_ops sifive_fu740_prci_wrpll_clk_ops = {
-+ .set_rate = sifive_prci_wrpll_set_rate,
-+ .round_rate = sifive_prci_wrpll_round_rate,
-+ .recalc_rate = sifive_prci_wrpll_recalc_rate,
-+};
-+
-+static const struct clk_ops sifive_fu740_prci_wrpll_ro_clk_ops = {
-+ .recalc_rate = sifive_prci_wrpll_recalc_rate,
-+};
-+
-+static const struct clk_ops sifive_fu740_prci_tlclksel_clk_ops = {
-+ .recalc_rate = sifive_prci_tlclksel_recalc_rate,
-+};
-+
-+static const struct clk_ops sifive_fu740_prci_hfpclkplldiv_clk_ops = {
-+ .recalc_rate = sifive_prci_hfpclkplldiv_recalc_rate,
-+};
-+
-+/* List of clock controls provided by the PRCI */
-+struct __prci_clock __prci_init_clocks_fu740[] = {
-+ [PRCI_CLK_COREPLL] = {
-+ .name = "corepll",
-+ .parent_name = "hfclk",
-+ .ops = &sifive_fu740_prci_wrpll_clk_ops,
-+ .pwd = &__prci_corepll_data,
-+ },
-+ [PRCI_CLK_DDRPLL] = {
-+ .name = "ddrpll",
-+ .parent_name = "hfclk",
-+ .ops = &sifive_fu740_prci_wrpll_ro_clk_ops,
-+ .pwd = &__prci_ddrpll_data,
-+ },
-+ [PRCI_CLK_GEMGXLPLL] = {
-+ .name = "gemgxlpll",
-+ .parent_name = "hfclk",
-+ .ops = &sifive_fu740_prci_wrpll_clk_ops,
-+ .pwd = &__prci_gemgxlpll_data,
-+ },
-+ [PRCI_CLK_DVFSCOREPLL] = {
-+ .name = "dvfscorepll",
-+ .parent_name = "hfclk",
-+ .ops = &sifive_fu740_prci_wrpll_clk_ops,
-+ .pwd = &__prci_dvfscorepll_data,
-+ },
-+ [PRCI_CLK_HFPCLKPLL] = {
-+ .name = "hfpclkpll",
-+ .parent_name = "hfclk",
-+ .ops = &sifive_fu740_prci_wrpll_clk_ops,
-+ .pwd = &__prci_hfpclkpll_data,
-+ },
-+ [PRCI_CLK_CLTXPLL] = {
-+ .name = "cltxpll",
-+ .parent_name = "hfclk",
-+ .ops = &sifive_fu740_prci_wrpll_clk_ops,
-+ .pwd = &__prci_cltxpll_data,
-+ },
-+ [PRCI_CLK_TLCLK] = {
-+ .name = "tlclk",
-+ .parent_name = "corepll",
-+ .ops = &sifive_fu740_prci_tlclksel_clk_ops,
-+ },
-+ [PRCI_CLK_PCLK] = {
-+ .name = "pclk",
-+ .parent_name = "hfpclkpll",
-+ .ops = &sifive_fu740_prci_hfpclkplldiv_clk_ops,
-+ },
-+};
-diff --git a/drivers/clk/sifive/fu740-prci.h b/drivers/clk/sifive/fu740-prci.h
-new file mode 100644
-index 00000000..13ef971f7
---- /dev/null
-+++ b/drivers/clk/sifive/fu740-prci.h
-@@ -0,0 +1,21 @@
-+/* SPDX-License-Identifier: GPL-2.0 */
-+/*
-+ * Copyright (C) 2020 SiFive, Inc.
-+ * Zong Li
-+ */
-+
-+#ifndef __SIFIVE_CLK_FU740_PRCI_H
-+#define __SIFIVE_CLK_FU740_PRCI_H
-+
-+#include "sifive-prci.h"
-+
-+#define NUM_CLOCK_FU740 8
-+
-+extern struct __prci_clock __prci_init_clocks_fu740[NUM_CLOCK_FU740];
-+
-+static const struct prci_clk_desc prci_clk_fu740 = {
-+ .clks = __prci_init_clocks_fu740,
-+ .num_clks = ARRAY_SIZE(__prci_init_clocks_fu740),
-+};
-+
-+#endif /* __SIFIVE_CLK_FU740_PRCI_H */
-diff --git a/drivers/clk/sifive/sifive-prci.c b/drivers/clk/sifive/sifive-prci.c
-index 70653d3..cc4b4c6 100644
---- a/drivers/clk/sifive/sifive-prci.c
-+++ b/drivers/clk/sifive/sifive-prci.c
-@@ -10,6 +10,7 @@
- #include <linux/of_device.h>
- #include "sifive-prci.h"
- #include "fu540-prci.h"
-+#include "fu740-prci.h"
-
- /*
- * Private functions
-@@ -225,6 +226,18 @@ unsigned long sifive_prci_tlclksel_recalc_rate(struct clk_hw *hw,
- return div_u64(parent_rate, div);
- }
-
-+/* HFPCLK clock integration */
-+
-+unsigned long sifive_prci_hfpclkplldiv_recalc_rate(struct clk_hw *hw,
-+ unsigned long parent_rate)
-+{
-+ struct __prci_clock *pc = clk_hw_to_prci_clock(hw);
-+ struct __prci_data *pd = pc->pd;
-+ u32 div = __prci_readl(pd, PRCI_HFPCLKPLLDIV_OFFSET);
-+
-+ return div_u64(parent_rate, div + 2);
-+}
-+
- /*
- * Core clock mux control
- */
-@@ -271,6 +284,112 @@ void sifive_prci_coreclksel_use_corepll(struct __prci_data *pd)
- }
-
- /**
-+ * sifive_prci_coreclksel_use_final_corepll() - switch the CORECLK mux to output
-+ * FINAL_COREPLL
-+ * @pd: struct __prci_data * for the PRCI containing the CORECLK mux reg
-+ *
-+ * Switch the CORECLK mux to the final COREPLL output clock; return once
-+ * complete.
-+ *
-+ * Context: Any context. Caller must prevent concurrent changes to the
-+ * PRCI_CORECLKSEL_OFFSET register.
-+ */
-+void sifive_prci_coreclksel_use_final_corepll(struct __prci_data *pd)
-+{
-+ u32 r;
-+
-+ r = __prci_readl(pd, PRCI_CORECLKSEL_OFFSET);
-+ r &= ~PRCI_CORECLKSEL_CORECLKSEL_MASK;
-+ __prci_writel(r, PRCI_CORECLKSEL_OFFSET, pd);
-+
-+ r = __prci_readl(pd, PRCI_CORECLKSEL_OFFSET); /* barrier */
-+}
-+
-+/**
-+ * sifive_prci_corepllsel_use_dvfscorepll() - switch the COREPLL mux to
-+ * output DVFS_COREPLL
-+ * @pd: struct __prci_data * for the PRCI containing the COREPLL mux reg
-+ *
-+ * Switch the COREPLL mux to the DVFSCOREPLL output clock; return once complete.
-+ *
-+ * Context: Any context. Caller must prevent concurrent changes to the
-+ * PRCI_COREPLLSEL_OFFSET register.
-+ */
-+void sifive_prci_corepllsel_use_dvfscorepll(struct __prci_data *pd)
-+{
-+ u32 r;
-+
-+ r = __prci_readl(pd, PRCI_COREPLLSEL_OFFSET);
-+ r |= PRCI_COREPLLSEL_COREPLLSEL_MASK;
-+ __prci_writel(r, PRCI_COREPLLSEL_OFFSET, pd);
-+
-+ r = __prci_readl(pd, PRCI_COREPLLSEL_OFFSET); /* barrier */
-+}
-+
-+/**
-+ * sifive_prci_corepllsel_use_corepll() - switch the COREPLL mux to
-+ * output COREPLL
-+ * @pd: struct __prci_data * for the PRCI containing the COREPLL mux reg
-+ *
-+ * Switch the COREPLL mux to the COREPLL output clock; return once complete.
-+ *
-+ * Context: Any context. Caller must prevent concurrent changes to the
-+ * PRCI_COREPLLSEL_OFFSET register.
-+ */
-+void sifive_prci_corepllsel_use_corepll(struct __prci_data *pd)
-+{
-+ u32 r;
-+
-+ r = __prci_readl(pd, PRCI_COREPLLSEL_OFFSET);
-+ r &= ~PRCI_COREPLLSEL_COREPLLSEL_MASK;
-+ __prci_writel(r, PRCI_COREPLLSEL_OFFSET, pd);
-+
-+ r = __prci_readl(pd, PRCI_COREPLLSEL_OFFSET); /* barrier */
-+}
-+
-+/**
-+ * sifive_prci_hfpclkpllsel_use_hfclk() - switch the HFPCLKPLL mux to
-+ * output HFCLK
-+ * @pd: struct __prci_data * for the PRCI containing the HFPCLKPLL mux reg
-+ *
-+ * Switch the HFPCLKPLL mux to the HFCLK input source; return once complete.
-+ *
-+ * Context: Any context. Caller must prevent concurrent changes to the
-+ * PRCI_HFPCLKPLLSEL_OFFSET register.
-+ */
-+void sifive_prci_hfpclkpllsel_use_hfclk(struct __prci_data *pd)
-+{
-+ u32 r;
-+
-+ r = __prci_readl(pd, PRCI_HFPCLKPLLSEL_OFFSET);
-+ r |= PRCI_HFPCLKPLLSEL_HFPCLKPLLSEL_MASK;
-+ __prci_writel(r, PRCI_HFPCLKPLLSEL_OFFSET, pd);
-+
-+ r = __prci_readl(pd, PRCI_HFPCLKPLLSEL_OFFSET); /* barrier */
-+}
-+
-+/**
-+ * sifive_prci_hfpclkpllsel_use_hfpclkpll() - switch the HFPCLKPLL mux to
-+ * output HFPCLKPLL
-+ * @pd: struct __prci_data * for the PRCI containing the HFPCLKPLL mux reg
-+ *
-+ * Switch the HFPCLKPLL mux to the HFPCLKPLL output clock; return once complete.
-+ *
-+ * Context: Any context. Caller must prevent concurrent changes to the
-+ * PRCI_HFPCLKPLLSEL_OFFSET register.
-+ */
-+void sifive_prci_hfpclkpllsel_use_hfpclkpll(struct __prci_data *pd)
-+{
-+ u32 r;
-+
-+ r = __prci_readl(pd, PRCI_HFPCLKPLLSEL_OFFSET);
-+ r &= ~PRCI_HFPCLKPLLSEL_HFPCLKPLLSEL_MASK;
-+ __prci_writel(r, PRCI_HFPCLKPLLSEL_OFFSET, pd);
-+
-+ r = __prci_readl(pd, PRCI_HFPCLKPLLSEL_OFFSET); /* barrier */
-+}
-+
-+/**
- * __prci_register_clocks() - register clock controls in the PRCI
- * @dev: Linux struct device
- * @pd: The pointer for PRCI per-device instance data
-@@ -377,6 +496,7 @@ static int sifive_prci_probe(struct platform_device *pdev)
-
- static const struct of_device_id sifive_prci_of_match[] = {
- {.compatible = "sifive,fu540-c000-prci", .data = &prci_clk_fu540},
-+ {.compatible = "sifive,fu740-c000-prci", .data = &prci_clk_fu740},
- {}
- };
-
-diff --git a/drivers/clk/sifive/sifive-prci.h b/drivers/clk/sifive/sifive-prci.h
-index 280df63..7e509df 100644
---- a/drivers/clk/sifive/sifive-prci.h
-+++ b/drivers/clk/sifive/sifive-prci.h
-@@ -117,6 +117,87 @@
- #define PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_MASK \
- (0x1 << PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_SHIFT)
-
-+/* CLTXPLLCFG0 */
-+#define PRCI_CLTXPLLCFG0_OFFSET 0x30
-+#define PRCI_CLTXPLLCFG0_DIVR_SHIFT 0
-+#define PRCI_CLTXPLLCFG0_DIVR_MASK (0x3f << PRCI_CLTXPLLCFG0_DIVR_SHIFT)
-+#define PRCI_CLTXPLLCFG0_DIVF_SHIFT 6
-+#define PRCI_CLTXPLLCFG0_DIVF_MASK (0x1ff << PRCI_CLTXPLLCFG0_DIVF_SHIFT)
-+#define PRCI_CLTXPLLCFG0_DIVQ_SHIFT 15
-+#define PRCI_CLTXPLLCFG0_DIVQ_MASK (0x7 << PRCI_CLTXPLLCFG0_DIVQ_SHIFT)
-+#define PRCI_CLTXPLLCFG0_RANGE_SHIFT 18
-+#define PRCI_CLTXPLLCFG0_RANGE_MASK (0x7 << PRCI_CLTXPLLCFG0_RANGE_SHIFT)
-+#define PRCI_CLTXPLLCFG0_BYPASS_SHIFT 24
-+#define PRCI_CLTXPLLCFG0_BYPASS_MASK (0x1 << PRCI_CLTXPLLCFG0_BYPASS_SHIFT)
-+#define PRCI_CLTXPLLCFG0_FSE_SHIFT 25
-+#define PRCI_CLTXPLLCFG0_FSE_MASK (0x1 << PRCI_CLTXPLLCFG0_FSE_SHIFT)
-+#define PRCI_CLTXPLLCFG0_LOCK_SHIFT 31
-+#define PRCI_CLTXPLLCFG0_LOCK_MASK (0x1 << PRCI_CLTXPLLCFG0_LOCK_SHIFT)
-+
-+/* CLTXPLLCFG1 */
-+#define PRCI_CLTXPLLCFG1_OFFSET 0x34
-+#define PRCI_CLTXPLLCFG1_CKE_SHIFT 31
-+#define PRCI_CLTXPLLCFG1_CKE_MASK (0x1 << PRCI_CLTXPLLCFG1_CKE_SHIFT)
-+
-+/* DVFSCOREPLLCFG0 */
-+#define PRCI_DVFSCOREPLLCFG0_OFFSET 0x38
-+
-+/* DVFSCOREPLLCFG1 */
-+#define PRCI_DVFSCOREPLLCFG1_OFFSET 0x3c
-+#define PRCI_DVFSCOREPLLCFG1_CKE_SHIFT 31
-+#define PRCI_DVFSCOREPLLCFG1_CKE_MASK (0x1 << PRCI_DVFSCOREPLLCFG1_CKE_SHIFT)
-+
-+/* COREPLLSEL */
-+#define PRCI_COREPLLSEL_OFFSET 0x40
-+#define PRCI_COREPLLSEL_COREPLLSEL_SHIFT 0
-+#define PRCI_COREPLLSEL_COREPLLSEL_MASK \
-+ (0x1 << PRCI_COREPLLSEL_COREPLLSEL_SHIFT)
-+
-+/* HFPCLKPLLCFG0 */
-+#define PRCI_HFPCLKPLLCFG0_OFFSET 0x50
-+#define PRCI_HFPCLKPLL_CFG0_DIVR_SHIFT 0
-+#define PRCI_HFPCLKPLL_CFG0_DIVR_MASK \
-+ (0x3f << PRCI_HFPCLKPLLCFG0_DIVR_SHIFT)
-+#define PRCI_HFPCLKPLL_CFG0_DIVF_SHIFT 6
-+#define PRCI_HFPCLKPLL_CFG0_DIVF_MASK \
-+ (0x1ff << PRCI_HFPCLKPLLCFG0_DIVF_SHIFT)
-+#define PRCI_HFPCLKPLL_CFG0_DIVQ_SHIFT 15
-+#define PRCI_HFPCLKPLL_CFG0_DIVQ_MASK \
-+ (0x7 << PRCI_HFPCLKPLLCFG0_DIVQ_SHIFT)
-+#define PRCI_HFPCLKPLL_CFG0_RANGE_SHIFT 18
-+#define PRCI_HFPCLKPLL_CFG0_RANGE_MASK \
-+ (0x7 << PRCI_HFPCLKPLLCFG0_RANGE_SHIFT)
-+#define PRCI_HFPCLKPLL_CFG0_BYPASS_SHIFT 24
-+#define PRCI_HFPCLKPLL_CFG0_BYPASS_MASK \
-+ (0x1 << PRCI_HFPCLKPLLCFG0_BYPASS_SHIFT)
-+#define PRCI_HFPCLKPLL_CFG0_FSE_SHIFT 25
-+#define PRCI_HFPCLKPLL_CFG0_FSE_MASK \
-+ (0x1 << PRCI_HFPCLKPLLCFG0_FSE_SHIFT)
-+#define PRCI_HFPCLKPLL_CFG0_LOCK_SHIFT 31
-+#define PRCI_HFPCLKPLL_CFG0_LOCK_MASK \
-+ (0x1 << PRCI_HFPCLKPLLCFG0_LOCK_SHIFT)
-+
-+/* HFPCLKPLLCFG1 */
-+#define PRCI_HFPCLKPLLCFG1_OFFSET 0x54
-+#define PRCI_HFPCLKPLLCFG1_CKE_SHIFT 31
-+#define PRCI_HFPCLKPLLCFG1_CKE_MASK \
-+ (0x1 << PRCI_HFPCLKPLLCFG1_CKE_SHIFT)
-+
-+/* HFPCLKPLLSEL */
-+#define PRCI_HFPCLKPLLSEL_OFFSET 0x58
-+#define PRCI_HFPCLKPLLSEL_HFPCLKPLLSEL_SHIFT 0
-+#define PRCI_HFPCLKPLLSEL_HFPCLKPLLSEL_MASK \
-+ (0x1 << PRCI_HFPCLKPLLSEL_HFPCLKPLLSEL_SHIFT)
-+
-+/* HFPCLKPLLDIV */
-+#define PRCI_HFPCLKPLLDIV_OFFSET 0x5c
-+
-+/* PRCIPLL */
-+#define PRCI_PRCIPLL_OFFSET 0xe0
-+
-+/* PROCMONCFG */
-+#define PRCI_PROCMONCFG_OFFSET 0xf0
-+
- /*
- * Private structures
- */
-@@ -187,6 +268,11 @@ struct prci_clk_desc {
- /* Core clock mux control */
- void sifive_prci_coreclksel_use_hfclk(struct __prci_data *pd);
- void sifive_prci_coreclksel_use_corepll(struct __prci_data *pd);
-+void sifive_prci_coreclksel_use_final_corepll(struct __prci_data *pd);
-+void sifive_prci_corepllsel_use_dvfscorepll(struct __prci_data *pd);
-+void sifive_prci_corepllsel_use_corepll(struct __prci_data *pd);
-+void sifive_prci_hfpclkpllsel_use_hfclk(struct __prci_data *pd);
-+void sifive_prci_hfpclkpllsel_use_hfpclkpll(struct __prci_data *pd);
-
- /* Linux clock framework integration */
- long sifive_prci_wrpll_round_rate(struct clk_hw *hw, unsigned long rate,
-@@ -197,5 +283,7 @@ unsigned long sifive_prci_wrpll_recalc_rate(struct clk_hw *hw,
- unsigned long parent_rate);
- unsigned long sifive_prci_tlclksel_recalc_rate(struct clk_hw *hw,
- unsigned long parent_rate);
-+unsigned long sifive_prci_hfpclkplldiv_recalc_rate(struct clk_hw *hw,
-+ unsigned long parent_rate);
-
- #endif /* __SIFIVE_CLK_SIFIVE_PRCI_H */
-diff --git a/include/dt-bindings/clock/sifive-fu740-prci.h b/include/dt-bindings/clock/sifive-fu740-prci.h
-new file mode 100644
-index 00000000..cd7706e
---- /dev/null
-+++ b/include/dt-bindings/clock/sifive-fu740-prci.h
-@@ -0,0 +1,23 @@
-+/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */
-+/*
-+ * Copyright (C) 2019 SiFive, Inc.
-+ * Wesley Terpstra
-+ * Paul Walmsley
-+ * Zong Li
-+ */
-+
-+#ifndef __DT_BINDINGS_CLOCK_SIFIVE_FU740_PRCI_H
-+#define __DT_BINDINGS_CLOCK_SIFIVE_FU740_PRCI_H
-+
-+/* Clock indexes for use by Device Tree data and the PRCI driver */
-+
-+#define PRCI_CLK_COREPLL 0
-+#define PRCI_CLK_DDRPLL 1
-+#define PRCI_CLK_GEMGXLPLL 2
-+#define PRCI_CLK_DVFSCOREPLL 3
-+#define PRCI_CLK_HFPCLKPLL 4
-+#define PRCI_CLK_CLTXPLL 5
-+#define PRCI_CLK_TLCLK 6
-+#define PRCI_CLK_PCLK 7
-+
-+#endif /* __DT_BINDINGS_CLOCK_SIFIVE_FU740_PRCI_H */
---
-2.7.4
-
+++ /dev/null
-From ff2bcef458e1fc95c6f3da7304df4119628f92c5 Mon Sep 17 00:00:00 2001
-From: Zong Li <zong.li@sifive.com>
-Date: Wed, 9 Dec 2020 17:49:15 +0800
-Subject: [PATCH 04/29] clk: sifive: Fix the wrong bit field shift
-
-The clk enable bit should be 31 instead of 24.
-
-Signed-off-by: Zong Li <zong.li@sifive.com>
-Reported-by: Pragnesh Patel <pragnesh.patel@sifive.com>
----
- drivers/clk/sifive/sifive-prci.h | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/drivers/clk/sifive/sifive-prci.h b/drivers/clk/sifive/sifive-prci.h
-index 7e509df..88493f3 100644
---- a/drivers/clk/sifive/sifive-prci.h
-+++ b/drivers/clk/sifive/sifive-prci.h
-@@ -59,7 +59,7 @@
-
- /* DDRPLLCFG1 */
- #define PRCI_DDRPLLCFG1_OFFSET 0x10
--#define PRCI_DDRPLLCFG1_CKE_SHIFT 24
-+#define PRCI_DDRPLLCFG1_CKE_SHIFT 31
- #define PRCI_DDRPLLCFG1_CKE_MASK (0x1 << PRCI_DDRPLLCFG1_CKE_SHIFT)
-
- /* GEMGXLPLLCFG0 */
-@@ -81,7 +81,7 @@
-
- /* GEMGXLPLLCFG1 */
- #define PRCI_GEMGXLPLLCFG1_OFFSET 0x20
--#define PRCI_GEMGXLPLLCFG1_CKE_SHIFT 24
-+#define PRCI_GEMGXLPLLCFG1_CKE_SHIFT 31
- #define PRCI_GEMGXLPLLCFG1_CKE_MASK (0x1 << PRCI_GEMGXLPLLCFG1_CKE_SHIFT)
-
- /* CORECLKSEL */
---
-2.7.4
-
+++ /dev/null
-From 37338a04280c6add6e376ed03d094276fb2759ba Mon Sep 17 00:00:00 2001
-From: Pragnesh Patel <pragnesh.patel@sifive.com>
-Date: Wed, 9 Dec 2020 17:49:16 +0800
-Subject: [PATCH 05/29] clk: sifive: Add clock enable and disable ops
-
-Add new functions "sifive_prci_clock_enable(), sifive_prci_clock_disable()
-and sifive_clk_is_enabled()" to enable or disable the PRCI clock
-
-Signed-off-by: Pragnesh Patel <pragnesh.patel@sifive.com>
-Tested-by: Zong Li <zong.li@sifive.com>
----
- drivers/clk/sifive/fu540-prci.c | 6 ++++
- drivers/clk/sifive/fu740-prci.c | 9 +++++
- drivers/clk/sifive/sifive-prci.c | 77 +++++++++++++++++++++++++++++++++++-----
- drivers/clk/sifive/sifive-prci.h | 10 ++++++
- 4 files changed, 93 insertions(+), 9 deletions(-)
-
-diff --git a/drivers/clk/sifive/fu540-prci.c b/drivers/clk/sifive/fu540-prci.c
-index e2353de..3b55883 100644
---- a/drivers/clk/sifive/fu540-prci.c
-+++ b/drivers/clk/sifive/fu540-prci.c
-@@ -24,16 +24,19 @@
-
- static struct __prci_wrpll_data __prci_corepll_data = {
- .cfg0_offs = PRCI_COREPLLCFG0_OFFSET,
-+ .cfg1_offs = PRCI_COREPLLCFG1_OFFSET,
- .enable_bypass = sifive_prci_coreclksel_use_hfclk,
- .disable_bypass = sifive_prci_coreclksel_use_corepll,
- };
-
- static struct __prci_wrpll_data __prci_ddrpll_data = {
- .cfg0_offs = PRCI_DDRPLLCFG0_OFFSET,
-+ .cfg1_offs = PRCI_DDRPLLCFG1_OFFSET,
- };
-
- static struct __prci_wrpll_data __prci_gemgxlpll_data = {
- .cfg0_offs = PRCI_GEMGXLPLLCFG0_OFFSET,
-+ .cfg1_offs = PRCI_GEMGXLPLLCFG1_OFFSET,
- };
-
- /* Linux clock framework integration */
-@@ -42,6 +45,9 @@ static const struct clk_ops sifive_fu540_prci_wrpll_clk_ops = {
- .set_rate = sifive_prci_wrpll_set_rate,
- .round_rate = sifive_prci_wrpll_round_rate,
- .recalc_rate = sifive_prci_wrpll_recalc_rate,
-+ .enable = sifive_prci_clock_enable,
-+ .disable = sifive_prci_clock_disable,
-+ .is_enabled = sifive_clk_is_enabled,
- };
-
- static const struct clk_ops sifive_fu540_prci_wrpll_ro_clk_ops = {
-diff --git a/drivers/clk/sifive/fu740-prci.c b/drivers/clk/sifive/fu740-prci.c
-index 41ddd44..db83002 100644
---- a/drivers/clk/sifive/fu740-prci.c
-+++ b/drivers/clk/sifive/fu740-prci.c
-@@ -12,32 +12,38 @@
-
- static struct __prci_wrpll_data __prci_corepll_data = {
- .cfg0_offs = PRCI_COREPLLCFG0_OFFSET,
-+ .cfg1_offs = PRCI_COREPLLCFG1_OFFSET,
- .enable_bypass = sifive_prci_coreclksel_use_hfclk,
- .disable_bypass = sifive_prci_coreclksel_use_final_corepll,
- };
-
- static struct __prci_wrpll_data __prci_ddrpll_data = {
- .cfg0_offs = PRCI_DDRPLLCFG0_OFFSET,
-+ .cfg1_offs = PRCI_DDRPLLCFG1_OFFSET,
- };
-
- static struct __prci_wrpll_data __prci_gemgxlpll_data = {
- .cfg0_offs = PRCI_GEMGXLPLLCFG0_OFFSET,
-+ .cfg1_offs = PRCI_GEMGXLPLLCFG1_OFFSET,
- };
-
- static struct __prci_wrpll_data __prci_dvfscorepll_data = {
- .cfg0_offs = PRCI_DVFSCOREPLLCFG0_OFFSET,
-+ .cfg1_offs = PRCI_DVFSCOREPLLCFG1_OFFSET,
- .enable_bypass = sifive_prci_corepllsel_use_corepll,
- .disable_bypass = sifive_prci_corepllsel_use_dvfscorepll,
- };
-
- static struct __prci_wrpll_data __prci_hfpclkpll_data = {
- .cfg0_offs = PRCI_HFPCLKPLLCFG0_OFFSET,
-+ .cfg1_offs = PRCI_HFPCLKPLLCFG1_OFFSET,
- .enable_bypass = sifive_prci_hfpclkpllsel_use_hfclk,
- .disable_bypass = sifive_prci_hfpclkpllsel_use_hfpclkpll,
- };
-
- static struct __prci_wrpll_data __prci_cltxpll_data = {
- .cfg0_offs = PRCI_CLTXPLLCFG0_OFFSET,
-+ .cfg1_offs = PRCI_CLTXPLLCFG1_OFFSET,
- };
-
- /* Linux clock framework integration */
-@@ -46,6 +52,9 @@ static const struct clk_ops sifive_fu740_prci_wrpll_clk_ops = {
- .set_rate = sifive_prci_wrpll_set_rate,
- .round_rate = sifive_prci_wrpll_round_rate,
- .recalc_rate = sifive_prci_wrpll_recalc_rate,
-+ .enable = sifive_prci_clock_enable,
-+ .disable = sifive_prci_clock_disable,
-+ .is_enabled = sifive_clk_is_enabled,
- };
-
- static const struct clk_ops sifive_fu740_prci_wrpll_ro_clk_ops = {
-diff --git a/drivers/clk/sifive/sifive-prci.c b/drivers/clk/sifive/sifive-prci.c
-index cc4b4c6..c78b042 100644
---- a/drivers/clk/sifive/sifive-prci.c
-+++ b/drivers/clk/sifive/sifive-prci.c
-@@ -113,7 +113,7 @@ static u32 __prci_wrpll_pack(const struct wrpll_cfg *c)
- }
-
- /**
-- * __prci_wrpll_read_cfg() - read the WRPLL configuration from the PRCI
-+ * __prci_wrpll_read_cfg0() - read the WRPLL configuration from the PRCI
- * @pd: PRCI context
- * @pwd: PRCI WRPLL metadata
- *
-@@ -124,14 +124,14 @@ static u32 __prci_wrpll_pack(const struct wrpll_cfg *c)
- * Context: Any context. Caller must prevent the records pointed to by
- * @pd and @pwd from changing during execution.
- */
--static void __prci_wrpll_read_cfg(struct __prci_data *pd,
-- struct __prci_wrpll_data *pwd)
-+static void __prci_wrpll_read_cfg0(struct __prci_data *pd,
-+ struct __prci_wrpll_data *pwd)
- {
- __prci_wrpll_unpack(&pwd->c, __prci_readl(pd, pwd->cfg0_offs));
- }
-
- /**
-- * __prci_wrpll_write_cfg() - write WRPLL configuration into the PRCI
-+ * __prci_wrpll_write_cfg0() - write WRPLL configuration into the PRCI
- * @pd: PRCI context
- * @pwd: PRCI WRPLL metadata
- * @c: WRPLL configuration record to write
-@@ -144,15 +144,29 @@ static void __prci_wrpll_read_cfg(struct __prci_data *pd,
- * Context: Any context. Caller must prevent the records pointed to by
- * @pd and @pwd from changing during execution.
- */
--static void __prci_wrpll_write_cfg(struct __prci_data *pd,
-- struct __prci_wrpll_data *pwd,
-- struct wrpll_cfg *c)
-+static void __prci_wrpll_write_cfg0(struct __prci_data *pd,
-+ struct __prci_wrpll_data *pwd,
-+ struct wrpll_cfg *c)
- {
- __prci_writel(__prci_wrpll_pack(c), pwd->cfg0_offs, pd);
-
- memcpy(&pwd->c, c, sizeof(*c));
- }
-
-+/**
-+ * __prci_wrpll_write_cfg1() - write Clock enable/disable configuration
-+ * into the PRCI
-+ * @pd: PRCI context
-+ * @pwd: PRCI WRPLL metadata
-+ * @enable: Clock enable or disable value
-+ */
-+static void __prci_wrpll_write_cfg1(struct __prci_data *pd,
-+ struct __prci_wrpll_data *pwd,
-+ u32 enable)
-+{
-+ __prci_writel(enable, pwd->cfg1_offs, pd);
-+}
-+
- /*
- * Linux clock framework integration
- *
-@@ -199,16 +213,61 @@ int sifive_prci_wrpll_set_rate(struct clk_hw *hw,
- if (pwd->enable_bypass)
- pwd->enable_bypass(pd);
-
-- __prci_wrpll_write_cfg(pd, pwd, &pwd->c);
-+ __prci_wrpll_write_cfg0(pd, pwd, &pwd->c);
-
- udelay(wrpll_calc_max_lock_us(&pwd->c));
-
-+ return 0;
-+}
-+
-+int sifive_clk_is_enabled(struct clk_hw *hw)
-+{
-+ struct __prci_clock *pc = clk_hw_to_prci_clock(hw);
-+ struct __prci_wrpll_data *pwd = pc->pwd;
-+ struct __prci_data *pd = pc->pd;
-+ u32 r;
-+
-+ r = __prci_readl(pd, pwd->cfg1_offs);
-+
-+ if (r & PRCI_COREPLLCFG1_CKE_MASK)
-+ return 1;
-+ else
-+ return 0;
-+}
-+
-+int sifive_prci_clock_enable(struct clk_hw *hw)
-+{
-+ struct __prci_clock *pc = clk_hw_to_prci_clock(hw);
-+ struct __prci_wrpll_data *pwd = pc->pwd;
-+ struct __prci_data *pd = pc->pd;
-+
-+ if (sifive_clk_is_enabled(hw))
-+ return 0;
-+
-+ __prci_wrpll_write_cfg1(pd, pwd, PRCI_COREPLLCFG1_CKE_MASK);
-+
- if (pwd->disable_bypass)
- pwd->disable_bypass(pd);
-
- return 0;
- }
-
-+void sifive_prci_clock_disable(struct clk_hw *hw)
-+{
-+ struct __prci_clock *pc = clk_hw_to_prci_clock(hw);
-+ struct __prci_wrpll_data *pwd = pc->pwd;
-+ struct __prci_data *pd = pc->pd;
-+ u32 r;
-+
-+ if (pwd->enable_bypass)
-+ pwd->enable_bypass(pd);
-+
-+ r = __prci_readl(pd, pwd->cfg1_offs);
-+ r &= ~PRCI_COREPLLCFG1_CKE_MASK;
-+
-+ __prci_wrpll_write_cfg1(pd, pwd, r);
-+}
-+
- /* TLCLKSEL clock integration */
-
- unsigned long sifive_prci_tlclksel_recalc_rate(struct clk_hw *hw,
-@@ -427,7 +486,7 @@ static int __prci_register_clocks(struct device *dev, struct __prci_data *pd,
- pic->pd = pd;
-
- if (pic->pwd)
-- __prci_wrpll_read_cfg(pd, pic->pwd);
-+ __prci_wrpll_read_cfg0(pd, pic->pwd);
-
- r = devm_clk_hw_register(dev, &pic->hw);
- if (r) {
-diff --git a/drivers/clk/sifive/sifive-prci.h b/drivers/clk/sifive/sifive-prci.h
-index 88493f3..dbdbd17 100644
---- a/drivers/clk/sifive/sifive-prci.h
-+++ b/drivers/clk/sifive/sifive-prci.h
-@@ -40,6 +40,11 @@
- #define PRCI_COREPLLCFG0_LOCK_SHIFT 31
- #define PRCI_COREPLLCFG0_LOCK_MASK (0x1 << PRCI_COREPLLCFG0_LOCK_SHIFT)
-
-+/* COREPLLCFG1 */
-+#define PRCI_COREPLLCFG1_OFFSET 0x8
-+#define PRCI_COREPLLCFG1_CKE_SHIFT 31
-+#define PRCI_COREPLLCFG1_CKE_MASK (0x1 << PRCI_COREPLLCFG1_CKE_SHIFT)
-+
- /* DDRPLLCFG0 */
- #define PRCI_DDRPLLCFG0_OFFSET 0xc
- #define PRCI_DDRPLLCFG0_DIVR_SHIFT 0
-@@ -220,6 +225,7 @@ struct __prci_data {
- * @enable_bypass: fn ptr to code to bypass the WRPLL (if applicable; else NULL)
- * @disable_bypass: fn ptr to code to not bypass the WRPLL (or NULL)
- * @cfg0_offs: WRPLL CFG0 register offset (in bytes) from the PRCI base address
-+ * @cfg1_offs: WRPLL CFG1 register offset (in bytes) from the PRCI base address
- *
- * @enable_bypass and @disable_bypass are used for WRPLL instances
- * that contain a separate external glitchless clock mux downstream
-@@ -230,6 +236,7 @@ struct __prci_wrpll_data {
- void (*enable_bypass)(struct __prci_data *pd);
- void (*disable_bypass)(struct __prci_data *pd);
- u8 cfg0_offs;
-+ u8 cfg1_offs;
- };
-
- /**
-@@ -279,6 +286,9 @@ long sifive_prci_wrpll_round_rate(struct clk_hw *hw, unsigned long rate,
- unsigned long *parent_rate);
- int sifive_prci_wrpll_set_rate(struct clk_hw *hw, unsigned long rate,
- unsigned long parent_rate);
-+int sifive_clk_is_enabled(struct clk_hw *hw);
-+int sifive_prci_clock_enable(struct clk_hw *hw);
-+void sifive_prci_clock_disable(struct clk_hw *hw);
- unsigned long sifive_prci_wrpll_recalc_rate(struct clk_hw *hw,
- unsigned long parent_rate);
- unsigned long sifive_prci_tlclksel_recalc_rate(struct clk_hw *hw,
---
-2.7.4
-
+++ /dev/null
-From 34d032292a2b6db16fc60e7c6706b1b508c2d932 Mon Sep 17 00:00:00 2001
-From: Yash Shah <yash.shah@sifive.com>
-Date: Tue, 8 Dec 2020 10:25:33 +0530
-Subject: [PATCH 06/29] dt-bindings: riscv: Update DT binding docs to support
- SiFive FU740 SoC
-
-Add new compatible strings in cpus.yaml to support the E71 and U74 CPU
-cores ("harts") that are present on FU740-C000 SoC.
-
-Signed-off-by: Yash Shah <yash.shah@sifive.com>
-Reviewed-by: Rob Herring <robh@kernel.org>
-Reviewed-by: Bin Meng <bin.meng@windriver.com>
----
- Documentation/devicetree/bindings/riscv/cpus.yaml | 6 ++++++
- 1 file changed, 6 insertions(+)
-
-diff --git a/Documentation/devicetree/bindings/riscv/cpus.yaml b/Documentation/devicetree/bindings/riscv/cpus.yaml
-index c6925e0..eb6843f 100644
---- a/Documentation/devicetree/bindings/riscv/cpus.yaml
-+++ b/Documentation/devicetree/bindings/riscv/cpus.yaml
-@@ -28,11 +28,17 @@ properties:
- - items:
- - enum:
- - sifive,rocket0
-+ - sifive,bullet0
- - sifive,e5
-+ - sifive,e7
- - sifive,e51
-+ - sifive,e71
- - sifive,u54-mc
-+ - sifive,u74-mc
- - sifive,u54
-+ - sifive,u74
- - sifive,u5
-+ - sifive,u7
- - const: riscv
- - const: riscv # Simulator only
- description:
---
-2.7.4
-
+++ /dev/null
-From 8a3d7aa89632d354932a621eb4fe22c560a406bd Mon Sep 17 00:00:00 2001
-From: Yash Shah <yash.shah@sifive.com>
-Date: Tue, 8 Dec 2020 10:25:34 +0530
-Subject: [PATCH 07/29] dt-bindings: spi: Update DT binding docs to support
- SiFive FU740 SoC
-
-Add new compatible strings to the DT binding documents to support SiFive
-FU740-C000.
-
-Signed-off-by: Yash Shah <yash.shah@sifive.com>
----
- Documentation/devicetree/bindings/spi/spi-sifive.yaml | 10 ++++++----
- 1 file changed, 6 insertions(+), 4 deletions(-)
-
-diff --git a/Documentation/devicetree/bindings/spi/spi-sifive.yaml b/Documentation/devicetree/bindings/spi/spi-sifive.yaml
-index 56dcf1d..6e7e394 100644
---- a/Documentation/devicetree/bindings/spi/spi-sifive.yaml
-+++ b/Documentation/devicetree/bindings/spi/spi-sifive.yaml
-@@ -17,15 +17,17 @@ allOf:
- properties:
- compatible:
- items:
-- - const: sifive,fu540-c000-spi
-+ - enum:
-+ - sifive,fu540-c000-spi
-+ - sifive,fu740-c000-spi
- - const: sifive,spi0
-
- description:
- Should be "sifive,<chip>-spi" and "sifive,spi<version>".
- Supported compatible strings are -
-- "sifive,fu540-c000-spi" for the SiFive SPI v0 as integrated
-- onto the SiFive FU540 chip, and "sifive,spi0" for the SiFive
-- SPI v0 IP block with no chip integration tweaks.
-+ "sifive,fu540-c000-spi" and "sifive,fu740-c000-spi" for the SiFive SPI v0
-+ as integrated onto the SiFive FU540 and FU740 chip resp, and "sifive,spi0"
-+ for the SiFive SPI v0 IP block with no chip integration tweaks.
- Please refer to sifive-blocks-ip-versioning.txt for details
-
- SPI RTL that corresponds to the IP block version numbers can be found here -
---
-2.7.4
-
+++ /dev/null
-From 789dc44312525e9669d0c6e01ccfc01bbdfb0e10 Mon Sep 17 00:00:00 2001
-From: Yash Shah <yash.shah@sifive.com>
-Date: Tue, 8 Dec 2020 10:25:35 +0530
-Subject: [PATCH 08/29] dt-bindings: pwm: Update DT binding docs to support
- SiFive FU740 SoC
-
-Add new compatible strings to the DT binding documents to support SiFive
-FU740-C000.
-
-Signed-off-by: Yash Shah <yash.shah@sifive.com>
----
- Documentation/devicetree/bindings/pwm/pwm-sifive.yaml | 9 ++++++---
- 1 file changed, 6 insertions(+), 3 deletions(-)
-
-diff --git a/Documentation/devicetree/bindings/pwm/pwm-sifive.yaml b/Documentation/devicetree/bindings/pwm/pwm-sifive.yaml
-index 5ac2527..84e6691 100644
---- a/Documentation/devicetree/bindings/pwm/pwm-sifive.yaml
-+++ b/Documentation/devicetree/bindings/pwm/pwm-sifive.yaml
-@@ -25,12 +25,15 @@ description:
- properties:
- compatible:
- items:
-- - const: sifive,fu540-c000-pwm
-+ - enum:
-+ - sifive,fu540-c000-pwm
-+ - sifive,fu740-c000-pwm
- - const: sifive,pwm0
- description:
- Should be "sifive,<chip>-pwm" and "sifive,pwm<version>". Supported
-- compatible strings are "sifive,fu540-c000-pwm" for the SiFive PWM v0
-- as integrated onto the SiFive FU540 chip, and "sifive,pwm0" for the
-+ compatible strings are "sifive,fu540-c000-pwm" and
-+ "sifive,fu740-c000-pwm" for the SiFive PWM v0 as integrated onto the
-+ SiFive FU540 and FU740 chip respectively, and "sifive,pwm0" for the
- SiFive PWM v0 IP block with no chip integration tweaks.
- Please refer to sifive-blocks-ip-versioning.txt for details.
-
---
-2.7.4
-
+++ /dev/null
-From 6bc4ee53eaffad7385babe568a7889b13752606f Mon Sep 17 00:00:00 2001
-From: Yash Shah <yash.shah@sifive.com>
-Date: Tue, 8 Dec 2020 10:25:36 +0530
-Subject: [PATCH 09/29] dt-bindings: serial: Update DT binding docs to support
- SiFive FU740 SoC
-
-Add new compatible strings to the DT binding documents to support SiFive
-FU740-C000.
-
-Signed-off-by: Yash Shah <yash.shah@sifive.com>
-Reviewed-by: Rob Herring <robh@kernel.org>
----
- Documentation/devicetree/bindings/serial/sifive-serial.yaml | 4 +++-
- 1 file changed, 3 insertions(+), 1 deletion(-)
-
-diff --git a/Documentation/devicetree/bindings/serial/sifive-serial.yaml b/Documentation/devicetree/bindings/serial/sifive-serial.yaml
-index 92283f6..3ac5c7f 100644
---- a/Documentation/devicetree/bindings/serial/sifive-serial.yaml
-+++ b/Documentation/devicetree/bindings/serial/sifive-serial.yaml
-@@ -17,7 +17,9 @@ allOf:
- properties:
- compatible:
- items:
-- - const: sifive,fu540-c000-uart
-+ - enum:
-+ - sifive,fu540-c000-uart
-+ - sifive,fu740-c000-uart
- - const: sifive,uart0
-
- description:
---
-2.7.4
-
+++ /dev/null
-From 9791e30869ff598c0faede92500d4d35c8bbba45 Mon Sep 17 00:00:00 2001
-From: Yash Shah <yash.shah@sifive.com>
-Date: Tue, 8 Dec 2020 10:25:37 +0530
-Subject: [PATCH 10/29] dt-bindings: gpio: Update DT binding docs to support
- SiFive FU740 SoC
-
-Add new compatible strings to the DT binding documents to support SiFive
-FU740-C000.
-
-Signed-off-by: Yash Shah <yash.shah@sifive.com>
-Reviewed-by: Rob Herring <robh@kernel.org>
----
- Documentation/devicetree/bindings/gpio/sifive,gpio.yaml | 4 +++-
- 1 file changed, 3 insertions(+), 1 deletion(-)
-
-diff --git a/Documentation/devicetree/bindings/gpio/sifive,gpio.yaml b/Documentation/devicetree/bindings/gpio/sifive,gpio.yaml
-index a0efd8d..ab22056 100644
---- a/Documentation/devicetree/bindings/gpio/sifive,gpio.yaml
-+++ b/Documentation/devicetree/bindings/gpio/sifive,gpio.yaml
-@@ -13,7 +13,9 @@ maintainers:
- properties:
- compatible:
- items:
-- - const: sifive,fu540-c000-gpio
-+ - enum:
-+ - sifive,fu540-c000-gpio
-+ - sifive,fu740-c000-gpio
- - const: sifive,gpio0
-
- reg:
---
-2.7.4
-
+++ /dev/null
-From 909e7d4601aa183dbdd3e8edb964e4c683a2c9e1 Mon Sep 17 00:00:00 2001
-From: Yash Shah <yash.shah@sifive.com>
-Date: Tue, 8 Dec 2020 10:25:38 +0530
-Subject: [PATCH 11/29] dt-bindings: i2c: Update DT binding docs to support
- SiFive FU740 SoC
-
-Add new compatible strings to the DT binding documents to support SiFive
-FU740-C000.
-
-Signed-off-by: Yash Shah <yash.shah@sifive.com>
-Reviewed-by: Rob Herring <robh@kernel.org>
----
- Documentation/devicetree/bindings/i2c/i2c-ocores.txt | 8 ++++++--
- 1 file changed, 6 insertions(+), 2 deletions(-)
-
-diff --git a/Documentation/devicetree/bindings/i2c/i2c-ocores.txt b/Documentation/devicetree/bindings/i2c/i2c-ocores.txt
-index 6b25a80..a37c945 100644
---- a/Documentation/devicetree/bindings/i2c/i2c-ocores.txt
-+++ b/Documentation/devicetree/bindings/i2c/i2c-ocores.txt
-@@ -5,8 +5,12 @@ Required properties:
- "aeroflexgaisler,i2cmst"
- "sifive,fu540-c000-i2c", "sifive,i2c0"
- For Opencore based I2C IP block reimplemented in
-- FU540-C000 SoC. Please refer to sifive-blocks-ip-versioning.txt
-- for additional details.
-+ FU540-C000 SoC.
-+ "sifive,fu740-c000-i2c", "sifive,i2c0"
-+ For Opencore based I2C IP block reimplemented in
-+ FU740-C000 SoC.
-+ Please refer to sifive-blocks-ip-versioning.txt for
-+ additional details.
- - reg : bus address start and address range size of device
- - clocks : handle to the controller clock; see the note below.
- Mutually exclusive with opencores,ip-clock-frequency
---
-2.7.4
-
+++ /dev/null
-From 7d2e730f1281b5530e55ebca1b0d9165e0298c00 Mon Sep 17 00:00:00 2001
-From: Yash Shah <yash.shah@sifive.com>
-Date: Tue, 8 Dec 2020 10:25:39 +0530
-Subject: [PATCH 12/29] riscv: dts: add initial support for the SiFive
- FU740-C000 SoC
-
-Add initial support for the SiFive FU540-C000 SoC. FU740-C000 is built
-around the SiFIve U7 Core Complex and a TileLink interconnect.
-
-This file is expected to grow as more device drivers are added to the
-kernel.
-
-Signed-off-by: Yash Shah <yash.shah@sifive.com>
----
- arch/riscv/boot/dts/sifive/fu740-c000.dtsi | 293 +++++++++++++++++++++++++++++
- 1 file changed, 293 insertions(+)
- create mode 100644 arch/riscv/boot/dts/sifive/fu740-c000.dtsi
-
-diff --git a/arch/riscv/boot/dts/sifive/fu740-c000.dtsi b/arch/riscv/boot/dts/sifive/fu740-c000.dtsi
-new file mode 100644
-index 00000000..eeb4f8c3
---- /dev/null
-+++ b/arch/riscv/boot/dts/sifive/fu740-c000.dtsi
-@@ -0,0 +1,293 @@
-+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
-+/* Copyright (c) 2020 SiFive, Inc */
-+
-+/dts-v1/;
-+
-+#include <dt-bindings/clock/sifive-fu740-prci.h>
-+
-+/ {
-+ #address-cells = <2>;
-+ #size-cells = <2>;
-+ compatible = "sifive,fu740-c000", "sifive,fu740";
-+
-+ aliases {
-+ serial0 = &uart0;
-+ serial1 = &uart1;
-+ ethernet0 = ð0;
-+ };
-+
-+ chosen {
-+ };
-+
-+ cpus {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ cpu0: cpu@0 {
-+ compatible = "sifive,bullet0", "riscv";
-+ device_type = "cpu";
-+ i-cache-block-size = <64>;
-+ i-cache-sets = <128>;
-+ i-cache-size = <16384>;
-+ next-level-cache = <&ccache>;
-+ reg = <0x0>;
-+ riscv,isa = "rv64imac";
-+ status = "disabled";
-+ cpu0_intc: interrupt-controller {
-+ #interrupt-cells = <1>;
-+ compatible = "riscv,cpu-intc";
-+ interrupt-controller;
-+ };
-+ };
-+ cpu1: cpu@1 {
-+ compatible = "sifive,bullet0", "riscv";
-+ 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 = <128>;
-+ i-cache-size = <32768>;
-+ i-tlb-sets = <1>;
-+ i-tlb-size = <40>;
-+ mmu-type = "riscv,sv39";
-+ next-level-cache = <&ccache>;
-+ reg = <0x1>;
-+ riscv,isa = "rv64imafdc";
-+ tlb-split;
-+ cpu1_intc: interrupt-controller {
-+ #interrupt-cells = <1>;
-+ compatible = "riscv,cpu-intc";
-+ interrupt-controller;
-+ };
-+ };
-+ cpu2: cpu@2 {
-+ compatible = "sifive,bullet0", "riscv";
-+ 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 = <128>;
-+ i-cache-size = <32768>;
-+ i-tlb-sets = <1>;
-+ i-tlb-size = <40>;
-+ mmu-type = "riscv,sv39";
-+ next-level-cache = <&ccache>;
-+ reg = <0x2>;
-+ riscv,isa = "rv64imafdc";
-+ tlb-split;
-+ cpu2_intc: interrupt-controller {
-+ #interrupt-cells = <1>;
-+ compatible = "riscv,cpu-intc";
-+ interrupt-controller;
-+ };
-+ };
-+ cpu3: cpu@3 {
-+ compatible = "sifive,bullet0", "riscv";
-+ 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 = <128>;
-+ i-cache-size = <32768>;
-+ i-tlb-sets = <1>;
-+ i-tlb-size = <40>;
-+ mmu-type = "riscv,sv39";
-+ next-level-cache = <&ccache>;
-+ reg = <0x3>;
-+ riscv,isa = "rv64imafdc";
-+ tlb-split;
-+ cpu3_intc: interrupt-controller {
-+ #interrupt-cells = <1>;
-+ compatible = "riscv,cpu-intc";
-+ interrupt-controller;
-+ };
-+ };
-+ cpu4: cpu@4 {
-+ compatible = "sifive,bullet0", "riscv";
-+ 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 = <128>;
-+ i-cache-size = <32768>;
-+ i-tlb-sets = <1>;
-+ i-tlb-size = <40>;
-+ mmu-type = "riscv,sv39";
-+ next-level-cache = <&ccache>;
-+ reg = <0x4>;
-+ riscv,isa = "rv64imafdc";
-+ tlb-split;
-+ cpu4_intc: interrupt-controller {
-+ #interrupt-cells = <1>;
-+ compatible = "riscv,cpu-intc";
-+ interrupt-controller;
-+ };
-+ };
-+ };
-+ soc {
-+ #address-cells = <2>;
-+ #size-cells = <2>;
-+ compatible = "simple-bus";
-+ ranges;
-+ plic0: interrupt-controller@c000000 {
-+ #interrupt-cells = <1>;
-+ #address-cells = <0>;
-+ compatible = "sifive,fu540-c000-plic", "sifive,plic-1.0.0";
-+ reg = <0x0 0xc000000 0x0 0x4000000>;
-+ riscv,ndev = <69>;
-+ interrupt-controller;
-+ interrupts-extended = <
-+ &cpu0_intc 0xffffffff
-+ &cpu1_intc 0xffffffff &cpu1_intc 9
-+ &cpu2_intc 0xffffffff &cpu2_intc 9
-+ &cpu3_intc 0xffffffff &cpu3_intc 9
-+ &cpu4_intc 0xffffffff &cpu4_intc 9>;
-+ };
-+ prci: clock-controller@10000000 {
-+ compatible = "sifive,fu740-c000-prci";
-+ reg = <0x0 0x10000000 0x0 0x1000>;
-+ clocks = <&hfclk>, <&rtcclk>;
-+ #clock-cells = <1>;
-+ };
-+ uart0: serial@10010000 {
-+ compatible = "sifive,fu740-c000-uart", "sifive,uart0";
-+ reg = <0x0 0x10010000 0x0 0x1000>;
-+ interrupt-parent = <&plic0>;
-+ interrupts = <39>;
-+ clocks = <&prci PRCI_CLK_PCLK>;
-+ status = "disabled";
-+ };
-+ uart1: serial@10011000 {
-+ compatible = "sifive,fu740-c000-uart", "sifive,uart0";
-+ reg = <0x0 0x10011000 0x0 0x1000>;
-+ interrupt-parent = <&plic0>;
-+ interrupts = <40>;
-+ clocks = <&prci PRCI_CLK_PCLK>;
-+ status = "disabled";
-+ };
-+ i2c0: i2c@10030000 {
-+ compatible = "sifive,fu740-c000-i2c", "sifive,i2c0";
-+ reg = <0x0 0x10030000 0x0 0x1000>;
-+ interrupt-parent = <&plic0>;
-+ interrupts = <52>;
-+ clocks = <&prci PRCI_CLK_PCLK>;
-+ reg-shift = <2>;
-+ reg-io-width = <1>;
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ status = "disabled";
-+ };
-+ i2c1: i2c@10031000 {
-+ compatible = "sifive,fu740-c000-i2c", "sifive,i2c0";
-+ reg = <0x0 0x10031000 0x0 0x1000>;
-+ interrupt-parent = <&plic0>;
-+ interrupts = <53>;
-+ clocks = <&prci PRCI_CLK_PCLK>;
-+ reg-shift = <2>;
-+ reg-io-width = <1>;
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ status = "disabled";
-+ };
-+ qspi0: spi@10040000 {
-+ compatible = "sifive,fu740-c000-spi", "sifive,spi0";
-+ reg = <0x0 0x10040000 0x0 0x1000>,
-+ <0x0 0x20000000 0x0 0x10000000>;
-+ interrupt-parent = <&plic0>;
-+ interrupts = <41>;
-+ clocks = <&prci PRCI_CLK_PCLK>;
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ status = "disabled";
-+ };
-+ qspi1: spi@10041000 {
-+ compatible = "sifive,fu740-c000-spi", "sifive,spi0";
-+ reg = <0x0 0x10041000 0x0 0x1000>,
-+ <0x0 0x30000000 0x0 0x10000000>;
-+ interrupt-parent = <&plic0>;
-+ interrupts = <42>;
-+ clocks = <&prci PRCI_CLK_PCLK>;
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ status = "disabled";
-+ };
-+ spi0: spi@10050000 {
-+ compatible = "sifive,fu740-c000-spi", "sifive,spi0";
-+ reg = <0x0 0x10050000 0x0 0x1000>;
-+ interrupt-parent = <&plic0>;
-+ interrupts = <43>;
-+ clocks = <&prci PRCI_CLK_PCLK>;
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ status = "disabled";
-+ };
-+ eth0: ethernet@10090000 {
-+ compatible = "sifive,fu540-c000-gem";
-+ interrupt-parent = <&plic0>;
-+ interrupts = <55>;
-+ reg = <0x0 0x10090000 0x0 0x2000>,
-+ <0x0 0x100a0000 0x0 0x1000>;
-+ local-mac-address = [00 00 00 00 00 00];
-+ clock-names = "pclk", "hclk";
-+ clocks = <&prci PRCI_CLK_GEMGXLPLL>,
-+ <&prci PRCI_CLK_GEMGXLPLL>;
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ status = "disabled";
-+ };
-+ pwm0: pwm@10020000 {
-+ compatible = "sifive,fu740-c000-pwm", "sifive,pwm0";
-+ reg = <0x0 0x10020000 0x0 0x1000>;
-+ interrupt-parent = <&plic0>;
-+ interrupts = <44>, <45>, <46>, <47>;
-+ clocks = <&prci PRCI_CLK_PCLK>;
-+ #pwm-cells = <3>;
-+ status = "disabled";
-+ };
-+ pwm1: pwm@10021000 {
-+ compatible = "sifive,fu740-c000-pwm", "sifive,pwm0";
-+ reg = <0x0 0x10021000 0x0 0x1000>;
-+ interrupt-parent = <&plic0>;
-+ interrupts = <48>, <49>, <50>, <51>;
-+ clocks = <&prci PRCI_CLK_PCLK>;
-+ #pwm-cells = <3>;
-+ status = "disabled";
-+ };
-+ ccache: cache-controller@2010000 {
-+ compatible = "sifive,fu740-c000-ccache", "cache";
-+ cache-block-size = <64>;
-+ cache-level = <2>;
-+ cache-sets = <2048>;
-+ cache-size = <2097152>;
-+ cache-unified;
-+ interrupt-parent = <&plic0>;
-+ interrupts = <19 20 21 22>;
-+ reg = <0x0 0x2010000 0x0 0x1000>;
-+ };
-+ gpio: gpio@10060000 {
-+ compatible = "sifive,fu740-c000-gpio", "sifive,gpio0";
-+ interrupt-parent = <&plic0>;
-+ interrupts = <23>, <24>, <25>, <26>, <27>, <28>, <29>,
-+ <30>, <31>, <32>, <33>, <34>, <35>, <36>,
-+ <37>, <38>;
-+ reg = <0x0 0x10060000 0x0 0x1000>;
-+ gpio-controller;
-+ #gpio-cells = <2>;
-+ interrupt-controller;
-+ #interrupt-cells = <2>;
-+ clocks = <&prci PRCI_CLK_PCLK>;
-+ status = "disabled";
-+ };
-+ };
-+};
---
-2.7.4
-
+++ /dev/null
-From 323c7d104a6fbe22100fdd7b62d53a4f4739affa Mon Sep 17 00:00:00 2001
-From: Yash Shah <yash.shah@sifive.com>
-Date: Tue, 8 Dec 2020 10:25:40 +0530
-Subject: [PATCH 13/29] dt-bindings: riscv: Update YAML doc to support SiFive
- HiFive Unmatched board
-
-Add new compatible strings to the YAML DT binding document to support
-SiFive's HiFive Unmatched board
-
-Signed-off-by: Yash Shah <yash.shah@sifive.com>
-Reviewed-by: Rob Herring <robh@kernel.org>
-Reviewed-by: Bin Meng <bin.meng@windriver.com>
----
- Documentation/devicetree/bindings/riscv/sifive.yaml | 17 ++++++++++++-----
- 1 file changed, 12 insertions(+), 5 deletions(-)
-
-diff --git a/Documentation/devicetree/bindings/riscv/sifive.yaml b/Documentation/devicetree/bindings/riscv/sifive.yaml
-index 3a8647d..ee0a239 100644
---- a/Documentation/devicetree/bindings/riscv/sifive.yaml
-+++ b/Documentation/devicetree/bindings/riscv/sifive.yaml
-@@ -17,11 +17,18 @@ properties:
- $nodename:
- const: '/'
- compatible:
-- items:
-- - enum:
-- - sifive,hifive-unleashed-a00
-- - const: sifive,fu540-c000
-- - const: sifive,fu540
-+ oneOf:
-+ - items:
-+ - enum:
-+ - sifive,hifive-unleashed-a00
-+ - const: sifive,fu540-c000
-+ - const: sifive,fu540
-+
-+ - items:
-+ - enum:
-+ - sifive,hifive-unmatched-a00
-+ - const: sifive,fu740-c000
-+ - const: sifive,fu740
-
- additionalProperties: true
-
---
-2.7.4
-
+++ /dev/null
-From 721f85343651f07ab6ed8064680ad8bbadf76d3f Mon Sep 17 00:00:00 2001
-From: Yash Shah <yash.shah@sifive.com>
-Date: Tue, 8 Dec 2020 10:25:41 +0530
-Subject: [PATCH 14/29] riscv: dts: add initial board data for the SiFive
- HiFive Unmatched
-
-Add initial board data for the SiFive HiFive Unmatched A00.
-This patch is dependent on Zong's Patchset[0].
-
-[0]: https://lore.kernel.org/linux-riscv/20201130082330.77268-4-zong.li@sifive.com/T/#u
-
-Signed-off-by: Yash Shah <yash.shah@sifive.com>
-Reviewed-by: Bin Meng <bin.meng@windriver.com>
----
- arch/riscv/boot/dts/sifive/Makefile | 3 +-
- .../riscv/boot/dts/sifive/hifive-unmatched-a00.dts | 253 +++++++++++++++++++++
- 2 files changed, 255 insertions(+), 1 deletion(-)
- create mode 100644 arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts
-
-diff --git a/arch/riscv/boot/dts/sifive/Makefile b/arch/riscv/boot/dts/sifive/Makefile
-index 6d6189e..74c47fe 100644
---- a/arch/riscv/boot/dts/sifive/Makefile
-+++ b/arch/riscv/boot/dts/sifive/Makefile
-@@ -1,2 +1,3 @@
- # SPDX-License-Identifier: GPL-2.0
--dtb-$(CONFIG_SOC_SIFIVE) += hifive-unleashed-a00.dtb
-+dtb-$(CONFIG_SOC_SIFIVE) += hifive-unleashed-a00.dtb \
-+ hifive-unmatched-a00.dtb
-diff --git a/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts b/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts
-new file mode 100644
-index 00000000..b1c3c59
---- /dev/null
-+++ b/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts
-@@ -0,0 +1,253 @@
-+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
-+/* Copyright (c) 2020 SiFive, Inc */
-+
-+#include "fu740-c000.dtsi"
-+#include <dt-bindings/interrupt-controller/irq.h>
-+
-+/* Clock frequency (in Hz) of the PCB crystal for rtcclk */
-+#define RTCCLK_FREQ 1000000
-+
-+/ {
-+ #address-cells = <2>;
-+ #size-cells = <2>;
-+ model = "SiFive HiFive Unmatched A00";
-+ compatible = "sifive,hifive-unmatched-a00", "sifive,fu740-c000",
-+ "sifive,fu740";
-+
-+ chosen {
-+ stdout-path = "serial0";
-+ };
-+
-+ cpus {
-+ timebase-frequency = <RTCCLK_FREQ>;
-+ };
-+
-+ memory@80000000 {
-+ device_type = "memory";
-+ reg = <0x0 0x80000000 0x2 0x00000000>;
-+ };
-+
-+ soc {
-+ };
-+
-+ hfclk: hfclk {
-+ #clock-cells = <0>;
-+ compatible = "fixed-clock";
-+ clock-frequency = <26000000>;
-+ clock-output-names = "hfclk";
-+ };
-+
-+ rtcclk: rtcclk {
-+ #clock-cells = <0>;
-+ compatible = "fixed-clock";
-+ clock-frequency = <RTCCLK_FREQ>;
-+ clock-output-names = "rtcclk";
-+ };
-+};
-+
-+&uart0 {
-+ status = "okay";
-+};
-+
-+&uart1 {
-+ status = "okay";
-+};
-+
-+&i2c0 {
-+ status = "okay";
-+
-+ temperature-sensor@4c {
-+ compatible = "ti,tmp451";
-+ reg = <0x4c>;
-+ interrupt-parent = <&gpio>;
-+ interrupts = <6 IRQ_TYPE_LEVEL_LOW>;
-+ };
-+
-+ pmic@58 {
-+ compatible = "dlg,da9063";
-+ reg = <0x58>;
-+ interrupt-parent = <&gpio>;
-+ interrupts = <1 IRQ_TYPE_LEVEL_LOW>;
-+ interrupt-controller;
-+
-+ regulators {
-+ vdd_bcore1: bcore1 {
-+ regulator-min-microvolt = <900000>;
-+ regulator-max-microvolt = <900000>;
-+ regulator-min-microamp = <5000000>;
-+ regulator-max-microamp = <5000000>;
-+ regulator-always-on;
-+ };
-+
-+ vdd_bcore2: bcore2 {
-+ regulator-min-microvolt = <900000>;
-+ regulator-max-microvolt = <900000>;
-+ regulator-min-microamp = <5000000>;
-+ regulator-max-microamp = <5000000>;
-+ regulator-always-on;
-+ };
-+
-+ vdd_bpro: bpro {
-+ regulator-min-microvolt = <1800000>;
-+ regulator-max-microvolt = <1800000>;
-+ regulator-min-microamp = <2500000>;
-+ regulator-max-microamp = <2500000>;
-+ regulator-always-on;
-+ };
-+
-+ vdd_bperi: bperi {
-+ regulator-min-microvolt = <1050000>;
-+ regulator-max-microvolt = <1050000>;
-+ regulator-min-microamp = <1500000>;
-+ regulator-max-microamp = <1500000>;
-+ regulator-always-on;
-+ };
-+
-+ vdd_bmem: bmem {
-+ regulator-min-microvolt = <1200000>;
-+ regulator-max-microvolt = <1200000>;
-+ regulator-min-microamp = <3000000>;
-+ regulator-max-microamp = <3000000>;
-+ regulator-always-on;
-+ };
-+
-+ vdd_bio: bio {
-+ regulator-min-microvolt = <1200000>;
-+ regulator-max-microvolt = <1200000>;
-+ regulator-min-microamp = <3000000>;
-+ regulator-max-microamp = <3000000>;
-+ regulator-always-on;
-+ };
-+
-+ vdd_ldo1: ldo1 {
-+ regulator-min-microvolt = <1800000>;
-+ regulator-max-microvolt = <1800000>;
-+ regulator-min-microamp = <100000>;
-+ regulator-max-microamp = <100000>;
-+ regulator-always-on;
-+ };
-+
-+ vdd_ldo2: ldo2 {
-+ regulator-min-microvolt = <1800000>;
-+ regulator-max-microvolt = <1800000>;
-+ regulator-min-microamp = <200000>;
-+ regulator-max-microamp = <200000>;
-+ regulator-always-on;
-+ };
-+
-+ vdd_ldo3: ldo3 {
-+ regulator-min-microvolt = <1800000>;
-+ regulator-max-microvolt = <1800000>;
-+ regulator-min-microamp = <200000>;
-+ regulator-max-microamp = <200000>;
-+ regulator-always-on;
-+ };
-+
-+ vdd_ldo4: ldo4 {
-+ regulator-min-microvolt = <1800000>;
-+ regulator-max-microvolt = <1800000>;
-+ regulator-min-microamp = <200000>;
-+ regulator-max-microamp = <200000>;
-+ regulator-always-on;
-+ };
-+
-+ vdd_ldo5: ldo5 {
-+ regulator-min-microvolt = <1800000>;
-+ regulator-max-microvolt = <1800000>;
-+ regulator-min-microamp = <100000>;
-+ regulator-max-microamp = <100000>;
-+ regulator-always-on;
-+ };
-+
-+ vdd_ldo6: ldo6 {
-+ regulator-min-microvolt = <3300000>;
-+ regulator-max-microvolt = <3300000>;
-+ regulator-min-microamp = <200000>;
-+ regulator-max-microamp = <200000>;
-+ regulator-always-on;
-+ };
-+
-+ vdd_ldo7: ldo7 {
-+ regulator-min-microvolt = <1800000>;
-+ regulator-max-microvolt = <1800000>;
-+ regulator-min-microamp = <200000>;
-+ regulator-max-microamp = <200000>;
-+ regulator-always-on;
-+ };
-+
-+ vdd_ldo8: ldo8 {
-+ regulator-min-microvolt = <1800000>;
-+ regulator-max-microvolt = <1800000>;
-+ regulator-min-microamp = <200000>;
-+ regulator-max-microamp = <200000>;
-+ regulator-always-on;
-+ };
-+
-+ vdd_ld09: ldo9 {
-+ regulator-min-microvolt = <1050000>;
-+ regulator-max-microvolt = <1050000>;
-+ regulator-min-microamp = <200000>;
-+ regulator-max-microamp = <200000>;
-+ };
-+
-+ vdd_ldo10: ldo10 {
-+ regulator-min-microvolt = <1000000>;
-+ regulator-max-microvolt = <1000000>;
-+ regulator-min-microamp = <300000>;
-+ regulator-max-microamp = <300000>;
-+ };
-+
-+ vdd_ldo11: ldo11 {
-+ regulator-min-microvolt = <2500000>;
-+ regulator-max-microvolt = <2500000>;
-+ regulator-min-microamp = <300000>;
-+ regulator-max-microamp = <300000>;
-+ regulator-always-on;
-+ };
-+ };
-+ };
-+};
-+
-+&qspi0 {
-+ status = "okay";
-+ flash@0 {
-+ compatible = "issi,is25wp256", "jedec,spi-nor";
-+ reg = <0>;
-+ spi-max-frequency = <50000000>;
-+ m25p,fast-read;
-+ spi-tx-bus-width = <4>;
-+ spi-rx-bus-width = <4>;
-+ };
-+};
-+
-+&spi0 {
-+ status = "okay";
-+ mmc@0 {
-+ compatible = "mmc-spi-slot";
-+ reg = <0>;
-+ spi-max-frequency = <20000000>;
-+ voltage-ranges = <3300 3300>;
-+ disable-wp;
-+ };
-+};
-+
-+ð0 {
-+ status = "okay";
-+ phy-mode = "gmii";
-+ phy-handle = <&phy0>;
-+ phy0: ethernet-phy@0 {
-+ reg = <0>;
-+ };
-+};
-+
-+&pwm0 {
-+ status = "okay";
-+};
-+
-+&pwm1 {
-+ status = "okay";
-+};
-+
-+&gpio {
-+ status = "okay";
-+};
---
-2.7.4
-
+++ /dev/null
-From f4a28f41637429a1784ab2bf5e16222ec91da575 Mon Sep 17 00:00:00 2001
-From: Yash Shah <yash.shah@sifive.com>
-Date: Thu, 10 Dec 2020 15:58:03 +0530
-Subject: [PATCH 16/29] RISC-V: sifive_l2_cache: Update L2 cache driver to
- support SiFive FU740
-
-SiFive FU740 has 4 ECC interrupt sources as compared to 3 in FU540.
-Update the L2 cache controller driver to support this additional
-interrupt in case of FU740-C000 chip.
-
-Signed-off-by: Yash Shah <yash.shah@sifive.com>
----
- drivers/soc/sifive/sifive_l2_cache.c | 27 ++++++++++++++++++++++++---
- 1 file changed, 24 insertions(+), 3 deletions(-)
-
-diff --git a/drivers/soc/sifive/sifive_l2_cache.c b/drivers/soc/sifive/sifive_l2_cache.c
-index 44d7e1951..59640a1 100644
---- a/drivers/soc/sifive/sifive_l2_cache.c
-+++ b/drivers/soc/sifive/sifive_l2_cache.c
-@@ -17,6 +17,10 @@
- #define SIFIVE_L2_DIRECCFIX_HIGH 0x104
- #define SIFIVE_L2_DIRECCFIX_COUNT 0x108
-
-+#define SIFIVE_L2_DIRECCFAIL_LOW 0x120
-+#define SIFIVE_L2_DIRECCFAIL_HIGH 0x124
-+#define SIFIVE_L2_DIRECCFAIL_COUNT 0x128
-+
- #define SIFIVE_L2_DATECCFIX_LOW 0x140
- #define SIFIVE_L2_DATECCFIX_HIGH 0x144
- #define SIFIVE_L2_DATECCFIX_COUNT 0x148
-@@ -29,7 +33,7 @@
- #define SIFIVE_L2_WAYENABLE 0x08
- #define SIFIVE_L2_ECCINJECTERR 0x40
-
--#define SIFIVE_L2_MAX_ECCINTR 3
-+#define SIFIVE_L2_MAX_ECCINTR 4
-
- static void __iomem *l2_base;
- static int g_irq[SIFIVE_L2_MAX_ECCINTR];
-@@ -39,6 +43,7 @@ enum {
- DIR_CORR = 0,
- DATA_CORR,
- DATA_UNCORR,
-+ DIR_UNCORR,
- };
-
- #ifdef CONFIG_DEBUG_FS
-@@ -93,6 +98,7 @@ static void l2_config_read(void)
-
- static const struct of_device_id sifive_l2_ids[] = {
- { .compatible = "sifive,fu540-c000-ccache" },
-+ { .compatible = "sifive,fu740-c000-ccache" },
- { /* end of table */ },
- };
-
-@@ -155,6 +161,15 @@ static irqreturn_t l2_int_handler(int irq, void *device)
- atomic_notifier_call_chain(&l2_err_chain, SIFIVE_L2_ERR_TYPE_CE,
- "DirECCFix");
- }
-+ if (irq == g_irq[DIR_UNCORR]) {
-+ add_h = readl(l2_base + SIFIVE_L2_DIRECCFAIL_HIGH);
-+ add_l = readl(l2_base + SIFIVE_L2_DIRECCFAIL_LOW);
-+ /* Reading this register clears the DirFail interrupt sig */
-+ readl(l2_base + SIFIVE_L2_DIRECCFAIL_COUNT);
-+ atomic_notifier_call_chain(&l2_err_chain, SIFIVE_L2_ERR_TYPE_UE,
-+ "DirECCFail");
-+ panic("L2CACHE: DirFail @ 0x%08X.%08X\n", add_h, add_l);
-+ }
- if (irq == g_irq[DATA_CORR]) {
- add_h = readl(l2_base + SIFIVE_L2_DATECCFIX_HIGH);
- add_l = readl(l2_base + SIFIVE_L2_DATECCFIX_LOW);
-@@ -181,7 +196,7 @@ static int __init sifive_l2_init(void)
- {
- struct device_node *np;
- struct resource res;
-- int i, rc;
-+ int i, rc, intr_num;
-
- np = of_find_matching_node(NULL, sifive_l2_ids);
- if (!np)
-@@ -194,7 +209,13 @@ static int __init sifive_l2_init(void)
- if (!l2_base)
- return -ENOMEM;
-
-- for (i = 0; i < SIFIVE_L2_MAX_ECCINTR; i++) {
-+ intr_num = of_property_count_u32_elems(np, "interrupts");
-+ if (!intr_num) {
-+ pr_err("L2CACHE: no interrupts property\n");
-+ return -ENODEV;
-+ }
-+
-+ for (i = 0; i < intr_num; i++) {
- g_irq[i] = irq_of_parse_and_map(np, i);
- rc = request_irq(g_irq[i], l2_int_handler, 0, "l2_ecc", NULL);
- if (rc) {
---
-2.7.4
-
+++ /dev/null
-From e00f15b712b61f35fec747912dd5d3e9553d89a1 Mon Sep 17 00:00:00 2001
-From: Greentime Hu <greentime.hu@sifive.com>
-Date: Fri, 13 Nov 2020 10:33:55 +0800
-Subject: [PATCH 17/29] gpio: sifive: To get gpio irq offset from device tree
- data
-
-We can get hwirq number of the gpio by its irq_data->hwirq so that we don't
-need to add more macros for different platforms. This patch is tested in
-SiFive Unleashed board and SiFive Unmatched board.
-
-Signed-off-by: Greentime Hu <greentime.hu@sifive.com>
----
- drivers/gpio/gpio-sifive.c | 14 ++++++++++----
- 1 file changed, 10 insertions(+), 4 deletions(-)
-
-diff --git a/drivers/gpio/gpio-sifive.c b/drivers/gpio/gpio-sifive.c
-index d5eb9ca..63593c2 100644
---- a/drivers/gpio/gpio-sifive.c
-+++ b/drivers/gpio/gpio-sifive.c
-@@ -29,7 +29,6 @@
- #define SIFIVE_GPIO_OUTPUT_XOR 0x40
-
- #define SIFIVE_GPIO_MAX 32
--#define SIFIVE_GPIO_IRQ_OFFSET 7
-
- struct sifive_gpio {
- void __iomem *base;
-@@ -37,7 +36,7 @@ struct sifive_gpio {
- struct regmap *regs;
- unsigned long irq_state;
- unsigned int trigger[SIFIVE_GPIO_MAX];
-- unsigned int irq_parent[SIFIVE_GPIO_MAX];
-+ unsigned int irq_number[SIFIVE_GPIO_MAX];
- };
-
- static void sifive_gpio_set_ie(struct sifive_gpio *chip, unsigned int offset)
-@@ -144,8 +143,12 @@ static int sifive_gpio_child_to_parent_hwirq(struct gpio_chip *gc,
- unsigned int *parent,
- unsigned int *parent_type)
- {
-+ struct sifive_gpio *chip = gpiochip_get_data(gc);
-+ struct irq_data *d = irq_get_irq_data(chip->irq_number[child]);
-+
- *parent_type = IRQ_TYPE_NONE;
-- *parent = child + SIFIVE_GPIO_IRQ_OFFSET;
-+ *parent = irqd_to_hwirq(d);
-+
- return 0;
- }
-
-@@ -165,7 +168,7 @@ static int sifive_gpio_probe(struct platform_device *pdev)
- struct irq_domain *parent;
- struct gpio_irq_chip *girq;
- struct sifive_gpio *chip;
-- int ret, ngpio;
-+ int ret, ngpio, i;
-
- chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
- if (!chip)
-@@ -200,6 +203,9 @@ static int sifive_gpio_probe(struct platform_device *pdev)
- return -ENODEV;
- }
-
-+ for (i = 0; i < ngpio; i++)
-+ chip->irq_number[i] = platform_get_irq(pdev, i);
-+
- ret = bgpio_init(&chip->gc, dev, 4,
- chip->base + SIFIVE_GPIO_INPUT_VAL,
- chip->base + SIFIVE_GPIO_OUTPUT_VAL,
---
-2.7.4
-
+++ /dev/null
-From 49e87f076a3d9d4b1ebadfe2b19250977be6d668 Mon Sep 17 00:00:00 2001
-From: Vincent Chen <vincent.chen@sifive.com>
-Date: Tue, 12 Jan 2021 14:43:50 +0800
-Subject: [PATCH 18/29] riscv: Add 3 SBI wrapper functions to get cpu
- manufactory information
-
-Add 3 wrapper functions to get vendor id, architecture id and implement id
-from M-mode
-
-Signed-off-by: Vincent Chen <vincent.chen@sifive.com>
----
- arch/riscv/include/asm/sbi.h | 3 +++
- arch/riscv/kernel/sbi.c | 15 +++++++++++++++
- 2 files changed, 18 insertions(+)
-
-diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h
-index 653edb2..97eb78d 100644
---- a/arch/riscv/include/asm/sbi.h
-+++ b/arch/riscv/include/asm/sbi.h
-@@ -97,6 +97,9 @@ struct sbiret sbi_ecall(int ext, int fid, unsigned long arg0,
-
- void sbi_console_putchar(int ch);
- int sbi_console_getchar(void);
-+long sbi_get_vendorid(void);
-+long sbi_get_archid(void);
-+long sbi_get_impid(void);
- void sbi_set_timer(uint64_t stime_value);
- void sbi_shutdown(void);
- void sbi_clear_ipi(void);
-diff --git a/arch/riscv/kernel/sbi.c b/arch/riscv/kernel/sbi.c
-index 226ccce..b8f82c7 100644
---- a/arch/riscv/kernel/sbi.c
-+++ b/arch/riscv/kernel/sbi.c
-@@ -547,6 +547,21 @@ static inline long sbi_get_firmware_version(void)
- return __sbi_base_ecall(SBI_EXT_BASE_GET_IMP_VERSION);
- }
-
-+long sbi_get_vendorid(void)
-+{
-+ return __sbi_base_ecall(SBI_EXT_BASE_GET_MVENDORID);
-+}
-+
-+long sbi_get_archid(void)
-+{
-+ return __sbi_base_ecall(SBI_EXT_BASE_GET_MARCHID);
-+}
-+
-+long sbi_get_impid(void)
-+{
-+ return __sbi_base_ecall(SBI_EXT_BASE_GET_MIMPID);
-+}
-+
- static void sbi_send_cpumask_ipi(const struct cpumask *target)
- {
- struct cpumask hartid_mask;
---
-2.7.4
-
+++ /dev/null
-From 34c4f71f957e4e15776493d094593970178ddc9e Mon Sep 17 00:00:00 2001
-From: Vincent Chen <vincent.chen@sifive.com>
-Date: Tue, 12 Jan 2021 15:15:23 +0800
-Subject: [PATCH 19/29] riscv: Get CPU manufactory information
-
-Issue 3 SBI calls to get the vendor ID, architecture ID and
-implementataion ID.
-
-Signed-off-by: Vincent Chen <vincent.chen@sifive.com>
----
- arch/riscv/include/asm/csr.h | 3 +++
- arch/riscv/include/asm/hwcap.h | 6 ++++++
- arch/riscv/include/asm/processor.h | 2 ++
- arch/riscv/kernel/cpufeature.c | 17 +++++++++++++++++
- arch/riscv/kernel/setup.c | 2 ++
- 5 files changed, 30 insertions(+)
-
-diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h
-index cec462e..076beb9 100644
---- a/arch/riscv/include/asm/csr.h
-+++ b/arch/riscv/include/asm/csr.h
-@@ -109,6 +109,9 @@
- #define CSR_MIP 0x344
- #define CSR_PMPCFG0 0x3a0
- #define CSR_PMPADDR0 0x3b0
-+#define CSR_MVENDORID 0xf11
-+#define CSR_MARCHID 0xf12
-+#define CSR_MIMPID 0xf13
- #define CSR_MHARTID 0xf14
-
- #ifdef CONFIG_RISCV_M_MODE
-diff --git a/arch/riscv/include/asm/hwcap.h b/arch/riscv/include/asm/hwcap.h
-index 5ce5046..952fe76 100644
---- a/arch/riscv/include/asm/hwcap.h
-+++ b/arch/riscv/include/asm/hwcap.h
-@@ -44,6 +44,12 @@ bool __riscv_isa_extension_available(const unsigned long *isa_bitmap, int bit);
- #define riscv_isa_extension_available(isa_bitmap, ext) \
- __riscv_isa_extension_available(isa_bitmap, RISCV_ISA_EXT_##ext)
-
-+struct cpu_manufactor_info_t {
-+ unsigned long vendorid;
-+ unsigned long archid;
-+ unsigned long impid;
-+};
-+
- #endif
-
- #endif /* _ASM_RISCV_HWCAP_H */
-diff --git a/arch/riscv/include/asm/processor.h b/arch/riscv/include/asm/processor.h
-index bdddcd5..c9639b5 100644
---- a/arch/riscv/include/asm/processor.h
-+++ b/arch/riscv/include/asm/processor.h
-@@ -71,6 +71,8 @@ int riscv_of_parent_hartid(struct device_node *node);
-
- extern void riscv_fill_hwcap(void);
-
-+void riscv_fill_cpu_manufactor_info(void);
-+
- #endif /* __ASSEMBLY__ */
-
- #endif /* _ASM_RISCV_PROCESSOR_H */
-diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c
-index ac202f4..0315297 100644
---- a/arch/riscv/kernel/cpufeature.c
-+++ b/arch/riscv/kernel/cpufeature.c
-@@ -12,6 +12,8 @@
- #include <asm/hwcap.h>
- #include <asm/smp.h>
- #include <asm/switch_to.h>
-+#include <asm/sbi.h>
-+#include <asm/csr.h>
-
- unsigned long elf_hwcap __read_mostly;
-
-@@ -22,6 +24,8 @@ static DECLARE_BITMAP(riscv_isa, RISCV_ISA_EXT_MAX) __read_mostly;
- bool has_fpu __read_mostly;
- #endif
-
-+struct cpu_manufactor_info_t cpu_manufactor_info;
-+
- /**
- * riscv_isa_extension_base() - Get base extension word
- *
-@@ -149,3 +153,16 @@ void riscv_fill_hwcap(void)
- has_fpu = true;
- #endif
- }
-+
-+void riscv_fill_cpu_manufactor_info(void)
-+{
-+#ifndef CONFIG_RISCV_M_MODE
-+ cpu_manufactor_info.vendorid = sbi_get_vendorid();
-+ cpu_manufactor_info.archid = sbi_get_archid();
-+ cpu_manufactor_info.impid = sbi_get_impid();
-+#else
-+ cpu_manufactor_info.vendorid = csr_read(CSR_MVENDORID);
-+ cpu_manufactor_info.archid = csr_read(CSR_MARCHID);
-+ cpu_manufactor_info.impid = csr_read(CSR_MIMPID);
-+#endif
-+}
-diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c
-index 117f321..c7c1ae9 100644
---- a/arch/riscv/kernel/setup.c
-+++ b/arch/riscv/kernel/setup.c
-@@ -107,6 +107,8 @@ void __init setup_arch(char **cmdline_p)
- #endif
-
- riscv_fill_hwcap();
-+
-+ riscv_fill_cpu_manufactor_info();
- }
-
- static int __init topology_init(void)
---
-2.7.4
-
+++ /dev/null
-From a3e6ca97499c444fee45c7efafcdef311142952c Mon Sep 17 00:00:00 2001
-From: Vincent Chen <vincent.chen@sifive.com>
-Date: Tue, 19 Jan 2021 03:30:22 -0800
-Subject: [PATCH 20/29] riscv: Introduce alternative mechanism to apply errata
- solution
-
-Introduce the "alternative" mechanism from ARM64 and x86 to apply the CPU
-vendors' errata solution at runtime. The main purpose of this patch is
-to provide a framework. Therefore, the implementation is quite basic for
-now so that some scenarios could not use this scheme such as patching code
-to a module, relocating the patching code and heterogeneous CPU topology.
-
-Users could use the two macros ALTINSN and ALTDATA to modify the existing
-instruction and data respectively. By specifying the parameters vendorid,
-archid and impid, the kernel can probably apply the patch codes based on
-the same information of the running CPU. To keep the flexibility, the user
-can pass the specific kernel configure to the alternative macro to enable
-or disable the errata solution at compile time.
-
-Rebased for v5.10.8 by David Abdurachmanov.
-
-Signed-off-by: David Abdurachmanov <david.abdurachmanov@sifive.com>
----
- arch/riscv/Kconfig | 7 ++
- arch/riscv/Makefile | 1 +
- arch/riscv/errata/Makefile | 1 +
- arch/riscv/errata/alternative.c | 74 ++++++++++++++++
- arch/riscv/include/asm/alternative-macros.h | 133 ++++++++++++++++++++++++++++
- arch/riscv/include/asm/alternative.h | 43 +++++++++
- arch/riscv/include/asm/asm.h | 1 +
- arch/riscv/include/asm/sections.h | 3 +
- arch/riscv/kernel/smpboot.c | 4 +
- arch/riscv/kernel/vmlinux.lds.S | 21 +++++
- 10 files changed, 288 insertions(+)
- create mode 100644 arch/riscv/errata/Makefile
- create mode 100644 arch/riscv/errata/alternative.c
- create mode 100644 arch/riscv/include/asm/alternative-macros.h
- create mode 100644 arch/riscv/include/asm/alternative.h
-
-diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
-index 3474286..2717aa0 100644
---- a/arch/riscv/Kconfig
-+++ b/arch/riscv/Kconfig
-@@ -84,6 +84,7 @@ config RISCV
- select PCI_MSI if PCI
- select RISCV_INTC
- select RISCV_TIMER if RISCV_SBI
-+ select RISCV_ERRATA
- select SPARSE_IRQ
- select SYSCTL_EXCEPTION_TRACE
- select THREAD_INFO_IN_TASK
-@@ -423,6 +424,12 @@ config BUILTIN_DTB
- depends on RISCV_M_MODE
- depends on OF
-
-+config RISCV_ERRATA
-+ bool "Runtime apply errata patch"
-+ help
-+ This option provides the support for applying the errata patch
-+ at runtime.
-+
- menu "Power management options"
-
- source "kernel/power/Kconfig"
-diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile
-index 0289a97..cd23fb0 100644
---- a/arch/riscv/Makefile
-+++ b/arch/riscv/Makefile
-@@ -75,6 +75,7 @@ KBUILD_IMAGE := $(boot)/Image.gz
- head-y := arch/riscv/kernel/head.o
-
- core-y += arch/riscv/
-+core-$(CONFIG_RISCV_ERRATA) += arch/riscv/errata/
-
- libs-y += arch/riscv/lib/
- libs-$(CONFIG_EFI_STUB) += $(objtree)/drivers/firmware/efi/libstub/lib.a
-diff --git a/arch/riscv/errata/Makefile b/arch/riscv/errata/Makefile
-new file mode 100644
-index 00000000..43e6d54
---- /dev/null
-+++ b/arch/riscv/errata/Makefile
-@@ -0,0 +1 @@
-+obj-y += alternative.o
-diff --git a/arch/riscv/errata/alternative.c b/arch/riscv/errata/alternative.c
-new file mode 100644
-index 00000000..0827c05
---- /dev/null
-+++ b/arch/riscv/errata/alternative.c
-@@ -0,0 +1,74 @@
-+// SPDX-License-Identifier: GPL-2.0-only
-+/*
-+ * alternative runtime patching
-+ * inspired by the ARM64 and x86 version
-+ *
-+ * Copyright (C) 2021 Sifive.
-+ */
-+
-+#include <linux/init.h>
-+#include <linux/cpu.h>
-+#include <linux/uaccess.h>
-+#include <asm/patch.h>
-+#include <asm/alternative.h>
-+#include <asm/sections.h>
-+
-+struct alt_region {
-+ struct alt_entry *begin;
-+ struct alt_entry *end;
-+};
-+
-+static bool __init default_checkfunc(struct alt_entry *alt)
-+{
-+ return false;
-+}
-+
-+static bool (*errata_checkfunc)(struct alt_entry *alt) = default_checkfunc;
-+typedef int (*patch_func_t)(void *addr, const void *insn, size_t size);
-+
-+static void __apply_alternatives(void *alt_region, void *alt_patch_func)
-+{
-+ struct alt_entry *alt;
-+ struct alt_region *region = alt_region;
-+
-+ for (alt = region->begin; alt < region->end; alt++) {
-+ if (!errata_checkfunc(alt))
-+ continue;
-+ ((patch_func_t)alt_patch_func)(alt->old_ptr, alt->alt_ptr, alt->old_len);
-+ }
-+}
-+
-+static void __init init_alternatvie(void)
-+{
-+ struct errata_checkfunc_id *ptr;
-+
-+ for (ptr = (struct errata_checkfunc_id *)__alt_checkfunc_table;
-+ ptr < (struct errata_checkfunc_id *)__alt_checkfunc_table_end;
-+ ptr++) {
-+ if (cpu_manufactor_info.vendorid == ptr->vendorid)
-+ errata_checkfunc = ptr->func;
-+ }
-+}
-+
-+/*
-+ * This is called very early in the boot process (directly after we run
-+ * a feature detect on the boot CPU). No need to worry about other CPUs
-+ * here.
-+ */
-+void __init apply_boot_alternatives(void)
-+{
-+ struct alt_region region;
-+
-+ init_alternatvie();
-+ /* If called on non-boot cpu things could go wrong */
-+ WARN_ON(smp_processor_id() != 0);
-+
-+ region.begin = (struct alt_entry *)__alt_insn;
-+ region.end = (struct alt_entry *)__alt_insn_end;
-+ __apply_alternatives(®ion, patch_text_nosync);
-+
-+ region.begin = (struct alt_entry *)__alt_data;
-+ region.end = (struct alt_entry *)__alt_data_end;
-+ __apply_alternatives(®ion, copy_to_kernel_nofault);
-+}
-+
-diff --git a/arch/riscv/include/asm/alternative-macros.h b/arch/riscv/include/asm/alternative-macros.h
-new file mode 100644
-index 00000000..dd06ded
---- /dev/null
-+++ b/arch/riscv/include/asm/alternative-macros.h
-@@ -0,0 +1,133 @@
-+/* SPDX-License-Identifier: GPL-2.0 */
-+#ifndef __ASM_ALTERNATIVE_MACROS_H
-+#define __ASM_ALTERNATIVE_MACROS_H
-+
-+#ifndef __ASSEMBLY__
-+
-+#include <asm/asm.h>
-+#include <linux/stringify.h>
-+
-+#define ALT_ENTRY(oldptr, altptr, vendorid, archid, impid, oldlen, altlen) \
-+ RISCV_PTR " " oldptr "\n" \
-+ RISCV_PTR " " altptr "\n" \
-+ REG_ASM " " vendorid "\n" \
-+ REG_ASM " " archid "\ n" \
-+ REG_ASM " " impid "\n" \
-+ ".word " oldlen "\n" \
-+ ".word " altlen "\n" \
-+
-+#define __ALTINSN_CFG(oldinsn, altinsn, vendorid, archid, impid, enable) \
-+ ".if " __stringify(enable) " == 1\n" \
-+ "886 :\n\t" \
-+ oldinsn "\n" \
-+ "887 :\n" \
-+ ".pushsection .altinsn, \"a\"\n" \
-+ ALT_ENTRY("886b", "888f", vendorid, archid, impid, "887b - 886b", "889f - 888f") \
-+ ".popsection\n" \
-+ ".subsection 1\n" \
-+ "888 :\n\t" \
-+ altinsn "\n" \
-+ "889 :\n\t" \
-+ ".previous\n" \
-+ ".org . - (887b - 886b) + (889b - 888b)\n\t" \
-+ ".org . - (889b - 888b) + (887b - 886b)\n\t" \
-+ ".endif\n"
-+
-+#define _ALTINSN_CFG(oldinsn, altinsn, vendorid, archid, impid, CONFIG_k, ...) \
-+ __ALTINSN_CFG(oldinsn, altinsn, vendorid, archid, impid, IS_ENABLED(CONFIG_k))
-+
-+#define __ALTDATA_CFG(oldptr, altptr, vendorid, archid, impid, oldlen, altlen, enable) \
-+ ".if " __stringify(enable) " == 1\n" \
-+ ".pushsection .altdata, \"a\"\n" \
-+ ALT_ENTRY(oldptr, altptr, vendorid, archid, impid, oldlen, altlen) \
-+ ".popsection\n" \
-+ ".previous\n" \
-+ ".endif\n"
-+
-+#define _ALTDATA_CFG(oldptr, altptr, vendorid, archid, impid, oldlen, altlen, CONFIG_k, ...) \
-+ __ALTDATA_CFG(oldptr, altptr, vendorid, archid, impid, oldlen, altlen, IS_ENABLED(CONFIG_k))
-+
-+#else
-+.macro ALT_ENTRY oldptr altptr vendorid archid impid oldlen alt_len
-+ RISCV_PTR \oldptr
-+ RISCV_PTR \altptr
-+ REG_ASM \vendorid
-+ REG_ASM \archid
-+ REG_ASM \impid
-+ .word \oldlen
-+ .word \alt_len
-+.endm
-+
-+.macro __ALTINSN_CFG insn1 insn2 vendorid archid impid enable = 1
-+ .if \enable
-+886 :
-+ \insn1
-+887 :
-+ .pushsection .altinsn, "a"
-+ ALT_ENTRY 886b, 888f, \vendorid, \archid, \impid, 887b - 886b, 889f - 888f
-+ .popsection
-+ .subsection 1
-+888 :
-+ \insn2
-+889 :
-+ .previous
-+ .org . - (889b - 888b) + (887b - 886b)
-+ .org . - (887b - 886b) + (889b - 888b)
-+ .endif
-+.endm
-+
-+#define _ALTINSN_CFG(oldinsn, altinsn, vendorid, archid, impid, CONFIG_k, ...) \
-+ __ALTINSN_CFG oldinsn, altinsn, vendorid, archid, impid, IS_ENABLED(CONFIG_k)
-+
-+.macro __ALTDATA_CFG oldptr altptr vendorid archid impid oldlen altlen enable = 1
-+ .if \enable
-+ .pushsection .altdata, "a"
-+ ALT_ENTRY \oldptr \altptr \vendorid \archid \impid \oldlen \altlen
-+ .popsection
-+ .org . - \oldlen + \altlen
-+ .org . - \altlen + \oldlen
-+ .endif
-+.endm
-+
-+#define _ALTDATA_CFG(oldptr, altptr, vendorid, archid, impid, oldlen, altlen, CONFIG_k, ...) \
-+ __ALTDATA_CFG oldptr, altptr, vendorid, archid, impid, oldlen, altlen, IS_ENABLED(CONFIG_k)
-+
-+#endif
-+
-+/*
-+ * Usage: asm(ALTINSN(oldinsn, altinsn, vendorid, archid, impid));
-+ *
-+ * Usage: asm(ALTERNATIVE(oldinsn, altinsn, vendorid, archid, impid, CONFIG_FOO));
-+ *
-+ * oldinsn: The old instruction which will be replaced.
-+ * altinsn: The replacement instruction.
-+ * vendorid: The CPU vendor ID.
-+ * archid: The CPU architecture ID.
-+ * impid: The CPU implement ID.
-+ *
-+ * N.B. If CONFIG_FOO is specified, but not selected, the whole block
-+ * will be omitted, including oldinstr.
-+ */
-+#define ALTINSN(oldinsn, altinsn, ...) \
-+ _ALTINSN_CFG(oldinsn, altinsn, __VA_ARGS__, 1)
-+
-+/*
-+ * Usage: asm(ALTDATA(oldptr, altptr, vendorid, archid, impid, oldlen, altlen));
-+ *
-+ * Usage: asm(ALTERNATIVE(oldptr, altptr, feature, CONFIG_FOO));
-+ *
-+ * oldptr: The address of old data.
-+ * altinsn: The address of replacement data.
-+ * vendorid: The CPU vendor ID.
-+ * archid: The CPU architecture ID.
-+ * impid: The CPU implement ID.
-+ * oldlen: The data length of old data.
-+ * newlen: The data length of new data.
-+ *
-+ * N.B. If CONFIG_FOO is specified, but not selected, the whole block
-+ * will be omitted.
-+ */
-+
-+#define ALTDATA(oldptr, altptr, ...) \
-+ _ALTDATA_CFG(oldptr, altptr, __VA_ARGS__, 1)
-+#endif
-diff --git a/arch/riscv/include/asm/alternative.h b/arch/riscv/include/asm/alternative.h
-new file mode 100644
-index 00000000..fc1d929
---- /dev/null
-+++ b/arch/riscv/include/asm/alternative.h
-@@ -0,0 +1,43 @@
-+/* SPDX-License-Identifier: GPL-2.0-only */
-+/*
-+ * Copyright (C) 2021 Sifive.
-+ */
-+
-+#ifndef __ASM_ALTERNATIVE_H
-+#define __ASM_ALTERNATIVE_H
-+
-+#include <asm/alternative-macros.h>
-+#ifndef __ASSEMBLY__
-+
-+#include <linux/init.h>
-+#include <linux/types.h>
-+#include <linux/stddef.h>
-+#include <asm/hwcap.h>
-+
-+void __init apply_boot_alternatives(void);
-+
-+struct alt_entry {
-+ void *old_ptr; /* address of original instruciton or data */
-+ void *alt_ptr; /* address of replacement instruction or data */
-+ unsigned long vendorid; /* cpu vendor id */
-+ unsigned long archid; /* cpu architecture id */
-+ unsigned long impid; /* cpu implement id */
-+ unsigned int old_len; /* size of original instruction(s) or data(s) */
-+ unsigned int alt_len; /* size of new instruction(s) or data(s) */
-+};
-+
-+struct errata_checkfunc_id {
-+ unsigned long vendorid;
-+ bool (*func)(struct alt_entry *alt);
-+};
-+
-+extern struct cpu_manufactor_info_t cpu_manufactor_info;
-+
-+#define REGISTER_ERRATA_CHECKFUNC(checkfunc, vendor_id) \
-+ static const struct errata_checkfunc_id _errata_check_##vendor_id \
-+ __used __section(".alt_checkfunc_table") \
-+ __aligned(__alignof__(struct errata_checkfunc_id)) = \
-+ { .vendorid = vendor_id, \
-+ .func = checkfunc }
-+#endif
-+#endif
-diff --git a/arch/riscv/include/asm/asm.h b/arch/riscv/include/asm/asm.h
-index 9c992a8..618d7c5 100644
---- a/arch/riscv/include/asm/asm.h
-+++ b/arch/riscv/include/asm/asm.h
-@@ -23,6 +23,7 @@
- #define REG_L __REG_SEL(ld, lw)
- #define REG_S __REG_SEL(sd, sw)
- #define REG_SC __REG_SEL(sc.d, sc.w)
-+#define REG_ASM __REG_SEL(.dword, .word)
- #define SZREG __REG_SEL(8, 4)
- #define LGREG __REG_SEL(3, 2)
-
-diff --git a/arch/riscv/include/asm/sections.h b/arch/riscv/include/asm/sections.h
-index 3a9971b..2ee8e12 100644
---- a/arch/riscv/include/asm/sections.h
-+++ b/arch/riscv/include/asm/sections.h
-@@ -9,5 +9,8 @@
-
- extern char _start[];
- extern char _start_kernel[];
-+extern char __alt_checkfunc_table[], __alt_checkfunc_table_end[];
-+extern char __alt_data[], __alt_data_end[];
-+extern char __alt_insn[], __alt_insn_end[];
-
- #endif /* __ASM_SECTIONS_H */
-diff --git a/arch/riscv/kernel/smpboot.c b/arch/riscv/kernel/smpboot.c
-index 96167d5..7177ee2 100644
---- a/arch/riscv/kernel/smpboot.c
-+++ b/arch/riscv/kernel/smpboot.c
-@@ -31,6 +31,7 @@
- #include <asm/sections.h>
- #include <asm/sbi.h>
- #include <asm/smp.h>
-+#include <asm/alternative.h>
-
- #include "head.h"
-
-@@ -39,6 +40,9 @@ static DECLARE_COMPLETION(cpu_running);
- void __init smp_prepare_boot_cpu(void)
- {
- init_cpu_topology();
-+#ifdef CONFIG_RISCV_ERRATA
-+ apply_boot_alternatives();
-+#endif
- }
-
- void __init smp_prepare_cpus(unsigned int max_cpus)
-diff --git a/arch/riscv/kernel/vmlinux.lds.S b/arch/riscv/kernel/vmlinux.lds.S
-index 3ffbd6c..9df933c 100644
---- a/arch/riscv/kernel/vmlinux.lds.S
-+++ b/arch/riscv/kernel/vmlinux.lds.S
-@@ -77,6 +77,27 @@ SECTIONS
-
- INIT_DATA_SECTION(16)
-
-+ . = ALIGN(8);
-+ .alt_checkfunc_table : {
-+ __alt_checkfunc_table = .;
-+ *(.alt_checkfunc_table)
-+ __alt_checkfunc_table_end = .;
-+ }
-+
-+ . = ALIGN(8);
-+ .altinsn : {
-+ __alt_insn = .;
-+ *(.altinsn)
-+ __alt_insn_end = .;
-+ }
-+
-+ . = ALIGN(8);
-+ .altdata : {
-+ __alt_data = .;
-+ *(.altdata)
-+ __alt_data_end = .;
-+ }
-+
- /* Start of data section */
- _sdata = .;
- RO_DATA(SECTION_ALIGN)
---
-2.7.4
-
+++ /dev/null
-From fb63756f6b2e49160aaf85789f8ed88135eeea50 Mon Sep 17 00:00:00 2001
-From: Vincent Chen <vincent.chen@sifive.com>
-Date: Tue, 12 Jan 2021 15:29:29 +0800
-Subject: [PATCH 21/29] riscv: sifive: apply errata cip-453 patch
-
-Add sign extension to the $badaddr when the exception type is instruction
-page fault or instruciton access fault to workaround the errata cip-453.
-
-To avoid affecting the existing code sequence, this patch creates a
-trampoline to add sign extension to the $baddaddr, and then replaces
-the original exception handlers with this trampoline by ALTDATA. In this
-case, only the specific sifive CPU jumps to the do_page_fault through
-this trampoline. Other CPUs are not affected.
-
-Signed-off-by: Vincent Chen <vincent.chen@sifive.com>
----
- arch/riscv/errata/Makefile | 1 +
- arch/riscv/errata/sifive/Makefile | 2 +
- arch/riscv/errata/sifive/altern_ops.c | 20 ++++++++++
- arch/riscv/errata/sifive/errata.h | 6 +++
- arch/riscv/errata/sifive/errata_cip_453.S | 64 +++++++++++++++++++++++++++++++
- 5 files changed, 93 insertions(+)
- create mode 100644 arch/riscv/errata/sifive/Makefile
- create mode 100644 arch/riscv/errata/sifive/altern_ops.c
- create mode 100644 arch/riscv/errata/sifive/errata.h
- create mode 100644 arch/riscv/errata/sifive/errata_cip_453.S
-
-diff --git a/arch/riscv/errata/Makefile b/arch/riscv/errata/Makefile
-index 43e6d54..be93ded 100644
---- a/arch/riscv/errata/Makefile
-+++ b/arch/riscv/errata/Makefile
-@@ -1 +1,2 @@
- obj-y += alternative.o
-+obj-$(CONFIG_SOC_SIFIVE) += sifive/
-diff --git a/arch/riscv/errata/sifive/Makefile b/arch/riscv/errata/sifive/Makefile
-new file mode 100644
-index 00000000..b7f4cd7
---- /dev/null
-+++ b/arch/riscv/errata/sifive/Makefile
-@@ -0,0 +1,2 @@
-+obj-y += altern_ops.o
-+obj-y += errata_cip_453.o
-diff --git a/arch/riscv/errata/sifive/altern_ops.c b/arch/riscv/errata/sifive/altern_ops.c
-new file mode 100644
-index 00000000..0dcec17
---- /dev/null
-+++ b/arch/riscv/errata/sifive/altern_ops.c
-@@ -0,0 +1,20 @@
-+// SPDX-License-Identifier: GPL-2.0-only
-+/*
-+ * Copyright (C) 2021 Sifive.
-+ */
-+
-+#include <asm/alternative.h>
-+#include <linux/kernel.h>
-+
-+#include "errata.h"
-+
-+static bool __init sifive_errata_check(struct alt_entry *alt)
-+{
-+ if (cpu_manufactor_info.vendorid == alt->vendorid &&
-+ cpu_manufactor_info.archid == alt->archid &&
-+ cpu_manufactor_info.impid == alt->impid)
-+ return true;
-+ return false;
-+}
-+
-+REGISTER_ERRATA_CHECKFUNC(sifive_errata_check, SIFIVE_VENDOR_ID);
-diff --git a/arch/riscv/errata/sifive/errata.h b/arch/riscv/errata/sifive/errata.h
-new file mode 100644
-index 00000000..1f3be47
---- /dev/null
-+++ b/arch/riscv/errata/sifive/errata.h
-@@ -0,0 +1,6 @@
-+/* SPDX-License-Identifier: GPL-2.0-only */
-+/*
-+ * Copyright (C) 2021 SiFive
-+ */
-+
-+#define SIFIVE_VENDOR_ID 0x489
-diff --git a/arch/riscv/errata/sifive/errata_cip_453.S b/arch/riscv/errata/sifive/errata_cip_453.S
-new file mode 100644
-index 00000000..c1ea974
---- /dev/null
-+++ b/arch/riscv/errata/sifive/errata_cip_453.S
-@@ -0,0 +1,64 @@
-+/* SPDX-License-Identifier: GPL-2.0-only */
-+/*
-+ * Copyright (C) 2021 SiFive
-+ */
-+
-+#include <linux/linkage.h>
-+#include <asm/asm.h>
-+#include <asm/asm-offsets.h>
-+#include <asm/alternative.h>
-+#include "errata.h"
-+
-+#define INSN_PAGE_FAULT excp_vect_table + 12 << RISCV_LGPTR
-+#define INSN_ACCESS_FAULT excp_vect_table + 1 << RISCV_LGPTR
-+#define P_TRAMPOLINE sifive_ipage_fault_trampoline
-+#define A_TRAMPOLINE sifive_iaccess_fault_trampoline
-+#define MARCHID 0x8000000000000007
-+#define MIMPID 0x20181004
-+#define LEN 1 << RISCV_LGPTR
-+
-+.macro ADD_SIGN_EXT pt_reg badaddr tmp_reg
-+ REG_L \badaddr, PT_BADADDR(\pt_reg)
-+ li \tmp_reg,1
-+ slli \tmp_reg,\tmp_reg,0x26
-+ and \tmp_reg,\tmp_reg,\badaddr
-+ beqz \tmp_reg, 1f
-+ li \tmp_reg,-1
-+ slli \tmp_reg,\tmp_reg,0x27
-+ or \badaddr,\tmp_reg,\badaddr
-+ REG_S \badaddr, PT_BADADDR(\pt_reg)
-+1:
-+.endm
-+
-+
-+.globl sifive_ipage_fault_trampoline
-+.type sifive_ipage_fault_trampoline, @object
-+.size sifive_ipage_fault_trampoline, 8
-+sifive_ipage_fault_trampoline:
-+.dword do_page_fault_trampoline
-+
-+ENTRY(do_page_fault_trampoline)
-+ ADD_SIGN_EXT a0, t0, t1
-+ la t0, do_page_fault
-+ jr t0
-+END(do_page_fault_trampoline)
-+
-+.globl sifive_iaccess_fault_trampoline
-+.type sifive_iaccess_fault_trampoline, @object
-+.size sifive_iaccess_fault_trampoline, 8
-+sifive_iaccess_fault_trampoline:
-+.dword do_trap_insn_fault_trampoline
-+
-+ENTRY(do_trap_insn_fault_trampoline)
-+ ADD_SIGN_EXT a0, t0, t1
-+ la t0, do_trap_insn_fault
-+ jr t0
-+END(do_trap_insn_fault_trampoline)
-+
-+/*
-+ * Replace the page fault exception handler with sifive_page_fault_trampoline
-+ * function
-+ */
-+ALTDATA(INSN_PAGE_FAULT, P_TRAMPOLINE, SIFIVE_VENDOR_ID, MARCHID, MIMPID, LEN, LEN)
-+ALTDATA(INSN_ACCESS_FAULT, A_TRAMPOLINE, SIFIVE_VENDOR_ID, MARCHID, MIMPID, LEN, LEN)
-+
---
-2.7.4
-
+++ /dev/null
-From 8a0380c3eee96adf57daf2f54fec5089c4dee576 Mon Sep 17 00:00:00 2001
-From: David Abdurachmanov <david.abdurachmanov@sifive.com>
-Date: Wed, 3 Feb 2021 07:00:15 -0800
-Subject: [PATCH 22/29] riscv: dts: fu740: fix cache-controller interrupts
-
-The order of interrupt numbers is incorrect.
-
-The order for FU740 is: DirError, DataError, DataFail, DirFail
-
-From SiFive FU740-C000 Manual:
-19 - L2 Cache DirError
-20 - L2 Cache DirFail
-21 - L2 Cache DataError
-22 - L2 Cache DataFail
-
-Signed-off-by: David Abdurachmanov <david.abdurachmanov@sifive.com>
----
- arch/riscv/boot/dts/sifive/fu740-c000.dtsi | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/arch/riscv/boot/dts/sifive/fu740-c000.dtsi b/arch/riscv/boot/dts/sifive/fu740-c000.dtsi
-index eeb4f8c3..d0d206c 100644
---- a/arch/riscv/boot/dts/sifive/fu740-c000.dtsi
-+++ b/arch/riscv/boot/dts/sifive/fu740-c000.dtsi
-@@ -272,7 +272,7 @@
- cache-size = <2097152>;
- cache-unified;
- interrupt-parent = <&plic0>;
-- interrupts = <19 20 21 22>;
-+ interrupts = <19 21 22 20>;
- reg = <0x0 0x2010000 0x0 0x1000>;
- };
- gpio: gpio@10060000 {
---
-2.7.4
-
+++ /dev/null
-From 58231edb72ab61199226250483038159b2c56c65 Mon Sep 17 00:00:00 2001
-From: David Abdurachmanov <david.abdurachmanov@sifive.com>
-Date: Wed, 17 Feb 2021 06:06:14 -0800
-Subject: [PATCH 23/29] riscv: sifive: fu740: cpu{1,2,3,4} set compatible to
- sifive,u74-mc
-
-Signed-off-by: David Abdurachmanov <david.abdurachmanov@sifive.com>
----
- arch/riscv/boot/dts/sifive/fu740-c000.dtsi | 8 ++++----
- 1 file changed, 4 insertions(+), 4 deletions(-)
-
-diff --git a/arch/riscv/boot/dts/sifive/fu740-c000.dtsi b/arch/riscv/boot/dts/sifive/fu740-c000.dtsi
-index d0d206c..cd9cc02 100644
---- a/arch/riscv/boot/dts/sifive/fu740-c000.dtsi
-+++ b/arch/riscv/boot/dts/sifive/fu740-c000.dtsi
-@@ -39,7 +39,7 @@
- };
- };
- cpu1: cpu@1 {
-- compatible = "sifive,bullet0", "riscv";
-+ compatible = "sifive,u74-mc", "sifive,bullet0", "riscv";
- d-cache-block-size = <64>;
- d-cache-sets = <64>;
- d-cache-size = <32768>;
-@@ -63,7 +63,7 @@
- };
- };
- cpu2: cpu@2 {
-- compatible = "sifive,bullet0", "riscv";
-+ compatible = "sifive,u74-mc", "sifive,bullet0", "riscv";
- d-cache-block-size = <64>;
- d-cache-sets = <64>;
- d-cache-size = <32768>;
-@@ -87,7 +87,7 @@
- };
- };
- cpu3: cpu@3 {
-- compatible = "sifive,bullet0", "riscv";
-+ compatible = "sifive,u74-mc", "sifive,bullet0", "riscv";
- d-cache-block-size = <64>;
- d-cache-sets = <64>;
- d-cache-size = <32768>;
-@@ -111,7 +111,7 @@
- };
- };
- cpu4: cpu@4 {
-- compatible = "sifive,bullet0", "riscv";
-+ compatible = "sifive,u74-mc", "sifive,bullet0", "riscv";
- d-cache-block-size = <64>;
- d-cache-sets = <64>;
- d-cache-size = <32768>;
---
-2.7.4
-
+++ /dev/null
-From 34222949288ef8b2666facee9ca9001c8cd93486 Mon Sep 17 00:00:00 2001
-From: Greentime Hu <greentime.hu@sifive.com>
-Date: Wed, 3 Feb 2021 11:22:10 +0800
-Subject: [PATCH 24/29] riscv: dts: Add PCIe support for the SiFive FU740-C000
- SoC
-
-Signed-off-by: Greentime Hu <greentime.hu@sifive.com>
----
- arch/riscv/boot/dts/sifive/fu740-c000.dtsi | 35 ++++++++++++++++++++++++++++++
- 1 file changed, 35 insertions(+)
-
-diff --git a/arch/riscv/boot/dts/sifive/fu740-c000.dtsi b/arch/riscv/boot/dts/sifive/fu740-c000.dtsi
-index cd9cc02..727fd91 100644
---- a/arch/riscv/boot/dts/sifive/fu740-c000.dtsi
-+++ b/arch/riscv/boot/dts/sifive/fu740-c000.dtsi
-@@ -159,6 +159,7 @@
- reg = <0x0 0x10000000 0x0 0x1000>;
- clocks = <&hfclk>, <&rtcclk>;
- #clock-cells = <1>;
-+ #reset-cells = <1>;
- };
- uart0: serial@10010000 {
- compatible = "sifive,fu740-c000-uart", "sifive,uart0";
-@@ -289,5 +290,39 @@
- clocks = <&prci PRCI_CLK_PCLK>;
- status = "disabled";
- };
-+ pcie@e00000000 {
-+ #address-cells = <3>;
-+ #interrupt-cells = <1>;
-+ #num-lanes = <8>;
-+ #size-cells = <2>;
-+ compatible = "sifive,fu740-pcie";
-+ reg = <0xe 0x00000000 0x1 0x0
-+ 0xd 0xf0000000 0x0 0x10000000
-+ 0x0 0x100d0000 0x0 0x1000>;
-+ reg-names = "dbi", "config", "mgmt";
-+ device_type = "pci";
-+ dma-coherent;
-+ bus-range = <0x0 0xff>;
-+ ranges = <0x81000000 0x0 0x60080000 0x0 0x60080000 0x0 0x10000 /* I/O */
-+ 0x82000000 0x0 0x60090000 0x0 0x60090000 0x0 0xff70000 /* mem */
-+ 0x82000000 0x0 0x70000000 0x0 0x70000000 0x0 0x1000000 /* mem */
-+ 0xc3000000 0x20 0x00000000 0x20 0x00000000 0x20 0x00000000>; /* mem prefetchable */
-+ num-lanes = <0x8>;
-+ msi-parent = <&plic0>;
-+ interrupts = <56 57 58 59 60 61 62 63 64>;
-+ interrupt-names = "msi", "inta", "intb", "intc", "intd";
-+ interrupt-parent = <&plic0>;
-+ interrupt-map-mask = <0x0 0x0 0x0 0x7>;
-+ interrupt-map = <0x0 0x0 0x0 0x1 &plic0 57>,
-+ <0x0 0x0 0x0 0x2 &plic0 58>,
-+ <0x0 0x0 0x0 0x3 &plic0 59>,
-+ <0x0 0x0 0x0 0x4 &plic0 60>;
-+ clock-names = "pcie_aux";
-+ clocks = <&prci PRCI_CLK_PCIE_AUX>;
-+ pwren-gpios = <&gpio 5 0>;
-+ perstn-gpios = <&gpio 8 0>;
-+ resets = <&prci 4>;
-+ status = "okay";
-+ };
- };
- };
---
-2.7.4
-
+++ /dev/null
-From 90591acb975baa3bedc7178e04bc92daaca3740f Mon Sep 17 00:00:00 2001
-From: Greentime Hu <greentime.hu@sifive.com>
-Date: Wed, 3 Feb 2021 11:00:32 +0800
-Subject: [PATCH 25/29] clk: sifive: Add pcie_aux clock in prci driver for PCIe
- driver
-
-We add pcie_aux clock in this patch so that pcie driver can use
-clk_prepare_enable() and clk_disable_unprepare() to enable and disable
-pcie_aux clock.
-
-Signed-off-by: Greentime Hu <greentime.hu@sifive.com>
----
- drivers/clk/sifive/fu740-prci.c | 11 +++++++
- drivers/clk/sifive/fu740-prci.h | 2 +-
- drivers/clk/sifive/sifive-prci.c | 41 +++++++++++++++++++++++++++
- drivers/clk/sifive/sifive-prci.h | 9 ++++++
- include/dt-bindings/clock/sifive-fu740-prci.h | 1 +
- 5 files changed, 63 insertions(+), 1 deletion(-)
-
-diff --git a/drivers/clk/sifive/fu740-prci.c b/drivers/clk/sifive/fu740-prci.c
-index db83002..76cbfb1 100644
---- a/drivers/clk/sifive/fu740-prci.c
-+++ b/drivers/clk/sifive/fu740-prci.c
-@@ -69,6 +69,12 @@ static const struct clk_ops sifive_fu740_prci_hfpclkplldiv_clk_ops = {
- .recalc_rate = sifive_prci_hfpclkplldiv_recalc_rate,
- };
-
-+static const struct clk_ops sifive_fu740_prci_pcie_aux_clk_ops = {
-+ .enable = sifive_prci_pcie_aux_clock_enable,
-+ .disable = sifive_prci_pcie_aux_clock_disable,
-+ .is_enabled = sifive_prci_pcie_aux_clock_is_enabled,
-+};
-+
- /* List of clock controls provided by the PRCI */
- struct __prci_clock __prci_init_clocks_fu740[] = {
- [PRCI_CLK_COREPLL] = {
-@@ -117,4 +123,9 @@ struct __prci_clock __prci_init_clocks_fu740[] = {
- .parent_name = "hfpclkpll",
- .ops = &sifive_fu740_prci_hfpclkplldiv_clk_ops,
- },
-+ [PRCI_CLK_PCIE_AUX] = {
-+ .name = "pcie_aux",
-+ .parent_name = "hfclk",
-+ .ops = &sifive_fu740_prci_pcie_aux_clk_ops,
-+ },
- };
-diff --git a/drivers/clk/sifive/fu740-prci.h b/drivers/clk/sifive/fu740-prci.h
-index 13ef971f7..511a0bf 100644
---- a/drivers/clk/sifive/fu740-prci.h
-+++ b/drivers/clk/sifive/fu740-prci.h
-@@ -9,7 +9,7 @@
-
- #include "sifive-prci.h"
-
--#define NUM_CLOCK_FU740 8
-+#define NUM_CLOCK_FU740 9
-
- extern struct __prci_clock __prci_init_clocks_fu740[NUM_CLOCK_FU740];
-
-diff --git a/drivers/clk/sifive/sifive-prci.c b/drivers/clk/sifive/sifive-prci.c
-index c78b042..baf7313 100644
---- a/drivers/clk/sifive/sifive-prci.c
-+++ b/drivers/clk/sifive/sifive-prci.c
-@@ -448,6 +448,47 @@ void sifive_prci_hfpclkpllsel_use_hfpclkpll(struct __prci_data *pd)
- r = __prci_readl(pd, PRCI_HFPCLKPLLSEL_OFFSET); /* barrier */
- }
-
-+/* PCIE AUX clock APIs for enable, disable. */
-+int sifive_prci_pcie_aux_clock_is_enabled(struct clk_hw *hw)
-+{
-+ struct __prci_clock *pc = clk_hw_to_prci_clock(hw);
-+ struct __prci_data *pd = pc->pd;
-+ u32 r;
-+
-+ r = __prci_readl(pd, PRCI_PCIE_AUX_OFFSET);
-+
-+ if (r & PRCI_PCIE_AUX_EN_MASK)
-+ return 1;
-+ else
-+ return 0;
-+}
-+
-+int sifive_prci_pcie_aux_clock_enable(struct clk_hw *hw)
-+{
-+ struct __prci_clock *pc = clk_hw_to_prci_clock(hw);
-+ struct __prci_data *pd = pc->pd;
-+ u32 r;
-+
-+ if (sifive_prci_pcie_aux_clock_is_enabled(hw))
-+ return 0;
-+
-+ __prci_writel(1, PRCI_PCIE_AUX_OFFSET, pd);
-+ r = __prci_readl(pd, PRCI_PCIE_AUX_OFFSET); /* barrier */
-+
-+ return 0;
-+}
-+
-+void sifive_prci_pcie_aux_clock_disable(struct clk_hw *hw)
-+{
-+ struct __prci_clock *pc = clk_hw_to_prci_clock(hw);
-+ struct __prci_data *pd = pc->pd;
-+ u32 r;
-+
-+ __prci_writel(0, PRCI_PCIE_AUX_OFFSET, pd);
-+ r = __prci_readl(pd, PRCI_PCIE_AUX_OFFSET); /* barrier */
-+
-+}
-+
- /**
- * __prci_register_clocks() - register clock controls in the PRCI
- * @dev: Linux struct device
-diff --git a/drivers/clk/sifive/sifive-prci.h b/drivers/clk/sifive/sifive-prci.h
-index dbdbd17..022c67c 100644
---- a/drivers/clk/sifive/sifive-prci.h
-+++ b/drivers/clk/sifive/sifive-prci.h
-@@ -67,6 +67,11 @@
- #define PRCI_DDRPLLCFG1_CKE_SHIFT 31
- #define PRCI_DDRPLLCFG1_CKE_MASK (0x1 << PRCI_DDRPLLCFG1_CKE_SHIFT)
-
-+/* PCIEAUX */
-+#define PRCI_PCIE_AUX_OFFSET 0x14
-+#define PRCI_PCIE_AUX_EN_SHIFT 0
-+#define PRCI_PCIE_AUX_EN_MASK (0x1 << PRCI_PCIE_AUX_EN_SHIFT)
-+
- /* GEMGXLPLLCFG0 */
- #define PRCI_GEMGXLPLLCFG0_OFFSET 0x1c
- #define PRCI_GEMGXLPLLCFG0_DIVR_SHIFT 0
-@@ -296,4 +301,8 @@ unsigned long sifive_prci_tlclksel_recalc_rate(struct clk_hw *hw,
- unsigned long sifive_prci_hfpclkplldiv_recalc_rate(struct clk_hw *hw,
- unsigned long parent_rate);
-
-+int sifive_prci_pcie_aux_clock_is_enabled(struct clk_hw *hw);
-+int sifive_prci_pcie_aux_clock_enable(struct clk_hw *hw);
-+void sifive_prci_pcie_aux_clock_disable(struct clk_hw *hw);
-+
- #endif /* __SIFIVE_CLK_SIFIVE_PRCI_H */
-diff --git a/include/dt-bindings/clock/sifive-fu740-prci.h b/include/dt-bindings/clock/sifive-fu740-prci.h
-index cd7706e..7899b7f 100644
---- a/include/dt-bindings/clock/sifive-fu740-prci.h
-+++ b/include/dt-bindings/clock/sifive-fu740-prci.h
-@@ -19,5 +19,6 @@
- #define PRCI_CLK_CLTXPLL 5
- #define PRCI_CLK_TLCLK 6
- #define PRCI_CLK_PCLK 7
-+#define PRCI_CLK_PCIE_AUX 8
-
- #endif /* __DT_BINDINGS_CLOCK_SIFIVE_FU740_PRCI_H */
---
-2.7.4
-
+++ /dev/null
-From a9b30eacb76d59ea18f138e0ad2b66e8a50ef24d Mon Sep 17 00:00:00 2001
-From: Greentime Hu <greentime.hu@sifive.com>
-Date: Wed, 3 Feb 2021 11:07:16 +0800
-Subject: [PATCH 26/29] clk: sifive: Use reset-simple in prci driver for PCIe
- driver
-
-We use reset-simple in this patch so that pcie driver can use
-devm_reset_control_get() to get this reset data structure and use
-reset_control_deassert() to deassert pcie_power_up_rst_n.
-
-Signed-off-by: Greentime Hu <greentime.hu@sifive.com>
----
- drivers/clk/sifive/Kconfig | 2 ++
- drivers/clk/sifive/sifive-prci.c | 14 ++++++++++++++
- drivers/clk/sifive/sifive-prci.h | 4 ++++
- drivers/reset/Kconfig | 3 ++-
- 4 files changed, 22 insertions(+), 1 deletion(-)
-
-diff --git a/drivers/clk/sifive/Kconfig b/drivers/clk/sifive/Kconfig
-index 1c14eb2..9132c3c 100644
---- a/drivers/clk/sifive/Kconfig
-+++ b/drivers/clk/sifive/Kconfig
-@@ -10,6 +10,8 @@ if CLK_SIFIVE
-
- config CLK_SIFIVE_PRCI
- bool "PRCI driver for SiFive SoCs"
-+ select RESET_CONTROLLER
-+ select RESET_SIMPLE
- select CLK_ANALOGBITS_WRPLL_CLN28HPC
- help
- Supports the Power Reset Clock interface (PRCI) IP block found in
-diff --git a/drivers/clk/sifive/sifive-prci.c b/drivers/clk/sifive/sifive-prci.c
-index baf7313..925affc 100644
---- a/drivers/clk/sifive/sifive-prci.c
-+++ b/drivers/clk/sifive/sifive-prci.c
-@@ -583,7 +583,21 @@ static int sifive_prci_probe(struct platform_device *pdev)
- if (IS_ERR(pd->va))
- return PTR_ERR(pd->va);
-
-+ pd->reset.rcdev.owner = THIS_MODULE;
-+ pd->reset.rcdev.nr_resets = PRCI_RST_NR;
-+ pd->reset.rcdev.ops = &reset_simple_ops;
-+ pd->reset.rcdev.of_node = pdev->dev.of_node;
-+ pd->reset.active_low = true;
-+ pd->reset.membase = pd->va + PRCI_DEVICESRESETREG_OFFSET;
-+ spin_lock_init(&pd->reset.lock);
-+
-+ r = devm_reset_controller_register(&pdev->dev, &pd->reset.rcdev);
-+ if (r) {
-+ dev_err(dev, "could not register reset controller: %d\n", r);
-+ return r;
-+ }
- r = __prci_register_clocks(dev, pd, desc);
-+
- if (r) {
- dev_err(dev, "could not register clocks: %d\n", r);
- return r;
-diff --git a/drivers/clk/sifive/sifive-prci.h b/drivers/clk/sifive/sifive-prci.h
-index 022c67c..91658a8 100644
---- a/drivers/clk/sifive/sifive-prci.h
-+++ b/drivers/clk/sifive/sifive-prci.h
-@@ -11,6 +11,7 @@
-
- #include <linux/clk/analogbits-wrpll-cln28hpc.h>
- #include <linux/clk-provider.h>
-+#include <linux/reset/reset-simple.h>
- #include <linux/platform_device.h>
-
- /*
-@@ -121,6 +122,8 @@
- #define PRCI_DEVICESRESETREG_CHIPLINK_RST_N_MASK \
- (0x1 << PRCI_DEVICESRESETREG_CHIPLINK_RST_N_SHIFT)
-
-+#define PRCI_RST_NR 7
-+
- /* CLKMUXSTATUSREG */
- #define PRCI_CLKMUXSTATUSREG_OFFSET 0x2c
- #define PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_SHIFT 1
-@@ -221,6 +224,7 @@
- */
- struct __prci_data {
- void __iomem *va;
-+ struct reset_simple_data reset;
- struct clk_hw_onecell_data hw_clks;
- };
-
-diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
-index 07d162b..124f4dc 100644
---- a/drivers/reset/Kconfig
-+++ b/drivers/reset/Kconfig
-@@ -165,7 +165,7 @@ config RESET_SCMI
-
- config RESET_SIMPLE
- bool "Simple Reset Controller Driver" if COMPILE_TEST
-- default ARCH_AGILEX || ARCH_ASPEED || ARCH_BITMAIN || ARCH_REALTEK || ARCH_STM32 || ARCH_STRATIX10 || ARCH_SUNXI || ARCH_ZX || ARC
-+ default ARCH_AGILEX || ARCH_ASPEED || ARCH_BITMAIN || ARCH_REALTEK || ARCH_STM32 || ARCH_STRATIX10 || ARCH_SUNXI || ARCH_ZX || ARC || RISCV
- help
- This enables a simple reset controller driver for reset lines that
- that can be asserted and deasserted by toggling bits in a contiguous,
-@@ -179,6 +179,7 @@ config RESET_SIMPLE
- - RCC reset controller in STM32 MCUs
- - Allwinner SoCs
- - ZTE's zx2967 family
-+ - SiFive FU740 SoCs
-
- config RESET_STM32MP157
- bool "STM32MP157 Reset Driver" if COMPILE_TEST
---
-2.7.4
-
+++ /dev/null
-From a57464df4cfa31061f665d2bac4222d625ec5ca9 Mon Sep 17 00:00:00 2001
-From: Greentime Hu <greentime.hu@sifive.com>
-Date: Wed, 3 Feb 2021 11:11:57 +0800
-Subject: [PATCH 27/29] MAINTAINERS: Add maintainers for SiFive FU740 PCIe
- driver
-
-Here add maintainer information for SiFive FU740 PCIe driver.
-
-Signed-off-by: Greentime Hu <greentime.hu@sifive.com>
----
- MAINTAINERS | 8 ++++++++
- 1 file changed, 8 insertions(+)
-
-diff --git a/MAINTAINERS b/MAINTAINERS
-index 281de21..5980c85 100644
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -13389,6 +13389,14 @@ S: Maintained
- F: Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt
- F: drivers/pci/controller/dwc/*imx6*
-
-+PCI DRIVER FOR FU740
-+M: Paul Walmsley <paul.walmsley@sifive.com>
-+M: Greentime Hu <greentime.hu@sifive.com>
-+L: linux-pci@vger.kernel.org
-+S: Maintained
-+F: Documentation/devicetree/bindings/pci/sifive,fu740-pcie.yaml
-+F: drivers/pci/controller/dwc/pcie-fu740.c
-+
- PCI DRIVER FOR INTEL VOLUME MANAGEMENT DEVICE (VMD)
- M: Jonathan Derrick <jonathan.derrick@intel.com>
- L: linux-pci@vger.kernel.org
---
-2.7.4
-
+++ /dev/null
-From 38fecc0dae7765bcd4de25863ef3156a18992040 Mon Sep 17 00:00:00 2001
-From: Greentime Hu <greentime.hu@sifive.com>
-Date: Wed, 3 Feb 2021 11:17:35 +0800
-Subject: [PATCH 28/29] dt-bindings: PCI: Add SiFive FU740 PCIe host controller
-
-Add PCIe host controller DT bindings of SiFive FU740.
-
-Signed-off-by: Greentime Hu <greentime.hu@sifive.com>
----
- .../devicetree/bindings/pci/sifive,fu740-pcie.yaml | 121 +++++++++++++++++++++
- 1 file changed, 121 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/pci/sifive,fu740-pcie.yaml
-
-diff --git a/Documentation/devicetree/bindings/pci/sifive,fu740-pcie.yaml b/Documentation/devicetree/bindings/pci/sifive,fu740-pcie.yaml
-new file mode 100644
-index 00000000..bcd1d18
---- /dev/null
-+++ b/Documentation/devicetree/bindings/pci/sifive,fu740-pcie.yaml
-@@ -0,0 +1,121 @@
-+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/pci/sifive,fu740-pcie.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: SiFive fu740 PCIe host controller
-+
-+description: |
-+ SiFive fu740 PCIe host controller is based on the Synopsys DesignWare
-+ PCI core. It shares common features with the PCIe DesignWare core and
-+ inherits common properties defined in
-+ Documentation/devicetree/bindings/pci/designware-pcie.txt.
-+
-+maintainers:
-+ - Paul Walmsley <paul.walmsley@sifive.com>
-+ - Greentime Hu <greentime.hu@sifive.com>
-+
-+allOf:
-+ - $ref: /schemas/pci/pci-bus.yaml#
-+
-+properties:
-+ compatible:
-+ const: sifive,fu740-pcie
-+
-+ reg:
-+ maxItems: 4
-+
-+ reg-names:
-+ items:
-+ - const: dbi
-+ - const: config
-+ - const: mgmt
-+
-+ device_type:
-+ const: pci
-+
-+ dma-coherent:
-+ description: Indicates that the PCIe IP block can ensure the coherency
-+
-+ bus-range:
-+ description: Range of bus numbers associated with this controller.
-+
-+ num-lanes: true
-+
-+ msi-parent: true
-+
-+ interrupt-names:
-+ items:
-+ - const: msi
-+ - const: inta
-+ - const: intb
-+ - const: intc
-+ - const: intd
-+
-+ resets:
-+ description: A phandle to the PCIe power up reset line
-+
-+ pwren-gpios:
-+ description: Should specify the GPIO for controlling the PCI bus device power on
-+
-+ perstn-gpios:
-+ description: Should specify the GPIO for controlling the PCI bus device reset
-+
-+required:
-+ - compatible
-+ - reg
-+ - reg-names
-+ - device_type
-+ - dma-coherent
-+ - bus-range
-+ - ranges
-+ - num-lanes
-+ - msi-parent
-+ - interrupts
-+ - interrupt-names
-+ - interrupt-parent
-+ - interrupt-map-mask
-+ - interrupt-map
-+ - clock-names
-+ - clocks
-+ - resets
-+ - pwren-gpios
-+ - perstn-gpios
-+
-+additionalProperties: false
-+
-+examples:
-+ - |
-+ pcie@e00000000 {
-+ #address-cells = <3>;
-+ #interrupt-cells = <1>;
-+ #size-cells = <2>;
-+ compatible = "sifive,fu740-pcie";
-+ reg = <0xe 0x00000000 0x1 0x0
-+ 0xd 0xf0000000 0x0 0x10000000
-+ 0x0 0x100d0000 0x0 0x1000>;
-+ reg-names = "dbi", "config", "mgmt";
-+ device_type = "pci";
-+ dma-coherent;
-+ bus-range = <0x0 0xff>;
-+ ranges = <0x81000000 0x0 0x60080000 0x0 0x60080000 0x0 0x10000 /* I/O */
-+ 0x82000000 0x0 0x60090000 0x0 0x60090000 0x0 0xff70000 /* mem */
-+ 0x82000000 0x0 0x70000000 0x0 0x70000000 0x0 0x1000000 /* mem */
-+ 0xc3000000 0x20 0x00000000 0x20 0x00000000 0x20 0x00000000>; /* mem prefetchable */
-+ num-lanes = <0x8>;
-+ msi-parent = <&plic0>;
-+ interrupts = <56 57 58 59 60 61 62 63 64>;
-+ interrupt-names = "msi", "inta", "intb", "intc", "intd";
-+ interrupt-parent = <&plic0>;
-+ interrupt-map-mask = <0x0 0x0 0x0 0x7>;
-+ interrupt-map = <0x0 0x0 0x0 0x1 &plic0 57>,
-+ <0x0 0x0 0x0 0x2 &plic0 58>,
-+ <0x0 0x0 0x0 0x3 &plic0 59>,
-+ <0x0 0x0 0x0 0x4 &plic0 60>;
-+ clock-names = "pcie_aux";
-+ clocks = <&prci PRCI_CLK_PCIE_AUX>;
-+ resets = <&prci 4>;
-+ pwren-gpios = <&gpio 5 0>;
-+ perstn-gpios = <&gpio 8 0>;
-+ };
---
-2.7.4
-
+++ /dev/null
-From 6da0f49824ae1fca4d0bf1ce433c870cf1b424ea Mon Sep 17 00:00:00 2001
-From: Paul Walmsley <paul.walmsley@sifive.com>
-Date: Wed, 3 Feb 2021 11:19:08 +0800
-Subject: [PATCH 29/29] PCI: designware: Add SiFive FU740 PCIe host controller
- driver
-
-Add driver for the SiFive FU740 PCIe host controller.
-This controller is based on the DesignWare PCIe core.
-
-Co-developed-by: Henry Styles <hes@sifive.com>
-Signed-off-by: Henry Styles <hes@sifive.com>
-Co-developed-by: Erik Danie <erik.danie@sifive.com>
-Signed-off-by: Erik Danie <erik.danie@sifive.com>
-Co-developed-by: Greentime Hu <greentime.hu@sifive.com>
-Signed-off-by: Greentime Hu <greentime.hu@sifive.com>
-Signed-off-by: Paul Walmsley <paul.walmsley@sifive.com>
----
- drivers/pci/controller/dwc/Kconfig | 9 +
- drivers/pci/controller/dwc/Makefile | 1 +
- drivers/pci/controller/dwc/pcie-fu740.c | 552 ++++++++++++++++++++++++++++++++
- 3 files changed, 562 insertions(+)
- create mode 100644 drivers/pci/controller/dwc/pcie-fu740.c
-
-diff --git a/drivers/pci/controller/dwc/Kconfig b/drivers/pci/controller/dwc/Kconfig
-index bc04986..ee13834 100644
---- a/drivers/pci/controller/dwc/Kconfig
-+++ b/drivers/pci/controller/dwc/Kconfig
-@@ -312,4 +312,13 @@ config PCIE_AL
- required only for DT-based platforms. ACPI platforms with the
- Annapurna Labs PCIe controller don't need to enable this.
-
-+config PCIE_FU740
-+ bool "SiFive FU740 PCIe host controller"
-+ depends on PCI_MSI_IRQ_DOMAIN
-+ depends on SOC_SIFIVE || COMPILE_TEST
-+ select PCIE_DW_HOST
-+ help
-+ Say Y here if you want PCIe controller support for the SiFive
-+ FU740.
-+
- endmenu
-diff --git a/drivers/pci/controller/dwc/Makefile b/drivers/pci/controller/dwc/Makefile
-index a751553..625f6aa 100644
---- a/drivers/pci/controller/dwc/Makefile
-+++ b/drivers/pci/controller/dwc/Makefile
-@@ -5,6 +5,7 @@ obj-$(CONFIG_PCIE_DW_EP) += pcie-designware-ep.o
- obj-$(CONFIG_PCIE_DW_PLAT) += pcie-designware-plat.o
- obj-$(CONFIG_PCI_DRA7XX) += pci-dra7xx.o
- obj-$(CONFIG_PCI_EXYNOS) += pci-exynos.o
-+obj-$(CONFIG_PCIE_FU740) += pcie-fu740.o
- obj-$(CONFIG_PCI_IMX6) += pci-imx6.o
- obj-$(CONFIG_PCIE_SPEAR13XX) += pcie-spear13xx.o
- obj-$(CONFIG_PCI_KEYSTONE) += pci-keystone.o
-diff --git a/drivers/pci/controller/dwc/pcie-fu740.c b/drivers/pci/controller/dwc/pcie-fu740.c
-new file mode 100644
-index 00000000..afb0404
---- /dev/null
-+++ b/drivers/pci/controller/dwc/pcie-fu740.c
-@@ -0,0 +1,552 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * FU740 DesignWare PCIe Controller integration
-+ * Copyright (C) 2019-2021 SiFive, Inc.
-+ * Paul Walmsley
-+ * Greentime Hu
-+ *
-+ * Based in part on the i.MX6 PCIe host controller shim which is:
-+ *
-+ * Copyright (C) 2013 Kosagi
-+ * http://www.kosagi.com
-+ */
-+
-+#include <linux/clk.h>
-+#include <linux/delay.h>
-+#include <linux/gpio.h>
-+#include <linux/kernel.h>
-+#include <linux/mfd/syscon.h>
-+#include <linux/module.h>
-+#include <linux/of_gpio.h>
-+#include <linux/of_device.h>
-+#include <linux/pci.h>
-+#include <linux/platform_device.h>
-+#include <linux/regmap.h>
-+#include <linux/regulator/consumer.h>
-+#include <linux/resource.h>
-+#include <linux/signal.h>
-+#include <linux/types.h>
-+#include <linux/interrupt.h>
-+#include <linux/reset.h>
-+#include <linux/pm_domain.h>
-+#include <linux/pm_runtime.h>
-+
-+#include "pcie-designware.h"
-+
-+#define to_fu740_pcie(x) dev_get_drvdata((x)->dev)
-+
-+struct fu740_pcie {
-+ struct dw_pcie *pci;
-+ void __iomem *mgmt_base;
-+ int perstn_gpio;
-+ int pwren_gpio;
-+ struct clk *pcie_aux;
-+ struct reset_control *rst;
-+};
-+
-+#define SIFIVE_DEVICESRESETREG 0x28
-+
-+#define PCIEX8MGMT_PERST_N 0x0
-+#define PCIEX8MGMT_APP_LTSSM_ENABLE 0x10
-+#define PCIEX8MGMT_APP_HOLD_PHY_RST 0x18
-+#define PCIEX8MGMT_DEVICE_TYPE 0x708
-+#define PCIEX8MGMT_PHY0_CR_PARA_ADDR 0x860
-+#define PCIEX8MGMT_PHY0_CR_PARA_RD_EN 0x870
-+#define PCIEX8MGMT_PHY0_CR_PARA_RD_DATA 0x878
-+#define PCIEX8MGMT_PHY0_CR_PARA_SEL 0x880
-+#define PCIEX8MGMT_PHY0_CR_PARA_WR_DATA 0x888
-+#define PCIEX8MGMT_PHY0_CR_PARA_WR_EN 0x890
-+#define PCIEX8MGMT_PHY0_CR_PARA_ACK 0x898
-+#define PCIEX8MGMT_PHY1_CR_PARA_ADDR 0x8a0
-+#define PCIEX8MGMT_PHY1_CR_PARA_RD_EN 0x8b0
-+#define PCIEX8MGMT_PHY1_CR_PARA_RD_DATA 0x8b8
-+#define PCIEX8MGMT_PHY1_CR_PARA_SEL 0x8c0
-+#define PCIEX8MGMT_PHY1_CR_PARA_WR_DATA 0x8c8
-+#define PCIEX8MGMT_PHY1_CR_PARA_WR_EN 0x8d0
-+#define PCIEX8MGMT_PHY1_CR_PARA_ACK 0x8d8
-+
-+/* PCIe Root Complex registers (memory-mapped) */
-+#define PCIE_RC_PF0_MSI_CAP 0x50
-+#define PCI_MSI_CAP_ID_NEXT_CTRL_REG (PCIE_RC_PF0_MSI_CAP + 0x0)
-+
-+#define PCIE_DSP_PF0_PCIE_CAP_BASE 0x70
-+#define PCIE_RC_LCR (PCIE_DSP_PF0_PCIE_CAP_BASE + 0xc)
-+#define PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN1 0x1
-+#define PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN2 0x2
-+#define PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN3 0x3
-+#define PCIE_RC_LCR_MAX_LINK_SPEEDS_MASK 0xf
-+
-+#define PCIE_RC_LCSR (PCIE_DSP_PF0_PCIE_CAP_BASE + 0x10)
-+
-+/* PCIe Port Logic registers (memory-mapped) */
-+#define PL_OFFSET 0x700
-+#define PCIE_PL_PFLR (PL_OFFSET + 0x08)
-+#define PCIE_PL_PFLR_LINK_STATE_MASK (0x3f << 16)
-+#define PCIE_PL_PFLR_FORCE_LINK (1 << 15)
-+#define PCIE_PHY_DEBUG_R0 (PL_OFFSET + 0x28)
-+#define PCIE_PHY_DEBUG_R1 (PL_OFFSET + 0x2c)
-+#define PCIE_PL_GEN2_CTRL_OFF (PL_OFFSET + 0x10c)
-+#define PCIE_PL_DIRECTED_SPEED_CHANGE_OFF 0x20000
-+
-+#define PCIE_PHY_CTRL (PL_OFFSET + 0x114)
-+#define PCIE_PHY_CTRL_DATA_LOC 0
-+#define PCIE_PHY_CTRL_CAP_ADR_LOC 16
-+#define PCIE_PHY_CTRL_CAP_DAT_LOC 17
-+#define PCIE_PHY_CTRL_WR_LOC 18
-+#define PCIE_PHY_CTRL_RD_LOC 19
-+
-+#define PCIE_PHY_STAT (PL_OFFSET + 0x110)
-+#define PCIE_PHY_STAT_ACK_LOC 16
-+
-+#define PCIE_LINK_WIDTH_SPEED_CONTROL 0x80C
-+
-+#define PCIE_PHY_MAX_RETRY_CNT 1000
-+
-+static void fu740_pcie_assert_perstn(struct fu740_pcie *afp)
-+{
-+ /* PERST_N GPIO */
-+ if (gpio_is_valid(afp->perstn_gpio))
-+ gpio_direction_output(afp->perstn_gpio, 0);
-+
-+ /* Controller PERST_N */
-+ __raw_writel(0x0, afp->mgmt_base + PCIEX8MGMT_PERST_N);
-+}
-+
-+static void fu740_pcie_deassert_perstn(struct fu740_pcie *afp)
-+{
-+ /* Controller PERST_N */
-+ __raw_writel(0x1, afp->mgmt_base + PCIEX8MGMT_PERST_N);
-+ /* PERST_N GPIO */
-+ if (gpio_is_valid(afp->perstn_gpio))
-+ gpio_direction_output(afp->perstn_gpio, 1);
-+}
-+
-+static void fu740_pcie_power_on(struct fu740_pcie *afp)
-+{
-+ if (gpio_is_valid(afp->pwren_gpio)) {
-+ gpio_direction_output(afp->pwren_gpio, 1);
-+ mdelay(100);
-+ }
-+}
-+
-+static void fu740_pcie_drive_perstn(struct fu740_pcie *afp)
-+{
-+ fu740_pcie_assert_perstn(afp);
-+ fu740_pcie_power_on(afp);
-+ fu740_pcie_deassert_perstn(afp);
-+}
-+
-+static void fu740_phyregreadwrite(const uint8_t phy, const uint8_t write,
-+ const uint16_t addr,
-+ const uint16_t wrdata, uint16_t *rddata,
-+ struct fu740_pcie *afp)
-+{
-+ unsigned char ack = 0;
-+ unsigned int cnt = 0;
-+ struct device *dev = afp->pci->dev;
-+
-+ /* setup */
-+ __raw_writel(addr,
-+ afp->mgmt_base +
-+ (phy ? PCIEX8MGMT_PHY1_CR_PARA_ADDR :
-+ PCIEX8MGMT_PHY0_CR_PARA_ADDR));
-+ if (write)
-+ __raw_writel(wrdata,
-+ afp->mgmt_base +
-+ (phy ? PCIEX8MGMT_PHY1_CR_PARA_WR_DATA :
-+ PCIEX8MGMT_PHY0_CR_PARA_WR_DATA));
-+ if (write)
-+ __raw_writel(1,
-+ afp->mgmt_base +
-+ (phy ? PCIEX8MGMT_PHY1_CR_PARA_WR_EN :
-+ PCIEX8MGMT_PHY0_CR_PARA_WR_EN));
-+ else
-+ __raw_writel(1,
-+ afp->mgmt_base +
-+ (phy ? PCIEX8MGMT_PHY1_CR_PARA_RD_EN :
-+ PCIEX8MGMT_PHY0_CR_PARA_RD_EN));
-+
-+ /* wait for wait_idle */
-+ do {
-+ if (__raw_readl
-+ (afp->mgmt_base +
-+ (phy ? PCIEX8MGMT_PHY1_CR_PARA_ACK :
-+ PCIEX8MGMT_PHY0_CR_PARA_ACK))) {
-+ ack = 1;
-+ if (!write)
-+ __raw_readl(afp->mgmt_base +
-+ (phy ?
-+ PCIEX8MGMT_PHY1_CR_PARA_RD_DATA :
-+ PCIEX8MGMT_PHY0_CR_PARA_RD_DATA));
-+ }
-+ } while (!ack);
-+
-+ /* clear */
-+ if (write)
-+ __raw_writel(0,
-+ afp->mgmt_base +
-+ (phy ? PCIEX8MGMT_PHY1_CR_PARA_WR_EN :
-+ PCIEX8MGMT_PHY0_CR_PARA_WR_EN));
-+ else
-+ __raw_writel(0,
-+ afp->mgmt_base +
-+ (phy ? PCIEX8MGMT_PHY1_CR_PARA_RD_EN :
-+ PCIEX8MGMT_PHY0_CR_PARA_RD_EN));
-+
-+ /* wait for ~wait_idle */
-+ while (__raw_readl
-+ (afp->mgmt_base +
-+ (phy ? PCIEX8MGMT_PHY1_CR_PARA_ACK :
-+ PCIEX8MGMT_PHY0_CR_PARA_ACK))) {
-+ cpu_relax();
-+ cnt++;
-+ if (cnt > PCIE_PHY_MAX_RETRY_CNT) {
-+ dev_err(dev, "PCIE phy doesn't enter idle state.\n");
-+ break;
-+ }
-+ }
-+}
-+
-+static void fu740_pcie_init_phy(struct fu740_pcie *afp)
-+{
-+ int lane;
-+
-+ /* enable phy cr_para_sel interfaces */
-+ __raw_writel(0x1, afp->mgmt_base + PCIEX8MGMT_PHY0_CR_PARA_SEL);
-+ __raw_writel(0x1, afp->mgmt_base + PCIEX8MGMT_PHY1_CR_PARA_SEL);
-+
-+ /* wait 10 cr_para cycles */
-+ msleep(1);
-+
-+ /* set PHY AC termination mode */
-+ for (lane = 0; lane < 4; lane++) {
-+ fu740_phyregreadwrite(0, 1,
-+ 0x1008 + (0x100 * lane),
-+ 0x0e21, NULL, afp);
-+ fu740_phyregreadwrite(1, 1,
-+ 0x1008 + (0x100 * lane),
-+ 0x0e21, NULL, afp);
-+ }
-+
-+}
-+
-+static int fu740_pcie_wait_for_link(struct fu740_pcie *afp)
-+{
-+ struct dw_pcie *pci = afp->pci;
-+
-+ /* check if the link is up or not */
-+ if (!dw_pcie_wait_for_link(pci))
-+ return 0;
-+
-+ return -ETIMEDOUT;
-+}
-+
-+static void fu740_pcie_ltssm_enable(struct device *dev)
-+{
-+ struct fu740_pcie *afp = dev_get_drvdata(dev);
-+
-+ /* Enable LTSSM */
-+ __raw_writel(0x1, afp->mgmt_base + PCIEX8MGMT_APP_LTSSM_ENABLE);
-+}
-+
-+static int fu740_pcie_establish_link(struct fu740_pcie *afp)
-+{
-+ struct dw_pcie *pci = afp->pci;
-+ struct device *dev = pci->dev;
-+ u32 tmp;
-+ int ret;
-+
-+ /*
-+ * Force Gen1 operation when starting the link. In case the link is
-+ * started in Gen2 mode, there is a possibility the devices on the
-+ * bus will not be detected at all. This happens with PCIe switches.
-+ */
-+ dw_pcie_dbi_ro_wr_en(pci);
-+ tmp = dw_pcie_readl_dbi(pci, PCIE_RC_LCR);
-+ tmp &= ~PCIE_RC_LCR_MAX_LINK_SPEEDS_MASK;
-+ tmp |= PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN1;
-+ dw_pcie_writel_dbi(pci, PCIE_RC_LCR, tmp);
-+ dw_pcie_dbi_ro_wr_dis(pci);
-+
-+ /* Start LTSSM. */
-+ fu740_pcie_ltssm_enable(dev);
-+
-+ ret = fu740_pcie_wait_for_link(afp);
-+ if (ret)
-+ goto err_reset_phy;
-+
-+ /* Now set it to operate in Gen3 */
-+ dw_pcie_dbi_ro_wr_en(pci);
-+ tmp = dw_pcie_readl_dbi(pci, PCIE_RC_LCR);
-+ tmp &= ~PCIE_RC_LCR_MAX_LINK_SPEEDS_MASK;
-+ tmp |= PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN3;
-+ dw_pcie_writel_dbi(pci, PCIE_RC_LCR, tmp);
-+ /* Enable DIRECTED SPEED CHANGE bit of GEN2_CTRL_OFF register */
-+ tmp = dw_pcie_readl_dbi(pci, PCIE_PL_GEN2_CTRL_OFF);
-+ tmp |= PCIE_PL_DIRECTED_SPEED_CHANGE_OFF;
-+ dw_pcie_writel_dbi(pci, PCIE_PL_GEN2_CTRL_OFF, tmp);
-+ dw_pcie_dbi_ro_wr_dis(pci);
-+
-+ ret = fu740_pcie_wait_for_link(afp);
-+ if (ret)
-+ goto err_reset_phy;
-+
-+ /*
-+ * Reenable DIRECTED SPEED CHANGE.
-+ *
-+ * You need to set this bit after each speed change, but after
-+ * reaching G1, setting it once doesn't seem to work (it reaches G3
-+ * equalization states and then times out, falls back to G1). But
-+ * If after that, you set it again, it then reaches G3 perfectly
-+ * fine.
-+ */
-+ dw_pcie_dbi_ro_wr_en(pci);
-+ tmp = dw_pcie_readl_dbi(pci, PCIE_PL_GEN2_CTRL_OFF);
-+ tmp |= PCIE_PL_DIRECTED_SPEED_CHANGE_OFF;
-+ dw_pcie_writel_dbi(pci, PCIE_PL_GEN2_CTRL_OFF, tmp);
-+ dw_pcie_dbi_ro_wr_dis(pci);
-+
-+ ret = fu740_pcie_wait_for_link(afp);
-+ if (ret)
-+ goto err_reset_phy;
-+
-+ tmp = dw_pcie_readl_dbi(pci, PCIE_RC_LCSR);
-+ dev_info(dev, "Link up, Gen%i\n", (tmp >> 16) & 0xf);
-+ return 0;
-+
-+ err_reset_phy:
-+ dev_err(dev, "PHY DEBUG_R0=0x%08x DEBUG_R1=0x%08x\n",
-+ dw_pcie_readl_dbi(pci, PCIE_PHY_DEBUG_R0),
-+ dw_pcie_readl_dbi(pci, PCIE_PHY_DEBUG_R1));
-+ return ret;
-+}
-+
-+static int fu740_pcie_host_init(struct pcie_port *pp)
-+{
-+ struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
-+ struct fu740_pcie *afp = to_fu740_pcie(pci);
-+ struct device *dev = pci->dev;
-+ int ret = 0;
-+
-+ /* power on reset */
-+ fu740_pcie_drive_perstn(afp);
-+
-+ /* enable pcieauxclk */
-+ ret = clk_prepare_enable(afp->pcie_aux);
-+ if (ret)
-+ dev_err(dev, "unable to enable pcie_aux clock\n");
-+
-+ /*
-+ * assert hold_phy_rst (hold the controller LTSSM in reset after
-+ * power_up_rst_n
-+ * for register programming with cr_para)
-+ */
-+ __raw_writel(0x1, afp->mgmt_base + PCIEX8MGMT_APP_HOLD_PHY_RST);
-+
-+ /* deassert power_up_rst_n */
-+ ret = reset_control_deassert(afp->rst);
-+ if (ret)
-+ dev_err(dev, "unable to deassert pcie_power_up_rst_n\n");
-+
-+ fu740_pcie_init_phy(afp);
-+
-+ /* disable pcieauxclk */
-+ clk_disable_unprepare(afp->pcie_aux);
-+ /* clear hold_phy_rst */
-+ __raw_writel(0x0, afp->mgmt_base + PCIEX8MGMT_APP_HOLD_PHY_RST);
-+ /* enable pcieauxclk */
-+ ret = clk_prepare_enable(afp->pcie_aux);
-+ /* set RC mode */
-+ __raw_writel(0x4, afp->mgmt_base + PCIEX8MGMT_DEVICE_TYPE);
-+
-+ dw_pcie_setup_rc(pp);
-+ fu740_pcie_establish_link(afp);
-+
-+ if (IS_ENABLED(CONFIG_PCI_MSI))
-+ dw_pcie_msi_init(pp);
-+
-+ return 0;
-+}
-+
-+static const struct dw_pcie_host_ops fu740_pcie_host_ops = {
-+ .host_init = fu740_pcie_host_init,
-+};
-+
-+static irqreturn_t fu740_pcie_msi_handler(int irq, void *arg)
-+{
-+ struct fu740_pcie *afp = arg;
-+ struct dw_pcie *pci = afp->pci;
-+ struct pcie_port *pp = &pci->pp;
-+
-+ return dw_handle_msi_irq(pp);
-+}
-+
-+static int fu740_pcie_add_pcie_port(struct fu740_pcie *afp,
-+ struct platform_device *pdev)
-+{
-+ struct dw_pcie *pci = afp->pci;
-+ struct pcie_port *pp = &pci->pp;
-+ struct device *dev = &pdev->dev;
-+ int ret;
-+
-+ if (IS_ENABLED(CONFIG_PCI_MSI)) {
-+ pp->msi_irq = platform_get_irq_byname(pdev, "msi");
-+ if (pp->msi_irq <= 0) {
-+ dev_err(dev, "failed to get MSI irq\n");
-+ return -ENODEV;
-+ }
-+
-+ ret = devm_request_irq(dev, pp->msi_irq,
-+ fu740_pcie_msi_handler,
-+ IRQF_SHARED | IRQF_NO_THREAD,
-+ "fu740-pcie-msi", afp);
-+ if (ret) {
-+ dev_err(dev, "failed to request MSI irq\n");
-+ return ret;
-+ }
-+ }
-+
-+ pp->ops = &fu740_pcie_host_ops;
-+
-+ ret = dw_pcie_host_init(pp);
-+ if (ret) {
-+ dev_err(dev, "failed to initialize host\n");
-+ return ret;
-+ }
-+
-+ return 0;
-+}
-+
-+static const struct dw_pcie_ops dw_pcie_ops = { };
-+
-+static const struct dev_pm_ops fu740_pcie_pm_ops = {
-+ SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(fu740_pcie_suspend_noirq,
-+ fu740_pcie_resume_noirq)
-+};
-+
-+static int fu740_pcie_probe(struct platform_device *pdev)
-+{
-+ struct device *dev = &pdev->dev;
-+ struct dw_pcie *pci;
-+ struct fu740_pcie *afp;
-+ struct resource *dbi_res, *mgmt_res;
-+ struct device_node *node = dev->of_node;
-+ int ret;
-+ u16 val;
-+
-+ afp = devm_kzalloc(dev, sizeof(*afp), GFP_KERNEL);
-+ if (!afp)
-+ return -ENOMEM;
-+
-+ pci = devm_kzalloc(dev, sizeof(*pci), GFP_KERNEL);
-+ if (!pci)
-+ return -ENOMEM;
-+
-+ pci->dev = dev;
-+ pci->ops = &dw_pcie_ops;
-+
-+ afp->pci = pci;
-+
-+ dbi_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi");
-+ if (!dbi_res) {
-+ dev_warn(dev, "missing required dbi address range");
-+ return -ENOENT;
-+ }
-+ pci->dbi_base = devm_ioremap_resource(dev, dbi_res);
-+ if (IS_ERR(pci->dbi_base))
-+ return PTR_ERR(pci->dbi_base);
-+
-+ mgmt_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mgmt");
-+ if (!mgmt_res) {
-+ dev_warn(dev, "missing required mgmt address range");
-+ return -ENOENT;
-+ }
-+ afp->mgmt_base = devm_ioremap_resource(dev, mgmt_res);
-+ if (IS_ERR(afp->mgmt_base))
-+ return PTR_ERR(afp->mgmt_base);
-+
-+ /* Fetch GPIOs */
-+ afp->perstn_gpio = of_get_named_gpio(node, "perstn-gpios", 0);
-+ if (gpio_is_valid(afp->perstn_gpio)) {
-+ ret = devm_gpio_request_one(dev, afp->perstn_gpio,
-+ GPIOF_OUT_INIT_LOW, "perstn-gpios");
-+ if (ret) {
-+ dev_err(dev, "unable to get perstn gpio\n");
-+ return ret;
-+ }
-+ } else if (afp->perstn_gpio == -EPROBE_DEFER) {
-+ dev_err(dev, "perst-gpios EPROBE_DEFER\n");
-+ return afp->perstn_gpio;
-+ }
-+
-+ afp->pwren_gpio = of_get_named_gpio(node, "pwren-gpios", 0);
-+ if (gpio_is_valid(afp->pwren_gpio)) {
-+ ret = devm_gpio_request_one(dev, afp->pwren_gpio,
-+ GPIOF_OUT_INIT_LOW, "pwren-gpios");
-+ if (ret) {
-+ dev_err(dev, "unable to get pwren gpio\n");
-+ return ret;
-+ }
-+ } else if (afp->pwren_gpio == -EPROBE_DEFER) {
-+ dev_err(dev, "pwren-gpios EPROBE_DEFER\n");
-+ return afp->pwren_gpio;
-+ }
-+
-+ /* Fetch clocks */
-+ afp->pcie_aux = devm_clk_get(dev, "pcie_aux");
-+ if (IS_ERR(afp->pcie_aux))
-+ return dev_err_probe(dev, PTR_ERR(afp->pcie_aux),
-+ "pcie_aux clock source missing or invalid\n");
-+
-+ /* Fetch reset */
-+ afp->rst = devm_reset_control_get(dev, NULL);
-+ if (IS_ERR(afp->rst))
-+ return dev_err_probe(dev, PTR_ERR(afp->rst), "unable to get reset\n");
-+
-+ platform_set_drvdata(pdev, afp);
-+
-+ ret = fu740_pcie_add_pcie_port(afp, pdev);
-+ if (ret < 0)
-+ return ret;
-+
-+ if (pci_msi_enabled()) {
-+ val = dw_pcie_readw_dbi(pci, PCI_MSI_CAP_ID_NEXT_CTRL_REG +
-+ PCI_MSI_FLAGS);
-+ val |= PCI_MSI_FLAGS_ENABLE;
-+ dw_pcie_writew_dbi(pci, PCI_MSI_CAP_ID_NEXT_CTRL_REG +
-+ PCI_MSI_FLAGS, val);
-+ }
-+
-+ return 0;
-+}
-+
-+static void fu740_pcie_shutdown(struct platform_device *pdev)
-+{
-+ struct fu740_pcie *afp = platform_get_drvdata(pdev);
-+
-+ /* bring down link, so bootloader gets clean state in case of reboot */
-+ fu740_pcie_assert_perstn(afp);
-+}
-+
-+static const struct of_device_id fu740_pcie_of_match[] = {
-+ {.compatible = "sifive,fu740-pcie"},
-+ {},
-+};
-+
-+static struct platform_driver fu740_pcie_driver = {
-+ .driver = {
-+ .name = "fu740-pcie",
-+ .of_match_table = fu740_pcie_of_match,
-+ .suppress_bind_attrs = true,
-+ .pm = &fu740_pcie_pm_ops,
-+ },
-+ .probe = fu740_pcie_probe,
-+ .shutdown = fu740_pcie_shutdown,
-+};
-+
-+static int __init fu740_pcie_init(void)
-+{
-+ return platform_driver_register(&fu740_pcie_driver);
-+}
-+
-+device_initcall(fu740_pcie_init);
---
-2.7.4
-
+++ /dev/null
-From 63d7d0e6553ed2990fec51b3f449e50153461650 Mon Sep 17 00:00:00 2001
-From: Stanislaw Kardach <kda@semihalf.com>
-Date: Mon, 12 Apr 2021 13:10:12 +0200
-Subject: [PATCH 28/28] riscv: enable generic PCI resource mapping
-
-Enable the PCI resource mapping on RISC-V using the generic framework.
-This allows userspace applications to mmap PCI resources using
-/sys/devices/pci*/*/resource* interface.
-The mmap has been tested with Intel x520-DA2 NIC card on a HiFive
-Unmatched board (SiFive FU740 SoC).
-
-Signed-off-by: Stanislaw Kardach <kda@semihalf.com>
----
- arch/riscv/include/asm/pci.h | 2 ++
- 1 file changed, 2 insertions(+)
-
-diff --git a/arch/riscv/include/asm/pci.h b/arch/riscv/include/asm/pci.h
-index 1c473a1..46e844f 100644
---- a/arch/riscv/include/asm/pci.h
-+++ b/arch/riscv/include/asm/pci.h
-@@ -18,6 +18,8 @@
- /* RISC-V shim does not initialize PCI bus */
- #define pcibios_assign_all_busses() 1
-
-+#define ARCH_GENERIC_PCI_MMAP_RESOURCE 1
-+
- extern int isa_dma_bridge_buggy;
-
- #ifdef CONFIG_PCI
---
-2.7.4
-
+++ /dev/null
-From 35f046065b988ea1b29df78728f5dbb6877aadc4 Mon Sep 17 00:00:00 2001
-From: David Abdurachmanov <david.abdurachmanov@sifive.com>
-Date: Tue, 28 Jan 2020 02:55:56 -0800
-Subject: [PATCH 4/7] SiFive Unleashed CPUFreq
-
-Source: https://github.com/sifive/riscv-linux/commits/dev/paulw/cpufreq-dt-aloe-v5.3-rc4
-
-Signed-off-by: David Abdurachmanov <david.abdurachmanov@sifive.com>
-Upstream-Status: Not posted for a review
----
- arch/riscv/Kconfig | 8 +++++
- arch/riscv/boot/dts/sifive/fu540-c000.dtsi | 5 ++++
- .../riscv/boot/dts/sifive/hifive-unleashed-a00.dts | 34 ++++++++++++++++++++++
- arch/riscv/configs/defconfig | 5 ++++
- 4 files changed, 52 insertions(+)
-
-diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
-index fa7dc03..73b1138 100644
---- a/arch/riscv/Kconfig
-+++ b/arch/riscv/Kconfig
-@@ -356,6 +356,14 @@ endchoice
-
- endmenu
-
-+menu "CPU Power Management"
-+
-+source "drivers/cpuidle/Kconfig"
-+
-+source "drivers/cpufreq/Kconfig"
-+
-+endmenu
-+
- menu "Power management options"
-
- source "kernel/power/Kconfig"
-diff --git a/arch/riscv/boot/dts/sifive/fu540-c000.dtsi b/arch/riscv/boot/dts/sifive/fu540-c000.dtsi
-index a2e3d54..a380bc7 100644
---- a/arch/riscv/boot/dts/sifive/fu540-c000.dtsi
-+++ b/arch/riscv/boot/dts/sifive/fu540-c000.dtsi
-@@ -30,6 +30,7 @@
- i-cache-size = <16384>;
- reg = <0>;
- riscv,isa = "rv64imac";
-+ clocks = <&prci PRCI_CLK_COREPLL>;
- status = "disabled";
- cpu0_intc: interrupt-controller {
- #interrupt-cells = <1>;
-@@ -54,6 +55,7 @@
- reg = <1>;
- riscv,isa = "rv64imafdc";
- tlb-split;
-+ clocks = <&prci PRCI_CLK_COREPLL>;
- next-level-cache = <&l2cache>;
- cpu1_intc: interrupt-controller {
- #interrupt-cells = <1>;
-@@ -78,6 +80,7 @@
- reg = <2>;
- riscv,isa = "rv64imafdc";
- tlb-split;
-+ clocks = <&prci PRCI_CLK_COREPLL>;
- next-level-cache = <&l2cache>;
- cpu2_intc: interrupt-controller {
- #interrupt-cells = <1>;
-@@ -102,6 +105,7 @@
- reg = <3>;
- riscv,isa = "rv64imafdc";
- tlb-split;
-+ clocks = <&prci PRCI_CLK_COREPLL>;
- next-level-cache = <&l2cache>;
- cpu3_intc: interrupt-controller {
- #interrupt-cells = <1>;
-@@ -126,6 +130,7 @@
- reg = <4>;
- riscv,isa = "rv64imafdc";
- tlb-split;
-+ clocks = <&prci PRCI_CLK_COREPLL>;
- next-level-cache = <&l2cache>;
- cpu4_intc: interrupt-controller {
- #interrupt-cells = <1>;
-diff --git a/arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts b/arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts
-index 88cfcb9..e1724e3 100644
---- a/arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts
-+++ b/arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts
-@@ -41,6 +41,40 @@
- clock-frequency = <RTCCLK_FREQ>;
- clock-output-names = "rtcclk";
- };
-+
-+ fu540_c000_opp_table: opp-table {
-+ compatible = "operating-points-v2";
-+ opp-shared;
-+
-+ opp-350000000 {
-+ opp-hz = /bits/ 64 <350000000>;
-+ };
-+ opp-700000000 {
-+ opp-hz = /bits/ 64 <700000000>;
-+ };
-+ opp-999999999 {
-+ opp-hz = /bits/ 64 <999999999>;
-+ };
-+ opp-1400000000 {
-+ opp-hz = /bits/ 64 <1400000000>;
-+ };
-+ };
-+};
-+
-+&cpu0 {
-+ operating-points-v2 = <&fu540_c000_opp_table>;
-+};
-+&cpu1 {
-+ operating-points-v2 = <&fu540_c000_opp_table>;
-+};
-+&cpu2 {
-+ operating-points-v2 = <&fu540_c000_opp_table>;
-+};
-+&cpu3 {
-+ operating-points-v2 = <&fu540_c000_opp_table>;
-+};
-+&cpu4 {
-+ operating-points-v2 = <&fu540_c000_opp_table>;
- };
-
- &uart0 {
-diff --git a/arch/riscv/configs/defconfig b/arch/riscv/configs/defconfig
-index e2ff95c..a2fb392 100644
---
-2.7.4
-
+++ /dev/null
-From ce24ba4d603a19690548b986d87ae2d9af26d015 Mon Sep 17 00:00:00 2001
-From: David Abdurachmanov <david.abdurachmanov@sifive.com>
-Date: Thu, 25 Mar 2021 04:34:52 -0700
-Subject: [PATCH 23/28] riscv: sifive: unmatched: add D12 PWM LED
-
-Signed-off-by: David Abdurachmanov <david.abdurachmanov@sifive.com>
----
- arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts | 12 ++++++++++++
- 1 file changed, 12 insertions(+)
-
-diff --git a/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts b/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts
-index e026f60..8461b33 100644
---- a/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts
-+++ b/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts
-@@ -3,6 +3,7 @@
-
- #include "fu740-c000.dtsi"
- #include <dt-bindings/interrupt-controller/irq.h>
-+#include <dt-bindings/pwm/pwm.h>
-
- /* Clock frequency (in Hz) of the PCB crystal for rtcclk */
- #define RTCCLK_FREQ 1000000
-@@ -30,6 +31,17 @@
- soc {
- };
-
-+ pwmleds {
-+ compatible = "pwm-leds";
-+ d12 {
-+ label = "green:d12";
-+ pwms = <&pwm0 0 7812500 PWM_POLARITY_INVERTED>;
-+ active-low = <1>;
-+ max-brightness = <255>;
-+ linux,default-trigger = "none";
-+ };
-+ };
-+
- hfclk: hfclk {
- #clock-cells = <0>;
- compatible = "fixed-clock";
---
-2.7.4
-
+++ /dev/null
-From f19634daf24481664cdc89dc0b5abd9b622718f5 Mon Sep 17 00:00:00 2001
-From: David Abdurachmanov <david.abdurachmanov@sifive.com>
-Date: Thu, 25 Mar 2021 04:37:20 -0700
-Subject: [PATCH 24/28] riscv: sifive: unmatched: add gpio-poweroff node
-
-Signed-off-by: David Abdurachmanov <david.abdurachmanov@sifive.com>
----
- arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts | 6 ++++++
- 1 file changed, 6 insertions(+)
-
-diff --git a/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts b/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts
-index 8461b33..9a7fa9b 100644
---- a/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts
-+++ b/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts
-@@ -2,6 +2,7 @@
- /* Copyright (c) 2020 SiFive, Inc */
-
- #include "fu740-c000.dtsi"
-+#include <dt-bindings/gpio/gpio.h>
- #include <dt-bindings/interrupt-controller/irq.h>
- #include <dt-bindings/pwm/pwm.h>
-
-@@ -55,6 +56,11 @@
- clock-frequency = <RTCCLK_FREQ>;
- clock-output-names = "rtcclk";
- };
-+
-+ gpio-poweroff {
-+ compatible = "gpio-poweroff";
-+ gpios = <&gpio 2 GPIO_ACTIVE_LOW>;
-+ };
- };
-
- &uart0 {
---
-2.7.4
-
+++ /dev/null
-From 2d375478fd6b5eeea711d081502cc8fd1a22987d Mon Sep 17 00:00:00 2001
-From: David Abdurachmanov <david.abdurachmanov@sifive.com>
-Date: Fri, 2 Apr 2021 06:31:07 -0700
-Subject: [PATCH 25/28] riscv: sifive: unmatched: add D2 RGB LED
-
-Signed-off-by: David Abdurachmanov <david.abdurachmanov@sifive.com>
----
- .../riscv/boot/dts/sifive/hifive-unmatched-a00.dts | 26 +++++++++++++++++++++-
- 1 file changed, 25 insertions(+), 1 deletion(-)
-
-diff --git a/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts b/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts
-index 9a7fa9b..235f78a 100644
---- a/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts
-+++ b/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts
-@@ -34,13 +34,37 @@
-
- pwmleds {
- compatible = "pwm-leds";
-- d12 {
-+ green-d12 {
- label = "green:d12";
- pwms = <&pwm0 0 7812500 PWM_POLARITY_INVERTED>;
- active-low = <1>;
- max-brightness = <255>;
- linux,default-trigger = "none";
- };
-+
-+ green-d2 {
-+ label = "green:d2";
-+ pwms = <&pwm0 1 7812500 PWM_POLARITY_INVERTED>;
-+ active-low = <1>;
-+ max-brightness = <255>;
-+ linux,default-trigger = "none";
-+ };
-+
-+ red-d2 {
-+ label = "red:d2";
-+ pwms = <&pwm0 2 7812500 PWM_POLARITY_INVERTED>;
-+ active-low = <1>;
-+ max-brightness = <255>;
-+ linux,default-trigger = "none";
-+ };
-+
-+ blue-d2 {
-+ label = "blue:d2";
-+ pwms = <&pwm0 3 7812500 PWM_POLARITY_INVERTED>;
-+ active-low = <1>;
-+ max-brightness = <255>;
-+ linux,default-trigger = "none";
-+ };
- };
-
- hfclk: hfclk {
---
-2.7.4
-
+++ /dev/null
-From 45ed220373844f72e9ddb05ef0a8f2bd391e0980 Mon Sep 17 00:00:00 2001
-From: David Abdurachmanov <david.abdurachmanov@sifive.com>
-Date: Tue, 6 Apr 2021 05:00:11 -0700
-Subject: [PATCH 26/28] riscv: sifive: unmatched: remove "A00" from model
-
-Signed-off-by: David Abdurachmanov <david.abdurachmanov@sifive.com>
----
- arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts b/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts
-index 235f78a..5fdd183 100644
---- a/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts
-+++ b/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts
-@@ -12,7 +12,7 @@
- / {
- #address-cells = <2>;
- #size-cells = <2>;
-- model = "SiFive HiFive Unmatched A00";
-+ model = "SiFive HiFive Unmatched";
- compatible = "sifive,hifive-unmatched-a00", "sifive,fu740-c000",
- "sifive,fu740";
-
---
-2.7.4
-
+++ /dev/null
-From 665297adfa377a3682b261b23f2a6f3ec56daa8b Mon Sep 17 00:00:00 2001
-From: David Abdurachmanov <david.abdurachmanov@sifive.com>
-Date: Wed, 7 Apr 2021 06:08:33 -0700
-Subject: [PATCH 27/28] riscv: sifive: unmatched: define LEDs color
-
-Signed-off-by: David Abdurachmanov <david.abdurachmanov@sifive.com>
----
- arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts | 5 +++++
- 1 file changed, 5 insertions(+)
-
-diff --git a/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts b/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts
-index 5fdd183..9be0564 100644
---- a/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts
-+++ b/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts
-@@ -4,6 +4,7 @@
- #include "fu740-c000.dtsi"
- #include <dt-bindings/gpio/gpio.h>
- #include <dt-bindings/interrupt-controller/irq.h>
-+#include <dt-bindings/leds/common.h>
- #include <dt-bindings/pwm/pwm.h>
-
- /* Clock frequency (in Hz) of the PCB crystal for rtcclk */
-@@ -36,6 +37,7 @@
- compatible = "pwm-leds";
- green-d12 {
- label = "green:d12";
-+ color = <LED_COLOR_ID_GREEN>;
- pwms = <&pwm0 0 7812500 PWM_POLARITY_INVERTED>;
- active-low = <1>;
- max-brightness = <255>;
-@@ -44,6 +46,7 @@
-
- green-d2 {
- label = "green:d2";
-+ color = <LED_COLOR_ID_GREEN>;
- pwms = <&pwm0 1 7812500 PWM_POLARITY_INVERTED>;
- active-low = <1>;
- max-brightness = <255>;
-@@ -52,6 +55,7 @@
-
- red-d2 {
- label = "red:d2";
-+ color = <LED_COLOR_ID_RED>;
- pwms = <&pwm0 2 7812500 PWM_POLARITY_INVERTED>;
- active-low = <1>;
- max-brightness = <255>;
-@@ -60,6 +64,7 @@
-
- blue-d2 {
- label = "blue:d2";
-+ color = <LED_COLOR_ID_BLUE>;
- pwms = <&pwm0 3 7812500 PWM_POLARITY_INVERTED>;
- active-low = <1>;
- max-brightness = <255>;
---
-2.7.4
-
+++ /dev/null
-From c1c831af223931219b7bf9158b1306b500116167 Mon Sep 17 00:00:00 2001
-From: David Abdurachmanov <david.abdurachmanov@sifive.com>
-Date: Fri, 5 Jun 2020 07:02:10 +0000
-Subject: [PATCH] SiFive HiFive Unleashed: Add PWM LEDs (D1, D2, D3, D4)
-
-By default no functions are assigned to LEDs. It's up to user/distribution
-to provide udev rules to configure them.
-
-Signed-off-by: David Abdurachmanov <david.abdurachmanov@sifive.com>
----
- .../riscv/boot/dts/sifive/hifive-unleashed-a00.dts | 32 ++++++++++++++++++++++
- 1 file changed, 32 insertions(+)
-
-diff --git a/arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts b/arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts
-index 6dd6fa4..c8a47bf 100644
---- a/arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts
-+++ b/arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts
-@@ -3,6 +3,7 @@
-
- #include "fu540-c000.dtsi"
- #include <dt-bindings/gpio/gpio.h>
-+#include <dt-bindings/pwm/pwm.h>
-
- /* Clock frequency (in Hz) of the PCB crystal for rtcclk */
- #define RTCCLK_FREQ 1000000
-@@ -27,6 +28,37 @@
- };
-
- soc {
-+ pwmleds {
-+ compatible = "pwm-leds";
-+ d1 {
-+ label = "green:d1";
-+ pwms = <&pwm0 0 7812500 PWM_POLARITY_INVERTED>;
-+ active-low = <1>;
-+ max-brightness = <255>;
-+ linux,default-trigger = "none";
-+ };
-+ d2 {
-+ label = "green:d2";
-+ pwms = <&pwm0 1 7812500 PWM_POLARITY_INVERTED>;
-+ active-low = <1>;
-+ max-brightness = <255>;
-+ linux,default-trigger = "none";
-+ };
-+ d3 {
-+ label = "green:d3";
-+ pwms = <&pwm0 2 7812500 PWM_POLARITY_INVERTED>;
-+ active-low = <1>;
-+ max-brightness = <255>;
-+ linux,default-trigger = "none";
-+ };
-+ d4 {
-+ label = "green:d4";
-+ pwms = <&pwm0 3 7812500 PWM_POLARITY_INVERTED>;
-+ active-low = <1>;
-+ max-brightness = <255>;
-+ linux,default-trigger = "none";
-+ };
-+ };
- };
-
- hfclk: hfclk {
---
-2.7.4
-
+++ /dev/null
-diff -ruN a/arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts b/arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts
---- a/arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts 2021-11-06 19:23:11.657526676 +0100
-+++ b/arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts 2021-11-06 19:00:10.140770182 +0100
-@@ -14,6 +14,13 @@
- model = "SiFive HiFive Unleashed A00";
- compatible = "sifive,hifive-unleashed-a00", "sifive,fu540-c000";
-
-+ aliases {
-+ led-boot = &power_green;
-+ led-failsafe = &power_green;
-+ led-running = &power_green;
-+ led-upgrade = &power_green;
-+ };
-+
- chosen {
- stdout-path = "serial0";
- };
-@@ -30,7 +37,7 @@
- soc {
- pwmleds {
- compatible = "pwm-leds";
-- d1 {
-+ power_green: d1 {
- label = "green:d1";
- pwms = <&pwm0 0 7812500 PWM_POLARITY_INVERTED>;
- active-low = <1>;
-@@ -56,7 +63,7 @@
- pwms = <&pwm0 3 7812500 PWM_POLARITY_INVERTED>;
- active-low = <1>;
- max-brightness = <255>;
-- linux,default-trigger = "none";
-+ linux,default-trigger = "mmc0";
- };
- };
- };
-diff -ruN a/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts b/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts
---- a/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts 2021-11-06 19:23:21.949472627 +0100
-+++ b/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts 2021-11-06 19:21:08.002175934 +0100
-@@ -17,6 +17,13 @@
- compatible = "sifive,hifive-unmatched-a00", "sifive,fu740-c000",
- "sifive,fu740";
-
-+ aliases {
-+ led-boot = &power_green;
-+ led-failsafe = &power_green;
-+ led-running = &power_green;
-+ led-upgrade = &power_green;
-+ };
-+
- chosen {
- stdout-path = "serial0";
- };
-@@ -35,7 +42,7 @@
-
- pwmleds {
- compatible = "pwm-leds";
-- green-d12 {
-+ power_green: green-d12 {
- label = "green:d12";
- color = <LED_COLOR_ID_GREEN>;
- pwms = <&pwm0 0 7812500 PWM_POLARITY_INVERTED>;
+++ /dev/null
-From 89c9a963944ed10a890b627e2e63e96fbff3aa36 Mon Sep 17 00:00:00 2001
-From: Vincent Pelletier <plr.vincent@gmail.com>
-Date: Sat, 19 Jun 2021 14:36:47 +0000
-Subject: [PATCH] riscv: dts: sifive unmatched: Expose the FU740 core supply
- regulator.
-
-Signed-off-by: Vincent Pelletier <plr.vincent@gmail.com>
----
- arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts | 5 +++++
- 1 file changed, 5 insertions(+)
-
-diff --git a/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts b/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts
-index 9be05644e3c02a..8728391b4a81ef 100644
---- a/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts
-+++ b/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts
-@@ -103,6 +103,11 @@
- &i2c0 {
- status = "okay";
-
-+ tps544b20@1e {
-+ compatible = "tps544b20";
-+ reg = <0x1e>;
-+ };
-+
- temperature-sensor@4c {
- compatible = "ti,tmp451";
- reg = <0x4c>;
+++ /dev/null
-From c5faf98f30ef3e1a3f56ace78741ccef2e4856aa Mon Sep 17 00:00:00 2001
-From: Vincent Pelletier <plr.vincent@gmail.com>
-Date: Sat, 19 Jun 2021 14:37:27 +0000
-Subject: [PATCH] riscv: dts: sifive unmatched: Link the tmp451 with its power
- supply.
-
-Signed-off-by: Vincent Pelletier <plr.vincent@gmail.com>
----
- arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts b/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts
-index 8728391b4a81ef..a6f3556c82ba15 100644
---- a/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts
-+++ b/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts
-@@ -111,6 +111,7 @@
- temperature-sensor@4c {
- compatible = "ti,tmp451";
- reg = <0x4c>;
-+ vcc-supply = <&vdd_bpro>;
- interrupt-parent = <&gpio>;
- interrupts = <6 IRQ_TYPE_LEVEL_LOW>;
- };
+++ /dev/null
-From 3eb8033e1f318477cf87e6e0ea837e75a87856e9 Mon Sep 17 00:00:00 2001
-From: Vincent Pelletier <plr.vincent@gmail.com>
-Date: Sat, 19 Jun 2021 14:37:53 +0000
-Subject: [PATCH] riscv: dts: sifive unmatched: Expose the board ID eeprom.
-
-Signed-off-by: Vincent Pelletier <plr.vincent@gmail.com>
----
- arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts | 10 ++++++++++
- 1 file changed, 10 insertions(+)
-
-diff --git a/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts b/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts
-index a6f3556c82ba15..4a7a7352b46dde 100644
---- a/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts
-+++ b/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts
-@@ -116,6 +116,16 @@
- interrupts = <6 IRQ_TYPE_LEVEL_LOW>;
- };
-
-+ eeprom@54 {
-+ compatible = "microchip,24c02", "atmel,24c02";
-+ reg = <0x54>;
-+ vcc-supply = <&vdd_bpro>;
-+ label = "board-id";
-+ pagesize = <16>;
-+ read-only;
-+ size = <256>;
-+ };
-+
- pmic@58 {
- compatible = "dlg,da9063";
- reg = <0x58>;
+++ /dev/null
-From eeaad1f6ab4fa5f854780587296c71dda9cda3b5 Mon Sep 17 00:00:00 2001
-From: Vincent Pelletier <plr.vincent@gmail.com>
-Date: Sat, 19 Jun 2021 14:40:14 +0000
-Subject: [PATCH] riscv: dts: sifive unmatched: Expose the PMIC sub-functions.
-
-Signed-off-by: Vincent Pelletier <plr.vincent@gmail.com>
----
- arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts | 12 ++++++++++++
- 1 file changed, 12 insertions(+)
-
-diff --git a/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts b/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts
-index 4a7a7352b46dde..66d3c50213443a 100644
---- a/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts
-+++ b/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts
-@@ -133,6 +133,18 @@
- interrupts = <1 IRQ_TYPE_LEVEL_LOW>;
- interrupt-controller;
-
-+ onkey {
-+ compatible = "dlg,da9063-onkey";
-+ };
-+
-+ rtc {
-+ compatible = "dlg,da9063-rtc";
-+ };
-+
-+ wdt {
-+ compatible = "dlg,da9063-watchdog";
-+ };
-+
- regulators {
- vdd_bcore1: bcore1 {
- regulator-min-microvolt = <1050000>;
+++ /dev/null
-From 00a903b88b10f77b053e910f72bd9feb0d5c7c17 Mon Sep 17 00:00:00 2001
-From: Vincent Pelletier <plr.vincent@gmail.com>
-Date: Sat, 19 Jun 2021 14:36:12 +0000
-Subject: [PATCH] riscv: dts: sifive unmatched: Expose fan PWM.
-
-Signed-off-by: Vincent Pelletier <plr.vincent@gmail.com>
----
- arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts | 12 ++++++++++++
- 1 file changed, 12 insertions(+)
-
-diff --git a/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts b/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts
-index 73b3f787773859..888a0aa3b7f475 100644
---- a/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts
-+++ b/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts
-@@ -90,6 +90,18 @@
- compatible = "gpio-poweroff";
- gpios = <&gpio 2 GPIO_ACTIVE_LOW>;
- };
-+
-+ fan0: asm2824-fan {
-+ compatible = "pwm-fan";
-+ pwms = <&pwm1 2 7812500 PWM_POLARITY_INVERTED>;
-+ cooling-levels = <255 153 85 25 0>;
-+ };
-+
-+ fan1: chassis-fan {
-+ compatible = "pwm-fan";
-+ pwms = <&pwm1 3 7812500 PWM_POLARITY_INVERTED>;
-+ cooling-levels = <255 153 85 25 0>;
-+ };
- };
-
- &uart0 {
+++ /dev/null
-From 1690b165f7a5b4858eac60abf221666e9cdb90de Mon Sep 17 00:00:00 2001
-From: "Opensource [Steve Twiss]" <stwiss.opensource@diasemi.com>
-Date: Sun, 23 Mar 2014 20:37:30 +0000
-Subject: [PATCH] mfd: da9063: Add HWMON dependencies
-
-Dependencies required for DA9063 HWMON support.
-
-Signed-off-by: Opensource [Steve Twiss] <stwiss.opensource@diasemi.com>
-
-Moved temperature offset reading to hwmon driver.
-
-Signed-off-by: Vincent Pelletier <plr.vincent@gmail.com>
----
- include/linux/mfd/da9063/registers.h | 34 ++++++++++++++++++++++++++++
- 1 file changed, 34 insertions(+)
-
-diff --git a/include/linux/mfd/da9063/registers.h b/include/linux/mfd/da9063/registers.h
-index 6e0f66a2e7279f..297631ddda3994 100644
---- a/include/linux/mfd/da9063/registers.h
-+++ b/include/linux/mfd/da9063/registers.h
-@@ -512,6 +512,7 @@
-
- /* DA9063_REG_GPIO_0_1 (addr=0x15) */
- #define DA9063_GPIO0_PIN_MASK 0x03
-+#define DA9063_GPIO0_PIN_MASK_SHIFT 0
- #define DA9063_GPIO0_PIN_ADCIN1 0x00
- #define DA9063_GPIO0_PIN_GPI 0x01
- #define DA9063_GPIO0_PIN_GPO_OD 0x02
-@@ -523,6 +524,7 @@
- #define DA9063_GPIO0_TYPE_GPO_VDD_IO2 0x04
- #define DA9063_GPIO0_NO_WAKEUP 0x08
- #define DA9063_GPIO1_PIN_MASK 0x30
-+#define DA9063_GPIO1_PIN_MASK_SHIFT 4
- #define DA9063_GPIO1_PIN_ADCIN2_COMP 0x00
- #define DA9063_GPIO1_PIN_GPI 0x10
- #define DA9063_GPIO1_PIN_GPO_OD 0x20
-@@ -536,6 +538,7 @@
-
- /* DA9063_REG_GPIO_2_3 (addr=0x16) */
- #define DA9063_GPIO2_PIN_MASK 0x03
-+#define DA9063_GPIO2_PIN_MASK_SHIFT 0
- #define DA9063_GPIO2_PIN_ADCIN3 0x00
- #define DA9063_GPIO2_PIN_GPI 0x01
- #define DA9063_GPIO2_PIN_GPO_PSS 0x02
-@@ -851,6 +854,7 @@
- #define DA9063_VSYS_VAL_BASE 0x00
-
- /* DA9063_REG_ADC_RES_L (addr=0x37) */
-+#define DA9063_ADC_RES_L_SHIFT 6
- #define DA9063_ADC_RES_L_BITS 2
- #define DA9063_ADC_RES_L_MASK 0xC0
-
-@@ -1014,6 +1018,36 @@
- #define DA9063_GPIO_DIM 0x80
- #define DA9063_GPIO_PWM_MASK 0x7F
-
-+/* DA9063_REG_ADC_CFG (addr=0xC9) */
-+#define DA9063_REG_ADCIN1_CUR_MASK 0x03
-+#define DA9063_REG_ADCIN1_CUR_SHIFT 0
-+#define DA9063_ADCIN1_CUR_1UA 0x00
-+#define DA9063_ADCIN1_CUR_2UA 0x01
-+#define DA9063_ADCIN1_CUR_10UA 0x02
-+#define DA9063_ADCIN1_CUR_40UA 0x03
-+#define DA9063_REG_ADCIN2_CUR_MASK 0x0C
-+#define DA9063_REG_ADCIN2_CUR_SHIFT 2
-+#define DA9063_ADCIN2_CUR_1UA 0x00
-+#define DA9063_ADCIN2_CUR_2UA 0x01
-+#define DA9063_ADCIN2_CUR_10UA 0x02
-+#define DA9063_ADCIN2_CUR_40UA 0x03
-+#define DA9063_REG_ADCIN3_CUR_MASK 0x10
-+#define DA9063_REG_ADCIN3_CUR_SHIFT 4
-+#define DA9063_ADCIN3_CUR_10UA 0x00
-+#define DA9063_ADCIN3_CUR_40UA 0x01
-+#define DA9063_REG_ADCIN1_DEB_MASK 0x20
-+#define DA9063_REG_ADCIN1_DEB_SHIFT 5
-+#define DA9063_ADCIN1_DEB_OFF 0x00
-+#define DA9063_ADCIN1_DEB_ON 0x01
-+#define DA9063_REG_ADCIN2_DEB_MASK 0x40
-+#define DA9063_REG_ADCIN2_DEB_SHIFT 6
-+#define DA9063_ADCIN2_DEB_OFF 0x00
-+#define DA9063_ADCIN2_DEB_ON 0x01
-+#define DA9063_REG_ADCIN3_DEB_MASK 0x80
-+#define DA9063_REG_ADCIN3_DEB_SHIFT 7
-+#define DA9063_ADCIN3_DEB_OFF 0x00
-+#define DA9063_ADCIN3_DEB_ON 0x01
-+
- /* DA9063_REG_CONFIG_H (addr=0x10D) */
- #define DA9063_PWM_CLK_MASK 0x01
- #define DA9063_PWM_CLK_PWM2MHZ 0x00
+++ /dev/null
-From a829b924463d46792484ab6341b9c606cc7269a7 Mon Sep 17 00:00:00 2001
-From: Vincent Pelletier <plr.vincent@gmail.com>
-Date: Sun, 23 Mar 2014 20:37:30 +0000
-Subject: [PATCH] hwmon: da9063: HWMON driver
-
-Add the HWMON driver for DA9063
-
-Originally-from: Opensource [Steve Twiss] <stwiss.opensource@diasemi.com>
-Signed-off-by: Vincent Pelletier <plr.vincent@gmail.com>
----
- drivers/hwmon/Kconfig | 10 ++
- drivers/hwmon/Makefile | 1 +
- drivers/hwmon/da9063-hwmon.c | 260 +++++++++++++++++++++++++++++++++++
- 3 files changed, 271 insertions(+)
- create mode 100644 drivers/hwmon/da9063-hwmon.c
-
-diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
-index 87624902ea8090..17244cfaa855db 100644
---- a/drivers/hwmon/Kconfig
-+++ b/drivers/hwmon/Kconfig
-@@ -515,6 +515,16 @@ config SENSORS_DA9055
- This driver can also be built as a module. If so, the module
- will be called da9055-hwmon.
-
-+config SENSORS_DA9063
-+ tristate "Dialog Semiconductor DA9063"
-+ depends on MFD_DA9063
-+ help
-+ If you say yes here you get support for the hardware
-+ monitoring features of the DA9063 Power Management IC.
-+
-+ This driver can also be built as a module. If so, the module
-+ will be called da9063-hwmon.
-+
- config SENSORS_I5K_AMB
- tristate "FB-DIMM AMB temperature sensor on Intel 5000 series chipsets"
- depends on PCI
-diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
-index 59e78bc212cf3c..6855711ed9ec0f 100644
---- a/drivers/hwmon/Makefile
-+++ b/drivers/hwmon/Makefile
-@@ -60,6 +60,7 @@ obj-$(CONFIG_SENSORS_CORSAIR_CPRO) += corsair-cpro.o
- obj-$(CONFIG_SENSORS_CORSAIR_PSU) += corsair-psu.o
- obj-$(CONFIG_SENSORS_DA9052_ADC)+= da9052-hwmon.o
- obj-$(CONFIG_SENSORS_DA9055)+= da9055-hwmon.o
-+obj-$(CONFIG_SENSORS_DA9063) += da9063-hwmon.o
- obj-$(CONFIG_SENSORS_DELL_SMM) += dell-smm-hwmon.o
- obj-$(CONFIG_SENSORS_DME1737) += dme1737.o
- obj-$(CONFIG_SENSORS_DRIVETEMP) += drivetemp.o
-diff --git a/drivers/hwmon/da9063-hwmon.c b/drivers/hwmon/da9063-hwmon.c
-new file mode 100644
-index 00000000000000..6367685536a179
---- /dev/null
-+++ b/drivers/hwmon/da9063-hwmon.c
-@@ -0,0 +1,260 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later
-+/* da9063-hwmon.c - Hardware monitor support for DA9063
-+ * Copyright (C) 2014 Dialog Semiconductor Ltd.
-+ * Copyright (C) 2021 Vincent Pelletier <plr.vincent@gmail.com>
-+ */
-+
-+#include <linux/delay.h>
-+#include <linux/err.h>
-+#include <linux/hwmon.h>
-+#include <linux/hwmon-sysfs.h>
-+#include <linux/init.h>
-+#include <linux/kernel.h>
-+#include <linux/mfd/da9063/core.h>
-+#include <linux/mod_devicetable.h>
-+#include <linux/module.h>
-+#include <linux/platform_device.h>
-+#include <linux/regmap.h>
-+#include <linux/slab.h>
-+#include <linux/string.h>
-+
-+#define DA9063_ADC_RES (1 << (DA9063_ADC_RES_L_BITS + DA9063_ADC_RES_M_BITS))
-+#define DA9063_ADC_MAX (DA9063_ADC_RES - 1)
-+#define DA9063_2V5 2500
-+#define DA9063_5V0 5000
-+#define DA9063_5V5 5500
-+#define DA9063_TJUNC_M -398
-+#define DA9063_TJUNC_O 330000
-+#define DA9063_VBBAT_M 2048
-+
-+enum da9063_adc {
-+ DA9063_CHAN_VSYS = DA9063_ADC_MUX_VSYS,
-+ DA9063_CHAN_ADCIN1 = DA9063_ADC_MUX_ADCIN1,
-+ DA9063_CHAN_ADCIN2 = DA9063_ADC_MUX_ADCIN2,
-+ DA9063_CHAN_ADCIN3 = DA9063_ADC_MUX_ADCIN3,
-+ DA9063_CHAN_TJUNC = DA9063_ADC_MUX_T_SENSE,
-+ DA9063_CHAN_VBBAT = DA9063_ADC_MUX_VBBAT,
-+ DA9063_CHAN_LDO_G1 = DA9063_ADC_MUX_LDO_G1,
-+ DA9063_CHAN_LDO_G2 = DA9063_ADC_MUX_LDO_G2,
-+ DA9063_CHAN_LDO_G3 = DA9063_ADC_MUX_LDO_G3
-+};
-+
-+struct da9063_hwmon {
-+ struct da9063 *da9063;
-+ struct mutex hwmon_mutex;
-+ struct completion adc_ready;
-+ signed char tjunc_offset;
-+};
-+
-+static int da9063_adc_manual_read(struct da9063_hwmon *hwmon, int channel)
-+{
-+ int ret;
-+ unsigned char val;
-+ unsigned char data[2];
-+ int adc_man;
-+
-+ mutex_lock(&hwmon->hwmon_mutex);
-+
-+ val = (channel & DA9063_ADC_MUX_MASK) | DA9063_ADC_MAN;
-+ ret = regmap_update_bits(hwmon->da9063->regmap, DA9063_REG_ADC_MAN,
-+ DA9063_ADC_MUX_MASK | DA9063_ADC_MAN, val);
-+ if (ret < 0)
-+ goto err_mread;
-+
-+ ret = wait_for_completion_timeout(&hwmon->adc_ready,
-+ msecs_to_jiffies(100));
-+ reinit_completion(&hwmon->adc_ready);
-+ if (ret == 0)
-+ dev_dbg(hwmon->da9063->dev,
-+ "Timeout while waiting for ADC completion IRQ\n");
-+
-+ ret = regmap_read(hwmon->da9063->regmap, DA9063_REG_ADC_MAN, &adc_man);
-+ if (ret < 0)
-+ goto err_mread;
-+
-+ /* data value is not ready */
-+ if (adc_man & DA9063_ADC_MAN) {
-+ ret = -ETIMEDOUT;
-+ goto err_mread;
-+ }
-+
-+ ret = regmap_bulk_read(hwmon->da9063->regmap,
-+ DA9063_REG_ADC_RES_L, data, 2);
-+ if (ret < 0)
-+ goto err_mread;
-+
-+ ret = (data[0] & DA9063_ADC_RES_L_MASK) >> DA9063_ADC_RES_L_SHIFT;
-+ ret |= data[1] << DA9063_ADC_RES_L_BITS;
-+err_mread:
-+ mutex_unlock(&hwmon->hwmon_mutex);
-+ return ret;
-+}
-+
-+static irqreturn_t da9063_hwmon_irq_handler(int irq, void *irq_data)
-+{
-+ struct da9063_hwmon *hwmon = irq_data;
-+
-+ complete(&hwmon->adc_ready);
-+ return IRQ_HANDLED;
-+}
-+
-+static umode_t da9063_is_visible(const void *drvdata, enum
-+ hwmon_sensor_types type, u32 attr, int channel)
-+{
-+ return 0444;
-+}
-+
-+static const enum da9063_adc da9063_in_index[] = {
-+ DA9063_CHAN_VSYS, DA9063_CHAN_VBBAT
-+};
-+
-+static int da9063_read(struct device *dev, enum hwmon_sensor_types type,
-+ u32 attr, int channel, long *val)
-+{
-+ struct da9063_hwmon *hwmon = dev_get_drvdata(dev);
-+ enum da9063_adc adc_channel;
-+ int tmp;
-+
-+ switch (type) {
-+ case hwmon_in:
-+ if (attr != hwmon_in_input)
-+ return -EOPNOTSUPP;
-+ adc_channel = da9063_in_index[channel];
-+ break;
-+ case hwmon_temp:
-+ if (attr != hwmon_temp_input)
-+ return -EOPNOTSUPP;
-+ adc_channel = DA9063_CHAN_TJUNC;
-+ break;
-+ default:
-+ return -EOPNOTSUPP;
-+ }
-+
-+ tmp = da9063_adc_manual_read(hwmon, adc_channel);
-+ if (tmp < 0)
-+ return tmp;
-+
-+ switch (adc_channel) {
-+ case DA9063_CHAN_VSYS:
-+ *val = ((DA9063_5V5 - DA9063_2V5) * tmp) / DA9063_ADC_MAX +
-+ DA9063_2V5;
-+ break;
-+ case DA9063_CHAN_TJUNC:
-+ tmp -= hwmon->tjunc_offset;
-+ *val = DA9063_TJUNC_M * tmp + DA9063_TJUNC_O;
-+ break;
-+ case DA9063_CHAN_VBBAT:
-+ *val = (DA9063_5V0 * tmp) / DA9063_ADC_MAX;
-+ break;
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ return 0;
-+}
-+
-+static const char * const da9063_in_name[] = {
-+ "VSYS", "VBBAT"
-+};
-+
-+static int da9063_read_string(struct device *dev, enum hwmon_sensor_types type,
-+ u32 attr, int channel, const char **str)
-+{
-+ switch (type) {
-+ case hwmon_in:
-+ if (attr != hwmon_in_label)
-+ return -EOPNOTSUPP;
-+ *str = da9063_in_name[channel];
-+ break;
-+ case hwmon_temp:
-+ if (attr != hwmon_temp_label)
-+ return -EOPNOTSUPP;
-+ *str = "TJUNC";
-+ break;
-+ default:
-+ return -EOPNOTSUPP;
-+ }
-+
-+ return 0;
-+}
-+
-+static const struct hwmon_ops da9063_ops = {
-+ .is_visible = da9063_is_visible,
-+ .read = da9063_read,
-+ .read_string = da9063_read_string,
-+};
-+
-+static const struct hwmon_channel_info *da9063_channel_info[] = {
-+ HWMON_CHANNEL_INFO(chip, HWMON_C_REGISTER_TZ),
-+ HWMON_CHANNEL_INFO(in,
-+ HWMON_I_INPUT | HWMON_I_LABEL,
-+ HWMON_I_INPUT | HWMON_I_LABEL),
-+ HWMON_CHANNEL_INFO(temp,
-+ HWMON_T_INPUT | HWMON_T_LABEL),
-+ NULL
-+};
-+
-+static const struct hwmon_chip_info da9063_chip_info = {
-+ .ops = &da9063_ops,
-+ .info = da9063_channel_info,
-+};
-+
-+static int da9063_hwmon_probe(struct platform_device *pdev)
-+{
-+ struct da9063 *da9063 = dev_get_drvdata(pdev->dev.parent);
-+ struct da9063_hwmon *hwmon;
-+ struct device *hwmon_dev;
-+ unsigned int tmp;
-+ int irq;
-+ int ret;
-+
-+ hwmon = devm_kzalloc(&pdev->dev, sizeof(struct da9063_hwmon),
-+ GFP_KERNEL);
-+ if (!hwmon)
-+ return -ENOMEM;
-+
-+ mutex_init(&hwmon->hwmon_mutex);
-+ init_completion(&hwmon->adc_ready);
-+ hwmon->da9063 = da9063;
-+
-+ irq = platform_get_irq_byname(pdev, DA9063_DRVNAME_HWMON);
-+ if (irq < 0)
-+ return irq;
-+
-+ ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
-+ da9063_hwmon_irq_handler,
-+ IRQF_TRIGGER_LOW | IRQF_ONESHOT,
-+ "HWMON", hwmon);
-+ if (ret) {
-+ dev_err(&pdev->dev, "Failed to request IRQ.\n");
-+ return ret;
-+ }
-+
-+ ret = regmap_read(da9063->regmap, DA9063_REG_T_OFFSET, &tmp);
-+ if (ret < 0) {
-+ tmp = 0;
-+ dev_warn(&pdev->dev,
-+ "Temperature trimming value cannot be read (defaulting to 0)\n");
-+ }
-+ hwmon->tjunc_offset = (signed char) tmp;
-+
-+ hwmon_dev = devm_hwmon_device_register_with_info(&pdev->dev, "da9063",
-+ hwmon,
-+ &da9063_chip_info,
-+ NULL);
-+
-+ return PTR_ERR_OR_ZERO(hwmon_dev);
-+}
-+
-+static struct platform_driver da9063_hwmon_driver = {
-+ .probe = da9063_hwmon_probe,
-+ .driver = {
-+ .name = DA9063_DRVNAME_HWMON,
-+ },
-+};
-+module_platform_driver(da9063_hwmon_driver);
-+
-+MODULE_DESCRIPTION("Hardware monitor support device driver for Dialog DA9063");
-+MODULE_AUTHOR("Vincent Pelletier <plr.vincent@gmail.com>");
-+MODULE_LICENSE("GPL v2");
-+MODULE_ALIAS("platform:" DA9063_DRVNAME_HWMON);
--- /dev/null
+From ab5c8f5492cce16ff2104393e2f1fa64a3ff6e88 Mon Sep 17 00:00:00 2001
+From: David Abdurachmanov <david.abdurachmanov@sifive.com>
+Date: Wed, 17 Feb 2021 06:06:14 -0800
+Subject: [PATCH 1/7] riscv: sifive: fu740: cpu{1,2,3,4} set compatible to
+ sifive,u74-mc
+
+Signed-off-by: David Abdurachmanov <david.abdurachmanov@sifive.com>
+---
+ arch/riscv/boot/dts/sifive/fu740-c000.dtsi | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/arch/riscv/boot/dts/sifive/fu740-c000.dtsi b/arch/riscv/boot/dts/sifive/fu740-c000.dtsi
+index abbb960..3095d82 100644
+--- a/arch/riscv/boot/dts/sifive/fu740-c000.dtsi
++++ b/arch/riscv/boot/dts/sifive/fu740-c000.dtsi
+@@ -39,7 +39,7 @@
+ };
+ };
+ cpu1: cpu@1 {
+- compatible = "sifive,bullet0", "riscv";
++ compatible = "sifive,u74-mc", "sifive,bullet0", "riscv";
+ d-cache-block-size = <64>;
+ d-cache-sets = <64>;
+ d-cache-size = <32768>;
+@@ -63,7 +63,7 @@
+ };
+ };
+ cpu2: cpu@2 {
+- compatible = "sifive,bullet0", "riscv";
++ compatible = "sifive,u74-mc", "sifive,bullet0", "riscv";
+ d-cache-block-size = <64>;
+ d-cache-sets = <64>;
+ d-cache-size = <32768>;
+@@ -87,7 +87,7 @@
+ };
+ };
+ cpu3: cpu@3 {
+- compatible = "sifive,bullet0", "riscv";
++ compatible = "sifive,u74-mc", "sifive,bullet0", "riscv";
+ d-cache-block-size = <64>;
+ d-cache-sets = <64>;
+ d-cache-size = <32768>;
+@@ -111,7 +111,7 @@
+ };
+ };
+ cpu4: cpu@4 {
+- compatible = "sifive,bullet0", "riscv";
++ compatible = "sifive,u74-mc", "sifive,bullet0", "riscv";
+ d-cache-block-size = <64>;
+ d-cache-sets = <64>;
+ d-cache-size = <32768>;
+--
+2.7.4
+
--- /dev/null
+From 657819ff477dd73cd71075609698aa57ba098d8c Mon Sep 17 00:00:00 2001
+From: David Abdurachmanov <david.abdurachmanov@sifive.com>
+Date: Wed, 15 Sep 2021 07:10:02 -0700
+Subject: [PATCH 2/7] riscv: sifive: unmatched: update regulators values
+
+These are the regulators values from the schematics for Rev3{A,B} boards.
+
+Note this is not fully correct as bcore1/bcore2 and bmem/bio are merged, but
+it's only supported in v5.15 kernel. See:
+
+541ee8f640327f951e7039278057827322231ab0 ("regulator: da9063: Add support for
+full-current mode.")
+
+This will be changed for v5.15 kernel based on the patch above.
+
+Signed-off-by: David Abdurachmanov <david.abdurachmanov@sifive.com>
+---
+ .../riscv/boot/dts/sifive/hifive-unmatched-a00.dts | 32 +++++++++++-----------
+ 1 file changed, 16 insertions(+), 16 deletions(-)
+
+diff --git a/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts b/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts
+index 2e4ea84..e026f60 100644
+--- a/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts
++++ b/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts
+@@ -72,16 +72,16 @@
+
+ regulators {
+ vdd_bcore1: bcore1 {
+- regulator-min-microvolt = <900000>;
+- regulator-max-microvolt = <900000>;
++ regulator-min-microvolt = <1050000>;
++ regulator-max-microvolt = <1050000>;
+ regulator-min-microamp = <5000000>;
+ regulator-max-microamp = <5000000>;
+ regulator-always-on;
+ };
+
+ vdd_bcore2: bcore2 {
+- regulator-min-microvolt = <900000>;
+- regulator-max-microvolt = <900000>;
++ regulator-min-microvolt = <1050000>;
++ regulator-max-microvolt = <1050000>;
+ regulator-min-microamp = <5000000>;
+ regulator-max-microamp = <5000000>;
+ regulator-always-on;
+@@ -136,48 +136,48 @@
+ };
+
+ vdd_ldo3: ldo3 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
+ regulator-min-microamp = <200000>;
+ regulator-max-microamp = <200000>;
+ regulator-always-on;
+ };
+
+ vdd_ldo4: ldo4 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
++ regulator-min-microvolt = <2500000>;
++ regulator-max-microvolt = <2500000>;
+ regulator-min-microamp = <200000>;
+ regulator-max-microamp = <200000>;
+ regulator-always-on;
+ };
+
+ vdd_ldo5: ldo5 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
+ regulator-min-microamp = <100000>;
+ regulator-max-microamp = <100000>;
+ regulator-always-on;
+ };
+
+ vdd_ldo6: ldo6 {
+- regulator-min-microvolt = <3300000>;
+- regulator-max-microvolt = <3300000>;
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
+ regulator-min-microamp = <200000>;
+ regulator-max-microamp = <200000>;
+ regulator-always-on;
+ };
+
+ vdd_ldo7: ldo7 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
+ regulator-min-microamp = <200000>;
+ regulator-max-microamp = <200000>;
+ regulator-always-on;
+ };
+
+ vdd_ldo8: ldo8 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
+ regulator-min-microamp = <200000>;
+ regulator-max-microamp = <200000>;
+ regulator-always-on;
+--
+2.7.4
+
--- /dev/null
+From 2c2d8ac8c124a2938c9326c14b2dffd46d76b4a8 Mon Sep 17 00:00:00 2001
+From: David Abdurachmanov <david.abdurachmanov@sifive.com>
+Date: Mon, 13 Sep 2021 02:15:37 -0700
+Subject: [PATCH 3/7] riscv: sifive: unmatched: define PWM LEDs
+
+Add D2 (RGB) and D12 (green) LEDs for SiFive Unmatched board.
+
+Signed-off-by: David Abdurachmanov <david.abdurachmanov@sifive.com>
+---
+ .../riscv/boot/dts/sifive/hifive-unmatched-a00.dts | 41 ++++++++++++++++++++++
+ 1 file changed, 41 insertions(+)
+
+diff --git a/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts b/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts
+index e026f60..200d022 100644
+--- a/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts
++++ b/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts
+@@ -3,6 +3,8 @@
+
+ #include "fu740-c000.dtsi"
+ #include <dt-bindings/interrupt-controller/irq.h>
++#include <dt-bindings/leds/common.h>
++#include <dt-bindings/pwm/pwm.h>
+
+ /* Clock frequency (in Hz) of the PCB crystal for rtcclk */
+ #define RTCCLK_FREQ 1000000
+@@ -30,6 +32,45 @@
+ soc {
+ };
+
++ pwmleds {
++ compatible = "pwm-leds";
++ green-d12 {
++ label = "green:d12";
++ color = <LED_COLOR_ID_GREEN>;
++ pwms = <&pwm0 0 7812500 PWM_POLARITY_INVERTED>;
++ active-low = <1>;
++ max-brightness = <255>;
++ linux,default-trigger = "none";
++ };
++
++ green-d2 {
++ label = "green:d2";
++ color = <LED_COLOR_ID_GREEN>;
++ pwms = <&pwm0 1 7812500 PWM_POLARITY_INVERTED>;
++ active-low = <1>;
++ max-brightness = <255>;
++ linux,default-trigger = "none";
++ };
++
++ red-d2 {
++ label = "red:d2";
++ color = <LED_COLOR_ID_RED>;
++ pwms = <&pwm0 2 7812500 PWM_POLARITY_INVERTED>;
++ active-low = <1>;
++ max-brightness = <255>;
++ linux,default-trigger = "none";
++ };
++
++ blue-d2 {
++ label = "blue:d2";
++ color = <LED_COLOR_ID_BLUE>;
++ pwms = <&pwm0 3 7812500 PWM_POLARITY_INVERTED>;
++ active-low = <1>;
++ max-brightness = <255>;
++ linux,default-trigger = "none";
++ };
++ };
++
+ hfclk: hfclk {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+--
+2.7.4
+
--- /dev/null
+From 14ede57943bc4209755d08daf93ac7be967d7fbe Mon Sep 17 00:00:00 2001
+From: David Abdurachmanov <david.abdurachmanov@sifive.com>
+Date: Mon, 13 Sep 2021 02:18:30 -0700
+Subject: [PATCH 4/7] riscv: sifive: unmatched: add gpio-poweroff node
+
+Add gpio-poweroff node to allow powering off the system.
+
+Signed-off-by: David Abdurachmanov <david.abdurachmanov@sifive.com>
+---
+ arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts b/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts
+index 200d022..4584676 100644
+@@ -84,6 +85,11 @@
+ clock-frequency = <RTCCLK_FREQ>;
+ clock-output-names = "rtcclk";
+ };
++
++ gpio-poweroff {
++ compatible = "gpio-poweroff";
++ gpios = <&gpio 2 GPIO_ACTIVE_LOW>;
++ };
+ };
+
+ &uart0 {
+--
+2.7.4
+
--- /dev/null
+From 082e93a136eafb444e93e518115aac349304b77e Mon Sep 17 00:00:00 2001
+From: David Abdurachmanov <david.abdurachmanov@sifive.com>
+Date: Fri, 5 Jun 2020 07:02:10 +0000
+Subject: [PATCH 5/7] SiFive HiFive Unleashed: Add PWM LEDs (D1, D2, D3, D4)
+
+By default no functions are assigned to LEDs. It's up to user/distribution
+to provide udev rules to configure them.
+
+Signed-off-by: David Abdurachmanov <david.abdurachmanov@sifive.com>
+---
+ .../riscv/boot/dts/sifive/hifive-unleashed-a00.dts | 32 ++++++++++++++++++++++
+ 1 file changed, 32 insertions(+)
+
+diff --git a/arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts b/arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts
+index 60846e8..a99aded 100644
+--- a/arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts
++++ b/arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts
+@@ -3,6 +3,7 @@
+
+ #include "fu540-c000.dtsi"
+ #include <dt-bindings/gpio/gpio.h>
++#include <dt-bindings/pwm/pwm.h>
+
+ /* Clock frequency (in Hz) of the PCB crystal for rtcclk */
+ #define RTCCLK_FREQ 1000000
+@@ -27,6 +28,37 @@
+ };
+
+ soc {
++ pwmleds {
++ compatible = "pwm-leds";
++ d1 {
++ label = "green:d1";
++ pwms = <&pwm0 0 7812500 PWM_POLARITY_INVERTED>;
++ active-low = <1>;
++ max-brightness = <255>;
++ linux,default-trigger = "none";
++ };
++ d2 {
++ label = "green:d2";
++ pwms = <&pwm0 1 7812500 PWM_POLARITY_INVERTED>;
++ active-low = <1>;
++ max-brightness = <255>;
++ linux,default-trigger = "none";
++ };
++ d3 {
++ label = "green:d3";
++ pwms = <&pwm0 2 7812500 PWM_POLARITY_INVERTED>;
++ active-low = <1>;
++ max-brightness = <255>;
++ linux,default-trigger = "none";
++ };
++ d4 {
++ label = "green:d4";
++ pwms = <&pwm0 3 7812500 PWM_POLARITY_INVERTED>;
++ active-low = <1>;
++ max-brightness = <255>;
++ linux,default-trigger = "none";
++ };
++ };
+ };
+
+ hfclk: hfclk {
+--
+2.7.4
+
--- /dev/null
+From d3cf2859a056273400fbdf9d389b75750ff6ca5e Mon Sep 17 00:00:00 2001
+From: David Abdurachmanov <david.abdurachmanov@sifive.com>
+Date: Fri, 14 May 2021 05:27:51 -0700
+Subject: [PATCH 6/7] riscv: sifive: unleashed: define opp table (cpufreq)
+
+Source: https://github.com/sifive/riscv-linux/commits/dev/paulw/cpufreq-dt-aloe-v5.3-rc4
+
+Signed-off-by: David Abdurachmanov <david.abdurachmanov@sifive.com>
+---
+ arch/riscv/Kconfig | 8 +++++
+ arch/riscv/boot/dts/sifive/fu540-c000.dtsi | 5 ++++
+ .../riscv/boot/dts/sifive/hifive-unleashed-a00.dts | 34 ++++++++++++++++++++++
+ 3 files changed, 47 insertions(+)
+
+diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
+index 3c3647a..7ae47ca 100644
+--- a/arch/riscv/Kconfig
++++ b/arch/riscv/Kconfig
+@@ -550,6 +550,14 @@ config BUILTIN_DTB
+ depends on OF
+ default y if XIP_KERNEL
+
++menu "CPU Power Management"
++
++source "drivers/cpuidle/Kconfig"
++
++source "drivers/cpufreq/Kconfig"
++
++endmenu
++
+ menu "Power management options"
+
+ source "kernel/power/Kconfig"
+diff --git a/arch/riscv/boot/dts/sifive/fu540-c000.dtsi b/arch/riscv/boot/dts/sifive/fu540-c000.dtsi
+index 7db8610..023a8fd 100644
+--- a/arch/riscv/boot/dts/sifive/fu540-c000.dtsi
++++ b/arch/riscv/boot/dts/sifive/fu540-c000.dtsi
+@@ -30,6 +30,7 @@
+ i-cache-size = <16384>;
+ reg = <0>;
+ riscv,isa = "rv64imac";
++ clocks = <&prci PRCI_CLK_COREPLL>;
+ status = "disabled";
+ cpu0_intc: interrupt-controller {
+ #interrupt-cells = <1>;
+@@ -54,6 +55,7 @@
+ reg = <1>;
+ riscv,isa = "rv64imafdc";
+ tlb-split;
++ clocks = <&prci PRCI_CLK_COREPLL>;
+ next-level-cache = <&l2cache>;
+ cpu1_intc: interrupt-controller {
+ #interrupt-cells = <1>;
+@@ -78,6 +80,7 @@
+ reg = <2>;
+ riscv,isa = "rv64imafdc";
+ tlb-split;
++ clocks = <&prci PRCI_CLK_COREPLL>;
+ next-level-cache = <&l2cache>;
+ cpu2_intc: interrupt-controller {
+ #interrupt-cells = <1>;
+@@ -102,6 +105,7 @@
+ reg = <3>;
+ riscv,isa = "rv64imafdc";
+ tlb-split;
++ clocks = <&prci PRCI_CLK_COREPLL>;
+ next-level-cache = <&l2cache>;
+ cpu3_intc: interrupt-controller {
+ #interrupt-cells = <1>;
+@@ -126,6 +130,7 @@
+ reg = <4>;
+ riscv,isa = "rv64imafdc";
+ tlb-split;
++ clocks = <&prci PRCI_CLK_COREPLL>;
+ next-level-cache = <&l2cache>;
+ cpu4_intc: interrupt-controller {
+ #interrupt-cells = <1>;
+diff --git a/arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts b/arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts
+index a99aded..b1e7f85 100644
+--- a/arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts
++++ b/arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts
+@@ -78,6 +78,40 @@
+ compatible = "gpio-restart";
+ gpios = <&gpio 10 GPIO_ACTIVE_LOW>;
+ };
++
++ fu540_c000_opp_table: opp-table {
++ compatible = "operating-points-v2";
++ opp-shared;
++
++ opp-350000000 {
++ opp-hz = /bits/ 64 <350000000>;
++ };
++ opp-700000000 {
++ opp-hz = /bits/ 64 <700000000>;
++ };
++ opp-999999999 {
++ opp-hz = /bits/ 64 <999999999>;
++ };
++ opp-1400000000 {
++ opp-hz = /bits/ 64 <1400000000>;
++ };
++ };
++};
++
++&cpu0 {
++ operating-points-v2 = <&fu540_c000_opp_table>;
++};
++&cpu1 {
++ operating-points-v2 = <&fu540_c000_opp_table>;
++};
++&cpu2 {
++ operating-points-v2 = <&fu540_c000_opp_table>;
++};
++&cpu3 {
++ operating-points-v2 = <&fu540_c000_opp_table>;
++};
++&cpu4 {
++ operating-points-v2 = <&fu540_c000_opp_table>;
+ };
+
+ &uart0 {
+--
+2.7.4
+
--- /dev/null
+From 512834e96c3dd8778278836e2d132d9381c1f129 Mon Sep 17 00:00:00 2001
+From: Stanislaw Kardach <kda@semihalf.com>
+Date: Mon, 12 Apr 2021 13:10:12 +0200
+Subject: [PATCH 7/7] riscv: enable generic PCI resource mapping
+
+Enable the PCI resource mapping on RISC-V using the generic framework.
+This allows userspace applications to mmap PCI resources using
+/sys/devices/pci*/*/resource* interface.
+The mmap has been tested with Intel x520-DA2 NIC card on a HiFive
+Unmatched board (SiFive FU740 SoC).
+
+Signed-off-by: Stanislaw Kardach <kda@semihalf.com>
+---
+ arch/riscv/include/asm/pci.h | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/arch/riscv/include/asm/pci.h b/arch/riscv/include/asm/pci.h
+index 658e112..7fd52a3 100644
+--- a/arch/riscv/include/asm/pci.h
++++ b/arch/riscv/include/asm/pci.h
+@@ -18,6 +18,8 @@
+ /* RISC-V shim does not initialize PCI bus */
+ #define pcibios_assign_all_busses() 1
+
++#define ARCH_GENERIC_PCI_MMAP_RESOURCE 1
++
+ extern int isa_dma_bridge_buggy;
+
+ #ifdef CONFIG_PCI
+--
+2.7.4
+
--- /dev/null
+From mboxrd@z Thu Jan 1 00:00:00 1970
+Return-Path: <SRS0=S+R5=LD=lists.infradead.org=linux-riscv-bounces+linux-riscv=archiver.kernel.org@kernel.org>
+X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on
+ aws-us-west-2-korg-lkml-1.web.codeaurora.org
+X-Spam-Level:
+X-Spam-Status: No, score=-21.9 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH,
+ DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,
+ INCLUDES_PATCH,MAILING_LIST_MULTI,MENTIONS_GIT_HOSTING,MSGID_FROM_MTA_HEADER,
+ SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=unavailable
+ autolearn_force=no version=3.4.0
+Received: from mail.kernel.org (mail.kernel.org [198.145.29.99])
+ by smtp.lore.kernel.org (Postfix) with ESMTP id 9A34CC48BCD
+ for <linux-riscv@archiver.kernel.org>; Wed, 9 Jun 2021 12:50:08 +0000 (UTC)
+Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133])
+ (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
+ (No client certificate requested)
+ by mail.kernel.org (Postfix) with ESMTPS id 69795611C9
+ for <linux-riscv@archiver.kernel.org>; Wed, 9 Jun 2021 12:50:08 +0000 (UTC)
+DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 69795611C9
+Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=wdc.com
+Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-riscv-bounces+linux-riscv=archiver.kernel.org@lists.infradead.org
+DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed;
+ d=lists.infradead.org; s=bombadil.20210309; h=Sender:
+ Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post:
+ List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:
+ Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description:
+ Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:
+ List-Owner; bh=64gRxQ9bX8C6wjLq0KuJ2lv98bQdXijt0LPnNpch3NU=; b=rgeSpoSWQ+Nca2
+ 9PLsgI7dOYVdTu48CyVJStiizsvIvVFN2rBAgELHF2nRCCtoSiPMxgcpCKtDcm7sh9lC8AblCoBjN
+ LXiPRHVYJAcRNiWiQ0qOTqHdTbezFdzSjNOs6drbaiI4B8AZtychw1hP+ubsb5czAaz6510OEVct/
+ h5M4Tlljcn/WIyulBd/tnuUOZPT0XL6rb2+TvRQvjXDBFHN+bWqP8OjXKnE1FTvy5MF8OTlUgI6wr
+ 3f4t/eS/PPbtXRD5raJzEwEQLJ6XY6NJABs40tKpWZNuUaqTfmonNdbP9y1htWhByhsAk+fw5WK/C
+ /KocvM6IzPmqGIBWcTdQ==;
+Received: from localhost ([::1] helo=bombadil.infradead.org)
+ by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux))
+ id 1lqxeS-00Do8i-Hj; Wed, 09 Jun 2021 12:49:44 +0000
+Received: from esa4.hgst.iphmx.com ([216.71.154.42])
+ by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux))
+ id 1lqx5h-00DbCQ-K0
+ for linux-riscv@lists.infradead.org; Wed, 09 Jun 2021 12:13:51 +0000
+DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple;
+ d=wdc.com; i=@wdc.com; q=dns/txt; s=dkim.wdc.com;
+ t=1623240829; x=1654776829;
+ h=from:to:cc:subject:date:message-id:in-reply-to:
+ references:content-transfer-encoding:mime-version;
+ bh=s4va/Owvq7MQI8rUsD/e02RmaYfJNzYNcxlXspGRY7g=;
+ b=G5GD9eN+rv669E7jyRnRAt0jw83CxhIrSiDIjXuPmhWyMhKeQGD7ACRm
+ ii6o0zmOREhGihtwB6X/xpY/2ZvK+cxcHmJXa+Ykyn8QN+/YKFtg3svfj
+ eiTN7U/mEozCoGNd1wXu59RQj11Xz60DN/qEUlYFaL6SjukUgifFVgbvG
+ uUj8AM8+xf1jKHi3Q/6nVPpJX8uiW/NPFHrwI8hxUwYr9viQwxXvc7FNr
+ fR8bH2c/HiGacGYEHosgP0WT//d9Huqn4JNINvjidK4ZSJ74cXlr8KwMG
+ 8snmfx4UjEWMhK1lCYalJEU7nxXFfih/6DMuFRorETpWQ+424BAKUJdDH Q==;
+IronPort-SDR: pYhRsIZkhfmi45K4HfnZj39kxfUGpxs1e+q+Wh8kDE+ySh35HkJaaUcpP04mb7VeIVtPRx/h6Q
+ imv6sn8fYo/V8ezHAq4jpd1QadqInKi1ubLnCE3Zy7GnhVBepoV6FbI14Y01V+5QIUwYdFNcGG
+ RsxDOTQyU5AljH0Rc6WkrpdVf5jsrXXMddmlDdi6QsfKGy7MwQ/NYojNIqyLhRSgu5w2uTIE7X
+ atSbjb8j2a+EJUY0WgYTGfNHKCdQLAhjcsWZgU7Iu0vSaBU6A7seCkqun24dvF/zYuzEj7wedD
+ TvE=
+X-IronPort-AV: E=Sophos;i="5.83,260,1616428800"; d="scan'208";a="170575129"
+Received: from mail-dm6nam12lp2169.outbound.protection.outlook.com (HELO
+ NAM12-DM6-obe.outbound.protection.outlook.com) ([104.47.59.169])
+ by ob1.hgst.iphmx.com with ESMTP; 09 Jun 2021 20:13:48 +0800
+ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none;
+ b=hrlr4Qi66FmbQW45zI7QeA9nEYSvxO+tR++vUyFHxjRqnr6WtjKgHM8hPpp8oHXaK82U0+KQUc2+WjLbe8LihexXFQs5zRwBDwuArmkKt85cL3utD3OBzTkr4A9ZhRS5mzztnn9kvTFNplPjSydXPetJQIZ9WKmihJrdeaGQ+zQ//6TdDWVpLyBbqiBVUbUwlKQbpbbfHvzQCHYQbIiUcGn4vaSXYp2Xp1Z5yYVtrfDK+TemKG/8fKQoJjg/tdmDtQ97Cgw7nX6Oc9kdmoTIxFilMy4XjPciPcNOPdLmboGCt6+TMBeftLc1VFNnr7PwuxOogv4I7eJ/P9UaK57k5A==
+ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com;
+ s=arcselector9901;
+ h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;
+ bh=Ibi36Vj2s7bu56DZaU1uSl4xNA3OB2FHlI/rBKn+8xo=;
+ b=CE3o+0GFLPMQuw0AK1IRf/vX00diXsjayn0MmpS7ntSVXgxXIAPT9aDtk7x0NovJBTk2LHI5Mtxvz6SwVnJzUqZmNsXUktEj5Iwdd8EPIIxgCOjugo/6WC0FqaFKNvJB4hQ0tjFxv+J5DexSJ8+mPx6Ucr4DwtUXrCWzOeXyF5YK68mU5FgttbyutW3CGsGkPgaPAdOxXOgJqyYu8X25unmzG12Jq2xC4oVKsbA+RfDiaMKm97q2Bhy+LcgJNS6/ktlFKSOVu1HQ0POYgba3mtldN3vg73wLbxrfsdoe4261aJpkM05GJFDzdTNp4t3rEGhNuLR1+8OmKfLlPeSU9w==
+ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass
+ smtp.mailfrom=wdc.com; dmarc=pass action=none header.from=wdc.com; dkim=pass
+ header.d=wdc.com; arc=none
+DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
+ d=sharedspace.onmicrosoft.com; s=selector2-sharedspace-onmicrosoft-com;
+ h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;
+ bh=Ibi36Vj2s7bu56DZaU1uSl4xNA3OB2FHlI/rBKn+8xo=;
+ b=Z76YsVxTHK6/ta19C5vwaBPYmtDa2GIM/ml4myQZfIaHFNzXPzZ+PFcYy/Xf1Ixd0GZHcuSZQYgs/SPHWATh+rOWBAislGv1zmSAG/g0tiDckB8WaCwh1e3qGW4ZmUTmAU7dxB0vn0pRSLTnc1hdCUZ73buM78qo9qwsQZv41d0=
+Authentication-Results: dabbelt.com; dkim=none (message not signed)
+ header.d=none;dabbelt.com; dmarc=none action=none header.from=wdc.com;
+Received: from CO6PR04MB7812.namprd04.prod.outlook.com (2603:10b6:303:138::6)
+ by CO6PR04MB7794.namprd04.prod.outlook.com (2603:10b6:303:13f::7)
+ with Microsoft SMTP Server (version=TLS1_2,
+ cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4219.21; Wed, 9 Jun
+ 2021 12:13:47 +0000
+Received: from CO6PR04MB7812.namprd04.prod.outlook.com
+ ([fe80::a153:b7f8:c87f:89f8]) by CO6PR04MB7812.namprd04.prod.outlook.com
+ ([fe80::a153:b7f8:c87f:89f8%9]) with mapi id 15.20.4219.021; Wed, 9 Jun 2021
+ 12:13:47 +0000
+From: Anup Patel <anup.patel@wdc.com>
+To: Palmer Dabbelt <palmer@dabbelt.com>,
+ Palmer Dabbelt <palmerdabbelt@google.com>,
+ Paul Walmsley <paul.walmsley@sifive.com>, Albert Ou <aou@eecs.berkeley.edu>
+Cc: Atish Patra <atish.patra@wdc.com>,
+ Alistair Francis <Alistair.Francis@wdc.com>,
+ Anup Patel <anup@brainfault.org>, linux-riscv@lists.infradead.org,
+ linux-kernel@vger.kernel.org, Anup Patel <anup.patel@wdc.com>
+Subject: [PATCH v7 1/1] RISC-V: Use SBI SRST extension when available
+Date: Wed, 9 Jun 2021 17:43:22 +0530
+Message-Id: <20210609121322.3058-2-anup.patel@wdc.com>
+X-Mailer: git-send-email 2.25.1
+In-Reply-To: <20210609121322.3058-1-anup.patel@wdc.com>
+References: <20210609121322.3058-1-anup.patel@wdc.com>
+X-Originating-IP: [122.172.176.125]
+X-ClientProxiedBy: MA1PR0101CA0036.INDPRD01.PROD.OUTLOOK.COM
+ (2603:1096:a00:22::22) To CO6PR04MB7812.namprd04.prod.outlook.com
+ (2603:10b6:303:138::6)
+MIME-Version: 1.0
+X-MS-Exchange-MessageSentRepresentingType: 1
+Received: from wdc.com (122.172.176.125) by
+ MA1PR0101CA0036.INDPRD01.PROD.OUTLOOK.COM (2603:1096:a00:22::22) with
+ Microsoft SMTP Server (version=TLS1_2,
+ cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4219.21 via Frontend
+ Transport; Wed, 9 Jun 2021 12:13:44 +0000
+X-MS-PublicTrafficType: Email
+X-MS-Office365-Filtering-Correlation-Id: 17406ef0-e8d7-4dc3-eee9-08d92b40085b
+X-MS-TrafficTypeDiagnostic: CO6PR04MB7794:
+X-MS-Exchange-Transport-Forked: True
+X-Microsoft-Antispam-PRVS: <CO6PR04MB77945CDDD1538EFCA060925B8D369@CO6PR04MB7794.namprd04.prod.outlook.com>
+WDCIPOUTBOUND: EOP-TRUE
+X-MS-Oob-TLC-OOBClassifiers: OLM:2887;
+X-MS-Exchange-SenderADCheck: 1
+X-Microsoft-Antispam: BCL:0;
+X-Microsoft-Antispam-Message-Info: IxB9oKL9LkeXCQ7mZ1A5qIcKlICr/TPZ/8V0ErM5hbqnvfK6Mf0mQL0tqqlJAOvLpCEVIyX7FllGqSlWsNG3ik/WbbDYQb9wAFCuFSAlGAeGppnJjJf0zfDAmp4NONB7kshKqtUYfGltTHTkV4ni+VEwWf/Q3T4vA0k3Jkt34iZFi9tOsSHkSWxPTsQyviBdCp3/36ZCVhYs6bXkf8sh0sA4Ql/l8t2zpcEUwjAm14ie3hOUBEp1W9qOz6StmR4xyl+zy49U38byeHu5XDF/qFT8FI4WclwFwxbDeTm8cU7MMg4D0xeR0Ytm2wVrgAdiapgQYLmxPIjIG96TRTbCupyuaJXmYcI6/x27PtiQYFwcpbRUjXDKRVX2WW74WHm88OOlTexD/OsbGHD6PVnc+InniK38yNcx06U9fIkDGSYWrJqLysALlO0V5gfkc35Fhttum638ES0S2sldGkFufM372EZeooczK7jeLMpoOTAnaLtPdTCGsHnnEDDbOK7NiptQlrLMhrNQ/70harAMmB6Vvdl+jvJi34DsuX+57WeQU8Ya1cyVxzFkWX2DwvPRsAnp/VNHzeQLc5MAIUYpwQvkJBcqihYMKrLMNOT94HmxBYmY2bcW/K9fXrPQ/whyJ5HoQuxydeiy7+QKg6FWnhguTACaaTKGKKIDIlfYA5FXYlZOaQ2iJFtiZP1GbxQnDEwz4SfGgCgBdiwqFm1NfGG7wRhqQa/Kgp3jBTHwaysCwcWu/Xdz/yiCV4lfQD/PTiOr5hmtld29G7WVDy9m6Q==
+X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:;
+ IPV:NLI; SFV:NSPM; H:CO6PR04MB7812.namprd04.prod.outlook.com; PTR:; CAT:NONE;
+ SFS:(4636009)(396003)(39860400002)(136003)(346002)(366004)(376002)(8676002)(316002)(55236004)(38100700002)(38350700002)(110136005)(86362001)(54906003)(4326008)(956004)(966005)(478600001)(26005)(186003)(55016002)(8936002)(2616005)(7696005)(52116002)(16526019)(5660300002)(8886007)(6666004)(1076003)(66476007)(66556008)(36756003)(66946007)(83380400001)(2906002)(44832011);
+ DIR:OUT; SFP:1102;
+X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1
+X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?2kfiFAcyFkAMcwkoCUqJGxdVnwsuTm5WWTXA4Pq0ZNAjWsfYI4MNugTA9f8C?=
+ =?us-ascii?Q?WaQrYEizTkvIlgRDqeKVRS0vaMaeU9XaSzO6UAJMnd0jY3BzkJgKUU9xj1aU?=
+ =?us-ascii?Q?vmwXKxCS+vZ2VKgLifaU1JCeemiJqV9aW+6AJEycq722bz9yXmcaJsaHWtX3?=
+ =?us-ascii?Q?4sSoLeVPvfzwzDZEEoGsZZi1G7inY2imGEgY/r3m5/qYvavJQ3An4e4sjEqZ?=
+ =?us-ascii?Q?Z4a4FAd/6c3X8cjmNwGvgWoAIM5WaJYFQe30MQ79alCUfZyiKB4tR0+5OGFd?=
+ =?us-ascii?Q?P/rQ169Z644JNKKcEabikpL7qZZJ6OMPTS7XR9x/7GzWOJ7soV3/3I2tfCdi?=
+ =?us-ascii?Q?xVsOK1DRF4y6gi5udvnb+Uu1U5wC1NlT0U/+TrnTSeY/IuLmMgFUysw+fQ+D?=
+ =?us-ascii?Q?DIVN44TKrMoEZKx9SKcx4jYpUGYvaCH4sVOAx3zWQC0Oz1Nz3/a/isywpQW9?=
+ =?us-ascii?Q?1I1kl/2N97K0EoWIPf6qPjyLVWXg1dOHfk6SjNW64JIIPUNnM3h7k2igDX3o?=
+ =?us-ascii?Q?d7lWyFfzoWhNC7opS71uzta+ti8aHxo+xzvYvf2wLb+fdyEP9t+oQVrEQYIW?=
+ =?us-ascii?Q?rAUKPqjEfAZOYBB28SaabfVt/QF6hFfV/0yJ/JV/Ie8ivC1t6iO+QZQscV7K?=
+ =?us-ascii?Q?d4Pg+xVSE+m+LsgNwO36cTTe6hSLBPnWU1NMOW2cxTRKGm0Lwd2HyjyKTBMD?=
+ =?us-ascii?Q?BcnKo9GXAVgOAGCG5cwEBN76q6sXxbWy0pjni3O2bLYBg4CIYCB/JNzOIfE0?=
+ =?us-ascii?Q?Toz6Qwc4aw5NxRLqz9IygGT6ZunRVUWUsgJrIt5U20elX+lRmtX1cqrQNTON?=
+ =?us-ascii?Q?ZHzuAI587pB0zK4EiS25hc9C8RtwjlY67heuMsYZDww5TU+NV3+0WN1/NrCX?=
+ =?us-ascii?Q?3kB7O188tvm1sWVhCaC6hk9s19nKGRgMS5OHXTMxhmyw1Dn/zorMYff3r9ZE?=
+ =?us-ascii?Q?sNiBI7fwru/Jsxt2/jNCpFaEYUa9JkrdSse76BXo/UxLALnxO3bzpym3Dq+T?=
+ =?us-ascii?Q?s4uEA8UncKM0e+Mhp9hW1c3DR61Qjj8wb+LV3XB0qYK/1rHs8IDdJ97tw1fp?=
+ =?us-ascii?Q?Ux9SlgS9YE2bEp6wxcX6TpA5DoYjqdlK50/4/DZ3YTXWlPTaQbt/j36TbEgZ?=
+ =?us-ascii?Q?hhIV08WX7EDjBz1QrFRppEtBghOJikHLdvPo6GnZkHNQ9cxaa8Jrk0iypK4d?=
+ =?us-ascii?Q?bMj47kiugWCGY+ZW2ioGV1GgH1aZEvAukQgTiAAiyGU83td11Q5Pv2N5ytvk?=
+ =?us-ascii?Q?i+Ux/DUoeU4VyqYnb69asjdyKI5RzIxQPdQAQ7x/TBlyPp/Yj2/v31b6lCYT?=
+ =?us-ascii?Q?b1iYdeIKK+6I6A+e/EUnPOKC?=
+X-OriginatorOrg: wdc.com
+X-MS-Exchange-CrossTenant-Network-Message-Id: 17406ef0-e8d7-4dc3-eee9-08d92b40085b
+X-MS-Exchange-CrossTenant-AuthSource: CO6PR04MB7812.namprd04.prod.outlook.com
+X-MS-Exchange-CrossTenant-AuthAs: Internal
+X-MS-Exchange-CrossTenant-OriginalArrivalTime: 09 Jun 2021 12:13:47.1304 (UTC)
+X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted
+X-MS-Exchange-CrossTenant-Id: b61c8803-16f3-4c35-9b17-6f65f441df86
+X-MS-Exchange-CrossTenant-MailboxType: HOSTED
+X-MS-Exchange-CrossTenant-UserPrincipalName: rHld9c5jovIZF30ZL04ehEJ81O0isWetsUM3vlp/0cN1LoJ5z8guKzUTANDGVGM0Eua+2cZ1jQGTC49NwWH4hA==
+X-MS-Exchange-Transport-CrossTenantHeadersStamped: CO6PR04MB7794
+X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3
+X-CRM114-CacheID: sfid-20210609_051349_766689_30430D67
+X-CRM114-Status: GOOD ( 15.29 )
+X-BeenThere: linux-riscv@lists.infradead.org
+X-Mailman-Version: 2.1.34
+Precedence: list
+List-Id: <linux-riscv.lists.infradead.org>
+List-Unsubscribe: <http://lists.infradead.org/mailman/options/linux-riscv>,
+ <mailto:linux-riscv-request@lists.infradead.org?subject=unsubscribe>
+List-Archive: <http://lists.infradead.org/pipermail/linux-riscv/>
+List-Post: <mailto:linux-riscv@lists.infradead.org>
+List-Help: <mailto:linux-riscv-request@lists.infradead.org?subject=help>
+List-Subscribe: <http://lists.infradead.org/mailman/listinfo/linux-riscv>,
+ <mailto:linux-riscv-request@lists.infradead.org?subject=subscribe>
+Content-Type: text/plain; charset="us-ascii"
+Content-Transfer-Encoding: 7bit
+Sender: "linux-riscv" <linux-riscv-bounces@lists.infradead.org>
+Errors-To: linux-riscv-bounces+linux-riscv=archiver.kernel.org@lists.infradead.org
+
+The SBI SRST extension provides a standard way to poweroff and
+reboot the system irrespective to whether Linux RISC-V S-mode
+is running natively (HS-mode) or inside Guest/VM (VS-mode).
+
+The SBI SRST extension is available in the SBI v0.3 specification.
+(Refer, https://github.com/riscv/riscv-sbi-doc/releases/tag/v0.3.0-rc1)
+
+This patch extends Linux RISC-V SBI implementation to detect
+and use SBI SRST extension.
+
+Signed-off-by: Anup Patel <anup.patel@wdc.com>
+Reviewed-by: Atish Patra <atish.patra@wdc.com>
+---
+ arch/riscv/include/asm/sbi.h | 24 ++++++++++++++++++++++++
+ arch/riscv/kernel/sbi.c | 35 +++++++++++++++++++++++++++++++++++
+ 2 files changed, 59 insertions(+)
+
+diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h
+index 0d42693cb65e..289621da4a2a 100644
+--- a/arch/riscv/include/asm/sbi.h
++++ b/arch/riscv/include/asm/sbi.h
+@@ -27,6 +27,7 @@ enum sbi_ext_id {
+ SBI_EXT_IPI = 0x735049,
+ SBI_EXT_RFENCE = 0x52464E43,
+ SBI_EXT_HSM = 0x48534D,
++ SBI_EXT_SRST = 0x53525354,
+ };
+
+ enum sbi_ext_base_fid {
+@@ -70,6 +71,21 @@ enum sbi_hsm_hart_status {
+ SBI_HSM_HART_STATUS_STOP_PENDING,
+ };
+
++enum sbi_ext_srst_fid {
++ SBI_EXT_SRST_RESET = 0,
++};
++
++enum sbi_srst_reset_type {
++ SBI_SRST_RESET_TYPE_SHUTDOWN = 0,
++ SBI_SRST_RESET_TYPE_COLD_REBOOT,
++ SBI_SRST_RESET_TYPE_WARM_REBOOT,
++};
++
++enum sbi_srst_reset_reason {
++ SBI_SRST_RESET_REASON_NONE = 0,
++ SBI_SRST_RESET_REASON_SYS_FAILURE,
++};
++
+ #define SBI_SPEC_VERSION_DEFAULT 0x1
+ #define SBI_SPEC_VERSION_MAJOR_SHIFT 24
+ #define SBI_SPEC_VERSION_MAJOR_MASK 0x7f
+@@ -148,6 +164,14 @@ static inline unsigned long sbi_minor_version(void)
+ return sbi_spec_version & SBI_SPEC_VERSION_MINOR_MASK;
+ }
+
++/* Make SBI version */
++static inline unsigned long sbi_mk_version(unsigned long major,
++ unsigned long minor)
++{
++ return ((major & SBI_SPEC_VERSION_MAJOR_MASK) <<
++ SBI_SPEC_VERSION_MAJOR_SHIFT) | minor;
++}
++
+ int sbi_err_map_linux_errno(int err);
+ #else /* CONFIG_RISCV_SBI */
+ static inline int sbi_remote_fence_i(const unsigned long *hart_mask) { return -1; }
+diff --git a/arch/riscv/kernel/sbi.c b/arch/riscv/kernel/sbi.c
+index 7402a417f38e..9a84f0cb5175 100644
+--- a/arch/riscv/kernel/sbi.c
++++ b/arch/riscv/kernel/sbi.c
+@@ -7,6 +7,7 @@
+
+ #include <linux/init.h>
+ #include <linux/pm.h>
++#include <linux/reboot.h>
+ #include <asm/sbi.h>
+ #include <asm/smp.h>
+
+@@ -501,6 +502,32 @@ int sbi_remote_hfence_vvma_asid(const unsigned long *hart_mask,
+ }
+ EXPORT_SYMBOL(sbi_remote_hfence_vvma_asid);
+
++static void sbi_srst_reset(unsigned long type, unsigned long reason)
++{
++ sbi_ecall(SBI_EXT_SRST, SBI_EXT_SRST_RESET, type, reason,
++ 0, 0, 0, 0);
++ pr_warn("%s: type=0x%lx reason=0x%lx failed\n",
++ __func__, type, reason);
++}
++
++static int sbi_srst_reboot(struct notifier_block *this,
++ unsigned long mode, void *cmd)
++{
++ sbi_srst_reset((mode == REBOOT_WARM || mode == REBOOT_SOFT) ?
++ SBI_SRST_RESET_TYPE_WARM_REBOOT :
++ SBI_SRST_RESET_TYPE_COLD_REBOOT,
++ SBI_SRST_RESET_REASON_NONE);
++ return NOTIFY_DONE;
++}
++
++static struct notifier_block sbi_srst_reboot_nb;
++
++static void sbi_srst_power_off(void)
++{
++ sbi_srst_reset(SBI_SRST_RESET_TYPE_SHUTDOWN,
++ SBI_SRST_RESET_REASON_NONE);
++}
++
+ /**
+ * sbi_probe_extension() - Check if an SBI extension ID is supported or not.
+ * @extid: The extension ID to be probed.
+@@ -608,6 +635,14 @@ void __init sbi_init(void)
+ } else {
+ __sbi_rfence = __sbi_rfence_v01;
+ }
++ if ((sbi_spec_version >= sbi_mk_version(0, 3)) &&
++ (sbi_probe_extension(SBI_EXT_SRST) > 0)) {
++ pr_info("SBI SRST extension detected\n");
++ pm_power_off = sbi_srst_power_off;
++ sbi_srst_reboot_nb.notifier_call = sbi_srst_reboot;
++ sbi_srst_reboot_nb.priority = 192;
++ register_restart_handler(&sbi_srst_reboot_nb);
++ }
+ } else {
+ __sbi_set_timer = __sbi_set_timer_v01;
+ __sbi_send_ipi = __sbi_send_ipi_v01;
+--
+2.25.1
+
+
+_______________________________________________
+linux-riscv mailing list
+linux-riscv@lists.infradead.org
+http://lists.infradead.org/mailman/listinfo/linux-riscv
+