kernel/starfive: restore files for v6.12

This is an automatically generated commit which aids following Kernel patch
history, as git will see the move and copy as a rename thus defeating the
purpose.

For the original discussion see:
https://lists.openwrt.org/pipermail/openwrt-devel/2023-October/041673.html

Signed-off-by: Zhihao Xu <ngc7331@outlook.com>
This commit is contained in:
Zhihao Xu 2026-02-17 20:11:40 +08:00 committed by Zoltan HERPAI
parent 6a7cb7b65d
commit 2c089a236f
57 changed files with 11743 additions and 0 deletions

View File

@ -0,0 +1,641 @@
CONFIG_64BIT=y
# CONFIG_ACPI is not set
CONFIG_AMBA_PL08X=y
# CONFIG_ARCH_CANAAN is not set
CONFIG_ARCH_DMA_ADDR_T_64BIT=y
CONFIG_ARCH_DMA_DEFAULT_COHERENT=y
CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE=y
# CONFIG_ARCH_MICROCHIP is not set
CONFIG_ARCH_MMAP_RND_BITS=18
CONFIG_ARCH_MMAP_RND_BITS_MAX=24
CONFIG_ARCH_MMAP_RND_BITS_MIN=18
CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=17
CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y
CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y
CONFIG_ARCH_PROC_KCORE_TEXT=y
# CONFIG_ARCH_RV32I is not set
CONFIG_ARCH_RV64I=y
CONFIG_ARCH_SELECT_MEMORY_MODEL=y
CONFIG_ARCH_SIFIVE=y
# CONFIG_ARCH_SOPHGO is not set
CONFIG_ARCH_SPARSEMEM_ENABLE=y
CONFIG_ARCH_STACKWALK=y
CONFIG_ARCH_STARFIVE=y
CONFIG_ARCH_SUSPEND_POSSIBLE=y
# CONFIG_ARCH_THEAD is not set
CONFIG_ARCH_WANTS_NO_INSTR=y
CONFIG_ARCH_WANTS_THP_SWAP=y
CONFIG_ARM_AMBA=y
# CONFIG_ARM_MHU_V2 is not set
CONFIG_ASN1=y
CONFIG_AUXILIARY_BUS=y
# CONFIG_AX45MP_L2_CACHE is not set
CONFIG_BLK_MQ_PCI=y
CONFIG_BLK_MQ_VIRTIO=y
CONFIG_BLK_PM=y
CONFIG_BUFFER_HEAD=y
# CONFIG_BUILTIN_DTB is not set
CONFIG_CC_HAVE_STACKPROTECTOR_TLS=y
CONFIG_CHECKPOINT_RESTORE=y
CONFIG_CLKSRC_MMIO=y
CONFIG_CLK_ANALOGBITS_WRPLL_CLN28HPC=y
CONFIG_CLK_SIFIVE=y
CONFIG_CLK_SIFIVE_PRCI=y
CONFIG_CLK_STARFIVE_JH7100=y
CONFIG_CLK_STARFIVE_JH7100_AUDIO=y
CONFIG_CLK_STARFIVE_JH7110_AON=y
CONFIG_CLK_STARFIVE_JH7110_ISP=y
CONFIG_CLK_STARFIVE_JH7110_PLL=y
CONFIG_CLK_STARFIVE_JH7110_STG=y
CONFIG_CLK_STARFIVE_JH7110_SYS=y
CONFIG_CLK_STARFIVE_JH7110_VOUT=y
CONFIG_CLK_STARFIVE_JH71X0=y
CONFIG_CLONE_BACKWARDS=y
CONFIG_CLZ_TAB=y
CONFIG_CMODEL_MEDANY=y
# CONFIG_CMODEL_MEDLOW is not set
CONFIG_COMMON_CLK=y
CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
# CONFIG_COMPAT_32BIT_TIME is not set
CONFIG_CONFIGFS_FS=y
CONFIG_CONTEXT_TRACKING=y
CONFIG_CONTEXT_TRACKING_IDLE=y
CONFIG_CPUFREQ_DT=y
CONFIG_CPUFREQ_DT_PLATDEV=y
CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
CONFIG_CPU_FREQ_GOV_ATTR_SET=y
CONFIG_CPU_FREQ_GOV_COMMON=y
CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
CONFIG_CPU_FREQ_GOV_ONDEMAND=y
CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
CONFIG_CPU_FREQ_GOV_POWERSAVE=y
CONFIG_CPU_FREQ_GOV_USERSPACE=y
CONFIG_CPU_FREQ_STAT=y
CONFIG_CPU_IDLE=y
CONFIG_CPU_IDLE_GOV_MENU=y
CONFIG_CPU_IDLE_MULTIPLE_DRIVERS=y
CONFIG_CPU_MITIGATIONS=y
CONFIG_CPU_PM=y
CONFIG_CPU_RMAP=y
CONFIG_CRC16=y
CONFIG_CRC7=y
CONFIG_CRC_ITU_T=y
CONFIG_CRYPTO_BLAKE2B=y
CONFIG_CRYPTO_CBC=y
CONFIG_CRYPTO_CMAC=y
CONFIG_CRYPTO_CRC32C=y
# CONFIG_CRYPTO_DEV_JH7110 is not set
CONFIG_CRYPTO_DRBG=y
CONFIG_CRYPTO_DRBG_HMAC=y
CONFIG_CRYPTO_DRBG_MENU=y
CONFIG_CRYPTO_ECB=y
CONFIG_CRYPTO_ECC=y
CONFIG_CRYPTO_ECDH=y
CONFIG_CRYPTO_HMAC=y
CONFIG_CRYPTO_HW=y
CONFIG_CRYPTO_JITTERENTROPY=y
CONFIG_CRYPTO_JITTERENTROPY_MEMORY_BLOCKS=64
CONFIG_CRYPTO_JITTERENTROPY_MEMORY_BLOCKSIZE=32
CONFIG_CRYPTO_JITTERENTROPY_OSR=1
CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
CONFIG_CRYPTO_LIB_GF128MUL=y
CONFIG_CRYPTO_LIB_POLY1305_RSIZE=1
CONFIG_CRYPTO_LIB_SHA256=y
CONFIG_CRYPTO_LIB_UTILS=y
CONFIG_CRYPTO_RNG=y
CONFIG_CRYPTO_RNG_DEFAULT=y
CONFIG_CRYPTO_RSA=y
CONFIG_CRYPTO_SHA256=y
CONFIG_CRYPTO_SHA3=y
CONFIG_CRYPTO_SHA512=y
CONFIG_CRYPTO_SM3=y
CONFIG_CRYPTO_SM3_GENERIC=y
CONFIG_CRYPTO_USER=y
CONFIG_CRYPTO_USER_API=y
CONFIG_CRYPTO_USER_API_AEAD=y
CONFIG_CRYPTO_USER_API_HASH=y
CONFIG_CRYPTO_USER_API_RNG=y
CONFIG_CRYPTO_USER_API_SKCIPHER=y
CONFIG_CRYPTO_XXHASH=y
CONFIG_CRYPTO_ZSTD=y
CONFIG_DEBUG_ATOMIC_SLEEP=y
CONFIG_DEBUG_GPIO=y
CONFIG_DEBUG_INFO=y
CONFIG_DEBUG_PINCTRL=y
CONFIG_DEBUG_RODATA_TEST=y
CONFIG_DEBUG_RT_MUTEXES=y
CONFIG_DEBUG_RWSEMS=y
CONFIG_DEBUG_SECTION_MISMATCH=y
CONFIG_DEBUG_SG=y
CONFIG_DEBUG_SPINLOCK=y
CONFIG_DEBUG_WX=y
CONFIG_DECOMPRESS_GZIP=y
# CONFIG_DEVFREQ_GOV_PASSIVE is not set
# CONFIG_DEVFREQ_GOV_PERFORMANCE is not set
# CONFIG_DEVFREQ_GOV_POWERSAVE is not set
# CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND is not set
# CONFIG_DEVFREQ_GOV_USERSPACE is not set
# CONFIG_DEVFREQ_THERMAL is not set
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
CONFIG_DMADEVICES=y
CONFIG_DMADEVICES_DEBUG=y
CONFIG_DMADEVICES_VDEBUG=y
CONFIG_DMA_BOUNCE_UNALIGNED_KMALLOC=y
CONFIG_DMA_ENGINE=y
CONFIG_DMA_GLOBAL_POOL=y
CONFIG_DMA_NEED_SYNC=y
CONFIG_DMA_OF=y
CONFIG_DMA_SHARED_BUFFER=y
CONFIG_DMA_VIRTUAL_CHANNELS=y
CONFIG_DMI=y
CONFIG_DMIID=y
# CONFIG_DMI_SYSFS is not set
CONFIG_DTC=y
CONFIG_DT_IDLE_GENPD=y
CONFIG_DT_IDLE_STATES=y
CONFIG_DWMAC_DWC_QOS_ETH=y
# CONFIG_DWMAC_GENERIC is not set
CONFIG_DWMAC_STARFIVE=y
CONFIG_DW_AXI_DMAC=y
CONFIG_E24=y
CONFIG_EDAC_SUPPORT=y
CONFIG_EEPROM_AT24=y
CONFIG_EFI=y
CONFIG_EFIVAR_FS=y
# CONFIG_EFI_BOOTLOADER_CONTROL is not set
# CONFIG_EFI_CAPSULE_LOADER is not set
# CONFIG_EFI_COCO_SECRET is not set
# CONFIG_EFI_DISABLE_PCI_DMA is not set
CONFIG_EFI_DISABLE_RUNTIME=y
CONFIG_EFI_EARLYCON=y
CONFIG_EFI_ESRT=y
CONFIG_EFI_GENERIC_STUB=y
CONFIG_EFI_PARAMS_FROM_FDT=y
CONFIG_EFI_RUNTIME_WRAPPERS=y
CONFIG_EFI_STUB=y
# CONFIG_EFI_TEST is not set
# CONFIG_EFI_ZBOOT is not set
# CONFIG_ERRATA_ANDES is not set
CONFIG_ERRATA_SIFIVE=y
CONFIG_ERRATA_SIFIVE_CIP_1200=y
CONFIG_ERRATA_SIFIVE_CIP_453=y
CONFIG_ERRATA_STARFIVE_JH7100=y
# CONFIG_ERRATA_THEAD is not set
CONFIG_EXCLUSIVE_SYSTEM_RAM=y
CONFIG_EXT4_FS=y
CONFIG_EXTCON=y
CONFIG_FAILOVER=y
CONFIG_FANOTIFY=y
CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-15"
CONFIG_FAT_DEFAULT_UTF8=y
CONFIG_FAT_FS=y
CONFIG_FIXED_PHY=y
CONFIG_FIX_EARLYCON_MEM=y
CONFIG_FONT_8x16=y
CONFIG_FONT_AUTOSELECT=y
CONFIG_FONT_SUPPORT=y
CONFIG_FPU=y
CONFIG_FRAME_POINTER=y
CONFIG_FS_IOMAP=y
CONFIG_FS_MBCACHE=y
CONFIG_FUNCTION_ALIGNMENT=0
CONFIG_FWNODE_MDIO=y
CONFIG_FW_LOADER_PAGED_BUF=y
CONFIG_FW_LOADER_SYSFS=y
CONFIG_GCC_SUPPORTS_DYNAMIC_FTRACE=y
CONFIG_GENERIC_ALLOCATOR=y
CONFIG_GENERIC_ARCH_TOPOLOGY=y
CONFIG_GENERIC_BUG=y
CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
CONFIG_GENERIC_CPU_DEVICES=y
CONFIG_GENERIC_CPU_VULNERABILITIES=y
CONFIG_GENERIC_CSUM=y
CONFIG_GENERIC_EARLY_IOREMAP=y
CONFIG_GENERIC_ENTRY=y
CONFIG_GENERIC_GETTIMEOFDAY=y
CONFIG_GENERIC_IDLE_POLL_SETUP=y
CONFIG_GENERIC_IOREMAP=y
CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
CONFIG_GENERIC_IRQ_IPI_MUX=y
CONFIG_GENERIC_IRQ_MATRIX_ALLOCATOR=y
CONFIG_GENERIC_IRQ_MIGRATION=y
CONFIG_GENERIC_IRQ_MULTI_HANDLER=y
CONFIG_GENERIC_IRQ_SHOW=y
CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED=y
CONFIG_GENERIC_MSI_IRQ=y
CONFIG_GENERIC_PCI_IOMAP=y
CONFIG_GENERIC_PHY=y
CONFIG_GENERIC_PHY_MIPI_DPHY=y
CONFIG_GENERIC_PINCONF=y
CONFIG_GENERIC_PINCTRL_GROUPS=y
CONFIG_GENERIC_PINMUX_FUNCTIONS=y
CONFIG_GENERIC_SCHED_CLOCK=y
CONFIG_GENERIC_SMP_IDLE_THREAD=y
CONFIG_GENERIC_STRNCPY_FROM_USER=y
CONFIG_GENERIC_STRNLEN_USER=y
CONFIG_GENERIC_TIME_VSYSCALL=y
CONFIG_GPIOLIB_FASTPATH_LIMIT=128
CONFIG_GPIOLIB_IRQCHIP=y
CONFIG_GPIO_CDEV=y
CONFIG_GPIO_TPS65086=y
CONFIG_HARDIRQS_SW_RESEND=y
CONFIG_HAS_DMA=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_IOPORT_MAP=y
CONFIG_HOTPLUG_CORE_SYNC=y
CONFIG_HOTPLUG_CORE_SYNC_DEAD=y
CONFIG_HOTPLUG_CPU=y
CONFIG_HUGETLBFS=y
CONFIG_HUGETLB_PAGE=y
CONFIG_HUGETLB_PMD_PAGE_TABLE_SHARING=y
CONFIG_HVC_DRIVER=y
CONFIG_HVC_RISCV_SBI=y
CONFIG_HWMON=y
CONFIG_HW_RANDOM=y
CONFIG_HW_RANDOM_JH7110=y
CONFIG_HW_RANDOM_STARFIVE_VIC=y
CONFIG_I2C=y
CONFIG_I2C_ALGOBIT=y
CONFIG_I2C_BOARDINFO=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_DESIGNWARE_CORE=y
CONFIG_I2C_DESIGNWARE_PLATFORM=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000
CONFIG_INITRAMFS_SOURCE=""
# CONFIG_IPMS_CAN is not set
CONFIG_IRQCHIP=y
CONFIG_IRQ_DOMAIN=y
CONFIG_IRQ_DOMAIN_HIERARCHY=y
CONFIG_IRQ_FORCED_THREADING=y
CONFIG_IRQ_STACKS=y
CONFIG_IRQ_WORK=y
CONFIG_JBD2=y
CONFIG_JH71XX_PMU=y
CONFIG_JUMP_LABEL=y
CONFIG_KCMP=y
# CONFIG_KERNEL_UNCOMPRESSED is not set
CONFIG_LEGACY_DIRECT_IO=y
CONFIG_LIBFDT=y
CONFIG_LOCKUP_DETECTOR=y
CONFIG_LOCK_DEBUGGING_SUPPORT=y
CONFIG_LOCK_SPIN_ON_OWNER=y
CONFIG_LSM=""
CONFIG_MAILBOX=y
# CONFIG_MAILBOX_TEST is not set
CONFIG_MARVELL_PHY=y
CONFIG_MDIO_BUS=y
CONFIG_MDIO_DEVICE=y
CONFIG_MDIO_DEVRES=y
CONFIG_MEMTEST=y
CONFIG_MFD_AXP20X=y
CONFIG_MFD_AXP20X_I2C=y
CONFIG_MFD_CORE=y
CONFIG_MFD_SYSCON=y
CONFIG_MFD_TPS65086=y
CONFIG_MICREL_PHY=y
CONFIG_MICROCHIP_PHY=y
CONFIG_MIGRATION=y
CONFIG_MMC=y
CONFIG_MMC_BLOCK=y
CONFIG_MMC_DEBUG=y
CONFIG_MMC_DW=y
# CONFIG_MMC_DW_BLUEFIELD is not set
# CONFIG_MMC_DW_EXYNOS is not set
# CONFIG_MMC_DW_HI3798CV200 is not set
# CONFIG_MMC_DW_HI3798MV200 is not set
# CONFIG_MMC_DW_K3 is not set
# CONFIG_MMC_DW_PCI is not set
CONFIG_MMC_DW_PLTFM=y
CONFIG_MMC_DW_STARFIVE=y
CONFIG_MMIOWB=y
CONFIG_MMU_LAZY_TLB_REFCOUNT=y
CONFIG_MODULES_TREE_LOOKUP=y
CONFIG_MODULES_USE_ELF_RELA=y
CONFIG_MOTORCOMM_PHY=y
CONFIG_MPILIB=y
CONFIG_MTD_SPI_NOR=y
CONFIG_MUTEX_SPIN_ON_OWNER=y
CONFIG_NAMESPACES=y
CONFIG_NEED_DMA_MAP_STATE=y
CONFIG_NET_DEVMEM=y
CONFIG_NET_EGRESS=y
CONFIG_NET_FAILOVER=y
CONFIG_NET_FLOW_LIMIT=y
CONFIG_NET_INGRESS=y
CONFIG_NET_NS=y
CONFIG_NET_PTP_CLASSIFY=y
CONFIG_NET_SELFTESTS=y
CONFIG_NET_XGRESS=y
CONFIG_NLS=y
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_DEFAULT="iso8859-15"
CONFIG_NLS_ISO8859_1=y
CONFIG_NLS_ISO8859_15=y
CONFIG_NONPORTABLE=y
CONFIG_NO_HZ_COMMON=y
CONFIG_NO_HZ_IDLE=y
CONFIG_NR_CPUS=8
# CONFIG_NSM is not set
CONFIG_NVMEM=y
CONFIG_NVMEM_LAYOUTS=y
CONFIG_NVMEM_SYSFS=y
CONFIG_OF=y
CONFIG_OF_ADDRESS=y
CONFIG_OF_DYNAMIC=y
CONFIG_OF_EARLY_FLATTREE=y
CONFIG_OF_FLATTREE=y
CONFIG_OF_GPIO=y
CONFIG_OF_IRQ=y
CONFIG_OF_KOBJ=y
CONFIG_OF_MDIO=y
CONFIG_OF_OVERLAY=y
CONFIG_OF_RESOLVE=y
CONFIG_OID_REGISTRY=y
CONFIG_OVERLAY_FS_INDEX=y
CONFIG_OVERLAY_FS_METACOPY=y
CONFIG_OVERLAY_FS_REDIRECT_DIR=y
CONFIG_PADATA=y
CONFIG_PAGE_EXTENSION=y
CONFIG_PAGE_OFFSET=0xff60000000000000
CONFIG_PAGE_POOL=y
CONFIG_PAGE_REPORTING=y
CONFIG_PAGE_SIZE_LESS_THAN_256KB=y
CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
CONFIG_PCI=y
CONFIG_PCIE_CADENCE=y
CONFIG_PCIE_CADENCE_HOST=y
CONFIG_PCIE_CADENCE_PLAT=y
CONFIG_PCIE_CADENCE_PLAT_HOST=y
# CONFIG_PCIE_FU740 is not set
CONFIG_PCIE_PLDA_HOST=y
CONFIG_PCIE_STARFIVE_HOST=y
CONFIG_PCI_DOMAINS=y
CONFIG_PCI_DOMAINS_GENERIC=y
CONFIG_PCI_LABEL=y
CONFIG_PCI_MSI=y
CONFIG_PCS_XPCS=y
CONFIG_PERF_EVENTS=y
CONFIG_PER_VMA_LOCK=y
CONFIG_PGTABLE_HAS_HUGE_LEAVES=y
CONFIG_PGTABLE_LEVELS=5
CONFIG_PHYLIB=y
CONFIG_PHYLIB_LEDS=y
CONFIG_PHYLINK=y
CONFIG_PHYS_ADDR_T_64BIT=y
# CONFIG_PHYS_RAM_BASE_FIXED is not set
CONFIG_PHY_STARFIVE_JH7110_DPHY_RX=y
# CONFIG_PHY_STARFIVE_JH7110_DPHY_TX is not set
CONFIG_PHY_STARFIVE_JH7110_PCIE=y
CONFIG_PHY_STARFIVE_JH7110_USB=y
CONFIG_PINCTRL=y
CONFIG_PINCTRL_STARFIVE_JH7100=y
CONFIG_PINCTRL_STARFIVE_JH7110=y
CONFIG_PINCTRL_STARFIVE_JH7110_AON=y
CONFIG_PINCTRL_STARFIVE_JH7110_SYS=y
CONFIG_PM=y
CONFIG_PM_ADVANCED_DEBUG=y
CONFIG_PM_CLK=y
CONFIG_PM_DEBUG=y
CONFIG_PM_DEVFREQ=y
# CONFIG_PM_DEVFREQ_EVENT is not set
CONFIG_PM_GENERIC_DOMAINS=y
CONFIG_PM_GENERIC_DOMAINS_OF=y
CONFIG_PM_OPP=y
CONFIG_POSIX_CPU_TIMERS_TASK_WORK=y
CONFIG_POSIX_MQUEUE=y
CONFIG_POSIX_MQUEUE_SYSCTL=y
CONFIG_POWER_RESET=y
CONFIG_POWER_RESET_GPIO_RESTART=y
CONFIG_POWER_RESET_SYSCON=y
CONFIG_POWER_RESET_SYSCON_POWEROFF=y
# CONFIG_POWER_RESET_TPS65086 is not set
CONFIG_PPS=y
CONFIG_PREEMPT_COUNT=y
CONFIG_PRINTK_TIME=y
CONFIG_PROC_CHILDREN=y
CONFIG_PROC_KCORE=y
CONFIG_PTDUMP_CORE=y
CONFIG_PTP_1588_CLOCK=y
CONFIG_PTP_1588_CLOCK_OPTIONAL=y
CONFIG_PWM=y
CONFIG_PWM_OCORES=y
# CONFIG_PWM_SIFIVE is not set
CONFIG_QUEUED_RWLOCKS=y
CONFIG_RANDSTRUCT_NONE=y
CONFIG_RATIONAL=y
CONFIG_RCU_EQS_DEBUG=y
CONFIG_RD_GZIP=y
CONFIG_REALTEK_PHY=y
# CONFIG_REALTEK_PHY_HWMON is not set
CONFIG_REGMAP=y
CONFIG_REGMAP_I2C=y
CONFIG_REGMAP_IRQ=y
CONFIG_REGMAP_MMIO=y
CONFIG_REGULATOR=y
CONFIG_REGULATOR_AXP20X=y
CONFIG_REGULATOR_TPS65086=y
# CONFIG_RESET_ATTACK_MITIGATION is not set
CONFIG_RESET_CONTROLLER=y
CONFIG_RESET_SIMPLE=y
CONFIG_RESET_STARFIVE_JH7100=y
CONFIG_RESET_STARFIVE_JH7100_AUDIO=m
CONFIG_RESET_STARFIVE_JH7110=y
CONFIG_RESET_STARFIVE_JH71X0=y
CONFIG_RFS_ACCEL=y
CONFIG_RISCV=y
CONFIG_RISCV_ALTERNATIVE=y
CONFIG_RISCV_APLIC=y
CONFIG_RISCV_APLIC_MSI=y
CONFIG_RISCV_BOOT_SPINWAIT=y
CONFIG_RISCV_DMA_NONCOHERENT=y
# CONFIG_RISCV_EFFICIENT_UNALIGNED_ACCESS is not set
# CONFIG_RISCV_EMULATED_UNALIGNED_ACCESS is not set
CONFIG_RISCV_IMSIC=y
CONFIG_RISCV_IMSIC_PCI=y
CONFIG_RISCV_INTC=y
CONFIG_RISCV_ISA_C=y
CONFIG_RISCV_ISA_FALLBACK=y
CONFIG_RISCV_ISA_SVNAPOT=y
# CONFIG_RISCV_ISA_SVPBMT is not set
# CONFIG_RISCV_ISA_V is not set
# CONFIG_RISCV_ISA_VENDOR_EXT_ANDES is not set
CONFIG_RISCV_ISA_ZAWRS=y
CONFIG_RISCV_ISA_ZBA=y
CONFIG_RISCV_ISA_ZBB=y
CONFIG_RISCV_ISA_ZBC=y
# CONFIG_RISCV_ISA_ZICBOM is not set
CONFIG_RISCV_ISA_ZICBOZ=y
CONFIG_RISCV_MISALIGNED=y
CONFIG_RISCV_NONSTANDARD_CACHE_OPS=y
CONFIG_RISCV_PMU=y
CONFIG_RISCV_PMU_LEGACY=y
CONFIG_RISCV_PMU_SBI=y
CONFIG_RISCV_PROBE_UNALIGNED_ACCESS=y
CONFIG_RISCV_SBI=y
CONFIG_RISCV_SBI_CPUIDLE=y
CONFIG_RISCV_SBI_V01=y
# CONFIG_RISCV_SLOW_UNALIGNED_ACCESS is not set
CONFIG_RISCV_TIMER=y
CONFIG_RISCV_USE_LINKER_RELAXATION=y
CONFIG_RPMSG=y
CONFIG_RPMSG_CHAR=y
# CONFIG_RPMSG_CTRL is not set
CONFIG_RPMSG_NS=y
# CONFIG_RPMSG_TTY is not set
CONFIG_RPMSG_VIRTIO=y
CONFIG_RPS=y
CONFIG_RTC_CLASS=y
CONFIG_RTC_DRV_HYM8563=y
CONFIG_RTC_DRV_STARFIVE=y
CONFIG_RTC_I2C_AND_SPI=y
# CONFIG_RUNTIME_KERNEL_TESTING_MENU is not set
CONFIG_RWSEM_SPIN_ON_OWNER=y
CONFIG_SCSI=y
CONFIG_SCSI_COMMON=y
CONFIG_SCSI_VIRTIO=y
CONFIG_SENSORS_SFCTEMP=y
# CONFIG_SERIAL_8250_16550A_VARIANTS is not set
CONFIG_SERIAL_8250_DW=y
CONFIG_SERIAL_8250_DWLIB=y
CONFIG_SERIAL_8250_EXTENDED=y
CONFIG_SERIAL_8250_MANY_PORTS=y
CONFIG_SERIAL_8250_NR_UARTS=6
CONFIG_SERIAL_8250_RUNTIME_UARTS=6
# CONFIG_SERIAL_8250_SHARE_IRQ is not set
CONFIG_SERIAL_EARLYCON_RISCV_SBI=y
CONFIG_SERIAL_MCTRL_GPIO=y
CONFIG_SERIAL_OF_PLATFORM=y
CONFIG_SERIAL_SIFIVE=y
CONFIG_SERIAL_SIFIVE_CONSOLE=y
CONFIG_SGL_ALLOC=y
CONFIG_SG_POOL=y
CONFIG_SIFIVE_CCACHE=y
CONFIG_SIFIVE_PLIC=y
CONFIG_SMP=y
# CONFIG_SND_SOC_STARFIVE is not set
CONFIG_SOCK_RX_QUEUE_MAPPING=y
CONFIG_SOC_STARFIVE=y
CONFIG_SOFTIRQ_ON_OWN_STACK=y
CONFIG_SOFTLOCKUP_DETECTOR=y
CONFIG_SOUND=y
CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
CONFIG_SPARSE_IRQ=y
CONFIG_SPI=y
CONFIG_SPI_CADENCE_QUADSPI=y
CONFIG_SPI_DYNAMIC=y
CONFIG_SPI_MASTER=y
CONFIG_SPI_MEM=y
CONFIG_SPI_PL022=y
CONFIG_SPI_SPIDEV=y
CONFIG_SPLIT_PMD_PTLOCKS=y
CONFIG_SPLIT_PTE_PTLOCKS=y
CONFIG_STARFIVE_JH7110_TIMER=y
CONFIG_STARFIVE_JH8100_INTC=y
CONFIG_STARFIVE_MBOX=y
# CONFIG_STARFIVE_MBOX_TEST is not set
CONFIG_STARFIVE_STARLINK_CACHE=y
# CONFIG_STARFIVE_STARLINK_PMU is not set
CONFIG_STARFIVE_WATCHDOG=y
CONFIG_STMMAC_ETH=y
CONFIG_STMMAC_PLATFORM=y
CONFIG_STMMAC_SELFTESTS=y
CONFIG_SWIOTLB=y
CONFIG_SWPHY=y
CONFIG_SYNC_FILE=y
CONFIG_SYSCTL_ARCH_UNALIGN_ALLOW=y
CONFIG_SYSCTL_EXCEPTION_TRACE=y
# CONFIG_SYSFB_SIMPLEFB is not set
CONFIG_THERMAL=y
CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0
CONFIG_THERMAL_GOV_STEP_WISE=y
CONFIG_THERMAL_HWMON=y
CONFIG_THERMAL_OF=y
CONFIG_THREAD_INFO_IN_TASK=y
CONFIG_THREAD_SIZE_ORDER=2
CONFIG_TICK_CPU_ACCOUNTING=y
CONFIG_TIMER_OF=y
CONFIG_TIMER_PROBE=y
CONFIG_TOOLCHAIN_HAS_V=y
CONFIG_TOOLCHAIN_HAS_VECTOR_CRYPTO=y
CONFIG_TOOLCHAIN_HAS_ZBB=y
CONFIG_TOOLCHAIN_HAS_ZBC=y
CONFIG_TOOLCHAIN_NEEDS_EXPLICIT_ZICSR_ZIFENCEI=y
CONFIG_TREE_RCU=y
CONFIG_TREE_SRCU=y
CONFIG_TTY_PRINTK=y
CONFIG_TTY_PRINTK_LEVEL=6
CONFIG_TUNE_GENERIC=y
CONFIG_UCS2_STRING=y
CONFIG_UNINLINE_SPIN_UNLOCK=y
CONFIG_USB=y
CONFIG_USB_CDNS3=y
CONFIG_USB_CDNS3_GADGET=y
CONFIG_USB_CDNS3_HOST=y
CONFIG_USB_CDNS3_STARFIVE=y
CONFIG_USB_CDNS_HOST=y
CONFIG_USB_CDNS_SUPPORT=y
CONFIG_USB_COMMON=y
CONFIG_USB_CONFIGFS=y
# CONFIG_USB_CONFIGFS_ACM is not set
# CONFIG_USB_CONFIGFS_ECM is not set
# CONFIG_USB_CONFIGFS_ECM_SUBSET is not set
# CONFIG_USB_CONFIGFS_EEM is not set
CONFIG_USB_CONFIGFS_F_FS=y
# CONFIG_USB_CONFIGFS_F_HID is not set
# CONFIG_USB_CONFIGFS_F_LB_SS is not set
# CONFIG_USB_CONFIGFS_F_MIDI is not set
# CONFIG_USB_CONFIGFS_F_MIDI2 is not set
# CONFIG_USB_CONFIGFS_F_PRINTER is not set
# CONFIG_USB_CONFIGFS_F_UAC1 is not set
# CONFIG_USB_CONFIGFS_F_UAC1_LEGACY is not set
# CONFIG_USB_CONFIGFS_F_UAC2 is not set
# CONFIG_USB_CONFIGFS_F_UVC is not set
CONFIG_USB_CONFIGFS_MASS_STORAGE=y
# CONFIG_USB_CONFIGFS_NCM is not set
# CONFIG_USB_CONFIGFS_OBEX is not set
# CONFIG_USB_CONFIGFS_RNDIS is not set
# CONFIG_USB_CONFIGFS_SERIAL is not set
CONFIG_USB_F_FS=y
CONFIG_USB_F_MASS_STORAGE=y
CONFIG_USB_GADGET=y
CONFIG_USB_LIBCOMPOSITE=y
CONFIG_USB_PCI=y
CONFIG_USB_ROLE_SWITCH=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=y
CONFIG_USELIB=y
CONFIG_USER_NS=y
CONFIG_USER_STACKTRACE_SUPPORT=y
CONFIG_VFAT_FS=y
CONFIG_VIRTIO=y
CONFIG_VIRTIO_ANCHOR=y
# CONFIG_VIRTIO_BLK is not set
# CONFIG_VIRTIO_DEBUG is not set
# CONFIG_VIRTIO_NET is not set
CONFIG_VMAP_STACK=y
CONFIG_VMCORE_INFO=y
CONFIG_WATCHDOG_CORE=y
CONFIG_WATCHDOG_SYSFS=y
CONFIG_WERROR=y
CONFIG_WQ_WATCHDOG=y
CONFIG_XARRAY_MULTI=y
CONFIG_XPS=y
CONFIG_XXHASH=y
CONFIG_ZLIB_INFLATE=y
CONFIG_ZONE_DMA32=y
CONFIG_ZSTD_COMMON=y
CONFIG_ZSTD_COMPRESS=y
CONFIG_ZSTD_DECOMPRESS=y

View File

@ -0,0 +1,176 @@
From 5605ebdd7f7033da8f1bcb77cb180ef16235d5c8 Mon Sep 17 00:00:00 2001
From: Hal Feng <hal.feng@starfivetech.com>
Date: Tue, 11 Apr 2023 16:31:15 +0800
Subject: [PATCH 01/55] riscv: dts: starfive: Add full support (except VIN and
VOUT) for JH7110 and VisionFive 2 board
Merge all StarFive dts patches together except VIN and VOUT.
Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
---
.../boot/dts/starfive/jh7110-common.dtsi | 2 +
.../jh7110-starfive-visionfive-2.dtsi | 100 ++++++++++++++++++
arch/riscv/boot/dts/starfive/jh7110.dtsi | 21 ++++
3 files changed, 123 insertions(+)
--- a/arch/riscv/boot/dts/starfive/jh7110-common.dtsi
+++ b/arch/riscv/boot/dts/starfive/jh7110-common.dtsi
@@ -18,6 +18,8 @@
i2c6 = &i2c6;
mmc0 = &mmc0;
mmc1 = &mmc1;
+ pcie0 = &pcie0;
+ pcie1 = &pcie1;
serial0 = &uart0;
};
--- a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
+++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
@@ -29,6 +29,24 @@
};
};
+&i2srx {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2srx_pins>;
+ status = "okay";
+};
+
+&i2stx0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mclk_ext_pins>;
+ status = "okay";
+};
+
+&i2stx1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2stx1_pins>;
+ status = "okay";
+};
+
&mmc0 {
non-removable;
};
@@ -40,3 +58,85 @@
&pcie1 {
status = "okay";
};
+
+&sysgpio {
+ i2srx_pins: i2srx-0 {
+ clk-sd-pins {
+ pinmux = <GPIOMUX(38, GPOUT_LOW,
+ GPOEN_DISABLE,
+ GPI_SYS_I2SRX_BCLK)>,
+ <GPIOMUX(63, GPOUT_LOW,
+ GPOEN_DISABLE,
+ GPI_SYS_I2SRX_LRCK)>,
+ <GPIOMUX(38, GPOUT_LOW,
+ GPOEN_DISABLE,
+ GPI_SYS_I2STX1_BCLK)>,
+ <GPIOMUX(63, GPOUT_LOW,
+ GPOEN_DISABLE,
+ GPI_SYS_I2STX1_LRCK)>,
+ <GPIOMUX(61, GPOUT_LOW,
+ GPOEN_DISABLE,
+ GPI_SYS_I2SRX_SDIN0)>;
+ input-enable;
+ };
+ };
+
+ i2stx1_pins: i2stx1-0 {
+ sd-pins {
+ pinmux = <GPIOMUX(44, GPOUT_SYS_I2STX1_SDO0,
+ GPOEN_ENABLE,
+ GPI_NONE)>;
+ bias-disable;
+ input-disable;
+ };
+ };
+
+ mclk_ext_pins: mclk-ext-0 {
+ mclk-ext-pins {
+ pinmux = <GPIOMUX(4, GPOUT_LOW,
+ GPOEN_DISABLE,
+ GPI_SYS_MCLK_EXT)>;
+ input-enable;
+ };
+ };
+
+ tdm_pins: tdm-0 {
+ tx-pins {
+ pinmux = <GPIOMUX(44, GPOUT_SYS_TDM_TXD,
+ GPOEN_ENABLE,
+ GPI_NONE)>;
+ bias-pull-up;
+ drive-strength = <2>;
+ input-disable;
+ input-schmitt-disable;
+ slew-rate = <0>;
+ };
+
+ rx-pins {
+ pinmux = <GPIOMUX(61, GPOUT_HIGH,
+ GPOEN_DISABLE,
+ GPI_SYS_TDM_RXD)>;
+ input-enable;
+ };
+
+ sync-pins {
+ pinmux = <GPIOMUX(63, GPOUT_HIGH,
+ GPOEN_DISABLE,
+ GPI_SYS_TDM_SYNC)>;
+ input-enable;
+ };
+
+ pcmclk-pins {
+ pinmux = <GPIOMUX(38, GPOUT_HIGH,
+ GPOEN_DISABLE,
+ GPI_SYS_TDM_CLK)>;
+ input-enable;
+ };
+ };
+};
+
+&tdm {
+ pinctrl-names = "default";
+ pinctrl-0 = <&tdm_pins>;
+ status = "okay";
+};
--- a/arch/riscv/boot/dts/starfive/jh7110.dtsi
+++ b/arch/riscv/boot/dts/starfive/jh7110.dtsi
@@ -259,6 +259,7 @@
clock-output-names = "dvp_clk";
#clock-cells = <0>;
};
+
gmac0_rgmii_rxin: gmac0-rgmii-rxin-clock {
compatible = "fixed-clock";
clock-output-names = "gmac0_rgmii_rxin";
@@ -919,6 +920,26 @@
#gpio-cells = <2>;
};
+ timer@13050000 {
+ compatible = "starfive,jh7110-timer";
+ reg = <0x0 0x13050000 0x0 0x10000>;
+ interrupts = <69>, <70>, <71>, <72>;
+ clocks = <&syscrg JH7110_SYSCLK_TIMER_APB>,
+ <&syscrg JH7110_SYSCLK_TIMER0>,
+ <&syscrg JH7110_SYSCLK_TIMER1>,
+ <&syscrg JH7110_SYSCLK_TIMER2>,
+ <&syscrg JH7110_SYSCLK_TIMER3>;
+ clock-names = "apb", "ch0", "ch1",
+ "ch2", "ch3";
+ resets = <&syscrg JH7110_SYSRST_TIMER_APB>,
+ <&syscrg JH7110_SYSRST_TIMER0>,
+ <&syscrg JH7110_SYSRST_TIMER1>,
+ <&syscrg JH7110_SYSRST_TIMER2>,
+ <&syscrg JH7110_SYSRST_TIMER3>;
+ reset-names = "apb", "ch0", "ch1",
+ "ch2", "ch3";
+ };
+
watchdog@13070000 {
compatible = "starfive,jh7110-wdt";
reg = <0x0 0x13070000 0x0 0x10000>;

View File

@ -0,0 +1,428 @@
From 9e8b51600e4b0ea28c599303b87f6b1b8585eee4 Mon Sep 17 00:00:00 2001
From: Xingyu Wu <xingyu.wu@starfivetech.com>
Date: Thu, 19 Oct 2023 13:35:00 +0800
Subject: [PATCH 02/55] clocksource: Add JH7110 timer driver
Add timer driver for the StarFive JH7110 SoC.
Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
---
drivers/clocksource/Kconfig | 11 +
drivers/clocksource/Makefile | 1 +
drivers/clocksource/timer-jh7110.c | 380 +++++++++++++++++++++++++++++
3 files changed, 392 insertions(+)
create mode 100644 drivers/clocksource/timer-jh7110.c
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -653,6 +653,17 @@ config RISCV_TIMER
is accessed via both the SBI and the rdcycle instruction. This is
required for all RISC-V systems.
+config STARFIVE_JH7110_TIMER
+ bool "Timer for the STARFIVE JH7110 SoC"
+ depends on ARCH_STARFIVE || COMPILE_TEST
+ select TIMER_OF
+ select CLKSRC_MMIO
+ default ARCH_STARFIVE
+ help
+ This enables the timer for StarFive JH7110 SoC. On RISC-V platform,
+ the system has started RISCV_TIMER, but you can also use this timer
+ which can provide four channels to do a lot more things on JH7110 SoC.
+
config CLINT_TIMER
bool "CLINT Timer for the RISC-V platform" if COMPILE_TEST
depends on GENERIC_SCHED_CLOCK && RISCV
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -81,6 +81,7 @@ obj-$(CONFIG_INGENIC_TIMER) += ingenic-
obj-$(CONFIG_CLKSRC_ST_LPC) += clksrc_st_lpc.o
obj-$(CONFIG_X86_NUMACHIP) += numachip.o
obj-$(CONFIG_RISCV_TIMER) += timer-riscv.o
+obj-$(CONFIG_STARFIVE_JH7110_TIMER) += timer-jh7110.o
obj-$(CONFIG_CLINT_TIMER) += timer-clint.o
obj-$(CONFIG_CSKY_MP_TIMER) += timer-mp-csky.o
obj-$(CONFIG_GX6605S_TIMER) += timer-gx6605s.o
--- /dev/null
+++ b/drivers/clocksource/timer-jh7110.c
@@ -0,0 +1,380 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Starfive JH7110 Timer driver
+ *
+ * Copyright (C) 2022-2023 StarFive Technology Co., Ltd.
+ *
+ * Author:
+ * Xingyu Wu <xingyu.wu@starfivetech.com>
+ * Samin Guo <samin.guo@starfivetech.com>
+ */
+
+#include <linux/clk.h>
+#include <linux/clockchips.h>
+#include <linux/clocksource.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/reset.h>
+#include <linux/sched_clock.h>
+
+/* Bias: Ch0-0x0, Ch1-0x40, Ch2-0x80, and so on. */
+#define JH7110_TIMER_CH_LEN 0x40
+#define JH7110_TIMER_CH_BASE(x) ((x) * JH7110_TIMER_CH_LEN)
+#define JH7110_TIMER_CH_MAX 4
+
+#define JH7110_CLOCK_SOURCE_RATING 200
+#define JH7110_VALID_BITS 32
+#define JH7110_DELAY_US 0
+#define JH7110_TIMEOUT_US 10000
+#define JH7110_CLOCKEVENT_RATING 300
+#define JH7110_TIMER_MAX_TICKS 0xffffffff
+#define JH7110_TIMER_MIN_TICKS 0xf
+#define JH7110_TIMER_RELOAD_VALUE 0
+
+#define JH7110_TIMER_INT_STATUS 0x00 /* RO[0:4]: Interrupt Status for channel0~4 */
+#define JH7110_TIMER_CTL 0x04 /* RW[0]: 0-continuous run, 1-single run */
+#define JH7110_TIMER_LOAD 0x08 /* RW: load value to counter */
+#define JH7110_TIMER_ENABLE 0x10 /* RW[0]: timer enable register */
+#define JH7110_TIMER_RELOAD 0x14 /* RW: write 1 or 0 both reload counter */
+#define JH7110_TIMER_VALUE 0x18 /* RO: timer value register */
+#define JH7110_TIMER_INT_CLR 0x20 /* RW: timer interrupt clear register */
+#define JH7110_TIMER_INT_MASK 0x24 /* RW[0]: timer interrupt mask register */
+
+#define JH7110_TIMER_INT_CLR_ENA BIT(0)
+#define JH7110_TIMER_INT_CLR_AVA_MASK BIT(1)
+
+struct jh7110_clkevt {
+ struct clock_event_device evt;
+ struct clocksource cs;
+ bool cs_is_valid;
+ struct clk *clk;
+ struct reset_control *rst;
+ u32 rate;
+ u32 reload_val;
+ void __iomem *base;
+ char name[sizeof("jh7110-timer.chX")];
+};
+
+struct jh7110_timer_priv {
+ struct clk *pclk;
+ struct reset_control *prst;
+ struct jh7110_clkevt clkevt[JH7110_TIMER_CH_MAX];
+};
+
+/* 0:continuous-run mode, 1:single-run mode */
+enum jh7110_timer_mode {
+ JH7110_TIMER_MODE_CONTIN,
+ JH7110_TIMER_MODE_SINGLE,
+};
+
+/* Interrupt Mask, 0:Unmask, 1:Mask */
+enum jh7110_timer_int_mask {
+ JH7110_TIMER_INT_ENA,
+ JH7110_TIMER_INT_DIS,
+};
+
+enum jh7110_timer_enable {
+ JH7110_TIMER_DIS,
+ JH7110_TIMER_ENA,
+};
+
+static inline struct jh7110_clkevt *to_jh7110_clkevt(struct clock_event_device *evt)
+{
+ return container_of(evt, struct jh7110_clkevt, evt);
+}
+
+/*
+ * BIT(0): Read value represent channel int status.
+ * Write 1 to this bit to clear interrupt. Write 0 has no effects.
+ * BIT(1): "1" means that it is clearing interrupt. BIT(0) can not be written.
+ */
+static inline int jh7110_timer_int_clear(struct jh7110_clkevt *clkevt)
+{
+ u32 value;
+ int ret;
+
+ /* Waiting interrupt can be cleared */
+ ret = readl_poll_timeout_atomic(clkevt->base + JH7110_TIMER_INT_CLR, value,
+ !(value & JH7110_TIMER_INT_CLR_AVA_MASK),
+ JH7110_DELAY_US, JH7110_TIMEOUT_US);
+ if (!ret)
+ writel(JH7110_TIMER_INT_CLR_ENA, clkevt->base + JH7110_TIMER_INT_CLR);
+
+ return ret;
+}
+
+static int jh7110_timer_start(struct jh7110_clkevt *clkevt)
+{
+ int ret;
+
+ /* Disable and clear interrupt first */
+ writel(JH7110_TIMER_INT_DIS, clkevt->base + JH7110_TIMER_INT_MASK);
+ ret = jh7110_timer_int_clear(clkevt);
+ if (ret)
+ return ret;
+
+ writel(JH7110_TIMER_INT_ENA, clkevt->base + JH7110_TIMER_INT_MASK);
+ writel(JH7110_TIMER_ENA, clkevt->base + JH7110_TIMER_ENABLE);
+
+ return 0;
+}
+
+static int jh7110_timer_shutdown(struct clock_event_device *evt)
+{
+ struct jh7110_clkevt *clkevt = to_jh7110_clkevt(evt);
+
+ writel(JH7110_TIMER_DIS, clkevt->base + JH7110_TIMER_ENABLE);
+ return jh7110_timer_int_clear(clkevt);
+}
+
+static void jh7110_timer_suspend(struct clock_event_device *evt)
+{
+ struct jh7110_clkevt *clkevt = to_jh7110_clkevt(evt);
+
+ clkevt->reload_val = readl(clkevt->base + JH7110_TIMER_LOAD);
+ jh7110_timer_shutdown(evt);
+}
+
+static void jh7110_timer_resume(struct clock_event_device *evt)
+{
+ struct jh7110_clkevt *clkevt = to_jh7110_clkevt(evt);
+
+ writel(clkevt->reload_val, clkevt->base + JH7110_TIMER_LOAD);
+ writel(JH7110_TIMER_RELOAD_VALUE, clkevt->base + JH7110_TIMER_RELOAD);
+ jh7110_timer_start(clkevt);
+}
+
+static int jh7110_timer_tick_resume(struct clock_event_device *evt)
+{
+ jh7110_timer_resume(evt);
+
+ return 0;
+}
+
+/* IRQ handler for the timer */
+static irqreturn_t jh7110_timer_interrupt(int irq, void *priv)
+{
+ struct clock_event_device *evt = (struct clock_event_device *)priv;
+ struct jh7110_clkevt *clkevt = to_jh7110_clkevt(evt);
+
+ if (jh7110_timer_int_clear(clkevt))
+ return IRQ_NONE;
+
+ if (evt->event_handler)
+ evt->event_handler(evt);
+
+ return IRQ_HANDLED;
+}
+
+static int jh7110_timer_set_periodic(struct clock_event_device *evt)
+{
+ struct jh7110_clkevt *clkevt = to_jh7110_clkevt(evt);
+ u32 periodic = DIV_ROUND_CLOSEST(clkevt->rate, HZ);
+
+ writel(JH7110_TIMER_MODE_CONTIN, clkevt->base + JH7110_TIMER_CTL);
+ writel(periodic, clkevt->base + JH7110_TIMER_LOAD);
+
+ return jh7110_timer_start(clkevt);
+}
+
+static int jh7110_timer_set_oneshot(struct clock_event_device *evt)
+{
+ struct jh7110_clkevt *clkevt = to_jh7110_clkevt(evt);
+
+ writel(JH7110_TIMER_MODE_SINGLE, clkevt->base + JH7110_TIMER_CTL);
+ writel(JH7110_TIMER_MAX_TICKS, clkevt->base + JH7110_TIMER_LOAD);
+
+ return jh7110_timer_start(clkevt);
+}
+
+static int jh7110_timer_set_next_event(unsigned long next,
+ struct clock_event_device *evt)
+{
+ struct jh7110_clkevt *clkevt = to_jh7110_clkevt(evt);
+
+ writel(JH7110_TIMER_MODE_SINGLE, clkevt->base + JH7110_TIMER_CTL);
+ writel(next, clkevt->base + JH7110_TIMER_LOAD);
+
+ return jh7110_timer_start(clkevt);
+}
+
+static void jh7110_set_clockevent(struct clock_event_device *evt)
+{
+ evt->features = CLOCK_EVT_FEAT_PERIODIC |
+ CLOCK_EVT_FEAT_ONESHOT |
+ CLOCK_EVT_FEAT_DYNIRQ;
+ evt->set_state_shutdown = jh7110_timer_shutdown;
+ evt->set_state_periodic = jh7110_timer_set_periodic;
+ evt->set_state_oneshot = jh7110_timer_set_oneshot;
+ evt->set_state_oneshot_stopped = jh7110_timer_shutdown;
+ evt->tick_resume = jh7110_timer_tick_resume;
+ evt->set_next_event = jh7110_timer_set_next_event;
+ evt->suspend = jh7110_timer_suspend;
+ evt->resume = jh7110_timer_resume;
+ evt->rating = JH7110_CLOCKEVENT_RATING;
+}
+
+static u64 jh7110_timer_clocksource_read(struct clocksource *cs)
+{
+ struct jh7110_clkevt *clkevt = container_of(cs, struct jh7110_clkevt, cs);
+
+ return (u64)readl(clkevt->base + JH7110_TIMER_VALUE);
+}
+
+static int jh7110_clocksource_init(struct jh7110_clkevt *clkevt)
+{
+ int ret;
+
+ clkevt->cs.name = clkevt->name;
+ clkevt->cs.rating = JH7110_CLOCK_SOURCE_RATING;
+ clkevt->cs.read = jh7110_timer_clocksource_read;
+ clkevt->cs.mask = CLOCKSOURCE_MASK(JH7110_VALID_BITS);
+ clkevt->cs.flags = CLOCK_SOURCE_IS_CONTINUOUS;
+
+ ret = clocksource_register_hz(&clkevt->cs, clkevt->rate);
+ if (ret)
+ return ret;
+
+ clkevt->cs_is_valid = true; /* clocksource register done */
+ writel(JH7110_TIMER_MODE_CONTIN, clkevt->base + JH7110_TIMER_CTL);
+ writel(JH7110_TIMER_MAX_TICKS, clkevt->base + JH7110_TIMER_LOAD);
+
+ return jh7110_timer_start(clkevt);
+}
+
+static void jh7110_clockevents_register(struct jh7110_clkevt *clkevt)
+{
+ clkevt->rate = clk_get_rate(clkevt->clk);
+
+ jh7110_set_clockevent(&clkevt->evt);
+ clkevt->evt.name = clkevt->name;
+ clkevt->evt.cpumask = cpu_possible_mask;
+
+ clockevents_config_and_register(&clkevt->evt, clkevt->rate,
+ JH7110_TIMER_MIN_TICKS, JH7110_TIMER_MAX_TICKS);
+}
+
+static void jh7110_timer_release(void *data)
+{
+ struct jh7110_timer_priv *priv = data;
+ int i;
+
+ for (i = 0; i < JH7110_TIMER_CH_MAX; i++) {
+ /* Disable each channel of timer */
+ if (priv->clkevt[i].base)
+ writel(JH7110_TIMER_DIS, priv->clkevt[i].base + JH7110_TIMER_ENABLE);
+
+ /* Avoid no initialization in the loop of the probe */
+ if (!IS_ERR_OR_NULL(priv->clkevt[i].rst))
+ reset_control_assert(priv->clkevt[i].rst);
+
+ if (priv->clkevt[i].cs_is_valid)
+ clocksource_unregister(&priv->clkevt[i].cs);
+ }
+
+ reset_control_assert(priv->prst);
+}
+
+static int jh7110_timer_probe(struct platform_device *pdev)
+{
+ struct jh7110_timer_priv *priv;
+ struct jh7110_clkevt *clkevt;
+ char name[sizeof("chX")];
+ int ch;
+ int ret;
+ void __iomem *base;
+
+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(base))
+ return dev_err_probe(&pdev->dev, PTR_ERR(base),
+ "failed to map registers\n");
+
+ priv->prst = devm_reset_control_get_exclusive(&pdev->dev, "apb");
+ if (IS_ERR(priv->prst))
+ return dev_err_probe(&pdev->dev, PTR_ERR(priv->prst),
+ "failed to get apb reset\n");
+
+ priv->pclk = devm_clk_get_enabled(&pdev->dev, "apb");
+ if (IS_ERR(priv->pclk))
+ return dev_err_probe(&pdev->dev, PTR_ERR(priv->pclk),
+ "failed to get & enable apb clock\n");
+
+ ret = reset_control_deassert(priv->prst);
+ if (ret)
+ return dev_err_probe(&pdev->dev, ret, "failed to deassert apb reset\n");
+
+ ret = devm_add_action_or_reset(&pdev->dev, jh7110_timer_release, priv);
+ if (ret)
+ return ret;
+
+ for (ch = 0; ch < JH7110_TIMER_CH_MAX; ch++) {
+ clkevt = &priv->clkevt[ch];
+ snprintf(name, sizeof(name), "ch%d", ch);
+
+ clkevt->base = base + JH7110_TIMER_CH_BASE(ch);
+ /* Ensure timer is disabled */
+ writel(JH7110_TIMER_DIS, clkevt->base + JH7110_TIMER_ENABLE);
+
+ clkevt->rst = devm_reset_control_get_exclusive(&pdev->dev, name);
+ if (IS_ERR(clkevt->rst))
+ return PTR_ERR(clkevt->rst);
+
+ clkevt->clk = devm_clk_get_enabled(&pdev->dev, name);
+ if (IS_ERR(clkevt->clk))
+ return PTR_ERR(clkevt->clk);
+
+ ret = reset_control_deassert(clkevt->rst);
+ if (ret)
+ return ret;
+
+ clkevt->evt.irq = platform_get_irq(pdev, ch);
+ if (clkevt->evt.irq < 0)
+ return clkevt->evt.irq;
+
+ snprintf(clkevt->name, sizeof(clkevt->name), "jh7110-timer.ch%d", ch);
+ jh7110_clockevents_register(clkevt);
+
+ ret = devm_request_irq(&pdev->dev, clkevt->evt.irq, jh7110_timer_interrupt,
+ IRQF_TIMER | IRQF_IRQPOLL,
+ clkevt->name, &clkevt->evt);
+ if (ret)
+ return ret;
+
+ ret = jh7110_clocksource_init(clkevt);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+static const struct of_device_id jh7110_timer_match[] = {
+ { .compatible = "starfive,jh7110-timer", },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, jh7110_timer_match);
+
+static struct platform_driver jh7110_timer_driver = {
+ .probe = jh7110_timer_probe,
+ .driver = {
+ .name = "jh7110-timer",
+ .of_match_table = jh7110_timer_match,
+ },
+};
+module_platform_driver(jh7110_timer_driver);
+
+MODULE_AUTHOR("Xingyu Wu <xingyu.wu@starfivetech.com>");
+MODULE_DESCRIPTION("StarFive JH7110 timer driver");
+MODULE_LICENSE("GPL");

View File

@ -0,0 +1,277 @@
From 4afaa19bcf6eac558a38468417520b65801e0cfd Mon Sep 17 00:00:00 2001
From: William Qiu <william.qiu@starfivetech.com>
Date: Fri, 22 Dec 2023 17:45:46 +0800
Subject: [PATCH 03/55] pwm: opencores: Add PWM driver support
Add driver for OpenCores PWM Controller. And add compatibility code
which based on StarFive SoC.
Co-developed-by: Hal Feng <hal.feng@starfivetech.com>
Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
Signed-off-by: William Qiu <william.qiu@starfivetech.com>
---
drivers/pwm/Kconfig | 12 ++
drivers/pwm/Makefile | 1 +
drivers/pwm/pwm-ocores.c | 230 +++++++++++++++++++++++++++++++++++++++
3 files changed, 243 insertions(+)
create mode 100644 drivers/pwm/pwm-ocores.c
--- a/drivers/pwm/Kconfig
+++ b/drivers/pwm/Kconfig
@@ -471,6 +471,18 @@ config PWM_NTXEC
controller found in certain e-book readers designed by the original
design manufacturer Netronix.
+config PWM_OCORES
+ tristate "OpenCores PWM support"
+ depends on HAS_IOMEM && OF
+ depends on COMMON_CLK
+ depends on ARCH_STARFIVE || COMPILE_TEST
+ help
+ If you say yes to this option, support will be included for the
+ OpenCores PWM. For details see https://opencores.org/projects/ptc.
+
+ To compile this driver as a module, choose M here: the module
+ will be called pwm-ocores.
+
config PWM_OMAP_DMTIMER
tristate "OMAP Dual-Mode Timer PWM support"
depends on OF
--- a/drivers/pwm/Makefile
+++ b/drivers/pwm/Makefile
@@ -42,6 +42,7 @@ obj-$(CONFIG_PWM_MICROCHIP_CORE) += pwm-
obj-$(CONFIG_PWM_MTK_DISP) += pwm-mtk-disp.o
obj-$(CONFIG_PWM_MXS) += pwm-mxs.o
obj-$(CONFIG_PWM_NTXEC) += pwm-ntxec.o
+obj-$(CONFIG_PWM_OCORES) += pwm-ocores.o
obj-$(CONFIG_PWM_OMAP_DMTIMER) += pwm-omap-dmtimer.o
obj-$(CONFIG_PWM_PCA9685) += pwm-pca9685.o
obj-$(CONFIG_PWM_PXA) += pwm-pxa.o
--- /dev/null
+++ b/drivers/pwm/pwm-ocores.c
@@ -0,0 +1,225 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * OpenCores PWM Driver
+ *
+ * https://opencores.org/projects/ptc
+ *
+ * Copyright (C) 2018-2023 StarFive Technology Co., Ltd.
+ *
+ * Limitations:
+ * - The hardware only do inverted polarity.
+ * - The hardware minimum period / duty_cycle is (1 / pwm_apb clock frequency) ns.
+ * - The hardware maximum period / duty_cycle is (U32_MAX / pwm_apb clock frequency) ns.
+ */
+
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/pwm.h>
+#include <linux/reset.h>
+#include <linux/slab.h>
+
+/* OCPWM_CTRL register bits*/
+#define REG_OCPWM_EN BIT(0)
+#define REG_OCPWM_ECLK BIT(1)
+#define REG_OCPWM_NEC BIT(2)
+#define REG_OCPWM_OE BIT(3)
+#define REG_OCPWM_SIGNLE BIT(4)
+#define REG_OCPWM_INTE BIT(5)
+#define REG_OCPWM_INT BIT(6)
+#define REG_OCPWM_CNTRRST BIT(7)
+#define REG_OCPWM_CAPTE BIT(8)
+
+struct ocores_pwm_device {
+ struct clk *clk;
+ struct reset_control *rst;
+ const struct ocores_pwm_data *data;
+ void __iomem *regs;
+ u32 clk_rate; /* PWM APB clock frequency */
+};
+
+struct ocores_pwm_data {
+ void __iomem *(*get_ch_base)(void __iomem *base, unsigned int channel);
+};
+
+static inline u32 ocores_readl(struct ocores_pwm_device *ddata,
+ unsigned int channel,
+ unsigned int offset)
+{
+ void __iomem *base = ddata->data->get_ch_base ?
+ ddata->data->get_ch_base(ddata->regs, channel) : ddata->regs;
+
+ return readl(base + offset);
+}
+
+static inline void ocores_writel(struct ocores_pwm_device *ddata,
+ unsigned int channel,
+ unsigned int offset, u32 val)
+{
+ void __iomem *base = ddata->data->get_ch_base ?
+ ddata->data->get_ch_base(ddata->regs, channel) : ddata->regs;
+
+ writel(val, base + offset);
+}
+
+static inline struct ocores_pwm_device *chip_to_ocores(struct pwm_chip *chip)
+{
+ return pwmchip_get_drvdata(chip);
+}
+
+static void __iomem *starfive_jh71x0_get_ch_base(void __iomem *base,
+ unsigned int channel)
+{
+ unsigned int offset = (channel > 3 ? 1 << 15 : 0) + (channel & 3) * 0x10;
+
+ return base + offset;
+}
+
+static int ocores_pwm_get_state(struct pwm_chip *chip,
+ struct pwm_device *pwm,
+ struct pwm_state *state)
+{
+ struct ocores_pwm_device *ddata = chip_to_ocores(chip);
+ u32 period_data, duty_data, ctrl_data;
+
+ period_data = ocores_readl(ddata, pwm->hwpwm, 0x8);
+ duty_data = ocores_readl(ddata, pwm->hwpwm, 0x4);
+ ctrl_data = ocores_readl(ddata, pwm->hwpwm, 0xC);
+
+ state->period = DIV_ROUND_UP_ULL((u64)period_data * NSEC_PER_SEC, ddata->clk_rate);
+ state->duty_cycle = DIV_ROUND_UP_ULL((u64)duty_data * NSEC_PER_SEC, ddata->clk_rate);
+ state->polarity = PWM_POLARITY_INVERSED;
+ state->enabled = (ctrl_data & REG_OCPWM_EN) ? true : false;
+
+ return 0;
+}
+
+static int ocores_pwm_apply(struct pwm_chip *chip,
+ struct pwm_device *pwm,
+ const struct pwm_state *state)
+{
+ struct ocores_pwm_device *ddata = chip_to_ocores(chip);
+ u32 ctrl_data = 0;
+ u64 period_data, duty_data;
+
+ if (state->polarity != PWM_POLARITY_INVERSED)
+ return -EINVAL;
+
+ ctrl_data = ocores_readl(ddata, pwm->hwpwm, 0xC);
+ ocores_writel(ddata, pwm->hwpwm, 0xC, 0);
+
+ period_data = DIV_ROUND_DOWN_ULL(state->period * ddata->clk_rate, NSEC_PER_SEC);
+ if (period_data <= U32_MAX)
+ ocores_writel(ddata, pwm->hwpwm, 0x8, (u32)period_data);
+ else
+ return -EINVAL;
+
+ duty_data = DIV_ROUND_DOWN_ULL(state->duty_cycle * ddata->clk_rate, NSEC_PER_SEC);
+ if (duty_data <= U32_MAX)
+ ocores_writel(ddata, pwm->hwpwm, 0x4, (u32)duty_data);
+ else
+ return -EINVAL;
+
+ ocores_writel(ddata, pwm->hwpwm, 0xC, 0);
+
+ if (state->enabled) {
+ ctrl_data = ocores_readl(ddata, pwm->hwpwm, 0xC);
+ ocores_writel(ddata, pwm->hwpwm, 0xC, ctrl_data | REG_OCPWM_EN | REG_OCPWM_OE);
+ }
+
+ return 0;
+}
+
+static const struct pwm_ops ocores_pwm_ops = {
+ .get_state = ocores_pwm_get_state,
+ .apply = ocores_pwm_apply,
+};
+
+static const struct ocores_pwm_data jh7100_pwm_data = {
+ .get_ch_base = starfive_jh71x0_get_ch_base,
+};
+
+static const struct ocores_pwm_data jh7110_pwm_data = {
+ .get_ch_base = starfive_jh71x0_get_ch_base,
+};
+
+static const struct of_device_id ocores_pwm_of_match[] = {
+ { .compatible = "opencores,pwm-v1" },
+ { .compatible = "starfive,jh7100-pwm", .data = &jh7100_pwm_data},
+ { .compatible = "starfive,jh7110-pwm", .data = &jh7110_pwm_data},
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, ocores_pwm_of_match);
+
+static void ocores_reset_control_assert(void *data)
+{
+ reset_control_assert(data);
+}
+
+static int ocores_pwm_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct ocores_pwm_device *ddata;
+ struct pwm_chip *chip;
+ int ret;
+
+ chip = devm_pwmchip_alloc(dev, 8, sizeof(*ddata));
+ if (IS_ERR(chip))
+ return PTR_ERR(chip);
+
+ chip->ops = &ocores_pwm_ops;
+
+ ddata = chip_to_ocores(chip);
+ ddata->data = of_device_get_match_data(dev);
+
+ ddata->regs = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(ddata->regs))
+ return dev_err_probe(dev, PTR_ERR(ddata->regs),
+ "Unable to map IO resources\n");
+
+ ddata->clk = devm_clk_get_enabled(dev, NULL);
+ if (IS_ERR(ddata->clk))
+ return dev_err_probe(dev, PTR_ERR(ddata->clk),
+ "Unable to get pwm's clock\n");
+
+ ddata->rst = devm_reset_control_get_optional_exclusive(dev, NULL);
+ if (IS_ERR(ddata->rst))
+ return dev_err_probe(dev, PTR_ERR(ddata->rst),
+ "Unable to get pwm's reset\n");
+
+ reset_control_deassert(ddata->rst);
+
+ ret = devm_add_action_or_reset(dev, ocores_reset_control_assert, ddata->rst);
+ if (ret)
+ return ret;
+
+ ddata->clk_rate = clk_get_rate(ddata->clk);
+ if (ddata->clk_rate <= 0)
+ return dev_err_probe(dev, ddata->clk_rate,
+ "Unable to get clock's rate\n");
+
+ ret = devm_pwmchip_add(dev, chip);
+ if (ret < 0)
+ return dev_err_probe(dev, ret, "Could not register PWM chip\n");
+
+ platform_set_drvdata(pdev, ddata);
+
+ return ret;
+}
+
+static struct platform_driver ocores_pwm_driver = {
+ .probe = ocores_pwm_probe,
+ .driver = {
+ .name = "ocores-pwm",
+ .of_match_table = ocores_pwm_of_match,
+ },
+};
+module_platform_driver(ocores_pwm_driver);
+
+MODULE_AUTHOR("Jieqin Chen");
+MODULE_AUTHOR("Hal Feng <hal.feng@starfivetech.com>");
+MODULE_DESCRIPTION("OpenCores PWM PTC driver");
+MODULE_LICENSE("GPL");

View File

@ -0,0 +1,60 @@
From c0d35bd6e76ccabfbbbddc41a0d77ecdfbb4ee31 Mon Sep 17 00:00:00 2001
From: "ziv.xu" <ziv.xu@starfivetech.com>
Date: Sun, 4 Feb 2024 10:35:24 +0800
Subject: [PATCH 04/55] spi: spl022: Get and deassert reset in probe()
This fix spi1~6 communication time out.
Signed-off-by: ziv.xu <ziv.xu@starfivetech.com>
Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
---
drivers/spi/spi-pl022.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
--- a/drivers/spi/spi-pl022.c
+++ b/drivers/spi/spi-pl022.c
@@ -33,6 +33,7 @@
#include <linux/pm_runtime.h>
#include <linux/of.h>
#include <linux/pinctrl/consumer.h>
+#include <linux/reset.h>
/*
* This macro is used to define some register default values.
@@ -363,6 +364,7 @@ struct pl022 {
resource_size_t phybase;
void __iomem *virtbase;
struct clk *clk;
+ struct reset_control *rst;
struct spi_controller *host;
struct pl022_ssp_controller *host_info;
struct spi_transfer *cur_transfer;
@@ -1930,6 +1932,19 @@ static int pl022_probe(struct amba_devic
goto err_no_clk;
}
+ pl022->rst = devm_reset_control_get(&adev->dev, NULL);
+ if (IS_ERR(pl022->rst)) {
+ status = PTR_ERR(pl022->rst);
+ dev_err(&adev->dev, "could not retrieve SSP/SPI bus reset\n");
+ goto err_no_rst;
+ }
+
+ status = reset_control_deassert(pl022->rst);
+ if (status) {
+ dev_err(&adev->dev, "could not deassert SSP/SPI bus reset\n");
+ goto err_no_rst_de;
+ }
+
/* Disable SSP */
writew((readw(SSP_CR1(pl022->virtbase)) & (~SSP_CR1_MASK_SSE)),
SSP_CR1(pl022->virtbase));
@@ -1985,6 +2000,8 @@ static int pl022_probe(struct amba_devic
if (platform_info->enable_dma)
pl022_dma_remove(pl022);
err_no_irq:
+ err_no_rst_de:
+ err_no_rst:
err_no_clk:
err_no_ioremap:
amba_release_regions(adev);

View File

@ -0,0 +1,33 @@
From a37f1f4370af69644c512e5e296a10357338c310 Mon Sep 17 00:00:00 2001
From: Hal Feng <hal.feng@starfivetech.com>
Date: Fri, 12 May 2023 17:33:20 +0800
Subject: [PATCH 05/55] i2c: designware: Delete SMBus functionalities
The driver didn't implement the smbus interface,
so replace the SMBus functionalities with
I2C_FUNC_SMBUS_EMUL.
Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
---
drivers/i2c/busses/i2c-designware-core.h | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
--- a/drivers/i2c/busses/i2c-designware-core.h
+++ b/drivers/i2c/busses/i2c-designware-core.h
@@ -17,12 +17,10 @@
#include <linux/regmap.h>
#include <linux/types.h>
-#define DW_IC_DEFAULT_FUNCTIONALITY (I2C_FUNC_I2C | \
- I2C_FUNC_SMBUS_BYTE | \
- I2C_FUNC_SMBUS_BYTE_DATA | \
- I2C_FUNC_SMBUS_WORD_DATA | \
- I2C_FUNC_SMBUS_BLOCK_DATA | \
- I2C_FUNC_SMBUS_I2C_BLOCK)
+#define DW_IC_DEFAULT_FUNCTIONALITY (I2C_FUNC_I2C | (I2C_FUNC_SMBUS_EMUL \
+ & ~I2C_FUNC_SMBUS_QUICK \
+ & ~I2C_FUNC_SMBUS_PROC_CALL \
+ & ~I2C_FUNC_SMBUS_PEC))
#define DW_IC_CON_MASTER BIT(0)
#define DW_IC_CON_SPEED_STD (1 << 1)

View File

@ -0,0 +1,29 @@
From 8850887a7b71b55250be2a15802963d6b32ea8ab Mon Sep 17 00:00:00 2001
From: Ziv Xu <ziv.xu@starfivetech.com>
Date: Fri, 19 Jan 2024 15:22:55 +0800
Subject: [PATCH 06/55] drivers: mtd: gigadevice: add gd25lq256d 32M flash
support
add gd25lq256d 32M flash support
Signed-off-by: Ziv Xu <ziv.xu@starfivetech.com>
Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
---
drivers/mtd/spi-nor/gigadevice.c | 6 ++++++
1 file changed, 6 insertions(+)
--- a/drivers/mtd/spi-nor/gigadevice.c
+++ b/drivers/mtd/spi-nor/gigadevice.c
@@ -95,6 +95,12 @@ static const struct flash_info gigadevic
.size = SZ_16M,
.flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB,
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
+ }, {
+ .id = SNOR_ID(0xc8, 0x60, 0x19),
+ .name = "gd25lq256d",
+ .size = SZ_32M,
+ .flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_QUAD_PP,
+ .no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
},
};

View File

@ -0,0 +1,804 @@
From f7db05ea5fffebed6db6693333a6877aa707b16d Mon Sep 17 00:00:00 2001
From: "shanlong.li" <shanlong.li@starfivetech.com>
Date: Thu, 8 Jun 2023 00:07:15 -0700
Subject: [PATCH 07/55] driver: mailbox: Add mailbox driver
Add mailbox driver.
Signed-off-by: shanlong.li <shanlong.li@starfivetech.com>
Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
---
drivers/mailbox/Kconfig | 13 +
drivers/mailbox/Makefile | 4 +
drivers/mailbox/starfive_mailbox-test.c | 405 ++++++++++++++++++++++++
drivers/mailbox/starfive_mailbox.c | 345 ++++++++++++++++++++
4 files changed, 767 insertions(+)
create mode 100644 drivers/mailbox/starfive_mailbox-test.c
create mode 100644 drivers/mailbox/starfive_mailbox.c
--- a/drivers/mailbox/Kconfig
+++ b/drivers/mailbox/Kconfig
@@ -295,4 +295,17 @@ config QCOM_IPCC
acts as an interrupt controller for receiving interrupts from clients.
Say Y here if you want to build this driver.
+config STARFIVE_MBOX
+ tristate "Platform Starfive Mailbox"
+ depends on OF
+ help
+ Say Y here if you want to build a platform specific variant RISCV
+ controller driver.
+
+config STARFIVE_MBOX_TEST
+ tristate "Starfive Mailbox Test Client"
+ depends on OF
+ depends on HAS_IOMEM
+ help
+ Test client to help with testing new Controller driver implementations.
endif
--- a/drivers/mailbox/Makefile
+++ b/drivers/mailbox/Makefile
@@ -64,3 +64,7 @@ obj-$(CONFIG_SPRD_MBOX) += sprd-mailbox
obj-$(CONFIG_QCOM_CPUCP_MBOX) += qcom-cpucp-mbox.o
obj-$(CONFIG_QCOM_IPCC) += qcom-ipcc.o
+
+obj-$(CONFIG_STARFIVE_MBOX) += starfive_mailbox.o
+ccflags-$(CONFIG_STARFIVE_MBOX) := -Wno-error=missing-prototypes
+obj-$(CONFIG_STARFIVE_MBOX_TEST) += starfive_mailbox-test.o
--- /dev/null
+++ b/drivers/mailbox/starfive_mailbox-test.c
@@ -0,0 +1,405 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2015 ST Microelectronics
+ *
+ * Author: Lee Jones <lee.jones@linaro.org>
+ */
+
+#include <linux/debugfs.h>
+#include <linux/err.h>
+#include <linux/fs.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/mailbox_client.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/poll.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+#include <linux/sched/signal.h>
+
+#include <linux/mailbox_controller.h>
+
+#define MBOX_MAX_SIG_LEN 8
+#define MBOX_MAX_MSG_LEN 16
+#define MBOX_BYTES_PER_LINE 16
+#define MBOX_HEXDUMP_LINE_LEN ((MBOX_BYTES_PER_LINE * 4) + 2)
+#define MBOX_HEXDUMP_MAX_LEN (MBOX_HEXDUMP_LINE_LEN * (MBOX_MAX_MSG_LEN / MBOX_BYTES_PER_LINE))
+
+static bool mbox_data_ready;
+
+struct mbox_test_device {
+ struct device *dev;
+ void __iomem *tx_mmio;
+ void __iomem *rx_mmio;
+ struct mbox_chan *tx_channel;
+ struct mbox_chan *rx_channel;
+ char *rx_buffer;
+ char *signal;
+ char *message;
+ spinlock_t lock;
+ wait_queue_head_t waitq;
+ struct fasync_struct *async_queue;
+ struct dentry *root_debugfs_dir;
+};
+
+static ssize_t mbox_test_signal_write(struct file *filp,
+ const char __user *userbuf,
+ size_t count, loff_t *ppos)
+{
+ struct mbox_test_device *tdev = filp->private_data;
+
+ if (!tdev->tx_channel) {
+ dev_err(tdev->dev, "Channel cannot do Tx\n");
+ return -EINVAL;
+ }
+
+ if (count > MBOX_MAX_SIG_LEN) {
+ dev_err(tdev->dev,
+ "Signal length %zd greater than max allowed %d\n",
+ count, MBOX_MAX_SIG_LEN);
+ return -EINVAL;
+ }
+
+ /* Only allocate memory if we need to */
+ if (!tdev->signal) {
+ tdev->signal = kzalloc(MBOX_MAX_SIG_LEN, GFP_KERNEL);
+ if (!tdev->signal)
+ return -ENOMEM;
+ }
+
+ if (copy_from_user(tdev->signal, userbuf, count)) {
+ kfree(tdev->signal);
+ tdev->signal = NULL;
+ return -EFAULT;
+ }
+
+ return count;
+}
+
+static const struct file_operations mbox_test_signal_ops = {
+ .write = mbox_test_signal_write,
+ .open = simple_open,
+ .llseek = generic_file_llseek,
+};
+
+static int mbox_test_message_fasync(int fd, struct file *filp, int on)
+{
+ struct mbox_test_device *tdev = filp->private_data;
+
+ return fasync_helper(fd, filp, on, &tdev->async_queue);
+}
+
+static ssize_t mbox_test_message_write(struct file *filp,
+ const char __user *userbuf,
+ size_t count, loff_t *ppos)
+{
+ struct mbox_test_device *tdev = filp->private_data;
+ void *data;
+ int ret;
+
+ if (!tdev->tx_channel) {
+ dev_err(tdev->dev, "Channel cannot do Tx\n");
+ return -EINVAL;
+ }
+
+ if (count > MBOX_MAX_MSG_LEN) {
+ dev_err(tdev->dev,
+ "Message length %zd greater than max allowed %d\n",
+ count, MBOX_MAX_MSG_LEN);
+ return -EINVAL;
+ }
+
+ tdev->message = kzalloc(MBOX_MAX_MSG_LEN, GFP_KERNEL);
+ if (!tdev->message)
+ return -ENOMEM;
+
+ ret = copy_from_user(tdev->message, userbuf, count);
+ if (ret) {
+ ret = -EFAULT;
+ goto out;
+ }
+
+ if (tdev->tx_mmio && tdev->signal) {
+ print_hex_dump_bytes("Client: Sending: Signal: ", DUMP_PREFIX_ADDRESS,
+ tdev->signal, MBOX_MAX_SIG_LEN);
+
+ data = tdev->signal;
+ } else
+ data = tdev->message;
+
+ print_hex_dump_bytes("Client: Sending: Message: ", DUMP_PREFIX_ADDRESS,
+ tdev->message, MBOX_MAX_MSG_LEN);
+
+ ret = mbox_send_message(tdev->tx_channel, data);
+ mbox_chan_txdone(tdev->tx_channel, ret);
+ if (ret < 0)
+ dev_err(tdev->dev, "Failed to send message via mailbox\n");
+
+out:
+ kfree(tdev->signal);
+ kfree(tdev->message);
+ tdev->signal = NULL;
+
+ return ret < 0 ? ret : count;
+}
+
+static bool mbox_test_message_data_ready(struct mbox_test_device *tdev)
+{
+ bool data_ready;
+ unsigned long flags;
+
+ spin_lock_irqsave(&tdev->lock, flags);
+ data_ready = mbox_data_ready;
+ spin_unlock_irqrestore(&tdev->lock, flags);
+
+ return data_ready;
+}
+
+static ssize_t mbox_test_message_read(struct file *filp, char __user *userbuf,
+ size_t count, loff_t *ppos)
+{
+ struct mbox_test_device *tdev = filp->private_data;
+ unsigned long flags;
+ char *touser, *ptr;
+ int ret;
+
+ touser = kzalloc(MBOX_HEXDUMP_MAX_LEN + 1, GFP_KERNEL);
+ if (!touser)
+ return -ENOMEM;
+
+ if (!tdev->rx_channel) {
+ ret = snprintf(touser, 20, "<NO RX CAPABILITY>\n");
+ ret = simple_read_from_buffer(userbuf, count, ppos,
+ touser, ret);
+ goto kfree_err;
+ }
+
+ do {
+ if (mbox_test_message_data_ready(tdev))
+ break;
+
+ if (filp->f_flags & O_NONBLOCK) {
+ ret = -EAGAIN;
+ goto waitq_err;
+ }
+
+ if (signal_pending(current)) {
+ ret = -ERESTARTSYS;
+ goto waitq_err;
+ }
+ schedule();
+
+ } while (1);
+
+ spin_lock_irqsave(&tdev->lock, flags);
+
+ ptr = tdev->rx_buffer;
+
+ mbox_data_ready = false;
+
+ spin_unlock_irqrestore(&tdev->lock, flags);
+ if (copy_to_user((void __user *)userbuf, ptr, 4))
+ ret = -EFAULT;
+
+waitq_err:
+ __set_current_state(TASK_RUNNING);
+kfree_err:
+ kfree(touser);
+ return ret;
+}
+
+static __poll_t
+mbox_test_message_poll(struct file *filp, struct poll_table_struct *wait)
+{
+ struct mbox_test_device *tdev = filp->private_data;
+
+ poll_wait(filp, &tdev->waitq, wait);
+
+ if (mbox_test_message_data_ready(tdev))
+ return EPOLLIN | EPOLLRDNORM;
+ return 0;
+}
+
+static const struct file_operations mbox_test_message_ops = {
+ .write = mbox_test_message_write,
+ .read = mbox_test_message_read,
+ .fasync = mbox_test_message_fasync,
+ .poll = mbox_test_message_poll,
+ .open = simple_open,
+ .llseek = generic_file_llseek,
+};
+
+static int mbox_test_add_debugfs(struct platform_device *pdev,
+ struct mbox_test_device *tdev)
+{
+ if (!debugfs_initialized())
+ return 0;
+
+ tdev->root_debugfs_dir = debugfs_create_dir(dev_name(&pdev->dev), NULL);
+ if (!tdev->root_debugfs_dir) {
+ dev_err(&pdev->dev, "Failed to create Mailbox debugfs\n");
+ return -EINVAL;
+ }
+
+ debugfs_create_file("message", 0600, tdev->root_debugfs_dir,
+ tdev, &mbox_test_message_ops);
+
+ debugfs_create_file("signal", 0200, tdev->root_debugfs_dir,
+ tdev, &mbox_test_signal_ops);
+
+ return 0;
+}
+
+static void mbox_test_receive_message(struct mbox_client *client, void *message)
+{
+ struct mbox_test_device *tdev = dev_get_drvdata(client->dev);
+ unsigned long flags;
+
+ spin_lock_irqsave(&tdev->lock, flags);
+ if (tdev->rx_mmio) {
+ memcpy_fromio(tdev->rx_buffer, tdev->rx_mmio, MBOX_MAX_MSG_LEN);
+ print_hex_dump_bytes("Client: Received [MMIO]: ", DUMP_PREFIX_ADDRESS,
+ tdev->rx_buffer, MBOX_MAX_MSG_LEN);
+ } else if (message) {
+ print_hex_dump_bytes("Client: Received [API]: ", DUMP_PREFIX_ADDRESS,
+ message, MBOX_MAX_MSG_LEN);
+ memcpy(tdev->rx_buffer, message, MBOX_MAX_MSG_LEN);
+ }
+ mbox_data_ready = true;
+ spin_unlock_irqrestore(&tdev->lock, flags);
+}
+
+static void mbox_test_prepare_message(struct mbox_client *client, void *message)
+{
+ struct mbox_test_device *tdev = dev_get_drvdata(client->dev);
+
+ if (tdev->tx_mmio) {
+ if (tdev->signal)
+ memcpy_toio(tdev->tx_mmio, tdev->message, MBOX_MAX_MSG_LEN);
+ else
+ memcpy_toio(tdev->tx_mmio, message, MBOX_MAX_MSG_LEN);
+ }
+}
+
+static struct mbox_chan *
+mbox_test_request_channel(struct platform_device *pdev, const char *name)
+{
+ struct mbox_client *client;
+ struct mbox_chan *channel;
+
+ client = devm_kzalloc(&pdev->dev, sizeof(*client), GFP_KERNEL);
+ if (!client)
+ return ERR_PTR(-ENOMEM);
+
+ client->dev = &pdev->dev;
+ client->rx_callback = mbox_test_receive_message;
+ client->tx_prepare = mbox_test_prepare_message;
+ client->tx_block = false;
+ client->knows_txdone = false;
+ client->tx_tout = 500;
+
+ channel = mbox_request_channel_byname(client, name);
+ if (IS_ERR(channel)) {
+ dev_warn(&pdev->dev, "Failed to request %s channel\n", name);
+ return NULL;
+ }
+
+ return channel;
+}
+
+static int mbox_test_probe(struct platform_device *pdev)
+{
+ struct mbox_test_device *tdev;
+ struct resource *res;
+ resource_size_t size;
+ int ret;
+
+ tdev = devm_kzalloc(&pdev->dev, sizeof(*tdev), GFP_KERNEL);
+ if (!tdev)
+ return -ENOMEM;
+
+ /* It's okay for MMIO to be NULL */
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ tdev->tx_mmio = devm_ioremap_resource(&pdev->dev, res);
+ if (PTR_ERR(tdev->tx_mmio) == -EBUSY) {
+ /* if reserved area in SRAM, try just ioremap */
+ size = resource_size(res);
+ tdev->tx_mmio = devm_ioremap(&pdev->dev, res->start, size);
+ } else if (IS_ERR(tdev->tx_mmio)) {
+ tdev->tx_mmio = NULL;
+ }
+
+ /* If specified, second reg entry is Rx MMIO */
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ tdev->rx_mmio = devm_ioremap_resource(&pdev->dev, res);
+ if (PTR_ERR(tdev->rx_mmio) == -EBUSY) {
+ size = resource_size(res);
+ tdev->rx_mmio = devm_ioremap(&pdev->dev, res->start, size);
+ } else if (IS_ERR(tdev->rx_mmio)) {
+ tdev->rx_mmio = tdev->tx_mmio;
+ }
+
+ tdev->tx_channel = mbox_test_request_channel(pdev, "tx");
+ tdev->rx_channel = mbox_test_request_channel(pdev, "rx");
+
+ if (!tdev->tx_channel && !tdev->rx_channel)
+ return -EPROBE_DEFER;
+
+ /* If Rx is not specified but has Rx MMIO, then Rx = Tx */
+ if (!tdev->rx_channel && (tdev->rx_mmio != tdev->tx_mmio))
+ tdev->rx_channel = tdev->tx_channel;
+
+ tdev->dev = &pdev->dev;
+ platform_set_drvdata(pdev, tdev);
+
+ spin_lock_init(&tdev->lock);
+
+ if (tdev->rx_channel) {
+ tdev->rx_buffer = devm_kzalloc(&pdev->dev,
+ MBOX_MAX_MSG_LEN, GFP_KERNEL);
+ if (!tdev->rx_buffer)
+ return -ENOMEM;
+ }
+
+ ret = mbox_test_add_debugfs(pdev, tdev);
+ if (ret)
+ return ret;
+
+ dev_info(&pdev->dev, "Successfully registered\n");
+
+ return 0;
+}
+
+static void mbox_test_remove(struct platform_device *pdev)
+{
+ struct mbox_test_device *tdev = platform_get_drvdata(pdev);
+
+ debugfs_remove_recursive(tdev->root_debugfs_dir);
+
+ if (tdev->tx_channel)
+ mbox_free_channel(tdev->tx_channel);
+ if (tdev->rx_channel)
+ mbox_free_channel(tdev->rx_channel);
+}
+
+static const struct of_device_id mbox_test_match[] = {
+ { .compatible = "starfive,mailbox-test" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, mbox_test_match);
+
+static struct platform_driver mbox_test_driver = {
+ .driver = {
+ .name = "mailbox_test",
+ .of_match_table = mbox_test_match,
+ },
+ .probe = mbox_test_probe,
+ .remove = mbox_test_remove,
+};
+module_platform_driver(mbox_test_driver);
+
+MODULE_DESCRIPTION("Generic Mailbox Testing Facility");
+MODULE_AUTHOR("Lee Jones <lee.jones@linaro.org");
+MODULE_LICENSE("GPL v2");
--- /dev/null
+++ b/drivers/mailbox/starfive_mailbox.c
@@ -0,0 +1,345 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * mailbox driver for StarFive JH7110 SoC
+ *
+ * Copyright (c) 2021 StarFive Technology Co., Ltd.
+ * Author: Shanlong Li <shanlong.li@starfivetech.com>
+ */
+
+#include <linux/bitops.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/mailbox_controller.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/clk.h>
+#include <linux/reset.h>
+#include <linux/pm_runtime.h>
+
+#include "mailbox.h"
+
+#define MBOX_CHAN_MAX 4
+
+#define MBOX_BASE(mbox, ch) ((mbox)->base + ((ch) * 0x10))
+#define MBOX_IRQ_REG 0x00
+#define MBOX_SET_REG 0x04
+#define MBOX_CLR_REG 0x08
+#define MBOX_CMD_REG 0x0c
+#define MBC_PEND_SMRY 0x100
+
+typedef enum {
+ MAILBOX_CORE_U7 = 0,
+ MAILBOX_CORE_HIFI4,
+ MAILBOX_CORE_E2,
+ MAILBOX_CORE_RSVD0,
+ MAILBOX_CORE_NUM,
+} mailbox_core_t;
+
+struct mailbox_irq_name_c{
+ int id;
+ char name[16];
+};
+
+static const struct mailbox_irq_name_c irq_peer_name[MBOX_CHAN_MAX] = {
+ {MAILBOX_CORE_U7, "u74_core"},
+ {MAILBOX_CORE_HIFI4, "hifi4_core"},
+ {MAILBOX_CORE_E2, "e24_core"},
+ {MAILBOX_CORE_RSVD0, "" },
+};
+
+/**
+ * starfive mailbox channel information
+ *
+ * A channel can be used for TX or RX, it can trigger remote
+ * processor interrupt to notify remote processor and can receive
+ * interrupt if has incoming message.
+ *
+ * @dst_irq: Interrupt vector for remote processor
+ * @core_id: id for remote processor
+ */
+struct starfive_chan_info {
+ unsigned int dst_irq;
+ mailbox_core_t core_id;
+};
+
+/**
+ * starfive mailbox controller data
+ *
+ * Mailbox controller includes 4 channels and can allocate
+ * channel for message transferring.
+ *
+ * @dev: Device to which it is attached
+ * @base: Base address of the register mapping region
+ * @chan: Representation of channels in mailbox controller
+ * @mchan: Representation of channel info
+ * @controller: Representation of a communication channel controller
+ */
+struct starfive_mbox {
+ struct device *dev;
+ void __iomem *base;
+ struct mbox_chan chan[MBOX_CHAN_MAX];
+ struct starfive_chan_info mchan[MBOX_CHAN_MAX];
+ struct mbox_controller controller;
+ struct clk *clk;
+ struct reset_control *rst_rresetn;
+};
+
+static struct starfive_mbox *to_starfive_mbox(struct mbox_controller *mbox)
+{
+ return container_of(mbox, struct starfive_mbox, controller);
+}
+
+static struct mbox_chan *
+starfive_of_mbox_index_xlate(struct mbox_controller *mbox,
+ const struct of_phandle_args *sp)
+{
+ struct starfive_mbox *sbox;
+
+ int ind = sp->args[0];
+ int core_id = sp->args[1];
+
+ if (ind >= mbox->num_chans || core_id >= MAILBOX_CORE_NUM)
+ return ERR_PTR(-EINVAL);
+
+ sbox = to_starfive_mbox(mbox);
+
+ sbox->mchan[ind].core_id = core_id;
+
+ return &mbox->chans[ind];
+}
+
+static irqreturn_t starfive_rx_irq_handler(int irq, void *p)
+{
+ struct mbox_chan *chan = p;
+ unsigned long ch = (unsigned long)chan->con_priv;
+ struct starfive_mbox *mbox = to_starfive_mbox(chan->mbox);
+ void __iomem *base = MBOX_BASE(mbox, ch);
+ u32 val;
+
+ val = readl(base + MBOX_CMD_REG);
+ if (!val)
+ return IRQ_NONE;
+
+ mbox_chan_received_data(chan, (void *)&val);
+ writel(val, base + MBOX_CLR_REG);
+ return IRQ_HANDLED;
+}
+
+static int starfive_mbox_check_state(struct mbox_chan *chan)
+{
+ unsigned long ch = (unsigned long)chan->con_priv;
+ struct starfive_mbox *mbox = to_starfive_mbox(chan->mbox);
+ unsigned long irq_flag = IRQF_SHARED;
+ long ret = 0;
+
+ pm_runtime_get_sync(mbox->dev);
+ /* MAILBOX should be with IRQF_NO_SUSPEND set */
+ if (!mbox->dev->pm_domain)
+ irq_flag |= IRQF_NO_SUSPEND;
+
+ /* Mailbox is idle so directly bail out */
+ if (readl(mbox->base + MBC_PEND_SMRY) & BIT(ch))
+ return -EBUSY;
+
+ if (mbox->mchan[ch].dst_irq > 0) {
+ dev_dbg(mbox->dev, "%s: host IRQ = %d, ch:%ld", __func__, mbox->mchan[ch].dst_irq, ch);
+ ret = devm_request_irq(mbox->dev, mbox->mchan[ch].dst_irq, starfive_rx_irq_handler,
+ irq_flag, irq_peer_name[ch].name, chan);
+ if (ret < 0)
+ dev_err(mbox->dev, "request_irq %d failed\n", mbox->mchan[ch].dst_irq);
+ }
+
+ return ret;
+}
+
+static int starfive_mbox_startup(struct mbox_chan *chan)
+{
+ return starfive_mbox_check_state(chan);
+}
+
+static void starfive_mbox_shutdown(struct mbox_chan *chan)
+{
+ struct starfive_mbox *mbox = to_starfive_mbox(chan->mbox);
+ unsigned long ch = (unsigned long)chan->con_priv;
+ void __iomem *base = MBOX_BASE(mbox, ch);
+
+ writel(0x0, base + MBOX_IRQ_REG);
+ writel(0x0, base + MBOX_CLR_REG);
+
+ if (mbox->mchan[ch].dst_irq > 0)
+ devm_free_irq(mbox->dev, mbox->mchan[ch].dst_irq, chan);
+ pm_runtime_put_sync(mbox->dev);
+}
+
+static int starfive_mbox_send_data(struct mbox_chan *chan, void *msg)
+{
+ unsigned long ch = (unsigned long)chan->con_priv;
+ struct starfive_mbox *mbox = to_starfive_mbox(chan->mbox);
+ struct starfive_chan_info *mchan = &mbox->mchan[ch];
+ void __iomem *base = MBOX_BASE(mbox, ch);
+ u32 *buf = msg;
+
+ /* Ensure channel is released */
+ if (readl(mbox->base + MBC_PEND_SMRY) & BIT(ch)) {
+ pr_debug("%s:%d. busy\n", __func__, __LINE__);
+ return -EBUSY;
+ }
+
+ /* Clear mask for destination interrupt */
+ writel(BIT(mchan->core_id), base + MBOX_IRQ_REG);
+
+ /* Fill message data */
+ writel(*buf, base + MBOX_SET_REG);
+ return 0;
+}
+
+static struct mbox_chan_ops starfive_mbox_ops = {
+ .startup = starfive_mbox_startup,
+ .send_data = starfive_mbox_send_data,
+ .shutdown = starfive_mbox_shutdown,
+};
+
+static const struct of_device_id starfive_mbox_of_match[] = {
+ { .compatible = "starfive,mail_box",},
+ {},
+};
+
+MODULE_DEVICE_TABLE(of, starfive_mbox_of_match);
+
+void starfive_mailbox_init(struct starfive_mbox *mbox)
+{
+ mbox->clk = devm_clk_get_optional(mbox->dev, "clk_apb");
+ if (IS_ERR(mbox->clk)) {
+ dev_err(mbox->dev, "failed to get mailbox\n");
+ return;
+ }
+
+ mbox->rst_rresetn = devm_reset_control_get_exclusive(mbox->dev, "mbx_rre");
+ if (IS_ERR(mbox->rst_rresetn)) {
+ dev_err(mbox->dev, "failed to get mailbox reset\n");
+ return;
+ }
+
+ clk_prepare_enable(mbox->clk);
+ reset_control_deassert(mbox->rst_rresetn);
+}
+
+static int starfive_mbox_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct starfive_mbox *mbox;
+ struct mbox_chan *chan;
+ struct resource *res;
+ unsigned long ch;
+ int err;
+
+ mbox = devm_kzalloc(dev, sizeof(*mbox), GFP_KERNEL);
+ if (!mbox)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ mbox->base = devm_ioremap_resource(dev, res);
+ mbox->dev = dev;
+
+ if (IS_ERR(mbox->base))
+ return PTR_ERR(mbox->base);
+
+ starfive_mailbox_init(mbox);
+
+ mbox->controller.dev = dev;
+ mbox->controller.chans = mbox->chan;
+ mbox->controller.num_chans = MBOX_CHAN_MAX;
+ mbox->controller.ops = &starfive_mbox_ops;
+ mbox->controller.of_xlate = starfive_of_mbox_index_xlate;
+ mbox->controller.txdone_irq = true;
+ mbox->controller.txdone_poll = false;
+
+ /* Initialize mailbox channel data */
+ chan = mbox->chan;
+ for (ch = 0; ch < MBOX_CHAN_MAX; ch++) {
+ mbox->mchan[ch].dst_irq = 0;
+ mbox->mchan[ch].core_id = (mailbox_core_t)ch;
+ chan[ch].con_priv = (void *)ch;
+ }
+ mbox->mchan[MAILBOX_CORE_HIFI4].dst_irq = platform_get_irq(pdev, 0);
+ mbox->mchan[MAILBOX_CORE_E2].dst_irq = platform_get_irq(pdev, 1);
+
+ err = mbox_controller_register(&mbox->controller);
+ if (err) {
+ dev_err(dev, "Failed to register mailbox %d\n", err);
+ return err;
+ }
+
+ platform_set_drvdata(pdev, mbox);
+ dev_info(dev, "Mailbox enabled\n");
+ pm_runtime_set_active(dev);
+ pm_runtime_enable(dev);
+
+ return 0;
+}
+
+static void starfive_mbox_remove(struct platform_device *pdev)
+{
+ struct starfive_mbox *mbox = platform_get_drvdata(pdev);
+
+ mbox_controller_unregister(&mbox->controller);
+ devm_clk_put(mbox->dev, mbox->clk);
+ pm_runtime_disable(mbox->dev);
+}
+
+static int __maybe_unused starfive_mbox_suspend(struct device *dev)
+{
+ struct starfive_mbox *mbox = dev_get_drvdata(dev);
+
+ clk_disable_unprepare(mbox->clk);
+
+ return 0;
+}
+
+static int __maybe_unused starfive_mbox_resume(struct device *dev)
+{
+ struct starfive_mbox *mbox = dev_get_drvdata(dev);
+ int ret;
+
+ ret = clk_prepare_enable(mbox->clk);
+ if (ret)
+ dev_err(dev, "failed to enable clock\n");
+
+ return ret;
+}
+
+static const struct dev_pm_ops starfive_mbox_pm_ops = {
+ .suspend = starfive_mbox_suspend,
+ .resume = starfive_mbox_resume,
+ SET_RUNTIME_PM_OPS(starfive_mbox_suspend, starfive_mbox_resume, NULL)
+};
+static struct platform_driver starfive_mbox_driver = {
+ .probe = starfive_mbox_probe,
+ .remove = starfive_mbox_remove,
+ .driver = {
+ .name = "mailbox",
+ .of_match_table = starfive_mbox_of_match,
+ .pm = &starfive_mbox_pm_ops,
+ },
+};
+
+static int __init starfive_mbox_init(void)
+{
+ return platform_driver_register(&starfive_mbox_driver);
+}
+core_initcall(starfive_mbox_init);
+
+static void __exit starfive_mbox_exit(void)
+{
+ platform_driver_unregister(&starfive_mbox_driver);
+}
+module_exit(starfive_mbox_exit);
+
+MODULE_DESCRIPTION("StarFive Mailbox Controller driver");
+MODULE_AUTHOR("Shanlong Li <shanlong.li@starfivetech.com>");
+MODULE_LICENSE("GPL");

View File

@ -0,0 +1,787 @@
From 5969d5b6f7cac455f6f9afc0fe64ac706002e5b5 Mon Sep 17 00:00:00 2001
From: "ziv.xu" <ziv.xu@starfivetech.com>
Date: Fri, 9 Jun 2023 15:31:53 +0800
Subject: [PATCH 08/55] driver: rtc: Add StarFive JH7110 rtc driver
Add RTC driver and support for StarFive JH7110 SoC.
Signed-off-by: ziv.xu <ziv.xu@starfivetech.com>
Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
---
drivers/rtc/Kconfig | 8 +
drivers/rtc/Makefile | 1 +
drivers/rtc/rtc-starfive.c | 741 +++++++++++++++++++++++++++++++++++++
3 files changed, 750 insertions(+)
create mode 100644 drivers/rtc/rtc-starfive.c
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -1372,6 +1372,14 @@ config RTC_DRV_NTXEC
embedded controller found in certain e-book readers designed by the
original design manufacturer Netronix.
+config RTC_DRV_STARFIVE
+ tristate "StarFive 32.768k-RTC"
+ depends on ARCH_STARFIVE
+ depends on OF
+ help
+ If you say Y here you will get support for the RTC found on
+ StarFive SOCS.
+
comment "on-CPU RTC drivers"
config RTC_DRV_ASM9260
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -169,6 +169,7 @@ obj-$(CONFIG_RTC_DRV_SH) += rtc-sh.o
obj-$(CONFIG_RTC_DRV_SNVS) += rtc-snvs.o
obj-$(CONFIG_RTC_DRV_SPEAR) += rtc-spear.o
obj-$(CONFIG_RTC_DRV_STARFIRE) += rtc-starfire.o
+obj-$(CONFIG_RTC_DRV_STARFIVE) += rtc-starfive.o
obj-$(CONFIG_RTC_DRV_STK17TA8) += rtc-stk17ta8.o
obj-$(CONFIG_RTC_DRV_ST_LPC) += rtc-st-lpc.o
obj-$(CONFIG_RTC_DRV_STM32) += rtc-stm32.o
--- /dev/null
+++ b/drivers/rtc/rtc-starfive.c
@@ -0,0 +1,741 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * RTC driver for the StarFive JH7110 SoC
+ *
+ * Copyright (C) 2021 StarFive Technology Co., Ltd.
+ */
+
+#include <asm/delay.h>
+#include <linux/bcd.h>
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/reset.h>
+#include <linux/completion.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/iopoll.h>
+#include <linux/platform_device.h>
+#include <linux/rtc.h>
+
+/* Registers */
+#define SFT_RTC_CFG 0x00
+#define SFT_RTC_SW_CAL_VALUE 0x04
+#define SFT_RTC_HW_CAL_CFG 0x08
+#define SFT_RTC_CMP_CFG 0x0C
+#define SFT_RTC_IRQ_EN 0x10
+#define SFT_RTC_IRQ_EVEVT 0x14
+#define SFT_RTC_IRQ_STATUS 0x18
+#define SFT_RTC_CAL_VALUE 0x24
+#define SFT_RTC_CFG_TIME 0x28
+#define SFT_RTC_CFG_DATE 0x2C
+#define SFT_RTC_ACT_TIME 0x34
+#define SFT_RTC_ACT_DATE 0x38
+#define SFT_RTC_TIME 0x3C
+#define SFT_RTC_DATE 0x40
+#define SFT_RTC_TIME_LATCH 0x44
+#define SFT_RTC_DATE_LATCH 0x48
+
+/* RTC_CFG */
+#define RTC_CFG_ENABLE_SHIFT 0 /* RW: RTC Enable. */
+#define RTC_CFG_CAL_EN_HW_SHIFT 1 /* RW: Enable of hardware calibretion. */
+#define RTC_CFG_CAL_SEL_SHIFT 2 /* RW: select the hw/sw calibretion mode.*/
+#define RTC_CFG_HOUR_MODE_SHIFT 3 /* RW: time hour mode. 24h|12h */
+
+/* RTC_SW_CAL_VALUE */
+#define RTC_SW_CAL_VALUE_MASK GENMASK(15, 0)
+#define RTC_SW_CAL_MAX RTC_SW_CAL_VALUE_MASK
+#define RTC_SW_CAL_MIN 0
+#define RTC_TICKS_PER_SEC 32768 /* Number of ticks per second */
+#define RTC_PPB_MULT 1000000000LL /* Multiplier for ppb conversions */
+
+/* RTC_HW_CAL_CFG */
+#define RTC_HW_CAL_REF_SEL_SHIFT 0
+#define RTC_HW_CAL_FRQ_SEL_SHIFT 1
+
+/* IRQ_EN/IRQ_EVEVT/IRQ_STATUS */
+#define RTC_IRQ_CAL_START BIT(0)
+#define RTC_IRQ_CAL_FINISH BIT(1)
+#define RTC_IRQ_CMP BIT(2)
+#define RTC_IRQ_1SEC BIT(3)
+#define RTC_IRQ_ALAEM BIT(4)
+#define RTC_IRQ_EVT_UPDATE_PSE BIT(31) /* WO: Enable of update time&&date, IRQ_EVEVT only */
+#define RTC_IRQ_ALL (RTC_IRQ_CAL_START \
+ | RTC_IRQ_CAL_FINISH \
+ | RTC_IRQ_CMP \
+ | RTC_IRQ_1SEC \
+ | RTC_IRQ_ALAEM)
+
+/* CAL_VALUE */
+#define RTC_CAL_VALUE_MASK GENMASK(15, 0)
+
+/* CFG_TIME/ACT_TIME/RTC_TIME */
+#define TIME_SEC_MASK GENMASK(6, 0)
+#define TIME_MIN_MASK GENMASK(13, 7)
+#define TIME_HOUR_MASK GENMASK(20, 14)
+
+/* CFG_DATE/ACT_DATE/RTC_DATE */
+#define DATE_DAY_MASK GENMASK(5, 0)
+#define DATE_MON_MASK GENMASK(10, 6)
+#define DATE_YEAR_MASK GENMASK(18, 11)
+
+#define INT_TIMEOUT_US 180
+
+enum RTC_HOUR_MODE {
+ RTC_HOUR_MODE_12H = 0,
+ RTC_HOUR_MODE_24H = 1
+};
+
+enum RTC_CAL_MODE {
+ RTC_CAL_MODE_SW = 0,
+ RTC_CAL_MODE_HW = 1
+};
+
+enum RTC_HW_CAL_REF_MODE {
+ RTC_CAL_CLK_REF = 0,
+ RTC_CAL_CLK_MARK = 1
+};
+
+static const unsigned long refclk_list[] = {
+ 1000000,
+ 2000000,
+ 4000000,
+ 5927000,
+ 6000000,
+ 7200000,
+ 8000000,
+ 10250000,
+ 11059200,
+ 12000000,
+ 12288000,
+ 13560000,
+ 16000000,
+ 19200000,
+ 20000000,
+ 22118000,
+ 24000000,
+ 24567000,
+ 25000000,
+ 26000000,
+ 27000000,
+ 30000000,
+ 32000000,
+ 33868800,
+ 36000000,
+ 36860000,
+ 40000000,
+ 44000000,
+ 50000000,
+ 54000000,
+ 28224000,
+ 28000000,
+};
+
+struct sft_rtc {
+ struct rtc_device *rtc_dev;
+ struct completion cal_done;
+ struct completion onesec_done;
+ struct clk *pclk;
+ struct clk *cal_clk;
+ struct reset_control *rst_array;
+ int hw_cal_map;
+ void __iomem *regs;
+ int rtc_irq;
+ int ms_pulse_irq;
+ int one_sec_pulse_irq;
+};
+
+static inline void sft_rtc_set_enabled(struct sft_rtc *srtc, bool enabled)
+{
+ u32 val;
+
+ if (enabled) {
+ val = readl(srtc->regs + SFT_RTC_CFG);
+ val |= BIT(RTC_CFG_ENABLE_SHIFT);
+ writel(val, srtc->regs + SFT_RTC_CFG);
+ } else {
+ val = readl(srtc->regs + SFT_RTC_CFG);
+ val &= ~BIT(RTC_CFG_ENABLE_SHIFT);
+ writel(val, srtc->regs + SFT_RTC_CFG);
+ }
+}
+
+static inline bool sft_rtc_get_enabled(struct sft_rtc *srtc)
+{
+ return !!(readl(srtc->regs + SFT_RTC_CFG) & BIT(RTC_CFG_ENABLE_SHIFT));
+}
+
+static inline void sft_rtc_set_mode(struct sft_rtc *srtc, enum RTC_HOUR_MODE mode)
+{
+ u32 val;
+
+ val = readl(srtc->regs + SFT_RTC_CFG);
+ val |= mode << RTC_CFG_HOUR_MODE_SHIFT;
+ writel(val, srtc->regs + SFT_RTC_CFG);
+}
+
+static inline int sft_rtc_irq_enable(struct sft_rtc *srtc, u32 irq, bool enable)
+{
+ u32 val;
+
+ if (!(irq & RTC_IRQ_ALL))
+ return -EINVAL;
+
+ if (enable) {
+ val = readl(srtc->regs + SFT_RTC_IRQ_EN);
+ val |= irq;
+ writel(val, srtc->regs + SFT_RTC_IRQ_EN);
+ } else {
+ val = readl(srtc->regs + SFT_RTC_IRQ_EN);
+ val &= ~irq;
+ writel(val, srtc->regs + SFT_RTC_IRQ_EN);
+ }
+ return 0;
+}
+
+static inline void
+sft_rtc_set_cal_hw_enable(struct sft_rtc *srtc, bool enable)
+{
+ u32 val;
+
+ if (enable) {
+ val = readl(srtc->regs + SFT_RTC_CFG);
+ val |= BIT(RTC_CFG_CAL_EN_HW_SHIFT);
+ writel(val, srtc->regs + SFT_RTC_CFG);
+ } else {
+ val = readl(srtc->regs + SFT_RTC_CFG);
+ val &= ~BIT(RTC_CFG_CAL_EN_HW_SHIFT);
+ writel(val, srtc->regs + SFT_RTC_CFG);
+ }
+}
+
+static inline void
+sft_rtc_set_cal_mode(struct sft_rtc *srtc, enum RTC_CAL_MODE mode)
+{
+ u32 val;
+
+ val = readl(srtc->regs + SFT_RTC_CFG);
+ val |= mode << RTC_CFG_CAL_SEL_SHIFT;
+ writel(val, srtc->regs + SFT_RTC_CFG);
+}
+
+static int sft_rtc_get_hw_calclk(struct device *dev, unsigned long freq)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(refclk_list); i++)
+ if (refclk_list[i] == freq)
+ return i;
+
+ dev_err(dev, "refclk: %ldHz do not support.\n", freq);
+ return -EINVAL;
+}
+
+static inline void sft_rtc_reg2time(struct rtc_time *tm, u32 reg)
+{
+ tm->tm_hour = bcd2bin(FIELD_GET(TIME_HOUR_MASK, reg));
+ tm->tm_min = bcd2bin(FIELD_GET(TIME_MIN_MASK, reg));
+ tm->tm_sec = bcd2bin(FIELD_GET(TIME_SEC_MASK, reg));
+}
+
+static inline void sft_rtc_reg2date(struct rtc_time *tm, u32 reg)
+{
+ tm->tm_year = bcd2bin(FIELD_GET(DATE_YEAR_MASK, reg)) + 100;
+ tm->tm_mon = bcd2bin(FIELD_GET(DATE_MON_MASK, reg)) - 1;
+ tm->tm_mday = bcd2bin(FIELD_GET(DATE_DAY_MASK, reg));
+}
+
+static inline u32 sft_rtc_time2reg(struct rtc_time *tm)
+{
+ return FIELD_PREP(TIME_HOUR_MASK, bin2bcd(tm->tm_hour)) |
+ FIELD_PREP(TIME_MIN_MASK, bin2bcd(tm->tm_min)) |
+ FIELD_PREP(TIME_SEC_MASK, bin2bcd(tm->tm_sec));
+}
+
+static inline u32 sft_rtc_date2reg(struct rtc_time *tm)
+{
+ return FIELD_PREP(DATE_YEAR_MASK, bin2bcd(tm->tm_year - 100)) |
+ FIELD_PREP(DATE_MON_MASK, bin2bcd(tm->tm_mon + 1)) |
+ FIELD_PREP(DATE_DAY_MASK, bin2bcd(tm->tm_mday));
+}
+
+static inline void sft_rtc_update_pulse(struct sft_rtc *srtc)
+{
+ u32 val;
+
+ val = readl(srtc->regs + SFT_RTC_IRQ_EVEVT);
+ val |= RTC_IRQ_EVT_UPDATE_PSE;
+ writel(val, srtc->regs + SFT_RTC_IRQ_EVEVT);
+}
+
+static irqreturn_t sft_rtc_irq_handler(int irq, void *data)
+{
+ struct sft_rtc *srtc = data;
+ struct timerqueue_node *next;
+ u32 irq_flags = 0;
+ u32 irq_mask = 0;
+ u32 val;
+ int ret = 0;
+
+ val = readl(srtc->regs + SFT_RTC_IRQ_EVEVT);
+ if (val & RTC_IRQ_CAL_START)
+ irq_mask |= RTC_IRQ_CAL_START;
+
+ if (val & RTC_IRQ_CAL_FINISH) {
+ irq_mask |= RTC_IRQ_CAL_FINISH;
+ complete(&srtc->cal_done);
+ }
+
+ if (val & RTC_IRQ_CMP)
+ irq_mask |= RTC_IRQ_CMP;
+
+ if (val & RTC_IRQ_1SEC) {
+ irq_flags |= RTC_PF;
+ irq_mask |= RTC_IRQ_1SEC;
+ complete(&srtc->onesec_done);
+ }
+
+ if (val & RTC_IRQ_ALAEM) {
+ irq_flags |= RTC_AF;
+ irq_mask |= RTC_IRQ_ALAEM;
+
+ next = timerqueue_getnext(&srtc->rtc_dev->timerqueue);
+ if (next == &srtc->rtc_dev->aie_timer.node)
+ dev_info(&srtc->rtc_dev->dev, "alarm expires");
+ }
+
+ writel(irq_mask, srtc->regs + SFT_RTC_IRQ_EVEVT);
+
+ /* Wait interrupt flag clear */
+ ret = readl_poll_timeout_atomic(srtc->regs + SFT_RTC_IRQ_EVEVT, val,
+ (val & irq_mask) == 0, 0, INT_TIMEOUT_US);
+ if (ret)
+ dev_warn(&srtc->rtc_dev->dev, "fail to clear rtc interrupt flag\n");
+
+ if (irq_flags)
+ rtc_update_irq(srtc->rtc_dev, 1, irq_flags | RTC_IRQF);
+
+ return IRQ_HANDLED;
+}
+
+static int sft_rtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+ struct sft_rtc *srtc = dev_get_drvdata(dev);
+ u32 val;
+ int irq_1sec_state_start, irq_1sec_state_end;
+
+ /* If the RTC is disabled, assume the values are invalid */
+ if (!sft_rtc_get_enabled(srtc))
+ return -EINVAL;
+
+ irq_1sec_state_start =
+ (readl(srtc->regs + SFT_RTC_IRQ_STATUS) & RTC_IRQ_1SEC) == 0 ? 0 : 1;
+
+read_again:
+ val = readl(srtc->regs + SFT_RTC_TIME);
+ sft_rtc_reg2time(tm, val);
+
+ val = readl(srtc->regs + SFT_RTC_DATE);
+ sft_rtc_reg2date(tm, val);
+
+ if (irq_1sec_state_start == 0) {
+ irq_1sec_state_end =
+ (readl(srtc->regs + SFT_RTC_IRQ_STATUS) & RTC_IRQ_1SEC) == 0 ? 0 : 1;
+ if (irq_1sec_state_end == 1) {
+ irq_1sec_state_start = 1;
+ goto read_again;
+ }
+ }
+
+ return 0;
+}
+
+static int sft_rtc_set_time(struct device *dev, struct rtc_time *tm)
+{
+ struct sft_rtc *srtc = dev_get_drvdata(dev);
+ u32 val;
+ int ret;
+
+ val = sft_rtc_time2reg(tm);
+ writel(val, srtc->regs + SFT_RTC_CFG_TIME);
+
+ val = sft_rtc_date2reg(tm);
+ writel(val, srtc->regs + SFT_RTC_CFG_DATE);
+
+ /* Update pulse */
+ sft_rtc_update_pulse(srtc);
+
+ /* Ensure that data is fully written */
+ ret = wait_for_completion_interruptible_timeout(&srtc->onesec_done,
+ usecs_to_jiffies(120));
+ if (ret) {
+ dev_warn(dev,
+ "rtc wait for completion interruptible timeout.\n");
+ }
+ return 0;
+}
+
+static int sft_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
+{
+ struct sft_rtc *srtc = dev_get_drvdata(dev);
+
+ return sft_rtc_irq_enable(srtc, RTC_IRQ_ALAEM, enabled);
+}
+
+static int sft_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
+{
+ struct sft_rtc *srtc = dev_get_drvdata(dev);
+ u32 val;
+
+ val = readl(srtc->regs + SFT_RTC_ACT_TIME);
+ sft_rtc_reg2time(&alarm->time, val);
+
+ val = readl(srtc->regs + SFT_RTC_ACT_DATE);
+ sft_rtc_reg2date(&alarm->time, val);
+
+ return 0;
+}
+
+static int sft_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
+{
+ struct sft_rtc *srtc = dev_get_drvdata(dev);
+ u32 val;
+
+ sft_rtc_alarm_irq_enable(dev, 0);
+
+ val = sft_rtc_time2reg(&alarm->time);
+ writel(val, srtc->regs + SFT_RTC_ACT_TIME);
+
+ val = sft_rtc_date2reg(&alarm->time);
+ writel(val, srtc->regs + SFT_RTC_ACT_DATE);
+
+ sft_rtc_alarm_irq_enable(dev, alarm->enabled);
+
+ return 0;
+}
+
+static int sft_rtc_get_offset(struct device *dev, long *offset)
+{
+ struct sft_rtc *srtc = dev_get_drvdata(dev);
+ s64 tmp;
+ u32 val;
+
+ val = readl(srtc->regs + SFT_RTC_CAL_VALUE)
+ & RTC_SW_CAL_VALUE_MASK;
+ val += 1;
+ /*
+ * the adjust val range is [0x0000-0xffff],
+ * the default val is 0x7fff (32768-1),mapping offset=0 ;
+ */
+ tmp = (s64)val - RTC_TICKS_PER_SEC;
+ tmp *= RTC_PPB_MULT;
+ tmp = div_s64(tmp, RTC_TICKS_PER_SEC);
+
+ /* Offset value operates in negative way, so swap sign */
+ *offset = -tmp;
+
+ return 0;
+}
+
+static int sft_rtc_set_offset(struct device *dev, long offset)
+{
+ struct sft_rtc *srtc = dev_get_drvdata(dev);
+ s64 tmp;
+ u32 val;
+
+ tmp = offset * RTC_TICKS_PER_SEC;
+ tmp = div_s64(tmp, RTC_PPB_MULT);
+
+ tmp = RTC_TICKS_PER_SEC - tmp;
+ tmp -= 1;
+ if (tmp > RTC_SW_CAL_MAX || tmp < RTC_SW_CAL_MIN) {
+ dev_err(dev, "offset is out of range.\n");
+ return -EINVAL;
+ }
+
+ val = tmp & RTC_SW_CAL_VALUE_MASK;
+ /* set software calibration value */
+ writel(val, srtc->regs + SFT_RTC_SW_CAL_VALUE);
+
+ /* set CFG_RTC-cal_sel to select calibretion by software. */
+ sft_rtc_set_cal_mode(srtc, RTC_CAL_MODE_SW);
+
+ return 0;
+}
+
+static __maybe_unused int
+sft_rtc_hw_adjustment(struct device *dev, unsigned int enable)
+{
+ struct sft_rtc *srtc = dev_get_drvdata(dev);
+ u32 val;
+
+ if (srtc->hw_cal_map <= 0) {
+ dev_err(dev, "fail to get cal-clock-freq.\n");
+ return -EFAULT;
+ }
+
+ if (enable) {
+ sft_rtc_irq_enable(srtc, RTC_IRQ_CAL_FINISH, true);
+
+ /* Set reference clock frequency value */
+ val = readl(srtc->regs + SFT_RTC_HW_CAL_CFG);
+ val |= (srtc->hw_cal_map << RTC_HW_CAL_FRQ_SEL_SHIFT);
+ writel(val, srtc->regs + SFT_RTC_HW_CAL_CFG);
+
+ /* Set CFG_RTC-cal_sel to select calibretion by hardware. */
+ sft_rtc_set_cal_mode(srtc, RTC_CAL_MODE_HW);
+
+ /* Set CFG_RTC-cal_en_hw to launch hardware calibretion.*/
+ sft_rtc_set_cal_hw_enable(srtc, true);
+
+ wait_for_completion_interruptible_timeout(&srtc->cal_done,
+ usecs_to_jiffies(100));
+
+ sft_rtc_irq_enable(srtc, RTC_IRQ_CAL_FINISH, false);
+ } else {
+ sft_rtc_set_cal_mode(srtc, RTC_CAL_MODE_SW);
+ sft_rtc_set_cal_hw_enable(srtc, false);
+ }
+
+ return 0;
+}
+
+static int sft_rtc_get_cal_clk(struct device *dev, struct sft_rtc *srtc)
+{
+ struct device_node *np = dev->of_node;
+ unsigned long cal_clk_freq;
+ u32 freq;
+ int ret;
+
+ srtc->cal_clk = devm_clk_get(dev, "cal_clk");
+ if (IS_ERR(srtc->cal_clk))
+ return PTR_ERR(srtc->cal_clk);
+
+ clk_prepare_enable(srtc->cal_clk);
+
+ cal_clk_freq = clk_get_rate(srtc->cal_clk);
+ if (!cal_clk_freq) {
+ dev_warn(dev,
+ "get rate failed, next try to get from dts.\n");
+ ret = of_property_read_u32(np, "rtc,cal-clock-freq", &freq);
+ if (!ret) {
+ cal_clk_freq = (u64)freq;
+ } else {
+ dev_err(dev,
+ "Need rtc,cal-clock-freq define in dts.\n");
+ goto err_disable_cal_clk;
+ }
+ }
+
+ srtc->hw_cal_map = sft_rtc_get_hw_calclk(dev, cal_clk_freq);
+ if (srtc->hw_cal_map < 0) {
+ ret = srtc->hw_cal_map;
+ goto err_disable_cal_clk;
+ }
+
+ return 0;
+
+err_disable_cal_clk:
+ clk_disable_unprepare(srtc->cal_clk);
+
+ return ret;
+}
+
+static int sft_rtc_get_irq(struct platform_device *pdev, struct sft_rtc *srtc)
+{
+ int ret;
+
+ srtc->rtc_irq = platform_get_irq_byname(pdev, "rtc");
+ if (srtc->rtc_irq < 0)
+ return -EINVAL;
+
+ ret = devm_request_irq(&pdev->dev, srtc->rtc_irq,
+ sft_rtc_irq_handler, 0,
+ KBUILD_MODNAME, srtc);
+ if (ret)
+ dev_err(&pdev->dev, "Failed to request interrupt, %d\n", ret);
+
+ return ret;
+}
+
+static const struct rtc_class_ops starfive_rtc_ops = {
+ .read_time = sft_rtc_read_time,
+ .set_time = sft_rtc_set_time,
+ .read_alarm = sft_rtc_read_alarm,
+ .set_alarm = sft_rtc_set_alarm,
+ .alarm_irq_enable = sft_rtc_alarm_irq_enable,
+ .set_offset = sft_rtc_set_offset,
+ .read_offset = sft_rtc_get_offset,
+};
+
+static int sft_rtc_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct sft_rtc *srtc;
+ struct rtc_time tm;
+ struct irq_desc *desc;
+ int ret;
+
+ srtc = devm_kzalloc(dev, sizeof(*srtc), GFP_KERNEL);
+ if (!srtc)
+ return -ENOMEM;
+
+ srtc->regs = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(srtc->regs))
+ return PTR_ERR(srtc->regs);
+
+ srtc->pclk = devm_clk_get(dev, "pclk");
+ if (IS_ERR(srtc->pclk)) {
+ ret = PTR_ERR(srtc->pclk);
+ dev_err(dev,
+ "Failed to retrieve the peripheral clock, %d\n", ret);
+ return ret;
+ }
+
+ srtc->rst_array = devm_reset_control_array_get_exclusive(dev);
+ if (IS_ERR(srtc->rst_array)) {
+ ret = PTR_ERR(srtc->rst_array);
+ dev_err(dev,
+ "Failed to retrieve the rtc reset, %d\n", ret);
+ return ret;
+ }
+
+ init_completion(&srtc->cal_done);
+ init_completion(&srtc->onesec_done);
+
+ ret = clk_prepare_enable(srtc->pclk);
+ if (ret) {
+ dev_err(dev,
+ "Failed to enable the peripheral clock, %d\n", ret);
+ return ret;
+ }
+
+ ret = sft_rtc_get_cal_clk(dev, srtc);
+ if (ret)
+ goto err_disable_pclk;
+
+ ret = reset_control_deassert(srtc->rst_array);
+ if (ret) {
+ dev_err(dev,
+ "Failed to deassert rtc resets, %d\n", ret);
+ goto err_disable_cal_clk;
+ }
+
+ ret = sft_rtc_get_irq(pdev, srtc);
+ if (ret)
+ goto err_disable_cal_clk;
+
+ srtc->rtc_dev = devm_rtc_allocate_device(dev);
+ if (IS_ERR(srtc->rtc_dev))
+ return PTR_ERR(srtc->rtc_dev);
+
+ platform_set_drvdata(pdev, srtc);
+
+ /* The RTC supports 01.01.2001 - 31.12.2099 */
+ srtc->rtc_dev->range_min = mktime64(2001, 1, 1, 0, 0, 0);
+ srtc->rtc_dev->range_max = mktime64(2099, 12, 31, 23, 59, 59);
+
+ srtc->rtc_dev->ops = &starfive_rtc_ops;
+ device_init_wakeup(dev, true);
+
+ desc = irq_to_desc(srtc->rtc_irq);
+ irq_desc_get_chip(desc)->flags = IRQCHIP_SKIP_SET_WAKE;
+
+ /* Always use 24-hour mode and keep the RTC values */
+ sft_rtc_set_mode(srtc, RTC_HOUR_MODE_24H);
+
+ sft_rtc_set_enabled(srtc, true);
+
+ if (device_property_read_bool(dev, "rtc,hw-adjustment"))
+ sft_rtc_hw_adjustment(dev, true);
+
+ /*
+ * If rtc time is out of supported range, reset it to the minimum time.
+ * notice that, actual year = 1900 + tm.tm_year
+ * actual month = 1 + tm.tm_mon
+ */
+ sft_rtc_read_time(dev, &tm);
+ if (tm.tm_year < 101 || tm.tm_year > 199 || tm.tm_mon < 0 || tm.tm_mon > 11 ||
+ tm.tm_mday < 1 || tm.tm_mday > 31 || tm.tm_hour < 0 || tm.tm_hour > 23 ||
+ tm.tm_min < 0 || tm.tm_min > 59 || tm.tm_sec < 0 || tm.tm_sec > 59) {
+ rtc_time64_to_tm(srtc->rtc_dev->range_min, &tm);
+ sft_rtc_set_time(dev, &tm);
+ }
+
+ ret = devm_rtc_register_device(srtc->rtc_dev);
+ if (ret)
+ goto err_disable_wakeup;
+
+ return 0;
+
+err_disable_wakeup:
+ device_init_wakeup(dev, false);
+
+err_disable_cal_clk:
+ clk_disable_unprepare(srtc->cal_clk);
+
+err_disable_pclk:
+ clk_disable_unprepare(srtc->pclk);
+
+ return ret;
+}
+
+static void sft_rtc_remove(struct platform_device *pdev)
+{
+ struct sft_rtc *srtc = platform_get_drvdata(pdev);
+
+ sft_rtc_alarm_irq_enable(&pdev->dev, 0);
+ device_init_wakeup(&pdev->dev, 0);
+
+ clk_disable_unprepare(srtc->pclk);
+ clk_disable_unprepare(srtc->cal_clk);
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int sft_rtc_suspend(struct device *dev)
+{
+ struct sft_rtc *srtc = dev_get_drvdata(dev);
+
+ if (device_may_wakeup(dev))
+ enable_irq_wake(srtc->rtc_irq);
+
+ return 0;
+}
+
+static int sft_rtc_resume(struct device *dev)
+{
+ struct sft_rtc *srtc = dev_get_drvdata(dev);
+
+ if (device_may_wakeup(dev))
+ disable_irq_wake(srtc->rtc_irq);
+
+ return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(sft_rtc_pm_ops, sft_rtc_suspend, sft_rtc_resume);
+
+static const struct of_device_id sft_rtc_of_match[] = {
+ { .compatible = "starfive,jh7110-rtc" },
+ { },
+};
+MODULE_DEVICE_TABLE(of, sft_rtc_of_match);
+
+static struct platform_driver starfive_rtc_driver = {
+ .driver = {
+ .name = "starfive-rtc",
+ .of_match_table = sft_rtc_of_match,
+ .pm = &sft_rtc_pm_ops,
+ },
+ .probe = sft_rtc_probe,
+ .remove = sft_rtc_remove,
+};
+module_platform_driver(starfive_rtc_driver);
+
+MODULE_AUTHOR("Samin Guo <samin.guo@starfivetech.com>");
+MODULE_AUTHOR("Hal Feng <hal.feng@starfivetech.com>");
+MODULE_DESCRIPTION("StarFive RTC driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:starfive-rtc");

View File

@ -0,0 +1,98 @@
From 20c14bbdff9e3be2ddbeffa266f08bae04216e63 Mon Sep 17 00:00:00 2001
From: Minda Chen <minda.chen@starfivetech.com>
Date: Sun, 25 Jun 2023 09:40:29 +0800
Subject: [PATCH 09/55] uart: 8250: Add dw auto flow ctrl support
Add designeware 8250 auto flow ctrl support. Enable
it by add auto-flow-control in dts.
Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
---
drivers/tty/serial/8250/8250_core.c | 2 ++
drivers/tty/serial/8250/8250_dw.c | 3 +++
drivers/tty/serial/8250/8250_port.c | 14 +++++++++++++-
include/linux/serial_8250.h | 1 +
include/uapi/linux/serial_core.h | 2 ++
5 files changed, 21 insertions(+), 1 deletion(-)
--- a/drivers/tty/serial/8250/8250_core.c
+++ b/drivers/tty/serial/8250/8250_core.c
@@ -810,6 +810,8 @@ int serial8250_register_8250_port(const
uart->dl_read = up->dl_read;
if (up->dl_write)
uart->dl_write = up->dl_write;
+ if (up->probe)
+ uart->probe = up->probe;
if (uart->port.type != PORT_8250_CIR) {
if (uart_console_registered(&uart->port))
--- a/drivers/tty/serial/8250/8250_dw.c
+++ b/drivers/tty/serial/8250/8250_dw.c
@@ -594,6 +594,9 @@ static int dw8250_probe(struct platform_
data->msr_mask_off |= UART_MSR_TERI;
}
+ if (device_property_read_bool(dev, "auto-flow-control"))
+ up->probe |= UART_PROBE_AFE;
+
/* If there is separate baudclk, get the rate from it. */
data->clk = devm_clk_get_optional_enabled(dev, "baudclk");
if (data->clk == NULL)
--- a/drivers/tty/serial/8250/8250_port.c
+++ b/drivers/tty/serial/8250/8250_port.c
@@ -319,6 +319,14 @@ static const struct serial8250_config ua
.rxtrig_bytes = {1, 8, 16, 30},
.flags = UART_CAP_FIFO | UART_CAP_AFE,
},
+ [PORT_16550A_AFE] = {
+ .name = "16550A_AFE",
+ .fifo_size = 16,
+ .tx_loadsz = 16,
+ .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
+ .rxtrig_bytes = {1, 4, 8, 14},
+ .flags = UART_CAP_FIFO | UART_CAP_AFE,
+ },
};
/* Uart divisor latch read */
@@ -1124,6 +1132,11 @@ static void autoconfig_16550a(struct uar
up->port.type = PORT_U6_16550A;
up->capabilities |= UART_CAP_AFE;
}
+
+ if ((up->port.type == PORT_16550A) && (up->probe & UART_PROBE_AFE)) {
+ up->port.type = PORT_16550A_AFE;
+ up->capabilities |= UART_CAP_AFE;
+ }
}
/*
@@ -2774,7 +2787,6 @@ serial8250_do_set_termios(struct uart_po
if (termios->c_cflag & CRTSCTS)
up->mcr |= UART_MCR_AFE;
}
-
/*
* Update the per-port timeout.
*/
--- a/include/linux/serial_8250.h
+++ b/include/linux/serial_8250.h
@@ -141,6 +141,7 @@ struct uart_8250_port {
unsigned char probe;
struct mctrl_gpios *gpios;
#define UART_PROBE_RSA (1 << 0)
+#define UART_PROBE_AFE (1 << 1)
/*
* Some bits in registers are cleared on a read, so they must
--- a/include/uapi/linux/serial_core.h
+++ b/include/uapi/linux/serial_core.h
@@ -231,6 +231,8 @@
/* Sunplus UART */
#define PORT_SUNPLUS 123
+#define PORT_16550A_AFE 124
+
/* Generic type identifier for ports which type is not important to userspace. */
#define PORT_GENERIC (-1)

View File

@ -0,0 +1,32 @@
From ee5aab642d8a99a7a48d9b30f098ca2a97f463c4 Mon Sep 17 00:00:00 2001
From: William Qiu <william.qiu@starfivetech.com>
Date: Wed, 20 Sep 2023 17:19:59 +0800
Subject: [PATCH 10/55] uart: 8250: add reset operation in runtime PM
add reset operation in runtime PM
Signed-off-by: William Qiu <william.qiu@starfivetech.com>
---
drivers/tty/serial/8250/8250_dw.c | 4 ++++
1 file changed, 4 insertions(+)
--- a/drivers/tty/serial/8250/8250_dw.c
+++ b/drivers/tty/serial/8250/8250_dw.c
@@ -712,6 +712,8 @@ static int dw8250_runtime_suspend(struct
{
struct dw8250_data *data = dev_get_drvdata(dev);
+ reset_control_assert(data->rst);
+
clk_disable_unprepare(data->clk);
clk_disable_unprepare(data->pclk);
@@ -734,6 +736,8 @@ static int dw8250_runtime_resume(struct
return ret;
}
+ reset_control_deassert(data->rst);
+
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,196 @@
From 356774301b12dbdfe4682e12c57bddb8058014a2 Mon Sep 17 00:00:00 2001
From: William Qiu <william.qiu@starfivetech.com>
Date: Sat, 12 Oct 2024 17:56:00 +0800
Subject: [PATCH 12/55] ipms: CAN: Solve CAN packet leakage problem
Improve RX interrupt trigger mechanism, reduce buffer trigger condition,
and increase polling value to solve the problem of CAN packet leakage.
Signed-off-by: William Qiu <william.qiu@starfivetech.com>
---
drivers/net/can/ipms_canfd.c | 108 +++++++++++++++++++----------------
1 file changed, 59 insertions(+), 49 deletions(-)
--- a/drivers/net/can/ipms_canfd.c
+++ b/drivers/net/can/ipms_canfd.c
@@ -5,28 +5,30 @@
* Copyright (c) 2022 StarFive Technology Co., Ltd.
*/
+#include <linux/can/dev.h>
+#include <linux/can/error.h>
#include <linux/clk.h>
-#include <linux/reset.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/io.h>
+#include <linux/jiffies.h>
#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/of.h>
+#include <linux/of_device.h>
#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+#include <linux/reset.h>
#include <linux/skbuff.h>
#include <linux/string.h>
#include <linux/types.h>
-#include <linux/can/dev.h>
-#include <linux/can/error.h>
-#include <linux/pm_runtime.h>
-#include <linux/of_device.h>
-#include <linux/mfd/syscon.h>
-#include <linux/regmap.h>
#define DRIVER_NAME "ipms_canfd"
+#define MAX_IRQ 16
/* CAN registers set */
enum canfd_device_reg {
@@ -124,7 +126,7 @@ enum canfd_reg_bitchange {
CAN_FD_SET_BEIF_MASK = 0x01,
CAN_FD_OFF_EPIE_MASK = 0xdf,
CAN_FD_OFF_BEIE_MASK = 0xfd,
- CAN_FD_SET_AFWL_MASK = 0x40,
+ CAN_FD_SET_AFWL_MASK = 0x20,
CAN_FD_SET_EWL_MASK = 0x0b,
CAN_FD_SET_KOER_MASK = 0xe0,
CAN_FD_SET_BIT_ERROR_MASK = 0x20,
@@ -366,12 +368,8 @@ static int can_rx(struct net_device *nde
struct can_frame *cf;
struct sk_buff *skb;
u32 can_id;
- u8 dlc, control, rx_status;
-
- rx_status = can_ioread8(priv->reg_base + CANFD_RCTRL_OFFSET);
+ u8 dlc, control;
- if (!(rx_status & CAN_FD_RSTAT_NOT_EMPTY_MASK))
- return 0;
control = can_ioread8(priv->reg_base + CANFD_RBUF_CTL_OFFSET);
can_id = priv->read_reg(priv, CANFD_RUBF_ID_OFFSET);
dlc = can_ioread8(priv->reg_base + CANFD_RBUF_CTL_OFFSET) & CAN_FD_SET_DLC_MASK;
@@ -403,7 +401,7 @@ static int can_rx(struct net_device *nde
canfd_reigister_set_bit(priv, CANFD_RCTRL_OFFSET, CAN_FD_SET_RREL_MASK);
stats->rx_bytes += can_fd_dlc2len(cf->can_dlc);
stats->rx_packets++;
- netif_receive_skb(skb);
+ netif_rx(skb);
return 1;
}
@@ -419,9 +417,9 @@ static int canfd_rx(struct net_device *n
int i;
rx_status = can_ioread8(priv->reg_base + CANFD_RCTRL_OFFSET);
-
if (!(rx_status & CAN_FD_RSTAT_NOT_EMPTY_MASK))
return 0;
+
control = can_ioread8(priv->reg_base + CANFD_RBUF_CTL_OFFSET);
can_id = priv->read_reg(priv, CANFD_RUBF_ID_OFFSET);
dlc = can_ioread8(priv->reg_base + CANFD_RBUF_CTL_OFFSET) & CAN_FD_SET_DLC_MASK;
@@ -557,6 +555,8 @@ static netdev_tx_t canfd_driver_start_xm
if (can_dropped_invalid_skb(ndev, skb))
return NETDEV_TX_OK;
+ netif_stop_queue(ndev);
+
switch (priv->tx_mode) {
case XMIT_FULL:
return NETDEV_TX_BUSY;
@@ -837,46 +837,56 @@ static irqreturn_t canfd_interrupt(int i
{
struct net_device *ndev = (struct net_device *)dev_id;
struct ipms_canfd_priv *priv = netdev_priv(ndev);
- u8 isr, eir;
+ u8 isr, eir, rx_status;
u8 isr_handled = 0, eir_handled = 0;
+ int num = 0;
- /* read the value of interrupt status register */
- isr = can_ioread8(priv->reg_base + CANFD_RTIF_OFFSET);
-
- /* read the value of error interrupt register */
- eir = can_ioread8(priv->reg_base + CANFD_ERRINT_OFFSET);
+ while (((isr = can_ioread8(priv->reg_base + CANFD_RTIF_OFFSET)) ||
+ (eir = can_ioread8(priv->reg_base + CANFD_ERRINT_OFFSET))) &&
+ num < MAX_IRQ) {
+ num++;
+
+ /* Check for Tx interrupt and Processing it */
+ if (isr & (CAN_FD_SET_TPIF_MASK | CAN_FD_SET_TSIF_MASK)) {
+ canfd_tx_interrupt(ndev, isr);
+ isr_handled |= (CAN_FD_SET_TPIF_MASK | CAN_FD_SET_TSIF_MASK);
+ break;
+ }
- /* Check for Tx interrupt and Processing it */
- if (isr & (CAN_FD_SET_TPIF_MASK | CAN_FD_SET_TSIF_MASK)) {
- canfd_tx_interrupt(ndev, isr);
- isr_handled |= (CAN_FD_SET_TPIF_MASK | CAN_FD_SET_TSIF_MASK);
- }
- if (isr & (CAN_FD_SET_RAFIF_MASK | CAN_FD_SET_RFIF_MASK)) {
- canfd_rxfull_interrupt(ndev, isr);
- isr_handled |= (CAN_FD_SET_RAFIF_MASK | CAN_FD_SET_RFIF_MASK);
- }
- /* Check Rx interrupt and Processing the receive interrupt routine */
- if (isr & CAN_FD_SET_RIF_MASK) {
- canfd_reigister_off_bit(priv, CANFD_RTIE_OFFSET, CAN_FD_OFF_RIE_MASK);
- canfd_reigister_set_bit(priv, CANFD_RTIF_OFFSET, CAN_FD_SET_RIF_MASK);
-
- napi_schedule(&priv->napi);
- isr_handled |= CAN_FD_SET_RIF_MASK;
- }
- if ((isr & CAN_FD_SET_EIF_MASK) | (eir & (CAN_FD_SET_EPIF_MASK | CAN_FD_SET_BEIF_MASK))) {
- /* reset EPIF and BEIF. Reset EIF */
- canfd_reigister_set_bit(priv, CANFD_ERRINT_OFFSET,
- eir & (CAN_FD_SET_EPIF_MASK | CAN_FD_SET_BEIF_MASK));
- canfd_reigister_set_bit(priv, CANFD_RTIF_OFFSET,
- isr & CAN_FD_SET_EIF_MASK);
+ if (unlikely(isr & (CAN_FD_SET_RAFIF_MASK | CAN_FD_SET_RFIF_MASK))) {
+ canfd_rxfull_interrupt(ndev, isr);
+ isr_handled |= (CAN_FD_SET_RAFIF_MASK | CAN_FD_SET_RFIF_MASK);
+ }
- canfd_error_interrupt(ndev, isr, eir);
+ /* Check Rx interrupt and Processing the receive interrupt routine */
+ if (isr & CAN_FD_SET_RIF_MASK) {
+ rx_status = can_ioread8(priv->reg_base + CANFD_RCTRL_OFFSET);
+ while (rx_status & CAN_FD_RSTAT_NOT_EMPTY_MASK) {
+ can_rx(ndev);
+ rx_status = can_ioread8(priv->reg_base + CANFD_RCTRL_OFFSET);
+ }
+ isr_handled |= CAN_FD_SET_RIF_MASK;
+ }
- isr_handled |= CAN_FD_SET_EIF_MASK;
- eir_handled |= (CAN_FD_SET_EPIF_MASK | CAN_FD_SET_BEIF_MASK);
+ if (unlikely((isr & CAN_FD_SET_EIF_MASK) |
+ (eir & (CAN_FD_SET_EPIF_MASK | CAN_FD_SET_BEIF_MASK)))) {
+ /* reset EPIF and BEIF. Reset EIF */
+ canfd_reigister_set_bit(priv, CANFD_ERRINT_OFFSET,
+ eir & (CAN_FD_SET_EPIF_MASK |
+ CAN_FD_SET_BEIF_MASK));
+ canfd_reigister_set_bit(priv, CANFD_RTIF_OFFSET,
+ isr & CAN_FD_SET_EIF_MASK);
+ canfd_error_interrupt(ndev, isr, eir);
+ isr_handled |= CAN_FD_SET_EIF_MASK;
+ eir_handled |= (CAN_FD_SET_EPIF_MASK | CAN_FD_SET_BEIF_MASK);
+ }
+ canfd_reigister_set_bit(priv, CANFD_RTIF_OFFSET, isr);
}
- if ((isr_handled == 0) && (eir_handled == 0)) {
- netdev_err(ndev, "Unhandled interrupt!\n");
+
+ if (num == 0) {
+ isr = can_ioread8(priv->reg_base + CANFD_RTIF_OFFSET);
+ eir = can_ioread8(priv->reg_base + CANFD_ERRINT_OFFSET);
+ netdev_err(ndev, "Unhandled interrupt!isr:%x,eir:%x\n", isr, eir);
return IRQ_NONE;
}

View File

@ -0,0 +1,40 @@
From 63ebc39891f7b292197f653f8f3aa9dfe35135ee Mon Sep 17 00:00:00 2001
From: "Kevin.xie" <kevin.xie@starfivetech.com>
Date: Thu, 24 Nov 2022 16:59:12 +0800
Subject: [PATCH 13/55] drivers: nvme: Add precheck and delay for CQE pending
status.
To workaroud the NVMe I/O timeout problem in bootup S10udev case
which caused by the CQE update lantancy.
Signed-off-by: Kevin.xie <kevin.xie@starfivetech.com>
---
drivers/nvme/host/pci.c | 10 ++++++++++
1 file changed, 10 insertions(+)
--- a/drivers/nvme/host/pci.c
+++ b/drivers/nvme/host/pci.c
@@ -28,6 +28,7 @@
#include <linux/io-64-nonatomic-hi-lo.h>
#include <linux/sed-opal.h>
#include <linux/pci-p2pdma.h>
+#include <linux/delay.h>
#include "trace.h"
#include "nvme.h"
@@ -1156,6 +1157,15 @@ static inline int nvme_poll_cq(struct nv
{
int found = 0;
+ /*
+ * In some cases, such as udev trigger, cqe status may update
+ * a little bit later than MSI, which cause an irq handle missing.
+ * To workaound, here we will prefetch the status first, and wait
+ * 1us if we get nothing.
+ */
+ if (!nvme_cqe_pending(nvmeq))
+ udelay(1);
+
while (nvme_cqe_pending(nvmeq)) {
found++;
/*

View File

@ -0,0 +1,508 @@
From 16fef31de538ce55e286b630d0b33d872707420d Mon Sep 17 00:00:00 2001
From: Mason Huo <mason.huo@starfivetech.com>
Date: Tue, 20 Jun 2023 13:37:52 +0800
Subject: [PATCH 14/55] riscv: Optimize memcpy with aligned version
Optimizing the 128 byte align case, this will improve the
performance of large block memcpy.
Here we combine the memcpy of glibc and kernel.
Signed-off-by: Mason Huo <mason.huo@starfivetech.com>
Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
---
arch/riscv/lib/Makefile | 3 +-
arch/riscv/lib/{memcpy.S => memcpy_aligned.S} | 37 +--
arch/riscv/lib/string.c | 266 ++++++++++++++++++
3 files changed, 274 insertions(+), 32 deletions(-)
rename arch/riscv/lib/{memcpy.S => memcpy_aligned.S} (65%)
create mode 100644 arch/riscv/lib/string.c
--- a/arch/riscv/lib/Makefile
+++ b/arch/riscv/lib/Makefile
@@ -1,6 +1,5 @@
# SPDX-License-Identifier: GPL-2.0-only
lib-y += delay.o
-lib-y += memcpy.o
lib-y += memset.o
lib-y += memmove.o
ifeq ($(CONFIG_KASAN_GENERIC)$(CONFIG_KASAN_SW_TAGS),)
@@ -16,6 +15,8 @@ lib-$(CONFIG_MMU) += uaccess.o
lib-$(CONFIG_64BIT) += tishift.o
lib-$(CONFIG_RISCV_ISA_ZICBOZ) += clear_page.o
lib-$(CONFIG_RISCV_ISA_ZBC) += crc32.o
+lib-y += string.o
+lib-y += memcpy_aligned.o
obj-$(CONFIG_FUNCTION_ERROR_INJECTION) += error-inject.o
lib-$(CONFIG_RISCV_ISA_V) += xor.o
--- a/arch/riscv/lib/memcpy.S
+++ /dev/null
@@ -1,110 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Copyright (C) 2013 Regents of the University of California
- */
-
-#include <linux/linkage.h>
-#include <asm/asm.h>
-
-/* void *memcpy(void *, const void *, size_t) */
-SYM_FUNC_START(__memcpy)
- move t6, a0 /* Preserve return value */
-
- /* Defer to byte-oriented copy for small sizes */
- sltiu a3, a2, 128
- bnez a3, 4f
- /* Use word-oriented copy only if low-order bits match */
- andi a3, t6, SZREG-1
- andi a4, a1, SZREG-1
- bne a3, a4, 4f
-
- beqz a3, 2f /* Skip if already aligned */
- /*
- * Round to nearest double word-aligned address
- * greater than or equal to start address
- */
- andi a3, a1, ~(SZREG-1)
- addi a3, a3, SZREG
- /* Handle initial misalignment */
- sub a4, a3, a1
-1:
- lb a5, 0(a1)
- addi a1, a1, 1
- sb a5, 0(t6)
- addi t6, t6, 1
- bltu a1, a3, 1b
- sub a2, a2, a4 /* Update count */
-
-2:
- andi a4, a2, ~((16*SZREG)-1)
- beqz a4, 4f
- add a3, a1, a4
-3:
- REG_L a4, 0(a1)
- REG_L a5, SZREG(a1)
- REG_L a6, 2*SZREG(a1)
- REG_L a7, 3*SZREG(a1)
- REG_L t0, 4*SZREG(a1)
- REG_L t1, 5*SZREG(a1)
- REG_L t2, 6*SZREG(a1)
- REG_L t3, 7*SZREG(a1)
- REG_L t4, 8*SZREG(a1)
- REG_L t5, 9*SZREG(a1)
- REG_S a4, 0(t6)
- REG_S a5, SZREG(t6)
- REG_S a6, 2*SZREG(t6)
- REG_S a7, 3*SZREG(t6)
- REG_S t0, 4*SZREG(t6)
- REG_S t1, 5*SZREG(t6)
- REG_S t2, 6*SZREG(t6)
- REG_S t3, 7*SZREG(t6)
- REG_S t4, 8*SZREG(t6)
- REG_S t5, 9*SZREG(t6)
- REG_L a4, 10*SZREG(a1)
- REG_L a5, 11*SZREG(a1)
- REG_L a6, 12*SZREG(a1)
- REG_L a7, 13*SZREG(a1)
- REG_L t0, 14*SZREG(a1)
- REG_L t1, 15*SZREG(a1)
- addi a1, a1, 16*SZREG
- REG_S a4, 10*SZREG(t6)
- REG_S a5, 11*SZREG(t6)
- REG_S a6, 12*SZREG(t6)
- REG_S a7, 13*SZREG(t6)
- REG_S t0, 14*SZREG(t6)
- REG_S t1, 15*SZREG(t6)
- addi t6, t6, 16*SZREG
- bltu a1, a3, 3b
- andi a2, a2, (16*SZREG)-1 /* Update count */
-
-4:
- /* Handle trailing misalignment */
- beqz a2, 6f
- add a3, a1, a2
-
- /* Use word-oriented copy if co-aligned to word boundary */
- or a5, a1, t6
- or a5, a5, a3
- andi a5, a5, 3
- bnez a5, 5f
-7:
- lw a4, 0(a1)
- addi a1, a1, 4
- sw a4, 0(t6)
- addi t6, t6, 4
- bltu a1, a3, 7b
-
- ret
-
-5:
- lb a4, 0(a1)
- addi a1, a1, 1
- sb a4, 0(t6)
- addi t6, t6, 1
- bltu a1, a3, 5b
-6:
- ret
-SYM_FUNC_END(__memcpy)
-SYM_FUNC_ALIAS_WEAK(memcpy, __memcpy)
-SYM_FUNC_ALIAS(__pi_memcpy, __memcpy)
-SYM_FUNC_ALIAS(__pi___memcpy, __memcpy)
--- /dev/null
+++ b/arch/riscv/lib/memcpy_aligned.S
@@ -0,0 +1,85 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2013 Regents of the University of California
+ */
+
+#include <linux/linkage.h>
+#include <asm/asm.h>
+
+/* void *__memcpy_aligned(void *, const void *, size_t) */
+SYM_FUNC_START(__memcpy_aligned)
+ move t6, a0 /* Preserve return value */
+
+2:
+ andi a4, a2, ~((16*SZREG)-1)
+ beqz a4, 4f
+ add a3, a1, a4
+3:
+ REG_L a4, 0(a1)
+ REG_L a5, SZREG(a1)
+ REG_L a6, 2*SZREG(a1)
+ REG_L a7, 3*SZREG(a1)
+ REG_L t0, 4*SZREG(a1)
+ REG_L t1, 5*SZREG(a1)
+ REG_L t2, 6*SZREG(a1)
+ REG_L t3, 7*SZREG(a1)
+ REG_L t4, 8*SZREG(a1)
+ REG_L t5, 9*SZREG(a1)
+ REG_S a4, 0(t6)
+ REG_S a5, SZREG(t6)
+ REG_S a6, 2*SZREG(t6)
+ REG_S a7, 3*SZREG(t6)
+ REG_S t0, 4*SZREG(t6)
+ REG_S t1, 5*SZREG(t6)
+ REG_S t2, 6*SZREG(t6)
+ REG_S t3, 7*SZREG(t6)
+ REG_S t4, 8*SZREG(t6)
+ REG_S t5, 9*SZREG(t6)
+ REG_L a4, 10*SZREG(a1)
+ REG_L a5, 11*SZREG(a1)
+ REG_L a6, 12*SZREG(a1)
+ REG_L a7, 13*SZREG(a1)
+ REG_L t0, 14*SZREG(a1)
+ REG_L t1, 15*SZREG(a1)
+ addi a1, a1, 16*SZREG
+ REG_S a4, 10*SZREG(t6)
+ REG_S a5, 11*SZREG(t6)
+ REG_S a6, 12*SZREG(t6)
+ REG_S a7, 13*SZREG(t6)
+ REG_S t0, 14*SZREG(t6)
+ REG_S t1, 15*SZREG(t6)
+ addi t6, t6, 16*SZREG
+ bltu a1, a3, 3b
+ andi a2, a2, (16*SZREG)-1 /* Update count */
+
+4:
+ /* Handle trailing misalignment */
+ beqz a2, 6f
+ add a3, a1, a2
+
+ /* Use word-oriented copy if co-aligned to word boundary */
+ or a5, a1, t6
+ or a5, a5, a3
+ andi a5, a5, 3
+ bnez a5, 5f
+7:
+ lw a4, 0(a1)
+ addi a1, a1, 4
+ sw a4, 0(t6)
+ addi t6, t6, 4
+ bltu a1, a3, 7b
+
+ ret
+
+5:
+ lb a4, 0(a1)
+ addi a1, a1, 1
+ sb a4, 0(t6)
+ addi t6, t6, 1
+ bltu a1, a3, 5b
+6:
+ ret
+SYM_FUNC_END(__memcpy_aligned)
+SYM_FUNC_ALIAS_WEAK(memcpy, __memcpy_aligned)
+SYM_FUNC_ALIAS(__pi_memcpy, __memcpy_aligned)
+SYM_FUNC_ALIAS(__pi___memcpy, __memcpy_aligned)
--- /dev/null
+++ b/arch/riscv/lib/string.c
@@ -0,0 +1,266 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copy memory to memory until the specified number of bytes
+ * has been copied. Overlap is NOT handled correctly.
+ * Copyright (C) 1991-2020 Free Software Foundation, Inc.
+ * This file is part of the GNU C Library.
+ * Contributed by Torbjorn Granlund (tege@sics.se).
+ *
+ * The GNU C Library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * The GNU C Library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the GNU C Library; if not, see
+ * <https://www.gnu.org/licenses/>.
+ *
+ */
+
+#define __NO_FORTIFY
+#include <linux/types.h>
+#include <linux/module.h>
+
+#define MERGE(w0, sh_1, w1, sh_2) (((w0) >> (sh_1)) | ((w1) << (sh_2)))
+#define OP_T_THRES 16
+#define op_t unsigned long
+#define OPSIZ (sizeof(op_t))
+#define OPSIZ_MASK (sizeof(op_t) - 1)
+#define FAST_COPY_THRES (128)
+#define byte unsigned char
+
+static void _wordcopy_fwd_aligned(long dstp, long srcp, size_t len)
+{
+ op_t a0, a1;
+
+ switch (len % 8) {
+ case 2:
+ a0 = ((op_t *) srcp)[0];
+ srcp -= 6 * OPSIZ;
+ dstp -= 7 * OPSIZ;
+ len += 6;
+ goto do1;
+ case 3:
+ a1 = ((op_t *) srcp)[0];
+ srcp -= 5 * OPSIZ;
+ dstp -= 6 * OPSIZ;
+ len += 5;
+ goto do2;
+ case 4:
+ a0 = ((op_t *) srcp)[0];
+ srcp -= 4 * OPSIZ;
+ dstp -= 5 * OPSIZ;
+ len += 4;
+ goto do3;
+ case 5:
+ a1 = ((op_t *) srcp)[0];
+ srcp -= 3 * OPSIZ;
+ dstp -= 4 * OPSIZ;
+ len += 3;
+ goto do4;
+ case 6:
+ a0 = ((op_t *) srcp)[0];
+ srcp -= 2 * OPSIZ;
+ dstp -= 3 * OPSIZ;
+ len += 2;
+ goto do5;
+ case 7:
+ a1 = ((op_t *) srcp)[0];
+ srcp -= 1 * OPSIZ;
+ dstp -= 2 * OPSIZ;
+ len += 1;
+ goto do6;
+
+ case 0:
+ if (OP_T_THRES <= 3 * OPSIZ && len == 0)
+ return;
+ a0 = ((op_t *) srcp)[0];
+ srcp -= 0 * OPSIZ;
+ dstp -= 1 * OPSIZ;
+ goto do7;
+ case 1:
+ a1 = ((op_t *) srcp)[0];
+ srcp -= -1 * OPSIZ;
+ dstp -= 0 * OPSIZ;
+ len -= 1;
+ if (OP_T_THRES <= 3 * OPSIZ && len == 0)
+ goto do0;
+ goto do8; /* No-op. */
+ }
+
+ do {
+do8:
+ a0 = ((op_t *) srcp)[0];
+ ((op_t *) dstp)[0] = a1;
+do7:
+ a1 = ((op_t *) srcp)[1];
+ ((op_t *) dstp)[1] = a0;
+do6:
+ a0 = ((op_t *) srcp)[2];
+ ((op_t *) dstp)[2] = a1;
+do5:
+ a1 = ((op_t *) srcp)[3];
+ ((op_t *) dstp)[3] = a0;
+do4:
+ a0 = ((op_t *) srcp)[4];
+ ((op_t *) dstp)[4] = a1;
+do3:
+ a1 = ((op_t *) srcp)[5];
+ ((op_t *) dstp)[5] = a0;
+do2:
+ a0 = ((op_t *) srcp)[6];
+ ((op_t *) dstp)[6] = a1;
+do1:
+ a1 = ((op_t *) srcp)[7];
+ ((op_t *) dstp)[7] = a0;
+
+ srcp += 8 * OPSIZ;
+ dstp += 8 * OPSIZ;
+ len -= 8;
+ } while (len != 0);
+
+ /* This is the right position for do0. Please don't move
+ * it into the loop.
+ */
+do0:
+ ((op_t *) dstp)[0] = a1;
+}
+
+static void _wordcopy_fwd_dest_aligned(long dstp, long srcp, size_t len)
+{
+ op_t a0, a1, a2, a3;
+ int sh_1, sh_2;
+
+ /* Calculate how to shift a word read at the memory operation
+ * aligned srcp to make it aligned for copy.
+ */
+
+ sh_1 = 8 * (srcp % OPSIZ);
+ sh_2 = 8 * OPSIZ - sh_1;
+
+ /* Make SRCP aligned by rounding it down to the beginning of the `op_t'
+ * it points in the middle of.
+ */
+ srcp &= -OPSIZ;
+
+ switch (len % 4) {
+ case 2:
+ a1 = ((op_t *) srcp)[0];
+ a2 = ((op_t *) srcp)[1];
+ srcp -= 1 * OPSIZ;
+ dstp -= 3 * OPSIZ;
+ len += 2;
+ goto do1;
+ case 3:
+ a0 = ((op_t *) srcp)[0];
+ a1 = ((op_t *) srcp)[1];
+ srcp -= 0 * OPSIZ;
+ dstp -= 2 * OPSIZ;
+ len += 1;
+ goto do2;
+ case 0:
+ if (OP_T_THRES <= 3 * OPSIZ && len == 0)
+ return;
+ a3 = ((op_t *) srcp)[0];
+ a0 = ((op_t *) srcp)[1];
+ srcp -= -1 * OPSIZ;
+ dstp -= 1 * OPSIZ;
+ len += 0;
+ goto do3;
+ case 1:
+ a2 = ((op_t *) srcp)[0];
+ a3 = ((op_t *) srcp)[1];
+ srcp -= -2 * OPSIZ;
+ dstp -= 0 * OPSIZ;
+ len -= 1;
+ if (OP_T_THRES <= 3 * OPSIZ && len == 0)
+ goto do0;
+ goto do4; /* No-op. */
+ }
+
+ do {
+do4:
+ a0 = ((op_t *) srcp)[0];
+ ((op_t *) dstp)[0] = MERGE(a2, sh_1, a3, sh_2);
+do3:
+ a1 = ((op_t *) srcp)[1];
+ ((op_t *) dstp)[1] = MERGE(a3, sh_1, a0, sh_2);
+do2:
+ a2 = ((op_t *) srcp)[2];
+ ((op_t *) dstp)[2] = MERGE(a0, sh_1, a1, sh_2);
+do1:
+ a3 = ((op_t *) srcp)[3];
+ ((op_t *) dstp)[3] = MERGE(a1, sh_1, a2, sh_2);
+
+ srcp += 4 * OPSIZ;
+ dstp += 4 * OPSIZ;
+ len -= 4;
+ } while (len != 0);
+
+ /* This is the right position for do0. Please don't move
+ * it into the loop.
+ */
+do0:
+ ((op_t *) dstp)[0] = MERGE(a2, sh_1, a3, sh_2);
+}
+
+#define BYTE_COPY_FWD(dst_bp, src_bp, nbytes) \
+do { \
+ size_t __nbytes = (nbytes); \
+ while (__nbytes > 0) { \
+ byte __x = ((byte *) src_bp)[0]; \
+ src_bp += 1; \
+ __nbytes -= 1; \
+ ((byte *) dst_bp)[0] = __x; \
+ dst_bp += 1; \
+ } \
+} while (0)
+
+#define WORD_COPY_FWD(dst_bp, src_bp, nbytes_left, nbytes) \
+do { \
+ if (src_bp % OPSIZ == 0) \
+ _wordcopy_fwd_aligned(dst_bp, src_bp, (nbytes) / OPSIZ); \
+ else \
+ _wordcopy_fwd_dest_aligned(dst_bp, src_bp, (nbytes) / OPSIZ); \
+ src_bp += (nbytes) & -OPSIZ; \
+ dst_bp += (nbytes) & -OPSIZ; \
+ (nbytes_left) = (nbytes) % OPSIZ; \
+} while (0)
+
+extern void *__memcpy_aligned(void *dest, const void *src, size_t len);
+void *__memcpy(void *dest, const void *src, size_t len)
+{
+ unsigned long dstp = (long) dest;
+ unsigned long srcp = (long) src;
+
+ /* If there not too few bytes to copy, use word copy. */
+ if (len >= OP_T_THRES) {
+ if ((len >= FAST_COPY_THRES) && ((dstp & OPSIZ_MASK) == 0) &&
+ ((srcp & OPSIZ_MASK) == 0)) {
+ __memcpy_aligned(dest, src, len);
+ return dest;
+ }
+ /* Copy just a few bytes to make DSTP aligned. */
+ len -= (-dstp) % OPSIZ;
+ BYTE_COPY_FWD(dstp, srcp, (-dstp) % OPSIZ);
+
+ /* Copy from SRCP to DSTP taking advantage of the known alignment of
+ * DSTP. Number of bytes remaining is put in the third argument,
+ * i.e. in LEN. This number may vary from machine to machine.
+ */
+ WORD_COPY_FWD(dstp, srcp, len, len);
+ /* Fall out and copy the tail. */
+ }
+
+ /* There are just a few bytes to copy. Use byte memory operations. */
+ BYTE_COPY_FWD(dstp, srcp, len);
+
+ return dest;
+}
+
+void *memcpy(void *dest, const void *src, size_t len) __weak __alias(__memcpy);

View File

@ -0,0 +1,36 @@
From a0eaebc3b3ae079772c1022c47d704c887c375d0 Mon Sep 17 00:00:00 2001
From: Hal Feng <hal.feng@starfivetech.com>
Date: Sun, 4 Feb 2024 15:27:09 +0800
Subject: [PATCH 15/55] riscv/purgatory: Change memcpy to the aligned version
Change memcpy to the aligned version, for purgatory.
Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
---
arch/riscv/purgatory/Makefile | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
--- a/arch/riscv/purgatory/Makefile
+++ b/arch/riscv/purgatory/Makefile
@@ -1,6 +1,6 @@
# SPDX-License-Identifier: GPL-2.0
-purgatory-y := purgatory.o sha256.o entry.o string.o ctype.o memcpy.o memset.o
+purgatory-y := purgatory.o sha256.o entry.o string.o ctype.o memcpy_aligned.o memcpy.o memset.o
ifeq ($(CONFIG_KASAN_GENERIC)$(CONFIG_KASAN_SW_TAGS),)
purgatory-y += strcmp.o strlen.o strncmp.o
endif
@@ -14,9 +14,12 @@ $(obj)/string.o: $(srctree)/lib/string.c
$(obj)/ctype.o: $(srctree)/lib/ctype.c FORCE
$(call if_changed_rule,cc_o_c)
-$(obj)/memcpy.o: $(srctree)/arch/riscv/lib/memcpy.S FORCE
+$(obj)/memcpy_aligned.o: $(srctree)/arch/riscv/lib/memcpy_aligned.S FORCE
$(call if_changed_rule,as_o_S)
+$(obj)/memcpy.o: $(srctree)/arch/riscv/lib/string.c FORCE
+ $(call if_changed_rule,cc_o_c)
+
$(obj)/memset.o: $(srctree)/arch/riscv/lib/memset.S FORCE
$(call if_changed_rule,as_o_S)

View File

@ -0,0 +1,22 @@
From 9b8ac2217743a522f0c4f3e360f089b434fcd04b Mon Sep 17 00:00:00 2001
From: Hal Feng <hal.feng@starfivetech.com>
Date: Tue, 21 Jan 2025 11:42:35 +0800
Subject: [PATCH 16/55] riscv: Fix __memcpy_aligned alias
Don't set the weak global alias of memcpy_aligned to memcpy.
This affected iperf3 test.
Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
---
arch/riscv/lib/memcpy_aligned.S | 1 -
1 file changed, 1 deletion(-)
--- a/arch/riscv/lib/memcpy_aligned.S
+++ b/arch/riscv/lib/memcpy_aligned.S
@@ -80,6 +80,5 @@ SYM_FUNC_START(__memcpy_aligned)
6:
ret
SYM_FUNC_END(__memcpy_aligned)
-SYM_FUNC_ALIAS_WEAK(memcpy, __memcpy_aligned)
SYM_FUNC_ALIAS(__pi_memcpy, __memcpy_aligned)
SYM_FUNC_ALIAS(__pi___memcpy, __memcpy_aligned)

View File

@ -0,0 +1,39 @@
From 8ea9ae21bde99c2c1832f364f973895e108a4851 Mon Sep 17 00:00:00 2001
From: Minda Chen <minda.chen@starfivetech.com>
Date: Thu, 18 Jul 2024 17:22:53 +0800
Subject: [PATCH 17/55] plic: irq: Set IRQCHIP_EOI_THREADED in PREEMPT_RT case
In ipms can device or other device, interrupt is trigger by level.
in PREEMPT_RT case. irq handle is in thread, If not set
IRQCHIP_EOI_THREADED, device irq in PLIC is cleared first, but
device irq reg is not clear, So the interrupt will be triggered
again, IRQCHIP_EOI_THREADED will clear device PLIC IRQ status
after clear device irq reg.
Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
---
drivers/irqchip/irq-sifive-plic.c | 6 ++++++
1 file changed, 6 insertions(+)
--- a/drivers/irqchip/irq-sifive-plic.c
+++ b/drivers/irqchip/irq-sifive-plic.c
@@ -209,6 +209,9 @@ static struct irq_chip plic_edge_chip =
#endif
.irq_set_type = plic_irq_set_type,
.flags = IRQCHIP_SKIP_SET_WAKE |
+#ifdef CONFIG_PREEMPT_RT
+ IRQCHIP_EOI_THREADED |
+#endif
IRQCHIP_AFFINITY_PRE_STARTUP,
};
@@ -224,6 +227,9 @@ static struct irq_chip plic_chip = {
#endif
.irq_set_type = plic_irq_set_type,
.flags = IRQCHIP_SKIP_SET_WAKE |
+#ifdef CONFIG_PREEMPT_RT
+ IRQCHIP_EOI_THREADED |
+#endif
IRQCHIP_AFFINITY_PRE_STARTUP,
};

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,23 @@
From 0eaf04ef4963db173428da176f52320754b0574c Mon Sep 17 00:00:00 2001
From: Hal Feng <hal.feng@starfivetech.com>
Date: Thu, 10 Oct 2024 11:05:20 +0800
Subject: [PATCH 19/55] net: stmmac: Extend waiting time of dma reset
Fix dma reset failure happening when disabling network.
Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
---
drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c
@@ -23,7 +23,7 @@ int dwmac4_dma_reset(void __iomem *ioadd
return readl_poll_timeout(ioaddr + DMA_BUS_MODE, value,
!(value & DMA_BUS_MODE_SFT_RESET),
- 10000, 1000000);
+ 10000, 3000000);
}
void dwmac4_set_rx_tail_ptr(struct stmmac_priv *priv, void __iomem *ioaddr,

View File

@ -0,0 +1,235 @@
From 714c99f993097e5c16822e73ba0a7945b86a20ea Mon Sep 17 00:00:00 2001
From: "xingyu.wu" <xingyu.wu@starfivetech.com>
Date: Tue, 28 Jun 2022 22:48:15 +0800
Subject: [PATCH 20/55] spi-pl022:starfive:Add platform bus register to adapt
overlay
Add platform bus register to adapt dtbo overlay.
Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
---
drivers/spi/spi-pl022.c | 143 ++++++++++++++++++++++++++++++++++++++--
1 file changed, 137 insertions(+), 6 deletions(-)
--- a/drivers/spi/spi-pl022.c
+++ b/drivers/spi/spi-pl022.c
@@ -34,6 +34,7 @@
#include <linux/of.h>
#include <linux/pinctrl/consumer.h>
#include <linux/reset.h>
+#include <linux/platform_device.h>
/*
* This macro is used to define some register default values.
@@ -1841,7 +1842,10 @@ pl022_platform_data_dt_get(struct device
return NULL;
}
- pd = devm_kzalloc(dev, sizeof(struct pl022_ssp_controller), GFP_KERNEL);
+ if (strncmp(dev->bus->name, "platform", strlen("platform")))
+ pd = devm_kzalloc(dev, sizeof(struct pl022_ssp_controller), GFP_KERNEL);
+ else
+ pd = kzalloc(sizeof(struct pl022_ssp_controller), GFP_KERNEL);
if (!pd)
return NULL;
@@ -1861,6 +1865,14 @@ static int pl022_probe(struct amba_devic
struct spi_controller *host;
struct pl022 *pl022 = NULL; /*Data for this driver */
int status = 0;
+ int platform_flag = 0;
+
+ if (strncmp(dev->bus->name, "platform", strlen("platform")))
+ platform_flag = 0;
+ else
+ platform_flag = 1;
+ dev_dbg(&adev->dev, "bus name:%s platform flag:%d",
+ dev->bus->name, platform_flag);
dev_info(&adev->dev,
"ARM PL022 driver, device ID: 0x%08x\n", adev->periphid);
@@ -1916,7 +1928,11 @@ static int pl022_probe(struct amba_devic
goto err_no_ioregion;
pl022->phybase = adev->res.start;
- pl022->virtbase = devm_ioremap(dev, adev->res.start,
+ if (platform_flag)
+ pl022->virtbase = ioremap(adev->res.start,
+ resource_size(&adev->res));
+ else
+ pl022->virtbase = devm_ioremap(dev, adev->res.start,
resource_size(&adev->res));
if (pl022->virtbase == NULL) {
status = -ENOMEM;
@@ -1925,14 +1941,28 @@ static int pl022_probe(struct amba_devic
dev_info(&adev->dev, "mapped registers from %pa to %p\n",
&adev->res.start, pl022->virtbase);
- pl022->clk = devm_clk_get_enabled(&adev->dev, NULL);
+ if (platform_flag)
+ pl022->clk = clk_get(&adev->dev, NULL);
+ else
+ pl022->clk = devm_clk_get_enabled(&adev->dev, NULL);
if (IS_ERR(pl022->clk)) {
status = PTR_ERR(pl022->clk);
dev_err(&adev->dev, "could not retrieve SSP/SPI bus clock\n");
goto err_no_clk;
}
- pl022->rst = devm_reset_control_get(&adev->dev, NULL);
+ if (platform_flag) {
+ status = clk_prepare_enable(pl022->clk);
+ if (status) {
+ dev_err(&adev->dev, "could not enable SSP/SPI bus clock\n");
+ goto err_no_clk_en;
+ }
+ }
+
+ if (platform_flag)
+ pl022->rst = reset_control_get_exclusive(&adev->dev, NULL);
+ else
+ pl022->rst = devm_reset_control_get(&adev->dev, NULL);
if (IS_ERR(pl022->rst)) {
status = PTR_ERR(pl022->rst);
dev_err(&adev->dev, "could not retrieve SSP/SPI bus reset\n");
@@ -1950,7 +1980,11 @@ static int pl022_probe(struct amba_devic
SSP_CR1(pl022->virtbase));
load_ssp_default_config(pl022);
- status = devm_request_irq(dev, adev->irq[0], pl022_interrupt_handler,
+ if (platform_flag)
+ status = request_irq(adev->irq[0], pl022_interrupt_handler,
+ 0, "pl022", pl022);
+ else
+ status = devm_request_irq(dev, adev->irq[0], pl022_interrupt_handler,
0, "pl022", pl022);
if (status < 0) {
dev_err(&adev->dev, "probe - cannot get IRQ (%d)\n", status);
@@ -1975,7 +2009,10 @@ static int pl022_probe(struct amba_devic
/* Register with the SPI framework */
amba_set_drvdata(adev, pl022);
- status = devm_spi_register_controller(&adev->dev, host);
+ if (platform_flag)
+ status = spi_register_controller(host);
+ else
+ status = devm_spi_register_controller(&adev->dev, host);
if (status != 0) {
dev_err_probe(&adev->dev, status,
"problem registering spi host\n");
@@ -2000,13 +2037,24 @@ static int pl022_probe(struct amba_devic
if (platform_info->enable_dma)
pl022_dma_remove(pl022);
err_no_irq:
+ if (platform_flag)
+ free_irq(adev->irq[0], pl022);
+ reset_control_assert(pl022->rst);
err_no_rst_de:
+ if (platform_flag)
+ reset_control_put(pl022->rst);
err_no_rst:
+ if (platform_flag)
+ clk_put(pl022->clk);
err_no_clk:
+ if (platform_flag)
+ iounmap(pl022->virtbase);
err_no_ioremap:
amba_release_regions(adev);
err_no_ioregion:
spi_controller_put(host);
+ if (platform_flag)
+ kfree(platform_info);
return status;
}
@@ -2205,6 +2253,89 @@ static void __exit pl022_exit(void)
}
module_exit(pl022_exit);
+/*
+ * Register PL022 in platform bus to accommodate overlay use.
+ * Because overlay only trigger response from the platform bus
+ * not amba bus.
+ */
+static int starfive_of_pl022_probe(struct platform_device *pdev)
+{
+ int ret;
+ const struct amba_id id = {
+ .id = 0x00041022,
+ .mask = 0x000fffff,
+ .data = &vendor_arm
+ };
+ struct amba_device *pcdev;
+ struct device *dev = &pdev->dev;
+
+ pcdev = devm_kzalloc(&pdev->dev, sizeof(*pcdev), GFP_KERNEL);
+ if (!pcdev)
+ return -ENOMEM;
+
+ pcdev->dev = pdev->dev;
+ pcdev->periphid = id.id;
+ pcdev->res = *(pdev->resource);
+
+ pcdev->irq[0] = platform_get_irq(pdev, 0);
+ if (pcdev->irq[0] < 0) {
+ dev_err(dev, "failed to get irq\n");
+ ret = -EINVAL;
+ }
+
+ ret = pl022_probe(pcdev, &id);
+
+ return ret;
+}
+
+static void starfive_of_pl022_remove(struct platform_device *pdev)
+{
+ u32 size;
+ int irq;
+ struct pl022 *pl022 = dev_get_drvdata(&pdev->dev);
+
+ if (!pl022)
+ return;
+
+ pm_runtime_get_noresume(&pdev->dev);
+
+ load_ssp_default_config(pl022);
+ if (pl022->host_info->enable_dma)
+ pl022_dma_remove(pl022);
+
+ irq = platform_get_irq(pdev, 0);
+ free_irq(irq, pl022);
+ reset_control_assert(pl022->rst);
+ reset_control_put(pl022->rst);
+ clk_disable_unprepare(pl022->clk);
+ clk_put(pl022->clk);
+ iounmap(pl022->virtbase);
+ kfree(pl022->host_info);
+
+ size = resource_size(pdev->resource);
+ release_mem_region(pdev->resource->start, size);
+}
+
+static const struct of_device_id starfive_of_pl022_match[] = {
+ { .compatible = "starfive,jh7110-spi-pl022" },
+ { },
+};
+MODULE_DEVICE_TABLE(of, starfive_of_pl022_match);
+
+static struct platform_driver starfive_of_pl022_driver = {
+ .driver = {
+ .name = "starfive-spi-pl022",
+ .of_match_table = starfive_of_pl022_match,
+ .pm = &pl022_dev_pm_ops,
+ },
+ .probe = starfive_of_pl022_probe,
+ .remove = starfive_of_pl022_remove,
+};
+
+module_platform_driver(starfive_of_pl022_driver);
+/* platform register end */
+
+MODULE_AUTHOR("xingyu.wu <xingyu.wu@starfivetech.com>");
MODULE_AUTHOR("Linus Walleij <linus.walleij@stericsson.com>");
MODULE_DESCRIPTION("PL022 SSP Controller Driver");
MODULE_LICENSE("GPL");

View File

@ -0,0 +1,92 @@
From 8063cc5e813c3a5f86a4f17e3681cda3dbebcb1a Mon Sep 17 00:00:00 2001
From: "xingyu.wu" <xingyu.wu@starfivetech.com>
Date: Tue, 19 Jul 2022 14:49:20 +0800
Subject: [PATCH 21/55] spi:pl022-starfive:Avoid power device error when
CONFIG_PM enable
It would be error when CONFIG_PM enable and use overlay by of-platform to register.
Add some power manager operation in platform probe function.
Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
Signed-off-by: Ziv Xu <ziv.xu@starfivetech.com>
Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
---
drivers/spi/spi-pl022.c | 36 ++++++++++++++++++++++++++++++++++--
1 file changed, 34 insertions(+), 2 deletions(-)
--- a/drivers/spi/spi-pl022.c
+++ b/drivers/spi/spi-pl022.c
@@ -35,6 +35,8 @@
#include <linux/pinctrl/consumer.h>
#include <linux/reset.h>
#include <linux/platform_device.h>
+#include <linux/clk/clk-conf.h>
+#include <linux/pm_domain.h>
/*
* This macro is used to define some register default values.
@@ -2019,7 +2021,8 @@ static int pl022_probe(struct amba_devic
goto err_spi_register;
}
dev_dbg(dev, "probe succeeded\n");
-
+ if (!platform_flag)
+ platform_info->autosuspend_delay = 100;
/* let runtime pm put suspend */
if (platform_info->autosuspend_delay > 0) {
dev_info(&adev->dev,
@@ -2029,7 +2032,10 @@ static int pl022_probe(struct amba_devic
platform_info->autosuspend_delay);
pm_runtime_use_autosuspend(dev);
}
- pm_runtime_put(dev);
+ if (platform_flag)
+ clk_disable_unprepare(pl022->clk);
+ else
+ pm_runtime_put(dev);
return 0;
@@ -2283,8 +2289,33 @@ static int starfive_of_pl022_probe(struc
ret = -EINVAL;
}
+ ret = of_clk_set_defaults(dev->of_node, false);
+ if (ret < 0)
+ goto err_probe;
+
+ ret = dev_pm_domain_attach(dev, true);
+ if (ret)
+ goto err_probe;
+
ret = pl022_probe(pcdev, &id);
+ struct pl022 *pl022 = amba_get_drvdata(pcdev);
+
+ pl022->host->dev.parent = &pdev->dev;
+ platform_set_drvdata(pdev, pl022);
+
+ pm_runtime_enable(&pdev->dev);
+ pm_runtime_set_autosuspend_delay(&pdev->dev, 100);
+ pm_runtime_use_autosuspend(&pdev->dev);
+
+ if (ret) {
+ pm_runtime_disable(dev);
+ pm_runtime_set_suspended(dev);
+ pm_runtime_put_noidle(dev);
+ dev_pm_domain_detach(dev, true);
+ }
+
+err_probe:
return ret;
}
@@ -2314,6 +2345,7 @@ static void starfive_of_pl022_remove(str
size = resource_size(pdev->resource);
release_mem_region(pdev->resource->start, size);
+ pm_runtime_disable(&pdev->dev);
}
static const struct of_device_id starfive_of_pl022_match[] = {

View File

@ -0,0 +1,396 @@
From 7a98fafdc544b85694db5d99cdf933a4640058f9 Mon Sep 17 00:00:00 2001
From: "ziv.xu" <ziv.xu@starfive.com>
Date: Wed, 23 Nov 2022 14:53:58 +0800
Subject: [PATCH 22/55] spi-pl022-starfive:fix the problem of spi overlay
reload
fix the problem of spi overlay reload
Signed-off-by: ziv.xu <ziv.xu@starfive.com>
Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
---
drivers/spi/spi-pl022.c | 266 ++++++++++++++++++++++++++--------------
1 file changed, 177 insertions(+), 89 deletions(-)
--- a/drivers/spi/spi-pl022.c
+++ b/drivers/spi/spi-pl022.c
@@ -1859,6 +1859,163 @@ pl022_platform_data_dt_get(struct device
return pd;
}
+static int pl022_platform_probe(struct platform_device *pdev, const struct amba_id *id)
+{
+ struct device *dev = &pdev->dev;
+ struct spi_controller *host;
+ struct pl022_ssp_controller *platform_info;
+ struct amba_device *adev;
+ struct pl022 *pl022 = NULL;
+ struct resource *res;
+ int status = 0;
+ int irq;
+
+ dev_info(dev,
+ "ARM PL022 driver for StarFive SoC platform, device ID: 0x%08x\n",
+ id->id);
+
+ adev = devm_kzalloc(dev, sizeof(*adev), GFP_KERNEL);
+ adev->dev = pdev->dev;
+ platform_info = pl022_platform_data_dt_get(dev);
+ if (!platform_info) {
+ dev_err(dev, "probe: no platform data defined\n");
+ return -ENODEV;
+ }
+ /* Allocate host with space for data */
+ host = spi_alloc_host(dev, sizeof(struct pl022));
+ if (host == NULL) {
+ dev_err(dev, "probe - cannot alloc SPI host\n");
+ return -ENOMEM;
+ }
+
+ pl022 = spi_controller_get_devdata(host);
+ pl022->host = host;
+ pl022->host_info = platform_info;
+ pl022->adev = adev;
+ pl022->vendor = id->data;
+ pl022->host->dev.parent = &pdev->dev;
+ /*
+ * Bus Number Which has been Assigned to this SSP controller
+ * on this board
+ */
+ host->bus_num = platform_info->bus_id;
+ host->cleanup = pl022_cleanup;
+ host->setup = pl022_setup;
+ /* If open CONFIG_PM, auto_runtime_pm should be false when of-platform.*/
+ host->auto_runtime_pm = true;
+ host->transfer_one = pl022_transfer_one;
+ host->set_cs = pl022_cs_control;
+ host->handle_err = pl022_handle_err;
+ host->unprepare_transfer_hardware = pl022_unprepare_transfer_hardware;
+ host->rt = platform_info->rt;
+ host->dev.of_node = dev->of_node;
+ host->use_gpio_descriptors = true;
+
+ /*
+ * Supports mode 0-3, loopback, and active low CS. Transfers are
+ * always MS bit first on the original pl022.
+ */
+ host->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LOOP;
+ if (pl022->vendor->extended_cr)
+ host->mode_bits |= SPI_LSB_FIRST;
+
+ dev_dbg(dev, "BUSNO: %d\n", host->bus_num);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ pl022->phybase = res->start;
+ pl022->virtbase = devm_ioremap_resource(dev, res);
+ if (pl022->virtbase == NULL) {
+ status = -ENOMEM;
+ goto err_no_ioremap;
+ }
+ dev_info(dev, "mapped registers from %llx to %llx\n",
+ pdev->resource->start, pdev->resource->end);
+
+ pl022->clk = devm_clk_get_enabled(dev, NULL);
+ if (IS_ERR(pl022->clk)) {
+ status = PTR_ERR(pl022->clk);
+ dev_err(dev, "could not retrieve SSP/SPI bus clock\n");
+ goto err_no_clk;
+ }
+
+ pl022->rst = devm_reset_control_get_exclusive(dev, NULL);
+ if (IS_ERR(pl022->rst)) {
+ status = PTR_ERR(pl022->rst);
+ dev_err(dev, "could not retrieve SSP/SPI bus reset\n");
+ goto err_no_rst;
+ }
+
+ status = reset_control_deassert(pl022->rst);
+ if (status) {
+ dev_err(dev, "could not deassert SSP/SPI bus reset\n");
+ goto err_no_rst_de;
+ }
+
+ /* Disable SSP */
+ writew((readw(SSP_CR1(pl022->virtbase)) & (~SSP_CR1_MASK_SSE)),
+ SSP_CR1(pl022->virtbase));
+ load_ssp_default_config(pl022);
+
+ /* Obtain IRQ line. */
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0) {
+ status = -ENXIO;
+ goto err_no_irq;
+ }
+ status = devm_request_irq(dev, irq, pl022_interrupt_handler,
+ 0, "pl022", pl022);
+ if (status < 0) {
+ dev_err(dev, "probe - cannot get IRQ (%d)\n", status);
+ goto err_no_irq;
+ }
+
+ /* Get DMA channels, try autoconfiguration first */
+ status = pl022_dma_autoprobe(pl022);
+ if (status == -EPROBE_DEFER) {
+ dev_dbg(dev, "deferring probe to get DMA channel\n");
+ goto err_no_irq;
+ }
+
+ /* dma is not used unless configured in the device tree */
+ platform_info->enable_dma = 0;
+
+ /* If that failed, use channels from platform_info */
+ if (status == 0)
+ platform_info->enable_dma = 1;
+ else if (platform_info->enable_dma) {
+ status = pl022_dma_probe(pl022);
+ if (status != 0)
+ platform_info->enable_dma = 0;
+ }
+
+ /* Register with the SPI framework */
+ dev_set_drvdata(dev, pl022);
+
+ status = devm_spi_register_controller(dev, host);
+ if (status != 0) {
+ dev_err(dev,
+ "probe - problem registering spi host\n");
+ goto err_spi_register;
+ }
+ dev_dbg(dev, "probe succeeded\n");
+
+ clk_disable_unprepare(pl022->clk);
+
+ return 0;
+ err_spi_register:
+ if (platform_info->enable_dma)
+ pl022_dma_remove(pl022);
+ err_no_irq:
+ reset_control_assert(pl022->rst);
+ err_no_rst_de:
+ err_no_rst:
+ err_no_clk:
+ err_no_ioremap:
+ release_mem_region(pdev->resource->start, resource_size(pdev->resource));
+ spi_controller_put(host);
+ return status;
+}
+
static int pl022_probe(struct amba_device *adev, const struct amba_id *id)
{
struct device *dev = &adev->dev;
@@ -1867,14 +2024,6 @@ static int pl022_probe(struct amba_devic
struct spi_controller *host;
struct pl022 *pl022 = NULL; /*Data for this driver */
int status = 0;
- int platform_flag = 0;
-
- if (strncmp(dev->bus->name, "platform", strlen("platform")))
- platform_flag = 0;
- else
- platform_flag = 1;
- dev_dbg(&adev->dev, "bus name:%s platform flag:%d",
- dev->bus->name, platform_flag);
dev_info(&adev->dev,
"ARM PL022 driver, device ID: 0x%08x\n", adev->periphid);
@@ -1930,11 +2079,7 @@ static int pl022_probe(struct amba_devic
goto err_no_ioregion;
pl022->phybase = adev->res.start;
- if (platform_flag)
- pl022->virtbase = ioremap(adev->res.start,
- resource_size(&adev->res));
- else
- pl022->virtbase = devm_ioremap(dev, adev->res.start,
+ pl022->virtbase = devm_ioremap(dev, adev->res.start,
resource_size(&adev->res));
if (pl022->virtbase == NULL) {
status = -ENOMEM;
@@ -1943,28 +2088,14 @@ static int pl022_probe(struct amba_devic
dev_info(&adev->dev, "mapped registers from %pa to %p\n",
&adev->res.start, pl022->virtbase);
- if (platform_flag)
- pl022->clk = clk_get(&adev->dev, NULL);
- else
- pl022->clk = devm_clk_get_enabled(&adev->dev, NULL);
+ pl022->clk = devm_clk_get_enabled(&adev->dev, NULL);
if (IS_ERR(pl022->clk)) {
status = PTR_ERR(pl022->clk);
dev_err(&adev->dev, "could not retrieve SSP/SPI bus clock\n");
goto err_no_clk;
}
- if (platform_flag) {
- status = clk_prepare_enable(pl022->clk);
- if (status) {
- dev_err(&adev->dev, "could not enable SSP/SPI bus clock\n");
- goto err_no_clk_en;
- }
- }
-
- if (platform_flag)
- pl022->rst = reset_control_get_exclusive(&adev->dev, NULL);
- else
- pl022->rst = devm_reset_control_get(&adev->dev, NULL);
+ pl022->rst = devm_reset_control_get(&adev->dev, NULL);
if (IS_ERR(pl022->rst)) {
status = PTR_ERR(pl022->rst);
dev_err(&adev->dev, "could not retrieve SSP/SPI bus reset\n");
@@ -1982,11 +2113,7 @@ static int pl022_probe(struct amba_devic
SSP_CR1(pl022->virtbase));
load_ssp_default_config(pl022);
- if (platform_flag)
- status = request_irq(adev->irq[0], pl022_interrupt_handler,
- 0, "pl022", pl022);
- else
- status = devm_request_irq(dev, adev->irq[0], pl022_interrupt_handler,
+ status = devm_request_irq(dev, adev->irq[0], pl022_interrupt_handler,
0, "pl022", pl022);
if (status < 0) {
dev_err(&adev->dev, "probe - cannot get IRQ (%d)\n", status);
@@ -2011,18 +2138,16 @@ static int pl022_probe(struct amba_devic
/* Register with the SPI framework */
amba_set_drvdata(adev, pl022);
- if (platform_flag)
- status = spi_register_controller(host);
- else
- status = devm_spi_register_controller(&adev->dev, host);
+
+ status = devm_spi_register_controller(&adev->dev, host);
if (status != 0) {
dev_err_probe(&adev->dev, status,
"problem registering spi host\n");
goto err_spi_register;
}
dev_dbg(dev, "probe succeeded\n");
- if (!platform_flag)
- platform_info->autosuspend_delay = 100;
+
+ platform_info->autosuspend_delay = 100;
/* let runtime pm put suspend */
if (platform_info->autosuspend_delay > 0) {
dev_info(&adev->dev,
@@ -2032,10 +2157,8 @@ static int pl022_probe(struct amba_devic
platform_info->autosuspend_delay);
pm_runtime_use_autosuspend(dev);
}
- if (platform_flag)
- clk_disable_unprepare(pl022->clk);
- else
- pm_runtime_put(dev);
+
+ pm_runtime_put(dev);
return 0;
@@ -2043,24 +2166,15 @@ static int pl022_probe(struct amba_devic
if (platform_info->enable_dma)
pl022_dma_remove(pl022);
err_no_irq:
- if (platform_flag)
- free_irq(adev->irq[0], pl022);
reset_control_assert(pl022->rst);
err_no_rst_de:
- if (platform_flag)
- reset_control_put(pl022->rst);
err_no_rst:
- if (platform_flag)
- clk_put(pl022->clk);
err_no_clk:
- if (platform_flag)
- iounmap(pl022->virtbase);
err_no_ioremap:
amba_release_regions(adev);
err_no_ioregion:
spi_controller_put(host);
- if (platform_flag)
- kfree(platform_info);
+
return status;
}
@@ -2272,23 +2386,8 @@ static int starfive_of_pl022_probe(struc
.mask = 0x000fffff,
.data = &vendor_arm
};
- struct amba_device *pcdev;
struct device *dev = &pdev->dev;
- pcdev = devm_kzalloc(&pdev->dev, sizeof(*pcdev), GFP_KERNEL);
- if (!pcdev)
- return -ENOMEM;
-
- pcdev->dev = pdev->dev;
- pcdev->periphid = id.id;
- pcdev->res = *(pdev->resource);
-
- pcdev->irq[0] = platform_get_irq(pdev, 0);
- if (pcdev->irq[0] < 0) {
- dev_err(dev, "failed to get irq\n");
- ret = -EINVAL;
- }
-
ret = of_clk_set_defaults(dev->of_node, false);
if (ret < 0)
goto err_probe;
@@ -2297,16 +2396,11 @@ static int starfive_of_pl022_probe(struc
if (ret)
goto err_probe;
- ret = pl022_probe(pcdev, &id);
-
- struct pl022 *pl022 = amba_get_drvdata(pcdev);
-
- pl022->host->dev.parent = &pdev->dev;
- platform_set_drvdata(pdev, pl022);
+ ret = pl022_platform_probe(pdev, &id);
- pm_runtime_enable(&pdev->dev);
- pm_runtime_set_autosuspend_delay(&pdev->dev, 100);
- pm_runtime_use_autosuspend(&pdev->dev);
+ pm_runtime_enable(dev);
+ pm_runtime_set_autosuspend_delay(dev, 100);
+ pm_runtime_use_autosuspend(dev);
if (ret) {
pm_runtime_disable(dev);
@@ -2321,31 +2415,25 @@ err_probe:
static void starfive_of_pl022_remove(struct platform_device *pdev)
{
- u32 size;
- int irq;
struct pl022 *pl022 = dev_get_drvdata(&pdev->dev);
if (!pl022)
return;
+ pm_runtime_get_sync(&pdev->dev);
pm_runtime_get_noresume(&pdev->dev);
load_ssp_default_config(pl022);
if (pl022->host_info->enable_dma)
pl022_dma_remove(pl022);
- irq = platform_get_irq(pdev, 0);
- free_irq(irq, pl022);
- reset_control_assert(pl022->rst);
- reset_control_put(pl022->rst);
clk_disable_unprepare(pl022->clk);
- clk_put(pl022->clk);
- iounmap(pl022->virtbase);
- kfree(pl022->host_info);
- size = resource_size(pdev->resource);
- release_mem_region(pdev->resource->start, size);
+ pm_runtime_put_noidle(&pdev->dev);
pm_runtime_disable(&pdev->dev);
+ pm_runtime_set_suspended(&pdev->dev);
+ pm_runtime_put_noidle(&pdev->dev);
+ dev_pm_domain_detach(&pdev->dev, true);
}
static const struct of_device_id starfive_of_pl022_match[] = {

View File

@ -0,0 +1,38 @@
From 4ed44e07a80ef61932b1b5012fc7f8a5a7767e41 Mon Sep 17 00:00:00 2001
From: "ziv.xu" <ziv.xu@starfive.com>
Date: Wed, 18 Jan 2023 15:50:47 +0800
Subject: [PATCH 23/55] spi-pl022-starfive:Enable spi to be compiled into
modules
Enable spi to be compiled into modules
Signed-off-by: ziv.xu <ziv.xu@starfive.com>
Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
---
drivers/spi/spi-pl022.c | 6 ++++++
1 file changed, 6 insertions(+)
--- a/drivers/spi/spi-pl022.c
+++ b/drivers/spi/spi-pl022.c
@@ -2365,7 +2365,11 @@ static int __init pl022_init(void)
{
return amba_driver_register(&pl022_driver);
}
+#if !IS_MODULE(CONFIG_SPI_PL022)
subsys_initcall(pl022_init);
+#else
+module_init(pl022_init);
+#endif
static void __exit pl022_exit(void)
{
@@ -2452,7 +2456,9 @@ static struct platform_driver starfive_o
.remove = starfive_of_pl022_remove,
};
+#if !IS_MODULE(CONFIG_SPI_PL022)
module_platform_driver(starfive_of_pl022_driver);
+#endif
/* platform register end */
MODULE_AUTHOR("xingyu.wu <xingyu.wu@starfivetech.com>");

View File

@ -0,0 +1,26 @@
From 1944de0e9d9c23f071ec1a75177ea7adbb87ba26 Mon Sep 17 00:00:00 2001
From: Hal Feng <hal.feng@starfivetech.com>
Date: Thu, 6 Jun 2024 11:01:58 +0800
Subject: [PATCH 24/55] spi: pl022: Prompt warning when frequency does not
support
Prompt warning when the frequency does not support.
Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
---
drivers/spi/spi-pl022.c | 4 ++++
1 file changed, 4 insertions(+)
--- a/drivers/spi/spi-pl022.c
+++ b/drivers/spi/spi-pl022.c
@@ -1556,6 +1556,10 @@ static int calculate_effective_freq(stru
WARN(!best_freq, "pl022: Matching cpsdvsr and scr not found for %d Hz rate \n",
freq);
+ if (best_freq != freq)
+ dev_warn(&pl022->adev->dev,
+ "Requested frequency: %d Hz is unsupported,select by default %d Hz\n",
+ freq, best_freq);
clk_freq->cpsdvsr = (u8) (best_cpsdvsr & 0xFF);
clk_freq->scr = (u8) (best_scr & 0xFF);
dev_dbg(&pl022->adev->dev,

View File

@ -0,0 +1,33 @@
From 1b818a33e3cd20250b72306946789d09d2c7b2c8 Mon Sep 17 00:00:00 2001
From: Hal Feng <hal.feng@starfivetech.com>
Date: Sun, 26 Jan 2025 16:56:05 +0800
Subject: [PATCH 25/55] spi: pl022: Fix spi overlay falut
set_cs() should not be set for spi controller when using overlay.
clk_disable_unprepare() is not needed after using
devm_clk_get_enabled() to get and enable clocks.
Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
---
drivers/spi/spi-pl022.c | 3 ---
1 file changed, 3 deletions(-)
--- a/drivers/spi/spi-pl022.c
+++ b/drivers/spi/spi-pl022.c
@@ -1908,7 +1908,6 @@ static int pl022_platform_probe(struct p
/* If open CONFIG_PM, auto_runtime_pm should be false when of-platform.*/
host->auto_runtime_pm = true;
host->transfer_one = pl022_transfer_one;
- host->set_cs = pl022_cs_control;
host->handle_err = pl022_handle_err;
host->unprepare_transfer_hardware = pl022_unprepare_transfer_hardware;
host->rt = platform_info->rt;
@@ -2435,8 +2434,6 @@ static void starfive_of_pl022_remove(str
if (pl022->host_info->enable_dma)
pl022_dma_remove(pl022);
- clk_disable_unprepare(pl022->clk);
-
pm_runtime_put_noidle(&pdev->dev);
pm_runtime_disable(&pdev->dev);
pm_runtime_set_suspended(&pdev->dev);

View File

@ -0,0 +1,42 @@
From 7e21305a33876bb56294389d5ecd6f497800e2fb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jo=C3=A3o=20M=C3=A1rio=20Domingos?=
<joao.mario@tecnico.ulisboa.pt>
Date: Tue, 16 Nov 2021 15:48:11 +0000
Subject: [PATCH 26/55] RISC-V: Added generic pmu-events mapfile
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The pmu-events now supports custom events for RISC-V, plus the cycle,
time and instret events were defined.
Signed-off-by: João Mário Domingos <joao.mario@tecnico.ulisboa.pt>
---
.../pmu-events/arch/riscv/riscv-generic.json | 20 +++++++++++++++++++
1 file changed, 20 insertions(+)
create mode 100644 tools/perf/pmu-events/arch/riscv/riscv-generic.json
--- /dev/null
+++ b/tools/perf/pmu-events/arch/riscv/riscv-generic.json
@@ -0,0 +1,20 @@
+[
+ {
+ "PublicDescription": "CPU Cycles",
+ "EventCode": "0x00",
+ "EventName": "riscv_cycles",
+ "BriefDescription": "CPU cycles RISC-V generic counter"
+ },
+ {
+ "PublicDescription": "CPU Time",
+ "EventCode": "0x01",
+ "EventName": "riscv_time",
+ "BriefDescription": "CPU time RISC-V generic counter"
+ },
+ {
+ "PublicDescription": "CPU Instructions",
+ "EventCode": "0x02",
+ "EventName": "riscv_instret",
+ "BriefDescription": "CPU retired instructions RISC-V generic counter"
+ }
+]
\ No newline at end of file

View File

@ -0,0 +1,93 @@
From f0b0e5392bd7bce16c86d4ed3fc66394db16eb7d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jo=C3=A3o=20M=C3=A1rio=20Domingos?=
<joao.mario@tecnico.ulisboa.pt>
Date: Tue, 16 Nov 2021 15:48:09 +0000
Subject: [PATCH 27/55] RISC-V: Create unique identification for SoC PMU
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The SBI PMU platform driver did not provide any identification for
perf events matching. This patch introduces a new sysfs file inside the
platform device (soc:pmu/id) for pmu identification.
The identification is a 64-bit value generated as:
[63-32]: mvendorid;
[31]: marchid[MSB];
[30-16]: marchid[15-0];
[15-0]: mimpid[15MSBs];
The CSRs are detailed in the RISC-V privileged spec [1].
The marchid is split in MSB + 15LSBs, due to the MSB being used for
open-source architecture identification.
[1] https://github.com/riscv/riscv-isa-manual
Signed-off-by: João Mário Domingos <joao.mario@tecnico.ulisboa.pt>
---
drivers/perf/riscv_pmu_sbi.c | 47 ++++++++++++++++++++++++++++++++++++
1 file changed, 47 insertions(+)
--- a/drivers/perf/riscv_pmu_sbi.c
+++ b/drivers/perf/riscv_pmu_sbi.c
@@ -1326,6 +1326,46 @@ static struct ctl_table sbi_pmu_sysctl_t
},
};
+static uint64_t pmu_sbi_get_pmu_id(void)
+{
+ union sbi_pmu_id {
+ uint64_t value;
+ struct {
+ uint16_t imp:16;
+ uint16_t arch:16;
+ uint32_t vendor:32;
+ };
+ } pmuid;
+
+ pmuid.value = 0;
+ pmuid.vendor = (uint32_t) sbi_get_mvendorid();
+ pmuid.arch = (sbi_get_marchid() >> (63 - 15) & (1 << 15)) | (sbi_get_marchid() & 0x7FFF);
+ pmuid.imp = (sbi_get_mimpid() >> 16);
+
+ return pmuid.value;
+}
+
+static ssize_t pmu_sbi_id_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int len;
+
+ len = sprintf(buf, "0x%llx\n", pmu_sbi_get_pmu_id());
+ if (len <= 0)
+ dev_err(dev, "mydrv: Invalid sprintf len: %dn", len);
+
+ return len;
+}
+
+static DEVICE_ATTR(id, S_IRUGO | S_IWUSR, pmu_sbi_id_show, 0);
+
+static struct attribute *pmu_sbi_attrs[] = {
+ &dev_attr_id.attr,
+ NULL
+};
+
+ATTRIBUTE_GROUPS(pmu_sbi);
+
static int pmu_sbi_device_probe(struct platform_device *pdev)
{
struct riscv_pmu *pmu = NULL;
@@ -1375,6 +1415,13 @@ static int pmu_sbi_device_probe(struct p
pmu->event_unmapped = pmu_sbi_event_unmapped;
pmu->csr_index = pmu_sbi_csr_index;
+ ret = sysfs_create_group(&pdev->dev.kobj, &pmu_sbi_group);
+ if (ret) {
+ dev_err(&pdev->dev, "sysfs creation failed\n");
+ return ret;
+ }
+ pdev->dev.groups = pmu_sbi_groups;
+
ret = riscv_pm_pmu_register(pmu);
if (ret)
goto out_unregister;

View File

@ -0,0 +1,55 @@
From 81ab7f42a1153d6d93b3d429ae0c779e97b0d3d6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jo=C3=A3o=20M=C3=A1rio=20Domingos?=
<joao.mario@tecnico.ulisboa.pt>
Date: Tue, 16 Nov 2021 15:48:10 +0000
Subject: [PATCH 28/55] RISC-V: Support CPUID for risc-v in perf
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This patch creates the header.c file for the risc-v architecture and introduces support for
PMU identification through sysfs.
It is now possible to configure pmu-events in risc-v.
Depends on patch [1], that introduces the id sysfs file.
Signed-off-by: João Mário Domingos <joao.mario@tecnico.ulisboa.pt>
Signed-off-by: minda.chen <minda.chen@starfivetech.com>
---
drivers/perf/riscv_pmu.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
--- a/drivers/perf/riscv_pmu.c
+++ b/drivers/perf/riscv_pmu.c
@@ -18,6 +18,23 @@
#include <asm/sbi.h>
+PMU_FORMAT_ATTR(event, "config:0-63");
+
+static struct attribute *riscv_arch_formats_attr[] = {
+ &format_attr_event.attr,
+ NULL,
+};
+
+static struct attribute_group riscv_pmu_format_group = {
+ .name = "format",
+ .attrs = riscv_arch_formats_attr,
+};
+
+static const struct attribute_group *riscv_pmu_attr_groups[] = {
+ &riscv_pmu_format_group,
+ NULL,
+};
+
static bool riscv_perf_user_access(struct perf_event *event)
{
return ((event->attr.type == PERF_TYPE_HARDWARE) ||
@@ -407,6 +424,7 @@ struct riscv_pmu *riscv_pmu_alloc(void)
cpuc->snapshot_addr = NULL;
}
pmu->pmu = (struct pmu) {
+ .attr_groups = riscv_pmu_attr_groups,
.event_init = riscv_pmu_event_init,
.event_mapped = riscv_pmu_event_mapped,
.event_unmapped = riscv_pmu_event_unmapped,

View File

@ -0,0 +1,24 @@
From 1664fcade482724f09a4e0cf25018b6ccebaed84 Mon Sep 17 00:00:00 2001
From: Walker Chen <walker.chen@starfivetech.com>
Date: Mon, 12 Jun 2023 21:21:45 +0800
Subject: [PATCH 29/55] dmaengine: dw-axi-dmac: Drop unused print message
Removed printing information which is not related to StarFive
platform.
Signed-off-by: Walker Chen <walker.chen@starfivetech.com>
---
drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
+++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
@@ -569,7 +569,7 @@ static void dw_axi_dma_set_hw_channel(st
unsigned long reg_value, val;
if (!chip->apb_regs) {
- dev_err(chip->dev, "apb_regs not initialized\n");
+ dev_dbg(chip->dev, "apb_regs not initialized\n");
return;
}

View File

@ -0,0 +1,32 @@
From 8339ccc47af05298612b7f01b8609f9081e9b081 Mon Sep 17 00:00:00 2001
From: Zoltan HERPAI <wigyori@uid0.hu>
Date: Sat, 31 May 2025 13:59:30 +0000
Subject: [PATCH 30/55] riscv: dts: starfive: vf2: add reserved-memory for E24
E24 is an rv32 RISC-V core in the JH7110 package. As the driver is now
available for it, add reserved memory as required.
Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>
---
.../dts/starfive/jh7110-starfive-visionfive-2.dtsi | 10 ++++++++++
1 file changed, 10 insertions(+)
--- a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
+++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
@@ -11,6 +11,16 @@
aliases {
ethernet1 = &gmac1;
};
+
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ e24_mem: e24@c0000000 {
+ reg = <0x0 0x6ce00000 0x0 0x1600000>;
+ };
+ };
};
&gmac1 {

View File

@ -0,0 +1,49 @@
From 907f68f5000522e3c78e9a5dca194f52f2ac54d3 Mon Sep 17 00:00:00 2001
From: Emil Renner Berthing <kernel@esmil.dk>
Date: Sun, 31 Oct 2021 17:15:58 +0100
Subject: [PATCH 1000/1021] riscv: dts: starfive: Add JH7100 high speed UARTs
Add missing device tree nodes for UART0 and UART1 on the StarFive JH7100
SoC. UART0 is used for Bluetooth on the BeagleV Starlight and StarFive
VisionFive V1 boards.
Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
---
arch/riscv/boot/dts/starfive/jh7100.dtsi | 26 ++++++++++++++++++++++++
1 file changed, 26 insertions(+)
--- a/arch/riscv/boot/dts/starfive/jh7100.dtsi
+++ b/arch/riscv/boot/dts/starfive/jh7100.dtsi
@@ -258,6 +258,32 @@
reg = <0x0 0x11850000 0x0 0x10000>;
};
+ uart0: serial@11870000 {
+ compatible = "starfive,jh7100-hsuart", "snps,dw-apb-uart";
+ reg = <0x0 0x11870000 0x0 0x10000>;
+ clocks = <&clkgen JH7100_CLK_UART0_CORE>,
+ <&clkgen JH7100_CLK_UART0_APB>;
+ clock-names = "baudclk", "apb_pclk";
+ resets = <&rstgen JH7100_RSTN_UART0_APB>;
+ interrupts = <92>;
+ reg-io-width = <4>;
+ reg-shift = <2>;
+ status = "disabled";
+ };
+
+ uart1: serial@11880000 {
+ compatible = "starfive,jh7100-hsuart", "snps,dw-apb-uart";
+ reg = <0x0 0x11880000 0x0 0x10000>;
+ clocks = <&clkgen JH7100_CLK_UART1_CORE>,
+ <&clkgen JH7100_CLK_UART1_APB>;
+ clock-names = "baudclk", "apb_pclk";
+ resets = <&rstgen JH7100_RSTN_UART1_APB>;
+ interrupts = <93>;
+ reg-io-width = <4>;
+ reg-shift = <2>;
+ status = "disabled";
+ };
+
i2c0: i2c@118b0000 {
compatible = "snps,designware-i2c";
reg = <0x0 0x118b0000 0x0 0x10000>;

View File

@ -0,0 +1,79 @@
From 920915a0d5495b1185391cceb92f9d5b26a875e4 Mon Sep 17 00:00:00 2001
From: Emil Renner Berthing <kernel@esmil.dk>
Date: Mon, 13 Sep 2021 01:18:01 +0200
Subject: [PATCH 1001/1021] riscv: dts: starfive: Enable Bluetooth on JH7100
boards
Add pinctrl and UART nodes for the Broadcom Wifi/Bluetooth module on the
BeagleV Starlight and StarFive VisionFive V1 boards.
Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
---
.../boot/dts/starfive/jh7100-common.dtsi | 49 +++++++++++++++++++
1 file changed, 49 insertions(+)
--- a/arch/riscv/boot/dts/starfive/jh7100-common.dtsi
+++ b/arch/riscv/boot/dts/starfive/jh7100-common.dtsi
@@ -289,6 +289,41 @@
};
};
+ uart0_pins: uart0-0 {
+ rx-pins {
+ pinmux = <GPIOMUX(40, GPO_LOW, GPO_DISABLE,
+ GPI_UART0_PAD_SIN)>;
+ bias-pull-up;
+ drive-strength = <14>;
+ input-enable;
+ input-schmitt-enable;
+ };
+ tx-pins {
+ pinmux = <GPIOMUX(41, GPO_UART0_PAD_SOUT,
+ GPO_ENABLE, GPI_NONE)>;
+ bias-disable;
+ drive-strength = <35>;
+ input-disable;
+ input-schmitt-disable;
+ };
+ cts-pins {
+ pinmux = <GPIOMUX(39, GPO_LOW, GPO_DISABLE,
+ GPI_UART0_PAD_CTSN)>;
+ bias-pull-down;
+ drive-strength = <14>;
+ input-enable;
+ input-schmitt-enable;
+ };
+ rts-pins {
+ pinmux = <GPIOMUX(42, GPO_UART0_PAD_RTSN,
+ GPO_ENABLE, GPI_NONE)>;
+ bias-disable;
+ drive-strength = <35>;
+ input-disable;
+ input-schmitt-disable;
+ };
+ };
+
uart3_pins: uart3-0 {
rx-pins {
pinmux = <GPIOMUX(13, GPO_LOW, GPO_DISABLE,
@@ -393,6 +428,20 @@
};
};
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins>;
+ uart-has-rtscts;
+ status = "okay";
+
+ bluetooth {
+ compatible = "brcm,bcm4330-bt";
+ max-speed = <4000000>;
+ device-wakeup-gpios = <&gpio 38 GPIO_ACTIVE_HIGH>;
+ reset-gpios = <&gpio 35 GPIO_ACTIVE_LOW>;
+ };
+};
+
&uart3 {
pinctrl-names = "default";
pinctrl-0 = <&uart3_pins>;

View File

@ -0,0 +1,25 @@
From 48358693ffb4bc661996d14adcd3942a318cdb79 Mon Sep 17 00:00:00 2001
From: Emil Renner Berthing <kernel@esmil.dk>
Date: Thu, 14 Oct 2021 20:56:54 +0200
Subject: [PATCH 1002/1021] serial: 8250_dw: Add starfive,jh7100-hsuart
compatible
This adds a compatible for the high speed UARTs on the StarFive JH7100
RISC-V SoC. Just like the regular uarts we also need to keep the input
clocks at their default rate and rely only on the divisor in the UART.
Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
---
drivers/tty/serial/8250/8250_dw.c | 1 +
1 file changed, 1 insertion(+)
--- a/drivers/tty/serial/8250/8250_dw.c
+++ b/drivers/tty/serial/8250/8250_dw.c
@@ -777,6 +777,7 @@ static const struct of_device_id dw8250_
{ .compatible = "marvell,armada-38x-uart", .data = &dw8250_armada_38x_data },
{ .compatible = "renesas,rzn1-uart", .data = &dw8250_renesas_rzn1_data },
{ .compatible = "sophgo,sg2044-uart", .data = &dw8250_skip_set_rate_data },
+ { .compatible = "starfive,jh7100-hsuart", .data = &dw8250_skip_set_rate_data },
{ .compatible = "starfive,jh7100-uart", .data = &dw8250_skip_set_rate_data },
{ /* Sentinel */ }
};

View File

@ -0,0 +1,28 @@
From bb3c832bd58bd2bca5f7f99bd19a0fe6ad3cf1a4 Mon Sep 17 00:00:00 2001
From: Samin Guo <samin.guo@starfivetech.com>
Date: Fri, 8 Jan 2021 03:11:04 +0800
Subject: [PATCH 1003/1021] drivers/tty/serial/8250: update driver for JH7100
---
drivers/tty/serial/8250/8250_port.c | 8 ++++++++
1 file changed, 8 insertions(+)
--- a/drivers/tty/serial/8250/8250_port.c
+++ b/drivers/tty/serial/8250/8250_port.c
@@ -68,8 +68,16 @@ static const struct serial8250_config ua
},
[PORT_16550] = {
.name = "16550",
+#ifdef CONFIG_SOC_STARFIVE
+ .fifo_size = 16,
+ .tx_loadsz = 16,
+ .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_00,
+ .rxtrig_bytes = {1, 4, 8, 14},
+ .flags = UART_CAP_FIFO,
+#else
.fifo_size = 1,
.tx_loadsz = 1,
+#endif
},
[PORT_16550A] = {
.name = "16550A",

View File

@ -0,0 +1,29 @@
From 995a9b41dd4e29d02ec549170f917b301d8a6d36 Mon Sep 17 00:00:00 2001
From: Emil Renner Berthing <kernel@esmil.dk>
Date: Sun, 3 Jul 2022 21:01:11 +0200
Subject: [PATCH 1004/1021] power: reset: tps65086: Allow building as a module
Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
---
drivers/power/reset/Kconfig | 2 +-
drivers/power/reset/tps65086-restart.c | 1 +
2 files changed, 2 insertions(+), 1 deletion(-)
--- a/drivers/power/reset/Kconfig
+++ b/drivers/power/reset/Kconfig
@@ -217,7 +217,7 @@ config POWER_RESET_ST
Reset support for STMicroelectronics boards.
config POWER_RESET_TPS65086
- bool "TPS65086 restart driver"
+ tristate "TPS65086 restart driver"
depends on MFD_TPS65086
help
This driver adds support for resetting the TPS65086 PMIC on restart.
--- a/drivers/power/reset/tps65086-restart.c
+++ b/drivers/power/reset/tps65086-restart.c
@@ -57,3 +57,4 @@ module_platform_driver(tps65086_restart_
MODULE_AUTHOR("Emil Renner Berthing <kernel@esmil.dk>");
MODULE_DESCRIPTION("TPS65086 restart driver");
+MODULE_LICENSE("GPL v2");

View File

@ -0,0 +1,33 @@
From bedd1e49a138fc532712ae3e889af17a0dbc9417 Mon Sep 17 00:00:00 2001
From: Emil Renner Berthing <kernel@esmil.dk>
Date: Sat, 20 Nov 2021 17:13:22 +0100
Subject: [PATCH 1005/1021] riscv: dts: starfive: Add StarFive JH7100 audio
clock node
Add device tree node for the audio clocks on the StarFive JH7100 RISC-V
SoC.
Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
---
arch/riscv/boot/dts/starfive/jh7100.dtsi | 10 ++++++++++
1 file changed, 10 insertions(+)
--- a/arch/riscv/boot/dts/starfive/jh7100.dtsi
+++ b/arch/riscv/boot/dts/starfive/jh7100.dtsi
@@ -239,6 +239,16 @@
};
};
+ audclk: clock-controller@10480000 {
+ compatible = "starfive,jh7100-audclk";
+ reg = <0x0 0x10480000 0x0 0x10000>;
+ clocks = <&clkgen JH7100_CLK_AUDIO_SRC>,
+ <&clkgen JH7100_CLK_AUDIO_12288>,
+ <&clkgen JH7100_CLK_DOM7AHB_BUS>;
+ clock-names = "audio_src", "audio_12288", "dom7ahb_bus";
+ #clock-cells = <1>;
+ };
+
clkgen: clock-controller@11800000 {
compatible = "starfive,jh7100-clkgen";
reg = <0x0 0x11800000 0x0 0x10000>;

View File

@ -0,0 +1,48 @@
From 052732a9fb44ab63e522a9b2949d64e2d2f2d4fc Mon Sep 17 00:00:00 2001
From: Emil Renner Berthing <kernel@esmil.dk>
Date: Sat, 20 Nov 2021 19:29:25 +0100
Subject: [PATCH 1006/1021] dt-bindings: reset: Add StarFive JH7100 audio reset
definitions
Add all resets for the StarFive JH7100 audio reset controller.
Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
---
.../dt-bindings/reset/starfive-jh7100-audio.h | 31 +++++++++++++++++++
1 file changed, 31 insertions(+)
create mode 100644 include/dt-bindings/reset/starfive-jh7100-audio.h
--- /dev/null
+++ b/include/dt-bindings/reset/starfive-jh7100-audio.h
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
+/*
+ * Copyright (C) 2021 Emil Renner Berthing
+ */
+
+#ifndef __DT_BINDINGS_RESET_STARFIVE_JH7100_AUDIO_H__
+#define __DT_BINDINGS_RESET_STARFIVE_JH7100_AUDIO_H__
+
+#define JH7100_AUDRSTN_APB_BUS 0
+#define JH7100_AUDRSTN_I2SADC_APB 1
+#define JH7100_AUDRSTN_I2SADC_SRST 2
+#define JH7100_AUDRSTN_PDM_APB 3
+#define JH7100_AUDRSTN_I2SVAD_APB 4
+#define JH7100_AUDRSTN_I2SVAD_SRST 5
+#define JH7100_AUDRSTN_SPDIF_APB 6
+#define JH7100_AUDRSTN_PWMDAC_APB 7
+#define JH7100_AUDRSTN_I2SDAC_APB 8
+#define JH7100_AUDRSTN_I2SDAC_SRST 9
+#define JH7100_AUDRSTN_I2S1_APB 10
+#define JH7100_AUDRSTN_I2S1_SRST 11
+#define JH7100_AUDRSTN_I2SDAC16K_APB 12
+#define JH7100_AUDRSTN_I2SDAC16K_SRST 13
+#define JH7100_AUDRSTN_DMA1P_AHB 14
+#define JH7100_AUDRSTN_USB_APB 15
+#define JH7100_AUDRST_USB_AXI 16
+#define JH7100_AUDRST_USB_PWRUP_RST_N 17
+#define JH7100_AUDRST_USB_PONRST 18
+
+#define JH7100_AUDRSTN_END 19
+
+#endif /* __DT_BINDINGS_RESET_STARFIVE_JH7100_AUDIO_H__ */

View File

@ -0,0 +1,144 @@
From 2828a23364ab4a55af817b7ab370e6fc225f025d Mon Sep 17 00:00:00 2001
From: Emil Renner Berthing <kernel@esmil.dk>
Date: Sat, 20 Nov 2021 19:30:49 +0100
Subject: [PATCH 1007/1021] reset: starfive: Add JH7100 audio reset driver
The audio resets are almost identical to the system resets, there are
just fewer of them. So factor out and export a generic probe function,
so most of the reset controller implementation can be shared.
Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
---
MAINTAINERS | 2 +-
drivers/reset/starfive/Kconfig | 7 ++
drivers/reset/starfive/Makefile | 2 +
.../starfive/reset-starfive-jh7100-audio.c | 66 +++++++++++++++++++
.../reset/starfive/reset-starfive-jh7100.h | 16 +++++
5 files changed, 92 insertions(+), 1 deletion(-)
create mode 100644 drivers/reset/starfive/reset-starfive-jh7100-audio.c
create mode 100644 drivers/reset/starfive/reset-starfive-jh7100.h
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -22078,7 +22078,7 @@ STARFIVE JH71X0 RESET CONTROLLER DRIVERS
M: Emil Renner Berthing <kernel@esmil.dk>
M: Hal Feng <hal.feng@starfivetech.com>
S: Maintained
-F: Documentation/devicetree/bindings/reset/starfive,jh7100-reset.yaml
+F: Documentation/devicetree/bindings/reset/starfive,jh7100-*.yaml
F: drivers/reset/starfive/reset-starfive-jh71*
F: include/dt-bindings/reset/starfive?jh71*.h
--- a/drivers/reset/starfive/Kconfig
+++ b/drivers/reset/starfive/Kconfig
@@ -11,6 +11,13 @@ config RESET_STARFIVE_JH7100
help
This enables the reset controller driver for the StarFive JH7100 SoC.
+config RESET_STARFIVE_JH7100_AUDIO
+ tristate "StarFive JH7100 Audio Reset Driver"
+ depends on RESET_STARFIVE_JH7100
+ default m if SOC_STARFIVE
+ help
+ This enables the audio reset driver for the StarFive JH7100 SoC.
+
config RESET_STARFIVE_JH7110
bool "StarFive JH7110 Reset Driver"
depends on CLK_STARFIVE_JH7110_SYS
--- a/drivers/reset/starfive/Makefile
+++ b/drivers/reset/starfive/Makefile
@@ -2,4 +2,6 @@
obj-$(CONFIG_RESET_STARFIVE_JH71X0) += reset-starfive-jh71x0.o
obj-$(CONFIG_RESET_STARFIVE_JH7100) += reset-starfive-jh7100.o
+obj-$(CONFIG_RESET_STARFIVE_JH7100_AUDIO) += reset-starfive-jh7100-audio.o
+
obj-$(CONFIG_RESET_STARFIVE_JH7110) += reset-starfive-jh7110.o
--- /dev/null
+++ b/drivers/reset/starfive/reset-starfive-jh7100-audio.c
@@ -0,0 +1,66 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Audio reset driver for the StarFive JH7100 SoC
+ *
+ * Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
+ */
+
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include "reset-starfive-jh71x0.h"
+
+#include <dt-bindings/reset/starfive-jh7100-audio.h>
+
+/* register offsets */
+#define JH7100_AUDRST_ASSERT0 0x00
+#define JH7100_AUDRST_STATUS0 0x04
+
+/*
+ * Writing a 1 to the n'th bit of the ASSERT register asserts
+ * line n, and writing a 0 deasserts the same line.
+ * Most reset lines have their status inverted so a 0 bit in the STATUS
+ * register means the line is asserted and a 1 means it's deasserted. A few
+ * lines don't though, so store the expected value of the status registers when
+ * all lines are asserted.
+ */
+static const u32 jh7100_audrst_asserted[1] = {
+ BIT(JH7100_AUDRST_USB_AXI) |
+ BIT(JH7100_AUDRST_USB_PWRUP_RST_N) |
+ BIT(JH7100_AUDRST_USB_PONRST)
+};
+
+static int jh7100_audrst_probe(struct platform_device *pdev)
+{
+ void __iomem *base = devm_platform_ioremap_resource(pdev, 0);
+
+ if (IS_ERR(base))
+ return PTR_ERR(base);
+
+ return reset_starfive_jh71x0_register(&pdev->dev, pdev->dev.of_node,
+ base + JH7100_AUDRST_ASSERT0,
+ base + JH7100_AUDRST_STATUS0,
+ jh7100_audrst_asserted,
+ JH7100_AUDRSTN_END,
+ THIS_MODULE);
+}
+
+static const struct of_device_id jh7100_audrst_dt_ids[] = {
+ { .compatible = "starfive,jh7100-audrst" },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, jh7100_audrst_dt_ids);
+
+static struct platform_driver jh7100_audrst_driver = {
+ .probe = jh7100_audrst_probe,
+ .driver = {
+ .name = "jh7100-reset-audio",
+ .of_match_table = jh7100_audrst_dt_ids,
+ },
+};
+module_platform_driver(jh7100_audrst_driver);
+
+MODULE_AUTHOR("Emil Renner Berthing");
+MODULE_DESCRIPTION("StarFive JH7100 audio reset driver");
+MODULE_LICENSE("GPL");
--- /dev/null
+++ b/drivers/reset/starfive/reset-starfive-jh7100.h
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
+ */
+
+#ifndef _RESET_STARFIVE_JH7100_H_
+#define _RESET_STARFIVE_JH7100_H_
+
+#include <linux/platform_device.h>
+
+int reset_starfive_jh7100_generic_probe(struct platform_device *pdev,
+ const u32 *asserted,
+ unsigned int status_offset,
+ unsigned int nr_resets);
+
+#endif

View File

@ -0,0 +1,29 @@
From a806acd4f507764123838c9620d4e581585f2099 Mon Sep 17 00:00:00 2001
From: Emil Renner Berthing <kernel@esmil.dk>
Date: Sat, 20 Nov 2021 21:33:08 +0100
Subject: [PATCH 1008/1021] riscv: dts: starfive: Add StarFive JH7100 audio
reset node
Add device tree node for the audio resets on the StarFive JH7100 RISC-V
SoC.
Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
---
arch/riscv/boot/dts/starfive/jh7100.dtsi | 6 ++++++
1 file changed, 6 insertions(+)
--- a/arch/riscv/boot/dts/starfive/jh7100.dtsi
+++ b/arch/riscv/boot/dts/starfive/jh7100.dtsi
@@ -249,6 +249,12 @@
#clock-cells = <1>;
};
+ audrst: reset-controller@10490000 {
+ compatible = "starfive,jh7100-audrst";
+ reg = <0x0 0x10490000 0x0 0x10000>;
+ #reset-cells = <1>;
+ };
+
clkgen: clock-controller@11800000 {
compatible = "starfive,jh7100-clkgen";
reg = <0x0 0x11800000 0x0 0x10000>;

View File

@ -0,0 +1,61 @@
From 174c73330839bad688b9fb2e9b6b9a2e5d74021f Mon Sep 17 00:00:00 2001
From: Emil Renner Berthing <kernel@esmil.dk>
Date: Thu, 14 Oct 2021 20:35:43 +0200
Subject: [PATCH 1009/1021] clk: starfive: jh7100: Keep more clocks alive
Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
---
drivers/clk/starfive/clk-starfive-jh7100.c | 19 ++++++++++---------
1 file changed, 10 insertions(+), 9 deletions(-)
--- a/drivers/clk/starfive/clk-starfive-jh7100.c
+++ b/drivers/clk/starfive/clk-starfive-jh7100.c
@@ -94,9 +94,9 @@ static const struct jh71x0_clk_data jh71
JH71X0_GATE(JH7100_CLK_DMA2PNOC_AXI, "dma2pnoc_axi", 0, JH7100_CLK_CPU_AXI),
JH71X0_GATE(JH7100_CLK_SGDMA2P_AHB, "sgdma2p_ahb", 0, JH7100_CLK_AHB_BUS),
JH71X0__DIV(JH7100_CLK_DLA_BUS, "dla_bus", 4, JH7100_CLK_DLA_ROOT),
- JH71X0_GATE(JH7100_CLK_DLA_AXI, "dla_axi", 0, JH7100_CLK_DLA_BUS),
- JH71X0_GATE(JH7100_CLK_DLANOC_AXI, "dlanoc_axi", 0, JH7100_CLK_DLA_BUS),
- JH71X0_GATE(JH7100_CLK_DLA_APB, "dla_apb", 0, JH7100_CLK_APB1_BUS),
+ JH71X0_GATE(JH7100_CLK_DLA_AXI, "dla_axi", CLK_IGNORE_UNUSED, JH7100_CLK_DLA_BUS),
+ JH71X0_GATE(JH7100_CLK_DLANOC_AXI, "dlanoc_axi", CLK_IGNORE_UNUSED, JH7100_CLK_DLA_BUS),
+ JH71X0_GATE(JH7100_CLK_DLA_APB, "dla_apb", CLK_IGNORE_UNUSED, JH7100_CLK_APB1_BUS),
JH71X0_GDIV(JH7100_CLK_VP6_CORE, "vp6_core", 0, 4, JH7100_CLK_DSP_ROOT_DIV),
JH71X0__DIV(JH7100_CLK_VP6BUS_SRC, "vp6bus_src", 4, JH7100_CLK_DSP_ROOT),
JH71X0_GDIV(JH7100_CLK_VP6_AXI, "vp6_axi", 0, 4, JH7100_CLK_VP6BUS_SRC),
@@ -163,8 +163,9 @@ static const struct jh71x0_clk_data jh71
JH71X0_GATE(JH7100_CLK_USB_AXI, "usb_axi", 0, JH7100_CLK_USB_BUS),
JH71X0_GATE(JH7100_CLK_USBNOC_AXI, "usbnoc_axi", 0, JH7100_CLK_USB_BUS),
JH71X0__DIV(JH7100_CLK_USBPHY_ROOTDIV, "usbphy_rootdiv", 4, JH7100_CLK_GMACUSB_ROOT),
- JH71X0_GDIV(JH7100_CLK_USBPHY_125M, "usbphy_125m", 0, 8, JH7100_CLK_USBPHY_ROOTDIV),
- JH71X0_GDIV(JH7100_CLK_USBPHY_PLLDIV25M, "usbphy_plldiv25m", 0, 32,
+ JH71X0_GDIV(JH7100_CLK_USBPHY_125M, "usbphy_125m", CLK_IGNORE_UNUSED, 8,
+ JH7100_CLK_USBPHY_ROOTDIV),
+ JH71X0_GDIV(JH7100_CLK_USBPHY_PLLDIV25M, "usbphy_plldiv25m", CLK_IGNORE_UNUSED, 32,
JH7100_CLK_USBPHY_ROOTDIV),
JH71X0__MUX(JH7100_CLK_USBPHY_25M, "usbphy_25m", 0, 2,
JH7100_CLK_OSC_SYS,
@@ -183,11 +184,11 @@ static const struct jh71x0_clk_data jh71
JH71X0__DIV(JH7100_CLK_VIN_BUS, "vin_bus", 8, JH7100_CLK_VIN_SRC),
JH71X0_GATE(JH7100_CLK_VIN_AXI, "vin_axi", 0, JH7100_CLK_VIN_BUS),
JH71X0_GATE(JH7100_CLK_VINNOC_AXI, "vinnoc_axi", 0, JH7100_CLK_VIN_BUS),
- JH71X0_GDIV(JH7100_CLK_VOUT_SRC, "vout_src", 0, 4, JH7100_CLK_VOUT_ROOT),
+ JH71X0_GDIV(JH7100_CLK_VOUT_SRC, "vout_src", CLK_IGNORE_UNUSED, 4, JH7100_CLK_VOUT_ROOT),
JH71X0__DIV(JH7100_CLK_DISPBUS_SRC, "dispbus_src", 4, JH7100_CLK_VOUTBUS_ROOT),
JH71X0__DIV(JH7100_CLK_DISP_BUS, "disp_bus", 4, JH7100_CLK_DISPBUS_SRC),
- JH71X0_GATE(JH7100_CLK_DISP_AXI, "disp_axi", 0, JH7100_CLK_DISP_BUS),
- JH71X0_GATE(JH7100_CLK_DISPNOC_AXI, "dispnoc_axi", 0, JH7100_CLK_DISP_BUS),
+ JH71X0_GATE(JH7100_CLK_DISP_AXI, "disp_axi", CLK_IGNORE_UNUSED, JH7100_CLK_DISP_BUS),
+ JH71X0_GATE(JH7100_CLK_DISPNOC_AXI, "dispnoc_axi", CLK_IGNORE_UNUSED, JH7100_CLK_DISP_BUS),
JH71X0_GATE(JH7100_CLK_SDIO0_AHB, "sdio0_ahb", 0, JH7100_CLK_AHB_BUS),
JH71X0_GDIV(JH7100_CLK_SDIO0_CCLKINT, "sdio0_cclkint", 0, 24, JH7100_CLK_PERH0_SRC),
JH71X0__INV(JH7100_CLK_SDIO0_CCLKINT_INV, "sdio0_cclkint_inv", JH7100_CLK_SDIO0_CCLKINT),
@@ -223,7 +224,7 @@ static const struct jh71x0_clk_data jh71
JH71X0_GATE(JH7100_CLK_AES, "aes_clk", 0, JH7100_CLK_SEC_AHB),
JH71X0_GATE(JH7100_CLK_SHA, "sha_clk", 0, JH7100_CLK_SEC_AHB),
JH71X0_GATE(JH7100_CLK_PKA, "pka_clk", 0, JH7100_CLK_SEC_AHB),
- JH71X0_GATE(JH7100_CLK_TRNG_APB, "trng_apb", 0, JH7100_CLK_APB1_BUS),
+ JH71X0_GATE(JH7100_CLK_TRNG_APB, "trng_apb", CLK_IGNORE_UNUSED, JH7100_CLK_APB1_BUS),
JH71X0_GATE(JH7100_CLK_OTP_APB, "otp_apb", 0, JH7100_CLK_APB1_BUS),
JH71X0_GATE(JH7100_CLK_UART0_APB, "uart0_apb", 0, JH7100_CLK_APB1_BUS),
JH71X0_GDIV(JH7100_CLK_UART0_CORE, "uart0_core", 0, 63, JH7100_CLK_PERH1_SRC),

View File

@ -0,0 +1,127 @@
From f3e66db46e8c849e154042c35bfa22fedc03c3df Mon Sep 17 00:00:00 2001
From: Emil Renner Berthing <kernel@esmil.dk>
Date: Sat, 17 Jul 2021 21:50:38 +0200
Subject: [PATCH 1010/1021] pinctrl: starfive: Reset pinmux settings
Current u-boot doesn't seem to take into account that some GPIOs are
configured as inputs/outputs of certain peripherals on power-up. This
means it ends up configuring some GPIOs as inputs to more than one
peripheral which the documentation explicitly says is illegal. Similarly
it also ends up configuring more than one GPIO as output of the same
peripheral. While not explicitly mentioned by the documentation this
also seems like a bad idea.
The easiest way to remedy this mess is to just disconnect all GPIOs from
peripherals and have our pinmux configuration set everything up
properly. This, however, means that we'd disconnect the serial console
from its pins for a while, so add a device tree property to keep
certain GPIOs from being reset.
Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
---
.../pinctrl/starfive,jh7100-pinctrl.yaml | 4 ++
.../starfive/pinctrl-starfive-jh7100.c | 66 +++++++++++++++++++
2 files changed, 70 insertions(+)
--- a/Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml
+++ b/Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml
@@ -88,6 +88,10 @@ properties:
$ref: /schemas/types.yaml#/definitions/uint32
enum: [0, 1, 2, 3, 4, 5, 6]
+ starfive,keep-gpiomux:
+ description: Keep pinmux for these GPIOs from being reset at boot.
+ $ref: /schemas/types.yaml#/definitions/uint32-array
+
required:
- compatible
- reg
--- a/drivers/pinctrl/starfive/pinctrl-starfive-jh7100.c
+++ b/drivers/pinctrl/starfive/pinctrl-starfive-jh7100.c
@@ -203,6 +203,10 @@ static u16 starfive_drive_strength_from_
return (clamp(i, 14U, 63U) - 14) / 7;
}
+static bool keepmux;
+module_param(keepmux, bool, 0644);
+MODULE_PARM_DESC(keepmux, "Keep pinmux settings from previous boot stage");
+
struct starfive_pinctrl {
struct gpio_chip gc;
struct pinctrl_gpio_range gpios;
@@ -1210,6 +1214,65 @@ static void starfive_disable_clock(void
clk_disable_unprepare(data);
}
+#define GPI_END (GPI_USB_OVER_CURRENT + 1)
+static void starfive_pinmux_reset(struct starfive_pinctrl *sfp)
+{
+ static const DECLARE_BITMAP(defaults, GPI_END) = {
+ BIT_MASK(GPI_I2C0_PAD_SCK_IN) |
+ BIT_MASK(GPI_I2C0_PAD_SDA_IN) |
+ BIT_MASK(GPI_I2C1_PAD_SCK_IN) |
+ BIT_MASK(GPI_I2C1_PAD_SDA_IN) |
+ BIT_MASK(GPI_I2C2_PAD_SCK_IN) |
+ BIT_MASK(GPI_I2C2_PAD_SDA_IN) |
+ BIT_MASK(GPI_I2C3_PAD_SCK_IN) |
+ BIT_MASK(GPI_I2C3_PAD_SDA_IN) |
+ BIT_MASK(GPI_SDIO0_PAD_CARD_DETECT_N) |
+
+ BIT_MASK(GPI_SDIO1_PAD_CARD_DETECT_N) |
+ BIT_MASK(GPI_SPI0_PAD_SS_IN_N) |
+ BIT_MASK(GPI_SPI1_PAD_SS_IN_N) |
+ BIT_MASK(GPI_SPI2_PAD_SS_IN_N) |
+ BIT_MASK(GPI_SPI2AHB_PAD_SS_N) |
+ BIT_MASK(GPI_SPI3_PAD_SS_IN_N),
+
+ BIT_MASK(GPI_UART0_PAD_SIN) |
+ BIT_MASK(GPI_UART1_PAD_SIN) |
+ BIT_MASK(GPI_UART2_PAD_SIN) |
+ BIT_MASK(GPI_UART3_PAD_SIN) |
+ BIT_MASK(GPI_USB_OVER_CURRENT)
+ };
+ DECLARE_BITMAP(keep, NR_GPIOS) = {};
+ struct device_node *np = sfp->gc.parent->of_node;
+ int len = of_property_count_u32_elems(np, "starfive,keep-gpiomux");
+ int i;
+
+ for (i = 0; i < len; i++) {
+ u32 gpio;
+
+ of_property_read_u32_index(np, "starfive,keep-gpiomux", i, &gpio);
+ if (gpio < NR_GPIOS)
+ set_bit(gpio, keep);
+ }
+
+ for (i = 0; i < NR_GPIOS; i++) {
+ if (test_bit(i, keep))
+ continue;
+
+ writel_relaxed(GPO_DISABLE, sfp->base + GPON_DOEN_CFG + 8 * i);
+ writel_relaxed(GPO_LOW, sfp->base + GPON_DOUT_CFG + 8 * i);
+ }
+
+ for (i = 0; i < GPI_END; i++) {
+ void __iomem *reg = sfp->base + GPI_CFG_OFFSET + 4 * i;
+ u32 din = readl_relaxed(reg);
+
+ if (din >= 2 && din < (NR_GPIOS + 2) && test_bit(din - 2, keep))
+ continue;
+
+ writel_relaxed(test_bit(i, defaults), reg);
+ }
+}
+
static int starfive_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
@@ -1271,6 +1334,9 @@ static int starfive_probe(struct platfor
writel(value, sfp->padctl + IO_PADSHARE_SEL);
}
+ if (!keepmux)
+ starfive_pinmux_reset(sfp);
+
value = readl(sfp->padctl + IO_PADSHARE_SEL);
switch (value) {
case 0:

View File

@ -0,0 +1,30 @@
From 690e2d40fe645e86dcd0ac265038426676473e19 Mon Sep 17 00:00:00 2001
From: Matteo Croce <technoboy85@gmail.com>
Date: Fri, 21 May 2021 03:26:38 +0200
Subject: [PATCH 1011/1021] net: stmmac: use GFP_DMA32
Signed-off-by: Matteo Croce <mcroce@microsoft.com>
---
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -1460,7 +1460,7 @@ static int stmmac_init_rx_buffers(struct
{
struct stmmac_rx_queue *rx_q = &dma_conf->rx_queue[queue];
struct stmmac_rx_buffer *buf = &rx_q->buf_pool[i];
- gfp_t gfp = (GFP_ATOMIC | __GFP_NOWARN);
+ gfp_t gfp = (GFP_ATOMIC | __GFP_NOWARN | GFP_DMA32);
if (priv->dma_cap.host_dma_width <= 32)
gfp |= GFP_DMA32;
@@ -4756,7 +4756,7 @@ static inline void stmmac_rx_refill(stru
struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue];
int dirty = stmmac_rx_dirty(priv, queue);
unsigned int entry = rx_q->dirty_rx;
- gfp_t gfp = (GFP_ATOMIC | __GFP_NOWARN);
+ gfp_t gfp = (GFP_ATOMIC | __GFP_NOWARN | GFP_DMA32);
if (priv->dma_cap.host_dma_width <= 32)
gfp |= GFP_DMA32;

View File

@ -0,0 +1,45 @@
From e941dae591d8cd24f6758ecded9cc9741082e76d Mon Sep 17 00:00:00 2001
From: Geert Uytterhoeven <geert@linux-m68k.org>
Date: Thu, 27 May 2021 20:13:43 +0200
Subject: [PATCH 1012/1021] dt-bindings: dma: dw-axi-dmac: Increase DMA channel
limit to 16
The first DMAC instance in the StarFive JH7100 SoC supports 16 DMA
channels.
FIXME Given there are more changes to the driver than just increasing
DMAC_MAX_CHANNELS, we probably need a new compatible value, too.
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
---
Documentation/devicetree/bindings/dma/snps,dw-axi-dmac.yaml | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
--- a/Documentation/devicetree/bindings/dma/snps,dw-axi-dmac.yaml
+++ b/Documentation/devicetree/bindings/dma/snps,dw-axi-dmac.yaml
@@ -57,7 +57,7 @@ properties:
dma-channels:
minimum: 1
- maximum: 8
+ maximum: 16
resets:
minItems: 1
@@ -81,14 +81,14 @@ properties:
Channel priority specifier associated with the DMA channels.
$ref: /schemas/types.yaml#/definitions/uint32-array
minItems: 1
- maxItems: 8
+ maxItems: 16
snps,block-size:
description: |
Channel block size specifier associated with the DMA channels.
$ref: /schemas/types.yaml#/definitions/uint32-array
minItems: 1
- maxItems: 8
+ maxItems: 16
snps,axi-max-burst-len:
description: |

View File

@ -0,0 +1,55 @@
From 38bf6380d873ebf247dde54a1b93dcfbf3ea19f6 Mon Sep 17 00:00:00 2001
From: Samin Guo <samin.guo@starfivetech.com>
Date: Wed, 17 Nov 2021 14:50:45 +0800
Subject: [PATCH 1013/1021] dmaengine: dw-axi-dmac: Handle xfer start while
non-idle
Signed-off-by: Samin Guo <samin.guo@starfivetech.com>
Signed-off-by: Curry Zhang <curry.zhang@starfivetech.com>
---
drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c | 12 +++++++++++-
drivers/dma/dw-axi-dmac/dw-axi-dmac.h | 1 +
2 files changed, 12 insertions(+), 1 deletion(-)
--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
+++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
@@ -428,11 +428,13 @@ static void axi_chan_block_xfer_start(st
u32 irq_mask;
u8 lms = 0; /* Select AXI0 master for LLI fetching */
+ chan->is_err = false;
if (unlikely(axi_chan_is_hw_enable(chan))) {
dev_err(chan2dev(chan), "%s is non-idle!\n",
axi_chan_name(chan));
- return;
+ axi_chan_disable(chan);
+ chan->is_err = true;
}
axi_dma_enable(chan->chip);
@@ -1074,6 +1076,14 @@ static noinline void axi_chan_handle_err
axi_chan_name(chan));
goto out;
}
+ if (chan->is_err) {
+ struct axi_dma_desc *desc = vd_to_axi_desc(vd);
+
+ axi_chan_block_xfer_start(chan, desc);
+ chan->is_err = false;
+ goto out;
+ }
+
/* Remove the completed descriptor from issued list */
list_del(&vd->node);
--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
+++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
@@ -50,6 +50,7 @@ struct axi_dma_chan {
struct dma_slave_config config;
enum dma_transfer_direction direction;
bool cyclic;
+ bool is_err;
/* these other elements are all protected by vc.lock */
bool is_paused;
};

View File

@ -0,0 +1,64 @@
From 43048e7698e0a2c0870112168ed138de4aa937cc Mon Sep 17 00:00:00 2001
From: Samin Guo <samin.guo@starfivetech.com>
Date: Wed, 17 Nov 2021 14:50:45 +0800
Subject: [PATCH 1014/1021] dmaengine: dw-axi-dmac: Add StarFive JH7100 support
Signed-off-by: Samin Guo <samin.guo@starfivetech.com>
Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
---
drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c | 12 ++++++++++++
drivers/dma/dw-axi-dmac/dw-axi-dmac.h | 4 ++++
2 files changed, 16 insertions(+)
--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
+++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
@@ -723,8 +723,13 @@ static int dw_axi_dma_set_hw_desc(struct
hw_desc->lli->block_ts_lo = cpu_to_le32(block_ts - 1);
+#ifdef CONFIG_SOC_STARFIVE
+ ctllo |= DWAXIDMAC_BURST_TRANS_LEN_16 << CH_CTL_L_DST_MSIZE_POS |
+ DWAXIDMAC_BURST_TRANS_LEN_16 << CH_CTL_L_SRC_MSIZE_POS;
+#else
ctllo |= DWAXIDMAC_BURST_TRANS_LEN_4 << CH_CTL_L_DST_MSIZE_POS |
DWAXIDMAC_BURST_TRANS_LEN_4 << CH_CTL_L_SRC_MSIZE_POS;
+#endif
hw_desc->lli->ctl_lo = cpu_to_le32(ctllo);
set_desc_src_master(hw_desc);
@@ -1589,7 +1594,11 @@ static int dw_probe(struct platform_devi
* Therefore, set constraint to 1024 * 4.
*/
dw->dma.dev->dma_parms = &dw->dma_parms;
+#ifdef CONFIG_SOC_STARFIVE
+ dma_set_max_seg_size(&pdev->dev, DMAC_MAX_BLK_SIZE);
+#else
dma_set_max_seg_size(&pdev->dev, MAX_BLOCK_SIZE);
+#endif
platform_set_drvdata(pdev, chip);
pm_runtime_enable(chip->dev);
@@ -1674,6 +1683,9 @@ static const struct of_device_id dw_dma_
.compatible = "intel,kmb-axi-dma",
.data = (void *)AXI_DMA_FLAG_HAS_APB_REGS,
}, {
+ .compatible = "starfive,jh7100-axi-dma",
+ .data = (void *)(AXI_DMA_FLAG_HAS_RESETS | AXI_DMA_FLAG_USE_CFG2),
+ }, {
.compatible = "starfive,jh7110-axi-dma",
.data = (void *)(AXI_DMA_FLAG_HAS_RESETS | AXI_DMA_FLAG_USE_CFG2),
}, {
--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
+++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
@@ -288,7 +288,11 @@ enum {
#define CH_CTL_L_SRC_MAST BIT(0)
/* CH_CFG_H */
+#ifdef CONFIG_SOC_STARFIVE
+#define CH_CFG_H_PRIORITY_POS 15
+#else
#define CH_CFG_H_PRIORITY_POS 17
+#endif
#define CH_CFG_H_DST_PER_POS 12
#define CH_CFG_H_SRC_PER_POS 7
#define CH_CFG_H_HS_SEL_DST_POS 4

View File

@ -0,0 +1,477 @@
From 4a5a14f6cce89d12efa90dd8e2a82e36df2ee179 Mon Sep 17 00:00:00 2001
From: Huan Feng <huan.feng@starfivetech.com>
Date: Fri, 8 Jan 2021 03:35:42 +0800
Subject: [PATCH 1015/1021] hwrng: Add StarFive JH7100 Random Number Generator
driver
Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
---
drivers/char/hw_random/Kconfig | 13 ++
drivers/char/hw_random/Makefile | 1 +
drivers/char/hw_random/starfive-vic-rng.c | 256 ++++++++++++++++++++++
drivers/char/hw_random/starfive-vic-rng.h | 167 ++++++++++++++
4 files changed, 437 insertions(+)
create mode 100644 drivers/char/hw_random/starfive-vic-rng.c
create mode 100644 drivers/char/hw_random/starfive-vic-rng.h
--- a/drivers/char/hw_random/Kconfig
+++ b/drivers/char/hw_random/Kconfig
@@ -323,6 +323,19 @@ config HW_RANDOM_POWERNV
If unsure, say Y.
+config HW_RANDOM_STARFIVE_VIC
+ tristate "Starfive VIC Random Number Generator support"
+ depends on HW_RANDOM && (SOC_STARFIVE || COMPILE_TEST)
+ default SOC_STARFIVE
+ help
+ This driver provides kernel-side support for the Random Number
+ Generator hardware found on Starfive VIC SoC.
+
+ To compile this driver as a module, choose M here: the
+ module will be called starfive-vic-rng.
+
+ If unsure, say Y.
+
config HW_RANDOM_HISI
tristate "Hisilicon Random Number Generator support"
depends on ARCH_HISI || COMPILE_TEST
--- a/drivers/char/hw_random/Makefile
+++ b/drivers/char/hw_random/Makefile
@@ -28,6 +28,7 @@ obj-$(CONFIG_HW_RANDOM_OCTEON) += octeon
obj-$(CONFIG_HW_RANDOM_NOMADIK) += nomadik-rng.o
obj-$(CONFIG_HW_RANDOM_PSERIES) += pseries-rng.o
obj-$(CONFIG_HW_RANDOM_POWERNV) += powernv-rng.o
+obj-$(CONFIG_HW_RANDOM_STARFIVE_VIC) += starfive-vic-rng.o
obj-$(CONFIG_HW_RANDOM_HISI) += hisi-rng.o
obj-$(CONFIG_HW_RANDOM_HISTB) += histb-rng.o
obj-$(CONFIG_HW_RANDOM_BCM2835) += bcm2835-rng.o
--- /dev/null
+++ b/drivers/char/hw_random/starfive-vic-rng.c
@@ -0,0 +1,256 @@
+/*
+ ******************************************************************************
+ * @file starfive-vic-rng.c
+ * @author StarFive Technology
+ * @version V1.0
+ * @date 08/13/2020
+ * @brief
+ ******************************************************************************
+ * @copy
+ *
+ * THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+ * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+ * TIME. AS A RESULT, STARFIVE SHALL NOT BE HELD LIABLE FOR ANY
+ * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+ * FROM THE CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+ * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+ *
+ * COPYRIGHT 2020 Shanghai StarFive Technology Co., Ltd.
+ */
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <linux/hw_random.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/random.h>
+
+#include "starfive-vic-rng.h"
+
+#define to_vic_rng(p) container_of(p, struct vic_rng, rng)
+
+struct vic_rng {
+ struct device *dev;
+ void __iomem *base;
+ struct hwrng rng;
+};
+
+static inline void vic_wait_till_idle(struct vic_rng *hrng)
+{
+ while(readl(hrng->base + VIC_STAT) & VIC_STAT_BUSY)
+ ;
+}
+
+static inline void vic_rng_irq_mask_clear(struct vic_rng *hrng)
+{
+ // clear register: ISTAT
+ u32 data = readl(hrng->base + VIC_ISTAT);
+ writel(data, hrng->base + VIC_ISTAT);
+ writel(0, hrng->base + VIC_ALARM);
+}
+
+static int vic_trng_cmd(struct vic_rng *hrng, u32 cmd) {
+ int res = 0;
+ // wait till idle
+ vic_wait_till_idle(hrng);
+ switch (cmd) {
+ case VIC_CTRL_CMD_NOP:
+ case VIC_CTRL_CMD_GEN_NOISE:
+ case VIC_CTRL_CMD_GEN_NONCE:
+ case VIC_CTRL_CMD_CREATE_STATE:
+ case VIC_CTRL_CMD_RENEW_STATE:
+ case VIC_CTRL_CMD_REFRESH_ADDIN:
+ case VIC_CTRL_CMD_GEN_RANDOM:
+ case VIC_CTRL_CMD_ADVANCE_STATE:
+ case VIC_CTRL_CMD_KAT:
+ case VIC_CTRL_CMD_ZEROIZE:
+ writel(cmd, hrng->base + VIC_CTRL);
+ break;
+ default:
+ res = -1;
+ break;
+ }
+
+ return res;
+}
+
+static int vic_rng_init(struct hwrng *rng)
+{
+ struct vic_rng *hrng = to_vic_rng(rng);
+
+ // wait till idle
+
+ // clear register: ISTAT
+ vic_rng_irq_mask_clear(hrng);
+
+ // set mission mode
+ writel(VIC_SMODE_SECURE_EN(1), hrng->base + VIC_SMODE);
+
+ vic_trng_cmd(hrng, VIC_CTRL_CMD_GEN_NOISE);
+ vic_wait_till_idle(hrng);
+
+ // set interrupt
+ writel(VIC_IE_ALL, hrng->base + VIC_IE);
+
+ // zeroize
+ vic_trng_cmd(hrng, VIC_CTRL_CMD_ZEROIZE);
+
+ vic_wait_till_idle(hrng);
+
+ return 0;
+}
+
+static irqreturn_t vic_rng_irq(int irq, void *priv)
+{
+ u32 status, val;
+ struct vic_rng *hrng = (struct vic_rng *)priv;
+
+ /*
+ * clearing the interrupt will also clear the error register
+ * read error and status before clearing
+ */
+ status = readl(hrng->base + VIC_ISTAT);
+
+ if (status & VIC_ISTAT_ALARMS) {
+ writel(VIC_ISTAT_ALARMS, hrng->base + VIC_ISTAT);
+ val = readl(hrng->base + VIC_ALARM);
+ if (val & VIC_ALARM_ILLEGAL_CMD_SEQ) {
+ writel(VIC_ALARM_ILLEGAL_CMD_SEQ, hrng->base + VIC_ALARM);
+ //dev_info(hrng->dev, "ILLEGAL CMD SEQ: LAST_CMD=0x%x\r\n",
+ //VIC_STAT_LAST_CMD(readl(hrng->base + VIC_STAT)));
+ } else {
+ dev_info(hrng->dev, "Failed test: %x\r\n", val);
+ }
+ }
+
+ if (status & VIC_ISTAT_ZEROIZE) {
+ writel(VIC_ISTAT_ZEROIZE, hrng->base + VIC_ISTAT);
+ //dev_info(hrng->dev, "zeroized\r\n");
+ }
+
+ if (status & VIC_ISTAT_KAT_COMPLETE) {
+ writel(VIC_ISTAT_KAT_COMPLETE, hrng->base + VIC_ISTAT);
+ //dev_info(hrng->dev, "kat_completed\r\n");
+ }
+
+ if (status & VIC_ISTAT_NOISE_RDY) {
+ writel(VIC_ISTAT_NOISE_RDY, hrng->base + VIC_ISTAT);
+ //dev_info(hrng->dev, "noise_rdy\r\n");
+ }
+
+ if (status & VIC_ISTAT_DONE) {
+ writel(VIC_ISTAT_DONE, hrng->base + VIC_ISTAT);
+ //dev_info(hrng->dev, "done\r\n");
+ /*
+ if (VIC_STAT_LAST_CMD(readl(hrng->base + VIC_STAT)) ==
+ VIC_CTRL_CMD_GEN_RANDOM) {
+ dev_info(hrng->dev, "Need Update Buffer\r\n");
+ }
+ */
+ }
+ vic_rng_irq_mask_clear(hrng);
+
+ return IRQ_HANDLED;
+}
+
+static void vic_rng_cleanup(struct hwrng *rng)
+{
+ struct vic_rng *hrng = to_vic_rng(rng);
+
+ writel(0, hrng->base + VIC_CTRL);
+}
+
+static int vic_rng_read(struct hwrng *rng, void *buf, size_t max, bool wait)
+{
+ struct vic_rng *hrng = to_vic_rng(rng);
+
+ vic_trng_cmd(hrng, VIC_CTRL_CMD_ZEROIZE);
+ vic_trng_cmd(hrng, VIC_CTRL_CMD_GEN_NOISE);
+ vic_trng_cmd(hrng, VIC_CTRL_CMD_CREATE_STATE);
+
+ vic_wait_till_idle(hrng);
+ max = min_t(size_t, max, (VIC_RAND_LEN * 4));
+
+ writel(0x0, hrng->base + VIC_MODE);
+ vic_trng_cmd(hrng, VIC_CTRL_CMD_GEN_RANDOM);
+
+ vic_wait_till_idle(hrng);
+ memcpy_fromio(buf, hrng->base + VIC_RAND0, max);
+ vic_trng_cmd(hrng, VIC_CTRL_CMD_ZEROIZE);
+
+ vic_wait_till_idle(hrng);
+ return max;
+}
+
+static int vic_rng_probe(struct platform_device *pdev)
+{
+ int ret;
+ int irq;
+ struct vic_rng *rng;
+ struct resource *res;
+
+ rng = devm_kzalloc(&pdev->dev, sizeof(*rng), GFP_KERNEL);
+ if (!rng){
+ return -ENOMEM;
+ }
+
+ platform_set_drvdata(pdev, rng);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ rng->base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(rng->base)){
+ return PTR_ERR(rng->base);
+ }
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq <= 0) {
+ dev_err(&pdev->dev, "Couldn't get irq %d\n", irq);
+ return irq;
+ }
+
+ ret = devm_request_irq(&pdev->dev, irq, vic_rng_irq, 0, pdev->name,
+ (void *)rng);
+ if (ret) {
+ dev_err(&pdev->dev, "Can't get interrupt working.\n");
+ return ret;
+ }
+
+ rng->rng.name = pdev->name;
+ rng->rng.init = vic_rng_init;
+ rng->rng.cleanup = vic_rng_cleanup;
+ rng->rng.read = vic_rng_read;
+
+ rng->dev = &pdev->dev;
+
+ ret = devm_hwrng_register(&pdev->dev, &rng->rng);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to register hwrng\n");
+ return ret;
+ }
+
+ dev_info(&pdev->dev, "Initialized\n");
+
+ return 0;
+}
+
+static const struct of_device_id vic_rng_dt_ids[] = {
+ { .compatible = "starfive,vic-rng" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, vic_rng_dt_ids);
+
+static struct platform_driver vic_rng_driver = {
+ .probe = vic_rng_probe,
+ .driver = {
+ .name = "vic-rng",
+ .of_match_table = vic_rng_dt_ids,
+ },
+};
+
+module_platform_driver(vic_rng_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Huan Feng <huan.feng@starfivetech.com>");
+MODULE_DESCRIPTION("Starfive VIC random number generator driver");
--- /dev/null
+++ b/drivers/char/hw_random/starfive-vic-rng.h
@@ -0,0 +1,167 @@
+/*
+ ******************************************************************************
+ * @file starfive-vic-rng.h
+ * @author StarFive Technology
+ * @version V1.0
+ * @date 08/13/2020
+ * @brief
+ ******************************************************************************
+ * @copy
+ *
+ * THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+ * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+ * TIME. AS A RESULT, STARFIVE SHALL NOT BE HELD LIABLE FOR ANY
+ * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+ * FROM THE CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+ * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+ *
+ * COPYRIGHT 2020 Shanghai StarFive Technology Co., Ltd.
+ */
+
+#define VIC_CTRL 0x00
+#define VIC_MODE 0x04
+#define VIC_SMODE 0x08
+#define VIC_STAT 0x0C
+#define VIC_IE 0x10
+#define VIC_ISTAT 0x14
+#define VIC_ALARM 0x18
+#define VIC_BUILD_ID 0x1C
+#define VIC_FEATURES 0x20
+#define VIC_RAND0 0x24
+#define VIC_NPA_DATA0 0x34
+#define VIC_SEED0 0x74
+#define VIC_IA_RDATA 0xA4
+#define VIC_IA_WDATA 0xA8
+#define VIC_IA_ADDR 0xAC
+#define VIC_IA_CMD 0xB0
+
+/* CTRL */
+#define VIC_CTRL_CMD_NOP 0
+#define VIC_CTRL_CMD_GEN_NOISE 1
+#define VIC_CTRL_CMD_GEN_NONCE 2
+#define VIC_CTRL_CMD_CREATE_STATE 3
+#define VIC_CTRL_CMD_RENEW_STATE 4
+#define VIC_CTRL_CMD_REFRESH_ADDIN 5
+#define VIC_CTRL_CMD_GEN_RANDOM 6
+#define VIC_CTRL_CMD_ADVANCE_STATE 7
+#define VIC_CTRL_CMD_KAT 8
+#define VIC_CTRL_CMD_ZEROIZE 15
+
+/* MODE */
+#define _VIC_MODE_ADDIN_PRESENT 4
+#define _VIC_MODE_PRED_RESIST 3
+#define _VIC_MODE_KAT_SEL 2
+#define _VIC_MODE_KAT_VEC 1
+#define _VIC_MODE_SEC_ALG 0
+
+#define VIC_MODE_ADDIN_PRESENT (1UL << _VIC_MODE_ADDIN_PRESENT)
+#define VIC_MODE_PRED_RESIST (1UL << _VIC_MODE_PRED_RESIST)
+#define VIC_MODE_KAT_SEL (1UL << _VIC_MODE_KAT_SEL)
+#define VIC_MODE_KAT_VEC (1UL << _VIC_MODE_KAT_VEC)
+#define VIC_MODE_SEC_ALG (1UL << _VIC_MODE_SEC_ALG)
+
+/* SMODE */
+#define _VIC_SMODE_MAX_REJECTS 2
+#define _VIC_SMODE_SECURE_EN 1
+#define _VIC_SMODE_NONCE 0
+
+#define VIC_SMODE_MAX_REJECTS(x) ((x) << _VIC_SMODE_MAX_REJECTS)
+#define VIC_SMODE_SECURE_EN(x) ((x) << _VIC_SMODE_SECURE_EN)
+#define VIC_SMODE_NONCE (1UL << _VIC_SMODE_NONCE)
+
+/* STAT */
+#define _VIC_STAT_BUSY 31
+#define _VIC_STAT_DRBG_STATE 7
+#define _VIC_STAT_SECURE 6
+#define _VIC_STAT_NONCE_MODE 5
+#define _VIC_STAT_SEC_ALG 4
+#define _VIC_STAT_LAST_CMD 0
+
+#define VIC_STAT_BUSY (1UL << _VIC_STAT_BUSY)
+#define VIC_STAT_DRBG_STATE (1UL << _VIC_STAT_DRBG_STATE)
+#define VIC_STAT_SECURE (1UL << _VIC_STAT_SECURE)
+#define VIC_STAT_NONCE_MODE (1UL << _VIC_STAT_NONCE_MODE)
+#define VIC_STAT_SEC_ALG (1UL << _VIC_STAT_SEC_ALG)
+#define VIC_STAT_LAST_CMD(x) (((x) >> _VIC_STAT_LAST_CMD) & 0xF)
+
+/* IE */
+#define _VIC_IE_GLBL 31
+#define _VIC_IE_DONE 4
+#define _VIC_IE_ALARMS 3
+#define _VIC_IE_NOISE_RDY 2
+#define _VIC_IE_KAT_COMPLETE 1
+#define _VIC_IE_ZEROIZE 0
+
+#define VIC_IE_GLBL (1UL << _VIC_IE_GLBL)
+#define VIC_IE_DONE (1UL << _VIC_IE_DONE)
+#define VIC_IE_ALARMS (1UL << _VIC_IE_ALARMS)
+#define VIC_IE_NOISE_RDY (1UL << _VIC_IE_NOISE_RDY)
+#define VIC_IE_KAT_COMPLETE (1UL << _VIC_IE_KAT_COMPLETE)
+#define VIC_IE_ZEROIZE (1UL << _VIC_IE_ZEROIZE)
+#define VIC_IE_ALL (VIC_IE_GLBL | VIC_IE_DONE | VIC_IE_ALARMS | \
+ VIC_IE_NOISE_RDY | VIC_IE_KAT_COMPLETE | VIC_IE_ZEROIZE)
+
+/* ISTAT */
+#define _VIC_ISTAT_DONE 4
+#define _VIC_ISTAT_ALARMS 3
+#define _VIC_ISTAT_NOISE_RDY 2
+#define _VIC_ISTAT_KAT_COMPLETE 1
+#define _VIC_ISTAT_ZEROIZE 0
+
+#define VIC_ISTAT_DONE (1UL << _VIC_ISTAT_DONE)
+#define VIC_ISTAT_ALARMS (1UL << _VIC_ISTAT_ALARMS)
+#define VIC_ISTAT_NOISE_RDY (1UL << _VIC_ISTAT_NOISE_RDY)
+#define VIC_ISTAT_KAT_COMPLETE (1UL << _VIC_ISTAT_KAT_COMPLETE)
+#define VIC_ISTAT_ZEROIZE (1UL << _VIC_ISTAT_ZEROIZE)
+
+/* ALARMS */
+#define VIC_ALARM_ILLEGAL_CMD_SEQ (1UL << 4)
+#define VIC_ALARM_FAILED_TEST_ID_OK 0
+#define VIC_ALARM_FAILED_TEST_ID_KAT_STAT 1
+#define VIC_ALARM_FAILED_TEST_ID_KAT 2
+#define VIC_ALARM_FAILED_TEST_ID_MONOBIT 3
+#define VIC_ALARM_FAILED_TEST_ID_RUN 4
+#define VIC_ALARM_FAILED_TEST_ID_LONGRUN 5
+#define VIC_ALARM_FAILED_TEST_ID_AUTOCORRELATION 6
+#define VIC_ALARM_FAILED_TEST_ID_POKER 7
+#define VIC_ALARM_FAILED_TEST_ID_REPETITION_COUNT 8
+#define VIC_ALARM_FAILED_TEST_ID_ADAPATIVE_PROPORTION 9
+
+/* BUILD_ID */
+#define VIC_BUILD_ID_STEPPING(x) (((x) >> 28) & 0xF)
+#define VIC_BUILD_ID_EPN(x) ((x) & 0xFFFF)
+
+/* FEATURES */
+#define VIC_FEATURES_AES_256(x) (((x) >> 9) & 1)
+#define VIC_FEATURES_EXTRA_PS_PRESENT(x) (((x) >> 8) & 1)
+#define VIC_FEATURES_DIAG_LEVEL_NS(x) (((x) >> 7) & 1)
+#define VIC_FEATURES_DIAG_LEVEL_CLP800(x) (((x) >> 4) & 7)
+#define VIC_FEATURES_DIAG_LEVEL_ST_HLT(x) (((x) >> 1) & 7)
+#define VIC_FEATURES_SECURE_RST_STATE(x) ((x) & 1)
+
+/* IA_CMD */
+#define VIC_IA_CMD_GO (1UL << 31)
+#define VIC_IA_CMD_WR (1)
+
+#define _VIC_SMODE_MAX_REJECTS_MASK 255UL
+#define _VIC_SMODE_SECURE_EN_MASK 1UL
+#define _VIC_SMODE_NONCE_MASK 1UL
+#define _VIC_MODE_SEC_ALG_MASK 1UL
+#define _VIC_MODE_ADDIN_PRESENT_MASK 1UL
+#define _VIC_MODE_PRED_RESIST_MASK 1UL
+
+#define VIC_SMODE_SET_MAX_REJECTS(y, x) (((y) & ~(_VIC_SMODE_MAX_REJECTS_MASK << _VIC_SMODE_MAX_REJECTS)) | ((x) << _VIC_SMODE_MAX_REJECTS))
+#define VIC_SMODE_SET_SECURE_EN(y, x) (((y) & ~(_VIC_SMODE_SECURE_EN_MASK << _VIC_SMODE_SECURE_EN)) | ((x) << _VIC_SMODE_SECURE_EN))
+#define VIC_SMODE_SET_NONCE(y, x) (((y) & ~(_VIC_SMODE_NONCE_MASK << _VIC_SMODE_NONCE)) | ((x) << _VIC_SMODE_NONCE))
+#define VIC_SMODE_GET_MAX_REJECTS(x) (((x) >> _VIC_SMODE_MAX_REJECTS) & _VIC_SMODE_MAX_REJECTS_MASK)
+#define VIC_SMODE_GET_SECURE_EN(x) (((x) >> _VIC_SMODE_SECURE_EN) & _VIC_SMODE_SECURE_EN_MASK)
+#define VIC_SMODE_GET_NONCE(x) (((x) >> _VIC_SMODE_NONCE) & _VIC_SMODE_NONCE_MASK)
+
+#define VIC_MODE_SET_SEC_ALG(y, x) (((y) & ~(_VIC_MODE_SEC_ALG_MASK << _VIC_MODE_SEC_ALG)) | ((x) << _VIC_MODE_SEC_ALG))
+#define VIC_MODE_SET_PRED_RESIST(y, x) (((y) & ~(_VIC_MODE_PRED_RESIST_MASK << _VIC_MODE_PRED_RESIST)) | ((x) << _VIC_MODE_PRED_RESIST))
+#define VIC_MODE_SET_ADDIN_PRESENT(y, x) (((y) & ~(_VIC_MODE_ADDIN_PRESENT_MASK << _VIC_MODE_ADDIN_PRESENT)) | ((x) << _VIC_MODE_ADDIN_PRESENT))
+#define VIC_MODE_GET_SEC_ALG(x) (((x) >> _VIC_MODE_SEC_ALG) & _VIC_MODE_SEC_ALG_MASK)
+#define VIC_MODE_GET_PRED_RESIST(x) (((x) >> _VIC_MODE_PRED_RESIST) & _VIC_MODE_PRED_RESIST_MASK)
+#define VIC_MODE_GET_ADDIN_PRESENT(x) (((x) >> _VIC_MODE_ADDIN_PRESENT) & _VIC_MODE_ADDIN_PRESENT_MASK)
+
+#define VIC_RAND_LEN 4

View File

@ -0,0 +1,119 @@
From d3bef81bd427caf4cbf7ecef64f0268a6ac8ce52 Mon Sep 17 00:00:00 2001
From: Emil Renner Berthing <emil.renner.berthing@canonical.com>
Date: Sat, 22 Jul 2023 15:59:02 +0200
Subject: [PATCH 1016/1021] usb: cdns3: starfive: Simplify mode init
The syscon regmap and offset to the USB mode register is only used at
probe time, so there is no need to store it in the device data. Just get
the regmap pointer in the cdns_mode_init() function where it is needed.
Also this function never uses the platform device, so just pass the
device pointer directly.
Signed-off-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
---
drivers/usb/cdns3/cdns3-starfive.c | 51 ++++++++++++------------------
1 file changed, 21 insertions(+), 30 deletions(-)
--- a/drivers/usb/cdns3/cdns3-starfive.c
+++ b/drivers/usb/cdns3/cdns3-starfive.c
@@ -34,46 +34,45 @@
struct cdns_starfive {
struct device *dev;
- struct regmap *stg_syscon;
struct reset_control *resets;
struct clk_bulk_data *clks;
int num_clks;
- u32 stg_usb_mode;
};
-static void cdns_mode_init(struct platform_device *pdev,
- struct cdns_starfive *data)
+static int cdns_mode_init(struct device *dev, struct cdns_starfive *data)
{
+ struct regmap *syscon;
+ unsigned int usb_mode;
enum usb_dr_mode mode;
- regmap_update_bits(data->stg_syscon, data->stg_usb_mode,
+ syscon = syscon_regmap_lookup_by_phandle_args(dev->of_node,
+ "starfive,stg-syscon", 1, &usb_mode);
+ if (IS_ERR(syscon))
+ return dev_err_probe(dev, PTR_ERR(syscon),
+ "Failed to parse starfive,stg-syscon\n");
+
+ regmap_update_bits(syscon, usb_mode,
USB_MISC_CFG_MASK,
USB_SUSPENDM_BYPS | USB_PLL_EN | USB_REFCLK_MODE);
/* dr mode setting */
- mode = usb_get_dr_mode(&pdev->dev);
+ mode = usb_get_dr_mode(dev);
switch (mode) {
case USB_DR_MODE_HOST:
- regmap_update_bits(data->stg_syscon,
- data->stg_usb_mode,
- USB_STRAP_MASK,
- USB_STRAP_HOST);
- regmap_update_bits(data->stg_syscon,
- data->stg_usb_mode,
- USB_SUSPENDM_MASK,
- USB_SUSPENDM_HOST);
+ regmap_update_bits(syscon, usb_mode, USB_STRAP_MASK, USB_STRAP_HOST);
+ regmap_update_bits(syscon, usb_mode, USB_SUSPENDM_MASK, USB_SUSPENDM_HOST);
break;
case USB_DR_MODE_PERIPHERAL:
- regmap_update_bits(data->stg_syscon, data->stg_usb_mode,
- USB_STRAP_MASK, USB_STRAP_DEVICE);
- regmap_update_bits(data->stg_syscon, data->stg_usb_mode,
- USB_SUSPENDM_MASK, 0);
+ regmap_update_bits(syscon, usb_mode, USB_STRAP_MASK, USB_STRAP_DEVICE);
+ regmap_update_bits(syscon, usb_mode, USB_SUSPENDM_MASK, 0);
break;
default:
break;
}
+
+ return 0;
}
static int cdns_clk_rst_init(struct cdns_starfive *data)
@@ -108,7 +107,6 @@ static int cdns_starfive_probe(struct pl
{
struct device *dev = &pdev->dev;
struct cdns_starfive *data;
- unsigned int args;
int ret;
data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
@@ -117,16 +115,6 @@ static int cdns_starfive_probe(struct pl
data->dev = dev;
- data->stg_syscon =
- syscon_regmap_lookup_by_phandle_args(pdev->dev.of_node,
- "starfive,stg-syscon", 1, &args);
-
- if (IS_ERR(data->stg_syscon))
- return dev_err_probe(dev, PTR_ERR(data->stg_syscon),
- "Failed to parse starfive,stg-syscon\n");
-
- data->stg_usb_mode = args;
-
data->num_clks = devm_clk_bulk_get_all(data->dev, &data->clks);
if (data->num_clks < 0)
return dev_err_probe(data->dev, -ENODEV,
@@ -137,7 +125,10 @@ static int cdns_starfive_probe(struct pl
return dev_err_probe(data->dev, PTR_ERR(data->resets),
"Failed to get resets");
- cdns_mode_init(pdev, data);
+ ret = cdns_mode_init(dev, data);
+ if (ret)
+ return ret;
+
ret = cdns_clk_rst_init(data);
if (ret)
return ret;

View File

@ -0,0 +1,126 @@
From 38b62b73015e3c843ff05400cd972683a7f3af04 Mon Sep 17 00:00:00 2001
From: Emil Renner Berthing <emil.renner.berthing@canonical.com>
Date: Sat, 22 Jul 2023 16:18:24 +0200
Subject: [PATCH 1017/1021] usb: cdns3: starfive: Don't store device
backpointer
Signed-off-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
---
drivers/usb/cdns3/cdns3-starfive.c | 37 ++++++++++++------------------
1 file changed, 15 insertions(+), 22 deletions(-)
--- a/drivers/usb/cdns3/cdns3-starfive.c
+++ b/drivers/usb/cdns3/cdns3-starfive.c
@@ -33,7 +33,6 @@
#define USB_REFCLK_MODE BIT(23)
struct cdns_starfive {
- struct device *dev;
struct reset_control *resets;
struct clk_bulk_data *clks;
int num_clks;
@@ -49,7 +48,7 @@ static int cdns_mode_init(struct device
"starfive,stg-syscon", 1, &usb_mode);
if (IS_ERR(syscon))
return dev_err_probe(dev, PTR_ERR(syscon),
- "Failed to parse starfive,stg-syscon\n");
+ "failed to parse starfive,stg-syscon\n");
regmap_update_bits(syscon, usb_mode,
USB_MISC_CFG_MASK,
@@ -75,18 +74,17 @@ static int cdns_mode_init(struct device
return 0;
}
-static int cdns_clk_rst_init(struct cdns_starfive *data)
+static int cdns_clk_rst_init(struct device *dev, struct cdns_starfive *data)
{
int ret;
ret = clk_bulk_prepare_enable(data->num_clks, data->clks);
if (ret)
- return dev_err_probe(data->dev, ret,
- "failed to enable clocks\n");
+ return dev_err_probe(dev, ret, "failed to enable clocks\n");
ret = reset_control_deassert(data->resets);
if (ret) {
- dev_err(data->dev, "failed to reset clocks\n");
+ dev_err(dev, "failed to reset clocks\n");
goto err_clk_init;
}
@@ -97,7 +95,7 @@ err_clk_init:
return ret;
}
-static void cdns_clk_rst_deinit(struct cdns_starfive *data)
+static void cdns_clk_rst_deinit(struct device *dev, struct cdns_starfive *data)
{
reset_control_assert(data->resets);
clk_bulk_disable_unprepare(data->num_clks, data->clks);
@@ -113,31 +111,26 @@ static int cdns_starfive_probe(struct pl
if (!data)
return -ENOMEM;
- data->dev = dev;
-
- data->num_clks = devm_clk_bulk_get_all(data->dev, &data->clks);
+ data->num_clks = devm_clk_bulk_get_all(dev, &data->clks);
if (data->num_clks < 0)
- return dev_err_probe(data->dev, -ENODEV,
- "Failed to get clocks\n");
+ return dev_err_probe(dev, -ENODEV, "failed to get clocks\n");
- data->resets = devm_reset_control_array_get_exclusive(data->dev);
+ data->resets = devm_reset_control_array_get_exclusive(dev);
if (IS_ERR(data->resets))
- return dev_err_probe(data->dev, PTR_ERR(data->resets),
- "Failed to get resets");
+ return dev_err_probe(dev, PTR_ERR(data->resets), "failed to get resets\n");
ret = cdns_mode_init(dev, data);
if (ret)
return ret;
- ret = cdns_clk_rst_init(data);
+ ret = cdns_clk_rst_init(dev, data);
if (ret)
return ret;
ret = of_platform_populate(dev->of_node, NULL, NULL, dev);
if (ret) {
- dev_err(dev, "Failed to create children\n");
- cdns_clk_rst_deinit(data);
- return ret;
+ cdns_clk_rst_deinit(dev, data);
+ return dev_err_probe(dev, ret, "failed to create children\n");
}
device_set_wakeup_capable(dev, true);
@@ -167,7 +160,7 @@ static void cdns_starfive_remove(struct
pm_runtime_disable(dev);
pm_runtime_put_noidle(dev);
- cdns_clk_rst_deinit(data);
+ cdns_clk_rst_deinit(dev, data);
platform_set_drvdata(pdev, NULL);
}
@@ -193,14 +186,14 @@ static int cdns_starfive_resume(struct d
{
struct cdns_starfive *data = dev_get_drvdata(dev);
- return cdns_clk_rst_init(data);
+ return cdns_clk_rst_init(dev, data);
}
static int cdns_starfive_suspend(struct device *dev)
{
struct cdns_starfive *data = dev_get_drvdata(dev);
- cdns_clk_rst_deinit(data);
+ cdns_clk_rst_deinit(dev, data);
return 0;
}

View File

@ -0,0 +1,113 @@
From eae127ccbe02ba20e4eb86081268205f7f40b8fc Mon Sep 17 00:00:00 2001
From: Emil Renner Berthing <emil.renner.berthing@canonical.com>
Date: Sat, 22 Jul 2023 16:21:04 +0200
Subject: [PATCH 1018/1021] usb: cdns3: starfive: Add StarFive JH7100 support
Signed-off-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
---
drivers/usb/cdns3/cdns3-starfive.c | 46 ++++++++++++++++++------------
1 file changed, 28 insertions(+), 18 deletions(-)
--- a/drivers/usb/cdns3/cdns3-starfive.c
+++ b/drivers/usb/cdns3/cdns3-starfive.c
@@ -20,17 +20,17 @@
#include <linux/usb/otg.h>
#include "core.h"
-#define USB_STRAP_HOST BIT(17)
-#define USB_STRAP_DEVICE BIT(18)
-#define USB_STRAP_MASK GENMASK(18, 16)
-
-#define USB_SUSPENDM_HOST BIT(19)
-#define USB_SUSPENDM_MASK BIT(19)
-
-#define USB_MISC_CFG_MASK GENMASK(23, 20)
-#define USB_SUSPENDM_BYPS BIT(20)
-#define USB_PLL_EN BIT(22)
-#define USB_REFCLK_MODE BIT(23)
+#define JH7110_STRAP_HOST BIT(17)
+#define JH7110_STRAP_DEVICE BIT(18)
+#define JH7110_STRAP_MASK GENMASK(18, 16)
+
+#define JH7110_SUSPENDM_HOST BIT(19)
+#define JH7110_SUSPENDM_MASK BIT(19)
+
+#define JH7110_MISC_CFG_MASK GENMASK(23, 20)
+#define JH7110_SUSPENDM_BYPS BIT(20)
+#define JH7110_PLL_EN BIT(22)
+#define JH7110_REFCLK_MODE BIT(23)
struct cdns_starfive {
struct reset_control *resets;
@@ -38,7 +38,14 @@ struct cdns_starfive {
int num_clks;
};
-static int cdns_mode_init(struct device *dev, struct cdns_starfive *data)
+typedef int (cdns_starfive_mode_init_t)(struct device *dev, struct cdns_starfive *data);
+
+static int cdns_jh7100_mode_init(struct device *dev, struct cdns_starfive *data)
+{
+ return 0;
+}
+
+static int cdns_jh7110_mode_init(struct device *dev, struct cdns_starfive *data)
{
struct regmap *syscon;
unsigned int usb_mode;
@@ -51,21 +58,21 @@ static int cdns_mode_init(struct device
"failed to parse starfive,stg-syscon\n");
regmap_update_bits(syscon, usb_mode,
- USB_MISC_CFG_MASK,
- USB_SUSPENDM_BYPS | USB_PLL_EN | USB_REFCLK_MODE);
+ JH7110_MISC_CFG_MASK,
+ JH7110_SUSPENDM_BYPS | JH7110_PLL_EN | JH7110_REFCLK_MODE);
/* dr mode setting */
mode = usb_get_dr_mode(dev);
switch (mode) {
case USB_DR_MODE_HOST:
- regmap_update_bits(syscon, usb_mode, USB_STRAP_MASK, USB_STRAP_HOST);
- regmap_update_bits(syscon, usb_mode, USB_SUSPENDM_MASK, USB_SUSPENDM_HOST);
+ regmap_update_bits(syscon, usb_mode, JH7110_STRAP_MASK, JH7110_STRAP_HOST);
+ regmap_update_bits(syscon, usb_mode, JH7110_SUSPENDM_MASK, JH7110_SUSPENDM_HOST);
break;
case USB_DR_MODE_PERIPHERAL:
- regmap_update_bits(syscon, usb_mode, USB_STRAP_MASK, USB_STRAP_DEVICE);
- regmap_update_bits(syscon, usb_mode, USB_SUSPENDM_MASK, 0);
+ regmap_update_bits(syscon, usb_mode, JH7110_STRAP_MASK, JH7110_STRAP_DEVICE);
+ regmap_update_bits(syscon, usb_mode, JH7110_SUSPENDM_MASK, 0);
break;
default:
break;
@@ -105,6 +112,7 @@ static int cdns_starfive_probe(struct pl
{
struct device *dev = &pdev->dev;
struct cdns_starfive *data;
+ cdns_starfive_mode_init_t *mode_init;
int ret;
data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
@@ -119,7 +127,8 @@ static int cdns_starfive_probe(struct pl
if (IS_ERR(data->resets))
return dev_err_probe(dev, PTR_ERR(data->resets), "failed to get resets\n");
- ret = cdns_mode_init(dev, data);
+ mode_init = device_get_match_data(dev);
+ ret = mode_init(dev, data);
if (ret)
return ret;
@@ -207,7 +216,8 @@ static const struct dev_pm_ops cdns_star
};
static const struct of_device_id cdns_starfive_of_match[] = {
- { .compatible = "starfive,jh7110-usb", },
+ { .compatible = "starfive,jh7100-usb", .data = cdns_jh7100_mode_init },
+ { .compatible = "starfive,jh7110-usb", .data = cdns_jh7110_mode_init },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, cdns_starfive_of_match);

View File

@ -0,0 +1,60 @@
From e73da6a4dc3f127d45e26d68ee051199c1fc2bb9 Mon Sep 17 00:00:00 2001
From: Emil Renner Berthing <emil.renner.berthing@canonical.com>
Date: Sat, 22 Jul 2023 16:36:17 +0200
Subject: [PATCH 1019/1021] riscv: dts: starfive: Add JH7100 USB node
Add the device tree node for the USB 3.0 peripheral on the
StarFive JH7100 SoC.
Signed-off-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
---
.../boot/dts/starfive/jh7100-common.dtsi | 5 ++++
arch/riscv/boot/dts/starfive/jh7100.dtsi | 26 +++++++++++++++++++
2 files changed, 31 insertions(+)
--- a/arch/riscv/boot/dts/starfive/jh7100-common.dtsi
+++ b/arch/riscv/boot/dts/starfive/jh7100-common.dtsi
@@ -447,3 +447,8 @@
pinctrl-0 = <&uart3_pins>;
status = "okay";
};
+
+&usb3 {
+ dr_mode = "host";
+ status = "okay";
+};
--- a/arch/riscv/boot/dts/starfive/jh7100.dtsi
+++ b/arch/riscv/boot/dts/starfive/jh7100.dtsi
@@ -255,6 +255,32 @@
#reset-cells = <1>;
};
+ usb3: usb@104c0000 {
+ compatible = "starfive,jh7100-usb";
+ ranges = <0x0 0x0 0x104c0000 0x100000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ clocks = <&audclk JH7100_AUDCLK_USB_LPM>,
+ <&audclk JH7100_AUDCLK_USB_STB>,
+ <&clkgen JH7100_CLK_USB_AXI>,
+ <&clkgen JH7100_CLK_USBNOC_AXI>;
+ clock-names = "lpm", "stb", "axi", "nocaxi";
+ resets = <&rstgen JH7100_RSTN_USB_AXI>,
+ <&rstgen JH7100_RSTN_USBNOC_AXI>;
+ reset-names = "axi", "nocaxi";
+ status = "disabled";
+
+ usb_cdns3: usb@0 {
+ compatible = "cdns,usb3";
+ reg = <0x00000 0x10000>,
+ <0x10000 0x10000>,
+ <0x20000 0x10000>;
+ reg-names = "otg", "xhci", "dev";
+ interrupts = <44>, <52>, <43>;
+ interrupt-names = "host", "peripheral", "otg";
+ };
+ };
+
clkgen: clock-controller@11800000 {
compatible = "starfive,jh7100-clkgen";
reg = <0x0 0x11800000 0x0 0x10000>;

View File

@ -0,0 +1,103 @@
From 8deff65d2d7ffea00231ec592d956aebf7de0852 Mon Sep 17 00:00:00 2001
From: Emil Renner Berthing <emil.renner.berthing@canonical.com>
Date: Sat, 22 Jul 2023 18:50:49 +0200
Subject: [PATCH 1020/1021] usb: cdns3: starfive: Initialize JH7100 host mode
These settings are directly copied from StarFive's port of u-boot
for the JH7100:
/* config strap */
_SET_SYSCON_REG_SCFG_usb0_mode_strap(0x2);
_SET_SYSCON_REG_SCFG_usb7_PLL_EN(0x1);
_SET_SYSCON_REG_SCFG_usb7_U3_EQ_EN(0x1);
_SET_SYSCON_REG_SCFG_usb7_U3_SSRX_SEL(0x1);
_SET_SYSCON_REG_SCFG_usb7_U3_SSTX_SEL(0x1);
_SET_SYSCON_REG_SCFG_usb3_utmi_iddig(0x1);
Signed-off-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
---
arch/riscv/boot/dts/starfive/jh7100.dtsi | 6 ++++
drivers/usb/cdns3/cdns3-starfive.c | 43 ++++++++++++++++++++++++
2 files changed, 49 insertions(+)
--- a/arch/riscv/boot/dts/starfive/jh7100.dtsi
+++ b/arch/riscv/boot/dts/starfive/jh7100.dtsi
@@ -255,6 +255,11 @@
#reset-cells = <1>;
};
+ sysaudio: syscon@104a0000 {
+ compatible = "starfive,jh7100-sysaudio", "syscon";
+ reg = <0x0 0x104a0000 0x0 0x10000>;
+ };
+
usb3: usb@104c0000 {
compatible = "starfive,jh7100-usb";
ranges = <0x0 0x0 0x104c0000 0x100000>;
@@ -268,6 +273,7 @@
resets = <&rstgen JH7100_RSTN_USB_AXI>,
<&rstgen JH7100_RSTN_USBNOC_AXI>;
reset-names = "axi", "nocaxi";
+ starfive,syscon = <&sysaudio>;
status = "disabled";
usb_cdns3: usb@0 {
--- a/drivers/usb/cdns3/cdns3-starfive.c
+++ b/drivers/usb/cdns3/cdns3-starfive.c
@@ -20,6 +20,19 @@
#include <linux/usb/otg.h>
#include "core.h"
+#define JH7100_USB0 0x20
+#define JH7100_USB0_MODE_STRAP_MASK GENMASK(2, 0)
+#define JH7100_USB0_MODE_STRAP_HOST 2
+
+#define JH7100_USB3 0x2c
+#define JH7100_USB3_UTMI_IDDIG BIT(21)
+
+#define JH7100_USB7 0x3c
+#define JH7100_USB7_SSRX_SEL BIT(18)
+#define JH7100_USB7_SSTX_SEL BIT(19)
+#define JH7100_USB7_PLL_EN BIT(23)
+#define JH7100_USB7_EQ_EN BIT(25)
+
#define JH7110_STRAP_HOST BIT(17)
#define JH7110_STRAP_DEVICE BIT(18)
#define JH7110_STRAP_MASK GENMASK(18, 16)
@@ -42,6 +55,36 @@ typedef int (cdns_starfive_mode_init_t)(
static int cdns_jh7100_mode_init(struct device *dev, struct cdns_starfive *data)
{
+ struct regmap *syscon;
+ enum usb_dr_mode mode;
+
+ syscon = syscon_regmap_lookup_by_phandle(dev->of_node, "starfive,syscon");
+ if (IS_ERR(syscon))
+ return dev_err_probe(dev, PTR_ERR(syscon),
+ "failed to get starfive,syscon\n");
+
+ /* dr mode setting */
+ mode = usb_get_dr_mode(dev);
+
+ switch (mode) {
+ case USB_DR_MODE_HOST:
+ regmap_update_bits(syscon, JH7100_USB0,
+ JH7100_USB0_MODE_STRAP_MASK, JH7100_USB0_MODE_STRAP_HOST);
+ regmap_update_bits(syscon, JH7100_USB7,
+ JH7100_USB7_PLL_EN, JH7100_USB7_PLL_EN);
+ regmap_update_bits(syscon, JH7100_USB7,
+ JH7100_USB7_EQ_EN, JH7100_USB7_EQ_EN);
+ regmap_update_bits(syscon, JH7100_USB7,
+ JH7100_USB7_SSRX_SEL, JH7100_USB7_SSRX_SEL);
+ regmap_update_bits(syscon, JH7100_USB7,
+ JH7100_USB7_SSTX_SEL, JH7100_USB7_SSTX_SEL);
+ regmap_update_bits(syscon, JH7100_USB3,
+ JH7100_USB3_UTMI_IDDIG, JH7100_USB3_UTMI_IDDIG);
+ break;
+ default:
+ break;
+ }
+
return 0;
}

View File

@ -0,0 +1,848 @@
From a861bf8cf26216da57b4886ecf48222e01e4fba9 Mon Sep 17 00:00:00 2001
From: Emil Renner Berthing <kernel@esmil.dk>
Date: Sun, 31 Oct 2021 17:15:58 +0100
Subject: [PATCH 1021/1021] riscv: dts: Add full JH7100, Starlight and
VisionFive support
Based on the device tree in https://github.com/starfive-tech/u-boot/
with contributions from:
yanhong.wang <yanhong.wang@starfivetech.com>
Huan.Feng <huan.feng@starfivetech.com>
ke.zhu <ke.zhu@starfivetech.com>
yiming.li <yiming.li@starfivetech.com>
jack.zhu <jack.zhu@starfivetech.com>
Samin Guo <samin.guo@starfivetech.com>
Chenjieqin <Jessica.Chen@starfivetech.com>
bo.li <bo.li@starfivetech.com>
Rearranged, cleanups, fixes, pins and resets added by Emil.
Cleanups, fixes, clocks added by Geert.
Cleanups and GPIO fixes from Drew.
Thermal zone added by Stephen.
PWM pins added by Jianlong.
cpu-map added by Jonas.
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
Signed-off-by: Stephen L Arnold <nerdboy@gentoo.org>
Signed-off-by: Drew Fustini <drew@beagleboard.org>
Signed-off-by: Jianlong Huang <jianlong.huang@starfivetech.com>
Signed-off-by: Jonas Hahnfeld <hahnjo@hahnjo.de>
Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
---
arch/riscv/boot/dts/starfive/Makefile | 2 +
.../starfive/jh7100-beaglev-starlight-a1.dts | 24 ++
.../dts/starfive/jh7100-beaglev-starlight.dts | 6 +
.../boot/dts/starfive/jh7100-common.dtsi | 177 ++++++++
.../jh7100-starfive-visionfive-v1.dts | 13 +
arch/riscv/boot/dts/starfive/jh7100.dtsi | 389 ++++++++++++++++++
6 files changed, 611 insertions(+)
create mode 100644 arch/riscv/boot/dts/starfive/jh7100-beaglev-starlight-a1.dts
--- a/arch/riscv/boot/dts/starfive/Makefile
+++ b/arch/riscv/boot/dts/starfive/Makefile
@@ -1,10 +1,12 @@
# SPDX-License-Identifier: GPL-2.0
# Enables support for device-tree overlays
+DTC_FLAGS_jh7100-beaglev-starlight-a1 := -@
DTC_FLAGS_jh7100-beaglev-starlight := -@
DTC_FLAGS_jh7100-starfive-visionfive-v1 := -@
DTC_FLAGS_jh7110-starfive-visionfive-2-v1.2a := -@
DTC_FLAGS_jh7110-starfive-visionfive-2-v1.3b := -@
+dtb-$(CONFIG_ARCH_STARFIVE) += jh7100-beaglev-starlight-a1.dtb
dtb-$(CONFIG_ARCH_STARFIVE) += jh7100-beaglev-starlight.dtb
dtb-$(CONFIG_ARCH_STARFIVE) += jh7100-starfive-visionfive-v1.dtb
--- /dev/null
+++ b/arch/riscv/boot/dts/starfive/jh7100-beaglev-starlight-a1.dts
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
+/*
+ * Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
+ */
+
+/dts-v1/;
+#include "jh7100-common.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ model = "BeagleV Starlight Beta A1";
+ compatible = "beagle,beaglev-starlight-jh7100-a1", "starfive,jh7100";
+
+ gpio-restart {
+ compatible = "gpio-restart";
+ gpios = <&gpio 63 GPIO_ACTIVE_HIGH>;
+ priority = <224>;
+ };
+};
+
+&gpio {
+ /* don't reset gpio mux for serial console and reset gpio */
+ starfive,keep-gpiomux = <13 14 63>;
+};
--- a/arch/riscv/boot/dts/starfive/jh7100-beaglev-starlight.dts
+++ b/arch/riscv/boot/dts/starfive/jh7100-beaglev-starlight.dts
@@ -6,6 +6,7 @@
/dts-v1/;
#include "jh7100-common.dtsi"
+#include <dt-bindings/gpio/gpio.h>
/ {
model = "BeagleV Starlight Beta";
@@ -16,6 +17,11 @@
phy-handle = <&phy>;
};
+&gpio {
+ /* don't reset gpio mux for serial console on uart3 */
+ starfive,keep-gpiomux = <13 14>;
+};
+
&mdio {
phy: ethernet-phy@7 {
reg = <7>;
--- a/arch/riscv/boot/dts/starfive/jh7100-common.dtsi
+++ b/arch/riscv/boot/dts/starfive/jh7100-common.dtsi
@@ -15,6 +15,7 @@
mmc0 = &sdio0;
mmc1 = &sdio1;
serial0 = &uart3;
+ serial1 = &uart0;
};
chosen {
@@ -47,11 +48,41 @@
#size-cells = <2>;
ranges;
+ linux,cma {
+ compatible = "shared-dma-pool";
+ alloc-ranges = <0x0 0xa0000000 0x0 0x28000000>;
+ size = <0x0 0x28000000>;
+ alignment = <0x0 0x1000>;
+ reusable;
+ linux,cma-default;
+ };
+
+ jpu_reserved: framebuffer@c9000000 {
+ reg = <0x0 0xc9000000 0x0 0x4000000>;
+ };
+
+ nvdla_reserved: framebuffer@d0000000 {
+ reg = <0x0 0xd0000000 0x0 0x28000000>;
+ no-map;
+ };
+
+ vin_reserved: framebuffer@f9000000 {
+ compatible = "shared-dma-pool";
+ reg = <0x0 0xf9000000 0x0 0x1000000>;
+ no-map;
+ };
+
dma-reserved@fa000000 {
reg = <0x0 0xfa000000 0x0 0x1000000>;
no-map;
};
+ sffb_reserved: framebuffer@fb000000 {
+ compatible = "shared-dma-pool";
+ reg = <0x0 0xfb000000 0x0 0x2000000>;
+ no-map;
+ };
+
linux,dma@107a000000 {
compatible = "shared-dma-pool";
reg = <0x10 0x7a000000 0x0 0x1000000>;
@@ -72,6 +103,44 @@
};
};
+&display {
+ memory-region = <&sffb_reserved>;
+ status = "okay";
+};
+
+&crtc {
+ ddr-format = <4>; //<WIN_FMT_RGB565>;
+ status = "okay";
+
+ port: port@0 {
+ reg = <0>;
+
+ crtc_0_out: endpoint {
+ remote-endpoint = <&hdmi_input0>;
+ };
+ };
+};
+
+&encoder {
+ encoder-type = <2>; // 2-TMDS, 3-LVDS, 6-DSI, 8-DPI
+ status = "okay";
+
+ ports {
+ port@0 {
+ hdmi_out: endpoint {
+ remote-endpoint = <&tda998x_0_input>;
+ };
+ };
+
+ port@1 {
+ hdmi_input0: endpoint {
+ remote-endpoint = <&crtc_0_out>;
+ };
+ };
+
+ };
+};
+
&gmac {
pinctrl-names = "default";
pinctrl-0 = <&gmac_pins>;
@@ -199,6 +268,20 @@
};
};
+ pwmdac_pins: pwmdac-0 {
+ pwmdac-pins {
+ pinmux = <GPIOMUX(23, GPO_PWMDAC_LEFT_OUT,
+ GPO_ENABLE, GPI_NONE)>,
+ <GPIOMUX(24, GPO_PWMDAC_RIGHT_OUT,
+ GPO_ENABLE, GPI_NONE)>;
+ bias-disable;
+ drive-strength = <35>;
+ input-disable;
+ input-schmitt-disable;
+ slew-rate = <0>;
+ };
+ };
+
pwm_pins: pwm-0 {
pwm-pins {
pinmux = <GPIOMUX(7,
@@ -289,6 +372,39 @@
};
};
+ spi2_pins: spi2-0 {
+ mosi-pins {
+ pinmux = <GPIOMUX(18, GPO_SPI2_PAD_TXD,
+ GPO_ENABLE, GPI_NONE)>;
+ bias-disable;
+ input-disable;
+ input-schmitt-disable;
+ };
+ miso-pins {
+ pinmux = <GPIOMUX(16, GPO_LOW, GPO_DISABLE,
+ GPI_SPI2_PAD_RXD)>;
+ bias-pull-up;
+ input-enable;
+ input-schmitt-enable;
+ };
+ sck-pins {
+ pinmux = <GPIOMUX(12, GPO_SPI2_PAD_SCK_OUT,
+ GPO_ENABLE, GPI_NONE)>;
+ bias-disable;
+ input-disable;
+ input-schmitt-disable;
+ };
+ ss-pins {
+ pinmux = <GPIOMUX(15, GPO_SPI2_PAD_SS_0_N,
+ GPO_ENABLE, GPI_NONE)>,
+ <GPIOMUX(11, GPO_SPI2_PAD_SS_1_N,
+ GPO_ENABLE, GPI_NONE)>;
+ bias-disable;
+ input-disable;
+ input-schmitt-disable;
+ };
+ };
+
uart0_pins: uart0-0 {
rx-pins {
pinmux = <GPIOMUX(40, GPO_LOW, GPO_DISABLE,
@@ -364,6 +480,17 @@
regulators {
};
};
+
+ tda998x@70 {
+ compatible = "nxp,tda998x";
+ reg = <0x70>;
+
+ port {
+ tda998x_0_input: endpoint {
+ remote-endpoint = <&hdmi_out>;
+ };
+ };
+ };
};
&i2c1 {
@@ -400,6 +527,44 @@
status = "okay";
};
+&pwmdac {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwmdac_pins>;
+ status = "okay";
+};
+
+&qspi {
+ nor_flash: nor-flash@0 {
+ compatible = "spi-flash";
+ reg = <0>;
+ spi-max-frequency = <31250000>;
+ page-size = <256>;
+ block-size = <16>;
+ cdns,read-delay = <4>;
+ cdns,tshsl-ns = <1>;
+ cdns,tsd2d-ns = <1>;
+ cdns,tchsh-ns = <1>;
+ cdns,tslch-ns = <1>;
+ spi-tx-bus-width = <1>;
+ spi-rx-bus-width = <1>;
+ };
+
+ nand_flash: nand-flash@1 {
+ compatible = "spi-flash-nand";
+ reg = <1>;
+ spi-max-frequency = <31250000>;
+ page-size = <2048>;
+ block-size = <17>;
+ cdns,read-delay = <4>;
+ cdns,tshsl-ns = <1>;
+ cdns,tsd2d-ns = <1>;
+ cdns,tchsh-ns = <1>;
+ cdns,tslch-ns = <1>;
+ spi-tx-bus-width = <1>;
+ spi-rx-bus-width = <1>;
+ };
+};
+
&sdio0 {
broken-cd;
bus-width = <4>;
@@ -428,6 +593,18 @@
};
};
+&spi2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi2_pins>;
+ status = "okay";
+
+ spi_dev0: spi@0 {
+ compatible = "rohm,dh2228fv";
+ spi-max-frequency = <10000000>;
+ reg = <0>;
+ };
+};
+
&uart0 {
pinctrl-names = "default";
pinctrl-0 = <&uart0_pins>;
--- a/arch/riscv/boot/dts/starfive/jh7100-starfive-visionfive-v1.dts
+++ b/arch/riscv/boot/dts/starfive/jh7100-starfive-visionfive-v1.dts
@@ -22,6 +22,19 @@
phy-handle = <&phy>;
};
+&gpio {
+ /* don't reset gpio mux for serial console and reset gpio */
+ starfive,keep-gpiomux = <13 14 63>;
+};
+
+&i2c0 {
+ eeprom@50 {
+ compatible = "atmel,24c04";
+ reg = <0x50>;
+ pagesize = <16>;
+ };
+};
+
/*
* The board uses a Motorcomm YT8521 PHY supporting RGMII-ID, but requires
* manual adjustment of the RX internal delay to work properly. The default
--- a/arch/riscv/boot/dts/starfive/jh7100.dtsi
+++ b/arch/riscv/boot/dts/starfive/jh7100.dtsi
@@ -6,7 +6,9 @@
/dts-v1/;
#include <dt-bindings/clock/starfive-jh7100.h>
+#include <dt-bindings/clock/starfive-jh7100-audio.h>
#include <dt-bindings/reset/starfive-jh7100.h>
+#include <dt-bindings/reset/starfive-jh7100-audio.h>
/ {
compatible = "starfive,jh7100";
@@ -37,6 +39,7 @@
riscv,isa-base = "rv64i";
riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "zicntr", "zicsr",
"zifencei", "zihpm";
+ starfive,itim = <&itim0>;
tlb-split;
cpu0_intc: interrupt-controller {
@@ -66,6 +69,7 @@
riscv,isa-base = "rv64i";
riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "zicntr", "zicsr",
"zifencei", "zihpm";
+ starfive,itim = <&itim1>;
tlb-split;
cpu1_intc: interrupt-controller {
@@ -153,6 +157,24 @@
dma-noncoherent;
ranges;
+ dtim: dtim@1000000 {
+ compatible = "starfive,dtim0";
+ reg = <0x0 0x1000000 0x0 0x2000>;
+ reg-names = "mem";
+ };
+
+ itim0: itim@1808000 {
+ compatible = "starfive,itim0";
+ reg = <0x0 0x1808000 0x0 0x8000>;
+ reg-names = "mem";
+ };
+
+ itim1: itim@1820000 {
+ compatible = "starfive,itim0";
+ reg = <0x0 0x1820000 0x0 0x8000>;
+ reg-names = "mem";
+ };
+
clint: clint@2000000 {
compatible = "starfive,jh7100-clint", "sifive,clint0";
reg = <0x0 0x2000000 0x0 0x10000>;
@@ -239,6 +261,124 @@
};
};
+ dma2p: dma-controller@100b0000 {
+ compatible = "starfive,jh7100-axi-dma";
+ reg = <0x0 0x100b0000 0x0 0x10000>;
+ clocks = <&clkgen JH7100_CLK_SGDMA2P_AXI>,
+ <&clkgen JH7100_CLK_SGDMA2P_AHB>;
+ clock-names = "core-clk", "cfgr-clk";
+ resets = <&rstgen JH7100_RSTN_SGDMA2P_AXI>,
+ <&rstgen JH7100_RSTN_SGDMA2P_AHB>;
+ reset-names = "axi", "ahb";
+ interrupts = <2>;
+ #dma-cells = <1>;
+ dma-channels = <4>;
+ snps,dma-masters = <1>;
+ snps,data-width = <4>;
+ snps,block-size = <4096 4096 4096 4096>;
+ snps,priority = <0 1 2 3>;
+ snps,axi-max-burst-len = <128>;
+ dma-coherent;
+ };
+
+ crypto: crypto@100d0000 {
+ compatible = "starfive,vic-sec";
+ reg = <0x0 0x100d0000 0x0 0x20000>,
+ <0x0 0x11800234 0x0 0xc>;
+ reg-names = "secmem", "secclk";
+ clocks = <&clkgen JH7100_CLK_SEC_AHB>;
+ interrupts = <31>;
+ };
+
+ i2sadc0: i2sadc0@10400000 {
+ compatible = "snps,designware-i2sadc0";
+ reg = <0x0 0x10400000 0x0 0x1000>;
+ clocks = <&clkgen JH7100_CLK_APB1_BUS>;
+ clock-names = "i2sclk";
+ interrupt-parent = <&plic>;
+ #sound-dai-cells = <0>;
+ dmas = <&dma2p 28>;
+ dma-names = "rx";
+ };
+
+ i2svad: i2svad@10420000 {
+ compatible = "starfive,sf-i2svad";
+ reg = <0x0 0x10420000 0x0 0x1000> ;
+ clocks = <&audclk JH7100_AUDCLK_I2SVAD_APB>;
+ clock-names = "i2svad_apb";
+ resets = <&audrst JH7100_AUDRSTN_I2SVAD_APB>,
+ <&audrst JH7100_AUDRSTN_I2SVAD_SRST>;
+ reset-names = "apb_i2svad", "i2svad_srst";
+ interrupts = <60>, <61>;
+ interrupt-names = "spintr", "slintr";
+ #sound-dai-cells = <0>;
+ };
+
+ pwmdac: pwmdac@10440000 {
+ compatible = "starfive,pwmdac";
+ reg = <0x0 0x10440000 0x0 0x1000>;
+ clocks = <&clkgen JH7100_CLK_AUDIO_ROOT>,
+ <&clkgen JH7100_CLK_AUDIO_SRC>,
+ <&clkgen JH7100_CLK_AUDIO_12288>,
+ <&audclk JH7100_AUDCLK_DMA1P_AHB>,
+ <&audclk JH7100_AUDCLK_PWMDAC_APB>,
+ <&audclk JH7100_AUDCLK_DAC_MCLK>;
+ clock-names = "audio_root",
+ "audio_src",
+ "audio_12288",
+ "dma1p_ahb",
+ "pwmdac_apb",
+ "dac_mclk";
+ resets = <&audrst JH7100_AUDRSTN_APB_BUS>,
+ <&audrst JH7100_AUDRSTN_DMA1P_AHB>,
+ <&audrst JH7100_AUDRSTN_PWMDAC_APB>;
+ reset-names = "apb_bus", "dma1p_ahb", "apb_pwmdac";
+ dmas = <&dma2p 23>;
+ dma-names = "tx";
+ #sound-dai-cells = <0>;
+ };
+
+ i2sdac0: i2sdac0@10450000 {
+ compatible = "snps,designware-i2sdac0";
+ reg = <0x0 0x10450000 0x0 0x1000>;
+ clocks = <&audclk JH7100_AUDCLK_DAC_MCLK>,
+ <&audclk JH7100_AUDCLK_I2SDAC_BCLK>,
+ <&audclk JH7100_AUDCLK_I2SDAC_LRCLK>,
+ <&audclk JH7100_AUDCLK_I2SDAC_APB>;
+ clock-names = "dac_mclk", "i2sdac0_bclk", "i2sdac0_lrclk", "i2sdac_apb";
+ resets = <&audrst JH7100_AUDRSTN_I2SDAC_APB>,
+ <&audrst JH7100_AUDRSTN_I2SDAC_SRST>;
+ reset-names = "apb_i2sdac", "i2sdac_srst";
+ #sound-dai-cells = <0>;
+ dmas = <&dma2p 30>;
+ dma-names = "tx";
+ };
+
+ i2sdac1: i2sdac1@10460000 {
+ compatible = "snps,designware-i2sdac1";
+ reg = <0x0 0x10460000 0x0 0x1000>;
+ clocks = <&audclk JH7100_AUDCLK_DAC_MCLK>,
+ <&audclk JH7100_AUDCLK_I2S1_BCLK>,
+ <&audclk JH7100_AUDCLK_I2S1_LRCLK>,
+ <&audclk JH7100_AUDCLK_I2S1_APB>;
+ clock-names = "dac_mclk", "i2sdac1_bclk", "i2sdac1_lrclk", "i2s1_apb";
+ resets = <&audrst JH7100_AUDRSTN_I2S1_APB>,
+ <&audrst JH7100_AUDRSTN_I2S1_SRST>;
+ #sound-dai-cells = <0>;
+ dmas = <&dma2p 31>;
+ dma-names = "tx";
+ };
+
+ i2sdac16k: i2sdac16k@10470000 {
+ compatible = "snps,designware-i2sdac16k";
+ reg = <0x0 0x10470000 0x0 0x1000>;
+ clocks = <&clkgen JH7100_CLK_APB1_BUS>;
+ clock-names = "i2sclk";
+ #sound-dai-cells = <0>;
+ dmas = <&dma2p 29>;
+ dma-names = "tx";
+ };
+
audclk: clock-controller@10480000 {
compatible = "starfive,jh7100-audclk";
reg = <0x0 0x10480000 0x0 0x10000>;
@@ -255,6 +395,50 @@
#reset-cells = <1>;
};
+ spdif_transmitter: spdif-transmitter {
+ compatible = "linux,spdif-dit";
+ #sound-dai-cells = <0>;
+ };
+
+ spdif_receiver: spdif-receiver {
+ compatible = "linux,spdif-dir";
+ #sound-dai-cells = <0>;
+ };
+
+ pwmdac_codec: pwmdac-transmitter {
+ compatible = "linux,pwmdac-dit";
+ #sound-dai-cells = <0>;
+ };
+
+ dmic_codec: dmic {
+ compatible = "dmic-codec";
+ #sound-dai-cells = <0>;
+ };
+
+ sound: snd-card {
+ compatible = "simple-audio-card";
+ simple-audio-card,name = "Starfive-Multi-Sound-Card";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ /* pwmdac */
+ simple-audio-card,dai-link@0 {
+ reg = <0>;
+ status = "okay";
+ format = "left_j";
+ bitclock-master = <&sndcpu0>;
+ frame-master = <&sndcpu0>;
+
+ sndcpu0: cpu {
+ sound-dai = <&pwmdac>;
+ };
+
+ codec {
+ sound-dai = <&pwmdac_codec>;
+ };
+ };
+ };
+
sysaudio: syscon@104a0000 {
compatible = "starfive,jh7100-sysaudio", "syscon";
reg = <0x0 0x104a0000 0x0 0x10000>;
@@ -287,6 +471,25 @@
};
};
+ dma1p: dma-controller@10500000 {
+ compatible = "starfive,jh7100-axi-dma";
+ reg = <0x0 0x10500000 0x0 0x10000>;
+ clocks = <&clkgen JH7100_CLK_SGDMA1P_AXI>,
+ <&clkgen JH7100_CLK_SGDMA1P_BUS>;
+ clock-names = "core-clk", "cfgr-clk";
+ resets = <&rstgen JH7100_RSTN_DMA1P_AXI>,
+ <&rstgen JH7100_RSTN_SGDMA1P_AXI>;
+ reset-names = "axi", "ahb";
+ interrupts = <1>;
+ #dma-cells = <1>;
+ dma-channels = <16>;
+ snps,dma-masters = <1>;
+ snps,data-width = <3>;
+ snps,block-size = <4096 4096 4096 4096 4096 4096 4096 4096 4096 4096 4096 4096 4096 4096 4096 4096>;
+ snps,priority = <0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15>;
+ snps,axi-max-burst-len = <64>;
+ };
+
clkgen: clock-controller@11800000 {
compatible = "starfive,jh7100-clkgen";
reg = <0x0 0x11800000 0x0 0x10000>;
@@ -295,6 +498,13 @@
#clock-cells = <1>;
};
+ otp: otp@11810000 {
+ compatible = "starfive,fu740-otp";
+ reg = <0x0 0x11810000 0x0 0x10000>;
+ clocks = <&clkgen JH7100_CLK_OTP_APB>;
+ fuse-count = <0x200>;
+ };
+
rstgen: reset-controller@11840000 {
compatible = "starfive,jh7100-reset";
reg = <0x0 0x11840000 0x0 0x10000>;
@@ -306,6 +516,21 @@
reg = <0x0 0x11850000 0x0 0x10000>;
};
+ qspi: spi@11860000 {
+ compatible = "cdns,qspi-nor";
+ reg = <0x0 0x11860000 0x0 0x10000>,
+ <0x0 0x20000000 0x0 0x20000000>;
+ clocks = <&clkgen JH7100_CLK_QSPI_AHB>;
+ interrupts = <3>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cdns,fifo-depth = <256>;
+ cdns,fifo-width = <4>;
+ cdns,trigger-address = <0x0>;
+ spi-max-frequency = <250000000>;
+ status = "disabled";
+ };
+
uart0: serial@11870000 {
compatible = "starfive,jh7100-hsuart", "snps,dw-apb-uart";
reg = <0x0 0x11870000 0x0 0x10000>;
@@ -332,6 +557,34 @@
status = "disabled";
};
+ spi0: spi@11890000 {
+ compatible = "snps,dw-apb-ssi";
+ reg = <0x0 0x11890000 0x0 0x10000>;
+ clocks = <&clkgen JH7100_CLK_SPI0_CORE>,
+ <&clkgen JH7100_CLK_SPI0_APB>;
+ clock-names = "ssi_clk", "pclk";
+ resets = <&rstgen JH7100_RSTN_SPI0_APB>;
+ reset-names = "spi";
+ interrupts = <94>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ spi1: spi@118a0000 {
+ compatible = "snps,dw-apb-ssi";
+ reg = <0x0 0x118a0000 0x0 0x10000>;
+ clocks = <&clkgen JH7100_CLK_SPI1_CORE>,
+ <&clkgen JH7100_CLK_SPI1_APB>;
+ clock-names = "ssi_clk", "pclk";
+ resets = <&rstgen JH7100_RSTN_SPI1_APB>;
+ reset-names = "spi";
+ interrupts = <95>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
i2c0: i2c@118b0000 {
compatible = "snps,designware-i2c";
reg = <0x0 0x118b0000 0x0 0x10000>;
@@ -358,6 +611,41 @@
status = "disabled";
};
+ trng: trng@118d0000 {
+ compatible = "starfive,vic-rng";
+ reg = <0x0 0x118d0000 0x0 0x10000>;
+ clocks = <&clkgen JH7100_CLK_TRNG_APB>;
+ interrupts = <98>;
+ };
+
+ vpu_enc: vpu_enc@118e0000 {
+ compatible = "cm,cm521-vpu";
+ reg = <0x0 0x118e0000 0x0 0x4000>;
+ reg-names = "control";
+ clocks = <&clkgen JH7100_CLK_VP6_CORE>;
+ clock-names = "vcodec";
+ interrupts = <26>;
+ };
+
+ vpu_dec: vpu_dec@118f0000 {
+ compatible = "c&m,cm511-vpu";
+ reg = <0 0x118f0000 0 0x10000>;
+ clocks = <&clkgen JH7100_CLK_VP6_CORE>;
+ clock-names = "vcodec";
+ interrupts = <23>;
+ //memory-region = <&vpu_reserved>;
+ };
+
+ jpu: coadj12@11900000 {
+ compatible = "cm,codaj12-jpu-1";
+ reg = <0x0 0x11900000 0x0 0x300>;
+ reg-names = "control";
+ clocks = <&clkgen JH7100_CLK_JPEG_APB>;
+ clock-names = "jpege";
+ interrupts = <24>;
+ memory-region = <&jpu_reserved>;
+ };
+
gpio: pinctrl@11910000 {
compatible = "starfive,jh7100-pinctrl";
reg = <0x0 0x11910000 0x0 0x10000>,
@@ -372,6 +660,86 @@
#interrupt-cells = <2>;
};
+ nvdla@11940000 {
+ compatible = "nvidia,nvdla_os_initial";
+ interrupts = <22>;
+ memory-region = <&nvdla_reserved>;
+ reg = <0x0 0x11940000 0x0 0x40000>;
+ status = "okay";
+ };
+
+ display: display-subsystem {
+ compatible = "starfive,display-subsystem";
+ dma-coherent;
+ status = "disabled";
+ };
+
+ encoder: display-encoder {
+ compatible = "starfive,display-encoder";
+ status = "disabled";
+ };
+
+ crtc: crtc@12000000 {
+ compatible = "starfive,jh7100-crtc";
+ reg = <0x0 0x12000000 0x0 0x10000>,
+ <0x0 0x12040000 0x0 0x10000>,
+ <0x0 0x12080000 0x0 0x10000>,
+ <0x0 0x120c0000 0x0 0x10000>,
+ <0x0 0x12240000 0x0 0x10000>,
+ <0x0 0x12250000 0x0 0x10000>,
+ <0x0 0x12260000 0x0 0x10000>;
+ reg-names = "lcdc", "vpp0", "vpp1", "vpp2", "clk", "rst", "sys";
+ clocks = <&clkgen JH7100_CLK_DISP_AXI>, <&clkgen JH7100_CLK_VOUT_SRC>;
+ clock-names = "disp_axi", "vout_src";
+ resets = <&rstgen JH7100_RSTN_DISP_AXI>, <&rstgen JH7100_RSTN_VOUT_SRC>;
+ reset-names = "disp_axi", "vout_src";
+ interrupts = <101>, <103>;
+ interrupt-names = "lcdc_irq", "vpp1_irq";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+
+ pp1 {
+ pp-id = <1>;
+ fifo-out;
+ //sys-bus-out;
+ src-format = <11>; //<COLOR_RGB565>;
+ src-width = <1920>;
+ src-height = <1080>;
+ dst-format = <7>; //<COLOR_RGB888_ARGB>;
+ dst-width = <1920>;
+ dst-height = <1080>;
+ };
+ };
+
+ spi2: spi@12410000 {
+ compatible = "snps,dw-apb-ssi";
+ reg = <0x0 0x12410000 0x0 0x10000>;
+ clocks = <&clkgen JH7100_CLK_SPI2_CORE>,
+ <&clkgen JH7100_CLK_SPI2_APB>;
+ clock-names = "ssi_clk", "pclk";
+ resets = <&rstgen JH7100_RSTN_SPI2_APB>;
+ reset-names = "spi";
+ interrupts = <70>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ spi3: spi@12420000 {
+ compatible = "snps,dw-apb-ssi";
+ reg = <0x0 0x12420000 0x0 0x10000>;
+ clocks = <&clkgen JH7100_CLK_SPI3_CORE>,
+ <&clkgen JH7100_CLK_SPI3_APB>;
+ clock-names = "ssi_clk", "pclk";
+ resets = <&rstgen JH7100_RSTN_SPI3_APB>;
+ reset-names = "spi";
+ interrupts = <71>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
uart2: serial@12430000 {
compatible = "starfive,jh7100-uart", "snps,dw-apb-uart";
reg = <0x0 0x12430000 0x0 0x10000>;
@@ -454,5 +822,26 @@
reset-names = "sense", "bus";
#thermal-sensor-cells = <0>;
};
+
+ xrp@f0000000 {
+ compatible = "cdns,xrp";
+ reg = <0x0 0xf0000000 0x0 0x01ffffff>,
+ <0x10 0x72000000 0x0 0x00001000>,
+ <0x10 0x72001000 0x0 0x00fff000>,
+ <0x0 0x124b0000 0x0 0x00010000>;
+ clocks = <&clkgen JH7100_CLK_VP6_CORE>;
+ interrupts = <27>, <28>;
+ firmware-name = "vp6_elf";
+ dsp-irq = <19 20>;
+ dsp-irq-src = <0x20 0x21>;
+ intc-irq-mode = <1>;
+ intc-irq = <0 1>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x40000000 0x0 0x40000000 0x01000000>,
+ <0xb0000000 0x10 0x70000000 0x3000000>;
+ dsp@0 {
+ };
+ };
};
};

View File

@ -0,0 +1,38 @@
From ec25d5b3e4ac00b76dce3593b54062ee7826cbbd Mon Sep 17 00:00:00 2001
From: Zoltan HERPAI <wigyori@uid0.hu>
Date: Sat, 31 May 2025 22:17:21 +0000
Subject: [PATCH 1022/1022] riscv: dts: starfive: vf1: add LED aliases and stop
heartbeat
Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>
---
arch/riscv/boot/dts/starfive/jh7100-common.dtsi | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
--- a/arch/riscv/boot/dts/starfive/jh7100-common.dtsi
+++ b/arch/riscv/boot/dts/starfive/jh7100-common.dtsi
@@ -16,6 +16,10 @@
mmc1 = &sdio1;
serial0 = &uart3;
serial1 = &uart0;
+ led-boot = &led_ack;
+ led-failsafe = &led_ack;
+ led-running = &led_ack;
+ led-upgrade = &led_ack;
};
chosen {
@@ -34,11 +38,11 @@
leds {
compatible = "gpio-leds";
- led-ack {
+ led_ack: led-ack {
gpios = <&gpio 43 GPIO_ACTIVE_HIGH>;
color = <LED_COLOR_ID_GREEN>;
function = LED_FUNCTION_HEARTBEAT;
- linux,default-trigger = "heartbeat";
+ default-state = "on";
label = "ack";
};
};

View File

@ -0,0 +1,34 @@
From 3a92ee5a97f030bdb1e88272a5d277ecb76836d6 Mon Sep 17 00:00:00 2001
From: Zoltan HERPAI <wigyori@uid0.hu>
Date: Sun, 1 Jun 2025 14:03:30 +0000
Subject: [PATCH 7/8] riscv: dts: starfive: visionfive2: add SYSLED support
A SYS LED is available at aongpio-3. Add standard heartbeat
support for it.
Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>
---
.../dts/starfive/jh7110-starfive-visionfive-2.dtsi | 12 ++++++++++++
1 file changed, 12 insertions(+)
--- a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
+++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
@@ -21,6 +21,18 @@
reg = <0x0 0x6ce00000 0x0 0x1600000>;
};
};
+
+ leds {
+ compatible = "gpio-leds";
+
+ led-ack {
+ gpios = <&aongpio 3 GPIO_ACTIVE_HIGH>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_HEARTBEAT;
+ linux,default-trigger = "heartbeat";
+ label = "ack";
+ };
+ };
};
&gmac1 {

View File

@ -0,0 +1,43 @@
From d930d3d22dcca6946dbdc822d7b8681f0d6372e5 Mon Sep 17 00:00:00 2001
From: Zoltan HERPAI <wigyori@uid0.hu>
Date: Sun, 1 Jun 2025 14:06:04 +0000
Subject: [PATCH 8/8] riscv: dts: starfive: visionfive2: add LED aliases and
stop heartbeat
Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>
---
.../boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
--- a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
+++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
@@ -6,10 +6,15 @@
/dts-v1/;
#include "jh7110-common.dtsi"
+#include <dt-bindings/leds/common.h>
/ {
aliases {
ethernet1 = &gmac1;
+ led-boot = &led_ack;
+ led-failsafe = &led_ack;
+ led-running = &led_ack;
+ led-upgrade = &led_ack;
};
reserved-memory {
@@ -25,11 +30,11 @@
leds {
compatible = "gpio-leds";
- led-ack {
+ led_ack: led-ack {
gpios = <&aongpio 3 GPIO_ACTIVE_HIGH>;
color = <LED_COLOR_ID_GREEN>;
function = LED_FUNCTION_HEARTBEAT;
- linux,default-trigger = "heartbeat";
+ default-state = "on";
label = "ack";
};
};

View File

@ -0,0 +1,31 @@
From 928a660ec1124853d2dae074e74ec7b20fe9bac2 Mon Sep 17 00:00:00 2001
From: Zoltan HERPAI <wigyori@uid0.hu>
Date: Sun, 1 Jun 2025 16:02:38 +0000
Subject: [PATCH] riscv: dts: starfive: visionfive2: add dma pool entry
In the VF2 SDK there is a reserved memory for a shared dma pool, which is
also updated by the SDK bootloader. Add this node here as well.
Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>
---
.../boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi | 9 +++++++++
1 file changed, 9 insertions(+)
--- a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
+++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
@@ -25,6 +25,15 @@
e24_mem: e24@c0000000 {
reg = <0x0 0x6ce00000 0x0 0x1600000>;
};
+
+ linux,cma {
+ compatible = "shared-dma-pool";
+ reusable;
+ size = <0x0 0x20000000>;
+ alignment = <0x0 0x1000>;
+ alloc-ranges = <0x0 0x70000000 0x0 0x20000000>;
+ linux,cma-default;
+ };
};
leds {