mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-21 14:37:57 +00:00
starfive: add new target for StarFive JH7100/7110 SoC
This target adds support for the StarFive JH7100 and JH7110 SoCs, based on 6.1, as well as a couple boards equipped with these. Specifications: SoCs: JH7100: - StarFive JH7100 dual-core RISC-V (U74, RC64GC) - additional monitoring (S7) and control (E24) cores - 2Mb L2 cache JH7110: - StarFive JH7110 quad-core RISC-V (U74, RV64GC) - additional monitoring (S7) and control (E24) cores - 2Mb L2 cache Boards: VisionFive1: - JH7100 @ 1GHz - Memory: 8Gb LPDDR4 - 4x USB3.0 - 1x GBit ethernet - AMPak 6236 wifi / bluetooth - audio - powered via USB-C VisionFive2: - JH7110 @ 1.5GHz - Memory: 2/4/8Gb DDR4 - 2x Gbit ethernet - 2x USB3.0 / 2x USB2.0 - eMMC / SDIO - various multimedia input/outputs (MIPI CSI, HDMI, audio) - M.2 key M slot - PoE support - powered via USB-C Installation: Standard SD-card installation via dd-ing the generated image to an SD-card of at least 256Mb. Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>
This commit is contained in:
parent
db0d7cf6a1
commit
4070e2a64c
21
target/linux/starfive/Makefile
Normal file
21
target/linux/starfive/Makefile
Normal file
@ -0,0 +1,21 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
#
|
||||
# Copyright (C) 2024 Toco Technologies <info@toco.ae>
|
||||
#
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
ARCH:=riscv64
|
||||
BOARD:=starfive
|
||||
BOARDNAME:=StarFive JH71x0 (7100/7110)
|
||||
FEATURES:=ext4
|
||||
KERNELNAME:=Image dtbs
|
||||
|
||||
KERNEL_PATCHVER:=6.1
|
||||
|
||||
include $(INCLUDE_DIR)/target.mk
|
||||
|
||||
define Target/Description
|
||||
Build firmware images for the StarFive JH71x0-based boards
|
||||
endef
|
||||
|
||||
$(eval $(call BuildTarget))
|
22
target/linux/starfive/base-files/etc/board.d/02_network
Normal file
22
target/linux/starfive/base-files/etc/board.d/02_network
Normal file
@ -0,0 +1,22 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
#
|
||||
# Copyright (C) 2022 OpenWrt.org
|
||||
#
|
||||
|
||||
. /lib/functions/uci-defaults.sh
|
||||
|
||||
board_config_update
|
||||
|
||||
case "$(board_name)" in
|
||||
starfive,visionfive-2-v1.3b|\
|
||||
starfive,visionfive-2-v1.2a)
|
||||
ucidef_set_interfaces_lan_wan "eth0" "eth1"
|
||||
;;
|
||||
*)
|
||||
ucidef_set_interface_lan 'eth0'
|
||||
;;
|
||||
esac
|
||||
|
||||
board_config_flush
|
||||
|
||||
exit 0
|
4
target/linux/starfive/base-files/etc/inittab
Normal file
4
target/linux/starfive/base-files/etc/inittab
Normal file
@ -0,0 +1,4 @@
|
||||
::sysinit:/etc/init.d/rcS S boot
|
||||
::shutdown:/etc/init.d/rcS K shutdown
|
||||
ttyS0::askfirst:/usr/libexec/login.sh
|
||||
tty1::askfirst:/usr/libexec/login.sh
|
@ -0,0 +1,53 @@
|
||||
#AP6212_NVRAM_V1.0_20140603
|
||||
# 2.4 GHz, 20 MHz BW mode
|
||||
|
||||
# The following parameter values are just placeholders, need to be updated.
|
||||
manfid=0x2d0
|
||||
prodid=0x0726
|
||||
vendid=0x14e4
|
||||
devid=0x43e2
|
||||
boardtype=0x0726
|
||||
boardrev=0x1101
|
||||
boardnum=22
|
||||
macaddr=00:90:4c:c5:12:38
|
||||
sromrev=11
|
||||
boardflags=0x00404201
|
||||
xtalfreq=26000
|
||||
nocrc=1
|
||||
ag0=255
|
||||
aa2g=1
|
||||
ccode=ALL
|
||||
|
||||
pa0itssit=0x20
|
||||
extpagain2g=0
|
||||
|
||||
#PA parameters for 2.4GHz, measured at CHIP OUTPUT
|
||||
pa2ga0=-168,7161,-820
|
||||
AvVmid_c0=0x0,0xc8
|
||||
cckpwroffset0=5
|
||||
|
||||
# PPR params
|
||||
maxp2ga0=90
|
||||
txpwrbckof=6
|
||||
cckbw202gpo=0x5555
|
||||
legofdmbw202gpo=0x77777777
|
||||
mcsbw202gpo=0xaaaaaaaa
|
||||
|
||||
# OFDM IIR :
|
||||
ofdmdigfilttype=7
|
||||
# PAPD mode:
|
||||
papdmode=2
|
||||
|
||||
il0macaddr=00:90:4c:c5:12:38
|
||||
wl0id=0x431b
|
||||
|
||||
#OOB parameters
|
||||
hostwake=0x40
|
||||
hostrdy=0x41
|
||||
usbrdy=0x03
|
||||
usbrdydelay=100
|
||||
deadman_to=0xffffffff
|
||||
# muxenab: 0x1 for UART enable, 0x10 for Host awake
|
||||
muxenab=0x10
|
||||
# CLDO PWM voltage settings - 0x4 - 1.1 volt
|
||||
#cldo_pwm=0x4
|
@ -0,0 +1 @@
|
||||
brcmfmac43430-sdio.txt
|
555
target/linux/starfive/config-6.1
Normal file
555
target/linux/starfive/config-6.1
Normal file
@ -0,0 +1,555 @@
|
||||
CONFIG_64BIT=y
|
||||
CONFIG_AMBA_PL08X=y
|
||||
CONFIG_ARCH_CLOCKSOURCE_INIT=y
|
||||
CONFIG_ARCH_DMA_ADDR_T_64BIT=y
|
||||
CONFIG_ARCH_HIBERNATION_POSSIBLE=y
|
||||
CONFIG_ARCH_MMAP_RND_BITS=18
|
||||
CONFIG_ARCH_MMAP_RND_BITS_MAX=24
|
||||
CONFIG_ARCH_MMAP_RND_BITS_MIN=18
|
||||
CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=17
|
||||
CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y
|
||||
CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y
|
||||
CONFIG_ARCH_RV64I=y
|
||||
CONFIG_ARCH_SELECT_MEMORY_MODEL=y
|
||||
CONFIG_ARCH_SIFIVE=y
|
||||
CONFIG_ARCH_SPARSEMEM_ENABLE=y
|
||||
CONFIG_ARCH_STACKWALK=y
|
||||
CONFIG_ARCH_STARFIVE=y
|
||||
CONFIG_ARCH_WANTS_THP_SWAP=y
|
||||
CONFIG_ARM_AMBA=y
|
||||
# CONFIG_ARM_MHU_V2 is not set
|
||||
CONFIG_ASN1=y
|
||||
CONFIG_ASSOCIATIVE_ARRAY=y
|
||||
CONFIG_AUXILIARY_BUS=y
|
||||
CONFIG_CC_HAVE_STACKPROTECTOR_TLS=y
|
||||
CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5"
|
||||
CONFIG_CC_NO_ARRAY_BOUNDS=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_CONTIG_ALLOC=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_PM=y
|
||||
CONFIG_CPU_RMAP=y
|
||||
CONFIG_CRASH_CORE=y
|
||||
CONFIG_CRC16=y
|
||||
CONFIG_CRC7=y
|
||||
CONFIG_CRC_ITU_T=y
|
||||
CONFIG_CRYPTO_BLAKE2B=y
|
||||
CONFIG_CRYPTO_CMAC=y
|
||||
CONFIG_CRYPTO_CRC32C=y
|
||||
CONFIG_CRYPTO_DEV_JH7110=y
|
||||
CONFIG_CRYPTO_DRBG=y
|
||||
CONFIG_CRYPTO_DRBG_HMAC=y
|
||||
CONFIG_CRYPTO_DRBG_MENU=y
|
||||
CONFIG_CRYPTO_ECB=y
|
||||
CONFIG_CRYPTO_ECC=y
|
||||
CONFIG_CRYPTO_ECDH=y
|
||||
CONFIG_CRYPTO_ENGINE=y
|
||||
CONFIG_CRYPTO_HASH_INFO=y
|
||||
CONFIG_CRYPTO_HMAC=y
|
||||
CONFIG_CRYPTO_HW=y
|
||||
CONFIG_CRYPTO_JITTERENTROPY=y
|
||||
CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
|
||||
CONFIG_CRYPTO_LIB_POLY1305_RSIZE=1
|
||||
CONFIG_CRYPTO_LIB_SHA1=y
|
||||
CONFIG_CRYPTO_LIB_SHA256=y
|
||||
CONFIG_CRYPTO_LIB_UTILS=y
|
||||
CONFIG_CRYPTO_RNG=y
|
||||
CONFIG_CRYPTO_RNG2=y
|
||||
CONFIG_CRYPTO_RNG_DEFAULT=y
|
||||
CONFIG_CRYPTO_RSA=y
|
||||
CONFIG_CRYPTO_SHA256=y
|
||||
CONFIG_CRYPTO_SHA512=y
|
||||
CONFIG_CRYPTO_SM3=y
|
||||
CONFIG_CRYPTO_SM3_GENERIC=y
|
||||
CONFIG_CRYPTO_USER=y
|
||||
CONFIG_CRYPTO_USER_API=y
|
||||
CONFIG_CRYPTO_USER_API_AEAD=y
|
||||
CONFIG_CRYPTO_USER_API_HASH=y
|
||||
CONFIG_CRYPTO_USER_API_RNG=y
|
||||
CONFIG_CRYPTO_USER_API_SKCIPHER=y
|
||||
CONFIG_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_TIMEKEEPING=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_DEVTMPFS_SAFE is not set
|
||||
CONFIG_DMADEVICES=y
|
||||
CONFIG_DMADEVICES_DEBUG=y
|
||||
CONFIG_DMADEVICES_VDEBUG=y
|
||||
CONFIG_DMA_ENGINE=y
|
||||
CONFIG_DMA_OF=y
|
||||
CONFIG_DMA_SHARED_BUFFER=y
|
||||
CONFIG_DMA_VIRTUAL_CHANNELS=y
|
||||
# CONFIG_DPM_WATCHDOG 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_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_SIFIVE=y
|
||||
CONFIG_ERRATA_SIFIVE_CIP_1200=y
|
||||
CONFIG_ERRATA_SIFIVE_CIP_453=y
|
||||
# CONFIG_ERRATA_THEAD is not set
|
||||
CONFIG_EXCLUSIVE_SYSTEM_RAM=y
|
||||
CONFIG_EXT4_FS=y
|
||||
CONFIG_EXT4_FS_POSIX_ACL=y
|
||||
CONFIG_EXTCON=y
|
||||
CONFIG_FAILOVER=y
|
||||
CONFIG_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_FS_IOMAP=y
|
||||
CONFIG_FS_MBCACHE=y
|
||||
CONFIG_FS_POSIX_ACL=y
|
||||
CONFIG_FWNODE_MDIO=y
|
||||
CONFIG_FW_LOADER_PAGED_BUF=y
|
||||
CONFIG_FW_LOADER_SYSFS=y
|
||||
CONFIG_GCC11_NO_ARRAY_BOUNDS=y
|
||||
CONFIG_GENERIC_ALLOCATOR=y
|
||||
CONFIG_GENERIC_ARCH_TOPOLOGY=y
|
||||
CONFIG_GENERIC_BUG=y
|
||||
CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y
|
||||
CONFIG_GENERIC_CLOCKEVENTS=y
|
||||
CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
|
||||
CONFIG_GENERIC_CSUM=y
|
||||
CONFIG_GENERIC_EARLY_IOREMAP=y
|
||||
CONFIG_GENERIC_GETTIMEOFDAY=y
|
||||
CONFIG_GENERIC_IDLE_POLL_SETUP=y
|
||||
CONFIG_GENERIC_IOREMAP=y
|
||||
CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
|
||||
CONFIG_GENERIC_IRQ_MIGRATION=y
|
||||
CONFIG_GENERIC_IRQ_MULTI_HANDLER=y
|
||||
CONFIG_GENERIC_IRQ_SHOW=y
|
||||
CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
|
||||
CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED=y
|
||||
CONFIG_GENERIC_MSI_IRQ=y
|
||||
CONFIG_GENERIC_MSI_IRQ_DOMAIN=y
|
||||
CONFIG_GENERIC_PCI_IOMAP=y
|
||||
CONFIG_GENERIC_PHY=y
|
||||
CONFIG_GENERIC_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_GLOB=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_MAP=y
|
||||
CONFIG_HOTPLUG_CPU=y
|
||||
CONFIG_HUGETLBFS=y
|
||||
CONFIG_HUGETLB_PAGE=y
|
||||
CONFIG_HVC_DRIVER=y
|
||||
CONFIG_HVC_RISCV_SBI=y
|
||||
CONFIG_HWMON=y
|
||||
CONFIG_HW_RANDOM=y
|
||||
CONFIG_HW_RANDOM_JH7110=y
|
||||
CONFIG_HW_RANDOM_STARFIVE_VIC=y
|
||||
CONFIG_I2C=y
|
||||
CONFIG_I2C_ALGOBIT=y
|
||||
CONFIG_I2C_BOARDINFO=y
|
||||
CONFIG_I2C_CHARDEV=y
|
||||
CONFIG_I2C_DESIGNWARE_CORE=y
|
||||
CONFIG_I2C_DESIGNWARE_PLATFORM=y
|
||||
CONFIG_IKCONFIG=y
|
||||
CONFIG_IKCONFIG_PROC=y
|
||||
CONFIG_INITRAMFS_SOURCE=""
|
||||
CONFIG_IRQCHIP=y
|
||||
CONFIG_IRQ_DOMAIN=y
|
||||
CONFIG_IRQ_DOMAIN_HIERARCHY=y
|
||||
CONFIG_IRQ_FORCED_THREADING=y
|
||||
CONFIG_IRQ_WORK=y
|
||||
CONFIG_JBD2=y
|
||||
CONFIG_JH71XX_PMU=y
|
||||
CONFIG_JUMP_LABEL=y
|
||||
CONFIG_LIBFDT=y
|
||||
CONFIG_LOCKUP_DETECTOR=y
|
||||
CONFIG_LOCK_DEBUGGING_SUPPORT=y
|
||||
CONFIG_LOCK_SPIN_ON_OWNER=y
|
||||
CONFIG_LSM=""
|
||||
CONFIG_MARVELL_PHY=y
|
||||
CONFIG_MDIO_BUS=y
|
||||
CONFIG_MDIO_DEVICE=y
|
||||
CONFIG_MDIO_DEVRES=y
|
||||
CONFIG_MEMFD_CREATE=y
|
||||
CONFIG_MEMORY_ISOLATION=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_K3 is not set
|
||||
# CONFIG_MMC_DW_PCI is not set
|
||||
CONFIG_MMC_DW_PLTFM=y
|
||||
CONFIG_MMC_DW_STARFIVE=y
|
||||
CONFIG_MMIOWB=y
|
||||
CONFIG_MODULES_TREE_LOOKUP=y
|
||||
CONFIG_MODULES_USE_ELF_RELA=y
|
||||
CONFIG_MODULE_SECTIONS=y
|
||||
CONFIG_MOTORCOMM_PHY=y
|
||||
CONFIG_MPILIB=y
|
||||
CONFIG_MTD_SPI_NOR=y
|
||||
CONFIG_MUTEX_SPIN_ON_OWNER=y
|
||||
CONFIG_NAMESPACES=y
|
||||
CONFIG_NEED_DMA_MAP_STATE=y
|
||||
CONFIG_NET_FAILOVER=y
|
||||
CONFIG_NET_FLOW_LIMIT=y
|
||||
CONFIG_NET_NS=y
|
||||
CONFIG_NET_SELFTESTS=y
|
||||
CONFIG_NLS=y
|
||||
CONFIG_NLS_CODEPAGE_437=y
|
||||
CONFIG_NLS_DEFAULT="iso8859-15"
|
||||
CONFIG_NLS_ISO8859_1=y
|
||||
CONFIG_NLS_ISO8859_15=y
|
||||
CONFIG_NO_HZ_COMMON=y
|
||||
CONFIG_NO_HZ_IDLE=y
|
||||
# CONFIG_NONPORTABLE is not set
|
||||
CONFIG_NR_CPUS=8
|
||||
CONFIG_NVMEM=y
|
||||
CONFIG_NVMEM_SYSFS=y
|
||||
CONFIG_NVME_CORE=y
|
||||
CONFIG_NVME_HWMON=y
|
||||
# CONFIG_NVME_MULTIPATH is not set
|
||||
CONFIG_OF=y
|
||||
CONFIG_OF_ADDRESS=y
|
||||
CONFIG_OF_DMA_DEFAULT_COHERENT=y
|
||||
CONFIG_OF_DYNAMIC=y
|
||||
CONFIG_OF_EARLY_FLATTREE=y
|
||||
CONFIG_OF_FLATTREE=y
|
||||
CONFIG_OF_GPIO=y
|
||||
CONFIG_OF_IRQ=y
|
||||
CONFIG_OF_KOBJ=y
|
||||
CONFIG_OF_MDIO=y
|
||||
CONFIG_OF_OVERLAY=y
|
||||
CONFIG_OF_RESOLVE=y
|
||||
CONFIG_OID_REGISTRY=y
|
||||
CONFIG_OVERLAY_FS_INDEX=y
|
||||
CONFIG_OVERLAY_FS_METACOPY=y
|
||||
CONFIG_OVERLAY_FS_REDIRECT_DIR=y
|
||||
CONFIG_PADATA=y
|
||||
CONFIG_PAGE_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_STARFIVE is not set
|
||||
CONFIG_PCI_DOMAINS=y
|
||||
CONFIG_PCI_DOMAINS_GENERIC=y
|
||||
CONFIG_PCI_MSI=y
|
||||
CONFIG_PCI_MSI_IRQ_DOMAIN=y
|
||||
CONFIG_PCS_XPCS=y
|
||||
CONFIG_PERF_EVENTS=y
|
||||
CONFIG_PGTABLE_LEVELS=5
|
||||
CONFIG_PHYLIB=y
|
||||
CONFIG_PHYLINK=y
|
||||
CONFIG_PHYS_ADDR_T_64BIT=y
|
||||
CONFIG_PHY_STARFIVE_DPHY_RX=y
|
||||
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_PORTABLE=y
|
||||
CONFIG_POSIX_CPU_TIMERS_TASK_WORK=y
|
||||
CONFIG_POSIX_MQUEUE=y
|
||||
CONFIG_POSIX_MQUEUE_SYSCTL=y
|
||||
CONFIG_POWER_RESET=y
|
||||
CONFIG_POWER_RESET_GPIO_RESTART=y
|
||||
CONFIG_POWER_RESET_SYSCON=y
|
||||
CONFIG_POWER_RESET_SYSCON_POWEROFF=y
|
||||
# CONFIG_POWER_RESET_TPS65086 is not set
|
||||
CONFIG_PPS=y
|
||||
CONFIG_PREEMPT_COUNT=y
|
||||
CONFIG_PREEMPT_NONE_BUILD=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_SIFIVE is not set
|
||||
CONFIG_PWM_SIFIVE_PTC=y
|
||||
CONFIG_PWM_STARFIVE_PTC=y
|
||||
CONFIG_PWM_SYSFS=y
|
||||
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_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=y
|
||||
CONFIG_RESET_STARFIVE_JH7110=y
|
||||
CONFIG_RESET_STARFIVE_JH71X0=y
|
||||
CONFIG_RFS_ACCEL=y
|
||||
CONFIG_RISCV=y
|
||||
CONFIG_RISCV_ALTERNATIVE=y
|
||||
CONFIG_RISCV_BOOT_SPINWAIT=y
|
||||
CONFIG_RISCV_DMA_NONCOHERENT=y
|
||||
CONFIG_RISCV_INTC=y
|
||||
CONFIG_RISCV_ISA_C=y
|
||||
# CONFIG_RISCV_ISA_SVPBMT is not set
|
||||
CONFIG_RISCV_ISA_ZICBOM=y
|
||||
CONFIG_RISCV_PMU=y
|
||||
CONFIG_RISCV_PMU_LEGACY=y
|
||||
CONFIG_RISCV_PMU_SBI=y
|
||||
CONFIG_RISCV_SBI=y
|
||||
CONFIG_RISCV_SBI_CPUIDLE=y
|
||||
CONFIG_RISCV_SBI_V01=y
|
||||
CONFIG_RISCV_TIMER=y
|
||||
CONFIG_RPMSG=y
|
||||
CONFIG_RPMSG_CHAR=y
|
||||
# CONFIG_RPMSG_CTRL is not set
|
||||
CONFIG_RPMSG_NS=y
|
||||
# CONFIG_RPMSG_TTY is not set
|
||||
CONFIG_RPMSG_VIRTIO=y
|
||||
CONFIG_RPS=y
|
||||
CONFIG_RTC_CLASS=y
|
||||
# CONFIG_RTC_DRV_EFI is not set
|
||||
CONFIG_RTC_DRV_GOLDFISH=y
|
||||
CONFIG_RTC_DRV_HYM8563=y
|
||||
CONFIG_RTC_I2C_AND_SPI=y
|
||||
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_DIAG=y
|
||||
CONFIG_SOCK_RX_QUEUE_MAPPING=y
|
||||
# CONFIG_SOC_MICROCHIP_POLARFIRE is not set
|
||||
CONFIG_SOC_SIFIVE=y
|
||||
CONFIG_SOC_STARFIVE=y
|
||||
# CONFIG_SOC_VIRT is not set
|
||||
CONFIG_SOFTLOCKUP_DETECTOR=y
|
||||
CONFIG_SOUND=y
|
||||
CONFIG_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_SPIDEV=y
|
||||
CONFIG_SRCU=y
|
||||
CONFIG_STARFIVE_TIMER=y
|
||||
CONFIG_STARFIVE_WATCHDOG=y
|
||||
CONFIG_STMMAC_ETH=y
|
||||
CONFIG_STMMAC_PLATFORM=y
|
||||
CONFIG_STMMAC_SELFTESTS=y
|
||||
CONFIG_SWIOTLB=y
|
||||
CONFIG_SWPHY=y
|
||||
CONFIG_SYNC_FILE=y
|
||||
CONFIG_SYSCTL_EXCEPTION_TRACE=y
|
||||
# CONFIG_SYSFB_SIMPLEFB is not set
|
||||
CONFIG_THERMAL=y
|
||||
CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
|
||||
CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0
|
||||
CONFIG_THERMAL_GOV_STEP_WISE=y
|
||||
CONFIG_THERMAL_OF=y
|
||||
CONFIG_THREAD_INFO_IN_TASK=y
|
||||
CONFIG_TICK_CPU_ACCOUNTING=y
|
||||
CONFIG_TIMER_OF=y
|
||||
CONFIG_TIMER_PROBE=y
|
||||
CONFIG_TMPFS_POSIX_ACL=y
|
||||
CONFIG_TOOLCHAIN_HAS_ZICBOM=y
|
||||
CONFIG_TOOLCHAIN_HAS_ZIHINTPAUSE=y
|
||||
CONFIG_TOOLCHAIN_NEEDS_EXPLICIT_ZICSR_ZIFENCEI=y
|
||||
CONFIG_TREE_RCU=y
|
||||
CONFIG_TREE_SRCU=y
|
||||
CONFIG_TTY_PRINTK=y
|
||||
CONFIG_TTY_PRINTK_LEVEL=6
|
||||
CONFIG_TUNE_GENERIC=y
|
||||
CONFIG_UCS2_STRING=y
|
||||
CONFIG_UNINLINE_SPIN_UNLOCK=y
|
||||
CONFIG_USB=y
|
||||
CONFIG_USB_COMMON=y
|
||||
CONFIG_USB_CONFIGFS=y
|
||||
# CONFIG_USB_CONFIGFS_ACM is not set
|
||||
# CONFIG_USB_CONFIGFS_ECM is not set
|
||||
# CONFIG_USB_CONFIGFS_ECM_SUBSET is not set
|
||||
# CONFIG_USB_CONFIGFS_EEM is not set
|
||||
CONFIG_USB_CONFIGFS_F_FS=y
|
||||
# CONFIG_USB_CONFIGFS_F_HID is not set
|
||||
# CONFIG_USB_CONFIGFS_F_LB_SS is not set
|
||||
# CONFIG_USB_CONFIGFS_F_MIDI is not set
|
||||
# CONFIG_USB_CONFIGFS_F_PRINTER is not set
|
||||
# CONFIG_USB_CONFIGFS_F_UAC1 is not set
|
||||
# CONFIG_USB_CONFIGFS_F_UAC1_LEGACY is not set
|
||||
# CONFIG_USB_CONFIGFS_F_UAC2 is not set
|
||||
# CONFIG_USB_CONFIGFS_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_PHY=y
|
||||
CONFIG_USB_ROLE_SWITCH=y
|
||||
CONFIG_USB_SUPPORT=y
|
||||
# CONFIG_USB_UHCI_HCD is not set
|
||||
CONFIG_USELIB=y
|
||||
CONFIG_USER_NS=y
|
||||
CONFIG_VFAT_FS=y
|
||||
# CONFIG_VIRTIO_BLK is not set
|
||||
# CONFIG_VIRTIO_NET is not set
|
||||
CONFIG_VMAP_STACK=y
|
||||
CONFIG_WATCHDOG_CORE=y
|
||||
CONFIG_WATCHDOG_SYSFS=y
|
||||
CONFIG_WERROR=y
|
||||
CONFIG_WQ_WATCHDOG=y
|
||||
CONFIG_XPS=y
|
||||
CONFIG_XXHASH=y
|
||||
CONFIG_ZLIB_INFLATE=y
|
||||
CONFIG_ZONE_DMA32=y
|
1
target/linux/starfive/generic/target.mk
Normal file
1
target/linux/starfive/generic/target.mk
Normal file
@ -0,0 +1 @@
|
||||
BOARDNAME:=Generic
|
5
target/linux/starfive/image/Config.in
Normal file
5
target/linux/starfive/image/Config.in
Normal file
@ -0,0 +1,5 @@
|
||||
config STARFIVE_SD_BOOT_PARTSIZE
|
||||
int "Boot (SD Card) filesystem partition size (in MB)"
|
||||
depends on TARGET_starfive
|
||||
default 32
|
||||
|
85
target/linux/starfive/image/Makefile
Normal file
85
target/linux/starfive/image/Makefile
Normal file
@ -0,0 +1,85 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
#
|
||||
# Copyright (C) 2023 Toco Technologies <info@toco.ae>
|
||||
#
|
||||
include $(TOPDIR)/rules.mk
|
||||
include $(INCLUDE_DIR)/image.mk
|
||||
|
||||
FAT32_BLOCK_SIZE=1024
|
||||
FAT32_BLOCKS=$(shell echo $$(($(CONFIG_STARFIVE_SD_BOOT_PARTSIZE)*1024*1024/$(FAT32_BLOCK_SIZE))))
|
||||
|
||||
define Build/boot-scr-jh7110
|
||||
rm -f $@-boot.scr
|
||||
mkimage -A riscv -O linux -T script -C none -a 0 -e 0 -d mmc.bootscript.jh7110 $@-boot.scr
|
||||
endef
|
||||
|
||||
define Build/boot-scr-jh7100
|
||||
rm -f $@-boot.scr
|
||||
mkimage -A riscv -O linux -T script -C none -a 0 -e 0 -d mmc.bootscript.jh7100 $@-boot.scr
|
||||
endef
|
||||
|
||||
define Build/riscv-sdcard
|
||||
rm -f $@.boot #$(KDIR_TMP)/$(IMG_PREFIX)-$(PROFILE)-boot.img
|
||||
mkfs.fat $@.boot -C $(FAT32_BLOCKS)
|
||||
mcopy -i $@.boot $(LINUX_DIR)/arch/riscv/boot/dts/$(DEVICE_DTS).dtb ::dtb
|
||||
mcopy -i $@.boot $@-boot.scr ::boot.scr.uimg
|
||||
mcopy -i $@.boot $(IMAGE_KERNEL) ::Image
|
||||
./gen_starfive_sdcard_img.sh \
|
||||
$@ \
|
||||
$@.boot \
|
||||
$(IMAGE_ROOTFS) \
|
||||
$(CONFIG_STARFIVE_SD_BOOT_PARTSIZE) \
|
||||
$(CONFIG_TARGET_ROOTFS_PARTSIZE)
|
||||
endef
|
||||
|
||||
define Device/Default
|
||||
PROFILES := Default
|
||||
KERNEL_NAME := Image
|
||||
KERNEL := kernel-bin
|
||||
IMAGES := sdcard.img.gz
|
||||
IMAGE/sdcard.img.gz := boot-scr-jh7110 | riscv-sdcard | append-metadata | gzip
|
||||
endef
|
||||
|
||||
define Device/JH7100
|
||||
PROFILES := Default
|
||||
KERNEL_NAME := Image
|
||||
KERNEL := kernel-bin
|
||||
IMAGES := sdcard.img.gz
|
||||
IMAGE/sdcard.img.gz := boot-scr-jh7100 | riscv-sdcard | append-metadata | gzip
|
||||
endef
|
||||
|
||||
define Device/visionfive2-v1.2a
|
||||
DEVICE_VENDOR := StarFive
|
||||
DEVICE_MODEL := VisionFive2 v1.2a
|
||||
DEVICE_DTS := starfive/jh7110-starfive-visionfive-2-v1.2a
|
||||
DEVICE_PACKAGES := kmod-eeprom-at24 kmod-pcie-starfive kmod-usb3 kmod-usb-cdns3-starfive
|
||||
endef
|
||||
TARGET_DEVICES += visionfive2-v1.2a
|
||||
|
||||
define Device/visionfive2-v1.3b
|
||||
DEVICE_VENDOR := StarFive
|
||||
DEVICE_MODEL := VisionFive2 v1.3b
|
||||
DEVICE_DTS := starfive/jh7110-starfive-visionfive-2-v1.3b
|
||||
DEVICE_PACKAGES := kmod-eeprom-at24 kmod-pcie-starfive kmod-usb3 kmod-usb-cdns3-starfive
|
||||
endef
|
||||
TARGET_DEVICES += visionfive2-v1.3b
|
||||
|
||||
define Device/beaglev-starlight
|
||||
$(call Device/JH7100)
|
||||
DEVICE_VENDOR := BeagleV
|
||||
DEVICE_MODEL := Starlight
|
||||
DEVICE_DTS := starfive/jh7100-beaglev-starlight
|
||||
endef
|
||||
TARGET_DEVICES += beaglev-starlight
|
||||
|
||||
define Device/visionfive-v1
|
||||
$(call Device/JH7100)
|
||||
DEVICE_VENDOR := StarFive
|
||||
DEVICE_MODEL := VisionFive v1
|
||||
DEVICE_DTS := starfive/jh7100-starfive-visionfive-v1
|
||||
DEVICE_PACKAGES := kmod-eeprom-at24 kmod-brcmfmac cypress-firmware-43430-sdio wpad-basic-mbedtls \
|
||||
kmod-usb3 kmod-usb-cdns3-starfive
|
||||
endef
|
||||
TARGET_DEVICES += visionfive-v1
|
||||
|
||||
$(eval $(call BuildImage))
|
24
target/linux/starfive/image/gen_starfive_sdcard_img.sh
Executable file
24
target/linux/starfive/image/gen_starfive_sdcard_img.sh
Executable file
@ -0,0 +1,24 @@
|
||||
#!/usr/bin/env bash
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
#
|
||||
# Copyright (C) 2023 OpenWrt.org
|
||||
#
|
||||
|
||||
set -ex
|
||||
[ $# -eq 5 ] || {
|
||||
echo "SYNTAX: $0 <file> <bootfs image> <rootfs image> <bootfs size> <rootfs size>"
|
||||
exit 1
|
||||
}
|
||||
|
||||
OUTPUT="$1"
|
||||
BOOTFS="$2"
|
||||
ROOTFS="$3"
|
||||
BOOTFSSIZE="$4"
|
||||
ROOTFSSIZE="$5"
|
||||
|
||||
set $(ptgen -o $OUTPUT -v -g -T sifiveu_spl -N loader1 -p 1024 -T sifiveu_uboot -N loader2 -p 4096 -t ef -N boot -p ${BOOTFSSIZE}M -N rootfs -p ${ROOTFSSIZE}M)
|
||||
|
||||
ROOTFSOFFSET=$(($7 / 512))
|
||||
|
||||
dd bs=512 if="$BOOTFS" of="$OUTPUT" seek=10274 conv=notrunc
|
||||
dd bs=512 if="$ROOTFS" of="$OUTPUT" seek=${ROOTFSOFFSET} conv=notrunc
|
4
target/linux/starfive/image/mmc.bootscript.jh7100
Normal file
4
target/linux/starfive/image/mmc.bootscript.jh7100
Normal file
@ -0,0 +1,4 @@
|
||||
fatload mmc 0:3 0x84000000 Image
|
||||
fatload mmc 0:3 0x88000000 dtb
|
||||
setenv bootargs "earlyprintk console=ttyS0,115200 debug rootwait earlycon=sbi root=/dev/mmcblk0p4"
|
||||
booti 0x84000000 - 0x88000000
|
5
target/linux/starfive/image/mmc.bootscript.jh7110
Normal file
5
target/linux/starfive/image/mmc.bootscript.jh7110
Normal file
@ -0,0 +1,5 @@
|
||||
fatload mmc 1:3 0xa0000000 Image
|
||||
fatload mmc 1:3 0x46000000 dtb
|
||||
run chipa_set_linux
|
||||
setenv bootargs "earlyprintk console=ttyS0,115200 debug rootwait earlycon=sbi root=/dev/mmcblk1p4"
|
||||
booti 0xa0000000 - 0x46000000
|
31
target/linux/starfive/modules.mk
Normal file
31
target/linux/starfive/modules.mk
Normal file
@ -0,0 +1,31 @@
|
||||
define KernelPackage/pcie-starfive
|
||||
SUBMENU:=$(OTHER_MENU)
|
||||
TITLE:=JH7110 PCIe controller support
|
||||
DEPENDS:=@TARGET_starfive
|
||||
KCONFIG:=CONFIG_PCIE_STARFIVE
|
||||
FILES:=$(LINUX_DIR)/drivers/pci/controller/pcie-starfive.ko
|
||||
AUTOLOAD:=$(call AutoLoad,41,pcie-starfive,1)
|
||||
endef
|
||||
|
||||
define KernelPackage/pcie-starfive/description
|
||||
PCIe support for JH7110
|
||||
endef
|
||||
|
||||
$(eval $(call KernelPackage,pcie-starfive))
|
||||
|
||||
|
||||
define KernelPackage/usb-cdns3-starfive
|
||||
TITLE:=Cadence USB3 StarFive USB driver
|
||||
DEPENDS:=@TARGET_starfive +kmod-usb-cdns3
|
||||
KCONFIG:= CONFIG_USB_CDNS3_STARFIVE
|
||||
FILES:= $(LINUX_DIR)/drivers/usb/cdns3/cdns3-starfive.ko
|
||||
AUTOLOAD:=$(call AutoLoad,53,cdns3-starfive,1)
|
||||
$(call AddDepends/usb)
|
||||
endef
|
||||
|
||||
define KernelPackage/usb-cdns3-starfive/description
|
||||
Add support for the Cadence USB3 controller found in StarFive SoCs.
|
||||
endef
|
||||
|
||||
|
||||
$(eval $(call KernelPackage,usb-cdns3-starfive))
|
@ -0,0 +1,482 @@
|
||||
From c960c73ee9fdaae51fcd8a14d44d576b1cf522b7 Mon Sep 17 00:00:00 2001
|
||||
From: Emil Renner Berthing <kernel@esmil.dk>
|
||||
Date: Sat, 1 Apr 2023 19:19:13 +0800
|
||||
Subject: [PATCH 001/122] dt-bindings: clock: Add StarFive JH7110 system clock
|
||||
and reset generator
|
||||
|
||||
Add bindings for the system clock and reset generator (SYSCRG) on the
|
||||
JH7110 RISC-V SoC by StarFive Ltd.
|
||||
|
||||
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
|
||||
Reviewed-by: Rob Herring <robh@kernel.org>
|
||||
Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
|
||||
Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
|
||||
Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
|
||||
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
|
||||
---
|
||||
.../clock/starfive,jh7110-syscrg.yaml | 104 +++++++++
|
||||
.../dt-bindings/clock/starfive,jh7110-crg.h | 203 ++++++++++++++++++
|
||||
.../dt-bindings/reset/starfive,jh7110-crg.h | 142 ++++++++++++
|
||||
3 files changed, 449 insertions(+)
|
||||
create mode 100644 Documentation/devicetree/bindings/clock/starfive,jh7110-syscrg.yaml
|
||||
create mode 100644 include/dt-bindings/clock/starfive,jh7110-crg.h
|
||||
create mode 100644 include/dt-bindings/reset/starfive,jh7110-crg.h
|
||||
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/clock/starfive,jh7110-syscrg.yaml
|
||||
@@ -0,0 +1,104 @@
|
||||
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
+%YAML 1.2
|
||||
+---
|
||||
+$id: http://devicetree.org/schemas/clock/starfive,jh7110-syscrg.yaml#
|
||||
+$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
+
|
||||
+title: StarFive JH7110 System Clock and Reset Generator
|
||||
+
|
||||
+maintainers:
|
||||
+ - Emil Renner Berthing <kernel@esmil.dk>
|
||||
+
|
||||
+properties:
|
||||
+ compatible:
|
||||
+ const: starfive,jh7110-syscrg
|
||||
+
|
||||
+ reg:
|
||||
+ maxItems: 1
|
||||
+
|
||||
+ clocks:
|
||||
+ oneOf:
|
||||
+ - items:
|
||||
+ - description: Main Oscillator (24 MHz)
|
||||
+ - description: GMAC1 RMII reference or GMAC1 RGMII RX
|
||||
+ - description: External I2S TX bit clock
|
||||
+ - description: External I2S TX left/right channel clock
|
||||
+ - description: External I2S RX bit clock
|
||||
+ - description: External I2S RX left/right channel clock
|
||||
+ - description: External TDM clock
|
||||
+ - description: External audio master clock
|
||||
+
|
||||
+ - items:
|
||||
+ - description: Main Oscillator (24 MHz)
|
||||
+ - description: GMAC1 RMII reference
|
||||
+ - description: GMAC1 RGMII RX
|
||||
+ - description: External I2S TX bit clock
|
||||
+ - description: External I2S TX left/right channel clock
|
||||
+ - description: External I2S RX bit clock
|
||||
+ - description: External I2S RX left/right channel clock
|
||||
+ - description: External TDM clock
|
||||
+ - description: External audio master clock
|
||||
+
|
||||
+ clock-names:
|
||||
+ oneOf:
|
||||
+ - items:
|
||||
+ - const: osc
|
||||
+ - enum:
|
||||
+ - gmac1_rmii_refin
|
||||
+ - gmac1_rgmii_rxin
|
||||
+ - const: i2stx_bclk_ext
|
||||
+ - const: i2stx_lrck_ext
|
||||
+ - const: i2srx_bclk_ext
|
||||
+ - const: i2srx_lrck_ext
|
||||
+ - const: tdm_ext
|
||||
+ - const: mclk_ext
|
||||
+
|
||||
+ - items:
|
||||
+ - const: osc
|
||||
+ - const: gmac1_rmii_refin
|
||||
+ - const: gmac1_rgmii_rxin
|
||||
+ - const: i2stx_bclk_ext
|
||||
+ - const: i2stx_lrck_ext
|
||||
+ - const: i2srx_bclk_ext
|
||||
+ - const: i2srx_lrck_ext
|
||||
+ - const: tdm_ext
|
||||
+ - const: mclk_ext
|
||||
+
|
||||
+ '#clock-cells':
|
||||
+ const: 1
|
||||
+ description:
|
||||
+ See <dt-bindings/clock/starfive,jh7110-crg.h> for valid indices.
|
||||
+
|
||||
+ '#reset-cells':
|
||||
+ const: 1
|
||||
+ description:
|
||||
+ See <dt-bindings/reset/starfive,jh7110-crg.h> for valid indices.
|
||||
+
|
||||
+required:
|
||||
+ - compatible
|
||||
+ - reg
|
||||
+ - clocks
|
||||
+ - clock-names
|
||||
+ - '#clock-cells'
|
||||
+ - '#reset-cells'
|
||||
+
|
||||
+additionalProperties: false
|
||||
+
|
||||
+examples:
|
||||
+ - |
|
||||
+ clock-controller@13020000 {
|
||||
+ compatible = "starfive,jh7110-syscrg";
|
||||
+ reg = <0x13020000 0x10000>;
|
||||
+ clocks = <&osc>, <&gmac1_rmii_refin>,
|
||||
+ <&gmac1_rgmii_rxin>,
|
||||
+ <&i2stx_bclk_ext>, <&i2stx_lrck_ext>,
|
||||
+ <&i2srx_bclk_ext>, <&i2srx_lrck_ext>,
|
||||
+ <&tdm_ext>, <&mclk_ext>;
|
||||
+ clock-names = "osc", "gmac1_rmii_refin",
|
||||
+ "gmac1_rgmii_rxin",
|
||||
+ "i2stx_bclk_ext", "i2stx_lrck_ext",
|
||||
+ "i2srx_bclk_ext", "i2srx_lrck_ext",
|
||||
+ "tdm_ext", "mclk_ext";
|
||||
+ #clock-cells = <1>;
|
||||
+ #reset-cells = <1>;
|
||||
+ };
|
||||
--- /dev/null
|
||||
+++ b/include/dt-bindings/clock/starfive,jh7110-crg.h
|
||||
@@ -0,0 +1,203 @@
|
||||
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
|
||||
+/*
|
||||
+ * Copyright 2022 Emil Renner Berthing <kernel@esmil.dk>
|
||||
+ */
|
||||
+
|
||||
+#ifndef __DT_BINDINGS_CLOCK_STARFIVE_JH7110_CRG_H__
|
||||
+#define __DT_BINDINGS_CLOCK_STARFIVE_JH7110_CRG_H__
|
||||
+
|
||||
+/* SYSCRG clocks */
|
||||
+#define JH7110_SYSCLK_CPU_ROOT 0
|
||||
+#define JH7110_SYSCLK_CPU_CORE 1
|
||||
+#define JH7110_SYSCLK_CPU_BUS 2
|
||||
+#define JH7110_SYSCLK_GPU_ROOT 3
|
||||
+#define JH7110_SYSCLK_PERH_ROOT 4
|
||||
+#define JH7110_SYSCLK_BUS_ROOT 5
|
||||
+#define JH7110_SYSCLK_NOCSTG_BUS 6
|
||||
+#define JH7110_SYSCLK_AXI_CFG0 7
|
||||
+#define JH7110_SYSCLK_STG_AXIAHB 8
|
||||
+#define JH7110_SYSCLK_AHB0 9
|
||||
+#define JH7110_SYSCLK_AHB1 10
|
||||
+#define JH7110_SYSCLK_APB_BUS 11
|
||||
+#define JH7110_SYSCLK_APB0 12
|
||||
+#define JH7110_SYSCLK_PLL0_DIV2 13
|
||||
+#define JH7110_SYSCLK_PLL1_DIV2 14
|
||||
+#define JH7110_SYSCLK_PLL2_DIV2 15
|
||||
+#define JH7110_SYSCLK_AUDIO_ROOT 16
|
||||
+#define JH7110_SYSCLK_MCLK_INNER 17
|
||||
+#define JH7110_SYSCLK_MCLK 18
|
||||
+#define JH7110_SYSCLK_MCLK_OUT 19
|
||||
+#define JH7110_SYSCLK_ISP_2X 20
|
||||
+#define JH7110_SYSCLK_ISP_AXI 21
|
||||
+#define JH7110_SYSCLK_GCLK0 22
|
||||
+#define JH7110_SYSCLK_GCLK1 23
|
||||
+#define JH7110_SYSCLK_GCLK2 24
|
||||
+#define JH7110_SYSCLK_CORE 25
|
||||
+#define JH7110_SYSCLK_CORE1 26
|
||||
+#define JH7110_SYSCLK_CORE2 27
|
||||
+#define JH7110_SYSCLK_CORE3 28
|
||||
+#define JH7110_SYSCLK_CORE4 29
|
||||
+#define JH7110_SYSCLK_DEBUG 30
|
||||
+#define JH7110_SYSCLK_RTC_TOGGLE 31
|
||||
+#define JH7110_SYSCLK_TRACE0 32
|
||||
+#define JH7110_SYSCLK_TRACE1 33
|
||||
+#define JH7110_SYSCLK_TRACE2 34
|
||||
+#define JH7110_SYSCLK_TRACE3 35
|
||||
+#define JH7110_SYSCLK_TRACE4 36
|
||||
+#define JH7110_SYSCLK_TRACE_COM 37
|
||||
+#define JH7110_SYSCLK_NOC_BUS_CPU_AXI 38
|
||||
+#define JH7110_SYSCLK_NOC_BUS_AXICFG0_AXI 39
|
||||
+#define JH7110_SYSCLK_OSC_DIV2 40
|
||||
+#define JH7110_SYSCLK_PLL1_DIV4 41
|
||||
+#define JH7110_SYSCLK_PLL1_DIV8 42
|
||||
+#define JH7110_SYSCLK_DDR_BUS 43
|
||||
+#define JH7110_SYSCLK_DDR_AXI 44
|
||||
+#define JH7110_SYSCLK_GPU_CORE 45
|
||||
+#define JH7110_SYSCLK_GPU_CORE_CLK 46
|
||||
+#define JH7110_SYSCLK_GPU_SYS_CLK 47
|
||||
+#define JH7110_SYSCLK_GPU_APB 48
|
||||
+#define JH7110_SYSCLK_GPU_RTC_TOGGLE 49
|
||||
+#define JH7110_SYSCLK_NOC_BUS_GPU_AXI 50
|
||||
+#define JH7110_SYSCLK_ISP_TOP_CORE 51
|
||||
+#define JH7110_SYSCLK_ISP_TOP_AXI 52
|
||||
+#define JH7110_SYSCLK_NOC_BUS_ISP_AXI 53
|
||||
+#define JH7110_SYSCLK_HIFI4_CORE 54
|
||||
+#define JH7110_SYSCLK_HIFI4_AXI 55
|
||||
+#define JH7110_SYSCLK_AXI_CFG1_MAIN 56
|
||||
+#define JH7110_SYSCLK_AXI_CFG1_AHB 57
|
||||
+#define JH7110_SYSCLK_VOUT_SRC 58
|
||||
+#define JH7110_SYSCLK_VOUT_AXI 59
|
||||
+#define JH7110_SYSCLK_NOC_BUS_DISP_AXI 60
|
||||
+#define JH7110_SYSCLK_VOUT_TOP_AHB 61
|
||||
+#define JH7110_SYSCLK_VOUT_TOP_AXI 62
|
||||
+#define JH7110_SYSCLK_VOUT_TOP_HDMITX0_MCLK 63
|
||||
+#define JH7110_SYSCLK_VOUT_TOP_MIPIPHY_REF 64
|
||||
+#define JH7110_SYSCLK_JPEGC_AXI 65
|
||||
+#define JH7110_SYSCLK_CODAJ12_AXI 66
|
||||
+#define JH7110_SYSCLK_CODAJ12_CORE 67
|
||||
+#define JH7110_SYSCLK_CODAJ12_APB 68
|
||||
+#define JH7110_SYSCLK_VDEC_AXI 69
|
||||
+#define JH7110_SYSCLK_WAVE511_AXI 70
|
||||
+#define JH7110_SYSCLK_WAVE511_BPU 71
|
||||
+#define JH7110_SYSCLK_WAVE511_VCE 72
|
||||
+#define JH7110_SYSCLK_WAVE511_APB 73
|
||||
+#define JH7110_SYSCLK_VDEC_JPG 74
|
||||
+#define JH7110_SYSCLK_VDEC_MAIN 75
|
||||
+#define JH7110_SYSCLK_NOC_BUS_VDEC_AXI 76
|
||||
+#define JH7110_SYSCLK_VENC_AXI 77
|
||||
+#define JH7110_SYSCLK_WAVE420L_AXI 78
|
||||
+#define JH7110_SYSCLK_WAVE420L_BPU 79
|
||||
+#define JH7110_SYSCLK_WAVE420L_VCE 80
|
||||
+#define JH7110_SYSCLK_WAVE420L_APB 81
|
||||
+#define JH7110_SYSCLK_NOC_BUS_VENC_AXI 82
|
||||
+#define JH7110_SYSCLK_AXI_CFG0_MAIN_DIV 83
|
||||
+#define JH7110_SYSCLK_AXI_CFG0_MAIN 84
|
||||
+#define JH7110_SYSCLK_AXI_CFG0_HIFI4 85
|
||||
+#define JH7110_SYSCLK_AXIMEM2_AXI 86
|
||||
+#define JH7110_SYSCLK_QSPI_AHB 87
|
||||
+#define JH7110_SYSCLK_QSPI_APB 88
|
||||
+#define JH7110_SYSCLK_QSPI_REF_SRC 89
|
||||
+#define JH7110_SYSCLK_QSPI_REF 90
|
||||
+#define JH7110_SYSCLK_SDIO0_AHB 91
|
||||
+#define JH7110_SYSCLK_SDIO1_AHB 92
|
||||
+#define JH7110_SYSCLK_SDIO0_SDCARD 93
|
||||
+#define JH7110_SYSCLK_SDIO1_SDCARD 94
|
||||
+#define JH7110_SYSCLK_USB_125M 95
|
||||
+#define JH7110_SYSCLK_NOC_BUS_STG_AXI 96
|
||||
+#define JH7110_SYSCLK_GMAC1_AHB 97
|
||||
+#define JH7110_SYSCLK_GMAC1_AXI 98
|
||||
+#define JH7110_SYSCLK_GMAC_SRC 99
|
||||
+#define JH7110_SYSCLK_GMAC1_GTXCLK 100
|
||||
+#define JH7110_SYSCLK_GMAC1_RMII_RTX 101
|
||||
+#define JH7110_SYSCLK_GMAC1_PTP 102
|
||||
+#define JH7110_SYSCLK_GMAC1_RX 103
|
||||
+#define JH7110_SYSCLK_GMAC1_RX_INV 104
|
||||
+#define JH7110_SYSCLK_GMAC1_TX 105
|
||||
+#define JH7110_SYSCLK_GMAC1_TX_INV 106
|
||||
+#define JH7110_SYSCLK_GMAC1_GTXC 107
|
||||
+#define JH7110_SYSCLK_GMAC0_GTXCLK 108
|
||||
+#define JH7110_SYSCLK_GMAC0_PTP 109
|
||||
+#define JH7110_SYSCLK_GMAC_PHY 110
|
||||
+#define JH7110_SYSCLK_GMAC0_GTXC 111
|
||||
+#define JH7110_SYSCLK_IOMUX_APB 112
|
||||
+#define JH7110_SYSCLK_MAILBOX_APB 113
|
||||
+#define JH7110_SYSCLK_INT_CTRL_APB 114
|
||||
+#define JH7110_SYSCLK_CAN0_APB 115
|
||||
+#define JH7110_SYSCLK_CAN0_TIMER 116
|
||||
+#define JH7110_SYSCLK_CAN0_CAN 117
|
||||
+#define JH7110_SYSCLK_CAN1_APB 118
|
||||
+#define JH7110_SYSCLK_CAN1_TIMER 119
|
||||
+#define JH7110_SYSCLK_CAN1_CAN 120
|
||||
+#define JH7110_SYSCLK_PWM_APB 121
|
||||
+#define JH7110_SYSCLK_WDT_APB 122
|
||||
+#define JH7110_SYSCLK_WDT_CORE 123
|
||||
+#define JH7110_SYSCLK_TIMER_APB 124
|
||||
+#define JH7110_SYSCLK_TIMER0 125
|
||||
+#define JH7110_SYSCLK_TIMER1 126
|
||||
+#define JH7110_SYSCLK_TIMER2 127
|
||||
+#define JH7110_SYSCLK_TIMER3 128
|
||||
+#define JH7110_SYSCLK_TEMP_APB 129
|
||||
+#define JH7110_SYSCLK_TEMP_CORE 130
|
||||
+#define JH7110_SYSCLK_SPI0_APB 131
|
||||
+#define JH7110_SYSCLK_SPI1_APB 132
|
||||
+#define JH7110_SYSCLK_SPI2_APB 133
|
||||
+#define JH7110_SYSCLK_SPI3_APB 134
|
||||
+#define JH7110_SYSCLK_SPI4_APB 135
|
||||
+#define JH7110_SYSCLK_SPI5_APB 136
|
||||
+#define JH7110_SYSCLK_SPI6_APB 137
|
||||
+#define JH7110_SYSCLK_I2C0_APB 138
|
||||
+#define JH7110_SYSCLK_I2C1_APB 139
|
||||
+#define JH7110_SYSCLK_I2C2_APB 140
|
||||
+#define JH7110_SYSCLK_I2C3_APB 141
|
||||
+#define JH7110_SYSCLK_I2C4_APB 142
|
||||
+#define JH7110_SYSCLK_I2C5_APB 143
|
||||
+#define JH7110_SYSCLK_I2C6_APB 144
|
||||
+#define JH7110_SYSCLK_UART0_APB 145
|
||||
+#define JH7110_SYSCLK_UART0_CORE 146
|
||||
+#define JH7110_SYSCLK_UART1_APB 147
|
||||
+#define JH7110_SYSCLK_UART1_CORE 148
|
||||
+#define JH7110_SYSCLK_UART2_APB 149
|
||||
+#define JH7110_SYSCLK_UART2_CORE 150
|
||||
+#define JH7110_SYSCLK_UART3_APB 151
|
||||
+#define JH7110_SYSCLK_UART3_CORE 152
|
||||
+#define JH7110_SYSCLK_UART4_APB 153
|
||||
+#define JH7110_SYSCLK_UART4_CORE 154
|
||||
+#define JH7110_SYSCLK_UART5_APB 155
|
||||
+#define JH7110_SYSCLK_UART5_CORE 156
|
||||
+#define JH7110_SYSCLK_PWMDAC_APB 157
|
||||
+#define JH7110_SYSCLK_PWMDAC_CORE 158
|
||||
+#define JH7110_SYSCLK_SPDIF_APB 159
|
||||
+#define JH7110_SYSCLK_SPDIF_CORE 160
|
||||
+#define JH7110_SYSCLK_I2STX0_APB 161
|
||||
+#define JH7110_SYSCLK_I2STX0_BCLK_MST 162
|
||||
+#define JH7110_SYSCLK_I2STX0_BCLK_MST_INV 163
|
||||
+#define JH7110_SYSCLK_I2STX0_LRCK_MST 164
|
||||
+#define JH7110_SYSCLK_I2STX0_BCLK 165
|
||||
+#define JH7110_SYSCLK_I2STX0_BCLK_INV 166
|
||||
+#define JH7110_SYSCLK_I2STX0_LRCK 167
|
||||
+#define JH7110_SYSCLK_I2STX1_APB 168
|
||||
+#define JH7110_SYSCLK_I2STX1_BCLK_MST 169
|
||||
+#define JH7110_SYSCLK_I2STX1_BCLK_MST_INV 170
|
||||
+#define JH7110_SYSCLK_I2STX1_LRCK_MST 171
|
||||
+#define JH7110_SYSCLK_I2STX1_BCLK 172
|
||||
+#define JH7110_SYSCLK_I2STX1_BCLK_INV 173
|
||||
+#define JH7110_SYSCLK_I2STX1_LRCK 174
|
||||
+#define JH7110_SYSCLK_I2SRX_APB 175
|
||||
+#define JH7110_SYSCLK_I2SRX_BCLK_MST 176
|
||||
+#define JH7110_SYSCLK_I2SRX_BCLK_MST_INV 177
|
||||
+#define JH7110_SYSCLK_I2SRX_LRCK_MST 178
|
||||
+#define JH7110_SYSCLK_I2SRX_BCLK 179
|
||||
+#define JH7110_SYSCLK_I2SRX_BCLK_INV 180
|
||||
+#define JH7110_SYSCLK_I2SRX_LRCK 181
|
||||
+#define JH7110_SYSCLK_PDM_DMIC 182
|
||||
+#define JH7110_SYSCLK_PDM_APB 183
|
||||
+#define JH7110_SYSCLK_TDM_AHB 184
|
||||
+#define JH7110_SYSCLK_TDM_APB 185
|
||||
+#define JH7110_SYSCLK_TDM_INTERNAL 186
|
||||
+#define JH7110_SYSCLK_TDM_TDM 187
|
||||
+#define JH7110_SYSCLK_TDM_TDM_INV 188
|
||||
+#define JH7110_SYSCLK_JTAG_CERTIFICATION_TRNG 189
|
||||
+
|
||||
+#define JH7110_SYSCLK_END 190
|
||||
+
|
||||
+#endif /* __DT_BINDINGS_CLOCK_STARFIVE_JH7110_CRG_H__ */
|
||||
--- /dev/null
|
||||
+++ b/include/dt-bindings/reset/starfive,jh7110-crg.h
|
||||
@@ -0,0 +1,142 @@
|
||||
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
|
||||
+/*
|
||||
+ * Copyright (C) 2022 Emil Renner Berthing <kernel@esmil.dk>
|
||||
+ */
|
||||
+
|
||||
+#ifndef __DT_BINDINGS_RESET_STARFIVE_JH7110_CRG_H__
|
||||
+#define __DT_BINDINGS_RESET_STARFIVE_JH7110_CRG_H__
|
||||
+
|
||||
+/* SYSCRG resets */
|
||||
+#define JH7110_SYSRST_JTAG_APB 0
|
||||
+#define JH7110_SYSRST_SYSCON_APB 1
|
||||
+#define JH7110_SYSRST_IOMUX_APB 2
|
||||
+#define JH7110_SYSRST_BUS 3
|
||||
+#define JH7110_SYSRST_DEBUG 4
|
||||
+#define JH7110_SYSRST_CORE0 5
|
||||
+#define JH7110_SYSRST_CORE1 6
|
||||
+#define JH7110_SYSRST_CORE2 7
|
||||
+#define JH7110_SYSRST_CORE3 8
|
||||
+#define JH7110_SYSRST_CORE4 9
|
||||
+#define JH7110_SYSRST_CORE0_ST 10
|
||||
+#define JH7110_SYSRST_CORE1_ST 11
|
||||
+#define JH7110_SYSRST_CORE2_ST 12
|
||||
+#define JH7110_SYSRST_CORE3_ST 13
|
||||
+#define JH7110_SYSRST_CORE4_ST 14
|
||||
+#define JH7110_SYSRST_TRACE0 15
|
||||
+#define JH7110_SYSRST_TRACE1 16
|
||||
+#define JH7110_SYSRST_TRACE2 17
|
||||
+#define JH7110_SYSRST_TRACE3 18
|
||||
+#define JH7110_SYSRST_TRACE4 19
|
||||
+#define JH7110_SYSRST_TRACE_COM 20
|
||||
+#define JH7110_SYSRST_GPU_APB 21
|
||||
+#define JH7110_SYSRST_GPU_DOMA 22
|
||||
+#define JH7110_SYSRST_NOC_BUS_APB 23
|
||||
+#define JH7110_SYSRST_NOC_BUS_AXICFG0_AXI 24
|
||||
+#define JH7110_SYSRST_NOC_BUS_CPU_AXI 25
|
||||
+#define JH7110_SYSRST_NOC_BUS_DISP_AXI 26
|
||||
+#define JH7110_SYSRST_NOC_BUS_GPU_AXI 27
|
||||
+#define JH7110_SYSRST_NOC_BUS_ISP_AXI 28
|
||||
+#define JH7110_SYSRST_NOC_BUS_DDRC 29
|
||||
+#define JH7110_SYSRST_NOC_BUS_STG_AXI 30
|
||||
+#define JH7110_SYSRST_NOC_BUS_VDEC_AXI 31
|
||||
+
|
||||
+#define JH7110_SYSRST_NOC_BUS_VENC_AXI 32
|
||||
+#define JH7110_SYSRST_AXI_CFG1_AHB 33
|
||||
+#define JH7110_SYSRST_AXI_CFG1_MAIN 34
|
||||
+#define JH7110_SYSRST_AXI_CFG0_MAIN 35
|
||||
+#define JH7110_SYSRST_AXI_CFG0_MAIN_DIV 36
|
||||
+#define JH7110_SYSRST_AXI_CFG0_HIFI4 37
|
||||
+#define JH7110_SYSRST_DDR_AXI 38
|
||||
+#define JH7110_SYSRST_DDR_OSC 39
|
||||
+#define JH7110_SYSRST_DDR_APB 40
|
||||
+#define JH7110_SYSRST_ISP_TOP 41
|
||||
+#define JH7110_SYSRST_ISP_TOP_AXI 42
|
||||
+#define JH7110_SYSRST_VOUT_TOP_SRC 43
|
||||
+#define JH7110_SYSRST_CODAJ12_AXI 44
|
||||
+#define JH7110_SYSRST_CODAJ12_CORE 45
|
||||
+#define JH7110_SYSRST_CODAJ12_APB 46
|
||||
+#define JH7110_SYSRST_WAVE511_AXI 47
|
||||
+#define JH7110_SYSRST_WAVE511_BPU 48
|
||||
+#define JH7110_SYSRST_WAVE511_VCE 49
|
||||
+#define JH7110_SYSRST_WAVE511_APB 50
|
||||
+#define JH7110_SYSRST_VDEC_JPG 51
|
||||
+#define JH7110_SYSRST_VDEC_MAIN 52
|
||||
+#define JH7110_SYSRST_AXIMEM0_AXI 53
|
||||
+#define JH7110_SYSRST_WAVE420L_AXI 54
|
||||
+#define JH7110_SYSRST_WAVE420L_BPU 55
|
||||
+#define JH7110_SYSRST_WAVE420L_VCE 56
|
||||
+#define JH7110_SYSRST_WAVE420L_APB 57
|
||||
+#define JH7110_SYSRST_AXIMEM1_AXI 58
|
||||
+#define JH7110_SYSRST_AXIMEM2_AXI 59
|
||||
+#define JH7110_SYSRST_INTMEM 60
|
||||
+#define JH7110_SYSRST_QSPI_AHB 61
|
||||
+#define JH7110_SYSRST_QSPI_APB 62
|
||||
+#define JH7110_SYSRST_QSPI_REF 63
|
||||
+
|
||||
+#define JH7110_SYSRST_SDIO0_AHB 64
|
||||
+#define JH7110_SYSRST_SDIO1_AHB 65
|
||||
+#define JH7110_SYSRST_GMAC1_AXI 66
|
||||
+#define JH7110_SYSRST_GMAC1_AHB 67
|
||||
+#define JH7110_SYSRST_MAILBOX_APB 68
|
||||
+#define JH7110_SYSRST_SPI0_APB 69
|
||||
+#define JH7110_SYSRST_SPI1_APB 70
|
||||
+#define JH7110_SYSRST_SPI2_APB 71
|
||||
+#define JH7110_SYSRST_SPI3_APB 72
|
||||
+#define JH7110_SYSRST_SPI4_APB 73
|
||||
+#define JH7110_SYSRST_SPI5_APB 74
|
||||
+#define JH7110_SYSRST_SPI6_APB 75
|
||||
+#define JH7110_SYSRST_I2C0_APB 76
|
||||
+#define JH7110_SYSRST_I2C1_APB 77
|
||||
+#define JH7110_SYSRST_I2C2_APB 78
|
||||
+#define JH7110_SYSRST_I2C3_APB 79
|
||||
+#define JH7110_SYSRST_I2C4_APB 80
|
||||
+#define JH7110_SYSRST_I2C5_APB 81
|
||||
+#define JH7110_SYSRST_I2C6_APB 82
|
||||
+#define JH7110_SYSRST_UART0_APB 83
|
||||
+#define JH7110_SYSRST_UART0_CORE 84
|
||||
+#define JH7110_SYSRST_UART1_APB 85
|
||||
+#define JH7110_SYSRST_UART1_CORE 86
|
||||
+#define JH7110_SYSRST_UART2_APB 87
|
||||
+#define JH7110_SYSRST_UART2_CORE 88
|
||||
+#define JH7110_SYSRST_UART3_APB 89
|
||||
+#define JH7110_SYSRST_UART3_CORE 90
|
||||
+#define JH7110_SYSRST_UART4_APB 91
|
||||
+#define JH7110_SYSRST_UART4_CORE 92
|
||||
+#define JH7110_SYSRST_UART5_APB 93
|
||||
+#define JH7110_SYSRST_UART5_CORE 94
|
||||
+#define JH7110_SYSRST_SPDIF_APB 95
|
||||
+
|
||||
+#define JH7110_SYSRST_PWMDAC_APB 96
|
||||
+#define JH7110_SYSRST_PDM_DMIC 97
|
||||
+#define JH7110_SYSRST_PDM_APB 98
|
||||
+#define JH7110_SYSRST_I2SRX_APB 99
|
||||
+#define JH7110_SYSRST_I2SRX_BCLK 100
|
||||
+#define JH7110_SYSRST_I2STX0_APB 101
|
||||
+#define JH7110_SYSRST_I2STX0_BCLK 102
|
||||
+#define JH7110_SYSRST_I2STX1_APB 103
|
||||
+#define JH7110_SYSRST_I2STX1_BCLK 104
|
||||
+#define JH7110_SYSRST_TDM_AHB 105
|
||||
+#define JH7110_SYSRST_TDM_CORE 106
|
||||
+#define JH7110_SYSRST_TDM_APB 107
|
||||
+#define JH7110_SYSRST_PWM_APB 108
|
||||
+#define JH7110_SYSRST_WDT_APB 109
|
||||
+#define JH7110_SYSRST_WDT_CORE 110
|
||||
+#define JH7110_SYSRST_CAN0_APB 111
|
||||
+#define JH7110_SYSRST_CAN0_CORE 112
|
||||
+#define JH7110_SYSRST_CAN0_TIMER 113
|
||||
+#define JH7110_SYSRST_CAN1_APB 114
|
||||
+#define JH7110_SYSRST_CAN1_CORE 115
|
||||
+#define JH7110_SYSRST_CAN1_TIMER 116
|
||||
+#define JH7110_SYSRST_TIMER_APB 117
|
||||
+#define JH7110_SYSRST_TIMER0 118
|
||||
+#define JH7110_SYSRST_TIMER1 119
|
||||
+#define JH7110_SYSRST_TIMER2 120
|
||||
+#define JH7110_SYSRST_TIMER3 121
|
||||
+#define JH7110_SYSRST_INT_CTRL_APB 122
|
||||
+#define JH7110_SYSRST_TEMP_APB 123
|
||||
+#define JH7110_SYSRST_TEMP_CORE 124
|
||||
+#define JH7110_SYSRST_JTAG_CERTIFICATION 125
|
||||
+
|
||||
+#define JH7110_SYSRST_END 126
|
||||
+
|
||||
+#endif /* __DT_BINDINGS_RESET_STARFIVE_JH7110_CRG_H__ */
|
@ -0,0 +1,176 @@
|
||||
From cd833f484009f37be57a2aa09257af6e8c1b25b6 Mon Sep 17 00:00:00 2001
|
||||
From: Emil Renner Berthing <kernel@esmil.dk>
|
||||
Date: Sat, 1 Apr 2023 19:19:14 +0800
|
||||
Subject: [PATCH 002/122] dt-bindings: clock: Add StarFive JH7110 always-on
|
||||
clock and reset generator
|
||||
|
||||
Add bindings for the always-on clock and reset generator (AONCRG) on the
|
||||
JH7110 RISC-V SoC by StarFive Ltd.
|
||||
|
||||
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
|
||||
Reviewed-by: Rob Herring <robh@kernel.org>
|
||||
Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
|
||||
Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
|
||||
Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
|
||||
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
|
||||
---
|
||||
.../clock/starfive,jh7110-aoncrg.yaml | 107 ++++++++++++++++++
|
||||
.../dt-bindings/clock/starfive,jh7110-crg.h | 18 +++
|
||||
.../dt-bindings/reset/starfive,jh7110-crg.h | 12 ++
|
||||
3 files changed, 137 insertions(+)
|
||||
create mode 100644 Documentation/devicetree/bindings/clock/starfive,jh7110-aoncrg.yaml
|
||||
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/clock/starfive,jh7110-aoncrg.yaml
|
||||
@@ -0,0 +1,107 @@
|
||||
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
+%YAML 1.2
|
||||
+---
|
||||
+$id: http://devicetree.org/schemas/clock/starfive,jh7110-aoncrg.yaml#
|
||||
+$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
+
|
||||
+title: StarFive JH7110 Always-On Clock and Reset Generator
|
||||
+
|
||||
+maintainers:
|
||||
+ - Emil Renner Berthing <kernel@esmil.dk>
|
||||
+
|
||||
+properties:
|
||||
+ compatible:
|
||||
+ const: starfive,jh7110-aoncrg
|
||||
+
|
||||
+ reg:
|
||||
+ maxItems: 1
|
||||
+
|
||||
+ clocks:
|
||||
+ oneOf:
|
||||
+ - items:
|
||||
+ - description: Main Oscillator (24 MHz)
|
||||
+ - description: GMAC0 RMII reference or GMAC0 RGMII RX
|
||||
+ - description: STG AXI/AHB
|
||||
+ - description: APB Bus
|
||||
+ - description: GMAC0 GTX
|
||||
+
|
||||
+ - items:
|
||||
+ - description: Main Oscillator (24 MHz)
|
||||
+ - description: GMAC0 RMII reference or GMAC0 RGMII RX
|
||||
+ - description: STG AXI/AHB or GMAC0 RGMII RX
|
||||
+ - description: APB Bus or STG AXI/AHB
|
||||
+ - description: GMAC0 GTX or APB Bus
|
||||
+ - description: RTC Oscillator (32.768 kHz) or GMAC0 GTX
|
||||
+
|
||||
+ - items:
|
||||
+ - description: Main Oscillator (24 MHz)
|
||||
+ - description: GMAC0 RMII reference
|
||||
+ - description: GMAC0 RGMII RX
|
||||
+ - description: STG AXI/AHB
|
||||
+ - description: APB Bus
|
||||
+ - description: GMAC0 GTX
|
||||
+ - description: RTC Oscillator (32.768 kHz)
|
||||
+
|
||||
+ clock-names:
|
||||
+ oneOf:
|
||||
+ - minItems: 5
|
||||
+ items:
|
||||
+ - const: osc
|
||||
+ - enum:
|
||||
+ - gmac0_rmii_refin
|
||||
+ - gmac0_rgmii_rxin
|
||||
+ - const: stg_axiahb
|
||||
+ - const: apb_bus
|
||||
+ - const: gmac0_gtxclk
|
||||
+ - const: rtc_osc
|
||||
+
|
||||
+ - minItems: 6
|
||||
+ items:
|
||||
+ - const: osc
|
||||
+ - const: gmac0_rmii_refin
|
||||
+ - const: gmac0_rgmii_rxin
|
||||
+ - const: stg_axiahb
|
||||
+ - const: apb_bus
|
||||
+ - const: gmac0_gtxclk
|
||||
+ - const: rtc_osc
|
||||
+
|
||||
+ '#clock-cells':
|
||||
+ const: 1
|
||||
+ description:
|
||||
+ See <dt-bindings/clock/starfive,jh7110-crg.h> for valid indices.
|
||||
+
|
||||
+ '#reset-cells':
|
||||
+ const: 1
|
||||
+ description:
|
||||
+ See <dt-bindings/reset/starfive,jh7110-crg.h> for valid indices.
|
||||
+
|
||||
+required:
|
||||
+ - compatible
|
||||
+ - reg
|
||||
+ - clocks
|
||||
+ - clock-names
|
||||
+ - '#clock-cells'
|
||||
+ - '#reset-cells'
|
||||
+
|
||||
+additionalProperties: false
|
||||
+
|
||||
+examples:
|
||||
+ - |
|
||||
+ #include <dt-bindings/clock/starfive,jh7110-crg.h>
|
||||
+
|
||||
+ clock-controller@17000000 {
|
||||
+ compatible = "starfive,jh7110-aoncrg";
|
||||
+ reg = <0x17000000 0x10000>;
|
||||
+ clocks = <&osc>, <&gmac0_rmii_refin>,
|
||||
+ <&gmac0_rgmii_rxin>,
|
||||
+ <&syscrg JH7110_SYSCLK_STG_AXIAHB>,
|
||||
+ <&syscrg JH7110_SYSCLK_APB_BUS>,
|
||||
+ <&syscrg JH7110_SYSCLK_GMAC0_GTXCLK>,
|
||||
+ <&rtc_osc>;
|
||||
+ clock-names = "osc", "gmac0_rmii_refin",
|
||||
+ "gmac0_rgmii_rxin", "stg_axiahb",
|
||||
+ "apb_bus", "gmac0_gtxclk",
|
||||
+ "rtc_osc";
|
||||
+ #clock-cells = <1>;
|
||||
+ #reset-cells = <1>;
|
||||
+ };
|
||||
--- a/include/dt-bindings/clock/starfive,jh7110-crg.h
|
||||
+++ b/include/dt-bindings/clock/starfive,jh7110-crg.h
|
||||
@@ -200,4 +200,22 @@
|
||||
|
||||
#define JH7110_SYSCLK_END 190
|
||||
|
||||
+/* AONCRG clocks */
|
||||
+#define JH7110_AONCLK_OSC_DIV4 0
|
||||
+#define JH7110_AONCLK_APB_FUNC 1
|
||||
+#define JH7110_AONCLK_GMAC0_AHB 2
|
||||
+#define JH7110_AONCLK_GMAC0_AXI 3
|
||||
+#define JH7110_AONCLK_GMAC0_RMII_RTX 4
|
||||
+#define JH7110_AONCLK_GMAC0_TX 5
|
||||
+#define JH7110_AONCLK_GMAC0_TX_INV 6
|
||||
+#define JH7110_AONCLK_GMAC0_RX 7
|
||||
+#define JH7110_AONCLK_GMAC0_RX_INV 8
|
||||
+#define JH7110_AONCLK_OTPC_APB 9
|
||||
+#define JH7110_AONCLK_RTC_APB 10
|
||||
+#define JH7110_AONCLK_RTC_INTERNAL 11
|
||||
+#define JH7110_AONCLK_RTC_32K 12
|
||||
+#define JH7110_AONCLK_RTC_CAL 13
|
||||
+
|
||||
+#define JH7110_AONCLK_END 14
|
||||
+
|
||||
#endif /* __DT_BINDINGS_CLOCK_STARFIVE_JH7110_CRG_H__ */
|
||||
--- a/include/dt-bindings/reset/starfive,jh7110-crg.h
|
||||
+++ b/include/dt-bindings/reset/starfive,jh7110-crg.h
|
||||
@@ -139,4 +139,16 @@
|
||||
|
||||
#define JH7110_SYSRST_END 126
|
||||
|
||||
+/* AONCRG resets */
|
||||
+#define JH7110_AONRST_GMAC0_AXI 0
|
||||
+#define JH7110_AONRST_GMAC0_AHB 1
|
||||
+#define JH7110_AONRST_IOMUX 2
|
||||
+#define JH7110_AONRST_PMU_APB 3
|
||||
+#define JH7110_AONRST_PMU_WKUP 4
|
||||
+#define JH7110_AONRST_RTC_APB 5
|
||||
+#define JH7110_AONRST_RTC_CAL 6
|
||||
+#define JH7110_AONRST_RTC_32K 7
|
||||
+
|
||||
+#define JH7110_AONRST_END 8
|
||||
+
|
||||
#endif /* __DT_BINDINGS_RESET_STARFIVE_JH7110_CRG_H__ */
|
@ -0,0 +1,53 @@
|
||||
From 124f322d1c42232e439ea9a356d68caf1d0656f3 Mon Sep 17 00:00:00 2001
|
||||
From: Hal Feng <hal.feng@starfivetech.com>
|
||||
Date: Sat, 1 Apr 2023 19:19:15 +0800
|
||||
Subject: [PATCH 003/122] clk: starfive: Replace SOC_STARFIVE with
|
||||
ARCH_STARFIVE
|
||||
|
||||
Using ARCH_FOO symbol is preferred than SOC_FOO.
|
||||
Set obj-y for starfive/ in Makefile, so the StarFive drivers
|
||||
can be compiled with COMPILE_TEST=y but ARCH_STARFIVE=n.
|
||||
|
||||
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
|
||||
Reviewed-by: Heiko Stuebner <heiko.stuebner@vrull.eu>
|
||||
Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
|
||||
Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
|
||||
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
|
||||
---
|
||||
drivers/clk/Makefile | 2 +-
|
||||
drivers/clk/starfive/Kconfig | 6 +++---
|
||||
2 files changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/drivers/clk/Makefile
|
||||
+++ b/drivers/clk/Makefile
|
||||
@@ -117,7 +117,7 @@ obj-$(CONFIG_PLAT_SPEAR) += spear/
|
||||
obj-y += sprd/
|
||||
obj-$(CONFIG_ARCH_STI) += st/
|
||||
obj-$(CONFIG_ARCH_STM32) += stm32/
|
||||
-obj-$(CONFIG_SOC_STARFIVE) += starfive/
|
||||
+obj-y += starfive/
|
||||
obj-$(CONFIG_ARCH_SUNXI) += sunxi/
|
||||
obj-y += sunxi-ng/
|
||||
obj-$(CONFIG_ARCH_TEGRA) += tegra/
|
||||
--- a/drivers/clk/starfive/Kconfig
|
||||
+++ b/drivers/clk/starfive/Kconfig
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
config CLK_STARFIVE_JH7100
|
||||
bool "StarFive JH7100 clock support"
|
||||
- depends on SOC_STARFIVE || COMPILE_TEST
|
||||
- default SOC_STARFIVE
|
||||
+ depends on ARCH_STARFIVE || COMPILE_TEST
|
||||
+ default ARCH_STARFIVE
|
||||
help
|
||||
Say yes here to support the clock controller on the StarFive JH7100
|
||||
SoC.
|
||||
@@ -11,7 +11,7 @@ config CLK_STARFIVE_JH7100
|
||||
config CLK_STARFIVE_JH7100_AUDIO
|
||||
tristate "StarFive JH7100 audio clock support"
|
||||
depends on CLK_STARFIVE_JH7100
|
||||
- default m if SOC_STARFIVE
|
||||
+ default m if ARCH_STARFIVE
|
||||
help
|
||||
Say Y or M here to support the audio clocks on the StarFive JH7100
|
||||
SoC.
|
@ -0,0 +1,749 @@
|
||||
From 6f14eb919e5b92076e17aec5388655348963eef7 Mon Sep 17 00:00:00 2001
|
||||
From: Emil Renner Berthing <kernel@esmil.dk>
|
||||
Date: Sat, 1 Apr 2023 19:19:16 +0800
|
||||
Subject: [PATCH 004/122] clk: starfive: Factor out common JH7100 and JH7110
|
||||
code
|
||||
|
||||
The clock control registers on the StarFive JH7100 and JH7110 work
|
||||
identically, so factor out the code then drivers for the two SoCs
|
||||
can share it without depending on each other. No functional change.
|
||||
|
||||
Tested-by: Tommaso Merciai <tomm.merciai@gmail.com>
|
||||
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
|
||||
Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
|
||||
Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
|
||||
Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
|
||||
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
|
||||
---
|
||||
drivers/clk/starfive/Kconfig | 5 +
|
||||
drivers/clk/starfive/Makefile | 3 +-
|
||||
drivers/clk/starfive/clk-starfive-jh7100.c | 325 --------------------
|
||||
drivers/clk/starfive/clk-starfive-jh7100.h | 2 +
|
||||
drivers/clk/starfive/clk-starfive-jh71x0.c | 333 +++++++++++++++++++++
|
||||
5 files changed, 342 insertions(+), 326 deletions(-)
|
||||
create mode 100644 drivers/clk/starfive/clk-starfive-jh71x0.c
|
||||
|
||||
--- a/drivers/clk/starfive/Kconfig
|
||||
+++ b/drivers/clk/starfive/Kconfig
|
||||
@@ -1,8 +1,12 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
+config CLK_STARFIVE_JH71X0
|
||||
+ bool
|
||||
+
|
||||
config CLK_STARFIVE_JH7100
|
||||
bool "StarFive JH7100 clock support"
|
||||
depends on ARCH_STARFIVE || COMPILE_TEST
|
||||
+ select CLK_STARFIVE_JH71X0
|
||||
default ARCH_STARFIVE
|
||||
help
|
||||
Say yes here to support the clock controller on the StarFive JH7100
|
||||
@@ -11,6 +15,7 @@ config CLK_STARFIVE_JH7100
|
||||
config CLK_STARFIVE_JH7100_AUDIO
|
||||
tristate "StarFive JH7100 audio clock support"
|
||||
depends on CLK_STARFIVE_JH7100
|
||||
+ select CLK_STARFIVE_JH71X0
|
||||
default m if ARCH_STARFIVE
|
||||
help
|
||||
Say Y or M here to support the audio clocks on the StarFive JH7100
|
||||
--- a/drivers/clk/starfive/Makefile
|
||||
+++ b/drivers/clk/starfive/Makefile
|
||||
@@ -1,4 +1,5 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
-# StarFive Clock
|
||||
+obj-$(CONFIG_CLK_STARFIVE_JH71X0) += clk-starfive-jh71x0.o
|
||||
+
|
||||
obj-$(CONFIG_CLK_STARFIVE_JH7100) += clk-starfive-jh7100.o
|
||||
obj-$(CONFIG_CLK_STARFIVE_JH7100_AUDIO) += clk-starfive-jh7100-audio.o
|
||||
--- a/drivers/clk/starfive/clk-starfive-jh7100.c
|
||||
+++ b/drivers/clk/starfive/clk-starfive-jh7100.c
|
||||
@@ -7,15 +7,10 @@
|
||||
* Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
|
||||
*/
|
||||
|
||||
-#include <linux/bits.h>
|
||||
#include <linux/clk-provider.h>
|
||||
-#include <linux/debugfs.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/init.h>
|
||||
-#include <linux/io.h>
|
||||
-#include <linux/kernel.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
-#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include <dt-bindings/clock/starfive-jh7100.h>
|
||||
@@ -269,326 +264,6 @@ static const struct jh7100_clk_data jh71
|
||||
JH7100_GATE(JH7100_CLK_SYSERR_APB, "syserr_apb", 0, JH7100_CLK_APB2_BUS),
|
||||
};
|
||||
|
||||
-static struct jh7100_clk *jh7100_clk_from(struct clk_hw *hw)
|
||||
-{
|
||||
- return container_of(hw, struct jh7100_clk, hw);
|
||||
-}
|
||||
-
|
||||
-static struct jh7100_clk_priv *jh7100_priv_from(struct jh7100_clk *clk)
|
||||
-{
|
||||
- return container_of(clk, struct jh7100_clk_priv, reg[clk->idx]);
|
||||
-}
|
||||
-
|
||||
-static u32 jh7100_clk_reg_get(struct jh7100_clk *clk)
|
||||
-{
|
||||
- struct jh7100_clk_priv *priv = jh7100_priv_from(clk);
|
||||
- void __iomem *reg = priv->base + 4 * clk->idx;
|
||||
-
|
||||
- return readl_relaxed(reg);
|
||||
-}
|
||||
-
|
||||
-static void jh7100_clk_reg_rmw(struct jh7100_clk *clk, u32 mask, u32 value)
|
||||
-{
|
||||
- struct jh7100_clk_priv *priv = jh7100_priv_from(clk);
|
||||
- void __iomem *reg = priv->base + 4 * clk->idx;
|
||||
- unsigned long flags;
|
||||
-
|
||||
- spin_lock_irqsave(&priv->rmw_lock, flags);
|
||||
- value |= readl_relaxed(reg) & ~mask;
|
||||
- writel_relaxed(value, reg);
|
||||
- spin_unlock_irqrestore(&priv->rmw_lock, flags);
|
||||
-}
|
||||
-
|
||||
-static int jh7100_clk_enable(struct clk_hw *hw)
|
||||
-{
|
||||
- struct jh7100_clk *clk = jh7100_clk_from(hw);
|
||||
-
|
||||
- jh7100_clk_reg_rmw(clk, JH7100_CLK_ENABLE, JH7100_CLK_ENABLE);
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-static void jh7100_clk_disable(struct clk_hw *hw)
|
||||
-{
|
||||
- struct jh7100_clk *clk = jh7100_clk_from(hw);
|
||||
-
|
||||
- jh7100_clk_reg_rmw(clk, JH7100_CLK_ENABLE, 0);
|
||||
-}
|
||||
-
|
||||
-static int jh7100_clk_is_enabled(struct clk_hw *hw)
|
||||
-{
|
||||
- struct jh7100_clk *clk = jh7100_clk_from(hw);
|
||||
-
|
||||
- return !!(jh7100_clk_reg_get(clk) & JH7100_CLK_ENABLE);
|
||||
-}
|
||||
-
|
||||
-static unsigned long jh7100_clk_recalc_rate(struct clk_hw *hw,
|
||||
- unsigned long parent_rate)
|
||||
-{
|
||||
- struct jh7100_clk *clk = jh7100_clk_from(hw);
|
||||
- u32 div = jh7100_clk_reg_get(clk) & JH7100_CLK_DIV_MASK;
|
||||
-
|
||||
- return div ? parent_rate / div : 0;
|
||||
-}
|
||||
-
|
||||
-static int jh7100_clk_determine_rate(struct clk_hw *hw,
|
||||
- struct clk_rate_request *req)
|
||||
-{
|
||||
- struct jh7100_clk *clk = jh7100_clk_from(hw);
|
||||
- unsigned long parent = req->best_parent_rate;
|
||||
- unsigned long rate = clamp(req->rate, req->min_rate, req->max_rate);
|
||||
- unsigned long div = min_t(unsigned long, DIV_ROUND_UP(parent, rate), clk->max_div);
|
||||
- unsigned long result = parent / div;
|
||||
-
|
||||
- /*
|
||||
- * we want the result clamped by min_rate and max_rate if possible:
|
||||
- * case 1: div hits the max divider value, which means it's less than
|
||||
- * parent / rate, so the result is greater than rate and min_rate in
|
||||
- * particular. we can't do anything about result > max_rate because the
|
||||
- * divider doesn't go any further.
|
||||
- * case 2: div = DIV_ROUND_UP(parent, rate) which means the result is
|
||||
- * always lower or equal to rate and max_rate. however the result may
|
||||
- * turn out lower than min_rate, but then the next higher rate is fine:
|
||||
- * div - 1 = ceil(parent / rate) - 1 < parent / rate
|
||||
- * and thus
|
||||
- * min_rate <= rate < parent / (div - 1)
|
||||
- */
|
||||
- if (result < req->min_rate && div > 1)
|
||||
- result = parent / (div - 1);
|
||||
-
|
||||
- req->rate = result;
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-static int jh7100_clk_set_rate(struct clk_hw *hw,
|
||||
- unsigned long rate,
|
||||
- unsigned long parent_rate)
|
||||
-{
|
||||
- struct jh7100_clk *clk = jh7100_clk_from(hw);
|
||||
- unsigned long div = clamp(DIV_ROUND_CLOSEST(parent_rate, rate),
|
||||
- 1UL, (unsigned long)clk->max_div);
|
||||
-
|
||||
- jh7100_clk_reg_rmw(clk, JH7100_CLK_DIV_MASK, div);
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-static unsigned long jh7100_clk_frac_recalc_rate(struct clk_hw *hw,
|
||||
- unsigned long parent_rate)
|
||||
-{
|
||||
- struct jh7100_clk *clk = jh7100_clk_from(hw);
|
||||
- u32 reg = jh7100_clk_reg_get(clk);
|
||||
- unsigned long div100 = 100 * (reg & JH7100_CLK_INT_MASK) +
|
||||
- ((reg & JH7100_CLK_FRAC_MASK) >> JH7100_CLK_FRAC_SHIFT);
|
||||
-
|
||||
- return (div100 >= JH7100_CLK_FRAC_MIN) ? 100 * parent_rate / div100 : 0;
|
||||
-}
|
||||
-
|
||||
-static int jh7100_clk_frac_determine_rate(struct clk_hw *hw,
|
||||
- struct clk_rate_request *req)
|
||||
-{
|
||||
- unsigned long parent100 = 100 * req->best_parent_rate;
|
||||
- unsigned long rate = clamp(req->rate, req->min_rate, req->max_rate);
|
||||
- unsigned long div100 = clamp(DIV_ROUND_CLOSEST(parent100, rate),
|
||||
- JH7100_CLK_FRAC_MIN, JH7100_CLK_FRAC_MAX);
|
||||
- unsigned long result = parent100 / div100;
|
||||
-
|
||||
- /* clamp the result as in jh7100_clk_determine_rate() above */
|
||||
- if (result > req->max_rate && div100 < JH7100_CLK_FRAC_MAX)
|
||||
- result = parent100 / (div100 + 1);
|
||||
- if (result < req->min_rate && div100 > JH7100_CLK_FRAC_MIN)
|
||||
- result = parent100 / (div100 - 1);
|
||||
-
|
||||
- req->rate = result;
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-static int jh7100_clk_frac_set_rate(struct clk_hw *hw,
|
||||
- unsigned long rate,
|
||||
- unsigned long parent_rate)
|
||||
-{
|
||||
- struct jh7100_clk *clk = jh7100_clk_from(hw);
|
||||
- unsigned long div100 = clamp(DIV_ROUND_CLOSEST(100 * parent_rate, rate),
|
||||
- JH7100_CLK_FRAC_MIN, JH7100_CLK_FRAC_MAX);
|
||||
- u32 value = ((div100 % 100) << JH7100_CLK_FRAC_SHIFT) | (div100 / 100);
|
||||
-
|
||||
- jh7100_clk_reg_rmw(clk, JH7100_CLK_DIV_MASK, value);
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-static u8 jh7100_clk_get_parent(struct clk_hw *hw)
|
||||
-{
|
||||
- struct jh7100_clk *clk = jh7100_clk_from(hw);
|
||||
- u32 value = jh7100_clk_reg_get(clk);
|
||||
-
|
||||
- return (value & JH7100_CLK_MUX_MASK) >> JH7100_CLK_MUX_SHIFT;
|
||||
-}
|
||||
-
|
||||
-static int jh7100_clk_set_parent(struct clk_hw *hw, u8 index)
|
||||
-{
|
||||
- struct jh7100_clk *clk = jh7100_clk_from(hw);
|
||||
- u32 value = (u32)index << JH7100_CLK_MUX_SHIFT;
|
||||
-
|
||||
- jh7100_clk_reg_rmw(clk, JH7100_CLK_MUX_MASK, value);
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-static int jh7100_clk_mux_determine_rate(struct clk_hw *hw,
|
||||
- struct clk_rate_request *req)
|
||||
-{
|
||||
- return clk_mux_determine_rate_flags(hw, req, 0);
|
||||
-}
|
||||
-
|
||||
-static int jh7100_clk_get_phase(struct clk_hw *hw)
|
||||
-{
|
||||
- struct jh7100_clk *clk = jh7100_clk_from(hw);
|
||||
- u32 value = jh7100_clk_reg_get(clk);
|
||||
-
|
||||
- return (value & JH7100_CLK_INVERT) ? 180 : 0;
|
||||
-}
|
||||
-
|
||||
-static int jh7100_clk_set_phase(struct clk_hw *hw, int degrees)
|
||||
-{
|
||||
- struct jh7100_clk *clk = jh7100_clk_from(hw);
|
||||
- u32 value;
|
||||
-
|
||||
- if (degrees == 0)
|
||||
- value = 0;
|
||||
- else if (degrees == 180)
|
||||
- value = JH7100_CLK_INVERT;
|
||||
- else
|
||||
- return -EINVAL;
|
||||
-
|
||||
- jh7100_clk_reg_rmw(clk, JH7100_CLK_INVERT, value);
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-#ifdef CONFIG_DEBUG_FS
|
||||
-static void jh7100_clk_debug_init(struct clk_hw *hw, struct dentry *dentry)
|
||||
-{
|
||||
- static const struct debugfs_reg32 jh7100_clk_reg = {
|
||||
- .name = "CTRL",
|
||||
- .offset = 0,
|
||||
- };
|
||||
- struct jh7100_clk *clk = jh7100_clk_from(hw);
|
||||
- struct jh7100_clk_priv *priv = jh7100_priv_from(clk);
|
||||
- struct debugfs_regset32 *regset;
|
||||
-
|
||||
- regset = devm_kzalloc(priv->dev, sizeof(*regset), GFP_KERNEL);
|
||||
- if (!regset)
|
||||
- return;
|
||||
-
|
||||
- regset->regs = &jh7100_clk_reg;
|
||||
- regset->nregs = 1;
|
||||
- regset->base = priv->base + 4 * clk->idx;
|
||||
-
|
||||
- debugfs_create_regset32("registers", 0400, dentry, regset);
|
||||
-}
|
||||
-#else
|
||||
-#define jh7100_clk_debug_init NULL
|
||||
-#endif
|
||||
-
|
||||
-static const struct clk_ops jh7100_clk_gate_ops = {
|
||||
- .enable = jh7100_clk_enable,
|
||||
- .disable = jh7100_clk_disable,
|
||||
- .is_enabled = jh7100_clk_is_enabled,
|
||||
- .debug_init = jh7100_clk_debug_init,
|
||||
-};
|
||||
-
|
||||
-static const struct clk_ops jh7100_clk_div_ops = {
|
||||
- .recalc_rate = jh7100_clk_recalc_rate,
|
||||
- .determine_rate = jh7100_clk_determine_rate,
|
||||
- .set_rate = jh7100_clk_set_rate,
|
||||
- .debug_init = jh7100_clk_debug_init,
|
||||
-};
|
||||
-
|
||||
-static const struct clk_ops jh7100_clk_fdiv_ops = {
|
||||
- .recalc_rate = jh7100_clk_frac_recalc_rate,
|
||||
- .determine_rate = jh7100_clk_frac_determine_rate,
|
||||
- .set_rate = jh7100_clk_frac_set_rate,
|
||||
- .debug_init = jh7100_clk_debug_init,
|
||||
-};
|
||||
-
|
||||
-static const struct clk_ops jh7100_clk_gdiv_ops = {
|
||||
- .enable = jh7100_clk_enable,
|
||||
- .disable = jh7100_clk_disable,
|
||||
- .is_enabled = jh7100_clk_is_enabled,
|
||||
- .recalc_rate = jh7100_clk_recalc_rate,
|
||||
- .determine_rate = jh7100_clk_determine_rate,
|
||||
- .set_rate = jh7100_clk_set_rate,
|
||||
- .debug_init = jh7100_clk_debug_init,
|
||||
-};
|
||||
-
|
||||
-static const struct clk_ops jh7100_clk_mux_ops = {
|
||||
- .determine_rate = jh7100_clk_mux_determine_rate,
|
||||
- .set_parent = jh7100_clk_set_parent,
|
||||
- .get_parent = jh7100_clk_get_parent,
|
||||
- .debug_init = jh7100_clk_debug_init,
|
||||
-};
|
||||
-
|
||||
-static const struct clk_ops jh7100_clk_gmux_ops = {
|
||||
- .enable = jh7100_clk_enable,
|
||||
- .disable = jh7100_clk_disable,
|
||||
- .is_enabled = jh7100_clk_is_enabled,
|
||||
- .determine_rate = jh7100_clk_mux_determine_rate,
|
||||
- .set_parent = jh7100_clk_set_parent,
|
||||
- .get_parent = jh7100_clk_get_parent,
|
||||
- .debug_init = jh7100_clk_debug_init,
|
||||
-};
|
||||
-
|
||||
-static const struct clk_ops jh7100_clk_mdiv_ops = {
|
||||
- .recalc_rate = jh7100_clk_recalc_rate,
|
||||
- .determine_rate = jh7100_clk_determine_rate,
|
||||
- .get_parent = jh7100_clk_get_parent,
|
||||
- .set_parent = jh7100_clk_set_parent,
|
||||
- .set_rate = jh7100_clk_set_rate,
|
||||
- .debug_init = jh7100_clk_debug_init,
|
||||
-};
|
||||
-
|
||||
-static const struct clk_ops jh7100_clk_gmd_ops = {
|
||||
- .enable = jh7100_clk_enable,
|
||||
- .disable = jh7100_clk_disable,
|
||||
- .is_enabled = jh7100_clk_is_enabled,
|
||||
- .recalc_rate = jh7100_clk_recalc_rate,
|
||||
- .determine_rate = jh7100_clk_determine_rate,
|
||||
- .get_parent = jh7100_clk_get_parent,
|
||||
- .set_parent = jh7100_clk_set_parent,
|
||||
- .set_rate = jh7100_clk_set_rate,
|
||||
- .debug_init = jh7100_clk_debug_init,
|
||||
-};
|
||||
-
|
||||
-static const struct clk_ops jh7100_clk_inv_ops = {
|
||||
- .get_phase = jh7100_clk_get_phase,
|
||||
- .set_phase = jh7100_clk_set_phase,
|
||||
- .debug_init = jh7100_clk_debug_init,
|
||||
-};
|
||||
-
|
||||
-const struct clk_ops *starfive_jh7100_clk_ops(u32 max)
|
||||
-{
|
||||
- if (max & JH7100_CLK_DIV_MASK) {
|
||||
- if (max & JH7100_CLK_MUX_MASK) {
|
||||
- if (max & JH7100_CLK_ENABLE)
|
||||
- return &jh7100_clk_gmd_ops;
|
||||
- return &jh7100_clk_mdiv_ops;
|
||||
- }
|
||||
- if (max & JH7100_CLK_ENABLE)
|
||||
- return &jh7100_clk_gdiv_ops;
|
||||
- if (max == JH7100_CLK_FRAC_MAX)
|
||||
- return &jh7100_clk_fdiv_ops;
|
||||
- return &jh7100_clk_div_ops;
|
||||
- }
|
||||
-
|
||||
- if (max & JH7100_CLK_MUX_MASK) {
|
||||
- if (max & JH7100_CLK_ENABLE)
|
||||
- return &jh7100_clk_gmux_ops;
|
||||
- return &jh7100_clk_mux_ops;
|
||||
- }
|
||||
-
|
||||
- if (max & JH7100_CLK_ENABLE)
|
||||
- return &jh7100_clk_gate_ops;
|
||||
-
|
||||
- return &jh7100_clk_inv_ops;
|
||||
-}
|
||||
-EXPORT_SYMBOL_GPL(starfive_jh7100_clk_ops);
|
||||
-
|
||||
static struct clk_hw *jh7100_clk_get(struct of_phandle_args *clkspec, void *data)
|
||||
{
|
||||
struct jh7100_clk_priv *priv = data;
|
||||
--- a/drivers/clk/starfive/clk-starfive-jh7100.h
|
||||
+++ b/drivers/clk/starfive/clk-starfive-jh7100.h
|
||||
@@ -4,6 +4,8 @@
|
||||
|
||||
#include <linux/bits.h>
|
||||
#include <linux/clk-provider.h>
|
||||
+#include <linux/device.h>
|
||||
+#include <linux/spinlock.h>
|
||||
|
||||
/* register fields */
|
||||
#define JH7100_CLK_ENABLE BIT(31)
|
||||
--- /dev/null
|
||||
+++ b/drivers/clk/starfive/clk-starfive-jh71x0.c
|
||||
@@ -0,0 +1,333 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0
|
||||
+/*
|
||||
+ * StarFive JH7100 Clock Generator Driver
|
||||
+ *
|
||||
+ * Copyright (C) 2021-2022 Emil Renner Berthing <kernel@esmil.dk>
|
||||
+ */
|
||||
+
|
||||
+#include <linux/clk-provider.h>
|
||||
+#include <linux/debugfs.h>
|
||||
+#include <linux/device.h>
|
||||
+#include <linux/io.h>
|
||||
+
|
||||
+#include "clk-starfive-jh7100.h"
|
||||
+
|
||||
+static struct jh7100_clk *jh7100_clk_from(struct clk_hw *hw)
|
||||
+{
|
||||
+ return container_of(hw, struct jh7100_clk, hw);
|
||||
+}
|
||||
+
|
||||
+static struct jh7100_clk_priv *jh7100_priv_from(struct jh7100_clk *clk)
|
||||
+{
|
||||
+ return container_of(clk, struct jh7100_clk_priv, reg[clk->idx]);
|
||||
+}
|
||||
+
|
||||
+static u32 jh7100_clk_reg_get(struct jh7100_clk *clk)
|
||||
+{
|
||||
+ struct jh7100_clk_priv *priv = jh7100_priv_from(clk);
|
||||
+ void __iomem *reg = priv->base + 4 * clk->idx;
|
||||
+
|
||||
+ return readl_relaxed(reg);
|
||||
+}
|
||||
+
|
||||
+static void jh7100_clk_reg_rmw(struct jh7100_clk *clk, u32 mask, u32 value)
|
||||
+{
|
||||
+ struct jh7100_clk_priv *priv = jh7100_priv_from(clk);
|
||||
+ void __iomem *reg = priv->base + 4 * clk->idx;
|
||||
+ unsigned long flags;
|
||||
+
|
||||
+ spin_lock_irqsave(&priv->rmw_lock, flags);
|
||||
+ value |= readl_relaxed(reg) & ~mask;
|
||||
+ writel_relaxed(value, reg);
|
||||
+ spin_unlock_irqrestore(&priv->rmw_lock, flags);
|
||||
+}
|
||||
+
|
||||
+static int jh7100_clk_enable(struct clk_hw *hw)
|
||||
+{
|
||||
+ struct jh7100_clk *clk = jh7100_clk_from(hw);
|
||||
+
|
||||
+ jh7100_clk_reg_rmw(clk, JH7100_CLK_ENABLE, JH7100_CLK_ENABLE);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void jh7100_clk_disable(struct clk_hw *hw)
|
||||
+{
|
||||
+ struct jh7100_clk *clk = jh7100_clk_from(hw);
|
||||
+
|
||||
+ jh7100_clk_reg_rmw(clk, JH7100_CLK_ENABLE, 0);
|
||||
+}
|
||||
+
|
||||
+static int jh7100_clk_is_enabled(struct clk_hw *hw)
|
||||
+{
|
||||
+ struct jh7100_clk *clk = jh7100_clk_from(hw);
|
||||
+
|
||||
+ return !!(jh7100_clk_reg_get(clk) & JH7100_CLK_ENABLE);
|
||||
+}
|
||||
+
|
||||
+static unsigned long jh7100_clk_recalc_rate(struct clk_hw *hw,
|
||||
+ unsigned long parent_rate)
|
||||
+{
|
||||
+ struct jh7100_clk *clk = jh7100_clk_from(hw);
|
||||
+ u32 div = jh7100_clk_reg_get(clk) & JH7100_CLK_DIV_MASK;
|
||||
+
|
||||
+ return div ? parent_rate / div : 0;
|
||||
+}
|
||||
+
|
||||
+static int jh7100_clk_determine_rate(struct clk_hw *hw,
|
||||
+ struct clk_rate_request *req)
|
||||
+{
|
||||
+ struct jh7100_clk *clk = jh7100_clk_from(hw);
|
||||
+ unsigned long parent = req->best_parent_rate;
|
||||
+ unsigned long rate = clamp(req->rate, req->min_rate, req->max_rate);
|
||||
+ unsigned long div = min_t(unsigned long, DIV_ROUND_UP(parent, rate), clk->max_div);
|
||||
+ unsigned long result = parent / div;
|
||||
+
|
||||
+ /*
|
||||
+ * we want the result clamped by min_rate and max_rate if possible:
|
||||
+ * case 1: div hits the max divider value, which means it's less than
|
||||
+ * parent / rate, so the result is greater than rate and min_rate in
|
||||
+ * particular. we can't do anything about result > max_rate because the
|
||||
+ * divider doesn't go any further.
|
||||
+ * case 2: div = DIV_ROUND_UP(parent, rate) which means the result is
|
||||
+ * always lower or equal to rate and max_rate. however the result may
|
||||
+ * turn out lower than min_rate, but then the next higher rate is fine:
|
||||
+ * div - 1 = ceil(parent / rate) - 1 < parent / rate
|
||||
+ * and thus
|
||||
+ * min_rate <= rate < parent / (div - 1)
|
||||
+ */
|
||||
+ if (result < req->min_rate && div > 1)
|
||||
+ result = parent / (div - 1);
|
||||
+
|
||||
+ req->rate = result;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int jh7100_clk_set_rate(struct clk_hw *hw,
|
||||
+ unsigned long rate,
|
||||
+ unsigned long parent_rate)
|
||||
+{
|
||||
+ struct jh7100_clk *clk = jh7100_clk_from(hw);
|
||||
+ unsigned long div = clamp(DIV_ROUND_CLOSEST(parent_rate, rate),
|
||||
+ 1UL, (unsigned long)clk->max_div);
|
||||
+
|
||||
+ jh7100_clk_reg_rmw(clk, JH7100_CLK_DIV_MASK, div);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static unsigned long jh7100_clk_frac_recalc_rate(struct clk_hw *hw,
|
||||
+ unsigned long parent_rate)
|
||||
+{
|
||||
+ struct jh7100_clk *clk = jh7100_clk_from(hw);
|
||||
+ u32 reg = jh7100_clk_reg_get(clk);
|
||||
+ unsigned long div100 = 100 * (reg & JH7100_CLK_INT_MASK) +
|
||||
+ ((reg & JH7100_CLK_FRAC_MASK) >> JH7100_CLK_FRAC_SHIFT);
|
||||
+
|
||||
+ return (div100 >= JH7100_CLK_FRAC_MIN) ? 100 * parent_rate / div100 : 0;
|
||||
+}
|
||||
+
|
||||
+static int jh7100_clk_frac_determine_rate(struct clk_hw *hw,
|
||||
+ struct clk_rate_request *req)
|
||||
+{
|
||||
+ unsigned long parent100 = 100 * req->best_parent_rate;
|
||||
+ unsigned long rate = clamp(req->rate, req->min_rate, req->max_rate);
|
||||
+ unsigned long div100 = clamp(DIV_ROUND_CLOSEST(parent100, rate),
|
||||
+ JH7100_CLK_FRAC_MIN, JH7100_CLK_FRAC_MAX);
|
||||
+ unsigned long result = parent100 / div100;
|
||||
+
|
||||
+ /* clamp the result as in jh7100_clk_determine_rate() above */
|
||||
+ if (result > req->max_rate && div100 < JH7100_CLK_FRAC_MAX)
|
||||
+ result = parent100 / (div100 + 1);
|
||||
+ if (result < req->min_rate && div100 > JH7100_CLK_FRAC_MIN)
|
||||
+ result = parent100 / (div100 - 1);
|
||||
+
|
||||
+ req->rate = result;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int jh7100_clk_frac_set_rate(struct clk_hw *hw,
|
||||
+ unsigned long rate,
|
||||
+ unsigned long parent_rate)
|
||||
+{
|
||||
+ struct jh7100_clk *clk = jh7100_clk_from(hw);
|
||||
+ unsigned long div100 = clamp(DIV_ROUND_CLOSEST(100 * parent_rate, rate),
|
||||
+ JH7100_CLK_FRAC_MIN, JH7100_CLK_FRAC_MAX);
|
||||
+ u32 value = ((div100 % 100) << JH7100_CLK_FRAC_SHIFT) | (div100 / 100);
|
||||
+
|
||||
+ jh7100_clk_reg_rmw(clk, JH7100_CLK_DIV_MASK, value);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static u8 jh7100_clk_get_parent(struct clk_hw *hw)
|
||||
+{
|
||||
+ struct jh7100_clk *clk = jh7100_clk_from(hw);
|
||||
+ u32 value = jh7100_clk_reg_get(clk);
|
||||
+
|
||||
+ return (value & JH7100_CLK_MUX_MASK) >> JH7100_CLK_MUX_SHIFT;
|
||||
+}
|
||||
+
|
||||
+static int jh7100_clk_set_parent(struct clk_hw *hw, u8 index)
|
||||
+{
|
||||
+ struct jh7100_clk *clk = jh7100_clk_from(hw);
|
||||
+ u32 value = (u32)index << JH7100_CLK_MUX_SHIFT;
|
||||
+
|
||||
+ jh7100_clk_reg_rmw(clk, JH7100_CLK_MUX_MASK, value);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int jh7100_clk_mux_determine_rate(struct clk_hw *hw,
|
||||
+ struct clk_rate_request *req)
|
||||
+{
|
||||
+ return clk_mux_determine_rate_flags(hw, req, 0);
|
||||
+}
|
||||
+
|
||||
+static int jh7100_clk_get_phase(struct clk_hw *hw)
|
||||
+{
|
||||
+ struct jh7100_clk *clk = jh7100_clk_from(hw);
|
||||
+ u32 value = jh7100_clk_reg_get(clk);
|
||||
+
|
||||
+ return (value & JH7100_CLK_INVERT) ? 180 : 0;
|
||||
+}
|
||||
+
|
||||
+static int jh7100_clk_set_phase(struct clk_hw *hw, int degrees)
|
||||
+{
|
||||
+ struct jh7100_clk *clk = jh7100_clk_from(hw);
|
||||
+ u32 value;
|
||||
+
|
||||
+ if (degrees == 0)
|
||||
+ value = 0;
|
||||
+ else if (degrees == 180)
|
||||
+ value = JH7100_CLK_INVERT;
|
||||
+ else
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ jh7100_clk_reg_rmw(clk, JH7100_CLK_INVERT, value);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#ifdef CONFIG_DEBUG_FS
|
||||
+static void jh7100_clk_debug_init(struct clk_hw *hw, struct dentry *dentry)
|
||||
+{
|
||||
+ static const struct debugfs_reg32 jh7100_clk_reg = {
|
||||
+ .name = "CTRL",
|
||||
+ .offset = 0,
|
||||
+ };
|
||||
+ struct jh7100_clk *clk = jh7100_clk_from(hw);
|
||||
+ struct jh7100_clk_priv *priv = jh7100_priv_from(clk);
|
||||
+ struct debugfs_regset32 *regset;
|
||||
+
|
||||
+ regset = devm_kzalloc(priv->dev, sizeof(*regset), GFP_KERNEL);
|
||||
+ if (!regset)
|
||||
+ return;
|
||||
+
|
||||
+ regset->regs = &jh7100_clk_reg;
|
||||
+ regset->nregs = 1;
|
||||
+ regset->base = priv->base + 4 * clk->idx;
|
||||
+
|
||||
+ debugfs_create_regset32("registers", 0400, dentry, regset);
|
||||
+}
|
||||
+#else
|
||||
+#define jh7100_clk_debug_init NULL
|
||||
+#endif
|
||||
+
|
||||
+static const struct clk_ops jh7100_clk_gate_ops = {
|
||||
+ .enable = jh7100_clk_enable,
|
||||
+ .disable = jh7100_clk_disable,
|
||||
+ .is_enabled = jh7100_clk_is_enabled,
|
||||
+ .debug_init = jh7100_clk_debug_init,
|
||||
+};
|
||||
+
|
||||
+static const struct clk_ops jh7100_clk_div_ops = {
|
||||
+ .recalc_rate = jh7100_clk_recalc_rate,
|
||||
+ .determine_rate = jh7100_clk_determine_rate,
|
||||
+ .set_rate = jh7100_clk_set_rate,
|
||||
+ .debug_init = jh7100_clk_debug_init,
|
||||
+};
|
||||
+
|
||||
+static const struct clk_ops jh7100_clk_fdiv_ops = {
|
||||
+ .recalc_rate = jh7100_clk_frac_recalc_rate,
|
||||
+ .determine_rate = jh7100_clk_frac_determine_rate,
|
||||
+ .set_rate = jh7100_clk_frac_set_rate,
|
||||
+ .debug_init = jh7100_clk_debug_init,
|
||||
+};
|
||||
+
|
||||
+static const struct clk_ops jh7100_clk_gdiv_ops = {
|
||||
+ .enable = jh7100_clk_enable,
|
||||
+ .disable = jh7100_clk_disable,
|
||||
+ .is_enabled = jh7100_clk_is_enabled,
|
||||
+ .recalc_rate = jh7100_clk_recalc_rate,
|
||||
+ .determine_rate = jh7100_clk_determine_rate,
|
||||
+ .set_rate = jh7100_clk_set_rate,
|
||||
+ .debug_init = jh7100_clk_debug_init,
|
||||
+};
|
||||
+
|
||||
+static const struct clk_ops jh7100_clk_mux_ops = {
|
||||
+ .determine_rate = jh7100_clk_mux_determine_rate,
|
||||
+ .set_parent = jh7100_clk_set_parent,
|
||||
+ .get_parent = jh7100_clk_get_parent,
|
||||
+ .debug_init = jh7100_clk_debug_init,
|
||||
+};
|
||||
+
|
||||
+static const struct clk_ops jh7100_clk_gmux_ops = {
|
||||
+ .enable = jh7100_clk_enable,
|
||||
+ .disable = jh7100_clk_disable,
|
||||
+ .is_enabled = jh7100_clk_is_enabled,
|
||||
+ .determine_rate = jh7100_clk_mux_determine_rate,
|
||||
+ .set_parent = jh7100_clk_set_parent,
|
||||
+ .get_parent = jh7100_clk_get_parent,
|
||||
+ .debug_init = jh7100_clk_debug_init,
|
||||
+};
|
||||
+
|
||||
+static const struct clk_ops jh7100_clk_mdiv_ops = {
|
||||
+ .recalc_rate = jh7100_clk_recalc_rate,
|
||||
+ .determine_rate = jh7100_clk_determine_rate,
|
||||
+ .get_parent = jh7100_clk_get_parent,
|
||||
+ .set_parent = jh7100_clk_set_parent,
|
||||
+ .set_rate = jh7100_clk_set_rate,
|
||||
+ .debug_init = jh7100_clk_debug_init,
|
||||
+};
|
||||
+
|
||||
+static const struct clk_ops jh7100_clk_gmd_ops = {
|
||||
+ .enable = jh7100_clk_enable,
|
||||
+ .disable = jh7100_clk_disable,
|
||||
+ .is_enabled = jh7100_clk_is_enabled,
|
||||
+ .recalc_rate = jh7100_clk_recalc_rate,
|
||||
+ .determine_rate = jh7100_clk_determine_rate,
|
||||
+ .get_parent = jh7100_clk_get_parent,
|
||||
+ .set_parent = jh7100_clk_set_parent,
|
||||
+ .set_rate = jh7100_clk_set_rate,
|
||||
+ .debug_init = jh7100_clk_debug_init,
|
||||
+};
|
||||
+
|
||||
+static const struct clk_ops jh7100_clk_inv_ops = {
|
||||
+ .get_phase = jh7100_clk_get_phase,
|
||||
+ .set_phase = jh7100_clk_set_phase,
|
||||
+ .debug_init = jh7100_clk_debug_init,
|
||||
+};
|
||||
+
|
||||
+const struct clk_ops *starfive_jh7100_clk_ops(u32 max)
|
||||
+{
|
||||
+ if (max & JH7100_CLK_DIV_MASK) {
|
||||
+ if (max & JH7100_CLK_MUX_MASK) {
|
||||
+ if (max & JH7100_CLK_ENABLE)
|
||||
+ return &jh7100_clk_gmd_ops;
|
||||
+ return &jh7100_clk_mdiv_ops;
|
||||
+ }
|
||||
+ if (max & JH7100_CLK_ENABLE)
|
||||
+ return &jh7100_clk_gdiv_ops;
|
||||
+ if (max == JH7100_CLK_FRAC_MAX)
|
||||
+ return &jh7100_clk_fdiv_ops;
|
||||
+ return &jh7100_clk_div_ops;
|
||||
+ }
|
||||
+
|
||||
+ if (max & JH7100_CLK_MUX_MASK) {
|
||||
+ if (max & JH7100_CLK_ENABLE)
|
||||
+ return &jh7100_clk_gmux_ops;
|
||||
+ return &jh7100_clk_mux_ops;
|
||||
+ }
|
||||
+
|
||||
+ if (max & JH7100_CLK_ENABLE)
|
||||
+ return &jh7100_clk_gate_ops;
|
||||
+
|
||||
+ return &jh7100_clk_inv_ops;
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(starfive_jh7100_clk_ops);
|
@ -0,0 +1,290 @@
|
||||
From 8daa4c812f3b32a4d56ab48945e552a137fca9b7 Mon Sep 17 00:00:00 2001
|
||||
From: Emil Renner Berthing <kernel@esmil.dk>
|
||||
Date: Sat, 1 Apr 2023 19:19:17 +0800
|
||||
Subject: [PATCH 005/122] clk: starfive: Rename clk-starfive-jh7100.h to
|
||||
clk-starfive-jh71x0.h
|
||||
|
||||
Rename clk-starfive-jh7100.h to clk-starfive-jh71x0.h for making
|
||||
the code to be common.
|
||||
|
||||
Tested-by: Tommaso Merciai <tomm.merciai@gmail.com>
|
||||
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
|
||||
Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
|
||||
Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
|
||||
Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
|
||||
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
|
||||
---
|
||||
drivers/clk/starfive/clk-starfive-jh7100-audio.c | 2 +-
|
||||
drivers/clk/starfive/clk-starfive-jh7100.c | 2 +-
|
||||
drivers/clk/starfive/clk-starfive-jh71x0.c | 2 +-
|
||||
.../starfive/{clk-starfive-jh7100.h => clk-starfive-jh71x0.h} | 0
|
||||
4 files changed, 3 insertions(+), 3 deletions(-)
|
||||
rename drivers/clk/starfive/{clk-starfive-jh7100.h => clk-starfive-jh71x0.h} (100%)
|
||||
|
||||
--- a/drivers/clk/starfive/clk-starfive-jh7100-audio.c
|
||||
+++ b/drivers/clk/starfive/clk-starfive-jh7100-audio.c
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
#include <dt-bindings/clock/starfive-jh7100-audio.h>
|
||||
|
||||
-#include "clk-starfive-jh7100.h"
|
||||
+#include "clk-starfive-jh71x0.h"
|
||||
|
||||
/* external clocks */
|
||||
#define JH7100_AUDCLK_AUDIO_SRC (JH7100_AUDCLK_END + 0)
|
||||
--- a/drivers/clk/starfive/clk-starfive-jh7100.c
|
||||
+++ b/drivers/clk/starfive/clk-starfive-jh7100.c
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
#include <dt-bindings/clock/starfive-jh7100.h>
|
||||
|
||||
-#include "clk-starfive-jh7100.h"
|
||||
+#include "clk-starfive-jh71x0.h"
|
||||
|
||||
/* external clocks */
|
||||
#define JH7100_CLK_OSC_SYS (JH7100_CLK_END + 0)
|
||||
--- a/drivers/clk/starfive/clk-starfive-jh71x0.c
|
||||
+++ b/drivers/clk/starfive/clk-starfive-jh71x0.c
|
||||
@@ -10,7 +10,7 @@
|
||||
#include <linux/device.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
-#include "clk-starfive-jh7100.h"
|
||||
+#include "clk-starfive-jh71x0.h"
|
||||
|
||||
static struct jh7100_clk *jh7100_clk_from(struct clk_hw *hw)
|
||||
{
|
||||
--- a/drivers/clk/starfive/clk-starfive-jh7100.h
|
||||
+++ /dev/null
|
||||
@@ -1,114 +0,0 @@
|
||||
-/* SPDX-License-Identifier: GPL-2.0 */
|
||||
-#ifndef __CLK_STARFIVE_JH7100_H
|
||||
-#define __CLK_STARFIVE_JH7100_H
|
||||
-
|
||||
-#include <linux/bits.h>
|
||||
-#include <linux/clk-provider.h>
|
||||
-#include <linux/device.h>
|
||||
-#include <linux/spinlock.h>
|
||||
-
|
||||
-/* register fields */
|
||||
-#define JH7100_CLK_ENABLE BIT(31)
|
||||
-#define JH7100_CLK_INVERT BIT(30)
|
||||
-#define JH7100_CLK_MUX_MASK GENMASK(27, 24)
|
||||
-#define JH7100_CLK_MUX_SHIFT 24
|
||||
-#define JH7100_CLK_DIV_MASK GENMASK(23, 0)
|
||||
-#define JH7100_CLK_FRAC_MASK GENMASK(15, 8)
|
||||
-#define JH7100_CLK_FRAC_SHIFT 8
|
||||
-#define JH7100_CLK_INT_MASK GENMASK(7, 0)
|
||||
-
|
||||
-/* fractional divider min/max */
|
||||
-#define JH7100_CLK_FRAC_MIN 100UL
|
||||
-#define JH7100_CLK_FRAC_MAX 25599UL
|
||||
-
|
||||
-/* clock data */
|
||||
-struct jh7100_clk_data {
|
||||
- const char *name;
|
||||
- unsigned long flags;
|
||||
- u32 max;
|
||||
- u8 parents[4];
|
||||
-};
|
||||
-
|
||||
-#define JH7100_GATE(_idx, _name, _flags, _parent) [_idx] = { \
|
||||
- .name = _name, \
|
||||
- .flags = CLK_SET_RATE_PARENT | (_flags), \
|
||||
- .max = JH7100_CLK_ENABLE, \
|
||||
- .parents = { [0] = _parent }, \
|
||||
-}
|
||||
-
|
||||
-#define JH7100__DIV(_idx, _name, _max, _parent) [_idx] = { \
|
||||
- .name = _name, \
|
||||
- .flags = 0, \
|
||||
- .max = _max, \
|
||||
- .parents = { [0] = _parent }, \
|
||||
-}
|
||||
-
|
||||
-#define JH7100_GDIV(_idx, _name, _flags, _max, _parent) [_idx] = { \
|
||||
- .name = _name, \
|
||||
- .flags = _flags, \
|
||||
- .max = JH7100_CLK_ENABLE | (_max), \
|
||||
- .parents = { [0] = _parent }, \
|
||||
-}
|
||||
-
|
||||
-#define JH7100_FDIV(_idx, _name, _parent) [_idx] = { \
|
||||
- .name = _name, \
|
||||
- .flags = 0, \
|
||||
- .max = JH7100_CLK_FRAC_MAX, \
|
||||
- .parents = { [0] = _parent }, \
|
||||
-}
|
||||
-
|
||||
-#define JH7100__MUX(_idx, _name, _nparents, ...) [_idx] = { \
|
||||
- .name = _name, \
|
||||
- .flags = 0, \
|
||||
- .max = ((_nparents) - 1) << JH7100_CLK_MUX_SHIFT, \
|
||||
- .parents = { __VA_ARGS__ }, \
|
||||
-}
|
||||
-
|
||||
-#define JH7100_GMUX(_idx, _name, _flags, _nparents, ...) [_idx] = { \
|
||||
- .name = _name, \
|
||||
- .flags = _flags, \
|
||||
- .max = JH7100_CLK_ENABLE | \
|
||||
- (((_nparents) - 1) << JH7100_CLK_MUX_SHIFT), \
|
||||
- .parents = { __VA_ARGS__ }, \
|
||||
-}
|
||||
-
|
||||
-#define JH7100_MDIV(_idx, _name, _max, _nparents, ...) [_idx] = { \
|
||||
- .name = _name, \
|
||||
- .flags = 0, \
|
||||
- .max = (((_nparents) - 1) << JH7100_CLK_MUX_SHIFT) | (_max), \
|
||||
- .parents = { __VA_ARGS__ }, \
|
||||
-}
|
||||
-
|
||||
-#define JH7100__GMD(_idx, _name, _flags, _max, _nparents, ...) [_idx] = { \
|
||||
- .name = _name, \
|
||||
- .flags = _flags, \
|
||||
- .max = JH7100_CLK_ENABLE | \
|
||||
- (((_nparents) - 1) << JH7100_CLK_MUX_SHIFT) | (_max), \
|
||||
- .parents = { __VA_ARGS__ }, \
|
||||
-}
|
||||
-
|
||||
-#define JH7100__INV(_idx, _name, _parent) [_idx] = { \
|
||||
- .name = _name, \
|
||||
- .flags = CLK_SET_RATE_PARENT, \
|
||||
- .max = JH7100_CLK_INVERT, \
|
||||
- .parents = { [0] = _parent }, \
|
||||
-}
|
||||
-
|
||||
-struct jh7100_clk {
|
||||
- struct clk_hw hw;
|
||||
- unsigned int idx;
|
||||
- unsigned int max_div;
|
||||
-};
|
||||
-
|
||||
-struct jh7100_clk_priv {
|
||||
- /* protect clk enable and set rate/parent from happening at the same time */
|
||||
- spinlock_t rmw_lock;
|
||||
- struct device *dev;
|
||||
- void __iomem *base;
|
||||
- struct clk_hw *pll[3];
|
||||
- struct jh7100_clk reg[];
|
||||
-};
|
||||
-
|
||||
-const struct clk_ops *starfive_jh7100_clk_ops(u32 max);
|
||||
-
|
||||
-#endif
|
||||
--- /dev/null
|
||||
+++ b/drivers/clk/starfive/clk-starfive-jh71x0.h
|
||||
@@ -0,0 +1,114 @@
|
||||
+/* SPDX-License-Identifier: GPL-2.0 */
|
||||
+#ifndef __CLK_STARFIVE_JH7100_H
|
||||
+#define __CLK_STARFIVE_JH7100_H
|
||||
+
|
||||
+#include <linux/bits.h>
|
||||
+#include <linux/clk-provider.h>
|
||||
+#include <linux/device.h>
|
||||
+#include <linux/spinlock.h>
|
||||
+
|
||||
+/* register fields */
|
||||
+#define JH7100_CLK_ENABLE BIT(31)
|
||||
+#define JH7100_CLK_INVERT BIT(30)
|
||||
+#define JH7100_CLK_MUX_MASK GENMASK(27, 24)
|
||||
+#define JH7100_CLK_MUX_SHIFT 24
|
||||
+#define JH7100_CLK_DIV_MASK GENMASK(23, 0)
|
||||
+#define JH7100_CLK_FRAC_MASK GENMASK(15, 8)
|
||||
+#define JH7100_CLK_FRAC_SHIFT 8
|
||||
+#define JH7100_CLK_INT_MASK GENMASK(7, 0)
|
||||
+
|
||||
+/* fractional divider min/max */
|
||||
+#define JH7100_CLK_FRAC_MIN 100UL
|
||||
+#define JH7100_CLK_FRAC_MAX 25599UL
|
||||
+
|
||||
+/* clock data */
|
||||
+struct jh7100_clk_data {
|
||||
+ const char *name;
|
||||
+ unsigned long flags;
|
||||
+ u32 max;
|
||||
+ u8 parents[4];
|
||||
+};
|
||||
+
|
||||
+#define JH7100_GATE(_idx, _name, _flags, _parent) [_idx] = { \
|
||||
+ .name = _name, \
|
||||
+ .flags = CLK_SET_RATE_PARENT | (_flags), \
|
||||
+ .max = JH7100_CLK_ENABLE, \
|
||||
+ .parents = { [0] = _parent }, \
|
||||
+}
|
||||
+
|
||||
+#define JH7100__DIV(_idx, _name, _max, _parent) [_idx] = { \
|
||||
+ .name = _name, \
|
||||
+ .flags = 0, \
|
||||
+ .max = _max, \
|
||||
+ .parents = { [0] = _parent }, \
|
||||
+}
|
||||
+
|
||||
+#define JH7100_GDIV(_idx, _name, _flags, _max, _parent) [_idx] = { \
|
||||
+ .name = _name, \
|
||||
+ .flags = _flags, \
|
||||
+ .max = JH7100_CLK_ENABLE | (_max), \
|
||||
+ .parents = { [0] = _parent }, \
|
||||
+}
|
||||
+
|
||||
+#define JH7100_FDIV(_idx, _name, _parent) [_idx] = { \
|
||||
+ .name = _name, \
|
||||
+ .flags = 0, \
|
||||
+ .max = JH7100_CLK_FRAC_MAX, \
|
||||
+ .parents = { [0] = _parent }, \
|
||||
+}
|
||||
+
|
||||
+#define JH7100__MUX(_idx, _name, _nparents, ...) [_idx] = { \
|
||||
+ .name = _name, \
|
||||
+ .flags = 0, \
|
||||
+ .max = ((_nparents) - 1) << JH7100_CLK_MUX_SHIFT, \
|
||||
+ .parents = { __VA_ARGS__ }, \
|
||||
+}
|
||||
+
|
||||
+#define JH7100_GMUX(_idx, _name, _flags, _nparents, ...) [_idx] = { \
|
||||
+ .name = _name, \
|
||||
+ .flags = _flags, \
|
||||
+ .max = JH7100_CLK_ENABLE | \
|
||||
+ (((_nparents) - 1) << JH7100_CLK_MUX_SHIFT), \
|
||||
+ .parents = { __VA_ARGS__ }, \
|
||||
+}
|
||||
+
|
||||
+#define JH7100_MDIV(_idx, _name, _max, _nparents, ...) [_idx] = { \
|
||||
+ .name = _name, \
|
||||
+ .flags = 0, \
|
||||
+ .max = (((_nparents) - 1) << JH7100_CLK_MUX_SHIFT) | (_max), \
|
||||
+ .parents = { __VA_ARGS__ }, \
|
||||
+}
|
||||
+
|
||||
+#define JH7100__GMD(_idx, _name, _flags, _max, _nparents, ...) [_idx] = { \
|
||||
+ .name = _name, \
|
||||
+ .flags = _flags, \
|
||||
+ .max = JH7100_CLK_ENABLE | \
|
||||
+ (((_nparents) - 1) << JH7100_CLK_MUX_SHIFT) | (_max), \
|
||||
+ .parents = { __VA_ARGS__ }, \
|
||||
+}
|
||||
+
|
||||
+#define JH7100__INV(_idx, _name, _parent) [_idx] = { \
|
||||
+ .name = _name, \
|
||||
+ .flags = CLK_SET_RATE_PARENT, \
|
||||
+ .max = JH7100_CLK_INVERT, \
|
||||
+ .parents = { [0] = _parent }, \
|
||||
+}
|
||||
+
|
||||
+struct jh7100_clk {
|
||||
+ struct clk_hw hw;
|
||||
+ unsigned int idx;
|
||||
+ unsigned int max_div;
|
||||
+};
|
||||
+
|
||||
+struct jh7100_clk_priv {
|
||||
+ /* protect clk enable and set rate/parent from happening at the same time */
|
||||
+ spinlock_t rmw_lock;
|
||||
+ struct device *dev;
|
||||
+ void __iomem *base;
|
||||
+ struct clk_hw *pll[3];
|
||||
+ struct jh7100_clk reg[];
|
||||
+};
|
||||
+
|
||||
+const struct clk_ops *starfive_jh7100_clk_ops(u32 max);
|
||||
+
|
||||
+#endif
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,30 @@
|
||||
From 0ee5a7565601fa785d7e55c57f26ff5d79473eb2 Mon Sep 17 00:00:00 2001
|
||||
From: Hal Feng <hal.feng@starfivetech.com>
|
||||
Date: Sat, 1 Apr 2023 19:19:19 +0800
|
||||
Subject: [PATCH 007/122] reset: starfive: Replace SOC_STARFIVE with
|
||||
ARCH_STARFIVE
|
||||
|
||||
Using ARCH_FOO symbol is preferred than SOC_FOO.
|
||||
|
||||
Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de>
|
||||
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
|
||||
Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
|
||||
Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
|
||||
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
|
||||
---
|
||||
drivers/reset/Kconfig | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/reset/Kconfig
|
||||
+++ b/drivers/reset/Kconfig
|
||||
@@ -234,8 +234,8 @@ config RESET_SOCFPGA
|
||||
|
||||
config RESET_STARFIVE_JH7100
|
||||
bool "StarFive JH7100 Reset Driver"
|
||||
- depends on SOC_STARFIVE || COMPILE_TEST
|
||||
- default SOC_STARFIVE
|
||||
+ depends on ARCH_STARFIVE || COMPILE_TEST
|
||||
+ default ARCH_STARFIVE
|
||||
help
|
||||
This enables the reset controller driver for the StarFive JH7100 SoC.
|
||||
|
@ -0,0 +1,436 @@
|
||||
From ea9e5879793f9743fbfe613174900ab0c431ac0e Mon Sep 17 00:00:00 2001
|
||||
From: Emil Renner Berthing <kernel@esmil.dk>
|
||||
Date: Sat, 1 Apr 2023 19:19:20 +0800
|
||||
Subject: [PATCH 008/122] reset: Create subdirectory for StarFive drivers
|
||||
|
||||
This moves the StarFive JH7100 reset driver to a new subdirectory in
|
||||
preparation for adding more StarFive reset drivers.
|
||||
|
||||
Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de>
|
||||
Tested-by: Tommaso Merciai <tomm.merciai@gmail.com>
|
||||
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
|
||||
Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
|
||||
Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
|
||||
Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
|
||||
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
|
||||
---
|
||||
drivers/reset/Kconfig | 8 +-------
|
||||
drivers/reset/Makefile | 2 +-
|
||||
drivers/reset/starfive/Kconfig | 8 ++++++++
|
||||
drivers/reset/starfive/Makefile | 2 ++
|
||||
drivers/reset/{ => starfive}/reset-starfive-jh7100.c | 0
|
||||
5 files changed, 12 insertions(+), 8 deletions(-)
|
||||
create mode 100644 drivers/reset/starfive/Kconfig
|
||||
create mode 100644 drivers/reset/starfive/Makefile
|
||||
rename drivers/reset/{ => starfive}/reset-starfive-jh7100.c (100%)
|
||||
|
||||
--- a/drivers/reset/Kconfig
|
||||
+++ b/drivers/reset/Kconfig
|
||||
@@ -232,13 +232,6 @@ config RESET_SOCFPGA
|
||||
This enables the reset driver for the SoCFPGA ARMv7 platforms. This
|
||||
driver gets initialized early during platform init calls.
|
||||
|
||||
-config RESET_STARFIVE_JH7100
|
||||
- bool "StarFive JH7100 Reset Driver"
|
||||
- depends on ARCH_STARFIVE || COMPILE_TEST
|
||||
- default ARCH_STARFIVE
|
||||
- help
|
||||
- This enables the reset controller driver for the StarFive JH7100 SoC.
|
||||
-
|
||||
config RESET_SUNPLUS
|
||||
bool "Sunplus SoCs Reset Driver" if COMPILE_TEST
|
||||
default ARCH_SUNPLUS
|
||||
@@ -320,6 +313,7 @@ config RESET_ZYNQ
|
||||
help
|
||||
This enables the reset controller driver for Xilinx Zynq SoCs.
|
||||
|
||||
+source "drivers/reset/starfive/Kconfig"
|
||||
source "drivers/reset/sti/Kconfig"
|
||||
source "drivers/reset/hisilicon/Kconfig"
|
||||
source "drivers/reset/tegra/Kconfig"
|
||||
--- a/drivers/reset/Makefile
|
||||
+++ b/drivers/reset/Makefile
|
||||
@@ -1,6 +1,7 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
obj-y += core.o
|
||||
obj-y += hisilicon/
|
||||
+obj-y += starfive/
|
||||
obj-$(CONFIG_ARCH_STI) += sti/
|
||||
obj-$(CONFIG_ARCH_TEGRA) += tegra/
|
||||
obj-$(CONFIG_RESET_A10SR) += reset-a10sr.o
|
||||
@@ -30,7 +31,6 @@ obj-$(CONFIG_RESET_RZG2L_USBPHY_CTRL) +=
|
||||
obj-$(CONFIG_RESET_SCMI) += reset-scmi.o
|
||||
obj-$(CONFIG_RESET_SIMPLE) += reset-simple.o
|
||||
obj-$(CONFIG_RESET_SOCFPGA) += reset-socfpga.o
|
||||
-obj-$(CONFIG_RESET_STARFIVE_JH7100) += reset-starfive-jh7100.o
|
||||
obj-$(CONFIG_RESET_SUNPLUS) += reset-sunplus.o
|
||||
obj-$(CONFIG_RESET_SUNXI) += reset-sunxi.o
|
||||
obj-$(CONFIG_RESET_TI_SCI) += reset-ti-sci.o
|
||||
--- /dev/null
|
||||
+++ b/drivers/reset/starfive/Kconfig
|
||||
@@ -0,0 +1,8 @@
|
||||
+# SPDX-License-Identifier: GPL-2.0-only
|
||||
+
|
||||
+config RESET_STARFIVE_JH7100
|
||||
+ bool "StarFive JH7100 Reset Driver"
|
||||
+ depends on ARCH_STARFIVE || COMPILE_TEST
|
||||
+ default ARCH_STARFIVE
|
||||
+ help
|
||||
+ This enables the reset controller driver for the StarFive JH7100 SoC.
|
||||
--- /dev/null
|
||||
+++ b/drivers/reset/starfive/Makefile
|
||||
@@ -0,0 +1,2 @@
|
||||
+# SPDX-License-Identifier: GPL-2.0
|
||||
+obj-$(CONFIG_RESET_STARFIVE_JH7100) += reset-starfive-jh7100.o
|
||||
--- a/drivers/reset/reset-starfive-jh7100.c
|
||||
+++ /dev/null
|
||||
@@ -1,173 +0,0 @@
|
||||
-// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
-/*
|
||||
- * Reset driver for the StarFive JH7100 SoC
|
||||
- *
|
||||
- * Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
|
||||
- */
|
||||
-
|
||||
-#include <linux/bitmap.h>
|
||||
-#include <linux/io.h>
|
||||
-#include <linux/io-64-nonatomic-lo-hi.h>
|
||||
-#include <linux/iopoll.h>
|
||||
-#include <linux/mod_devicetable.h>
|
||||
-#include <linux/platform_device.h>
|
||||
-#include <linux/reset-controller.h>
|
||||
-#include <linux/spinlock.h>
|
||||
-
|
||||
-#include <dt-bindings/reset/starfive-jh7100.h>
|
||||
-
|
||||
-/* register offsets */
|
||||
-#define JH7100_RESET_ASSERT0 0x00
|
||||
-#define JH7100_RESET_ASSERT1 0x04
|
||||
-#define JH7100_RESET_ASSERT2 0x08
|
||||
-#define JH7100_RESET_ASSERT3 0x0c
|
||||
-#define JH7100_RESET_STATUS0 0x10
|
||||
-#define JH7100_RESET_STATUS1 0x14
|
||||
-#define JH7100_RESET_STATUS2 0x18
|
||||
-#define JH7100_RESET_STATUS3 0x1c
|
||||
-
|
||||
-/*
|
||||
- * Writing a 1 to the n'th bit of the m'th ASSERT register asserts
|
||||
- * line 32m + n, and writing a 0 deasserts the same line.
|
||||
- * Most reset lines have their status inverted so a 0 bit in the STATUS
|
||||
- * register means the line is asserted and a 1 means it's deasserted. A few
|
||||
- * lines don't though, so store the expected value of the status registers when
|
||||
- * all lines are asserted.
|
||||
- */
|
||||
-static const u64 jh7100_reset_asserted[2] = {
|
||||
- /* STATUS0 */
|
||||
- BIT_ULL_MASK(JH7100_RST_U74) |
|
||||
- BIT_ULL_MASK(JH7100_RST_VP6_DRESET) |
|
||||
- BIT_ULL_MASK(JH7100_RST_VP6_BRESET) |
|
||||
- /* STATUS1 */
|
||||
- BIT_ULL_MASK(JH7100_RST_HIFI4_DRESET) |
|
||||
- BIT_ULL_MASK(JH7100_RST_HIFI4_BRESET),
|
||||
- /* STATUS2 */
|
||||
- BIT_ULL_MASK(JH7100_RST_E24) |
|
||||
- /* STATUS3 */
|
||||
- 0,
|
||||
-};
|
||||
-
|
||||
-struct jh7100_reset {
|
||||
- struct reset_controller_dev rcdev;
|
||||
- /* protect registers against concurrent read-modify-write */
|
||||
- spinlock_t lock;
|
||||
- void __iomem *base;
|
||||
-};
|
||||
-
|
||||
-static inline struct jh7100_reset *
|
||||
-jh7100_reset_from(struct reset_controller_dev *rcdev)
|
||||
-{
|
||||
- return container_of(rcdev, struct jh7100_reset, rcdev);
|
||||
-}
|
||||
-
|
||||
-static int jh7100_reset_update(struct reset_controller_dev *rcdev,
|
||||
- unsigned long id, bool assert)
|
||||
-{
|
||||
- struct jh7100_reset *data = jh7100_reset_from(rcdev);
|
||||
- unsigned long offset = BIT_ULL_WORD(id);
|
||||
- u64 mask = BIT_ULL_MASK(id);
|
||||
- void __iomem *reg_assert = data->base + JH7100_RESET_ASSERT0 + offset * sizeof(u64);
|
||||
- void __iomem *reg_status = data->base + JH7100_RESET_STATUS0 + offset * sizeof(u64);
|
||||
- u64 done = jh7100_reset_asserted[offset] & mask;
|
||||
- u64 value;
|
||||
- unsigned long flags;
|
||||
- int ret;
|
||||
-
|
||||
- if (!assert)
|
||||
- done ^= mask;
|
||||
-
|
||||
- spin_lock_irqsave(&data->lock, flags);
|
||||
-
|
||||
- value = readq(reg_assert);
|
||||
- if (assert)
|
||||
- value |= mask;
|
||||
- else
|
||||
- value &= ~mask;
|
||||
- writeq(value, reg_assert);
|
||||
-
|
||||
- /* if the associated clock is gated, deasserting might otherwise hang forever */
|
||||
- ret = readq_poll_timeout_atomic(reg_status, value, (value & mask) == done, 0, 1000);
|
||||
-
|
||||
- spin_unlock_irqrestore(&data->lock, flags);
|
||||
- return ret;
|
||||
-}
|
||||
-
|
||||
-static int jh7100_reset_assert(struct reset_controller_dev *rcdev,
|
||||
- unsigned long id)
|
||||
-{
|
||||
- return jh7100_reset_update(rcdev, id, true);
|
||||
-}
|
||||
-
|
||||
-static int jh7100_reset_deassert(struct reset_controller_dev *rcdev,
|
||||
- unsigned long id)
|
||||
-{
|
||||
- return jh7100_reset_update(rcdev, id, false);
|
||||
-}
|
||||
-
|
||||
-static int jh7100_reset_reset(struct reset_controller_dev *rcdev,
|
||||
- unsigned long id)
|
||||
-{
|
||||
- int ret;
|
||||
-
|
||||
- ret = jh7100_reset_assert(rcdev, id);
|
||||
- if (ret)
|
||||
- return ret;
|
||||
-
|
||||
- return jh7100_reset_deassert(rcdev, id);
|
||||
-}
|
||||
-
|
||||
-static int jh7100_reset_status(struct reset_controller_dev *rcdev,
|
||||
- unsigned long id)
|
||||
-{
|
||||
- struct jh7100_reset *data = jh7100_reset_from(rcdev);
|
||||
- unsigned long offset = BIT_ULL_WORD(id);
|
||||
- u64 mask = BIT_ULL_MASK(id);
|
||||
- void __iomem *reg_status = data->base + JH7100_RESET_STATUS0 + offset * sizeof(u64);
|
||||
- u64 value = readq(reg_status);
|
||||
-
|
||||
- return !((value ^ jh7100_reset_asserted[offset]) & mask);
|
||||
-}
|
||||
-
|
||||
-static const struct reset_control_ops jh7100_reset_ops = {
|
||||
- .assert = jh7100_reset_assert,
|
||||
- .deassert = jh7100_reset_deassert,
|
||||
- .reset = jh7100_reset_reset,
|
||||
- .status = jh7100_reset_status,
|
||||
-};
|
||||
-
|
||||
-static int __init jh7100_reset_probe(struct platform_device *pdev)
|
||||
-{
|
||||
- struct jh7100_reset *data;
|
||||
-
|
||||
- data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
|
||||
- if (!data)
|
||||
- return -ENOMEM;
|
||||
-
|
||||
- data->base = devm_platform_ioremap_resource(pdev, 0);
|
||||
- if (IS_ERR(data->base))
|
||||
- return PTR_ERR(data->base);
|
||||
-
|
||||
- data->rcdev.ops = &jh7100_reset_ops;
|
||||
- data->rcdev.owner = THIS_MODULE;
|
||||
- data->rcdev.nr_resets = JH7100_RSTN_END;
|
||||
- data->rcdev.dev = &pdev->dev;
|
||||
- data->rcdev.of_node = pdev->dev.of_node;
|
||||
- spin_lock_init(&data->lock);
|
||||
-
|
||||
- return devm_reset_controller_register(&pdev->dev, &data->rcdev);
|
||||
-}
|
||||
-
|
||||
-static const struct of_device_id jh7100_reset_dt_ids[] = {
|
||||
- { .compatible = "starfive,jh7100-reset" },
|
||||
- { /* sentinel */ }
|
||||
-};
|
||||
-
|
||||
-static struct platform_driver jh7100_reset_driver = {
|
||||
- .driver = {
|
||||
- .name = "jh7100-reset",
|
||||
- .of_match_table = jh7100_reset_dt_ids,
|
||||
- .suppress_bind_attrs = true,
|
||||
- },
|
||||
-};
|
||||
-builtin_platform_driver_probe(jh7100_reset_driver, jh7100_reset_probe);
|
||||
--- /dev/null
|
||||
+++ b/drivers/reset/starfive/reset-starfive-jh7100.c
|
||||
@@ -0,0 +1,173 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
+/*
|
||||
+ * Reset driver for the StarFive JH7100 SoC
|
||||
+ *
|
||||
+ * Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
|
||||
+ */
|
||||
+
|
||||
+#include <linux/bitmap.h>
|
||||
+#include <linux/io.h>
|
||||
+#include <linux/io-64-nonatomic-lo-hi.h>
|
||||
+#include <linux/iopoll.h>
|
||||
+#include <linux/mod_devicetable.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/reset-controller.h>
|
||||
+#include <linux/spinlock.h>
|
||||
+
|
||||
+#include <dt-bindings/reset/starfive-jh7100.h>
|
||||
+
|
||||
+/* register offsets */
|
||||
+#define JH7100_RESET_ASSERT0 0x00
|
||||
+#define JH7100_RESET_ASSERT1 0x04
|
||||
+#define JH7100_RESET_ASSERT2 0x08
|
||||
+#define JH7100_RESET_ASSERT3 0x0c
|
||||
+#define JH7100_RESET_STATUS0 0x10
|
||||
+#define JH7100_RESET_STATUS1 0x14
|
||||
+#define JH7100_RESET_STATUS2 0x18
|
||||
+#define JH7100_RESET_STATUS3 0x1c
|
||||
+
|
||||
+/*
|
||||
+ * Writing a 1 to the n'th bit of the m'th ASSERT register asserts
|
||||
+ * line 32m + n, and writing a 0 deasserts the same line.
|
||||
+ * Most reset lines have their status inverted so a 0 bit in the STATUS
|
||||
+ * register means the line is asserted and a 1 means it's deasserted. A few
|
||||
+ * lines don't though, so store the expected value of the status registers when
|
||||
+ * all lines are asserted.
|
||||
+ */
|
||||
+static const u64 jh7100_reset_asserted[2] = {
|
||||
+ /* STATUS0 */
|
||||
+ BIT_ULL_MASK(JH7100_RST_U74) |
|
||||
+ BIT_ULL_MASK(JH7100_RST_VP6_DRESET) |
|
||||
+ BIT_ULL_MASK(JH7100_RST_VP6_BRESET) |
|
||||
+ /* STATUS1 */
|
||||
+ BIT_ULL_MASK(JH7100_RST_HIFI4_DRESET) |
|
||||
+ BIT_ULL_MASK(JH7100_RST_HIFI4_BRESET),
|
||||
+ /* STATUS2 */
|
||||
+ BIT_ULL_MASK(JH7100_RST_E24) |
|
||||
+ /* STATUS3 */
|
||||
+ 0,
|
||||
+};
|
||||
+
|
||||
+struct jh7100_reset {
|
||||
+ struct reset_controller_dev rcdev;
|
||||
+ /* protect registers against concurrent read-modify-write */
|
||||
+ spinlock_t lock;
|
||||
+ void __iomem *base;
|
||||
+};
|
||||
+
|
||||
+static inline struct jh7100_reset *
|
||||
+jh7100_reset_from(struct reset_controller_dev *rcdev)
|
||||
+{
|
||||
+ return container_of(rcdev, struct jh7100_reset, rcdev);
|
||||
+}
|
||||
+
|
||||
+static int jh7100_reset_update(struct reset_controller_dev *rcdev,
|
||||
+ unsigned long id, bool assert)
|
||||
+{
|
||||
+ struct jh7100_reset *data = jh7100_reset_from(rcdev);
|
||||
+ unsigned long offset = BIT_ULL_WORD(id);
|
||||
+ u64 mask = BIT_ULL_MASK(id);
|
||||
+ void __iomem *reg_assert = data->base + JH7100_RESET_ASSERT0 + offset * sizeof(u64);
|
||||
+ void __iomem *reg_status = data->base + JH7100_RESET_STATUS0 + offset * sizeof(u64);
|
||||
+ u64 done = jh7100_reset_asserted[offset] & mask;
|
||||
+ u64 value;
|
||||
+ unsigned long flags;
|
||||
+ int ret;
|
||||
+
|
||||
+ if (!assert)
|
||||
+ done ^= mask;
|
||||
+
|
||||
+ spin_lock_irqsave(&data->lock, flags);
|
||||
+
|
||||
+ value = readq(reg_assert);
|
||||
+ if (assert)
|
||||
+ value |= mask;
|
||||
+ else
|
||||
+ value &= ~mask;
|
||||
+ writeq(value, reg_assert);
|
||||
+
|
||||
+ /* if the associated clock is gated, deasserting might otherwise hang forever */
|
||||
+ ret = readq_poll_timeout_atomic(reg_status, value, (value & mask) == done, 0, 1000);
|
||||
+
|
||||
+ spin_unlock_irqrestore(&data->lock, flags);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int jh7100_reset_assert(struct reset_controller_dev *rcdev,
|
||||
+ unsigned long id)
|
||||
+{
|
||||
+ return jh7100_reset_update(rcdev, id, true);
|
||||
+}
|
||||
+
|
||||
+static int jh7100_reset_deassert(struct reset_controller_dev *rcdev,
|
||||
+ unsigned long id)
|
||||
+{
|
||||
+ return jh7100_reset_update(rcdev, id, false);
|
||||
+}
|
||||
+
|
||||
+static int jh7100_reset_reset(struct reset_controller_dev *rcdev,
|
||||
+ unsigned long id)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = jh7100_reset_assert(rcdev, id);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ return jh7100_reset_deassert(rcdev, id);
|
||||
+}
|
||||
+
|
||||
+static int jh7100_reset_status(struct reset_controller_dev *rcdev,
|
||||
+ unsigned long id)
|
||||
+{
|
||||
+ struct jh7100_reset *data = jh7100_reset_from(rcdev);
|
||||
+ unsigned long offset = BIT_ULL_WORD(id);
|
||||
+ u64 mask = BIT_ULL_MASK(id);
|
||||
+ void __iomem *reg_status = data->base + JH7100_RESET_STATUS0 + offset * sizeof(u64);
|
||||
+ u64 value = readq(reg_status);
|
||||
+
|
||||
+ return !((value ^ jh7100_reset_asserted[offset]) & mask);
|
||||
+}
|
||||
+
|
||||
+static const struct reset_control_ops jh7100_reset_ops = {
|
||||
+ .assert = jh7100_reset_assert,
|
||||
+ .deassert = jh7100_reset_deassert,
|
||||
+ .reset = jh7100_reset_reset,
|
||||
+ .status = jh7100_reset_status,
|
||||
+};
|
||||
+
|
||||
+static int __init jh7100_reset_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct jh7100_reset *data;
|
||||
+
|
||||
+ data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
|
||||
+ if (!data)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ data->base = devm_platform_ioremap_resource(pdev, 0);
|
||||
+ if (IS_ERR(data->base))
|
||||
+ return PTR_ERR(data->base);
|
||||
+
|
||||
+ data->rcdev.ops = &jh7100_reset_ops;
|
||||
+ data->rcdev.owner = THIS_MODULE;
|
||||
+ data->rcdev.nr_resets = JH7100_RSTN_END;
|
||||
+ data->rcdev.dev = &pdev->dev;
|
||||
+ data->rcdev.of_node = pdev->dev.of_node;
|
||||
+ spin_lock_init(&data->lock);
|
||||
+
|
||||
+ return devm_reset_controller_register(&pdev->dev, &data->rcdev);
|
||||
+}
|
||||
+
|
||||
+static const struct of_device_id jh7100_reset_dt_ids[] = {
|
||||
+ { .compatible = "starfive,jh7100-reset" },
|
||||
+ { /* sentinel */ }
|
||||
+};
|
||||
+
|
||||
+static struct platform_driver jh7100_reset_driver = {
|
||||
+ .driver = {
|
||||
+ .name = "jh7100-reset",
|
||||
+ .of_match_table = jh7100_reset_dt_ids,
|
||||
+ .suppress_bind_attrs = true,
|
||||
+ },
|
||||
+};
|
||||
+builtin_platform_driver_probe(jh7100_reset_driver, jh7100_reset_probe);
|
@ -0,0 +1,390 @@
|
||||
From a8051a7daa45056f469686286886968bc62b94df Mon Sep 17 00:00:00 2001
|
||||
From: Emil Renner Berthing <kernel@esmil.dk>
|
||||
Date: Sat, 1 Apr 2023 19:19:21 +0800
|
||||
Subject: [PATCH 009/122] reset: starfive: Factor out common JH71X0 reset code
|
||||
|
||||
The StarFive JH7100 SoC has additional reset controllers for audio and
|
||||
video, but the registers follow the same structure. On the JH7110 the
|
||||
reset registers don't get their own memory range, but instead follow the
|
||||
clock control registers. The registers still follow the same structure
|
||||
though, so let's factor out the common code to handle all these cases.
|
||||
|
||||
Tested-by: Tommaso Merciai <tomm.merciai@gmail.com>
|
||||
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
|
||||
Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
|
||||
Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
|
||||
Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
|
||||
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
|
||||
---
|
||||
drivers/reset/starfive/Kconfig | 4 +
|
||||
drivers/reset/starfive/Makefile | 2 +
|
||||
.../reset/starfive/reset-starfive-jh7100.c | 150 +---------------
|
||||
.../reset/starfive/reset-starfive-jh71x0.c | 162 ++++++++++++++++++
|
||||
.../reset/starfive/reset-starfive-jh71x0.h | 11 ++
|
||||
5 files changed, 180 insertions(+), 149 deletions(-)
|
||||
create mode 100644 drivers/reset/starfive/reset-starfive-jh71x0.c
|
||||
create mode 100644 drivers/reset/starfive/reset-starfive-jh71x0.h
|
||||
|
||||
--- a/drivers/reset/starfive/Kconfig
|
||||
+++ b/drivers/reset/starfive/Kconfig
|
||||
@@ -1,8 +1,12 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
+config RESET_STARFIVE_JH71X0
|
||||
+ bool
|
||||
+
|
||||
config RESET_STARFIVE_JH7100
|
||||
bool "StarFive JH7100 Reset Driver"
|
||||
depends on ARCH_STARFIVE || COMPILE_TEST
|
||||
+ select RESET_STARFIVE_JH71X0
|
||||
default ARCH_STARFIVE
|
||||
help
|
||||
This enables the reset controller driver for the StarFive JH7100 SoC.
|
||||
--- a/drivers/reset/starfive/Makefile
|
||||
+++ b/drivers/reset/starfive/Makefile
|
||||
@@ -1,2 +1,4 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
+obj-$(CONFIG_RESET_STARFIVE_JH71X0) += reset-starfive-jh71x0.o
|
||||
+
|
||||
obj-$(CONFIG_RESET_STARFIVE_JH7100) += reset-starfive-jh7100.o
|
||||
--- a/drivers/reset/starfive/reset-starfive-jh7100.c
|
||||
+++ b/drivers/reset/starfive/reset-starfive-jh7100.c
|
||||
@@ -5,158 +5,10 @@
|
||||
* Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
|
||||
*/
|
||||
|
||||
-#include <linux/bitmap.h>
|
||||
-#include <linux/io.h>
|
||||
-#include <linux/io-64-nonatomic-lo-hi.h>
|
||||
-#include <linux/iopoll.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/platform_device.h>
|
||||
-#include <linux/reset-controller.h>
|
||||
-#include <linux/spinlock.h>
|
||||
|
||||
-#include <dt-bindings/reset/starfive-jh7100.h>
|
||||
-
|
||||
-/* register offsets */
|
||||
-#define JH7100_RESET_ASSERT0 0x00
|
||||
-#define JH7100_RESET_ASSERT1 0x04
|
||||
-#define JH7100_RESET_ASSERT2 0x08
|
||||
-#define JH7100_RESET_ASSERT3 0x0c
|
||||
-#define JH7100_RESET_STATUS0 0x10
|
||||
-#define JH7100_RESET_STATUS1 0x14
|
||||
-#define JH7100_RESET_STATUS2 0x18
|
||||
-#define JH7100_RESET_STATUS3 0x1c
|
||||
-
|
||||
-/*
|
||||
- * Writing a 1 to the n'th bit of the m'th ASSERT register asserts
|
||||
- * line 32m + n, and writing a 0 deasserts the same line.
|
||||
- * Most reset lines have their status inverted so a 0 bit in the STATUS
|
||||
- * register means the line is asserted and a 1 means it's deasserted. A few
|
||||
- * lines don't though, so store the expected value of the status registers when
|
||||
- * all lines are asserted.
|
||||
- */
|
||||
-static const u64 jh7100_reset_asserted[2] = {
|
||||
- /* STATUS0 */
|
||||
- BIT_ULL_MASK(JH7100_RST_U74) |
|
||||
- BIT_ULL_MASK(JH7100_RST_VP6_DRESET) |
|
||||
- BIT_ULL_MASK(JH7100_RST_VP6_BRESET) |
|
||||
- /* STATUS1 */
|
||||
- BIT_ULL_MASK(JH7100_RST_HIFI4_DRESET) |
|
||||
- BIT_ULL_MASK(JH7100_RST_HIFI4_BRESET),
|
||||
- /* STATUS2 */
|
||||
- BIT_ULL_MASK(JH7100_RST_E24) |
|
||||
- /* STATUS3 */
|
||||
- 0,
|
||||
-};
|
||||
-
|
||||
-struct jh7100_reset {
|
||||
- struct reset_controller_dev rcdev;
|
||||
- /* protect registers against concurrent read-modify-write */
|
||||
- spinlock_t lock;
|
||||
- void __iomem *base;
|
||||
-};
|
||||
-
|
||||
-static inline struct jh7100_reset *
|
||||
-jh7100_reset_from(struct reset_controller_dev *rcdev)
|
||||
-{
|
||||
- return container_of(rcdev, struct jh7100_reset, rcdev);
|
||||
-}
|
||||
-
|
||||
-static int jh7100_reset_update(struct reset_controller_dev *rcdev,
|
||||
- unsigned long id, bool assert)
|
||||
-{
|
||||
- struct jh7100_reset *data = jh7100_reset_from(rcdev);
|
||||
- unsigned long offset = BIT_ULL_WORD(id);
|
||||
- u64 mask = BIT_ULL_MASK(id);
|
||||
- void __iomem *reg_assert = data->base + JH7100_RESET_ASSERT0 + offset * sizeof(u64);
|
||||
- void __iomem *reg_status = data->base + JH7100_RESET_STATUS0 + offset * sizeof(u64);
|
||||
- u64 done = jh7100_reset_asserted[offset] & mask;
|
||||
- u64 value;
|
||||
- unsigned long flags;
|
||||
- int ret;
|
||||
-
|
||||
- if (!assert)
|
||||
- done ^= mask;
|
||||
-
|
||||
- spin_lock_irqsave(&data->lock, flags);
|
||||
-
|
||||
- value = readq(reg_assert);
|
||||
- if (assert)
|
||||
- value |= mask;
|
||||
- else
|
||||
- value &= ~mask;
|
||||
- writeq(value, reg_assert);
|
||||
-
|
||||
- /* if the associated clock is gated, deasserting might otherwise hang forever */
|
||||
- ret = readq_poll_timeout_atomic(reg_status, value, (value & mask) == done, 0, 1000);
|
||||
-
|
||||
- spin_unlock_irqrestore(&data->lock, flags);
|
||||
- return ret;
|
||||
-}
|
||||
-
|
||||
-static int jh7100_reset_assert(struct reset_controller_dev *rcdev,
|
||||
- unsigned long id)
|
||||
-{
|
||||
- return jh7100_reset_update(rcdev, id, true);
|
||||
-}
|
||||
-
|
||||
-static int jh7100_reset_deassert(struct reset_controller_dev *rcdev,
|
||||
- unsigned long id)
|
||||
-{
|
||||
- return jh7100_reset_update(rcdev, id, false);
|
||||
-}
|
||||
-
|
||||
-static int jh7100_reset_reset(struct reset_controller_dev *rcdev,
|
||||
- unsigned long id)
|
||||
-{
|
||||
- int ret;
|
||||
-
|
||||
- ret = jh7100_reset_assert(rcdev, id);
|
||||
- if (ret)
|
||||
- return ret;
|
||||
-
|
||||
- return jh7100_reset_deassert(rcdev, id);
|
||||
-}
|
||||
-
|
||||
-static int jh7100_reset_status(struct reset_controller_dev *rcdev,
|
||||
- unsigned long id)
|
||||
-{
|
||||
- struct jh7100_reset *data = jh7100_reset_from(rcdev);
|
||||
- unsigned long offset = BIT_ULL_WORD(id);
|
||||
- u64 mask = BIT_ULL_MASK(id);
|
||||
- void __iomem *reg_status = data->base + JH7100_RESET_STATUS0 + offset * sizeof(u64);
|
||||
- u64 value = readq(reg_status);
|
||||
-
|
||||
- return !((value ^ jh7100_reset_asserted[offset]) & mask);
|
||||
-}
|
||||
-
|
||||
-static const struct reset_control_ops jh7100_reset_ops = {
|
||||
- .assert = jh7100_reset_assert,
|
||||
- .deassert = jh7100_reset_deassert,
|
||||
- .reset = jh7100_reset_reset,
|
||||
- .status = jh7100_reset_status,
|
||||
-};
|
||||
-
|
||||
-static int __init jh7100_reset_probe(struct platform_device *pdev)
|
||||
-{
|
||||
- struct jh7100_reset *data;
|
||||
-
|
||||
- data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
|
||||
- if (!data)
|
||||
- return -ENOMEM;
|
||||
-
|
||||
- data->base = devm_platform_ioremap_resource(pdev, 0);
|
||||
- if (IS_ERR(data->base))
|
||||
- return PTR_ERR(data->base);
|
||||
-
|
||||
- data->rcdev.ops = &jh7100_reset_ops;
|
||||
- data->rcdev.owner = THIS_MODULE;
|
||||
- data->rcdev.nr_resets = JH7100_RSTN_END;
|
||||
- data->rcdev.dev = &pdev->dev;
|
||||
- data->rcdev.of_node = pdev->dev.of_node;
|
||||
- spin_lock_init(&data->lock);
|
||||
-
|
||||
- return devm_reset_controller_register(&pdev->dev, &data->rcdev);
|
||||
-}
|
||||
+#include "reset-starfive-jh71x0.h"
|
||||
|
||||
static const struct of_device_id jh7100_reset_dt_ids[] = {
|
||||
{ .compatible = "starfive,jh7100-reset" },
|
||||
--- /dev/null
|
||||
+++ b/drivers/reset/starfive/reset-starfive-jh71x0.c
|
||||
@@ -0,0 +1,162 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
+/*
|
||||
+ * Reset driver for the StarFive JH7100 SoC
|
||||
+ *
|
||||
+ * Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
|
||||
+ */
|
||||
+
|
||||
+#include <linux/bitmap.h>
|
||||
+#include <linux/device.h>
|
||||
+#include <linux/io.h>
|
||||
+#include <linux/io-64-nonatomic-lo-hi.h>
|
||||
+#include <linux/iopoll.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/reset-controller.h>
|
||||
+#include <linux/spinlock.h>
|
||||
+
|
||||
+#include "reset-starfive-jh71x0.h"
|
||||
+
|
||||
+#include <dt-bindings/reset/starfive-jh7100.h>
|
||||
+
|
||||
+/* register offsets */
|
||||
+#define JH7100_RESET_ASSERT0 0x00
|
||||
+#define JH7100_RESET_ASSERT1 0x04
|
||||
+#define JH7100_RESET_ASSERT2 0x08
|
||||
+#define JH7100_RESET_ASSERT3 0x0c
|
||||
+#define JH7100_RESET_STATUS0 0x10
|
||||
+#define JH7100_RESET_STATUS1 0x14
|
||||
+#define JH7100_RESET_STATUS2 0x18
|
||||
+#define JH7100_RESET_STATUS3 0x1c
|
||||
+
|
||||
+/*
|
||||
+ * Writing a 1 to the n'th bit of the m'th ASSERT register asserts
|
||||
+ * line 32m + n, and writing a 0 deasserts the same line.
|
||||
+ * Most reset lines have their status inverted so a 0 bit in the STATUS
|
||||
+ * register means the line is asserted and a 1 means it's deasserted. A few
|
||||
+ * lines don't though, so store the expected value of the status registers when
|
||||
+ * all lines are asserted.
|
||||
+ */
|
||||
+static const u64 jh7100_reset_asserted[2] = {
|
||||
+ /* STATUS0 */
|
||||
+ BIT_ULL_MASK(JH7100_RST_U74) |
|
||||
+ BIT_ULL_MASK(JH7100_RST_VP6_DRESET) |
|
||||
+ BIT_ULL_MASK(JH7100_RST_VP6_BRESET) |
|
||||
+ /* STATUS1 */
|
||||
+ BIT_ULL_MASK(JH7100_RST_HIFI4_DRESET) |
|
||||
+ BIT_ULL_MASK(JH7100_RST_HIFI4_BRESET),
|
||||
+ /* STATUS2 */
|
||||
+ BIT_ULL_MASK(JH7100_RST_E24) |
|
||||
+ /* STATUS3 */
|
||||
+ 0,
|
||||
+};
|
||||
+
|
||||
+struct jh7100_reset {
|
||||
+ struct reset_controller_dev rcdev;
|
||||
+ /* protect registers against concurrent read-modify-write */
|
||||
+ spinlock_t lock;
|
||||
+ void __iomem *base;
|
||||
+};
|
||||
+
|
||||
+static inline struct jh7100_reset *
|
||||
+jh7100_reset_from(struct reset_controller_dev *rcdev)
|
||||
+{
|
||||
+ return container_of(rcdev, struct jh7100_reset, rcdev);
|
||||
+}
|
||||
+
|
||||
+static int jh7100_reset_update(struct reset_controller_dev *rcdev,
|
||||
+ unsigned long id, bool assert)
|
||||
+{
|
||||
+ struct jh7100_reset *data = jh7100_reset_from(rcdev);
|
||||
+ unsigned long offset = BIT_ULL_WORD(id);
|
||||
+ u64 mask = BIT_ULL_MASK(id);
|
||||
+ void __iomem *reg_assert = data->base + JH7100_RESET_ASSERT0 + offset * sizeof(u64);
|
||||
+ void __iomem *reg_status = data->base + JH7100_RESET_STATUS0 + offset * sizeof(u64);
|
||||
+ u64 done = jh7100_reset_asserted[offset] & mask;
|
||||
+ u64 value;
|
||||
+ unsigned long flags;
|
||||
+ int ret;
|
||||
+
|
||||
+ if (!assert)
|
||||
+ done ^= mask;
|
||||
+
|
||||
+ spin_lock_irqsave(&data->lock, flags);
|
||||
+
|
||||
+ value = readq(reg_assert);
|
||||
+ if (assert)
|
||||
+ value |= mask;
|
||||
+ else
|
||||
+ value &= ~mask;
|
||||
+ writeq(value, reg_assert);
|
||||
+
|
||||
+ /* if the associated clock is gated, deasserting might otherwise hang forever */
|
||||
+ ret = readq_poll_timeout_atomic(reg_status, value, (value & mask) == done, 0, 1000);
|
||||
+
|
||||
+ spin_unlock_irqrestore(&data->lock, flags);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int jh7100_reset_assert(struct reset_controller_dev *rcdev,
|
||||
+ unsigned long id)
|
||||
+{
|
||||
+ return jh7100_reset_update(rcdev, id, true);
|
||||
+}
|
||||
+
|
||||
+static int jh7100_reset_deassert(struct reset_controller_dev *rcdev,
|
||||
+ unsigned long id)
|
||||
+{
|
||||
+ return jh7100_reset_update(rcdev, id, false);
|
||||
+}
|
||||
+
|
||||
+static int jh7100_reset_reset(struct reset_controller_dev *rcdev,
|
||||
+ unsigned long id)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = jh7100_reset_assert(rcdev, id);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ return jh7100_reset_deassert(rcdev, id);
|
||||
+}
|
||||
+
|
||||
+static int jh7100_reset_status(struct reset_controller_dev *rcdev,
|
||||
+ unsigned long id)
|
||||
+{
|
||||
+ struct jh7100_reset *data = jh7100_reset_from(rcdev);
|
||||
+ unsigned long offset = BIT_ULL_WORD(id);
|
||||
+ u64 mask = BIT_ULL_MASK(id);
|
||||
+ void __iomem *reg_status = data->base + JH7100_RESET_STATUS0 + offset * sizeof(u64);
|
||||
+ u64 value = readq(reg_status);
|
||||
+
|
||||
+ return !((value ^ jh7100_reset_asserted[offset]) & mask);
|
||||
+}
|
||||
+
|
||||
+static const struct reset_control_ops jh7100_reset_ops = {
|
||||
+ .assert = jh7100_reset_assert,
|
||||
+ .deassert = jh7100_reset_deassert,
|
||||
+ .reset = jh7100_reset_reset,
|
||||
+ .status = jh7100_reset_status,
|
||||
+};
|
||||
+
|
||||
+int jh7100_reset_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct jh7100_reset *data;
|
||||
+
|
||||
+ data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
|
||||
+ if (!data)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ data->base = devm_platform_ioremap_resource(pdev, 0);
|
||||
+ if (IS_ERR(data->base))
|
||||
+ return PTR_ERR(data->base);
|
||||
+
|
||||
+ data->rcdev.ops = &jh7100_reset_ops;
|
||||
+ data->rcdev.owner = THIS_MODULE;
|
||||
+ data->rcdev.nr_resets = JH7100_RSTN_END;
|
||||
+ data->rcdev.dev = &pdev->dev;
|
||||
+ data->rcdev.of_node = pdev->dev.of_node;
|
||||
+ spin_lock_init(&data->lock);
|
||||
+
|
||||
+ return devm_reset_controller_register(&pdev->dev, &data->rcdev);
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(jh7100_reset_probe);
|
||||
--- /dev/null
|
||||
+++ b/drivers/reset/starfive/reset-starfive-jh71x0.h
|
||||
@@ -0,0 +1,11 @@
|
||||
+/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
+/*
|
||||
+ * Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
|
||||
+ */
|
||||
+
|
||||
+#ifndef __RESET_STARFIVE_JH71X0_H
|
||||
+#define __RESET_STARFIVE_JH71X0_H
|
||||
+
|
||||
+int jh7100_reset_probe(struct platform_device *pdev);
|
||||
+
|
||||
+#endif /* __RESET_STARFIVE_JH71X0_H */
|
@ -0,0 +1,215 @@
|
||||
From dbee38aac9811a25e3e3204f813048bf64155248 Mon Sep 17 00:00:00 2001
|
||||
From: Emil Renner Berthing <kernel@esmil.dk>
|
||||
Date: Sat, 1 Apr 2023 19:19:22 +0800
|
||||
Subject: [PATCH 010/122] reset: starfive: Extract the common JH71X0 reset code
|
||||
|
||||
Extract the common JH71X0 reset code for reusing them to
|
||||
support JH7110 SoC.
|
||||
|
||||
Tested-by: Tommaso Merciai <tomm.merciai@gmail.com>
|
||||
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
|
||||
Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
|
||||
Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
|
||||
Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
|
||||
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
|
||||
---
|
||||
.../reset/starfive/reset-starfive-jh7100.c | 49 ++++++++++++
|
||||
.../reset/starfive/reset-starfive-jh71x0.c | 76 ++++++-------------
|
||||
.../reset/starfive/reset-starfive-jh71x0.h | 5 +-
|
||||
3 files changed, 76 insertions(+), 54 deletions(-)
|
||||
|
||||
--- a/drivers/reset/starfive/reset-starfive-jh7100.c
|
||||
+++ b/drivers/reset/starfive/reset-starfive-jh7100.c
|
||||
@@ -10,6 +10,55 @@
|
||||
|
||||
#include "reset-starfive-jh71x0.h"
|
||||
|
||||
+#include <dt-bindings/reset/starfive-jh7100.h>
|
||||
+
|
||||
+/* register offsets */
|
||||
+#define JH7100_RESET_ASSERT0 0x00
|
||||
+#define JH7100_RESET_ASSERT1 0x04
|
||||
+#define JH7100_RESET_ASSERT2 0x08
|
||||
+#define JH7100_RESET_ASSERT3 0x0c
|
||||
+#define JH7100_RESET_STATUS0 0x10
|
||||
+#define JH7100_RESET_STATUS1 0x14
|
||||
+#define JH7100_RESET_STATUS2 0x18
|
||||
+#define JH7100_RESET_STATUS3 0x1c
|
||||
+
|
||||
+/*
|
||||
+ * Writing a 1 to the n'th bit of the m'th ASSERT register asserts
|
||||
+ * line 32m + n, and writing a 0 deasserts the same line.
|
||||
+ * Most reset lines have their status inverted so a 0 bit in the STATUS
|
||||
+ * register means the line is asserted and a 1 means it's deasserted. A few
|
||||
+ * lines don't though, so store the expected value of the status registers when
|
||||
+ * all lines are asserted.
|
||||
+ */
|
||||
+static const u64 jh7100_reset_asserted[2] = {
|
||||
+ /* STATUS0 */
|
||||
+ BIT_ULL_MASK(JH7100_RST_U74) |
|
||||
+ BIT_ULL_MASK(JH7100_RST_VP6_DRESET) |
|
||||
+ BIT_ULL_MASK(JH7100_RST_VP6_BRESET) |
|
||||
+ /* STATUS1 */
|
||||
+ BIT_ULL_MASK(JH7100_RST_HIFI4_DRESET) |
|
||||
+ BIT_ULL_MASK(JH7100_RST_HIFI4_BRESET),
|
||||
+ /* STATUS2 */
|
||||
+ BIT_ULL_MASK(JH7100_RST_E24) |
|
||||
+ /* STATUS3 */
|
||||
+ 0,
|
||||
+};
|
||||
+
|
||||
+static int __init jh7100_reset_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ void __iomem *base = devm_platform_ioremap_resource(pdev, 0);
|
||||
+
|
||||
+ if (IS_ERR(base))
|
||||
+ return PTR_ERR(base);
|
||||
+
|
||||
+ return reset_starfive_jh7100_register(&pdev->dev, pdev->dev.of_node,
|
||||
+ base + JH7100_RESET_ASSERT0,
|
||||
+ base + JH7100_RESET_STATUS0,
|
||||
+ jh7100_reset_asserted,
|
||||
+ JH7100_RSTN_END,
|
||||
+ THIS_MODULE);
|
||||
+}
|
||||
+
|
||||
static const struct of_device_id jh7100_reset_dt_ids[] = {
|
||||
{ .compatible = "starfive,jh7100-reset" },
|
||||
{ /* sentinel */ }
|
||||
--- a/drivers/reset/starfive/reset-starfive-jh71x0.c
|
||||
+++ b/drivers/reset/starfive/reset-starfive-jh71x0.c
|
||||
@@ -10,51 +10,18 @@
|
||||
#include <linux/io.h>
|
||||
#include <linux/io-64-nonatomic-lo-hi.h>
|
||||
#include <linux/iopoll.h>
|
||||
-#include <linux/platform_device.h>
|
||||
#include <linux/reset-controller.h>
|
||||
#include <linux/spinlock.h>
|
||||
|
||||
#include "reset-starfive-jh71x0.h"
|
||||
|
||||
-#include <dt-bindings/reset/starfive-jh7100.h>
|
||||
-
|
||||
-/* register offsets */
|
||||
-#define JH7100_RESET_ASSERT0 0x00
|
||||
-#define JH7100_RESET_ASSERT1 0x04
|
||||
-#define JH7100_RESET_ASSERT2 0x08
|
||||
-#define JH7100_RESET_ASSERT3 0x0c
|
||||
-#define JH7100_RESET_STATUS0 0x10
|
||||
-#define JH7100_RESET_STATUS1 0x14
|
||||
-#define JH7100_RESET_STATUS2 0x18
|
||||
-#define JH7100_RESET_STATUS3 0x1c
|
||||
-
|
||||
-/*
|
||||
- * Writing a 1 to the n'th bit of the m'th ASSERT register asserts
|
||||
- * line 32m + n, and writing a 0 deasserts the same line.
|
||||
- * Most reset lines have their status inverted so a 0 bit in the STATUS
|
||||
- * register means the line is asserted and a 1 means it's deasserted. A few
|
||||
- * lines don't though, so store the expected value of the status registers when
|
||||
- * all lines are asserted.
|
||||
- */
|
||||
-static const u64 jh7100_reset_asserted[2] = {
|
||||
- /* STATUS0 */
|
||||
- BIT_ULL_MASK(JH7100_RST_U74) |
|
||||
- BIT_ULL_MASK(JH7100_RST_VP6_DRESET) |
|
||||
- BIT_ULL_MASK(JH7100_RST_VP6_BRESET) |
|
||||
- /* STATUS1 */
|
||||
- BIT_ULL_MASK(JH7100_RST_HIFI4_DRESET) |
|
||||
- BIT_ULL_MASK(JH7100_RST_HIFI4_BRESET),
|
||||
- /* STATUS2 */
|
||||
- BIT_ULL_MASK(JH7100_RST_E24) |
|
||||
- /* STATUS3 */
|
||||
- 0,
|
||||
-};
|
||||
-
|
||||
struct jh7100_reset {
|
||||
struct reset_controller_dev rcdev;
|
||||
/* protect registers against concurrent read-modify-write */
|
||||
spinlock_t lock;
|
||||
- void __iomem *base;
|
||||
+ void __iomem *assert;
|
||||
+ void __iomem *status;
|
||||
+ const u64 *asserted;
|
||||
};
|
||||
|
||||
static inline struct jh7100_reset *
|
||||
@@ -69,9 +36,9 @@ static int jh7100_reset_update(struct re
|
||||
struct jh7100_reset *data = jh7100_reset_from(rcdev);
|
||||
unsigned long offset = BIT_ULL_WORD(id);
|
||||
u64 mask = BIT_ULL_MASK(id);
|
||||
- void __iomem *reg_assert = data->base + JH7100_RESET_ASSERT0 + offset * sizeof(u64);
|
||||
- void __iomem *reg_status = data->base + JH7100_RESET_STATUS0 + offset * sizeof(u64);
|
||||
- u64 done = jh7100_reset_asserted[offset] & mask;
|
||||
+ void __iomem *reg_assert = data->assert + offset * sizeof(u64);
|
||||
+ void __iomem *reg_status = data->status + offset * sizeof(u64);
|
||||
+ u64 done = data->asserted ? data->asserted[offset] & mask : 0;
|
||||
u64 value;
|
||||
unsigned long flags;
|
||||
int ret;
|
||||
@@ -125,10 +92,10 @@ static int jh7100_reset_status(struct re
|
||||
struct jh7100_reset *data = jh7100_reset_from(rcdev);
|
||||
unsigned long offset = BIT_ULL_WORD(id);
|
||||
u64 mask = BIT_ULL_MASK(id);
|
||||
- void __iomem *reg_status = data->base + JH7100_RESET_STATUS0 + offset * sizeof(u64);
|
||||
+ void __iomem *reg_status = data->status + offset * sizeof(u64);
|
||||
u64 value = readq(reg_status);
|
||||
|
||||
- return !((value ^ jh7100_reset_asserted[offset]) & mask);
|
||||
+ return !((value ^ data->asserted[offset]) & mask);
|
||||
}
|
||||
|
||||
static const struct reset_control_ops jh7100_reset_ops = {
|
||||
@@ -138,25 +105,28 @@ static const struct reset_control_ops jh
|
||||
.status = jh7100_reset_status,
|
||||
};
|
||||
|
||||
-int jh7100_reset_probe(struct platform_device *pdev)
|
||||
+int reset_starfive_jh7100_register(struct device *dev, struct device_node *of_node,
|
||||
+ void __iomem *assert, void __iomem *status,
|
||||
+ const u64 *asserted, unsigned int nr_resets,
|
||||
+ struct module *owner)
|
||||
{
|
||||
struct jh7100_reset *data;
|
||||
|
||||
- data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
|
||||
+ data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
|
||||
- data->base = devm_platform_ioremap_resource(pdev, 0);
|
||||
- if (IS_ERR(data->base))
|
||||
- return PTR_ERR(data->base);
|
||||
-
|
||||
data->rcdev.ops = &jh7100_reset_ops;
|
||||
- data->rcdev.owner = THIS_MODULE;
|
||||
- data->rcdev.nr_resets = JH7100_RSTN_END;
|
||||
- data->rcdev.dev = &pdev->dev;
|
||||
- data->rcdev.of_node = pdev->dev.of_node;
|
||||
+ data->rcdev.owner = owner;
|
||||
+ data->rcdev.nr_resets = nr_resets;
|
||||
+ data->rcdev.dev = dev;
|
||||
+ data->rcdev.of_node = of_node;
|
||||
+
|
||||
spin_lock_init(&data->lock);
|
||||
+ data->assert = assert;
|
||||
+ data->status = status;
|
||||
+ data->asserted = asserted;
|
||||
|
||||
- return devm_reset_controller_register(&pdev->dev, &data->rcdev);
|
||||
+ return devm_reset_controller_register(dev, &data->rcdev);
|
||||
}
|
||||
-EXPORT_SYMBOL_GPL(jh7100_reset_probe);
|
||||
+EXPORT_SYMBOL_GPL(reset_starfive_jh7100_register);
|
||||
--- a/drivers/reset/starfive/reset-starfive-jh71x0.h
|
||||
+++ b/drivers/reset/starfive/reset-starfive-jh71x0.h
|
||||
@@ -6,6 +6,9 @@
|
||||
#ifndef __RESET_STARFIVE_JH71X0_H
|
||||
#define __RESET_STARFIVE_JH71X0_H
|
||||
|
||||
-int jh7100_reset_probe(struct platform_device *pdev);
|
||||
+int reset_starfive_jh7100_register(struct device *dev, struct device_node *of_node,
|
||||
+ void __iomem *assert, void __iomem *status,
|
||||
+ const u64 *asserted, unsigned int nr_resets,
|
||||
+ struct module *owner);
|
||||
|
||||
#endif /* __RESET_STARFIVE_JH71X0_H */
|
@ -0,0 +1,167 @@
|
||||
From 798b9b4681be53ddbf1d8db8a88ff19aaaca500f Mon Sep 17 00:00:00 2001
|
||||
From: Emil Renner Berthing <kernel@esmil.dk>
|
||||
Date: Sat, 1 Apr 2023 19:19:23 +0800
|
||||
Subject: [PATCH 011/122] reset: starfive: Rename "jh7100" to "jh71x0" for the
|
||||
common code
|
||||
|
||||
For the common code will be shared with the StarFive JH7110 SoC.
|
||||
|
||||
Tested-by: Tommaso Merciai <tomm.merciai@gmail.com>
|
||||
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
|
||||
Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
|
||||
Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
|
||||
Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
|
||||
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
|
||||
---
|
||||
.../reset/starfive/reset-starfive-jh7100.c | 2 +-
|
||||
.../reset/starfive/reset-starfive-jh71x0.c | 50 +++++++++----------
|
||||
.../reset/starfive/reset-starfive-jh71x0.h | 2 +-
|
||||
3 files changed, 27 insertions(+), 27 deletions(-)
|
||||
|
||||
--- a/drivers/reset/starfive/reset-starfive-jh7100.c
|
||||
+++ b/drivers/reset/starfive/reset-starfive-jh7100.c
|
||||
@@ -51,7 +51,7 @@ static int __init jh7100_reset_probe(str
|
||||
if (IS_ERR(base))
|
||||
return PTR_ERR(base);
|
||||
|
||||
- return reset_starfive_jh7100_register(&pdev->dev, pdev->dev.of_node,
|
||||
+ return reset_starfive_jh71x0_register(&pdev->dev, pdev->dev.of_node,
|
||||
base + JH7100_RESET_ASSERT0,
|
||||
base + JH7100_RESET_STATUS0,
|
||||
jh7100_reset_asserted,
|
||||
--- a/drivers/reset/starfive/reset-starfive-jh71x0.c
|
||||
+++ b/drivers/reset/starfive/reset-starfive-jh71x0.c
|
||||
@@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
- * Reset driver for the StarFive JH7100 SoC
|
||||
+ * Reset driver for the StarFive JH71X0 SoCs
|
||||
*
|
||||
* Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
|
||||
*/
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
#include "reset-starfive-jh71x0.h"
|
||||
|
||||
-struct jh7100_reset {
|
||||
+struct jh71x0_reset {
|
||||
struct reset_controller_dev rcdev;
|
||||
/* protect registers against concurrent read-modify-write */
|
||||
spinlock_t lock;
|
||||
@@ -24,16 +24,16 @@ struct jh7100_reset {
|
||||
const u64 *asserted;
|
||||
};
|
||||
|
||||
-static inline struct jh7100_reset *
|
||||
-jh7100_reset_from(struct reset_controller_dev *rcdev)
|
||||
+static inline struct jh71x0_reset *
|
||||
+jh71x0_reset_from(struct reset_controller_dev *rcdev)
|
||||
{
|
||||
- return container_of(rcdev, struct jh7100_reset, rcdev);
|
||||
+ return container_of(rcdev, struct jh71x0_reset, rcdev);
|
||||
}
|
||||
|
||||
-static int jh7100_reset_update(struct reset_controller_dev *rcdev,
|
||||
+static int jh71x0_reset_update(struct reset_controller_dev *rcdev,
|
||||
unsigned long id, bool assert)
|
||||
{
|
||||
- struct jh7100_reset *data = jh7100_reset_from(rcdev);
|
||||
+ struct jh71x0_reset *data = jh71x0_reset_from(rcdev);
|
||||
unsigned long offset = BIT_ULL_WORD(id);
|
||||
u64 mask = BIT_ULL_MASK(id);
|
||||
void __iomem *reg_assert = data->assert + offset * sizeof(u64);
|
||||
@@ -62,34 +62,34 @@ static int jh7100_reset_update(struct re
|
||||
return ret;
|
||||
}
|
||||
|
||||
-static int jh7100_reset_assert(struct reset_controller_dev *rcdev,
|
||||
+static int jh71x0_reset_assert(struct reset_controller_dev *rcdev,
|
||||
unsigned long id)
|
||||
{
|
||||
- return jh7100_reset_update(rcdev, id, true);
|
||||
+ return jh71x0_reset_update(rcdev, id, true);
|
||||
}
|
||||
|
||||
-static int jh7100_reset_deassert(struct reset_controller_dev *rcdev,
|
||||
+static int jh71x0_reset_deassert(struct reset_controller_dev *rcdev,
|
||||
unsigned long id)
|
||||
{
|
||||
- return jh7100_reset_update(rcdev, id, false);
|
||||
+ return jh71x0_reset_update(rcdev, id, false);
|
||||
}
|
||||
|
||||
-static int jh7100_reset_reset(struct reset_controller_dev *rcdev,
|
||||
+static int jh71x0_reset_reset(struct reset_controller_dev *rcdev,
|
||||
unsigned long id)
|
||||
{
|
||||
int ret;
|
||||
|
||||
- ret = jh7100_reset_assert(rcdev, id);
|
||||
+ ret = jh71x0_reset_assert(rcdev, id);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
- return jh7100_reset_deassert(rcdev, id);
|
||||
+ return jh71x0_reset_deassert(rcdev, id);
|
||||
}
|
||||
|
||||
-static int jh7100_reset_status(struct reset_controller_dev *rcdev,
|
||||
+static int jh71x0_reset_status(struct reset_controller_dev *rcdev,
|
||||
unsigned long id)
|
||||
{
|
||||
- struct jh7100_reset *data = jh7100_reset_from(rcdev);
|
||||
+ struct jh71x0_reset *data = jh71x0_reset_from(rcdev);
|
||||
unsigned long offset = BIT_ULL_WORD(id);
|
||||
u64 mask = BIT_ULL_MASK(id);
|
||||
void __iomem *reg_status = data->status + offset * sizeof(u64);
|
||||
@@ -98,25 +98,25 @@ static int jh7100_reset_status(struct re
|
||||
return !((value ^ data->asserted[offset]) & mask);
|
||||
}
|
||||
|
||||
-static const struct reset_control_ops jh7100_reset_ops = {
|
||||
- .assert = jh7100_reset_assert,
|
||||
- .deassert = jh7100_reset_deassert,
|
||||
- .reset = jh7100_reset_reset,
|
||||
- .status = jh7100_reset_status,
|
||||
+static const struct reset_control_ops jh71x0_reset_ops = {
|
||||
+ .assert = jh71x0_reset_assert,
|
||||
+ .deassert = jh71x0_reset_deassert,
|
||||
+ .reset = jh71x0_reset_reset,
|
||||
+ .status = jh71x0_reset_status,
|
||||
};
|
||||
|
||||
-int reset_starfive_jh7100_register(struct device *dev, struct device_node *of_node,
|
||||
+int reset_starfive_jh71x0_register(struct device *dev, struct device_node *of_node,
|
||||
void __iomem *assert, void __iomem *status,
|
||||
const u64 *asserted, unsigned int nr_resets,
|
||||
struct module *owner)
|
||||
{
|
||||
- struct jh7100_reset *data;
|
||||
+ struct jh71x0_reset *data;
|
||||
|
||||
data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
|
||||
- data->rcdev.ops = &jh7100_reset_ops;
|
||||
+ data->rcdev.ops = &jh71x0_reset_ops;
|
||||
data->rcdev.owner = owner;
|
||||
data->rcdev.nr_resets = nr_resets;
|
||||
data->rcdev.dev = dev;
|
||||
@@ -129,4 +129,4 @@ int reset_starfive_jh7100_register(struc
|
||||
|
||||
return devm_reset_controller_register(dev, &data->rcdev);
|
||||
}
|
||||
-EXPORT_SYMBOL_GPL(reset_starfive_jh7100_register);
|
||||
+EXPORT_SYMBOL_GPL(reset_starfive_jh71x0_register);
|
||||
--- a/drivers/reset/starfive/reset-starfive-jh71x0.h
|
||||
+++ b/drivers/reset/starfive/reset-starfive-jh71x0.h
|
||||
@@ -6,7 +6,7 @@
|
||||
#ifndef __RESET_STARFIVE_JH71X0_H
|
||||
#define __RESET_STARFIVE_JH71X0_H
|
||||
|
||||
-int reset_starfive_jh7100_register(struct device *dev, struct device_node *of_node,
|
||||
+int reset_starfive_jh71x0_register(struct device *dev, struct device_node *of_node,
|
||||
void __iomem *assert, void __iomem *status,
|
||||
const u64 *asserted, unsigned int nr_resets,
|
||||
struct module *owner);
|
@ -0,0 +1,146 @@
|
||||
From 365bb978e5e11a16c362d9c2c64d7bf8d04999df Mon Sep 17 00:00:00 2001
|
||||
From: Emil Renner Berthing <kernel@esmil.dk>
|
||||
Date: Sat, 1 Apr 2023 19:19:24 +0800
|
||||
Subject: [PATCH 012/122] reset: starfive: jh71x0: Use 32bit I/O on 32bit
|
||||
registers
|
||||
|
||||
We currently use 64bit I/O on the 32bit registers. This works because
|
||||
there are an even number of assert and status registers, so they're only
|
||||
ever accessed in pairs on 64bit boundaries.
|
||||
|
||||
There are however other reset controllers for audio and video on the
|
||||
JH7100 SoC with only one status register that isn't 64bit aligned so
|
||||
64bit I/O results in an unaligned access exception.
|
||||
|
||||
Switch to 32bit I/O in preparation for supporting these resets too.
|
||||
|
||||
Tested-by: Tommaso Merciai <tomm.merciai@gmail.com>
|
||||
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
|
||||
Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
|
||||
Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
|
||||
Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
|
||||
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
|
||||
---
|
||||
.../reset/starfive/reset-starfive-jh7100.c | 14 ++++-----
|
||||
.../reset/starfive/reset-starfive-jh71x0.c | 31 +++++++++----------
|
||||
.../reset/starfive/reset-starfive-jh71x0.h | 2 +-
|
||||
3 files changed, 23 insertions(+), 24 deletions(-)
|
||||
|
||||
--- a/drivers/reset/starfive/reset-starfive-jh7100.c
|
||||
+++ b/drivers/reset/starfive/reset-starfive-jh7100.c
|
||||
@@ -30,16 +30,16 @@
|
||||
* lines don't though, so store the expected value of the status registers when
|
||||
* all lines are asserted.
|
||||
*/
|
||||
-static const u64 jh7100_reset_asserted[2] = {
|
||||
+static const u32 jh7100_reset_asserted[4] = {
|
||||
/* STATUS0 */
|
||||
- BIT_ULL_MASK(JH7100_RST_U74) |
|
||||
- BIT_ULL_MASK(JH7100_RST_VP6_DRESET) |
|
||||
- BIT_ULL_MASK(JH7100_RST_VP6_BRESET) |
|
||||
+ BIT(JH7100_RST_U74 % 32) |
|
||||
+ BIT(JH7100_RST_VP6_DRESET % 32) |
|
||||
+ BIT(JH7100_RST_VP6_BRESET % 32),
|
||||
/* STATUS1 */
|
||||
- BIT_ULL_MASK(JH7100_RST_HIFI4_DRESET) |
|
||||
- BIT_ULL_MASK(JH7100_RST_HIFI4_BRESET),
|
||||
+ BIT(JH7100_RST_HIFI4_DRESET % 32) |
|
||||
+ BIT(JH7100_RST_HIFI4_BRESET % 32),
|
||||
/* STATUS2 */
|
||||
- BIT_ULL_MASK(JH7100_RST_E24) |
|
||||
+ BIT(JH7100_RST_E24 % 32),
|
||||
/* STATUS3 */
|
||||
0,
|
||||
};
|
||||
--- a/drivers/reset/starfive/reset-starfive-jh71x0.c
|
||||
+++ b/drivers/reset/starfive/reset-starfive-jh71x0.c
|
||||
@@ -8,7 +8,6 @@
|
||||
#include <linux/bitmap.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/io.h>
|
||||
-#include <linux/io-64-nonatomic-lo-hi.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include <linux/reset-controller.h>
|
||||
#include <linux/spinlock.h>
|
||||
@@ -21,7 +20,7 @@ struct jh71x0_reset {
|
||||
spinlock_t lock;
|
||||
void __iomem *assert;
|
||||
void __iomem *status;
|
||||
- const u64 *asserted;
|
||||
+ const u32 *asserted;
|
||||
};
|
||||
|
||||
static inline struct jh71x0_reset *
|
||||
@@ -34,12 +33,12 @@ static int jh71x0_reset_update(struct re
|
||||
unsigned long id, bool assert)
|
||||
{
|
||||
struct jh71x0_reset *data = jh71x0_reset_from(rcdev);
|
||||
- unsigned long offset = BIT_ULL_WORD(id);
|
||||
- u64 mask = BIT_ULL_MASK(id);
|
||||
- void __iomem *reg_assert = data->assert + offset * sizeof(u64);
|
||||
- void __iomem *reg_status = data->status + offset * sizeof(u64);
|
||||
- u64 done = data->asserted ? data->asserted[offset] & mask : 0;
|
||||
- u64 value;
|
||||
+ unsigned long offset = id / 32;
|
||||
+ u32 mask = BIT(id % 32);
|
||||
+ void __iomem *reg_assert = data->assert + offset * sizeof(u32);
|
||||
+ void __iomem *reg_status = data->status + offset * sizeof(u32);
|
||||
+ u32 done = data->asserted ? data->asserted[offset] & mask : 0;
|
||||
+ u32 value;
|
||||
unsigned long flags;
|
||||
int ret;
|
||||
|
||||
@@ -48,15 +47,15 @@ static int jh71x0_reset_update(struct re
|
||||
|
||||
spin_lock_irqsave(&data->lock, flags);
|
||||
|
||||
- value = readq(reg_assert);
|
||||
+ value = readl(reg_assert);
|
||||
if (assert)
|
||||
value |= mask;
|
||||
else
|
||||
value &= ~mask;
|
||||
- writeq(value, reg_assert);
|
||||
+ writel(value, reg_assert);
|
||||
|
||||
/* if the associated clock is gated, deasserting might otherwise hang forever */
|
||||
- ret = readq_poll_timeout_atomic(reg_status, value, (value & mask) == done, 0, 1000);
|
||||
+ ret = readl_poll_timeout_atomic(reg_status, value, (value & mask) == done, 0, 1000);
|
||||
|
||||
spin_unlock_irqrestore(&data->lock, flags);
|
||||
return ret;
|
||||
@@ -90,10 +89,10 @@ static int jh71x0_reset_status(struct re
|
||||
unsigned long id)
|
||||
{
|
||||
struct jh71x0_reset *data = jh71x0_reset_from(rcdev);
|
||||
- unsigned long offset = BIT_ULL_WORD(id);
|
||||
- u64 mask = BIT_ULL_MASK(id);
|
||||
- void __iomem *reg_status = data->status + offset * sizeof(u64);
|
||||
- u64 value = readq(reg_status);
|
||||
+ unsigned long offset = id / 32;
|
||||
+ u32 mask = BIT(id % 32);
|
||||
+ void __iomem *reg_status = data->status + offset * sizeof(u32);
|
||||
+ u32 value = readl(reg_status);
|
||||
|
||||
return !((value ^ data->asserted[offset]) & mask);
|
||||
}
|
||||
@@ -107,7 +106,7 @@ static const struct reset_control_ops jh
|
||||
|
||||
int reset_starfive_jh71x0_register(struct device *dev, struct device_node *of_node,
|
||||
void __iomem *assert, void __iomem *status,
|
||||
- const u64 *asserted, unsigned int nr_resets,
|
||||
+ const u32 *asserted, unsigned int nr_resets,
|
||||
struct module *owner)
|
||||
{
|
||||
struct jh71x0_reset *data;
|
||||
--- a/drivers/reset/starfive/reset-starfive-jh71x0.h
|
||||
+++ b/drivers/reset/starfive/reset-starfive-jh71x0.h
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
int reset_starfive_jh71x0_register(struct device *dev, struct device_node *of_node,
|
||||
void __iomem *assert, void __iomem *status,
|
||||
- const u64 *asserted, unsigned int nr_resets,
|
||||
+ const u32 *asserted, unsigned int nr_resets,
|
||||
struct module *owner);
|
||||
|
||||
#endif /* __RESET_STARFIVE_JH71X0_H */
|
@ -0,0 +1,557 @@
|
||||
From eea853275c704f6c24a418a50715bc5ad68a6283 Mon Sep 17 00:00:00 2001
|
||||
From: Emil Renner Berthing <kernel@esmil.dk>
|
||||
Date: Sat, 1 Apr 2023 19:19:25 +0800
|
||||
Subject: [PATCH 013/122] clk: starfive: Add StarFive JH7110 system clock
|
||||
driver
|
||||
|
||||
Add driver for the StarFive JH7110 system clock controller and
|
||||
register an auxiliary device for system reset controller which
|
||||
is named as "rst-sys".
|
||||
|
||||
Tested-by: Tommaso Merciai <tomm.merciai@gmail.com>
|
||||
Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
|
||||
Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
|
||||
Co-developed-by: Hal Feng <hal.feng@starfivetech.com>
|
||||
Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
|
||||
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
|
||||
---
|
||||
drivers/clk/starfive/Kconfig | 11 +
|
||||
drivers/clk/starfive/Makefile | 2 +
|
||||
.../clk/starfive/clk-starfive-jh7110-sys.c | 490 ++++++++++++++++++
|
||||
drivers/clk/starfive/clk-starfive-jh7110.h | 11 +
|
||||
4 files changed, 514 insertions(+)
|
||||
create mode 100644 drivers/clk/starfive/clk-starfive-jh7110-sys.c
|
||||
create mode 100644 drivers/clk/starfive/clk-starfive-jh7110.h
|
||||
|
||||
--- a/drivers/clk/starfive/Kconfig
|
||||
+++ b/drivers/clk/starfive/Kconfig
|
||||
@@ -20,3 +20,14 @@ config CLK_STARFIVE_JH7100_AUDIO
|
||||
help
|
||||
Say Y or M here to support the audio clocks on the StarFive JH7100
|
||||
SoC.
|
||||
+
|
||||
+config CLK_STARFIVE_JH7110_SYS
|
||||
+ bool "StarFive JH7110 system clock support"
|
||||
+ depends on ARCH_STARFIVE || COMPILE_TEST
|
||||
+ select AUXILIARY_BUS
|
||||
+ select CLK_STARFIVE_JH71X0
|
||||
+ select RESET_STARFIVE_JH7110
|
||||
+ default ARCH_STARFIVE
|
||||
+ help
|
||||
+ Say yes here to support the system clock controller on the
|
||||
+ StarFive JH7110 SoC.
|
||||
--- a/drivers/clk/starfive/Makefile
|
||||
+++ b/drivers/clk/starfive/Makefile
|
||||
@@ -3,3 +3,5 @@ obj-$(CONFIG_CLK_STARFIVE_JH71X0) += clk
|
||||
|
||||
obj-$(CONFIG_CLK_STARFIVE_JH7100) += clk-starfive-jh7100.o
|
||||
obj-$(CONFIG_CLK_STARFIVE_JH7100_AUDIO) += clk-starfive-jh7100-audio.o
|
||||
+
|
||||
+obj-$(CONFIG_CLK_STARFIVE_JH7110_SYS) += clk-starfive-jh7110-sys.o
|
||||
--- /dev/null
|
||||
+++ b/drivers/clk/starfive/clk-starfive-jh7110-sys.c
|
||||
@@ -0,0 +1,490 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0
|
||||
+/*
|
||||
+ * StarFive JH7110 System Clock Driver
|
||||
+ *
|
||||
+ * Copyright (C) 2022 Emil Renner Berthing <kernel@esmil.dk>
|
||||
+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/auxiliary_bus.h>
|
||||
+#include <linux/clk-provider.h>
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/io.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+
|
||||
+#include <dt-bindings/clock/starfive,jh7110-crg.h>
|
||||
+
|
||||
+#include "clk-starfive-jh7110.h"
|
||||
+
|
||||
+/* external clocks */
|
||||
+#define JH7110_SYSCLK_OSC (JH7110_SYSCLK_END + 0)
|
||||
+#define JH7110_SYSCLK_GMAC1_RMII_REFIN (JH7110_SYSCLK_END + 1)
|
||||
+#define JH7110_SYSCLK_GMAC1_RGMII_RXIN (JH7110_SYSCLK_END + 2)
|
||||
+#define JH7110_SYSCLK_I2STX_BCLK_EXT (JH7110_SYSCLK_END + 3)
|
||||
+#define JH7110_SYSCLK_I2STX_LRCK_EXT (JH7110_SYSCLK_END + 4)
|
||||
+#define JH7110_SYSCLK_I2SRX_BCLK_EXT (JH7110_SYSCLK_END + 5)
|
||||
+#define JH7110_SYSCLK_I2SRX_LRCK_EXT (JH7110_SYSCLK_END + 6)
|
||||
+#define JH7110_SYSCLK_TDM_EXT (JH7110_SYSCLK_END + 7)
|
||||
+#define JH7110_SYSCLK_MCLK_EXT (JH7110_SYSCLK_END + 8)
|
||||
+#define JH7110_SYSCLK_PLL0_OUT (JH7110_SYSCLK_END + 9)
|
||||
+#define JH7110_SYSCLK_PLL1_OUT (JH7110_SYSCLK_END + 10)
|
||||
+#define JH7110_SYSCLK_PLL2_OUT (JH7110_SYSCLK_END + 11)
|
||||
+
|
||||
+static const struct jh71x0_clk_data jh7110_sysclk_data[] __initconst = {
|
||||
+ /* root */
|
||||
+ JH71X0__MUX(JH7110_SYSCLK_CPU_ROOT, "cpu_root", 2,
|
||||
+ JH7110_SYSCLK_OSC,
|
||||
+ JH7110_SYSCLK_PLL0_OUT),
|
||||
+ JH71X0__DIV(JH7110_SYSCLK_CPU_CORE, "cpu_core", 7, JH7110_SYSCLK_CPU_ROOT),
|
||||
+ JH71X0__DIV(JH7110_SYSCLK_CPU_BUS, "cpu_bus", 2, JH7110_SYSCLK_CPU_CORE),
|
||||
+ JH71X0__MUX(JH7110_SYSCLK_GPU_ROOT, "gpu_root", 2,
|
||||
+ JH7110_SYSCLK_PLL2_OUT,
|
||||
+ JH7110_SYSCLK_PLL1_OUT),
|
||||
+ JH71X0_MDIV(JH7110_SYSCLK_PERH_ROOT, "perh_root", 2, 2,
|
||||
+ JH7110_SYSCLK_PLL0_OUT,
|
||||
+ JH7110_SYSCLK_PLL2_OUT),
|
||||
+ JH71X0__MUX(JH7110_SYSCLK_BUS_ROOT, "bus_root", 2,
|
||||
+ JH7110_SYSCLK_OSC,
|
||||
+ JH7110_SYSCLK_PLL2_OUT),
|
||||
+ JH71X0__DIV(JH7110_SYSCLK_NOCSTG_BUS, "nocstg_bus", 3, JH7110_SYSCLK_BUS_ROOT),
|
||||
+ JH71X0__DIV(JH7110_SYSCLK_AXI_CFG0, "axi_cfg0", 3, JH7110_SYSCLK_BUS_ROOT),
|
||||
+ JH71X0__DIV(JH7110_SYSCLK_STG_AXIAHB, "stg_axiahb", 2, JH7110_SYSCLK_AXI_CFG0),
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_AHB0, "ahb0", CLK_IS_CRITICAL, JH7110_SYSCLK_STG_AXIAHB),
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_AHB1, "ahb1", CLK_IS_CRITICAL, JH7110_SYSCLK_STG_AXIAHB),
|
||||
+ JH71X0__DIV(JH7110_SYSCLK_APB_BUS, "apb_bus", 8, JH7110_SYSCLK_STG_AXIAHB),
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_APB0, "apb0", CLK_IS_CRITICAL, JH7110_SYSCLK_APB_BUS),
|
||||
+ JH71X0__DIV(JH7110_SYSCLK_PLL0_DIV2, "pll0_div2", 2, JH7110_SYSCLK_PLL0_OUT),
|
||||
+ JH71X0__DIV(JH7110_SYSCLK_PLL1_DIV2, "pll1_div2", 2, JH7110_SYSCLK_PLL1_OUT),
|
||||
+ JH71X0__DIV(JH7110_SYSCLK_PLL2_DIV2, "pll2_div2", 2, JH7110_SYSCLK_PLL2_OUT),
|
||||
+ JH71X0__DIV(JH7110_SYSCLK_AUDIO_ROOT, "audio_root", 8, JH7110_SYSCLK_PLL2_OUT),
|
||||
+ JH71X0__DIV(JH7110_SYSCLK_MCLK_INNER, "mclk_inner", 64, JH7110_SYSCLK_AUDIO_ROOT),
|
||||
+ JH71X0__MUX(JH7110_SYSCLK_MCLK, "mclk", 2,
|
||||
+ JH7110_SYSCLK_MCLK_INNER,
|
||||
+ JH7110_SYSCLK_MCLK_EXT),
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_MCLK_OUT, "mclk_out", 0, JH7110_SYSCLK_MCLK_INNER),
|
||||
+ JH71X0_MDIV(JH7110_SYSCLK_ISP_2X, "isp_2x", 8, 2,
|
||||
+ JH7110_SYSCLK_PLL2_OUT,
|
||||
+ JH7110_SYSCLK_PLL1_OUT),
|
||||
+ JH71X0__DIV(JH7110_SYSCLK_ISP_AXI, "isp_axi", 4, JH7110_SYSCLK_ISP_2X),
|
||||
+ JH71X0_GDIV(JH7110_SYSCLK_GCLK0, "gclk0", 0, 62, JH7110_SYSCLK_PLL0_DIV2),
|
||||
+ JH71X0_GDIV(JH7110_SYSCLK_GCLK1, "gclk1", 0, 62, JH7110_SYSCLK_PLL1_DIV2),
|
||||
+ JH71X0_GDIV(JH7110_SYSCLK_GCLK2, "gclk2", 0, 62, JH7110_SYSCLK_PLL2_DIV2),
|
||||
+ /* cores */
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_CORE, "core", CLK_IS_CRITICAL, JH7110_SYSCLK_CPU_CORE),
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_CORE1, "core1", CLK_IS_CRITICAL, JH7110_SYSCLK_CPU_CORE),
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_CORE2, "core2", CLK_IS_CRITICAL, JH7110_SYSCLK_CPU_CORE),
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_CORE3, "core3", CLK_IS_CRITICAL, JH7110_SYSCLK_CPU_CORE),
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_CORE4, "core4", CLK_IS_CRITICAL, JH7110_SYSCLK_CPU_CORE),
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_DEBUG, "debug", 0, JH7110_SYSCLK_CPU_BUS),
|
||||
+ JH71X0__DIV(JH7110_SYSCLK_RTC_TOGGLE, "rtc_toggle", 6, JH7110_SYSCLK_OSC),
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_TRACE0, "trace0", 0, JH7110_SYSCLK_CPU_CORE),
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_TRACE1, "trace1", 0, JH7110_SYSCLK_CPU_CORE),
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_TRACE2, "trace2", 0, JH7110_SYSCLK_CPU_CORE),
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_TRACE3, "trace3", 0, JH7110_SYSCLK_CPU_CORE),
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_TRACE4, "trace4", 0, JH7110_SYSCLK_CPU_CORE),
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_TRACE_COM, "trace_com", 0, JH7110_SYSCLK_CPU_BUS),
|
||||
+ /* noc */
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_NOC_BUS_CPU_AXI, "noc_bus_cpu_axi", CLK_IS_CRITICAL,
|
||||
+ JH7110_SYSCLK_CPU_BUS),
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_NOC_BUS_AXICFG0_AXI, "noc_bus_axicfg0_axi", CLK_IS_CRITICAL,
|
||||
+ JH7110_SYSCLK_AXI_CFG0),
|
||||
+ /* ddr */
|
||||
+ JH71X0__DIV(JH7110_SYSCLK_OSC_DIV2, "osc_div2", 2, JH7110_SYSCLK_OSC),
|
||||
+ JH71X0__DIV(JH7110_SYSCLK_PLL1_DIV4, "pll1_div4", 2, JH7110_SYSCLK_PLL1_DIV2),
|
||||
+ JH71X0__DIV(JH7110_SYSCLK_PLL1_DIV8, "pll1_div8", 2, JH7110_SYSCLK_PLL1_DIV4),
|
||||
+ JH71X0__MUX(JH7110_SYSCLK_DDR_BUS, "ddr_bus", 4,
|
||||
+ JH7110_SYSCLK_OSC_DIV2,
|
||||
+ JH7110_SYSCLK_PLL1_DIV2,
|
||||
+ JH7110_SYSCLK_PLL1_DIV4,
|
||||
+ JH7110_SYSCLK_PLL1_DIV8),
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_DDR_AXI, "ddr_axi", CLK_IS_CRITICAL, JH7110_SYSCLK_DDR_BUS),
|
||||
+ /* gpu */
|
||||
+ JH71X0__DIV(JH7110_SYSCLK_GPU_CORE, "gpu_core", 7, JH7110_SYSCLK_GPU_ROOT),
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_GPU_CORE_CLK, "gpu_core_clk", 0, JH7110_SYSCLK_GPU_CORE),
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_GPU_SYS_CLK, "gpu_sys_clk", 0, JH7110_SYSCLK_ISP_AXI),
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_GPU_APB, "gpu_apb", 0, JH7110_SYSCLK_APB_BUS),
|
||||
+ JH71X0_GDIV(JH7110_SYSCLK_GPU_RTC_TOGGLE, "gpu_rtc_toggle", 0, 12, JH7110_SYSCLK_OSC),
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_NOC_BUS_GPU_AXI, "noc_bus_gpu_axi", 0, JH7110_SYSCLK_GPU_CORE),
|
||||
+ /* isp */
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_ISP_TOP_CORE, "isp_top_core", 0, JH7110_SYSCLK_ISP_2X),
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_ISP_TOP_AXI, "isp_top_axi", 0, JH7110_SYSCLK_ISP_AXI),
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_NOC_BUS_ISP_AXI, "noc_bus_isp_axi", CLK_IS_CRITICAL,
|
||||
+ JH7110_SYSCLK_ISP_AXI),
|
||||
+ /* hifi4 */
|
||||
+ JH71X0__DIV(JH7110_SYSCLK_HIFI4_CORE, "hifi4_core", 15, JH7110_SYSCLK_BUS_ROOT),
|
||||
+ JH71X0__DIV(JH7110_SYSCLK_HIFI4_AXI, "hifi4_axi", 2, JH7110_SYSCLK_HIFI4_CORE),
|
||||
+ /* axi_cfg1 */
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_AXI_CFG1_MAIN, "axi_cfg1_main", CLK_IS_CRITICAL,
|
||||
+ JH7110_SYSCLK_ISP_AXI),
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_AXI_CFG1_AHB, "axi_cfg1_ahb", CLK_IS_CRITICAL,
|
||||
+ JH7110_SYSCLK_AHB0),
|
||||
+ /* vout */
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_VOUT_SRC, "vout_src", 0, JH7110_SYSCLK_PLL2_OUT),
|
||||
+ JH71X0__DIV(JH7110_SYSCLK_VOUT_AXI, "vout_axi", 7, JH7110_SYSCLK_PLL2_OUT),
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_NOC_BUS_DISP_AXI, "noc_bus_disp_axi", 0, JH7110_SYSCLK_VOUT_AXI),
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_VOUT_TOP_AHB, "vout_top_ahb", 0, JH7110_SYSCLK_AHB1),
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_VOUT_TOP_AXI, "vout_top_axi", 0, JH7110_SYSCLK_VOUT_AXI),
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_VOUT_TOP_HDMITX0_MCLK, "vout_top_hdmitx0_mclk", 0,
|
||||
+ JH7110_SYSCLK_MCLK),
|
||||
+ JH71X0__DIV(JH7110_SYSCLK_VOUT_TOP_MIPIPHY_REF, "vout_top_mipiphy_ref", 2,
|
||||
+ JH7110_SYSCLK_OSC),
|
||||
+ /* jpegc */
|
||||
+ JH71X0__DIV(JH7110_SYSCLK_JPEGC_AXI, "jpegc_axi", 16, JH7110_SYSCLK_PLL2_OUT),
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_CODAJ12_AXI, "codaj12_axi", 0, JH7110_SYSCLK_JPEGC_AXI),
|
||||
+ JH71X0_GDIV(JH7110_SYSCLK_CODAJ12_CORE, "codaj12_core", 0, 16, JH7110_SYSCLK_PLL2_OUT),
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_CODAJ12_APB, "codaj12_apb", 0, JH7110_SYSCLK_APB_BUS),
|
||||
+ /* vdec */
|
||||
+ JH71X0__DIV(JH7110_SYSCLK_VDEC_AXI, "vdec_axi", 7, JH7110_SYSCLK_BUS_ROOT),
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_WAVE511_AXI, "wave511_axi", 0, JH7110_SYSCLK_VDEC_AXI),
|
||||
+ JH71X0_GDIV(JH7110_SYSCLK_WAVE511_BPU, "wave511_bpu", 0, 7, JH7110_SYSCLK_BUS_ROOT),
|
||||
+ JH71X0_GDIV(JH7110_SYSCLK_WAVE511_VCE, "wave511_vce", 0, 7, JH7110_SYSCLK_PLL0_OUT),
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_WAVE511_APB, "wave511_apb", 0, JH7110_SYSCLK_APB_BUS),
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_VDEC_JPG, "vdec_jpg", 0, JH7110_SYSCLK_JPEGC_AXI),
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_VDEC_MAIN, "vdec_main", 0, JH7110_SYSCLK_VDEC_AXI),
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_NOC_BUS_VDEC_AXI, "noc_bus_vdec_axi", 0, JH7110_SYSCLK_VDEC_AXI),
|
||||
+ /* venc */
|
||||
+ JH71X0__DIV(JH7110_SYSCLK_VENC_AXI, "venc_axi", 15, JH7110_SYSCLK_PLL2_OUT),
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_WAVE420L_AXI, "wave420l_axi", 0, JH7110_SYSCLK_VENC_AXI),
|
||||
+ JH71X0_GDIV(JH7110_SYSCLK_WAVE420L_BPU, "wave420l_bpu", 0, 15, JH7110_SYSCLK_PLL2_OUT),
|
||||
+ JH71X0_GDIV(JH7110_SYSCLK_WAVE420L_VCE, "wave420l_vce", 0, 15, JH7110_SYSCLK_PLL2_OUT),
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_WAVE420L_APB, "wave420l_apb", 0, JH7110_SYSCLK_APB_BUS),
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_NOC_BUS_VENC_AXI, "noc_bus_venc_axi", 0, JH7110_SYSCLK_VENC_AXI),
|
||||
+ /* axi_cfg0 */
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_AXI_CFG0_MAIN_DIV, "axi_cfg0_main_div", CLK_IS_CRITICAL,
|
||||
+ JH7110_SYSCLK_AHB1),
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_AXI_CFG0_MAIN, "axi_cfg0_main", CLK_IS_CRITICAL,
|
||||
+ JH7110_SYSCLK_AXI_CFG0),
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_AXI_CFG0_HIFI4, "axi_cfg0_hifi4", CLK_IS_CRITICAL,
|
||||
+ JH7110_SYSCLK_HIFI4_AXI),
|
||||
+ /* intmem */
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_AXIMEM2_AXI, "aximem2_axi", 0, JH7110_SYSCLK_AXI_CFG0),
|
||||
+ /* qspi */
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_QSPI_AHB, "qspi_ahb", 0, JH7110_SYSCLK_AHB1),
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_QSPI_APB, "qspi_apb", 0, JH7110_SYSCLK_APB_BUS),
|
||||
+ JH71X0__DIV(JH7110_SYSCLK_QSPI_REF_SRC, "qspi_ref_src", 16, JH7110_SYSCLK_PLL0_OUT),
|
||||
+ JH71X0_GMUX(JH7110_SYSCLK_QSPI_REF, "qspi_ref", 0, 2,
|
||||
+ JH7110_SYSCLK_OSC,
|
||||
+ JH7110_SYSCLK_QSPI_REF_SRC),
|
||||
+ /* sdio */
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_SDIO0_AHB, "sdio0_ahb", 0, JH7110_SYSCLK_AHB0),
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_SDIO1_AHB, "sdio1_ahb", 0, JH7110_SYSCLK_AHB0),
|
||||
+ JH71X0_GDIV(JH7110_SYSCLK_SDIO0_SDCARD, "sdio0_sdcard", 0, 15, JH7110_SYSCLK_AXI_CFG0),
|
||||
+ JH71X0_GDIV(JH7110_SYSCLK_SDIO1_SDCARD, "sdio1_sdcard", 0, 15, JH7110_SYSCLK_AXI_CFG0),
|
||||
+ /* stg */
|
||||
+ JH71X0__DIV(JH7110_SYSCLK_USB_125M, "usb_125m", 15, JH7110_SYSCLK_PLL0_OUT),
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_NOC_BUS_STG_AXI, "noc_bus_stg_axi", CLK_IS_CRITICAL,
|
||||
+ JH7110_SYSCLK_NOCSTG_BUS),
|
||||
+ /* gmac1 */
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_GMAC1_AHB, "gmac1_ahb", 0, JH7110_SYSCLK_AHB0),
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_GMAC1_AXI, "gmac1_axi", 0, JH7110_SYSCLK_STG_AXIAHB),
|
||||
+ JH71X0__DIV(JH7110_SYSCLK_GMAC_SRC, "gmac_src", 7, JH7110_SYSCLK_PLL0_OUT),
|
||||
+ JH71X0__DIV(JH7110_SYSCLK_GMAC1_GTXCLK, "gmac1_gtxclk", 15, JH7110_SYSCLK_PLL0_OUT),
|
||||
+ JH71X0__DIV(JH7110_SYSCLK_GMAC1_RMII_RTX, "gmac1_rmii_rtx", 30,
|
||||
+ JH7110_SYSCLK_GMAC1_RMII_REFIN),
|
||||
+ JH71X0_GDIV(JH7110_SYSCLK_GMAC1_PTP, "gmac1_ptp", 0, 31, JH7110_SYSCLK_GMAC_SRC),
|
||||
+ JH71X0__MUX(JH7110_SYSCLK_GMAC1_RX, "gmac1_rx", 2,
|
||||
+ JH7110_SYSCLK_GMAC1_RGMII_RXIN,
|
||||
+ JH7110_SYSCLK_GMAC1_RMII_RTX),
|
||||
+ JH71X0__INV(JH7110_SYSCLK_GMAC1_RX_INV, "gmac1_rx_inv", JH7110_SYSCLK_GMAC1_RX),
|
||||
+ JH71X0_GMUX(JH7110_SYSCLK_GMAC1_TX, "gmac1_tx",
|
||||
+ CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT, 2,
|
||||
+ JH7110_SYSCLK_GMAC1_GTXCLK,
|
||||
+ JH7110_SYSCLK_GMAC1_RMII_RTX),
|
||||
+ JH71X0__INV(JH7110_SYSCLK_GMAC1_TX_INV, "gmac1_tx_inv", JH7110_SYSCLK_GMAC1_TX),
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_GMAC1_GTXC, "gmac1_gtxc", 0, JH7110_SYSCLK_GMAC1_GTXCLK),
|
||||
+ /* gmac0 */
|
||||
+ JH71X0_GDIV(JH7110_SYSCLK_GMAC0_GTXCLK, "gmac0_gtxclk", 0, 15, JH7110_SYSCLK_PLL0_OUT),
|
||||
+ JH71X0_GDIV(JH7110_SYSCLK_GMAC0_PTP, "gmac0_ptp", 0, 31, JH7110_SYSCLK_GMAC_SRC),
|
||||
+ JH71X0_GDIV(JH7110_SYSCLK_GMAC_PHY, "gmac_phy", 0, 31, JH7110_SYSCLK_GMAC_SRC),
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_GMAC0_GTXC, "gmac0_gtxc", 0, JH7110_SYSCLK_GMAC0_GTXCLK),
|
||||
+ /* apb misc */
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_IOMUX_APB, "iomux_apb", 0, JH7110_SYSCLK_APB_BUS),
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_MAILBOX_APB, "mailbox_apb", 0, JH7110_SYSCLK_APB_BUS),
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_INT_CTRL_APB, "int_ctrl_apb", 0, JH7110_SYSCLK_APB_BUS),
|
||||
+ /* can0 */
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_CAN0_APB, "can0_apb", 0, JH7110_SYSCLK_APB_BUS),
|
||||
+ JH71X0_GDIV(JH7110_SYSCLK_CAN0_TIMER, "can0_timer", 0, 24, JH7110_SYSCLK_OSC),
|
||||
+ JH71X0_GDIV(JH7110_SYSCLK_CAN0_CAN, "can0_can", 0, 63, JH7110_SYSCLK_PERH_ROOT),
|
||||
+ /* can1 */
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_CAN1_APB, "can1_apb", 0, JH7110_SYSCLK_APB_BUS),
|
||||
+ JH71X0_GDIV(JH7110_SYSCLK_CAN1_TIMER, "can1_timer", 0, 24, JH7110_SYSCLK_OSC),
|
||||
+ JH71X0_GDIV(JH7110_SYSCLK_CAN1_CAN, "can1_can", 0, 63, JH7110_SYSCLK_PERH_ROOT),
|
||||
+ /* pwm */
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_PWM_APB, "pwm_apb", 0, JH7110_SYSCLK_APB_BUS),
|
||||
+ /* wdt */
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_WDT_APB, "wdt_apb", 0, JH7110_SYSCLK_APB_BUS),
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_WDT_CORE, "wdt_core", 0, JH7110_SYSCLK_OSC),
|
||||
+ /* timer */
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_TIMER_APB, "timer_apb", 0, JH7110_SYSCLK_APB_BUS),
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_TIMER0, "timer0", 0, JH7110_SYSCLK_OSC),
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_TIMER1, "timer1", 0, JH7110_SYSCLK_OSC),
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_TIMER2, "timer2", 0, JH7110_SYSCLK_OSC),
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_TIMER3, "timer3", 0, JH7110_SYSCLK_OSC),
|
||||
+ /* temp sensor */
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_TEMP_APB, "temp_apb", 0, JH7110_SYSCLK_APB_BUS),
|
||||
+ JH71X0_GDIV(JH7110_SYSCLK_TEMP_CORE, "temp_core", 0, 24, JH7110_SYSCLK_OSC),
|
||||
+ /* spi */
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_SPI0_APB, "spi0_apb", 0, JH7110_SYSCLK_APB0),
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_SPI1_APB, "spi1_apb", 0, JH7110_SYSCLK_APB0),
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_SPI2_APB, "spi2_apb", 0, JH7110_SYSCLK_APB0),
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_SPI3_APB, "spi3_apb", 0, JH7110_SYSCLK_APB_BUS),
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_SPI4_APB, "spi4_apb", 0, JH7110_SYSCLK_APB_BUS),
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_SPI5_APB, "spi5_apb", 0, JH7110_SYSCLK_APB_BUS),
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_SPI6_APB, "spi6_apb", 0, JH7110_SYSCLK_APB_BUS),
|
||||
+ /* i2c */
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_I2C0_APB, "i2c0_apb", 0, JH7110_SYSCLK_APB0),
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_I2C1_APB, "i2c1_apb", 0, JH7110_SYSCLK_APB0),
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_I2C2_APB, "i2c2_apb", 0, JH7110_SYSCLK_APB0),
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_I2C3_APB, "i2c3_apb", 0, JH7110_SYSCLK_APB_BUS),
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_I2C4_APB, "i2c4_apb", 0, JH7110_SYSCLK_APB_BUS),
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_I2C5_APB, "i2c5_apb", 0, JH7110_SYSCLK_APB_BUS),
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_I2C6_APB, "i2c6_apb", 0, JH7110_SYSCLK_APB_BUS),
|
||||
+ /* uart */
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_UART0_APB, "uart0_apb", 0, JH7110_SYSCLK_APB0),
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_UART0_CORE, "uart0_core", 0, JH7110_SYSCLK_OSC),
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_UART1_APB, "uart1_apb", 0, JH7110_SYSCLK_APB0),
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_UART1_CORE, "uart1_core", 0, JH7110_SYSCLK_OSC),
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_UART2_APB, "uart2_apb", 0, JH7110_SYSCLK_APB0),
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_UART2_CORE, "uart2_core", 0, JH7110_SYSCLK_OSC),
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_UART3_APB, "uart3_apb", 0, JH7110_SYSCLK_APB0),
|
||||
+ JH71X0_GDIV(JH7110_SYSCLK_UART3_CORE, "uart3_core", 0, 10, JH7110_SYSCLK_PERH_ROOT),
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_UART4_APB, "uart4_apb", 0, JH7110_SYSCLK_APB0),
|
||||
+ JH71X0_GDIV(JH7110_SYSCLK_UART4_CORE, "uart4_core", 0, 10, JH7110_SYSCLK_PERH_ROOT),
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_UART5_APB, "uart5_apb", 0, JH7110_SYSCLK_APB0),
|
||||
+ JH71X0_GDIV(JH7110_SYSCLK_UART5_CORE, "uart5_core", 0, 10, JH7110_SYSCLK_PERH_ROOT),
|
||||
+ /* pwmdac */
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_PWMDAC_APB, "pwmdac_apb", 0, JH7110_SYSCLK_APB0),
|
||||
+ JH71X0_GDIV(JH7110_SYSCLK_PWMDAC_CORE, "pwmdac_core", 0, 256, JH7110_SYSCLK_AUDIO_ROOT),
|
||||
+ /* spdif */
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_SPDIF_APB, "spdif_apb", 0, JH7110_SYSCLK_APB0),
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_SPDIF_CORE, "spdif_core", 0, JH7110_SYSCLK_MCLK),
|
||||
+ /* i2stx0 */
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_I2STX0_APB, "i2stx0_apb", 0, JH7110_SYSCLK_APB0),
|
||||
+ JH71X0_GDIV(JH7110_SYSCLK_I2STX0_BCLK_MST, "i2stx0_bclk_mst", 0, 32, JH7110_SYSCLK_MCLK),
|
||||
+ JH71X0__INV(JH7110_SYSCLK_I2STX0_BCLK_MST_INV, "i2stx0_bclk_mst_inv",
|
||||
+ JH7110_SYSCLK_I2STX0_BCLK_MST),
|
||||
+ JH71X0_MDIV(JH7110_SYSCLK_I2STX0_LRCK_MST, "i2stx0_lrck_mst", 64, 2,
|
||||
+ JH7110_SYSCLK_I2STX0_BCLK_MST_INV,
|
||||
+ JH7110_SYSCLK_I2STX0_BCLK_MST),
|
||||
+ JH71X0__MUX(JH7110_SYSCLK_I2STX0_BCLK, "i2stx0_bclk", 2,
|
||||
+ JH7110_SYSCLK_I2STX0_BCLK_MST,
|
||||
+ JH7110_SYSCLK_I2STX_BCLK_EXT),
|
||||
+ JH71X0__INV(JH7110_SYSCLK_I2STX0_BCLK_INV, "i2stx0_bclk_inv", JH7110_SYSCLK_I2STX0_BCLK),
|
||||
+ JH71X0__MUX(JH7110_SYSCLK_I2STX0_LRCK, "i2stx0_lrck", 2,
|
||||
+ JH7110_SYSCLK_I2STX0_LRCK_MST,
|
||||
+ JH7110_SYSCLK_I2STX_LRCK_EXT),
|
||||
+ /* i2stx1 */
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_I2STX1_APB, "i2stx1_apb", 0, JH7110_SYSCLK_APB0),
|
||||
+ JH71X0_GDIV(JH7110_SYSCLK_I2STX1_BCLK_MST, "i2stx1_bclk_mst", 0, 32, JH7110_SYSCLK_MCLK),
|
||||
+ JH71X0__INV(JH7110_SYSCLK_I2STX1_BCLK_MST_INV, "i2stx1_bclk_mst_inv",
|
||||
+ JH7110_SYSCLK_I2STX1_BCLK_MST),
|
||||
+ JH71X0_MDIV(JH7110_SYSCLK_I2STX1_LRCK_MST, "i2stx1_lrck_mst", 64, 2,
|
||||
+ JH7110_SYSCLK_I2STX1_BCLK_MST_INV,
|
||||
+ JH7110_SYSCLK_I2STX1_BCLK_MST),
|
||||
+ JH71X0__MUX(JH7110_SYSCLK_I2STX1_BCLK, "i2stx1_bclk", 2,
|
||||
+ JH7110_SYSCLK_I2STX1_BCLK_MST,
|
||||
+ JH7110_SYSCLK_I2STX_BCLK_EXT),
|
||||
+ JH71X0__INV(JH7110_SYSCLK_I2STX1_BCLK_INV, "i2stx1_bclk_inv", JH7110_SYSCLK_I2STX1_BCLK),
|
||||
+ JH71X0__MUX(JH7110_SYSCLK_I2STX1_LRCK, "i2stx1_lrck", 2,
|
||||
+ JH7110_SYSCLK_I2STX1_LRCK_MST,
|
||||
+ JH7110_SYSCLK_I2STX_LRCK_EXT),
|
||||
+ /* i2srx */
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_I2SRX_APB, "i2srx_apb", 0, JH7110_SYSCLK_APB0),
|
||||
+ JH71X0_GDIV(JH7110_SYSCLK_I2SRX_BCLK_MST, "i2srx_bclk_mst", 0, 32, JH7110_SYSCLK_MCLK),
|
||||
+ JH71X0__INV(JH7110_SYSCLK_I2SRX_BCLK_MST_INV, "i2srx_bclk_mst_inv",
|
||||
+ JH7110_SYSCLK_I2SRX_BCLK_MST),
|
||||
+ JH71X0_MDIV(JH7110_SYSCLK_I2SRX_LRCK_MST, "i2srx_lrck_mst", 64, 2,
|
||||
+ JH7110_SYSCLK_I2SRX_BCLK_MST_INV,
|
||||
+ JH7110_SYSCLK_I2SRX_BCLK_MST),
|
||||
+ JH71X0__MUX(JH7110_SYSCLK_I2SRX_BCLK, "i2srx_bclk", 2,
|
||||
+ JH7110_SYSCLK_I2SRX_BCLK_MST,
|
||||
+ JH7110_SYSCLK_I2SRX_BCLK_EXT),
|
||||
+ JH71X0__INV(JH7110_SYSCLK_I2SRX_BCLK_INV, "i2srx_bclk_inv", JH7110_SYSCLK_I2SRX_BCLK),
|
||||
+ JH71X0__MUX(JH7110_SYSCLK_I2SRX_LRCK, "i2srx_lrck", 2,
|
||||
+ JH7110_SYSCLK_I2SRX_LRCK_MST,
|
||||
+ JH7110_SYSCLK_I2SRX_LRCK_EXT),
|
||||
+ /* pdm */
|
||||
+ JH71X0_GDIV(JH7110_SYSCLK_PDM_DMIC, "pdm_dmic", 0, 64, JH7110_SYSCLK_MCLK),
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_PDM_APB, "pdm_apb", 0, JH7110_SYSCLK_APB0),
|
||||
+ /* tdm */
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_TDM_AHB, "tdm_ahb", 0, JH7110_SYSCLK_AHB0),
|
||||
+ JH71X0_GATE(JH7110_SYSCLK_TDM_APB, "tdm_apb", 0, JH7110_SYSCLK_APB0),
|
||||
+ JH71X0_GDIV(JH7110_SYSCLK_TDM_INTERNAL, "tdm_internal", 0, 64, JH7110_SYSCLK_MCLK),
|
||||
+ JH71X0__MUX(JH7110_SYSCLK_TDM_TDM, "tdm_tdm", 2,
|
||||
+ JH7110_SYSCLK_TDM_INTERNAL,
|
||||
+ JH7110_SYSCLK_TDM_EXT),
|
||||
+ JH71X0__INV(JH7110_SYSCLK_TDM_TDM_INV, "tdm_tdm_inv", JH7110_SYSCLK_TDM_TDM),
|
||||
+ /* jtag */
|
||||
+ JH71X0__DIV(JH7110_SYSCLK_JTAG_CERTIFICATION_TRNG, "jtag_certification_trng", 4,
|
||||
+ JH7110_SYSCLK_OSC),
|
||||
+};
|
||||
+
|
||||
+static struct clk_hw *jh7110_sysclk_get(struct of_phandle_args *clkspec, void *data)
|
||||
+{
|
||||
+ struct jh71x0_clk_priv *priv = data;
|
||||
+ unsigned int idx = clkspec->args[0];
|
||||
+
|
||||
+ if (idx < JH7110_SYSCLK_END)
|
||||
+ return &priv->reg[idx].hw;
|
||||
+
|
||||
+ return ERR_PTR(-EINVAL);
|
||||
+}
|
||||
+
|
||||
+static void jh7110_reset_unregister_adev(void *_adev)
|
||||
+{
|
||||
+ struct auxiliary_device *adev = _adev;
|
||||
+
|
||||
+ auxiliary_device_delete(adev);
|
||||
+}
|
||||
+
|
||||
+static void jh7110_reset_adev_release(struct device *dev)
|
||||
+{
|
||||
+ struct auxiliary_device *adev = to_auxiliary_dev(dev);
|
||||
+
|
||||
+ auxiliary_device_uninit(adev);
|
||||
+}
|
||||
+
|
||||
+int jh7110_reset_controller_register(struct jh71x0_clk_priv *priv,
|
||||
+ const char *adev_name,
|
||||
+ u32 adev_id)
|
||||
+{
|
||||
+ struct auxiliary_device *adev;
|
||||
+ int ret;
|
||||
+
|
||||
+ adev = devm_kzalloc(priv->dev, sizeof(*adev), GFP_KERNEL);
|
||||
+ if (!adev)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ adev->name = adev_name;
|
||||
+ adev->dev.parent = priv->dev;
|
||||
+ adev->dev.release = jh7110_reset_adev_release;
|
||||
+ adev->id = adev_id;
|
||||
+
|
||||
+ ret = auxiliary_device_init(adev);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = auxiliary_device_add(adev);
|
||||
+ if (ret) {
|
||||
+ auxiliary_device_uninit(adev);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ return devm_add_action_or_reset(priv->dev,
|
||||
+ jh7110_reset_unregister_adev, adev);
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(jh7110_reset_controller_register);
|
||||
+
|
||||
+static int __init jh7110_syscrg_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct jh71x0_clk_priv *priv;
|
||||
+ unsigned int idx;
|
||||
+ int ret;
|
||||
+
|
||||
+ priv = devm_kzalloc(&pdev->dev,
|
||||
+ struct_size(priv, reg, JH7110_SYSCLK_END),
|
||||
+ GFP_KERNEL);
|
||||
+ if (!priv)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ spin_lock_init(&priv->rmw_lock);
|
||||
+ priv->dev = &pdev->dev;
|
||||
+ priv->base = devm_platform_ioremap_resource(pdev, 0);
|
||||
+ if (IS_ERR(priv->base))
|
||||
+ return PTR_ERR(priv->base);
|
||||
+
|
||||
+ dev_set_drvdata(priv->dev, (void *)(&priv->base));
|
||||
+
|
||||
+ /*
|
||||
+ * These PLL clocks are not actually fixed factor clocks and can be
|
||||
+ * controlled by the syscon registers of JH7110. They will be dropped
|
||||
+ * and registered in the PLL clock driver instead.
|
||||
+ */
|
||||
+ /* 24MHz -> 1000.0MHz */
|
||||
+ priv->pll[0] = devm_clk_hw_register_fixed_factor(priv->dev, "pll0_out",
|
||||
+ "osc", 0, 125, 3);
|
||||
+ if (IS_ERR(priv->pll[0]))
|
||||
+ return PTR_ERR(priv->pll[0]);
|
||||
+
|
||||
+ /* 24MHz -> 1066.0MHz */
|
||||
+ priv->pll[1] = devm_clk_hw_register_fixed_factor(priv->dev, "pll1_out",
|
||||
+ "osc", 0, 533, 12);
|
||||
+ if (IS_ERR(priv->pll[1]))
|
||||
+ return PTR_ERR(priv->pll[1]);
|
||||
+
|
||||
+ /* 24MHz -> 1188.0MHz */
|
||||
+ priv->pll[2] = devm_clk_hw_register_fixed_factor(priv->dev, "pll2_out",
|
||||
+ "osc", 0, 99, 2);
|
||||
+ if (IS_ERR(priv->pll[2]))
|
||||
+ return PTR_ERR(priv->pll[2]);
|
||||
+
|
||||
+ for (idx = 0; idx < JH7110_SYSCLK_END; idx++) {
|
||||
+ u32 max = jh7110_sysclk_data[idx].max;
|
||||
+ struct clk_parent_data parents[4] = {};
|
||||
+ struct clk_init_data init = {
|
||||
+ .name = jh7110_sysclk_data[idx].name,
|
||||
+ .ops = starfive_jh71x0_clk_ops(max),
|
||||
+ .parent_data = parents,
|
||||
+ .num_parents =
|
||||
+ ((max & JH71X0_CLK_MUX_MASK) >> JH71X0_CLK_MUX_SHIFT) + 1,
|
||||
+ .flags = jh7110_sysclk_data[idx].flags,
|
||||
+ };
|
||||
+ struct jh71x0_clk *clk = &priv->reg[idx];
|
||||
+ unsigned int i;
|
||||
+
|
||||
+ for (i = 0; i < init.num_parents; i++) {
|
||||
+ unsigned int pidx = jh7110_sysclk_data[idx].parents[i];
|
||||
+
|
||||
+ if (pidx < JH7110_SYSCLK_END)
|
||||
+ parents[i].hw = &priv->reg[pidx].hw;
|
||||
+ else if (pidx == JH7110_SYSCLK_OSC)
|
||||
+ parents[i].fw_name = "osc";
|
||||
+ else if (pidx == JH7110_SYSCLK_GMAC1_RMII_REFIN)
|
||||
+ parents[i].fw_name = "gmac1_rmii_refin";
|
||||
+ else if (pidx == JH7110_SYSCLK_GMAC1_RGMII_RXIN)
|
||||
+ parents[i].fw_name = "gmac1_rgmii_rxin";
|
||||
+ else if (pidx == JH7110_SYSCLK_I2STX_BCLK_EXT)
|
||||
+ parents[i].fw_name = "i2stx_bclk_ext";
|
||||
+ else if (pidx == JH7110_SYSCLK_I2STX_LRCK_EXT)
|
||||
+ parents[i].fw_name = "i2stx_lrck_ext";
|
||||
+ else if (pidx == JH7110_SYSCLK_I2SRX_BCLK_EXT)
|
||||
+ parents[i].fw_name = "i2srx_bclk_ext";
|
||||
+ else if (pidx == JH7110_SYSCLK_I2SRX_LRCK_EXT)
|
||||
+ parents[i].fw_name = "i2srx_lrck_ext";
|
||||
+ else if (pidx == JH7110_SYSCLK_TDM_EXT)
|
||||
+ parents[i].fw_name = "tdm_ext";
|
||||
+ else if (pidx == JH7110_SYSCLK_MCLK_EXT)
|
||||
+ parents[i].fw_name = "mclk_ext";
|
||||
+ else
|
||||
+ parents[i].hw = priv->pll[pidx - JH7110_SYSCLK_PLL0_OUT];
|
||||
+ }
|
||||
+
|
||||
+ clk->hw.init = &init;
|
||||
+ clk->idx = idx;
|
||||
+ clk->max_div = max & JH71X0_CLK_DIV_MASK;
|
||||
+
|
||||
+ ret = devm_clk_hw_register(&pdev->dev, &clk->hw);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ ret = devm_of_clk_add_hw_provider(&pdev->dev, jh7110_sysclk_get, priv);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ return jh7110_reset_controller_register(priv, "rst-sys", 0);
|
||||
+}
|
||||
+
|
||||
+static const struct of_device_id jh7110_syscrg_match[] = {
|
||||
+ { .compatible = "starfive,jh7110-syscrg" },
|
||||
+ { /* sentinel */ }
|
||||
+};
|
||||
+
|
||||
+static struct platform_driver jh7110_syscrg_driver = {
|
||||
+ .driver = {
|
||||
+ .name = "clk-starfive-jh7110-sys",
|
||||
+ .of_match_table = jh7110_syscrg_match,
|
||||
+ .suppress_bind_attrs = true,
|
||||
+ },
|
||||
+};
|
||||
+builtin_platform_driver_probe(jh7110_syscrg_driver, jh7110_syscrg_probe);
|
||||
--- /dev/null
|
||||
+++ b/drivers/clk/starfive/clk-starfive-jh7110.h
|
||||
@@ -0,0 +1,11 @@
|
||||
+/* SPDX-License-Identifier: GPL-2.0 */
|
||||
+#ifndef __CLK_STARFIVE_JH7110_H
|
||||
+#define __CLK_STARFIVE_JH7110_H
|
||||
+
|
||||
+#include "clk-starfive-jh71x0.h"
|
||||
+
|
||||
+int jh7110_reset_controller_register(struct jh71x0_clk_priv *priv,
|
||||
+ const char *adev_name,
|
||||
+ u32 adev_id);
|
||||
+
|
||||
+#endif
|
@ -0,0 +1,206 @@
|
||||
From 6b9f7a65cd2e9cc4bdc2ee3c3fb46bef4568af0a Mon Sep 17 00:00:00 2001
|
||||
From: Emil Renner Berthing <kernel@esmil.dk>
|
||||
Date: Sat, 1 Apr 2023 19:19:26 +0800
|
||||
Subject: [PATCH 014/122] clk: starfive: Add StarFive JH7110 always-on clock
|
||||
driver
|
||||
|
||||
Add driver for the StarFive JH7110 always-on clock controller
|
||||
and register an auxiliary device for always-on reset controller
|
||||
which is named as "rst-aon".
|
||||
|
||||
Tested-by: Tommaso Merciai <tomm.merciai@gmail.com>
|
||||
Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
|
||||
Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
|
||||
Co-developed-by: Hal Feng <hal.feng@starfivetech.com>
|
||||
Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
|
||||
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
|
||||
---
|
||||
drivers/clk/starfive/Kconfig | 11 ++
|
||||
drivers/clk/starfive/Makefile | 1 +
|
||||
.../clk/starfive/clk-starfive-jh7110-aon.c | 156 ++++++++++++++++++
|
||||
3 files changed, 168 insertions(+)
|
||||
create mode 100644 drivers/clk/starfive/clk-starfive-jh7110-aon.c
|
||||
|
||||
--- a/drivers/clk/starfive/Kconfig
|
||||
+++ b/drivers/clk/starfive/Kconfig
|
||||
@@ -31,3 +31,14 @@ config CLK_STARFIVE_JH7110_SYS
|
||||
help
|
||||
Say yes here to support the system clock controller on the
|
||||
StarFive JH7110 SoC.
|
||||
+
|
||||
+config CLK_STARFIVE_JH7110_AON
|
||||
+ tristate "StarFive JH7110 always-on clock support"
|
||||
+ depends on CLK_STARFIVE_JH7110_SYS
|
||||
+ select AUXILIARY_BUS
|
||||
+ select CLK_STARFIVE_JH71X0
|
||||
+ select RESET_STARFIVE_JH7110
|
||||
+ default m if ARCH_STARFIVE
|
||||
+ help
|
||||
+ Say yes here to support the always-on clock controller on the
|
||||
+ StarFive JH7110 SoC.
|
||||
--- a/drivers/clk/starfive/Makefile
|
||||
+++ b/drivers/clk/starfive/Makefile
|
||||
@@ -5,3 +5,4 @@ obj-$(CONFIG_CLK_STARFIVE_JH7100) += clk
|
||||
obj-$(CONFIG_CLK_STARFIVE_JH7100_AUDIO) += clk-starfive-jh7100-audio.o
|
||||
|
||||
obj-$(CONFIG_CLK_STARFIVE_JH7110_SYS) += clk-starfive-jh7110-sys.o
|
||||
+obj-$(CONFIG_CLK_STARFIVE_JH7110_AON) += clk-starfive-jh7110-aon.o
|
||||
--- /dev/null
|
||||
+++ b/drivers/clk/starfive/clk-starfive-jh7110-aon.c
|
||||
@@ -0,0 +1,156 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0
|
||||
+/*
|
||||
+ * StarFive JH7110 Always-On Clock Driver
|
||||
+ *
|
||||
+ * Copyright (C) 2022 Emil Renner Berthing <kernel@esmil.dk>
|
||||
+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/clk-provider.h>
|
||||
+#include <linux/io.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+
|
||||
+#include <dt-bindings/clock/starfive,jh7110-crg.h>
|
||||
+
|
||||
+#include "clk-starfive-jh7110.h"
|
||||
+
|
||||
+/* external clocks */
|
||||
+#define JH7110_AONCLK_OSC (JH7110_AONCLK_END + 0)
|
||||
+#define JH7110_AONCLK_GMAC0_RMII_REFIN (JH7110_AONCLK_END + 1)
|
||||
+#define JH7110_AONCLK_GMAC0_RGMII_RXIN (JH7110_AONCLK_END + 2)
|
||||
+#define JH7110_AONCLK_STG_AXIAHB (JH7110_AONCLK_END + 3)
|
||||
+#define JH7110_AONCLK_APB_BUS (JH7110_AONCLK_END + 4)
|
||||
+#define JH7110_AONCLK_GMAC0_GTXCLK (JH7110_AONCLK_END + 5)
|
||||
+#define JH7110_AONCLK_RTC_OSC (JH7110_AONCLK_END + 6)
|
||||
+
|
||||
+static const struct jh71x0_clk_data jh7110_aonclk_data[] = {
|
||||
+ /* source */
|
||||
+ JH71X0__DIV(JH7110_AONCLK_OSC_DIV4, "osc_div4", 4, JH7110_AONCLK_OSC),
|
||||
+ JH71X0__MUX(JH7110_AONCLK_APB_FUNC, "apb_func", 2,
|
||||
+ JH7110_AONCLK_OSC_DIV4,
|
||||
+ JH7110_AONCLK_OSC),
|
||||
+ /* gmac0 */
|
||||
+ JH71X0_GATE(JH7110_AONCLK_GMAC0_AHB, "gmac0_ahb", 0, JH7110_AONCLK_STG_AXIAHB),
|
||||
+ JH71X0_GATE(JH7110_AONCLK_GMAC0_AXI, "gmac0_axi", 0, JH7110_AONCLK_STG_AXIAHB),
|
||||
+ JH71X0__DIV(JH7110_AONCLK_GMAC0_RMII_RTX, "gmac0_rmii_rtx", 30,
|
||||
+ JH7110_AONCLK_GMAC0_RMII_REFIN),
|
||||
+ JH71X0_GMUX(JH7110_AONCLK_GMAC0_TX, "gmac0_tx",
|
||||
+ CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT, 2,
|
||||
+ JH7110_AONCLK_GMAC0_GTXCLK,
|
||||
+ JH7110_AONCLK_GMAC0_RMII_RTX),
|
||||
+ JH71X0__INV(JH7110_AONCLK_GMAC0_TX_INV, "gmac0_tx_inv", JH7110_AONCLK_GMAC0_TX),
|
||||
+ JH71X0__MUX(JH7110_AONCLK_GMAC0_RX, "gmac0_rx", 2,
|
||||
+ JH7110_AONCLK_GMAC0_RGMII_RXIN,
|
||||
+ JH7110_AONCLK_GMAC0_RMII_RTX),
|
||||
+ JH71X0__INV(JH7110_AONCLK_GMAC0_RX_INV, "gmac0_rx_inv", JH7110_AONCLK_GMAC0_RX),
|
||||
+ /* otpc */
|
||||
+ JH71X0_GATE(JH7110_AONCLK_OTPC_APB, "otpc_apb", 0, JH7110_AONCLK_APB_BUS),
|
||||
+ /* rtc */
|
||||
+ JH71X0_GATE(JH7110_AONCLK_RTC_APB, "rtc_apb", 0, JH7110_AONCLK_APB_BUS),
|
||||
+ JH71X0__DIV(JH7110_AONCLK_RTC_INTERNAL, "rtc_internal", 1022, JH7110_AONCLK_OSC),
|
||||
+ JH71X0__MUX(JH7110_AONCLK_RTC_32K, "rtc_32k", 2,
|
||||
+ JH7110_AONCLK_RTC_OSC,
|
||||
+ JH7110_AONCLK_RTC_INTERNAL),
|
||||
+ JH71X0_GATE(JH7110_AONCLK_RTC_CAL, "rtc_cal", 0, JH7110_AONCLK_OSC),
|
||||
+};
|
||||
+
|
||||
+static struct clk_hw *jh7110_aonclk_get(struct of_phandle_args *clkspec, void *data)
|
||||
+{
|
||||
+ struct jh71x0_clk_priv *priv = data;
|
||||
+ unsigned int idx = clkspec->args[0];
|
||||
+
|
||||
+ if (idx < JH7110_AONCLK_END)
|
||||
+ return &priv->reg[idx].hw;
|
||||
+
|
||||
+ return ERR_PTR(-EINVAL);
|
||||
+}
|
||||
+
|
||||
+static int jh7110_aoncrg_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct jh71x0_clk_priv *priv;
|
||||
+ unsigned int idx;
|
||||
+ int ret;
|
||||
+
|
||||
+ priv = devm_kzalloc(&pdev->dev,
|
||||
+ struct_size(priv, reg, JH7110_AONCLK_END),
|
||||
+ GFP_KERNEL);
|
||||
+ if (!priv)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ spin_lock_init(&priv->rmw_lock);
|
||||
+ priv->dev = &pdev->dev;
|
||||
+ priv->base = devm_platform_ioremap_resource(pdev, 0);
|
||||
+ if (IS_ERR(priv->base))
|
||||
+ return PTR_ERR(priv->base);
|
||||
+
|
||||
+ dev_set_drvdata(priv->dev, (void *)(&priv->base));
|
||||
+
|
||||
+ for (idx = 0; idx < JH7110_AONCLK_END; idx++) {
|
||||
+ u32 max = jh7110_aonclk_data[idx].max;
|
||||
+ struct clk_parent_data parents[4] = {};
|
||||
+ struct clk_init_data init = {
|
||||
+ .name = jh7110_aonclk_data[idx].name,
|
||||
+ .ops = starfive_jh71x0_clk_ops(max),
|
||||
+ .parent_data = parents,
|
||||
+ .num_parents =
|
||||
+ ((max & JH71X0_CLK_MUX_MASK) >> JH71X0_CLK_MUX_SHIFT) + 1,
|
||||
+ .flags = jh7110_aonclk_data[idx].flags,
|
||||
+ };
|
||||
+ struct jh71x0_clk *clk = &priv->reg[idx];
|
||||
+ unsigned int i;
|
||||
+
|
||||
+ for (i = 0; i < init.num_parents; i++) {
|
||||
+ unsigned int pidx = jh7110_aonclk_data[idx].parents[i];
|
||||
+
|
||||
+ if (pidx < JH7110_AONCLK_END)
|
||||
+ parents[i].hw = &priv->reg[pidx].hw;
|
||||
+ else if (pidx == JH7110_AONCLK_OSC)
|
||||
+ parents[i].fw_name = "osc";
|
||||
+ else if (pidx == JH7110_AONCLK_GMAC0_RMII_REFIN)
|
||||
+ parents[i].fw_name = "gmac0_rmii_refin";
|
||||
+ else if (pidx == JH7110_AONCLK_GMAC0_RGMII_RXIN)
|
||||
+ parents[i].fw_name = "gmac0_rgmii_rxin";
|
||||
+ else if (pidx == JH7110_AONCLK_STG_AXIAHB)
|
||||
+ parents[i].fw_name = "stg_axiahb";
|
||||
+ else if (pidx == JH7110_AONCLK_APB_BUS)
|
||||
+ parents[i].fw_name = "apb_bus";
|
||||
+ else if (pidx == JH7110_AONCLK_GMAC0_GTXCLK)
|
||||
+ parents[i].fw_name = "gmac0_gtxclk";
|
||||
+ else if (pidx == JH7110_AONCLK_RTC_OSC)
|
||||
+ parents[i].fw_name = "rtc_osc";
|
||||
+ }
|
||||
+
|
||||
+ clk->hw.init = &init;
|
||||
+ clk->idx = idx;
|
||||
+ clk->max_div = max & JH71X0_CLK_DIV_MASK;
|
||||
+
|
||||
+ ret = devm_clk_hw_register(&pdev->dev, &clk->hw);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ ret = devm_of_clk_add_hw_provider(&pdev->dev, jh7110_aonclk_get, priv);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ return jh7110_reset_controller_register(priv, "rst-aon", 1);
|
||||
+}
|
||||
+
|
||||
+static const struct of_device_id jh7110_aoncrg_match[] = {
|
||||
+ { .compatible = "starfive,jh7110-aoncrg" },
|
||||
+ { /* sentinel */ }
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, jh7110_aoncrg_match);
|
||||
+
|
||||
+static struct platform_driver jh7110_aoncrg_driver = {
|
||||
+ .probe = jh7110_aoncrg_probe,
|
||||
+ .driver = {
|
||||
+ .name = "clk-starfive-jh7110-aon",
|
||||
+ .of_match_table = jh7110_aoncrg_match,
|
||||
+ },
|
||||
+};
|
||||
+module_platform_driver(jh7110_aoncrg_driver);
|
||||
+
|
||||
+MODULE_AUTHOR("Emil Renner Berthing");
|
||||
+MODULE_DESCRIPTION("StarFive JH7110 always-on clock driver");
|
||||
+MODULE_LICENSE("GPL");
|
@ -0,0 +1,113 @@
|
||||
From ea2f40c943f4a6d39a2f3ea4660266250d37c95a Mon Sep 17 00:00:00 2001
|
||||
From: Hal Feng <hal.feng@starfivetech.com>
|
||||
Date: Sat, 1 Apr 2023 19:19:27 +0800
|
||||
Subject: [PATCH 015/122] reset: starfive: Add StarFive JH7110 reset driver
|
||||
|
||||
Add auxiliary driver to support StarFive JH7110 system
|
||||
and always-on resets.
|
||||
|
||||
Tested-by: Tommaso Merciai <tomm.merciai@gmail.com>
|
||||
Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
|
||||
Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
|
||||
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
|
||||
---
|
||||
drivers/reset/starfive/Kconfig | 8 +++
|
||||
drivers/reset/starfive/Makefile | 1 +
|
||||
.../reset/starfive/reset-starfive-jh7110.c | 70 +++++++++++++++++++
|
||||
3 files changed, 79 insertions(+)
|
||||
create mode 100644 drivers/reset/starfive/reset-starfive-jh7110.c
|
||||
|
||||
--- a/drivers/reset/starfive/Kconfig
|
||||
+++ b/drivers/reset/starfive/Kconfig
|
||||
@@ -10,3 +10,11 @@ config RESET_STARFIVE_JH7100
|
||||
default ARCH_STARFIVE
|
||||
help
|
||||
This enables the reset controller driver for the StarFive JH7100 SoC.
|
||||
+
|
||||
+config RESET_STARFIVE_JH7110
|
||||
+ bool "StarFive JH7110 Reset Driver"
|
||||
+ depends on AUXILIARY_BUS && CLK_STARFIVE_JH7110_SYS
|
||||
+ select RESET_STARFIVE_JH71X0
|
||||
+ default ARCH_STARFIVE
|
||||
+ help
|
||||
+ This enables the reset controller driver for the StarFive JH7110 SoC.
|
||||
--- a/drivers/reset/starfive/Makefile
|
||||
+++ b/drivers/reset/starfive/Makefile
|
||||
@@ -2,3 +2,4 @@
|
||||
obj-$(CONFIG_RESET_STARFIVE_JH71X0) += reset-starfive-jh71x0.o
|
||||
|
||||
obj-$(CONFIG_RESET_STARFIVE_JH7100) += reset-starfive-jh7100.o
|
||||
+obj-$(CONFIG_RESET_STARFIVE_JH7110) += reset-starfive-jh7110.o
|
||||
--- /dev/null
|
||||
+++ b/drivers/reset/starfive/reset-starfive-jh7110.c
|
||||
@@ -0,0 +1,70 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
+/*
|
||||
+ * Reset driver for the StarFive JH7110 SoC
|
||||
+ *
|
||||
+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/auxiliary_bus.h>
|
||||
+
|
||||
+#include "reset-starfive-jh71x0.h"
|
||||
+
|
||||
+#include <dt-bindings/reset/starfive,jh7110-crg.h>
|
||||
+
|
||||
+struct jh7110_reset_info {
|
||||
+ unsigned int nr_resets;
|
||||
+ unsigned int assert_offset;
|
||||
+ unsigned int status_offset;
|
||||
+};
|
||||
+
|
||||
+static const struct jh7110_reset_info jh7110_sys_info = {
|
||||
+ .nr_resets = JH7110_SYSRST_END,
|
||||
+ .assert_offset = 0x2F8,
|
||||
+ .status_offset = 0x308,
|
||||
+};
|
||||
+
|
||||
+static const struct jh7110_reset_info jh7110_aon_info = {
|
||||
+ .nr_resets = JH7110_AONRST_END,
|
||||
+ .assert_offset = 0x38,
|
||||
+ .status_offset = 0x3C,
|
||||
+};
|
||||
+
|
||||
+static int jh7110_reset_probe(struct auxiliary_device *adev,
|
||||
+ const struct auxiliary_device_id *id)
|
||||
+{
|
||||
+ struct jh7110_reset_info *info = (struct jh7110_reset_info *)(id->driver_data);
|
||||
+ void __iomem **base = (void __iomem **)dev_get_drvdata(adev->dev.parent);
|
||||
+
|
||||
+ if (!info || !base)
|
||||
+ return -ENODEV;
|
||||
+
|
||||
+ return reset_starfive_jh71x0_register(&adev->dev, adev->dev.parent->of_node,
|
||||
+ *base + info->assert_offset,
|
||||
+ *base + info->status_offset,
|
||||
+ NULL,
|
||||
+ info->nr_resets,
|
||||
+ NULL);
|
||||
+}
|
||||
+
|
||||
+static const struct auxiliary_device_id jh7110_reset_ids[] = {
|
||||
+ {
|
||||
+ .name = "clk_starfive_jh7110_sys.rst-sys",
|
||||
+ .driver_data = (kernel_ulong_t)&jh7110_sys_info,
|
||||
+ },
|
||||
+ {
|
||||
+ .name = "clk_starfive_jh7110_sys.rst-aon",
|
||||
+ .driver_data = (kernel_ulong_t)&jh7110_aon_info,
|
||||
+ },
|
||||
+ { /* sentinel */ }
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(auxiliary, jh7110_reset_ids);
|
||||
+
|
||||
+static struct auxiliary_driver jh7110_reset_driver = {
|
||||
+ .probe = jh7110_reset_probe,
|
||||
+ .id_table = jh7110_reset_ids,
|
||||
+};
|
||||
+module_auxiliary_driver(jh7110_reset_driver);
|
||||
+
|
||||
+MODULE_AUTHOR("Hal Feng <hal.feng@starfivetech.com>");
|
||||
+MODULE_DESCRIPTION("StarFive JH7110 reset driver");
|
||||
+MODULE_LICENSE("GPL");
|
@ -0,0 +1,50 @@
|
||||
From 17fecb06e9de3ae5bbf7aecc4d91e14517982f5c Mon Sep 17 00:00:00 2001
|
||||
From: "shanlong.li" <shanlong.li@starfivetech.com>
|
||||
Date: Wed, 17 May 2023 20:41:51 -0700
|
||||
Subject: [PATCH 016/122] MAINTAINERS: generalise StarFive clk/reset entries
|
||||
|
||||
Update the MAINTAINERS entry for StarFive's clock and reset drivers to
|
||||
account for the addition of JH7110 support and Hal's role in that.
|
||||
|
||||
Signed-off-by: shanlong.li <shanlong.li@starfivetech.com>
|
||||
---
|
||||
MAINTAINERS | 16 +++++++++-------
|
||||
1 file changed, 9 insertions(+), 7 deletions(-)
|
||||
|
||||
--- a/MAINTAINERS
|
||||
+++ b/MAINTAINERS
|
||||
@@ -19650,12 +19650,13 @@ M: Emil Renner Berthing <kernel@esmil.dk
|
||||
S: Maintained
|
||||
F: arch/riscv/boot/dts/starfive/
|
||||
|
||||
-STARFIVE JH7100 CLOCK DRIVERS
|
||||
+STARFIVE JH71X0 CLOCK DRIVERS
|
||||
M: Emil Renner Berthing <kernel@esmil.dk>
|
||||
+M: Hal Feng <hal.feng@starfivetech.com>
|
||||
S: Maintained
|
||||
-F: Documentation/devicetree/bindings/clock/starfive,jh7100-*.yaml
|
||||
-F: drivers/clk/starfive/clk-starfive-jh7100*
|
||||
-F: include/dt-bindings/clock/starfive-jh7100*.h
|
||||
+F: Documentation/devicetree/bindings/clock/starfive,jh71*.yaml
|
||||
+F: drivers/clk/starfive/clk-starfive-jh71*
|
||||
+F: include/dt-bindings/clock/starfive?jh71*.h
|
||||
|
||||
STARFIVE JH7100 PINCTRL DRIVER
|
||||
M: Emil Renner Berthing <kernel@esmil.dk>
|
||||
@@ -19665,12 +19666,13 @@ F: Documentation/devicetree/bindings/pin
|
||||
F: drivers/pinctrl/starfive/
|
||||
F: include/dt-bindings/pinctrl/pinctrl-starfive-jh7100.h
|
||||
|
||||
-STARFIVE JH7100 RESET CONTROLLER DRIVER
|
||||
+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: drivers/reset/reset-starfive-jh7100.c
|
||||
-F: include/dt-bindings/reset/starfive-jh7100.h
|
||||
+F: drivers/reset/starfive/reset-starfive-jh71*
|
||||
+F: include/dt-bindings/reset/starfive?jh71*.h
|
||||
|
||||
STATIC BRANCH/CALL
|
||||
M: Peter Zijlstra <peterz@infradead.org>
|
@ -0,0 +1,128 @@
|
||||
From d9d4e0fb44a50cace195e1639cfb23e518e17e88 Mon Sep 17 00:00:00 2001
|
||||
From: Stephen Boyd <sboyd@kernel.org>
|
||||
Date: Thu, 13 Apr 2023 13:55:28 -0700
|
||||
Subject: [PATCH 017/122] clk: starfive: Avoid casting iomem pointers
|
||||
|
||||
Let's use a wrapper struct for the auxiliary_device made in
|
||||
jh7110_reset_controller_register() so that we can stop casting iomem
|
||||
pointers. The casts trip up tools like sparse, and make for some awkward
|
||||
casts that are largely unnecessary. While we're here, change the
|
||||
allocation from devm and actually free the auxiliary_device memory in
|
||||
the release function. This avoids any use after free problems where the
|
||||
parent device driver is unbound from the device but the
|
||||
auxiliuary_device is still in use accessing devm freed memory.
|
||||
|
||||
Cc: Tommaso Merciai <tomm.merciai@gmail.com>
|
||||
Cc: Emil Renner Berthing <emil.renner.berthing@canonical.com>
|
||||
Cc: Hal Feng <hal.feng@starfivetech.com>
|
||||
Cc: Conor Dooley <conor.dooley@microchip.com>
|
||||
Cc: Xingyu Wu <xingyu.wu@starfivetech.com>
|
||||
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
|
||||
Fixes: edab7204afe5 ("clk: starfive: Add StarFive JH7110 system clock driver")
|
||||
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
|
||||
Link: https://lore.kernel.org/r/20230413205528.4044216-1-sboyd@kernel.org
|
||||
---
|
||||
drivers/clk/starfive/clk-starfive-jh7110-sys.c | 15 ++++++++++++---
|
||||
drivers/reset/starfive/reset-starfive-jh7110.c | 9 ++++++---
|
||||
include/soc/starfive/reset-starfive-jh71x0.h | 17 +++++++++++++++++
|
||||
3 files changed, 35 insertions(+), 6 deletions(-)
|
||||
create mode 100644 include/soc/starfive/reset-starfive-jh71x0.h
|
||||
|
||||
--- a/drivers/clk/starfive/clk-starfive-jh7110-sys.c
|
||||
+++ b/drivers/clk/starfive/clk-starfive-jh7110-sys.c
|
||||
@@ -11,6 +11,9 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/platform_device.h>
|
||||
+#include <linux/slab.h>
|
||||
+
|
||||
+#include <soc/starfive/reset-starfive-jh71x0.h>
|
||||
|
||||
#include <dt-bindings/clock/starfive,jh7110-crg.h>
|
||||
|
||||
@@ -335,26 +338,32 @@ static void jh7110_reset_unregister_adev
|
||||
struct auxiliary_device *adev = _adev;
|
||||
|
||||
auxiliary_device_delete(adev);
|
||||
+ auxiliary_device_uninit(adev);
|
||||
}
|
||||
|
||||
static void jh7110_reset_adev_release(struct device *dev)
|
||||
{
|
||||
struct auxiliary_device *adev = to_auxiliary_dev(dev);
|
||||
+ struct jh71x0_reset_adev *rdev = to_jh71x0_reset_adev(adev);
|
||||
|
||||
- auxiliary_device_uninit(adev);
|
||||
+ kfree(rdev);
|
||||
}
|
||||
|
||||
int jh7110_reset_controller_register(struct jh71x0_clk_priv *priv,
|
||||
const char *adev_name,
|
||||
u32 adev_id)
|
||||
{
|
||||
+ struct jh71x0_reset_adev *rdev;
|
||||
struct auxiliary_device *adev;
|
||||
int ret;
|
||||
|
||||
- adev = devm_kzalloc(priv->dev, sizeof(*adev), GFP_KERNEL);
|
||||
- if (!adev)
|
||||
+ rdev = kzalloc(sizeof(*rdev), GFP_KERNEL);
|
||||
+ if (!rdev)
|
||||
return -ENOMEM;
|
||||
|
||||
+ rdev->base = priv->base;
|
||||
+
|
||||
+ adev = &rdev->adev;
|
||||
adev->name = adev_name;
|
||||
adev->dev.parent = priv->dev;
|
||||
adev->dev.release = jh7110_reset_adev_release;
|
||||
--- a/drivers/reset/starfive/reset-starfive-jh7110.c
|
||||
+++ b/drivers/reset/starfive/reset-starfive-jh7110.c
|
||||
@@ -7,6 +7,8 @@
|
||||
|
||||
#include <linux/auxiliary_bus.h>
|
||||
|
||||
+#include <soc/starfive/reset-starfive-jh71x0.h>
|
||||
+
|
||||
#include "reset-starfive-jh71x0.h"
|
||||
|
||||
#include <dt-bindings/reset/starfive,jh7110-crg.h>
|
||||
@@ -33,14 +35,15 @@ static int jh7110_reset_probe(struct aux
|
||||
const struct auxiliary_device_id *id)
|
||||
{
|
||||
struct jh7110_reset_info *info = (struct jh7110_reset_info *)(id->driver_data);
|
||||
- void __iomem **base = (void __iomem **)dev_get_drvdata(adev->dev.parent);
|
||||
+ struct jh71x0_reset_adev *rdev = to_jh71x0_reset_adev(adev);
|
||||
+ void __iomem *base = rdev->base;
|
||||
|
||||
if (!info || !base)
|
||||
return -ENODEV;
|
||||
|
||||
return reset_starfive_jh71x0_register(&adev->dev, adev->dev.parent->of_node,
|
||||
- *base + info->assert_offset,
|
||||
- *base + info->status_offset,
|
||||
+ base + info->assert_offset,
|
||||
+ base + info->status_offset,
|
||||
NULL,
|
||||
info->nr_resets,
|
||||
NULL);
|
||||
--- /dev/null
|
||||
+++ b/include/soc/starfive/reset-starfive-jh71x0.h
|
||||
@@ -0,0 +1,17 @@
|
||||
+/* SPDX-License-Identifier: GPL-2.0 */
|
||||
+#ifndef __SOC_STARFIVE_RESET_JH71X0_H
|
||||
+#define __SOC_STARFIVE_RESET_JH71X0_H
|
||||
+
|
||||
+#include <linux/auxiliary_bus.h>
|
||||
+#include <linux/compiler_types.h>
|
||||
+#include <linux/container_of.h>
|
||||
+
|
||||
+struct jh71x0_reset_adev {
|
||||
+ void __iomem *base;
|
||||
+ struct auxiliary_device adev;
|
||||
+};
|
||||
+
|
||||
+#define to_jh71x0_reset_adev(_adev) \
|
||||
+ container_of((_adev), struct jh71x0_reset_adev, adev)
|
||||
+
|
||||
+#endif
|
@ -0,0 +1,27 @@
|
||||
From f043ba93a8f22fda312574eb98217be15468b7ef Mon Sep 17 00:00:00 2001
|
||||
From: Emil Renner Berthing <kernel@esmil.dk>
|
||||
Date: Sat, 1 Apr 2023 19:19:28 +0800
|
||||
Subject: [PATCH 018/122] dt-bindings: timer: Add StarFive JH7110 clint
|
||||
|
||||
Add compatible string for the StarFive JH7110 clint.
|
||||
|
||||
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
|
||||
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
|
||||
Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
|
||||
Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
|
||||
Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
|
||||
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
|
||||
---
|
||||
Documentation/devicetree/bindings/timer/sifive,clint.yaml | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
--- a/Documentation/devicetree/bindings/timer/sifive,clint.yaml
|
||||
+++ b/Documentation/devicetree/bindings/timer/sifive,clint.yaml
|
||||
@@ -27,6 +27,7 @@ properties:
|
||||
- enum:
|
||||
- sifive,fu540-c000-clint
|
||||
- starfive,jh7100-clint
|
||||
+ - starfive,jh7110-clint
|
||||
- canaan,k210-clint
|
||||
- const: sifive,clint0
|
||||
- items:
|
@ -0,0 +1,28 @@
|
||||
From dba83b8b65b4ef47e8986739b6734894f3979c52 Mon Sep 17 00:00:00 2001
|
||||
From: Emil Renner Berthing <kernel@esmil.dk>
|
||||
Date: Sat, 1 Apr 2023 19:19:29 +0800
|
||||
Subject: [PATCH 019/122] dt-bindings: interrupt-controller: Add StarFive
|
||||
JH7110 plic
|
||||
|
||||
Add compatible string for StarFive JH7110 plic.
|
||||
|
||||
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
|
||||
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
|
||||
Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
|
||||
Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
|
||||
Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
|
||||
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
|
||||
---
|
||||
.../bindings/interrupt-controller/sifive,plic-1.0.0.yaml | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
--- a/Documentation/devicetree/bindings/interrupt-controller/sifive,plic-1.0.0.yaml
|
||||
+++ b/Documentation/devicetree/bindings/interrupt-controller/sifive,plic-1.0.0.yaml
|
||||
@@ -60,6 +60,7 @@ properties:
|
||||
- enum:
|
||||
- sifive,fu540-c000-plic
|
||||
- starfive,jh7100-plic
|
||||
+ - starfive,jh7110-plic
|
||||
- canaan,k210-plic
|
||||
- const: sifive,plic-1.0.0
|
||||
- items:
|
@ -0,0 +1,27 @@
|
||||
From fccbb0c52438762999ea16c85d4ebf4cc7e2deff Mon Sep 17 00:00:00 2001
|
||||
From: Hal Feng <hal.feng@starfivetech.com>
|
||||
Date: Sat, 1 Apr 2023 19:19:30 +0800
|
||||
Subject: [PATCH 020/122] dt-bindings: riscv: Add SiFive S7 compatible
|
||||
|
||||
Add a new compatible string in cpu.yaml for SiFive S7 CPU
|
||||
core which is used on SiFive U74-MC core complex etc.
|
||||
|
||||
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
|
||||
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
|
||||
Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
|
||||
Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
|
||||
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
|
||||
---
|
||||
Documentation/devicetree/bindings/riscv/cpus.yaml | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
--- a/Documentation/devicetree/bindings/riscv/cpus.yaml
|
||||
+++ b/Documentation/devicetree/bindings/riscv/cpus.yaml
|
||||
@@ -33,6 +33,7 @@ properties:
|
||||
- sifive,e5
|
||||
- sifive,e7
|
||||
- sifive,e71
|
||||
+ - sifive,s7
|
||||
- sifive,u74-mc
|
||||
- sifive,u54
|
||||
- sifive,u74
|
@ -0,0 +1,549 @@
|
||||
From ca57ce82224c21f93ad43754474fb8de1baf5caa Mon Sep 17 00:00:00 2001
|
||||
From: Emil Renner Berthing <kernel@esmil.dk>
|
||||
Date: Sat, 1 Apr 2023 19:19:31 +0800
|
||||
Subject: [PATCH 021/122] riscv: dts: starfive: Add initial StarFive JH7110
|
||||
device tree
|
||||
|
||||
Add initial device tree for the JH7110 RISC-V SoC by StarFive
|
||||
Technology Ltd.
|
||||
|
||||
Tested-by: Tommaso Merciai <tomm.merciai@gmail.com>
|
||||
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
|
||||
Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
|
||||
Co-developed-by: Jianlong Huang <jianlong.huang@starfivetech.com>
|
||||
Signed-off-by: Jianlong Huang <jianlong.huang@starfivetech.com>
|
||||
Co-developed-by: Hal Feng <hal.feng@starfivetech.com>
|
||||
Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
|
||||
[conor: squashed in the removal of the S7's non-existent mmu]
|
||||
Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
|
||||
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
|
||||
---
|
||||
arch/riscv/Kconfig.socs | 5 +
|
||||
arch/riscv/boot/dts/starfive/jh7110.dtsi | 500 +++++++++++++++++++++++
|
||||
2 files changed, 505 insertions(+)
|
||||
create mode 100644 arch/riscv/boot/dts/starfive/jh7110.dtsi
|
||||
|
||||
--- a/arch/riscv/Kconfig.socs
|
||||
+++ b/arch/riscv/Kconfig.socs
|
||||
@@ -7,6 +7,8 @@ config SOC_MICROCHIP_POLARFIRE
|
||||
help
|
||||
This enables support for Microchip PolarFire SoC platforms.
|
||||
|
||||
+config ARCH_SIFIVE
|
||||
+ def_bool SOC_SIFIVE
|
||||
config SOC_SIFIVE
|
||||
bool "SiFive SoCs"
|
||||
select SERIAL_SIFIVE if TTY
|
||||
@@ -18,6 +20,9 @@ config SOC_SIFIVE
|
||||
help
|
||||
This enables support for SiFive SoC platform hardware.
|
||||
|
||||
+config ARCH_STARFIVE
|
||||
+ def_bool SOC_STARFIVE
|
||||
+
|
||||
config SOC_STARFIVE
|
||||
bool "StarFive SoCs"
|
||||
select PINCTRL
|
||||
--- /dev/null
|
||||
+++ b/arch/riscv/boot/dts/starfive/jh7110.dtsi
|
||||
@@ -0,0 +1,500 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0 OR MIT
|
||||
+/*
|
||||
+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
|
||||
+ * Copyright (C) 2022 Emil Renner Berthing <kernel@esmil.dk>
|
||||
+ */
|
||||
+
|
||||
+/dts-v1/;
|
||||
+#include <dt-bindings/clock/starfive,jh7110-crg.h>
|
||||
+#include <dt-bindings/reset/starfive,jh7110-crg.h>
|
||||
+
|
||||
+/ {
|
||||
+ compatible = "starfive,jh7110";
|
||||
+ #address-cells = <2>;
|
||||
+ #size-cells = <2>;
|
||||
+
|
||||
+ cpus {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+
|
||||
+ S7_0: cpu@0 {
|
||||
+ compatible = "sifive,s7", "riscv";
|
||||
+ reg = <0>;
|
||||
+ device_type = "cpu";
|
||||
+ i-cache-block-size = <64>;
|
||||
+ i-cache-sets = <64>;
|
||||
+ i-cache-size = <16384>;
|
||||
+ next-level-cache = <&ccache>;
|
||||
+ riscv,isa = "rv64imac_zba_zbb";
|
||||
+ status = "disabled";
|
||||
+
|
||||
+ cpu0_intc: interrupt-controller {
|
||||
+ compatible = "riscv,cpu-intc";
|
||||
+ interrupt-controller;
|
||||
+ #interrupt-cells = <1>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ U74_1: cpu@1 {
|
||||
+ compatible = "sifive,u74-mc", "riscv";
|
||||
+ reg = <1>;
|
||||
+ d-cache-block-size = <64>;
|
||||
+ d-cache-sets = <64>;
|
||||
+ d-cache-size = <32768>;
|
||||
+ d-tlb-sets = <1>;
|
||||
+ d-tlb-size = <40>;
|
||||
+ device_type = "cpu";
|
||||
+ i-cache-block-size = <64>;
|
||||
+ i-cache-sets = <64>;
|
||||
+ i-cache-size = <32768>;
|
||||
+ i-tlb-sets = <1>;
|
||||
+ i-tlb-size = <40>;
|
||||
+ mmu-type = "riscv,sv39";
|
||||
+ next-level-cache = <&ccache>;
|
||||
+ riscv,isa = "rv64imafdc_zba_zbb";
|
||||
+ tlb-split;
|
||||
+
|
||||
+ cpu1_intc: interrupt-controller {
|
||||
+ compatible = "riscv,cpu-intc";
|
||||
+ interrupt-controller;
|
||||
+ #interrupt-cells = <1>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ U74_2: cpu@2 {
|
||||
+ compatible = "sifive,u74-mc", "riscv";
|
||||
+ reg = <2>;
|
||||
+ d-cache-block-size = <64>;
|
||||
+ d-cache-sets = <64>;
|
||||
+ d-cache-size = <32768>;
|
||||
+ d-tlb-sets = <1>;
|
||||
+ d-tlb-size = <40>;
|
||||
+ device_type = "cpu";
|
||||
+ i-cache-block-size = <64>;
|
||||
+ i-cache-sets = <64>;
|
||||
+ i-cache-size = <32768>;
|
||||
+ i-tlb-sets = <1>;
|
||||
+ i-tlb-size = <40>;
|
||||
+ mmu-type = "riscv,sv39";
|
||||
+ next-level-cache = <&ccache>;
|
||||
+ riscv,isa = "rv64imafdc_zba_zbb";
|
||||
+ tlb-split;
|
||||
+
|
||||
+ cpu2_intc: interrupt-controller {
|
||||
+ compatible = "riscv,cpu-intc";
|
||||
+ interrupt-controller;
|
||||
+ #interrupt-cells = <1>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ U74_3: cpu@3 {
|
||||
+ compatible = "sifive,u74-mc", "riscv";
|
||||
+ reg = <3>;
|
||||
+ d-cache-block-size = <64>;
|
||||
+ d-cache-sets = <64>;
|
||||
+ d-cache-size = <32768>;
|
||||
+ d-tlb-sets = <1>;
|
||||
+ d-tlb-size = <40>;
|
||||
+ device_type = "cpu";
|
||||
+ i-cache-block-size = <64>;
|
||||
+ i-cache-sets = <64>;
|
||||
+ i-cache-size = <32768>;
|
||||
+ i-tlb-sets = <1>;
|
||||
+ i-tlb-size = <40>;
|
||||
+ mmu-type = "riscv,sv39";
|
||||
+ next-level-cache = <&ccache>;
|
||||
+ riscv,isa = "rv64imafdc_zba_zbb";
|
||||
+ tlb-split;
|
||||
+
|
||||
+ cpu3_intc: interrupt-controller {
|
||||
+ compatible = "riscv,cpu-intc";
|
||||
+ interrupt-controller;
|
||||
+ #interrupt-cells = <1>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ U74_4: cpu@4 {
|
||||
+ compatible = "sifive,u74-mc", "riscv";
|
||||
+ reg = <4>;
|
||||
+ d-cache-block-size = <64>;
|
||||
+ d-cache-sets = <64>;
|
||||
+ d-cache-size = <32768>;
|
||||
+ d-tlb-sets = <1>;
|
||||
+ d-tlb-size = <40>;
|
||||
+ device_type = "cpu";
|
||||
+ i-cache-block-size = <64>;
|
||||
+ i-cache-sets = <64>;
|
||||
+ i-cache-size = <32768>;
|
||||
+ i-tlb-sets = <1>;
|
||||
+ i-tlb-size = <40>;
|
||||
+ mmu-type = "riscv,sv39";
|
||||
+ next-level-cache = <&ccache>;
|
||||
+ riscv,isa = "rv64imafdc_zba_zbb";
|
||||
+ tlb-split;
|
||||
+
|
||||
+ cpu4_intc: interrupt-controller {
|
||||
+ compatible = "riscv,cpu-intc";
|
||||
+ interrupt-controller;
|
||||
+ #interrupt-cells = <1>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ cpu-map {
|
||||
+ cluster0 {
|
||||
+ core0 {
|
||||
+ cpu = <&S7_0>;
|
||||
+ };
|
||||
+
|
||||
+ core1 {
|
||||
+ cpu = <&U74_1>;
|
||||
+ };
|
||||
+
|
||||
+ core2 {
|
||||
+ cpu = <&U74_2>;
|
||||
+ };
|
||||
+
|
||||
+ core3 {
|
||||
+ cpu = <&U74_3>;
|
||||
+ };
|
||||
+
|
||||
+ core4 {
|
||||
+ cpu = <&U74_4>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ gmac0_rgmii_rxin: gmac0-rgmii-rxin-clock {
|
||||
+ compatible = "fixed-clock";
|
||||
+ clock-output-names = "gmac0_rgmii_rxin";
|
||||
+ #clock-cells = <0>;
|
||||
+ };
|
||||
+
|
||||
+ gmac0_rmii_refin: gmac0-rmii-refin-clock {
|
||||
+ compatible = "fixed-clock";
|
||||
+ clock-output-names = "gmac0_rmii_refin";
|
||||
+ #clock-cells = <0>;
|
||||
+ };
|
||||
+
|
||||
+ gmac1_rgmii_rxin: gmac1-rgmii-rxin-clock {
|
||||
+ compatible = "fixed-clock";
|
||||
+ clock-output-names = "gmac1_rgmii_rxin";
|
||||
+ #clock-cells = <0>;
|
||||
+ };
|
||||
+
|
||||
+ gmac1_rmii_refin: gmac1-rmii-refin-clock {
|
||||
+ compatible = "fixed-clock";
|
||||
+ clock-output-names = "gmac1_rmii_refin";
|
||||
+ #clock-cells = <0>;
|
||||
+ };
|
||||
+
|
||||
+ i2srx_bclk_ext: i2srx-bclk-ext-clock {
|
||||
+ compatible = "fixed-clock";
|
||||
+ clock-output-names = "i2srx_bclk_ext";
|
||||
+ #clock-cells = <0>;
|
||||
+ };
|
||||
+
|
||||
+ i2srx_lrck_ext: i2srx-lrck-ext-clock {
|
||||
+ compatible = "fixed-clock";
|
||||
+ clock-output-names = "i2srx_lrck_ext";
|
||||
+ #clock-cells = <0>;
|
||||
+ };
|
||||
+
|
||||
+ i2stx_bclk_ext: i2stx-bclk-ext-clock {
|
||||
+ compatible = "fixed-clock";
|
||||
+ clock-output-names = "i2stx_bclk_ext";
|
||||
+ #clock-cells = <0>;
|
||||
+ };
|
||||
+
|
||||
+ i2stx_lrck_ext: i2stx-lrck-ext-clock {
|
||||
+ compatible = "fixed-clock";
|
||||
+ clock-output-names = "i2stx_lrck_ext";
|
||||
+ #clock-cells = <0>;
|
||||
+ };
|
||||
+
|
||||
+ mclk_ext: mclk-ext-clock {
|
||||
+ compatible = "fixed-clock";
|
||||
+ clock-output-names = "mclk_ext";
|
||||
+ #clock-cells = <0>;
|
||||
+ };
|
||||
+
|
||||
+ osc: oscillator {
|
||||
+ compatible = "fixed-clock";
|
||||
+ clock-output-names = "osc";
|
||||
+ #clock-cells = <0>;
|
||||
+ };
|
||||
+
|
||||
+ rtc_osc: rtc-oscillator {
|
||||
+ compatible = "fixed-clock";
|
||||
+ clock-output-names = "rtc_osc";
|
||||
+ #clock-cells = <0>;
|
||||
+ };
|
||||
+
|
||||
+ tdm_ext: tdm-ext-clock {
|
||||
+ compatible = "fixed-clock";
|
||||
+ clock-output-names = "tdm_ext";
|
||||
+ #clock-cells = <0>;
|
||||
+ };
|
||||
+
|
||||
+ soc {
|
||||
+ compatible = "simple-bus";
|
||||
+ interrupt-parent = <&plic>;
|
||||
+ #address-cells = <2>;
|
||||
+ #size-cells = <2>;
|
||||
+ ranges;
|
||||
+
|
||||
+ clint: timer@2000000 {
|
||||
+ compatible = "starfive,jh7110-clint", "sifive,clint0";
|
||||
+ reg = <0x0 0x2000000 0x0 0x10000>;
|
||||
+ interrupts-extended = <&cpu0_intc 3>, <&cpu0_intc 7>,
|
||||
+ <&cpu1_intc 3>, <&cpu1_intc 7>,
|
||||
+ <&cpu2_intc 3>, <&cpu2_intc 7>,
|
||||
+ <&cpu3_intc 3>, <&cpu3_intc 7>,
|
||||
+ <&cpu4_intc 3>, <&cpu4_intc 7>;
|
||||
+ };
|
||||
+
|
||||
+ ccache: cache-controller@2010000 {
|
||||
+ compatible = "starfive,jh7110-ccache", "sifive,ccache0", "cache";
|
||||
+ reg = <0x0 0x2010000 0x0 0x4000>;
|
||||
+ interrupts = <1>, <3>, <4>, <2>;
|
||||
+ cache-block-size = <64>;
|
||||
+ cache-level = <2>;
|
||||
+ cache-sets = <2048>;
|
||||
+ cache-size = <2097152>;
|
||||
+ cache-unified;
|
||||
+ };
|
||||
+
|
||||
+ plic: interrupt-controller@c000000 {
|
||||
+ compatible = "starfive,jh7110-plic", "sifive,plic-1.0.0";
|
||||
+ reg = <0x0 0xc000000 0x0 0x4000000>;
|
||||
+ interrupts-extended = <&cpu0_intc 11>,
|
||||
+ <&cpu1_intc 11>, <&cpu1_intc 9>,
|
||||
+ <&cpu2_intc 11>, <&cpu2_intc 9>,
|
||||
+ <&cpu3_intc 11>, <&cpu3_intc 9>,
|
||||
+ <&cpu4_intc 11>, <&cpu4_intc 9>;
|
||||
+ interrupt-controller;
|
||||
+ #interrupt-cells = <1>;
|
||||
+ #address-cells = <0>;
|
||||
+ riscv,ndev = <136>;
|
||||
+ };
|
||||
+
|
||||
+ uart0: serial@10000000 {
|
||||
+ compatible = "snps,dw-apb-uart";
|
||||
+ reg = <0x0 0x10000000 0x0 0x10000>;
|
||||
+ clocks = <&syscrg JH7110_SYSCLK_UART0_CORE>,
|
||||
+ <&syscrg JH7110_SYSCLK_UART0_APB>;
|
||||
+ clock-names = "baudclk", "apb_pclk";
|
||||
+ resets = <&syscrg JH7110_SYSRST_UART0_APB>;
|
||||
+ interrupts = <32>;
|
||||
+ reg-io-width = <4>;
|
||||
+ reg-shift = <2>;
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
+ uart1: serial@10010000 {
|
||||
+ compatible = "snps,dw-apb-uart";
|
||||
+ reg = <0x0 0x10010000 0x0 0x10000>;
|
||||
+ clocks = <&syscrg JH7110_SYSCLK_UART1_CORE>,
|
||||
+ <&syscrg JH7110_SYSCLK_UART1_APB>;
|
||||
+ clock-names = "baudclk", "apb_pclk";
|
||||
+ resets = <&syscrg JH7110_SYSRST_UART1_APB>;
|
||||
+ interrupts = <33>;
|
||||
+ reg-io-width = <4>;
|
||||
+ reg-shift = <2>;
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
+ uart2: serial@10020000 {
|
||||
+ compatible = "snps,dw-apb-uart";
|
||||
+ reg = <0x0 0x10020000 0x0 0x10000>;
|
||||
+ clocks = <&syscrg JH7110_SYSCLK_UART2_CORE>,
|
||||
+ <&syscrg JH7110_SYSCLK_UART2_APB>;
|
||||
+ clock-names = "baudclk", "apb_pclk";
|
||||
+ resets = <&syscrg JH7110_SYSRST_UART2_APB>;
|
||||
+ interrupts = <34>;
|
||||
+ reg-io-width = <4>;
|
||||
+ reg-shift = <2>;
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
+ i2c0: i2c@10030000 {
|
||||
+ compatible = "snps,designware-i2c";
|
||||
+ reg = <0x0 0x10030000 0x0 0x10000>;
|
||||
+ clocks = <&syscrg JH7110_SYSCLK_I2C0_APB>;
|
||||
+ clock-names = "ref";
|
||||
+ resets = <&syscrg JH7110_SYSRST_I2C0_APB>;
|
||||
+ interrupts = <35>;
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
+ i2c1: i2c@10040000 {
|
||||
+ compatible = "snps,designware-i2c";
|
||||
+ reg = <0x0 0x10040000 0x0 0x10000>;
|
||||
+ clocks = <&syscrg JH7110_SYSCLK_I2C1_APB>;
|
||||
+ clock-names = "ref";
|
||||
+ resets = <&syscrg JH7110_SYSRST_I2C1_APB>;
|
||||
+ interrupts = <36>;
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
+ i2c2: i2c@10050000 {
|
||||
+ compatible = "snps,designware-i2c";
|
||||
+ reg = <0x0 0x10050000 0x0 0x10000>;
|
||||
+ clocks = <&syscrg JH7110_SYSCLK_I2C2_APB>;
|
||||
+ clock-names = "ref";
|
||||
+ resets = <&syscrg JH7110_SYSRST_I2C2_APB>;
|
||||
+ interrupts = <37>;
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
+ uart3: serial@12000000 {
|
||||
+ compatible = "snps,dw-apb-uart";
|
||||
+ reg = <0x0 0x12000000 0x0 0x10000>;
|
||||
+ clocks = <&syscrg JH7110_SYSCLK_UART3_CORE>,
|
||||
+ <&syscrg JH7110_SYSCLK_UART3_APB>;
|
||||
+ clock-names = "baudclk", "apb_pclk";
|
||||
+ resets = <&syscrg JH7110_SYSRST_UART3_APB>;
|
||||
+ interrupts = <45>;
|
||||
+ reg-io-width = <4>;
|
||||
+ reg-shift = <2>;
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
+ uart4: serial@12010000 {
|
||||
+ compatible = "snps,dw-apb-uart";
|
||||
+ reg = <0x0 0x12010000 0x0 0x10000>;
|
||||
+ clocks = <&syscrg JH7110_SYSCLK_UART4_CORE>,
|
||||
+ <&syscrg JH7110_SYSCLK_UART4_APB>;
|
||||
+ clock-names = "baudclk", "apb_pclk";
|
||||
+ resets = <&syscrg JH7110_SYSRST_UART4_APB>;
|
||||
+ interrupts = <46>;
|
||||
+ reg-io-width = <4>;
|
||||
+ reg-shift = <2>;
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
+ uart5: serial@12020000 {
|
||||
+ compatible = "snps,dw-apb-uart";
|
||||
+ reg = <0x0 0x12020000 0x0 0x10000>;
|
||||
+ clocks = <&syscrg JH7110_SYSCLK_UART5_CORE>,
|
||||
+ <&syscrg JH7110_SYSCLK_UART5_APB>;
|
||||
+ clock-names = "baudclk", "apb_pclk";
|
||||
+ resets = <&syscrg JH7110_SYSRST_UART5_APB>;
|
||||
+ interrupts = <47>;
|
||||
+ reg-io-width = <4>;
|
||||
+ reg-shift = <2>;
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
+ i2c3: i2c@12030000 {
|
||||
+ compatible = "snps,designware-i2c";
|
||||
+ reg = <0x0 0x12030000 0x0 0x10000>;
|
||||
+ clocks = <&syscrg JH7110_SYSCLK_I2C3_APB>;
|
||||
+ clock-names = "ref";
|
||||
+ resets = <&syscrg JH7110_SYSRST_I2C3_APB>;
|
||||
+ interrupts = <48>;
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
+ i2c4: i2c@12040000 {
|
||||
+ compatible = "snps,designware-i2c";
|
||||
+ reg = <0x0 0x12040000 0x0 0x10000>;
|
||||
+ clocks = <&syscrg JH7110_SYSCLK_I2C4_APB>;
|
||||
+ clock-names = "ref";
|
||||
+ resets = <&syscrg JH7110_SYSRST_I2C4_APB>;
|
||||
+ interrupts = <49>;
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
+ i2c5: i2c@12050000 {
|
||||
+ compatible = "snps,designware-i2c";
|
||||
+ reg = <0x0 0x12050000 0x0 0x10000>;
|
||||
+ clocks = <&syscrg JH7110_SYSCLK_I2C5_APB>;
|
||||
+ clock-names = "ref";
|
||||
+ resets = <&syscrg JH7110_SYSRST_I2C5_APB>;
|
||||
+ interrupts = <50>;
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
+ i2c6: i2c@12060000 {
|
||||
+ compatible = "snps,designware-i2c";
|
||||
+ reg = <0x0 0x12060000 0x0 0x10000>;
|
||||
+ clocks = <&syscrg JH7110_SYSCLK_I2C6_APB>;
|
||||
+ clock-names = "ref";
|
||||
+ resets = <&syscrg JH7110_SYSRST_I2C6_APB>;
|
||||
+ interrupts = <51>;
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
+ syscrg: clock-controller@13020000 {
|
||||
+ compatible = "starfive,jh7110-syscrg";
|
||||
+ reg = <0x0 0x13020000 0x0 0x10000>;
|
||||
+ clocks = <&osc>, <&gmac1_rmii_refin>,
|
||||
+ <&gmac1_rgmii_rxin>,
|
||||
+ <&i2stx_bclk_ext>, <&i2stx_lrck_ext>,
|
||||
+ <&i2srx_bclk_ext>, <&i2srx_lrck_ext>,
|
||||
+ <&tdm_ext>, <&mclk_ext>;
|
||||
+ clock-names = "osc", "gmac1_rmii_refin",
|
||||
+ "gmac1_rgmii_rxin",
|
||||
+ "i2stx_bclk_ext", "i2stx_lrck_ext",
|
||||
+ "i2srx_bclk_ext", "i2srx_lrck_ext",
|
||||
+ "tdm_ext", "mclk_ext";
|
||||
+ #clock-cells = <1>;
|
||||
+ #reset-cells = <1>;
|
||||
+ };
|
||||
+
|
||||
+ sysgpio: pinctrl@13040000 {
|
||||
+ compatible = "starfive,jh7110-sys-pinctrl";
|
||||
+ reg = <0x0 0x13040000 0x0 0x10000>;
|
||||
+ clocks = <&syscrg JH7110_SYSCLK_IOMUX_APB>;
|
||||
+ resets = <&syscrg JH7110_SYSRST_IOMUX_APB>;
|
||||
+ interrupts = <86>;
|
||||
+ interrupt-controller;
|
||||
+ #interrupt-cells = <2>;
|
||||
+ gpio-controller;
|
||||
+ #gpio-cells = <2>;
|
||||
+ };
|
||||
+
|
||||
+ aoncrg: clock-controller@17000000 {
|
||||
+ compatible = "starfive,jh7110-aoncrg";
|
||||
+ reg = <0x0 0x17000000 0x0 0x10000>;
|
||||
+ clocks = <&osc>, <&gmac0_rmii_refin>,
|
||||
+ <&gmac0_rgmii_rxin>,
|
||||
+ <&syscrg JH7110_SYSCLK_STG_AXIAHB>,
|
||||
+ <&syscrg JH7110_SYSCLK_APB_BUS>,
|
||||
+ <&syscrg JH7110_SYSCLK_GMAC0_GTXCLK>,
|
||||
+ <&rtc_osc>;
|
||||
+ clock-names = "osc", "gmac0_rmii_refin",
|
||||
+ "gmac0_rgmii_rxin", "stg_axiahb",
|
||||
+ "apb_bus", "gmac0_gtxclk",
|
||||
+ "rtc_osc";
|
||||
+ #clock-cells = <1>;
|
||||
+ #reset-cells = <1>;
|
||||
+ };
|
||||
+
|
||||
+ aongpio: pinctrl@17020000 {
|
||||
+ compatible = "starfive,jh7110-aon-pinctrl";
|
||||
+ reg = <0x0 0x17020000 0x0 0x10000>;
|
||||
+ resets = <&aoncrg JH7110_AONRST_IOMUX>;
|
||||
+ interrupts = <85>;
|
||||
+ interrupt-controller;
|
||||
+ #interrupt-cells = <2>;
|
||||
+ gpio-controller;
|
||||
+ #gpio-cells = <2>;
|
||||
+ };
|
||||
+ };
|
||||
+};
|
@ -0,0 +1,331 @@
|
||||
From 878c16d22c0feb52c3af65139734b8bb45e349e1 Mon Sep 17 00:00:00 2001
|
||||
From: Jianlong Huang <jianlong.huang@starfivetech.com>
|
||||
Date: Sat, 1 Apr 2023 19:19:32 +0800
|
||||
Subject: [PATCH 022/122] riscv: dts: starfive: Add StarFive JH7110 pin
|
||||
function definitions
|
||||
|
||||
Add pin function definitions for StarFive JH7110 SoC.
|
||||
|
||||
Tested-by: Tommaso Merciai <tomm.merciai@gmail.com>
|
||||
Co-developed-by: Emil Renner Berthing <kernel@esmil.dk>
|
||||
Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
|
||||
Signed-off-by: Jianlong Huang <jianlong.huang@starfivetech.com>
|
||||
Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
|
||||
Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
|
||||
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
|
||||
---
|
||||
arch/riscv/boot/dts/starfive/jh7110-pinfunc.h | 308 ++++++++++++++++++
|
||||
1 file changed, 308 insertions(+)
|
||||
create mode 100644 arch/riscv/boot/dts/starfive/jh7110-pinfunc.h
|
||||
|
||||
--- /dev/null
|
||||
+++ b/arch/riscv/boot/dts/starfive/jh7110-pinfunc.h
|
||||
@@ -0,0 +1,308 @@
|
||||
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
|
||||
+/*
|
||||
+ * Copyright (C) 2022 Emil Renner Berthing <kernel@esmil.dk>
|
||||
+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
|
||||
+ */
|
||||
+
|
||||
+#ifndef __JH7110_PINFUNC_H__
|
||||
+#define __JH7110_PINFUNC_H__
|
||||
+
|
||||
+/*
|
||||
+ * mux bits:
|
||||
+ * | 31 - 24 | 23 - 16 | 15 - 10 | 9 - 8 | 7 - 0 |
|
||||
+ * | din | dout | doen | function | gpio nr |
|
||||
+ *
|
||||
+ * dout: output signal
|
||||
+ * doen: output enable signal
|
||||
+ * din: optional input signal, 0xff = none
|
||||
+ * function: function selector
|
||||
+ * gpio nr: gpio number, 0 - 63
|
||||
+ */
|
||||
+#define GPIOMUX(n, dout, doen, din) ( \
|
||||
+ (((din) & 0xff) << 24) | \
|
||||
+ (((dout) & 0xff) << 16) | \
|
||||
+ (((doen) & 0x3f) << 10) | \
|
||||
+ ((n) & 0x3f))
|
||||
+
|
||||
+#define PINMUX(n, func) ((1 << 10) | (((func) & 0x3) << 8) | ((n) & 0xff))
|
||||
+
|
||||
+/* sys_iomux dout */
|
||||
+#define GPOUT_LOW 0
|
||||
+#define GPOUT_HIGH 1
|
||||
+#define GPOUT_SYS_WAVE511_UART_TX 2
|
||||
+#define GPOUT_SYS_CAN0_STBY 3
|
||||
+#define GPOUT_SYS_CAN0_TST_NEXT_BIT 4
|
||||
+#define GPOUT_SYS_CAN0_TST_SAMPLE_POINT 5
|
||||
+#define GPOUT_SYS_CAN0_TXD 6
|
||||
+#define GPOUT_SYS_USB_DRIVE_VBUS 7
|
||||
+#define GPOUT_SYS_QSPI_CS1 8
|
||||
+#define GPOUT_SYS_SPDIF 9
|
||||
+#define GPOUT_SYS_HDMI_CEC_SDA 10
|
||||
+#define GPOUT_SYS_HDMI_DDC_SCL 11
|
||||
+#define GPOUT_SYS_HDMI_DDC_SDA 12
|
||||
+#define GPOUT_SYS_WATCHDOG 13
|
||||
+#define GPOUT_SYS_I2C0_CLK 14
|
||||
+#define GPOUT_SYS_I2C0_DATA 15
|
||||
+#define GPOUT_SYS_SDIO0_BACK_END_POWER 16
|
||||
+#define GPOUT_SYS_SDIO0_CARD_POWER_EN 17
|
||||
+#define GPOUT_SYS_SDIO0_CCMD_OD_PULLUP_EN 18
|
||||
+#define GPOUT_SYS_SDIO0_RST 19
|
||||
+#define GPOUT_SYS_UART0_TX 20
|
||||
+#define GPOUT_SYS_HIFI4_JTAG_TDO 21
|
||||
+#define GPOUT_SYS_JTAG_TDO 22
|
||||
+#define GPOUT_SYS_PDM_MCLK 23
|
||||
+#define GPOUT_SYS_PWM_CHANNEL0 24
|
||||
+#define GPOUT_SYS_PWM_CHANNEL1 25
|
||||
+#define GPOUT_SYS_PWM_CHANNEL2 26
|
||||
+#define GPOUT_SYS_PWM_CHANNEL3 27
|
||||
+#define GPOUT_SYS_PWMDAC_LEFT 28
|
||||
+#define GPOUT_SYS_PWMDAC_RIGHT 29
|
||||
+#define GPOUT_SYS_SPI0_CLK 30
|
||||
+#define GPOUT_SYS_SPI0_FSS 31
|
||||
+#define GPOUT_SYS_SPI0_TXD 32
|
||||
+#define GPOUT_SYS_GMAC_PHYCLK 33
|
||||
+#define GPOUT_SYS_I2SRX_BCLK 34
|
||||
+#define GPOUT_SYS_I2SRX_LRCK 35
|
||||
+#define GPOUT_SYS_I2STX0_BCLK 36
|
||||
+#define GPOUT_SYS_I2STX0_LRCK 37
|
||||
+#define GPOUT_SYS_MCLK 38
|
||||
+#define GPOUT_SYS_TDM_CLK 39
|
||||
+#define GPOUT_SYS_TDM_SYNC 40
|
||||
+#define GPOUT_SYS_TDM_TXD 41
|
||||
+#define GPOUT_SYS_TRACE_DATA0 42
|
||||
+#define GPOUT_SYS_TRACE_DATA1 43
|
||||
+#define GPOUT_SYS_TRACE_DATA2 44
|
||||
+#define GPOUT_SYS_TRACE_DATA3 45
|
||||
+#define GPOUT_SYS_TRACE_REF 46
|
||||
+#define GPOUT_SYS_CAN1_STBY 47
|
||||
+#define GPOUT_SYS_CAN1_TST_NEXT_BIT 48
|
||||
+#define GPOUT_SYS_CAN1_TST_SAMPLE_POINT 49
|
||||
+#define GPOUT_SYS_CAN1_TXD 50
|
||||
+#define GPOUT_SYS_I2C1_CLK 51
|
||||
+#define GPOUT_SYS_I2C1_DATA 52
|
||||
+#define GPOUT_SYS_SDIO1_BACK_END_POWER 53
|
||||
+#define GPOUT_SYS_SDIO1_CARD_POWER_EN 54
|
||||
+#define GPOUT_SYS_SDIO1_CLK 55
|
||||
+#define GPOUT_SYS_SDIO1_CMD_OD_PULLUP_EN 56
|
||||
+#define GPOUT_SYS_SDIO1_CMD 57
|
||||
+#define GPOUT_SYS_SDIO1_DATA0 58
|
||||
+#define GPOUT_SYS_SDIO1_DATA1 59
|
||||
+#define GPOUT_SYS_SDIO1_DATA2 60
|
||||
+#define GPOUT_SYS_SDIO1_DATA3 61
|
||||
+#define GPOUT_SYS_SDIO1_DATA4 63
|
||||
+#define GPOUT_SYS_SDIO1_DATA5 63
|
||||
+#define GPOUT_SYS_SDIO1_DATA6 64
|
||||
+#define GPOUT_SYS_SDIO1_DATA7 65
|
||||
+#define GPOUT_SYS_SDIO1_RST 66
|
||||
+#define GPOUT_SYS_UART1_RTS 67
|
||||
+#define GPOUT_SYS_UART1_TX 68
|
||||
+#define GPOUT_SYS_I2STX1_SDO0 69
|
||||
+#define GPOUT_SYS_I2STX1_SDO1 70
|
||||
+#define GPOUT_SYS_I2STX1_SDO2 71
|
||||
+#define GPOUT_SYS_I2STX1_SDO3 72
|
||||
+#define GPOUT_SYS_SPI1_CLK 73
|
||||
+#define GPOUT_SYS_SPI1_FSS 74
|
||||
+#define GPOUT_SYS_SPI1_TXD 75
|
||||
+#define GPOUT_SYS_I2C2_CLK 76
|
||||
+#define GPOUT_SYS_I2C2_DATA 77
|
||||
+#define GPOUT_SYS_UART2_RTS 78
|
||||
+#define GPOUT_SYS_UART2_TX 79
|
||||
+#define GPOUT_SYS_SPI2_CLK 80
|
||||
+#define GPOUT_SYS_SPI2_FSS 81
|
||||
+#define GPOUT_SYS_SPI2_TXD 82
|
||||
+#define GPOUT_SYS_I2C3_CLK 83
|
||||
+#define GPOUT_SYS_I2C3_DATA 84
|
||||
+#define GPOUT_SYS_UART3_TX 85
|
||||
+#define GPOUT_SYS_SPI3_CLK 86
|
||||
+#define GPOUT_SYS_SPI3_FSS 87
|
||||
+#define GPOUT_SYS_SPI3_TXD 88
|
||||
+#define GPOUT_SYS_I2C4_CLK 89
|
||||
+#define GPOUT_SYS_I2C4_DATA 90
|
||||
+#define GPOUT_SYS_UART4_RTS 91
|
||||
+#define GPOUT_SYS_UART4_TX 92
|
||||
+#define GPOUT_SYS_SPI4_CLK 93
|
||||
+#define GPOUT_SYS_SPI4_FSS 94
|
||||
+#define GPOUT_SYS_SPI4_TXD 95
|
||||
+#define GPOUT_SYS_I2C5_CLK 96
|
||||
+#define GPOUT_SYS_I2C5_DATA 97
|
||||
+#define GPOUT_SYS_UART5_RTS 98
|
||||
+#define GPOUT_SYS_UART5_TX 99
|
||||
+#define GPOUT_SYS_SPI5_CLK 100
|
||||
+#define GPOUT_SYS_SPI5_FSS 101
|
||||
+#define GPOUT_SYS_SPI5_TXD 102
|
||||
+#define GPOUT_SYS_I2C6_CLK 103
|
||||
+#define GPOUT_SYS_I2C6_DATA 104
|
||||
+#define GPOUT_SYS_SPI6_CLK 105
|
||||
+#define GPOUT_SYS_SPI6_FSS 106
|
||||
+#define GPOUT_SYS_SPI6_TXD 107
|
||||
+
|
||||
+/* aon_iomux dout */
|
||||
+#define GPOUT_AON_CLK_32K_OUT 2
|
||||
+#define GPOUT_AON_PTC0_PWM4 3
|
||||
+#define GPOUT_AON_PTC0_PWM5 4
|
||||
+#define GPOUT_AON_PTC0_PWM6 5
|
||||
+#define GPOUT_AON_PTC0_PWM7 6
|
||||
+#define GPOUT_AON_CLK_GCLK0 7
|
||||
+#define GPOUT_AON_CLK_GCLK1 8
|
||||
+#define GPOUT_AON_CLK_GCLK2 9
|
||||
+
|
||||
+/* sys_iomux doen */
|
||||
+#define GPOEN_ENABLE 0
|
||||
+#define GPOEN_DISABLE 1
|
||||
+#define GPOEN_SYS_HDMI_CEC_SDA 2
|
||||
+#define GPOEN_SYS_HDMI_DDC_SCL 3
|
||||
+#define GPOEN_SYS_HDMI_DDC_SDA 4
|
||||
+#define GPOEN_SYS_I2C0_CLK 5
|
||||
+#define GPOEN_SYS_I2C0_DATA 6
|
||||
+#define GPOEN_SYS_HIFI4_JTAG_TDO 7
|
||||
+#define GPOEN_SYS_JTAG_TDO 8
|
||||
+#define GPOEN_SYS_PWM0_CHANNEL0 9
|
||||
+#define GPOEN_SYS_PWM0_CHANNEL1 10
|
||||
+#define GPOEN_SYS_PWM0_CHANNEL2 11
|
||||
+#define GPOEN_SYS_PWM0_CHANNEL3 12
|
||||
+#define GPOEN_SYS_SPI0_NSSPCTL 13
|
||||
+#define GPOEN_SYS_SPI0_NSSP 14
|
||||
+#define GPOEN_SYS_TDM_SYNC 15
|
||||
+#define GPOEN_SYS_TDM_TXD 16
|
||||
+#define GPOEN_SYS_I2C1_CLK 17
|
||||
+#define GPOEN_SYS_I2C1_DATA 18
|
||||
+#define GPOEN_SYS_SDIO1_CMD 19
|
||||
+#define GPOEN_SYS_SDIO1_DATA0 20
|
||||
+#define GPOEN_SYS_SDIO1_DATA1 21
|
||||
+#define GPOEN_SYS_SDIO1_DATA2 22
|
||||
+#define GPOEN_SYS_SDIO1_DATA3 23
|
||||
+#define GPOEN_SYS_SDIO1_DATA4 24
|
||||
+#define GPOEN_SYS_SDIO1_DATA5 25
|
||||
+#define GPOEN_SYS_SDIO1_DATA6 26
|
||||
+#define GPOEN_SYS_SDIO1_DATA7 27
|
||||
+#define GPOEN_SYS_SPI1_NSSPCTL 28
|
||||
+#define GPOEN_SYS_SPI1_NSSP 29
|
||||
+#define GPOEN_SYS_I2C2_CLK 30
|
||||
+#define GPOEN_SYS_I2C2_DATA 31
|
||||
+#define GPOEN_SYS_SPI2_NSSPCTL 32
|
||||
+#define GPOEN_SYS_SPI2_NSSP 33
|
||||
+#define GPOEN_SYS_I2C3_CLK 34
|
||||
+#define GPOEN_SYS_I2C3_DATA 35
|
||||
+#define GPOEN_SYS_SPI3_NSSPCTL 36
|
||||
+#define GPOEN_SYS_SPI3_NSSP 37
|
||||
+#define GPOEN_SYS_I2C4_CLK 38
|
||||
+#define GPOEN_SYS_I2C4_DATA 39
|
||||
+#define GPOEN_SYS_SPI4_NSSPCTL 40
|
||||
+#define GPOEN_SYS_SPI4_NSSP 41
|
||||
+#define GPOEN_SYS_I2C5_CLK 42
|
||||
+#define GPOEN_SYS_I2C5_DATA 43
|
||||
+#define GPOEN_SYS_SPI5_NSSPCTL 44
|
||||
+#define GPOEN_SYS_SPI5_NSSP 45
|
||||
+#define GPOEN_SYS_I2C6_CLK 46
|
||||
+#define GPOEN_SYS_I2C6_DATA 47
|
||||
+#define GPOEN_SYS_SPI6_NSSPCTL 48
|
||||
+#define GPOEN_SYS_SPI6_NSSP 49
|
||||
+
|
||||
+/* aon_iomux doen */
|
||||
+#define GPOEN_AON_PTC0_OE_N_4 2
|
||||
+#define GPOEN_AON_PTC0_OE_N_5 3
|
||||
+#define GPOEN_AON_PTC0_OE_N_6 4
|
||||
+#define GPOEN_AON_PTC0_OE_N_7 5
|
||||
+
|
||||
+/* sys_iomux gin */
|
||||
+#define GPI_NONE 255
|
||||
+
|
||||
+#define GPI_SYS_WAVE511_UART_RX 0
|
||||
+#define GPI_SYS_CAN0_RXD 1
|
||||
+#define GPI_SYS_USB_OVERCURRENT 2
|
||||
+#define GPI_SYS_SPDIF 3
|
||||
+#define GPI_SYS_JTAG_RST 4
|
||||
+#define GPI_SYS_HDMI_CEC_SDA 5
|
||||
+#define GPI_SYS_HDMI_DDC_SCL 6
|
||||
+#define GPI_SYS_HDMI_DDC_SDA 7
|
||||
+#define GPI_SYS_HDMI_HPD 8
|
||||
+#define GPI_SYS_I2C0_CLK 9
|
||||
+#define GPI_SYS_I2C0_DATA 10
|
||||
+#define GPI_SYS_SDIO0_CD 11
|
||||
+#define GPI_SYS_SDIO0_INT 12
|
||||
+#define GPI_SYS_SDIO0_WP 13
|
||||
+#define GPI_SYS_UART0_RX 14
|
||||
+#define GPI_SYS_HIFI4_JTAG_TCK 15
|
||||
+#define GPI_SYS_HIFI4_JTAG_TDI 16
|
||||
+#define GPI_SYS_HIFI4_JTAG_TMS 17
|
||||
+#define GPI_SYS_HIFI4_JTAG_RST 18
|
||||
+#define GPI_SYS_JTAG_TDI 19
|
||||
+#define GPI_SYS_JTAG_TMS 20
|
||||
+#define GPI_SYS_PDM_DMIC0 21
|
||||
+#define GPI_SYS_PDM_DMIC1 22
|
||||
+#define GPI_SYS_I2SRX_SDIN0 23
|
||||
+#define GPI_SYS_I2SRX_SDIN1 24
|
||||
+#define GPI_SYS_I2SRX_SDIN2 25
|
||||
+#define GPI_SYS_SPI0_CLK 26
|
||||
+#define GPI_SYS_SPI0_FSS 27
|
||||
+#define GPI_SYS_SPI0_RXD 28
|
||||
+#define GPI_SYS_JTAG_TCK 29
|
||||
+#define GPI_SYS_MCLK_EXT 30
|
||||
+#define GPI_SYS_I2SRX_BCLK 31
|
||||
+#define GPI_SYS_I2SRX_LRCK 32
|
||||
+#define GPI_SYS_I2STX0_BCLK 33
|
||||
+#define GPI_SYS_I2STX0_LRCK 34
|
||||
+#define GPI_SYS_TDM_CLK 35
|
||||
+#define GPI_SYS_TDM_RXD 36
|
||||
+#define GPI_SYS_TDM_SYNC 37
|
||||
+#define GPI_SYS_CAN1_RXD 38
|
||||
+#define GPI_SYS_I2C1_CLK 39
|
||||
+#define GPI_SYS_I2C1_DATA 40
|
||||
+#define GPI_SYS_SDIO1_CD 41
|
||||
+#define GPI_SYS_SDIO1_INT 42
|
||||
+#define GPI_SYS_SDIO1_WP 43
|
||||
+#define GPI_SYS_SDIO1_CMD 44
|
||||
+#define GPI_SYS_SDIO1_DATA0 45
|
||||
+#define GPI_SYS_SDIO1_DATA1 46
|
||||
+#define GPI_SYS_SDIO1_DATA2 47
|
||||
+#define GPI_SYS_SDIO1_DATA3 48
|
||||
+#define GPI_SYS_SDIO1_DATA4 49
|
||||
+#define GPI_SYS_SDIO1_DATA5 50
|
||||
+#define GPI_SYS_SDIO1_DATA6 51
|
||||
+#define GPI_SYS_SDIO1_DATA7 52
|
||||
+#define GPI_SYS_SDIO1_STRB 53
|
||||
+#define GPI_SYS_UART1_CTS 54
|
||||
+#define GPI_SYS_UART1_RX 55
|
||||
+#define GPI_SYS_SPI1_CLK 56
|
||||
+#define GPI_SYS_SPI1_FSS 57
|
||||
+#define GPI_SYS_SPI1_RXD 58
|
||||
+#define GPI_SYS_I2C2_CLK 59
|
||||
+#define GPI_SYS_I2C2_DATA 60
|
||||
+#define GPI_SYS_UART2_CTS 61
|
||||
+#define GPI_SYS_UART2_RX 62
|
||||
+#define GPI_SYS_SPI2_CLK 63
|
||||
+#define GPI_SYS_SPI2_FSS 64
|
||||
+#define GPI_SYS_SPI2_RXD 65
|
||||
+#define GPI_SYS_I2C3_CLK 66
|
||||
+#define GPI_SYS_I2C3_DATA 67
|
||||
+#define GPI_SYS_UART3_RX 68
|
||||
+#define GPI_SYS_SPI3_CLK 69
|
||||
+#define GPI_SYS_SPI3_FSS 70
|
||||
+#define GPI_SYS_SPI3_RXD 71
|
||||
+#define GPI_SYS_I2C4_CLK 72
|
||||
+#define GPI_SYS_I2C4_DATA 73
|
||||
+#define GPI_SYS_UART4_CTS 74
|
||||
+#define GPI_SYS_UART4_RX 75
|
||||
+#define GPI_SYS_SPI4_CLK 76
|
||||
+#define GPI_SYS_SPI4_FSS 77
|
||||
+#define GPI_SYS_SPI4_RXD 78
|
||||
+#define GPI_SYS_I2C5_CLK 79
|
||||
+#define GPI_SYS_I2C5_DATA 80
|
||||
+#define GPI_SYS_UART5_CTS 81
|
||||
+#define GPI_SYS_UART5_RX 82
|
||||
+#define GPI_SYS_SPI5_CLK 83
|
||||
+#define GPI_SYS_SPI5_FSS 84
|
||||
+#define GPI_SYS_SPI5_RXD 85
|
||||
+#define GPI_SYS_I2C6_CLK 86
|
||||
+#define GPI_SYS_I2C6_DATA 87
|
||||
+#define GPI_SYS_SPI6_CLK 88
|
||||
+#define GPI_SYS_SPI6_FSS 89
|
||||
+#define GPI_SYS_SPI6_RXD 90
|
||||
+
|
||||
+/* aon_iomux gin */
|
||||
+#define GPI_AON_PMU_GPIO_WAKEUP_0 0
|
||||
+#define GPI_AON_PMU_GPIO_WAKEUP_1 1
|
||||
+#define GPI_AON_PMU_GPIO_WAKEUP_2 2
|
||||
+#define GPI_AON_PMU_GPIO_WAKEUP_3 3
|
||||
+
|
||||
+#endif
|
@ -0,0 +1,290 @@
|
||||
From 76bc84c399f11c7d6a37fe68cbd5f182e4c18369 Mon Sep 17 00:00:00 2001
|
||||
From: Emil Renner Berthing <kernel@esmil.dk>
|
||||
Date: Sat, 1 Apr 2023 19:19:33 +0800
|
||||
Subject: [PATCH 023/122] riscv: dts: starfive: Add StarFive JH7110 VisionFive
|
||||
2 board device tree
|
||||
|
||||
Add a minimal device tree for StarFive JH7110 VisionFive 2 board
|
||||
which has version A and version B. Support booting and basic
|
||||
clock/reset/pinctrl/uart drivers.
|
||||
|
||||
Tested-by: Tommaso Merciai <tomm.merciai@gmail.com>
|
||||
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
|
||||
Acked-by: Conor Dooley <conor.dooley@microchip.com>
|
||||
Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
|
||||
Co-developed-by: Jianlong Huang <jianlong.huang@starfivetech.com>
|
||||
Signed-off-by: Jianlong Huang <jianlong.huang@starfivetech.com>
|
||||
Co-developed-by: Hal Feng <hal.feng@starfivetech.com>
|
||||
Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
|
||||
Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
|
||||
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
|
||||
---
|
||||
arch/riscv/boot/dts/starfive/Makefile | 6 +-
|
||||
.../jh7110-starfive-visionfive-2-v1.2a.dts | 13 ++
|
||||
.../jh7110-starfive-visionfive-2-v1.3b.dts | 13 ++
|
||||
.../jh7110-starfive-visionfive-2.dtsi | 215 ++++++++++++++++++
|
||||
4 files changed, 246 insertions(+), 1 deletion(-)
|
||||
create mode 100644 arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-v1.2a.dts
|
||||
create mode 100644 arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-v1.3b.dts
|
||||
create mode 100644 arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
|
||||
|
||||
--- a/arch/riscv/boot/dts/starfive/Makefile
|
||||
+++ b/arch/riscv/boot/dts/starfive/Makefile
|
||||
@@ -1,2 +1,6 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
-dtb-$(CONFIG_SOC_STARFIVE) += jh7100-beaglev-starlight.dtb
|
||||
+dtb-$(CONFIG_ARCH_STARFIVE) += jh7100-beaglev-starlight.dtb
|
||||
+dtb-$(CONFIG_ARCH_STARFIVE) += jh7100-starfive-visionfive-v1.dtb
|
||||
+
|
||||
+dtb-$(CONFIG_ARCH_STARFIVE) += jh7110-starfive-visionfive-2-v1.2a.dtb
|
||||
+dtb-$(CONFIG_ARCH_STARFIVE) += jh7110-starfive-visionfive-2-v1.3b.dtb
|
||||
--- /dev/null
|
||||
+++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-v1.2a.dts
|
||||
@@ -0,0 +1,13 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0 OR MIT
|
||||
+/*
|
||||
+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
|
||||
+ * Copyright (C) 2022 Emil Renner Berthing <kernel@esmil.dk>
|
||||
+ */
|
||||
+
|
||||
+/dts-v1/;
|
||||
+#include "jh7110-starfive-visionfive-2.dtsi"
|
||||
+
|
||||
+/ {
|
||||
+ model = "StarFive VisionFive 2 v1.2A";
|
||||
+ compatible = "starfive,visionfive-2-v1.2a", "starfive,jh7110";
|
||||
+};
|
||||
--- /dev/null
|
||||
+++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-v1.3b.dts
|
||||
@@ -0,0 +1,13 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0 OR MIT
|
||||
+/*
|
||||
+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
|
||||
+ * Copyright (C) 2022 Emil Renner Berthing <kernel@esmil.dk>
|
||||
+ */
|
||||
+
|
||||
+/dts-v1/;
|
||||
+#include "jh7110-starfive-visionfive-2.dtsi"
|
||||
+
|
||||
+/ {
|
||||
+ model = "StarFive VisionFive 2 v1.3B";
|
||||
+ compatible = "starfive,visionfive-2-v1.3b", "starfive,jh7110";
|
||||
+};
|
||||
--- /dev/null
|
||||
+++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
|
||||
@@ -0,0 +1,215 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0 OR MIT
|
||||
+/*
|
||||
+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
|
||||
+ * Copyright (C) 2022 Emil Renner Berthing <kernel@esmil.dk>
|
||||
+ */
|
||||
+
|
||||
+/dts-v1/;
|
||||
+#include "jh7110.dtsi"
|
||||
+#include "jh7110-pinfunc.h"
|
||||
+#include <dt-bindings/gpio/gpio.h>
|
||||
+
|
||||
+/ {
|
||||
+ aliases {
|
||||
+ i2c0 = &i2c0;
|
||||
+ i2c2 = &i2c2;
|
||||
+ i2c5 = &i2c5;
|
||||
+ i2c6 = &i2c6;
|
||||
+ serial0 = &uart0;
|
||||
+ };
|
||||
+
|
||||
+ chosen {
|
||||
+ stdout-path = "serial0:115200n8";
|
||||
+ };
|
||||
+
|
||||
+ cpus {
|
||||
+ timebase-frequency = <4000000>;
|
||||
+ };
|
||||
+
|
||||
+ memory@40000000 {
|
||||
+ device_type = "memory";
|
||||
+ reg = <0x0 0x40000000 0x1 0x0>;
|
||||
+ };
|
||||
+
|
||||
+ gpio-restart {
|
||||
+ compatible = "gpio-restart";
|
||||
+ gpios = <&sysgpio 35 GPIO_ACTIVE_HIGH>;
|
||||
+ priority = <224>;
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&gmac0_rgmii_rxin {
|
||||
+ clock-frequency = <125000000>;
|
||||
+};
|
||||
+
|
||||
+&gmac0_rmii_refin {
|
||||
+ clock-frequency = <50000000>;
|
||||
+};
|
||||
+
|
||||
+&gmac1_rgmii_rxin {
|
||||
+ clock-frequency = <125000000>;
|
||||
+};
|
||||
+
|
||||
+&gmac1_rmii_refin {
|
||||
+ clock-frequency = <50000000>;
|
||||
+};
|
||||
+
|
||||
+&i2srx_bclk_ext {
|
||||
+ clock-frequency = <12288000>;
|
||||
+};
|
||||
+
|
||||
+&i2srx_lrck_ext {
|
||||
+ clock-frequency = <192000>;
|
||||
+};
|
||||
+
|
||||
+&i2stx_bclk_ext {
|
||||
+ clock-frequency = <12288000>;
|
||||
+};
|
||||
+
|
||||
+&i2stx_lrck_ext {
|
||||
+ clock-frequency = <192000>;
|
||||
+};
|
||||
+
|
||||
+&mclk_ext {
|
||||
+ clock-frequency = <12288000>;
|
||||
+};
|
||||
+
|
||||
+&osc {
|
||||
+ clock-frequency = <24000000>;
|
||||
+};
|
||||
+
|
||||
+&rtc_osc {
|
||||
+ clock-frequency = <32768>;
|
||||
+};
|
||||
+
|
||||
+&tdm_ext {
|
||||
+ clock-frequency = <49152000>;
|
||||
+};
|
||||
+
|
||||
+&i2c0 {
|
||||
+ clock-frequency = <100000>;
|
||||
+ i2c-sda-hold-time-ns = <300>;
|
||||
+ i2c-sda-falling-time-ns = <510>;
|
||||
+ i2c-scl-falling-time-ns = <510>;
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&i2c0_pins>;
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&i2c2 {
|
||||
+ clock-frequency = <100000>;
|
||||
+ i2c-sda-hold-time-ns = <300>;
|
||||
+ i2c-sda-falling-time-ns = <510>;
|
||||
+ i2c-scl-falling-time-ns = <510>;
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&i2c2_pins>;
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&i2c5 {
|
||||
+ clock-frequency = <100000>;
|
||||
+ i2c-sda-hold-time-ns = <300>;
|
||||
+ i2c-sda-falling-time-ns = <510>;
|
||||
+ i2c-scl-falling-time-ns = <510>;
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&i2c5_pins>;
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&i2c6 {
|
||||
+ clock-frequency = <100000>;
|
||||
+ i2c-sda-hold-time-ns = <300>;
|
||||
+ i2c-sda-falling-time-ns = <510>;
|
||||
+ i2c-scl-falling-time-ns = <510>;
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&i2c6_pins>;
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&sysgpio {
|
||||
+ i2c0_pins: i2c0-0 {
|
||||
+ i2c-pins {
|
||||
+ pinmux = <GPIOMUX(57, GPOUT_LOW,
|
||||
+ GPOEN_SYS_I2C0_CLK,
|
||||
+ GPI_SYS_I2C0_CLK)>,
|
||||
+ <GPIOMUX(58, GPOUT_LOW,
|
||||
+ GPOEN_SYS_I2C0_DATA,
|
||||
+ GPI_SYS_I2C0_DATA)>;
|
||||
+ bias-disable; /* external pull-up */
|
||||
+ input-enable;
|
||||
+ input-schmitt-enable;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ i2c2_pins: i2c2-0 {
|
||||
+ i2c-pins {
|
||||
+ pinmux = <GPIOMUX(3, GPOUT_LOW,
|
||||
+ GPOEN_SYS_I2C2_CLK,
|
||||
+ GPI_SYS_I2C2_CLK)>,
|
||||
+ <GPIOMUX(2, GPOUT_LOW,
|
||||
+ GPOEN_SYS_I2C2_DATA,
|
||||
+ GPI_SYS_I2C2_DATA)>;
|
||||
+ bias-disable; /* external pull-up */
|
||||
+ input-enable;
|
||||
+ input-schmitt-enable;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ i2c5_pins: i2c5-0 {
|
||||
+ i2c-pins {
|
||||
+ pinmux = <GPIOMUX(19, GPOUT_LOW,
|
||||
+ GPOEN_SYS_I2C5_CLK,
|
||||
+ GPI_SYS_I2C5_CLK)>,
|
||||
+ <GPIOMUX(20, GPOUT_LOW,
|
||||
+ GPOEN_SYS_I2C5_DATA,
|
||||
+ GPI_SYS_I2C5_DATA)>;
|
||||
+ bias-disable; /* external pull-up */
|
||||
+ input-enable;
|
||||
+ input-schmitt-enable;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ i2c6_pins: i2c6-0 {
|
||||
+ i2c-pins {
|
||||
+ pinmux = <GPIOMUX(16, GPOUT_LOW,
|
||||
+ GPOEN_SYS_I2C6_CLK,
|
||||
+ GPI_SYS_I2C6_CLK)>,
|
||||
+ <GPIOMUX(17, GPOUT_LOW,
|
||||
+ GPOEN_SYS_I2C6_DATA,
|
||||
+ GPI_SYS_I2C6_DATA)>;
|
||||
+ bias-disable; /* external pull-up */
|
||||
+ input-enable;
|
||||
+ input-schmitt-enable;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ uart0_pins: uart0-0 {
|
||||
+ tx-pins {
|
||||
+ pinmux = <GPIOMUX(5, GPOUT_SYS_UART0_TX,
|
||||
+ GPOEN_ENABLE,
|
||||
+ GPI_NONE)>;
|
||||
+ bias-disable;
|
||||
+ drive-strength = <12>;
|
||||
+ input-disable;
|
||||
+ input-schmitt-disable;
|
||||
+ slew-rate = <0>;
|
||||
+ };
|
||||
+
|
||||
+ rx-pins {
|
||||
+ pinmux = <GPIOMUX(6, GPOUT_LOW,
|
||||
+ GPOEN_DISABLE,
|
||||
+ GPI_SYS_UART0_RX)>;
|
||||
+ bias-disable; /* external pull-up */
|
||||
+ drive-strength = <2>;
|
||||
+ input-enable;
|
||||
+ input-schmitt-enable;
|
||||
+ slew-rate = <0>;
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&uart0 {
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&uart0_pins>;
|
||||
+ status = "okay";
|
||||
+};
|
@ -0,0 +1,43 @@
|
||||
From cbb348ddbc68fe4fc8ac80bed11c298149e7893f Mon Sep 17 00:00:00 2001
|
||||
From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
|
||||
Date: Tue, 18 Oct 2022 00:05:42 +0300
|
||||
Subject: [PATCH 024/122] riscv: dts: starfive: Add StarFive VisionFive V1
|
||||
device tree
|
||||
|
||||
Add initial device tree for the StarFive VisionFive V1 SBC, which
|
||||
is similar with the already supported BeagleV Starlight Beta board,
|
||||
both being based on the StarFive JH7100 SoC.
|
||||
|
||||
Link: https://github.com/starfive-tech/VisionFive
|
||||
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
|
||||
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
|
||||
Reviewed-by: Matthias Brugger <mbrugger@suse.com>
|
||||
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
|
||||
---
|
||||
.../jh7100-starfive-visionfive-v1.dts | 20 +++++++++++++++++++
|
||||
1 file changed, 20 insertions(+)
|
||||
create mode 100644 arch/riscv/boot/dts/starfive/jh7100-starfive-visionfive-v1.dts
|
||||
|
||||
--- /dev/null
|
||||
+++ b/arch/riscv/boot/dts/starfive/jh7100-starfive-visionfive-v1.dts
|
||||
@@ -0,0 +1,20 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0 OR MIT
|
||||
+/*
|
||||
+ * Copyright (C) 2021 StarFive Technology Co., Ltd.
|
||||
+ * Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
|
||||
+ */
|
||||
+
|
||||
+/dts-v1/;
|
||||
+#include "jh7100-common.dtsi"
|
||||
+#include <dt-bindings/gpio/gpio.h>
|
||||
+
|
||||
+/ {
|
||||
+ model = "StarFive VisionFive V1";
|
||||
+ compatible = "starfive,visionfive-v1", "starfive,jh7100";
|
||||
+
|
||||
+ gpio-restart {
|
||||
+ compatible = "gpio-restart";
|
||||
+ gpios = <&gpio 63 GPIO_ACTIVE_HIGH>;
|
||||
+ priority = <224>;
|
||||
+ };
|
||||
+};
|
@ -0,0 +1,349 @@
|
||||
From 2101233d71b74e33de33e4cc292c6a8cf5da9d42 Mon Sep 17 00:00:00 2001
|
||||
From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
|
||||
Date: Tue, 18 Oct 2022 00:05:41 +0300
|
||||
Subject: [PATCH 025/122] riscv: dts: starfive: Add common DT for JH7100 based
|
||||
boards
|
||||
|
||||
In preparation for adding initial device tree support for the StarFive
|
||||
VisionFive board, which is similar with BeagleV Starlight, move most
|
||||
of the content from jh7100-beaglev-starlight.dts to a new file, to be
|
||||
shared between the two boards.
|
||||
|
||||
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
|
||||
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
|
||||
Reviewed-by: Matthias Brugger <mbrugger@suse.com>
|
||||
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
|
||||
---
|
||||
.../dts/starfive/jh7100-beaglev-starlight.dts | 153 +----------------
|
||||
.../boot/dts/starfive/jh7100-common.dtsi | 161 ++++++++++++++++++
|
||||
2 files changed, 162 insertions(+), 152 deletions(-)
|
||||
create mode 100644 arch/riscv/boot/dts/starfive/jh7100-common.dtsi
|
||||
|
||||
--- a/arch/riscv/boot/dts/starfive/jh7100-beaglev-starlight.dts
|
||||
+++ b/arch/riscv/boot/dts/starfive/jh7100-beaglev-starlight.dts
|
||||
@@ -5,160 +5,9 @@
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
-#include "jh7100.dtsi"
|
||||
-#include <dt-bindings/gpio/gpio.h>
|
||||
-#include <dt-bindings/leds/common.h>
|
||||
-#include <dt-bindings/pinctrl/pinctrl-starfive-jh7100.h>
|
||||
+#include "jh7100-common.dtsi"
|
||||
|
||||
/ {
|
||||
model = "BeagleV Starlight Beta";
|
||||
compatible = "beagle,beaglev-starlight-jh7100-r0", "starfive,jh7100";
|
||||
-
|
||||
- aliases {
|
||||
- serial0 = &uart3;
|
||||
- };
|
||||
-
|
||||
- chosen {
|
||||
- stdout-path = "serial0:115200n8";
|
||||
- };
|
||||
-
|
||||
- cpus {
|
||||
- timebase-frequency = <6250000>;
|
||||
- };
|
||||
-
|
||||
- memory@80000000 {
|
||||
- device_type = "memory";
|
||||
- reg = <0x0 0x80000000 0x2 0x0>;
|
||||
- };
|
||||
-
|
||||
- leds {
|
||||
- compatible = "gpio-leds";
|
||||
-
|
||||
- led-ack {
|
||||
- gpios = <&gpio 43 GPIO_ACTIVE_HIGH>;
|
||||
- color = <LED_COLOR_ID_GREEN>;
|
||||
- function = LED_FUNCTION_HEARTBEAT;
|
||||
- linux,default-trigger = "heartbeat";
|
||||
- label = "ack";
|
||||
- };
|
||||
- };
|
||||
-};
|
||||
-
|
||||
-&gpio {
|
||||
- i2c0_pins: i2c0-0 {
|
||||
- i2c-pins {
|
||||
- pinmux = <GPIOMUX(62, GPO_LOW,
|
||||
- GPO_I2C0_PAD_SCK_OEN,
|
||||
- GPI_I2C0_PAD_SCK_IN)>,
|
||||
- <GPIOMUX(61, GPO_LOW,
|
||||
- GPO_I2C0_PAD_SDA_OEN,
|
||||
- GPI_I2C0_PAD_SDA_IN)>;
|
||||
- bias-disable; /* external pull-up */
|
||||
- input-enable;
|
||||
- input-schmitt-enable;
|
||||
- };
|
||||
- };
|
||||
-
|
||||
- i2c1_pins: i2c1-0 {
|
||||
- i2c-pins {
|
||||
- pinmux = <GPIOMUX(47, GPO_LOW,
|
||||
- GPO_I2C1_PAD_SCK_OEN,
|
||||
- GPI_I2C1_PAD_SCK_IN)>,
|
||||
- <GPIOMUX(48, GPO_LOW,
|
||||
- GPO_I2C1_PAD_SDA_OEN,
|
||||
- GPI_I2C1_PAD_SDA_IN)>;
|
||||
- bias-pull-up;
|
||||
- input-enable;
|
||||
- input-schmitt-enable;
|
||||
- };
|
||||
- };
|
||||
-
|
||||
- i2c2_pins: i2c2-0 {
|
||||
- i2c-pins {
|
||||
- pinmux = <GPIOMUX(60, GPO_LOW,
|
||||
- GPO_I2C2_PAD_SCK_OEN,
|
||||
- GPI_I2C2_PAD_SCK_IN)>,
|
||||
- <GPIOMUX(59, GPO_LOW,
|
||||
- GPO_I2C2_PAD_SDA_OEN,
|
||||
- GPI_I2C2_PAD_SDA_IN)>;
|
||||
- bias-disable; /* external pull-up */
|
||||
- input-enable;
|
||||
- input-schmitt-enable;
|
||||
- };
|
||||
- };
|
||||
-
|
||||
- uart3_pins: uart3-0 {
|
||||
- rx-pins {
|
||||
- pinmux = <GPIOMUX(13, GPO_LOW, GPO_DISABLE,
|
||||
- GPI_UART3_PAD_SIN)>;
|
||||
- bias-pull-up;
|
||||
- drive-strength = <14>;
|
||||
- input-enable;
|
||||
- input-schmitt-enable;
|
||||
- slew-rate = <0>;
|
||||
- };
|
||||
- tx-pins {
|
||||
- pinmux = <GPIOMUX(14, GPO_UART3_PAD_SOUT,
|
||||
- GPO_ENABLE, GPI_NONE)>;
|
||||
- bias-disable;
|
||||
- drive-strength = <35>;
|
||||
- input-disable;
|
||||
- input-schmitt-disable;
|
||||
- slew-rate = <0>;
|
||||
- };
|
||||
- };
|
||||
-};
|
||||
-
|
||||
-&i2c0 {
|
||||
- clock-frequency = <100000>;
|
||||
- i2c-sda-hold-time-ns = <300>;
|
||||
- i2c-sda-falling-time-ns = <500>;
|
||||
- i2c-scl-falling-time-ns = <500>;
|
||||
- pinctrl-names = "default";
|
||||
- pinctrl-0 = <&i2c0_pins>;
|
||||
- status = "okay";
|
||||
-
|
||||
- pmic@5e {
|
||||
- compatible = "ti,tps65086";
|
||||
- reg = <0x5e>;
|
||||
- gpio-controller;
|
||||
- #gpio-cells = <2>;
|
||||
-
|
||||
- regulators {
|
||||
- };
|
||||
- };
|
||||
-};
|
||||
-
|
||||
-&i2c1 {
|
||||
- clock-frequency = <400000>;
|
||||
- i2c-sda-hold-time-ns = <300>;
|
||||
- i2c-sda-falling-time-ns = <100>;
|
||||
- i2c-scl-falling-time-ns = <100>;
|
||||
- pinctrl-names = "default";
|
||||
- pinctrl-0 = <&i2c1_pins>;
|
||||
- status = "okay";
|
||||
-};
|
||||
-
|
||||
-&i2c2 {
|
||||
- clock-frequency = <100000>;
|
||||
- i2c-sda-hold-time-ns = <300>;
|
||||
- i2c-sda-falling-time-ns = <500>;
|
||||
- i2c-scl-falling-time-ns = <500>;
|
||||
- pinctrl-names = "default";
|
||||
- pinctrl-0 = <&i2c2_pins>;
|
||||
- status = "okay";
|
||||
-};
|
||||
-
|
||||
-&osc_sys {
|
||||
- clock-frequency = <25000000>;
|
||||
-};
|
||||
-
|
||||
-&osc_aud {
|
||||
- clock-frequency = <27000000>;
|
||||
-};
|
||||
-
|
||||
-&uart3 {
|
||||
- pinctrl-names = "default";
|
||||
- pinctrl-0 = <&uart3_pins>;
|
||||
- status = "okay";
|
||||
};
|
||||
--- /dev/null
|
||||
+++ b/arch/riscv/boot/dts/starfive/jh7100-common.dtsi
|
||||
@@ -0,0 +1,161 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0 OR MIT
|
||||
+/*
|
||||
+ * Copyright (C) 2021 StarFive Technology Co., Ltd.
|
||||
+ * Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
|
||||
+ */
|
||||
+
|
||||
+/dts-v1/;
|
||||
+#include "jh7100.dtsi"
|
||||
+#include <dt-bindings/gpio/gpio.h>
|
||||
+#include <dt-bindings/leds/common.h>
|
||||
+#include <dt-bindings/pinctrl/pinctrl-starfive-jh7100.h>
|
||||
+
|
||||
+/ {
|
||||
+ aliases {
|
||||
+ serial0 = &uart3;
|
||||
+ };
|
||||
+
|
||||
+ chosen {
|
||||
+ stdout-path = "serial0:115200n8";
|
||||
+ };
|
||||
+
|
||||
+ cpus {
|
||||
+ timebase-frequency = <6250000>;
|
||||
+ };
|
||||
+
|
||||
+ memory@80000000 {
|
||||
+ device_type = "memory";
|
||||
+ reg = <0x0 0x80000000 0x2 0x0>;
|
||||
+ };
|
||||
+
|
||||
+ leds {
|
||||
+ compatible = "gpio-leds";
|
||||
+
|
||||
+ led-ack {
|
||||
+ gpios = <&gpio 43 GPIO_ACTIVE_HIGH>;
|
||||
+ color = <LED_COLOR_ID_GREEN>;
|
||||
+ function = LED_FUNCTION_HEARTBEAT;
|
||||
+ linux,default-trigger = "heartbeat";
|
||||
+ label = "ack";
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&gpio {
|
||||
+ i2c0_pins: i2c0-0 {
|
||||
+ i2c-pins {
|
||||
+ pinmux = <GPIOMUX(62, GPO_LOW,
|
||||
+ GPO_I2C0_PAD_SCK_OEN,
|
||||
+ GPI_I2C0_PAD_SCK_IN)>,
|
||||
+ <GPIOMUX(61, GPO_LOW,
|
||||
+ GPO_I2C0_PAD_SDA_OEN,
|
||||
+ GPI_I2C0_PAD_SDA_IN)>;
|
||||
+ bias-disable; /* external pull-up */
|
||||
+ input-enable;
|
||||
+ input-schmitt-enable;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ i2c1_pins: i2c1-0 {
|
||||
+ i2c-pins {
|
||||
+ pinmux = <GPIOMUX(47, GPO_LOW,
|
||||
+ GPO_I2C1_PAD_SCK_OEN,
|
||||
+ GPI_I2C1_PAD_SCK_IN)>,
|
||||
+ <GPIOMUX(48, GPO_LOW,
|
||||
+ GPO_I2C1_PAD_SDA_OEN,
|
||||
+ GPI_I2C1_PAD_SDA_IN)>;
|
||||
+ bias-pull-up;
|
||||
+ input-enable;
|
||||
+ input-schmitt-enable;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ i2c2_pins: i2c2-0 {
|
||||
+ i2c-pins {
|
||||
+ pinmux = <GPIOMUX(60, GPO_LOW,
|
||||
+ GPO_I2C2_PAD_SCK_OEN,
|
||||
+ GPI_I2C2_PAD_SCK_IN)>,
|
||||
+ <GPIOMUX(59, GPO_LOW,
|
||||
+ GPO_I2C2_PAD_SDA_OEN,
|
||||
+ GPI_I2C2_PAD_SDA_IN)>;
|
||||
+ bias-disable; /* external pull-up */
|
||||
+ input-enable;
|
||||
+ input-schmitt-enable;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ uart3_pins: uart3-0 {
|
||||
+ rx-pins {
|
||||
+ pinmux = <GPIOMUX(13, GPO_LOW, GPO_DISABLE,
|
||||
+ GPI_UART3_PAD_SIN)>;
|
||||
+ bias-pull-up;
|
||||
+ drive-strength = <14>;
|
||||
+ input-enable;
|
||||
+ input-schmitt-enable;
|
||||
+ slew-rate = <0>;
|
||||
+ };
|
||||
+ tx-pins {
|
||||
+ pinmux = <GPIOMUX(14, GPO_UART3_PAD_SOUT,
|
||||
+ GPO_ENABLE, GPI_NONE)>;
|
||||
+ bias-disable;
|
||||
+ drive-strength = <35>;
|
||||
+ input-disable;
|
||||
+ input-schmitt-disable;
|
||||
+ slew-rate = <0>;
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&i2c0 {
|
||||
+ clock-frequency = <100000>;
|
||||
+ i2c-sda-hold-time-ns = <300>;
|
||||
+ i2c-sda-falling-time-ns = <500>;
|
||||
+ i2c-scl-falling-time-ns = <500>;
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&i2c0_pins>;
|
||||
+ status = "okay";
|
||||
+
|
||||
+ pmic@5e {
|
||||
+ compatible = "ti,tps65086";
|
||||
+ reg = <0x5e>;
|
||||
+ gpio-controller;
|
||||
+ #gpio-cells = <2>;
|
||||
+
|
||||
+ regulators {
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&i2c1 {
|
||||
+ clock-frequency = <400000>;
|
||||
+ i2c-sda-hold-time-ns = <300>;
|
||||
+ i2c-sda-falling-time-ns = <100>;
|
||||
+ i2c-scl-falling-time-ns = <100>;
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&i2c1_pins>;
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&i2c2 {
|
||||
+ clock-frequency = <100000>;
|
||||
+ i2c-sda-hold-time-ns = <300>;
|
||||
+ i2c-sda-falling-time-ns = <500>;
|
||||
+ i2c-scl-falling-time-ns = <500>;
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&i2c2_pins>;
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&osc_sys {
|
||||
+ clock-frequency = <25000000>;
|
||||
+};
|
||||
+
|
||||
+&osc_aud {
|
||||
+ clock-frequency = <27000000>;
|
||||
+};
|
||||
+
|
||||
+&uart3 {
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&uart3_pins>;
|
||||
+ status = "okay";
|
||||
+};
|
@ -0,0 +1,303 @@
|
||||
From 28518a9637fee6b84464beff9d4308edc3efba72 Mon Sep 17 00:00:00 2001
|
||||
From: Jianlong Huang <jianlong.huang@starfivetech.com>
|
||||
Date: Thu, 9 Feb 2023 22:36:59 +0800
|
||||
Subject: [PATCH 026/122] dt-bindings: pinctrl: Add StarFive JH7110 sys pinctrl
|
||||
|
||||
Add pinctrl bindings for StarFive JH7110 SoC sys pinctrl controller.
|
||||
|
||||
Reviewed-by: Rob Herring <robh@kernel.org>
|
||||
Signed-off-by: Jianlong Huang <jianlong.huang@starfivetech.com>
|
||||
Co-developed-by: Emil Renner Berthing <kernel@esmil.dk>
|
||||
Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
|
||||
Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
|
||||
---
|
||||
.../pinctrl/starfive,jh7110-sys-pinctrl.yaml | 142 ++++++++++++++++++
|
||||
MAINTAINERS | 6 +-
|
||||
.../pinctrl/starfive,jh7110-pinctrl.h | 115 ++++++++++++++
|
||||
3 files changed, 261 insertions(+), 2 deletions(-)
|
||||
create mode 100644 Documentation/devicetree/bindings/pinctrl/starfive,jh7110-sys-pinctrl.yaml
|
||||
create mode 100644 include/dt-bindings/pinctrl/starfive,jh7110-pinctrl.h
|
||||
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/pinctrl/starfive,jh7110-sys-pinctrl.yaml
|
||||
@@ -0,0 +1,142 @@
|
||||
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
+%YAML 1.2
|
||||
+---
|
||||
+$id: http://devicetree.org/schemas/pinctrl/starfive,jh7110-sys-pinctrl.yaml#
|
||||
+$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
+
|
||||
+title: StarFive JH7110 SYS Pin Controller
|
||||
+
|
||||
+description: |
|
||||
+ Bindings for the JH7110 RISC-V SoC from StarFive Technology Ltd.
|
||||
+
|
||||
+ Out of the SoC's many pins only the ones named PAD_GPIO0 to PAD_GPIO63
|
||||
+ can be multiplexed and have configurable bias, drive strength,
|
||||
+ schmitt trigger etc.
|
||||
+ Some peripherals have their I/O go through the 64 "GPIOs". This also
|
||||
+ includes a number of other UARTs, I2Cs, SPIs, PWMs etc.
|
||||
+ All these peripherals are connected to all 64 GPIOs such that
|
||||
+ any GPIO can be set up to be controlled by any of the peripherals.
|
||||
+
|
||||
+maintainers:
|
||||
+ - Jianlong Huang <jianlong.huang@starfivetech.com>
|
||||
+
|
||||
+properties:
|
||||
+ compatible:
|
||||
+ const: starfive,jh7110-sys-pinctrl
|
||||
+
|
||||
+ reg:
|
||||
+ maxItems: 1
|
||||
+
|
||||
+ clocks:
|
||||
+ maxItems: 1
|
||||
+
|
||||
+ resets:
|
||||
+ maxItems: 1
|
||||
+
|
||||
+ interrupts:
|
||||
+ maxItems: 1
|
||||
+
|
||||
+ interrupt-controller: true
|
||||
+
|
||||
+ '#interrupt-cells':
|
||||
+ const: 2
|
||||
+
|
||||
+ gpio-controller: true
|
||||
+
|
||||
+ '#gpio-cells':
|
||||
+ const: 2
|
||||
+
|
||||
+patternProperties:
|
||||
+ '-[0-9]+$':
|
||||
+ type: object
|
||||
+ additionalProperties: false
|
||||
+ patternProperties:
|
||||
+ '-pins$':
|
||||
+ type: object
|
||||
+ description: |
|
||||
+ A pinctrl node should contain at least one subnode representing the
|
||||
+ pinctrl groups available on the machine. Each subnode will list the
|
||||
+ pins it needs, and how they should be configured, with regard to
|
||||
+ muxer configuration, bias, input enable/disable, input schmitt
|
||||
+ trigger enable/disable, slew-rate and drive strength.
|
||||
+ allOf:
|
||||
+ - $ref: /schemas/pinctrl/pincfg-node.yaml
|
||||
+ - $ref: /schemas/pinctrl/pinmux-node.yaml
|
||||
+ additionalProperties: false
|
||||
+
|
||||
+ properties:
|
||||
+ pinmux:
|
||||
+ description: |
|
||||
+ The list of GPIOs and their mux settings that properties in the
|
||||
+ node apply to. This should be set using the GPIOMUX or PINMUX
|
||||
+ macros.
|
||||
+
|
||||
+ bias-disable: true
|
||||
+
|
||||
+ bias-pull-up:
|
||||
+ type: boolean
|
||||
+
|
||||
+ bias-pull-down:
|
||||
+ type: boolean
|
||||
+
|
||||
+ drive-strength:
|
||||
+ enum: [ 2, 4, 8, 12 ]
|
||||
+
|
||||
+ input-enable: true
|
||||
+
|
||||
+ input-disable: true
|
||||
+
|
||||
+ input-schmitt-enable: true
|
||||
+
|
||||
+ input-schmitt-disable: true
|
||||
+
|
||||
+ slew-rate:
|
||||
+ maximum: 1
|
||||
+
|
||||
+required:
|
||||
+ - compatible
|
||||
+ - reg
|
||||
+ - clocks
|
||||
+ - interrupts
|
||||
+ - interrupt-controller
|
||||
+ - '#interrupt-cells'
|
||||
+ - gpio-controller
|
||||
+ - '#gpio-cells'
|
||||
+
|
||||
+additionalProperties: false
|
||||
+
|
||||
+examples:
|
||||
+ - |
|
||||
+ pinctrl@13040000 {
|
||||
+ compatible = "starfive,jh7110-sys-pinctrl";
|
||||
+ reg = <0x13040000 0x10000>;
|
||||
+ clocks = <&syscrg 112>;
|
||||
+ resets = <&syscrg 2>;
|
||||
+ interrupts = <86>;
|
||||
+ interrupt-controller;
|
||||
+ #interrupt-cells = <2>;
|
||||
+ gpio-controller;
|
||||
+ #gpio-cells = <2>;
|
||||
+
|
||||
+ uart0-0 {
|
||||
+ tx-pins {
|
||||
+ pinmux = <0xff140005>;
|
||||
+ bias-disable;
|
||||
+ drive-strength = <12>;
|
||||
+ input-disable;
|
||||
+ input-schmitt-disable;
|
||||
+ slew-rate = <0>;
|
||||
+ };
|
||||
+
|
||||
+ rx-pins {
|
||||
+ pinmux = <0x0E000406>;
|
||||
+ bias-pull-up;
|
||||
+ drive-strength = <2>;
|
||||
+ input-enable;
|
||||
+ input-schmitt-enable;
|
||||
+ slew-rate = <0>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+...
|
||||
--- a/MAINTAINERS
|
||||
+++ b/MAINTAINERS
|
||||
@@ -19658,13 +19658,15 @@ F: Documentation/devicetree/bindings/clo
|
||||
F: drivers/clk/starfive/clk-starfive-jh71*
|
||||
F: include/dt-bindings/clock/starfive?jh71*.h
|
||||
|
||||
-STARFIVE JH7100 PINCTRL DRIVER
|
||||
+STARFIVE JH71X0 PINCTRL DRIVERS
|
||||
M: Emil Renner Berthing <kernel@esmil.dk>
|
||||
+M: Jianlong Huang <jianlong.huang@starfivetech.com>
|
||||
L: linux-gpio@vger.kernel.org
|
||||
S: Maintained
|
||||
-F: Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml
|
||||
+F: Documentation/devicetree/bindings/pinctrl/starfive,jh71*.yaml
|
||||
F: drivers/pinctrl/starfive/
|
||||
F: include/dt-bindings/pinctrl/pinctrl-starfive-jh7100.h
|
||||
+F: include/dt-bindings/pinctrl/starfive,jh7110-pinctrl.h
|
||||
|
||||
STARFIVE JH71X0 RESET CONTROLLER DRIVERS
|
||||
M: Emil Renner Berthing <kernel@esmil.dk>
|
||||
--- /dev/null
|
||||
+++ b/include/dt-bindings/pinctrl/starfive,jh7110-pinctrl.h
|
||||
@@ -0,0 +1,115 @@
|
||||
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
|
||||
+/*
|
||||
+ * Copyright (C) 2022 Emil Renner Berthing <kernel@esmil.dk>
|
||||
+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
|
||||
+ */
|
||||
+
|
||||
+#ifndef __DT_BINDINGS_PINCTRL_STARFIVE_JH7110_H__
|
||||
+#define __DT_BINDINGS_PINCTRL_STARFIVE_JH7110_H__
|
||||
+
|
||||
+/* sys_iomux pins */
|
||||
+#define PAD_GPIO0 0
|
||||
+#define PAD_GPIO1 1
|
||||
+#define PAD_GPIO2 2
|
||||
+#define PAD_GPIO3 3
|
||||
+#define PAD_GPIO4 4
|
||||
+#define PAD_GPIO5 5
|
||||
+#define PAD_GPIO6 6
|
||||
+#define PAD_GPIO7 7
|
||||
+#define PAD_GPIO8 8
|
||||
+#define PAD_GPIO9 9
|
||||
+#define PAD_GPIO10 10
|
||||
+#define PAD_GPIO11 11
|
||||
+#define PAD_GPIO12 12
|
||||
+#define PAD_GPIO13 13
|
||||
+#define PAD_GPIO14 14
|
||||
+#define PAD_GPIO15 15
|
||||
+#define PAD_GPIO16 16
|
||||
+#define PAD_GPIO17 17
|
||||
+#define PAD_GPIO18 18
|
||||
+#define PAD_GPIO19 19
|
||||
+#define PAD_GPIO20 20
|
||||
+#define PAD_GPIO21 21
|
||||
+#define PAD_GPIO22 22
|
||||
+#define PAD_GPIO23 23
|
||||
+#define PAD_GPIO24 24
|
||||
+#define PAD_GPIO25 25
|
||||
+#define PAD_GPIO26 26
|
||||
+#define PAD_GPIO27 27
|
||||
+#define PAD_GPIO28 28
|
||||
+#define PAD_GPIO29 29
|
||||
+#define PAD_GPIO30 30
|
||||
+#define PAD_GPIO31 31
|
||||
+#define PAD_GPIO32 32
|
||||
+#define PAD_GPIO33 33
|
||||
+#define PAD_GPIO34 34
|
||||
+#define PAD_GPIO35 35
|
||||
+#define PAD_GPIO36 36
|
||||
+#define PAD_GPIO37 37
|
||||
+#define PAD_GPIO38 38
|
||||
+#define PAD_GPIO39 39
|
||||
+#define PAD_GPIO40 40
|
||||
+#define PAD_GPIO41 41
|
||||
+#define PAD_GPIO42 42
|
||||
+#define PAD_GPIO43 43
|
||||
+#define PAD_GPIO44 44
|
||||
+#define PAD_GPIO45 45
|
||||
+#define PAD_GPIO46 46
|
||||
+#define PAD_GPIO47 47
|
||||
+#define PAD_GPIO48 48
|
||||
+#define PAD_GPIO49 49
|
||||
+#define PAD_GPIO50 50
|
||||
+#define PAD_GPIO51 51
|
||||
+#define PAD_GPIO52 52
|
||||
+#define PAD_GPIO53 53
|
||||
+#define PAD_GPIO54 54
|
||||
+#define PAD_GPIO55 55
|
||||
+#define PAD_GPIO56 56
|
||||
+#define PAD_GPIO57 57
|
||||
+#define PAD_GPIO58 58
|
||||
+#define PAD_GPIO59 59
|
||||
+#define PAD_GPIO60 60
|
||||
+#define PAD_GPIO61 61
|
||||
+#define PAD_GPIO62 62
|
||||
+#define PAD_GPIO63 63
|
||||
+#define PAD_SD0_CLK 64
|
||||
+#define PAD_SD0_CMD 65
|
||||
+#define PAD_SD0_DATA0 66
|
||||
+#define PAD_SD0_DATA1 67
|
||||
+#define PAD_SD0_DATA2 68
|
||||
+#define PAD_SD0_DATA3 69
|
||||
+#define PAD_SD0_DATA4 70
|
||||
+#define PAD_SD0_DATA5 71
|
||||
+#define PAD_SD0_DATA6 72
|
||||
+#define PAD_SD0_DATA7 73
|
||||
+#define PAD_SD0_STRB 74
|
||||
+#define PAD_GMAC1_MDC 75
|
||||
+#define PAD_GMAC1_MDIO 76
|
||||
+#define PAD_GMAC1_RXD0 77
|
||||
+#define PAD_GMAC1_RXD1 78
|
||||
+#define PAD_GMAC1_RXD2 79
|
||||
+#define PAD_GMAC1_RXD3 80
|
||||
+#define PAD_GMAC1_RXDV 81
|
||||
+#define PAD_GMAC1_RXC 82
|
||||
+#define PAD_GMAC1_TXD0 83
|
||||
+#define PAD_GMAC1_TXD1 84
|
||||
+#define PAD_GMAC1_TXD2 85
|
||||
+#define PAD_GMAC1_TXD3 86
|
||||
+#define PAD_GMAC1_TXEN 87
|
||||
+#define PAD_GMAC1_TXC 88
|
||||
+#define PAD_QSPI_SCLK 89
|
||||
+#define PAD_QSPI_CS0 90
|
||||
+#define PAD_QSPI_DATA0 91
|
||||
+#define PAD_QSPI_DATA1 92
|
||||
+#define PAD_QSPI_DATA2 93
|
||||
+#define PAD_QSPI_DATA3 94
|
||||
+
|
||||
+#define GPOUT_LOW 0
|
||||
+#define GPOUT_HIGH 1
|
||||
+
|
||||
+#define GPOEN_ENABLE 0
|
||||
+#define GPOEN_DISABLE 1
|
||||
+
|
||||
+#define GPI_NONE 255
|
||||
+
|
||||
+#endif
|
@ -0,0 +1,176 @@
|
||||
From 514cae455122c799638226f4358e8e6f5e155248 Mon Sep 17 00:00:00 2001
|
||||
From: Jianlong Huang <jianlong.huang@starfivetech.com>
|
||||
Date: Thu, 9 Feb 2023 22:37:00 +0800
|
||||
Subject: [PATCH 027/122] dt-bindings: pinctrl: Add StarFive JH7110 aon pinctrl
|
||||
|
||||
Add pinctrl bindings for StarFive JH7110 SoC aon pinctrl controller.
|
||||
|
||||
Reviewed-by: Rob Herring <robh@kernel.org>
|
||||
Signed-off-by: Jianlong Huang <jianlong.huang@starfivetech.com>
|
||||
Co-developed-by: Emil Renner Berthing <kernel@esmil.dk>
|
||||
Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
|
||||
Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
|
||||
---
|
||||
.../pinctrl/starfive,jh7110-aon-pinctrl.yaml | 124 ++++++++++++++++++
|
||||
.../pinctrl/starfive,jh7110-pinctrl.h | 22 ++++
|
||||
2 files changed, 146 insertions(+)
|
||||
create mode 100644 Documentation/devicetree/bindings/pinctrl/starfive,jh7110-aon-pinctrl.yaml
|
||||
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/pinctrl/starfive,jh7110-aon-pinctrl.yaml
|
||||
@@ -0,0 +1,124 @@
|
||||
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
+%YAML 1.2
|
||||
+---
|
||||
+$id: http://devicetree.org/schemas/pinctrl/starfive,jh7110-aon-pinctrl.yaml#
|
||||
+$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
+
|
||||
+title: StarFive JH7110 AON Pin Controller
|
||||
+
|
||||
+description: |
|
||||
+ Bindings for the JH7110 RISC-V SoC from StarFive Technology Ltd.
|
||||
+
|
||||
+ Out of the SoC's many pins only the ones named PAD_RGPIO0 to PAD_RGPIO3
|
||||
+ can be multiplexed and have configurable bias, drive strength,
|
||||
+ schmitt trigger etc.
|
||||
+ Some peripherals such as PWM have their I/O go through the 4 "GPIOs".
|
||||
+
|
||||
+maintainers:
|
||||
+ - Jianlong Huang <jianlong.huang@starfivetech.com>
|
||||
+
|
||||
+properties:
|
||||
+ compatible:
|
||||
+ const: starfive,jh7110-aon-pinctrl
|
||||
+
|
||||
+ reg:
|
||||
+ maxItems: 1
|
||||
+
|
||||
+ resets:
|
||||
+ maxItems: 1
|
||||
+
|
||||
+ interrupts:
|
||||
+ maxItems: 1
|
||||
+
|
||||
+ interrupt-controller: true
|
||||
+
|
||||
+ '#interrupt-cells':
|
||||
+ const: 2
|
||||
+
|
||||
+ gpio-controller: true
|
||||
+
|
||||
+ '#gpio-cells':
|
||||
+ const: 2
|
||||
+
|
||||
+patternProperties:
|
||||
+ '-[0-9]+$':
|
||||
+ type: object
|
||||
+ additionalProperties: false
|
||||
+ patternProperties:
|
||||
+ '-pins$':
|
||||
+ type: object
|
||||
+ description: |
|
||||
+ A pinctrl node should contain at least one subnode representing the
|
||||
+ pinctrl groups available on the machine. Each subnode will list the
|
||||
+ pins it needs, and how they should be configured, with regard to
|
||||
+ muxer configuration, bias, input enable/disable, input schmitt
|
||||
+ trigger enable/disable, slew-rate and drive strength.
|
||||
+ allOf:
|
||||
+ - $ref: /schemas/pinctrl/pincfg-node.yaml
|
||||
+ - $ref: /schemas/pinctrl/pinmux-node.yaml
|
||||
+ additionalProperties: false
|
||||
+
|
||||
+ properties:
|
||||
+ pinmux:
|
||||
+ description: |
|
||||
+ The list of GPIOs and their mux settings that properties in the
|
||||
+ node apply to. This should be set using the GPIOMUX macro.
|
||||
+
|
||||
+ bias-disable: true
|
||||
+
|
||||
+ bias-pull-up:
|
||||
+ type: boolean
|
||||
+
|
||||
+ bias-pull-down:
|
||||
+ type: boolean
|
||||
+
|
||||
+ drive-strength:
|
||||
+ enum: [ 2, 4, 8, 12 ]
|
||||
+
|
||||
+ input-enable: true
|
||||
+
|
||||
+ input-disable: true
|
||||
+
|
||||
+ input-schmitt-enable: true
|
||||
+
|
||||
+ input-schmitt-disable: true
|
||||
+
|
||||
+ slew-rate:
|
||||
+ maximum: 1
|
||||
+
|
||||
+required:
|
||||
+ - compatible
|
||||
+ - reg
|
||||
+ - interrupts
|
||||
+ - interrupt-controller
|
||||
+ - '#interrupt-cells'
|
||||
+ - gpio-controller
|
||||
+ - '#gpio-cells'
|
||||
+
|
||||
+additionalProperties: false
|
||||
+
|
||||
+examples:
|
||||
+ - |
|
||||
+ pinctrl@17020000 {
|
||||
+ compatible = "starfive,jh7110-aon-pinctrl";
|
||||
+ reg = <0x17020000 0x10000>;
|
||||
+ resets = <&aoncrg 2>;
|
||||
+ interrupts = <85>;
|
||||
+ interrupt-controller;
|
||||
+ #interrupt-cells = <2>;
|
||||
+ gpio-controller;
|
||||
+ #gpio-cells = <2>;
|
||||
+
|
||||
+ pwm-0 {
|
||||
+ pwm-pins {
|
||||
+ pinmux = <0xff030802>;
|
||||
+ bias-disable;
|
||||
+ drive-strength = <12>;
|
||||
+ input-disable;
|
||||
+ input-schmitt-disable;
|
||||
+ slew-rate = <0>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+...
|
||||
--- a/include/dt-bindings/pinctrl/starfive,jh7110-pinctrl.h
|
||||
+++ b/include/dt-bindings/pinctrl/starfive,jh7110-pinctrl.h
|
||||
@@ -104,6 +104,28 @@
|
||||
#define PAD_QSPI_DATA2 93
|
||||
#define PAD_QSPI_DATA3 94
|
||||
|
||||
+/* aon_iomux pins */
|
||||
+#define PAD_TESTEN 0
|
||||
+#define PAD_RGPIO0 1
|
||||
+#define PAD_RGPIO1 2
|
||||
+#define PAD_RGPIO2 3
|
||||
+#define PAD_RGPIO3 4
|
||||
+#define PAD_RSTN 5
|
||||
+#define PAD_GMAC0_MDC 6
|
||||
+#define PAD_GMAC0_MDIO 7
|
||||
+#define PAD_GMAC0_RXD0 8
|
||||
+#define PAD_GMAC0_RXD1 9
|
||||
+#define PAD_GMAC0_RXD2 10
|
||||
+#define PAD_GMAC0_RXD3 11
|
||||
+#define PAD_GMAC0_RXDV 12
|
||||
+#define PAD_GMAC0_RXC 13
|
||||
+#define PAD_GMAC0_TXD0 14
|
||||
+#define PAD_GMAC0_TXD1 15
|
||||
+#define PAD_GMAC0_TXD2 16
|
||||
+#define PAD_GMAC0_TXD3 17
|
||||
+#define PAD_GMAC0_TXEN 18
|
||||
+#define PAD_GMAC0_TXC 19
|
||||
+
|
||||
#define GPOUT_LOW 0
|
||||
#define GPOUT_HIGH 1
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,224 @@
|
||||
From 9c1a9d6dfd6a9c28794536c8af002746a20d840f Mon Sep 17 00:00:00 2001
|
||||
From: Jianlong Huang <jianlong.huang@starfivetech.com>
|
||||
Date: Thu, 9 Feb 2023 22:37:02 +0800
|
||||
Subject: [PATCH 029/122] pinctrl: starfive: Add StarFive JH7110 aon controller
|
||||
driver
|
||||
|
||||
Add pinctrl driver for StarFive JH7110 SoC aon pinctrl controller.
|
||||
|
||||
Co-developed-by: Emil Renner Berthing <kernel@esmil.dk>
|
||||
Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
|
||||
Signed-off-by: Jianlong Huang <jianlong.huang@starfivetech.com>
|
||||
Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
|
||||
---
|
||||
drivers/pinctrl/starfive/Kconfig | 12 ++
|
||||
drivers/pinctrl/starfive/Makefile | 1 +
|
||||
.../starfive/pinctrl-starfive-jh7110-aon.c | 177 ++++++++++++++++++
|
||||
3 files changed, 190 insertions(+)
|
||||
create mode 100644 drivers/pinctrl/starfive/pinctrl-starfive-jh7110-aon.c
|
||||
|
||||
--- a/drivers/pinctrl/starfive/Kconfig
|
||||
+++ b/drivers/pinctrl/starfive/Kconfig
|
||||
@@ -37,3 +37,15 @@ config PINCTRL_STARFIVE_JH7110_SYS
|
||||
This also provides an interface to the GPIO pins not used by other
|
||||
peripherals supporting inputs, outputs, configuring pull-up/pull-down
|
||||
and interrupts on input changes.
|
||||
+
|
||||
+config PINCTRL_STARFIVE_JH7110_AON
|
||||
+ tristate "Always-on pinctrl and GPIO driver for the StarFive JH7110 SoC"
|
||||
+ depends on SOC_STARFIVE || COMPILE_TEST
|
||||
+ depends on OF
|
||||
+ select PINCTRL_STARFIVE_JH7110
|
||||
+ default SOC_STARFIVE
|
||||
+ help
|
||||
+ Say yes here to support always-on pin control on the StarFive JH7110 SoC.
|
||||
+ This also provides an interface to the GPIO pins not used by other
|
||||
+ peripherals supporting inputs, outputs, configuring pull-up/pull-down
|
||||
+ and interrupts on input changes.
|
||||
--- a/drivers/pinctrl/starfive/Makefile
|
||||
+++ b/drivers/pinctrl/starfive/Makefile
|
||||
@@ -4,3 +4,4 @@ obj-$(CONFIG_PINCTRL_STARFIVE_JH7100) +=
|
||||
|
||||
obj-$(CONFIG_PINCTRL_STARFIVE_JH7110) += pinctrl-starfive-jh7110.o
|
||||
obj-$(CONFIG_PINCTRL_STARFIVE_JH7110_SYS) += pinctrl-starfive-jh7110-sys.o
|
||||
+obj-$(CONFIG_PINCTRL_STARFIVE_JH7110_AON) += pinctrl-starfive-jh7110-aon.o
|
||||
--- /dev/null
|
||||
+++ b/drivers/pinctrl/starfive/pinctrl-starfive-jh7110-aon.c
|
||||
@@ -0,0 +1,177 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0
|
||||
+/*
|
||||
+ * Pinctrl / GPIO driver for StarFive JH7110 SoC aon controller
|
||||
+ *
|
||||
+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/err.h>
|
||||
+#include <linux/gpio/driver.h>
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/interrupt.h>
|
||||
+#include <linux/io.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/of.h>
|
||||
+#include <linux/of_device.h>
|
||||
+#include <linux/of_irq.h>
|
||||
+#include <linux/of_platform.h>
|
||||
+#include <linux/pinctrl/pinconf.h>
|
||||
+#include <linux/pinctrl/pinconf-generic.h>
|
||||
+#include <linux/pinctrl/pinctrl.h>
|
||||
+#include <linux/pinctrl/pinmux.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/pm_runtime.h>
|
||||
+#include <linux/regmap.h>
|
||||
+#include <linux/slab.h>
|
||||
+
|
||||
+#include <dt-bindings/pinctrl/starfive,jh7110-pinctrl.h>
|
||||
+
|
||||
+#include "../core.h"
|
||||
+#include "../pinconf.h"
|
||||
+#include "../pinmux.h"
|
||||
+#include "pinctrl-starfive-jh7110.h"
|
||||
+
|
||||
+#define JH7110_AON_NGPIO 4
|
||||
+#define JH7110_AON_GC_BASE 64
|
||||
+
|
||||
+/* registers */
|
||||
+#define JH7110_AON_DOEN 0x0
|
||||
+#define JH7110_AON_DOUT 0x4
|
||||
+#define JH7110_AON_GPI 0x8
|
||||
+#define JH7110_AON_GPIOIN 0x2c
|
||||
+
|
||||
+#define JH7110_AON_GPIOEN 0xc
|
||||
+#define JH7110_AON_GPIOIS 0x10
|
||||
+#define JH7110_AON_GPIOIC 0x14
|
||||
+#define JH7110_AON_GPIOIBE 0x18
|
||||
+#define JH7110_AON_GPIOIEV 0x1c
|
||||
+#define JH7110_AON_GPIOIE 0x20
|
||||
+#define JH7110_AON_GPIORIS 0x28
|
||||
+#define JH7110_AON_GPIOMIS 0x28
|
||||
+
|
||||
+#define JH7110_AON_GPO_PDA_0_5_CFG 0x30
|
||||
+
|
||||
+static const struct pinctrl_pin_desc jh7110_aon_pins[] = {
|
||||
+ PINCTRL_PIN(PAD_TESTEN, "TESTEN"),
|
||||
+ PINCTRL_PIN(PAD_RGPIO0, "RGPIO0"),
|
||||
+ PINCTRL_PIN(PAD_RGPIO1, "RGPIO1"),
|
||||
+ PINCTRL_PIN(PAD_RGPIO2, "RGPIO2"),
|
||||
+ PINCTRL_PIN(PAD_RGPIO3, "RGPIO3"),
|
||||
+ PINCTRL_PIN(PAD_RSTN, "RSTN"),
|
||||
+ PINCTRL_PIN(PAD_GMAC0_MDC, "GMAC0_MDC"),
|
||||
+ PINCTRL_PIN(PAD_GMAC0_MDIO, "GMAC0_MDIO"),
|
||||
+ PINCTRL_PIN(PAD_GMAC0_RXD0, "GMAC0_RXD0"),
|
||||
+ PINCTRL_PIN(PAD_GMAC0_RXD1, "GMAC0_RXD1"),
|
||||
+ PINCTRL_PIN(PAD_GMAC0_RXD2, "GMAC0_RXD2"),
|
||||
+ PINCTRL_PIN(PAD_GMAC0_RXD3, "GMAC0_RXD3"),
|
||||
+ PINCTRL_PIN(PAD_GMAC0_RXDV, "GMAC0_RXDV"),
|
||||
+ PINCTRL_PIN(PAD_GMAC0_RXC, "GMAC0_RXC"),
|
||||
+ PINCTRL_PIN(PAD_GMAC0_TXD0, "GMAC0_TXD0"),
|
||||
+ PINCTRL_PIN(PAD_GMAC0_TXD1, "GMAC0_TXD1"),
|
||||
+ PINCTRL_PIN(PAD_GMAC0_TXD2, "GMAC0_TXD2"),
|
||||
+ PINCTRL_PIN(PAD_GMAC0_TXD3, "GMAC0_TXD3"),
|
||||
+ PINCTRL_PIN(PAD_GMAC0_TXEN, "GMAC0_TXEN"),
|
||||
+ PINCTRL_PIN(PAD_GMAC0_TXC, "GMAC0_TXC"),
|
||||
+};
|
||||
+
|
||||
+static int jh7110_aon_set_one_pin_mux(struct jh7110_pinctrl *sfp,
|
||||
+ unsigned int pin,
|
||||
+ unsigned int din, u32 dout,
|
||||
+ u32 doen, u32 func)
|
||||
+{
|
||||
+ if (pin < sfp->gc.ngpio && func == 0)
|
||||
+ jh7110_set_gpiomux(sfp, pin, din, dout, doen);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int jh7110_aon_get_padcfg_base(struct jh7110_pinctrl *sfp,
|
||||
+ unsigned int pin)
|
||||
+{
|
||||
+ if (pin < PAD_GMAC0_MDC)
|
||||
+ return JH7110_AON_GPO_PDA_0_5_CFG;
|
||||
+
|
||||
+ return -1;
|
||||
+}
|
||||
+
|
||||
+static void jh7110_aon_irq_handler(struct irq_desc *desc)
|
||||
+{
|
||||
+ struct jh7110_pinctrl *sfp = jh7110_from_irq_desc(desc);
|
||||
+ struct irq_chip *chip = irq_desc_get_chip(desc);
|
||||
+ unsigned long mis;
|
||||
+ unsigned int pin;
|
||||
+
|
||||
+ chained_irq_enter(chip, desc);
|
||||
+
|
||||
+ mis = readl_relaxed(sfp->base + JH7110_AON_GPIOMIS);
|
||||
+ for_each_set_bit(pin, &mis, JH7110_AON_NGPIO)
|
||||
+ generic_handle_domain_irq(sfp->gc.irq.domain, pin);
|
||||
+
|
||||
+ chained_irq_exit(chip, desc);
|
||||
+}
|
||||
+
|
||||
+static int jh7110_aon_init_hw(struct gpio_chip *gc)
|
||||
+{
|
||||
+ struct jh7110_pinctrl *sfp = container_of(gc,
|
||||
+ struct jh7110_pinctrl, gc);
|
||||
+
|
||||
+ /* mask all GPIO interrupts */
|
||||
+ writel_relaxed(0, sfp->base + JH7110_AON_GPIOIE);
|
||||
+ /* clear edge interrupt flags */
|
||||
+ writel_relaxed(0, sfp->base + JH7110_AON_GPIOIC);
|
||||
+ writel_relaxed(0x0f, sfp->base + JH7110_AON_GPIOIC);
|
||||
+ /* enable GPIO interrupts */
|
||||
+ writel_relaxed(1, sfp->base + JH7110_AON_GPIOEN);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct jh7110_gpio_irq_reg jh7110_aon_irq_reg = {
|
||||
+ .is_reg_base = JH7110_AON_GPIOIS,
|
||||
+ .ic_reg_base = JH7110_AON_GPIOIC,
|
||||
+ .ibe_reg_base = JH7110_AON_GPIOIBE,
|
||||
+ .iev_reg_base = JH7110_AON_GPIOIEV,
|
||||
+ .ie_reg_base = JH7110_AON_GPIOIE,
|
||||
+ .ris_reg_base = JH7110_AON_GPIORIS,
|
||||
+ .mis_reg_base = JH7110_AON_GPIOMIS,
|
||||
+};
|
||||
+
|
||||
+static const struct jh7110_pinctrl_soc_info jh7110_aon_pinctrl_info = {
|
||||
+ .pins = jh7110_aon_pins,
|
||||
+ .npins = ARRAY_SIZE(jh7110_aon_pins),
|
||||
+ .ngpios = JH7110_AON_NGPIO,
|
||||
+ .gc_base = JH7110_AON_GC_BASE,
|
||||
+ .dout_reg_base = JH7110_AON_DOUT,
|
||||
+ .dout_mask = GENMASK(3, 0),
|
||||
+ .doen_reg_base = JH7110_AON_DOEN,
|
||||
+ .doen_mask = GENMASK(2, 0),
|
||||
+ .gpi_reg_base = JH7110_AON_GPI,
|
||||
+ .gpi_mask = GENMASK(3, 0),
|
||||
+ .gpioin_reg_base = JH7110_AON_GPIOIN,
|
||||
+ .irq_reg = &jh7110_aon_irq_reg,
|
||||
+ .jh7110_set_one_pin_mux = jh7110_aon_set_one_pin_mux,
|
||||
+ .jh7110_get_padcfg_base = jh7110_aon_get_padcfg_base,
|
||||
+ .jh7110_gpio_irq_handler = jh7110_aon_irq_handler,
|
||||
+ .jh7110_gpio_init_hw = jh7110_aon_init_hw,
|
||||
+};
|
||||
+
|
||||
+static const struct of_device_id jh7110_aon_pinctrl_of_match[] = {
|
||||
+ {
|
||||
+ .compatible = "starfive,jh7110-aon-pinctrl",
|
||||
+ .data = &jh7110_aon_pinctrl_info,
|
||||
+ },
|
||||
+ { /* sentinel */ }
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, jh7110_aon_pinctrl_of_match);
|
||||
+
|
||||
+static struct platform_driver jh7110_aon_pinctrl_driver = {
|
||||
+ .probe = jh7110_pinctrl_probe,
|
||||
+ .driver = {
|
||||
+ .name = "starfive-jh7110-aon-pinctrl",
|
||||
+ .of_match_table = jh7110_aon_pinctrl_of_match,
|
||||
+ },
|
||||
+};
|
||||
+module_platform_driver(jh7110_aon_pinctrl_driver);
|
||||
+
|
||||
+MODULE_DESCRIPTION("Pinctrl driver for the StarFive JH7110 SoC aon controller");
|
||||
+MODULE_AUTHOR("Jianlong Huang <jianlong.huang@starfivetech.com>");
|
||||
+MODULE_LICENSE("GPL");
|
@ -0,0 +1,228 @@
|
||||
From 537ee9e5bb7b4ebee4ad5a607098c8200af6c261 Mon Sep 17 00:00:00 2001
|
||||
From: "shanlong.li" <shanlong.li@starfivetech.com>
|
||||
Date: Thu, 18 May 2023 19:27:28 -0700
|
||||
Subject: [PATCH 030/122] config: add jh7110 defconfig for test mini
|
||||
|
||||
add jh7110 defconfig for test mini
|
||||
|
||||
Signed-off-by: shanlong.li <shanlong.li@starfivetech.com>
|
||||
---
|
||||
arch/riscv/configs/jh7110_defconfig | 212 ++++++++++++++++++++++++++++
|
||||
1 file changed, 212 insertions(+)
|
||||
create mode 100755 arch/riscv/configs/jh7110_defconfig
|
||||
|
||||
--- /dev/null
|
||||
+++ b/arch/riscv/configs/jh7110_defconfig
|
||||
@@ -0,0 +1,212 @@
|
||||
+CONFIG_WERROR=y
|
||||
+CONFIG_SYSVIPC=y
|
||||
+# CONFIG_CROSS_MEMORY_ATTACH is not set
|
||||
+CONFIG_NO_HZ_IDLE=y
|
||||
+CONFIG_HIGH_RES_TIMERS=y
|
||||
+CONFIG_PSI=y
|
||||
+# CONFIG_CPU_ISOLATION is not set
|
||||
+CONFIG_IKCONFIG=y
|
||||
+CONFIG_IKCONFIG_PROC=y
|
||||
+CONFIG_CGROUPS=y
|
||||
+CONFIG_CGROUP_SCHED=y
|
||||
+CONFIG_CGROUP_PIDS=y
|
||||
+CONFIG_CGROUP_CPUACCT=y
|
||||
+CONFIG_NAMESPACES=y
|
||||
+CONFIG_BLK_DEV_INITRD=y
|
||||
+CONFIG_RD_GZIP=y
|
||||
+# CONFIG_RD_BZIP2 is not set
|
||||
+# CONFIG_RD_LZMA is not set
|
||||
+# CONFIG_RD_XZ is not set
|
||||
+# CONFIG_RD_LZO is not set
|
||||
+# CONFIG_RD_LZ4 is not set
|
||||
+CONFIG_EXPERT=y
|
||||
+# CONFIG_SYSFS_SYSCALL is not set
|
||||
+CONFIG_KCMP=y
|
||||
+CONFIG_PERF_EVENTS=y
|
||||
+CONFIG_ARCH_STARFIVE=y
|
||||
+CONFIG_SOC_STARFIVE=y
|
||||
+CONFIG_ERRATA_SIFIVE=y
|
||||
+CONFIG_SMP=y
|
||||
+# CONFIG_RISCV_ISA_SVPBMT is not set
|
||||
+# CONFIG_COMPAT is not set
|
||||
+CONFIG_CPU_IDLE=y
|
||||
+CONFIG_RISCV_SBI_CPUIDLE=y
|
||||
+CONFIG_JUMP_LABEL=y
|
||||
+# CONFIG_STACKPROTECTOR is not set
|
||||
+CONFIG_MODULES=y
|
||||
+CONFIG_MODULE_UNLOAD=y
|
||||
+CONFIG_MODULE_COMPRESS_ZSTD=y
|
||||
+# CONFIG_BLOCK_LEGACY_AUTOLOAD is not set
|
||||
+CONFIG_BLK_WBT=y
|
||||
+# CONFIG_BLK_DEBUG_FS is not set
|
||||
+CONFIG_PARTITION_ADVANCED=y
|
||||
+# CONFIG_MQ_IOSCHED_DEADLINE is not set
|
||||
+# CONFIG_MQ_IOSCHED_KYBER is not set
|
||||
+CONFIG_IOSCHED_BFQ=y
|
||||
+CONFIG_KSM=y
|
||||
+# CONFIG_VM_EVENT_COUNTERS is not set
|
||||
+CONFIG_NET=y
|
||||
+CONFIG_PACKET=y
|
||||
+CONFIG_UNIX=y
|
||||
+CONFIG_INET=y
|
||||
+CONFIG_IP_ADVANCED_ROUTER=y
|
||||
+CONFIG_IP_MULTIPLE_TABLES=y
|
||||
+CONFIG_INET_DIAG=m
|
||||
+# CONFIG_IPV6_SIT is not set
|
||||
+CONFIG_IPV6_MULTIPLE_TABLES=y
|
||||
+# CONFIG_WIRELESS is not set
|
||||
+# CONFIG_ETHTOOL_NETLINK is not set
|
||||
+CONFIG_DEVTMPFS=y
|
||||
+CONFIG_DEVTMPFS_MOUNT=y
|
||||
+# CONFIG_STANDALONE is not set
|
||||
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
|
||||
+# CONFIG_FW_LOADER is not set
|
||||
+CONFIG_EFI_DISABLE_RUNTIME=y
|
||||
+CONFIG_ZRAM=y
|
||||
+CONFIG_ZRAM_MEMORY_TRACKING=y
|
||||
+CONFIG_BLK_DEV_LOOP=y
|
||||
+CONFIG_BLK_DEV_LOOP_MIN_COUNT=1
|
||||
+CONFIG_NETDEVICES=y
|
||||
+CONFIG_STMMAC_ETH=y
|
||||
+CONFIG_DWMAC_DWC_QOS_ETH=y
|
||||
+# CONFIG_DWMAC_GENERIC is not set
|
||||
+CONFIG_DWMAC_STARFIVE=y
|
||||
+CONFIG_MICROCHIP_PHY=y
|
||||
+CONFIG_MOTORCOMM_PHY=y
|
||||
+# CONFIG_WLAN is not set
|
||||
+# CONFIG_INPUT_KEYBOARD is not set
|
||||
+# CONFIG_INPUT_MOUSE is not set
|
||||
+# CONFIG_SERIO is not set
|
||||
+# CONFIG_VT is not set
|
||||
+# CONFIG_LEGACY_PTYS is not set
|
||||
+# CONFIG_LDISC_AUTOLOAD is not set
|
||||
+CONFIG_SERIAL_8250=y
|
||||
+# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set
|
||||
+# CONFIG_SERIAL_8250_16550A_VARIANTS is not set
|
||||
+CONFIG_SERIAL_8250_CONSOLE=y
|
||||
+CONFIG_SERIAL_8250_DW=y
|
||||
+CONFIG_SERIAL_OF_PLATFORM=y
|
||||
+# CONFIG_DEVMEM is not set
|
||||
+# CONFIG_RANDOM_TRUST_BOOTLOADER is not set
|
||||
+CONFIG_I2C=y
|
||||
+# CONFIG_I2C_COMPAT is not set
|
||||
+CONFIG_I2C_CHARDEV=y
|
||||
+# CONFIG_I2C_HELPER_AUTO is not set
|
||||
+CONFIG_I2C_DESIGNWARE_PLATFORM=y
|
||||
+# CONFIG_PTP_1588_CLOCK is not set
|
||||
+CONFIG_PINCTRL_STARFIVE_JH7110=y
|
||||
+CONFIG_GPIOLIB_FASTPATH_LIMIT=128
|
||||
+CONFIG_GPIO_SYSFS=y
|
||||
+CONFIG_POWER_RESET=y
|
||||
+CONFIG_POWER_RESET_GPIO_RESTART=y
|
||||
+CONFIG_SENSORS_SFCTEMP=y
|
||||
+# CONFIG_HID is not set
|
||||
+CONFIG_MMC=y
|
||||
+# CONFIG_PWRSEQ_EMMC is not set
|
||||
+# CONFIG_PWRSEQ_SIMPLE is not set
|
||||
+CONFIG_MMC_DW=y
|
||||
+# CONFIG_VIRTIO_MENU is not set
|
||||
+CONFIG_CLK_STARFIVE_JH7110_AON=y
|
||||
+# CONFIG_VHOST_MENU is not set
|
||||
+# CONFIG_IOMMU_SUPPORT is not set
|
||||
+CONFIG_BTRFS_FS=y
|
||||
+CONFIG_BTRFS_FS_POSIX_ACL=y
|
||||
+# CONFIG_DNOTIFY is not set
|
||||
+CONFIG_FANOTIFY=y
|
||||
+CONFIG_AUTOFS_FS=y
|
||||
+CONFIG_VFAT_FS=y
|
||||
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-15"
|
||||
+CONFIG_FAT_DEFAULT_UTF8=y
|
||||
+CONFIG_PROC_KCORE=y
|
||||
+CONFIG_PROC_CHILDREN=y
|
||||
+CONFIG_TMPFS=y
|
||||
+CONFIG_TMPFS_POSIX_ACL=y
|
||||
+CONFIG_EFIVAR_FS=y
|
||||
+# CONFIG_MISC_FILESYSTEMS is not set
|
||||
+# CONFIG_NETWORK_FILESYSTEMS is not set
|
||||
+CONFIG_NLS_DEFAULT="iso8859-15"
|
||||
+CONFIG_NLS_CODEPAGE_437=y
|
||||
+CONFIG_NLS_ISO8859_15=y
|
||||
+CONFIG_LSM=""
|
||||
+CONFIG_CRYPTO_ZSTD=y
|
||||
+# CONFIG_RAID6_PQ_BENCHMARK is not set
|
||||
+# CONFIG_DEBUG_MISC is not set
|
||||
+CONFIG_STRIP_ASM_SYMS=y
|
||||
+CONFIG_DEBUG_SECTION_MISMATCH=y
|
||||
+# CONFIG_SECTION_MISMATCH_WARN_ONLY is not set
|
||||
+CONFIG_DEBUG_FS=y
|
||||
+# CONFIG_SLUB_DEBUG is not set
|
||||
+CONFIG_PAGE_TABLE_CHECK=y
|
||||
+CONFIG_DEBUG_RODATA_TEST=y
|
||||
+CONFIG_DEBUG_WX=y
|
||||
+CONFIG_SOFTLOCKUP_DETECTOR=y
|
||||
+CONFIG_WQ_WATCHDOG=y
|
||||
+# CONFIG_SCHED_DEBUG is not set
|
||||
+CONFIG_STACKTRACE=y
|
||||
+CONFIG_RCU_CPU_STALL_TIMEOUT=60
|
||||
+# CONFIG_RCU_TRACE is not set
|
||||
+# CONFIG_FTRACE is not set
|
||||
+# CONFIG_RUNTIME_TESTING_MENU is not set
|
||||
+CONFIG_EXT4_FS=y
|
||||
+CONFIG_CPUFREQ_DT_PLATDEV=y
|
||||
+CONFIG_CPUFREQ_DT=y
|
||||
+CONFIG_CPU_FREQ=y
|
||||
+CONFIG_HIBERNATION=y
|
||||
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
|
||||
+CONFIG_SWAP=y
|
||||
+CONFIG_PCIE_STARFIVE=y
|
||||
+CONFIG_PCI_MSI=y
|
||||
+CONFIG_PCI=y
|
||||
+CONFIG_USB_CDNS3_STARFIVE=y
|
||||
+CONFIG_PHY_STARFIVE_JH7110_PCIE=y
|
||||
+CONFIG_PHY_STARFIVE_JH7110_USB=y
|
||||
+CONFIG_USB_CDNS_SUPPORT=y
|
||||
+CONFIG_USB_CDNS3=y
|
||||
+CONFIG_USB=y
|
||||
+CONFIG_USB_SUPPORT=y
|
||||
+CONFIG_VIDEO_STARFIVE_CAMSS=y
|
||||
+CONFIG_VIDEO_CADENCE_CSI2RX=y
|
||||
+CONFIG_VIDEO_DEV=y
|
||||
+CONFIG_V4L_PLATFORM_DRIVERS=y
|
||||
+CONFIG_MEDIA_PLATFORM_DRIVERS=y
|
||||
+CONFIG_MEDIA_PLATFORM_SUPPORT=y
|
||||
+CONFIG_MEDIA_SUPPORT=y
|
||||
+CONFIG_PHY_STARFIVE_DPHY_RX=y
|
||||
+CONFIG_CRYPTO_DEV_JH7110=y
|
||||
+CONFIG_CRYPTO_HW=y
|
||||
+CONFIG_CRYPTO=y
|
||||
+CONFIG_SND_SOC_JH7110_TDM=y
|
||||
+CONFIG_SND_SOC_STARFIVE=y
|
||||
+CONFIG_SND_SOC=y
|
||||
+CONFIG_SND=y
|
||||
+CONFIG_SOUND=y
|
||||
+CONFIG_DW_AXI_DMAC=y
|
||||
+CONFIG_DMADEVICES=y
|
||||
+CONFIG_HAS_IOMEM=y
|
||||
+CONFIG_PWM_STARFIVE_PTC=y
|
||||
+CONFIG_PWM=y
|
||||
+CONFIG_STARFIVE_TIMER=y
|
||||
+CONFIG_SECTION_MISMATCH_WARN_ONLY=y
|
||||
+CONFIG_GENERIC_CLOCKEVENTS=y
|
||||
+CONFIG_STARFIVE_WATCHDOG=y
|
||||
+CONFIG_WATCHDOG=y
|
||||
+CONFIG_HW_RANDOM_JH7110=y
|
||||
+CONFIG_HW_RANDOM=y
|
||||
+CONFIG_STMMAC_PLATFORM=y
|
||||
+CONFIG_SPI_CADENCE_QUADSPI=y
|
||||
+CONFIG_SPI_MASTER=y
|
||||
+CONFIG_SPI=y
|
||||
+CONFIG_MMC_DW_STARFIVE=y
|
||||
+CONFIG_CLK_STARFIVE_JH7110_PLL=y
|
||||
+CONFIG_CLK_STARFIVE_JH7110_VOUT=y
|
||||
+CONFIG_CLK_STARFIVE_JH7110_ISP=y
|
||||
+CONFIG_CLK_STARFIVE_JH7110_STG=y
|
||||
+CONFIG_JH71XX_PMU=y
|
||||
+CONFIG_PM=y
|
||||
+CONFIG_PINCTRL_STARFIVE_JH7110_AON=y
|
||||
+CONFIG_PINCTRL_STARFIVE_JH7110_SYS=y
|
||||
+CONFIG_CLK_STARFIVE_JH7110_AON=y
|
||||
+CONFIG_CLK_STARFIVE_JH7110_SYS=y
|
||||
+CONFIG_SIFIVE_CCACHE=y
|
||||
+CONFIG_CLINT_TIMER=y
|
||||
+CONFIG_SIFIVE_PLIC=y
|
@ -0,0 +1,80 @@
|
||||
From 07f62b08668c0295b1c6342f9708b7e36093ff59 Mon Sep 17 00:00:00 2001
|
||||
From: Xingyu Wu <xingyu.wu@starfivetech.com>
|
||||
Date: Tue, 21 Feb 2023 17:13:48 +0800
|
||||
Subject: [PATCH 031/122] dt-bindings: clock: Add StarFive JH7110 PLL clock
|
||||
generator
|
||||
|
||||
Add bindings for the PLL clock generator on the JH7110 RISC-V SoC.
|
||||
|
||||
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
|
||||
Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
|
||||
---
|
||||
.../bindings/clock/starfive,jh7110-pll.yaml | 46 +++++++++++++++++++
|
||||
.../dt-bindings/clock/starfive,jh7110-crg.h | 6 +++
|
||||
2 files changed, 52 insertions(+)
|
||||
create mode 100644 Documentation/devicetree/bindings/clock/starfive,jh7110-pll.yaml
|
||||
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/clock/starfive,jh7110-pll.yaml
|
||||
@@ -0,0 +1,46 @@
|
||||
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
+%YAML 1.2
|
||||
+---
|
||||
+$id: http://devicetree.org/schemas/clock/starfive,jh7110-pll.yaml#
|
||||
+$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
+
|
||||
+title: StarFive JH7110 PLL Clock Generator
|
||||
+
|
||||
+description:
|
||||
+ This PLL are high speed, low jitter frequency synthesizers in JH7110.
|
||||
+ Each PLL clocks work in integer mode or fraction mode by some dividers,
|
||||
+ and the configuration registers and dividers are set in several syscon
|
||||
+ registers. So pll node should be a child of SYS-SYSCON node.
|
||||
+ The formula for calculating frequency is that,
|
||||
+ Fvco = Fref * (NI + NF) / M / Q1
|
||||
+
|
||||
+maintainers:
|
||||
+ - Xingyu Wu <xingyu.wu@starfivetech.com>
|
||||
+
|
||||
+properties:
|
||||
+ compatible:
|
||||
+ const: starfive,jh7110-pll
|
||||
+
|
||||
+ clocks:
|
||||
+ maxItems: 1
|
||||
+ description: Main Oscillator (24 MHz)
|
||||
+
|
||||
+ '#clock-cells':
|
||||
+ const: 1
|
||||
+ description:
|
||||
+ See <dt-bindings/clock/starfive,jh7110-crg.h> for valid indices.
|
||||
+
|
||||
+required:
|
||||
+ - compatible
|
||||
+ - clocks
|
||||
+ - '#clock-cells'
|
||||
+
|
||||
+additionalProperties: false
|
||||
+
|
||||
+examples:
|
||||
+ - |
|
||||
+ pll-clock-controller {
|
||||
+ compatible = "starfive,jh7110-pll";
|
||||
+ clocks = <&osc>;
|
||||
+ #clock-cells = <1>;
|
||||
+ };
|
||||
--- a/include/dt-bindings/clock/starfive,jh7110-crg.h
|
||||
+++ b/include/dt-bindings/clock/starfive,jh7110-crg.h
|
||||
@@ -6,6 +6,12 @@
|
||||
#ifndef __DT_BINDINGS_CLOCK_STARFIVE_JH7110_CRG_H__
|
||||
#define __DT_BINDINGS_CLOCK_STARFIVE_JH7110_CRG_H__
|
||||
|
||||
+/* PLL clocks */
|
||||
+#define JH7110_CLK_PLL0_OUT 0
|
||||
+#define JH7110_CLK_PLL1_OUT 1
|
||||
+#define JH7110_CLK_PLL2_OUT 2
|
||||
+#define JH7110_PLLCLK_END 3
|
||||
+
|
||||
/* SYSCRG clocks */
|
||||
#define JH7110_SYSCLK_CPU_ROOT 0
|
||||
#define JH7110_SYSCLK_CPU_CORE 1
|
@ -0,0 +1,786 @@
|
||||
From 0bc7aa28dcdee75a52b1874a02dfbf0107c2d448 Mon Sep 17 00:00:00 2001
|
||||
From: Xingyu Wu <xingyu.wu@starfivetech.com>
|
||||
Date: Fri, 17 Feb 2023 17:30:09 +0800
|
||||
Subject: [PATCH 032/122] clk: starfive: Add StarFive JH7110 PLL clock driver
|
||||
|
||||
Add driver for the StarFive JH7110 PLL clock controller
|
||||
and they work by reading and setting syscon registers.
|
||||
|
||||
Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
|
||||
---
|
||||
MAINTAINERS | 6 +
|
||||
drivers/clk/starfive/Kconfig | 8 +
|
||||
drivers/clk/starfive/Makefile | 1 +
|
||||
.../clk/starfive/clk-starfive-jh7110-pll.c | 427 ++++++++++++++++++
|
||||
.../clk/starfive/clk-starfive-jh7110-pll.h | 293 ++++++++++++
|
||||
5 files changed, 735 insertions(+)
|
||||
create mode 100644 drivers/clk/starfive/clk-starfive-jh7110-pll.c
|
||||
create mode 100644 drivers/clk/starfive/clk-starfive-jh7110-pll.h
|
||||
|
||||
--- a/MAINTAINERS
|
||||
+++ b/MAINTAINERS
|
||||
@@ -19650,6 +19650,12 @@ M: Emil Renner Berthing <kernel@esmil.dk
|
||||
S: Maintained
|
||||
F: arch/riscv/boot/dts/starfive/
|
||||
|
||||
+STARFIVE JH7110 PLL CLOCK DRIVER
|
||||
+M: Xingyu Wu <xingyu.wu@starfivetech.com>
|
||||
+S: Supported
|
||||
+F: Documentation/devicetree/bindings/clock/starfive,jh7110-pll.yaml
|
||||
+F: drivers/clk/starfive/clk-starfive-jh7110-pll.*
|
||||
+
|
||||
STARFIVE JH71X0 CLOCK DRIVERS
|
||||
M: Emil Renner Berthing <kernel@esmil.dk>
|
||||
M: Hal Feng <hal.feng@starfivetech.com>
|
||||
--- a/drivers/clk/starfive/Kconfig
|
||||
+++ b/drivers/clk/starfive/Kconfig
|
||||
@@ -21,6 +21,14 @@ config CLK_STARFIVE_JH7100_AUDIO
|
||||
Say Y or M here to support the audio clocks on the StarFive JH7100
|
||||
SoC.
|
||||
|
||||
+config CLK_STARFIVE_JH7110_PLL
|
||||
+ bool "StarFive JH7110 PLL clock support"
|
||||
+ depends on ARCH_STARFIVE || COMPILE_TEST
|
||||
+ default ARCH_STARFIVE
|
||||
+ help
|
||||
+ Say yes here to support the PLL clock controller on the
|
||||
+ StarFive JH7110 SoC.
|
||||
+
|
||||
config CLK_STARFIVE_JH7110_SYS
|
||||
bool "StarFive JH7110 system clock support"
|
||||
depends on ARCH_STARFIVE || COMPILE_TEST
|
||||
--- a/drivers/clk/starfive/Makefile
|
||||
+++ b/drivers/clk/starfive/Makefile
|
||||
@@ -4,5 +4,6 @@ obj-$(CONFIG_CLK_STARFIVE_JH71X0) += clk
|
||||
obj-$(CONFIG_CLK_STARFIVE_JH7100) += clk-starfive-jh7100.o
|
||||
obj-$(CONFIG_CLK_STARFIVE_JH7100_AUDIO) += clk-starfive-jh7100-audio.o
|
||||
|
||||
+obj-$(CONFIG_CLK_STARFIVE_JH7110_PLL) += clk-starfive-jh7110-pll.o
|
||||
obj-$(CONFIG_CLK_STARFIVE_JH7110_SYS) += clk-starfive-jh7110-sys.o
|
||||
obj-$(CONFIG_CLK_STARFIVE_JH7110_AON) += clk-starfive-jh7110-aon.o
|
||||
--- /dev/null
|
||||
+++ b/drivers/clk/starfive/clk-starfive-jh7110-pll.c
|
||||
@@ -0,0 +1,427 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0
|
||||
+/*
|
||||
+ * StarFive JH7110 PLL Clock Generator Driver
|
||||
+ *
|
||||
+ * Copyright (C) 2023 StarFive Technology Co., Ltd.
|
||||
+ *
|
||||
+ * This driver is about to register JH7110 PLL clock generator and support ops.
|
||||
+ * The JH7110 have three PLL clock, PLL0, PLL1 and PLL2.
|
||||
+ * Each PLL clocks work in integer mode or fraction mode by some dividers,
|
||||
+ * and the configuration registers and dividers are set in several syscon registers.
|
||||
+ * The formula for calculating frequency is:
|
||||
+ * Fvco = Fref * (NI + NF) / M / Q1
|
||||
+ * Fref: OSC source clock rate
|
||||
+ * NI: integer frequency dividing ratio of feedback divider, set by fbdiv[11:0].
|
||||
+ * NF: fractional frequency dividing ratio, set by frac[23:0]. NF = frac[23:0] / 2^24 = 0 ~ 0.999.
|
||||
+ * M: frequency dividing ratio of pre-divider, set by prediv[5:0].
|
||||
+ * Q1: frequency dividing ratio of post divider, set by postdiv1[1:0], Q1= 1,2,4,8.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/clk-provider.h>
|
||||
+#include <linux/debugfs.h>
|
||||
+#include <linux/device.h>
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/mfd/syscon.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/regmap.h>
|
||||
+
|
||||
+#include <dt-bindings/clock/starfive,jh7110-crg.h>
|
||||
+
|
||||
+#include "clk-starfive-jh7110-pll.h"
|
||||
+
|
||||
+static struct jh7110_clk_pll_data *jh7110_pll_data_from(struct clk_hw *hw)
|
||||
+{
|
||||
+ return container_of(hw, struct jh7110_clk_pll_data, hw);
|
||||
+}
|
||||
+
|
||||
+static struct jh7110_clk_pll_priv *jh7110_pll_priv_from(struct jh7110_clk_pll_data *data)
|
||||
+{
|
||||
+ return container_of(data, struct jh7110_clk_pll_priv, data[data->idx]);
|
||||
+}
|
||||
+
|
||||
+/* Read register value from syscon and calculate PLL(x) frequency */
|
||||
+static unsigned long jh7110_pll_get_freq(struct jh7110_clk_pll_data *data,
|
||||
+ unsigned long parent_rate)
|
||||
+{
|
||||
+ struct jh7110_clk_pll_priv *priv = jh7110_pll_priv_from(data);
|
||||
+ struct jh7110_pll_syscon_offset *offset = &data->offset;
|
||||
+ struct jh7110_pll_syscon_mask *mask = &data->mask;
|
||||
+ struct jh7110_pll_syscon_shift *shift = &data->shift;
|
||||
+ unsigned long freq = 0;
|
||||
+ unsigned long frac_cal;
|
||||
+ u32 dacpd;
|
||||
+ u32 dsmpd;
|
||||
+ u32 fbdiv;
|
||||
+ u32 prediv;
|
||||
+ u32 postdiv1;
|
||||
+ u32 frac;
|
||||
+ u32 reg_val;
|
||||
+
|
||||
+ if (regmap_read(priv->syscon_regmap, offset->dacpd, ®_val))
|
||||
+ goto read_error;
|
||||
+ dacpd = (reg_val & mask->dacpd) >> shift->dacpd;
|
||||
+
|
||||
+ if (regmap_read(priv->syscon_regmap, offset->dsmpd, ®_val))
|
||||
+ goto read_error;
|
||||
+ dsmpd = (reg_val & mask->dsmpd) >> shift->dsmpd;
|
||||
+
|
||||
+ if (regmap_read(priv->syscon_regmap, offset->fbdiv, ®_val))
|
||||
+ goto read_error;
|
||||
+ fbdiv = (reg_val & mask->fbdiv) >> shift->fbdiv;
|
||||
+ /* fbdiv value should be 8 to 4095 */
|
||||
+ if (fbdiv < 8)
|
||||
+ goto read_error;
|
||||
+
|
||||
+ if (regmap_read(priv->syscon_regmap, offset->prediv, ®_val))
|
||||
+ goto read_error;
|
||||
+ prediv = (reg_val & mask->prediv) >> shift->prediv;
|
||||
+
|
||||
+ if (regmap_read(priv->syscon_regmap, offset->postdiv1, ®_val))
|
||||
+ goto read_error;
|
||||
+ /* postdiv1 = 2 ^ reg_val */
|
||||
+ postdiv1 = 1 << ((reg_val & mask->postdiv1) >> shift->postdiv1);
|
||||
+
|
||||
+ if (regmap_read(priv->syscon_regmap, offset->frac, ®_val))
|
||||
+ goto read_error;
|
||||
+ frac = (reg_val & mask->frac) >> shift->frac;
|
||||
+
|
||||
+ /*
|
||||
+ * Integer Mode (Both 1) or Fraction Mode (Both 0).
|
||||
+ * And the decimal places are counted by expanding them by
|
||||
+ * a factor of STARFIVE_PLL_FRAC_PATR_SIZE.
|
||||
+ */
|
||||
+ if (dacpd == 1 && dsmpd == 1)
|
||||
+ frac_cal = 0;
|
||||
+ else if (dacpd == 0 && dsmpd == 0)
|
||||
+ frac_cal = (unsigned long)frac * STARFIVE_PLL_FRAC_PATR_SIZE / (1 << 24);
|
||||
+ else
|
||||
+ goto read_error;
|
||||
+
|
||||
+ /* Fvco = Fref * (NI + NF) / M / Q1 */
|
||||
+ freq = parent_rate / STARFIVE_PLL_FRAC_PATR_SIZE *
|
||||
+ (fbdiv * STARFIVE_PLL_FRAC_PATR_SIZE + frac_cal) / prediv / postdiv1;
|
||||
+
|
||||
+read_error:
|
||||
+ return freq;
|
||||
+}
|
||||
+
|
||||
+static unsigned long jh7110_pll_rate_sub_fabs(unsigned long rate1, unsigned long rate2)
|
||||
+{
|
||||
+ return rate1 > rate2 ? (rate1 - rate2) : (rate2 - rate1);
|
||||
+}
|
||||
+
|
||||
+/* Select the appropriate frequency from the already configured registers value */
|
||||
+static void jh7110_pll_select_near_freq_id(struct jh7110_clk_pll_data *data,
|
||||
+ unsigned long rate)
|
||||
+{
|
||||
+ const struct starfive_pll_syscon_value *syscon_val;
|
||||
+ unsigned int id;
|
||||
+ unsigned int pll_arry_size;
|
||||
+ unsigned long rate_diff;
|
||||
+
|
||||
+ if (data->idx == JH7110_CLK_PLL0_OUT)
|
||||
+ pll_arry_size = ARRAY_SIZE(jh7110_pll0_syscon_freq);
|
||||
+ else if (data->idx == JH7110_CLK_PLL1_OUT)
|
||||
+ pll_arry_size = ARRAY_SIZE(jh7110_pll1_syscon_freq);
|
||||
+ else
|
||||
+ pll_arry_size = ARRAY_SIZE(jh7110_pll2_syscon_freq);
|
||||
+
|
||||
+ /* compare the frequency one by one from small to large in order */
|
||||
+ for (id = 0; id < pll_arry_size; id++) {
|
||||
+ if (data->idx == JH7110_CLK_PLL0_OUT)
|
||||
+ syscon_val = &jh7110_pll0_syscon_freq[id];
|
||||
+ else if (data->idx == JH7110_CLK_PLL1_OUT)
|
||||
+ syscon_val = &jh7110_pll1_syscon_freq[id];
|
||||
+ else
|
||||
+ syscon_val = &jh7110_pll2_syscon_freq[id];
|
||||
+
|
||||
+ if (rate == syscon_val->freq)
|
||||
+ goto match_end;
|
||||
+
|
||||
+ /* select near frequency */
|
||||
+ if (rate < syscon_val->freq) {
|
||||
+ /* The last frequency is closer to the target rate than this time. */
|
||||
+ if (id > 0)
|
||||
+ if (rate_diff < jh7110_pll_rate_sub_fabs(rate, syscon_val->freq))
|
||||
+ id--;
|
||||
+
|
||||
+ goto match_end;
|
||||
+ } else {
|
||||
+ rate_diff = jh7110_pll_rate_sub_fabs(rate, syscon_val->freq);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+match_end:
|
||||
+ data->freq_select_idx = id;
|
||||
+}
|
||||
+
|
||||
+static int jh7110_pll_set_freq_syscon(struct jh7110_clk_pll_data *data)
|
||||
+{
|
||||
+ struct jh7110_clk_pll_priv *priv = jh7110_pll_priv_from(data);
|
||||
+ struct jh7110_pll_syscon_offset *offset = &data->offset;
|
||||
+ struct jh7110_pll_syscon_mask *mask = &data->mask;
|
||||
+ struct jh7110_pll_syscon_shift *shift = &data->shift;
|
||||
+ unsigned int freq_idx = data->freq_select_idx;
|
||||
+ const struct starfive_pll_syscon_value *syscon_val;
|
||||
+ int ret;
|
||||
+
|
||||
+ if (data->idx == JH7110_CLK_PLL0_OUT)
|
||||
+ syscon_val = &jh7110_pll0_syscon_freq[freq_idx];
|
||||
+ else if (data->idx == JH7110_CLK_PLL1_OUT)
|
||||
+ syscon_val = &jh7110_pll1_syscon_freq[freq_idx];
|
||||
+ else
|
||||
+ syscon_val = &jh7110_pll2_syscon_freq[freq_idx];
|
||||
+
|
||||
+ ret = regmap_update_bits(priv->syscon_regmap, offset->dacpd, mask->dacpd,
|
||||
+ (syscon_val->dacpd << shift->dacpd));
|
||||
+ if (ret)
|
||||
+ goto set_failed;
|
||||
+
|
||||
+ ret = regmap_update_bits(priv->syscon_regmap, offset->dsmpd, mask->dsmpd,
|
||||
+ (syscon_val->dsmpd << shift->dsmpd));
|
||||
+ if (ret)
|
||||
+ goto set_failed;
|
||||
+
|
||||
+ ret = regmap_update_bits(priv->syscon_regmap, offset->prediv, mask->prediv,
|
||||
+ (syscon_val->prediv << shift->prediv));
|
||||
+ if (ret)
|
||||
+ goto set_failed;
|
||||
+
|
||||
+ ret = regmap_update_bits(priv->syscon_regmap, offset->fbdiv, mask->fbdiv,
|
||||
+ (syscon_val->fbdiv << shift->fbdiv));
|
||||
+ if (ret)
|
||||
+ goto set_failed;
|
||||
+
|
||||
+ ret = regmap_update_bits(priv->syscon_regmap, offset->postdiv1, mask->postdiv1,
|
||||
+ ((syscon_val->postdiv1 >> 1) << shift->postdiv1));
|
||||
+ if (ret)
|
||||
+ goto set_failed;
|
||||
+
|
||||
+ /* frac: Integer Mode (Both 1) or Fraction Mode (Both 0) */
|
||||
+ if (syscon_val->dacpd == 0 && syscon_val->dsmpd == 0)
|
||||
+ ret = regmap_update_bits(priv->syscon_regmap, offset->frac, mask->frac,
|
||||
+ (syscon_val->frac << shift->frac));
|
||||
+ else if (syscon_val->dacpd != syscon_val->dsmpd)
|
||||
+ ret = -EINVAL;
|
||||
+
|
||||
+set_failed:
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static unsigned long jh7110_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
|
||||
+{
|
||||
+ struct jh7110_clk_pll_data *data = jh7110_pll_data_from(hw);
|
||||
+
|
||||
+ return jh7110_pll_get_freq(data, parent_rate);
|
||||
+}
|
||||
+
|
||||
+static int jh7110_pll_determine_rate(struct clk_hw *hw, struct clk_rate_request *req)
|
||||
+{
|
||||
+ struct jh7110_clk_pll_data *data = jh7110_pll_data_from(hw);
|
||||
+
|
||||
+ jh7110_pll_select_near_freq_id(data, req->rate);
|
||||
+
|
||||
+ if (data->idx == JH7110_CLK_PLL0_OUT)
|
||||
+ req->rate = jh7110_pll0_syscon_freq[data->freq_select_idx].freq;
|
||||
+ else if (data->idx == JH7110_CLK_PLL1_OUT)
|
||||
+ req->rate = jh7110_pll1_syscon_freq[data->freq_select_idx].freq;
|
||||
+ else
|
||||
+ req->rate = jh7110_pll2_syscon_freq[data->freq_select_idx].freq;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int jh7110_pll_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
+ unsigned long parent_rate)
|
||||
+{
|
||||
+ struct jh7110_clk_pll_data *data = jh7110_pll_data_from(hw);
|
||||
+
|
||||
+ return jh7110_pll_set_freq_syscon(data);
|
||||
+}
|
||||
+
|
||||
+#ifdef CONFIG_DEBUG_FS
|
||||
+static void jh7110_pll_debug_init(struct clk_hw *hw, struct dentry *dentry)
|
||||
+{
|
||||
+ static const struct debugfs_reg32 jh7110_clk_pll_reg = {
|
||||
+ .name = "CTRL",
|
||||
+ .offset = 0,
|
||||
+ };
|
||||
+ struct jh7110_clk_pll_data *data = jh7110_pll_data_from(hw);
|
||||
+ struct jh7110_clk_pll_priv *priv = jh7110_pll_priv_from(data);
|
||||
+ struct debugfs_regset32 *regset;
|
||||
+
|
||||
+ regset = devm_kzalloc(priv->dev, sizeof(*regset), GFP_KERNEL);
|
||||
+ if (!regset)
|
||||
+ return;
|
||||
+
|
||||
+ regset->regs = &jh7110_clk_pll_reg;
|
||||
+ regset->nregs = 1;
|
||||
+
|
||||
+ debugfs_create_regset32("registers", 0400, dentry, regset);
|
||||
+}
|
||||
+#else
|
||||
+#define jh7110_pll_debug_init NULL
|
||||
+#endif
|
||||
+
|
||||
+static const struct clk_ops jh7110_pll_ops = {
|
||||
+ .recalc_rate = jh7110_pll_recalc_rate,
|
||||
+ .determine_rate = jh7110_pll_determine_rate,
|
||||
+ .set_rate = jh7110_pll_set_rate,
|
||||
+ .debug_init = jh7110_pll_debug_init,
|
||||
+};
|
||||
+
|
||||
+/* get offset, mask and shift of PLL(x) syscon */
|
||||
+static int jh7110_pll_data_get(struct jh7110_clk_pll_data *data, int index)
|
||||
+{
|
||||
+ struct jh7110_pll_syscon_offset *offset = &data->offset;
|
||||
+ struct jh7110_pll_syscon_mask *mask = &data->mask;
|
||||
+ struct jh7110_pll_syscon_shift *shift = &data->shift;
|
||||
+
|
||||
+ if (index == JH7110_CLK_PLL0_OUT) {
|
||||
+ offset->dacpd = STARFIVE_JH7110_PLL0_DACPD_OFFSET;
|
||||
+ offset->dsmpd = STARFIVE_JH7110_PLL0_DSMPD_OFFSET;
|
||||
+ offset->fbdiv = STARFIVE_JH7110_PLL0_FBDIV_OFFSET;
|
||||
+ offset->frac = STARFIVE_JH7110_PLL0_FRAC_OFFSET;
|
||||
+ offset->prediv = STARFIVE_JH7110_PLL0_PREDIV_OFFSET;
|
||||
+ offset->postdiv1 = STARFIVE_JH7110_PLL0_POSTDIV1_OFFSET;
|
||||
+
|
||||
+ mask->dacpd = STARFIVE_JH7110_PLL0_DACPD_MASK;
|
||||
+ mask->dsmpd = STARFIVE_JH7110_PLL0_DSMPD_MASK;
|
||||
+ mask->fbdiv = STARFIVE_JH7110_PLL0_FBDIV_MASK;
|
||||
+ mask->frac = STARFIVE_JH7110_PLL0_FRAC_MASK;
|
||||
+ mask->prediv = STARFIVE_JH7110_PLL0_PREDIV_MASK;
|
||||
+ mask->postdiv1 = STARFIVE_JH7110_PLL0_POSTDIV1_MASK;
|
||||
+
|
||||
+ shift->dacpd = STARFIVE_JH7110_PLL0_DACPD_SHIFT;
|
||||
+ shift->dsmpd = STARFIVE_JH7110_PLL0_DSMPD_SHIFT;
|
||||
+ shift->fbdiv = STARFIVE_JH7110_PLL0_FBDIV_SHIFT;
|
||||
+ shift->frac = STARFIVE_JH7110_PLL0_FRAC_SHIFT;
|
||||
+ shift->prediv = STARFIVE_JH7110_PLL0_PREDIV_SHIFT;
|
||||
+ shift->postdiv1 = STARFIVE_JH7110_PLL0_POSTDIV1_SHIFT;
|
||||
+
|
||||
+ } else if (index == JH7110_CLK_PLL1_OUT) {
|
||||
+ offset->dacpd = STARFIVE_JH7110_PLL1_DACPD_OFFSET;
|
||||
+ offset->dsmpd = STARFIVE_JH7110_PLL1_DSMPD_OFFSET;
|
||||
+ offset->fbdiv = STARFIVE_JH7110_PLL1_FBDIV_OFFSET;
|
||||
+ offset->frac = STARFIVE_JH7110_PLL1_FRAC_OFFSET;
|
||||
+ offset->prediv = STARFIVE_JH7110_PLL1_PREDIV_OFFSET;
|
||||
+ offset->postdiv1 = STARFIVE_JH7110_PLL1_POSTDIV1_OFFSET;
|
||||
+
|
||||
+ mask->dacpd = STARFIVE_JH7110_PLL1_DACPD_MASK;
|
||||
+ mask->dsmpd = STARFIVE_JH7110_PLL1_DSMPD_MASK;
|
||||
+ mask->fbdiv = STARFIVE_JH7110_PLL1_FBDIV_MASK;
|
||||
+ mask->frac = STARFIVE_JH7110_PLL1_FRAC_MASK;
|
||||
+ mask->prediv = STARFIVE_JH7110_PLL1_PREDIV_MASK;
|
||||
+ mask->postdiv1 = STARFIVE_JH7110_PLL1_POSTDIV1_MASK;
|
||||
+
|
||||
+ shift->dacpd = STARFIVE_JH7110_PLL1_DACPD_SHIFT;
|
||||
+ shift->dsmpd = STARFIVE_JH7110_PLL1_DSMPD_SHIFT;
|
||||
+ shift->fbdiv = STARFIVE_JH7110_PLL1_FBDIV_SHIFT;
|
||||
+ shift->frac = STARFIVE_JH7110_PLL1_FRAC_SHIFT;
|
||||
+ shift->prediv = STARFIVE_JH7110_PLL1_PREDIV_SHIFT;
|
||||
+ shift->postdiv1 = STARFIVE_JH7110_PLL1_POSTDIV1_SHIFT;
|
||||
+
|
||||
+ } else if (index == JH7110_CLK_PLL2_OUT) {
|
||||
+ offset->dacpd = STARFIVE_JH7110_PLL2_DACPD_OFFSET;
|
||||
+ offset->dsmpd = STARFIVE_JH7110_PLL2_DSMPD_OFFSET;
|
||||
+ offset->fbdiv = STARFIVE_JH7110_PLL2_FBDIV_OFFSET;
|
||||
+ offset->frac = STARFIVE_JH7110_PLL2_FRAC_OFFSET;
|
||||
+ offset->prediv = STARFIVE_JH7110_PLL2_PREDIV_OFFSET;
|
||||
+ offset->postdiv1 = STARFIVE_JH7110_PLL2_POSTDIV1_OFFSET;
|
||||
+
|
||||
+ mask->dacpd = STARFIVE_JH7110_PLL2_DACPD_MASK;
|
||||
+ mask->dsmpd = STARFIVE_JH7110_PLL2_DSMPD_MASK;
|
||||
+ mask->fbdiv = STARFIVE_JH7110_PLL2_FBDIV_MASK;
|
||||
+ mask->frac = STARFIVE_JH7110_PLL2_FRAC_MASK;
|
||||
+ mask->prediv = STARFIVE_JH7110_PLL2_PREDIV_MASK;
|
||||
+ mask->postdiv1 = STARFIVE_JH7110_PLL2_POSTDIV1_MASK;
|
||||
+
|
||||
+ shift->dacpd = STARFIVE_JH7110_PLL2_DACPD_SHIFT;
|
||||
+ shift->dsmpd = STARFIVE_JH7110_PLL2_DSMPD_SHIFT;
|
||||
+ shift->fbdiv = STARFIVE_JH7110_PLL2_FBDIV_SHIFT;
|
||||
+ shift->frac = STARFIVE_JH7110_PLL2_FRAC_SHIFT;
|
||||
+ shift->prediv = STARFIVE_JH7110_PLL2_PREDIV_SHIFT;
|
||||
+ shift->postdiv1 = STARFIVE_JH7110_PLL2_POSTDIV1_SHIFT;
|
||||
+
|
||||
+ } else {
|
||||
+ return -ENOENT;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct clk_hw *jh7110_pll_get(struct of_phandle_args *clkspec, void *data)
|
||||
+{
|
||||
+ struct jh7110_clk_pll_priv *priv = data;
|
||||
+ unsigned int idx = clkspec->args[0];
|
||||
+
|
||||
+ if (idx < JH7110_PLLCLK_END)
|
||||
+ return &priv->data[idx].hw;
|
||||
+
|
||||
+ return ERR_PTR(-EINVAL);
|
||||
+}
|
||||
+
|
||||
+static int jh7110_pll_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ const char *pll_name[JH7110_PLLCLK_END] = {
|
||||
+ "pll0_out",
|
||||
+ "pll1_out",
|
||||
+ "pll2_out"
|
||||
+ };
|
||||
+ struct jh7110_clk_pll_priv *priv;
|
||||
+ struct jh7110_clk_pll_data *data;
|
||||
+ int ret;
|
||||
+ unsigned int idx;
|
||||
+
|
||||
+ priv = devm_kzalloc(&pdev->dev, struct_size(priv, data, JH7110_PLLCLK_END),
|
||||
+ GFP_KERNEL);
|
||||
+ if (!priv)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ priv->dev = &pdev->dev;
|
||||
+ priv->syscon_regmap = syscon_node_to_regmap(priv->dev->of_node->parent);
|
||||
+ if (IS_ERR(priv->syscon_regmap))
|
||||
+ return PTR_ERR(priv->syscon_regmap);
|
||||
+
|
||||
+ for (idx = 0; idx < JH7110_PLLCLK_END; idx++) {
|
||||
+ struct clk_parent_data parents = {
|
||||
+ .index = 0,
|
||||
+ };
|
||||
+ struct clk_init_data init = {
|
||||
+ .name = pll_name[idx],
|
||||
+ .ops = &jh7110_pll_ops,
|
||||
+ .parent_data = &parents,
|
||||
+ .num_parents = 1,
|
||||
+ .flags = 0,
|
||||
+ };
|
||||
+
|
||||
+ data = &priv->data[idx];
|
||||
+
|
||||
+ ret = jh7110_pll_data_get(data, idx);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ data->hw.init = &init;
|
||||
+ data->idx = idx;
|
||||
+
|
||||
+ ret = devm_clk_hw_register(&pdev->dev, &data->hw);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ return devm_of_clk_add_hw_provider(&pdev->dev, jh7110_pll_get, priv);
|
||||
+}
|
||||
+
|
||||
+static const struct of_device_id jh7110_pll_match[] = {
|
||||
+ { .compatible = "starfive,jh7110-pll" },
|
||||
+ { /* sentinel */ }
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, jh7110_pll_match);
|
||||
+
|
||||
+static struct platform_driver jh7110_pll_driver = {
|
||||
+ .driver = {
|
||||
+ .name = "clk-starfive-jh7110-pll",
|
||||
+ .of_match_table = jh7110_pll_match,
|
||||
+ },
|
||||
+};
|
||||
+builtin_platform_driver_probe(jh7110_pll_driver, jh7110_pll_probe);
|
||||
--- /dev/null
|
||||
+++ b/drivers/clk/starfive/clk-starfive-jh7110-pll.h
|
||||
@@ -0,0 +1,293 @@
|
||||
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
|
||||
+/*
|
||||
+ * StarFive JH7110 PLL Clock Generator Driver
|
||||
+ *
|
||||
+ * Copyright (C) 2023 StarFive Technology Co., Ltd.
|
||||
+ */
|
||||
+
|
||||
+#ifndef _CLK_STARFIVE_JH7110_PLL_H_
|
||||
+#define _CLK_STARFIVE_JH7110_PLL_H_
|
||||
+
|
||||
+#include <linux/bits.h>
|
||||
+
|
||||
+/* The decimal places are counted by expanding them by a factor of STARFIVE_PLL_FRAC_PATR_SIZE */
|
||||
+#define STARFIVE_PLL_FRAC_PATR_SIZE 1000
|
||||
+
|
||||
+#define STARFIVE_JH7110_PLL0_DACPD_OFFSET 0x18
|
||||
+#define STARFIVE_JH7110_PLL0_DACPD_SHIFT 24
|
||||
+#define STARFIVE_JH7110_PLL0_DACPD_MASK BIT(24)
|
||||
+#define STARFIVE_JH7110_PLL0_DSMPD_OFFSET 0x18
|
||||
+#define STARFIVE_JH7110_PLL0_DSMPD_SHIFT 25
|
||||
+#define STARFIVE_JH7110_PLL0_DSMPD_MASK BIT(25)
|
||||
+#define STARFIVE_JH7110_PLL0_FBDIV_OFFSET 0x1c
|
||||
+#define STARFIVE_JH7110_PLL0_FBDIV_SHIFT 0
|
||||
+#define STARFIVE_JH7110_PLL0_FBDIV_MASK GENMASK(11, 0)
|
||||
+#define STARFIVE_JH7110_PLL0_FRAC_OFFSET 0x20
|
||||
+#define STARFIVE_JH7110_PLL0_FRAC_SHIFT 0
|
||||
+#define STARFIVE_JH7110_PLL0_FRAC_MASK GENMASK(23, 0)
|
||||
+#define STARFIVE_JH7110_PLL0_POSTDIV1_OFFSET 0x20
|
||||
+#define STARFIVE_JH7110_PLL0_POSTDIV1_SHIFT 28
|
||||
+#define STARFIVE_JH7110_PLL0_POSTDIV1_MASK GENMASK(29, 28)
|
||||
+#define STARFIVE_JH7110_PLL0_PREDIV_OFFSET 0x24
|
||||
+#define STARFIVE_JH7110_PLL0_PREDIV_SHIFT 0
|
||||
+#define STARFIVE_JH7110_PLL0_PREDIV_MASK GENMASK(5, 0)
|
||||
+
|
||||
+#define STARFIVE_JH7110_PLL1_DACPD_OFFSET 0x24
|
||||
+#define STARFIVE_JH7110_PLL1_DACPD_SHIFT 15
|
||||
+#define STARFIVE_JH7110_PLL1_DACPD_MASK BIT(15)
|
||||
+#define STARFIVE_JH7110_PLL1_DSMPD_OFFSET 0x24
|
||||
+#define STARFIVE_JH7110_PLL1_DSMPD_SHIFT 16
|
||||
+#define STARFIVE_JH7110_PLL1_DSMPD_MASK BIT(16)
|
||||
+#define STARFIVE_JH7110_PLL1_FBDIV_OFFSET 0x24
|
||||
+#define STARFIVE_JH7110_PLL1_FBDIV_SHIFT 17
|
||||
+#define STARFIVE_JH7110_PLL1_FBDIV_MASK GENMASK(28, 17)
|
||||
+#define STARFIVE_JH7110_PLL1_FRAC_OFFSET 0x28
|
||||
+#define STARFIVE_JH7110_PLL1_FRAC_SHIFT 0
|
||||
+#define STARFIVE_JH7110_PLL1_FRAC_MASK GENMASK(23, 0)
|
||||
+#define STARFIVE_JH7110_PLL1_POSTDIV1_OFFSET 0x28
|
||||
+#define STARFIVE_JH7110_PLL1_POSTDIV1_SHIFT 28
|
||||
+#define STARFIVE_JH7110_PLL1_POSTDIV1_MASK GENMASK(29, 28)
|
||||
+#define STARFIVE_JH7110_PLL1_PREDIV_OFFSET 0x2c
|
||||
+#define STARFIVE_JH7110_PLL1_PREDIV_SHIFT 0
|
||||
+#define STARFIVE_JH7110_PLL1_PREDIV_MASK GENMASK(5, 0)
|
||||
+
|
||||
+#define STARFIVE_JH7110_PLL2_DACPD_OFFSET 0x2c
|
||||
+#define STARFIVE_JH7110_PLL2_DACPD_SHIFT 15
|
||||
+#define STARFIVE_JH7110_PLL2_DACPD_MASK BIT(15)
|
||||
+#define STARFIVE_JH7110_PLL2_DSMPD_OFFSET 0x2c
|
||||
+#define STARFIVE_JH7110_PLL2_DSMPD_SHIFT 16
|
||||
+#define STARFIVE_JH7110_PLL2_DSMPD_MASK BIT(16)
|
||||
+#define STARFIVE_JH7110_PLL2_FBDIV_OFFSET 0x2c
|
||||
+#define STARFIVE_JH7110_PLL2_FBDIV_SHIFT 17
|
||||
+#define STARFIVE_JH7110_PLL2_FBDIV_MASK GENMASK(28, 17)
|
||||
+#define STARFIVE_JH7110_PLL2_FRAC_OFFSET 0x30
|
||||
+#define STARFIVE_JH7110_PLL2_FRAC_SHIFT 0
|
||||
+#define STARFIVE_JH7110_PLL2_FRAC_MASK GENMASK(23, 0)
|
||||
+#define STARFIVE_JH7110_PLL2_POSTDIV1_OFFSET 0x30
|
||||
+#define STARFIVE_JH7110_PLL2_POSTDIV1_SHIFT 28
|
||||
+#define STARFIVE_JH7110_PLL2_POSTDIV1_MASK GENMASK(29, 28)
|
||||
+#define STARFIVE_JH7110_PLL2_PREDIV_OFFSET 0x34
|
||||
+#define STARFIVE_JH7110_PLL2_PREDIV_SHIFT 0
|
||||
+#define STARFIVE_JH7110_PLL2_PREDIV_MASK GENMASK(5, 0)
|
||||
+
|
||||
+struct jh7110_pll_syscon_offset {
|
||||
+ unsigned int dacpd;
|
||||
+ unsigned int dsmpd;
|
||||
+ unsigned int fbdiv;
|
||||
+ unsigned int frac;
|
||||
+ unsigned int prediv;
|
||||
+ unsigned int postdiv1;
|
||||
+};
|
||||
+
|
||||
+struct jh7110_pll_syscon_mask {
|
||||
+ u32 dacpd;
|
||||
+ u32 dsmpd;
|
||||
+ u32 fbdiv;
|
||||
+ u32 frac;
|
||||
+ u32 prediv;
|
||||
+ u32 postdiv1;
|
||||
+};
|
||||
+
|
||||
+struct jh7110_pll_syscon_shift {
|
||||
+ char dacpd;
|
||||
+ char dsmpd;
|
||||
+ char fbdiv;
|
||||
+ char frac;
|
||||
+ char prediv;
|
||||
+ char postdiv1;
|
||||
+};
|
||||
+
|
||||
+struct jh7110_clk_pll_data {
|
||||
+ struct clk_hw hw;
|
||||
+ unsigned int idx;
|
||||
+ unsigned int freq_select_idx;
|
||||
+
|
||||
+ struct jh7110_pll_syscon_offset offset;
|
||||
+ struct jh7110_pll_syscon_mask mask;
|
||||
+ struct jh7110_pll_syscon_shift shift;
|
||||
+};
|
||||
+
|
||||
+struct jh7110_clk_pll_priv {
|
||||
+ struct device *dev;
|
||||
+ struct regmap *syscon_regmap;
|
||||
+ struct jh7110_clk_pll_data data[];
|
||||
+};
|
||||
+
|
||||
+struct starfive_pll_syscon_value {
|
||||
+ unsigned long freq;
|
||||
+ u32 prediv;
|
||||
+ u32 fbdiv;
|
||||
+ u32 postdiv1;
|
||||
+/* Both daxpd and dsmpd set 1 while integer mode */
|
||||
+/* Both daxpd and dsmpd set 0 while fraction mode */
|
||||
+ u32 dacpd;
|
||||
+ u32 dsmpd;
|
||||
+/* frac value should be decimals multiplied by 2^24 */
|
||||
+ u32 frac;
|
||||
+};
|
||||
+
|
||||
+enum starfive_pll0_freq_index {
|
||||
+ PLL0_FREQ_375 = 0,
|
||||
+ PLL0_FREQ_500,
|
||||
+ PLL0_FREQ_625,
|
||||
+ PLL0_FREQ_750,
|
||||
+ PLL0_FREQ_875,
|
||||
+ PLL0_FREQ_1000,
|
||||
+ PLL0_FREQ_1250,
|
||||
+ PLL0_FREQ_1375,
|
||||
+ PLL0_FREQ_1500,
|
||||
+ PLL0_FREQ_MAX
|
||||
+};
|
||||
+
|
||||
+enum starfive_pll1_freq_index {
|
||||
+ PLL1_FREQ_1066 = 0,
|
||||
+ PLL1_FREQ_1200,
|
||||
+ PLL1_FREQ_1400,
|
||||
+ PLL1_FREQ_1600,
|
||||
+ PLL1_FREQ_MAX
|
||||
+};
|
||||
+
|
||||
+enum starfive_pll2_freq_index {
|
||||
+ PLL2_FREQ_1188 = 0,
|
||||
+ PLL2_FREQ_12288,
|
||||
+ PLL2_FREQ_MAX
|
||||
+};
|
||||
+
|
||||
+/*
|
||||
+ * Because the pll frequency is relatively fixed,
|
||||
+ * it cannot be set arbitrarily, so it needs a specific configuration.
|
||||
+ * PLL0 frequency should be multiple of 125MHz (USB frequency).
|
||||
+ */
|
||||
+static const struct starfive_pll_syscon_value
|
||||
+ jh7110_pll0_syscon_freq[PLL0_FREQ_MAX] = {
|
||||
+ [PLL0_FREQ_375] = {
|
||||
+ .freq = 375000000,
|
||||
+ .prediv = 8,
|
||||
+ .fbdiv = 125,
|
||||
+ .postdiv1 = 1,
|
||||
+ .dacpd = 1,
|
||||
+ .dsmpd = 1,
|
||||
+ },
|
||||
+ [PLL0_FREQ_500] = {
|
||||
+ .freq = 500000000,
|
||||
+ .prediv = 6,
|
||||
+ .fbdiv = 125,
|
||||
+ .postdiv1 = 1,
|
||||
+ .dacpd = 1,
|
||||
+ .dsmpd = 1,
|
||||
+ },
|
||||
+ [PLL0_FREQ_625] = {
|
||||
+ .freq = 625000000,
|
||||
+ .prediv = 24,
|
||||
+ .fbdiv = 625,
|
||||
+ .postdiv1 = 1,
|
||||
+ .dacpd = 1,
|
||||
+ .dsmpd = 1,
|
||||
+ },
|
||||
+ [PLL0_FREQ_750] = {
|
||||
+ .freq = 750000000,
|
||||
+ .prediv = 4,
|
||||
+ .fbdiv = 125,
|
||||
+ .postdiv1 = 1,
|
||||
+ .dacpd = 1,
|
||||
+ .dsmpd = 1,
|
||||
+ },
|
||||
+ [PLL0_FREQ_875] = {
|
||||
+ .freq = 875000000,
|
||||
+ .prediv = 24,
|
||||
+ .fbdiv = 875,
|
||||
+ .postdiv1 = 1,
|
||||
+ .dacpd = 1,
|
||||
+ .dsmpd = 1,
|
||||
+ },
|
||||
+ [PLL0_FREQ_1000] = {
|
||||
+ .freq = 1000000000,
|
||||
+ .prediv = 3,
|
||||
+ .fbdiv = 125,
|
||||
+ .postdiv1 = 1,
|
||||
+ .dacpd = 1,
|
||||
+ .dsmpd = 1,
|
||||
+ },
|
||||
+ [PLL0_FREQ_1250] = {
|
||||
+ .freq = 1250000000,
|
||||
+ .prediv = 12,
|
||||
+ .fbdiv = 625,
|
||||
+ .postdiv1 = 1,
|
||||
+ .dacpd = 1,
|
||||
+ .dsmpd = 1,
|
||||
+ },
|
||||
+ [PLL0_FREQ_1375] = {
|
||||
+ .freq = 1375000000,
|
||||
+ .prediv = 24,
|
||||
+ .fbdiv = 1375,
|
||||
+ .postdiv1 = 1,
|
||||
+ .dacpd = 1,
|
||||
+ .dsmpd = 1,
|
||||
+ },
|
||||
+ [PLL0_FREQ_1500] = {
|
||||
+ .freq = 1500000000,
|
||||
+ .prediv = 2,
|
||||
+ .fbdiv = 125,
|
||||
+ .postdiv1 = 1,
|
||||
+ .dacpd = 1,
|
||||
+ .dsmpd = 1,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static const struct starfive_pll_syscon_value
|
||||
+ jh7110_pll1_syscon_freq[PLL1_FREQ_MAX] = {
|
||||
+ [PLL1_FREQ_1066] = {
|
||||
+ .freq = 1066000000,
|
||||
+ .prediv = 12,
|
||||
+ .fbdiv = 533,
|
||||
+ .postdiv1 = 1,
|
||||
+ .dacpd = 1,
|
||||
+ .dsmpd = 1,
|
||||
+ },
|
||||
+ [PLL1_FREQ_1200] = {
|
||||
+ .freq = 1200000000,
|
||||
+ .prediv = 1,
|
||||
+ .fbdiv = 50,
|
||||
+ .postdiv1 = 1,
|
||||
+ .dacpd = 1,
|
||||
+ .dsmpd = 1,
|
||||
+ },
|
||||
+ [PLL1_FREQ_1400] = {
|
||||
+ .freq = 1400000000,
|
||||
+ .prediv = 6,
|
||||
+ .fbdiv = 350,
|
||||
+ .postdiv1 = 1,
|
||||
+ .dacpd = 1,
|
||||
+ .dsmpd = 1,
|
||||
+ },
|
||||
+ [PLL1_FREQ_1600] = {
|
||||
+ .freq = 1600000000,
|
||||
+ .prediv = 3,
|
||||
+ .fbdiv = 200,
|
||||
+ .postdiv1 = 1,
|
||||
+ .dacpd = 1,
|
||||
+ .dsmpd = 1,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static const struct starfive_pll_syscon_value
|
||||
+ jh7110_pll2_syscon_freq[PLL2_FREQ_MAX] = {
|
||||
+ [PLL2_FREQ_1188] = {
|
||||
+ .freq = 1188000000,
|
||||
+ .prediv = 2,
|
||||
+ .fbdiv = 99,
|
||||
+ .postdiv1 = 1,
|
||||
+ .dacpd = 1,
|
||||
+ .dsmpd = 1,
|
||||
+ },
|
||||
+ [PLL2_FREQ_12288] = {
|
||||
+ .freq = 1228800000,
|
||||
+ .prediv = 5,
|
||||
+ .fbdiv = 256,
|
||||
+ .postdiv1 = 1,
|
||||
+ .dacpd = 1,
|
||||
+ .dsmpd = 1,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+#endif
|
@ -0,0 +1,75 @@
|
||||
From 1f788a0a5092b1e1cfd02aa7f31ceb551befa7e6 Mon Sep 17 00:00:00 2001
|
||||
From: Xingyu Wu <xingyu.wu@starfivetech.com>
|
||||
Date: Tue, 14 Mar 2023 16:43:50 +0800
|
||||
Subject: [PATCH 033/122] dt-bindings: clock: jh7110-syscrg: Add PLL clock
|
||||
inputs
|
||||
|
||||
Add PLL clock inputs from PLL clock generator.
|
||||
|
||||
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
|
||||
Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
|
||||
---
|
||||
.../clock/starfive,jh7110-syscrg.yaml | 20 +++++++++++++++++--
|
||||
1 file changed, 18 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/Documentation/devicetree/bindings/clock/starfive,jh7110-syscrg.yaml
|
||||
+++ b/Documentation/devicetree/bindings/clock/starfive,jh7110-syscrg.yaml
|
||||
@@ -27,6 +27,9 @@ properties:
|
||||
- description: External I2S RX left/right channel clock
|
||||
- description: External TDM clock
|
||||
- description: External audio master clock
|
||||
+ - description: PLL0
|
||||
+ - description: PLL1
|
||||
+ - description: PLL2
|
||||
|
||||
- items:
|
||||
- description: Main Oscillator (24 MHz)
|
||||
@@ -38,6 +41,9 @@ properties:
|
||||
- description: External I2S RX left/right channel clock
|
||||
- description: External TDM clock
|
||||
- description: External audio master clock
|
||||
+ - description: PLL0
|
||||
+ - description: PLL1
|
||||
+ - description: PLL2
|
||||
|
||||
clock-names:
|
||||
oneOf:
|
||||
@@ -52,6 +58,9 @@ properties:
|
||||
- const: i2srx_lrck_ext
|
||||
- const: tdm_ext
|
||||
- const: mclk_ext
|
||||
+ - const: pll0_out
|
||||
+ - const: pll1_out
|
||||
+ - const: pll2_out
|
||||
|
||||
- items:
|
||||
- const: osc
|
||||
@@ -63,6 +72,9 @@ properties:
|
||||
- const: i2srx_lrck_ext
|
||||
- const: tdm_ext
|
||||
- const: mclk_ext
|
||||
+ - const: pll0_out
|
||||
+ - const: pll1_out
|
||||
+ - const: pll2_out
|
||||
|
||||
'#clock-cells':
|
||||
const: 1
|
||||
@@ -93,12 +105,16 @@ examples:
|
||||
<&gmac1_rgmii_rxin>,
|
||||
<&i2stx_bclk_ext>, <&i2stx_lrck_ext>,
|
||||
<&i2srx_bclk_ext>, <&i2srx_lrck_ext>,
|
||||
- <&tdm_ext>, <&mclk_ext>;
|
||||
+ <&tdm_ext>, <&mclk_ext>,
|
||||
+ <&pllclk JH7110_CLK_PLL0_OUT>,
|
||||
+ <&pllclk JH7110_CLK_PLL1_OUT>,
|
||||
+ <&pllclk JH7110_CLK_PLL2_OUT>;
|
||||
clock-names = "osc", "gmac1_rmii_refin",
|
||||
"gmac1_rgmii_rxin",
|
||||
"i2stx_bclk_ext", "i2stx_lrck_ext",
|
||||
"i2srx_bclk_ext", "i2srx_lrck_ext",
|
||||
- "tdm_ext", "mclk_ext";
|
||||
+ "tdm_ext", "mclk_ext",
|
||||
+ "pll0_out", "pll1_out", "pll2_out";
|
||||
#clock-cells = <1>;
|
||||
#reset-cells = <1>;
|
||||
};
|
@ -0,0 +1,71 @@
|
||||
From ffd7ee4fbd69d477a2156d9cba6ae80434a4c894 Mon Sep 17 00:00:00 2001
|
||||
From: Xingyu Wu <xingyu.wu@starfivetech.com>
|
||||
Date: Tue, 14 Mar 2023 17:16:07 +0800
|
||||
Subject: [PATCH 034/122] clk: starfive: jh7110-sys: Modify PLL clocks source
|
||||
|
||||
Modify PLL clocks source to be got from dts instead of
|
||||
the fixed factor clocks.
|
||||
|
||||
Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
|
||||
---
|
||||
drivers/clk/starfive/Kconfig | 1 +
|
||||
.../clk/starfive/clk-starfive-jh7110-sys.c | 31 ++++---------------
|
||||
2 files changed, 7 insertions(+), 25 deletions(-)
|
||||
|
||||
--- a/drivers/clk/starfive/Kconfig
|
||||
+++ b/drivers/clk/starfive/Kconfig
|
||||
@@ -35,6 +35,7 @@ config CLK_STARFIVE_JH7110_SYS
|
||||
select AUXILIARY_BUS
|
||||
select CLK_STARFIVE_JH71X0
|
||||
select RESET_STARFIVE_JH7110
|
||||
+ select CLK_STARFIVE_JH7110_PLL
|
||||
default ARCH_STARFIVE
|
||||
help
|
||||
Say yes here to support the system clock controller on the
|
||||
--- a/drivers/clk/starfive/clk-starfive-jh7110-sys.c
|
||||
+++ b/drivers/clk/starfive/clk-starfive-jh7110-sys.c
|
||||
@@ -404,29 +404,6 @@ static int __init jh7110_syscrg_probe(st
|
||||
|
||||
dev_set_drvdata(priv->dev, (void *)(&priv->base));
|
||||
|
||||
- /*
|
||||
- * These PLL clocks are not actually fixed factor clocks and can be
|
||||
- * controlled by the syscon registers of JH7110. They will be dropped
|
||||
- * and registered in the PLL clock driver instead.
|
||||
- */
|
||||
- /* 24MHz -> 1000.0MHz */
|
||||
- priv->pll[0] = devm_clk_hw_register_fixed_factor(priv->dev, "pll0_out",
|
||||
- "osc", 0, 125, 3);
|
||||
- if (IS_ERR(priv->pll[0]))
|
||||
- return PTR_ERR(priv->pll[0]);
|
||||
-
|
||||
- /* 24MHz -> 1066.0MHz */
|
||||
- priv->pll[1] = devm_clk_hw_register_fixed_factor(priv->dev, "pll1_out",
|
||||
- "osc", 0, 533, 12);
|
||||
- if (IS_ERR(priv->pll[1]))
|
||||
- return PTR_ERR(priv->pll[1]);
|
||||
-
|
||||
- /* 24MHz -> 1188.0MHz */
|
||||
- priv->pll[2] = devm_clk_hw_register_fixed_factor(priv->dev, "pll2_out",
|
||||
- "osc", 0, 99, 2);
|
||||
- if (IS_ERR(priv->pll[2]))
|
||||
- return PTR_ERR(priv->pll[2]);
|
||||
-
|
||||
for (idx = 0; idx < JH7110_SYSCLK_END; idx++) {
|
||||
u32 max = jh7110_sysclk_data[idx].max;
|
||||
struct clk_parent_data parents[4] = {};
|
||||
@@ -464,8 +441,12 @@ static int __init jh7110_syscrg_probe(st
|
||||
parents[i].fw_name = "tdm_ext";
|
||||
else if (pidx == JH7110_SYSCLK_MCLK_EXT)
|
||||
parents[i].fw_name = "mclk_ext";
|
||||
- else
|
||||
- parents[i].hw = priv->pll[pidx - JH7110_SYSCLK_PLL0_OUT];
|
||||
+ else if (pidx == JH7110_SYSCLK_PLL0_OUT)
|
||||
+ parents[i].fw_name = "pll0_out";
|
||||
+ else if (pidx == JH7110_SYSCLK_PLL1_OUT)
|
||||
+ parents[i].fw_name = "pll1_out";
|
||||
+ else if (pidx == JH7110_SYSCLK_PLL2_OUT)
|
||||
+ parents[i].fw_name = "pll2_out";
|
||||
}
|
||||
|
||||
clk->hw.init = &init;
|
@ -0,0 +1,86 @@
|
||||
From 35bc6491a7b24872155a616f7770d3a5d6e40344 Mon Sep 17 00:00:00 2001
|
||||
From: Walker Chen <walker.chen@starfivetech.com>
|
||||
Date: Thu, 19 Jan 2023 17:44:46 +0800
|
||||
Subject: [PATCH 035/122] dt-bindings: power: Add starfive,jh7110-pmu
|
||||
|
||||
Add bindings for the Power Management Unit on the StarFive JH7110 SoC.
|
||||
|
||||
Signed-off-by: Walker Chen <walker.chen@starfivetech.com>
|
||||
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
|
||||
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
|
||||
Reviewed-by: Heiko Stuebner <heiko@sntech.de>
|
||||
---
|
||||
.../bindings/power/starfive,jh7110-pmu.yaml | 45 +++++++++++++++++++
|
||||
.../dt-bindings/power/starfive,jh7110-pmu.h | 17 +++++++
|
||||
2 files changed, 62 insertions(+)
|
||||
create mode 100644 Documentation/devicetree/bindings/power/starfive,jh7110-pmu.yaml
|
||||
create mode 100644 include/dt-bindings/power/starfive,jh7110-pmu.h
|
||||
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/power/starfive,jh7110-pmu.yaml
|
||||
@@ -0,0 +1,45 @@
|
||||
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
+%YAML 1.2
|
||||
+---
|
||||
+$id: http://devicetree.org/schemas/power/starfive,jh7110-pmu.yaml#
|
||||
+$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
+
|
||||
+title: StarFive JH7110 Power Management Unit
|
||||
+
|
||||
+maintainers:
|
||||
+ - Walker Chen <walker.chen@starfivetech.com>
|
||||
+
|
||||
+description: |
|
||||
+ StarFive JH7110 SoC includes support for multiple power domains which can be
|
||||
+ powered on/off by software based on different application scenes to save power.
|
||||
+
|
||||
+properties:
|
||||
+ compatible:
|
||||
+ enum:
|
||||
+ - starfive,jh7110-pmu
|
||||
+
|
||||
+ reg:
|
||||
+ maxItems: 1
|
||||
+
|
||||
+ interrupts:
|
||||
+ maxItems: 1
|
||||
+
|
||||
+ "#power-domain-cells":
|
||||
+ const: 1
|
||||
+
|
||||
+required:
|
||||
+ - compatible
|
||||
+ - reg
|
||||
+ - interrupts
|
||||
+ - "#power-domain-cells"
|
||||
+
|
||||
+additionalProperties: false
|
||||
+
|
||||
+examples:
|
||||
+ - |
|
||||
+ pwrc: power-controller@17030000 {
|
||||
+ compatible = "starfive,jh7110-pmu";
|
||||
+ reg = <0x17030000 0x10000>;
|
||||
+ interrupts = <111>;
|
||||
+ #power-domain-cells = <1>;
|
||||
+ };
|
||||
--- /dev/null
|
||||
+++ b/include/dt-bindings/power/starfive,jh7110-pmu.h
|
||||
@@ -0,0 +1,17 @@
|
||||
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
|
||||
+/*
|
||||
+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
|
||||
+ * Author: Walker Chen <walker.chen@starfivetech.com>
|
||||
+ */
|
||||
+#ifndef __DT_BINDINGS_POWER_JH7110_POWER_H__
|
||||
+#define __DT_BINDINGS_POWER_JH7110_POWER_H__
|
||||
+
|
||||
+#define JH7110_PD_SYSTOP 0
|
||||
+#define JH7110_PD_CPU 1
|
||||
+#define JH7110_PD_GPUA 2
|
||||
+#define JH7110_PD_VDEC 3
|
||||
+#define JH7110_PD_VOUT 4
|
||||
+#define JH7110_PD_ISP 5
|
||||
+#define JH7110_PD_VENC 6
|
||||
+
|
||||
+#endif
|
@ -0,0 +1,478 @@
|
||||
From 3e3b85a1064b07a5107504af1e8f0a42ff9d1fc1 Mon Sep 17 00:00:00 2001
|
||||
From: Walker Chen <walker.chen@starfivetech.com>
|
||||
Date: Thu, 19 Jan 2023 17:44:47 +0800
|
||||
Subject: [PATCH 036/122] soc: starfive: Add StarFive JH71XX pmu driver
|
||||
|
||||
Add pmu driver for the StarFive JH71XX SoC.
|
||||
|
||||
As the power domains provider, the Power Management Unit (PMU) is
|
||||
designed for including multiple PM domains that can be used for power
|
||||
gating of selected IP blocks for power saving by reduced leakage
|
||||
current. It accepts software encourage command to switch the power mode
|
||||
of SoC.
|
||||
|
||||
Signed-off-by: Walker Chen <walker.chen@starfivetech.com>
|
||||
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
|
||||
Reviewed-by: Heiko Stuebner <heiko@sntech.de>
|
||||
---
|
||||
MAINTAINERS | 14 ++
|
||||
drivers/soc/Kconfig | 1 +
|
||||
drivers/soc/Makefile | 1 +
|
||||
drivers/soc/starfive/Kconfig | 12 +
|
||||
drivers/soc/starfive/Makefile | 3 +
|
||||
drivers/soc/starfive/jh71xx_pmu.c | 383 ++++++++++++++++++++++++++++++
|
||||
6 files changed, 414 insertions(+)
|
||||
create mode 100644 drivers/soc/starfive/Kconfig
|
||||
create mode 100644 drivers/soc/starfive/Makefile
|
||||
create mode 100644 drivers/soc/starfive/jh71xx_pmu.c
|
||||
|
||||
--- a/MAINTAINERS
|
||||
+++ b/MAINTAINERS
|
||||
@@ -19682,6 +19682,20 @@ F: Documentation/devicetree/bindings/res
|
||||
F: drivers/reset/starfive/reset-starfive-jh71*
|
||||
F: include/dt-bindings/reset/starfive?jh71*.h
|
||||
|
||||
+STARFIVE SOC DRIVER
|
||||
+M: Conor Dooley <conor@kernel.org>
|
||||
+S: Maintained
|
||||
+T: git https://git.kernel.org/pub/scm/linux/kernel/git/conor/linux.git/
|
||||
+F: drivers/soc/starfive/
|
||||
+F: include/soc/starfive/
|
||||
+
|
||||
+STARFIVE JH71XX PMU CONTROLLER DRIVER
|
||||
+M: Walker Chen <walker.chen@starfivetech.com>
|
||||
+S: Supported
|
||||
+F: Documentation/devicetree/bindings/power/starfive*
|
||||
+F: drivers/soc/starfive/jh71xx_pmu.c
|
||||
+F: include/dt-bindings/power/starfive,jh7110-pmu.h
|
||||
+
|
||||
STATIC BRANCH/CALL
|
||||
M: Peter Zijlstra <peterz@infradead.org>
|
||||
M: Josh Poimboeuf <jpoimboe@kernel.org>
|
||||
--- a/drivers/soc/Kconfig
|
||||
+++ b/drivers/soc/Kconfig
|
||||
@@ -21,6 +21,7 @@ source "drivers/soc/renesas/Kconfig"
|
||||
source "drivers/soc/rockchip/Kconfig"
|
||||
source "drivers/soc/samsung/Kconfig"
|
||||
source "drivers/soc/sifive/Kconfig"
|
||||
+source "drivers/soc/starfive/Kconfig"
|
||||
source "drivers/soc/sunxi/Kconfig"
|
||||
source "drivers/soc/tegra/Kconfig"
|
||||
source "drivers/soc/ti/Kconfig"
|
||||
--- a/drivers/soc/Makefile
|
||||
+++ b/drivers/soc/Makefile
|
||||
@@ -27,6 +27,7 @@ obj-y += renesas/
|
||||
obj-y += rockchip/
|
||||
obj-$(CONFIG_SOC_SAMSUNG) += samsung/
|
||||
obj-$(CONFIG_SOC_SIFIVE) += sifive/
|
||||
+obj-$(CONFIG_SOC_STARFIVE) += starfive/
|
||||
obj-y += sunxi/
|
||||
obj-$(CONFIG_ARCH_TEGRA) += tegra/
|
||||
obj-y += ti/
|
||||
--- /dev/null
|
||||
+++ b/drivers/soc/starfive/Kconfig
|
||||
@@ -0,0 +1,12 @@
|
||||
+# SPDX-License-Identifier: GPL-2.0
|
||||
+
|
||||
+config JH71XX_PMU
|
||||
+ bool "Support PMU for StarFive JH71XX Soc"
|
||||
+ depends on PM
|
||||
+ depends on SOC_STARFIVE || COMPILE_TEST
|
||||
+ default SOC_STARFIVE
|
||||
+ select PM_GENERIC_DOMAINS
|
||||
+ help
|
||||
+ Say 'y' here to enable support power domain support.
|
||||
+ In order to meet low power requirements, a Power Management Unit (PMU)
|
||||
+ is designed for controlling power resources in StarFive JH71XX SoCs.
|
||||
--- /dev/null
|
||||
+++ b/drivers/soc/starfive/Makefile
|
||||
@@ -0,0 +1,3 @@
|
||||
+# SPDX-License-Identifier: GPL-2.0
|
||||
+
|
||||
+obj-$(CONFIG_JH71XX_PMU) += jh71xx_pmu.o
|
||||
--- /dev/null
|
||||
+++ b/drivers/soc/starfive/jh71xx_pmu.c
|
||||
@@ -0,0 +1,383 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
+/*
|
||||
+ * StarFive JH71XX PMU (Power Management Unit) Controller Driver
|
||||
+ *
|
||||
+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/interrupt.h>
|
||||
+#include <linux/io.h>
|
||||
+#include <linux/iopoll.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/of.h>
|
||||
+#include <linux/of_device.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/pm_domain.h>
|
||||
+#include <dt-bindings/power/starfive,jh7110-pmu.h>
|
||||
+
|
||||
+/* register offset */
|
||||
+#define JH71XX_PMU_SW_TURN_ON_POWER 0x0C
|
||||
+#define JH71XX_PMU_SW_TURN_OFF_POWER 0x10
|
||||
+#define JH71XX_PMU_SW_ENCOURAGE 0x44
|
||||
+#define JH71XX_PMU_TIMER_INT_MASK 0x48
|
||||
+#define JH71XX_PMU_CURR_POWER_MODE 0x80
|
||||
+#define JH71XX_PMU_EVENT_STATUS 0x88
|
||||
+#define JH71XX_PMU_INT_STATUS 0x8C
|
||||
+
|
||||
+/* sw encourage cfg */
|
||||
+#define JH71XX_PMU_SW_ENCOURAGE_EN_LO 0x05
|
||||
+#define JH71XX_PMU_SW_ENCOURAGE_EN_HI 0x50
|
||||
+#define JH71XX_PMU_SW_ENCOURAGE_DIS_LO 0x0A
|
||||
+#define JH71XX_PMU_SW_ENCOURAGE_DIS_HI 0xA0
|
||||
+#define JH71XX_PMU_SW_ENCOURAGE_ON 0xFF
|
||||
+
|
||||
+/* pmu int status */
|
||||
+#define JH71XX_PMU_INT_SEQ_DONE BIT(0)
|
||||
+#define JH71XX_PMU_INT_HW_REQ BIT(1)
|
||||
+#define JH71XX_PMU_INT_SW_FAIL GENMASK(3, 2)
|
||||
+#define JH71XX_PMU_INT_HW_FAIL GENMASK(5, 4)
|
||||
+#define JH71XX_PMU_INT_PCH_FAIL GENMASK(8, 6)
|
||||
+#define JH71XX_PMU_INT_ALL_MASK GENMASK(8, 0)
|
||||
+
|
||||
+/*
|
||||
+ * The time required for switching power status is based on the time
|
||||
+ * to turn on the largest domain's power, which is at microsecond level
|
||||
+ */
|
||||
+#define JH71XX_PMU_TIMEOUT_US 100
|
||||
+
|
||||
+struct jh71xx_domain_info {
|
||||
+ const char * const name;
|
||||
+ unsigned int flags;
|
||||
+ u8 bit;
|
||||
+};
|
||||
+
|
||||
+struct jh71xx_pmu_match_data {
|
||||
+ const struct jh71xx_domain_info *domain_info;
|
||||
+ int num_domains;
|
||||
+};
|
||||
+
|
||||
+struct jh71xx_pmu {
|
||||
+ struct device *dev;
|
||||
+ const struct jh71xx_pmu_match_data *match_data;
|
||||
+ void __iomem *base;
|
||||
+ struct generic_pm_domain **genpd;
|
||||
+ struct genpd_onecell_data genpd_data;
|
||||
+ int irq;
|
||||
+ spinlock_t lock; /* protects pmu reg */
|
||||
+};
|
||||
+
|
||||
+struct jh71xx_pmu_dev {
|
||||
+ const struct jh71xx_domain_info *domain_info;
|
||||
+ struct jh71xx_pmu *pmu;
|
||||
+ struct generic_pm_domain genpd;
|
||||
+};
|
||||
+
|
||||
+static int jh71xx_pmu_get_state(struct jh71xx_pmu_dev *pmd, u32 mask, bool *is_on)
|
||||
+{
|
||||
+ struct jh71xx_pmu *pmu = pmd->pmu;
|
||||
+
|
||||
+ if (!mask)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ *is_on = readl(pmu->base + JH71XX_PMU_CURR_POWER_MODE) & mask;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int jh71xx_pmu_set_state(struct jh71xx_pmu_dev *pmd, u32 mask, bool on)
|
||||
+{
|
||||
+ struct jh71xx_pmu *pmu = pmd->pmu;
|
||||
+ unsigned long flags;
|
||||
+ u32 val;
|
||||
+ u32 mode;
|
||||
+ u32 encourage_lo;
|
||||
+ u32 encourage_hi;
|
||||
+ bool is_on;
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = jh71xx_pmu_get_state(pmd, mask, &is_on);
|
||||
+ if (ret) {
|
||||
+ dev_dbg(pmu->dev, "unable to get current state for %s\n",
|
||||
+ pmd->genpd.name);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ if (is_on == on) {
|
||||
+ dev_dbg(pmu->dev, "pm domain [%s] is already %sable status.\n",
|
||||
+ pmd->genpd.name, on ? "en" : "dis");
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ spin_lock_irqsave(&pmu->lock, flags);
|
||||
+
|
||||
+ /*
|
||||
+ * The PMU accepts software encourage to switch power mode in the following 2 steps:
|
||||
+ *
|
||||
+ * 1.Configure the register SW_TURN_ON_POWER (offset 0x0c) by writing 1 to
|
||||
+ * the bit corresponding to the power domain that will be turned on
|
||||
+ * and writing 0 to the others.
|
||||
+ * Likewise, configure the register SW_TURN_OFF_POWER (offset 0x10) by
|
||||
+ * writing 1 to the bit corresponding to the power domain that will be
|
||||
+ * turned off and writing 0 to the others.
|
||||
+ */
|
||||
+ if (on) {
|
||||
+ mode = JH71XX_PMU_SW_TURN_ON_POWER;
|
||||
+ encourage_lo = JH71XX_PMU_SW_ENCOURAGE_EN_LO;
|
||||
+ encourage_hi = JH71XX_PMU_SW_ENCOURAGE_EN_HI;
|
||||
+ } else {
|
||||
+ mode = JH71XX_PMU_SW_TURN_OFF_POWER;
|
||||
+ encourage_lo = JH71XX_PMU_SW_ENCOURAGE_DIS_LO;
|
||||
+ encourage_hi = JH71XX_PMU_SW_ENCOURAGE_DIS_HI;
|
||||
+ }
|
||||
+
|
||||
+ writel(mask, pmu->base + mode);
|
||||
+
|
||||
+ /*
|
||||
+ * 2.Write SW encourage command sequence to the Software Encourage Reg (offset 0x44)
|
||||
+ * First write SW_MODE_ENCOURAGE_ON to JH71XX_PMU_SW_ENCOURAGE. This will reset
|
||||
+ * the state machine which parses the command sequence. This register must be
|
||||
+ * written every time software wants to power on/off a domain.
|
||||
+ * Then write the lower bits of the command sequence, followed by the upper
|
||||
+ * bits. The sequence differs between powering on & off a domain.
|
||||
+ */
|
||||
+ writel(JH71XX_PMU_SW_ENCOURAGE_ON, pmu->base + JH71XX_PMU_SW_ENCOURAGE);
|
||||
+ writel(encourage_lo, pmu->base + JH71XX_PMU_SW_ENCOURAGE);
|
||||
+ writel(encourage_hi, pmu->base + JH71XX_PMU_SW_ENCOURAGE);
|
||||
+
|
||||
+ spin_unlock_irqrestore(&pmu->lock, flags);
|
||||
+
|
||||
+ /* Wait for the power domain bit to be enabled / disabled */
|
||||
+ if (on) {
|
||||
+ ret = readl_poll_timeout_atomic(pmu->base + JH71XX_PMU_CURR_POWER_MODE,
|
||||
+ val, val & mask,
|
||||
+ 1, JH71XX_PMU_TIMEOUT_US);
|
||||
+ } else {
|
||||
+ ret = readl_poll_timeout_atomic(pmu->base + JH71XX_PMU_CURR_POWER_MODE,
|
||||
+ val, !(val & mask),
|
||||
+ 1, JH71XX_PMU_TIMEOUT_US);
|
||||
+ }
|
||||
+
|
||||
+ if (ret) {
|
||||
+ dev_err(pmu->dev, "%s: failed to power %s\n",
|
||||
+ pmd->genpd.name, on ? "on" : "off");
|
||||
+ return -ETIMEDOUT;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int jh71xx_pmu_on(struct generic_pm_domain *genpd)
|
||||
+{
|
||||
+ struct jh71xx_pmu_dev *pmd = container_of(genpd,
|
||||
+ struct jh71xx_pmu_dev, genpd);
|
||||
+ u32 pwr_mask = BIT(pmd->domain_info->bit);
|
||||
+
|
||||
+ return jh71xx_pmu_set_state(pmd, pwr_mask, true);
|
||||
+}
|
||||
+
|
||||
+static int jh71xx_pmu_off(struct generic_pm_domain *genpd)
|
||||
+{
|
||||
+ struct jh71xx_pmu_dev *pmd = container_of(genpd,
|
||||
+ struct jh71xx_pmu_dev, genpd);
|
||||
+ u32 pwr_mask = BIT(pmd->domain_info->bit);
|
||||
+
|
||||
+ return jh71xx_pmu_set_state(pmd, pwr_mask, false);
|
||||
+}
|
||||
+
|
||||
+static void jh71xx_pmu_int_enable(struct jh71xx_pmu *pmu, u32 mask, bool enable)
|
||||
+{
|
||||
+ u32 val;
|
||||
+ unsigned long flags;
|
||||
+
|
||||
+ spin_lock_irqsave(&pmu->lock, flags);
|
||||
+ val = readl(pmu->base + JH71XX_PMU_TIMER_INT_MASK);
|
||||
+
|
||||
+ if (enable)
|
||||
+ val &= ~mask;
|
||||
+ else
|
||||
+ val |= mask;
|
||||
+
|
||||
+ writel(val, pmu->base + JH71XX_PMU_TIMER_INT_MASK);
|
||||
+ spin_unlock_irqrestore(&pmu->lock, flags);
|
||||
+}
|
||||
+
|
||||
+static irqreturn_t jh71xx_pmu_interrupt(int irq, void *data)
|
||||
+{
|
||||
+ struct jh71xx_pmu *pmu = data;
|
||||
+ u32 val;
|
||||
+
|
||||
+ val = readl(pmu->base + JH71XX_PMU_INT_STATUS);
|
||||
+
|
||||
+ if (val & JH71XX_PMU_INT_SEQ_DONE)
|
||||
+ dev_dbg(pmu->dev, "sequence done.\n");
|
||||
+ if (val & JH71XX_PMU_INT_HW_REQ)
|
||||
+ dev_dbg(pmu->dev, "hardware encourage requestion.\n");
|
||||
+ if (val & JH71XX_PMU_INT_SW_FAIL)
|
||||
+ dev_err(pmu->dev, "software encourage fail.\n");
|
||||
+ if (val & JH71XX_PMU_INT_HW_FAIL)
|
||||
+ dev_err(pmu->dev, "hardware encourage fail.\n");
|
||||
+ if (val & JH71XX_PMU_INT_PCH_FAIL)
|
||||
+ dev_err(pmu->dev, "p-channel fail event.\n");
|
||||
+
|
||||
+ /* clear interrupts */
|
||||
+ writel(val, pmu->base + JH71XX_PMU_INT_STATUS);
|
||||
+ writel(val, pmu->base + JH71XX_PMU_EVENT_STATUS);
|
||||
+
|
||||
+ return IRQ_HANDLED;
|
||||
+}
|
||||
+
|
||||
+static int jh71xx_pmu_init_domain(struct jh71xx_pmu *pmu, int index)
|
||||
+{
|
||||
+ struct jh71xx_pmu_dev *pmd;
|
||||
+ u32 pwr_mask;
|
||||
+ int ret;
|
||||
+ bool is_on = false;
|
||||
+
|
||||
+ pmd = devm_kzalloc(pmu->dev, sizeof(*pmd), GFP_KERNEL);
|
||||
+ if (!pmd)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ pmd->domain_info = &pmu->match_data->domain_info[index];
|
||||
+ pmd->pmu = pmu;
|
||||
+ pwr_mask = BIT(pmd->domain_info->bit);
|
||||
+
|
||||
+ pmd->genpd.name = pmd->domain_info->name;
|
||||
+ pmd->genpd.flags = pmd->domain_info->flags;
|
||||
+
|
||||
+ ret = jh71xx_pmu_get_state(pmd, pwr_mask, &is_on);
|
||||
+ if (ret)
|
||||
+ dev_warn(pmu->dev, "unable to get current state for %s\n",
|
||||
+ pmd->genpd.name);
|
||||
+
|
||||
+ pmd->genpd.power_on = jh71xx_pmu_on;
|
||||
+ pmd->genpd.power_off = jh71xx_pmu_off;
|
||||
+ pm_genpd_init(&pmd->genpd, NULL, !is_on);
|
||||
+
|
||||
+ pmu->genpd_data.domains[index] = &pmd->genpd;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int jh71xx_pmu_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct device *dev = &pdev->dev;
|
||||
+ struct device_node *np = dev->of_node;
|
||||
+ const struct jh71xx_pmu_match_data *match_data;
|
||||
+ struct jh71xx_pmu *pmu;
|
||||
+ unsigned int i;
|
||||
+ int ret;
|
||||
+
|
||||
+ pmu = devm_kzalloc(dev, sizeof(*pmu), GFP_KERNEL);
|
||||
+ if (!pmu)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ pmu->base = devm_platform_ioremap_resource(pdev, 0);
|
||||
+ if (IS_ERR(pmu->base))
|
||||
+ return PTR_ERR(pmu->base);
|
||||
+
|
||||
+ pmu->irq = platform_get_irq(pdev, 0);
|
||||
+ if (pmu->irq < 0)
|
||||
+ return pmu->irq;
|
||||
+
|
||||
+ ret = devm_request_irq(dev, pmu->irq, jh71xx_pmu_interrupt,
|
||||
+ 0, pdev->name, pmu);
|
||||
+ if (ret)
|
||||
+ dev_err(dev, "failed to request irq\n");
|
||||
+
|
||||
+ match_data = of_device_get_match_data(dev);
|
||||
+ if (!match_data)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ pmu->genpd = devm_kcalloc(dev, match_data->num_domains,
|
||||
+ sizeof(struct generic_pm_domain *),
|
||||
+ GFP_KERNEL);
|
||||
+ if (!pmu->genpd)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ pmu->dev = dev;
|
||||
+ pmu->match_data = match_data;
|
||||
+ pmu->genpd_data.domains = pmu->genpd;
|
||||
+ pmu->genpd_data.num_domains = match_data->num_domains;
|
||||
+
|
||||
+ for (i = 0; i < match_data->num_domains; i++) {
|
||||
+ ret = jh71xx_pmu_init_domain(pmu, i);
|
||||
+ if (ret) {
|
||||
+ dev_err(dev, "failed to initialize power domain\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ spin_lock_init(&pmu->lock);
|
||||
+ jh71xx_pmu_int_enable(pmu, JH71XX_PMU_INT_ALL_MASK & ~JH71XX_PMU_INT_PCH_FAIL, true);
|
||||
+
|
||||
+ ret = of_genpd_add_provider_onecell(np, &pmu->genpd_data);
|
||||
+ if (ret) {
|
||||
+ dev_err(dev, "failed to register genpd driver: %d\n", ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ dev_dbg(dev, "registered %u power domains\n", i);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct jh71xx_domain_info jh7110_power_domains[] = {
|
||||
+ [JH7110_PD_SYSTOP] = {
|
||||
+ .name = "SYSTOP",
|
||||
+ .bit = 0,
|
||||
+ .flags = GENPD_FLAG_ALWAYS_ON,
|
||||
+ },
|
||||
+ [JH7110_PD_CPU] = {
|
||||
+ .name = "CPU",
|
||||
+ .bit = 1,
|
||||
+ .flags = GENPD_FLAG_ALWAYS_ON,
|
||||
+ },
|
||||
+ [JH7110_PD_GPUA] = {
|
||||
+ .name = "GPUA",
|
||||
+ .bit = 2,
|
||||
+ },
|
||||
+ [JH7110_PD_VDEC] = {
|
||||
+ .name = "VDEC",
|
||||
+ .bit = 3,
|
||||
+ },
|
||||
+ [JH7110_PD_VOUT] = {
|
||||
+ .name = "VOUT",
|
||||
+ .bit = 4,
|
||||
+ },
|
||||
+ [JH7110_PD_ISP] = {
|
||||
+ .name = "ISP",
|
||||
+ .bit = 5,
|
||||
+ },
|
||||
+ [JH7110_PD_VENC] = {
|
||||
+ .name = "VENC",
|
||||
+ .bit = 6,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static const struct jh71xx_pmu_match_data jh7110_pmu = {
|
||||
+ .num_domains = ARRAY_SIZE(jh7110_power_domains),
|
||||
+ .domain_info = jh7110_power_domains,
|
||||
+};
|
||||
+
|
||||
+static const struct of_device_id jh71xx_pmu_of_match[] = {
|
||||
+ {
|
||||
+ .compatible = "starfive,jh7110-pmu",
|
||||
+ .data = (void *)&jh7110_pmu,
|
||||
+ }, {
|
||||
+ /* sentinel */
|
||||
+ }
|
||||
+};
|
||||
+
|
||||
+static struct platform_driver jh71xx_pmu_driver = {
|
||||
+ .probe = jh71xx_pmu_probe,
|
||||
+ .driver = {
|
||||
+ .name = "jh71xx-pmu",
|
||||
+ .of_match_table = jh71xx_pmu_of_match,
|
||||
+ .suppress_bind_attrs = true,
|
||||
+ },
|
||||
+};
|
||||
+builtin_platform_driver(jh71xx_pmu_driver);
|
||||
+
|
||||
+MODULE_AUTHOR("Walker Chen <walker.chen@starfivetech.com>");
|
||||
+MODULE_DESCRIPTION("StarFive JH71XX PMU Driver");
|
||||
+MODULE_LICENSE("GPL");
|
@ -0,0 +1,98 @@
|
||||
From 27d38dda7527414eb84ef471425e96c9d2566b38 Mon Sep 17 00:00:00 2001
|
||||
From: William Qiu <william.qiu@starfivetech.com>
|
||||
Date: Thu, 6 Apr 2023 15:46:13 +0800
|
||||
Subject: [PATCH 037/122] dt-bindings: soc: starfive: Add StarFive syscon
|
||||
module
|
||||
|
||||
Add documentation to describe StarFive System Controller Registers.
|
||||
|
||||
Signed-off-by: William Qiu <william.qiu@starfivetech.com>
|
||||
---
|
||||
.../soc/starfive/starfive,jh7110-syscon.yaml | 58 +++++++++++++++++++
|
||||
MAINTAINERS | 6 ++
|
||||
2 files changed, 64 insertions(+)
|
||||
create mode 100644 Documentation/devicetree/bindings/soc/starfive/starfive,jh7110-syscon.yaml
|
||||
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/soc/starfive/starfive,jh7110-syscon.yaml
|
||||
@@ -0,0 +1,58 @@
|
||||
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
+%YAML 1.2
|
||||
+---
|
||||
+$id: http://devicetree.org/schemas/soc/starfive/starfive,jh7110-syscon.yaml#
|
||||
+$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
+
|
||||
+title: StarFive JH7110 SoC system controller
|
||||
+
|
||||
+maintainers:
|
||||
+ - William Qiu <william.qiu@starfivetech.com>
|
||||
+
|
||||
+description: |
|
||||
+ The StarFive JH7110 SoC system controller provides register information such
|
||||
+ as offset, mask and shift to configure related modules such as MMC and PCIe.
|
||||
+
|
||||
+properties:
|
||||
+ compatible:
|
||||
+ oneOf:
|
||||
+ - items:
|
||||
+ - enum:
|
||||
+ - starfive,jh7110-aon-syscon
|
||||
+ - starfive,jh7110-sys-syscon
|
||||
+ - const: syscon
|
||||
+ - const: simple-mfd
|
||||
+ - items:
|
||||
+ - const: starfive,jh7110-stg-syscon
|
||||
+ - const: syscon
|
||||
+
|
||||
+ reg:
|
||||
+ maxItems: 1
|
||||
+
|
||||
+ clock-controller:
|
||||
+ $ref: /schemas/clock/starfive,jh7110-pll.yaml#
|
||||
+ type: object
|
||||
+
|
||||
+ power-controller:
|
||||
+ $ref: /schemas/power/starfive,jh7110-pmu.yaml#
|
||||
+ type: object
|
||||
+
|
||||
+required:
|
||||
+ - compatible
|
||||
+ - reg
|
||||
+
|
||||
+additionalProperties: false
|
||||
+
|
||||
+examples:
|
||||
+ - |
|
||||
+ syscon@10240000 {
|
||||
+ compatible = "starfive,jh7110-stg-syscon", "syscon";
|
||||
+ reg = <0x10240000 0x1000>;
|
||||
+ };
|
||||
+
|
||||
+ syscon@13030000 {
|
||||
+ compatible = "starfive,jh7110-sys-syscon", "syscon", "simple-mfd";
|
||||
+ reg = <0x13030000 0x1000>;
|
||||
+ };
|
||||
+
|
||||
+...
|
||||
--- a/MAINTAINERS
|
||||
+++ b/MAINTAINERS
|
||||
@@ -19656,6 +19656,11 @@ S: Supported
|
||||
F: Documentation/devicetree/bindings/clock/starfive,jh7110-pll.yaml
|
||||
F: drivers/clk/starfive/clk-starfive-jh7110-pll.*
|
||||
|
||||
+STARFIVE JH7110 SYSCON
|
||||
+M: William Qiu <william.qiu@starfivetech.com>
|
||||
+S: Supported
|
||||
+F: Documentation/devicetree/bindings/soc/starfive/starfive,jh7110-syscon.yaml
|
||||
+
|
||||
STARFIVE JH71X0 CLOCK DRIVERS
|
||||
M: Emil Renner Berthing <kernel@esmil.dk>
|
||||
M: Hal Feng <hal.feng@starfivetech.com>
|
||||
@@ -19686,6 +19691,7 @@ STARFIVE SOC DRIVER
|
||||
M: Conor Dooley <conor@kernel.org>
|
||||
S: Maintained
|
||||
T: git https://git.kernel.org/pub/scm/linux/kernel/git/conor/linux.git/
|
||||
+F: Documentation/devicetree/bindings/soc/starfive/
|
||||
F: drivers/soc/starfive/
|
||||
F: include/soc/starfive/
|
||||
|
@ -0,0 +1,52 @@
|
||||
From 40098f3d986dc90f6a7be0e5a35ddaccd1ded0b5 Mon Sep 17 00:00:00 2001
|
||||
From: William Qiu <william.qiu@starfivetech.com>
|
||||
Date: Thu, 6 Apr 2023 15:46:34 +0800
|
||||
Subject: [PATCH 038/122] riscv: dts: starfive: jh7110: Add syscon nodes
|
||||
|
||||
Add stg_syscon/sys_syscon/aon_syscon nodes for JH7110 Soc.
|
||||
|
||||
Signed-off-by: William Qiu <william.qiu@starfivetech.com>
|
||||
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
|
||||
Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
|
||||
---
|
||||
arch/riscv/boot/dts/starfive/jh7110.dtsi | 15 +++++++++++++++
|
||||
1 file changed, 15 insertions(+)
|
||||
|
||||
--- a/arch/riscv/boot/dts/starfive/jh7110.dtsi
|
||||
+++ b/arch/riscv/boot/dts/starfive/jh7110.dtsi
|
||||
@@ -353,6 +353,11 @@
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
+ stg_syscon: syscon@10240000 {
|
||||
+ compatible = "starfive,jh7110-stg-syscon", "syscon";
|
||||
+ reg = <0x0 0x10240000 0x0 0x1000>;
|
||||
+ };
|
||||
+
|
||||
uart3: serial@12000000 {
|
||||
compatible = "snps,dw-apb-uart";
|
||||
reg = <0x0 0x12000000 0x0 0x10000>;
|
||||
@@ -457,6 +462,11 @@
|
||||
#reset-cells = <1>;
|
||||
};
|
||||
|
||||
+ sys_syscon: syscon@13030000 {
|
||||
+ compatible = "starfive,jh7110-sys-syscon", "syscon", "simple-mfd";
|
||||
+ reg = <0x0 0x13030000 0x0 0x1000>;
|
||||
+ };
|
||||
+
|
||||
sysgpio: pinctrl@13040000 {
|
||||
compatible = "starfive,jh7110-sys-pinctrl";
|
||||
reg = <0x0 0x13040000 0x0 0x10000>;
|
||||
@@ -486,6 +496,11 @@
|
||||
#reset-cells = <1>;
|
||||
};
|
||||
|
||||
+ aon_syscon: syscon@17010000 {
|
||||
+ compatible = "starfive,jh7110-aon-syscon", "syscon", "simple-mfd";
|
||||
+ reg = <0x0 0x17010000 0x0 0x1000>;
|
||||
+ };
|
||||
+
|
||||
aongpio: pinctrl@17020000 {
|
||||
compatible = "starfive,jh7110-aon-pinctrl";
|
||||
reg = <0x0 0x17020000 0x0 0x10000>;
|
@ -0,0 +1,48 @@
|
||||
From f0548ab9212ef35abe79f46e5f509f4fc9d78699 Mon Sep 17 00:00:00 2001
|
||||
From: Xingyu Wu <xingyu.wu@starfivetech.com>
|
||||
Date: Mon, 20 Feb 2023 14:33:33 +0800
|
||||
Subject: [PATCH 039/122] riscv: dts: starfive: jh7110: Add PLL clock node and
|
||||
modify syscrg node
|
||||
|
||||
Add the PLL clock node for the Starfive JH7110 SoC and
|
||||
modify the SYSCRG node to add PLL clocks input.
|
||||
|
||||
Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
|
||||
---
|
||||
arch/riscv/boot/dts/starfive/jh7110.dtsi | 14 ++++++++++++--
|
||||
1 file changed, 12 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/arch/riscv/boot/dts/starfive/jh7110.dtsi
|
||||
+++ b/arch/riscv/boot/dts/starfive/jh7110.dtsi
|
||||
@@ -452,12 +452,16 @@
|
||||
<&gmac1_rgmii_rxin>,
|
||||
<&i2stx_bclk_ext>, <&i2stx_lrck_ext>,
|
||||
<&i2srx_bclk_ext>, <&i2srx_lrck_ext>,
|
||||
- <&tdm_ext>, <&mclk_ext>;
|
||||
+ <&tdm_ext>, <&mclk_ext>,
|
||||
+ <&pllclk JH7110_CLK_PLL0_OUT>,
|
||||
+ <&pllclk JH7110_CLK_PLL1_OUT>,
|
||||
+ <&pllclk JH7110_CLK_PLL2_OUT>;
|
||||
clock-names = "osc", "gmac1_rmii_refin",
|
||||
"gmac1_rgmii_rxin",
|
||||
"i2stx_bclk_ext", "i2stx_lrck_ext",
|
||||
"i2srx_bclk_ext", "i2srx_lrck_ext",
|
||||
- "tdm_ext", "mclk_ext";
|
||||
+ "tdm_ext", "mclk_ext",
|
||||
+ "pll0_out", "pll1_out", "pll2_out";
|
||||
#clock-cells = <1>;
|
||||
#reset-cells = <1>;
|
||||
};
|
||||
@@ -465,6 +469,12 @@
|
||||
sys_syscon: syscon@13030000 {
|
||||
compatible = "starfive,jh7110-sys-syscon", "syscon", "simple-mfd";
|
||||
reg = <0x0 0x13030000 0x0 0x1000>;
|
||||
+
|
||||
+ pllclk: clock-controller {
|
||||
+ compatible = "starfive,jh7110-pll";
|
||||
+ clocks = <&osc>;
|
||||
+ #clock-cells = <1>;
|
||||
+ };
|
||||
};
|
||||
|
||||
sysgpio: pinctrl@13040000 {
|
@ -0,0 +1,49 @@
|
||||
From 5866a8486a261decacd19769556d1b79b5d1269d Mon Sep 17 00:00:00 2001
|
||||
From: Emil Renner Berthing <kernel@esmil.dk>
|
||||
Date: Mon, 8 Aug 2022 17:13:34 +0200
|
||||
Subject: [PATCH 040/122] dt-bindings: net: snps,dwmac: Add dwmac-5.20 version
|
||||
|
||||
Add dwmac-5.20 IP version to snps.dwmac.yaml
|
||||
|
||||
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
|
||||
Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
|
||||
Signed-off-by: Samin Guo <samin.guo@starfivetech.com>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
---
|
||||
Documentation/devicetree/bindings/net/snps,dwmac.yaml | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
--- a/Documentation/devicetree/bindings/net/snps,dwmac.yaml
|
||||
+++ b/Documentation/devicetree/bindings/net/snps,dwmac.yaml
|
||||
@@ -30,6 +30,7 @@ select:
|
||||
- snps,dwmac-4.10a
|
||||
- snps,dwmac-4.20a
|
||||
- snps,dwmac-5.10a
|
||||
+ - snps,dwmac-5.20
|
||||
- snps,dwxgmac
|
||||
- snps,dwxgmac-2.10
|
||||
|
||||
@@ -87,6 +88,7 @@ properties:
|
||||
- snps,dwmac-4.10a
|
||||
- snps,dwmac-4.20a
|
||||
- snps,dwmac-5.10a
|
||||
+ - snps,dwmac-5.20
|
||||
- snps,dwxgmac
|
||||
- snps,dwxgmac-2.10
|
||||
|
||||
@@ -393,6 +395,7 @@ allOf:
|
||||
- snps,dwmac-3.50a
|
||||
- snps,dwmac-4.10a
|
||||
- snps,dwmac-4.20a
|
||||
+ - snps,dwmac-5.20
|
||||
- snps,dwxgmac
|
||||
- snps,dwxgmac-2.10
|
||||
- st,spear600-gmac
|
||||
@@ -447,6 +450,7 @@ allOf:
|
||||
- snps,dwmac-4.10a
|
||||
- snps,dwmac-4.20a
|
||||
- snps,dwmac-5.10a
|
||||
+ - snps,dwmac-5.20
|
||||
- snps,dwxgmac
|
||||
- snps,dwxgmac-2.10
|
||||
- st,spear600-gmac
|
@ -0,0 +1,29 @@
|
||||
From cb00f835fc9f3ece473e7081f17c8613bf08a8ef Mon Sep 17 00:00:00 2001
|
||||
From: Emil Renner Berthing <kernel@esmil.dk>
|
||||
Date: Sun, 7 Aug 2022 22:26:00 +0200
|
||||
Subject: [PATCH 041/122] net: stmmac: platform: Add snps,dwmac-5.20 IP
|
||||
compatible string
|
||||
|
||||
Add "snps,dwmac-5.20" compatible string for 5.20 version that can avoid
|
||||
to define some platform data in the glue layer.
|
||||
|
||||
Tested-by: Tommaso Merciai <tomm.merciai@gmail.com>
|
||||
Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
Signed-off-by: Samin Guo <samin.guo@starfivetech.com>
|
||||
---
|
||||
drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
|
||||
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
|
||||
@@ -519,7 +519,8 @@ stmmac_probe_config_dt(struct platform_d
|
||||
if (of_device_is_compatible(np, "snps,dwmac-4.00") ||
|
||||
of_device_is_compatible(np, "snps,dwmac-4.10a") ||
|
||||
of_device_is_compatible(np, "snps,dwmac-4.20a") ||
|
||||
- of_device_is_compatible(np, "snps,dwmac-5.10a")) {
|
||||
+ of_device_is_compatible(np, "snps,dwmac-5.10a") ||
|
||||
+ of_device_is_compatible(np, "snps,dwmac-5.20")) {
|
||||
plat->has_gmac4 = 1;
|
||||
plat->has_gmac = 0;
|
||||
plat->pmt = 1;
|
@ -0,0 +1,46 @@
|
||||
From 3b0609e57e031a3b680131b3fc25bc1165e3360f Mon Sep 17 00:00:00 2001
|
||||
From: Samin Guo <samin.guo@starfivetech.com>
|
||||
Date: Mon, 27 Feb 2023 18:26:04 +0800
|
||||
Subject: [PATCH 042/122] dt-bindings: net: snps,dwmac: Add 'ahb'
|
||||
reset/reset-name
|
||||
|
||||
According to:
|
||||
stmmac_platform.c: stmmac_probe_config_dt
|
||||
stmmac_main.c: stmmac_dvr_probe
|
||||
|
||||
dwmac controller may require one (stmmaceth) or two (stmmaceth+ahb)
|
||||
reset signals, and the maxItems of resets/reset-names is going to be 2.
|
||||
|
||||
The gmac of Starfive Jh7110 SOC must have two resets.
|
||||
it uses snps,dwmac-5.20 IP.
|
||||
|
||||
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
|
||||
Signed-off-by: Samin Guo <samin.guo@starfivetech.com>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
---
|
||||
.../devicetree/bindings/net/snps,dwmac.yaml | 12 ++++++++----
|
||||
1 file changed, 8 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/Documentation/devicetree/bindings/net/snps,dwmac.yaml
|
||||
+++ b/Documentation/devicetree/bindings/net/snps,dwmac.yaml
|
||||
@@ -133,12 +133,16 @@ properties:
|
||||
- ptp_ref
|
||||
|
||||
resets:
|
||||
- maxItems: 1
|
||||
- description:
|
||||
- MAC Reset signal.
|
||||
+ minItems: 1
|
||||
+ items:
|
||||
+ - description: GMAC stmmaceth reset
|
||||
+ - description: AHB reset
|
||||
|
||||
reset-names:
|
||||
- const: stmmaceth
|
||||
+ minItems: 1
|
||||
+ items:
|
||||
+ - const: stmmaceth
|
||||
+ - const: ahb
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
@ -0,0 +1,190 @@
|
||||
From 6bef17fa124f20723724e2a9a1d890fd1a9d5eaa Mon Sep 17 00:00:00 2001
|
||||
From: Yanhong Wang <yanhong.wang@starfivetech.com>
|
||||
Date: Mon, 31 Oct 2022 18:08:15 +0800
|
||||
Subject: [PATCH 043/122] dt-bindings: net: Add support StarFive dwmac
|
||||
|
||||
Add documentation to describe StarFive dwmac driver(GMAC).
|
||||
|
||||
Signed-off-by: Yanhong Wang <yanhong.wang@starfivetech.com>
|
||||
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
Signed-off-by: Samin Guo <samin.guo@starfivetech.com>
|
||||
---
|
||||
.../devicetree/bindings/net/snps,dwmac.yaml | 1 +
|
||||
.../bindings/net/starfive,jh7110-dwmac.yaml | 144 ++++++++++++++++++
|
||||
MAINTAINERS | 6 +
|
||||
3 files changed, 151 insertions(+)
|
||||
create mode 100644 Documentation/devicetree/bindings/net/starfive,jh7110-dwmac.yaml
|
||||
|
||||
--- a/Documentation/devicetree/bindings/net/snps,dwmac.yaml
|
||||
+++ b/Documentation/devicetree/bindings/net/snps,dwmac.yaml
|
||||
@@ -91,6 +91,7 @@ properties:
|
||||
- snps,dwmac-5.20
|
||||
- snps,dwxgmac
|
||||
- snps,dwxgmac-2.10
|
||||
+ - starfive,jh7110-dwmac
|
||||
|
||||
reg:
|
||||
minItems: 1
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/net/starfive,jh7110-dwmac.yaml
|
||||
@@ -0,0 +1,144 @@
|
||||
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
+# Copyright (C) 2022 StarFive Technology Co., Ltd.
|
||||
+%YAML 1.2
|
||||
+---
|
||||
+$id: http://devicetree.org/schemas/net/starfive,jh7110-dwmac.yaml#
|
||||
+$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
+
|
||||
+title: StarFive JH7110 DWMAC glue layer
|
||||
+
|
||||
+maintainers:
|
||||
+ - Emil Renner Berthing <kernel@esmil.dk>
|
||||
+ - Samin Guo <samin.guo@starfivetech.com>
|
||||
+
|
||||
+select:
|
||||
+ properties:
|
||||
+ compatible:
|
||||
+ contains:
|
||||
+ enum:
|
||||
+ - starfive,jh7110-dwmac
|
||||
+ required:
|
||||
+ - compatible
|
||||
+
|
||||
+properties:
|
||||
+ compatible:
|
||||
+ items:
|
||||
+ - enum:
|
||||
+ - starfive,jh7110-dwmac
|
||||
+ - const: snps,dwmac-5.20
|
||||
+
|
||||
+ reg:
|
||||
+ maxItems: 1
|
||||
+
|
||||
+ clocks:
|
||||
+ items:
|
||||
+ - description: GMAC main clock
|
||||
+ - description: GMAC AHB clock
|
||||
+ - description: PTP clock
|
||||
+ - description: TX clock
|
||||
+ - description: GTX clock
|
||||
+
|
||||
+ clock-names:
|
||||
+ items:
|
||||
+ - const: stmmaceth
|
||||
+ - const: pclk
|
||||
+ - const: ptp_ref
|
||||
+ - const: tx
|
||||
+ - const: gtx
|
||||
+
|
||||
+ interrupts:
|
||||
+ minItems: 3
|
||||
+ maxItems: 3
|
||||
+
|
||||
+ interrupt-names:
|
||||
+ minItems: 3
|
||||
+ maxItems: 3
|
||||
+
|
||||
+ resets:
|
||||
+ items:
|
||||
+ - description: MAC Reset signal.
|
||||
+ - description: AHB Reset signal.
|
||||
+
|
||||
+ reset-names:
|
||||
+ items:
|
||||
+ - const: stmmaceth
|
||||
+ - const: ahb
|
||||
+
|
||||
+ starfive,tx-use-rgmii-clk:
|
||||
+ description:
|
||||
+ Tx clock is provided by external rgmii clock.
|
||||
+ type: boolean
|
||||
+
|
||||
+ starfive,syscon:
|
||||
+ $ref: /schemas/types.yaml#/definitions/phandle-array
|
||||
+ items:
|
||||
+ - items:
|
||||
+ - description: phandle to syscon that configures phy mode
|
||||
+ - description: Offset of phy mode selection
|
||||
+ - description: Shift of phy mode selection
|
||||
+ description:
|
||||
+ A phandle to syscon with two arguments that configure phy mode.
|
||||
+ The argument one is the offset of phy mode selection, the
|
||||
+ argument two is the shift of phy mode selection.
|
||||
+
|
||||
+required:
|
||||
+ - compatible
|
||||
+ - reg
|
||||
+ - clocks
|
||||
+ - clock-names
|
||||
+ - interrupts
|
||||
+ - interrupt-names
|
||||
+ - resets
|
||||
+ - reset-names
|
||||
+
|
||||
+allOf:
|
||||
+ - $ref: snps,dwmac.yaml#
|
||||
+
|
||||
+unevaluatedProperties: false
|
||||
+
|
||||
+examples:
|
||||
+ - |
|
||||
+ ethernet@16030000 {
|
||||
+ compatible = "starfive,jh7110-dwmac", "snps,dwmac-5.20";
|
||||
+ reg = <0x16030000 0x10000>;
|
||||
+ clocks = <&clk 3>, <&clk 2>, <&clk 109>,
|
||||
+ <&clk 6>, <&clk 111>;
|
||||
+ clock-names = "stmmaceth", "pclk", "ptp_ref",
|
||||
+ "tx", "gtx";
|
||||
+ resets = <&rst 1>, <&rst 2>;
|
||||
+ reset-names = "stmmaceth", "ahb";
|
||||
+ interrupts = <7>, <6>, <5>;
|
||||
+ interrupt-names = "macirq", "eth_wake_irq", "eth_lpi";
|
||||
+ phy-mode = "rgmii-id";
|
||||
+ snps,multicast-filter-bins = <64>;
|
||||
+ snps,perfect-filter-entries = <8>;
|
||||
+ rx-fifo-depth = <2048>;
|
||||
+ tx-fifo-depth = <2048>;
|
||||
+ snps,fixed-burst;
|
||||
+ snps,no-pbl-x8;
|
||||
+ snps,tso;
|
||||
+ snps,force_thresh_dma_mode;
|
||||
+ snps,axi-config = <&stmmac_axi_setup>;
|
||||
+ snps,en-tx-lpi-clockgating;
|
||||
+ snps,txpbl = <16>;
|
||||
+ snps,rxpbl = <16>;
|
||||
+ starfive,syscon = <&aon_syscon 0xc 0x12>;
|
||||
+ phy-handle = <&phy0>;
|
||||
+
|
||||
+ mdio {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ compatible = "snps,dwmac-mdio";
|
||||
+
|
||||
+ phy0: ethernet-phy@0 {
|
||||
+ reg = <0>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ stmmac_axi_setup: stmmac-axi-config {
|
||||
+ snps,lpi_en;
|
||||
+ snps,wr_osr_lmt = <4>;
|
||||
+ snps,rd_osr_lmt = <4>;
|
||||
+ snps,blen = <256 128 64 32 0 0 0>;
|
||||
+ };
|
||||
+ };
|
||||
--- a/MAINTAINERS
|
||||
+++ b/MAINTAINERS
|
||||
@@ -19650,6 +19650,12 @@ M: Emil Renner Berthing <kernel@esmil.dk
|
||||
S: Maintained
|
||||
F: arch/riscv/boot/dts/starfive/
|
||||
|
||||
+STARFIVE DWMAC GLUE LAYER
|
||||
+M: Emil Renner Berthing <kernel@esmil.dk>
|
||||
+M: Samin Guo <samin.guo@starfivetech.com>
|
||||
+S: Maintained
|
||||
+F: Documentation/devicetree/bindings/net/starfive,jh7110-dwmac.yaml
|
||||
+
|
||||
STARFIVE JH7110 PLL CLOCK DRIVER
|
||||
M: Xingyu Wu <xingyu.wu@starfivetech.com>
|
||||
S: Supported
|
@ -0,0 +1,187 @@
|
||||
From 7c82049adb0460985dd6a1e5c9b6954d901247d2 Mon Sep 17 00:00:00 2001
|
||||
From: Samin Guo <samin.guo@starfivetech.com>
|
||||
Date: Fri, 3 Mar 2023 16:50:58 +0800
|
||||
Subject: [PATCH 044/122] net: stmmac: Add glue layer for StarFive JH7110 SoC
|
||||
|
||||
This adds StarFive dwmac driver support on the StarFive JH7110 SoC.
|
||||
|
||||
Tested-by: Tommaso Merciai <tomm.merciai@gmail.com>
|
||||
Co-developed-by: Emil Renner Berthing <kernel@esmil.dk>
|
||||
Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
Signed-off-by: Samin Guo <samin.guo@starfivetech.com>
|
||||
---
|
||||
MAINTAINERS | 1 +
|
||||
drivers/net/ethernet/stmicro/stmmac/Kconfig | 12 ++
|
||||
drivers/net/ethernet/stmicro/stmmac/Makefile | 1 +
|
||||
.../ethernet/stmicro/stmmac/dwmac-starfive.c | 123 ++++++++++++++++++
|
||||
4 files changed, 137 insertions(+)
|
||||
create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwmac-starfive.c
|
||||
|
||||
--- a/MAINTAINERS
|
||||
+++ b/MAINTAINERS
|
||||
@@ -19655,6 +19655,7 @@ M: Emil Renner Berthing <kernel@esmil.dk
|
||||
M: Samin Guo <samin.guo@starfivetech.com>
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/net/starfive,jh7110-dwmac.yaml
|
||||
+F: drivers/net/ethernet/stmicro/stmmac/dwmac-starfive.c
|
||||
|
||||
STARFIVE JH7110 PLL CLOCK DRIVER
|
||||
M: Xingyu Wu <xingyu.wu@starfivetech.com>
|
||||
--- a/drivers/net/ethernet/stmicro/stmmac/Kconfig
|
||||
+++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig
|
||||
@@ -165,6 +165,18 @@ config DWMAC_SOCFPGA
|
||||
for the stmmac device driver. This driver is used for
|
||||
arria5 and cyclone5 FPGA SoCs.
|
||||
|
||||
+config DWMAC_STARFIVE
|
||||
+ tristate "StarFive dwmac support"
|
||||
+ depends on OF && (ARCH_STARFIVE || COMPILE_TEST)
|
||||
+ select MFD_SYSCON
|
||||
+ default m if ARCH_STARFIVE
|
||||
+ help
|
||||
+ Support for ethernet controllers on StarFive RISC-V SoCs
|
||||
+
|
||||
+ This selects the StarFive platform specific glue layer support for
|
||||
+ the stmmac device driver. This driver is used for StarFive JH7110
|
||||
+ ethernet controller.
|
||||
+
|
||||
config DWMAC_STI
|
||||
tristate "STi GMAC support"
|
||||
default ARCH_STI
|
||||
--- a/drivers/net/ethernet/stmicro/stmmac/Makefile
|
||||
+++ b/drivers/net/ethernet/stmicro/stmmac/Makefile
|
||||
@@ -23,6 +23,7 @@ obj-$(CONFIG_DWMAC_OXNAS) += dwmac-oxnas
|
||||
obj-$(CONFIG_DWMAC_QCOM_ETHQOS) += dwmac-qcom-ethqos.o
|
||||
obj-$(CONFIG_DWMAC_ROCKCHIP) += dwmac-rk.o
|
||||
obj-$(CONFIG_DWMAC_SOCFPGA) += dwmac-altr-socfpga.o
|
||||
+obj-$(CONFIG_DWMAC_STARFIVE) += dwmac-starfive.o
|
||||
obj-$(CONFIG_DWMAC_STI) += dwmac-sti.o
|
||||
obj-$(CONFIG_DWMAC_STM32) += dwmac-stm32.o
|
||||
obj-$(CONFIG_DWMAC_SUNXI) += dwmac-sunxi.o
|
||||
--- /dev/null
|
||||
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-starfive.c
|
||||
@@ -0,0 +1,123 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0+
|
||||
+/*
|
||||
+ * StarFive DWMAC platform driver
|
||||
+ *
|
||||
+ * Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
|
||||
+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#include <linux/mfd/syscon.h>
|
||||
+#include <linux/of_device.h>
|
||||
+#include <linux/regmap.h>
|
||||
+
|
||||
+#include "stmmac_platform.h"
|
||||
+
|
||||
+struct starfive_dwmac {
|
||||
+ struct device *dev;
|
||||
+ struct clk *clk_tx;
|
||||
+};
|
||||
+
|
||||
+static void starfive_dwmac_fix_mac_speed(void *priv, unsigned int speed)
|
||||
+{
|
||||
+ struct starfive_dwmac *dwmac = priv;
|
||||
+ unsigned long rate;
|
||||
+ int err;
|
||||
+
|
||||
+ rate = clk_get_rate(dwmac->clk_tx);
|
||||
+
|
||||
+ switch (speed) {
|
||||
+ case SPEED_1000:
|
||||
+ rate = 125000000;
|
||||
+ break;
|
||||
+ case SPEED_100:
|
||||
+ rate = 25000000;
|
||||
+ break;
|
||||
+ case SPEED_10:
|
||||
+ rate = 2500000;
|
||||
+ break;
|
||||
+ default:
|
||||
+ dev_err(dwmac->dev, "invalid speed %u\n", speed);
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ err = clk_set_rate(dwmac->clk_tx, rate);
|
||||
+ if (err)
|
||||
+ dev_err(dwmac->dev, "failed to set tx rate %lu\n", rate);
|
||||
+}
|
||||
+
|
||||
+static int starfive_dwmac_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct plat_stmmacenet_data *plat_dat;
|
||||
+ struct stmmac_resources stmmac_res;
|
||||
+ struct starfive_dwmac *dwmac;
|
||||
+ struct clk *clk_gtx;
|
||||
+ int err;
|
||||
+
|
||||
+ err = stmmac_get_platform_resources(pdev, &stmmac_res);
|
||||
+ if (err)
|
||||
+ return dev_err_probe(&pdev->dev, err,
|
||||
+ "failed to get resources\n");
|
||||
+
|
||||
+ plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
|
||||
+ if (IS_ERR(plat_dat))
|
||||
+ return dev_err_probe(&pdev->dev, PTR_ERR(plat_dat),
|
||||
+ "dt configuration failed\n");
|
||||
+
|
||||
+ dwmac = devm_kzalloc(&pdev->dev, sizeof(*dwmac), GFP_KERNEL);
|
||||
+ if (!dwmac)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ dwmac->clk_tx = devm_clk_get_enabled(&pdev->dev, "tx");
|
||||
+ if (IS_ERR(dwmac->clk_tx))
|
||||
+ return dev_err_probe(&pdev->dev, PTR_ERR(dwmac->clk_tx),
|
||||
+ "error getting tx clock\n");
|
||||
+
|
||||
+ clk_gtx = devm_clk_get_enabled(&pdev->dev, "gtx");
|
||||
+ if (IS_ERR(clk_gtx))
|
||||
+ return dev_err_probe(&pdev->dev, PTR_ERR(clk_gtx),
|
||||
+ "error getting gtx clock\n");
|
||||
+
|
||||
+ /* Generally, the rgmii_tx clock is provided by the internal clock,
|
||||
+ * which needs to match the corresponding clock frequency according
|
||||
+ * to different speeds. If the rgmii_tx clock is provided by the
|
||||
+ * external rgmii_rxin, there is no need to configure the clock
|
||||
+ * internally, because rgmii_rxin will be adaptively adjusted.
|
||||
+ */
|
||||
+ if (!device_property_read_bool(&pdev->dev, "starfive,tx-use-rgmii-clk"))
|
||||
+ plat_dat->fix_mac_speed = starfive_dwmac_fix_mac_speed;
|
||||
+
|
||||
+ dwmac->dev = &pdev->dev;
|
||||
+ plat_dat->bsp_priv = dwmac;
|
||||
+ plat_dat->dma_cfg->dche = true;
|
||||
+
|
||||
+ err = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
|
||||
+ if (err) {
|
||||
+ stmmac_remove_config_dt(pdev, plat_dat);
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct of_device_id starfive_dwmac_match[] = {
|
||||
+ { .compatible = "starfive,jh7110-dwmac" },
|
||||
+ { /* sentinel */ }
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, starfive_dwmac_match);
|
||||
+
|
||||
+static struct platform_driver starfive_dwmac_driver = {
|
||||
+ .probe = starfive_dwmac_probe,
|
||||
+ .remove = stmmac_pltfr_remove,
|
||||
+ .driver = {
|
||||
+ .name = "starfive-dwmac",
|
||||
+ .pm = &stmmac_pltfr_pm_ops,
|
||||
+ .of_match_table = starfive_dwmac_match,
|
||||
+ },
|
||||
+};
|
||||
+module_platform_driver(starfive_dwmac_driver);
|
||||
+
|
||||
+MODULE_LICENSE("GPL");
|
||||
+MODULE_DESCRIPTION("StarFive DWMAC platform driver");
|
||||
+MODULE_AUTHOR("Emil Renner Berthing <kernel@esmil.dk>");
|
||||
+MODULE_AUTHOR("Samin Guo <samin.guo@starfivetech.com>");
|
@ -0,0 +1,93 @@
|
||||
From 20886cd583e8d569d78ea0e723f98384a61ab54b Mon Sep 17 00:00:00 2001
|
||||
From: Samin Guo <samin.guo@starfivetech.com>
|
||||
Date: Thu, 2 Mar 2023 19:52:37 +0800
|
||||
Subject: [PATCH 045/122] net: stmmac: dwmac-starfive: Add phy interface
|
||||
settings
|
||||
|
||||
dwmac supports multiple modess. When working under rmii and rgmii,
|
||||
you need to set different phy interfaces.
|
||||
|
||||
According to the dwmac document, when working in rmii, it needs to be
|
||||
set to 0x4, and rgmii needs to be set to 0x1.
|
||||
|
||||
The phy interface needs to be set in syscon, the format is as follows:
|
||||
starfive,syscon: <&syscon, offset, shift>
|
||||
|
||||
Tested-by: Tommaso Merciai <tomm.merciai@gmail.com>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
Signed-off-by: Samin Guo <samin.guo@starfivetech.com>
|
||||
---
|
||||
.../ethernet/stmicro/stmmac/dwmac-starfive.c | 48 +++++++++++++++++++
|
||||
1 file changed, 48 insertions(+)
|
||||
|
||||
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-starfive.c
|
||||
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-starfive.c
|
||||
@@ -13,6 +13,10 @@
|
||||
|
||||
#include "stmmac_platform.h"
|
||||
|
||||
+#define STARFIVE_DWMAC_PHY_INFT_RGMII 0x1
|
||||
+#define STARFIVE_DWMAC_PHY_INFT_RMII 0x4
|
||||
+#define STARFIVE_DWMAC_PHY_INFT_FIELD 0x7U
|
||||
+
|
||||
struct starfive_dwmac {
|
||||
struct device *dev;
|
||||
struct clk *clk_tx;
|
||||
@@ -46,6 +50,46 @@ static void starfive_dwmac_fix_mac_speed
|
||||
dev_err(dwmac->dev, "failed to set tx rate %lu\n", rate);
|
||||
}
|
||||
|
||||
+static int starfive_dwmac_set_mode(struct plat_stmmacenet_data *plat_dat)
|
||||
+{
|
||||
+ struct starfive_dwmac *dwmac = plat_dat->bsp_priv;
|
||||
+ struct regmap *regmap;
|
||||
+ unsigned int args[2];
|
||||
+ unsigned int mode;
|
||||
+ int err;
|
||||
+
|
||||
+ switch (plat_dat->interface) {
|
||||
+ case PHY_INTERFACE_MODE_RMII:
|
||||
+ mode = STARFIVE_DWMAC_PHY_INFT_RMII;
|
||||
+ break;
|
||||
+
|
||||
+ case PHY_INTERFACE_MODE_RGMII:
|
||||
+ case PHY_INTERFACE_MODE_RGMII_ID:
|
||||
+ mode = STARFIVE_DWMAC_PHY_INFT_RGMII;
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ dev_err(dwmac->dev, "unsupported interface %d\n",
|
||||
+ plat_dat->interface);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ regmap = syscon_regmap_lookup_by_phandle_args(dwmac->dev->of_node,
|
||||
+ "starfive,syscon",
|
||||
+ 2, args);
|
||||
+ if (IS_ERR(regmap))
|
||||
+ return dev_err_probe(dwmac->dev, PTR_ERR(regmap), "getting the regmap failed\n");
|
||||
+
|
||||
+ /* args[0]:offset args[1]: shift */
|
||||
+ err = regmap_update_bits(regmap, args[0],
|
||||
+ STARFIVE_DWMAC_PHY_INFT_FIELD << args[1],
|
||||
+ mode << args[1]);
|
||||
+ if (err)
|
||||
+ return dev_err_probe(dwmac->dev, err, "error setting phy mode\n");
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int starfive_dwmac_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct plat_stmmacenet_data *plat_dat;
|
||||
@@ -91,6 +135,10 @@ static int starfive_dwmac_probe(struct p
|
||||
plat_dat->bsp_priv = dwmac;
|
||||
plat_dat->dma_cfg->dche = true;
|
||||
|
||||
+ err = starfive_dwmac_set_mode(plat_dat);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
err = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
|
||||
if (err) {
|
||||
stmmac_remove_config_dt(pdev, plat_dat);
|
@ -0,0 +1,101 @@
|
||||
From cad740398f4cb6604abf1ddcc70121b2634ac233 Mon Sep 17 00:00:00 2001
|
||||
From: Samin Guo <samin.guo@starfivetech.com>
|
||||
Date: Fri, 3 Mar 2023 16:49:31 +0800
|
||||
Subject: [PATCH 046/122] riscv: dts: starfive: jh7110: Add ethernet device
|
||||
nodes
|
||||
|
||||
Add JH7110 ethernet device node to support gmac driver for the JH7110
|
||||
RISC-V SoC.
|
||||
|
||||
Tested-by: Tommaso Merciai <tomm.merciai@gmail.com>
|
||||
Signed-off-by: Yanhong Wang <yanhong.wang@starfivetech.com>
|
||||
Signed-off-by: Samin Guo <samin.guo@starfivetech.com>
|
||||
---
|
||||
arch/riscv/boot/dts/starfive/jh7110.dtsi | 69 ++++++++++++++++++++++++
|
||||
1 file changed, 69 insertions(+)
|
||||
|
||||
--- a/arch/riscv/boot/dts/starfive/jh7110.dtsi
|
||||
+++ b/arch/riscv/boot/dts/starfive/jh7110.dtsi
|
||||
@@ -230,6 +230,13 @@
|
||||
#clock-cells = <0>;
|
||||
};
|
||||
|
||||
+ stmmac_axi_setup: stmmac-axi-config {
|
||||
+ snps,lpi_en;
|
||||
+ snps,wr_osr_lmt = <4>;
|
||||
+ snps,rd_osr_lmt = <4>;
|
||||
+ snps,blen = <256 128 64 32 0 0 0>;
|
||||
+ };
|
||||
+
|
||||
tdm_ext: tdm-ext-clock {
|
||||
compatible = "fixed-clock";
|
||||
clock-output-names = "tdm_ext";
|
||||
@@ -489,6 +496,68 @@
|
||||
#gpio-cells = <2>;
|
||||
};
|
||||
|
||||
+ gmac0: ethernet@16030000 {
|
||||
+ compatible = "starfive,jh7110-dwmac", "snps,dwmac-5.20";
|
||||
+ reg = <0x0 0x16030000 0x0 0x10000>;
|
||||
+ clocks = <&aoncrg JH7110_AONCLK_GMAC0_AXI>,
|
||||
+ <&aoncrg JH7110_AONCLK_GMAC0_AHB>,
|
||||
+ <&syscrg JH7110_SYSCLK_GMAC0_PTP>,
|
||||
+ <&aoncrg JH7110_AONCLK_GMAC0_TX_INV>,
|
||||
+ <&syscrg JH7110_SYSCLK_GMAC0_GTXC>;
|
||||
+ clock-names = "stmmaceth", "pclk", "ptp_ref",
|
||||
+ "tx", "gtx";
|
||||
+ resets = <&aoncrg JH7110_AONRST_GMAC0_AXI>,
|
||||
+ <&aoncrg JH7110_AONRST_GMAC0_AHB>;
|
||||
+ reset-names = "stmmaceth", "ahb";
|
||||
+ interrupts = <7>, <6>, <5>;
|
||||
+ interrupt-names = "macirq", "eth_wake_irq", "eth_lpi";
|
||||
+ rx-fifo-depth = <2048>;
|
||||
+ tx-fifo-depth = <2048>;
|
||||
+ snps,multicast-filter-bins = <64>;
|
||||
+ snps,perfect-filter-entries = <8>;
|
||||
+ snps,fixed-burst;
|
||||
+ snps,no-pbl-x8;
|
||||
+ snps,force_thresh_dma_mode;
|
||||
+ snps,axi-config = <&stmmac_axi_setup>;
|
||||
+ snps,tso;
|
||||
+ snps,en-tx-lpi-clockgating;
|
||||
+ snps,txpbl = <16>;
|
||||
+ snps,rxpbl = <16>;
|
||||
+ starfive,syscon = <&aon_syscon 0xc 0x12>;
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
+ gmac1: ethernet@16040000 {
|
||||
+ compatible = "starfive,jh7110-dwmac", "snps,dwmac-5.20";
|
||||
+ reg = <0x0 0x16040000 0x0 0x10000>;
|
||||
+ clocks = <&syscrg JH7110_SYSCLK_GMAC1_AXI>,
|
||||
+ <&syscrg JH7110_SYSCLK_GMAC1_AHB>,
|
||||
+ <&syscrg JH7110_SYSCLK_GMAC1_PTP>,
|
||||
+ <&syscrg JH7110_SYSCLK_GMAC1_TX_INV>,
|
||||
+ <&syscrg JH7110_SYSCLK_GMAC1_GTXC>;
|
||||
+ clock-names = "stmmaceth", "pclk", "ptp_ref",
|
||||
+ "tx", "gtx";
|
||||
+ resets = <&syscrg JH7110_SYSRST_GMAC1_AXI>,
|
||||
+ <&syscrg JH7110_SYSRST_GMAC1_AHB>;
|
||||
+ reset-names = "stmmaceth", "ahb";
|
||||
+ interrupts = <78>, <77>, <76>;
|
||||
+ interrupt-names = "macirq", "eth_wake_irq", "eth_lpi";
|
||||
+ rx-fifo-depth = <2048>;
|
||||
+ tx-fifo-depth = <2048>;
|
||||
+ snps,multicast-filter-bins = <64>;
|
||||
+ snps,perfect-filter-entries = <8>;
|
||||
+ snps,fixed-burst;
|
||||
+ snps,no-pbl-x8;
|
||||
+ snps,force_thresh_dma_mode;
|
||||
+ snps,axi-config = <&stmmac_axi_setup>;
|
||||
+ snps,tso;
|
||||
+ snps,en-tx-lpi-clockgating;
|
||||
+ snps,txpbl = <16>;
|
||||
+ snps,rxpbl = <16>;
|
||||
+ starfive,syscon = <&sys_syscon 0x90 0x2>;
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
aoncrg: clock-controller@17000000 {
|
||||
compatible = "starfive,jh7110-aoncrg";
|
||||
reg = <0x0 0x17000000 0x0 0x10000>;
|
@ -0,0 +1,128 @@
|
||||
From 6fd84cb9cceaa711671500a92dcee5b1072ab95a Mon Sep 17 00:00:00 2001
|
||||
From: Samin Guo <samin.guo@starfivetech.com>
|
||||
Date: Tue, 1 Nov 2022 18:11:02 +0800
|
||||
Subject: [PATCH 047/122] riscv: dts: starfive: visionfive 2: Add configuration
|
||||
of gmac and phy
|
||||
|
||||
v1.3B:
|
||||
v1.3B uses motorcomm YT8531(rgmii-id phy) x2, need delay and
|
||||
inverse configurations.
|
||||
The tx_clk of v1.3B uses an external clock and needs to be
|
||||
switched to an external clock source.
|
||||
|
||||
v1.2A:
|
||||
v1.2A gmac0 uses motorcomm YT8531(rgmii-id) PHY, and needs delay
|
||||
configurations.
|
||||
v1.2A gmac1 uses motorcomm YT8512(rmii) PHY, and needs to
|
||||
switch rx and rx to external clock sources.
|
||||
|
||||
Tested-by: Tommaso Merciai <tomm.merciai@gmail.com>
|
||||
Signed-off-by: Samin Guo <samin.guo@starfivetech.com>
|
||||
---
|
||||
.../jh7110-starfive-visionfive-2-v1.2a.dts | 13 +++++++
|
||||
.../jh7110-starfive-visionfive-2-v1.3b.dts | 27 +++++++++++++++
|
||||
.../jh7110-starfive-visionfive-2.dtsi | 34 +++++++++++++++++++
|
||||
3 files changed, 74 insertions(+)
|
||||
|
||||
--- a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-v1.2a.dts
|
||||
+++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-v1.2a.dts
|
||||
@@ -11,3 +11,16 @@
|
||||
model = "StarFive VisionFive 2 v1.2A";
|
||||
compatible = "starfive,visionfive-2-v1.2a", "starfive,jh7110";
|
||||
};
|
||||
+
|
||||
+&gmac1 {
|
||||
+ phy-mode = "rmii";
|
||||
+ assigned-clocks = <&syscrg JH7110_SYSCLK_GMAC1_TX>,
|
||||
+ <&syscrg JH7110_SYSCLK_GMAC1_RX>;
|
||||
+ assigned-clock-parents = <&syscrg JH7110_SYSCLK_GMAC1_RMII_RTX>,
|
||||
+ <&syscrg JH7110_SYSCLK_GMAC1_RMII_RTX>;
|
||||
+};
|
||||
+
|
||||
+&phy0 {
|
||||
+ rx-internal-delay-ps = <1900>;
|
||||
+ tx-internal-delay-ps = <1350>;
|
||||
+};
|
||||
--- a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-v1.3b.dts
|
||||
+++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-v1.3b.dts
|
||||
@@ -11,3 +11,30 @@
|
||||
model = "StarFive VisionFive 2 v1.3B";
|
||||
compatible = "starfive,visionfive-2-v1.3b", "starfive,jh7110";
|
||||
};
|
||||
+
|
||||
+&gmac0 {
|
||||
+ starfive,tx-use-rgmii-clk;
|
||||
+ assigned-clocks = <&aoncrg JH7110_AONCLK_GMAC0_TX>;
|
||||
+ assigned-clock-parents = <&aoncrg JH7110_AONCLK_GMAC0_RMII_RTX>;
|
||||
+};
|
||||
+
|
||||
+&gmac1 {
|
||||
+ starfive,tx-use-rgmii-clk;
|
||||
+ assigned-clocks = <&syscrg JH7110_SYSCLK_GMAC1_TX>;
|
||||
+ assigned-clock-parents = <&syscrg JH7110_SYSCLK_GMAC1_RMII_RTX>;
|
||||
+};
|
||||
+
|
||||
+&phy0 {
|
||||
+ motorcomm,tx-clk-adj-enabled;
|
||||
+ motorcomm,tx-clk-100-inverted;
|
||||
+ motorcomm,tx-clk-1000-inverted;
|
||||
+ rx-internal-delay-ps = <1500>;
|
||||
+ tx-internal-delay-ps = <1500>;
|
||||
+};
|
||||
+
|
||||
+&phy1 {
|
||||
+ motorcomm,tx-clk-adj-enabled;
|
||||
+ motorcomm,tx-clk-100-inverted;
|
||||
+ rx-internal-delay-ps = <300>;
|
||||
+ tx-internal-delay-ps = <0>;
|
||||
+};
|
||||
--- a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
|
||||
+++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
|
||||
@@ -11,6 +11,8 @@
|
||||
|
||||
/ {
|
||||
aliases {
|
||||
+ ethernet0 = &gmac0;
|
||||
+ ethernet1 = &gmac1;
|
||||
i2c0 = &i2c0;
|
||||
i2c2 = &i2c2;
|
||||
i2c5 = &i2c5;
|
||||
@@ -86,6 +88,38 @@
|
||||
clock-frequency = <49152000>;
|
||||
};
|
||||
|
||||
+&gmac0 {
|
||||
+ phy-handle = <&phy0>;
|
||||
+ phy-mode = "rgmii-id";
|
||||
+ status = "okay";
|
||||
+
|
||||
+ mdio {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ compatible = "snps,dwmac-mdio";
|
||||
+
|
||||
+ phy0: ethernet-phy@0 {
|
||||
+ reg = <0>;
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&gmac1 {
|
||||
+ phy-handle = <&phy1>;
|
||||
+ phy-mode = "rgmii-id";
|
||||
+ status = "okay";
|
||||
+
|
||||
+ mdio {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ compatible = "snps,dwmac-mdio";
|
||||
+
|
||||
+ phy1: ethernet-phy@1 {
|
||||
+ reg = <0>;
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
&i2c0 {
|
||||
clock-frequency = <100000>;
|
||||
i2c-sda-hold-time-ns = <300>;
|
@ -0,0 +1,147 @@
|
||||
From 96edc2f71ea7ac6683011609f6d1f51ae9ea0b7a Mon Sep 17 00:00:00 2001
|
||||
From: Frank Sae <Frank.Sae@motor-comm.com>
|
||||
Date: Thu, 2 Feb 2023 11:00:33 +0800
|
||||
Subject: [PATCH 048/122] dt-bindings: net: Add Motorcomm yt8xxx ethernet phy
|
||||
|
||||
Add a YAML binding document for the Motorcomm yt8xxx Ethernet phy.
|
||||
|
||||
Signed-off-by: Frank Sae <Frank.Sae@motor-comm.com>
|
||||
Reviewed-by: Rob Herring <robh@kernel.org>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
.../bindings/net/motorcomm,yt8xxx.yaml | 117 ++++++++++++++++++
|
||||
.../devicetree/bindings/vendor-prefixes.yaml | 2 +
|
||||
2 files changed, 119 insertions(+)
|
||||
create mode 100644 Documentation/devicetree/bindings/net/motorcomm,yt8xxx.yaml
|
||||
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/net/motorcomm,yt8xxx.yaml
|
||||
@@ -0,0 +1,117 @@
|
||||
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
+%YAML 1.2
|
||||
+---
|
||||
+$id: http://devicetree.org/schemas/net/motorcomm,yt8xxx.yaml#
|
||||
+$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
+
|
||||
+title: MotorComm yt8xxx Ethernet PHY
|
||||
+
|
||||
+maintainers:
|
||||
+ - Frank Sae <frank.sae@motor-comm.com>
|
||||
+
|
||||
+allOf:
|
||||
+ - $ref: ethernet-phy.yaml#
|
||||
+
|
||||
+properties:
|
||||
+ compatible:
|
||||
+ enum:
|
||||
+ - ethernet-phy-id4f51.e91a
|
||||
+ - ethernet-phy-id4f51.e91b
|
||||
+
|
||||
+ rx-internal-delay-ps:
|
||||
+ description: |
|
||||
+ RGMII RX Clock Delay used only when PHY operates in RGMII mode with
|
||||
+ internal delay (phy-mode is 'rgmii-id' or 'rgmii-rxid') in pico-seconds.
|
||||
+ enum: [ 0, 150, 300, 450, 600, 750, 900, 1050, 1200, 1350, 1500, 1650,
|
||||
+ 1800, 1900, 1950, 2050, 2100, 2200, 2250, 2350, 2500, 2650, 2800,
|
||||
+ 2950, 3100, 3250, 3400, 3550, 3700, 3850, 4000, 4150 ]
|
||||
+ default: 1950
|
||||
+
|
||||
+ tx-internal-delay-ps:
|
||||
+ description: |
|
||||
+ RGMII TX Clock Delay used only when PHY operates in RGMII mode with
|
||||
+ internal delay (phy-mode is 'rgmii-id' or 'rgmii-txid') in pico-seconds.
|
||||
+ enum: [ 0, 150, 300, 450, 600, 750, 900, 1050, 1200, 1350, 1500, 1650, 1800,
|
||||
+ 1950, 2100, 2250 ]
|
||||
+ default: 1950
|
||||
+
|
||||
+ motorcomm,clk-out-frequency-hz:
|
||||
+ description: clock output on clock output pin.
|
||||
+ enum: [0, 25000000, 125000000]
|
||||
+ default: 0
|
||||
+
|
||||
+ motorcomm,keep-pll-enabled:
|
||||
+ description: |
|
||||
+ If set, keep the PLL enabled even if there is no link. Useful if you
|
||||
+ want to use the clock output without an ethernet link.
|
||||
+ type: boolean
|
||||
+
|
||||
+ motorcomm,auto-sleep-disabled:
|
||||
+ description: |
|
||||
+ If set, PHY will not enter sleep mode and close AFE after unplug cable
|
||||
+ for a timer.
|
||||
+ type: boolean
|
||||
+
|
||||
+ motorcomm,tx-clk-adj-enabled:
|
||||
+ description: |
|
||||
+ This configuration is mainly to adapt to VF2 with JH7110 SoC.
|
||||
+ Useful if you want to use tx-clk-xxxx-inverted to adj the delay of tx clk.
|
||||
+ type: boolean
|
||||
+
|
||||
+ motorcomm,tx-clk-10-inverted:
|
||||
+ description: |
|
||||
+ Use original or inverted RGMII Transmit PHY Clock to drive the RGMII
|
||||
+ Transmit PHY Clock delay train configuration when speed is 10Mbps.
|
||||
+ type: boolean
|
||||
+
|
||||
+ motorcomm,tx-clk-100-inverted:
|
||||
+ description: |
|
||||
+ Use original or inverted RGMII Transmit PHY Clock to drive the RGMII
|
||||
+ Transmit PHY Clock delay train configuration when speed is 100Mbps.
|
||||
+ type: boolean
|
||||
+
|
||||
+ motorcomm,tx-clk-1000-inverted:
|
||||
+ description: |
|
||||
+ Use original or inverted RGMII Transmit PHY Clock to drive the RGMII
|
||||
+ Transmit PHY Clock delay train configuration when speed is 1000Mbps.
|
||||
+ type: boolean
|
||||
+
|
||||
+unevaluatedProperties: false
|
||||
+
|
||||
+examples:
|
||||
+ - |
|
||||
+ mdio {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ phy-mode = "rgmii-id";
|
||||
+ ethernet-phy@4 {
|
||||
+ /* Only needed to make DT lint tools work. Do not copy/paste
|
||||
+ * into real DTS files.
|
||||
+ */
|
||||
+ compatible = "ethernet-phy-id4f51.e91a";
|
||||
+
|
||||
+ reg = <4>;
|
||||
+ rx-internal-delay-ps = <2100>;
|
||||
+ tx-internal-delay-ps = <150>;
|
||||
+ motorcomm,clk-out-frequency-hz = <0>;
|
||||
+ motorcomm,keep-pll-enabled;
|
||||
+ motorcomm,auto-sleep-disabled;
|
||||
+ };
|
||||
+ };
|
||||
+ - |
|
||||
+ mdio {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ phy-mode = "rgmii";
|
||||
+ ethernet-phy@5 {
|
||||
+ /* Only needed to make DT lint tools work. Do not copy/paste
|
||||
+ * into real DTS files.
|
||||
+ */
|
||||
+ compatible = "ethernet-phy-id4f51.e91a";
|
||||
+
|
||||
+ reg = <5>;
|
||||
+ motorcomm,clk-out-frequency-hz = <125000000>;
|
||||
+ motorcomm,keep-pll-enabled;
|
||||
+ motorcomm,auto-sleep-disabled;
|
||||
+ };
|
||||
+ };
|
||||
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
|
||||
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
|
||||
@@ -831,6 +831,8 @@ patternProperties:
|
||||
description: Moortec Semiconductor Ltd.
|
||||
"^mosaixtech,.*":
|
||||
description: Mosaix Technologies, Inc.
|
||||
+ "^motorcomm,.*":
|
||||
+ description: MotorComm, Inc.
|
||||
"^motorola,.*":
|
||||
description: Motorola, Inc.
|
||||
"^moxa,.*":
|
@ -0,0 +1,34 @@
|
||||
From 2d146c6e550a4fb7f24ca44739cf14594cc2f892 Mon Sep 17 00:00:00 2001
|
||||
From: Samin Guo <samin.guo@starfivetech.com>
|
||||
Date: Tue, 25 Apr 2023 18:51:15 +0800
|
||||
Subject: [PATCH 049/122] dt-bindings: net: motorcomm: Add pad driver strength
|
||||
cfg
|
||||
|
||||
The motorcomm phy (YT8531) supports the ability to adjust the drive
|
||||
strength of the rx_clk/rx_data, the value range of pad driver
|
||||
strength is 0 to 7.
|
||||
|
||||
Signed-off-by: Samin Guo <samin.guo@starfivetech.com>
|
||||
---
|
||||
.../devicetree/bindings/net/motorcomm,yt8xxx.yaml | 10 ++++++++++
|
||||
1 file changed, 10 insertions(+)
|
||||
|
||||
--- a/Documentation/devicetree/bindings/net/motorcomm,yt8xxx.yaml
|
||||
+++ b/Documentation/devicetree/bindings/net/motorcomm,yt8xxx.yaml
|
||||
@@ -18,6 +18,16 @@ properties:
|
||||
- ethernet-phy-id4f51.e91a
|
||||
- ethernet-phy-id4f51.e91b
|
||||
|
||||
+ rx-clk-driver-strength:
|
||||
+ description: drive strength of rx_clk pad.
|
||||
+ enum: [ 0, 1, 2, 3, 4, 5, 6, 7 ]
|
||||
+ default: 3
|
||||
+
|
||||
+ rx-data-driver-strength:
|
||||
+ description: drive strength of rxd/rx_ctl rgmii pad.
|
||||
+ enum: [ 0, 1, 2, 3, 4, 5, 6, 7 ]
|
||||
+ default: 3
|
||||
+
|
||||
rx-internal-delay-ps:
|
||||
description: |
|
||||
RGMII RX Clock Delay used only when PHY operates in RGMII mode with
|
@ -0,0 +1,34 @@
|
||||
From c156cb9ec64669600c96dbb01bf38dd2370b1850 Mon Sep 17 00:00:00 2001
|
||||
From: Samin Guo <samin.guo@starfivetech.com>
|
||||
Date: Wed, 26 Apr 2023 14:41:12 +0800
|
||||
Subject: [PATCH 050/122] riscv: dts: starfive: visionfive-2-v1.3B: Set the
|
||||
driver strength of RXC/RXD
|
||||
|
||||
VisionFive 2 v1.3B needs to increase the driver strength of rxd/rxc
|
||||
to increase the stability of gmac's transmission.
|
||||
|
||||
Signed-off-by: Samin Guo <samin.guo@starfivetech.com>
|
||||
---
|
||||
.../boot/dts/starfive/jh7110-starfive-visionfive-2-v1.3b.dts | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
--- a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-v1.3b.dts
|
||||
+++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-v1.3b.dts
|
||||
@@ -28,6 +28,8 @@
|
||||
motorcomm,tx-clk-adj-enabled;
|
||||
motorcomm,tx-clk-100-inverted;
|
||||
motorcomm,tx-clk-1000-inverted;
|
||||
+ rx-clk-driver-strength = <0x6>;
|
||||
+ rx-data-driver-strength = <0x3>;
|
||||
rx-internal-delay-ps = <1500>;
|
||||
tx-internal-delay-ps = <1500>;
|
||||
};
|
||||
@@ -35,6 +37,8 @@
|
||||
&phy1 {
|
||||
motorcomm,tx-clk-adj-enabled;
|
||||
motorcomm,tx-clk-100-inverted;
|
||||
+ rx-clk-driver-strength = <0x6>;
|
||||
+ rx-data-driver-strength = <0x3>;
|
||||
rx-internal-delay-ps = <300>;
|
||||
tx-internal-delay-ps = <0>;
|
||||
};
|
@ -0,0 +1,193 @@
|
||||
From 84575863e4cf1a5dd877a11d31115c19004ac36a Mon Sep 17 00:00:00 2001
|
||||
From: Xingyu Wu <xingyu.wu@starfivetech.com>
|
||||
Date: Thu, 18 May 2023 18:12:24 +0800
|
||||
Subject: [PATCH 051/122] dt-bindings: clock: Add StarFive JH7110
|
||||
System-Top-Group clock and reset generator
|
||||
|
||||
Add bindings for the System-Top-Group clock and reset generator (STGCRG)
|
||||
on the JH7110 RISC-V SoC by StarFive Ltd.
|
||||
|
||||
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
|
||||
Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
|
||||
---
|
||||
.../clock/starfive,jh7110-stgcrg.yaml | 82 +++++++++++++++++++
|
||||
.../dt-bindings/clock/starfive,jh7110-crg.h | 34 ++++++++
|
||||
.../dt-bindings/reset/starfive,jh7110-crg.h | 28 +++++++
|
||||
3 files changed, 144 insertions(+)
|
||||
create mode 100644 Documentation/devicetree/bindings/clock/starfive,jh7110-stgcrg.yaml
|
||||
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/clock/starfive,jh7110-stgcrg.yaml
|
||||
@@ -0,0 +1,82 @@
|
||||
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
+%YAML 1.2
|
||||
+---
|
||||
+$id: http://devicetree.org/schemas/clock/starfive,jh7110-stgcrg.yaml#
|
||||
+$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
+
|
||||
+title: StarFive JH7110 System-Top-Group Clock and Reset Generator
|
||||
+
|
||||
+maintainers:
|
||||
+ - Xingyu Wu <xingyu.wu@starfivetech.com>
|
||||
+
|
||||
+properties:
|
||||
+ compatible:
|
||||
+ const: starfive,jh7110-stgcrg
|
||||
+
|
||||
+ reg:
|
||||
+ maxItems: 1
|
||||
+
|
||||
+ clocks:
|
||||
+ items:
|
||||
+ - description: Main Oscillator (24 MHz)
|
||||
+ - description: HIFI4 core
|
||||
+ - description: STG AXI/AHB
|
||||
+ - description: USB (125 MHz)
|
||||
+ - description: CPU Bus
|
||||
+ - description: HIFI4 Axi
|
||||
+ - description: NOC STG Bus
|
||||
+ - description: APB Bus
|
||||
+
|
||||
+ clock-names:
|
||||
+ items:
|
||||
+ - const: osc
|
||||
+ - const: hifi4_core
|
||||
+ - const: stg_axiahb
|
||||
+ - const: usb_125m
|
||||
+ - const: cpu_bus
|
||||
+ - const: hifi4_axi
|
||||
+ - const: nocstg_bus
|
||||
+ - const: apb_bus
|
||||
+
|
||||
+ '#clock-cells':
|
||||
+ const: 1
|
||||
+ description:
|
||||
+ See <dt-bindings/clock/starfive,jh7110-crg.h> for valid indices.
|
||||
+
|
||||
+ '#reset-cells':
|
||||
+ const: 1
|
||||
+ description:
|
||||
+ See <dt-bindings/reset/starfive,jh7110-crg.h> for valid indices.
|
||||
+
|
||||
+required:
|
||||
+ - compatible
|
||||
+ - reg
|
||||
+ - clocks
|
||||
+ - clock-names
|
||||
+ - '#clock-cells'
|
||||
+ - '#reset-cells'
|
||||
+
|
||||
+additionalProperties: false
|
||||
+
|
||||
+examples:
|
||||
+ - |
|
||||
+ #include <dt-bindings/clock/starfive,jh7110-crg.h>
|
||||
+
|
||||
+ stgcrg: clock-controller@10230000 {
|
||||
+ compatible = "starfive,jh7110-stgcrg";
|
||||
+ reg = <0x10230000 0x10000>;
|
||||
+ clocks = <&osc>,
|
||||
+ <&syscrg JH7110_SYSCLK_HIFI4_CORE>,
|
||||
+ <&syscrg JH7110_SYSCLK_STG_AXIAHB>,
|
||||
+ <&syscrg JH7110_SYSCLK_USB_125M>,
|
||||
+ <&syscrg JH7110_SYSCLK_CPU_BUS>,
|
||||
+ <&syscrg JH7110_SYSCLK_HIFI4_AXI>,
|
||||
+ <&syscrg JH7110_SYSCLK_NOCSTG_BUS>,
|
||||
+ <&syscrg JH7110_SYSCLK_APB_BUS>;
|
||||
+ clock-names = "osc", "hifi4_core",
|
||||
+ "stg_axiahb", "usb_125m",
|
||||
+ "cpu_bus", "hifi4_axi",
|
||||
+ "nocstg_bus", "apb_bus";
|
||||
+ #clock-cells = <1>;
|
||||
+ #reset-cells = <1>;
|
||||
+ };
|
||||
--- a/include/dt-bindings/clock/starfive,jh7110-crg.h
|
||||
+++ b/include/dt-bindings/clock/starfive,jh7110-crg.h
|
||||
@@ -1,6 +1,7 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 OR MIT */
|
||||
/*
|
||||
* Copyright 2022 Emil Renner Berthing <kernel@esmil.dk>
|
||||
+ * Copyright 2022 StarFive Technology Co., Ltd.
|
||||
*/
|
||||
|
||||
#ifndef __DT_BINDINGS_CLOCK_STARFIVE_JH7110_CRG_H__
|
||||
@@ -224,4 +225,37 @@
|
||||
|
||||
#define JH7110_AONCLK_END 14
|
||||
|
||||
+/* STGCRG clocks */
|
||||
+#define JH7110_STGCLK_HIFI4_CLK_CORE 0
|
||||
+#define JH7110_STGCLK_USB0_APB 1
|
||||
+#define JH7110_STGCLK_USB0_UTMI_APB 2
|
||||
+#define JH7110_STGCLK_USB0_AXI 3
|
||||
+#define JH7110_STGCLK_USB0_LPM 4
|
||||
+#define JH7110_STGCLK_USB0_STB 5
|
||||
+#define JH7110_STGCLK_USB0_APP_125 6
|
||||
+#define JH7110_STGCLK_USB0_REFCLK 7
|
||||
+#define JH7110_STGCLK_PCIE0_AXI_MST0 8
|
||||
+#define JH7110_STGCLK_PCIE0_APB 9
|
||||
+#define JH7110_STGCLK_PCIE0_TL 10
|
||||
+#define JH7110_STGCLK_PCIE1_AXI_MST0 11
|
||||
+#define JH7110_STGCLK_PCIE1_APB 12
|
||||
+#define JH7110_STGCLK_PCIE1_TL 13
|
||||
+#define JH7110_STGCLK_PCIE_SLV_MAIN 14
|
||||
+#define JH7110_STGCLK_SEC_AHB 15
|
||||
+#define JH7110_STGCLK_SEC_MISC_AHB 16
|
||||
+#define JH7110_STGCLK_GRP0_MAIN 17
|
||||
+#define JH7110_STGCLK_GRP0_BUS 18
|
||||
+#define JH7110_STGCLK_GRP0_STG 19
|
||||
+#define JH7110_STGCLK_GRP1_MAIN 20
|
||||
+#define JH7110_STGCLK_GRP1_BUS 21
|
||||
+#define JH7110_STGCLK_GRP1_STG 22
|
||||
+#define JH7110_STGCLK_GRP1_HIFI 23
|
||||
+#define JH7110_STGCLK_E2_RTC 24
|
||||
+#define JH7110_STGCLK_E2_CORE 25
|
||||
+#define JH7110_STGCLK_E2_DBG 26
|
||||
+#define JH7110_STGCLK_DMA1P_AXI 27
|
||||
+#define JH7110_STGCLK_DMA1P_AHB 28
|
||||
+
|
||||
+#define JH7110_STGCLK_END 29
|
||||
+
|
||||
#endif /* __DT_BINDINGS_CLOCK_STARFIVE_JH7110_CRG_H__ */
|
||||
--- a/include/dt-bindings/reset/starfive,jh7110-crg.h
|
||||
+++ b/include/dt-bindings/reset/starfive,jh7110-crg.h
|
||||
@@ -1,6 +1,7 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 OR MIT */
|
||||
/*
|
||||
* Copyright (C) 2022 Emil Renner Berthing <kernel@esmil.dk>
|
||||
+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
|
||||
*/
|
||||
|
||||
#ifndef __DT_BINDINGS_RESET_STARFIVE_JH7110_CRG_H__
|
||||
@@ -151,4 +152,31 @@
|
||||
|
||||
#define JH7110_AONRST_END 8
|
||||
|
||||
+/* STGCRG resets */
|
||||
+#define JH7110_STGRST_SYSCON 0
|
||||
+#define JH7110_STGRST_HIFI4_CORE 1
|
||||
+#define JH7110_STGRST_HIFI4_AXI 2
|
||||
+#define JH7110_STGRST_SEC_AHB 3
|
||||
+#define JH7110_STGRST_E24_CORE 4
|
||||
+#define JH7110_STGRST_DMA1P_AXI 5
|
||||
+#define JH7110_STGRST_DMA1P_AHB 6
|
||||
+#define JH7110_STGRST_USB0_AXI 7
|
||||
+#define JH7110_STGRST_USB0_APB 8
|
||||
+#define JH7110_STGRST_USB0_UTMI_APB 9
|
||||
+#define JH7110_STGRST_USB0_PWRUP 10
|
||||
+#define JH7110_STGRST_PCIE0_AXI_MST0 11
|
||||
+#define JH7110_STGRST_PCIE0_AXI_SLV0 12
|
||||
+#define JH7110_STGRST_PCIE0_AXI_SLV 13
|
||||
+#define JH7110_STGRST_PCIE0_BRG 14
|
||||
+#define JH7110_STGRST_PCIE0_CORE 15
|
||||
+#define JH7110_STGRST_PCIE0_APB 16
|
||||
+#define JH7110_STGRST_PCIE1_AXI_MST0 17
|
||||
+#define JH7110_STGRST_PCIE1_AXI_SLV0 18
|
||||
+#define JH7110_STGRST_PCIE1_AXI_SLV 19
|
||||
+#define JH7110_STGRST_PCIE1_BRG 20
|
||||
+#define JH7110_STGRST_PCIE1_CORE 21
|
||||
+#define JH7110_STGRST_PCIE1_APB 22
|
||||
+
|
||||
+#define JH7110_STGRST_END 23
|
||||
+
|
||||
#endif /* __DT_BINDINGS_RESET_STARFIVE_JH7110_CRG_H__ */
|
@ -0,0 +1,218 @@
|
||||
From 9a02d66b0515d987037d0229b99367412b9eb38c Mon Sep 17 00:00:00 2001
|
||||
From: Emil Renner Berthing <emil.renner.berthing@canonical.com>
|
||||
Date: Thu, 18 May 2023 18:12:25 +0800
|
||||
Subject: [PATCH 052/122] clk: starfive: Add StarFive JH7110 System-Top-Group
|
||||
clock driver
|
||||
|
||||
Add driver for the StarFive JH7110 System-Top-Group clock controller.
|
||||
|
||||
Co-developed-by: Xingyu Wu <xingyu.wu@starfivetech.com>
|
||||
Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
|
||||
Signed-off-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
|
||||
---
|
||||
drivers/clk/starfive/Kconfig | 11 ++
|
||||
drivers/clk/starfive/Makefile | 1 +
|
||||
.../clk/starfive/clk-starfive-jh7110-stg.c | 173 ++++++++++++++++++
|
||||
3 files changed, 185 insertions(+)
|
||||
create mode 100644 drivers/clk/starfive/clk-starfive-jh7110-stg.c
|
||||
|
||||
--- a/drivers/clk/starfive/Kconfig
|
||||
+++ b/drivers/clk/starfive/Kconfig
|
||||
@@ -51,3 +51,14 @@ config CLK_STARFIVE_JH7110_AON
|
||||
help
|
||||
Say yes here to support the always-on clock controller on the
|
||||
StarFive JH7110 SoC.
|
||||
+
|
||||
+config CLK_STARFIVE_JH7110_STG
|
||||
+ tristate "StarFive JH7110 System-Top-Group clock support"
|
||||
+ depends on CLK_STARFIVE_JH7110_SYS
|
||||
+ select AUXILIARY_BUS
|
||||
+ select CLK_STARFIVE_JH71X0
|
||||
+ select RESET_STARFIVE_JH7110
|
||||
+ default m if ARCH_STARFIVE
|
||||
+ help
|
||||
+ Say yes here to support the System-Top-Group clock controller
|
||||
+ on the StarFive JH7110 SoC.
|
||||
--- a/drivers/clk/starfive/Makefile
|
||||
+++ b/drivers/clk/starfive/Makefile
|
||||
@@ -7,3 +7,4 @@ obj-$(CONFIG_CLK_STARFIVE_JH7100_AUDIO)
|
||||
obj-$(CONFIG_CLK_STARFIVE_JH7110_PLL) += clk-starfive-jh7110-pll.o
|
||||
obj-$(CONFIG_CLK_STARFIVE_JH7110_SYS) += clk-starfive-jh7110-sys.o
|
||||
obj-$(CONFIG_CLK_STARFIVE_JH7110_AON) += clk-starfive-jh7110-aon.o
|
||||
+obj-$(CONFIG_CLK_STARFIVE_JH7110_STG) += clk-starfive-jh7110-stg.o
|
||||
--- /dev/null
|
||||
+++ b/drivers/clk/starfive/clk-starfive-jh7110-stg.c
|
||||
@@ -0,0 +1,173 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0
|
||||
+/*
|
||||
+ * StarFive JH7110 System-Top-Group Clock Driver
|
||||
+ *
|
||||
+ * Copyright (C) 2022 Emil Renner Berthing <kernel@esmil.dk>
|
||||
+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/clk-provider.h>
|
||||
+#include <linux/io.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+
|
||||
+#include <dt-bindings/clock/starfive,jh7110-crg.h>
|
||||
+
|
||||
+#include "clk-starfive-jh7110.h"
|
||||
+
|
||||
+/* external clocks */
|
||||
+#define JH7110_STGCLK_OSC (JH7110_STGCLK_END + 0)
|
||||
+#define JH7110_STGCLK_HIFI4_CORE (JH7110_STGCLK_END + 1)
|
||||
+#define JH7110_STGCLK_STG_AXIAHB (JH7110_STGCLK_END + 2)
|
||||
+#define JH7110_STGCLK_USB_125M (JH7110_STGCLK_END + 3)
|
||||
+#define JH7110_STGCLK_CPU_BUS (JH7110_STGCLK_END + 4)
|
||||
+#define JH7110_STGCLK_HIFI4_AXI (JH7110_STGCLK_END + 5)
|
||||
+#define JH7110_STGCLK_NOCSTG_BUS (JH7110_STGCLK_END + 6)
|
||||
+#define JH7110_STGCLK_APB_BUS (JH7110_STGCLK_END + 7)
|
||||
+#define JH7110_STGCLK_EXT_END (JH7110_STGCLK_END + 8)
|
||||
+
|
||||
+static const struct jh71x0_clk_data jh7110_stgclk_data[] = {
|
||||
+ /* hifi4 */
|
||||
+ JH71X0_GATE(JH7110_STGCLK_HIFI4_CLK_CORE, "hifi4_clk_core", 0,
|
||||
+ JH7110_STGCLK_HIFI4_CORE),
|
||||
+ /* usb */
|
||||
+ JH71X0_GATE(JH7110_STGCLK_USB0_APB, "usb0_apb", 0, JH7110_STGCLK_APB_BUS),
|
||||
+ JH71X0_GATE(JH7110_STGCLK_USB0_UTMI_APB, "usb0_utmi_apb", 0, JH7110_STGCLK_APB_BUS),
|
||||
+ JH71X0_GATE(JH7110_STGCLK_USB0_AXI, "usb0_axi", 0, JH7110_STGCLK_STG_AXIAHB),
|
||||
+ JH71X0_GDIV(JH7110_STGCLK_USB0_LPM, "usb0_lpm", 0, 2, JH7110_STGCLK_OSC),
|
||||
+ JH71X0_GDIV(JH7110_STGCLK_USB0_STB, "usb0_stb", 0, 4, JH7110_STGCLK_OSC),
|
||||
+ JH71X0_GATE(JH7110_STGCLK_USB0_APP_125, "usb0_app_125", 0, JH7110_STGCLK_USB_125M),
|
||||
+ JH71X0__DIV(JH7110_STGCLK_USB0_REFCLK, "usb0_refclk", 2, JH7110_STGCLK_OSC),
|
||||
+ /* pci-e */
|
||||
+ JH71X0_GATE(JH7110_STGCLK_PCIE0_AXI_MST0, "pcie0_axi_mst0", 0,
|
||||
+ JH7110_STGCLK_STG_AXIAHB),
|
||||
+ JH71X0_GATE(JH7110_STGCLK_PCIE0_APB, "pcie0_apb", 0, JH7110_STGCLK_APB_BUS),
|
||||
+ JH71X0_GATE(JH7110_STGCLK_PCIE0_TL, "pcie0_tl", 0, JH7110_STGCLK_STG_AXIAHB),
|
||||
+ JH71X0_GATE(JH7110_STGCLK_PCIE1_AXI_MST0, "pcie1_axi_mst0", 0,
|
||||
+ JH7110_STGCLK_STG_AXIAHB),
|
||||
+ JH71X0_GATE(JH7110_STGCLK_PCIE1_APB, "pcie1_apb", 0, JH7110_STGCLK_APB_BUS),
|
||||
+ JH71X0_GATE(JH7110_STGCLK_PCIE1_TL, "pcie1_tl", 0, JH7110_STGCLK_STG_AXIAHB),
|
||||
+ JH71X0_GATE(JH7110_STGCLK_PCIE_SLV_MAIN, "pcie_slv_main", CLK_IS_CRITICAL,
|
||||
+ JH7110_STGCLK_STG_AXIAHB),
|
||||
+ /* security */
|
||||
+ JH71X0_GATE(JH7110_STGCLK_SEC_AHB, "sec_ahb", 0, JH7110_STGCLK_STG_AXIAHB),
|
||||
+ JH71X0_GATE(JH7110_STGCLK_SEC_MISC_AHB, "sec_misc_ahb", 0, JH7110_STGCLK_STG_AXIAHB),
|
||||
+ /* stg mtrx */
|
||||
+ JH71X0_GATE(JH7110_STGCLK_GRP0_MAIN, "mtrx_grp0_main", CLK_IS_CRITICAL,
|
||||
+ JH7110_STGCLK_CPU_BUS),
|
||||
+ JH71X0_GATE(JH7110_STGCLK_GRP0_BUS, "mtrx_grp0_bus", CLK_IS_CRITICAL,
|
||||
+ JH7110_STGCLK_NOCSTG_BUS),
|
||||
+ JH71X0_GATE(JH7110_STGCLK_GRP0_STG, "mtrx_grp0_stg", CLK_IS_CRITICAL,
|
||||
+ JH7110_STGCLK_STG_AXIAHB),
|
||||
+ JH71X0_GATE(JH7110_STGCLK_GRP1_MAIN, "mtrx_grp1_main", CLK_IS_CRITICAL,
|
||||
+ JH7110_STGCLK_CPU_BUS),
|
||||
+ JH71X0_GATE(JH7110_STGCLK_GRP1_BUS, "mtrx_grp1_bus", CLK_IS_CRITICAL,
|
||||
+ JH7110_STGCLK_NOCSTG_BUS),
|
||||
+ JH71X0_GATE(JH7110_STGCLK_GRP1_STG, "mtrx_grp1_stg", CLK_IS_CRITICAL,
|
||||
+ JH7110_STGCLK_STG_AXIAHB),
|
||||
+ JH71X0_GATE(JH7110_STGCLK_GRP1_HIFI, "mtrx_grp1_hifi", CLK_IS_CRITICAL,
|
||||
+ JH7110_STGCLK_HIFI4_AXI),
|
||||
+ /* e24_rvpi */
|
||||
+ JH71X0_GDIV(JH7110_STGCLK_E2_RTC, "e2_rtc", 0, 24, JH7110_STGCLK_OSC),
|
||||
+ JH71X0_GATE(JH7110_STGCLK_E2_CORE, "e2_core", 0, JH7110_STGCLK_STG_AXIAHB),
|
||||
+ JH71X0_GATE(JH7110_STGCLK_E2_DBG, "e2_dbg", 0, JH7110_STGCLK_STG_AXIAHB),
|
||||
+ /* dw_sgdma1p */
|
||||
+ JH71X0_GATE(JH7110_STGCLK_DMA1P_AXI, "dma1p_axi", 0, JH7110_STGCLK_STG_AXIAHB),
|
||||
+ JH71X0_GATE(JH7110_STGCLK_DMA1P_AHB, "dma1p_ahb", 0, JH7110_STGCLK_STG_AXIAHB),
|
||||
+};
|
||||
+
|
||||
+static struct clk_hw *jh7110_stgclk_get(struct of_phandle_args *clkspec, void *data)
|
||||
+{
|
||||
+ struct jh71x0_clk_priv *priv = data;
|
||||
+ unsigned int idx = clkspec->args[0];
|
||||
+
|
||||
+ if (idx < JH7110_STGCLK_END)
|
||||
+ return &priv->reg[idx].hw;
|
||||
+
|
||||
+ return ERR_PTR(-EINVAL);
|
||||
+}
|
||||
+
|
||||
+static int jh7110_stgcrg_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct jh71x0_clk_priv *priv;
|
||||
+ unsigned int idx;
|
||||
+ int ret;
|
||||
+
|
||||
+ priv = devm_kzalloc(&pdev->dev, struct_size(priv, reg, JH7110_STGCLK_END),
|
||||
+ GFP_KERNEL);
|
||||
+ if (!priv)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ spin_lock_init(&priv->rmw_lock);
|
||||
+ priv->dev = &pdev->dev;
|
||||
+ priv->base = devm_platform_ioremap_resource(pdev, 0);
|
||||
+ if (IS_ERR(priv->base))
|
||||
+ return PTR_ERR(priv->base);
|
||||
+
|
||||
+ for (idx = 0; idx < JH7110_STGCLK_END; idx++) {
|
||||
+ u32 max = jh7110_stgclk_data[idx].max;
|
||||
+ struct clk_parent_data parents[4] = {};
|
||||
+ struct clk_init_data init = {
|
||||
+ .name = jh7110_stgclk_data[idx].name,
|
||||
+ .ops = starfive_jh71x0_clk_ops(max),
|
||||
+ .parent_data = parents,
|
||||
+ .num_parents =
|
||||
+ ((max & JH71X0_CLK_MUX_MASK) >> JH71X0_CLK_MUX_SHIFT) + 1,
|
||||
+ .flags = jh7110_stgclk_data[idx].flags,
|
||||
+ };
|
||||
+ struct jh71x0_clk *clk = &priv->reg[idx];
|
||||
+ const char *fw_name[JH7110_STGCLK_EXT_END - JH7110_STGCLK_END] = {
|
||||
+ "osc",
|
||||
+ "hifi4_core",
|
||||
+ "stg_axiahb",
|
||||
+ "usb_125m",
|
||||
+ "cpu_bus",
|
||||
+ "hifi4_axi",
|
||||
+ "nocstg_bus",
|
||||
+ "apb_bus"
|
||||
+ };
|
||||
+ unsigned int i;
|
||||
+
|
||||
+ for (i = 0; i < init.num_parents; i++) {
|
||||
+ unsigned int pidx = jh7110_stgclk_data[idx].parents[i];
|
||||
+
|
||||
+ if (pidx < JH7110_STGCLK_END)
|
||||
+ parents[i].hw = &priv->reg[pidx].hw;
|
||||
+ else if (pidx < JH7110_STGCLK_EXT_END)
|
||||
+ parents[i].fw_name = fw_name[pidx - JH7110_STGCLK_END];
|
||||
+ }
|
||||
+
|
||||
+ clk->hw.init = &init;
|
||||
+ clk->idx = idx;
|
||||
+ clk->max_div = max & JH71X0_CLK_DIV_MASK;
|
||||
+
|
||||
+ ret = devm_clk_hw_register(&pdev->dev, &clk->hw);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ ret = devm_of_clk_add_hw_provider(&pdev->dev, jh7110_stgclk_get, priv);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ return jh7110_reset_controller_register(priv, "rst-stg", 2);
|
||||
+}
|
||||
+
|
||||
+static const struct of_device_id jh7110_stgcrg_match[] = {
|
||||
+ { .compatible = "starfive,jh7110-stgcrg" },
|
||||
+ { /* sentinel */ }
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, jh7110_stgcrg_match);
|
||||
+
|
||||
+static struct platform_driver jh7110_stgcrg_driver = {
|
||||
+ .probe = jh7110_stgcrg_probe,
|
||||
+ .driver = {
|
||||
+ .name = "clk-starfive-jh7110-stg",
|
||||
+ .of_match_table = jh7110_stgcrg_match,
|
||||
+ },
|
||||
+};
|
||||
+module_platform_driver(jh7110_stgcrg_driver);
|
||||
+
|
||||
+MODULE_AUTHOR("Xingyu Wu <xingyu.wu@starfivetech.com>");
|
||||
+MODULE_AUTHOR("Emil Renner Berthing <kernel@esmil.dk>");
|
||||
+MODULE_DESCRIPTION("StarFive JH7110 System-Top-Group clock driver");
|
||||
+MODULE_LICENSE("GPL");
|
@ -0,0 +1,156 @@
|
||||
From 70df2590923e262ce8bf2b4f497f3481511d4fd6 Mon Sep 17 00:00:00 2001
|
||||
From: Xingyu Wu <xingyu.wu@starfivetech.com>
|
||||
Date: Thu, 18 May 2023 18:12:26 +0800
|
||||
Subject: [PATCH 053/122] dt-bindings: clock: Add StarFive JH7110
|
||||
Image-Signal-Process clock and reset generator
|
||||
|
||||
Add bindings for the Image-Signal-Process clock and reset
|
||||
generator (ISPCRG) on the JH7110 RISC-V SoC by StarFive Ltd.
|
||||
|
||||
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
|
||||
Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
|
||||
---
|
||||
.../clock/starfive,jh7110-ispcrg.yaml | 87 +++++++++++++++++++
|
||||
.../dt-bindings/clock/starfive,jh7110-crg.h | 18 ++++
|
||||
.../dt-bindings/reset/starfive,jh7110-crg.h | 16 ++++
|
||||
3 files changed, 121 insertions(+)
|
||||
create mode 100644 Documentation/devicetree/bindings/clock/starfive,jh7110-ispcrg.yaml
|
||||
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/clock/starfive,jh7110-ispcrg.yaml
|
||||
@@ -0,0 +1,87 @@
|
||||
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
+%YAML 1.2
|
||||
+---
|
||||
+$id: http://devicetree.org/schemas/clock/starfive,jh7110-ispcrg.yaml#
|
||||
+$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
+
|
||||
+title: StarFive JH7110 Image-Signal-Process Clock and Reset Generator
|
||||
+
|
||||
+maintainers:
|
||||
+ - Xingyu Wu <xingyu.wu@starfivetech.com>
|
||||
+
|
||||
+properties:
|
||||
+ compatible:
|
||||
+ const: starfive,jh7110-ispcrg
|
||||
+
|
||||
+ reg:
|
||||
+ maxItems: 1
|
||||
+
|
||||
+ clocks:
|
||||
+ items:
|
||||
+ - description: ISP Top core
|
||||
+ - description: ISP Top Axi
|
||||
+ - description: NOC ISP Bus
|
||||
+ - description: external DVP
|
||||
+
|
||||
+ clock-names:
|
||||
+ items:
|
||||
+ - const: isp_top_core
|
||||
+ - const: isp_top_axi
|
||||
+ - const: noc_bus_isp_axi
|
||||
+ - const: dvp_clk
|
||||
+
|
||||
+ resets:
|
||||
+ items:
|
||||
+ - description: ISP Top core
|
||||
+ - description: ISP Top Axi
|
||||
+ - description: NOC ISP Bus
|
||||
+
|
||||
+ '#clock-cells':
|
||||
+ const: 1
|
||||
+ description:
|
||||
+ See <dt-bindings/clock/starfive,jh7110-crg.h> for valid indices.
|
||||
+
|
||||
+ '#reset-cells':
|
||||
+ const: 1
|
||||
+ description:
|
||||
+ See <dt-bindings/reset/starfive,jh7110-crg.h> for valid indices.
|
||||
+
|
||||
+ power-domains:
|
||||
+ maxItems: 1
|
||||
+ description:
|
||||
+ ISP domain power
|
||||
+
|
||||
+required:
|
||||
+ - compatible
|
||||
+ - reg
|
||||
+ - clocks
|
||||
+ - clock-names
|
||||
+ - resets
|
||||
+ - '#clock-cells'
|
||||
+ - '#reset-cells'
|
||||
+ - power-domains
|
||||
+
|
||||
+additionalProperties: false
|
||||
+
|
||||
+examples:
|
||||
+ - |
|
||||
+ #include <dt-bindings/clock/starfive,jh7110-crg.h>
|
||||
+ #include <dt-bindings/power/starfive,jh7110-pmu.h>
|
||||
+ #include <dt-bindings/reset/starfive,jh7110-crg.h>
|
||||
+
|
||||
+ ispcrg: clock-controller@19810000 {
|
||||
+ compatible = "starfive,jh7110-ispcrg";
|
||||
+ reg = <0x19810000 0x10000>;
|
||||
+ clocks = <&syscrg JH7110_SYSCLK_ISP_TOP_CORE>,
|
||||
+ <&syscrg JH7110_SYSCLK_ISP_TOP_AXI>,
|
||||
+ <&syscrg JH7110_SYSCLK_NOC_BUS_ISP_AXI>,
|
||||
+ <&dvp_clk>;
|
||||
+ clock-names = "isp_top_core", "isp_top_axi",
|
||||
+ "noc_bus_isp_axi", "dvp_clk";
|
||||
+ resets = <&syscrg JH7110_SYSRST_ISP_TOP>,
|
||||
+ <&syscrg JH7110_SYSRST_ISP_TOP_AXI>,
|
||||
+ <&syscrg JH7110_SYSRST_NOC_BUS_ISP_AXI>;
|
||||
+ #clock-cells = <1>;
|
||||
+ #reset-cells = <1>;
|
||||
+ power-domains = <&pwrc JH7110_PD_ISP>;
|
||||
+ };
|
||||
--- a/include/dt-bindings/clock/starfive,jh7110-crg.h
|
||||
+++ b/include/dt-bindings/clock/starfive,jh7110-crg.h
|
||||
@@ -258,4 +258,22 @@
|
||||
|
||||
#define JH7110_STGCLK_END 29
|
||||
|
||||
+/* ISPCRG clocks */
|
||||
+#define JH7110_ISPCLK_DOM4_APB_FUNC 0
|
||||
+#define JH7110_ISPCLK_MIPI_RX0_PXL 1
|
||||
+#define JH7110_ISPCLK_DVP_INV 2
|
||||
+#define JH7110_ISPCLK_M31DPHY_CFG_IN 3
|
||||
+#define JH7110_ISPCLK_M31DPHY_REF_IN 4
|
||||
+#define JH7110_ISPCLK_M31DPHY_TX_ESC_LAN0 5
|
||||
+#define JH7110_ISPCLK_VIN_APB 6
|
||||
+#define JH7110_ISPCLK_VIN_SYS 7
|
||||
+#define JH7110_ISPCLK_VIN_PIXEL_IF0 8
|
||||
+#define JH7110_ISPCLK_VIN_PIXEL_IF1 9
|
||||
+#define JH7110_ISPCLK_VIN_PIXEL_IF2 10
|
||||
+#define JH7110_ISPCLK_VIN_PIXEL_IF3 11
|
||||
+#define JH7110_ISPCLK_VIN_P_AXI_WR 12
|
||||
+#define JH7110_ISPCLK_ISPV2_TOP_WRAPPER_C 13
|
||||
+
|
||||
+#define JH7110_ISPCLK_END 14
|
||||
+
|
||||
#endif /* __DT_BINDINGS_CLOCK_STARFIVE_JH7110_CRG_H__ */
|
||||
--- a/include/dt-bindings/reset/starfive,jh7110-crg.h
|
||||
+++ b/include/dt-bindings/reset/starfive,jh7110-crg.h
|
||||
@@ -179,4 +179,20 @@
|
||||
|
||||
#define JH7110_STGRST_END 23
|
||||
|
||||
+/* ISPCRG resets */
|
||||
+#define JH7110_ISPRST_ISPV2_TOP_WRAPPER_P 0
|
||||
+#define JH7110_ISPRST_ISPV2_TOP_WRAPPER_C 1
|
||||
+#define JH7110_ISPRST_M31DPHY_HW 2
|
||||
+#define JH7110_ISPRST_M31DPHY_B09_AON 3
|
||||
+#define JH7110_ISPRST_VIN_APB 4
|
||||
+#define JH7110_ISPRST_VIN_PIXEL_IF0 5
|
||||
+#define JH7110_ISPRST_VIN_PIXEL_IF1 6
|
||||
+#define JH7110_ISPRST_VIN_PIXEL_IF2 7
|
||||
+#define JH7110_ISPRST_VIN_PIXEL_IF3 8
|
||||
+#define JH7110_ISPRST_VIN_SYS 9
|
||||
+#define JH7110_ISPRST_VIN_P_AXI_RD 10
|
||||
+#define JH7110_ISPRST_VIN_P_AXI_WR 11
|
||||
+
|
||||
+#define JH7110_ISPRST_END 12
|
||||
+
|
||||
#endif /* __DT_BINDINGS_RESET_STARFIVE_JH7110_CRG_H__ */
|
@ -0,0 +1,293 @@
|
||||
From 003c13d81b525a184c5ca551e536e6786e2d2f5c Mon Sep 17 00:00:00 2001
|
||||
From: Xingyu Wu <xingyu.wu@starfivetech.com>
|
||||
Date: Thu, 18 May 2023 18:12:27 +0800
|
||||
Subject: [PATCH 054/122] clk: starfive: Add StarFive JH7110
|
||||
Image-Signal-Process clock driver
|
||||
|
||||
Add driver for the StarFive JH7110 Image-Signal-Process clock controller.
|
||||
And these clock controllers should power on and enable the clocks from
|
||||
SYSCRG first before registering.
|
||||
|
||||
Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
|
||||
---
|
||||
drivers/clk/starfive/Kconfig | 11 +
|
||||
drivers/clk/starfive/Makefile | 1 +
|
||||
.../clk/starfive/clk-starfive-jh7110-isp.c | 232 ++++++++++++++++++
|
||||
drivers/clk/starfive/clk-starfive-jh7110.h | 6 +
|
||||
4 files changed, 250 insertions(+)
|
||||
create mode 100644 drivers/clk/starfive/clk-starfive-jh7110-isp.c
|
||||
|
||||
--- a/drivers/clk/starfive/Kconfig
|
||||
+++ b/drivers/clk/starfive/Kconfig
|
||||
@@ -62,3 +62,14 @@ config CLK_STARFIVE_JH7110_STG
|
||||
help
|
||||
Say yes here to support the System-Top-Group clock controller
|
||||
on the StarFive JH7110 SoC.
|
||||
+
|
||||
+config CLK_STARFIVE_JH7110_ISP
|
||||
+ tristate "StarFive JH7110 Image-Signal-Process clock support"
|
||||
+ depends on CLK_STARFIVE_JH7110_SYS && JH71XX_PMU
|
||||
+ select AUXILIARY_BUS
|
||||
+ select CLK_STARFIVE_JH71X0
|
||||
+ select RESET_STARFIVE_JH7110
|
||||
+ default m if ARCH_STARFIVE
|
||||
+ help
|
||||
+ Say yes here to support the Image-Signal-Process clock controller
|
||||
+ on the StarFive JH7110 SoC.
|
||||
--- a/drivers/clk/starfive/Makefile
|
||||
+++ b/drivers/clk/starfive/Makefile
|
||||
@@ -8,3 +8,4 @@ obj-$(CONFIG_CLK_STARFIVE_JH7110_PLL) +=
|
||||
obj-$(CONFIG_CLK_STARFIVE_JH7110_SYS) += clk-starfive-jh7110-sys.o
|
||||
obj-$(CONFIG_CLK_STARFIVE_JH7110_AON) += clk-starfive-jh7110-aon.o
|
||||
obj-$(CONFIG_CLK_STARFIVE_JH7110_STG) += clk-starfive-jh7110-stg.o
|
||||
+obj-$(CONFIG_CLK_STARFIVE_JH7110_ISP) += clk-starfive-jh7110-isp.o
|
||||
--- /dev/null
|
||||
+++ b/drivers/clk/starfive/clk-starfive-jh7110-isp.c
|
||||
@@ -0,0 +1,232 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0
|
||||
+/*
|
||||
+ * StarFive JH7110 Image-Signal-Process Clock Driver
|
||||
+ *
|
||||
+ * Copyright (C) 2022-2023 StarFive Technology Co., Ltd.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/clk.h>
|
||||
+#include <linux/clk-provider.h>
|
||||
+#include <linux/io.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/pm_runtime.h>
|
||||
+#include <linux/reset.h>
|
||||
+
|
||||
+#include <dt-bindings/clock/starfive,jh7110-crg.h>
|
||||
+
|
||||
+#include "clk-starfive-jh7110.h"
|
||||
+
|
||||
+/* external clocks */
|
||||
+#define JH7110_ISPCLK_ISP_TOP_CORE (JH7110_ISPCLK_END + 0)
|
||||
+#define JH7110_ISPCLK_ISP_TOP_AXI (JH7110_ISPCLK_END + 1)
|
||||
+#define JH7110_ISPCLK_NOC_BUS_ISP_AXI (JH7110_ISPCLK_END + 2)
|
||||
+#define JH7110_ISPCLK_DVP_CLK (JH7110_ISPCLK_END + 3)
|
||||
+#define JH7110_ISPCLK_EXT_END (JH7110_ISPCLK_END + 4)
|
||||
+
|
||||
+static struct clk_bulk_data jh7110_isp_top_clks[] = {
|
||||
+ { .id = "isp_top_core" },
|
||||
+ { .id = "isp_top_axi" }
|
||||
+};
|
||||
+
|
||||
+static const struct jh71x0_clk_data jh7110_ispclk_data[] = {
|
||||
+ /* syscon */
|
||||
+ JH71X0__DIV(JH7110_ISPCLK_DOM4_APB_FUNC, "dom4_apb_func", 15,
|
||||
+ JH7110_ISPCLK_ISP_TOP_AXI),
|
||||
+ JH71X0__DIV(JH7110_ISPCLK_MIPI_RX0_PXL, "mipi_rx0_pxl", 8,
|
||||
+ JH7110_ISPCLK_ISP_TOP_CORE),
|
||||
+ JH71X0__INV(JH7110_ISPCLK_DVP_INV, "dvp_inv", JH7110_ISPCLK_DVP_CLK),
|
||||
+ /* vin */
|
||||
+ JH71X0__DIV(JH7110_ISPCLK_M31DPHY_CFG_IN, "m31dphy_cfg_in", 16,
|
||||
+ JH7110_ISPCLK_ISP_TOP_CORE),
|
||||
+ JH71X0__DIV(JH7110_ISPCLK_M31DPHY_REF_IN, "m31dphy_ref_in", 16,
|
||||
+ JH7110_ISPCLK_ISP_TOP_CORE),
|
||||
+ JH71X0__DIV(JH7110_ISPCLK_M31DPHY_TX_ESC_LAN0, "m31dphy_tx_esc_lan0", 60,
|
||||
+ JH7110_ISPCLK_ISP_TOP_CORE),
|
||||
+ JH71X0_GATE(JH7110_ISPCLK_VIN_APB, "vin_apb", 0,
|
||||
+ JH7110_ISPCLK_DOM4_APB_FUNC),
|
||||
+ JH71X0__DIV(JH7110_ISPCLK_VIN_SYS, "vin_sys", 8, JH7110_ISPCLK_ISP_TOP_CORE),
|
||||
+ JH71X0_GATE(JH7110_ISPCLK_VIN_PIXEL_IF0, "vin_pixel_if0", 0,
|
||||
+ JH7110_ISPCLK_MIPI_RX0_PXL),
|
||||
+ JH71X0_GATE(JH7110_ISPCLK_VIN_PIXEL_IF1, "vin_pixel_if1", 0,
|
||||
+ JH7110_ISPCLK_MIPI_RX0_PXL),
|
||||
+ JH71X0_GATE(JH7110_ISPCLK_VIN_PIXEL_IF2, "vin_pixel_if2", 0,
|
||||
+ JH7110_ISPCLK_MIPI_RX0_PXL),
|
||||
+ JH71X0_GATE(JH7110_ISPCLK_VIN_PIXEL_IF3, "vin_pixel_if3", 0,
|
||||
+ JH7110_ISPCLK_MIPI_RX0_PXL),
|
||||
+ JH71X0__MUX(JH7110_ISPCLK_VIN_P_AXI_WR, "vin_p_axi_wr", 2,
|
||||
+ JH7110_ISPCLK_MIPI_RX0_PXL,
|
||||
+ JH7110_ISPCLK_DVP_INV),
|
||||
+ /* ispv2_top_wrapper */
|
||||
+ JH71X0_GMUX(JH7110_ISPCLK_ISPV2_TOP_WRAPPER_C, "ispv2_top_wrapper_c", 0, 2,
|
||||
+ JH7110_ISPCLK_MIPI_RX0_PXL,
|
||||
+ JH7110_ISPCLK_DVP_INV),
|
||||
+};
|
||||
+
|
||||
+static inline int jh7110_isp_top_rst_init(struct jh71x0_clk_priv *priv)
|
||||
+{
|
||||
+ struct reset_control *top_rsts;
|
||||
+
|
||||
+ /* The resets should be shared and other ISP modules will use its. */
|
||||
+ top_rsts = devm_reset_control_array_get_shared(priv->dev);
|
||||
+ if (IS_ERR(top_rsts))
|
||||
+ return dev_err_probe(priv->dev, PTR_ERR(top_rsts),
|
||||
+ "failed to get top resets\n");
|
||||
+
|
||||
+ return reset_control_deassert(top_rsts);
|
||||
+}
|
||||
+
|
||||
+static struct clk_hw *jh7110_ispclk_get(struct of_phandle_args *clkspec, void *data)
|
||||
+{
|
||||
+ struct jh71x0_clk_priv *priv = data;
|
||||
+ unsigned int idx = clkspec->args[0];
|
||||
+
|
||||
+ if (idx < JH7110_ISPCLK_END)
|
||||
+ return &priv->reg[idx].hw;
|
||||
+
|
||||
+ return ERR_PTR(-EINVAL);
|
||||
+}
|
||||
+
|
||||
+#ifdef CONFIG_PM
|
||||
+static int jh7110_ispcrg_suspend(struct device *dev)
|
||||
+{
|
||||
+ struct top_sysclk *top = dev_get_drvdata(dev);
|
||||
+
|
||||
+ clk_bulk_disable_unprepare(top->top_clks_num, top->top_clks);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int jh7110_ispcrg_resume(struct device *dev)
|
||||
+{
|
||||
+ struct top_sysclk *top = dev_get_drvdata(dev);
|
||||
+
|
||||
+ return clk_bulk_prepare_enable(top->top_clks_num, top->top_clks);
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
+static const struct dev_pm_ops jh7110_ispcrg_pm_ops = {
|
||||
+ SET_RUNTIME_PM_OPS(jh7110_ispcrg_suspend, jh7110_ispcrg_resume, NULL)
|
||||
+};
|
||||
+
|
||||
+static int jh7110_ispcrg_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct jh71x0_clk_priv *priv;
|
||||
+ struct top_sysclk *top;
|
||||
+ unsigned int idx;
|
||||
+ int ret;
|
||||
+
|
||||
+ priv = devm_kzalloc(&pdev->dev,
|
||||
+ struct_size(priv, reg, JH7110_ISPCLK_END),
|
||||
+ GFP_KERNEL);
|
||||
+ if (!priv)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ top = devm_kzalloc(&pdev->dev, sizeof(*top), GFP_KERNEL);
|
||||
+ if (!top)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ spin_lock_init(&priv->rmw_lock);
|
||||
+ priv->dev = &pdev->dev;
|
||||
+ priv->base = devm_platform_ioremap_resource(pdev, 0);
|
||||
+ if (IS_ERR(priv->base))
|
||||
+ return PTR_ERR(priv->base);
|
||||
+
|
||||
+ top->top_clks = jh7110_isp_top_clks;
|
||||
+ top->top_clks_num = ARRAY_SIZE(jh7110_isp_top_clks);
|
||||
+ ret = devm_clk_bulk_get(priv->dev, top->top_clks_num, top->top_clks);
|
||||
+ if (ret)
|
||||
+ return dev_err_probe(priv->dev, ret, "failed to get main clocks\n");
|
||||
+ dev_set_drvdata(priv->dev, top);
|
||||
+
|
||||
+ /* enable power domain and clocks */
|
||||
+ pm_runtime_enable(priv->dev);
|
||||
+ ret = pm_runtime_get_sync(priv->dev);
|
||||
+ if (ret < 0)
|
||||
+ return dev_err_probe(priv->dev, ret, "failed to turn on power\n");
|
||||
+
|
||||
+ ret = jh7110_isp_top_rst_init(priv);
|
||||
+ if (ret)
|
||||
+ goto err_exit;
|
||||
+
|
||||
+ for (idx = 0; idx < JH7110_ISPCLK_END; idx++) {
|
||||
+ u32 max = jh7110_ispclk_data[idx].max;
|
||||
+ struct clk_parent_data parents[4] = {};
|
||||
+ struct clk_init_data init = {
|
||||
+ .name = jh7110_ispclk_data[idx].name,
|
||||
+ .ops = starfive_jh71x0_clk_ops(max),
|
||||
+ .parent_data = parents,
|
||||
+ .num_parents =
|
||||
+ ((max & JH71X0_CLK_MUX_MASK) >> JH71X0_CLK_MUX_SHIFT) + 1,
|
||||
+ .flags = jh7110_ispclk_data[idx].flags,
|
||||
+ };
|
||||
+ struct jh71x0_clk *clk = &priv->reg[idx];
|
||||
+ unsigned int i;
|
||||
+ const char *fw_name[JH7110_ISPCLK_EXT_END - JH7110_ISPCLK_END] = {
|
||||
+ "isp_top_core",
|
||||
+ "isp_top_axi",
|
||||
+ "noc_bus_isp_axi",
|
||||
+ "dvp_clk"
|
||||
+ };
|
||||
+
|
||||
+ for (i = 0; i < init.num_parents; i++) {
|
||||
+ unsigned int pidx = jh7110_ispclk_data[idx].parents[i];
|
||||
+
|
||||
+ if (pidx < JH7110_ISPCLK_END)
|
||||
+ parents[i].hw = &priv->reg[pidx].hw;
|
||||
+ else
|
||||
+ parents[i].fw_name = fw_name[pidx - JH7110_ISPCLK_END];
|
||||
+ }
|
||||
+
|
||||
+ clk->hw.init = &init;
|
||||
+ clk->idx = idx;
|
||||
+ clk->max_div = max & JH71X0_CLK_DIV_MASK;
|
||||
+
|
||||
+ ret = devm_clk_hw_register(&pdev->dev, &clk->hw);
|
||||
+ if (ret)
|
||||
+ goto err_exit;
|
||||
+ }
|
||||
+
|
||||
+ ret = devm_of_clk_add_hw_provider(&pdev->dev, jh7110_ispclk_get, priv);
|
||||
+ if (ret)
|
||||
+ goto err_exit;
|
||||
+
|
||||
+ ret = jh7110_reset_controller_register(priv, "rst-isp", 3);
|
||||
+ if (ret)
|
||||
+ goto err_exit;
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+err_exit:
|
||||
+ pm_runtime_put_sync(priv->dev);
|
||||
+ pm_runtime_disable(priv->dev);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int jh7110_ispcrg_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+ pm_runtime_put_sync(&pdev->dev);
|
||||
+ pm_runtime_disable(&pdev->dev);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct of_device_id jh7110_ispcrg_match[] = {
|
||||
+ { .compatible = "starfive,jh7110-ispcrg" },
|
||||
+ { /* sentinel */ }
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, jh7110_ispcrg_match);
|
||||
+
|
||||
+static struct platform_driver jh7110_ispcrg_driver = {
|
||||
+ .probe = jh7110_ispcrg_probe,
|
||||
+ .remove = jh7110_ispcrg_remove,
|
||||
+ .driver = {
|
||||
+ .name = "clk-starfive-jh7110-isp",
|
||||
+ .of_match_table = jh7110_ispcrg_match,
|
||||
+ .pm = &jh7110_ispcrg_pm_ops,
|
||||
+ },
|
||||
+};
|
||||
+module_platform_driver(jh7110_ispcrg_driver);
|
||||
+
|
||||
+MODULE_AUTHOR("Xingyu Wu <xingyu.wu@starfivetech.com>");
|
||||
+MODULE_DESCRIPTION("StarFive JH7110 Image-Signal-Process clock driver");
|
||||
+MODULE_LICENSE("GPL");
|
||||
--- a/drivers/clk/starfive/clk-starfive-jh7110.h
|
||||
+++ b/drivers/clk/starfive/clk-starfive-jh7110.h
|
||||
@@ -4,6 +4,12 @@
|
||||
|
||||
#include "clk-starfive-jh71x0.h"
|
||||
|
||||
+/* top clocks of ISP/VOUT domain from SYSCRG */
|
||||
+struct top_sysclk {
|
||||
+ struct clk_bulk_data *top_clks;
|
||||
+ int top_clks_num;
|
||||
+};
|
||||
+
|
||||
int jh7110_reset_controller_register(struct jh71x0_clk_priv *priv,
|
||||
const char *adev_name,
|
||||
u32 adev_id);
|
@ -0,0 +1,163 @@
|
||||
From 06fa910083f37ecbc9234c7230dcbbd4d83e2f02 Mon Sep 17 00:00:00 2001
|
||||
From: Xingyu Wu <xingyu.wu@starfivetech.com>
|
||||
Date: Thu, 18 May 2023 18:12:28 +0800
|
||||
Subject: [PATCH 055/122] dt-bindings: clock: Add StarFive JH7110 Video-Output
|
||||
clock and reset generator
|
||||
|
||||
Add bindings for the Video-Output clock and reset generator (VOUTCRG)
|
||||
on the JH7110 RISC-V SoC by StarFive Ltd.
|
||||
|
||||
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
|
||||
Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
|
||||
---
|
||||
.../clock/starfive,jh7110-voutcrg.yaml | 90 +++++++++++++++++++
|
||||
.../dt-bindings/clock/starfive,jh7110-crg.h | 22 +++++
|
||||
.../dt-bindings/reset/starfive,jh7110-crg.h | 16 ++++
|
||||
3 files changed, 128 insertions(+)
|
||||
create mode 100644 Documentation/devicetree/bindings/clock/starfive,jh7110-voutcrg.yaml
|
||||
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/clock/starfive,jh7110-voutcrg.yaml
|
||||
@@ -0,0 +1,90 @@
|
||||
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
+%YAML 1.2
|
||||
+---
|
||||
+$id: http://devicetree.org/schemas/clock/starfive,jh7110-voutcrg.yaml#
|
||||
+$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
+
|
||||
+title: StarFive JH7110 Video-Output Clock and Reset Generator
|
||||
+
|
||||
+maintainers:
|
||||
+ - Xingyu Wu <xingyu.wu@starfivetech.com>
|
||||
+
|
||||
+properties:
|
||||
+ compatible:
|
||||
+ const: starfive,jh7110-voutcrg
|
||||
+
|
||||
+ reg:
|
||||
+ maxItems: 1
|
||||
+
|
||||
+ clocks:
|
||||
+ items:
|
||||
+ - description: Vout Top core
|
||||
+ - description: Vout Top Ahb
|
||||
+ - description: Vout Top Axi
|
||||
+ - description: Vout Top HDMI MCLK
|
||||
+ - description: I2STX0 BCLK
|
||||
+ - description: external HDMI pixel
|
||||
+
|
||||
+ clock-names:
|
||||
+ items:
|
||||
+ - const: vout_src
|
||||
+ - const: vout_top_ahb
|
||||
+ - const: vout_top_axi
|
||||
+ - const: vout_top_hdmitx0_mclk
|
||||
+ - const: i2stx0_bclk
|
||||
+ - const: hdmitx0_pixelclk
|
||||
+
|
||||
+ resets:
|
||||
+ maxItems: 1
|
||||
+ description: Vout Top core
|
||||
+
|
||||
+ '#clock-cells':
|
||||
+ const: 1
|
||||
+ description:
|
||||
+ See <dt-bindings/clock/starfive,jh7110-crg.h> for valid indices.
|
||||
+
|
||||
+ '#reset-cells':
|
||||
+ const: 1
|
||||
+ description:
|
||||
+ See <dt-bindings/reset/starfive,jh7110-crg.h> for valid indices.
|
||||
+
|
||||
+ power-domains:
|
||||
+ maxItems: 1
|
||||
+ description:
|
||||
+ Vout domain power
|
||||
+
|
||||
+required:
|
||||
+ - compatible
|
||||
+ - reg
|
||||
+ - clocks
|
||||
+ - clock-names
|
||||
+ - resets
|
||||
+ - '#clock-cells'
|
||||
+ - '#reset-cells'
|
||||
+ - power-domains
|
||||
+
|
||||
+additionalProperties: false
|
||||
+
|
||||
+examples:
|
||||
+ - |
|
||||
+ #include <dt-bindings/clock/starfive,jh7110-crg.h>
|
||||
+ #include <dt-bindings/power/starfive,jh7110-pmu.h>
|
||||
+ #include <dt-bindings/reset/starfive,jh7110-crg.h>
|
||||
+
|
||||
+ voutcrg: clock-controller@295C0000 {
|
||||
+ compatible = "starfive,jh7110-voutcrg";
|
||||
+ reg = <0x295C0000 0x10000>;
|
||||
+ clocks = <&syscrg JH7110_SYSCLK_VOUT_SRC>,
|
||||
+ <&syscrg JH7110_SYSCLK_VOUT_TOP_AHB>,
|
||||
+ <&syscrg JH7110_SYSCLK_VOUT_TOP_AXI>,
|
||||
+ <&syscrg JH7110_SYSCLK_VOUT_TOP_HDMITX0_MCLK>,
|
||||
+ <&syscrg JH7110_SYSCLK_I2STX0_BCLK>,
|
||||
+ <&hdmitx0_pixelclk>;
|
||||
+ clock-names = "vout_src", "vout_top_ahb",
|
||||
+ "vout_top_axi", "vout_top_hdmitx0_mclk",
|
||||
+ "i2stx0_bclk", "hdmitx0_pixelclk";
|
||||
+ resets = <&syscrg JH7110_SYSRST_VOUT_TOP_SRC>;
|
||||
+ #clock-cells = <1>;
|
||||
+ #reset-cells = <1>;
|
||||
+ power-domains = <&pwrc JH7110_PD_VOUT>;
|
||||
+ };
|
||||
--- a/include/dt-bindings/clock/starfive,jh7110-crg.h
|
||||
+++ b/include/dt-bindings/clock/starfive,jh7110-crg.h
|
||||
@@ -276,4 +276,26 @@
|
||||
|
||||
#define JH7110_ISPCLK_END 14
|
||||
|
||||
+/* VOUTCRG clocks */
|
||||
+#define JH7110_VOUTCLK_APB 0
|
||||
+#define JH7110_VOUTCLK_DC8200_PIX 1
|
||||
+#define JH7110_VOUTCLK_DSI_SYS 2
|
||||
+#define JH7110_VOUTCLK_TX_ESC 3
|
||||
+#define JH7110_VOUTCLK_DC8200_AXI 4
|
||||
+#define JH7110_VOUTCLK_DC8200_CORE 5
|
||||
+#define JH7110_VOUTCLK_DC8200_AHB 6
|
||||
+#define JH7110_VOUTCLK_DC8200_PIX0 7
|
||||
+#define JH7110_VOUTCLK_DC8200_PIX1 8
|
||||
+#define JH7110_VOUTCLK_DOM_VOUT_TOP_LCD 9
|
||||
+#define JH7110_VOUTCLK_DSITX_APB 10
|
||||
+#define JH7110_VOUTCLK_DSITX_SYS 11
|
||||
+#define JH7110_VOUTCLK_DSITX_DPI 12
|
||||
+#define JH7110_VOUTCLK_DSITX_TXESC 13
|
||||
+#define JH7110_VOUTCLK_MIPITX_DPHY_TXESC 14
|
||||
+#define JH7110_VOUTCLK_HDMI_TX_MCLK 15
|
||||
+#define JH7110_VOUTCLK_HDMI_TX_BCLK 16
|
||||
+#define JH7110_VOUTCLK_HDMI_TX_SYS 17
|
||||
+
|
||||
+#define JH7110_VOUTCLK_END 18
|
||||
+
|
||||
#endif /* __DT_BINDINGS_CLOCK_STARFIVE_JH7110_CRG_H__ */
|
||||
--- a/include/dt-bindings/reset/starfive,jh7110-crg.h
|
||||
+++ b/include/dt-bindings/reset/starfive,jh7110-crg.h
|
||||
@@ -195,4 +195,20 @@
|
||||
|
||||
#define JH7110_ISPRST_END 12
|
||||
|
||||
+/* VOUTCRG resets */
|
||||
+#define JH7110_VOUTRST_DC8200_AXI 0
|
||||
+#define JH7110_VOUTRST_DC8200_AHB 1
|
||||
+#define JH7110_VOUTRST_DC8200_CORE 2
|
||||
+#define JH7110_VOUTRST_DSITX_DPI 3
|
||||
+#define JH7110_VOUTRST_DSITX_APB 4
|
||||
+#define JH7110_VOUTRST_DSITX_RXESC 5
|
||||
+#define JH7110_VOUTRST_DSITX_SYS 6
|
||||
+#define JH7110_VOUTRST_DSITX_TXBYTEHS 7
|
||||
+#define JH7110_VOUTRST_DSITX_TXESC 8
|
||||
+#define JH7110_VOUTRST_HDMI_TX_HDMI 9
|
||||
+#define JH7110_VOUTRST_MIPITX_DPHY_SYS 10
|
||||
+#define JH7110_VOUTRST_MIPITX_DPHY_TXBYTEHS 11
|
||||
+
|
||||
+#define JH7110_VOUTRST_END 12
|
||||
+
|
||||
#endif /* __DT_BINDINGS_RESET_STARFIVE_JH7110_CRG_H__ */
|
@ -0,0 +1,284 @@
|
||||
From 2e632d5c5f8b4577ac823f6a9dcf3eacdb14a0ba Mon Sep 17 00:00:00 2001
|
||||
From: Xingyu Wu <xingyu.wu@starfivetech.com>
|
||||
Date: Thu, 18 May 2023 18:12:29 +0800
|
||||
Subject: [PATCH 056/122] clk: starfive: Add StarFive JH7110 Video-Output clock
|
||||
driver
|
||||
|
||||
Add driver for the StarFive JH7110 Video-Output clock controller.
|
||||
And these clock controllers should power on and enable the clocks from
|
||||
SYSCRG first before registering.
|
||||
|
||||
Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
|
||||
---
|
||||
drivers/clk/starfive/Kconfig | 11 +
|
||||
drivers/clk/starfive/Makefile | 1 +
|
||||
.../clk/starfive/clk-starfive-jh7110-vout.c | 239 ++++++++++++++++++
|
||||
3 files changed, 251 insertions(+)
|
||||
create mode 100644 drivers/clk/starfive/clk-starfive-jh7110-vout.c
|
||||
|
||||
--- a/drivers/clk/starfive/Kconfig
|
||||
+++ b/drivers/clk/starfive/Kconfig
|
||||
@@ -73,3 +73,14 @@ config CLK_STARFIVE_JH7110_ISP
|
||||
help
|
||||
Say yes here to support the Image-Signal-Process clock controller
|
||||
on the StarFive JH7110 SoC.
|
||||
+
|
||||
+config CLK_STARFIVE_JH7110_VOUT
|
||||
+ tristate "StarFive JH7110 Video-Output clock support"
|
||||
+ depends on CLK_STARFIVE_JH7110_SYS && JH71XX_PMU
|
||||
+ select AUXILIARY_BUS
|
||||
+ select CLK_STARFIVE_JH71X0
|
||||
+ select RESET_STARFIVE_JH7110
|
||||
+ default m if ARCH_STARFIVE
|
||||
+ help
|
||||
+ Say yes here to support the Video-Output clock controller
|
||||
+ on the StarFive JH7110 SoC.
|
||||
--- a/drivers/clk/starfive/Makefile
|
||||
+++ b/drivers/clk/starfive/Makefile
|
||||
@@ -9,3 +9,4 @@ obj-$(CONFIG_CLK_STARFIVE_JH7110_SYS) +=
|
||||
obj-$(CONFIG_CLK_STARFIVE_JH7110_AON) += clk-starfive-jh7110-aon.o
|
||||
obj-$(CONFIG_CLK_STARFIVE_JH7110_STG) += clk-starfive-jh7110-stg.o
|
||||
obj-$(CONFIG_CLK_STARFIVE_JH7110_ISP) += clk-starfive-jh7110-isp.o
|
||||
+obj-$(CONFIG_CLK_STARFIVE_JH7110_VOUT) += clk-starfive-jh7110-vout.o
|
||||
--- /dev/null
|
||||
+++ b/drivers/clk/starfive/clk-starfive-jh7110-vout.c
|
||||
@@ -0,0 +1,239 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0
|
||||
+/*
|
||||
+ * StarFive JH7110 Video-Output Clock Driver
|
||||
+ *
|
||||
+ * Copyright (C) 2022-2023 StarFive Technology Co., Ltd.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/clk.h>
|
||||
+#include <linux/clk-provider.h>
|
||||
+#include <linux/io.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/pm_runtime.h>
|
||||
+#include <linux/reset.h>
|
||||
+
|
||||
+#include <dt-bindings/clock/starfive,jh7110-crg.h>
|
||||
+
|
||||
+#include "clk-starfive-jh7110.h"
|
||||
+
|
||||
+/* external clocks */
|
||||
+#define JH7110_VOUTCLK_VOUT_SRC (JH7110_VOUTCLK_END + 0)
|
||||
+#define JH7110_VOUTCLK_VOUT_TOP_AHB (JH7110_VOUTCLK_END + 1)
|
||||
+#define JH7110_VOUTCLK_VOUT_TOP_AXI (JH7110_VOUTCLK_END + 2)
|
||||
+#define JH7110_VOUTCLK_VOUT_TOP_HDMITX0_MCLK (JH7110_VOUTCLK_END + 3)
|
||||
+#define JH7110_VOUTCLK_I2STX0_BCLK (JH7110_VOUTCLK_END + 4)
|
||||
+#define JH7110_VOUTCLK_HDMITX0_PIXELCLK (JH7110_VOUTCLK_END + 5)
|
||||
+#define JH7110_VOUTCLK_EXT_END (JH7110_VOUTCLK_END + 6)
|
||||
+
|
||||
+static struct clk_bulk_data jh7110_vout_top_clks[] = {
|
||||
+ { .id = "vout_src" },
|
||||
+ { .id = "vout_top_ahb" }
|
||||
+};
|
||||
+
|
||||
+static const struct jh71x0_clk_data jh7110_voutclk_data[] = {
|
||||
+ /* divider */
|
||||
+ JH71X0__DIV(JH7110_VOUTCLK_APB, "apb", 8, JH7110_VOUTCLK_VOUT_TOP_AHB),
|
||||
+ JH71X0__DIV(JH7110_VOUTCLK_DC8200_PIX, "dc8200_pix", 63, JH7110_VOUTCLK_VOUT_SRC),
|
||||
+ JH71X0__DIV(JH7110_VOUTCLK_DSI_SYS, "dsi_sys", 31, JH7110_VOUTCLK_VOUT_SRC),
|
||||
+ JH71X0__DIV(JH7110_VOUTCLK_TX_ESC, "tx_esc", 31, JH7110_VOUTCLK_VOUT_TOP_AHB),
|
||||
+ /* dc8200 */
|
||||
+ JH71X0_GATE(JH7110_VOUTCLK_DC8200_AXI, "dc8200_axi", 0, JH7110_VOUTCLK_VOUT_TOP_AXI),
|
||||
+ JH71X0_GATE(JH7110_VOUTCLK_DC8200_CORE, "dc8200_core", 0, JH7110_VOUTCLK_VOUT_TOP_AXI),
|
||||
+ JH71X0_GATE(JH7110_VOUTCLK_DC8200_AHB, "dc8200_ahb", 0, JH7110_VOUTCLK_VOUT_TOP_AHB),
|
||||
+ JH71X0_GMUX(JH7110_VOUTCLK_DC8200_PIX0, "dc8200_pix0", 0, 2,
|
||||
+ JH7110_VOUTCLK_DC8200_PIX,
|
||||
+ JH7110_VOUTCLK_HDMITX0_PIXELCLK),
|
||||
+ JH71X0_GMUX(JH7110_VOUTCLK_DC8200_PIX1, "dc8200_pix1", 0, 2,
|
||||
+ JH7110_VOUTCLK_DC8200_PIX,
|
||||
+ JH7110_VOUTCLK_HDMITX0_PIXELCLK),
|
||||
+ /* LCD */
|
||||
+ JH71X0_GMUX(JH7110_VOUTCLK_DOM_VOUT_TOP_LCD, "dom_vout_top_lcd", 0, 2,
|
||||
+ JH7110_VOUTCLK_DC8200_PIX0,
|
||||
+ JH7110_VOUTCLK_DC8200_PIX1),
|
||||
+ /* dsiTx */
|
||||
+ JH71X0_GATE(JH7110_VOUTCLK_DSITX_APB, "dsiTx_apb", 0, JH7110_VOUTCLK_DSI_SYS),
|
||||
+ JH71X0_GATE(JH7110_VOUTCLK_DSITX_SYS, "dsiTx_sys", 0, JH7110_VOUTCLK_DSI_SYS),
|
||||
+ JH71X0_GMUX(JH7110_VOUTCLK_DSITX_DPI, "dsiTx_dpi", 0, 2,
|
||||
+ JH7110_VOUTCLK_DC8200_PIX,
|
||||
+ JH7110_VOUTCLK_HDMITX0_PIXELCLK),
|
||||
+ JH71X0_GATE(JH7110_VOUTCLK_DSITX_TXESC, "dsiTx_txesc", 0, JH7110_VOUTCLK_TX_ESC),
|
||||
+ /* mipitx DPHY */
|
||||
+ JH71X0_GATE(JH7110_VOUTCLK_MIPITX_DPHY_TXESC, "mipitx_dphy_txesc", 0,
|
||||
+ JH7110_VOUTCLK_TX_ESC),
|
||||
+ /* hdmi */
|
||||
+ JH71X0_GATE(JH7110_VOUTCLK_HDMI_TX_MCLK, "hdmi_tx_mclk", 0,
|
||||
+ JH7110_VOUTCLK_VOUT_TOP_HDMITX0_MCLK),
|
||||
+ JH71X0_GATE(JH7110_VOUTCLK_HDMI_TX_BCLK, "hdmi_tx_bclk", 0,
|
||||
+ JH7110_VOUTCLK_I2STX0_BCLK),
|
||||
+ JH71X0_GATE(JH7110_VOUTCLK_HDMI_TX_SYS, "hdmi_tx_sys", 0, JH7110_VOUTCLK_APB),
|
||||
+};
|
||||
+
|
||||
+static int jh7110_vout_top_rst_init(struct jh71x0_clk_priv *priv)
|
||||
+{
|
||||
+ struct reset_control *top_rst;
|
||||
+
|
||||
+ /* The reset should be shared and other Vout modules will use its. */
|
||||
+ top_rst = devm_reset_control_get_shared(priv->dev, NULL);
|
||||
+ if (IS_ERR(top_rst))
|
||||
+ return dev_err_probe(priv->dev, PTR_ERR(top_rst), "failed to get top reset\n");
|
||||
+
|
||||
+ return reset_control_deassert(top_rst);
|
||||
+}
|
||||
+
|
||||
+static struct clk_hw *jh7110_voutclk_get(struct of_phandle_args *clkspec, void *data)
|
||||
+{
|
||||
+ struct jh71x0_clk_priv *priv = data;
|
||||
+ unsigned int idx = clkspec->args[0];
|
||||
+
|
||||
+ if (idx < JH7110_VOUTCLK_END)
|
||||
+ return &priv->reg[idx].hw;
|
||||
+
|
||||
+ return ERR_PTR(-EINVAL);
|
||||
+}
|
||||
+
|
||||
+#ifdef CONFIG_PM
|
||||
+static int jh7110_voutcrg_suspend(struct device *dev)
|
||||
+{
|
||||
+ struct top_sysclk *top = dev_get_drvdata(dev);
|
||||
+
|
||||
+ clk_bulk_disable_unprepare(top->top_clks_num, top->top_clks);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int jh7110_voutcrg_resume(struct device *dev)
|
||||
+{
|
||||
+ struct top_sysclk *top = dev_get_drvdata(dev);
|
||||
+
|
||||
+ return clk_bulk_prepare_enable(top->top_clks_num, top->top_clks);
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
+static const struct dev_pm_ops jh7110_voutcrg_pm_ops = {
|
||||
+ SET_RUNTIME_PM_OPS(jh7110_voutcrg_suspend, jh7110_voutcrg_resume, NULL)
|
||||
+};
|
||||
+
|
||||
+static int jh7110_voutcrg_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct jh71x0_clk_priv *priv;
|
||||
+ struct top_sysclk *top;
|
||||
+ unsigned int idx;
|
||||
+ int ret;
|
||||
+
|
||||
+ priv = devm_kzalloc(&pdev->dev,
|
||||
+ struct_size(priv, reg, JH7110_VOUTCLK_END),
|
||||
+ GFP_KERNEL);
|
||||
+ if (!priv)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ top = devm_kzalloc(&pdev->dev, sizeof(*top), GFP_KERNEL);
|
||||
+ if (!top)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ spin_lock_init(&priv->rmw_lock);
|
||||
+ priv->dev = &pdev->dev;
|
||||
+ priv->base = devm_platform_ioremap_resource(pdev, 0);
|
||||
+ if (IS_ERR(priv->base))
|
||||
+ return PTR_ERR(priv->base);
|
||||
+
|
||||
+ top->top_clks = jh7110_vout_top_clks;
|
||||
+ top->top_clks_num = ARRAY_SIZE(jh7110_vout_top_clks);
|
||||
+ ret = devm_clk_bulk_get(priv->dev, top->top_clks_num, top->top_clks);
|
||||
+ if (ret)
|
||||
+ return dev_err_probe(priv->dev, ret, "failed to get top clocks\n");
|
||||
+ dev_set_drvdata(priv->dev, top);
|
||||
+
|
||||
+ /* enable power domain and clocks */
|
||||
+ pm_runtime_enable(priv->dev);
|
||||
+ ret = pm_runtime_get_sync(priv->dev);
|
||||
+ if (ret < 0)
|
||||
+ return dev_err_probe(priv->dev, ret, "failed to turn on power\n");
|
||||
+
|
||||
+ ret = jh7110_vout_top_rst_init(priv);
|
||||
+ if (ret)
|
||||
+ goto err_exit;
|
||||
+
|
||||
+ for (idx = 0; idx < JH7110_VOUTCLK_END; idx++) {
|
||||
+ u32 max = jh7110_voutclk_data[idx].max;
|
||||
+ struct clk_parent_data parents[4] = {};
|
||||
+ struct clk_init_data init = {
|
||||
+ .name = jh7110_voutclk_data[idx].name,
|
||||
+ .ops = starfive_jh71x0_clk_ops(max),
|
||||
+ .parent_data = parents,
|
||||
+ .num_parents =
|
||||
+ ((max & JH71X0_CLK_MUX_MASK) >> JH71X0_CLK_MUX_SHIFT) + 1,
|
||||
+ .flags = jh7110_voutclk_data[idx].flags,
|
||||
+ };
|
||||
+ struct jh71x0_clk *clk = &priv->reg[idx];
|
||||
+ unsigned int i;
|
||||
+ const char *fw_name[JH7110_VOUTCLK_EXT_END - JH7110_VOUTCLK_END] = {
|
||||
+ "vout_src",
|
||||
+ "vout_top_ahb",
|
||||
+ "vout_top_axi",
|
||||
+ "vout_top_hdmitx0_mclk",
|
||||
+ "i2stx0_bclk",
|
||||
+ "hdmitx0_pixelclk"
|
||||
+ };
|
||||
+
|
||||
+ for (i = 0; i < init.num_parents; i++) {
|
||||
+ unsigned int pidx = jh7110_voutclk_data[idx].parents[i];
|
||||
+
|
||||
+ if (pidx < JH7110_VOUTCLK_END)
|
||||
+ parents[i].hw = &priv->reg[pidx].hw;
|
||||
+ else if (pidx < JH7110_VOUTCLK_EXT_END)
|
||||
+ parents[i].fw_name = fw_name[pidx - JH7110_VOUTCLK_END];
|
||||
+ }
|
||||
+
|
||||
+ clk->hw.init = &init;
|
||||
+ clk->idx = idx;
|
||||
+ clk->max_div = max & JH71X0_CLK_DIV_MASK;
|
||||
+
|
||||
+ ret = devm_clk_hw_register(&pdev->dev, &clk->hw);
|
||||
+ if (ret)
|
||||
+ goto err_exit;
|
||||
+ }
|
||||
+
|
||||
+ ret = devm_of_clk_add_hw_provider(&pdev->dev, jh7110_voutclk_get, priv);
|
||||
+ if (ret)
|
||||
+ goto err_exit;
|
||||
+
|
||||
+ ret = jh7110_reset_controller_register(priv, "rst-vo", 4);
|
||||
+ if (ret)
|
||||
+ goto err_exit;
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+err_exit:
|
||||
+ pm_runtime_put_sync(priv->dev);
|
||||
+ pm_runtime_disable(priv->dev);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int jh7110_voutcrg_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+ pm_runtime_put_sync(&pdev->dev);
|
||||
+ pm_runtime_disable(&pdev->dev);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct of_device_id jh7110_voutcrg_match[] = {
|
||||
+ { .compatible = "starfive,jh7110-voutcrg" },
|
||||
+ { /* sentinel */ }
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, jh7110_voutcrg_match);
|
||||
+
|
||||
+static struct platform_driver jh7110_voutcrg_driver = {
|
||||
+ .probe = jh7110_voutcrg_probe,
|
||||
+ .remove = jh7110_voutcrg_remove,
|
||||
+ .driver = {
|
||||
+ .name = "clk-starfive-jh7110-vout",
|
||||
+ .of_match_table = jh7110_voutcrg_match,
|
||||
+ .pm = &jh7110_voutcrg_pm_ops,
|
||||
+ },
|
||||
+};
|
||||
+module_platform_driver(jh7110_voutcrg_driver);
|
||||
+
|
||||
+MODULE_AUTHOR("Xingyu Wu <xingyu.wu@starfivetech.com>");
|
||||
+MODULE_DESCRIPTION("StarFive JH7110 Video-Output clock driver");
|
||||
+MODULE_LICENSE("GPL");
|
@ -0,0 +1,61 @@
|
||||
From a04a6eb3b4d112f3600bbd783249f24a43797e7a Mon Sep 17 00:00:00 2001
|
||||
From: Xingyu Wu <xingyu.wu@starfivetech.com>
|
||||
Date: Thu, 18 May 2023 18:12:31 +0800
|
||||
Subject: [PATCH 057/122] reset: starfive: jh7110: Add StarFive STG/ISP/VOUT
|
||||
resets support
|
||||
|
||||
Add new struct members and auxiliary_device_id of resets to support
|
||||
System-Top-Group, Image-Signal-Process and Video-Output on the StarFive
|
||||
JH7110 SoC.
|
||||
|
||||
Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
|
||||
---
|
||||
.../reset/starfive/reset-starfive-jh7110.c | 30 +++++++++++++++++++
|
||||
1 file changed, 30 insertions(+)
|
||||
|
||||
--- a/drivers/reset/starfive/reset-starfive-jh7110.c
|
||||
+++ b/drivers/reset/starfive/reset-starfive-jh7110.c
|
||||
@@ -31,6 +31,24 @@ static const struct jh7110_reset_info jh
|
||||
.status_offset = 0x3C,
|
||||
};
|
||||
|
||||
+static const struct jh7110_reset_info jh7110_stg_info = {
|
||||
+ .nr_resets = JH7110_STGRST_END,
|
||||
+ .assert_offset = 0x74,
|
||||
+ .status_offset = 0x78,
|
||||
+};
|
||||
+
|
||||
+static const struct jh7110_reset_info jh7110_isp_info = {
|
||||
+ .nr_resets = JH7110_ISPRST_END,
|
||||
+ .assert_offset = 0x38,
|
||||
+ .status_offset = 0x3C,
|
||||
+};
|
||||
+
|
||||
+static const struct jh7110_reset_info jh7110_vout_info = {
|
||||
+ .nr_resets = JH7110_VOUTRST_END,
|
||||
+ .assert_offset = 0x48,
|
||||
+ .status_offset = 0x4C,
|
||||
+};
|
||||
+
|
||||
static int jh7110_reset_probe(struct auxiliary_device *adev,
|
||||
const struct auxiliary_device_id *id)
|
||||
{
|
||||
@@ -58,6 +76,18 @@ static const struct auxiliary_device_id
|
||||
.name = "clk_starfive_jh7110_sys.rst-aon",
|
||||
.driver_data = (kernel_ulong_t)&jh7110_aon_info,
|
||||
},
|
||||
+ {
|
||||
+ .name = "clk_starfive_jh7110_sys.rst-stg",
|
||||
+ .driver_data = (kernel_ulong_t)&jh7110_stg_info,
|
||||
+ },
|
||||
+ {
|
||||
+ .name = "clk_starfive_jh7110_sys.rst-isp",
|
||||
+ .driver_data = (kernel_ulong_t)&jh7110_isp_info,
|
||||
+ },
|
||||
+ {
|
||||
+ .name = "clk_starfive_jh7110_sys.rst-vo",
|
||||
+ .driver_data = (kernel_ulong_t)&jh7110_vout_info,
|
||||
+ },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(auxiliary, jh7110_reset_ids);
|
@ -0,0 +1,819 @@
|
||||
From 758c8c4c30f495465f34735aef2458c0cc255a75 Mon Sep 17 00:00:00 2001
|
||||
From: "shanlong.li" <shanlong.li@starfivetech.com>
|
||||
Date: Wed, 31 May 2023 01:03:02 -0700
|
||||
Subject: [PATCH 058/122] clk: starfive: update jh7110 PLL clock driver
|
||||
|
||||
Update the StarFive JH7110 PLL clock controller
|
||||
and they work by reading and setting syscon registers.
|
||||
|
||||
Signed-off-by: shanlong.li <shanlong.li@starfivetech.com>
|
||||
---
|
||||
.../clk/starfive/clk-starfive-jh7110-pll.c | 269 +++++-------------
|
||||
.../clk/starfive/clk-starfive-jh7110-pll.h | 264 +++++++++--------
|
||||
2 files changed, 227 insertions(+), 306 deletions(-)
|
||||
|
||||
--- a/drivers/clk/starfive/clk-starfive-jh7110-pll.c
|
||||
+++ b/drivers/clk/starfive/clk-starfive-jh7110-pll.c
|
||||
@@ -24,11 +24,29 @@
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regmap.h>
|
||||
+#include <linux/of_platform.h>
|
||||
|
||||
#include <dt-bindings/clock/starfive,jh7110-crg.h>
|
||||
|
||||
#include "clk-starfive-jh7110-pll.h"
|
||||
|
||||
+struct jh7110_pll_conf_variant {
|
||||
+ unsigned int pll_nums;
|
||||
+ struct jh7110_pll_syscon_conf conf[];
|
||||
+};
|
||||
+
|
||||
+static const struct jh7110_pll_conf_variant jh7110_pll_variant = {
|
||||
+ .pll_nums = JH7110_PLLCLK_END,
|
||||
+ .conf = {
|
||||
+ JH7110_PLL(JH7110_CLK_PLL0_OUT, "pll0_out",
|
||||
+ JH7110_PLL0_FREQ_MAX, jh7110_pll0_syscon_val_preset),
|
||||
+ JH7110_PLL(JH7110_CLK_PLL1_OUT, "pll1_out",
|
||||
+ JH7110_PLL1_FREQ_MAX, jh7110_pll1_syscon_val_preset),
|
||||
+ JH7110_PLL(JH7110_CLK_PLL2_OUT, "pll2_out",
|
||||
+ JH7110_PLL2_FREQ_MAX, jh7110_pll2_syscon_val_preset),
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
static struct jh7110_clk_pll_data *jh7110_pll_data_from(struct clk_hw *hw)
|
||||
{
|
||||
return container_of(hw, struct jh7110_clk_pll_data, hw);
|
||||
@@ -44,10 +62,9 @@ static unsigned long jh7110_pll_get_freq
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct jh7110_clk_pll_priv *priv = jh7110_pll_priv_from(data);
|
||||
- struct jh7110_pll_syscon_offset *offset = &data->offset;
|
||||
- struct jh7110_pll_syscon_mask *mask = &data->mask;
|
||||
- struct jh7110_pll_syscon_shift *shift = &data->shift;
|
||||
- unsigned long freq = 0;
|
||||
+ struct jh7110_pll_syscon_offset *offset = &data->conf.offsets;
|
||||
+ struct jh7110_pll_syscon_mask *mask = &data->conf.masks;
|
||||
+ struct jh7110_pll_syscon_shift *shift = &data->conf.shifts;
|
||||
unsigned long frac_cal;
|
||||
u32 dacpd;
|
||||
u32 dsmpd;
|
||||
@@ -57,32 +74,23 @@ static unsigned long jh7110_pll_get_freq
|
||||
u32 frac;
|
||||
u32 reg_val;
|
||||
|
||||
- if (regmap_read(priv->syscon_regmap, offset->dacpd, ®_val))
|
||||
- goto read_error;
|
||||
+ regmap_read(priv->syscon_regmap, offset->dacpd, ®_val);
|
||||
dacpd = (reg_val & mask->dacpd) >> shift->dacpd;
|
||||
|
||||
- if (regmap_read(priv->syscon_regmap, offset->dsmpd, ®_val))
|
||||
- goto read_error;
|
||||
+ regmap_read(priv->syscon_regmap, offset->dsmpd, ®_val);
|
||||
dsmpd = (reg_val & mask->dsmpd) >> shift->dsmpd;
|
||||
|
||||
- if (regmap_read(priv->syscon_regmap, offset->fbdiv, ®_val))
|
||||
- goto read_error;
|
||||
+ regmap_read(priv->syscon_regmap, offset->fbdiv, ®_val);
|
||||
fbdiv = (reg_val & mask->fbdiv) >> shift->fbdiv;
|
||||
- /* fbdiv value should be 8 to 4095 */
|
||||
- if (fbdiv < 8)
|
||||
- goto read_error;
|
||||
|
||||
- if (regmap_read(priv->syscon_regmap, offset->prediv, ®_val))
|
||||
- goto read_error;
|
||||
+ regmap_read(priv->syscon_regmap, offset->prediv, ®_val);
|
||||
prediv = (reg_val & mask->prediv) >> shift->prediv;
|
||||
|
||||
- if (regmap_read(priv->syscon_regmap, offset->postdiv1, ®_val))
|
||||
- goto read_error;
|
||||
+ regmap_read(priv->syscon_regmap, offset->postdiv1, ®_val);
|
||||
/* postdiv1 = 2 ^ reg_val */
|
||||
postdiv1 = 1 << ((reg_val & mask->postdiv1) >> shift->postdiv1);
|
||||
|
||||
- if (regmap_read(priv->syscon_regmap, offset->frac, ®_val))
|
||||
- goto read_error;
|
||||
+ regmap_read(priv->syscon_regmap, offset->frac, ®_val);
|
||||
frac = (reg_val & mask->frac) >> shift->frac;
|
||||
|
||||
/*
|
||||
@@ -95,14 +103,11 @@ static unsigned long jh7110_pll_get_freq
|
||||
else if (dacpd == 0 && dsmpd == 0)
|
||||
frac_cal = (unsigned long)frac * STARFIVE_PLL_FRAC_PATR_SIZE / (1 << 24);
|
||||
else
|
||||
- goto read_error;
|
||||
+ return 0;
|
||||
|
||||
/* Fvco = Fref * (NI + NF) / M / Q1 */
|
||||
- freq = parent_rate / STARFIVE_PLL_FRAC_PATR_SIZE *
|
||||
- (fbdiv * STARFIVE_PLL_FRAC_PATR_SIZE + frac_cal) / prediv / postdiv1;
|
||||
-
|
||||
-read_error:
|
||||
- return freq;
|
||||
+ return (parent_rate / STARFIVE_PLL_FRAC_PATR_SIZE *
|
||||
+ (fbdiv * STARFIVE_PLL_FRAC_PATR_SIZE + frac_cal) / prediv / postdiv1);
|
||||
}
|
||||
|
||||
static unsigned long jh7110_pll_rate_sub_fabs(unsigned long rate1, unsigned long rate2)
|
||||
@@ -114,40 +119,27 @@ static unsigned long jh7110_pll_rate_sub
|
||||
static void jh7110_pll_select_near_freq_id(struct jh7110_clk_pll_data *data,
|
||||
unsigned long rate)
|
||||
{
|
||||
- const struct starfive_pll_syscon_value *syscon_val;
|
||||
+ const struct jh7110_pll_syscon_val *val;
|
||||
unsigned int id;
|
||||
- unsigned int pll_arry_size;
|
||||
unsigned long rate_diff;
|
||||
|
||||
- if (data->idx == JH7110_CLK_PLL0_OUT)
|
||||
- pll_arry_size = ARRAY_SIZE(jh7110_pll0_syscon_freq);
|
||||
- else if (data->idx == JH7110_CLK_PLL1_OUT)
|
||||
- pll_arry_size = ARRAY_SIZE(jh7110_pll1_syscon_freq);
|
||||
- else
|
||||
- pll_arry_size = ARRAY_SIZE(jh7110_pll2_syscon_freq);
|
||||
-
|
||||
/* compare the frequency one by one from small to large in order */
|
||||
- for (id = 0; id < pll_arry_size; id++) {
|
||||
- if (data->idx == JH7110_CLK_PLL0_OUT)
|
||||
- syscon_val = &jh7110_pll0_syscon_freq[id];
|
||||
- else if (data->idx == JH7110_CLK_PLL1_OUT)
|
||||
- syscon_val = &jh7110_pll1_syscon_freq[id];
|
||||
- else
|
||||
- syscon_val = &jh7110_pll2_syscon_freq[id];
|
||||
+ for (id = 0; id < data->conf.preset_val_nums; id++) {
|
||||
+ val = &data->conf.preset_val[id];
|
||||
|
||||
- if (rate == syscon_val->freq)
|
||||
+ if (rate == val->freq)
|
||||
goto match_end;
|
||||
|
||||
/* select near frequency */
|
||||
- if (rate < syscon_val->freq) {
|
||||
+ if (rate < val->freq) {
|
||||
/* The last frequency is closer to the target rate than this time. */
|
||||
if (id > 0)
|
||||
- if (rate_diff < jh7110_pll_rate_sub_fabs(rate, syscon_val->freq))
|
||||
+ if (rate_diff < jh7110_pll_rate_sub_fabs(rate, val->freq))
|
||||
id--;
|
||||
|
||||
goto match_end;
|
||||
} else {
|
||||
- rate_diff = jh7110_pll_rate_sub_fabs(rate, syscon_val->freq);
|
||||
+ rate_diff = jh7110_pll_rate_sub_fabs(rate, val->freq);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -158,54 +150,34 @@ match_end:
|
||||
static int jh7110_pll_set_freq_syscon(struct jh7110_clk_pll_data *data)
|
||||
{
|
||||
struct jh7110_clk_pll_priv *priv = jh7110_pll_priv_from(data);
|
||||
- struct jh7110_pll_syscon_offset *offset = &data->offset;
|
||||
- struct jh7110_pll_syscon_mask *mask = &data->mask;
|
||||
- struct jh7110_pll_syscon_shift *shift = &data->shift;
|
||||
- unsigned int freq_idx = data->freq_select_idx;
|
||||
- const struct starfive_pll_syscon_value *syscon_val;
|
||||
- int ret;
|
||||
+ struct jh7110_pll_syscon_offset *offset = &data->conf.offsets;
|
||||
+ struct jh7110_pll_syscon_mask *mask = &data->conf.masks;
|
||||
+ struct jh7110_pll_syscon_shift *shift = &data->conf.shifts;
|
||||
+ const struct jh7110_pll_syscon_val *val = &data->conf.preset_val[data->freq_select_idx];
|
||||
|
||||
- if (data->idx == JH7110_CLK_PLL0_OUT)
|
||||
- syscon_val = &jh7110_pll0_syscon_freq[freq_idx];
|
||||
- else if (data->idx == JH7110_CLK_PLL1_OUT)
|
||||
- syscon_val = &jh7110_pll1_syscon_freq[freq_idx];
|
||||
- else
|
||||
- syscon_val = &jh7110_pll2_syscon_freq[freq_idx];
|
||||
+ /* frac: Integer Mode (Both 1) or Fraction Mode (Both 0) */
|
||||
+ if (val->dacpd == 0 && val->dsmpd == 0)
|
||||
+ regmap_update_bits(priv->syscon_regmap, offset->frac, mask->frac,
|
||||
+ (val->frac << shift->frac));
|
||||
+ else if (val->dacpd != val->dsmpd)
|
||||
+ return -EINVAL;
|
||||
|
||||
- ret = regmap_update_bits(priv->syscon_regmap, offset->dacpd, mask->dacpd,
|
||||
- (syscon_val->dacpd << shift->dacpd));
|
||||
- if (ret)
|
||||
- goto set_failed;
|
||||
-
|
||||
- ret = regmap_update_bits(priv->syscon_regmap, offset->dsmpd, mask->dsmpd,
|
||||
- (syscon_val->dsmpd << shift->dsmpd));
|
||||
- if (ret)
|
||||
- goto set_failed;
|
||||
-
|
||||
- ret = regmap_update_bits(priv->syscon_regmap, offset->prediv, mask->prediv,
|
||||
- (syscon_val->prediv << shift->prediv));
|
||||
- if (ret)
|
||||
- goto set_failed;
|
||||
-
|
||||
- ret = regmap_update_bits(priv->syscon_regmap, offset->fbdiv, mask->fbdiv,
|
||||
- (syscon_val->fbdiv << shift->fbdiv));
|
||||
- if (ret)
|
||||
- goto set_failed;
|
||||
-
|
||||
- ret = regmap_update_bits(priv->syscon_regmap, offset->postdiv1, mask->postdiv1,
|
||||
- ((syscon_val->postdiv1 >> 1) << shift->postdiv1));
|
||||
- if (ret)
|
||||
- goto set_failed;
|
||||
+ /* fbdiv value should be 8 to 4095 */
|
||||
+ if (val->fbdiv < 8)
|
||||
+ return -EINVAL;
|
||||
|
||||
- /* frac: Integer Mode (Both 1) or Fraction Mode (Both 0) */
|
||||
- if (syscon_val->dacpd == 0 && syscon_val->dsmpd == 0)
|
||||
- ret = regmap_update_bits(priv->syscon_regmap, offset->frac, mask->frac,
|
||||
- (syscon_val->frac << shift->frac));
|
||||
- else if (syscon_val->dacpd != syscon_val->dsmpd)
|
||||
- ret = -EINVAL;
|
||||
+ regmap_update_bits(priv->syscon_regmap, offset->dacpd, mask->dacpd,
|
||||
+ (val->dacpd << shift->dacpd));
|
||||
+ regmap_update_bits(priv->syscon_regmap, offset->dsmpd, mask->dsmpd,
|
||||
+ (val->dsmpd << shift->dsmpd));
|
||||
+ regmap_update_bits(priv->syscon_regmap, offset->prediv, mask->prediv,
|
||||
+ (val->prediv << shift->prediv));
|
||||
+ regmap_update_bits(priv->syscon_regmap, offset->fbdiv, mask->fbdiv,
|
||||
+ (val->fbdiv << shift->fbdiv));
|
||||
+ regmap_update_bits(priv->syscon_regmap, offset->postdiv1, mask->postdiv1,
|
||||
+ ((val->postdiv1 >> 1) << shift->postdiv1));
|
||||
|
||||
-set_failed:
|
||||
- return ret;
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
static unsigned long jh7110_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
|
||||
@@ -220,13 +192,7 @@ static int jh7110_pll_determine_rate(str
|
||||
struct jh7110_clk_pll_data *data = jh7110_pll_data_from(hw);
|
||||
|
||||
jh7110_pll_select_near_freq_id(data, req->rate);
|
||||
-
|
||||
- if (data->idx == JH7110_CLK_PLL0_OUT)
|
||||
- req->rate = jh7110_pll0_syscon_freq[data->freq_select_idx].freq;
|
||||
- else if (data->idx == JH7110_CLK_PLL1_OUT)
|
||||
- req->rate = jh7110_pll1_syscon_freq[data->freq_select_idx].freq;
|
||||
- else
|
||||
- req->rate = jh7110_pll2_syscon_freq[data->freq_select_idx].freq;
|
||||
+ req->rate = data->conf.preset_val[data->freq_select_idx].freq;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -270,92 +236,12 @@ static const struct clk_ops jh7110_pll_o
|
||||
.debug_init = jh7110_pll_debug_init,
|
||||
};
|
||||
|
||||
-/* get offset, mask and shift of PLL(x) syscon */
|
||||
-static int jh7110_pll_data_get(struct jh7110_clk_pll_data *data, int index)
|
||||
-{
|
||||
- struct jh7110_pll_syscon_offset *offset = &data->offset;
|
||||
- struct jh7110_pll_syscon_mask *mask = &data->mask;
|
||||
- struct jh7110_pll_syscon_shift *shift = &data->shift;
|
||||
-
|
||||
- if (index == JH7110_CLK_PLL0_OUT) {
|
||||
- offset->dacpd = STARFIVE_JH7110_PLL0_DACPD_OFFSET;
|
||||
- offset->dsmpd = STARFIVE_JH7110_PLL0_DSMPD_OFFSET;
|
||||
- offset->fbdiv = STARFIVE_JH7110_PLL0_FBDIV_OFFSET;
|
||||
- offset->frac = STARFIVE_JH7110_PLL0_FRAC_OFFSET;
|
||||
- offset->prediv = STARFIVE_JH7110_PLL0_PREDIV_OFFSET;
|
||||
- offset->postdiv1 = STARFIVE_JH7110_PLL0_POSTDIV1_OFFSET;
|
||||
-
|
||||
- mask->dacpd = STARFIVE_JH7110_PLL0_DACPD_MASK;
|
||||
- mask->dsmpd = STARFIVE_JH7110_PLL0_DSMPD_MASK;
|
||||
- mask->fbdiv = STARFIVE_JH7110_PLL0_FBDIV_MASK;
|
||||
- mask->frac = STARFIVE_JH7110_PLL0_FRAC_MASK;
|
||||
- mask->prediv = STARFIVE_JH7110_PLL0_PREDIV_MASK;
|
||||
- mask->postdiv1 = STARFIVE_JH7110_PLL0_POSTDIV1_MASK;
|
||||
-
|
||||
- shift->dacpd = STARFIVE_JH7110_PLL0_DACPD_SHIFT;
|
||||
- shift->dsmpd = STARFIVE_JH7110_PLL0_DSMPD_SHIFT;
|
||||
- shift->fbdiv = STARFIVE_JH7110_PLL0_FBDIV_SHIFT;
|
||||
- shift->frac = STARFIVE_JH7110_PLL0_FRAC_SHIFT;
|
||||
- shift->prediv = STARFIVE_JH7110_PLL0_PREDIV_SHIFT;
|
||||
- shift->postdiv1 = STARFIVE_JH7110_PLL0_POSTDIV1_SHIFT;
|
||||
-
|
||||
- } else if (index == JH7110_CLK_PLL1_OUT) {
|
||||
- offset->dacpd = STARFIVE_JH7110_PLL1_DACPD_OFFSET;
|
||||
- offset->dsmpd = STARFIVE_JH7110_PLL1_DSMPD_OFFSET;
|
||||
- offset->fbdiv = STARFIVE_JH7110_PLL1_FBDIV_OFFSET;
|
||||
- offset->frac = STARFIVE_JH7110_PLL1_FRAC_OFFSET;
|
||||
- offset->prediv = STARFIVE_JH7110_PLL1_PREDIV_OFFSET;
|
||||
- offset->postdiv1 = STARFIVE_JH7110_PLL1_POSTDIV1_OFFSET;
|
||||
-
|
||||
- mask->dacpd = STARFIVE_JH7110_PLL1_DACPD_MASK;
|
||||
- mask->dsmpd = STARFIVE_JH7110_PLL1_DSMPD_MASK;
|
||||
- mask->fbdiv = STARFIVE_JH7110_PLL1_FBDIV_MASK;
|
||||
- mask->frac = STARFIVE_JH7110_PLL1_FRAC_MASK;
|
||||
- mask->prediv = STARFIVE_JH7110_PLL1_PREDIV_MASK;
|
||||
- mask->postdiv1 = STARFIVE_JH7110_PLL1_POSTDIV1_MASK;
|
||||
-
|
||||
- shift->dacpd = STARFIVE_JH7110_PLL1_DACPD_SHIFT;
|
||||
- shift->dsmpd = STARFIVE_JH7110_PLL1_DSMPD_SHIFT;
|
||||
- shift->fbdiv = STARFIVE_JH7110_PLL1_FBDIV_SHIFT;
|
||||
- shift->frac = STARFIVE_JH7110_PLL1_FRAC_SHIFT;
|
||||
- shift->prediv = STARFIVE_JH7110_PLL1_PREDIV_SHIFT;
|
||||
- shift->postdiv1 = STARFIVE_JH7110_PLL1_POSTDIV1_SHIFT;
|
||||
-
|
||||
- } else if (index == JH7110_CLK_PLL2_OUT) {
|
||||
- offset->dacpd = STARFIVE_JH7110_PLL2_DACPD_OFFSET;
|
||||
- offset->dsmpd = STARFIVE_JH7110_PLL2_DSMPD_OFFSET;
|
||||
- offset->fbdiv = STARFIVE_JH7110_PLL2_FBDIV_OFFSET;
|
||||
- offset->frac = STARFIVE_JH7110_PLL2_FRAC_OFFSET;
|
||||
- offset->prediv = STARFIVE_JH7110_PLL2_PREDIV_OFFSET;
|
||||
- offset->postdiv1 = STARFIVE_JH7110_PLL2_POSTDIV1_OFFSET;
|
||||
-
|
||||
- mask->dacpd = STARFIVE_JH7110_PLL2_DACPD_MASK;
|
||||
- mask->dsmpd = STARFIVE_JH7110_PLL2_DSMPD_MASK;
|
||||
- mask->fbdiv = STARFIVE_JH7110_PLL2_FBDIV_MASK;
|
||||
- mask->frac = STARFIVE_JH7110_PLL2_FRAC_MASK;
|
||||
- mask->prediv = STARFIVE_JH7110_PLL2_PREDIV_MASK;
|
||||
- mask->postdiv1 = STARFIVE_JH7110_PLL2_POSTDIV1_MASK;
|
||||
-
|
||||
- shift->dacpd = STARFIVE_JH7110_PLL2_DACPD_SHIFT;
|
||||
- shift->dsmpd = STARFIVE_JH7110_PLL2_DSMPD_SHIFT;
|
||||
- shift->fbdiv = STARFIVE_JH7110_PLL2_FBDIV_SHIFT;
|
||||
- shift->frac = STARFIVE_JH7110_PLL2_FRAC_SHIFT;
|
||||
- shift->prediv = STARFIVE_JH7110_PLL2_PREDIV_SHIFT;
|
||||
- shift->postdiv1 = STARFIVE_JH7110_PLL2_POSTDIV1_SHIFT;
|
||||
-
|
||||
- } else {
|
||||
- return -ENOENT;
|
||||
- }
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
static struct clk_hw *jh7110_pll_get(struct of_phandle_args *clkspec, void *data)
|
||||
{
|
||||
struct jh7110_clk_pll_priv *priv = data;
|
||||
unsigned int idx = clkspec->args[0];
|
||||
|
||||
- if (idx < JH7110_PLLCLK_END)
|
||||
+ if (idx < priv->pll_nums)
|
||||
return &priv->data[idx].hw;
|
||||
|
||||
return ERR_PTR(-EINVAL);
|
||||
@@ -363,17 +249,17 @@ static struct clk_hw *jh7110_pll_get(str
|
||||
|
||||
static int jh7110_pll_probe(struct platform_device *pdev)
|
||||
{
|
||||
- const char *pll_name[JH7110_PLLCLK_END] = {
|
||||
- "pll0_out",
|
||||
- "pll1_out",
|
||||
- "pll2_out"
|
||||
- };
|
||||
+ const struct jh7110_pll_conf_variant *variant;
|
||||
struct jh7110_clk_pll_priv *priv;
|
||||
struct jh7110_clk_pll_data *data;
|
||||
int ret;
|
||||
unsigned int idx;
|
||||
|
||||
- priv = devm_kzalloc(&pdev->dev, struct_size(priv, data, JH7110_PLLCLK_END),
|
||||
+ variant = of_device_get_match_data(&pdev->dev);
|
||||
+ if (!variant)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ priv = devm_kzalloc(&pdev->dev, struct_size(priv, data, variant->pll_nums),
|
||||
GFP_KERNEL);
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
@@ -383,12 +269,13 @@ static int jh7110_pll_probe(struct platf
|
||||
if (IS_ERR(priv->syscon_regmap))
|
||||
return PTR_ERR(priv->syscon_regmap);
|
||||
|
||||
- for (idx = 0; idx < JH7110_PLLCLK_END; idx++) {
|
||||
+ priv->pll_nums = variant->pll_nums;
|
||||
+ for (idx = 0; idx < priv->pll_nums; idx++) {
|
||||
struct clk_parent_data parents = {
|
||||
.index = 0,
|
||||
};
|
||||
struct clk_init_data init = {
|
||||
- .name = pll_name[idx],
|
||||
+ .name = variant->conf[idx].name,
|
||||
.ops = &jh7110_pll_ops,
|
||||
.parent_data = &parents,
|
||||
.num_parents = 1,
|
||||
@@ -396,11 +283,7 @@ static int jh7110_pll_probe(struct platf
|
||||
};
|
||||
|
||||
data = &priv->data[idx];
|
||||
-
|
||||
- ret = jh7110_pll_data_get(data, idx);
|
||||
- if (ret)
|
||||
- return ret;
|
||||
-
|
||||
+ data->conf = variant->conf[idx];
|
||||
data->hw.init = &init;
|
||||
data->idx = idx;
|
||||
|
||||
@@ -413,7 +296,7 @@ static int jh7110_pll_probe(struct platf
|
||||
}
|
||||
|
||||
static const struct of_device_id jh7110_pll_match[] = {
|
||||
- { .compatible = "starfive,jh7110-pll" },
|
||||
+ { .compatible = "starfive,jh7110-pll", .data = &jh7110_pll_variant },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, jh7110_pll_match);
|
||||
--- a/drivers/clk/starfive/clk-starfive-jh7110-pll.h
|
||||
+++ b/drivers/clk/starfive/clk-starfive-jh7110-pll.h
|
||||
@@ -13,62 +13,93 @@
|
||||
/* The decimal places are counted by expanding them by a factor of STARFIVE_PLL_FRAC_PATR_SIZE */
|
||||
#define STARFIVE_PLL_FRAC_PATR_SIZE 1000
|
||||
|
||||
-#define STARFIVE_JH7110_PLL0_DACPD_OFFSET 0x18
|
||||
-#define STARFIVE_JH7110_PLL0_DACPD_SHIFT 24
|
||||
-#define STARFIVE_JH7110_PLL0_DACPD_MASK BIT(24)
|
||||
-#define STARFIVE_JH7110_PLL0_DSMPD_OFFSET 0x18
|
||||
-#define STARFIVE_JH7110_PLL0_DSMPD_SHIFT 25
|
||||
-#define STARFIVE_JH7110_PLL0_DSMPD_MASK BIT(25)
|
||||
-#define STARFIVE_JH7110_PLL0_FBDIV_OFFSET 0x1c
|
||||
-#define STARFIVE_JH7110_PLL0_FBDIV_SHIFT 0
|
||||
-#define STARFIVE_JH7110_PLL0_FBDIV_MASK GENMASK(11, 0)
|
||||
-#define STARFIVE_JH7110_PLL0_FRAC_OFFSET 0x20
|
||||
-#define STARFIVE_JH7110_PLL0_FRAC_SHIFT 0
|
||||
-#define STARFIVE_JH7110_PLL0_FRAC_MASK GENMASK(23, 0)
|
||||
-#define STARFIVE_JH7110_PLL0_POSTDIV1_OFFSET 0x20
|
||||
-#define STARFIVE_JH7110_PLL0_POSTDIV1_SHIFT 28
|
||||
-#define STARFIVE_JH7110_PLL0_POSTDIV1_MASK GENMASK(29, 28)
|
||||
-#define STARFIVE_JH7110_PLL0_PREDIV_OFFSET 0x24
|
||||
-#define STARFIVE_JH7110_PLL0_PREDIV_SHIFT 0
|
||||
-#define STARFIVE_JH7110_PLL0_PREDIV_MASK GENMASK(5, 0)
|
||||
-
|
||||
-#define STARFIVE_JH7110_PLL1_DACPD_OFFSET 0x24
|
||||
-#define STARFIVE_JH7110_PLL1_DACPD_SHIFT 15
|
||||
-#define STARFIVE_JH7110_PLL1_DACPD_MASK BIT(15)
|
||||
-#define STARFIVE_JH7110_PLL1_DSMPD_OFFSET 0x24
|
||||
-#define STARFIVE_JH7110_PLL1_DSMPD_SHIFT 16
|
||||
-#define STARFIVE_JH7110_PLL1_DSMPD_MASK BIT(16)
|
||||
-#define STARFIVE_JH7110_PLL1_FBDIV_OFFSET 0x24
|
||||
-#define STARFIVE_JH7110_PLL1_FBDIV_SHIFT 17
|
||||
-#define STARFIVE_JH7110_PLL1_FBDIV_MASK GENMASK(28, 17)
|
||||
-#define STARFIVE_JH7110_PLL1_FRAC_OFFSET 0x28
|
||||
-#define STARFIVE_JH7110_PLL1_FRAC_SHIFT 0
|
||||
-#define STARFIVE_JH7110_PLL1_FRAC_MASK GENMASK(23, 0)
|
||||
-#define STARFIVE_JH7110_PLL1_POSTDIV1_OFFSET 0x28
|
||||
-#define STARFIVE_JH7110_PLL1_POSTDIV1_SHIFT 28
|
||||
-#define STARFIVE_JH7110_PLL1_POSTDIV1_MASK GENMASK(29, 28)
|
||||
-#define STARFIVE_JH7110_PLL1_PREDIV_OFFSET 0x2c
|
||||
-#define STARFIVE_JH7110_PLL1_PREDIV_SHIFT 0
|
||||
-#define STARFIVE_JH7110_PLL1_PREDIV_MASK GENMASK(5, 0)
|
||||
-
|
||||
-#define STARFIVE_JH7110_PLL2_DACPD_OFFSET 0x2c
|
||||
-#define STARFIVE_JH7110_PLL2_DACPD_SHIFT 15
|
||||
-#define STARFIVE_JH7110_PLL2_DACPD_MASK BIT(15)
|
||||
-#define STARFIVE_JH7110_PLL2_DSMPD_OFFSET 0x2c
|
||||
-#define STARFIVE_JH7110_PLL2_DSMPD_SHIFT 16
|
||||
-#define STARFIVE_JH7110_PLL2_DSMPD_MASK BIT(16)
|
||||
-#define STARFIVE_JH7110_PLL2_FBDIV_OFFSET 0x2c
|
||||
-#define STARFIVE_JH7110_PLL2_FBDIV_SHIFT 17
|
||||
-#define STARFIVE_JH7110_PLL2_FBDIV_MASK GENMASK(28, 17)
|
||||
-#define STARFIVE_JH7110_PLL2_FRAC_OFFSET 0x30
|
||||
-#define STARFIVE_JH7110_PLL2_FRAC_SHIFT 0
|
||||
-#define STARFIVE_JH7110_PLL2_FRAC_MASK GENMASK(23, 0)
|
||||
-#define STARFIVE_JH7110_PLL2_POSTDIV1_OFFSET 0x30
|
||||
-#define STARFIVE_JH7110_PLL2_POSTDIV1_SHIFT 28
|
||||
-#define STARFIVE_JH7110_PLL2_POSTDIV1_MASK GENMASK(29, 28)
|
||||
-#define STARFIVE_JH7110_PLL2_PREDIV_OFFSET 0x34
|
||||
-#define STARFIVE_JH7110_PLL2_PREDIV_SHIFT 0
|
||||
-#define STARFIVE_JH7110_PLL2_PREDIV_MASK GENMASK(5, 0)
|
||||
+#define STARFIVE_JH7110_CLK_PLL0_OUT_DACPD_OFFSET 0x18
|
||||
+#define STARFIVE_JH7110_CLK_PLL0_OUT_DACPD_SHIFT 24
|
||||
+#define STARFIVE_JH7110_CLK_PLL0_OUT_DACPD_MASK BIT(24)
|
||||
+#define STARFIVE_JH7110_CLK_PLL0_OUT_DSMPD_OFFSET 0x18
|
||||
+#define STARFIVE_JH7110_CLK_PLL0_OUT_DSMPD_SHIFT 25
|
||||
+#define STARFIVE_JH7110_CLK_PLL0_OUT_DSMPD_MASK BIT(25)
|
||||
+#define STARFIVE_JH7110_CLK_PLL0_OUT_FBDIV_OFFSET 0x1c
|
||||
+#define STARFIVE_JH7110_CLK_PLL0_OUT_FBDIV_SHIFT 0
|
||||
+#define STARFIVE_JH7110_CLK_PLL0_OUT_FBDIV_MASK GENMASK(11, 0)
|
||||
+#define STARFIVE_JH7110_CLK_PLL0_OUT_FRAC_OFFSET 0x20
|
||||
+#define STARFIVE_JH7110_CLK_PLL0_OUT_FRAC_SHIFT 0
|
||||
+#define STARFIVE_JH7110_CLK_PLL0_OUT_FRAC_MASK GENMASK(23, 0)
|
||||
+#define STARFIVE_JH7110_CLK_PLL0_OUT_POSTDIV1_OFFSET 0x20
|
||||
+#define STARFIVE_JH7110_CLK_PLL0_OUT_POSTDIV1_SHIFT 28
|
||||
+#define STARFIVE_JH7110_CLK_PLL0_OUT_POSTDIV1_MASK GENMASK(29, 28)
|
||||
+#define STARFIVE_JH7110_CLK_PLL0_OUT_PREDIV_OFFSET 0x24
|
||||
+#define STARFIVE_JH7110_CLK_PLL0_OUT_PREDIV_SHIFT 0
|
||||
+#define STARFIVE_JH7110_CLK_PLL0_OUT_PREDIV_MASK GENMASK(5, 0)
|
||||
+
|
||||
+#define STARFIVE_JH7110_CLK_PLL1_OUT_DACPD_OFFSET 0x24
|
||||
+#define STARFIVE_JH7110_CLK_PLL1_OUT_DACPD_SHIFT 15
|
||||
+#define STARFIVE_JH7110_CLK_PLL1_OUT_DACPD_MASK BIT(15)
|
||||
+#define STARFIVE_JH7110_CLK_PLL1_OUT_DSMPD_OFFSET 0x24
|
||||
+#define STARFIVE_JH7110_CLK_PLL1_OUT_DSMPD_SHIFT 16
|
||||
+#define STARFIVE_JH7110_CLK_PLL1_OUT_DSMPD_MASK BIT(16)
|
||||
+#define STARFIVE_JH7110_CLK_PLL1_OUT_FBDIV_OFFSET 0x24
|
||||
+#define STARFIVE_JH7110_CLK_PLL1_OUT_FBDIV_SHIFT 17
|
||||
+#define STARFIVE_JH7110_CLK_PLL1_OUT_FBDIV_MASK GENMASK(28, 17)
|
||||
+#define STARFIVE_JH7110_CLK_PLL1_OUT_FRAC_OFFSET 0x28
|
||||
+#define STARFIVE_JH7110_CLK_PLL1_OUT_FRAC_SHIFT 0
|
||||
+#define STARFIVE_JH7110_CLK_PLL1_OUT_FRAC_MASK GENMASK(23, 0)
|
||||
+#define STARFIVE_JH7110_CLK_PLL1_OUT_POSTDIV1_OFFSET 0x28
|
||||
+#define STARFIVE_JH7110_CLK_PLL1_OUT_POSTDIV1_SHIFT 28
|
||||
+#define STARFIVE_JH7110_CLK_PLL1_OUT_POSTDIV1_MASK GENMASK(29, 28)
|
||||
+#define STARFIVE_JH7110_CLK_PLL1_OUT_PREDIV_OFFSET 0x2c
|
||||
+#define STARFIVE_JH7110_CLK_PLL1_OUT_PREDIV_SHIFT 0
|
||||
+#define STARFIVE_JH7110_CLK_PLL1_OUT_PREDIV_MASK GENMASK(5, 0)
|
||||
+
|
||||
+#define STARFIVE_JH7110_CLK_PLL2_OUT_DACPD_OFFSET 0x2c
|
||||
+#define STARFIVE_JH7110_CLK_PLL2_OUT_DACPD_SHIFT 15
|
||||
+#define STARFIVE_JH7110_CLK_PLL2_OUT_DACPD_MASK BIT(15)
|
||||
+#define STARFIVE_JH7110_CLK_PLL2_OUT_DSMPD_OFFSET 0x2c
|
||||
+#define STARFIVE_JH7110_CLK_PLL2_OUT_DSMPD_SHIFT 16
|
||||
+#define STARFIVE_JH7110_CLK_PLL2_OUT_DSMPD_MASK BIT(16)
|
||||
+#define STARFIVE_JH7110_CLK_PLL2_OUT_FBDIV_OFFSET 0x2c
|
||||
+#define STARFIVE_JH7110_CLK_PLL2_OUT_FBDIV_SHIFT 17
|
||||
+#define STARFIVE_JH7110_CLK_PLL2_OUT_FBDIV_MASK GENMASK(28, 17)
|
||||
+#define STARFIVE_JH7110_CLK_PLL2_OUT_FRAC_OFFSET 0x30
|
||||
+#define STARFIVE_JH7110_CLK_PLL2_OUT_FRAC_SHIFT 0
|
||||
+#define STARFIVE_JH7110_CLK_PLL2_OUT_FRAC_MASK GENMASK(23, 0)
|
||||
+#define STARFIVE_JH7110_CLK_PLL2_OUT_POSTDIV1_OFFSET 0x30
|
||||
+#define STARFIVE_JH7110_CLK_PLL2_OUT_POSTDIV1_SHIFT 28
|
||||
+#define STARFIVE_JH7110_CLK_PLL2_OUT_POSTDIV1_MASK GENMASK(29, 28)
|
||||
+#define STARFIVE_JH7110_CLK_PLL2_OUT_PREDIV_OFFSET 0x34
|
||||
+#define STARFIVE_JH7110_CLK_PLL2_OUT_PREDIV_SHIFT 0
|
||||
+#define STARFIVE_JH7110_CLK_PLL2_OUT_PREDIV_MASK GENMASK(5, 0)
|
||||
+
|
||||
+#define JH7110_PLL(_idx, _name, _nums, _val) \
|
||||
+[_idx] = { \
|
||||
+ .name = _name, \
|
||||
+ .offsets = { \
|
||||
+ .dacpd = STARFIVE_##_idx##_DACPD_OFFSET, \
|
||||
+ .dsmpd = STARFIVE_##_idx##_DSMPD_OFFSET, \
|
||||
+ .fbdiv = STARFIVE_##_idx##_FBDIV_OFFSET, \
|
||||
+ .frac = STARFIVE_##_idx##_FRAC_OFFSET, \
|
||||
+ .prediv = STARFIVE_##_idx##_PREDIV_OFFSET, \
|
||||
+ .postdiv1 = STARFIVE_##_idx##_POSTDIV1_OFFSET, \
|
||||
+ }, \
|
||||
+ .masks = { \
|
||||
+ .dacpd = STARFIVE_##_idx##_DACPD_MASK, \
|
||||
+ .dsmpd = STARFIVE_##_idx##_DSMPD_MASK, \
|
||||
+ .fbdiv = STARFIVE_##_idx##_FBDIV_MASK, \
|
||||
+ .frac = STARFIVE_##_idx##_FRAC_MASK, \
|
||||
+ .prediv = STARFIVE_##_idx##_PREDIV_MASK, \
|
||||
+ .postdiv1 = STARFIVE_##_idx##_POSTDIV1_MASK, \
|
||||
+ }, \
|
||||
+ .shifts = { \
|
||||
+ .dacpd = STARFIVE_##_idx##_DACPD_SHIFT, \
|
||||
+ .dsmpd = STARFIVE_##_idx##_DSMPD_SHIFT, \
|
||||
+ .fbdiv = STARFIVE_##_idx##_FBDIV_SHIFT, \
|
||||
+ .frac = STARFIVE_##_idx##_FRAC_SHIFT, \
|
||||
+ .prediv = STARFIVE_##_idx##_PREDIV_SHIFT, \
|
||||
+ .postdiv1 = STARFIVE_##_idx##_POSTDIV1_SHIFT, \
|
||||
+ }, \
|
||||
+ .preset_val_nums = _nums, \
|
||||
+ .preset_val = _val, \
|
||||
+}
|
||||
|
||||
struct jh7110_pll_syscon_offset {
|
||||
unsigned int dacpd;
|
||||
@@ -97,23 +128,7 @@ struct jh7110_pll_syscon_shift {
|
||||
char postdiv1;
|
||||
};
|
||||
|
||||
-struct jh7110_clk_pll_data {
|
||||
- struct clk_hw hw;
|
||||
- unsigned int idx;
|
||||
- unsigned int freq_select_idx;
|
||||
-
|
||||
- struct jh7110_pll_syscon_offset offset;
|
||||
- struct jh7110_pll_syscon_mask mask;
|
||||
- struct jh7110_pll_syscon_shift shift;
|
||||
-};
|
||||
-
|
||||
-struct jh7110_clk_pll_priv {
|
||||
- struct device *dev;
|
||||
- struct regmap *syscon_regmap;
|
||||
- struct jh7110_clk_pll_data data[];
|
||||
-};
|
||||
-
|
||||
-struct starfive_pll_syscon_value {
|
||||
+struct jh7110_pll_syscon_val {
|
||||
unsigned long freq;
|
||||
u32 prediv;
|
||||
u32 fbdiv;
|
||||
@@ -126,31 +141,54 @@ struct starfive_pll_syscon_value {
|
||||
u32 frac;
|
||||
};
|
||||
|
||||
-enum starfive_pll0_freq_index {
|
||||
- PLL0_FREQ_375 = 0,
|
||||
- PLL0_FREQ_500,
|
||||
- PLL0_FREQ_625,
|
||||
- PLL0_FREQ_750,
|
||||
- PLL0_FREQ_875,
|
||||
- PLL0_FREQ_1000,
|
||||
- PLL0_FREQ_1250,
|
||||
- PLL0_FREQ_1375,
|
||||
- PLL0_FREQ_1500,
|
||||
- PLL0_FREQ_MAX
|
||||
-};
|
||||
-
|
||||
-enum starfive_pll1_freq_index {
|
||||
- PLL1_FREQ_1066 = 0,
|
||||
- PLL1_FREQ_1200,
|
||||
- PLL1_FREQ_1400,
|
||||
- PLL1_FREQ_1600,
|
||||
- PLL1_FREQ_MAX
|
||||
-};
|
||||
-
|
||||
-enum starfive_pll2_freq_index {
|
||||
- PLL2_FREQ_1188 = 0,
|
||||
- PLL2_FREQ_12288,
|
||||
- PLL2_FREQ_MAX
|
||||
+struct jh7110_pll_syscon_conf {
|
||||
+ char *name;
|
||||
+ struct jh7110_pll_syscon_offset offsets;
|
||||
+ struct jh7110_pll_syscon_mask masks;
|
||||
+ struct jh7110_pll_syscon_shift shifts;
|
||||
+ unsigned int preset_val_nums;
|
||||
+ const struct jh7110_pll_syscon_val *preset_val;
|
||||
+};
|
||||
+
|
||||
+struct jh7110_clk_pll_data {
|
||||
+ struct clk_hw hw;
|
||||
+ unsigned int idx;
|
||||
+ unsigned int freq_select_idx;
|
||||
+ struct jh7110_pll_syscon_conf conf;
|
||||
+};
|
||||
+
|
||||
+struct jh7110_clk_pll_priv {
|
||||
+ unsigned int pll_nums;
|
||||
+ struct device *dev;
|
||||
+ struct regmap *syscon_regmap;
|
||||
+ struct jh7110_clk_pll_data data[];
|
||||
+};
|
||||
+
|
||||
+enum jh7110_pll0_freq_index {
|
||||
+ JH7110_PLL0_FREQ_375 = 0,
|
||||
+ JH7110_PLL0_FREQ_500,
|
||||
+ JH7110_PLL0_FREQ_625,
|
||||
+ JH7110_PLL0_FREQ_750,
|
||||
+ JH7110_PLL0_FREQ_875,
|
||||
+ JH7110_PLL0_FREQ_1000,
|
||||
+ JH7110_PLL0_FREQ_1250,
|
||||
+ JH7110_PLL0_FREQ_1375,
|
||||
+ JH7110_PLL0_FREQ_1500,
|
||||
+ JH7110_PLL0_FREQ_MAX
|
||||
+};
|
||||
+
|
||||
+enum jh7110_pll1_freq_index {
|
||||
+ JH7110_PLL1_FREQ_1066 = 0,
|
||||
+ JH7110_PLL1_FREQ_1200,
|
||||
+ JH7110_PLL1_FREQ_1400,
|
||||
+ JH7110_PLL1_FREQ_1600,
|
||||
+ JH7110_PLL1_FREQ_MAX
|
||||
+};
|
||||
+
|
||||
+enum jh7110_pll2_freq_index {
|
||||
+ JH7110_PLL2_FREQ_1188 = 0,
|
||||
+ JH7110_PLL2_FREQ_12288,
|
||||
+ JH7110_PLL2_FREQ_MAX
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -158,9 +196,9 @@ enum starfive_pll2_freq_index {
|
||||
* it cannot be set arbitrarily, so it needs a specific configuration.
|
||||
* PLL0 frequency should be multiple of 125MHz (USB frequency).
|
||||
*/
|
||||
-static const struct starfive_pll_syscon_value
|
||||
- jh7110_pll0_syscon_freq[PLL0_FREQ_MAX] = {
|
||||
- [PLL0_FREQ_375] = {
|
||||
+static const struct jh7110_pll_syscon_val
|
||||
+ jh7110_pll0_syscon_val_preset[] = {
|
||||
+ [JH7110_PLL0_FREQ_375] = {
|
||||
.freq = 375000000,
|
||||
.prediv = 8,
|
||||
.fbdiv = 125,
|
||||
@@ -168,7 +206,7 @@ static const struct starfive_pll_syscon_
|
||||
.dacpd = 1,
|
||||
.dsmpd = 1,
|
||||
},
|
||||
- [PLL0_FREQ_500] = {
|
||||
+ [JH7110_PLL0_FREQ_500] = {
|
||||
.freq = 500000000,
|
||||
.prediv = 6,
|
||||
.fbdiv = 125,
|
||||
@@ -176,7 +214,7 @@ static const struct starfive_pll_syscon_
|
||||
.dacpd = 1,
|
||||
.dsmpd = 1,
|
||||
},
|
||||
- [PLL0_FREQ_625] = {
|
||||
+ [JH7110_PLL0_FREQ_625] = {
|
||||
.freq = 625000000,
|
||||
.prediv = 24,
|
||||
.fbdiv = 625,
|
||||
@@ -184,7 +222,7 @@ static const struct starfive_pll_syscon_
|
||||
.dacpd = 1,
|
||||
.dsmpd = 1,
|
||||
},
|
||||
- [PLL0_FREQ_750] = {
|
||||
+ [JH7110_PLL0_FREQ_750] = {
|
||||
.freq = 750000000,
|
||||
.prediv = 4,
|
||||
.fbdiv = 125,
|
||||
@@ -192,7 +230,7 @@ static const struct starfive_pll_syscon_
|
||||
.dacpd = 1,
|
||||
.dsmpd = 1,
|
||||
},
|
||||
- [PLL0_FREQ_875] = {
|
||||
+ [JH7110_PLL0_FREQ_875] = {
|
||||
.freq = 875000000,
|
||||
.prediv = 24,
|
||||
.fbdiv = 875,
|
||||
@@ -200,7 +238,7 @@ static const struct starfive_pll_syscon_
|
||||
.dacpd = 1,
|
||||
.dsmpd = 1,
|
||||
},
|
||||
- [PLL0_FREQ_1000] = {
|
||||
+ [JH7110_PLL0_FREQ_1000] = {
|
||||
.freq = 1000000000,
|
||||
.prediv = 3,
|
||||
.fbdiv = 125,
|
||||
@@ -208,7 +246,7 @@ static const struct starfive_pll_syscon_
|
||||
.dacpd = 1,
|
||||
.dsmpd = 1,
|
||||
},
|
||||
- [PLL0_FREQ_1250] = {
|
||||
+ [JH7110_PLL0_FREQ_1250] = {
|
||||
.freq = 1250000000,
|
||||
.prediv = 12,
|
||||
.fbdiv = 625,
|
||||
@@ -216,7 +254,7 @@ static const struct starfive_pll_syscon_
|
||||
.dacpd = 1,
|
||||
.dsmpd = 1,
|
||||
},
|
||||
- [PLL0_FREQ_1375] = {
|
||||
+ [JH7110_PLL0_FREQ_1375] = {
|
||||
.freq = 1375000000,
|
||||
.prediv = 24,
|
||||
.fbdiv = 1375,
|
||||
@@ -224,7 +262,7 @@ static const struct starfive_pll_syscon_
|
||||
.dacpd = 1,
|
||||
.dsmpd = 1,
|
||||
},
|
||||
- [PLL0_FREQ_1500] = {
|
||||
+ [JH7110_PLL0_FREQ_1500] = {
|
||||
.freq = 1500000000,
|
||||
.prediv = 2,
|
||||
.fbdiv = 125,
|
||||
@@ -234,9 +272,9 @@ static const struct starfive_pll_syscon_
|
||||
},
|
||||
};
|
||||
|
||||
-static const struct starfive_pll_syscon_value
|
||||
- jh7110_pll1_syscon_freq[PLL1_FREQ_MAX] = {
|
||||
- [PLL1_FREQ_1066] = {
|
||||
+static const struct jh7110_pll_syscon_val
|
||||
+ jh7110_pll1_syscon_val_preset[] = {
|
||||
+ [JH7110_PLL1_FREQ_1066] = {
|
||||
.freq = 1066000000,
|
||||
.prediv = 12,
|
||||
.fbdiv = 533,
|
||||
@@ -244,7 +282,7 @@ static const struct starfive_pll_syscon_
|
||||
.dacpd = 1,
|
||||
.dsmpd = 1,
|
||||
},
|
||||
- [PLL1_FREQ_1200] = {
|
||||
+ [JH7110_PLL1_FREQ_1200] = {
|
||||
.freq = 1200000000,
|
||||
.prediv = 1,
|
||||
.fbdiv = 50,
|
||||
@@ -252,7 +290,7 @@ static const struct starfive_pll_syscon_
|
||||
.dacpd = 1,
|
||||
.dsmpd = 1,
|
||||
},
|
||||
- [PLL1_FREQ_1400] = {
|
||||
+ [JH7110_PLL1_FREQ_1400] = {
|
||||
.freq = 1400000000,
|
||||
.prediv = 6,
|
||||
.fbdiv = 350,
|
||||
@@ -260,7 +298,7 @@ static const struct starfive_pll_syscon_
|
||||
.dacpd = 1,
|
||||
.dsmpd = 1,
|
||||
},
|
||||
- [PLL1_FREQ_1600] = {
|
||||
+ [JH7110_PLL1_FREQ_1600] = {
|
||||
.freq = 1600000000,
|
||||
.prediv = 3,
|
||||
.fbdiv = 200,
|
||||
@@ -270,9 +308,9 @@ static const struct starfive_pll_syscon_
|
||||
},
|
||||
};
|
||||
|
||||
-static const struct starfive_pll_syscon_value
|
||||
- jh7110_pll2_syscon_freq[PLL2_FREQ_MAX] = {
|
||||
- [PLL2_FREQ_1188] = {
|
||||
+static const struct jh7110_pll_syscon_val
|
||||
+ jh7110_pll2_syscon_val_preset[] = {
|
||||
+ [JH7110_PLL2_FREQ_1188] = {
|
||||
.freq = 1188000000,
|
||||
.prediv = 2,
|
||||
.fbdiv = 99,
|
||||
@@ -280,7 +318,7 @@ static const struct starfive_pll_syscon_
|
||||
.dacpd = 1,
|
||||
.dsmpd = 1,
|
||||
},
|
||||
- [PLL2_FREQ_12288] = {
|
||||
+ [JH7110_PLL2_FREQ_12288] = {
|
||||
.freq = 1228800000,
|
||||
.prediv = 5,
|
||||
.fbdiv = 256,
|
@ -0,0 +1,113 @@
|
||||
From 944b96d734199642e2ede978c48d754109ca334c Mon Sep 17 00:00:00 2001
|
||||
From: Xingyu Wu <xingyu.wu@starfivetech.com>
|
||||
Date: Mon, 20 Mar 2023 21:54:31 +0800
|
||||
Subject: [PATCH 059/122] dt-bindings: timer: Add timer for StarFive JH7110 SoC
|
||||
|
||||
Add bindings for the timer on the JH7110 RISC-V SoC
|
||||
by StarFive Technology Ltd.
|
||||
|
||||
Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
|
||||
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
|
||||
---
|
||||
.../bindings/timer/starfive,jh7110-timer.yaml | 95 +++++++++++++++++++
|
||||
1 file changed, 95 insertions(+)
|
||||
create mode 100644 Documentation/devicetree/bindings/timer/starfive,jh7110-timer.yaml
|
||||
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/timer/starfive,jh7110-timer.yaml
|
||||
@@ -0,0 +1,95 @@
|
||||
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
+%YAML 1.2
|
||||
+---
|
||||
+$id: http://devicetree.org/schemas/timer/starfive,jh7110-timer.yaml#
|
||||
+$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
+
|
||||
+title: StarFive JH7110 Timer
|
||||
+maintainers:
|
||||
+ - Xingyu Wu <xingyu.wu@starfivetech.com>
|
||||
+ - Samin Guo <samin.guo@starfivetech.com>
|
||||
+
|
||||
+description:
|
||||
+ This timer has four free-running 32 bit counters in StarFive JH7110 SoC.
|
||||
+ And each channel(counter) triggers an interrupt when timeout. They support
|
||||
+ one-shot mode and continuous-run mode.
|
||||
+
|
||||
+properties:
|
||||
+ compatible:
|
||||
+ const: starfive,jh7110-timer
|
||||
+
|
||||
+ reg:
|
||||
+ maxItems: 1
|
||||
+
|
||||
+ interrupts:
|
||||
+ items:
|
||||
+ - description: channel 0
|
||||
+ - description: channel 1
|
||||
+ - description: channel 2
|
||||
+ - description: channel 3
|
||||
+
|
||||
+ clocks:
|
||||
+ items:
|
||||
+ - description: timer APB
|
||||
+ - description: channel 0
|
||||
+ - description: channel 1
|
||||
+ - description: channel 2
|
||||
+ - description: channel 3
|
||||
+
|
||||
+ clock-names:
|
||||
+ items:
|
||||
+ - const: apb
|
||||
+ - const: ch0
|
||||
+ - const: ch1
|
||||
+ - const: ch2
|
||||
+ - const: ch3
|
||||
+
|
||||
+ resets:
|
||||
+ items:
|
||||
+ - description: timer APB
|
||||
+ - description: channel 0
|
||||
+ - description: channel 1
|
||||
+ - description: channel 2
|
||||
+ - description: channel 3
|
||||
+
|
||||
+ reset-names:
|
||||
+ items:
|
||||
+ - const: apb
|
||||
+ - const: ch0
|
||||
+ - const: ch1
|
||||
+ - const: ch2
|
||||
+ - const: ch3
|
||||
+
|
||||
+required:
|
||||
+ - compatible
|
||||
+ - reg
|
||||
+ - interrupts
|
||||
+ - clocks
|
||||
+ - clock-names
|
||||
+ - resets
|
||||
+ - reset-names
|
||||
+
|
||||
+additionalProperties: false
|
||||
+
|
||||
+examples:
|
||||
+ - |
|
||||
+ timer@13050000 {
|
||||
+ compatible = "starfive,jh7110-timer";
|
||||
+ reg = <0x13050000 0x10000>;
|
||||
+ interrupts = <69>, <70>, <71> ,<72>;
|
||||
+ clocks = <&clk 124>,
|
||||
+ <&clk 125>,
|
||||
+ <&clk 126>,
|
||||
+ <&clk 127>,
|
||||
+ <&clk 128>;
|
||||
+ clock-names = "apb", "ch0", "ch1",
|
||||
+ "ch2", "ch3";
|
||||
+ resets = <&rst 117>,
|
||||
+ <&rst 118>,
|
||||
+ <&rst 119>,
|
||||
+ <&rst 120>,
|
||||
+ <&rst 121>;
|
||||
+ reset-names = "apb", "ch0", "ch1",
|
||||
+ "ch2", "ch3";
|
||||
+ };
|
||||
+
|
@ -0,0 +1,540 @@
|
||||
From 3fbdabd59bac0978536fb11b1b9deb81559f1c54 Mon Sep 17 00:00:00 2001
|
||||
From: Xingyu Wu <xingyu.wu@starfivetech.com>
|
||||
Date: Mon, 20 Mar 2023 21:54:32 +0800
|
||||
Subject: [PATCH 060/122] clocksource: Add StarFive timer driver
|
||||
|
||||
Add timer driver for the StarFive JH7110 SoC.
|
||||
|
||||
Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
|
||||
---
|
||||
drivers/clocksource/Kconfig | 12 +
|
||||
drivers/clocksource/Makefile | 1 +
|
||||
drivers/clocksource/timer-starfive.c | 390 +++++++++++++++++++++++++++
|
||||
drivers/clocksource/timer-starfive.h | 96 +++++++
|
||||
4 files changed, 499 insertions(+)
|
||||
create mode 100644 drivers/clocksource/timer-starfive.c
|
||||
create mode 100644 drivers/clocksource/timer-starfive.h
|
||||
|
||||
--- a/drivers/clocksource/Kconfig
|
||||
+++ b/drivers/clocksource/Kconfig
|
||||
@@ -630,6 +630,18 @@ config RISCV_TIMER
|
||||
is accessed via both the SBI and the rdcycle instruction. This is
|
||||
required for all RISC-V systems.
|
||||
|
||||
+config STARFIVE_TIMER
|
||||
+ bool "Timer for the STARFIVE SoCs"
|
||||
+ depends on ARCH_STARFIVE || COMPILE_TEST
|
||||
+ select TIMER_OF
|
||||
+ select CLKSRC_MMIO
|
||||
+ default ARCH_STARFIVE
|
||||
+ help
|
||||
+ This enables the timer for StarFive SoCs. On RISC-V platform,
|
||||
+ the system has started RISCV_TIMER. But you can also use this timer
|
||||
+ to do a lot more on StarFive SoCs. This timer can provide high
|
||||
+ precision and four channels to use in JH7110 SoC.
|
||||
+
|
||||
config CLINT_TIMER
|
||||
bool "CLINT Timer for the RISC-V platform" if COMPILE_TEST
|
||||
depends on GENERIC_SCHED_CLOCK && RISCV
|
||||
--- a/drivers/clocksource/Makefile
|
||||
+++ b/drivers/clocksource/Makefile
|
||||
@@ -80,6 +80,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_TIMER) += timer-starfive.o
|
||||
obj-$(CONFIG_CLINT_TIMER) += timer-clint.o
|
||||
obj-$(CONFIG_CSKY_MP_TIMER) += timer-mp-csky.o
|
||||
obj-$(CONFIG_GX6605S_TIMER) += timer-gx6605s.o
|
||||
--- /dev/null
|
||||
+++ b/drivers/clocksource/timer-starfive.c
|
||||
@@ -0,0 +1,390 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0
|
||||
+/*
|
||||
+ * Starfive Timer driver
|
||||
+ *
|
||||
+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
|
||||
+ *
|
||||
+ * Author:
|
||||
+ * Xingyu Wu <xingyu.wu@starfivetech.com>
|
||||
+ * Samin Guo <samin.guo@starfivetech.com>
|
||||
+ */
|
||||
+
|
||||
+#include <linux/clk.h>
|
||||
+#include <linux/clockchips.h>
|
||||
+#include <linux/clocksource.h>
|
||||
+#include <linux/err.h>
|
||||
+#include <linux/interrupt.h>
|
||||
+#include <linux/io.h>
|
||||
+#include <linux/iopoll.h>
|
||||
+#include <linux/irq.h>
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/of.h>
|
||||
+#include <linux/of_device.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/reset.h>
|
||||
+#include <linux/sched_clock.h>
|
||||
+
|
||||
+#include "timer-starfive.h"
|
||||
+
|
||||
+static const struct starfive_timer_chan_base starfive_timer_jh7110_base = {
|
||||
+ .ctrl = STARFIVE_TIMER_JH7110_CTL,
|
||||
+ .load = STARFIVE_TIMER_JH7110_LOAD,
|
||||
+ .enable = STARFIVE_TIMER_JH7110_ENABLE,
|
||||
+ .reload = STARFIVE_TIMER_JH7110_RELOAD,
|
||||
+ .value = STARFIVE_TIMER_JH7110_VALUE,
|
||||
+ .intclr = STARFIVE_TIMER_JH7110_INT_CLR,
|
||||
+ .intmask = STARFIVE_TIMER_JH7110_INT_MASK,
|
||||
+ .channel_num = STARFIVE_TIMER_CH_4,
|
||||
+ .channel_base = {STARFIVE_TIMER_CH_BASE(0), STARFIVE_TIMER_CH_BASE(1),
|
||||
+ STARFIVE_TIMER_CH_BASE(2), STARFIVE_TIMER_CH_BASE(3)},
|
||||
+};
|
||||
+
|
||||
+static inline struct starfive_clkevt *to_starfive_clkevt(struct clock_event_device *evt)
|
||||
+{
|
||||
+ return container_of(evt, struct starfive_clkevt, evt);
|
||||
+}
|
||||
+
|
||||
+/* 0:continuous-run mode, 1:single-run mode */
|
||||
+static inline void starfive_timer_set_mod(struct starfive_clkevt *clkevt, int mod)
|
||||
+{
|
||||
+ writel(mod, clkevt->ctrl);
|
||||
+}
|
||||
+
|
||||
+/* Interrupt Mask Register, 0:Unmask, 1:Mask */
|
||||
+static inline void starfive_timer_int_enable(struct starfive_clkevt *clkevt)
|
||||
+{
|
||||
+ writel(STARFIVE_TIMER_INTMASK_DIS, clkevt->intmask);
|
||||
+}
|
||||
+
|
||||
+static inline void starfive_timer_int_disable(struct starfive_clkevt *clkevt)
|
||||
+{
|
||||
+ writel(STARFIVE_TIMER_INTMASK_ENA, clkevt->intmask);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * BIT(0): Read value represent channel intr status.
|
||||
+ * Write 1 to this bit to clear interrupt. Write 0 has no effects.
|
||||
+ * BIT(1): "1" means that it is clearing interrupt. BIT(0) can not be written.
|
||||
+ */
|
||||
+static inline int starfive_timer_int_clear(struct starfive_clkevt *clkevt)
|
||||
+{
|
||||
+ u32 value;
|
||||
+ int ret;
|
||||
+
|
||||
+ /* waiting interrupt can be to clearing */
|
||||
+ ret = readl_poll_timeout_atomic(clkevt->intclr, value,
|
||||
+ !(value & STARFIVE_TIMER_JH7110_INT_CLR_AVA_MASK),
|
||||
+ STARFIVE_DELAY_US, STARFIVE_TIMEOUT_US);
|
||||
+ if (!ret)
|
||||
+ writel(0x1, clkevt->intclr);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * The initial value to be loaded into the
|
||||
+ * counter and is also used as the reload value.
|
||||
+ * val = clock rate --> 1s
|
||||
+ */
|
||||
+static inline void starfive_timer_set_load(struct starfive_clkevt *clkevt, u32 val)
|
||||
+{
|
||||
+ writel(val, clkevt->load);
|
||||
+}
|
||||
+
|
||||
+static inline u32 starfive_timer_get_val(struct starfive_clkevt *clkevt)
|
||||
+{
|
||||
+ return readl(clkevt->value);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Write RELOAD register to reload preset value to counter.
|
||||
+ * (Write 0 and write 1 are both ok)
|
||||
+ */
|
||||
+static inline void starfive_timer_set_reload(struct starfive_clkevt *clkevt)
|
||||
+{
|
||||
+ writel(0, clkevt->reload);
|
||||
+}
|
||||
+
|
||||
+static inline void starfive_timer_enable(struct starfive_clkevt *clkevt)
|
||||
+{
|
||||
+ writel(STARFIVE_TIMER_ENA, clkevt->enable);
|
||||
+}
|
||||
+
|
||||
+static inline void starfive_timer_disable(struct starfive_clkevt *clkevt)
|
||||
+{
|
||||
+ writel(STARFIVE_TIMER_DIS, clkevt->enable);
|
||||
+}
|
||||
+
|
||||
+static int starfive_timer_int_init_enable(struct starfive_clkevt *clkevt)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ starfive_timer_int_disable(clkevt);
|
||||
+ ret = starfive_timer_int_clear(clkevt);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ starfive_timer_int_enable(clkevt);
|
||||
+ starfive_timer_enable(clkevt);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int starfive_timer_shutdown(struct clock_event_device *evt)
|
||||
+{
|
||||
+ struct starfive_clkevt *clkevt = to_starfive_clkevt(evt);
|
||||
+
|
||||
+ starfive_timer_disable(clkevt);
|
||||
+ return starfive_timer_int_clear(clkevt);
|
||||
+}
|
||||
+
|
||||
+static void starfive_timer_suspend(struct clock_event_device *evt)
|
||||
+{
|
||||
+ struct starfive_clkevt *clkevt = to_starfive_clkevt(evt);
|
||||
+
|
||||
+ clkevt->reload_val = starfive_timer_get_val(clkevt);
|
||||
+ starfive_timer_shutdown(evt);
|
||||
+}
|
||||
+
|
||||
+static void starfive_timer_resume(struct clock_event_device *evt)
|
||||
+{
|
||||
+ struct starfive_clkevt *clkevt = to_starfive_clkevt(evt);
|
||||
+
|
||||
+ starfive_timer_set_load(clkevt, clkevt->reload_val);
|
||||
+ starfive_timer_set_reload(clkevt);
|
||||
+ starfive_timer_int_enable(clkevt);
|
||||
+ starfive_timer_enable(clkevt);
|
||||
+}
|
||||
+
|
||||
+static int starfive_timer_tick_resume(struct clock_event_device *evt)
|
||||
+{
|
||||
+ starfive_timer_resume(evt);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int starfive_clocksource_init(struct starfive_clkevt *clkevt)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ starfive_timer_set_mod(clkevt, STARFIVE_TIMER_MOD_CONTIN);
|
||||
+ starfive_timer_set_load(clkevt, STARFIVE_TIMER_MAX_TICKS);
|
||||
+ ret = starfive_timer_int_init_enable(clkevt);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ return clocksource_mmio_init(clkevt->value, clkevt->name, clkevt->rate,
|
||||
+ STARFIVE_CLOCK_SOURCE_RATING, STARFIVE_VALID_BITS,
|
||||
+ clocksource_mmio_readl_down);
|
||||
+}
|
||||
+
|
||||
+/* IRQ handler for the timer */
|
||||
+static irqreturn_t starfive_timer_interrupt(int irq, void *priv)
|
||||
+{
|
||||
+ struct clock_event_device *evt = (struct clock_event_device *)priv;
|
||||
+ struct starfive_clkevt *clkevt = to_starfive_clkevt(evt);
|
||||
+
|
||||
+ if (starfive_timer_int_clear(clkevt))
|
||||
+ return IRQ_NONE;
|
||||
+
|
||||
+ if (evt->event_handler)
|
||||
+ evt->event_handler(evt);
|
||||
+
|
||||
+ return IRQ_HANDLED;
|
||||
+}
|
||||
+
|
||||
+static int starfive_timer_set_periodic(struct clock_event_device *evt)
|
||||
+{
|
||||
+ struct starfive_clkevt *clkevt = to_starfive_clkevt(evt);
|
||||
+
|
||||
+ starfive_timer_disable(clkevt);
|
||||
+ starfive_timer_set_mod(clkevt, STARFIVE_TIMER_MOD_CONTIN);
|
||||
+ starfive_timer_set_load(clkevt, clkevt->periodic);
|
||||
+
|
||||
+ return starfive_timer_int_init_enable(clkevt);
|
||||
+}
|
||||
+
|
||||
+static int starfive_timer_set_oneshot(struct clock_event_device *evt)
|
||||
+{
|
||||
+ struct starfive_clkevt *clkevt = to_starfive_clkevt(evt);
|
||||
+
|
||||
+ starfive_timer_disable(clkevt);
|
||||
+ starfive_timer_set_mod(clkevt, STARFIVE_TIMER_MOD_SINGLE);
|
||||
+ starfive_timer_set_load(clkevt, STARFIVE_TIMER_MAX_TICKS);
|
||||
+
|
||||
+ return starfive_timer_int_init_enable(clkevt);
|
||||
+}
|
||||
+
|
||||
+static int starfive_timer_set_next_event(unsigned long next,
|
||||
+ struct clock_event_device *evt)
|
||||
+{
|
||||
+ struct starfive_clkevt *clkevt = to_starfive_clkevt(evt);
|
||||
+
|
||||
+ starfive_timer_disable(clkevt);
|
||||
+ starfive_timer_set_mod(clkevt, STARFIVE_TIMER_MOD_SINGLE);
|
||||
+ starfive_timer_set_load(clkevt, next);
|
||||
+ starfive_timer_enable(clkevt);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void starfive_set_clockevent(struct clock_event_device *evt)
|
||||
+{
|
||||
+ evt->features = CLOCK_EVT_FEAT_PERIODIC |
|
||||
+ CLOCK_EVT_FEAT_ONESHOT |
|
||||
+ CLOCK_EVT_FEAT_DYNIRQ;
|
||||
+ evt->set_state_shutdown = starfive_timer_shutdown;
|
||||
+ evt->set_state_periodic = starfive_timer_set_periodic;
|
||||
+ evt->set_state_oneshot = starfive_timer_set_oneshot;
|
||||
+ evt->set_state_oneshot_stopped = starfive_timer_shutdown;
|
||||
+ evt->tick_resume = starfive_timer_tick_resume;
|
||||
+ evt->set_next_event = starfive_timer_set_next_event;
|
||||
+ evt->suspend = starfive_timer_suspend;
|
||||
+ evt->resume = starfive_timer_resume;
|
||||
+ evt->rating = STARFIVE_CLOCKEVENT_RATING;
|
||||
+}
|
||||
+
|
||||
+static void starfive_clockevents_register(struct starfive_clkevt *clkevt)
|
||||
+{
|
||||
+ clkevt->rate = clk_get_rate(clkevt->clk);
|
||||
+ clkevt->periodic = DIV_ROUND_CLOSEST(clkevt->rate, HZ);
|
||||
+
|
||||
+ starfive_set_clockevent(&clkevt->evt);
|
||||
+ clkevt->evt.name = clkevt->name;
|
||||
+ clkevt->evt.irq = clkevt->irq;
|
||||
+ clkevt->evt.cpumask = cpu_possible_mask;
|
||||
+
|
||||
+ clockevents_config_and_register(&clkevt->evt, clkevt->rate,
|
||||
+ STARFIVE_TIMER_MIN_TICKS, STARFIVE_TIMER_MAX_TICKS);
|
||||
+}
|
||||
+
|
||||
+static void __init starfive_clkevt_base_init(const struct starfive_timer_chan_base *timer,
|
||||
+ struct starfive_clkevt *clkevt,
|
||||
+ void __iomem *base, int ch)
|
||||
+{
|
||||
+ void __iomem *channel_base;
|
||||
+
|
||||
+ channel_base = base + timer->channel_base[ch];
|
||||
+ clkevt->base = channel_base;
|
||||
+ clkevt->ctrl = channel_base + timer->ctrl;
|
||||
+ clkevt->load = channel_base + timer->load;
|
||||
+ clkevt->enable = channel_base + timer->enable;
|
||||
+ clkevt->reload = channel_base + timer->reload;
|
||||
+ clkevt->value = channel_base + timer->value;
|
||||
+ clkevt->intclr = channel_base + timer->intclr;
|
||||
+ clkevt->intmask = channel_base + timer->intmask;
|
||||
+}
|
||||
+
|
||||
+static int __init starfive_timer_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ const struct starfive_timer_chan_base *timer_base = of_device_get_match_data(&pdev->dev);
|
||||
+ char name[10];
|
||||
+ struct starfive_timer_priv *priv;
|
||||
+ struct starfive_clkevt *clkevt;
|
||||
+ struct clk *pclk;
|
||||
+ struct reset_control *rst;
|
||||
+ int ch;
|
||||
+ int ret;
|
||||
+
|
||||
+ priv = devm_kzalloc(&pdev->dev, struct_size(priv, clkevt, timer_base->channel_num),
|
||||
+ GFP_KERNEL);
|
||||
+ if (!priv)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ priv->base = devm_platform_ioremap_resource(pdev, 0);
|
||||
+ if (IS_ERR(priv->base))
|
||||
+ return dev_err_probe(&pdev->dev, PTR_ERR(priv->base),
|
||||
+ "failed to map registers\n");
|
||||
+
|
||||
+ rst = devm_reset_control_get_exclusive(&pdev->dev, "apb");
|
||||
+ if (IS_ERR(rst))
|
||||
+ return dev_err_probe(&pdev->dev, PTR_ERR(rst), "failed to get apb reset\n");
|
||||
+
|
||||
+ pclk = devm_clk_get_enabled(&pdev->dev, "apb");
|
||||
+ if (IS_ERR(pclk))
|
||||
+ return dev_err_probe(&pdev->dev, PTR_ERR(pclk),
|
||||
+ "failed to get & enable apb clock\n");
|
||||
+
|
||||
+ ret = reset_control_deassert(rst);
|
||||
+ if (ret)
|
||||
+ goto err;
|
||||
+
|
||||
+ priv->dev = &pdev->dev;
|
||||
+ platform_set_drvdata(pdev, priv);
|
||||
+
|
||||
+ for (ch = 0; ch < timer_base->channel_num; ch++) {
|
||||
+ clkevt = &priv->clkevt[ch];
|
||||
+ snprintf(name, sizeof(name), "ch%d", ch);
|
||||
+
|
||||
+ starfive_clkevt_base_init(timer_base, clkevt, priv->base, ch);
|
||||
+ /* Ensure timers are disabled */
|
||||
+ starfive_timer_disable(clkevt);
|
||||
+
|
||||
+ rst = devm_reset_control_get_exclusive(&pdev->dev, name);
|
||||
+ if (IS_ERR(rst)) {
|
||||
+ ret = PTR_ERR(rst);
|
||||
+ goto err;
|
||||
+ }
|
||||
+
|
||||
+ clkevt->clk = devm_clk_get_enabled(&pdev->dev, name);
|
||||
+ if (IS_ERR(clkevt->clk)) {
|
||||
+ ret = PTR_ERR(clkevt->clk);
|
||||
+ goto err;
|
||||
+ }
|
||||
+
|
||||
+ ret = reset_control_deassert(rst);
|
||||
+ if (ret)
|
||||
+ goto ch_err;
|
||||
+
|
||||
+ clkevt->irq = platform_get_irq(pdev, ch);
|
||||
+ if (clkevt->irq < 0) {
|
||||
+ ret = clkevt->irq;
|
||||
+ goto ch_err;
|
||||
+ }
|
||||
+
|
||||
+ snprintf(clkevt->name, sizeof(clkevt->name), "%s.ch%d", pdev->name, ch);
|
||||
+ starfive_clockevents_register(clkevt);
|
||||
+
|
||||
+ ret = devm_request_irq(&pdev->dev, clkevt->irq, starfive_timer_interrupt,
|
||||
+ IRQF_TIMER | IRQF_IRQPOLL,
|
||||
+ clkevt->name, &clkevt->evt);
|
||||
+ if (ret)
|
||||
+ goto ch_err;
|
||||
+
|
||||
+ ret = starfive_clocksource_init(clkevt);
|
||||
+ if (ret)
|
||||
+ goto ch_err;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+ch_err:
|
||||
+ /* Only unregister the failed channel and the rest timer channels continue to work. */
|
||||
+ clk_disable_unprepare(clkevt->clk);
|
||||
+err:
|
||||
+ /* If no other channel successfully registers, pclk should be disabled. */
|
||||
+ if (!ch)
|
||||
+ clk_disable_unprepare(pclk);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static const struct of_device_id starfive_timer_match[] = {
|
||||
+ { .compatible = "starfive,jh7110-timer", .data = &starfive_timer_jh7110_base },
|
||||
+ { /* sentinel */ }
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, starfive_timer_match);
|
||||
+
|
||||
+static struct platform_driver starfive_timer_driver = {
|
||||
+ .probe = starfive_timer_probe,
|
||||
+ .driver = {
|
||||
+ .name = "starfive-timer",
|
||||
+ .of_match_table = starfive_timer_match,
|
||||
+ },
|
||||
+};
|
||||
+module_platform_driver(starfive_timer_driver);
|
||||
+
|
||||
+MODULE_AUTHOR("Xingyu Wu <xingyu.wu@starfivetech.com>");
|
||||
+MODULE_DESCRIPTION("StarFive timer driver");
|
||||
+MODULE_LICENSE("GPL");
|
||||
--- /dev/null
|
||||
+++ b/drivers/clocksource/timer-starfive.h
|
||||
@@ -0,0 +1,96 @@
|
||||
+/* SPDX-License-Identifier: GPL-2.0 */
|
||||
+/*
|
||||
+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
|
||||
+ */
|
||||
+
|
||||
+#ifndef __STARFIVE_TIMER_H__
|
||||
+#define __STARFIVE_TIMER_H__
|
||||
+
|
||||
+/* Bias: Ch0-0x0, Ch1-0x40, Ch2-0x80, and so on. */
|
||||
+#define STARFIVE_TIMER_CH_LEN 0x40
|
||||
+#define STARFIVE_TIMER_CH_BASE(x) ((STARFIVE_TIMER_CH_##x) * STARFIVE_TIMER_CH_LEN)
|
||||
+
|
||||
+#define STARFIVE_CLOCK_SOURCE_RATING 200
|
||||
+#define STARFIVE_VALID_BITS 32
|
||||
+#define STARFIVE_DELAY_US 0
|
||||
+#define STARFIVE_TIMEOUT_US 10000
|
||||
+#define STARFIVE_CLOCKEVENT_RATING 300
|
||||
+#define STARFIVE_TIMER_MAX_TICKS 0xffffffff
|
||||
+#define STARFIVE_TIMER_MIN_TICKS 0xf
|
||||
+
|
||||
+#define STARFIVE_TIMER_JH7110_INT_STATUS 0x00 /* RO[0:4]: Interrupt Status for channel0~4 */
|
||||
+#define STARFIVE_TIMER_JH7110_CTL 0x04 /* RW[0]: 0-continuous run, 1-single run */
|
||||
+#define STARFIVE_TIMER_JH7110_LOAD 0x08 /* RW: load value to counter */
|
||||
+#define STARFIVE_TIMER_JH7110_ENABLE 0x10 /* RW[0]: timer enable register */
|
||||
+#define STARFIVE_TIMER_JH7110_RELOAD 0x14 /* RW: write 1 or 0 both reload counter */
|
||||
+#define STARFIVE_TIMER_JH7110_VALUE 0x18 /* RO: timer value register */
|
||||
+#define STARFIVE_TIMER_JH7110_INT_CLR 0x20 /* RW: timer interrupt clear register */
|
||||
+#define STARFIVE_TIMER_JH7110_INT_MASK 0x24 /* RW[0]: timer interrupt mask register */
|
||||
+#define STARFIVE_TIMER_JH7110_INT_CLR_AVA_MASK BIT(1)
|
||||
+
|
||||
+enum STARFIVE_TIMER_CH {
|
||||
+ STARFIVE_TIMER_CH_0 = 0,
|
||||
+ STARFIVE_TIMER_CH_1,
|
||||
+ STARFIVE_TIMER_CH_2,
|
||||
+ STARFIVE_TIMER_CH_3,
|
||||
+ STARFIVE_TIMER_CH_4,
|
||||
+ STARFIVE_TIMER_CH_5,
|
||||
+ STARFIVE_TIMER_CH_6,
|
||||
+ STARFIVE_TIMER_CH_7,
|
||||
+ STARFIVE_TIMER_CH_MAX
|
||||
+};
|
||||
+
|
||||
+enum STARFIVE_TIMER_INTMASK {
|
||||
+ STARFIVE_TIMER_INTMASK_DIS = 0,
|
||||
+ STARFIVE_TIMER_INTMASK_ENA = 1
|
||||
+};
|
||||
+
|
||||
+enum STARFIVE_TIMER_MOD {
|
||||
+ STARFIVE_TIMER_MOD_CONTIN = 0,
|
||||
+ STARFIVE_TIMER_MOD_SINGLE = 1
|
||||
+};
|
||||
+
|
||||
+enum STARFIVE_TIMER_CTL_EN {
|
||||
+ STARFIVE_TIMER_DIS = 0,
|
||||
+ STARFIVE_TIMER_ENA = 1
|
||||
+};
|
||||
+
|
||||
+struct starfive_timer_chan_base {
|
||||
+ /* Resgister */
|
||||
+ unsigned int ctrl;
|
||||
+ unsigned int load;
|
||||
+ unsigned int enable;
|
||||
+ unsigned int reload;
|
||||
+ unsigned int value;
|
||||
+ unsigned int intclr;
|
||||
+ unsigned int intmask;
|
||||
+
|
||||
+ unsigned int channel_num; /* timer channel numbers */
|
||||
+ unsigned int channel_base[];
|
||||
+};
|
||||
+
|
||||
+struct starfive_clkevt {
|
||||
+ struct clock_event_device evt;
|
||||
+ struct clk *clk;
|
||||
+ char name[20];
|
||||
+ int irq;
|
||||
+ u32 periodic;
|
||||
+ u32 rate;
|
||||
+ u32 reload_val;
|
||||
+ void __iomem *base;
|
||||
+ void __iomem *ctrl;
|
||||
+ void __iomem *load;
|
||||
+ void __iomem *enable;
|
||||
+ void __iomem *reload;
|
||||
+ void __iomem *value;
|
||||
+ void __iomem *intclr;
|
||||
+ void __iomem *intmask;
|
||||
+};
|
||||
+
|
||||
+struct starfive_timer_priv {
|
||||
+ struct device *dev;
|
||||
+ void __iomem *base;
|
||||
+ struct starfive_clkevt clkevt[];
|
||||
+};
|
||||
+
|
||||
+#endif /* __STARFIVE_TIMER_H__ */
|
@ -0,0 +1,36 @@
|
||||
From 16214121afaadb8ae9aaf73351e874405eb47c15 Mon Sep 17 00:00:00 2001
|
||||
From: Samin Guo <samin.guo@starfivetech.com>
|
||||
Date: Tue, 25 Apr 2023 18:51:15 +0800
|
||||
Subject: [PATCH 061/122] dt-bindings: net: motorcomm: Add pad driver strength
|
||||
cfg
|
||||
|
||||
The motorcomm phy (YT8531) supports the ability to adjust the drive
|
||||
strength of the rx_clk/rx_data, the value range of pad driver
|
||||
strength is 0 to 7.
|
||||
|
||||
Signed-off-by: Samin Guo <samin.guo@starfivetech.com>
|
||||
---
|
||||
.../devicetree/bindings/net/motorcomm,yt8xxx.yaml | 12 ++++++++++++
|
||||
1 file changed, 12 insertions(+)
|
||||
|
||||
--- a/Documentation/devicetree/bindings/net/motorcomm,yt8xxx.yaml
|
||||
+++ b/Documentation/devicetree/bindings/net/motorcomm,yt8xxx.yaml
|
||||
@@ -62,6 +62,18 @@ properties:
|
||||
for a timer.
|
||||
type: boolean
|
||||
|
||||
+ motorcomm,rx-clk-driver-strength:
|
||||
+ description: drive strength of rx_clk pad.
|
||||
+ $ref: /schemas/types.yaml#/definitions/uint32
|
||||
+ enum: [ 0, 1, 2, 3, 4, 5, 6, 7 ]
|
||||
+ default: 3
|
||||
+
|
||||
+ motorcomm,rx-data-driver-strength:
|
||||
+ description: drive strength of rx_data/rx_ctl rgmii pad.
|
||||
+ $ref: /schemas/types.yaml#/definitions/uint32
|
||||
+ enum: [ 0, 1, 2, 3, 4, 5, 6, 7 ]
|
||||
+ default: 3
|
||||
+
|
||||
motorcomm,tx-clk-adj-enabled:
|
||||
description: |
|
||||
This configuration is mainly to adapt to VF2 with JH7110 SoC.
|
@ -0,0 +1,71 @@
|
||||
From 99f0bf43994dada29e33fd8718fd25484634da3a Mon Sep 17 00:00:00 2001
|
||||
From: William Qiu <william.qiu@starfivetech.com>
|
||||
Date: Tue, 21 Mar 2023 13:52:27 +0800
|
||||
Subject: [PATCH 062/122] dt-bindings: PWM: Add StarFive PWM module
|
||||
|
||||
Add documentation to describe StarFive Pulse Width Modulation
|
||||
controller driver.
|
||||
|
||||
Signed-off-by: William Qiu <william.qiu@starfivetech.com>
|
||||
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
|
||||
---
|
||||
.../bindings/pwm/starfive,jh7110-pwm.yaml | 53 +++++++++++++++++++
|
||||
1 file changed, 53 insertions(+)
|
||||
create mode 100644 Documentation/devicetree/bindings/pwm/starfive,jh7110-pwm.yaml
|
||||
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/pwm/starfive,jh7110-pwm.yaml
|
||||
@@ -0,0 +1,53 @@
|
||||
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
+%YAML 1.2
|
||||
+---
|
||||
+$id: http://devicetree.org/schemas/pwm/starfive,jh7110-pwm.yaml#
|
||||
+$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
+
|
||||
+title: StarFive PWM controller
|
||||
+
|
||||
+maintainers:
|
||||
+ - William Qiu <william.qiu@starfivetech.com>
|
||||
+
|
||||
+description:
|
||||
+ StarFive SoCs contain PWM and when operating in PWM mode, the PTC core generates
|
||||
+ binary signal with user-programmable low and high periods. Clock source for the
|
||||
+ PWM can be either system clockor external clock. Each PWM timer block provides 8
|
||||
+ PWM channels.
|
||||
+
|
||||
+allOf:
|
||||
+ - $ref: pwm.yaml#
|
||||
+
|
||||
+properties:
|
||||
+ compatible:
|
||||
+ const: starfive,jh7110-pwm
|
||||
+
|
||||
+ reg:
|
||||
+ maxItems: 1
|
||||
+
|
||||
+ clocks:
|
||||
+ maxItems: 1
|
||||
+
|
||||
+ resets:
|
||||
+ maxItems: 1
|
||||
+
|
||||
+ "#pwm-cells":
|
||||
+ const: 3
|
||||
+
|
||||
+required:
|
||||
+ - compatible
|
||||
+ - reg
|
||||
+ - clocks
|
||||
+ - resets
|
||||
+
|
||||
+additionalProperties: false
|
||||
+
|
||||
+examples:
|
||||
+ - |
|
||||
+ pwm@120d0000 {
|
||||
+ compatible = "starfive,jh7110-pwm";
|
||||
+ reg = <0x120d0000 0x10000>;
|
||||
+ clocks = <&syscrg 121>;
|
||||
+ resets = <&syscrg 108>;
|
||||
+ #pwm-cells = <3>;
|
||||
+ };
|
@ -0,0 +1,294 @@
|
||||
From fddea961e7ce1f26dd549e3d92ede624246690c0 Mon Sep 17 00:00:00 2001
|
||||
From: William Qiu <william.qiu@starfivetech.com>
|
||||
Date: Tue, 21 Mar 2023 13:52:28 +0800
|
||||
Subject: [PATCH 063/122] pwm: starfive: Add PWM driver support
|
||||
|
||||
Add Pulse Width Modulation driver support for StarFive
|
||||
JH7110 soc.
|
||||
|
||||
Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
|
||||
Signed-off-by: William Qiu <william.qiu@starfivetech.com>
|
||||
---
|
||||
drivers/pwm/Kconfig | 10 ++
|
||||
drivers/pwm/Makefile | 1 +
|
||||
drivers/pwm/pwm-starfive-ptc.c | 245 +++++++++++++++++++++++++++++++++
|
||||
3 files changed, 256 insertions(+)
|
||||
create mode 100644 drivers/pwm/pwm-starfive-ptc.c
|
||||
|
||||
--- a/drivers/pwm/Kconfig
|
||||
+++ b/drivers/pwm/Kconfig
|
||||
@@ -536,6 +536,16 @@ config PWM_SPRD
|
||||
To compile this driver as a module, choose M here: the module
|
||||
will be called pwm-sprd.
|
||||
|
||||
+config PWM_STARFIVE_PTC
|
||||
+ tristate "StarFive PWM PTC support"
|
||||
+ depends on OF
|
||||
+ depends on COMMON_CLK
|
||||
+ help
|
||||
+ Generic PWM framework driver for StarFive SoCs.
|
||||
+
|
||||
+ To compile this driver as a module, choose M here: the module
|
||||
+ will be called pwm-starfive-ptc.
|
||||
+
|
||||
config PWM_STI
|
||||
tristate "STiH4xx PWM support"
|
||||
depends on ARCH_STI || COMPILE_TEST
|
||||
--- a/drivers/pwm/Makefile
|
||||
+++ b/drivers/pwm/Makefile
|
||||
@@ -49,6 +49,7 @@ obj-$(CONFIG_PWM_SIFIVE) += pwm-sifive.o
|
||||
obj-$(CONFIG_PWM_SL28CPLD) += pwm-sl28cpld.o
|
||||
obj-$(CONFIG_PWM_SPEAR) += pwm-spear.o
|
||||
obj-$(CONFIG_PWM_SPRD) += pwm-sprd.o
|
||||
+obj-$(CONFIG_PWM_STARFIVE_PTC) += pwm-starfive-ptc.o
|
||||
obj-$(CONFIG_PWM_STI) += pwm-sti.o
|
||||
obj-$(CONFIG_PWM_STM32) += pwm-stm32.o
|
||||
obj-$(CONFIG_PWM_STM32_LP) += pwm-stm32-lp.o
|
||||
--- /dev/null
|
||||
+++ b/drivers/pwm/pwm-starfive-ptc.c
|
||||
@@ -0,0 +1,245 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0
|
||||
+/*
|
||||
+ * PWM driver for the StarFive JH7110 SoC
|
||||
+ *
|
||||
+ * Copyright (C) 2018 StarFive Technology Co., Ltd.
|
||||
+ */
|
||||
+
|
||||
+#include <dt-bindings/pwm/pwm.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/pwm.h>
|
||||
+#include <linux/slab.h>
|
||||
+#include <linux/clk.h>
|
||||
+#include <linux/reset.h>
|
||||
+#include <linux/io.h>
|
||||
+
|
||||
+/* how many parameters can be transferred to ptc */
|
||||
+#define OF_PWM_N_CELLS 3
|
||||
+
|
||||
+/* PTC Register offsets */
|
||||
+#define REG_RPTC_CNTR 0x0
|
||||
+#define REG_RPTC_HRC 0x4
|
||||
+#define REG_RPTC_LRC 0x8
|
||||
+#define REG_RPTC_CTRL 0xC
|
||||
+
|
||||
+/* Bit for PWM clock */
|
||||
+#define BIT_PWM_CLOCK_EN 31
|
||||
+
|
||||
+/* Bit for clock gen soft reset */
|
||||
+#define BIT_CLK_GEN_SOFT_RESET 13
|
||||
+
|
||||
+#define NS_PER_SECOND 1000000000
|
||||
+
|
||||
+/*
|
||||
+ * Access PTC register (cntr hrc lrc and ctrl),
|
||||
+ * need to replace PWM_BASE_ADDR
|
||||
+ */
|
||||
+#define REG_PTC_BASE_ADDR_SUB(base, N) \
|
||||
+((base) + (((N) > 3) ? (((N) % 4) * 0x10 + (1 << 15)) : ((N) * 0x10)))
|
||||
+#define REG_PTC_RPTC_CNTR(base, N) (REG_PTC_BASE_ADDR_SUB(base, N))
|
||||
+#define REG_PTC_RPTC_HRC(base, N) (REG_PTC_BASE_ADDR_SUB(base, N) + 0x4)
|
||||
+#define REG_PTC_RPTC_LRC(base, N) (REG_PTC_BASE_ADDR_SUB(base, N) + 0x8)
|
||||
+#define REG_PTC_RPTC_CTRL(base, N) (REG_PTC_BASE_ADDR_SUB(base, N) + 0xC)
|
||||
+
|
||||
+/* PTC_RPTC_CTRL */
|
||||
+#define PTC_EN BIT(0)
|
||||
+#define PTC_ECLK BIT(1)
|
||||
+#define PTC_NEC BIT(2)
|
||||
+#define PTC_OE BIT(3)
|
||||
+#define PTC_SIGNLE BIT(4)
|
||||
+#define PTC_INTE BIT(5)
|
||||
+#define PTC_INT BIT(6)
|
||||
+#define PTC_CNTRRST BIT(7)
|
||||
+#define PTC_CAPTE BIT(8)
|
||||
+
|
||||
+struct starfive_pwm_ptc_device {
|
||||
+ struct pwm_chip chip;
|
||||
+ struct clk *clk;
|
||||
+ struct reset_control *rst;
|
||||
+ void __iomem *regs;
|
||||
+ int irq;
|
||||
+ unsigned int approx_freq;/*pwm apb clock frequency*/
|
||||
+};
|
||||
+
|
||||
+static inline
|
||||
+struct starfive_pwm_ptc_device *chip_to_starfive_ptc(struct pwm_chip *c)
|
||||
+{
|
||||
+ return container_of(c, struct starfive_pwm_ptc_device, chip);
|
||||
+}
|
||||
+
|
||||
+static int starfive_pwm_ptc_get_state(struct pwm_chip *chip,
|
||||
+ struct pwm_device *dev,
|
||||
+ struct pwm_state *state)
|
||||
+{
|
||||
+ struct starfive_pwm_ptc_device *pwm = chip_to_starfive_ptc(chip);
|
||||
+ u32 data_lrc, data_hrc;
|
||||
+ u32 pwm_clk_ns = 0;
|
||||
+
|
||||
+ data_lrc = ioread32(REG_PTC_RPTC_LRC(pwm->regs, dev->hwpwm));
|
||||
+ data_hrc = ioread32(REG_PTC_RPTC_HRC(pwm->regs, dev->hwpwm));
|
||||
+
|
||||
+ pwm_clk_ns = NS_PER_SECOND / pwm->approx_freq;
|
||||
+
|
||||
+ state->period = data_lrc * pwm_clk_ns;
|
||||
+ state->duty_cycle = data_hrc * pwm_clk_ns;
|
||||
+ state->polarity = PWM_POLARITY_NORMAL;
|
||||
+ state->enabled = 1;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int starfive_pwm_ptc_apply(struct pwm_chip *chip,
|
||||
+ struct pwm_device *dev,
|
||||
+ struct pwm_state *state)
|
||||
+{
|
||||
+ struct starfive_pwm_ptc_device *pwm = chip_to_starfive_ptc(chip);
|
||||
+ u32 data_hrc = 0;
|
||||
+ u32 data_lrc = 0;
|
||||
+ u32 period_data = 0;
|
||||
+ u32 duty_data = 0;
|
||||
+ s64 multi = pwm->approx_freq;
|
||||
+ s64 div = NS_PER_SECOND;
|
||||
+ void __iomem *reg_addr;
|
||||
+
|
||||
+ if (state->duty_cycle > state->period)
|
||||
+ state->duty_cycle = state->period;
|
||||
+
|
||||
+ while (multi % 10 == 0 && div % 10 == 0 && multi > 0 && div > 0) {
|
||||
+ multi /= 10;
|
||||
+ div /= 10;
|
||||
+ }
|
||||
+
|
||||
+ period_data = (u32)(state->period * multi / div);
|
||||
+ if (abs(period_data * div / multi - state->period)
|
||||
+ > abs((period_data + 1) * div / multi - state->period) ||
|
||||
+ (state->period > 0 && period_data == 0))
|
||||
+ period_data += 1;
|
||||
+
|
||||
+ if (state->enabled) {
|
||||
+ duty_data = (u32)(state->duty_cycle * multi / div);
|
||||
+ if (abs(duty_data * div / multi - state->duty_cycle)
|
||||
+ > abs((duty_data + 1) * div / multi - state->duty_cycle) ||
|
||||
+ (state->duty_cycle > 0 && duty_data == 0))
|
||||
+ duty_data += 1;
|
||||
+ } else {
|
||||
+ duty_data = 0;
|
||||
+ }
|
||||
+
|
||||
+ if (state->polarity == PWM_POLARITY_NORMAL)
|
||||
+ data_hrc = period_data - duty_data;
|
||||
+ else
|
||||
+ data_hrc = duty_data;
|
||||
+
|
||||
+ data_lrc = period_data;
|
||||
+
|
||||
+ reg_addr = REG_PTC_RPTC_HRC(pwm->regs, dev->hwpwm);
|
||||
+ iowrite32(data_hrc, reg_addr);
|
||||
+
|
||||
+ reg_addr = REG_PTC_RPTC_LRC(pwm->regs, dev->hwpwm);
|
||||
+ iowrite32(data_lrc, reg_addr);
|
||||
+
|
||||
+ reg_addr = REG_PTC_RPTC_CNTR(pwm->regs, dev->hwpwm);
|
||||
+ iowrite32(0, reg_addr);
|
||||
+
|
||||
+ reg_addr = REG_PTC_RPTC_CTRL(pwm->regs, dev->hwpwm);
|
||||
+ iowrite32(PTC_EN | PTC_OE, reg_addr);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct pwm_ops starfive_pwm_ptc_ops = {
|
||||
+ .get_state = starfive_pwm_ptc_get_state,
|
||||
+ .apply = (void *)starfive_pwm_ptc_apply,
|
||||
+ .owner = THIS_MODULE,
|
||||
+};
|
||||
+
|
||||
+static int starfive_pwm_ptc_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct device *dev = &pdev->dev;
|
||||
+ struct starfive_pwm_ptc_device *pwm;
|
||||
+ struct pwm_chip *chip;
|
||||
+ int ret;
|
||||
+
|
||||
+ pwm = devm_kzalloc(dev, sizeof(*pwm), GFP_KERNEL);
|
||||
+ if (!pwm)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ chip = &pwm->chip;
|
||||
+ chip->dev = dev;
|
||||
+ chip->ops = &starfive_pwm_ptc_ops;
|
||||
+ chip->npwm = 8;
|
||||
+
|
||||
+ chip->of_pwm_n_cells = OF_PWM_N_CELLS;
|
||||
+ chip->base = -1;
|
||||
+
|
||||
+ pwm->regs = devm_platform_ioremap_resource(pdev, 0);
|
||||
+ if (IS_ERR(pwm->regs))
|
||||
+ return dev_err_probe(dev, PTR_ERR(pwm->regs),
|
||||
+ "Unable to map IO resources\n");
|
||||
+
|
||||
+ pwm->clk = devm_clk_get(dev, NULL);
|
||||
+ if (IS_ERR(pwm->clk))
|
||||
+ return dev_err_probe(dev, PTR_ERR(pwm->clk),
|
||||
+ "Unable to get pwm clock\n");
|
||||
+
|
||||
+ pwm->rst = devm_reset_control_get_exclusive(dev, NULL);
|
||||
+ if (IS_ERR(pwm->rst))
|
||||
+ return dev_err_probe(dev, PTR_ERR(pwm->rst),
|
||||
+ "Unable to get pwm reset\n");
|
||||
+
|
||||
+ ret = clk_prepare_enable(pwm->clk);
|
||||
+ if (ret) {
|
||||
+ dev_err(dev,
|
||||
+ "Failed to enable pwm clock, %d\n", ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ reset_control_deassert(pwm->rst);
|
||||
+
|
||||
+ pwm->approx_freq = (unsigned int)clk_get_rate(pwm->clk);
|
||||
+ if (!pwm->approx_freq)
|
||||
+ dev_err(dev, "get pwm apb clock rate failed.\n");
|
||||
+
|
||||
+ ret = devm_pwmchip_add(dev, chip);
|
||||
+ if (ret < 0) {
|
||||
+ dev_err(dev, "cannot register PTC: %d\n", ret);
|
||||
+ clk_disable_unprepare(pwm->clk);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ platform_set_drvdata(pdev, pwm);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int starfive_pwm_ptc_remove(struct platform_device *dev)
|
||||
+{
|
||||
+ struct starfive_pwm_ptc_device *pwm = platform_get_drvdata(dev);
|
||||
+ struct pwm_chip *chip = &pwm->chip;
|
||||
+
|
||||
+ pwmchip_remove(chip);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct of_device_id starfive_pwm_ptc_of_match[] = {
|
||||
+ { .compatible = "starfive,jh7110-pwm" },
|
||||
+ {},
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, starfive_pwm_ptc_of_match);
|
||||
+
|
||||
+static struct platform_driver starfive_pwm_ptc_driver = {
|
||||
+ .probe = starfive_pwm_ptc_probe,
|
||||
+ .remove = starfive_pwm_ptc_remove,
|
||||
+ .driver = {
|
||||
+ .name = "pwm-starfive-ptc",
|
||||
+ .of_match_table = starfive_pwm_ptc_of_match,
|
||||
+ },
|
||||
+};
|
||||
+module_platform_driver(starfive_pwm_ptc_driver);
|
||||
+
|
||||
+MODULE_AUTHOR("Jenny Zhang <jenny.zhang@starfivetech.com>");
|
||||
+MODULE_AUTHOR("Hal Feng <hal.feng@starfivetech.com>");
|
||||
+MODULE_DESCRIPTION("StarFive PWM PTC driver");
|
||||
+MODULE_LICENSE("GPL");
|
@ -0,0 +1,90 @@
|
||||
From 207dde3ed123613cd84c8f706a24d75cefece67c Mon Sep 17 00:00:00 2001
|
||||
From: Jia Jie Ho <jiajie.ho@starfivetech.com>
|
||||
Date: Mon, 15 May 2023 20:53:52 +0800
|
||||
Subject: [PATCH 064/122] dt-bindings: crypto: Add StarFive crypto module
|
||||
|
||||
Add documentation to describe StarFive cryptographic engine.
|
||||
|
||||
Co-developed-by: Huan Feng <huan.feng@starfivetech.com>
|
||||
Signed-off-by: Huan Feng <huan.feng@starfivetech.com>
|
||||
Signed-off-by: Jia Jie Ho <jiajie.ho@starfivetech.com>
|
||||
Reviewed-by: Rob Herring <robh@kernel.org>
|
||||
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
|
||||
---
|
||||
.../crypto/starfive,jh7110-crypto.yaml | 70 +++++++++++++++++++
|
||||
1 file changed, 70 insertions(+)
|
||||
create mode 100644 Documentation/devicetree/bindings/crypto/starfive,jh7110-crypto.yaml
|
||||
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/crypto/starfive,jh7110-crypto.yaml
|
||||
@@ -0,0 +1,70 @@
|
||||
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
+%YAML 1.2
|
||||
+---
|
||||
+$id: http://devicetree.org/schemas/crypto/starfive,jh7110-crypto.yaml#
|
||||
+$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
+
|
||||
+title: StarFive Cryptographic Module
|
||||
+
|
||||
+maintainers:
|
||||
+ - Jia Jie Ho <jiajie.ho@starfivetech.com>
|
||||
+ - William Qiu <william.qiu@starfivetech.com>
|
||||
+
|
||||
+properties:
|
||||
+ compatible:
|
||||
+ const: starfive,jh7110-crypto
|
||||
+
|
||||
+ reg:
|
||||
+ maxItems: 1
|
||||
+
|
||||
+ clocks:
|
||||
+ items:
|
||||
+ - description: Hardware reference clock
|
||||
+ - description: AHB reference clock
|
||||
+
|
||||
+ clock-names:
|
||||
+ items:
|
||||
+ - const: hclk
|
||||
+ - const: ahb
|
||||
+
|
||||
+ interrupts:
|
||||
+ maxItems: 1
|
||||
+
|
||||
+ resets:
|
||||
+ maxItems: 1
|
||||
+
|
||||
+ dmas:
|
||||
+ items:
|
||||
+ - description: TX DMA channel
|
||||
+ - description: RX DMA channel
|
||||
+
|
||||
+ dma-names:
|
||||
+ items:
|
||||
+ - const: tx
|
||||
+ - const: rx
|
||||
+
|
||||
+required:
|
||||
+ - compatible
|
||||
+ - reg
|
||||
+ - clocks
|
||||
+ - clock-names
|
||||
+ - resets
|
||||
+ - dmas
|
||||
+ - dma-names
|
||||
+
|
||||
+additionalProperties: false
|
||||
+
|
||||
+examples:
|
||||
+ - |
|
||||
+ crypto: crypto@16000000 {
|
||||
+ compatible = "starfive,jh7110-crypto";
|
||||
+ reg = <0x16000000 0x4000>;
|
||||
+ clocks = <&clk 15>, <&clk 16>;
|
||||
+ clock-names = "hclk", "ahb";
|
||||
+ interrupts = <28>;
|
||||
+ resets = <&reset 3>;
|
||||
+ dmas = <&dma 1 2>,
|
||||
+ <&dma 0 2>;
|
||||
+ dma-names = "tx", "rx";
|
||||
+ };
|
||||
+...
|
@ -0,0 +1,337 @@
|
||||
From 8b1069fcc1dbb524556d851f3dedf0629a71f17b Mon Sep 17 00:00:00 2001
|
||||
From: Jia Jie Ho <jiajie.ho@starfivetech.com>
|
||||
Date: Mon, 15 May 2023 20:53:53 +0800
|
||||
Subject: [PATCH 065/122] crypto: starfive - Add crypto engine support
|
||||
|
||||
Adding device probe and DMA init for StarFive cryptographic module.
|
||||
|
||||
Co-developed-by: Huan Feng <huan.feng@starfivetech.com>
|
||||
Signed-off-by: Huan Feng <huan.feng@starfivetech.com>
|
||||
Signed-off-by: Jia Jie Ho <jiajie.ho@starfivetech.com>
|
||||
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
|
||||
---
|
||||
drivers/crypto/Kconfig | 1 +
|
||||
drivers/crypto/Makefile | 1 +
|
||||
drivers/crypto/starfive/Kconfig | 17 +++
|
||||
drivers/crypto/starfive/Makefile | 4 +
|
||||
drivers/crypto/starfive/jh7110-cryp.c | 201 ++++++++++++++++++++++++++
|
||||
drivers/crypto/starfive/jh7110-cryp.h | 63 ++++++++
|
||||
6 files changed, 287 insertions(+)
|
||||
create mode 100644 drivers/crypto/starfive/Kconfig
|
||||
create mode 100644 drivers/crypto/starfive/Makefile
|
||||
create mode 100644 drivers/crypto/starfive/jh7110-cryp.c
|
||||
create mode 100644 drivers/crypto/starfive/jh7110-cryp.h
|
||||
|
||||
--- a/drivers/crypto/Kconfig
|
||||
+++ b/drivers/crypto/Kconfig
|
||||
@@ -823,5 +823,6 @@ config CRYPTO_DEV_SA2UL
|
||||
|
||||
source "drivers/crypto/keembay/Kconfig"
|
||||
source "drivers/crypto/aspeed/Kconfig"
|
||||
+source "drivers/crypto/starfive/Kconfig"
|
||||
|
||||
endif # CRYPTO_HW
|
||||
--- a/drivers/crypto/Makefile
|
||||
+++ b/drivers/crypto/Makefile
|
||||
@@ -53,3 +53,4 @@ obj-y += xilinx/
|
||||
obj-y += hisilicon/
|
||||
obj-$(CONFIG_CRYPTO_DEV_AMLOGIC_GXL) += amlogic/
|
||||
obj-y += keembay/
|
||||
+obj-y += starfive/
|
||||
--- /dev/null
|
||||
+++ b/drivers/crypto/starfive/Kconfig
|
||||
@@ -0,0 +1,17 @@
|
||||
+#
|
||||
+# StarFive crypto drivers configuration
|
||||
+#
|
||||
+
|
||||
+config CRYPTO_DEV_JH7110
|
||||
+ tristate "StarFive JH7110 cryptographic engine driver"
|
||||
+ depends on SOC_STARFIVE || COMPILE_TEST
|
||||
+ select CRYPTO_ENGINE
|
||||
+ select ARM_AMBA
|
||||
+ select DMADEVICES
|
||||
+ select AMBA_PL08X
|
||||
+ help
|
||||
+ Support for StarFive JH7110 crypto hardware acceleration engine.
|
||||
+ This module provides acceleration for public key algo,
|
||||
+ skciphers, AEAD and hash functions.
|
||||
+
|
||||
+ If you choose 'M' here, this module will be called jh7110-crypto.
|
||||
--- /dev/null
|
||||
+++ b/drivers/crypto/starfive/Makefile
|
||||
@@ -0,0 +1,4 @@
|
||||
+# SPDX-License-Identifier: GPL-2.0
|
||||
+
|
||||
+obj-$(CONFIG_CRYPTO_DEV_JH7110) += jh7110-crypto.o
|
||||
+jh7110-crypto-objs := jh7110-cryp.o
|
||||
--- /dev/null
|
||||
+++ b/drivers/crypto/starfive/jh7110-cryp.c
|
||||
@@ -0,0 +1,201 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0
|
||||
+/*
|
||||
+ * Cryptographic API.
|
||||
+ *
|
||||
+ * Support for StarFive hardware cryptographic engine.
|
||||
+ * Copyright (c) 2022 StarFive Technology
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#include <linux/clk.h>
|
||||
+#include <linux/delay.h>
|
||||
+#include <linux/interrupt.h>
|
||||
+#include <linux/iopoll.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/of_device.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/pm_runtime.h>
|
||||
+#include <linux/reset.h>
|
||||
+
|
||||
+#include "jh7110-cryp.h"
|
||||
+
|
||||
+#define DRIVER_NAME "jh7110-crypto"
|
||||
+
|
||||
+struct starfive_dev_list {
|
||||
+ struct list_head dev_list;
|
||||
+ spinlock_t lock; /* protect dev_list */
|
||||
+};
|
||||
+
|
||||
+static struct starfive_dev_list dev_list = {
|
||||
+ .dev_list = LIST_HEAD_INIT(dev_list.dev_list),
|
||||
+ .lock = __SPIN_LOCK_UNLOCKED(dev_list.lock),
|
||||
+};
|
||||
+
|
||||
+struct starfive_cryp_dev *starfive_cryp_find_dev(struct starfive_cryp_ctx *ctx)
|
||||
+{
|
||||
+ struct starfive_cryp_dev *cryp = NULL, *tmp;
|
||||
+
|
||||
+ spin_lock_bh(&dev_list.lock);
|
||||
+ if (!ctx->cryp) {
|
||||
+ list_for_each_entry(tmp, &dev_list.dev_list, list) {
|
||||
+ cryp = tmp;
|
||||
+ break;
|
||||
+ }
|
||||
+ ctx->cryp = cryp;
|
||||
+ } else {
|
||||
+ cryp = ctx->cryp;
|
||||
+ }
|
||||
+
|
||||
+ spin_unlock_bh(&dev_list.lock);
|
||||
+
|
||||
+ return cryp;
|
||||
+}
|
||||
+
|
||||
+static int starfive_dma_init(struct starfive_cryp_dev *cryp)
|
||||
+{
|
||||
+ dma_cap_mask_t mask;
|
||||
+
|
||||
+ dma_cap_zero(mask);
|
||||
+ dma_cap_set(DMA_SLAVE, mask);
|
||||
+
|
||||
+ cryp->tx = dma_request_chan(cryp->dev, "tx");
|
||||
+ if (IS_ERR(cryp->tx))
|
||||
+ return dev_err_probe(cryp->dev, PTR_ERR(cryp->tx),
|
||||
+ "Error requesting tx dma channel.\n");
|
||||
+
|
||||
+ cryp->rx = dma_request_chan(cryp->dev, "rx");
|
||||
+ if (IS_ERR(cryp->rx)) {
|
||||
+ dma_release_channel(cryp->tx);
|
||||
+ return dev_err_probe(cryp->dev, PTR_ERR(cryp->rx),
|
||||
+ "Error requesting rx dma channel.\n");
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void starfive_dma_cleanup(struct starfive_cryp_dev *cryp)
|
||||
+{
|
||||
+ dma_release_channel(cryp->tx);
|
||||
+ dma_release_channel(cryp->rx);
|
||||
+}
|
||||
+
|
||||
+static int starfive_cryp_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct starfive_cryp_dev *cryp;
|
||||
+ struct resource *res;
|
||||
+ int ret;
|
||||
+
|
||||
+ cryp = devm_kzalloc(&pdev->dev, sizeof(*cryp), GFP_KERNEL);
|
||||
+ if (!cryp)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ platform_set_drvdata(pdev, cryp);
|
||||
+ cryp->dev = &pdev->dev;
|
||||
+
|
||||
+ cryp->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
|
||||
+ if (IS_ERR(cryp->base))
|
||||
+ return dev_err_probe(&pdev->dev, PTR_ERR(cryp->base),
|
||||
+ "Error remapping memory for platform device\n");
|
||||
+
|
||||
+ cryp->phys_base = res->start;
|
||||
+ cryp->dma_maxburst = 32;
|
||||
+
|
||||
+ cryp->hclk = devm_clk_get(&pdev->dev, "hclk");
|
||||
+ if (IS_ERR(cryp->hclk))
|
||||
+ return dev_err_probe(&pdev->dev, PTR_ERR(cryp->hclk),
|
||||
+ "Error getting hardware reference clock\n");
|
||||
+
|
||||
+ cryp->ahb = devm_clk_get(&pdev->dev, "ahb");
|
||||
+ if (IS_ERR(cryp->ahb))
|
||||
+ return dev_err_probe(&pdev->dev, PTR_ERR(cryp->ahb),
|
||||
+ "Error getting ahb reference clock\n");
|
||||
+
|
||||
+ cryp->rst = devm_reset_control_get_shared(cryp->dev, NULL);
|
||||
+ if (IS_ERR(cryp->rst))
|
||||
+ return dev_err_probe(&pdev->dev, PTR_ERR(cryp->rst),
|
||||
+ "Error getting hardware reset line\n");
|
||||
+
|
||||
+ clk_prepare_enable(cryp->hclk);
|
||||
+ clk_prepare_enable(cryp->ahb);
|
||||
+ reset_control_deassert(cryp->rst);
|
||||
+
|
||||
+ spin_lock(&dev_list.lock);
|
||||
+ list_add(&cryp->list, &dev_list.dev_list);
|
||||
+ spin_unlock(&dev_list.lock);
|
||||
+
|
||||
+ ret = starfive_dma_init(cryp);
|
||||
+ if (ret) {
|
||||
+ if (ret == -EPROBE_DEFER)
|
||||
+ goto err_probe_defer;
|
||||
+ else
|
||||
+ goto err_dma_init;
|
||||
+ }
|
||||
+
|
||||
+ /* Initialize crypto engine */
|
||||
+ cryp->engine = crypto_engine_alloc_init(&pdev->dev, 1);
|
||||
+ if (!cryp->engine) {
|
||||
+ ret = -ENOMEM;
|
||||
+ goto err_engine;
|
||||
+ }
|
||||
+
|
||||
+ ret = crypto_engine_start(cryp->engine);
|
||||
+ if (ret)
|
||||
+ goto err_engine_start;
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+err_engine_start:
|
||||
+ crypto_engine_exit(cryp->engine);
|
||||
+err_engine:
|
||||
+ starfive_dma_cleanup(cryp);
|
||||
+err_dma_init:
|
||||
+ spin_lock(&dev_list.lock);
|
||||
+ list_del(&cryp->list);
|
||||
+ spin_unlock(&dev_list.lock);
|
||||
+
|
||||
+ clk_disable_unprepare(cryp->hclk);
|
||||
+ clk_disable_unprepare(cryp->ahb);
|
||||
+ reset_control_assert(cryp->rst);
|
||||
+err_probe_defer:
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int starfive_cryp_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct starfive_cryp_dev *cryp = platform_get_drvdata(pdev);
|
||||
+
|
||||
+ crypto_engine_stop(cryp->engine);
|
||||
+ crypto_engine_exit(cryp->engine);
|
||||
+
|
||||
+ starfive_dma_cleanup(cryp);
|
||||
+
|
||||
+ spin_lock(&dev_list.lock);
|
||||
+ list_del(&cryp->list);
|
||||
+ spin_unlock(&dev_list.lock);
|
||||
+
|
||||
+ clk_disable_unprepare(cryp->hclk);
|
||||
+ clk_disable_unprepare(cryp->ahb);
|
||||
+ reset_control_assert(cryp->rst);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct of_device_id starfive_dt_ids[] __maybe_unused = {
|
||||
+ { .compatible = "starfive,jh7110-crypto", .data = NULL},
|
||||
+ {},
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, starfive_dt_ids);
|
||||
+
|
||||
+static struct platform_driver starfive_cryp_driver = {
|
||||
+ .probe = starfive_cryp_probe,
|
||||
+ .remove = starfive_cryp_remove,
|
||||
+ .driver = {
|
||||
+ .name = DRIVER_NAME,
|
||||
+ .of_match_table = starfive_dt_ids,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+module_platform_driver(starfive_cryp_driver);
|
||||
+
|
||||
+MODULE_LICENSE("GPL");
|
||||
+MODULE_DESCRIPTION("StarFive JH7110 Cryptographic Module");
|
||||
--- /dev/null
|
||||
+++ b/drivers/crypto/starfive/jh7110-cryp.h
|
||||
@@ -0,0 +1,63 @@
|
||||
+/* SPDX-License-Identifier: GPL-2.0 */
|
||||
+#ifndef __STARFIVE_STR_H__
|
||||
+#define __STARFIVE_STR_H__
|
||||
+
|
||||
+#include <linux/delay.h>
|
||||
+#include <linux/dma-mapping.h>
|
||||
+#include <linux/dmaengine.h>
|
||||
+
|
||||
+#include <crypto/engine.h>
|
||||
+
|
||||
+#define STARFIVE_ALG_CR_OFFSET 0x0
|
||||
+#define STARFIVE_ALG_FIFO_OFFSET 0x4
|
||||
+#define STARFIVE_IE_MASK_OFFSET 0x8
|
||||
+#define STARFIVE_IE_FLAG_OFFSET 0xc
|
||||
+#define STARFIVE_DMA_IN_LEN_OFFSET 0x10
|
||||
+#define STARFIVE_DMA_OUT_LEN_OFFSET 0x14
|
||||
+
|
||||
+#define STARFIVE_MSG_BUFFER_SIZE SZ_16K
|
||||
+
|
||||
+union starfive_alg_cr {
|
||||
+ u32 v;
|
||||
+ struct {
|
||||
+ u32 start :1;
|
||||
+ u32 aes_dma_en :1;
|
||||
+ u32 rsvd_0 :1;
|
||||
+ u32 hash_dma_en :1;
|
||||
+ u32 alg_done :1;
|
||||
+ u32 rsvd_1 :3;
|
||||
+ u32 clear :1;
|
||||
+ u32 rsvd_2 :23;
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+struct starfive_cryp_ctx {
|
||||
+ struct crypto_engine_ctx enginectx;
|
||||
+ struct starfive_cryp_dev *cryp;
|
||||
+};
|
||||
+
|
||||
+struct starfive_cryp_dev {
|
||||
+ struct list_head list;
|
||||
+ struct device *dev;
|
||||
+
|
||||
+ struct clk *hclk;
|
||||
+ struct clk *ahb;
|
||||
+ struct reset_control *rst;
|
||||
+
|
||||
+ void __iomem *base;
|
||||
+ phys_addr_t phys_base;
|
||||
+
|
||||
+ u32 dma_maxburst;
|
||||
+ struct dma_chan *tx;
|
||||
+ struct dma_chan *rx;
|
||||
+ struct dma_slave_config cfg_in;
|
||||
+ struct dma_slave_config cfg_out;
|
||||
+
|
||||
+ struct crypto_engine *engine;
|
||||
+
|
||||
+ union starfive_alg_cr alg_cr;
|
||||
+};
|
||||
+
|
||||
+struct starfive_cryp_dev *starfive_cryp_find_dev(struct starfive_cryp_ctx *ctx);
|
||||
+
|
||||
+#endif
|
@ -0,0 +1,29 @@
|
||||
From 0d3ee821ed469a787e8007de2d87e98a2370e087 Mon Sep 17 00:00:00 2001
|
||||
From: Jia Jie Ho <jiajie.ho@starfivetech.com>
|
||||
Date: Fri, 19 May 2023 21:42:33 +0800
|
||||
Subject: [PATCH 066/122] crypto: starfive - Fix driver dependencies
|
||||
|
||||
Kconfig updated to depend on DMADEVICES instead of selecting it.
|
||||
|
||||
Reported-by: kernel test robot <lkp@intel.com>
|
||||
Link: https://lore.kernel.org/oe-kbuild-all/202305191929.Eq4OVZ6D-lkp@intel.com/
|
||||
Signed-off-by: Jia Jie Ho <jiajie.ho@starfivetech.com>
|
||||
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
|
||||
---
|
||||
drivers/crypto/starfive/Kconfig | 3 +--
|
||||
1 file changed, 1 insertion(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/crypto/starfive/Kconfig
|
||||
+++ b/drivers/crypto/starfive/Kconfig
|
||||
@@ -4,10 +4,9 @@
|
||||
|
||||
config CRYPTO_DEV_JH7110
|
||||
tristate "StarFive JH7110 cryptographic engine driver"
|
||||
- depends on SOC_STARFIVE || COMPILE_TEST
|
||||
+ depends on (SOC_STARFIVE || COMPILE_TEST) && DMADEVICES
|
||||
select CRYPTO_ENGINE
|
||||
select ARM_AMBA
|
||||
- select DMADEVICES
|
||||
select AMBA_PL08X
|
||||
help
|
||||
Support for StarFive JH7110 crypto hardware acceleration engine.
|
@ -0,0 +1,23 @@
|
||||
From e8d070e2eb856856055566d3515072a8346446f3 Mon Sep 17 00:00:00 2001
|
||||
From: "shanlong.li" <shanlong.li@starfivetech.com>
|
||||
Date: Wed, 31 May 2023 01:37:41 -0700
|
||||
Subject: [PATCH 067/122] riscv: Kconfig: Add select ARM_AMBA to SOC_STARFIVE
|
||||
|
||||
Selects ARM_AMBA platform support for StarFive SoCs required by spi and
|
||||
crypto dma engine.
|
||||
|
||||
Signed-off-by: shanlong.li <shanlong.li@starfivetech.com>
|
||||
---
|
||||
arch/riscv/Kconfig.socs | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
--- a/arch/riscv/Kconfig.socs
|
||||
+++ b/arch/riscv/Kconfig.socs
|
||||
@@ -4,6 +4,7 @@ config SOC_MICROCHIP_POLARFIRE
|
||||
bool "Microchip PolarFire SoCs"
|
||||
select MCHP_CLK_MPFS
|
||||
select SIFIVE_PLIC
|
||||
+ select ARM_AMBA
|
||||
help
|
||||
This enables support for Microchip PolarFire SoC platforms.
|
||||
|
@ -0,0 +1,117 @@
|
||||
From 3b90e0fb53c31c50e64d2039e30ec25c1d8a8d5c Mon Sep 17 00:00:00 2001
|
||||
From: Walker Chen <walker.chen@starfivetech.com>
|
||||
Date: Fri, 26 May 2023 22:54:00 +0800
|
||||
Subject: [PATCH 068/122] ASoC: dt-bindings: Add TDM controller bindings for
|
||||
StarFive JH7110
|
||||
|
||||
Add bindings for TDM driver which supports multi-channel audio playback
|
||||
and capture on JH7110 platform.
|
||||
|
||||
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
|
||||
Signed-off-by: Walker Chen <walker.chen@starfivetech.com>
|
||||
---
|
||||
.../bindings/sound/starfive,jh7110-tdm.yaml | 98 +++++++++++++++++++
|
||||
1 file changed, 98 insertions(+)
|
||||
create mode 100644 Documentation/devicetree/bindings/sound/starfive,jh7110-tdm.yaml
|
||||
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/sound/starfive,jh7110-tdm.yaml
|
||||
@@ -0,0 +1,98 @@
|
||||
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
+%YAML 1.2
|
||||
+---
|
||||
+$id: http://devicetree.org/schemas/sound/starfive,jh7110-tdm.yaml#
|
||||
+$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
+
|
||||
+title: StarFive JH7110 TDM Controller
|
||||
+
|
||||
+description: |
|
||||
+ The TDM Controller is a Time Division Multiplexed audio interface
|
||||
+ integrated in StarFive JH7110 SoC, allowing up to 8 channels of
|
||||
+ audio over a serial interface. The TDM controller can operate both
|
||||
+ in master and slave mode.
|
||||
+
|
||||
+maintainers:
|
||||
+ - Walker Chen <walker.chen@starfivetech.com>
|
||||
+
|
||||
+allOf:
|
||||
+ - $ref: dai-common.yaml#
|
||||
+
|
||||
+properties:
|
||||
+ compatible:
|
||||
+ enum:
|
||||
+ - starfive,jh7110-tdm
|
||||
+
|
||||
+ reg:
|
||||
+ maxItems: 1
|
||||
+
|
||||
+ clocks:
|
||||
+ items:
|
||||
+ - description: TDM AHB Clock
|
||||
+ - description: TDM APB Clock
|
||||
+ - description: TDM Internal Clock
|
||||
+ - description: TDM Clock
|
||||
+ - description: Inner MCLK
|
||||
+ - description: TDM External Clock
|
||||
+
|
||||
+ clock-names:
|
||||
+ items:
|
||||
+ - const: tdm_ahb
|
||||
+ - const: tdm_apb
|
||||
+ - const: tdm_internal
|
||||
+ - const: tdm
|
||||
+ - const: mclk_inner
|
||||
+ - const: tdm_ext
|
||||
+
|
||||
+ resets:
|
||||
+ items:
|
||||
+ - description: tdm ahb reset line
|
||||
+ - description: tdm apb reset line
|
||||
+ - description: tdm core reset line
|
||||
+
|
||||
+ dmas:
|
||||
+ items:
|
||||
+ - description: RX DMA Channel
|
||||
+ - description: TX DMA Channel
|
||||
+
|
||||
+ dma-names:
|
||||
+ items:
|
||||
+ - const: rx
|
||||
+ - const: tx
|
||||
+
|
||||
+ "#sound-dai-cells":
|
||||
+ const: 0
|
||||
+
|
||||
+required:
|
||||
+ - compatible
|
||||
+ - reg
|
||||
+ - clocks
|
||||
+ - clock-names
|
||||
+ - resets
|
||||
+ - dmas
|
||||
+ - dma-names
|
||||
+ - "#sound-dai-cells"
|
||||
+
|
||||
+additionalProperties: false
|
||||
+
|
||||
+examples:
|
||||
+ - |
|
||||
+ tdm@10090000 {
|
||||
+ compatible = "starfive,jh7110-tdm";
|
||||
+ reg = <0x10090000 0x1000>;
|
||||
+ clocks = <&syscrg 184>,
|
||||
+ <&syscrg 185>,
|
||||
+ <&syscrg 186>,
|
||||
+ <&syscrg 187>,
|
||||
+ <&syscrg 17>,
|
||||
+ <&tdm_ext>;
|
||||
+ clock-names = "tdm_ahb", "tdm_apb",
|
||||
+ "tdm_internal", "tdm",
|
||||
+ "mclk_inner", "tdm_ext";
|
||||
+ resets = <&syscrg 105>,
|
||||
+ <&syscrg 107>,
|
||||
+ <&syscrg 106>;
|
||||
+ dmas = <&dma 20>, <&dma 21>;
|
||||
+ dma-names = "rx","tx";
|
||||
+ #sound-dai-cells = <0>;
|
||||
+ };
|
@ -0,0 +1,744 @@
|
||||
From 9d90936b0f69d891001a11d3f6c0c3728d8b6d85 Mon Sep 17 00:00:00 2001
|
||||
From: Walker Chen <walker.chen@starfivetech.com>
|
||||
Date: Fri, 26 May 2023 22:54:01 +0800
|
||||
Subject: [PATCH 069/122] ASoC: starfive: Add JH7110 TDM driver
|
||||
|
||||
Add tdm driver support for the StarFive JH7110 SoC.
|
||||
|
||||
Signed-off-by: Walker Chen <walker.chen@starfivetech.com>
|
||||
---
|
||||
sound/soc/Kconfig | 1 +
|
||||
sound/soc/Makefile | 1 +
|
||||
sound/soc/starfive/Kconfig | 15 +
|
||||
sound/soc/starfive/Makefile | 2 +
|
||||
sound/soc/starfive/jh7110_tdm.c | 679 ++++++++++++++++++++++++++++++++
|
||||
5 files changed, 698 insertions(+)
|
||||
create mode 100644 sound/soc/starfive/Kconfig
|
||||
create mode 100644 sound/soc/starfive/Makefile
|
||||
create mode 100644 sound/soc/starfive/jh7110_tdm.c
|
||||
|
||||
--- a/sound/soc/Kconfig
|
||||
+++ b/sound/soc/Kconfig
|
||||
@@ -91,6 +91,7 @@ source "sound/soc/sh/Kconfig"
|
||||
source "sound/soc/sof/Kconfig"
|
||||
source "sound/soc/spear/Kconfig"
|
||||
source "sound/soc/sprd/Kconfig"
|
||||
+source "sound/soc/starfive/Kconfig"
|
||||
source "sound/soc/sti/Kconfig"
|
||||
source "sound/soc/stm/Kconfig"
|
||||
source "sound/soc/sunxi/Kconfig"
|
||||
--- a/sound/soc/Makefile
|
||||
+++ b/sound/soc/Makefile
|
||||
@@ -59,6 +59,7 @@ obj-$(CONFIG_SND_SOC) += sh/
|
||||
obj-$(CONFIG_SND_SOC) += sof/
|
||||
obj-$(CONFIG_SND_SOC) += spear/
|
||||
obj-$(CONFIG_SND_SOC) += sprd/
|
||||
+obj-$(CONFIG_SND_SOC) += starfive/
|
||||
obj-$(CONFIG_SND_SOC) += sti/
|
||||
obj-$(CONFIG_SND_SOC) += stm/
|
||||
obj-$(CONFIG_SND_SOC) += sunxi/
|
||||
--- /dev/null
|
||||
+++ b/sound/soc/starfive/Kconfig
|
||||
@@ -0,0 +1,15 @@
|
||||
+# SPDX-License-Identifier: GPL-2.0-only
|
||||
+config SND_SOC_STARFIVE
|
||||
+ tristate "Audio support for StarFive SoC"
|
||||
+ depends on COMPILE_TEST || ARCH_STARFIVE
|
||||
+ help
|
||||
+ Say Y or M if you want to add support for codecs attached to
|
||||
+ the Starfive SoCs' Audio interfaces. You will also need to
|
||||
+ select the audio interfaces to support below.
|
||||
+
|
||||
+config SND_SOC_JH7110_TDM
|
||||
+ tristate "JH7110 TDM device driver"
|
||||
+ depends on HAVE_CLK && SND_SOC_STARFIVE
|
||||
+ select SND_SOC_GENERIC_DMAENGINE_PCM
|
||||
+ help
|
||||
+ Say Y or M if you want to add support for StarFive TDM driver.
|
||||
--- /dev/null
|
||||
+++ b/sound/soc/starfive/Makefile
|
||||
@@ -0,0 +1,2 @@
|
||||
+# StarFive Platform Support
|
||||
+obj-$(CONFIG_SND_SOC_JH7110_TDM) += jh7110_tdm.o
|
||||
--- /dev/null
|
||||
+++ b/sound/soc/starfive/jh7110_tdm.c
|
||||
@@ -0,0 +1,679 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0
|
||||
+/*
|
||||
+ * jh7110_tdm.c -- StarFive JH7110 TDM driver
|
||||
+ *
|
||||
+ * Copyright (C) 2023 StarFive Technology Co., Ltd.
|
||||
+ *
|
||||
+ * Author: Walker Chen <walker.chen@starfivetech.com>
|
||||
+ */
|
||||
+
|
||||
+#include <linux/clk.h>
|
||||
+#include <linux/device.h>
|
||||
+#include <linux/dmaengine.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/of_irq.h>
|
||||
+#include <linux/of_platform.h>
|
||||
+#include <linux/pm_runtime.h>
|
||||
+#include <linux/regmap.h>
|
||||
+#include <linux/reset.h>
|
||||
+#include <linux/types.h>
|
||||
+#include <sound/dmaengine_pcm.h>
|
||||
+#include <sound/initval.h>
|
||||
+#include <sound/pcm.h>
|
||||
+#include <sound/pcm_params.h>
|
||||
+#include <sound/soc.h>
|
||||
+#include <sound/soc-dai.h>
|
||||
+
|
||||
+#define TDM_PCMGBCR 0x00
|
||||
+ #define PCMGBCR_MASK 0x1e
|
||||
+ #define PCMGBCR_ENABLE BIT(0)
|
||||
+ #define PCMGBCR_TRITXEN BIT(4)
|
||||
+ #define CLKPOL_BIT 5
|
||||
+ #define TRITXEN_BIT 4
|
||||
+ #define ELM_BIT 3
|
||||
+ #define SYNCM_BIT 2
|
||||
+ #define MS_BIT 1
|
||||
+#define TDM_PCMTXCR 0x04
|
||||
+ #define PCMTXCR_TXEN BIT(0)
|
||||
+ #define IFL_BIT 11
|
||||
+ #define WL_BIT 8
|
||||
+ #define SSCALE_BIT 4
|
||||
+ #define SL_BIT 2
|
||||
+ #define LRJ_BIT 1
|
||||
+#define TDM_PCMRXCR 0x08
|
||||
+ #define PCMRXCR_RXEN BIT(0)
|
||||
+ #define PCMRXCR_RXSL_MASK 0xc
|
||||
+ #define PCMRXCR_RXSL_16BIT 0x4
|
||||
+ #define PCMRXCR_RXSL_32BIT 0x8
|
||||
+ #define PCMRXCR_SCALE_MASK 0xf0
|
||||
+ #define PCMRXCR_SCALE_1CH 0x10
|
||||
+#define TDM_PCMDIV 0x0c
|
||||
+
|
||||
+#define JH7110_TDM_FIFO 0x170c0000
|
||||
+#define JH7110_TDM_FIFO_DEPTH 32
|
||||
+
|
||||
+enum TDM_MASTER_SLAVE_MODE {
|
||||
+ TDM_AS_MASTER = 0,
|
||||
+ TDM_AS_SLAVE,
|
||||
+};
|
||||
+
|
||||
+enum TDM_CLKPOL {
|
||||
+ /* tx raising and rx falling */
|
||||
+ TDM_TX_RASING_RX_FALLING = 0,
|
||||
+ /* tx falling and rx raising */
|
||||
+ TDM_TX_FALLING_RX_RASING,
|
||||
+};
|
||||
+
|
||||
+enum TDM_ELM {
|
||||
+ /* only work while SYNCM=0 */
|
||||
+ TDM_ELM_LATE = 0,
|
||||
+ TDM_ELM_EARLY,
|
||||
+};
|
||||
+
|
||||
+enum TDM_SYNCM {
|
||||
+ /* short frame sync */
|
||||
+ TDM_SYNCM_SHORT = 0,
|
||||
+ /* long frame sync */
|
||||
+ TDM_SYNCM_LONG,
|
||||
+};
|
||||
+
|
||||
+enum TDM_IFL {
|
||||
+ /* FIFO to send or received : half-1/2, Quarter-1/4 */
|
||||
+ TDM_FIFO_HALF = 0,
|
||||
+ TDM_FIFO_QUARTER,
|
||||
+};
|
||||
+
|
||||
+enum TDM_WL {
|
||||
+ /* send or received word length */
|
||||
+ TDM_8BIT_WORD_LEN = 0,
|
||||
+ TDM_16BIT_WORD_LEN,
|
||||
+ TDM_20BIT_WORD_LEN,
|
||||
+ TDM_24BIT_WORD_LEN,
|
||||
+ TDM_32BIT_WORD_LEN,
|
||||
+};
|
||||
+
|
||||
+enum TDM_SL {
|
||||
+ /* send or received slot length */
|
||||
+ TDM_8BIT_SLOT_LEN = 0,
|
||||
+ TDM_16BIT_SLOT_LEN,
|
||||
+ TDM_32BIT_SLOT_LEN,
|
||||
+};
|
||||
+
|
||||
+enum TDM_LRJ {
|
||||
+ /* left-justify or right-justify */
|
||||
+ TDM_RIGHT_JUSTIFY = 0,
|
||||
+ TDM_LEFT_JUSTIFT,
|
||||
+};
|
||||
+
|
||||
+struct tdm_chan_cfg {
|
||||
+ enum TDM_IFL ifl;
|
||||
+ enum TDM_WL wl;
|
||||
+ unsigned char sscale;
|
||||
+ enum TDM_SL sl;
|
||||
+ enum TDM_LRJ lrj;
|
||||
+ unsigned char enable;
|
||||
+};
|
||||
+
|
||||
+struct jh7110_tdm_dev {
|
||||
+ void __iomem *tdm_base;
|
||||
+ struct device *dev;
|
||||
+ struct clk_bulk_data clks[6];
|
||||
+ struct reset_control *resets;
|
||||
+
|
||||
+ enum TDM_CLKPOL clkpolity;
|
||||
+ enum TDM_ELM elm;
|
||||
+ enum TDM_SYNCM syncm;
|
||||
+ enum TDM_MASTER_SLAVE_MODE ms_mode;
|
||||
+
|
||||
+ struct tdm_chan_cfg tx;
|
||||
+ struct tdm_chan_cfg rx;
|
||||
+
|
||||
+ u16 syncdiv;
|
||||
+ u32 samplerate;
|
||||
+ u32 pcmclk;
|
||||
+
|
||||
+ /* data related to DMA transfers b/w tdm and DMAC */
|
||||
+ struct snd_dmaengine_dai_dma_data play_dma_data;
|
||||
+ struct snd_dmaengine_dai_dma_data capture_dma_data;
|
||||
+ u32 saved_pcmgbcr;
|
||||
+ u32 saved_pcmtxcr;
|
||||
+ u32 saved_pcmrxcr;
|
||||
+ u32 saved_pcmdiv;
|
||||
+};
|
||||
+
|
||||
+static inline u32 jh7110_tdm_readl(struct jh7110_tdm_dev *tdm, u16 reg)
|
||||
+{
|
||||
+ return readl_relaxed(tdm->tdm_base + reg);
|
||||
+}
|
||||
+
|
||||
+static inline void jh7110_tdm_writel(struct jh7110_tdm_dev *tdm, u16 reg, u32 val)
|
||||
+{
|
||||
+ writel_relaxed(val, tdm->tdm_base + reg);
|
||||
+}
|
||||
+
|
||||
+static void jh7110_tdm_save_context(struct jh7110_tdm_dev *tdm,
|
||||
+ struct snd_pcm_substream *substream)
|
||||
+{
|
||||
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
||||
+ tdm->saved_pcmtxcr = jh7110_tdm_readl(tdm, TDM_PCMTXCR);
|
||||
+ else
|
||||
+ tdm->saved_pcmrxcr = jh7110_tdm_readl(tdm, TDM_PCMRXCR);
|
||||
+}
|
||||
+
|
||||
+static void jh7110_tdm_start(struct jh7110_tdm_dev *tdm,
|
||||
+ struct snd_pcm_substream *substream)
|
||||
+{
|
||||
+ u32 data;
|
||||
+
|
||||
+ data = jh7110_tdm_readl(tdm, TDM_PCMGBCR);
|
||||
+ jh7110_tdm_writel(tdm, TDM_PCMGBCR, data | PCMGBCR_ENABLE);
|
||||
+
|
||||
+ /* restore context */
|
||||
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
||||
+ jh7110_tdm_writel(tdm, TDM_PCMTXCR, tdm->saved_pcmtxcr | PCMTXCR_TXEN);
|
||||
+ else
|
||||
+ jh7110_tdm_writel(tdm, TDM_PCMRXCR, tdm->saved_pcmrxcr | PCMRXCR_RXEN);
|
||||
+}
|
||||
+
|
||||
+static void jh7110_tdm_stop(struct jh7110_tdm_dev *tdm,
|
||||
+ struct snd_pcm_substream *substream)
|
||||
+{
|
||||
+ unsigned int val;
|
||||
+
|
||||
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
||||
+ val = jh7110_tdm_readl(tdm, TDM_PCMTXCR);
|
||||
+ val &= ~PCMTXCR_TXEN;
|
||||
+ jh7110_tdm_writel(tdm, TDM_PCMTXCR, val);
|
||||
+ } else {
|
||||
+ val = jh7110_tdm_readl(tdm, TDM_PCMRXCR);
|
||||
+ val &= ~PCMRXCR_RXEN;
|
||||
+ jh7110_tdm_writel(tdm, TDM_PCMRXCR, val);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int jh7110_tdm_syncdiv(struct jh7110_tdm_dev *tdm)
|
||||
+{
|
||||
+ u32 sl, sscale, syncdiv;
|
||||
+
|
||||
+ if (tdm->rx.sl >= tdm->tx.sl)
|
||||
+ sl = tdm->rx.sl;
|
||||
+ else
|
||||
+ sl = tdm->tx.sl;
|
||||
+
|
||||
+ if (tdm->rx.sscale >= tdm->tx.sscale)
|
||||
+ sscale = tdm->rx.sscale;
|
||||
+ else
|
||||
+ sscale = tdm->tx.sscale;
|
||||
+
|
||||
+ syncdiv = tdm->pcmclk / tdm->samplerate - 1;
|
||||
+
|
||||
+ if ((syncdiv + 1) < (sl * sscale)) {
|
||||
+ dev_err(tdm->dev, "Failed to set syncdiv!\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ if (tdm->syncm == TDM_SYNCM_LONG &&
|
||||
+ (tdm->rx.sscale <= 1 || tdm->tx.sscale <= 1) &&
|
||||
+ ((syncdiv + 1) <= sl)) {
|
||||
+ dev_err(tdm->dev, "Wrong syncdiv! It must be (syncdiv+1) > max[tx.sl, rx.sl]\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ jh7110_tdm_writel(tdm, TDM_PCMDIV, syncdiv);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int jh7110_tdm_config(struct jh7110_tdm_dev *tdm,
|
||||
+ struct snd_pcm_substream *substream)
|
||||
+{
|
||||
+ u32 datarx, datatx;
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = jh7110_tdm_syncdiv(tdm);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ datarx = (tdm->rx.ifl << IFL_BIT) |
|
||||
+ (tdm->rx.wl << WL_BIT) |
|
||||
+ (tdm->rx.sscale << SSCALE_BIT) |
|
||||
+ (tdm->rx.sl << SL_BIT) |
|
||||
+ (tdm->rx.lrj << LRJ_BIT);
|
||||
+
|
||||
+ datatx = (tdm->tx.ifl << IFL_BIT) |
|
||||
+ (tdm->tx.wl << WL_BIT) |
|
||||
+ (tdm->tx.sscale << SSCALE_BIT) |
|
||||
+ (tdm->tx.sl << SL_BIT) |
|
||||
+ (tdm->tx.lrj << LRJ_BIT);
|
||||
+
|
||||
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
||||
+ jh7110_tdm_writel(tdm, TDM_PCMTXCR, datatx);
|
||||
+ else
|
||||
+ jh7110_tdm_writel(tdm, TDM_PCMRXCR, datarx);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void jh7110_tdm_clk_disable(struct jh7110_tdm_dev *tdm)
|
||||
+{
|
||||
+ clk_bulk_disable_unprepare(ARRAY_SIZE(tdm->clks), tdm->clks);
|
||||
+}
|
||||
+
|
||||
+static int jh7110_tdm_clk_enable(struct jh7110_tdm_dev *tdm)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = clk_bulk_prepare_enable(ARRAY_SIZE(tdm->clks), tdm->clks);
|
||||
+ if (ret) {
|
||||
+ dev_err(tdm->dev, "Failed to enable tdm clocks\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ ret = reset_control_deassert(tdm->resets);
|
||||
+ if (ret) {
|
||||
+ dev_err(tdm->dev, "Failed to deassert tdm resets\n");
|
||||
+ goto dis_tdm_clk;
|
||||
+ }
|
||||
+
|
||||
+ /* select tdm_ext clock as the clock source for tdm */
|
||||
+ ret = clk_set_parent(tdm->clks[5].clk, tdm->clks[4].clk);
|
||||
+ if (ret) {
|
||||
+ dev_err(tdm->dev, "Can't set extern clock source for clk_tdm\n");
|
||||
+ goto dis_tdm_clk;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+dis_tdm_clk:
|
||||
+ clk_bulk_disable_unprepare(ARRAY_SIZE(tdm->clks), tdm->clks);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int jh7110_tdm_runtime_suspend(struct device *dev)
|
||||
+{
|
||||
+ struct jh7110_tdm_dev *tdm = dev_get_drvdata(dev);
|
||||
+
|
||||
+ jh7110_tdm_clk_disable(tdm);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int jh7110_tdm_runtime_resume(struct device *dev)
|
||||
+{
|
||||
+ struct jh7110_tdm_dev *tdm = dev_get_drvdata(dev);
|
||||
+
|
||||
+ return jh7110_tdm_clk_enable(tdm);
|
||||
+}
|
||||
+
|
||||
+static int jh7110_tdm_system_suspend(struct device *dev)
|
||||
+{
|
||||
+ struct jh7110_tdm_dev *tdm = dev_get_drvdata(dev);
|
||||
+
|
||||
+ /* save context */
|
||||
+ tdm->saved_pcmgbcr = jh7110_tdm_readl(tdm, TDM_PCMGBCR);
|
||||
+ tdm->saved_pcmdiv = jh7110_tdm_readl(tdm, TDM_PCMDIV);
|
||||
+
|
||||
+ return pm_runtime_force_suspend(dev);
|
||||
+}
|
||||
+
|
||||
+static int jh7110_tdm_system_resume(struct device *dev)
|
||||
+{
|
||||
+ struct jh7110_tdm_dev *tdm = dev_get_drvdata(dev);
|
||||
+
|
||||
+ /* restore context */
|
||||
+ jh7110_tdm_writel(tdm, TDM_PCMGBCR, tdm->saved_pcmgbcr);
|
||||
+ jh7110_tdm_writel(tdm, TDM_PCMDIV, tdm->saved_pcmdiv);
|
||||
+
|
||||
+ return pm_runtime_force_resume(dev);
|
||||
+}
|
||||
+
|
||||
+static const struct snd_soc_component_driver jh7110_tdm_component = {
|
||||
+ .name = "jh7110-tdm",
|
||||
+};
|
||||
+
|
||||
+static int jh7110_tdm_startup(struct snd_pcm_substream *substream,
|
||||
+ struct snd_soc_dai *cpu_dai)
|
||||
+{
|
||||
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
|
||||
+ struct snd_soc_dai_link *dai_link = rtd->dai_link;
|
||||
+
|
||||
+ dai_link->stop_dma_first = 1;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int jh7110_tdm_hw_params(struct snd_pcm_substream *substream,
|
||||
+ struct snd_pcm_hw_params *params,
|
||||
+ struct snd_soc_dai *dai)
|
||||
+{
|
||||
+ struct jh7110_tdm_dev *tdm = snd_soc_dai_get_drvdata(dai);
|
||||
+ int chan_wl, chan_sl, chan_nr;
|
||||
+ unsigned int data_width;
|
||||
+ unsigned int dma_bus_width;
|
||||
+ struct snd_dmaengine_dai_dma_data *dma_data = NULL;
|
||||
+ int ret;
|
||||
+
|
||||
+ data_width = params_width(params);
|
||||
+
|
||||
+ tdm->samplerate = params_rate(params);
|
||||
+ tdm->pcmclk = params_channels(params) * tdm->samplerate * data_width;
|
||||
+
|
||||
+ switch (params_format(params)) {
|
||||
+ case SNDRV_PCM_FORMAT_S16_LE:
|
||||
+ chan_wl = TDM_16BIT_WORD_LEN;
|
||||
+ chan_sl = TDM_16BIT_SLOT_LEN;
|
||||
+ dma_bus_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
|
||||
+ break;
|
||||
+
|
||||
+ case SNDRV_PCM_FORMAT_S32_LE:
|
||||
+ chan_wl = TDM_32BIT_WORD_LEN;
|
||||
+ chan_sl = TDM_32BIT_SLOT_LEN;
|
||||
+ dma_bus_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ dev_err(tdm->dev, "tdm: unsupported PCM fmt");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ chan_nr = params_channels(params);
|
||||
+ switch (chan_nr) {
|
||||
+ case 1:
|
||||
+ case 2:
|
||||
+ case 4:
|
||||
+ case 6:
|
||||
+ case 8:
|
||||
+ break;
|
||||
+ default:
|
||||
+ dev_err(tdm->dev, "channel not supported\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
||||
+ tdm->tx.wl = chan_wl;
|
||||
+ tdm->tx.sl = chan_sl;
|
||||
+ tdm->tx.sscale = chan_nr;
|
||||
+ tdm->play_dma_data.addr_width = dma_bus_width;
|
||||
+ dma_data = &tdm->play_dma_data;
|
||||
+ } else {
|
||||
+ tdm->rx.wl = chan_wl;
|
||||
+ tdm->rx.sl = chan_sl;
|
||||
+ tdm->rx.sscale = chan_nr;
|
||||
+ tdm->capture_dma_data.addr_width = dma_bus_width;
|
||||
+ dma_data = &tdm->capture_dma_data;
|
||||
+ }
|
||||
+
|
||||
+ snd_soc_dai_set_dma_data(dai, substream, dma_data);
|
||||
+
|
||||
+ ret = jh7110_tdm_config(tdm, substream);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ jh7110_tdm_save_context(tdm, substream);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int jh7110_tdm_trigger(struct snd_pcm_substream *substream,
|
||||
+ int cmd, struct snd_soc_dai *dai)
|
||||
+{
|
||||
+ struct jh7110_tdm_dev *tdm = snd_soc_dai_get_drvdata(dai);
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ switch (cmd) {
|
||||
+ case SNDRV_PCM_TRIGGER_START:
|
||||
+ case SNDRV_PCM_TRIGGER_RESUME:
|
||||
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
|
||||
+ jh7110_tdm_start(tdm, substream);
|
||||
+ break;
|
||||
+
|
||||
+ case SNDRV_PCM_TRIGGER_STOP:
|
||||
+ case SNDRV_PCM_TRIGGER_SUSPEND:
|
||||
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
|
||||
+ jh7110_tdm_stop(tdm, substream);
|
||||
+ break;
|
||||
+ default:
|
||||
+ ret = -EINVAL;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int jh7110_tdm_set_dai_fmt(struct snd_soc_dai *cpu_dai,
|
||||
+ unsigned int fmt)
|
||||
+{
|
||||
+ struct jh7110_tdm_dev *tdm = snd_soc_dai_get_drvdata(cpu_dai);
|
||||
+ unsigned int gbcr;
|
||||
+
|
||||
+ /* set master/slave audio interface */
|
||||
+ switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
|
||||
+ case SND_SOC_DAIFMT_BP_FP:
|
||||
+ /* cpu is master */
|
||||
+ tdm->ms_mode = TDM_AS_MASTER;
|
||||
+ break;
|
||||
+ case SND_SOC_DAIFMT_BC_FC:
|
||||
+ /* codec is master */
|
||||
+ tdm->ms_mode = TDM_AS_SLAVE;
|
||||
+ break;
|
||||
+ case SND_SOC_DAIFMT_BC_FP:
|
||||
+ case SND_SOC_DAIFMT_BP_FC:
|
||||
+ return -EINVAL;
|
||||
+ default:
|
||||
+ dev_dbg(tdm->dev, "dwc : Invalid clock provider format\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ gbcr = (tdm->clkpolity << CLKPOL_BIT) |
|
||||
+ (tdm->elm << ELM_BIT) |
|
||||
+ (tdm->syncm << SYNCM_BIT) |
|
||||
+ (tdm->ms_mode << MS_BIT);
|
||||
+ jh7110_tdm_writel(tdm, TDM_PCMGBCR, gbcr);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct snd_soc_dai_ops jh7110_tdm_dai_ops = {
|
||||
+ .startup = jh7110_tdm_startup,
|
||||
+ .hw_params = jh7110_tdm_hw_params,
|
||||
+ .trigger = jh7110_tdm_trigger,
|
||||
+ .set_fmt = jh7110_tdm_set_dai_fmt,
|
||||
+};
|
||||
+
|
||||
+static int jh7110_tdm_dai_probe(struct snd_soc_dai *dai)
|
||||
+{
|
||||
+ struct jh7110_tdm_dev *tdm = snd_soc_dai_get_drvdata(dai);
|
||||
+
|
||||
+ snd_soc_dai_init_dma_data(dai, &tdm->play_dma_data, &tdm->capture_dma_data);
|
||||
+ snd_soc_dai_set_drvdata(dai, tdm);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#define JH7110_TDM_RATES SNDRV_PCM_RATE_8000_48000
|
||||
+
|
||||
+#define JH7110_TDM_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
|
||||
+ SNDRV_PCM_FMTBIT_S32_LE)
|
||||
+
|
||||
+static struct snd_soc_dai_driver jh7110_tdm_dai = {
|
||||
+ .name = "sf_tdm",
|
||||
+ .id = 0,
|
||||
+ .playback = {
|
||||
+ .stream_name = "Playback",
|
||||
+ .channels_min = 1,
|
||||
+ .channels_max = 8,
|
||||
+ .rates = JH7110_TDM_RATES,
|
||||
+ .formats = JH7110_TDM_FORMATS,
|
||||
+ },
|
||||
+ .capture = {
|
||||
+ .stream_name = "Capture",
|
||||
+ .channels_min = 1,
|
||||
+ .channels_max = 8,
|
||||
+ .rates = JH7110_TDM_RATES,
|
||||
+ .formats = JH7110_TDM_FORMATS,
|
||||
+ },
|
||||
+ .ops = &jh7110_tdm_dai_ops,
|
||||
+ .probe = jh7110_tdm_dai_probe,
|
||||
+ .symmetric_rate = 1,
|
||||
+};
|
||||
+
|
||||
+static const struct snd_pcm_hardware jh7110_pcm_hardware = {
|
||||
+ .info = (SNDRV_PCM_INFO_MMAP |
|
||||
+ SNDRV_PCM_INFO_MMAP_VALID |
|
||||
+ SNDRV_PCM_INFO_PAUSE |
|
||||
+ SNDRV_PCM_INFO_RESUME |
|
||||
+ SNDRV_PCM_INFO_INTERLEAVED |
|
||||
+ SNDRV_PCM_INFO_BLOCK_TRANSFER),
|
||||
+ .buffer_bytes_max = 192512,
|
||||
+ .period_bytes_min = 4096,
|
||||
+ .period_bytes_max = 32768,
|
||||
+ .periods_min = 1,
|
||||
+ .periods_max = 48,
|
||||
+ .fifo_size = 16,
|
||||
+};
|
||||
+
|
||||
+static const struct snd_dmaengine_pcm_config jh7110_dmaengine_pcm_config = {
|
||||
+ .pcm_hardware = &jh7110_pcm_hardware,
|
||||
+ .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config,
|
||||
+ .prealloc_buffer_size = 192512,
|
||||
+};
|
||||
+
|
||||
+static void jh7110_tdm_init_params(struct jh7110_tdm_dev *tdm)
|
||||
+{
|
||||
+ tdm->clkpolity = TDM_TX_RASING_RX_FALLING;
|
||||
+ tdm->elm = TDM_ELM_LATE;
|
||||
+ tdm->syncm = TDM_SYNCM_SHORT;
|
||||
+
|
||||
+ tdm->rx.ifl = TDM_FIFO_HALF;
|
||||
+ tdm->tx.ifl = TDM_FIFO_HALF;
|
||||
+ tdm->rx.wl = TDM_16BIT_WORD_LEN;
|
||||
+ tdm->tx.wl = TDM_16BIT_WORD_LEN;
|
||||
+ tdm->rx.sscale = 2;
|
||||
+ tdm->tx.sscale = 2;
|
||||
+ tdm->rx.lrj = TDM_LEFT_JUSTIFT;
|
||||
+ tdm->tx.lrj = TDM_LEFT_JUSTIFT;
|
||||
+
|
||||
+ tdm->play_dma_data.addr = JH7110_TDM_FIFO;
|
||||
+ tdm->play_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
|
||||
+ tdm->play_dma_data.fifo_size = JH7110_TDM_FIFO_DEPTH / 2;
|
||||
+ tdm->play_dma_data.maxburst = 16;
|
||||
+
|
||||
+ tdm->capture_dma_data.addr = JH7110_TDM_FIFO;
|
||||
+ tdm->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
|
||||
+ tdm->capture_dma_data.fifo_size = JH7110_TDM_FIFO_DEPTH / 2;
|
||||
+ tdm->capture_dma_data.maxburst = 8;
|
||||
+}
|
||||
+
|
||||
+static int jh7110_tdm_clk_reset_get(struct platform_device *pdev,
|
||||
+ struct jh7110_tdm_dev *tdm)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ tdm->clks[0].id = "mclk_inner";
|
||||
+ tdm->clks[1].id = "tdm_ahb";
|
||||
+ tdm->clks[2].id = "tdm_apb";
|
||||
+ tdm->clks[3].id = "tdm_internal";
|
||||
+ tdm->clks[4].id = "tdm_ext";
|
||||
+ tdm->clks[5].id = "tdm";
|
||||
+
|
||||
+ ret = devm_clk_bulk_get(&pdev->dev, ARRAY_SIZE(tdm->clks), tdm->clks);
|
||||
+ if (ret) {
|
||||
+ dev_err(&pdev->dev, "Failed to get tdm clocks\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ tdm->resets = devm_reset_control_array_get_exclusive(&pdev->dev);
|
||||
+ if (IS_ERR_OR_NULL(tdm->resets)) {
|
||||
+ ret = PTR_ERR(tdm->resets);
|
||||
+ dev_err(&pdev->dev, "Failed to get tdm resets");
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int jh7110_tdm_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct jh7110_tdm_dev *tdm;
|
||||
+ int ret;
|
||||
+
|
||||
+ tdm = devm_kzalloc(&pdev->dev, sizeof(*tdm), GFP_KERNEL);
|
||||
+ if (!tdm)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ tdm->tdm_base = devm_platform_ioremap_resource(pdev, 0);
|
||||
+ if (IS_ERR(tdm->tdm_base))
|
||||
+ return PTR_ERR(tdm->tdm_base);
|
||||
+
|
||||
+ tdm->dev = &pdev->dev;
|
||||
+
|
||||
+ ret = jh7110_tdm_clk_reset_get(pdev, tdm);
|
||||
+ if (ret) {
|
||||
+ dev_err(&pdev->dev, "Failed to enable audio-tdm clock\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ jh7110_tdm_init_params(tdm);
|
||||
+
|
||||
+ dev_set_drvdata(&pdev->dev, tdm);
|
||||
+ ret = devm_snd_soc_register_component(&pdev->dev, &jh7110_tdm_component,
|
||||
+ &jh7110_tdm_dai, 1);
|
||||
+ if (ret) {
|
||||
+ dev_err(&pdev->dev, "Failed to register dai\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ ret = devm_snd_dmaengine_pcm_register(&pdev->dev,
|
||||
+ &jh7110_dmaengine_pcm_config,
|
||||
+ SND_DMAENGINE_PCM_FLAG_COMPAT);
|
||||
+ if (ret) {
|
||||
+ dev_err(&pdev->dev, "Could not register pcm: %d\n", ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ pm_runtime_enable(&pdev->dev);
|
||||
+ if (!pm_runtime_enabled(&pdev->dev)) {
|
||||
+ ret = jh7110_tdm_runtime_resume(&pdev->dev);
|
||||
+ if (ret)
|
||||
+ goto err_pm_disable;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+err_pm_disable:
|
||||
+ pm_runtime_disable(&pdev->dev);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int jh7110_tdm_dev_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+ pm_runtime_disable(&pdev->dev);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct of_device_id jh7110_tdm_of_match[] = {
|
||||
+ { .compatible = "starfive,jh7110-tdm", },
|
||||
+ {}
|
||||
+};
|
||||
+
|
||||
+MODULE_DEVICE_TABLE(of, jh7110_tdm_of_match);
|
||||
+
|
||||
+static const struct dev_pm_ops jh7110_tdm_pm_ops = {
|
||||
+ RUNTIME_PM_OPS(jh7110_tdm_runtime_suspend,
|
||||
+ jh7110_tdm_runtime_resume, NULL)
|
||||
+ SYSTEM_SLEEP_PM_OPS(jh7110_tdm_system_suspend,
|
||||
+ jh7110_tdm_system_resume)
|
||||
+};
|
||||
+
|
||||
+static struct platform_driver jh7110_tdm_driver = {
|
||||
+ .driver = {
|
||||
+ .name = "jh7110-tdm",
|
||||
+ .of_match_table = jh7110_tdm_of_match,
|
||||
+ .pm = pm_ptr(&jh7110_tdm_pm_ops),
|
||||
+ },
|
||||
+ .probe = jh7110_tdm_probe,
|
||||
+ .remove = jh7110_tdm_dev_remove,
|
||||
+};
|
||||
+module_platform_driver(jh7110_tdm_driver);
|
||||
+
|
||||
+MODULE_DESCRIPTION("StarFive JH7110 TDM ASoC Driver");
|
||||
+MODULE_AUTHOR("Walker Chen <walker.chen@starfivetech.com>");
|
||||
+MODULE_LICENSE("GPL");
|
@ -0,0 +1,32 @@
|
||||
From 598083825494088f927fa42c5a7bb2872029a7bc Mon Sep 17 00:00:00 2001
|
||||
From: Changhuang Liang <changhuang.liang@starfivetech.com>
|
||||
Date: Thu, 18 May 2023 23:01:59 -0700
|
||||
Subject: [PATCH 070/122] dt-bindings: power: Add power-domain header for
|
||||
JH7110
|
||||
|
||||
Add power-domain header for JH7110 SoC, it can use to operate dphy
|
||||
power.
|
||||
|
||||
Signed-off-by: Changhuang Liang <changhuang.liang@starfivetech.com>
|
||||
---
|
||||
include/dt-bindings/power/starfive,jh7110-pmu.h | 5 ++++-
|
||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/include/dt-bindings/power/starfive,jh7110-pmu.h
|
||||
+++ b/include/dt-bindings/power/starfive,jh7110-pmu.h
|
||||
@@ -1,6 +1,6 @@
|
||||
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
|
||||
/*
|
||||
- * Copyright (C) 2022 StarFive Technology Co., Ltd.
|
||||
+ * Copyright (C) 2022-2023 StarFive Technology Co., Ltd.
|
||||
* Author: Walker Chen <walker.chen@starfivetech.com>
|
||||
*/
|
||||
#ifndef __DT_BINDINGS_POWER_JH7110_POWER_H__
|
||||
@@ -14,4 +14,7 @@
|
||||
#define JH7110_PD_ISP 5
|
||||
#define JH7110_PD_VENC 6
|
||||
|
||||
+#define JH7110_PD_DPHY_TX 0
|
||||
+#define JH7110_PD_DPHY_RX 1
|
||||
+
|
||||
#endif
|
@ -0,0 +1,28 @@
|
||||
From d83b51f60997365b80637f71924ab3dec91d5b77 Mon Sep 17 00:00:00 2001
|
||||
From: Changhuang Liang <changhuang.liang@starfivetech.com>
|
||||
Date: Thu, 18 May 2023 23:02:00 -0700
|
||||
Subject: [PATCH 071/122] soc: starfive: Replace SOC_STARFIVE with
|
||||
ARCH_STARFIVE
|
||||
|
||||
Using ARCH_FOO symbol is preferred than SOC_FOO.
|
||||
|
||||
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
|
||||
Reviewed-by: Walker Chen <walker.chen@starfivetech.com>
|
||||
Signed-off-by: Changhuang Liang <changhuang.liang@starfivetech.com>
|
||||
---
|
||||
drivers/soc/starfive/Kconfig | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/soc/starfive/Kconfig
|
||||
+++ b/drivers/soc/starfive/Kconfig
|
||||
@@ -3,8 +3,8 @@
|
||||
config JH71XX_PMU
|
||||
bool "Support PMU for StarFive JH71XX Soc"
|
||||
depends on PM
|
||||
- depends on SOC_STARFIVE || COMPILE_TEST
|
||||
- default SOC_STARFIVE
|
||||
+ depends on ARCH_STARFIVE || COMPILE_TEST
|
||||
+ default ARCH_STARFIVE
|
||||
select PM_GENERIC_DOMAINS
|
||||
help
|
||||
Say 'y' here to enable support power domain support.
|
@ -0,0 +1,175 @@
|
||||
From 52e2ade50f3ec212468e284b1236aaa521ba5913 Mon Sep 17 00:00:00 2001
|
||||
From: Changhuang Liang <changhuang.liang@starfivetech.com>
|
||||
Date: Thu, 18 May 2023 23:02:01 -0700
|
||||
Subject: [PATCH 072/122] soc: starfive: Extract JH7110 pmu private operations
|
||||
|
||||
Move JH7110 private operation into private data of compatible. Convenient
|
||||
to add AON PMU which would not have interrupts property.
|
||||
|
||||
Signed-off-by: Changhuang Liang <changhuang.liang@starfivetech.com>
|
||||
Reviewed-by: Walker Chen <walker.chen@starfivetech.com>
|
||||
---
|
||||
drivers/soc/starfive/jh71xx_pmu.c | 89 +++++++++++++++++++++----------
|
||||
1 file changed, 62 insertions(+), 27 deletions(-)
|
||||
|
||||
--- a/drivers/soc/starfive/jh71xx_pmu.c
|
||||
+++ b/drivers/soc/starfive/jh71xx_pmu.c
|
||||
@@ -51,9 +51,17 @@ struct jh71xx_domain_info {
|
||||
u8 bit;
|
||||
};
|
||||
|
||||
+struct jh71xx_pmu;
|
||||
+struct jh71xx_pmu_dev;
|
||||
+
|
||||
struct jh71xx_pmu_match_data {
|
||||
const struct jh71xx_domain_info *domain_info;
|
||||
int num_domains;
|
||||
+ unsigned int pmu_status;
|
||||
+ int (*pmu_parse_irq)(struct platform_device *pdev,
|
||||
+ struct jh71xx_pmu *pmu);
|
||||
+ int (*pmu_set_state)(struct jh71xx_pmu_dev *pmd,
|
||||
+ u32 mask, bool on);
|
||||
};
|
||||
|
||||
struct jh71xx_pmu {
|
||||
@@ -79,12 +87,12 @@ static int jh71xx_pmu_get_state(struct j
|
||||
if (!mask)
|
||||
return -EINVAL;
|
||||
|
||||
- *is_on = readl(pmu->base + JH71XX_PMU_CURR_POWER_MODE) & mask;
|
||||
+ *is_on = readl(pmu->base + pmu->match_data->pmu_status) & mask;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int jh71xx_pmu_set_state(struct jh71xx_pmu_dev *pmd, u32 mask, bool on)
|
||||
+static int jh7110_pmu_set_state(struct jh71xx_pmu_dev *pmd, u32 mask, bool on)
|
||||
{
|
||||
struct jh71xx_pmu *pmu = pmd->pmu;
|
||||
unsigned long flags;
|
||||
@@ -92,22 +100,8 @@ static int jh71xx_pmu_set_state(struct j
|
||||
u32 mode;
|
||||
u32 encourage_lo;
|
||||
u32 encourage_hi;
|
||||
- bool is_on;
|
||||
int ret;
|
||||
|
||||
- ret = jh71xx_pmu_get_state(pmd, mask, &is_on);
|
||||
- if (ret) {
|
||||
- dev_dbg(pmu->dev, "unable to get current state for %s\n",
|
||||
- pmd->genpd.name);
|
||||
- return ret;
|
||||
- }
|
||||
-
|
||||
- if (is_on == on) {
|
||||
- dev_dbg(pmu->dev, "pm domain [%s] is already %sable status.\n",
|
||||
- pmd->genpd.name, on ? "en" : "dis");
|
||||
- return 0;
|
||||
- }
|
||||
-
|
||||
spin_lock_irqsave(&pmu->lock, flags);
|
||||
|
||||
/*
|
||||
@@ -166,6 +160,29 @@ static int jh71xx_pmu_set_state(struct j
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int jh71xx_pmu_set_state(struct jh71xx_pmu_dev *pmd, u32 mask, bool on)
|
||||
+{
|
||||
+ struct jh71xx_pmu *pmu = pmd->pmu;
|
||||
+ const struct jh71xx_pmu_match_data *match_data = pmu->match_data;
|
||||
+ bool is_on;
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = jh71xx_pmu_get_state(pmd, mask, &is_on);
|
||||
+ if (ret) {
|
||||
+ dev_dbg(pmu->dev, "unable to get current state for %s\n",
|
||||
+ pmd->genpd.name);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ if (is_on == on) {
|
||||
+ dev_dbg(pmu->dev, "pm domain [%s] is already %sable status.\n",
|
||||
+ pmd->genpd.name, on ? "en" : "dis");
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ return match_data->pmu_set_state(pmd, mask, on);
|
||||
+}
|
||||
+
|
||||
static int jh71xx_pmu_on(struct generic_pm_domain *genpd)
|
||||
{
|
||||
struct jh71xx_pmu_dev *pmd = container_of(genpd,
|
||||
@@ -226,6 +243,25 @@ static irqreturn_t jh71xx_pmu_interrupt(
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
+static int jh7110_pmu_parse_irq(struct platform_device *pdev, struct jh71xx_pmu *pmu)
|
||||
+{
|
||||
+ struct device *dev = &pdev->dev;
|
||||
+ int ret;
|
||||
+
|
||||
+ pmu->irq = platform_get_irq(pdev, 0);
|
||||
+ if (pmu->irq < 0)
|
||||
+ return pmu->irq;
|
||||
+
|
||||
+ ret = devm_request_irq(dev, pmu->irq, jh71xx_pmu_interrupt,
|
||||
+ 0, pdev->name, pmu);
|
||||
+ if (ret)
|
||||
+ dev_err(dev, "failed to request irq\n");
|
||||
+
|
||||
+ jh71xx_pmu_int_enable(pmu, JH71XX_PMU_INT_ALL_MASK & ~JH71XX_PMU_INT_PCH_FAIL, true);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int jh71xx_pmu_init_domain(struct jh71xx_pmu *pmu, int index)
|
||||
{
|
||||
struct jh71xx_pmu_dev *pmd;
|
||||
@@ -275,19 +311,18 @@ static int jh71xx_pmu_probe(struct platf
|
||||
if (IS_ERR(pmu->base))
|
||||
return PTR_ERR(pmu->base);
|
||||
|
||||
- pmu->irq = platform_get_irq(pdev, 0);
|
||||
- if (pmu->irq < 0)
|
||||
- return pmu->irq;
|
||||
-
|
||||
- ret = devm_request_irq(dev, pmu->irq, jh71xx_pmu_interrupt,
|
||||
- 0, pdev->name, pmu);
|
||||
- if (ret)
|
||||
- dev_err(dev, "failed to request irq\n");
|
||||
+ spin_lock_init(&pmu->lock);
|
||||
|
||||
match_data = of_device_get_match_data(dev);
|
||||
if (!match_data)
|
||||
return -EINVAL;
|
||||
|
||||
+ ret = match_data->pmu_parse_irq(pdev, pmu);
|
||||
+ if (ret) {
|
||||
+ dev_err(dev, "failed to parse irq\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
pmu->genpd = devm_kcalloc(dev, match_data->num_domains,
|
||||
sizeof(struct generic_pm_domain *),
|
||||
GFP_KERNEL);
|
||||
@@ -307,9 +342,6 @@ static int jh71xx_pmu_probe(struct platf
|
||||
}
|
||||
}
|
||||
|
||||
- spin_lock_init(&pmu->lock);
|
||||
- jh71xx_pmu_int_enable(pmu, JH71XX_PMU_INT_ALL_MASK & ~JH71XX_PMU_INT_PCH_FAIL, true);
|
||||
-
|
||||
ret = of_genpd_add_provider_onecell(np, &pmu->genpd_data);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to register genpd driver: %d\n", ret);
|
||||
@@ -357,6 +389,9 @@ static const struct jh71xx_domain_info j
|
||||
static const struct jh71xx_pmu_match_data jh7110_pmu = {
|
||||
.num_domains = ARRAY_SIZE(jh7110_power_domains),
|
||||
.domain_info = jh7110_power_domains,
|
||||
+ .pmu_status = JH71XX_PMU_CURR_POWER_MODE,
|
||||
+ .pmu_parse_irq = jh7110_pmu_parse_irq,
|
||||
+ .pmu_set_state = jh7110_pmu_set_state,
|
||||
};
|
||||
|
||||
static const struct of_device_id jh71xx_pmu_of_match[] = {
|
@ -0,0 +1,119 @@
|
||||
From 3124d653318c50e20eadbb3998eafa5928ac9b63 Mon Sep 17 00:00:00 2001
|
||||
From: Changhuang Liang <changhuang.liang@starfivetech.com>
|
||||
Date: Thu, 18 May 2023 23:02:02 -0700
|
||||
Subject: [PATCH 073/122] soc: starfive: Add JH7110 AON PMU support
|
||||
|
||||
Add AON PMU for StarFive JH7110 SoC. It can be used to turn on/off the
|
||||
dphy rx/tx power switch.
|
||||
|
||||
Reviewed-by: Walker Chen <walker.chen@starfivetech.com>
|
||||
Signed-off-by: Changhuang Liang <changhuang.liang@starfivetech.com>
|
||||
---
|
||||
drivers/soc/starfive/jh71xx_pmu.c | 57 ++++++++++++++++++++++++++++---
|
||||
1 file changed, 52 insertions(+), 5 deletions(-)
|
||||
|
||||
--- a/drivers/soc/starfive/jh71xx_pmu.c
|
||||
+++ b/drivers/soc/starfive/jh71xx_pmu.c
|
||||
@@ -2,7 +2,7 @@
|
||||
/*
|
||||
* StarFive JH71XX PMU (Power Management Unit) Controller Driver
|
||||
*
|
||||
- * Copyright (C) 2022 StarFive Technology Co., Ltd.
|
||||
+ * Copyright (C) 2022-2023 StarFive Technology Co., Ltd.
|
||||
*/
|
||||
|
||||
#include <linux/interrupt.h>
|
||||
@@ -24,6 +24,9 @@
|
||||
#define JH71XX_PMU_EVENT_STATUS 0x88
|
||||
#define JH71XX_PMU_INT_STATUS 0x8C
|
||||
|
||||
+/* aon pmu register offset */
|
||||
+#define JH71XX_AON_PMU_SWITCH 0x00
|
||||
+
|
||||
/* sw encourage cfg */
|
||||
#define JH71XX_PMU_SW_ENCOURAGE_EN_LO 0x05
|
||||
#define JH71XX_PMU_SW_ENCOURAGE_EN_HI 0x50
|
||||
@@ -160,6 +163,26 @@ static int jh7110_pmu_set_state(struct j
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int jh7110_aon_pmu_set_state(struct jh71xx_pmu_dev *pmd, u32 mask, bool on)
|
||||
+{
|
||||
+ struct jh71xx_pmu *pmu = pmd->pmu;
|
||||
+ unsigned long flags;
|
||||
+ u32 val;
|
||||
+
|
||||
+ spin_lock_irqsave(&pmu->lock, flags);
|
||||
+ val = readl(pmu->base + JH71XX_AON_PMU_SWITCH);
|
||||
+
|
||||
+ if (on)
|
||||
+ val |= mask;
|
||||
+ else
|
||||
+ val &= ~mask;
|
||||
+
|
||||
+ writel(val, pmu->base + JH71XX_AON_PMU_SWITCH);
|
||||
+ spin_unlock_irqrestore(&pmu->lock, flags);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int jh71xx_pmu_set_state(struct jh71xx_pmu_dev *pmd, u32 mask, bool on)
|
||||
{
|
||||
struct jh71xx_pmu *pmu = pmd->pmu;
|
||||
@@ -317,10 +340,12 @@ static int jh71xx_pmu_probe(struct platf
|
||||
if (!match_data)
|
||||
return -EINVAL;
|
||||
|
||||
- ret = match_data->pmu_parse_irq(pdev, pmu);
|
||||
- if (ret) {
|
||||
- dev_err(dev, "failed to parse irq\n");
|
||||
- return ret;
|
||||
+ if (match_data->pmu_parse_irq) {
|
||||
+ ret = match_data->pmu_parse_irq(pdev, pmu);
|
||||
+ if (ret) {
|
||||
+ dev_err(dev, "failed to parse irq\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
}
|
||||
|
||||
pmu->genpd = devm_kcalloc(dev, match_data->num_domains,
|
||||
@@ -394,11 +419,32 @@ static const struct jh71xx_pmu_match_dat
|
||||
.pmu_set_state = jh7110_pmu_set_state,
|
||||
};
|
||||
|
||||
+static const struct jh71xx_domain_info jh7110_aon_power_domains[] = {
|
||||
+ [JH7110_PD_DPHY_TX] = {
|
||||
+ .name = "DPHY-TX",
|
||||
+ .bit = 30,
|
||||
+ },
|
||||
+ [JH7110_PD_DPHY_RX] = {
|
||||
+ .name = "DPHY-RX",
|
||||
+ .bit = 31,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static const struct jh71xx_pmu_match_data jh7110_aon_pmu = {
|
||||
+ .num_domains = ARRAY_SIZE(jh7110_aon_power_domains),
|
||||
+ .domain_info = jh7110_aon_power_domains,
|
||||
+ .pmu_status = JH71XX_AON_PMU_SWITCH,
|
||||
+ .pmu_set_state = jh7110_aon_pmu_set_state,
|
||||
+};
|
||||
+
|
||||
static const struct of_device_id jh71xx_pmu_of_match[] = {
|
||||
{
|
||||
.compatible = "starfive,jh7110-pmu",
|
||||
.data = (void *)&jh7110_pmu,
|
||||
}, {
|
||||
+ .compatible = "starfive,jh7110-aon-syscon",
|
||||
+ .data = (void *)&jh7110_aon_pmu,
|
||||
+ }, {
|
||||
/* sentinel */
|
||||
}
|
||||
};
|
||||
@@ -414,5 +460,6 @@ static struct platform_driver jh71xx_pmu
|
||||
builtin_platform_driver(jh71xx_pmu_driver);
|
||||
|
||||
MODULE_AUTHOR("Walker Chen <walker.chen@starfivetech.com>");
|
||||
+MODULE_AUTHOR("Changhuang Liang <changhuang.liang@starfivetech.com>");
|
||||
MODULE_DESCRIPTION("StarFive JH71XX PMU Driver");
|
||||
MODULE_LICENSE("GPL");
|
@ -0,0 +1,88 @@
|
||||
From 7492ebbdd926da258f9abea5c41a9f8c4ec48631 Mon Sep 17 00:00:00 2001
|
||||
From: Changhuang Liang <changhuang.liang@starfivetech.com>
|
||||
Date: Mon, 29 May 2023 05:15:01 -0700
|
||||
Subject: [PATCH 074/122] dt-bindings: phy: Add starfive,jh7110-dphy-rx
|
||||
|
||||
StarFive SoCs like the jh7110 use a MIPI D-PHY RX controller based on
|
||||
a M31 IP. Add a binding for it.
|
||||
|
||||
Signed-off-by: Changhuang Liang <changhuang.liang@starfivetech.com>
|
||||
---
|
||||
.../bindings/phy/starfive,jh7110-dphy-rx.yaml | 71 +++++++++++++++++++
|
||||
1 file changed, 71 insertions(+)
|
||||
create mode 100644 Documentation/devicetree/bindings/phy/starfive,jh7110-dphy-rx.yaml
|
||||
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/phy/starfive,jh7110-dphy-rx.yaml
|
||||
@@ -0,0 +1,71 @@
|
||||
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
+%YAML 1.2
|
||||
+---
|
||||
+$id: http://devicetree.org/schemas/phy/starfive,jh7110-dphy-rx.yaml#
|
||||
+$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
+
|
||||
+title: StarFive SoC MIPI D-PHY Rx Controller
|
||||
+
|
||||
+maintainers:
|
||||
+ - Jack Zhu <jack.zhu@starfivetech.com>
|
||||
+ - Changhuang Liang <changhuang.liang@starfivetech.com>
|
||||
+
|
||||
+description:
|
||||
+ The StarFive SoC uses the MIPI CSI D-PHY based on M31 IP to transfer
|
||||
+ CSI camera data.
|
||||
+
|
||||
+properties:
|
||||
+ compatible:
|
||||
+ const: starfive,jh7110-dphy-rx
|
||||
+
|
||||
+ reg:
|
||||
+ maxItems: 1
|
||||
+
|
||||
+ clocks:
|
||||
+ items:
|
||||
+ - description: config clock
|
||||
+ - description: reference clock
|
||||
+ - description: escape mode transmit clock
|
||||
+
|
||||
+ clock-names:
|
||||
+ items:
|
||||
+ - const: cfg
|
||||
+ - const: ref
|
||||
+ - const: tx
|
||||
+
|
||||
+ resets:
|
||||
+ items:
|
||||
+ - description: DPHY_HW reset
|
||||
+ - description: DPHY_B09_ALWAYS_ON reset
|
||||
+
|
||||
+ power-domains:
|
||||
+ maxItems: 1
|
||||
+
|
||||
+ "#phy-cells":
|
||||
+ const: 0
|
||||
+
|
||||
+required:
|
||||
+ - compatible
|
||||
+ - reg
|
||||
+ - clocks
|
||||
+ - clock-names
|
||||
+ - resets
|
||||
+ - power-domains
|
||||
+ - "#phy-cells"
|
||||
+
|
||||
+additionalProperties: false
|
||||
+
|
||||
+examples:
|
||||
+ - |
|
||||
+ phy@19820000 {
|
||||
+ compatible = "starfive,jh7110-dphy-rx";
|
||||
+ reg = <0x19820000 0x10000>;
|
||||
+ clocks = <&ispcrg 3>,
|
||||
+ <&ispcrg 4>,
|
||||
+ <&ispcrg 5>;
|
||||
+ clock-names = "cfg", "ref", "tx";
|
||||
+ resets = <&ispcrg 2>,
|
||||
+ <&ispcrg 3>;
|
||||
+ power-domains = <&dphy_pwrc 1>;
|
||||
+ #phy-cells = <0>;
|
||||
+ };
|
@ -0,0 +1,365 @@
|
||||
From f6fbb431f9e3ac5c9144edf05340db9a96dffa59 Mon Sep 17 00:00:00 2001
|
||||
From: Changhuang Liang <changhuang.liang@starfivetech.com>
|
||||
Date: Mon, 29 May 2023 05:15:02 -0700
|
||||
Subject: [PATCH 075/122] phy: starfive: Add mipi dphy rx support
|
||||
|
||||
Add mipi dphy rx support for the StarFive JH7110 SoC. It is used to
|
||||
transfer CSI camera data.
|
||||
|
||||
Signed-off-by: Changhuang Liang <changhuang.liang@starfivetech.com>
|
||||
---
|
||||
drivers/phy/Kconfig | 1 +
|
||||
drivers/phy/Makefile | 1 +
|
||||
drivers/phy/starfive/Kconfig | 13 +
|
||||
drivers/phy/starfive/Makefile | 2 +
|
||||
drivers/phy/starfive/phy-starfive-dphy-rx.c | 301 ++++++++++++++++++++
|
||||
5 files changed, 318 insertions(+)
|
||||
create mode 100644 drivers/phy/starfive/Kconfig
|
||||
create mode 100644 drivers/phy/starfive/Makefile
|
||||
create mode 100644 drivers/phy/starfive/phy-starfive-dphy-rx.c
|
||||
|
||||
--- a/drivers/phy/Kconfig
|
||||
+++ b/drivers/phy/Kconfig
|
||||
@@ -91,6 +91,7 @@ source "drivers/phy/rockchip/Kconfig"
|
||||
source "drivers/phy/samsung/Kconfig"
|
||||
source "drivers/phy/socionext/Kconfig"
|
||||
source "drivers/phy/st/Kconfig"
|
||||
+source "drivers/phy/starfive/Kconfig"
|
||||
source "drivers/phy/sunplus/Kconfig"
|
||||
source "drivers/phy/tegra/Kconfig"
|
||||
source "drivers/phy/ti/Kconfig"
|
||||
--- a/drivers/phy/Makefile
|
||||
+++ b/drivers/phy/Makefile
|
||||
@@ -31,6 +31,7 @@ obj-y += allwinner/ \
|
||||
samsung/ \
|
||||
socionext/ \
|
||||
st/ \
|
||||
+ starfive/ \
|
||||
sunplus/ \
|
||||
tegra/ \
|
||||
ti/ \
|
||||
--- /dev/null
|
||||
+++ b/drivers/phy/starfive/Kconfig
|
||||
@@ -0,0 +1,13 @@
|
||||
+# SPDX-License-Identifier: GPL-2.0-only
|
||||
+#
|
||||
+# Phy drivers for StarFive platforms
|
||||
+#
|
||||
+
|
||||
+config PHY_STARFIVE_DPHY_RX
|
||||
+ tristate "StarFive D-PHY RX Support"
|
||||
+ select GENERIC_PHY
|
||||
+ select GENERIC_PHY_MIPI_DPHY
|
||||
+ help
|
||||
+ Choose this option if you have a StarFive D-PHY in your
|
||||
+ system. If M is selected, the module will be called
|
||||
+ phy-starfive-dphy-rx.
|
||||
--- /dev/null
|
||||
+++ b/drivers/phy/starfive/Makefile
|
||||
@@ -0,0 +1,2 @@
|
||||
+# SPDX-License-Identifier: GPL-2.0
|
||||
+obj-$(CONFIG_PHY_STARFIVE_DPHY_RX) += phy-starfive-dphy-rx.o
|
||||
--- /dev/null
|
||||
+++ b/drivers/phy/starfive/phy-starfive-dphy-rx.c
|
||||
@@ -0,0 +1,301 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0+
|
||||
+/*
|
||||
+ * DPHY driver for the StarFive JH7110 SoC
|
||||
+ *
|
||||
+ * Copyright (C) 2023 StarFive Technology Co., Ltd.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/bitfield.h>
|
||||
+#include <linux/bitops.h>
|
||||
+#include <linux/clk.h>
|
||||
+#include <linux/io.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/of.h>
|
||||
+#include <linux/of_device.h>
|
||||
+#include <linux/phy/phy.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/pm_runtime.h>
|
||||
+#include <linux/reset.h>
|
||||
+
|
||||
+#define STF_DPHY_APBCFGSAIF_SYSCFG(x) (x)
|
||||
+
|
||||
+#define STF_DPHY_DA_CDPHY_R100_CTRL0_2D1C_EFUSE_EN BIT(6)
|
||||
+#define STF_DPHY_DA_CDPHY_R100_CTRL0_2D1C_EFUSE_IN GENMASK(12, 7)
|
||||
+#define STF_DPHY_DA_CDPHY_R100_CTRL1_2D1C_EFUSE_EN BIT(19)
|
||||
+#define STF_DPHY_DA_CDPHY_R100_CTRL1_2D1C_EFUSE_IN GENMASK(25, 20)
|
||||
+
|
||||
+#define STF_DPHY_DATA_BUS16_8 BIT(8)
|
||||
+#define STF_DPHY_DEBUG_MODE_SEL GENMASK(15, 9)
|
||||
+
|
||||
+#define STF_DPHY_ENABLE_CLK BIT(6)
|
||||
+#define STF_DPHY_ENABLE_CLK1 BIT(7)
|
||||
+#define STF_DPHY_ENABLE_LAN0 BIT(8)
|
||||
+#define STF_DPHY_ENABLE_LAN1 BIT(9)
|
||||
+#define STF_DPHY_ENABLE_LAN2 BIT(10)
|
||||
+#define STF_DPHY_ENABLE_LAN3 BIT(11)
|
||||
+#define STF_DPHY_GPI_EN GENMASK(17, 12)
|
||||
+#define STF_DPHY_HS_FREQ_CHANGE_CLK BIT(18)
|
||||
+#define STF_DPHY_HS_FREQ_CHANGE_CLK1 BIT(19)
|
||||
+#define STF_DPHY_LANE_SWAP_CLK GENMASK(22, 20)
|
||||
+#define STF_DPHY_LANE_SWAP_CLK1 GENMASK(25, 23)
|
||||
+#define STF_DPHY_LANE_SWAP_LAN0 GENMASK(28, 26)
|
||||
+#define STF_DPHY_LANE_SWAP_LAN1 GENMASK(31, 29)
|
||||
+
|
||||
+#define STF_DPHY_LANE_SWAP_LAN2 GENMASK(2, 0)
|
||||
+#define STF_DPHY_LANE_SWAP_LAN3 GENMASK(5, 3)
|
||||
+#define STF_DPHY_MP_TEST_EN BIT(6)
|
||||
+#define STF_DPHY_MP_TEST_MODE_SEL GENMASK(11, 7)
|
||||
+#define STF_DPHY_PLL_CLK_SEL GENMASK(21, 12)
|
||||
+#define STF_DPHY_PRECOUNTER_IN_CLK GENMASK(29, 22)
|
||||
+
|
||||
+#define STF_DPHY_PRECOUNTER_IN_CLK1 GENMASK(7, 0)
|
||||
+#define STF_DPHY_PRECOUNTER_IN_LAN0 GENMASK(15, 8)
|
||||
+#define STF_DPHY_PRECOUNTER_IN_LAN1 GENMASK(23, 16)
|
||||
+#define STF_DPHY_PRECOUNTER_IN_LAN2 GENMASK(31, 24)
|
||||
+
|
||||
+#define STF_DPHY_PRECOUNTER_IN_LAN3 GENMASK(7, 0)
|
||||
+#define STF_DPHY_RX_1C2C_SEL BIT(8)
|
||||
+
|
||||
+#define STF_MAP_LANES_NUM 6
|
||||
+
|
||||
+struct regval {
|
||||
+ u32 addr;
|
||||
+ u32 val;
|
||||
+};
|
||||
+
|
||||
+struct stf_dphy_info {
|
||||
+ /**
|
||||
+ * @maps:
|
||||
+ *
|
||||
+ * Physical lanes and logic lanes mapping table.
|
||||
+ *
|
||||
+ * The default order is:
|
||||
+ * [clk lane0, data lane 0, data lane 1, data lane 2, date lane 3, clk lane 1]
|
||||
+ */
|
||||
+ u8 maps[STF_MAP_LANES_NUM];
|
||||
+};
|
||||
+
|
||||
+struct stf_dphy {
|
||||
+ struct device *dev;
|
||||
+ void __iomem *regs;
|
||||
+ struct clk *cfg_clk;
|
||||
+ struct clk *ref_clk;
|
||||
+ struct clk *tx_clk;
|
||||
+ struct reset_control *rstc;
|
||||
+ struct regulator *mipi_0p9;
|
||||
+ struct phy *phy;
|
||||
+ const struct stf_dphy_info *info;
|
||||
+};
|
||||
+
|
||||
+static const struct regval stf_dphy_init_list[] = {
|
||||
+ { STF_DPHY_APBCFGSAIF_SYSCFG(4), 0x00000000 },
|
||||
+ { STF_DPHY_APBCFGSAIF_SYSCFG(8), 0x00000000 },
|
||||
+ { STF_DPHY_APBCFGSAIF_SYSCFG(12), 0x0000fff0 },
|
||||
+ { STF_DPHY_APBCFGSAIF_SYSCFG(16), 0x00000000 },
|
||||
+ { STF_DPHY_APBCFGSAIF_SYSCFG(20), 0x00000000 },
|
||||
+ { STF_DPHY_APBCFGSAIF_SYSCFG(24), 0x00000000 },
|
||||
+ { STF_DPHY_APBCFGSAIF_SYSCFG(28), 0x00000000 },
|
||||
+ { STF_DPHY_APBCFGSAIF_SYSCFG(32), 0x00000000 },
|
||||
+ { STF_DPHY_APBCFGSAIF_SYSCFG(36), 0x00000000 },
|
||||
+ { STF_DPHY_APBCFGSAIF_SYSCFG(40), 0x00000000 },
|
||||
+ { STF_DPHY_APBCFGSAIF_SYSCFG(40), 0x00000000 },
|
||||
+ { STF_DPHY_APBCFGSAIF_SYSCFG(48), 0x24000000 },
|
||||
+ { STF_DPHY_APBCFGSAIF_SYSCFG(52), 0x00000000 },
|
||||
+ { STF_DPHY_APBCFGSAIF_SYSCFG(56), 0x00000000 },
|
||||
+ { STF_DPHY_APBCFGSAIF_SYSCFG(60), 0x00000000 },
|
||||
+ { STF_DPHY_APBCFGSAIF_SYSCFG(64), 0x00000000 },
|
||||
+ { STF_DPHY_APBCFGSAIF_SYSCFG(68), 0x00000000 },
|
||||
+ { STF_DPHY_APBCFGSAIF_SYSCFG(72), 0x00000000 },
|
||||
+ { STF_DPHY_APBCFGSAIF_SYSCFG(76), 0x00000000 },
|
||||
+ { STF_DPHY_APBCFGSAIF_SYSCFG(80), 0x00000000 },
|
||||
+ { STF_DPHY_APBCFGSAIF_SYSCFG(84), 0x00000000 },
|
||||
+ { STF_DPHY_APBCFGSAIF_SYSCFG(88), 0x00000000 },
|
||||
+ { STF_DPHY_APBCFGSAIF_SYSCFG(92), 0x00000000 },
|
||||
+ { STF_DPHY_APBCFGSAIF_SYSCFG(96), 0x00000000 },
|
||||
+ { STF_DPHY_APBCFGSAIF_SYSCFG(100), 0x02000000 },
|
||||
+ { STF_DPHY_APBCFGSAIF_SYSCFG(104), 0x00000000 },
|
||||
+ { STF_DPHY_APBCFGSAIF_SYSCFG(108), 0x00000000 },
|
||||
+ { STF_DPHY_APBCFGSAIF_SYSCFG(112), 0x00000000 },
|
||||
+ { STF_DPHY_APBCFGSAIF_SYSCFG(116), 0x00000000 },
|
||||
+ { STF_DPHY_APBCFGSAIF_SYSCFG(120), 0x00000000 },
|
||||
+ { STF_DPHY_APBCFGSAIF_SYSCFG(124), 0x0000000c },
|
||||
+ { STF_DPHY_APBCFGSAIF_SYSCFG(128), 0x00000000 },
|
||||
+ { STF_DPHY_APBCFGSAIF_SYSCFG(132), 0xcc500000 },
|
||||
+ { STF_DPHY_APBCFGSAIF_SYSCFG(136), 0x000000cc },
|
||||
+ { STF_DPHY_APBCFGSAIF_SYSCFG(140), 0x00000000 },
|
||||
+ { STF_DPHY_APBCFGSAIF_SYSCFG(144), 0x00000000 },
|
||||
+};
|
||||
+
|
||||
+static int stf_dphy_configure(struct phy *phy, union phy_configure_opts *opts)
|
||||
+{
|
||||
+ struct stf_dphy *dphy = phy_get_drvdata(phy);
|
||||
+ const struct stf_dphy_info *info = dphy->info;
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < ARRAY_SIZE(stf_dphy_init_list); i++)
|
||||
+ writel(stf_dphy_init_list[i].val,
|
||||
+ dphy->regs + stf_dphy_init_list[i].addr);
|
||||
+
|
||||
+ writel(FIELD_PREP(STF_DPHY_DA_CDPHY_R100_CTRL0_2D1C_EFUSE_EN, 1) |
|
||||
+ FIELD_PREP(STF_DPHY_DA_CDPHY_R100_CTRL0_2D1C_EFUSE_IN, 0x1b) |
|
||||
+ FIELD_PREP(STF_DPHY_DA_CDPHY_R100_CTRL1_2D1C_EFUSE_EN, 1) |
|
||||
+ FIELD_PREP(STF_DPHY_DA_CDPHY_R100_CTRL1_2D1C_EFUSE_IN, 0x1b),
|
||||
+ dphy->regs + STF_DPHY_APBCFGSAIF_SYSCFG(0));
|
||||
+
|
||||
+ writel(FIELD_PREP(STF_DPHY_DATA_BUS16_8, 0) |
|
||||
+ FIELD_PREP(STF_DPHY_DEBUG_MODE_SEL, 0x5a),
|
||||
+ dphy->regs + STF_DPHY_APBCFGSAIF_SYSCFG(184));
|
||||
+
|
||||
+ writel(FIELD_PREP(STF_DPHY_ENABLE_CLK, 1) |
|
||||
+ FIELD_PREP(STF_DPHY_ENABLE_CLK1, 1) |
|
||||
+ FIELD_PREP(STF_DPHY_ENABLE_LAN0, 1) |
|
||||
+ FIELD_PREP(STF_DPHY_ENABLE_LAN1, 1) |
|
||||
+ FIELD_PREP(STF_DPHY_ENABLE_LAN2, 1) |
|
||||
+ FIELD_PREP(STF_DPHY_ENABLE_LAN3, 1) |
|
||||
+ FIELD_PREP(STF_DPHY_GPI_EN, 0) |
|
||||
+ FIELD_PREP(STF_DPHY_HS_FREQ_CHANGE_CLK, 0) |
|
||||
+ FIELD_PREP(STF_DPHY_HS_FREQ_CHANGE_CLK1, 0) |
|
||||
+ FIELD_PREP(STF_DPHY_LANE_SWAP_CLK, info->maps[0]) |
|
||||
+ FIELD_PREP(STF_DPHY_LANE_SWAP_CLK1, info->maps[5]) |
|
||||
+ FIELD_PREP(STF_DPHY_LANE_SWAP_LAN0, info->maps[1]) |
|
||||
+ FIELD_PREP(STF_DPHY_LANE_SWAP_LAN1, info->maps[2]),
|
||||
+ dphy->regs + STF_DPHY_APBCFGSAIF_SYSCFG(188));
|
||||
+
|
||||
+ writel(FIELD_PREP(STF_DPHY_LANE_SWAP_LAN2, info->maps[3]) |
|
||||
+ FIELD_PREP(STF_DPHY_LANE_SWAP_LAN3, info->maps[4]) |
|
||||
+ FIELD_PREP(STF_DPHY_MP_TEST_EN, 0) |
|
||||
+ FIELD_PREP(STF_DPHY_MP_TEST_MODE_SEL, 0) |
|
||||
+ FIELD_PREP(STF_DPHY_PLL_CLK_SEL, 0x37c) |
|
||||
+ FIELD_PREP(STF_DPHY_PRECOUNTER_IN_CLK, 8),
|
||||
+ dphy->regs + STF_DPHY_APBCFGSAIF_SYSCFG(192));
|
||||
+
|
||||
+ writel(FIELD_PREP(STF_DPHY_PRECOUNTER_IN_CLK1, 8) |
|
||||
+ FIELD_PREP(STF_DPHY_PRECOUNTER_IN_LAN0, 7) |
|
||||
+ FIELD_PREP(STF_DPHY_PRECOUNTER_IN_LAN1, 7) |
|
||||
+ FIELD_PREP(STF_DPHY_PRECOUNTER_IN_LAN2, 7),
|
||||
+ dphy->regs + STF_DPHY_APBCFGSAIF_SYSCFG(196));
|
||||
+
|
||||
+ writel(FIELD_PREP(STF_DPHY_PRECOUNTER_IN_LAN3, 7) |
|
||||
+ FIELD_PREP(STF_DPHY_RX_1C2C_SEL, 0),
|
||||
+ dphy->regs + STF_DPHY_APBCFGSAIF_SYSCFG(200));
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int stf_dphy_power_on(struct phy *phy)
|
||||
+{
|
||||
+ struct stf_dphy *dphy = phy_get_drvdata(phy);
|
||||
+ int ret;
|
||||
+
|
||||
+ pm_runtime_get_sync(dphy->dev);
|
||||
+
|
||||
+ ret = regulator_enable(dphy->mipi_0p9);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ clk_set_rate(dphy->cfg_clk, 99000000);
|
||||
+ clk_set_rate(dphy->ref_clk, 49500000);
|
||||
+ clk_set_rate(dphy->tx_clk, 19800000);
|
||||
+ reset_control_deassert(dphy->rstc);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int stf_dphy_power_off(struct phy *phy)
|
||||
+{
|
||||
+ struct stf_dphy *dphy = phy_get_drvdata(phy);
|
||||
+
|
||||
+ reset_control_assert(dphy->rstc);
|
||||
+
|
||||
+ regulator_disable(dphy->mipi_0p9);
|
||||
+
|
||||
+ pm_runtime_put_sync(dphy->dev);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct phy_ops stf_dphy_ops = {
|
||||
+ .configure = stf_dphy_configure,
|
||||
+ .power_on = stf_dphy_power_on,
|
||||
+ .power_off = stf_dphy_power_off,
|
||||
+};
|
||||
+
|
||||
+static int stf_dphy_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct phy_provider *phy_provider;
|
||||
+ struct stf_dphy *dphy;
|
||||
+
|
||||
+ dphy = devm_kzalloc(&pdev->dev, sizeof(*dphy), GFP_KERNEL);
|
||||
+ if (!dphy)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ dphy->info = of_device_get_match_data(&pdev->dev);
|
||||
+
|
||||
+ dev_set_drvdata(&pdev->dev, dphy);
|
||||
+ dphy->dev = &pdev->dev;
|
||||
+
|
||||
+ dphy->regs = devm_platform_ioremap_resource(pdev, 0);
|
||||
+ if (IS_ERR(dphy->regs))
|
||||
+ return PTR_ERR(dphy->regs);
|
||||
+
|
||||
+ dphy->cfg_clk = devm_clk_get(&pdev->dev, "cfg");
|
||||
+ if (IS_ERR(dphy->cfg_clk))
|
||||
+ return PTR_ERR(dphy->cfg_clk);
|
||||
+
|
||||
+ dphy->ref_clk = devm_clk_get(&pdev->dev, "ref");
|
||||
+ if (IS_ERR(dphy->ref_clk))
|
||||
+ return PTR_ERR(dphy->ref_clk);
|
||||
+
|
||||
+ dphy->tx_clk = devm_clk_get(&pdev->dev, "tx");
|
||||
+ if (IS_ERR(dphy->tx_clk))
|
||||
+ return PTR_ERR(dphy->tx_clk);
|
||||
+
|
||||
+ dphy->rstc = devm_reset_control_array_get_exclusive(&pdev->dev);
|
||||
+ if (IS_ERR(dphy->rstc))
|
||||
+ return PTR_ERR(dphy->rstc);
|
||||
+
|
||||
+ dphy->mipi_0p9 = devm_regulator_get(&pdev->dev, "mipi_0p9");
|
||||
+ if (IS_ERR(dphy->mipi_0p9))
|
||||
+ return PTR_ERR(dphy->mipi_0p9);
|
||||
+
|
||||
+ dphy->phy = devm_phy_create(&pdev->dev, NULL, &stf_dphy_ops);
|
||||
+ if (IS_ERR(dphy->phy)) {
|
||||
+ dev_err(&pdev->dev, "Failed to create PHY\n");
|
||||
+ return PTR_ERR(dphy->phy);
|
||||
+ }
|
||||
+
|
||||
+ pm_runtime_enable(&pdev->dev);
|
||||
+
|
||||
+ phy_set_drvdata(dphy->phy, dphy);
|
||||
+ phy_provider = devm_of_phy_provider_register(&pdev->dev,
|
||||
+ of_phy_simple_xlate);
|
||||
+
|
||||
+ return PTR_ERR_OR_ZERO(phy_provider);
|
||||
+}
|
||||
+
|
||||
+static const struct stf_dphy_info starfive_dphy_info = {
|
||||
+ .maps = {4, 0, 1, 2, 3, 5},
|
||||
+};
|
||||
+
|
||||
+static const struct of_device_id stf_dphy_dt_ids[] = {
|
||||
+ {
|
||||
+ .compatible = "starfive,jh7110-dphy-rx",
|
||||
+ .data = &starfive_dphy_info,
|
||||
+ },
|
||||
+ { /* sentinel */ },
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, stf_dphy_dt_ids);
|
||||
+
|
||||
+static struct platform_driver stf_dphy_driver = {
|
||||
+ .probe = stf_dphy_probe,
|
||||
+ .driver = {
|
||||
+ .name = "starfive-dphy-rx",
|
||||
+ .of_match_table = stf_dphy_dt_ids,
|
||||
+ },
|
||||
+};
|
||||
+module_platform_driver(stf_dphy_driver);
|
||||
+
|
||||
+MODULE_AUTHOR("Jack Zhu <jack.zhu@starfivetech.com>");
|
||||
+MODULE_AUTHOR("Changhuang Liang <changhuang.liang@starfivetech.com>");
|
||||
+MODULE_DESCRIPTION("StarFive DPHY RX driver");
|
||||
+MODULE_LICENSE("GPL");
|
@ -0,0 +1,306 @@
|
||||
From 243b040c3517093309a41877e3c1c6e8a7540071 Mon Sep 17 00:00:00 2001
|
||||
From: Jack Zhu <jack.zhu@starfivetech.com>
|
||||
Date: Tue, 23 May 2023 16:56:22 +0800
|
||||
Subject: [PATCH 076/122] media: dt-bindings: cadence-csi2rx: Convert to DT
|
||||
schema
|
||||
|
||||
Convert DT bindings document for Cadence MIPI-CSI2 RX controller to
|
||||
DT schema format.
|
||||
|
||||
For compatible, new compatibles should not be messed with conversion,
|
||||
but the original binding did not specify any SoC-specific compatible
|
||||
string, so add the StarFive compatible string.
|
||||
|
||||
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
|
||||
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
|
||||
Signed-off-by: Jack Zhu <jack.zhu@starfivetech.com>
|
||||
---
|
||||
.../devicetree/bindings/media/cdns,csi2rx.txt | 100 ----------
|
||||
.../bindings/media/cdns,csi2rx.yaml | 177 ++++++++++++++++++
|
||||
2 files changed, 177 insertions(+), 100 deletions(-)
|
||||
delete mode 100644 Documentation/devicetree/bindings/media/cdns,csi2rx.txt
|
||||
create mode 100644 Documentation/devicetree/bindings/media/cdns,csi2rx.yaml
|
||||
|
||||
--- a/Documentation/devicetree/bindings/media/cdns,csi2rx.txt
|
||||
+++ /dev/null
|
||||
@@ -1,100 +0,0 @@
|
||||
-Cadence MIPI-CSI2 RX controller
|
||||
-===============================
|
||||
-
|
||||
-The Cadence MIPI-CSI2 RX controller is a CSI-2 bridge supporting up to 4 CSI
|
||||
-lanes in input, and 4 different pixel streams in output.
|
||||
-
|
||||
-Required properties:
|
||||
- - compatible: must be set to "cdns,csi2rx" and an SoC-specific compatible
|
||||
- - reg: base address and size of the memory mapped region
|
||||
- - clocks: phandles to the clocks driving the controller
|
||||
- - clock-names: must contain:
|
||||
- * sys_clk: main clock
|
||||
- * p_clk: register bank clock
|
||||
- * pixel_if[0-3]_clk: pixel stream output clock, one for each stream
|
||||
- implemented in hardware, between 0 and 3
|
||||
-
|
||||
-Optional properties:
|
||||
- - phys: phandle to the external D-PHY, phy-names must be provided
|
||||
- - phy-names: must contain "dphy", if the implementation uses an
|
||||
- external D-PHY
|
||||
-
|
||||
-Required subnodes:
|
||||
- - ports: A ports node with one port child node per device input and output
|
||||
- port, in accordance with the video interface bindings defined in
|
||||
- Documentation/devicetree/bindings/media/video-interfaces.txt. The
|
||||
- port nodes are numbered as follows:
|
||||
-
|
||||
- Port Description
|
||||
- -----------------------------
|
||||
- 0 CSI-2 input
|
||||
- 1 Stream 0 output
|
||||
- 2 Stream 1 output
|
||||
- 3 Stream 2 output
|
||||
- 4 Stream 3 output
|
||||
-
|
||||
- The stream output port nodes are optional if they are not
|
||||
- connected to anything at the hardware level or implemented
|
||||
- in the design.Since there is only one endpoint per port,
|
||||
- the endpoints are not numbered.
|
||||
-
|
||||
-
|
||||
-Example:
|
||||
-
|
||||
-csi2rx: csi-bridge@0d060000 {
|
||||
- compatible = "cdns,csi2rx";
|
||||
- reg = <0x0d060000 0x1000>;
|
||||
- clocks = <&byteclock>, <&byteclock>
|
||||
- <&coreclock>, <&coreclock>,
|
||||
- <&coreclock>, <&coreclock>;
|
||||
- clock-names = "sys_clk", "p_clk",
|
||||
- "pixel_if0_clk", "pixel_if1_clk",
|
||||
- "pixel_if2_clk", "pixel_if3_clk";
|
||||
-
|
||||
- ports {
|
||||
- #address-cells = <1>;
|
||||
- #size-cells = <0>;
|
||||
-
|
||||
- port@0 {
|
||||
- reg = <0>;
|
||||
-
|
||||
- csi2rx_in_sensor: endpoint {
|
||||
- remote-endpoint = <&sensor_out_csi2rx>;
|
||||
- clock-lanes = <0>;
|
||||
- data-lanes = <1 2>;
|
||||
- };
|
||||
- };
|
||||
-
|
||||
- port@1 {
|
||||
- reg = <1>;
|
||||
-
|
||||
- csi2rx_out_grabber0: endpoint {
|
||||
- remote-endpoint = <&grabber0_in_csi2rx>;
|
||||
- };
|
||||
- };
|
||||
-
|
||||
- port@2 {
|
||||
- reg = <2>;
|
||||
-
|
||||
- csi2rx_out_grabber1: endpoint {
|
||||
- remote-endpoint = <&grabber1_in_csi2rx>;
|
||||
- };
|
||||
- };
|
||||
-
|
||||
- port@3 {
|
||||
- reg = <3>;
|
||||
-
|
||||
- csi2rx_out_grabber2: endpoint {
|
||||
- remote-endpoint = <&grabber2_in_csi2rx>;
|
||||
- };
|
||||
- };
|
||||
-
|
||||
- port@4 {
|
||||
- reg = <4>;
|
||||
-
|
||||
- csi2rx_out_grabber3: endpoint {
|
||||
- remote-endpoint = <&grabber3_in_csi2rx>;
|
||||
- };
|
||||
- };
|
||||
- };
|
||||
-};
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/media/cdns,csi2rx.yaml
|
||||
@@ -0,0 +1,177 @@
|
||||
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
+%YAML 1.2
|
||||
+---
|
||||
+$id: http://devicetree.org/schemas/media/cdns,csi2rx.yaml#
|
||||
+$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
+
|
||||
+title: Cadence MIPI-CSI2 RX controller
|
||||
+
|
||||
+maintainers:
|
||||
+ - Maxime Ripard <mripard@kernel.org>
|
||||
+
|
||||
+description:
|
||||
+ The Cadence MIPI-CSI2 RX controller is a CSI-2 bridge supporting up to 4 CSI
|
||||
+ lanes in input, and 4 different pixel streams in output.
|
||||
+
|
||||
+properties:
|
||||
+ compatible:
|
||||
+ items:
|
||||
+ - enum:
|
||||
+ - starfive,jh7110-csi2rx
|
||||
+ - const: cdns,csi2rx
|
||||
+
|
||||
+ reg:
|
||||
+ maxItems: 1
|
||||
+
|
||||
+ clocks:
|
||||
+ items:
|
||||
+ - description: CSI2Rx system clock
|
||||
+ - description: Gated Register bank clock for APB interface
|
||||
+ - description: pixel Clock for Stream interface 0
|
||||
+ - description: pixel Clock for Stream interface 1
|
||||
+ - description: pixel Clock for Stream interface 2
|
||||
+ - description: pixel Clock for Stream interface 3
|
||||
+
|
||||
+ clock-names:
|
||||
+ items:
|
||||
+ - const: sys_clk
|
||||
+ - const: p_clk
|
||||
+ - const: pixel_if0_clk
|
||||
+ - const: pixel_if1_clk
|
||||
+ - const: pixel_if2_clk
|
||||
+ - const: pixel_if3_clk
|
||||
+
|
||||
+ phys:
|
||||
+ maxItems: 1
|
||||
+ description: MIPI D-PHY
|
||||
+
|
||||
+ phy-names:
|
||||
+ items:
|
||||
+ - const: dphy
|
||||
+
|
||||
+ ports:
|
||||
+ $ref: /schemas/graph.yaml#/properties/ports
|
||||
+
|
||||
+ properties:
|
||||
+ port@0:
|
||||
+ $ref: /schemas/graph.yaml#/$defs/port-base
|
||||
+ unevaluatedProperties: false
|
||||
+ description:
|
||||
+ Input port node, single endpoint describing the CSI-2 transmitter.
|
||||
+
|
||||
+ properties:
|
||||
+ endpoint:
|
||||
+ $ref: video-interfaces.yaml#
|
||||
+ unevaluatedProperties: false
|
||||
+
|
||||
+ properties:
|
||||
+ bus-type:
|
||||
+ const: 4
|
||||
+
|
||||
+ clock-lanes:
|
||||
+ const: 0
|
||||
+
|
||||
+ data-lanes:
|
||||
+ minItems: 1
|
||||
+ maxItems: 4
|
||||
+ items:
|
||||
+ maximum: 4
|
||||
+
|
||||
+ required:
|
||||
+ - data-lanes
|
||||
+
|
||||
+ port@1:
|
||||
+ $ref: /schemas/graph.yaml#/properties/port
|
||||
+ description:
|
||||
+ Stream 0 Output port node
|
||||
+
|
||||
+ port@2:
|
||||
+ $ref: /schemas/graph.yaml#/properties/port
|
||||
+ description:
|
||||
+ Stream 1 Output port node
|
||||
+
|
||||
+ port@3:
|
||||
+ $ref: /schemas/graph.yaml#/properties/port
|
||||
+ description:
|
||||
+ Stream 2 Output port node
|
||||
+
|
||||
+ port@4:
|
||||
+ $ref: /schemas/graph.yaml#/properties/port
|
||||
+ description:
|
||||
+ Stream 3 Output port node
|
||||
+
|
||||
+ required:
|
||||
+ - port@0
|
||||
+
|
||||
+required:
|
||||
+ - compatible
|
||||
+ - reg
|
||||
+ - clocks
|
||||
+ - clock-names
|
||||
+ - ports
|
||||
+
|
||||
+additionalProperties: false
|
||||
+
|
||||
+examples:
|
||||
+ - |
|
||||
+ csi@d060000 {
|
||||
+ compatible = "starfive,jh7110-csi2rx", "cdns,csi2rx";
|
||||
+ reg = <0x0d060000 0x1000>;
|
||||
+ clocks = <&byteclock 7>, <&byteclock 6>,
|
||||
+ <&coreclock 8>, <&coreclock 9>,
|
||||
+ <&coreclock 10>, <&coreclock 11>;
|
||||
+ clock-names = "sys_clk", "p_clk",
|
||||
+ "pixel_if0_clk", "pixel_if1_clk",
|
||||
+ "pixel_if2_clk", "pixel_if3_clk";
|
||||
+ phys = <&csi_phy>;
|
||||
+ phy-names = "dphy";
|
||||
+
|
||||
+ ports {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+
|
||||
+ port@0 {
|
||||
+ reg = <0>;
|
||||
+
|
||||
+ csi2rx_in_sensor: endpoint {
|
||||
+ remote-endpoint = <&sensor_out_csi2rx>;
|
||||
+ clock-lanes = <0>;
|
||||
+ data-lanes = <1 2>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ port@1 {
|
||||
+ reg = <1>;
|
||||
+
|
||||
+ csi2rx_out_grabber0: endpoint {
|
||||
+ remote-endpoint = <&grabber0_in_csi2rx>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ port@2 {
|
||||
+ reg = <2>;
|
||||
+
|
||||
+ csi2rx_out_grabber1: endpoint {
|
||||
+ remote-endpoint = <&grabber1_in_csi2rx>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ port@3 {
|
||||
+ reg = <3>;
|
||||
+
|
||||
+ csi2rx_out_grabber2: endpoint {
|
||||
+ remote-endpoint = <&grabber2_in_csi2rx>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ port@4 {
|
||||
+ reg = <4>;
|
||||
+
|
||||
+ csi2rx_out_grabber3: endpoint {
|
||||
+ remote-endpoint = <&grabber3_in_csi2rx>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+...
|
@ -0,0 +1,55 @@
|
||||
From 60817a4e755c6e98092fdceec35fcda94d35e4b1 Mon Sep 17 00:00:00 2001
|
||||
From: Jack Zhu <jack.zhu@starfivetech.com>
|
||||
Date: Tue, 23 May 2023 16:56:23 +0800
|
||||
Subject: [PATCH 077/122] media: dt-bindings: cadence-csi2rx: Add resets
|
||||
property
|
||||
|
||||
Add resets property for Cadence MIPI-CSI2 RX controller
|
||||
|
||||
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
|
||||
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
|
||||
Signed-off-by: Jack Zhu <jack.zhu@starfivetech.com>
|
||||
---
|
||||
.../bindings/media/cdns,csi2rx.yaml | 24 +++++++++++++++++++
|
||||
1 file changed, 24 insertions(+)
|
||||
|
||||
--- a/Documentation/devicetree/bindings/media/cdns,csi2rx.yaml
|
||||
+++ b/Documentation/devicetree/bindings/media/cdns,csi2rx.yaml
|
||||
@@ -41,6 +41,24 @@ properties:
|
||||
- const: pixel_if2_clk
|
||||
- const: pixel_if3_clk
|
||||
|
||||
+ resets:
|
||||
+ items:
|
||||
+ - description: CSI2Rx system reset
|
||||
+ - description: Gated Register bank reset for APB interface
|
||||
+ - description: pixel reset for Stream interface 0
|
||||
+ - description: pixel reset for Stream interface 1
|
||||
+ - description: pixel reset for Stream interface 2
|
||||
+ - description: pixel reset for Stream interface 3
|
||||
+
|
||||
+ reset-names:
|
||||
+ items:
|
||||
+ - const: sys
|
||||
+ - const: reg_bank
|
||||
+ - const: pixel_if0
|
||||
+ - const: pixel_if1
|
||||
+ - const: pixel_if2
|
||||
+ - const: pixel_if3
|
||||
+
|
||||
phys:
|
||||
maxItems: 1
|
||||
description: MIPI D-PHY
|
||||
@@ -123,6 +141,12 @@ examples:
|
||||
clock-names = "sys_clk", "p_clk",
|
||||
"pixel_if0_clk", "pixel_if1_clk",
|
||||
"pixel_if2_clk", "pixel_if3_clk";
|
||||
+ resets = <&bytereset 9>, <&bytereset 4>,
|
||||
+ <&corereset 5>, <&corereset 6>,
|
||||
+ <&corereset 7>, <&corereset 8>;
|
||||
+ reset-names = "sys", "reg_bank",
|
||||
+ "pixel_if0", "pixel_if1",
|
||||
+ "pixel_if2", "pixel_if3";
|
||||
phys = <&csi_phy>;
|
||||
phy-names = "dphy";
|
||||
|
@ -0,0 +1,129 @@
|
||||
From 2fbf4d367b25de4fa2f2d9cec57c88766c37d9de Mon Sep 17 00:00:00 2001
|
||||
From: Jack Zhu <jack.zhu@starfivetech.com>
|
||||
Date: Tue, 23 May 2023 16:56:24 +0800
|
||||
Subject: [PATCH 078/122] media: cadence: Add operation on reset
|
||||
|
||||
Add operation on reset for Cadence MIPI-CSI2 RX Controller.
|
||||
|
||||
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
|
||||
Signed-off-by: Jack Zhu <jack.zhu@starfivetech.com>
|
||||
---
|
||||
drivers/media/platform/cadence/cdns-csi2rx.c | 40 +++++++++++++++++---
|
||||
1 file changed, 35 insertions(+), 5 deletions(-)
|
||||
|
||||
--- a/drivers/media/platform/cadence/cdns-csi2rx.c
|
||||
+++ b/drivers/media/platform/cadence/cdns-csi2rx.c
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <linux/of_graph.h>
|
||||
#include <linux/phy/phy.h>
|
||||
#include <linux/platform_device.h>
|
||||
+#include <linux/reset.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <media/v4l2-ctrls.h>
|
||||
@@ -68,6 +69,9 @@ struct csi2rx_priv {
|
||||
struct clk *sys_clk;
|
||||
struct clk *p_clk;
|
||||
struct clk *pixel_clk[CSI2RX_STREAMS_MAX];
|
||||
+ struct reset_control *sys_rst;
|
||||
+ struct reset_control *p_rst;
|
||||
+ struct reset_control *pixel_rst[CSI2RX_STREAMS_MAX];
|
||||
struct phy *dphy;
|
||||
|
||||
u8 lanes[CSI2RX_LANES_MAX];
|
||||
@@ -112,6 +116,7 @@ static int csi2rx_start(struct csi2rx_pr
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
+ reset_control_deassert(csi2rx->p_rst);
|
||||
csi2rx_reset(csi2rx);
|
||||
|
||||
reg = csi2rx->num_lanes << 8;
|
||||
@@ -154,6 +159,8 @@ static int csi2rx_start(struct csi2rx_pr
|
||||
if (ret)
|
||||
goto err_disable_pixclk;
|
||||
|
||||
+ reset_control_deassert(csi2rx->pixel_rst[i]);
|
||||
+
|
||||
writel(CSI2RX_STREAM_CFG_FIFO_MODE_LARGE_BUF,
|
||||
csi2rx->base + CSI2RX_STREAM_CFG_REG(i));
|
||||
|
||||
@@ -169,13 +176,16 @@ static int csi2rx_start(struct csi2rx_pr
|
||||
if (ret)
|
||||
goto err_disable_pixclk;
|
||||
|
||||
+ reset_control_deassert(csi2rx->sys_rst);
|
||||
clk_disable_unprepare(csi2rx->p_clk);
|
||||
|
||||
return 0;
|
||||
|
||||
err_disable_pixclk:
|
||||
- for (; i > 0; i--)
|
||||
+ for (; i > 0; i--) {
|
||||
+ reset_control_assert(csi2rx->pixel_rst[i - 1]);
|
||||
clk_disable_unprepare(csi2rx->pixel_clk[i - 1]);
|
||||
+ }
|
||||
|
||||
err_disable_pclk:
|
||||
clk_disable_unprepare(csi2rx->p_clk);
|
||||
@@ -188,14 +198,17 @@ static void csi2rx_stop(struct csi2rx_pr
|
||||
unsigned int i;
|
||||
|
||||
clk_prepare_enable(csi2rx->p_clk);
|
||||
+ reset_control_assert(csi2rx->sys_rst);
|
||||
clk_disable_unprepare(csi2rx->sys_clk);
|
||||
|
||||
for (i = 0; i < csi2rx->max_streams; i++) {
|
||||
writel(0, csi2rx->base + CSI2RX_STREAM_CTRL_REG(i));
|
||||
|
||||
+ reset_control_assert(csi2rx->pixel_rst[i]);
|
||||
clk_disable_unprepare(csi2rx->pixel_clk[i]);
|
||||
}
|
||||
|
||||
+ reset_control_assert(csi2rx->p_rst);
|
||||
clk_disable_unprepare(csi2rx->p_clk);
|
||||
|
||||
if (v4l2_subdev_call(csi2rx->source_subdev, video, s_stream, false))
|
||||
@@ -299,6 +312,16 @@ static int csi2rx_get_resources(struct c
|
||||
return PTR_ERR(csi2rx->p_clk);
|
||||
}
|
||||
|
||||
+ csi2rx->sys_rst = devm_reset_control_get_optional_exclusive(&pdev->dev,
|
||||
+ "sys");
|
||||
+ if (IS_ERR(csi2rx->sys_rst))
|
||||
+ return PTR_ERR(csi2rx->sys_rst);
|
||||
+
|
||||
+ csi2rx->p_rst = devm_reset_control_get_optional_exclusive(&pdev->dev,
|
||||
+ "reg_bank");
|
||||
+ if (IS_ERR(csi2rx->p_rst))
|
||||
+ return PTR_ERR(csi2rx->p_rst);
|
||||
+
|
||||
csi2rx->dphy = devm_phy_optional_get(&pdev->dev, "dphy");
|
||||
if (IS_ERR(csi2rx->dphy)) {
|
||||
dev_err(&pdev->dev, "Couldn't get external D-PHY\n");
|
||||
@@ -349,14 +372,21 @@ static int csi2rx_get_resources(struct c
|
||||
}
|
||||
|
||||
for (i = 0; i < csi2rx->max_streams; i++) {
|
||||
- char clk_name[16];
|
||||
+ char name[16];
|
||||
|
||||
- snprintf(clk_name, sizeof(clk_name), "pixel_if%u_clk", i);
|
||||
- csi2rx->pixel_clk[i] = devm_clk_get(&pdev->dev, clk_name);
|
||||
+ snprintf(name, sizeof(name), "pixel_if%u_clk", i);
|
||||
+ csi2rx->pixel_clk[i] = devm_clk_get(&pdev->dev, name);
|
||||
if (IS_ERR(csi2rx->pixel_clk[i])) {
|
||||
- dev_err(&pdev->dev, "Couldn't get clock %s\n", clk_name);
|
||||
+ dev_err(&pdev->dev, "Couldn't get clock %s\n", name);
|
||||
return PTR_ERR(csi2rx->pixel_clk[i]);
|
||||
}
|
||||
+
|
||||
+ snprintf(name, sizeof(name), "pixel_if%u", i);
|
||||
+ csi2rx->pixel_rst[i] =
|
||||
+ devm_reset_control_get_optional_exclusive(&pdev->dev,
|
||||
+ name);
|
||||
+ if (IS_ERR(csi2rx->pixel_rst[i]))
|
||||
+ return PTR_ERR(csi2rx->pixel_rst[i]);
|
||||
}
|
||||
|
||||
return 0;
|
@ -0,0 +1,141 @@
|
||||
From e97eb58b321b5b25b7d5c40880e6eb133d381581 Mon Sep 17 00:00:00 2001
|
||||
From: Jack Zhu <jack.zhu@starfivetech.com>
|
||||
Date: Tue, 23 May 2023 16:56:25 +0800
|
||||
Subject: [PATCH 079/122] media: cadence: Add support for external dphy
|
||||
|
||||
Add support for external MIPI D-PHY.
|
||||
|
||||
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
|
||||
Signed-off-by: Jack Zhu <jack.zhu@starfivetech.com>
|
||||
---
|
||||
drivers/media/platform/cadence/cdns-csi2rx.c | 66 +++++++++++++++++---
|
||||
1 file changed, 56 insertions(+), 10 deletions(-)
|
||||
|
||||
--- a/drivers/media/platform/cadence/cdns-csi2rx.c
|
||||
+++ b/drivers/media/platform/cadence/cdns-csi2rx.c
|
||||
@@ -31,6 +31,12 @@
|
||||
#define CSI2RX_STATIC_CFG_DLANE_MAP(llane, plane) ((plane) << (16 + (llane) * 4))
|
||||
#define CSI2RX_STATIC_CFG_LANES_MASK GENMASK(11, 8)
|
||||
|
||||
+#define CSI2RX_DPHY_LANE_CTRL_REG 0x40
|
||||
+#define CSI2RX_DPHY_CL_RST BIT(16)
|
||||
+#define CSI2RX_DPHY_DL_RST(i) BIT((i) + 12)
|
||||
+#define CSI2RX_DPHY_CL_EN BIT(4)
|
||||
+#define CSI2RX_DPHY_DL_EN(i) BIT(i)
|
||||
+
|
||||
#define CSI2RX_STREAM_BASE(n) (((n) + 1) * 0x100)
|
||||
|
||||
#define CSI2RX_STREAM_CTRL_REG(n) (CSI2RX_STREAM_BASE(n) + 0x000)
|
||||
@@ -105,6 +111,24 @@ static void csi2rx_reset(struct csi2rx_p
|
||||
writel(0, csi2rx->base + CSI2RX_SOFT_RESET_REG);
|
||||
}
|
||||
|
||||
+static int csi2rx_configure_ext_dphy(struct csi2rx_priv *csi2rx)
|
||||
+{
|
||||
+ union phy_configure_opts opts = { };
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = phy_power_on(csi2rx->dphy);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = phy_configure(csi2rx->dphy, &opts);
|
||||
+ if (ret) {
|
||||
+ phy_power_off(csi2rx->dphy);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int csi2rx_start(struct csi2rx_priv *csi2rx)
|
||||
{
|
||||
unsigned int i;
|
||||
@@ -144,6 +168,17 @@ static int csi2rx_start(struct csi2rx_pr
|
||||
if (ret)
|
||||
goto err_disable_pclk;
|
||||
|
||||
+ /* Enable DPHY clk and data lanes. */
|
||||
+ if (csi2rx->dphy) {
|
||||
+ reg = CSI2RX_DPHY_CL_EN | CSI2RX_DPHY_CL_RST;
|
||||
+ for (i = 0; i < csi2rx->num_lanes; i++) {
|
||||
+ reg |= CSI2RX_DPHY_DL_EN(csi2rx->lanes[i] - 1);
|
||||
+ reg |= CSI2RX_DPHY_DL_RST(csi2rx->lanes[i] - 1);
|
||||
+ }
|
||||
+
|
||||
+ writel(reg, csi2rx->base + CSI2RX_DPHY_LANE_CTRL_REG);
|
||||
+ }
|
||||
+
|
||||
/*
|
||||
* Create a static mapping between the CSI virtual channels
|
||||
* and the output stream.
|
||||
@@ -177,10 +212,22 @@ static int csi2rx_start(struct csi2rx_pr
|
||||
goto err_disable_pixclk;
|
||||
|
||||
reset_control_deassert(csi2rx->sys_rst);
|
||||
+
|
||||
+ if (csi2rx->dphy) {
|
||||
+ ret = csi2rx_configure_ext_dphy(csi2rx);
|
||||
+ if (ret) {
|
||||
+ dev_err(csi2rx->dev,
|
||||
+ "Failed to configure external DPHY: %d\n", ret);
|
||||
+ goto err_disable_sysclk;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
clk_disable_unprepare(csi2rx->p_clk);
|
||||
|
||||
return 0;
|
||||
|
||||
+err_disable_sysclk:
|
||||
+ clk_disable_unprepare(csi2rx->sys_clk);
|
||||
err_disable_pixclk:
|
||||
for (; i > 0; i--) {
|
||||
reset_control_assert(csi2rx->pixel_rst[i - 1]);
|
||||
@@ -213,6 +260,13 @@ static void csi2rx_stop(struct csi2rx_pr
|
||||
|
||||
if (v4l2_subdev_call(csi2rx->source_subdev, video, s_stream, false))
|
||||
dev_warn(csi2rx->dev, "Couldn't disable our subdev\n");
|
||||
+
|
||||
+ if (csi2rx->dphy) {
|
||||
+ writel(0, csi2rx->base + CSI2RX_DPHY_LANE_CTRL_REG);
|
||||
+
|
||||
+ if (phy_power_off(csi2rx->dphy))
|
||||
+ dev_warn(csi2rx->dev, "Couldn't power off DPHY\n");
|
||||
+ }
|
||||
}
|
||||
|
||||
static int csi2rx_s_stream(struct v4l2_subdev *subdev, int enable)
|
||||
@@ -328,15 +382,6 @@ static int csi2rx_get_resources(struct c
|
||||
return PTR_ERR(csi2rx->dphy);
|
||||
}
|
||||
|
||||
- /*
|
||||
- * FIXME: Once we'll have external D-PHY support, the check
|
||||
- * will need to be removed.
|
||||
- */
|
||||
- if (csi2rx->dphy) {
|
||||
- dev_err(&pdev->dev, "External D-PHY not supported yet\n");
|
||||
- return -EINVAL;
|
||||
- }
|
||||
-
|
||||
ret = clk_prepare_enable(csi2rx->p_clk);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Couldn't prepare and enable P clock\n");
|
||||
@@ -366,7 +411,7 @@ static int csi2rx_get_resources(struct c
|
||||
* FIXME: Once we'll have internal D-PHY support, the check
|
||||
* will need to be removed.
|
||||
*/
|
||||
- if (csi2rx->has_internal_dphy) {
|
||||
+ if (!csi2rx->dphy && csi2rx->has_internal_dphy) {
|
||||
dev_err(&pdev->dev, "Internal D-PHY not supported yet\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -494,6 +539,7 @@ static int csi2rx_probe(struct platform_
|
||||
dev_info(&pdev->dev,
|
||||
"Probed CSI2RX with %u/%u lanes, %u streams, %s D-PHY\n",
|
||||
csi2rx->num_lanes, csi2rx->max_lanes, csi2rx->max_streams,
|
||||
+ csi2rx->dphy ? "external" :
|
||||
csi2rx->has_internal_dphy ? "internal" : "no");
|
||||
|
||||
return 0;
|
@ -0,0 +1,23 @@
|
||||
From d541f0ab42983dbc856f2229ee471677e80945a3 Mon Sep 17 00:00:00 2001
|
||||
From: Jack Zhu <jack.zhu@starfivetech.com>
|
||||
Date: Tue, 23 May 2023 16:56:26 +0800
|
||||
Subject: [PATCH 080/122] media: cadence: Add support for JH7110 SoC
|
||||
|
||||
Add support for Starfive JH7110 SoC which has the cadence csi2 receiver.
|
||||
|
||||
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
|
||||
Signed-off-by: Jack Zhu <jack.zhu@starfivetech.com>
|
||||
---
|
||||
drivers/media/platform/cadence/cdns-csi2rx.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
--- a/drivers/media/platform/cadence/cdns-csi2rx.c
|
||||
+++ b/drivers/media/platform/cadence/cdns-csi2rx.c
|
||||
@@ -565,6 +565,7 @@ static int csi2rx_remove(struct platform
|
||||
}
|
||||
|
||||
static const struct of_device_id csi2rx_of_table[] = {
|
||||
+ { .compatible = "starfive,jh7110-csi2rx" },
|
||||
{ .compatible = "cdns,csi2rx" },
|
||||
{ },
|
||||
};
|
@ -0,0 +1,197 @@
|
||||
From f3195b45a3845fd3892ca932a9cc8e352942dbcd Mon Sep 17 00:00:00 2001
|
||||
From: Jack Zhu <jack.zhu@starfivetech.com>
|
||||
Date: Fri, 12 May 2023 18:28:39 +0800
|
||||
Subject: [PATCH 081/122] media: dt-bindings: Add JH7110 Camera Subsystem
|
||||
|
||||
Add the bindings documentation for Starfive JH7110 Camera Subsystem
|
||||
which is used for handing image sensor data.
|
||||
|
||||
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
|
||||
Signed-off-by: Jack Zhu <jack.zhu@starfivetech.com>
|
||||
---
|
||||
.../bindings/media/starfive,jh7110-camss.yaml | 179 ++++++++++++++++++
|
||||
1 file changed, 179 insertions(+)
|
||||
create mode 100644 Documentation/devicetree/bindings/media/starfive,jh7110-camss.yaml
|
||||
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/media/starfive,jh7110-camss.yaml
|
||||
@@ -0,0 +1,179 @@
|
||||
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
+%YAML 1.2
|
||||
+---
|
||||
+$id: http://devicetree.org/schemas/media/starfive,jh7110-camss.yaml#
|
||||
+$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
+
|
||||
+title: Starfive SoC CAMSS ISP
|
||||
+
|
||||
+maintainers:
|
||||
+ - Jack Zhu <jack.zhu@starfivetech.com>
|
||||
+ - Changhuang Liang <changhuang.liang@starfivetech.com>
|
||||
+
|
||||
+description:
|
||||
+ The Starfive CAMSS ISP is a Camera interface for Starfive JH7110 SoC. It
|
||||
+ consists of a VIN controller (Video In Controller, a top-level control until)
|
||||
+ and an ISP.
|
||||
+
|
||||
+properties:
|
||||
+ compatible:
|
||||
+ const: starfive,jh7110-camss
|
||||
+
|
||||
+ reg:
|
||||
+ maxItems: 2
|
||||
+
|
||||
+ reg-names:
|
||||
+ items:
|
||||
+ - const: syscon
|
||||
+ - const: isp
|
||||
+
|
||||
+ clocks:
|
||||
+ maxItems: 7
|
||||
+
|
||||
+ clock-names:
|
||||
+ items:
|
||||
+ - const: apb_func
|
||||
+ - const: wrapper_clk_c
|
||||
+ - const: dvp_inv
|
||||
+ - const: axiwr
|
||||
+ - const: mipi_rx0_pxl
|
||||
+ - const: ispcore_2x
|
||||
+ - const: isp_axi
|
||||
+
|
||||
+ resets:
|
||||
+ maxItems: 6
|
||||
+
|
||||
+ reset-names:
|
||||
+ items:
|
||||
+ - const: wrapper_p
|
||||
+ - const: wrapper_c
|
||||
+ - const: axird
|
||||
+ - const: axiwr
|
||||
+ - const: isp_top_n
|
||||
+ - const: isp_top_axi
|
||||
+
|
||||
+ power-domains:
|
||||
+ items:
|
||||
+ - description: JH7110 ISP Power Domain Switch Controller.
|
||||
+
|
||||
+ interrupts:
|
||||
+ maxItems: 4
|
||||
+
|
||||
+ ports:
|
||||
+ $ref: /schemas/graph.yaml#/properties/ports
|
||||
+
|
||||
+ properties:
|
||||
+ port@0:
|
||||
+ $ref: /schemas/graph.yaml#/$defs/port-base
|
||||
+ unevaluatedProperties: false
|
||||
+ description: Input port for receiving DVP data.
|
||||
+
|
||||
+ properties:
|
||||
+ endpoint:
|
||||
+ $ref: video-interfaces.yaml#
|
||||
+ unevaluatedProperties: false
|
||||
+
|
||||
+ properties:
|
||||
+ bus-type:
|
||||
+ enum: [5, 6]
|
||||
+
|
||||
+ bus-width:
|
||||
+ enum: [8, 10, 12]
|
||||
+
|
||||
+ data-shift:
|
||||
+ enum: [0, 2]
|
||||
+ default: 0
|
||||
+
|
||||
+ hsync-active:
|
||||
+ enum: [0, 1]
|
||||
+ default: 1
|
||||
+
|
||||
+ vsync-active:
|
||||
+ enum: [0, 1]
|
||||
+ default: 1
|
||||
+
|
||||
+ required:
|
||||
+ - bus-type
|
||||
+ - bus-width
|
||||
+
|
||||
+ port@1:
|
||||
+ $ref: /schemas/graph.yaml#/properties/port
|
||||
+ description: Input port for receiving CSI data.
|
||||
+
|
||||
+ required:
|
||||
+ - port@0
|
||||
+ - port@1
|
||||
+
|
||||
+required:
|
||||
+ - compatible
|
||||
+ - reg
|
||||
+ - reg-names
|
||||
+ - clocks
|
||||
+ - clock-names
|
||||
+ - resets
|
||||
+ - reset-names
|
||||
+ - power-domains
|
||||
+ - interrupts
|
||||
+ - ports
|
||||
+
|
||||
+additionalProperties: false
|
||||
+
|
||||
+examples:
|
||||
+ - |
|
||||
+ isp@19840000 {
|
||||
+ compatible = "starfive,jh7110-camss";
|
||||
+ reg = <0x19840000 0x10000>,
|
||||
+ <0x19870000 0x30000>;
|
||||
+ reg-names = "syscon", "isp";
|
||||
+ clocks = <&ispcrg 0>,
|
||||
+ <&ispcrg 13>,
|
||||
+ <&ispcrg 2>,
|
||||
+ <&ispcrg 12>,
|
||||
+ <&ispcrg 1>,
|
||||
+ <&syscrg 51>,
|
||||
+ <&syscrg 52>;
|
||||
+ clock-names = "apb_func",
|
||||
+ "wrapper_clk_c",
|
||||
+ "dvp_inv",
|
||||
+ "axiwr",
|
||||
+ "mipi_rx0_pxl",
|
||||
+ "ispcore_2x",
|
||||
+ "isp_axi";
|
||||
+ resets = <&ispcrg 0>,
|
||||
+ <&ispcrg 1>,
|
||||
+ <&ispcrg 10>,
|
||||
+ <&ispcrg 11>,
|
||||
+ <&syscrg 41>,
|
||||
+ <&syscrg 42>;
|
||||
+ reset-names = "wrapper_p",
|
||||
+ "wrapper_c",
|
||||
+ "axird",
|
||||
+ "axiwr",
|
||||
+ "isp_top_n",
|
||||
+ "isp_top_axi";
|
||||
+ power-domains = <&pwrc 5>;
|
||||
+ interrupts = <92>, <87>, <88>, <90>;
|
||||
+
|
||||
+ ports {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ port@0 {
|
||||
+ reg = <0>;
|
||||
+ vin_from_sc2235: endpoint {
|
||||
+ remote-endpoint = <&sc2235_to_vin>;
|
||||
+ bus-width = <8>;
|
||||
+ data-shift = <2>;
|
||||
+ hsync-active = <1>;
|
||||
+ vsync-active = <0>;
|
||||
+ pclk-sample = <1>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ port@1 {
|
||||
+ reg = <1>;
|
||||
+ vin_from_csi2rx: endpoint {
|
||||
+ remote-endpoint = <&csi2rx_to_vin>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
@ -0,0 +1,106 @@
|
||||
From 949807343300a75b6e7c3e47463f817a7b6bc790 Mon Sep 17 00:00:00 2001
|
||||
From: Jack Zhu <jack.zhu@starfivetech.com>
|
||||
Date: Fri, 12 May 2023 18:28:40 +0800
|
||||
Subject: [PATCH 082/122] media: admin-guide: Add starfive_camss.rst for
|
||||
Starfive Camera Subsystem
|
||||
|
||||
Add starfive_camss.rst file that documents the Starfive Camera
|
||||
Subsystem driver which is used for handing image sensor data.
|
||||
|
||||
Signed-off-by: Jack Zhu <jack.zhu@starfivetech.com>
|
||||
---
|
||||
.../admin-guide/media/starfive_camss.rst | 57 +++++++++++++++++++
|
||||
.../media/starfive_camss_graph.dot | 16 ++++++
|
||||
.../admin-guide/media/v4l-drivers.rst | 1 +
|
||||
3 files changed, 74 insertions(+)
|
||||
create mode 100644 Documentation/admin-guide/media/starfive_camss.rst
|
||||
create mode 100644 Documentation/admin-guide/media/starfive_camss_graph.dot
|
||||
|
||||
--- /dev/null
|
||||
+++ b/Documentation/admin-guide/media/starfive_camss.rst
|
||||
@@ -0,0 +1,57 @@
|
||||
+.. SPDX-License-Identifier: GPL-2.0
|
||||
+
|
||||
+.. include:: <isonum.txt>
|
||||
+
|
||||
+================================
|
||||
+Starfive Camera Subsystem driver
|
||||
+================================
|
||||
+
|
||||
+Introduction
|
||||
+------------
|
||||
+
|
||||
+This file documents the driver for the Starfive Camera Subsystem found on
|
||||
+Starfive JH7110 SoC. The driver is located under drivers/media/platform/
|
||||
+starfive.
|
||||
+
|
||||
+The driver implements V4L2, Media controller and v4l2_subdev interfaces.
|
||||
+Camera sensor using V4L2 subdev interface in the kernel is supported.
|
||||
+
|
||||
+The driver has been successfully used on the Gstreamer 1.18.5 with
|
||||
+v4l2src plugin.
|
||||
+
|
||||
+
|
||||
+Starfive Camera Subsystem hardware
|
||||
+----------------------------------
|
||||
+
|
||||
+The Starfive Camera Subsystem hardware consists of:
|
||||
+
|
||||
+- MIPI DPHY Receiver: receives mipi data from a MIPI camera sensor.
|
||||
+- MIPI CSIRx Controller: is responsible for handling and decoding CSI2 protocol
|
||||
+ based camera sensor data stream.
|
||||
+- ISP: handles the image data streams from the MIPI CSIRx Controller.
|
||||
+- VIN(Video In): a top-level module, is responsible for controlling power
|
||||
+ and clocks to other modules, dumps the input data to memory or transfers the
|
||||
+ input data to ISP.
|
||||
+
|
||||
+
|
||||
+Topology
|
||||
+--------
|
||||
+
|
||||
+The media controller pipeline graph is as follows:
|
||||
+
|
||||
+.. _starfive_camss_graph:
|
||||
+
|
||||
+.. kernel-figure:: starfive_camss_graph.dot
|
||||
+ :alt: starfive_camss_graph.dot
|
||||
+ :align: center
|
||||
+
|
||||
+The driver has 2 video devices:
|
||||
+
|
||||
+- stf_vin0_wr_video0: capture device for images directly from the VIN module.
|
||||
+- stf_vin0_isp0_video1: capture device for images without scaling.
|
||||
+
|
||||
+The driver has 3 subdevices:
|
||||
+
|
||||
+- stf_isp0: is responsible for all the isp operations.
|
||||
+- stf_vin0_wr: used to dump RAW images to memory.
|
||||
+- stf_vin0_isp0: used to capture images for the stf_vin0_isp0_video1 device.
|
||||
--- /dev/null
|
||||
+++ b/Documentation/admin-guide/media/starfive_camss_graph.dot
|
||||
@@ -0,0 +1,16 @@
|
||||
+digraph board {
|
||||
+ rankdir=TB
|
||||
+ n00000001 [label="{{<port0> 0} | stf_isp0\n/dev/v4l-subdev0 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
|
||||
+ n00000001:port1 -> n0000000d:port0
|
||||
+ n00000004 [label="{{<port0> 0} | stf_vin0_wr\n/dev/v4l-subdev1 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
|
||||
+ n00000004:port1 -> n00000007 [style=bold]
|
||||
+ n00000007 [label="stf_vin0_wr_video0\n/dev/video0", shape=box, style=filled, fillcolor=yellow]
|
||||
+ n0000000d [label="{{<port0> 0} | stf_vin0_isp0\n/dev/v4l-subdev2 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
|
||||
+ n0000000d:port1 -> n00000010 [style=bold]
|
||||
+ n00000010 [label="stf_vin0_isp0_video1\n/dev/video1", shape=box, style=filled, fillcolor=yellow]
|
||||
+ n00000018 [label="{{<port0> 0} | cdns_csi2rx.19800000.csi-bridge\n | {<port1> 1 | <port2> 2 | <port3> 3 | <port4> 4}}", shape=Mrecord, style=filled, fillcolor=green]
|
||||
+ n00000018:port1 -> n00000004:port0 [style=dashed]
|
||||
+ n00000018:port1 -> n00000001:port0
|
||||
+ n00000028 [label="{{} | imx219 6-0010\n | {<port0> 0}}", shape=Mrecord, style=filled, fillcolor=green]
|
||||
+ n00000028:port0 -> n00000018:port0 [style=bold]
|
||||
+}
|
||||
--- a/Documentation/admin-guide/media/v4l-drivers.rst
|
||||
+++ b/Documentation/admin-guide/media/v4l-drivers.rst
|
||||
@@ -30,5 +30,6 @@ Video4Linux (V4L) driver-specific docume
|
||||
si470x
|
||||
si4713
|
||||
si476x
|
||||
+ starfive_camss
|
||||
vimc
|
||||
vivid
|
@ -0,0 +1,630 @@
|
||||
From 0dc93c9321ba947ac429baeb58202496e4b0f219 Mon Sep 17 00:00:00 2001
|
||||
From: Jack Zhu <jack.zhu@starfivetech.com>
|
||||
Date: Fri, 12 May 2023 18:28:41 +0800
|
||||
Subject: [PATCH 083/122] media: starfive: Add basic driver
|
||||
|
||||
Add basic platform driver for StarFive Camera Subsystem.
|
||||
|
||||
Signed-off-by: Jack Zhu <jack.zhu@starfivetech.com>
|
||||
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
|
||||
---
|
||||
drivers/media/platform/Kconfig | 1 +
|
||||
drivers/media/platform/Makefile | 1 +
|
||||
drivers/media/platform/starfive/Kconfig | 19 +
|
||||
drivers/media/platform/starfive/Makefile | 9 +
|
||||
drivers/media/platform/starfive/stf_camss.c | 372 +++++++++++++++++++
|
||||
drivers/media/platform/starfive/stf_camss.h | 153 ++++++++
|
||||
drivers/media/platform/starfive/stf_common.h | 18 +
|
||||
7 files changed, 573 insertions(+)
|
||||
create mode 100644 drivers/media/platform/starfive/Kconfig
|
||||
create mode 100644 drivers/media/platform/starfive/Makefile
|
||||
create mode 100644 drivers/media/platform/starfive/stf_camss.c
|
||||
create mode 100644 drivers/media/platform/starfive/stf_camss.h
|
||||
create mode 100644 drivers/media/platform/starfive/stf_common.h
|
||||
|
||||
--- a/drivers/media/platform/Kconfig
|
||||
+++ b/drivers/media/platform/Kconfig
|
||||
@@ -79,6 +79,7 @@ source "drivers/media/platform/renesas/K
|
||||
source "drivers/media/platform/rockchip/Kconfig"
|
||||
source "drivers/media/platform/samsung/Kconfig"
|
||||
source "drivers/media/platform/st/Kconfig"
|
||||
+source "drivers/media/platform/starfive/Kconfig"
|
||||
source "drivers/media/platform/sunxi/Kconfig"
|
||||
source "drivers/media/platform/ti/Kconfig"
|
||||
source "drivers/media/platform/verisilicon/Kconfig"
|
||||
--- a/drivers/media/platform/Makefile
|
||||
+++ b/drivers/media/platform/Makefile
|
||||
@@ -22,6 +22,7 @@ obj-y += renesas/
|
||||
obj-y += rockchip/
|
||||
obj-y += samsung/
|
||||
obj-y += st/
|
||||
+obj-y += starfive/
|
||||
obj-y += sunxi/
|
||||
obj-y += ti/
|
||||
obj-y += verisilicon/
|
||||
--- /dev/null
|
||||
+++ b/drivers/media/platform/starfive/Kconfig
|
||||
@@ -0,0 +1,19 @@
|
||||
+# SPDX-License-Identifier: GPL-2.0-only
|
||||
+
|
||||
+comment "Starfive media platform drivers"
|
||||
+
|
||||
+config VIDEO_STARFIVE_CAMSS
|
||||
+ tristate "Starfive Camera Subsystem driver"
|
||||
+ depends on V4L_PLATFORM_DRIVERS
|
||||
+ depends on VIDEO_DEV && OF
|
||||
+ depends on DMA_CMA
|
||||
+ select MEDIA_CONTROLLER
|
||||
+ select VIDEO_V4L2_SUBDEV_API
|
||||
+ select VIDEOBUF2_DMA_CONTIG
|
||||
+ select V4L2_FWNODE
|
||||
+ help
|
||||
+ Enable this to support for the Starfive Camera subsystem
|
||||
+ found on Starfive JH7110 SoC.
|
||||
+
|
||||
+ To compile this driver as a module, choose M here: the
|
||||
+ module will be called stf-camss.
|
||||
--- /dev/null
|
||||
+++ b/drivers/media/platform/starfive/Makefile
|
||||
@@ -0,0 +1,9 @@
|
||||
+# SPDX-License-Identifier: GPL-2.0
|
||||
+#
|
||||
+# Makefile for StarFive camera subsystem driver.
|
||||
+#
|
||||
+
|
||||
+starfive-camss-objs += \
|
||||
+ stf_camss.o
|
||||
+
|
||||
+obj-$(CONFIG_VIDEO_STARFIVE_CAMSS) += starfive-camss.o \
|
||||
--- /dev/null
|
||||
+++ b/drivers/media/platform/starfive/stf_camss.c
|
||||
@@ -0,0 +1,372 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0
|
||||
+/*
|
||||
+ * stf_camss.c
|
||||
+ *
|
||||
+ * Starfive Camera Subsystem driver
|
||||
+ *
|
||||
+ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
|
||||
+ */
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/of.h>
|
||||
+#include <linux/of_graph.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/pm_runtime.h>
|
||||
+#include <linux/videodev2.h>
|
||||
+#include <media/media-device.h>
|
||||
+#include <media/v4l2-async.h>
|
||||
+#include <media/v4l2-fwnode.h>
|
||||
+#include <media/v4l2-mc.h>
|
||||
+
|
||||
+#include "stf_camss.h"
|
||||
+
|
||||
+static const char * const stfcamss_clocks[] = {
|
||||
+ "clk_apb_func",
|
||||
+ "clk_wrapper_clk_c",
|
||||
+ "clk_dvp_inv",
|
||||
+ "clk_axiwr",
|
||||
+ "clk_mipi_rx0_pxl",
|
||||
+ "clk_ispcore_2x",
|
||||
+ "clk_isp_axi",
|
||||
+};
|
||||
+
|
||||
+static const char * const stfcamss_resets[] = {
|
||||
+ "rst_wrapper_p",
|
||||
+ "rst_wrapper_c",
|
||||
+ "rst_axird",
|
||||
+ "rst_axiwr",
|
||||
+ "rst_isp_top_n",
|
||||
+ "rst_isp_top_axi",
|
||||
+};
|
||||
+
|
||||
+static int stfcamss_get_mem_res(struct platform_device *pdev,
|
||||
+ struct stfcamss *stfcamss)
|
||||
+{
|
||||
+ stfcamss->syscon_base =
|
||||
+ devm_platform_ioremap_resource_byname(pdev, "syscon");
|
||||
+ if (IS_ERR(stfcamss->syscon_base))
|
||||
+ return PTR_ERR(stfcamss->syscon_base);
|
||||
+
|
||||
+ stfcamss->isp_base =
|
||||
+ devm_platform_ioremap_resource_byname(pdev, "isp");
|
||||
+ if (IS_ERR(stfcamss->isp_base))
|
||||
+ return PTR_ERR(stfcamss->isp_base);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * stfcamss_of_parse_endpoint_node - Parse port endpoint node
|
||||
+ * @dev: Device
|
||||
+ * @node: Device node to be parsed
|
||||
+ * @csd: Parsed data from port endpoint node
|
||||
+ *
|
||||
+ * Return 0 on success or a negative error code on failure
|
||||
+ */
|
||||
+static int stfcamss_of_parse_endpoint_node(struct device *dev,
|
||||
+ struct device_node *node,
|
||||
+ struct stfcamss_async_subdev *csd)
|
||||
+{
|
||||
+ struct v4l2_fwnode_endpoint vep = { { 0 } };
|
||||
+
|
||||
+ v4l2_fwnode_endpoint_parse(of_fwnode_handle(node), &vep);
|
||||
+ dev_dbg(dev, "vep.base.port = 0x%x, id = 0x%x\n",
|
||||
+ vep.base.port, vep.base.id);
|
||||
+
|
||||
+ csd->port = vep.base.port;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * stfcamss_of_parse_ports - Parse ports node
|
||||
+ * @stfcamss: STFCAMSS device
|
||||
+ *
|
||||
+ * Return number of "port" nodes found in "ports" node
|
||||
+ */
|
||||
+static int stfcamss_of_parse_ports(struct stfcamss *stfcamss)
|
||||
+{
|
||||
+ struct device *dev = stfcamss->dev;
|
||||
+ struct device_node *node = NULL;
|
||||
+ struct device_node *remote = NULL;
|
||||
+ int ret, num_subdevs = 0;
|
||||
+
|
||||
+ for_each_endpoint_of_node(dev->of_node, node) {
|
||||
+ struct stfcamss_async_subdev *csd;
|
||||
+
|
||||
+ if (!of_device_is_available(node))
|
||||
+ continue;
|
||||
+
|
||||
+ remote = of_graph_get_remote_port_parent(node);
|
||||
+ if (!remote) {
|
||||
+ dev_err(dev, "Cannot get remote parent\n");
|
||||
+ ret = -EINVAL;
|
||||
+ goto err_cleanup;
|
||||
+ }
|
||||
+
|
||||
+ csd = v4l2_async_nf_add_fwnode(&stfcamss->notifier,
|
||||
+ of_fwnode_handle(remote),
|
||||
+ struct stfcamss_async_subdev);
|
||||
+ of_node_put(remote);
|
||||
+ if (IS_ERR(csd)) {
|
||||
+ ret = PTR_ERR(csd);
|
||||
+ goto err_cleanup;
|
||||
+ }
|
||||
+
|
||||
+ ret = stfcamss_of_parse_endpoint_node(dev, node, csd);
|
||||
+ if (ret < 0)
|
||||
+ goto err_cleanup;
|
||||
+
|
||||
+ num_subdevs++;
|
||||
+ }
|
||||
+
|
||||
+ return num_subdevs;
|
||||
+
|
||||
+err_cleanup:
|
||||
+ of_node_put(node);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int stfcamss_subdev_notifier_bound(struct v4l2_async_notifier *async,
|
||||
+ struct v4l2_subdev *subdev,
|
||||
+ struct v4l2_async_subdev *asd)
|
||||
+{
|
||||
+ struct stfcamss *stfcamss =
|
||||
+ container_of(async, struct stfcamss, notifier);
|
||||
+ struct host_data *host_data = &stfcamss->host_data;
|
||||
+ struct media_entity *source;
|
||||
+ int i, j;
|
||||
+
|
||||
+ source = &subdev->entity;
|
||||
+
|
||||
+ for (i = 0; i < source->num_pads; i++) {
|
||||
+ if (source->pads[i].flags & MEDIA_PAD_FL_SOURCE)
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if (i == source->num_pads) {
|
||||
+ dev_err(stfcamss->dev, "No source pad in external entity\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ for (j = 0; host_data->host_entity[j] && (j < HOST_ENTITY_MAX); j++) {
|
||||
+ struct media_entity *input;
|
||||
+ int ret;
|
||||
+
|
||||
+ input = host_data->host_entity[j];
|
||||
+
|
||||
+ ret = media_create_pad_link(
|
||||
+ source,
|
||||
+ i,
|
||||
+ input,
|
||||
+ STF_PAD_SINK,
|
||||
+ source->function == MEDIA_ENT_F_CAM_SENSOR ?
|
||||
+ MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED :
|
||||
+ 0);
|
||||
+ if (ret < 0) {
|
||||
+ dev_err(stfcamss->dev,
|
||||
+ "Failed to link %s->%s entities: %d\n",
|
||||
+ source->name, input->name, ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int stfcamss_subdev_notifier_complete(struct v4l2_async_notifier *ntf)
|
||||
+{
|
||||
+ struct stfcamss *stfcamss =
|
||||
+ container_of(ntf, struct stfcamss, notifier);
|
||||
+
|
||||
+ return v4l2_device_register_subdev_nodes(&stfcamss->v4l2_dev);
|
||||
+}
|
||||
+
|
||||
+static const struct v4l2_async_notifier_operations
|
||||
+stfcamss_subdev_notifier_ops = {
|
||||
+ .bound = stfcamss_subdev_notifier_bound,
|
||||
+ .complete = stfcamss_subdev_notifier_complete,
|
||||
+};
|
||||
+
|
||||
+static const struct media_device_ops stfcamss_media_ops = {
|
||||
+ .link_notify = v4l2_pipeline_link_notify,
|
||||
+};
|
||||
+
|
||||
+static void stfcamss_mc_init(struct platform_device *pdev,
|
||||
+ struct stfcamss *stfcamss)
|
||||
+{
|
||||
+ stfcamss->media_dev.dev = stfcamss->dev;
|
||||
+ strscpy(stfcamss->media_dev.model, "Starfive Camera Subsystem",
|
||||
+ sizeof(stfcamss->media_dev.model));
|
||||
+ snprintf(stfcamss->media_dev.bus_info,
|
||||
+ sizeof(stfcamss->media_dev.bus_info),
|
||||
+ "%s:%s", dev_bus_name(&pdev->dev), pdev->name);
|
||||
+ stfcamss->media_dev.hw_revision = 0x01;
|
||||
+ stfcamss->media_dev.ops = &stfcamss_media_ops;
|
||||
+ media_device_init(&stfcamss->media_dev);
|
||||
+
|
||||
+ stfcamss->v4l2_dev.mdev = &stfcamss->media_dev;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * stfcamss_probe - Probe STFCAMSS platform device
|
||||
+ * @pdev: Pointer to STFCAMSS platform device
|
||||
+ *
|
||||
+ * Return 0 on success or a negative error code on failure
|
||||
+ */
|
||||
+static int stfcamss_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct stfcamss *stfcamss;
|
||||
+ struct device *dev = &pdev->dev;
|
||||
+ int ret = 0, i, num_subdevs;
|
||||
+
|
||||
+ stfcamss = devm_kzalloc(dev, sizeof(*stfcamss), GFP_KERNEL);
|
||||
+ if (!stfcamss)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ for (i = 0; i < ARRAY_SIZE(stfcamss->irq); ++i) {
|
||||
+ stfcamss->irq[i] = platform_get_irq(pdev, i);
|
||||
+ if (stfcamss->irq[i] < 0)
|
||||
+ return dev_err_probe(&pdev->dev, stfcamss->irq[i],
|
||||
+ "Failed to get clock%d", i);
|
||||
+ }
|
||||
+
|
||||
+ stfcamss->nclks = ARRAY_SIZE(stfcamss->sys_clk);
|
||||
+ for (i = 0; i < ARRAY_SIZE(stfcamss->sys_clk); ++i)
|
||||
+ stfcamss->sys_clk[i].id = stfcamss_clocks[i];
|
||||
+ ret = devm_clk_bulk_get(dev, stfcamss->nclks, stfcamss->sys_clk);
|
||||
+ if (ret) {
|
||||
+ dev_err(dev, "Failed to get clk controls\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ stfcamss->nrsts = ARRAY_SIZE(stfcamss->sys_rst);
|
||||
+ for (i = 0; i < ARRAY_SIZE(stfcamss->sys_rst); ++i)
|
||||
+ stfcamss->sys_rst[i].id = stfcamss_resets[i];
|
||||
+ ret = devm_reset_control_bulk_get_shared(dev, stfcamss->nrsts,
|
||||
+ stfcamss->sys_rst);
|
||||
+ if (ret) {
|
||||
+ dev_err(dev, "Failed to get reset controls\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ ret = stfcamss_get_mem_res(pdev, stfcamss);
|
||||
+ if (ret) {
|
||||
+ dev_err(dev, "Could not map registers\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ stfcamss->dev = dev;
|
||||
+ platform_set_drvdata(pdev, stfcamss);
|
||||
+
|
||||
+ v4l2_async_nf_init(&stfcamss->notifier);
|
||||
+
|
||||
+ num_subdevs = stfcamss_of_parse_ports(stfcamss);
|
||||
+ if (num_subdevs < 0) {
|
||||
+ dev_err(dev, "Failed to find subdevices\n");
|
||||
+ return -ENODEV;
|
||||
+ }
|
||||
+
|
||||
+ stfcamss_mc_init(pdev, stfcamss);
|
||||
+
|
||||
+ ret = v4l2_device_register(stfcamss->dev, &stfcamss->v4l2_dev);
|
||||
+ if (ret < 0) {
|
||||
+ dev_err(dev, "Failed to register V4L2 device: %d\n", ret);
|
||||
+ goto err_cleanup_notifier;
|
||||
+ }
|
||||
+
|
||||
+ ret = media_device_register(&stfcamss->media_dev);
|
||||
+ if (ret) {
|
||||
+ dev_err(dev, "Failed to register media device: %d\n", ret);
|
||||
+ goto err_unregister_device;
|
||||
+ }
|
||||
+
|
||||
+ stfcamss->notifier.ops = &stfcamss_subdev_notifier_ops;
|
||||
+ ret = v4l2_async_nf_register(&stfcamss->v4l2_dev, &stfcamss->notifier);
|
||||
+ if (ret) {
|
||||
+ dev_err(dev, "Failed to register async subdev nodes: %d\n",
|
||||
+ ret);
|
||||
+ goto err_unregister_media_dev;
|
||||
+ }
|
||||
+
|
||||
+ pm_runtime_enable(dev);
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+err_unregister_media_dev:
|
||||
+ media_device_unregister(&stfcamss->media_dev);
|
||||
+err_unregister_device:
|
||||
+ v4l2_device_unregister(&stfcamss->v4l2_dev);
|
||||
+err_cleanup_notifier:
|
||||
+ v4l2_async_nf_cleanup(&stfcamss->notifier);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * stfcamss_remove - Remove STFCAMSS platform device
|
||||
+ * @pdev: Pointer to STFCAMSS platform device
|
||||
+ *
|
||||
+ * Always returns 0.
|
||||
+ */
|
||||
+static int stfcamss_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct stfcamss *stfcamss = platform_get_drvdata(pdev);
|
||||
+
|
||||
+ v4l2_device_unregister(&stfcamss->v4l2_dev);
|
||||
+ media_device_cleanup(&stfcamss->media_dev);
|
||||
+ pm_runtime_disable(&pdev->dev);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct of_device_id stfcamss_of_match[] = {
|
||||
+ { .compatible = "starfive,jh7110-camss" },
|
||||
+ { /* sentinel */ },
|
||||
+};
|
||||
+
|
||||
+MODULE_DEVICE_TABLE(of, stfcamss_of_match);
|
||||
+
|
||||
+static int __maybe_unused stfcamss_runtime_suspend(struct device *dev)
|
||||
+{
|
||||
+ struct stfcamss *stfcamss = dev_get_drvdata(dev);
|
||||
+
|
||||
+ reset_control_assert(stfcamss->sys_rst[STF_RST_ISP_TOP_AXI].rstc);
|
||||
+ reset_control_assert(stfcamss->sys_rst[STF_RST_ISP_TOP_N].rstc);
|
||||
+ clk_disable_unprepare(stfcamss->sys_clk[STF_CLK_ISP_AXI].clk);
|
||||
+ clk_disable_unprepare(stfcamss->sys_clk[STF_CLK_ISPCORE_2X].clk);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int __maybe_unused stfcamss_runtime_resume(struct device *dev)
|
||||
+{
|
||||
+ struct stfcamss *stfcamss = dev_get_drvdata(dev);
|
||||
+
|
||||
+ clk_prepare_enable(stfcamss->sys_clk[STF_CLK_ISPCORE_2X].clk);
|
||||
+ clk_prepare_enable(stfcamss->sys_clk[STF_CLK_ISP_AXI].clk);
|
||||
+ reset_control_deassert(stfcamss->sys_rst[STF_RST_ISP_TOP_N].rstc);
|
||||
+ reset_control_deassert(stfcamss->sys_rst[STF_RST_ISP_TOP_AXI].rstc);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct dev_pm_ops stfcamss_pm_ops = {
|
||||
+ SET_RUNTIME_PM_OPS(stfcamss_runtime_suspend,
|
||||
+ stfcamss_runtime_resume,
|
||||
+ NULL)
|
||||
+};
|
||||
+
|
||||
+static struct platform_driver stfcamss_driver = {
|
||||
+ .probe = stfcamss_probe,
|
||||
+ .remove = stfcamss_remove,
|
||||
+ .driver = {
|
||||
+ .name = DRV_NAME,
|
||||
+ .pm = &stfcamss_pm_ops,
|
||||
+ .of_match_table = of_match_ptr(stfcamss_of_match),
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+module_platform_driver(stfcamss_driver);
|
||||
+
|
||||
+MODULE_AUTHOR("StarFive Corporation");
|
||||
+MODULE_DESCRIPTION("StarFive Camera Subsystem driver");
|
||||
+MODULE_LICENSE("GPL");
|
||||
--- /dev/null
|
||||
+++ b/drivers/media/platform/starfive/stf_camss.h
|
||||
@@ -0,0 +1,153 @@
|
||||
+/* SPDX-License-Identifier: GPL-2.0 */
|
||||
+/*
|
||||
+ * stf_camss.h
|
||||
+ *
|
||||
+ * Starfive Camera Subsystem driver
|
||||
+ *
|
||||
+ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
|
||||
+ */
|
||||
+
|
||||
+#ifndef STF_CAMSS_H
|
||||
+#define STF_CAMSS_H
|
||||
+
|
||||
+#include <linux/clk.h>
|
||||
+#include <linux/delay.h>
|
||||
+#include <linux/reset.h>
|
||||
+#include <media/v4l2-device.h>
|
||||
+
|
||||
+#include "stf_common.h"
|
||||
+
|
||||
+#define DRV_NAME "starfive-camss"
|
||||
+#define STF_DVP_NAME "stf_dvp"
|
||||
+#define STF_CSI_NAME "cdns_csi2rx"
|
||||
+#define STF_ISP_NAME "stf_isp"
|
||||
+#define STF_VIN_NAME "stf_vin"
|
||||
+
|
||||
+#define STF_PAD_SINK 0
|
||||
+#define STF_PAD_SRC 1
|
||||
+#define STF_PADS_NUM 2
|
||||
+
|
||||
+enum port_num {
|
||||
+ PORT_NUMBER_DVP_SENSOR = 0,
|
||||
+ PORT_NUMBER_CSI2RX
|
||||
+};
|
||||
+
|
||||
+enum stf_clk {
|
||||
+ STF_CLK_APB_FUNC = 0,
|
||||
+ STF_CLK_WRAPPER_CLK_C,
|
||||
+ STF_CLK_DVP_INV,
|
||||
+ STF_CLK_AXIWR,
|
||||
+ STF_CLK_MIPI_RX0_PXL,
|
||||
+ STF_CLK_ISPCORE_2X,
|
||||
+ STF_CLK_ISP_AXI,
|
||||
+ STF_CLK_NUM
|
||||
+};
|
||||
+
|
||||
+enum stf_rst {
|
||||
+ STF_RST_WRAPPER_P = 0,
|
||||
+ STF_RST_WRAPPER_C,
|
||||
+ STF_RST_AXIRD,
|
||||
+ STF_RST_AXIWR,
|
||||
+ STF_RST_ISP_TOP_N,
|
||||
+ STF_RST_ISP_TOP_AXI,
|
||||
+ STF_RST_NUM
|
||||
+};
|
||||
+
|
||||
+enum stf_irq {
|
||||
+ STF_IRQ_VINWR = 0,
|
||||
+ STF_IRQ_ISP,
|
||||
+ STF_IRQ_ISPCSIL,
|
||||
+ STF_IRQ_NUM
|
||||
+};
|
||||
+
|
||||
+#define HOST_ENTITY_MAX 2
|
||||
+
|
||||
+struct host_data {
|
||||
+ struct media_entity *host_entity[HOST_ENTITY_MAX];
|
||||
+};
|
||||
+
|
||||
+struct stfcamss {
|
||||
+ struct v4l2_device v4l2_dev;
|
||||
+ struct media_device media_dev;
|
||||
+ struct media_pipeline pipe;
|
||||
+ struct device *dev;
|
||||
+ struct v4l2_async_notifier notifier;
|
||||
+ struct host_data host_data;
|
||||
+ void __iomem *syscon_base;
|
||||
+ void __iomem *isp_base;
|
||||
+ int irq[STF_IRQ_NUM];
|
||||
+ struct clk_bulk_data sys_clk[STF_CLK_NUM];
|
||||
+ int nclks;
|
||||
+ struct reset_control_bulk_data sys_rst[STF_RST_NUM];
|
||||
+ int nrsts;
|
||||
+};
|
||||
+
|
||||
+struct stfcamss_async_subdev {
|
||||
+ struct v4l2_async_subdev asd; /* must be first */
|
||||
+ enum port_num port;
|
||||
+};
|
||||
+
|
||||
+static inline u32 stf_isp_reg_read(struct stfcamss *stfcamss, u32 reg)
|
||||
+{
|
||||
+ return ioread32(stfcamss->isp_base + reg);
|
||||
+}
|
||||
+
|
||||
+static inline void stf_isp_reg_write(struct stfcamss *stfcamss,
|
||||
+ u32 reg, u32 val)
|
||||
+{
|
||||
+ iowrite32(val, stfcamss->isp_base + reg);
|
||||
+}
|
||||
+
|
||||
+static inline void stf_isp_reg_write_delay(struct stfcamss *stfcamss,
|
||||
+ u32 reg, u32 val, u32 delay)
|
||||
+{
|
||||
+ iowrite32(val, stfcamss->isp_base + reg);
|
||||
+ usleep_range(1000 * delay, 1000 * delay + 100);
|
||||
+}
|
||||
+
|
||||
+static inline void stf_isp_reg_set_bit(struct stfcamss *stfcamss,
|
||||
+ u32 reg, u32 mask, u32 val)
|
||||
+{
|
||||
+ u32 value;
|
||||
+
|
||||
+ value = ioread32(stfcamss->isp_base + reg) & ~mask;
|
||||
+ val &= mask;
|
||||
+ val |= value;
|
||||
+ iowrite32(val, stfcamss->isp_base + reg);
|
||||
+}
|
||||
+
|
||||
+static inline void stf_isp_reg_set(struct stfcamss *stfcamss, u32 reg, u32 mask)
|
||||
+{
|
||||
+ iowrite32(ioread32(stfcamss->isp_base + reg) | mask,
|
||||
+ stfcamss->isp_base + reg);
|
||||
+}
|
||||
+
|
||||
+static inline u32 stf_syscon_reg_read(struct stfcamss *stfcamss, u32 reg)
|
||||
+{
|
||||
+ return ioread32(stfcamss->syscon_base + reg);
|
||||
+}
|
||||
+
|
||||
+static inline void stf_syscon_reg_write(struct stfcamss *stfcamss,
|
||||
+ u32 reg, u32 val)
|
||||
+{
|
||||
+ iowrite32(val, stfcamss->syscon_base + reg);
|
||||
+}
|
||||
+
|
||||
+static inline void stf_syscon_reg_set_bit(struct stfcamss *stfcamss,
|
||||
+ u32 reg, u32 bit_mask)
|
||||
+{
|
||||
+ u32 value;
|
||||
+
|
||||
+ value = ioread32(stfcamss->syscon_base + reg);
|
||||
+ iowrite32(value | bit_mask, stfcamss->syscon_base + reg);
|
||||
+}
|
||||
+
|
||||
+static inline void stf_syscon_reg_clear_bit(struct stfcamss *stfcamss,
|
||||
+ u32 reg, u32 bit_mask)
|
||||
+{
|
||||
+ u32 value;
|
||||
+
|
||||
+ value = ioread32(stfcamss->syscon_base + reg);
|
||||
+ iowrite32(value & ~bit_mask, stfcamss->syscon_base + reg);
|
||||
+}
|
||||
+#endif /* STF_CAMSS_H */
|
||||
--- /dev/null
|
||||
+++ b/drivers/media/platform/starfive/stf_common.h
|
||||
@@ -0,0 +1,18 @@
|
||||
+/* SPDX-License-Identifier: GPL-2.0 */
|
||||
+/*
|
||||
+ * stf_common.h
|
||||
+ *
|
||||
+ * StarFive Camera Subsystem - Common definitions
|
||||
+ *
|
||||
+ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
|
||||
+ */
|
||||
+
|
||||
+#ifndef STF_COMMON_H
|
||||
+#define STF_COMMON_H
|
||||
+
|
||||
+enum stf_subdev_type {
|
||||
+ STF_SUBDEV_TYPE_VIN,
|
||||
+ STF_SUBDEV_TYPE_ISP,
|
||||
+};
|
||||
+
|
||||
+#endif /* STF_COMMON_H */
|
@ -0,0 +1,992 @@
|
||||
From 70a588f7daefe34697ccd04fa6ac3a6d4b63be88 Mon Sep 17 00:00:00 2001
|
||||
From: Jack Zhu <jack.zhu@starfivetech.com>
|
||||
Date: Fri, 12 May 2023 18:28:42 +0800
|
||||
Subject: [PATCH 084/122] media: starfive: Add video driver
|
||||
|
||||
Add video driver for StarFive Camera Subsystem.
|
||||
|
||||
Signed-off-by: Jack Zhu <jack.zhu@starfivetech.com>
|
||||
---
|
||||
drivers/media/platform/starfive/Makefile | 3 +-
|
||||
drivers/media/platform/starfive/stf_video.c | 864 ++++++++++++++++++++
|
||||
drivers/media/platform/starfive/stf_video.h | 95 +++
|
||||
3 files changed, 961 insertions(+), 1 deletion(-)
|
||||
create mode 100644 drivers/media/platform/starfive/stf_video.c
|
||||
create mode 100644 drivers/media/platform/starfive/stf_video.h
|
||||
|
||||
--- a/drivers/media/platform/starfive/Makefile
|
||||
+++ b/drivers/media/platform/starfive/Makefile
|
||||
@@ -4,6 +4,7 @@
|
||||
#
|
||||
|
||||
starfive-camss-objs += \
|
||||
- stf_camss.o
|
||||
+ stf_camss.o \
|
||||
+ stf_video.o
|
||||
|
||||
obj-$(CONFIG_VIDEO_STARFIVE_CAMSS) += starfive-camss.o \
|
||||
--- /dev/null
|
||||
+++ b/drivers/media/platform/starfive/stf_video.c
|
||||
@@ -0,0 +1,864 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0
|
||||
+/*
|
||||
+ * stf_video.c
|
||||
+ *
|
||||
+ * StarFive Camera Subsystem - V4L2 device node
|
||||
+ *
|
||||
+ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
|
||||
+ */
|
||||
+
|
||||
+#include <media/media-entity.h>
|
||||
+#include <media/v4l2-ctrls.h>
|
||||
+#include <media/v4l2-event.h>
|
||||
+#include <media/v4l2-mc.h>
|
||||
+#include <media/videobuf2-dma-contig.h>
|
||||
+
|
||||
+#include "stf_camss.h"
|
||||
+#include "stf_video.h"
|
||||
+
|
||||
+static const struct stfcamss_format_info formats_pix_wr[] = {
|
||||
+ { MEDIA_BUS_FMT_SRGGB10_1X10, V4L2_PIX_FMT_SRGGB10, 1,
|
||||
+ { { 1, 1 } }, { { 1, 1 } }, { 10 } },
|
||||
+ { MEDIA_BUS_FMT_SGRBG10_1X10, V4L2_PIX_FMT_SGRBG10, 1,
|
||||
+ { { 1, 1 } }, { { 1, 1 } }, { 10 } },
|
||||
+ { MEDIA_BUS_FMT_SGBRG10_1X10, V4L2_PIX_FMT_SGBRG10, 1,
|
||||
+ { { 1, 1 } }, { { 1, 1 } }, { 10 } },
|
||||
+ { MEDIA_BUS_FMT_SBGGR10_1X10, V4L2_PIX_FMT_SBGGR10, 1,
|
||||
+ { { 1, 1 } }, { { 1, 1 } }, { 10 } },
|
||||
+};
|
||||
+
|
||||
+static const struct stfcamss_format_info formats_pix_isp[] = {
|
||||
+ { MEDIA_BUS_FMT_Y12_1X12, V4L2_PIX_FMT_NV12, 1,
|
||||
+ { { 1, 1 } }, { { 2, 3 } }, { 8 } },
|
||||
+};
|
||||
+
|
||||
+/* -----------------------------------------------------------------------------
|
||||
+ * Helper functions
|
||||
+ */
|
||||
+
|
||||
+static int video_find_format(u32 code, u32 pixelformat,
|
||||
+ const struct stfcamss_format_info *formats,
|
||||
+ unsigned int nformats)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < nformats; i++) {
|
||||
+ if (formats[i].code == code &&
|
||||
+ formats[i].pixelformat == pixelformat)
|
||||
+ return i;
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < nformats; i++)
|
||||
+ if (formats[i].code == code)
|
||||
+ return i;
|
||||
+
|
||||
+ for (i = 0; i < nformats; i++)
|
||||
+ if (formats[i].pixelformat == pixelformat)
|
||||
+ return i;
|
||||
+
|
||||
+ return -EINVAL;
|
||||
+}
|
||||
+
|
||||
+static int __video_try_fmt(struct stfcamss_video *video, struct v4l2_format *f)
|
||||
+{
|
||||
+ struct v4l2_pix_format *pix;
|
||||
+ const struct stfcamss_format_info *fi;
|
||||
+ u32 width, height;
|
||||
+ u32 bpl;
|
||||
+ int i;
|
||||
+
|
||||
+ pix = &f->fmt.pix;
|
||||
+
|
||||
+ for (i = 0; i < video->nformats; i++)
|
||||
+ if (pix->pixelformat == video->formats[i].pixelformat)
|
||||
+ break;
|
||||
+
|
||||
+ if (i == video->nformats)
|
||||
+ i = 0; /* default format */
|
||||
+
|
||||
+ fi = &video->formats[i];
|
||||
+ width = pix->width;
|
||||
+ height = pix->height;
|
||||
+
|
||||
+ memset(pix, 0, sizeof(*pix));
|
||||
+
|
||||
+ pix->pixelformat = fi->pixelformat;
|
||||
+ pix->width = clamp_t(u32, width, STFCAMSS_FRAME_MIN_WIDTH,
|
||||
+ STFCAMSS_FRAME_MAX_WIDTH);
|
||||
+ pix->height = clamp_t(u32, height, STFCAMSS_FRAME_MIN_HEIGHT,
|
||||
+ STFCAMSS_FRAME_MAX_HEIGHT);
|
||||
+ bpl = pix->width / fi->hsub[0].numerator *
|
||||
+ fi->hsub[0].denominator * fi->bpp[0] / 8;
|
||||
+ bpl = ALIGN(bpl, video->bpl_alignment);
|
||||
+ pix->bytesperline = bpl;
|
||||
+ pix->sizeimage = pix->height / fi->vsub[0].numerator *
|
||||
+ fi->vsub[0].denominator * bpl;
|
||||
+
|
||||
+ pix->field = V4L2_FIELD_NONE;
|
||||
+ pix->colorspace = V4L2_COLORSPACE_SRGB;
|
||||
+ pix->flags = 0;
|
||||
+ pix->ycbcr_enc =
|
||||
+ V4L2_MAP_YCBCR_ENC_DEFAULT(pix->colorspace);
|
||||
+ pix->quantization = V4L2_MAP_QUANTIZATION_DEFAULT(true,
|
||||
+ pix->colorspace,
|
||||
+ pix->ycbcr_enc);
|
||||
+ pix->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(pix->colorspace);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int stf_video_init_format(struct stfcamss_video *video)
|
||||
+{
|
||||
+ int ret;
|
||||
+ struct v4l2_format format = {
|
||||
+ .type = video->type,
|
||||
+ .fmt.pix = {
|
||||
+ .width = 1920,
|
||||
+ .height = 1080,
|
||||
+ .pixelformat = V4L2_PIX_FMT_RGB565,
|
||||
+ },
|
||||
+ };
|
||||
+
|
||||
+ ret = __video_try_fmt(video, &format);
|
||||
+
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ video->active_fmt = format;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/* -----------------------------------------------------------------------------
|
||||
+ * Video queue operations
|
||||
+ */
|
||||
+
|
||||
+static int video_queue_setup(struct vb2_queue *q,
|
||||
+ unsigned int *num_buffers,
|
||||
+ unsigned int *num_planes,
|
||||
+ unsigned int sizes[],
|
||||
+ struct device *alloc_devs[])
|
||||
+{
|
||||
+ struct stfcamss_video *video = vb2_get_drv_priv(q);
|
||||
+ const struct v4l2_pix_format *format = &video->active_fmt.fmt.pix;
|
||||
+
|
||||
+ if (*num_planes) {
|
||||
+ if (*num_planes != 1)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if (sizes[0] < format->sizeimage)
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ *num_planes = 1;
|
||||
+ sizes[0] = format->sizeimage;
|
||||
+ if (!sizes[0])
|
||||
+ dev_err(video->stfcamss->dev,
|
||||
+ "%s: error size is zero!!!\n", __func__);
|
||||
+
|
||||
+ dev_dbg(video->stfcamss->dev, "planes = %d, size = %d\n",
|
||||
+ *num_planes, sizes[0]);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int video_buf_init(struct vb2_buffer *vb)
|
||||
+{
|
||||
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
|
||||
+ struct stfcamss_video *video = vb2_get_drv_priv(vb->vb2_queue);
|
||||
+ struct stfcamss_buffer *buffer =
|
||||
+ container_of(vbuf, struct stfcamss_buffer, vb);
|
||||
+ const struct v4l2_pix_format *fmt = &video->active_fmt.fmt.pix;
|
||||
+ dma_addr_t *paddr;
|
||||
+
|
||||
+ buffer->sizeimage = 0;
|
||||
+
|
||||
+ paddr = vb2_plane_cookie(vb, 0);
|
||||
+ buffer->sizeimage = vb2_plane_size(vb, 0);
|
||||
+ buffer->addr[0] = *paddr;
|
||||
+ if (fmt->pixelformat == V4L2_PIX_FMT_NV12 ||
|
||||
+ fmt->pixelformat == V4L2_PIX_FMT_NV21 ||
|
||||
+ fmt->pixelformat == V4L2_PIX_FMT_NV16 ||
|
||||
+ fmt->pixelformat == V4L2_PIX_FMT_NV61)
|
||||
+ buffer->addr[1] =
|
||||
+ buffer->addr[0] + fmt->bytesperline * fmt->height;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int video_buf_prepare(struct vb2_buffer *vb)
|
||||
+{
|
||||
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
|
||||
+ struct stfcamss_video *video = vb2_get_drv_priv(vb->vb2_queue);
|
||||
+ const struct v4l2_pix_format *fmt = &video->active_fmt.fmt.pix;
|
||||
+
|
||||
+ if (fmt->sizeimage > vb2_plane_size(vb, 0)) {
|
||||
+ dev_err(video->stfcamss->dev,
|
||||
+ "sizeimage = %d, plane size = %d\n",
|
||||
+ fmt->sizeimage, (unsigned int)vb2_plane_size(vb, 0));
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ vb2_set_plane_payload(vb, 0, fmt->sizeimage);
|
||||
+
|
||||
+ vbuf->field = V4L2_FIELD_NONE;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void video_buf_queue(struct vb2_buffer *vb)
|
||||
+{
|
||||
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
|
||||
+ struct stfcamss_video *video = vb2_get_drv_priv(vb->vb2_queue);
|
||||
+ struct stfcamss_buffer *buffer =
|
||||
+ container_of(vbuf, struct stfcamss_buffer, vb);
|
||||
+
|
||||
+ video->ops->queue_buffer(video, buffer);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * video_mbus_to_pix - Convert v4l2_mbus_framefmt to v4l2_pix_format
|
||||
+ * @mbus: v4l2_mbus_framefmt format (input)
|
||||
+ * @pix: v4l2_pix_format_mplane format (output)
|
||||
+ * @f: a pointer to formats array element to be used for the conversion
|
||||
+ * @alignment: bytesperline alignment value
|
||||
+ *
|
||||
+ * Fill the output pix structure with information from the input mbus format.
|
||||
+ *
|
||||
+ * Return 0 on success or a negative error code otherwise
|
||||
+ */
|
||||
+static int video_mbus_to_pix(const struct v4l2_mbus_framefmt *mbus,
|
||||
+ struct v4l2_pix_format *pix,
|
||||
+ const struct stfcamss_format_info *f,
|
||||
+ unsigned int alignment)
|
||||
+{
|
||||
+ u32 bytesperline;
|
||||
+
|
||||
+ memset(pix, 0, sizeof(*pix));
|
||||
+ v4l2_fill_pix_format(pix, mbus);
|
||||
+ pix->pixelformat = f->pixelformat;
|
||||
+ bytesperline = pix->width / f->hsub[0].numerator *
|
||||
+ f->hsub[0].denominator * f->bpp[0] / 8;
|
||||
+ bytesperline = ALIGN(bytesperline, alignment);
|
||||
+ pix->bytesperline = bytesperline;
|
||||
+ pix->sizeimage = pix->height / f->vsub[0].numerator *
|
||||
+ f->vsub[0].denominator * bytesperline;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct v4l2_subdev *video_remote_subdev(struct stfcamss_video *video,
|
||||
+ u32 *pad)
|
||||
+{
|
||||
+ struct media_pad *remote;
|
||||
+
|
||||
+ remote = media_pad_remote_pad_first(&video->pad);
|
||||
+
|
||||
+ if (!remote || !is_media_entity_v4l2_subdev(remote->entity))
|
||||
+ return NULL;
|
||||
+
|
||||
+ if (pad)
|
||||
+ *pad = remote->index;
|
||||
+
|
||||
+ return media_entity_to_v4l2_subdev(remote->entity);
|
||||
+}
|
||||
+
|
||||
+static int video_get_subdev_format(struct stfcamss_video *video,
|
||||
+ struct v4l2_format *format)
|
||||
+{
|
||||
+ struct v4l2_pix_format *pix = &video->active_fmt.fmt.pix;
|
||||
+ struct v4l2_subdev_format fmt;
|
||||
+ struct v4l2_subdev *subdev;
|
||||
+ u32 pixelformat;
|
||||
+ u32 pad;
|
||||
+ int ret;
|
||||
+
|
||||
+ subdev = video_remote_subdev(video, &pad);
|
||||
+ if (!subdev)
|
||||
+ return -EPIPE;
|
||||
+
|
||||
+ fmt.pad = pad;
|
||||
+ fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
|
||||
+
|
||||
+ ret = v4l2_subdev_call(subdev, pad, get_fmt, NULL, &fmt);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ pixelformat = pix->pixelformat;
|
||||
+ ret = video_find_format(fmt.format.code, pixelformat,
|
||||
+ video->formats, video->nformats);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ format->type = video->type;
|
||||
+
|
||||
+ return video_mbus_to_pix(&fmt.format, &format->fmt.pix,
|
||||
+ &video->formats[ret], video->bpl_alignment);
|
||||
+}
|
||||
+
|
||||
+static int video_check_format(struct stfcamss_video *video)
|
||||
+{
|
||||
+ struct v4l2_pix_format *pix = &video->active_fmt.fmt.pix;
|
||||
+ struct v4l2_format format;
|
||||
+ struct v4l2_pix_format *sd_pix = &format.fmt.pix;
|
||||
+ int ret;
|
||||
+
|
||||
+ sd_pix->pixelformat = pix->pixelformat;
|
||||
+ ret = video_get_subdev_format(video, &format);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ if (pix->pixelformat != sd_pix->pixelformat ||
|
||||
+ pix->height > sd_pix->height ||
|
||||
+ pix->width > sd_pix->width ||
|
||||
+ pix->field != format.fmt.pix.field) {
|
||||
+ dev_err(video->stfcamss->dev,
|
||||
+ "%s, not match:\n"
|
||||
+ "0x%x 0x%x\n0x%x 0x%x\n0x%x 0x%x\n",
|
||||
+ __func__,
|
||||
+ pix->pixelformat, sd_pix->pixelformat,
|
||||
+ pix->height, sd_pix->height,
|
||||
+ pix->field, format.fmt.pix.field);
|
||||
+ return -EPIPE;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int video_start_streaming(struct vb2_queue *q, unsigned int count)
|
||||
+{
|
||||
+ struct stfcamss_video *video = vb2_get_drv_priv(q);
|
||||
+ struct video_device *vdev = &video->vdev;
|
||||
+ struct media_entity *entity;
|
||||
+ struct media_pad *pad;
|
||||
+ struct v4l2_subdev *subdev;
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = video_device_pipeline_start(vdev, &video->stfcamss->pipe);
|
||||
+ if (ret < 0) {
|
||||
+ dev_err(video->stfcamss->dev,
|
||||
+ "Failed to media_pipeline_start: %d\n", ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ ret = video_check_format(video);
|
||||
+ if (ret < 0)
|
||||
+ goto error;
|
||||
+ entity = &vdev->entity;
|
||||
+ while (1) {
|
||||
+ pad = &entity->pads[0];
|
||||
+ if (!(pad->flags & MEDIA_PAD_FL_SINK))
|
||||
+ break;
|
||||
+
|
||||
+ pad = media_pad_remote_pad_first(pad);
|
||||
+ if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
|
||||
+ break;
|
||||
+
|
||||
+ entity = pad->entity;
|
||||
+ subdev = media_entity_to_v4l2_subdev(entity);
|
||||
+
|
||||
+ ret = v4l2_subdev_call(subdev, video, s_stream, 1);
|
||||
+ if (ret < 0 && ret != -ENOIOCTLCMD)
|
||||
+ goto error;
|
||||
+ }
|
||||
+ return 0;
|
||||
+
|
||||
+error:
|
||||
+ video_device_pipeline_stop(vdev);
|
||||
+ video->ops->flush_buffers(video, VB2_BUF_STATE_QUEUED);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static void video_stop_streaming(struct vb2_queue *q)
|
||||
+{
|
||||
+ struct stfcamss_video *video = vb2_get_drv_priv(q);
|
||||
+ struct video_device *vdev = &video->vdev;
|
||||
+ struct media_entity *entity;
|
||||
+ struct media_pad *pad;
|
||||
+ struct v4l2_subdev *subdev;
|
||||
+
|
||||
+ entity = &vdev->entity;
|
||||
+ while (1) {
|
||||
+ pad = &entity->pads[0];
|
||||
+ if (!(pad->flags & MEDIA_PAD_FL_SINK))
|
||||
+ break;
|
||||
+
|
||||
+ pad = media_pad_remote_pad_first(pad);
|
||||
+ if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
|
||||
+ break;
|
||||
+
|
||||
+ entity = pad->entity;
|
||||
+ subdev = media_entity_to_v4l2_subdev(entity);
|
||||
+
|
||||
+ v4l2_subdev_call(subdev, video, s_stream, 0);
|
||||
+ }
|
||||
+
|
||||
+ video_device_pipeline_stop(vdev);
|
||||
+ video->ops->flush_buffers(video, VB2_BUF_STATE_ERROR);
|
||||
+}
|
||||
+
|
||||
+static const struct vb2_ops stf_video_vb2_q_ops = {
|
||||
+ .queue_setup = video_queue_setup,
|
||||
+ .wait_prepare = vb2_ops_wait_prepare,
|
||||
+ .wait_finish = vb2_ops_wait_finish,
|
||||
+ .buf_init = video_buf_init,
|
||||
+ .buf_prepare = video_buf_prepare,
|
||||
+ .buf_queue = video_buf_queue,
|
||||
+ .start_streaming = video_start_streaming,
|
||||
+ .stop_streaming = video_stop_streaming,
|
||||
+};
|
||||
+
|
||||
+/* -----------------------------------------------------------------------------
|
||||
+ * V4L2 ioctls
|
||||
+ */
|
||||
+
|
||||
+static int video_querycap(struct file *file, void *fh,
|
||||
+ struct v4l2_capability *cap)
|
||||
+{
|
||||
+ struct stfcamss_video *video = video_drvdata(file);
|
||||
+
|
||||
+ strscpy(cap->driver, "stf camss", sizeof(cap->driver));
|
||||
+ strscpy(cap->card, "Starfive Camera Subsystem", sizeof(cap->card));
|
||||
+ snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
|
||||
+ dev_name(video->stfcamss->dev));
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int video_get_pfmt_by_index(struct stfcamss_video *video, int ndx)
|
||||
+{
|
||||
+ int i, j, k;
|
||||
+
|
||||
+ /* find index "i" of "k"th unique pixelformat in formats array */
|
||||
+ k = -1;
|
||||
+ for (i = 0; i < video->nformats; i++) {
|
||||
+ for (j = 0; j < i; j++) {
|
||||
+ if (video->formats[i].pixelformat ==
|
||||
+ video->formats[j].pixelformat)
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if (j == i)
|
||||
+ k++;
|
||||
+
|
||||
+ if (k == ndx)
|
||||
+ return i;
|
||||
+ }
|
||||
+
|
||||
+ return -EINVAL;
|
||||
+}
|
||||
+
|
||||
+static int video_get_pfmt_by_mcode(struct stfcamss_video *video, u32 mcode)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < video->nformats; i++) {
|
||||
+ if (video->formats[i].code == mcode)
|
||||
+ return i;
|
||||
+ }
|
||||
+
|
||||
+ return -EINVAL;
|
||||
+}
|
||||
+
|
||||
+static int video_enum_fmt(struct file *file, void *fh, struct v4l2_fmtdesc *f)
|
||||
+{
|
||||
+ struct stfcamss_video *video = video_drvdata(file);
|
||||
+ int i;
|
||||
+
|
||||
+ if (f->type != video->type)
|
||||
+ return -EINVAL;
|
||||
+ if (f->index >= video->nformats)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if (f->mbus_code) {
|
||||
+ /* Each entry in formats[] table has unique mbus_code */
|
||||
+ if (f->index > 0)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ i = video_get_pfmt_by_mcode(video, f->mbus_code);
|
||||
+ } else {
|
||||
+ i = video_get_pfmt_by_index(video, f->index);
|
||||
+ }
|
||||
+
|
||||
+ if (i < 0)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ f->pixelformat = video->formats[i].pixelformat;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int video_enum_framesizes(struct file *file, void *fh,
|
||||
+ struct v4l2_frmsizeenum *fsize)
|
||||
+{
|
||||
+ struct stfcamss_video *video = video_drvdata(file);
|
||||
+ int i;
|
||||
+
|
||||
+ if (fsize->index)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ for (i = 0; i < video->nformats; i++) {
|
||||
+ if (video->formats[i].pixelformat == fsize->pixel_format)
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if (i == video->nformats)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ fsize->type = V4L2_FRMSIZE_TYPE_CONTINUOUS;
|
||||
+ fsize->stepwise.min_width = STFCAMSS_FRAME_MIN_WIDTH;
|
||||
+ fsize->stepwise.max_width = STFCAMSS_FRAME_MAX_WIDTH;
|
||||
+ fsize->stepwise.min_height = STFCAMSS_FRAME_MIN_HEIGHT;
|
||||
+ fsize->stepwise.max_height = STFCAMSS_FRAME_MAX_HEIGHT;
|
||||
+ fsize->stepwise.step_width = 1;
|
||||
+ fsize->stepwise.step_height = 1;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int video_g_fmt(struct file *file, void *fh, struct v4l2_format *f)
|
||||
+{
|
||||
+ struct stfcamss_video *video = video_drvdata(file);
|
||||
+
|
||||
+ *f = video->active_fmt;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int video_s_fmt(struct file *file, void *fh, struct v4l2_format *f)
|
||||
+{
|
||||
+ struct stfcamss_video *video = video_drvdata(file);
|
||||
+ int ret;
|
||||
+
|
||||
+ if (vb2_is_busy(&video->vb2_q))
|
||||
+ return -EBUSY;
|
||||
+
|
||||
+ ret = __video_try_fmt(video, f);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ video->active_fmt = *f;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int video_try_fmt(struct file *file, void *fh, struct v4l2_format *f)
|
||||
+{
|
||||
+ struct stfcamss_video *video = video_drvdata(file);
|
||||
+
|
||||
+ return __video_try_fmt(video, f);
|
||||
+}
|
||||
+
|
||||
+static int video_enum_input(struct file *file, void *fh,
|
||||
+ struct v4l2_input *input)
|
||||
+{
|
||||
+ if (input->index > 0)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ strscpy(input->name, "camera", sizeof(input->name));
|
||||
+ input->type = V4L2_INPUT_TYPE_CAMERA;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int video_g_input(struct file *file, void *fh, unsigned int *input)
|
||||
+{
|
||||
+ *input = 0;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int video_s_input(struct file *file, void *fh, unsigned int input)
|
||||
+{
|
||||
+ return input == 0 ? 0 : -EINVAL;
|
||||
+}
|
||||
+
|
||||
+static int video_g_parm(struct file *file, void *priv,
|
||||
+ struct v4l2_streamparm *p)
|
||||
+{
|
||||
+ struct stfcamss_video *video = video_drvdata(file);
|
||||
+ struct video_device *vdev = &video->vdev;
|
||||
+ struct media_entity *entity;
|
||||
+ struct v4l2_subdev *subdev;
|
||||
+ struct media_pad *pad;
|
||||
+ int ret, is_support = 0;
|
||||
+
|
||||
+ entity = &vdev->entity;
|
||||
+ while (1) {
|
||||
+ pad = &entity->pads[0];
|
||||
+ if (!(pad->flags & MEDIA_PAD_FL_SINK))
|
||||
+ break;
|
||||
+
|
||||
+ pad = media_pad_remote_pad_first(pad);
|
||||
+ if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
|
||||
+ break;
|
||||
+
|
||||
+ entity = pad->entity;
|
||||
+ subdev = media_entity_to_v4l2_subdev(entity);
|
||||
+
|
||||
+ ret = v4l2_g_parm_cap(vdev, subdev, p);
|
||||
+ if (ret < 0 && ret != -ENOIOCTLCMD)
|
||||
+ break;
|
||||
+ if (!ret)
|
||||
+ is_support = 1;
|
||||
+ }
|
||||
+
|
||||
+ return is_support ? 0 : ret;
|
||||
+}
|
||||
+
|
||||
+static int video_s_parm(struct file *file, void *priv,
|
||||
+ struct v4l2_streamparm *p)
|
||||
+{
|
||||
+ struct stfcamss_video *video = video_drvdata(file);
|
||||
+ struct video_device *vdev = &video->vdev;
|
||||
+ struct media_entity *entity;
|
||||
+ struct v4l2_subdev *subdev;
|
||||
+ struct media_pad *pad;
|
||||
+ struct v4l2_streamparm tmp_p;
|
||||
+ int ret, is_support = 0;
|
||||
+
|
||||
+ entity = &vdev->entity;
|
||||
+ while (1) {
|
||||
+ pad = &entity->pads[0];
|
||||
+ if (!(pad->flags & MEDIA_PAD_FL_SINK))
|
||||
+ break;
|
||||
+
|
||||
+ pad = media_pad_remote_pad_first(pad);
|
||||
+ if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
|
||||
+ break;
|
||||
+
|
||||
+ entity = pad->entity;
|
||||
+ subdev = media_entity_to_v4l2_subdev(entity);
|
||||
+
|
||||
+ tmp_p = *p;
|
||||
+ ret = v4l2_s_parm_cap(vdev, subdev, &tmp_p);
|
||||
+ if (ret < 0 && ret != -ENOIOCTLCMD)
|
||||
+ break;
|
||||
+ if (!ret) {
|
||||
+ is_support = 1;
|
||||
+ *p = tmp_p;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return is_support ? 0 : ret;
|
||||
+}
|
||||
+
|
||||
+static const struct v4l2_ioctl_ops stf_vid_vin_ioctl_ops = {
|
||||
+ .vidioc_querycap = video_querycap,
|
||||
+ .vidioc_enum_fmt_vid_cap = video_enum_fmt,
|
||||
+ .vidioc_enum_fmt_vid_out = video_enum_fmt,
|
||||
+ .vidioc_enum_framesizes = video_enum_framesizes,
|
||||
+ .vidioc_g_fmt_vid_cap = video_g_fmt,
|
||||
+ .vidioc_s_fmt_vid_cap = video_s_fmt,
|
||||
+ .vidioc_try_fmt_vid_cap = video_try_fmt,
|
||||
+ .vidioc_g_fmt_vid_out = video_g_fmt,
|
||||
+ .vidioc_s_fmt_vid_out = video_s_fmt,
|
||||
+ .vidioc_try_fmt_vid_out = video_try_fmt,
|
||||
+ .vidioc_reqbufs = vb2_ioctl_reqbufs,
|
||||
+ .vidioc_querybuf = vb2_ioctl_querybuf,
|
||||
+ .vidioc_qbuf = vb2_ioctl_qbuf,
|
||||
+ .vidioc_expbuf = vb2_ioctl_expbuf,
|
||||
+ .vidioc_dqbuf = vb2_ioctl_dqbuf,
|
||||
+ .vidioc_create_bufs = vb2_ioctl_create_bufs,
|
||||
+ .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
|
||||
+ .vidioc_streamon = vb2_ioctl_streamon,
|
||||
+ .vidioc_streamoff = vb2_ioctl_streamoff,
|
||||
+ .vidioc_enum_input = video_enum_input,
|
||||
+ .vidioc_g_input = video_g_input,
|
||||
+ .vidioc_s_input = video_s_input,
|
||||
+ .vidioc_g_parm = video_g_parm,
|
||||
+ .vidioc_s_parm = video_s_parm,
|
||||
+};
|
||||
+
|
||||
+static const struct v4l2_ioctl_ops stf_vid_isp_ioctl_ops = {
|
||||
+ .vidioc_querycap = video_querycap,
|
||||
+ .vidioc_enum_fmt_vid_cap = video_enum_fmt,
|
||||
+ .vidioc_enum_fmt_vid_out = video_enum_fmt,
|
||||
+ .vidioc_enum_framesizes = video_enum_framesizes,
|
||||
+ .vidioc_g_fmt_vid_cap = video_g_fmt,
|
||||
+ .vidioc_s_fmt_vid_cap = video_s_fmt,
|
||||
+ .vidioc_try_fmt_vid_cap = video_try_fmt,
|
||||
+ .vidioc_g_fmt_vid_out = video_g_fmt,
|
||||
+ .vidioc_s_fmt_vid_out = video_s_fmt,
|
||||
+ .vidioc_try_fmt_vid_out = video_try_fmt,
|
||||
+ .vidioc_reqbufs = vb2_ioctl_reqbufs,
|
||||
+ .vidioc_querybuf = vb2_ioctl_querybuf,
|
||||
+ .vidioc_qbuf = vb2_ioctl_qbuf,
|
||||
+ .vidioc_expbuf = vb2_ioctl_expbuf,
|
||||
+ .vidioc_dqbuf = vb2_ioctl_dqbuf,
|
||||
+ .vidioc_create_bufs = vb2_ioctl_create_bufs,
|
||||
+ .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
|
||||
+ .vidioc_streamon = vb2_ioctl_streamon,
|
||||
+ .vidioc_streamoff = vb2_ioctl_streamoff,
|
||||
+ .vidioc_enum_input = video_enum_input,
|
||||
+ .vidioc_g_input = video_g_input,
|
||||
+ .vidioc_s_input = video_s_input,
|
||||
+ .vidioc_g_parm = video_g_parm,
|
||||
+ .vidioc_s_parm = video_s_parm,
|
||||
+};
|
||||
+
|
||||
+/* -----------------------------------------------------------------------------
|
||||
+ * V4L2 file operations
|
||||
+ */
|
||||
+
|
||||
+static int video_open(struct file *file)
|
||||
+{
|
||||
+ struct video_device *vdev = video_devdata(file);
|
||||
+ struct stfcamss_video *video = video_drvdata(file);
|
||||
+ struct v4l2_fh *vfh;
|
||||
+ int ret;
|
||||
+
|
||||
+ mutex_lock(&video->lock);
|
||||
+
|
||||
+ vfh = kzalloc(sizeof(*vfh), GFP_KERNEL);
|
||||
+ if (!vfh) {
|
||||
+ ret = -ENOMEM;
|
||||
+ goto error_alloc;
|
||||
+ }
|
||||
+
|
||||
+ v4l2_fh_init(vfh, vdev);
|
||||
+ v4l2_fh_add(vfh);
|
||||
+
|
||||
+ file->private_data = vfh;
|
||||
+
|
||||
+ ret = v4l2_pipeline_pm_get(&vdev->entity);
|
||||
+ if (ret < 0) {
|
||||
+ dev_err(video->stfcamss->dev,
|
||||
+ "Failed to power up pipeline: %d\n", ret);
|
||||
+ goto error_pm_use;
|
||||
+ }
|
||||
+ mutex_unlock(&video->lock);
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+error_pm_use:
|
||||
+ v4l2_fh_release(file);
|
||||
+error_alloc:
|
||||
+ mutex_unlock(&video->lock);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int video_release(struct file *file)
|
||||
+{
|
||||
+ struct video_device *vdev = video_devdata(file);
|
||||
+
|
||||
+ vb2_fop_release(file);
|
||||
+ v4l2_pipeline_pm_put(&vdev->entity);
|
||||
+ file->private_data = NULL;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct v4l2_file_operations stf_vid_fops = {
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .unlocked_ioctl = video_ioctl2,
|
||||
+ .open = video_open,
|
||||
+ .release = video_release,
|
||||
+ .poll = vb2_fop_poll,
|
||||
+ .mmap = vb2_fop_mmap,
|
||||
+ .read = vb2_fop_read,
|
||||
+};
|
||||
+
|
||||
+/* -----------------------------------------------------------------------------
|
||||
+ * STFCAMSS video core
|
||||
+ */
|
||||
+
|
||||
+static void stf_video_release(struct video_device *vdev)
|
||||
+{
|
||||
+ struct stfcamss_video *video = video_get_drvdata(vdev);
|
||||
+
|
||||
+ media_entity_cleanup(&vdev->entity);
|
||||
+
|
||||
+ mutex_destroy(&video->q_lock);
|
||||
+ mutex_destroy(&video->lock);
|
||||
+}
|
||||
+
|
||||
+int stf_video_register(struct stfcamss_video *video,
|
||||
+ struct v4l2_device *v4l2_dev, const char *name)
|
||||
+{
|
||||
+ struct video_device *vdev;
|
||||
+ struct vb2_queue *q;
|
||||
+ struct media_pad *pad = &video->pad;
|
||||
+ int ret;
|
||||
+
|
||||
+ vdev = &video->vdev;
|
||||
+
|
||||
+ mutex_init(&video->q_lock);
|
||||
+
|
||||
+ q = &video->vb2_q;
|
||||
+ q->drv_priv = video;
|
||||
+ q->mem_ops = &vb2_dma_contig_memops;
|
||||
+ q->ops = &stf_video_vb2_q_ops;
|
||||
+ q->type = video->type;
|
||||
+ q->io_modes = VB2_DMABUF | VB2_MMAP | VB2_READ;
|
||||
+ q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
|
||||
+ q->buf_struct_size = sizeof(struct stfcamss_buffer);
|
||||
+ q->dev = video->stfcamss->dev;
|
||||
+ q->lock = &video->q_lock;
|
||||
+ q->min_buffers_needed = STFCAMSS_MIN_BUFFERS;
|
||||
+ ret = vb2_queue_init(q);
|
||||
+ if (ret < 0) {
|
||||
+ dev_err(video->stfcamss->dev,
|
||||
+ "Failed to init vb2 queue: %d\n", ret);
|
||||
+ goto err_vb2_init;
|
||||
+ }
|
||||
+
|
||||
+ pad->flags = MEDIA_PAD_FL_SINK;
|
||||
+ ret = media_entity_pads_init(&vdev->entity, 1, pad);
|
||||
+ if (ret < 0) {
|
||||
+ dev_err(video->stfcamss->dev,
|
||||
+ "Failed to init video entity: %d\n", ret);
|
||||
+ goto err_vb2_init;
|
||||
+ }
|
||||
+
|
||||
+ mutex_init(&video->lock);
|
||||
+
|
||||
+ if (video->id == STF_V_LINE_WR) {
|
||||
+ video->formats = formats_pix_wr;
|
||||
+ video->nformats = ARRAY_SIZE(formats_pix_wr);
|
||||
+ video->bpl_alignment = STFCAMSS_FRAME_WIDTH_ALIGN_8;
|
||||
+ vdev->ioctl_ops = &stf_vid_vin_ioctl_ops;
|
||||
+ } else {
|
||||
+ video->formats = formats_pix_isp;
|
||||
+ video->nformats = ARRAY_SIZE(formats_pix_isp);
|
||||
+ video->bpl_alignment = STFCAMSS_FRAME_WIDTH_ALIGN_8;
|
||||
+ vdev->ioctl_ops = &stf_vid_isp_ioctl_ops;
|
||||
+ }
|
||||
+
|
||||
+ ret = stf_video_init_format(video);
|
||||
+ if (ret < 0) {
|
||||
+ dev_err(video->stfcamss->dev,
|
||||
+ "Failed to init format: %d\n", ret);
|
||||
+ goto err_vid_init_format;
|
||||
+ }
|
||||
+
|
||||
+ vdev->fops = &stf_vid_fops;
|
||||
+ vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE;
|
||||
+ vdev->vfl_dir = VFL_DIR_RX;
|
||||
+ vdev->device_caps |= V4L2_CAP_STREAMING | V4L2_CAP_READWRITE;
|
||||
+ vdev->release = stf_video_release;
|
||||
+ vdev->v4l2_dev = v4l2_dev;
|
||||
+ vdev->queue = &video->vb2_q;
|
||||
+ vdev->lock = &video->lock;
|
||||
+ strscpy(vdev->name, name, sizeof(vdev->name));
|
||||
+
|
||||
+ ret = video_register_device(vdev, VFL_TYPE_VIDEO, video->id);
|
||||
+ if (ret < 0) {
|
||||
+ dev_err(video->stfcamss->dev,
|
||||
+ "Failed to register video device: %d\n", ret);
|
||||
+ goto err_vid_reg;
|
||||
+ }
|
||||
+
|
||||
+ video_set_drvdata(vdev, video);
|
||||
+ return 0;
|
||||
+
|
||||
+err_vid_reg:
|
||||
+err_vid_init_format:
|
||||
+ media_entity_cleanup(&vdev->entity);
|
||||
+ mutex_destroy(&video->lock);
|
||||
+err_vb2_init:
|
||||
+ mutex_destroy(&video->q_lock);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+void stf_video_unregister(struct stfcamss_video *video)
|
||||
+{
|
||||
+ vb2_video_unregister_device(&video->vdev);
|
||||
+}
|
||||
--- /dev/null
|
||||
+++ b/drivers/media/platform/starfive/stf_video.h
|
||||
@@ -0,0 +1,95 @@
|
||||
+/* SPDX-License-Identifier: GPL-2.0 */
|
||||
+/*
|
||||
+ * stf_video.h
|
||||
+ *
|
||||
+ * StarFive Camera Subsystem - V4L2 device node
|
||||
+ *
|
||||
+ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
|
||||
+ */
|
||||
+
|
||||
+#ifndef STF_VIDEO_H
|
||||
+#define STF_VIDEO_H
|
||||
+
|
||||
+#include <linux/mutex.h>
|
||||
+#include <linux/videodev2.h>
|
||||
+#include <media/v4l2-dev.h>
|
||||
+#include <media/v4l2-fh.h>
|
||||
+#include <media/v4l2-ioctl.h>
|
||||
+#include <media/videobuf2-v4l2.h>
|
||||
+
|
||||
+#define STFCAMSS_FRAME_MIN_WIDTH 64
|
||||
+#define STFCAMSS_FRAME_MAX_WIDTH 1920
|
||||
+#define STFCAMSS_FRAME_MIN_HEIGHT 64
|
||||
+#define STFCAMSS_FRAME_MAX_HEIGHT 1080
|
||||
+#define STFCAMSS_FRAME_WIDTH_ALIGN_8 8
|
||||
+#define STFCAMSS_FRAME_WIDTH_ALIGN_128 128
|
||||
+#define STFCAMSS_MIN_BUFFERS 2
|
||||
+
|
||||
+#define STFCAMSS_MAX_ENTITY_NAME_LEN 27
|
||||
+
|
||||
+enum stf_v_line_id {
|
||||
+ STF_V_LINE_WR = 0,
|
||||
+ STF_V_LINE_ISP,
|
||||
+ STF_V_LINE_MAX,
|
||||
+};
|
||||
+
|
||||
+struct stfcamss_buffer {
|
||||
+ struct vb2_v4l2_buffer vb;
|
||||
+ dma_addr_t addr[3];
|
||||
+ struct list_head queue;
|
||||
+ int sizeimage;
|
||||
+};
|
||||
+
|
||||
+struct fract {
|
||||
+ u8 numerator;
|
||||
+ u8 denominator;
|
||||
+};
|
||||
+
|
||||
+/*
|
||||
+ * struct stfcamss_format_info - ISP media bus format information
|
||||
+ * @code: V4L2 media bus format code
|
||||
+ * @pixelformat: V4L2 pixel format FCC identifier
|
||||
+ * @planes: Number of planes
|
||||
+ * @hsub: Horizontal subsampling (for each plane)
|
||||
+ * @vsub: Vertical subsampling (for each plane)
|
||||
+ * @bpp: Bits per pixel when stored in memory (for each plane)
|
||||
+ */
|
||||
+struct stfcamss_format_info {
|
||||
+ u32 code;
|
||||
+ u32 pixelformat;
|
||||
+ u8 planes;
|
||||
+ struct fract hsub[3];
|
||||
+ struct fract vsub[3];
|
||||
+ u8 bpp[3];
|
||||
+};
|
||||
+
|
||||
+struct stfcamss_video {
|
||||
+ struct stfcamss *stfcamss;
|
||||
+ u8 id;
|
||||
+ struct vb2_queue vb2_q;
|
||||
+ struct video_device vdev;
|
||||
+ struct media_pad pad;
|
||||
+ struct media_pipeline pipe;
|
||||
+ struct v4l2_format active_fmt;
|
||||
+ enum v4l2_buf_type type;
|
||||
+ const struct stfcamss_video_ops *ops;
|
||||
+ struct mutex lock; /* serialize device access */
|
||||
+ struct mutex q_lock; /* protects the queue */
|
||||
+ unsigned int bpl_alignment;
|
||||
+ const struct stfcamss_format_info *formats;
|
||||
+ unsigned int nformats;
|
||||
+};
|
||||
+
|
||||
+struct stfcamss_video_ops {
|
||||
+ int (*queue_buffer)(struct stfcamss_video *vid,
|
||||
+ struct stfcamss_buffer *buf);
|
||||
+ int (*flush_buffers)(struct stfcamss_video *vid,
|
||||
+ enum vb2_buffer_state state);
|
||||
+};
|
||||
+
|
||||
+int stf_video_register(struct stfcamss_video *video,
|
||||
+ struct v4l2_device *v4l2_dev, const char *name);
|
||||
+
|
||||
+void stf_video_unregister(struct stfcamss_video *video);
|
||||
+
|
||||
+#endif /* STF_VIDEO_H */
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,68 @@
|
||||
From 2ebd77fa8fb95f60b275cefb98ea7d6f4df06e55 Mon Sep 17 00:00:00 2001
|
||||
From: Minda Chen <minda.chen@starfivetech.com>
|
||||
Date: Thu, 18 May 2023 19:27:44 +0800
|
||||
Subject: [PATCH 087/122] dt-bindings: phy: Add StarFive JH7110 USB PHY
|
||||
|
||||
Add StarFive JH7110 SoC USB 2.0 PHY dt-binding.
|
||||
|
||||
Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
|
||||
Reviewed-by: Hal Feng <hal.feng@starfivetech.com>
|
||||
Reviewed-by: Rob Herring <robh@kernel.org>
|
||||
---
|
||||
.../bindings/phy/starfive,jh7110-usb-phy.yaml | 50 +++++++++++++++++++
|
||||
1 file changed, 50 insertions(+)
|
||||
create mode 100644 Documentation/devicetree/bindings/phy/starfive,jh7110-usb-phy.yaml
|
||||
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/phy/starfive,jh7110-usb-phy.yaml
|
||||
@@ -0,0 +1,50 @@
|
||||
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
+%YAML 1.2
|
||||
+---
|
||||
+$id: http://devicetree.org/schemas/phy/starfive,jh7110-usb-phy.yaml#
|
||||
+$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
+
|
||||
+title: StarFive JH7110 USB 2.0 PHY
|
||||
+
|
||||
+maintainers:
|
||||
+ - Minda Chen <minda.chen@starfivetech.com>
|
||||
+
|
||||
+properties:
|
||||
+ compatible:
|
||||
+ const: starfive,jh7110-usb-phy
|
||||
+
|
||||
+ reg:
|
||||
+ maxItems: 1
|
||||
+
|
||||
+ "#phy-cells":
|
||||
+ const: 0
|
||||
+
|
||||
+ clocks:
|
||||
+ items:
|
||||
+ - description: PHY 125m
|
||||
+ - description: app 125m
|
||||
+
|
||||
+ clock-names:
|
||||
+ items:
|
||||
+ - const: 125m
|
||||
+ - const: app_125m
|
||||
+
|
||||
+required:
|
||||
+ - compatible
|
||||
+ - reg
|
||||
+ - clocks
|
||||
+ - clock-names
|
||||
+ - "#phy-cells"
|
||||
+
|
||||
+additionalProperties: false
|
||||
+
|
||||
+examples:
|
||||
+ - |
|
||||
+ phy@10200000 {
|
||||
+ compatible = "starfive,jh7110-usb-phy";
|
||||
+ reg = <0x10200000 0x10000>;
|
||||
+ clocks = <&syscrg 95>,
|
||||
+ <&stgcrg 6>;
|
||||
+ clock-names = "125m", "app_125m";
|
||||
+ #phy-cells = <0>;
|
||||
+ };
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user