mirror of
https://git.openwrt.org/openwrt/openwrt.git
synced 2026-05-05 18:06:12 +02:00
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:
parent
6a7cb7b65d
commit
2c089a236f
641
target/linux/starfive/config-6.12
Normal file
641
target/linux/starfive/config-6.12
Normal 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
|
||||
@ -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>;
|
||||
@ -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");
|
||||
@ -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");
|
||||
@ -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);
|
||||
@ -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)
|
||||
@ -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,
|
||||
},
|
||||
};
|
||||
|
||||
@ -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");
|
||||
@ -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");
|
||||
@ -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)
|
||||
|
||||
@ -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
@ -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;
|
||||
}
|
||||
|
||||
@ -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++;
|
||||
/*
|
||||
@ -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);
|
||||
@ -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)
|
||||
|
||||
@ -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)
|
||||
@ -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
@ -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,
|
||||
@ -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");
|
||||
@ -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[] = {
|
||||
@ -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[] = {
|
||||
@ -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>");
|
||||
@ -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,
|
||||
@ -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);
|
||||
@ -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
|
||||
@ -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;
|
||||
@ -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,
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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 {
|
||||
@ -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>;
|
||||
@ -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>;
|
||||
@ -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 */ }
|
||||
};
|
||||
@ -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",
|
||||
@ -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");
|
||||
@ -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>;
|
||||
@ -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__ */
|
||||
@ -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
|
||||
@ -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>;
|
||||
@ -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),
|
||||
@ -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:
|
||||
@ -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;
|
||||
@ -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: |
|
||||
@ -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;
|
||||
};
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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;
|
||||
@ -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;
|
||||
}
|
||||
@ -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);
|
||||
@ -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>;
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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 {
|
||||
+ };
|
||||
+ };
|
||||
};
|
||||
};
|
||||
@ -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";
|
||||
};
|
||||
};
|
||||
@ -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 {
|
||||
@ -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";
|
||||
};
|
||||
};
|
||||
@ -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 {
|
||||
Loading…
x
Reference in New Issue
Block a user