diff --git a/config/kernel/linux-rockchip-rk3588-edge.config b/config/kernel/linux-rockchip-rk3588-edge.config index f90c74f39e..61ed71dce2 100644 --- a/config/kernel/linux-rockchip-rk3588-edge.config +++ b/config/kernel/linux-rockchip-rk3588-edge.config @@ -1,6 +1,6 @@ # # Automatically generated file; DO NOT EDIT. -# Linux/arm64 6.2.0-rc7 Kernel Configuration +# Linux/arm64 6.4.1 Kernel Configuration # CONFIG_CC_VERSION_TEXT="aarch64-linux-gnu-gcc (Ubuntu 11.3.0-1ubuntu1~22.04) 11.3.0" CONFIG_CC_IS_GCC=y @@ -140,7 +140,6 @@ CONFIG_CPU_ISOLATION=y CONFIG_TREE_RCU=y CONFIG_PREEMPT_RCU=y # CONFIG_RCU_EXPERT is not set -CONFIG_SRCU=y CONFIG_TREE_SRCU=y CONFIG_TASKS_RCU_GENERIC=y CONFIG_TASKS_RCU=y @@ -154,7 +153,6 @@ CONFIG_IKCONFIG_PROC=y CONFIG_IKHEADERS=m CONFIG_LOG_BUF_SHIFT=18 CONFIG_LOG_CPU_MAX_BUF_SHIFT=12 -CONFIG_PRINTK_SAFE_LOG_BUF_SHIFT=13 # CONFIG_PRINTK_INDEX is not set CONFIG_GENERIC_SCHED_CLOCK=y @@ -168,7 +166,6 @@ CONFIG_ARCH_SUPPORTS_NUMA_BALANCING=y CONFIG_CC_HAS_INT128=y CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5" CONFIG_GCC11_NO_ARRAY_BOUNDS=y -CONFIG_GCC12_NO_ARRAY_BOUNDS=y CONFIG_CC_NO_ARRAY_BOUNDS=y CONFIG_ARCH_SUPPORTS_INT128=y CONFIG_NUMA_BALANCING=y @@ -184,6 +181,7 @@ CONFIG_CGROUP_SCHED=y CONFIG_FAIR_GROUP_SCHED=y CONFIG_CFS_BANDWIDTH=y CONFIG_RT_GROUP_SCHED=y +CONFIG_SCHED_MM_CID=y CONFIG_CGROUP_PIDS=y CONFIG_CGROUP_RDMA=y CONFIG_CGROUP_FREEZER=y @@ -194,7 +192,7 @@ CONFIG_CGROUP_DEVICE=y CONFIG_CGROUP_CPUACCT=y CONFIG_CGROUP_PERF=y CONFIG_CGROUP_BPF=y -# CONFIG_CGROUP_MISC is not set +CONFIG_CGROUP_MISC=y # CONFIG_CGROUP_DEBUG is not set CONFIG_SOCK_CGROUP_DATA=y CONFIG_NAMESPACES=y @@ -206,7 +204,6 @@ CONFIG_PID_NS=y CONFIG_NET_NS=y CONFIG_CHECKPOINT_RESTORE=y CONFIG_SCHED_AUTOGROUP=y -# CONFIG_SYSFS_DEPRECATED is not set CONFIG_RELAY=y CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="" @@ -218,6 +215,7 @@ CONFIG_RD_LZO=y CONFIG_RD_LZ4=y CONFIG_RD_ZSTD=y CONFIG_BOOT_CONFIG=y +# CONFIG_BOOT_CONFIG_FORCE is not set # CONFIG_BOOT_CONFIG_EMBED is not set CONFIG_INITRAMFS_PRESERVE_MTIME=y CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y @@ -257,7 +255,7 @@ CONFIG_ARCH_HAS_MEMBARRIER_SYNC_CORE=y CONFIG_KCMP=y CONFIG_RSEQ=y # CONFIG_DEBUG_RSEQ is not set -# CONFIG_EMBEDDED is not set +CONFIG_EMBEDDED=y CONFIG_HAVE_PERF_EVENTS=y CONFIG_GUEST_PERF_EVENTS=y # CONFIG_PC104 is not set @@ -300,6 +298,7 @@ CONFIG_FIX_EARLYCON_MEM=y CONFIG_PGTABLE_LEVELS=4 CONFIG_ARCH_SUPPORTS_UPROBES=y CONFIG_ARCH_PROC_KCORE_TEXT=y +CONFIG_BUILTIN_RETURN_ADDRESS_STRIPS_PAC=y # # Platform selection @@ -371,7 +370,7 @@ CONFIG_ARM64_ERRATUM_1463225=y CONFIG_ARM64_ERRATUM_1542419=y CONFIG_ARM64_ERRATUM_1508412=y CONFIG_ARM64_ERRATUM_2051678=y -# CONFIG_ARM64_ERRATUM_2077057 is not set +CONFIG_ARM64_ERRATUM_2077057=y CONFIG_ARM64_ERRATUM_2658417=y CONFIG_ARM64_WORKAROUND_TSB_FLUSH_FAILURE=y CONFIG_ARM64_ERRATUM_2054223=y @@ -392,6 +391,7 @@ CONFIG_QCOM_FALKOR_ERRATUM_1009=y CONFIG_QCOM_QDF2400_ERRATUM_0065=y CONFIG_QCOM_FALKOR_ERRATUM_E1041=y CONFIG_NVIDIA_CARMEL_CNP_ERRATUM=y +CONFIG_ROCKCHIP_ERRATUM_3588001=y CONFIG_SOCIONEXT_SYNQUACER_PREITS=y # end of ARM errata workarounds via the alternatives framework @@ -413,10 +413,10 @@ CONFIG_HOTPLUG_CPU=y CONFIG_NUMA=y CONFIG_NODES_SHIFT=4 # CONFIG_HZ_100 is not set -CONFIG_HZ_250=y -# CONFIG_HZ_300 is not set +# CONFIG_HZ_250 is not set +CONFIG_HZ_300=y # CONFIG_HZ_1000 is not set -CONFIG_HZ=250 +CONFIG_HZ=300 CONFIG_SCHED_HRTICK=y CONFIG_ARCH_SPARSEMEM_ENABLE=y CONFIG_HW_PERF_EVENTS=y @@ -425,11 +425,11 @@ CONFIG_PARAVIRT_TIME_ACCOUNTING=y CONFIG_KEXEC=y CONFIG_KEXEC_FILE=y # CONFIG_KEXEC_SIG is not set -CONFIG_CRASH_DUMP=y +# CONFIG_CRASH_DUMP is not set CONFIG_TRANS_TABLE=y CONFIG_XEN_DOM0=y CONFIG_XEN=y -CONFIG_ARCH_FORCE_MAX_ORDER=11 +CONFIG_ARCH_FORCE_MAX_ORDER=10 CONFIG_UNMAP_KERNEL_AT_EL0=y CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY=y CONFIG_RODATA_FULL_DEFAULT_ENABLED=y @@ -471,7 +471,7 @@ CONFIG_ARM64_PTR_AUTH=y CONFIG_ARM64_PTR_AUTH_KERNEL=y CONFIG_CC_HAS_BRANCH_PROT_PAC_RET=y CONFIG_CC_HAS_SIGN_RETURN_ADDRESS=y -CONFIG_AS_HAS_PAC=y +CONFIG_AS_HAS_ARMV8_3=y CONFIG_AS_HAS_CFI_NEGATE_RA_STATE=y # end of ARMv8.3 architectural features @@ -599,10 +599,8 @@ CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y # CONFIG_CPUFREQ_DT=y CONFIG_CPUFREQ_DT_PLATDEV=y -CONFIG_ACPI_CPPC_CPUFREQ=y -CONFIG_ACPI_CPPC_CPUFREQ_FIE=y -CONFIG_ARM_SCPI_CPUFREQ=y -CONFIG_ARM_SCMI_CPUFREQ=m +CONFIG_ARM_ROCKCHIP_CPUFREQ=y +# CONFIG_ARM_SCMI_CPUFREQ is not set # end of CPU Frequency scaling # end of CPU Power Management @@ -615,11 +613,12 @@ CONFIG_ACPI_TABLE_LIB=y CONFIG_ACPI_SPCR_TABLE=y # CONFIG_ACPI_FPDT is not set # CONFIG_ACPI_EC_DEBUGFS is not set -CONFIG_ACPI_AC=y -CONFIG_ACPI_BATTERY=y -CONFIG_ACPI_BUTTON=y -CONFIG_ACPI_VIDEO=y -CONFIG_ACPI_FAN=y +CONFIG_ACPI_AC=m +CONFIG_ACPI_BATTERY=m +CONFIG_ACPI_BUTTON=m +# CONFIG_ACPI_TINY_POWER_BUTTON is not set +CONFIG_ACPI_VIDEO=m +CONFIG_ACPI_FAN=m # CONFIG_ACPI_TAD is not set CONFIG_ACPI_DOCK=y CONFIG_ACPI_PROCESSOR_IDLE=y @@ -628,14 +627,14 @@ CONFIG_ACPI_CPPC_LIB=y CONFIG_ACPI_PROCESSOR=y CONFIG_ACPI_IPMI=m CONFIG_ACPI_HOTPLUG_CPU=y -CONFIG_ACPI_THERMAL=y +CONFIG_ACPI_THERMAL=m CONFIG_ARCH_HAS_ACPI_TABLE_UPGRADE=y CONFIG_ACPI_TABLE_UPGRADE=y # CONFIG_ACPI_DEBUG is not set CONFIG_ACPI_PCI_SLOT=y CONFIG_ACPI_CONTAINER=y CONFIG_ACPI_HED=y -CONFIG_ACPI_CUSTOM_METHOD=y +CONFIG_ACPI_CUSTOM_METHOD=m # CONFIG_ACPI_BGRT is not set CONFIG_ACPI_REDUCED_HARDWARE_ONLY=y CONFIG_ACPI_NUMA=y @@ -679,6 +678,7 @@ CONFIG_KVM_GENERIC_DIRTYLOG_READ_PROTECT=y CONFIG_HAVE_KVM_IRQ_BYPASS=y CONFIG_HAVE_KVM_VCPU_RUN_PID_CHANGE=y CONFIG_KVM_XFER_TO_GUEST_WORK=y +CONFIG_KVM_GENERIC_HARDWARE_ENABLING=y CONFIG_VIRTUALIZATION=y CONFIG_KVM=y # CONFIG_NVHE_EL2_DEBUG is not set @@ -725,6 +725,7 @@ CONFIG_HAVE_ARCH_JUMP_LABEL=y CONFIG_HAVE_ARCH_JUMP_LABEL_RELATIVE=y CONFIG_MMU_GATHER_TABLE_FREE=y CONFIG_MMU_GATHER_RCU_TABLE_FREE=y +CONFIG_MMU_LAZY_TLB_REFCOUNT=y CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG=y CONFIG_ARCH_HAS_NMI_SAFE_THIS_CPU_OPS=y CONFIG_HAVE_ALIGNED_STRUCT_PAGE=y @@ -798,18 +799,21 @@ CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y # end of GCOV-based kernel profiling CONFIG_HAVE_GCC_PLUGINS=y -CONFIG_FUNCTION_ALIGNMENT=0 +CONFIG_FUNCTION_ALIGNMENT_4B=y +CONFIG_FUNCTION_ALIGNMENT=4 # end of General architecture-dependent options CONFIG_RT_MUTEXES=y CONFIG_BASE_SMALL=0 CONFIG_MODULES=y -# CONFIG_MODULE_FORCE_LOAD is not set +# CONFIG_MODULE_DEBUG is not set +CONFIG_MODULE_FORCE_LOAD=y CONFIG_MODULE_UNLOAD=y CONFIG_MODULE_FORCE_UNLOAD=y # CONFIG_MODULE_UNLOAD_TAINT_TRACKING is not set -# CONFIG_MODVERSIONS is not set -# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_MODVERSIONS=y +CONFIG_ASM_MODVERSIONS=y +CONFIG_MODULE_SRCVERSION_ALL=y # CONFIG_MODULE_SIG is not set CONFIG_MODULE_COMPRESS_NONE=y # CONFIG_MODULE_COMPRESS_GZIP is not set @@ -822,6 +826,7 @@ CONFIG_MODULES_TREE_LOOKUP=y CONFIG_BLOCK=y CONFIG_BLOCK_LEGACY_AUTOLOAD=y CONFIG_BLK_CGROUP_RWSTAT=y +CONFIG_BLK_CGROUP_PUNT_BIO=y CONFIG_BLK_DEV_BSG_COMMON=y CONFIG_BLK_ICQ=y CONFIG_BLK_DEV_BSGLIB=y @@ -867,7 +872,6 @@ CONFIG_EFI_PARTITION=y CONFIG_CMDLINE_PARTITION=y # end of Partition Types -CONFIG_BLOCK_COMPAT=y CONFIG_BLK_MQ_PCI=y CONFIG_BLK_MQ_VIRTIO=y CONFIG_BLK_PM=y @@ -938,13 +942,13 @@ CONFIG_ZBUD=y CONFIG_Z3FOLD=y CONFIG_ZSMALLOC=y # CONFIG_ZSMALLOC_STAT is not set +CONFIG_ZSMALLOC_CHAIN_SIZE=8 # # SLAB allocator options # # CONFIG_SLAB is not set CONFIG_SLUB=y -# CONFIG_SLOB_DEPRECATED is not set # CONFIG_SLUB_TINY is not set CONFIG_SLAB_MERGE_DEFAULT=y CONFIG_SLAB_FREELIST_RANDOM=y @@ -997,7 +1001,7 @@ CONFIG_HAVE_SETUP_PER_CPU_AREA=y CONFIG_FRONTSWAP=y CONFIG_CMA=y # CONFIG_CMA_DEBUG is not set -CONFIG_CMA_DEBUGFS=y +# CONFIG_CMA_DEBUGFS is not set # CONFIG_CMA_SYSFS is not set CONFIG_CMA_AREAS=7 CONFIG_GENERIC_EARLY_IOREMAP=y @@ -1016,6 +1020,7 @@ CONFIG_ARCH_USES_PG_ARCH_X=y CONFIG_VM_EVENT_COUNTERS=y CONFIG_PERCPU_STATS=y # CONFIG_GUP_TEST is not set +# CONFIG_DMAPOOL_TEST is not set CONFIG_ARCH_HAS_PTE_SPECIAL=y CONFIG_MAPPING_DIRTY_HELPERS=y CONFIG_SECRETMEM=y @@ -1024,17 +1029,14 @@ CONFIG_SECRETMEM=y CONFIG_LRU_GEN=y # CONFIG_LRU_GEN_ENABLED is not set # CONFIG_LRU_GEN_STATS is not set +CONFIG_ARCH_SUPPORTS_PER_VMA_LOCK=y +CONFIG_PER_VMA_LOCK=y +CONFIG_LOCK_MM_AND_FIND_VMA=y # # Data Access Monitoring # -CONFIG_DAMON=y -CONFIG_DAMON_VADDR=y -CONFIG_DAMON_PADDR=y -# CONFIG_DAMON_SYSFS is not set -# CONFIG_DAMON_DBGFS is not set -CONFIG_DAMON_RECLAIM=y -CONFIG_DAMON_LRU_SORT=y +# CONFIG_DAMON is not set # end of Data Access Monitoring # end of Memory Management options @@ -1072,6 +1074,8 @@ CONFIG_NET_KEY=m CONFIG_NET_KEY_MIGRATE=y CONFIG_XDP_SOCKETS=y # CONFIG_XDP_SOCKETS_DIAG is not set +CONFIG_NET_HANDSHAKE=y +# CONFIG_NET_HANDSHAKE_KUNIT_TEST is not set CONFIG_INET=y CONFIG_IP_MULTICAST=y CONFIG_IP_ADVANCED_ROUTER=y @@ -1182,6 +1186,7 @@ CONFIG_NETFILTER_SKIP_EGRESS=y CONFIG_NETFILTER_NETLINK=m CONFIG_NETFILTER_FAMILY_BRIDGE=y CONFIG_NETFILTER_FAMILY_ARP=y +CONFIG_NETFILTER_BPF_LINK=y CONFIG_NETFILTER_NETLINK_HOOK=m CONFIG_NETFILTER_NETLINK_ACCT=m CONFIG_NETFILTER_NETLINK_QUEUE=m @@ -1198,6 +1203,7 @@ CONFIG_NF_CONNTRACK_EVENTS=y CONFIG_NF_CONNTRACK_TIMEOUT=y CONFIG_NF_CONNTRACK_TIMESTAMP=y CONFIG_NF_CONNTRACK_LABELS=y +CONFIG_NF_CONNTRACK_OVS=y CONFIG_NF_CT_PROTO_DCCP=y CONFIG_NF_CT_PROTO_GRE=y CONFIG_NF_CT_PROTO_SCTP=y @@ -1452,7 +1458,6 @@ CONFIG_IP_NF_TARGET_MASQUERADE=m CONFIG_IP_NF_TARGET_NETMAP=m CONFIG_IP_NF_TARGET_REDIRECT=m CONFIG_IP_NF_MANGLE=m -CONFIG_IP_NF_TARGET_CLUSTERIP=m CONFIG_IP_NF_TARGET_ECN=m CONFIG_IP_NF_TARGET_TTL=m CONFIG_IP_NF_RAW=m @@ -1640,10 +1645,8 @@ CONFIG_NET_SCHED=y # # Queueing/Scheduling # -CONFIG_NET_SCH_CBQ=m CONFIG_NET_SCH_HTB=m CONFIG_NET_SCH_HFSC=m -CONFIG_NET_SCH_ATM=m CONFIG_NET_SCH_PRIO=m CONFIG_NET_SCH_MULTIQ=m CONFIG_NET_SCH_RED=m @@ -1653,9 +1656,9 @@ CONFIG_NET_SCH_TEQL=m CONFIG_NET_SCH_TBF=m CONFIG_NET_SCH_CBS=m CONFIG_NET_SCH_ETF=m +CONFIG_NET_SCH_MQPRIO_LIB=m CONFIG_NET_SCH_TAPRIO=m CONFIG_NET_SCH_GRED=m -CONFIG_NET_SCH_DSMARK=m CONFIG_NET_SCH_NETEM=m CONFIG_NET_SCH_DRR=m CONFIG_NET_SCH_MQPRIO=m @@ -1686,14 +1689,11 @@ CONFIG_DEFAULT_NET_SCH="pfifo_fast" # CONFIG_NET_CLS=y CONFIG_NET_CLS_BASIC=m -CONFIG_NET_CLS_TCINDEX=m CONFIG_NET_CLS_ROUTE4=m CONFIG_NET_CLS_FW=m CONFIG_NET_CLS_U32=m CONFIG_CLS_U32_PERF=y CONFIG_CLS_U32_MARK=y -CONFIG_NET_CLS_RSVP=m -CONFIG_NET_CLS_RSVP6=m CONFIG_NET_CLS_FLOW=m CONFIG_NET_CLS_CGROUP=m CONFIG_NET_CLS_BPF=m @@ -1767,6 +1767,7 @@ CONFIG_NET_L3_MASTER_DEV=y # CONFIG_QRTR is not set # CONFIG_NET_NCSI is not set CONFIG_PCPU_DEV_REFCNT=y +CONFIG_MAX_SKB_FRAGS=17 CONFIG_RPS=y CONFIG_RFS_ACCEL=y CONFIG_SOCK_RX_QUEUE_MAPPING=y @@ -1874,11 +1875,13 @@ CONFIG_BT_MTKSDIO=m CONFIG_BT_MTKUART=m CONFIG_BT_HCIRSI=m CONFIG_BT_VIRTIO=m +# CONFIG_BT_NXPUART is not set # end of Bluetooth device drivers CONFIG_AF_RXRPC=m # CONFIG_AF_RXRPC_IPV6 is not set # CONFIG_AF_RXRPC_INJECT_LOSS is not set +# CONFIG_AF_RXRPC_INJECT_RX_DELAY is not set # CONFIG_AF_RXRPC_DEBUG is not set # CONFIG_RXKAD is not set # CONFIG_RXPERF is not set @@ -1992,7 +1995,7 @@ CONFIG_NET_SELFTESTS=y CONFIG_NET_SOCK_MSG=y CONFIG_NET_DEVLINK=y CONFIG_PAGE_POOL=y -# CONFIG_PAGE_POOL_STATS is not set +CONFIG_PAGE_POOL_STATS=y CONFIG_FAILOVER=y CONFIG_ETHTOOL_NETLINK=y # CONFIG_NETDEV_ADDR_LIST_TEST is not set @@ -2012,10 +2015,10 @@ CONFIG_PCIEAER=y CONFIG_PCIEAER_INJECT=m CONFIG_PCIE_ECRC=y CONFIG_PCIEASPM=y -# CONFIG_PCIEASPM_DEFAULT is not set +CONFIG_PCIEASPM_DEFAULT=y # CONFIG_PCIEASPM_POWERSAVE is not set # CONFIG_PCIEASPM_POWER_SUPERSAVE is not set -CONFIG_PCIEASPM_PERFORMANCE=y +# CONFIG_PCIEASPM_PERFORMANCE is not set CONFIG_PCIE_PME=y # CONFIG_PCIE_DPC is not set # CONFIG_PCIE_PTM is not set @@ -2048,51 +2051,51 @@ CONFIG_HOTPLUG_PCI_ACPI=y # # PCI controller drivers # -# CONFIG_PCI_FTPCI100 is not set -CONFIG_PCI_HOST_COMMON=y -CONFIG_PCI_HOST_GENERIC=y -# CONFIG_PCIE_XILINX is not set -CONFIG_PCI_XGENE=y -CONFIG_PCI_XGENE_MSI=y CONFIG_PCIE_ALTERA=y CONFIG_PCIE_ALTERA_MSI=y CONFIG_PCI_HOST_THUNDER_PEM=y CONFIG_PCI_HOST_THUNDER_ECAM=y +# CONFIG_PCI_FTPCI100 is not set +CONFIG_PCI_HOST_COMMON=y +CONFIG_PCI_HOST_GENERIC=y +# CONFIG_PCIE_HISI_ERR is not set +# CONFIG_PCIE_MICROCHIP_HOST is not set CONFIG_PCIE_ROCKCHIP=y CONFIG_PCIE_ROCKCHIP_HOST=y CONFIG_PCIE_ROCKCHIP_EP=y -# CONFIG_PCIE_MICROCHIP_HOST is not set -# CONFIG_PCIE_HISI_ERR is not set +CONFIG_PCI_XGENE=y +CONFIG_PCI_XGENE_MSI=y +# CONFIG_PCIE_XILINX is not set # -# DesignWare PCI Core Support -# -CONFIG_PCIE_DW=y -CONFIG_PCIE_DW_HOST=y -CONFIG_PCIE_DW_EP=y -CONFIG_PCIE_DW_PLAT=y -CONFIG_PCIE_DW_PLAT_HOST=y -CONFIG_PCIE_DW_PLAT_EP=y -CONFIG_PCI_HISI=y -CONFIG_PCIE_ROCKCHIP_DW_HOST=y -# CONFIG_PCIE_KIRIN is not set -# CONFIG_PCI_MESON is not set -# CONFIG_PCIE_AL is not set -# end of DesignWare PCI Core Support - -# -# Mobiveil PCIe Core Support -# -# end of Mobiveil PCIe Core Support - -# -# Cadence PCIe controllers support +# Cadence-based PCIe controllers # # CONFIG_PCIE_CADENCE_PLAT_HOST is not set # CONFIG_PCIE_CADENCE_PLAT_EP is not set # CONFIG_PCI_J721E_HOST is not set # CONFIG_PCI_J721E_EP is not set -# end of Cadence PCIe controllers support +# end of Cadence-based PCIe controllers + +# +# DesignWare-based PCIe controllers +# +CONFIG_PCIE_DW=y +CONFIG_PCIE_DW_HOST=y +CONFIG_PCIE_DW_EP=y +# CONFIG_PCIE_AL is not set +# CONFIG_PCI_MESON is not set +CONFIG_PCI_HISI=y +# CONFIG_PCIE_KIRIN is not set +CONFIG_PCIE_DW_PLAT=y +CONFIG_PCIE_DW_PLAT_HOST=y +CONFIG_PCIE_DW_PLAT_EP=y +CONFIG_PCIE_ROCKCHIP_DW_HOST=y +# end of DesignWare-based PCIe controllers + +# +# Mobiveil-based PCIe controllers +# +# end of Mobiveil-based PCIe controllers # end of PCI controller drivers # @@ -2138,16 +2141,14 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # Firmware loader # CONFIG_FW_LOADER=y +CONFIG_FW_LOADER_DEBUG=y CONFIG_FW_LOADER_PAGED_BUF=y CONFIG_FW_LOADER_SYSFS=y CONFIG_EXTRA_FIRMWARE="" -CONFIG_FW_LOADER_USER_HELPER=y -CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y -CONFIG_FW_LOADER_COMPRESS=y -CONFIG_FW_LOADER_COMPRESS_XZ=y -# CONFIG_FW_LOADER_COMPRESS_ZSTD is not set +# CONFIG_FW_LOADER_USER_HELPER is not set +# CONFIG_FW_LOADER_COMPRESS is not set CONFIG_FW_CACHE=y -# CONFIG_FW_UPLOAD is not set +CONFIG_FW_UPLOAD=y # end of Firmware loader CONFIG_WANT_DEV_COREDUMP=y @@ -2163,6 +2164,7 @@ CONFIG_GENERIC_CPU_AUTOPROBE=y CONFIG_GENERIC_CPU_VULNERABILITIES=y CONFIG_SOC_BUS=y CONFIG_REGMAP=y +# CONFIG_REGMAP_KUNIT is not set CONFIG_REGMAP_I2C=y CONFIG_REGMAP_SLIMBUS=m CONFIG_REGMAP_SPI=m @@ -2177,6 +2179,7 @@ CONFIG_DMA_SHARED_BUFFER=y # CONFIG_DMA_FENCE_TRACE is not set CONFIG_GENERIC_ARCH_TOPOLOGY=y CONFIG_GENERIC_ARCH_NUMA=y +# CONFIG_FW_DEVLINK_SYNC_STATE_TIMEOUT is not set # end of Generic Driver Options # @@ -2203,6 +2206,7 @@ CONFIG_CONNECTOR=m # ARM System Control and Management Interface Protocol # CONFIG_ARM_SCMI_PROTOCOL=y +# CONFIG_ARM_SCMI_RAW_MODE_SUPPORT is not set CONFIG_ARM_SCMI_HAVE_TRANSPORT=y CONFIG_ARM_SCMI_HAVE_SHMEM=y CONFIG_ARM_SCMI_HAVE_MSG=y @@ -2428,7 +2432,7 @@ CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y # CONFIG_MTD_SPI_NOR_SWP_DISABLE is not set CONFIG_MTD_SPI_NOR_SWP_DISABLE_ON_VOLATILE=y # CONFIG_MTD_SPI_NOR_SWP_KEEP is not set -CONFIG_MTD_UBI=m +CONFIG_MTD_UBI=y CONFIG_MTD_UBI_WL_THRESHOLD=4096 CONFIG_MTD_UBI_BEB_LIMIT=20 # CONFIG_MTD_UBI_FASTMAP is not set @@ -2486,6 +2490,7 @@ CONFIG_XEN_BLKDEV_BACKEND=m CONFIG_VIRTIO_BLK=y CONFIG_BLK_DEV_RBD=m CONFIG_BLK_DEV_UBLK=m +CONFIG_BLKDEV_UBLK_LEGACY_OPCODES=y # # NVME Support @@ -2576,7 +2581,6 @@ CONFIG_BCM_VK=m CONFIG_MISC_ALCOR_PCI=m CONFIG_MISC_RTSX_PCI=m CONFIG_MISC_RTSX_USB=m -CONFIG_HABANA_AI=m CONFIG_UACCE=m # CONFIG_PVPANIC is not set CONFIG_GP_PCI1XXXX=m @@ -2721,8 +2725,6 @@ CONFIG_SATA_MOBILE_LPM_POLICY=0 CONFIG_SATA_AHCI_PLATFORM=y CONFIG_AHCI_DWC=y CONFIG_AHCI_CEVA=y -CONFIG_AHCI_XGENE=y -CONFIG_AHCI_QORIQ=y CONFIG_SATA_INIC162X=m CONFIG_SATA_ACARD_AHCI=m CONFIG_SATA_SIL24=y @@ -2867,6 +2869,7 @@ CONFIG_TCM_USER2=m CONFIG_LOOPBACK_TARGET=m CONFIG_TCM_FC=m CONFIG_ISCSI_TARGET=m +# CONFIG_REMOTE_TARGET is not set CONFIG_FUSION=y CONFIG_FUSION_SPI=m CONFIG_FUSION_FC=m @@ -2964,16 +2967,21 @@ CONFIG_NET_DSA_LOOP=m CONFIG_NET_DSA_HIRSCHMANN_HELLCREEK=m CONFIG_NET_DSA_LANTIQ_GSWIP=m CONFIG_NET_DSA_MT7530=m +CONFIG_NET_DSA_MT7530_MDIO=m +CONFIG_NET_DSA_MT7530_MMIO=m CONFIG_NET_DSA_MV88E6060=m CONFIG_NET_DSA_MICROCHIP_KSZ_COMMON=m CONFIG_NET_DSA_MICROCHIP_KSZ9477_I2C=m CONFIG_NET_DSA_MICROCHIP_KSZ_SPI=m +# CONFIG_NET_DSA_MICROCHIP_KSZ_PTP is not set CONFIG_NET_DSA_MICROCHIP_KSZ8863_SMI=m CONFIG_NET_DSA_MV88E6XXX=m # CONFIG_NET_DSA_MV88E6XXX_PTP is not set +# CONFIG_NET_DSA_MSCC_OCELOT_EXT is not set # CONFIG_NET_DSA_MSCC_SEVILLE is not set CONFIG_NET_DSA_AR9331=m CONFIG_NET_DSA_QCA8K=m +# CONFIG_NET_DSA_QCA8K_LEDS_SUPPORT is not set CONFIG_NET_DSA_SJA1105=m # CONFIG_NET_DSA_SJA1105_PTP is not set CONFIG_NET_DSA_XRS700X=m @@ -3014,6 +3022,7 @@ CONFIG_AMD8111_ETH=m CONFIG_PCNET32=m CONFIG_AMD_XGBE=m # CONFIG_AMD_XGBE_DCB is not set +# CONFIG_PDS_CORE is not set CONFIG_NET_VENDOR_AQUANTIA=y CONFIG_AQTION=m CONFIG_NET_VENDOR_ARC=y @@ -3107,7 +3116,6 @@ CONFIG_E1000E=m CONFIG_IGB=m CONFIG_IGB_HWMON=y CONFIG_IGBVF=m -CONFIG_IXGB=m CONFIG_IXGBE=m CONFIG_IXGBE_HWMON=y CONFIG_IXGBE_DCB=y @@ -3121,10 +3129,6 @@ CONFIG_I40EVF=m # CONFIG_ICE is not set CONFIG_FM10K=m # CONFIG_IGC is not set -CONFIG_NET_VENDOR_WANGXUN=y -CONFIG_LIBWX=m -CONFIG_NGBE=m -# CONFIG_TXGBE is not set CONFIG_JME=m CONFIG_NET_VENDOR_ADI=y CONFIG_ADIN1110=m @@ -3157,8 +3161,6 @@ CONFIG_MLX5_EN_RXNFC=y CONFIG_MLX5_MPFS=y CONFIG_MLX5_ESWITCH=y CONFIG_MLX5_BRIDGE=y -CONFIG_MLX5_CLS_ACT=y -CONFIG_MLX5_TC_SAMPLE=y CONFIG_MLX5_CORE_EN_DCB=y # CONFIG_MLX5_CORE_IPOIB is not set # CONFIG_MLX5_EN_MACSEC is not set @@ -3187,6 +3189,7 @@ CONFIG_MSCC_OCELOT_SWITCH=m CONFIG_NET_VENDOR_MICROSOFT=y CONFIG_NET_VENDOR_MYRI=y CONFIG_MYRI10GE=m +# CONFIG_FEALNX is not set CONFIG_NET_VENDOR_NI=y # CONFIG_NI_XGE_MANAGEMENT_ENET is not set CONFIG_NET_VENDOR_NATSEMI=y @@ -3278,6 +3281,10 @@ CONFIG_NET_VENDOR_VERTEXCOM=y CONFIG_NET_VENDOR_VIA=y # CONFIG_VIA_RHINE is not set # CONFIG_VIA_VELOCITY is not set +CONFIG_NET_VENDOR_WANGXUN=y +CONFIG_LIBWX=m +CONFIG_NGBE=m +# CONFIG_TXGBE is not set CONFIG_NET_VENDOR_WIZNET=y # CONFIG_WIZNET_W5100 is not set # CONFIG_WIZNET_W5300 is not set @@ -3292,6 +3299,7 @@ CONFIG_PHYLINK=y CONFIG_PHYLIB=y CONFIG_SWPHY=y CONFIG_LED_TRIGGER_PHY=y +CONFIG_PHYLIB_LEDS=y CONFIG_FIXED_PHY=y CONFIG_SFP=m @@ -3323,13 +3331,16 @@ CONFIG_MARVELL_88X2222_PHY=m CONFIG_MAXLINEAR_GPHY=m CONFIG_MEDIATEK_GE_PHY=m CONFIG_MICREL_PHY=y +# CONFIG_MICROCHIP_T1S_PHY is not set CONFIG_MICROCHIP_PHY=m CONFIG_MICROCHIP_T1_PHY=m CONFIG_MICROSEMI_PHY=m CONFIG_MOTORCOMM_PHY=y CONFIG_NATIONAL_PHY=m +# CONFIG_NXP_CBTX_PHY is not set CONFIG_NXP_C45_TJA11XX_PHY=m # CONFIG_NXP_TJA11XX_PHY is not set +# CONFIG_NCN26000_PHY is not set CONFIG_AT803X_PHY=m CONFIG_QSEMI_PHY=m CONFIG_REALTEK_PHY=y @@ -3441,6 +3452,7 @@ CONFIG_MDIO_BUS_MUX_MMIOREG=y # PCS device drivers # CONFIG_PCS_XPCS=y +CONFIG_PCS_MTK_LYNXI=m CONFIG_PCS_ALTERA_TSE=m # end of PCS device drivers @@ -3569,6 +3581,7 @@ CONFIG_ATH11K_AHB=m # CONFIG_ATH11K_PCI is not set # CONFIG_ATH11K_DEBUG is not set # CONFIG_ATH11K_TRACING is not set +# CONFIG_ATH12K is not set CONFIG_WLAN_VENDOR_ATMEL=y CONFIG_ATMEL=m CONFIG_PCI_ATMEL=m @@ -3615,6 +3628,7 @@ CONFIG_BRCMFMAC_PCIE=y CONFIG_BRCM_TRACING=y CONFIG_BRCMDBG=y CONFIG_WLAN_VENDOR_CISCO=y +# CONFIG_AIRO is not set CONFIG_WLAN_VENDOR_INTEL=y CONFIG_IPW2100=m CONFIG_IPW2100_MONITOR=y @@ -3779,12 +3793,16 @@ CONFIG_RTW88_8822C=m CONFIG_RTW88_8723D=m CONFIG_RTW88_8821C=m CONFIG_RTW88_8822BE=m +# CONFIG_RTW88_8822BS is not set # CONFIG_RTW88_8822BU is not set CONFIG_RTW88_8822CE=m +# CONFIG_RTW88_8822CS is not set # CONFIG_RTW88_8822CU is not set CONFIG_RTW88_8723DE=m +# CONFIG_RTW88_8723DS is not set # CONFIG_RTW88_8723DU is not set CONFIG_RTW88_8821CE=m +# CONFIG_RTW88_8821CS is not set # CONFIG_RTW88_8821CU is not set # CONFIG_RTW88_DEBUG is not set # CONFIG_RTW88_DEBUGFS is not set @@ -3821,7 +3839,6 @@ CONFIG_WLCORE_SPI=m CONFIG_WLCORE_SDIO=m CONFIG_RTL8723DU=m CONFIG_RTL8723DS=m -CONFIG_RTL8822CS=m CONFIG_RTL8822BU=m CONFIG_RTL8821CU=m CONFIG_88XXAU=m @@ -3835,8 +3852,8 @@ CONFIG_ZD1211RW=m CONFIG_WLAN_VENDOR_QUANTENNA=y CONFIG_QTNFMAC=m CONFIG_QTNFMAC_PCIE=m -CONFIG_MAC80211_HWSIM=m CONFIG_USB_NET_RNDIS_WLAN=m +CONFIG_MAC80211_HWSIM=m CONFIG_VIRT_WIFI=m CONFIG_WAN=y CONFIG_HDLC=m @@ -3910,7 +3927,6 @@ CONFIG_INPUT_EVDEV=y # CONFIG_INPUT_KEYBOARD=y CONFIG_KEYBOARD_ADC=m -CONFIG_KEYBOARD_ADP5520=m # CONFIG_KEYBOARD_ADP5588 is not set # CONFIG_KEYBOARD_ADP5589 is not set CONFIG_KEYBOARD_ATKBD=y @@ -3935,7 +3951,6 @@ CONFIG_KEYBOARD_GPIO_POLLED=m # CONFIG_KEYBOARD_SAMSUNG is not set # CONFIG_KEYBOARD_STOWAWAY is not set # CONFIG_KEYBOARD_SUNKBD is not set -CONFIG_KEYBOARD_IQS62X=m # CONFIG_KEYBOARD_OMAP4 is not set # CONFIG_KEYBOARD_TM2_TOUCHKEY is not set # CONFIG_KEYBOARD_XTKBD is not set @@ -4057,6 +4072,7 @@ CONFIG_TOUCHSCREEN_MMS114=m CONFIG_TOUCHSCREEN_MELFAS_MIP4=m CONFIG_TOUCHSCREEN_MSG2638=m CONFIG_TOUCHSCREEN_MTOUCH=m +# CONFIG_TOUCHSCREEN_NOVATEK_NVT_TS is not set CONFIG_TOUCHSCREEN_IMAGIS=m CONFIG_TOUCHSCREEN_IMX6UL_TSC=m CONFIG_TOUCHSCREEN_INEXIO=m @@ -4065,7 +4081,6 @@ CONFIG_TOUCHSCREEN_PENMOUNT=m CONFIG_TOUCHSCREEN_EDT_FT5X06=m CONFIG_TOUCHSCREEN_TOUCHRIGHT=m CONFIG_TOUCHSCREEN_TOUCHWIN=m -CONFIG_TOUCHSCREEN_UCB1400=m CONFIG_TOUCHSCREEN_PIXCIR=m CONFIG_TOUCHSCREEN_WDT87XX_I2C=m CONFIG_TOUCHSCREEN_WM97XX=m @@ -4116,12 +4131,9 @@ CONFIG_TOUCHSCREEN_ZINITIX=m # CONFIG_TOUCHSCREEN_HIMAX_HX83112B is not set CONFIG_INPUT_MISC=y # CONFIG_INPUT_AD714X is not set -# CONFIG_INPUT_ARIZONA_HAPTICS is not set -CONFIG_INPUT_ATC260X_ONKEY=m # CONFIG_INPUT_ATMEL_CAPTOUCH is not set # CONFIG_INPUT_BMA150 is not set # CONFIG_INPUT_E3X0_BUTTON is not set -CONFIG_INPUT_MAX77650_ONKEY=m # CONFIG_INPUT_MMA8450 is not set CONFIG_INPUT_GPIO_BEEPER=m CONFIG_INPUT_GPIO_DECODER=m @@ -4133,11 +4145,11 @@ CONFIG_INPUT_ATI_REMOTE2=m # CONFIG_INPUT_YEALINK is not set # CONFIG_INPUT_CM109 is not set # CONFIG_INPUT_REGULATOR_HAPTIC is not set -CONFIG_INPUT_AXP20X_PEK=m CONFIG_INPUT_UINPUT=m # CONFIG_INPUT_PCF8574 is not set # CONFIG_INPUT_PWM_BEEPER is not set # CONFIG_INPUT_PWM_VIBRA is not set +# CONFIG_INPUT_RK805_PWRKEY is not set # CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set CONFIG_INPUT_DA7280_HAPTICS=m # CONFIG_INPUT_ADXL34X is not set @@ -4152,8 +4164,6 @@ CONFIG_INPUT_SOC_BUTTON_ARRAY=m # CONFIG_INPUT_DRV260X_HAPTICS is not set # CONFIG_INPUT_DRV2665_HAPTICS is not set # CONFIG_INPUT_DRV2667_HAPTICS is not set -CONFIG_INPUT_RAVE_SP_PWRBUTTON=m -CONFIG_INPUT_RT5120_PWRKEY=m CONFIG_RMI4_CORE=m CONFIG_RMI4_I2C=m CONFIG_RMI4_SPI=m @@ -4219,12 +4229,14 @@ CONFIG_SERIAL_8250_16550A_VARIANTS=y CONFIG_SERIAL_8250_FINTEK=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_DMA=y +CONFIG_SERIAL_8250_PCILIB=y CONFIG_SERIAL_8250_PCI=m CONFIG_SERIAL_8250_EXAR=m CONFIG_SERIAL_8250_NR_UARTS=8 CONFIG_SERIAL_8250_RUNTIME_UARTS=8 CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_MANY_PORTS=y +# CONFIG_SERIAL_8250_PCI1XXXX is not set CONFIG_SERIAL_8250_SHARE_IRQ=y # CONFIG_SERIAL_8250_DETECT_IRQ is not set CONFIG_SERIAL_8250_RSA=y @@ -4242,7 +4254,7 @@ CONFIG_SERIAL_AMBA_PL010=y CONFIG_SERIAL_AMBA_PL010_CONSOLE=y CONFIG_SERIAL_AMBA_PL011=y CONFIG_SERIAL_AMBA_PL011_CONSOLE=y -CONFIG_SERIAL_EARLYCON_ARM_SEMIHOST=y +# CONFIG_SERIAL_EARLYCON_SEMIHOST is not set # CONFIG_SERIAL_MAX3100 is not set # CONFIG_SERIAL_MAX310X is not set # CONFIG_SERIAL_UARTLITE is not set @@ -4267,7 +4279,6 @@ CONFIG_SERIAL_ARC_NR_PORTS=1 CONFIG_SERIAL_RP2=m CONFIG_SERIAL_RP2_NR_UARTS=32 CONFIG_SERIAL_FSL_LPUART=m -# CONFIG_SERIAL_FSL_LPUART_CONSOLE is not set CONFIG_SERIAL_FSL_LINFLEXUART=m CONFIG_SERIAL_CONEXANT_DIGICOLOR=m CONFIG_SERIAL_SPRD=m @@ -4474,7 +4485,6 @@ CONFIG_SPI_DW_PCI=m CONFIG_SPI_DW_MMIO=m CONFIG_SPI_HISI_KUNPENG=m CONFIG_SPI_HISI_SFC_V3XX=m -CONFIG_SPI_NXP_FLEXSPI=m CONFIG_SPI_GPIO=m CONFIG_SPI_FSL_LIB=m CONFIG_SPI_FSL_SPI=m @@ -4485,7 +4495,7 @@ CONFIG_SPI_OC_TINY=m CONFIG_SPI_PL022=y # CONFIG_SPI_PXA2XX is not set CONFIG_SPI_ROCKCHIP=y -CONFIG_SPI_ROCKCHIP_SFC=m +CONFIG_SPI_ROCKCHIP_SFC=y # CONFIG_SPI_SC18IS602 is not set # CONFIG_SPI_SIFIVE is not set # CONFIG_SPI_SN_F_OSPI is not set @@ -4549,13 +4559,11 @@ CONFIG_PINCONF=y CONFIG_GENERIC_PINCONF=y # CONFIG_DEBUG_PINCTRL is not set # CONFIG_PINCTRL_AMD is not set -CONFIG_PINCTRL_AS3722=m -CONFIG_PINCTRL_AXP209=m CONFIG_PINCTRL_CY8C95X0=m -CONFIG_PINCTRL_MAX77620=y # CONFIG_PINCTRL_MCP23S08 is not set # CONFIG_PINCTRL_MICROCHIP_SGPIO is not set # CONFIG_PINCTRL_OCELOT is not set +CONFIG_PINCTRL_RK805=m CONFIG_PINCTRL_ROCKCHIP=y CONFIG_PINCTRL_SINGLE=y CONFIG_PINCTRL_STMFX=m @@ -4571,6 +4579,7 @@ CONFIG_GPIOLIB_FASTPATH_LIMIT=512 CONFIG_OF_GPIO=y CONFIG_GPIO_ACPI=y CONFIG_GPIOLIB_IRQCHIP=y +CONFIG_OF_GPIO_MM_GPIOCHIP=y # CONFIG_DEBUG_GPIO is not set CONFIG_GPIO_SYSFS=y CONFIG_GPIO_CDEV=y @@ -4608,6 +4617,7 @@ CONFIG_GPIO_AMD_FCH=m # I2C GPIO expanders # CONFIG_GPIO_ADNP=m +# CONFIG_GPIO_FXL6408 is not set CONFIG_GPIO_GW_PLD=m CONFIG_GPIO_MAX7300=m CONFIG_GPIO_MAX732X=m @@ -4621,16 +4631,6 @@ CONFIG_GPIO_TPIC2810=m # # MFD GPIO expanders # -CONFIG_GPIO_ADP5520=m -CONFIG_GPIO_ARIZONA=m -CONFIG_GPIO_BD71815=m -CONFIG_GPIO_BD71828=m -CONFIG_GPIO_BD9571MWV=m -CONFIG_GPIO_MAX77620=y -CONFIG_GPIO_MAX77650=m -# CONFIG_GPIO_RC5T583 is not set -CONFIG_GPIO_TQMX86=m -CONFIG_GPIO_UCB1400=m # end of MFD GPIO expanders # @@ -4676,7 +4676,6 @@ CONFIG_W1_CON=y CONFIG_W1_MASTER_MATROX=m CONFIG_W1_MASTER_DS2490=m CONFIG_W1_MASTER_DS2482=m -CONFIG_W1_MASTER_DS1WM=m CONFIG_W1_MASTER_GPIO=m CONFIG_W1_MASTER_SGI=m # end of 1-wire Bus Masters @@ -4706,8 +4705,6 @@ CONFIG_W1_SLAVE_DS28E17=m # end of 1-wire Slaves CONFIG_POWER_RESET=y -# CONFIG_POWER_RESET_AS3722 is not set -CONFIG_POWER_RESET_ATC260X=m CONFIG_POWER_RESET_BRCMSTB=y CONFIG_POWER_RESET_GPIO=y CONFIG_POWER_RESET_GPIO_RESTART=y @@ -4724,7 +4721,6 @@ CONFIG_SYSCON_REBOOT_MODE=y CONFIG_POWER_SUPPLY=y # CONFIG_POWER_SUPPLY_DEBUG is not set CONFIG_POWER_SUPPLY_HWMON=y -# CONFIG_PDA_POWER is not set CONFIG_GENERIC_ADC_BATTERY=m # CONFIG_IP5XXX_POWER is not set # CONFIG_TEST_POWER is not set @@ -4742,9 +4738,6 @@ CONFIG_BATTERY_BQ27XXX=m CONFIG_BATTERY_BQ27XXX_I2C=m CONFIG_BATTERY_BQ27XXX_HDQ=m # CONFIG_BATTERY_BQ27XXX_DT_UPDATES_NVM is not set -CONFIG_CHARGER_AXP20X=m -CONFIG_BATTERY_AXP20X=m -CONFIG_AXP20X_POWER=m CONFIG_BATTERY_MAX17040=m CONFIG_BATTERY_MAX17042=m CONFIG_BATTERY_MAX1721X=m @@ -4756,7 +4749,6 @@ CONFIG_CHARGER_GPIO=m CONFIG_CHARGER_LT3651=m CONFIG_CHARGER_LTC4162L=m CONFIG_CHARGER_DETECTOR_MAX14656=m -CONFIG_CHARGER_MAX77650=m # CONFIG_CHARGER_MAX77976 is not set # CONFIG_CHARGER_MT6370 is not set # CONFIG_CHARGER_BQ2415X is not set @@ -4767,16 +4759,18 @@ CONFIG_CHARGER_MAX77650=m # CONFIG_CHARGER_BQ25890 is not set # CONFIG_CHARGER_BQ25980 is not set CONFIG_CHARGER_BQ256XX=m +# CONFIG_CHARGER_RK817 is not set CONFIG_CHARGER_SMB347=m # CONFIG_BATTERY_GAUGE_LTC2941 is not set CONFIG_BATTERY_GOLDFISH=m CONFIG_BATTERY_RT5033=m # CONFIG_CHARGER_RT9455 is not set +# CONFIG_CHARGER_RT9467 is not set +# CONFIG_CHARGER_RT9471 is not set # CONFIG_CHARGER_CROS_USBPD is not set CONFIG_CHARGER_CROS_PCHG=m CONFIG_CHARGER_UCS1002=m # CONFIG_CHARGER_BD99954 is not set -# CONFIG_RN5T618_POWER is not set # CONFIG_BATTERY_UG3105 is not set CONFIG_HWMON=y CONFIG_HWMON_VID=m @@ -4859,6 +4853,7 @@ CONFIG_SENSORS_MAX6639=m CONFIG_SENSORS_MAX6650=m CONFIG_SENSORS_MAX6697=m CONFIG_SENSORS_MAX31790=m +# CONFIG_SENSORS_MC34VR500 is not set CONFIG_SENSORS_MCP3021=m CONFIG_SENSORS_TC654=m CONFIG_SENSORS_TPS23861=m @@ -4897,6 +4892,7 @@ CONFIG_SENSORS_OCC=m CONFIG_SENSORS_PCF8591=m CONFIG_PMBUS=m CONFIG_SENSORS_PMBUS=m +# CONFIG_SENSORS_ACBEL_FSG032 is not set # CONFIG_SENSORS_ADM1266 is not set CONFIG_SENSORS_ADM1275=m CONFIG_SENSORS_BEL_PFE=m @@ -4929,12 +4925,14 @@ CONFIG_SENSORS_MAX8688=m CONFIG_SENSORS_MP2888=m # CONFIG_SENSORS_MP2975 is not set # CONFIG_SENSORS_MP5023 is not set +# CONFIG_SENSORS_MPQ7932 is not set CONFIG_SENSORS_PIM4328=m # CONFIG_SENSORS_PLI1209BC is not set CONFIG_SENSORS_PM6764TR=m CONFIG_SENSORS_PXE1610=m CONFIG_SENSORS_Q54SJ108A2=m CONFIG_SENSORS_STPDDC60=m +# CONFIG_SENSORS_TDA38640 is not set CONFIG_SENSORS_TPS40422=m CONFIG_SENSORS_TPS53679=m CONFIG_SENSORS_TPS546D24=m @@ -4953,7 +4951,6 @@ CONFIG_SENSORS_SHT3x=m CONFIG_SENSORS_SHT4x=m CONFIG_SENSORS_SHTC1=m CONFIG_SENSORS_SIS5595=m -# CONFIG_SENSORS_SY7636A is not set CONFIG_SENSORS_DME1737=m CONFIG_SENSORS_EMC1403=m CONFIG_SENSORS_EMC2103=m @@ -5026,7 +5023,6 @@ CONFIG_CPU_FREQ_THERMAL=y CONFIG_DEVFREQ_THERMAL=y CONFIG_THERMAL_EMULATION=y CONFIG_THERMAL_MMIO=m -CONFIG_MAX77620_THERMAL=m CONFIG_ROCKCHIP_THERMAL=y # CONFIG_TI_SOC_THERMAL is not set # CONFIG_GENERIC_ADC_THERMAL is not set @@ -5047,19 +5043,15 @@ CONFIG_WATCHDOG_SYSFS=y # Watchdog Device Drivers # CONFIG_SOFT_WATCHDOG=m -CONFIG_BD957XMUF_WATCHDOG=m CONFIG_GPIO_WATCHDOG=m CONFIG_WDAT_WDT=m # CONFIG_XILINX_WATCHDOG is not set # CONFIG_ZIIRAVE_WATCHDOG is not set -CONFIG_RAVE_SP_WATCHDOG=m CONFIG_ARM_SP805_WATCHDOG=y CONFIG_ARM_SBSA_WATCHDOG=y # CONFIG_CADENCE_WATCHDOG is not set CONFIG_DW_WATCHDOG=y -CONFIG_RN5T618_WATCHDOG=m # CONFIG_MAX63XX_WATCHDOG is not set -CONFIG_MAX77620_WATCHDOG=m CONFIG_ARM_SMC_WATCHDOG=y # CONFIG_ALIM7101_WDT is not set # CONFIG_I6300ESB_WDT is not set @@ -5106,19 +5098,19 @@ CONFIG_BCMA_DEBUG=y # CONFIG_MFD_CORE=y # CONFIG_MFD_ACT8945A is not set -CONFIG_MFD_AS3711=y +# CONFIG_MFD_AS3711 is not set # CONFIG_MFD_SMPRO is not set -CONFIG_MFD_AS3722=m -CONFIG_PMIC_ADP5520=y -CONFIG_MFD_AAT2870_CORE=y +# CONFIG_MFD_AS3722 is not set +# CONFIG_PMIC_ADP5520 is not set +# CONFIG_MFD_AAT2870_CORE is not set # CONFIG_MFD_ATMEL_FLEXCOM is not set # CONFIG_MFD_ATMEL_HLCDC is not set # CONFIG_MFD_BCM590XX is not set -CONFIG_MFD_BD9571MWV=y -CONFIG_MFD_AXP20X=y -CONFIG_MFD_AXP20X_I2C=y +# CONFIG_MFD_BD9571MWV is not set +# CONFIG_MFD_AXP20X_I2C is not set CONFIG_MFD_CROS_EC_DEV=y # CONFIG_MFD_MADERA is not set +# CONFIG_MFD_MAX597X is not set # CONFIG_PMIC_DA903X is not set # CONFIG_MFD_DA9052_SPI is not set # CONFIG_MFD_DA9052_I2C is not set @@ -5131,20 +5123,19 @@ CONFIG_MFD_CROS_EC_DEV=y # CONFIG_MFD_MC13XXX_SPI is not set # CONFIG_MFD_MC13XXX_I2C is not set # CONFIG_MFD_MP2629 is not set -CONFIG_MFD_HI6421_PMIC=y +# CONFIG_MFD_HI6421_PMIC is not set # CONFIG_MFD_HI6421_SPMI is not set -# CONFIG_HTC_PASIC3 is not set # CONFIG_LPC_ICH is not set # CONFIG_LPC_SCH is not set -CONFIG_MFD_IQS62X=m +# CONFIG_MFD_IQS62X is not set # CONFIG_MFD_JANZ_CMODIO is not set # CONFIG_MFD_KEMPLD is not set # CONFIG_MFD_88PM800 is not set # CONFIG_MFD_88PM805 is not set # CONFIG_MFD_88PM860X is not set # CONFIG_MFD_MAX14577 is not set -CONFIG_MFD_MAX77620=y -CONFIG_MFD_MAX77650=m +# CONFIG_MFD_MAX77620 is not set +# CONFIG_MFD_MAX77650 is not set # CONFIG_MFD_MAX77686 is not set # CONFIG_MFD_MAX77693 is not set # CONFIG_MFD_MAX77714 is not set @@ -5164,20 +5155,20 @@ CONFIG_MFD_OCELOT=m CONFIG_MFD_NTXEC=m # CONFIG_MFD_RETU is not set # CONFIG_MFD_PCF50633 is not set -CONFIG_UCB1400_CORE=m -CONFIG_MFD_SY7636A=m +# CONFIG_MFD_SY7636A is not set CONFIG_MFD_RDC321X=m -CONFIG_MFD_RT4831=m -CONFIG_MFD_RT5033=m -CONFIG_MFD_RT5120=m -CONFIG_MFD_RC5T583=y -# CONFIG_MFD_RK808 is not set -CONFIG_MFD_RN5T618=m -CONFIG_MFD_SEC_CORE=y +# CONFIG_MFD_RT4831 is not set +# CONFIG_MFD_RT5033 is not set +# CONFIG_MFD_RT5120 is not set +# CONFIG_MFD_RC5T583 is not set +CONFIG_MFD_RK8XX=y +CONFIG_MFD_RK8XX_I2C=m +CONFIG_MFD_RK8XX_SPI=m +# CONFIG_MFD_RN5T618 is not set +# CONFIG_MFD_SEC_CORE is not set # CONFIG_MFD_SI476X_CORE is not set CONFIG_MFD_SIMPLE_MFD_I2C=m -CONFIG_MFD_SM501=m -CONFIG_MFD_SM501_GPIO=y +# CONFIG_MFD_SM501 is not set # CONFIG_MFD_SKY81452 is not set # CONFIG_MFD_STMPE is not set CONFIG_MFD_SYSCON=y @@ -5203,37 +5194,30 @@ CONFIG_MFD_SYSCON=y # CONFIG_TWL4030_CORE is not set # CONFIG_TWL6040_CORE is not set CONFIG_MFD_WL1273_CORE=m -CONFIG_MFD_LM3533=m +# CONFIG_MFD_LM3533 is not set # CONFIG_MFD_TC3589X is not set -CONFIG_MFD_TQMX86=m -CONFIG_MFD_VX855=m +# CONFIG_MFD_TQMX86 is not set +# CONFIG_MFD_VX855 is not set # CONFIG_MFD_LOCHNAGAR is not set -CONFIG_MFD_ARIZONA=m -CONFIG_MFD_ARIZONA_I2C=m -CONFIG_MFD_ARIZONA_SPI=m -# CONFIG_MFD_CS47L24 is not set -CONFIG_MFD_WM5102=y -# CONFIG_MFD_WM5110 is not set -# CONFIG_MFD_WM8997 is not set -# CONFIG_MFD_WM8998 is not set +# CONFIG_MFD_ARIZONA_I2C is not set +# CONFIG_MFD_ARIZONA_SPI is not set # CONFIG_MFD_WM8400 is not set # CONFIG_MFD_WM831X_I2C is not set # CONFIG_MFD_WM831X_SPI is not set # CONFIG_MFD_WM8350_I2C is not set # CONFIG_MFD_WM8994 is not set -CONFIG_MFD_ROHM_BD718XX=y -CONFIG_MFD_ROHM_BD71828=m -CONFIG_MFD_ROHM_BD957XMUF=m +# CONFIG_MFD_ROHM_BD718XX is not set +# CONFIG_MFD_ROHM_BD71828 is not set +# CONFIG_MFD_ROHM_BD957XMUF is not set # CONFIG_MFD_STPMIC1 is not set CONFIG_MFD_STMFX=m # CONFIG_MFD_WCD934X is not set -CONFIG_MFD_ATC260X=m -CONFIG_MFD_ATC260X_I2C=m +# CONFIG_MFD_ATC260X_I2C is not set # CONFIG_MFD_KHADAS_MCU is not set -CONFIG_MFD_QCOM_PM8008=m +# CONFIG_MFD_QCOM_PM8008 is not set CONFIG_MFD_VEXPRESS_SYSREG=y -CONFIG_RAVE_SP_CORE=m -# CONFIG_MFD_INTEL_M10_BMC is not set +# CONFIG_RAVE_SP_CORE is not set +# CONFIG_MFD_INTEL_M10_BMC_SPI is not set CONFIG_MFD_RSMU_I2C=m CONFIG_MFD_RSMU_SPI=m # end of Multifunction device drivers @@ -5243,31 +5227,17 @@ CONFIG_REGULATOR=y CONFIG_REGULATOR_FIXED_VOLTAGE=y # CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set # CONFIG_REGULATOR_USERSPACE_CONSUMER is not set -CONFIG_REGULATOR_88PG86X=m -# CONFIG_REGULATOR_ACT8865 is not set +# CONFIG_REGULATOR_88PG86X is not set +CONFIG_REGULATOR_ACT8865=y # CONFIG_REGULATOR_AD5398 is not set -CONFIG_REGULATOR_AAT2870=m -CONFIG_REGULATOR_ARIZONA_LDO1=m -CONFIG_REGULATOR_ARIZONA_MICSUPP=m -CONFIG_REGULATOR_ARM_SCMI=m -CONFIG_REGULATOR_AS3711=m -CONFIG_REGULATOR_AS3722=m -CONFIG_REGULATOR_ATC260X=m -CONFIG_REGULATOR_AXP20X=m -CONFIG_REGULATOR_BD71815=m -CONFIG_REGULATOR_BD71828=m -CONFIG_REGULATOR_BD718XX=m -CONFIG_REGULATOR_BD9571MWV=m -CONFIG_REGULATOR_BD957XMUF=m +# CONFIG_REGULATOR_ARM_SCMI is not set # CONFIG_REGULATOR_CROS_EC is not set -CONFIG_REGULATOR_DA9121=m +# CONFIG_REGULATOR_DA9121 is not set # CONFIG_REGULATOR_DA9210 is not set # CONFIG_REGULATOR_DA9211 is not set CONFIG_REGULATOR_FAN53555=y CONFIG_REGULATOR_FAN53880=m CONFIG_REGULATOR_GPIO=y -# CONFIG_REGULATOR_HI6421 is not set -CONFIG_REGULATOR_HI6421V530=y # CONFIG_REGULATOR_ISL9305 is not set # CONFIG_REGULATOR_ISL6271A is not set # CONFIG_REGULATOR_LP3971 is not set @@ -5277,14 +5247,13 @@ CONFIG_REGULATOR_HI6421V530=y # CONFIG_REGULATOR_LTC3589 is not set # CONFIG_REGULATOR_LTC3676 is not set # CONFIG_REGULATOR_MAX1586 is not set -CONFIG_REGULATOR_MAX77620=y -CONFIG_REGULATOR_MAX77650=m # CONFIG_REGULATOR_MAX8649 is not set # CONFIG_REGULATOR_MAX8660 is not set CONFIG_REGULATOR_MAX8893=m # CONFIG_REGULATOR_MAX8952 is not set CONFIG_REGULATOR_MAX8973=y # CONFIG_REGULATOR_MAX20086 is not set +# CONFIG_REGULATOR_MAX20411 is not set # CONFIG_REGULATOR_MAX77826 is not set CONFIG_REGULATOR_MCP16502=m CONFIG_REGULATOR_MP5416=m @@ -5304,14 +5273,11 @@ CONFIG_REGULATOR_PWM=y CONFIG_REGULATOR_QCOM_SPMI=y # CONFIG_REGULATOR_QCOM_USB_VBUS is not set # CONFIG_REGULATOR_RASPBERRYPI_TOUCHSCREEN_ATTINY is not set -CONFIG_REGULATOR_RC5T583=m -CONFIG_REGULATOR_RN5T618=m -CONFIG_REGULATOR_ROHM=m +CONFIG_REGULATOR_RK808=y # CONFIG_REGULATOR_RT4801 is not set -CONFIG_REGULATOR_RT4831=m -CONFIG_REGULATOR_RT5033=m -CONFIG_REGULATOR_RT5120=m +# CONFIG_REGULATOR_RT4803 is not set # CONFIG_REGULATOR_RT5190A is not set +# CONFIG_REGULATOR_RT5739 is not set CONFIG_REGULATOR_RT5759=m CONFIG_REGULATOR_RT6160=m # CONFIG_REGULATOR_RT6190 is not set @@ -5319,11 +5285,7 @@ CONFIG_REGULATOR_RT6245=m CONFIG_REGULATOR_RTQ2134=m # CONFIG_REGULATOR_RTMV20 is not set CONFIG_REGULATOR_RTQ6752=m -# CONFIG_REGULATOR_S2MPA01 is not set -CONFIG_REGULATOR_S2MPS11=y -# CONFIG_REGULATOR_S5M8767 is not set CONFIG_REGULATOR_SLG51000=m -# CONFIG_REGULATOR_SY7636A is not set # CONFIG_REGULATOR_SY8106A is not set CONFIG_REGULATOR_SY8824X=m # CONFIG_REGULATOR_SY8827N is not set @@ -5429,7 +5391,6 @@ CONFIG_V4L2_FWNODE=m CONFIG_V4L2_ASYNC=m CONFIG_VIDEOBUF_GEN=m CONFIG_VIDEOBUF_DMA_SG=m -CONFIG_VIDEOBUF_VMALLOC=m # end of Video4Linux options # @@ -5637,6 +5598,9 @@ CONFIG_VIDEO_DT3155=m CONFIG_VIDEO_IVTV=m CONFIG_VIDEO_IVTV_ALSA=m CONFIG_VIDEO_FB_IVTV=m +CONFIG_VIDEO_HEXIUM_GEMINI=m +CONFIG_VIDEO_HEXIUM_ORION=m +CONFIG_VIDEO_MXB=m # # Media capture/analog/hybrid TV support @@ -5680,6 +5644,10 @@ CONFIG_DVB_PLUTO2=m CONFIG_DVB_PT1=m CONFIG_DVB_PT3=m CONFIG_DVB_SMIPCIE=m +CONFIG_DVB_BUDGET_CORE=m +CONFIG_DVB_BUDGET=m +CONFIG_DVB_BUDGET_CI=m +CONFIG_DVB_BUDGET_AV=m CONFIG_RADIO_ADAPTERS=m CONFIG_RADIO_MAXIRADIO=m CONFIG_RADIO_SAA7706H=m @@ -5833,9 +5801,12 @@ CONFIG_MEDIA_COMMON_OPTIONS=y # CONFIG_CYPRESS_FIRMWARE=m CONFIG_TTPCI_EEPROM=m +CONFIG_UVC_COMMON=m CONFIG_VIDEO_CX2341X=m CONFIG_VIDEO_TVEEPROM=m CONFIG_DVB_B2C2_FLEXCOP=m +CONFIG_VIDEO_SAA7146=m +CONFIG_VIDEO_SAA7146_VV=m CONFIG_SMS_SIANO_MDTV=m CONFIG_SMS_SIANO_RC=y # CONFIG_SMS_SIANO_DEBUGFS is not set @@ -5874,22 +5845,21 @@ CONFIG_VIDEO_IMX219=m CONFIG_VIDEO_IMX258=m CONFIG_VIDEO_IMX274=m CONFIG_VIDEO_IMX290=m +# CONFIG_VIDEO_IMX296 is not set CONFIG_VIDEO_IMX319=m CONFIG_VIDEO_IMX334=m CONFIG_VIDEO_IMX335=m CONFIG_VIDEO_IMX355=m CONFIG_VIDEO_IMX412=m +# CONFIG_VIDEO_IMX415 is not set CONFIG_VIDEO_MAX9271_LIB=m CONFIG_VIDEO_MT9M001=m -CONFIG_VIDEO_MT9M032=m CONFIG_VIDEO_MT9M111=m CONFIG_VIDEO_MT9P031=m -CONFIG_VIDEO_MT9T001=m CONFIG_VIDEO_MT9T112=m CONFIG_VIDEO_MT9V011=m CONFIG_VIDEO_MT9V032=m CONFIG_VIDEO_MT9V111=m -CONFIG_VIDEO_NOON010PC30=m # CONFIG_VIDEO_OG01A1B is not set CONFIG_VIDEO_OV02A10=m # CONFIG_VIDEO_OV08D10 is not set @@ -5917,6 +5887,7 @@ CONFIG_VIDEO_OV7670=m CONFIG_VIDEO_OV772X=m CONFIG_VIDEO_OV7740=m CONFIG_VIDEO_OV8856=m +# CONFIG_VIDEO_OV8858 is not set CONFIG_VIDEO_OV8865=m CONFIG_VIDEO_OV9282=m CONFIG_VIDEO_OV9640=m @@ -5928,13 +5899,9 @@ CONFIG_VIDEO_RJ54N1=m CONFIG_VIDEO_S5C73M3=m CONFIG_VIDEO_S5K5BAF=m CONFIG_VIDEO_S5K6A3=m -CONFIG_VIDEO_S5K6AA=m -CONFIG_VIDEO_SR030PC30=m # CONFIG_VIDEO_ST_VGXY61 is not set -CONFIG_VIDEO_VS6624=m CONFIG_VIDEO_CCS=m CONFIG_VIDEO_ET8EK8=m -CONFIG_VIDEO_M5MOLS=m # end of Camera sensor devices # @@ -6023,7 +5990,6 @@ CONFIG_VIDEO_CX25840=m # # Video encoders # -CONFIG_VIDEO_AD9389B=m CONFIG_VIDEO_ADV7170=m CONFIG_VIDEO_ADV7175=m CONFIG_VIDEO_ADV7343=m @@ -6288,11 +6254,12 @@ CONFIG_DVB_DUMMY_FE=m # Graphics support # CONFIG_APERTURE_HELPERS=y +CONFIG_VIDEO_CMDLINE=y CONFIG_VIDEO_NOMODESET=y CONFIG_DRM=m CONFIG_DRM_MIPI_DBI=m CONFIG_DRM_MIPI_DSI=y -CONFIG_DRM_USE_DYNAMIC_DEBUG=y +CONFIG_DRM_KUNIT_TEST_HELPERS=m CONFIG_DRM_KUNIT_TEST=m CONFIG_DRM_KMS_HELPER=m # CONFIG_DRM_DEBUG_DP_MST_TOPOLOGY_REFS is not set @@ -6354,11 +6321,9 @@ CONFIG_DRM_VMWGFX=m CONFIG_DRM_UDL=m CONFIG_DRM_AST=m CONFIG_DRM_MGAG200=m -# CONFIG_DRM_RCAR_DW_HDMI is not set -# CONFIG_DRM_RCAR_USE_LVDS is not set -# CONFIG_DRM_RCAR_USE_MIPI_DSI is not set CONFIG_DRM_QXL=m CONFIG_DRM_VIRTIO_GPU=m +CONFIG_DRM_VIRTIO_GPU_KMS=y CONFIG_DRM_PANEL=y # @@ -6367,6 +6332,7 @@ CONFIG_DRM_PANEL=y CONFIG_DRM_PANEL_ABT_Y030XX067A=m CONFIG_DRM_PANEL_ARM_VERSATILE=m # CONFIG_DRM_PANEL_ASUS_Z00T_TM5P5_NT35596 is not set +# CONFIG_DRM_PANEL_AUO_A030JTN01 is not set # CONFIG_DRM_PANEL_BOE_BF060Y8M_AJ0 is not set CONFIG_DRM_PANEL_BOE_HIMAX8279D=m CONFIG_DRM_PANEL_BOE_TV101WUM_NL6=m @@ -6378,6 +6344,7 @@ CONFIG_DRM_PANEL_EDP=m CONFIG_DRM_PANEL_ELIDA_KD35T133=m CONFIG_DRM_PANEL_FEIXIN_K101_IM2BA02=m CONFIG_DRM_PANEL_FEIYANG_FY07024DI26A30D=m +# CONFIG_DRM_PANEL_HIMAX_HX8394 is not set CONFIG_DRM_PANEL_ILITEK_IL9322=m CONFIG_DRM_PANEL_ILITEK_ILI9341=m CONFIG_DRM_PANEL_ILITEK_ILI9881C=m @@ -6393,16 +6360,19 @@ CONFIG_DRM_PANEL_LEADTEK_LTK500HD1829=m # CONFIG_DRM_PANEL_SAMSUNG_LD9040 is not set CONFIG_DRM_PANEL_LG_LB035Q02=m # CONFIG_DRM_PANEL_LG_LG4573 is not set +# CONFIG_DRM_PANEL_MAGNACHIP_D53E6EA8966 is not set CONFIG_DRM_PANEL_NEC_NL8048HL11=m # CONFIG_DRM_PANEL_NEWVISION_NV3051D is not set CONFIG_DRM_PANEL_NEWVISION_NV3052C=m CONFIG_DRM_PANEL_NOVATEK_NT35510=m CONFIG_DRM_PANEL_NOVATEK_NT35560=m # CONFIG_DRM_PANEL_NOVATEK_NT35950 is not set +# CONFIG_DRM_PANEL_NOVATEK_NT36523 is not set CONFIG_DRM_PANEL_NOVATEK_NT36672A=m CONFIG_DRM_PANEL_NOVATEK_NT39016=m # CONFIG_DRM_PANEL_MANTIX_MLAF057WE51 is not set CONFIG_DRM_PANEL_OLIMEX_LCD_OLINUXINO=m +# CONFIG_DRM_PANEL_ORISETECH_OTA5601A is not set CONFIG_DRM_PANEL_ORISETECH_OTM8009A=m # CONFIG_DRM_PANEL_OSD_OSD101T2587_53TS is not set CONFIG_DRM_PANEL_PANASONIC_VVX10F034N00=m @@ -6429,6 +6399,7 @@ CONFIG_DRM_PANEL_SITRONIX_ST7701=m # CONFIG_DRM_PANEL_SITRONIX_ST7703 is not set # CONFIG_DRM_PANEL_SITRONIX_ST7789V is not set CONFIG_DRM_PANEL_SONY_ACX565AKM=m +# CONFIG_DRM_PANEL_SONY_TD4353_JDI is not set # CONFIG_DRM_PANEL_SONY_TULIP_TRULY_NT35521 is not set CONFIG_DRM_PANEL_TDO_TL070WSH30=m CONFIG_DRM_PANEL_TPO_TD028TTEC1=m @@ -6436,6 +6407,7 @@ CONFIG_DRM_PANEL_TPO_TD043MTEA1=m CONFIG_DRM_PANEL_TPO_TPG110=m CONFIG_DRM_PANEL_TRULY_NT35597_WQXGA=m # CONFIG_DRM_PANEL_VISIONOX_RM69299 is not set +# CONFIG_DRM_PANEL_VISIONOX_VTDR6130 is not set CONFIG_DRM_PANEL_WIDECHIPS_WS2401=m CONFIG_DRM_PANEL_XINPENG_XPP055C272=m # end of Display Panels @@ -6446,7 +6418,6 @@ CONFIG_DRM_PANEL_BRIDGE=y # # Display Interface Bridges # -CONFIG_DRM_CDNS_DSI=m CONFIG_DRM_CHIPONE_ICN6211=m CONFIG_DRM_CHRONTEL_CH7033=m CONFIG_DRM_CROS_EC_ANX7688=m @@ -6463,6 +6434,7 @@ CONFIG_DRM_NWL_MIPI_DSI=m # CONFIG_DRM_NXP_PTN3460 is not set # CONFIG_DRM_PARADE_PS8622 is not set CONFIG_DRM_PARADE_PS8640=m +# CONFIG_DRM_SAMSUNG_DSIM is not set # CONFIG_DRM_SIL_SII8620 is not set CONFIG_DRM_SII902X=m CONFIG_DRM_SII9234=m @@ -6485,6 +6457,8 @@ CONFIG_DRM_ANALOGIX_DP=m CONFIG_DRM_I2C_ADV7511=m CONFIG_DRM_I2C_ADV7511_AUDIO=y CONFIG_DRM_I2C_ADV7511_CEC=y +CONFIG_DRM_CDNS_DSI=m +CONFIG_DRM_CDNS_DSI_J721E=y # CONFIG_DRM_CDNS_MHDP8546 is not set CONFIG_DRM_DW_HDMI=m CONFIG_DRM_DW_HDMI_AHB_AUDIO=m @@ -6499,9 +6473,6 @@ CONFIG_DRM_ETNAVIV_THERMAL=y CONFIG_DRM_HISI_HIBMC=m CONFIG_DRM_HISI_KIRIN=m CONFIG_DRM_LOGICVC=m -CONFIG_DRM_MXS=y -CONFIG_DRM_MXSFB=m -# CONFIG_DRM_IMX_LCDIF is not set # CONFIG_DRM_ARCPGU is not set CONFIG_DRM_BOCHS=m # CONFIG_DRM_CIRRUS_QEMU is not set @@ -6528,11 +6499,6 @@ CONFIG_DRM_SSD130X=m CONFIG_DRM_SSD130X_I2C=m CONFIG_DRM_SSD130X_SPI=m CONFIG_DRM_LEGACY=y -# CONFIG_DRM_TDFX is not set -# CONFIG_DRM_R128 is not set -# CONFIG_DRM_MGA is not set -# CONFIG_DRM_VIA is not set -# CONFIG_DRM_SAVAGE is not set CONFIG_DRM_EXPORT_FOR_TESTS=y CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y CONFIG_DRM_LIB_RANDOM=y @@ -6540,7 +6506,6 @@ CONFIG_DRM_LIB_RANDOM=y # # Frame buffer Devices # -CONFIG_FB_CMDLINE=y CONFIG_FB_NOTIFY=y CONFIG_FB=y CONFIG_FIRMWARE_EDID=y @@ -6589,7 +6554,6 @@ CONFIG_FB_EFI=y # CONFIG_FB_ARK is not set # CONFIG_FB_PM3 is not set # CONFIG_FB_CARMINE is not set -# CONFIG_FB_SM501 is not set # CONFIG_FB_SMSCUFX is not set CONFIG_FB_UDL=m # CONFIG_FB_IBM_GXT4500 is not set @@ -6620,24 +6584,19 @@ CONFIG_LCD_PLATFORM=m CONFIG_LCD_OTM3225A=m CONFIG_BACKLIGHT_CLASS_DEVICE=y # CONFIG_BACKLIGHT_KTD253 is not set -CONFIG_BACKLIGHT_LM3533=m +# CONFIG_BACKLIGHT_KTZ8866 is not set CONFIG_BACKLIGHT_PWM=m CONFIG_BACKLIGHT_MT6370=m CONFIG_BACKLIGHT_QCOM_WLED=m -CONFIG_BACKLIGHT_RT4831=m -CONFIG_BACKLIGHT_ADP5520=m # CONFIG_BACKLIGHT_ADP8860 is not set # CONFIG_BACKLIGHT_ADP8870 is not set -CONFIG_BACKLIGHT_AAT2870=m # CONFIG_BACKLIGHT_LM3630A is not set # CONFIG_BACKLIGHT_LM3639 is not set CONFIG_BACKLIGHT_LP855X=y -CONFIG_BACKLIGHT_AS3711=m CONFIG_BACKLIGHT_GPIO=m # CONFIG_BACKLIGHT_LV5207LP is not set # CONFIG_BACKLIGHT_BD6107 is not set # CONFIG_BACKLIGHT_ARCXCNN is not set -CONFIG_BACKLIGHT_RAVE_SP=m CONFIG_BACKLIGHT_LED=m # end of Backlight & LCD device support @@ -6815,6 +6774,7 @@ CONFIG_SND_HDA_CODEC_SI3054=m CONFIG_SND_HDA_GENERIC=m CONFIG_SND_HDA_POWER_SAVE_DEFAULT=0 CONFIG_SND_HDA_INTEL_HDMI_SILENT_STREAM=y +# CONFIG_SND_HDA_CTL_DEV_ID is not set # end of HD-Audio CONFIG_SND_HDA_CORE=m @@ -6946,6 +6906,7 @@ CONFIG_SND_SOC_AK5386=m CONFIG_SND_SOC_AK5558=m CONFIG_SND_SOC_ALC5623=m CONFIG_SND_SOC_AW8738=m +# CONFIG_SND_SOC_AW88395 is not set CONFIG_SND_SOC_BD28623=m CONFIG_SND_SOC_BT_SCO=m CONFIG_SND_SOC_CROS_EC_CODEC=m @@ -6958,12 +6919,15 @@ CONFIG_SND_SOC_CS35L41_LIB=m CONFIG_SND_SOC_CS35L41=m CONFIG_SND_SOC_CS35L41_SPI=m CONFIG_SND_SOC_CS35L41_I2C=m -CONFIG_SND_SOC_CS35L45_TABLES=m CONFIG_SND_SOC_CS35L45=m CONFIG_SND_SOC_CS35L45_SPI=m CONFIG_SND_SOC_CS35L45_I2C=m +# CONFIG_SND_SOC_CS35L56_I2C is not set +# CONFIG_SND_SOC_CS35L56_SPI is not set +# CONFIG_SND_SOC_CS35L56_SDW is not set CONFIG_SND_SOC_CS42L42_CORE=m CONFIG_SND_SOC_CS42L42=m +# CONFIG_SND_SOC_CS42L42_SDW is not set CONFIG_SND_SOC_CS42L51=m CONFIG_SND_SOC_CS42L51_I2C=m CONFIG_SND_SOC_CS42L52=m @@ -6997,6 +6961,7 @@ CONFIG_SND_SOC_ES8328_SPI=m CONFIG_SND_SOC_GTM601=m CONFIG_SND_SOC_HDA=m CONFIG_SND_SOC_ICS43432=m +# CONFIG_SND_SOC_IDT821034 is not set CONFIG_SND_SOC_INNO_RK3036=m CONFIG_SND_SOC_MAX98088=m CONFIG_SND_SOC_MAX98090=m @@ -7005,6 +6970,7 @@ CONFIG_SND_SOC_MAX98504=m CONFIG_SND_SOC_MAX9867=m CONFIG_SND_SOC_MAX98927=m CONFIG_SND_SOC_MAX98520=m +# CONFIG_SND_SOC_MAX98363 is not set CONFIG_SND_SOC_MAX98373=m CONFIG_SND_SOC_MAX98373_I2C=m CONFIG_SND_SOC_MAX98373_SDW=m @@ -7032,7 +6998,9 @@ CONFIG_SND_SOC_PCM5102A=m CONFIG_SND_SOC_PCM512x=m CONFIG_SND_SOC_PCM512x_I2C=m CONFIG_SND_SOC_PCM512x_SPI=m +# CONFIG_SND_SOC_PEB2466 is not set CONFIG_SND_SOC_RK3328=m +# CONFIG_SND_SOC_RK817 is not set CONFIG_SND_SOC_RL6231=m CONFIG_SND_SOC_RT1308_SDW=m CONFIG_SND_SOC_RT1316_SDW=m @@ -7052,6 +7020,8 @@ CONFIG_SND_SOC_RT700_SDW=m CONFIG_SND_SOC_RT711=m CONFIG_SND_SOC_RT711_SDW=m CONFIG_SND_SOC_RT711_SDCA_SDW=m +# CONFIG_SND_SOC_RT712_SDCA_SDW is not set +# CONFIG_SND_SOC_RT712_SDCA_DMIC_SDW is not set CONFIG_SND_SOC_RT715=m CONFIG_SND_SOC_RT715_SDW=m CONFIG_SND_SOC_RT715_SDCA_SDW=m @@ -7063,6 +7033,7 @@ CONFIG_SND_SOC_SIGMADSP_I2C=m CONFIG_SND_SOC_SIGMADSP_REGMAP=m CONFIG_SND_SOC_SIMPLE_AMPLIFIER=m CONFIG_SND_SOC_SIMPLE_MUX=m +# CONFIG_SND_SOC_SMA1303 is not set CONFIG_SND_SOC_SPDIF=m CONFIG_SND_SOC_SRC4XXX_I2C=m CONFIG_SND_SOC_SRC4XXX=m @@ -7167,10 +7138,7 @@ CONFIG_SND_SYNTH_EMUX=m CONFIG_SND_XEN_FRONTEND=m CONFIG_SND_VIRTIO=m CONFIG_AC97_BUS=m - -# -# HID support -# +CONFIG_HID_SUPPORT=y CONFIG_HID=y CONFIG_HID_BATTERY_STRENGTH=y CONFIG_HIDRAW=y @@ -7207,6 +7175,7 @@ CONFIG_HID_EMS_FF=m CONFIG_HID_ELAN=m CONFIG_HID_ELECOM=m CONFIG_HID_ELO=m +# CONFIG_HID_EVISION is not set CONFIG_HID_EZKEY=m CONFIG_HID_FT260=m CONFIG_HID_GEMBIRD=m @@ -7279,6 +7248,7 @@ CONFIG_HID_SONY=m CONFIG_SONY_FF=y CONFIG_HID_SPEEDLINK=m CONFIG_HID_STEAM=m +# CONFIG_STEAM_FF is not set CONFIG_HID_STEELSERIES=m CONFIG_HID_SUNPLUS=m CONFIG_HID_RMI=m @@ -7306,6 +7276,11 @@ CONFIG_HID_ALPS=m CONFIG_HID_MCP2221=m # end of Special HID drivers +# +# HID-BPF support +# +# end of HID-BPF support + # # USB HID support # @@ -7314,18 +7289,12 @@ CONFIG_HID_PID=y CONFIG_USB_HIDDEV=y # end of USB HID support -# -# I2C HID support -# +CONFIG_I2C_HID=y CONFIG_I2C_HID_ACPI=m CONFIG_I2C_HID_OF=m CONFIG_I2C_HID_OF_ELAN=m CONFIG_I2C_HID_OF_GOODIX=m -# end of I2C HID support - CONFIG_I2C_HID_CORE=m -# end of HID support - CONFIG_USB_OHCI_LITTLE_ENDIAN=y CONFIG_USB_SUPPORT=y CONFIG_USB_COMMON=y @@ -7373,7 +7342,6 @@ CONFIG_USB_OHCI_HCD=y CONFIG_USB_OHCI_HCD_PCI=y CONFIG_USB_OHCI_HCD_PLATFORM=y CONFIG_USB_UHCI_HCD=m -# CONFIG_USB_U132_HCD is not set CONFIG_USB_SL811_HCD=m CONFIG_USB_SL811_HCD_ISO=y CONFIG_USB_R8A66597_HCD=m @@ -7562,7 +7530,6 @@ CONFIG_USB_LCD=m CONFIG_USB_CYPRESS_CY7C63=m CONFIG_USB_CYTHERM=m CONFIG_USB_IDMOUSE=m -CONFIG_USB_FTDI_ELAN=m CONFIG_USB_APPLEDISPLAY=m CONFIG_APPLE_MFI_FASTCHARGE=m CONFIG_USB_SISUSBVGA=m @@ -7707,7 +7674,7 @@ CONFIG_USB_G_WEBCAM=m CONFIG_USB_RAW_GADGET=m # end of USB Gadget precomposed configurations -CONFIG_TYPEC=m +CONFIG_TYPEC=y CONFIG_TYPEC_TCPM=m CONFIG_TYPEC_TCPCI=m CONFIG_TYPEC_RT1711H=m @@ -7729,6 +7696,7 @@ CONFIG_TYPEC_WUSB3801=m # USB Type-C Multiplexer/DeMultiplexer Switch support # CONFIG_TYPEC_MUX_FSA4480=m +# CONFIG_TYPEC_MUX_GPIO_SBU is not set CONFIG_TYPEC_MUX_PI3USB30532=m # end of USB Type-C Multiplexer/DeMultiplexer Switch support @@ -7820,7 +7788,6 @@ CONFIG_LEDS_CR0014114=m CONFIG_LEDS_EL15203000=m # CONFIG_LEDS_LM3530 is not set CONFIG_LEDS_LM3532=m -CONFIG_LEDS_LM3533=m # CONFIG_LEDS_LM3642 is not set CONFIG_LEDS_LM3692X=m # CONFIG_LEDS_PCA9532 is not set @@ -7835,12 +7802,11 @@ CONFIG_LEDS_GPIO=y # CONFIG_LEDS_DAC124S085 is not set CONFIG_LEDS_PWM=m CONFIG_LEDS_REGULATOR=m +# CONFIG_LEDS_BD2606MVV is not set # CONFIG_LEDS_BD2802 is not set # CONFIG_LEDS_LT3593 is not set -CONFIG_LEDS_ADP5520=m # CONFIG_LEDS_TCA6507 is not set # CONFIG_LEDS_TLC591XX is not set -CONFIG_LEDS_MAX77650=m # CONFIG_LEDS_LM355x is not set # CONFIG_LEDS_IS31FL319X is not set # CONFIG_LEDS_IS31FL32XX is not set @@ -7863,6 +7829,7 @@ CONFIG_LEDS_LM3697=m # CONFIG_LEDS_AS3645A is not set # CONFIG_LEDS_KTD2692 is not set # CONFIG_LEDS_LM3601X is not set +# CONFIG_LEDS_MT6370_FLASH is not set # CONFIG_LEDS_RT4505 is not set # CONFIG_LEDS_RT8515 is not set # CONFIG_LEDS_SGM3140 is not set @@ -7883,7 +7850,6 @@ CONFIG_LEDS_TRIGGER_HEARTBEAT=y CONFIG_LEDS_TRIGGER_BACKLIGHT=m CONFIG_LEDS_TRIGGER_CPU=y CONFIG_LEDS_TRIGGER_ACTIVITY=y -CONFIG_LEDS_TRIGGER_GPIO=m CONFIG_LEDS_TRIGGER_DEFAULT_ON=y # @@ -7926,80 +7892,71 @@ CONFIG_RTC_NVMEM=y CONFIG_RTC_INTF_SYSFS=y CONFIG_RTC_INTF_PROC=y CONFIG_RTC_INTF_DEV=y -CONFIG_RTC_INTF_DEV_UIE_EMUL=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set # CONFIG_RTC_DRV_TEST is not set # # I2C RTC drivers # -CONFIG_RTC_DRV_ABB5ZES3=m -CONFIG_RTC_DRV_ABEOZ9=m -CONFIG_RTC_DRV_ABX80X=m -CONFIG_RTC_DRV_AS3722=m -CONFIG_RTC_DRV_DS1307=y -# CONFIG_RTC_DRV_DS1307_CENTURY is not set +# CONFIG_RTC_DRV_ABB5ZES3 is not set +# CONFIG_RTC_DRV_ABEOZ9 is not set +# CONFIG_RTC_DRV_ABX80X is not set +# CONFIG_RTC_DRV_DS1307 is not set # CONFIG_RTC_DRV_DS1374 is not set # CONFIG_RTC_DRV_DS1672 is not set CONFIG_RTC_DRV_HYM8563=y # CONFIG_RTC_DRV_MAX6900 is not set -CONFIG_RTC_DRV_MAX77686=y -CONFIG_RTC_DRV_NCT3018Y=m +# CONFIG_RTC_DRV_NCT3018Y is not set +CONFIG_RTC_DRV_RK808=y # CONFIG_RTC_DRV_RS5C372 is not set # CONFIG_RTC_DRV_ISL1208 is not set # CONFIG_RTC_DRV_ISL12022 is not set -CONFIG_RTC_DRV_ISL12026=m -CONFIG_RTC_DRV_X1205=m -CONFIG_RTC_DRV_PCF8523=m -CONFIG_RTC_DRV_PCF85063=m -CONFIG_RTC_DRV_PCF85363=m -CONFIG_RTC_DRV_PCF8563=m -CONFIG_RTC_DRV_PCF8583=m -CONFIG_RTC_DRV_M41T80=m -CONFIG_RTC_DRV_M41T80_WDT=y -CONFIG_RTC_DRV_BD70528=m -CONFIG_RTC_DRV_BQ32K=m -CONFIG_RTC_DRV_RC5T583=m -CONFIG_RTC_DRV_RC5T619=m -CONFIG_RTC_DRV_S35390A=m -CONFIG_RTC_DRV_FM3130=m -CONFIG_RTC_DRV_RX8010=m -CONFIG_RTC_DRV_RX8581=m -CONFIG_RTC_DRV_RX8025=m -CONFIG_RTC_DRV_EM3027=m -CONFIG_RTC_DRV_RV3028=m +# CONFIG_RTC_DRV_ISL12026 is not set +# CONFIG_RTC_DRV_X1205 is not set +# CONFIG_RTC_DRV_PCF8523 is not set +# CONFIG_RTC_DRV_PCF85063 is not set +# CONFIG_RTC_DRV_PCF85363 is not set +# CONFIG_RTC_DRV_PCF8563 is not set +# CONFIG_RTC_DRV_PCF8583 is not set +# CONFIG_RTC_DRV_M41T80 is not set +# CONFIG_RTC_DRV_BQ32K is not set +# CONFIG_RTC_DRV_S35390A is not set +# CONFIG_RTC_DRV_FM3130 is not set +# CONFIG_RTC_DRV_RX8010 is not set +# CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_RX8025 is not set +# CONFIG_RTC_DRV_EM3027 is not set +# CONFIG_RTC_DRV_RV3028 is not set # CONFIG_RTC_DRV_RV3032 is not set -CONFIG_RTC_DRV_RV8803=m -CONFIG_RTC_DRV_S5M=m -CONFIG_RTC_DRV_SD3078=m +# CONFIG_RTC_DRV_RV8803 is not set +# CONFIG_RTC_DRV_SD3078 is not set # # SPI RTC drivers # -CONFIG_RTC_DRV_M41T93=m -CONFIG_RTC_DRV_M41T94=m -CONFIG_RTC_DRV_DS1302=m -CONFIG_RTC_DRV_DS1305=m -CONFIG_RTC_DRV_DS1343=m -CONFIG_RTC_DRV_DS1347=m -CONFIG_RTC_DRV_DS1390=m -CONFIG_RTC_DRV_MAX6916=m -CONFIG_RTC_DRV_R9701=m -CONFIG_RTC_DRV_RX4581=m -CONFIG_RTC_DRV_RS5C348=m -CONFIG_RTC_DRV_MAX6902=m -CONFIG_RTC_DRV_PCF2123=m -CONFIG_RTC_DRV_MCP795=m +# CONFIG_RTC_DRV_M41T93 is not set +# CONFIG_RTC_DRV_M41T94 is not set +# CONFIG_RTC_DRV_DS1302 is not set +# CONFIG_RTC_DRV_DS1305 is not set +# CONFIG_RTC_DRV_DS1343 is not set +# CONFIG_RTC_DRV_DS1347 is not set +# CONFIG_RTC_DRV_DS1390 is not set +# CONFIG_RTC_DRV_MAX6916 is not set +# CONFIG_RTC_DRV_R9701 is not set +# CONFIG_RTC_DRV_RX4581 is not set +# CONFIG_RTC_DRV_RS5C348 is not set +# CONFIG_RTC_DRV_MAX6902 is not set +# CONFIG_RTC_DRV_PCF2123 is not set +# CONFIG_RTC_DRV_MCP795 is not set CONFIG_RTC_I2C_AND_SPI=y # # SPI and I2C RTC drivers # -CONFIG_RTC_DRV_DS3232=m -CONFIG_RTC_DRV_DS3232_HWMON=y -CONFIG_RTC_DRV_PCF2127=m -CONFIG_RTC_DRV_RV3029C2=m -CONFIG_RTC_DRV_RV3029_HWMON=y -CONFIG_RTC_DRV_RX6110=m +# CONFIG_RTC_DRV_DS3232 is not set +# CONFIG_RTC_DRV_PCF2127 is not set +# CONFIG_RTC_DRV_RV3029C2 is not set +# CONFIG_RTC_DRV_RX6110 is not set # # Platform RTC drivers @@ -8010,7 +7967,7 @@ CONFIG_RTC_DRV_RX6110=m # CONFIG_RTC_DRV_DS1685_FAMILY is not set # CONFIG_RTC_DRV_DS1742 is not set # CONFIG_RTC_DRV_DS2404 is not set -CONFIG_RTC_DRV_EFI=y +# CONFIG_RTC_DRV_EFI is not set # CONFIG_RTC_DRV_STK17TA8 is not set # CONFIG_RTC_DRV_M48T86 is not set # CONFIG_RTC_DRV_M48T35 is not set @@ -8018,26 +7975,25 @@ CONFIG_RTC_DRV_EFI=y # CONFIG_RTC_DRV_MSM6242 is not set # CONFIG_RTC_DRV_BQ4802 is not set # CONFIG_RTC_DRV_RP5C01 is not set -# CONFIG_RTC_DRV_V3020 is not set -# CONFIG_RTC_DRV_OPTEE is not set +CONFIG_RTC_DRV_OPTEE=m # CONFIG_RTC_DRV_ZYNQMP is not set -CONFIG_RTC_DRV_CROS_EC=y -CONFIG_RTC_DRV_NTXEC=m +# CONFIG_RTC_DRV_CROS_EC is not set +# CONFIG_RTC_DRV_NTXEC is not set # # on-CPU RTC drivers # -CONFIG_RTC_DRV_PL030=m -CONFIG_RTC_DRV_PL031=m -CONFIG_RTC_DRV_CADENCE=m +# CONFIG_RTC_DRV_PL030 is not set +# CONFIG_RTC_DRV_PL031 is not set +# CONFIG_RTC_DRV_CADENCE is not set # CONFIG_RTC_DRV_FTRTC010 is not set # CONFIG_RTC_DRV_R7301 is not set # # HID Sensor RTC drivers # -CONFIG_RTC_DRV_HID_SENSOR_TIME=m -CONFIG_RTC_DRV_GOLDFISH=m +# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set +# CONFIG_RTC_DRV_GOLDFISH is not set CONFIG_DMADEVICES=y # CONFIG_DMADEVICES_DEBUG is not set @@ -8055,12 +8011,12 @@ CONFIG_BCM_SBA_RAID=m CONFIG_DW_AXI_DMAC=m CONFIG_FSL_EDMA=y CONFIG_FSL_QDMA=m -CONFIG_HISI_DMA=m # CONFIG_INTEL_IDMA64 is not set CONFIG_MV_XOR_V2=y CONFIG_PL330_DMA=y CONFIG_PLX_DMA=m # CONFIG_XILINX_DMA is not set +# CONFIG_XILINX_XDMA is not set # CONFIG_XILINX_ZYNQMP_DMA is not set # CONFIG_XILINX_ZYNQMP_DPDMA is not set CONFIG_QCOM_HIDMA_MGMT=y @@ -8117,7 +8073,6 @@ CONFIG_VFIO_PCI=y CONFIG_MLX5_VFIO_PCI=m # CONFIG_HISI_ACC_VFIO_PCI is not set # CONFIG_VFIO_PLATFORM is not set -# CONFIG_VFIO_MDEV is not set CONFIG_VIRT_DRIVERS=y CONFIG_VMGENID=y CONFIG_NITRO_ENCLAVES=m @@ -8142,9 +8097,12 @@ CONFIG_VDPA_USER=m CONFIG_IFCVF=m CONFIG_MLX5_VDPA=y CONFIG_MLX5_VDPA_NET=m +# CONFIG_MLX5_VDPA_STEERING_DEBUG is not set CONFIG_VP_VDPA=m +# CONFIG_SNET_VDPA is not set CONFIG_VHOST_IOTLB=m CONFIG_VHOST_RING=m +CONFIG_VHOST_TASK=y CONFIG_VHOST=m CONFIG_VHOST_MENU=y CONFIG_VHOST_NET=m @@ -8198,7 +8156,6 @@ CONFIG_RTLLIB_CRYPTO_WEP=m CONFIG_RTL8192E=m CONFIG_RTL8723BS=m CONFIG_R8712U=m -CONFIG_R8188EU=m CONFIG_RTS5208=m CONFIG_VT6655=m CONFIG_VT6656=m @@ -8239,12 +8196,6 @@ CONFIG_AD9834=m # CONFIG_AD5933 is not set # end of Network Analyzer, Impedance Converters -# -# Active energy metering IC -# -# CONFIG_ADE7854 is not set -# end of Active energy metering IC - # # Resolver to digital converters # @@ -8254,6 +8205,11 @@ CONFIG_AD9834=m CONFIG_FB_SM750=m CONFIG_STAGING_MEDIA=y +CONFIG_DVB_AV7110_IR=y +CONFIG_DVB_AV7110=m +CONFIG_DVB_AV7110_OSD=y +CONFIG_DVB_BUDGET_PATCH=m +CONFIG_DVB_SP8870=m # CONFIG_VIDEO_MAX96712 is not set CONFIG_VIDEO_ROCKCHIP_VDEC=m CONFIG_STAGING_MEDIA_DEPRECATED=y @@ -8261,26 +8217,6 @@ CONFIG_STAGING_MEDIA_DEPRECATED=y # # Atmel media platform drivers # -CONFIG_VIDEO_CPIA2=m -CONFIG_VIDEO_SAA7146=m -CONFIG_VIDEO_SAA7146_VV=m -CONFIG_DVB_AV7110_IR=y -CONFIG_DVB_AV7110=m -CONFIG_DVB_AV7110_OSD=y -CONFIG_DVB_BUDGET_PATCH=m -CONFIG_DVB_SP8870=m -CONFIG_VIDEO_HEXIUM_GEMINI=m -CONFIG_VIDEO_HEXIUM_ORION=m -CONFIG_VIDEO_MXB=m -CONFIG_DVB_BUDGET_CORE=m -CONFIG_DVB_BUDGET=m -CONFIG_DVB_BUDGET_CI=m -CONFIG_DVB_BUDGET_AV=m -CONFIG_VIDEO_STKWEBCAM=m -CONFIG_VIDEO_TM6000=m -CONFIG_VIDEO_TM6000_ALSA=m -CONFIG_VIDEO_TM6000_DVB=m -CONFIG_USB_ZR364XX=m # CONFIG_STAGING_BOARD is not set # CONFIG_LTE_GDM724X is not set CONFIG_FB_TFT=m @@ -8325,6 +8261,7 @@ CONFIG_HMS_ANYBUSS_BUS=m # CONFIG_HMS_PROFINET is not set # CONFIG_QLGE is not set # CONFIG_VME_BUS is not set +# CONFIG_RTL8723CS is not set # CONFIG_GOLDFISH is not set CONFIG_CHROME_PLATFORMS=y CONFIG_CHROMEOS_ACPI=m @@ -8333,6 +8270,7 @@ CONFIG_CROS_EC=y CONFIG_CROS_EC_I2C=y # CONFIG_CROS_EC_RPMSG is not set CONFIG_CROS_EC_SPI=y +# CONFIG_CROS_EC_UART is not set CONFIG_CROS_EC_PROTO=y # CONFIG_CROS_KBD_LED_BACKLIGHT is not set CONFIG_CROS_EC_CHARDEV=y @@ -8361,33 +8299,32 @@ CONFIG_COMMON_CLK=y # # Clock driver for ARM Reference designs # -CONFIG_CLK_ICST=y +# CONFIG_CLK_ICST is not set # CONFIG_CLK_SP810 is not set -CONFIG_CLK_VEXPRESS_OSC=m +# CONFIG_CLK_VEXPRESS_OSC is not set # end of Clock driver for ARM Reference designs -CONFIG_LMK04832=m -# CONFIG_COMMON_CLK_MAX77686 is not set +# CONFIG_LMK04832 is not set # CONFIG_COMMON_CLK_MAX9485 is not set +CONFIG_COMMON_CLK_RK808=y CONFIG_COMMON_CLK_SCMI=y -CONFIG_COMMON_CLK_SCPI=y -CONFIG_COMMON_CLK_SI5341=m +# CONFIG_COMMON_CLK_SCPI is not set +# CONFIG_COMMON_CLK_SI5341 is not set # CONFIG_COMMON_CLK_SI5351 is not set # CONFIG_COMMON_CLK_SI514 is not set -CONFIG_COMMON_CLK_SI544=m +# CONFIG_COMMON_CLK_SI544 is not set # CONFIG_COMMON_CLK_SI570 is not set # CONFIG_COMMON_CLK_CDCE706 is not set # CONFIG_COMMON_CLK_CDCE925 is not set -CONFIG_COMMON_CLK_CS2000_CP=y -CONFIG_COMMON_CLK_S2MPS11=y -CONFIG_COMMON_CLK_AXI_CLKGEN=m -CONFIG_COMMON_CLK_XGENE=y +# CONFIG_COMMON_CLK_CS2000_CP is not set +# CONFIG_COMMON_CLK_AXI_CLKGEN is not set +# CONFIG_COMMON_CLK_XGENE is not set CONFIG_COMMON_CLK_PWM=y # CONFIG_COMMON_CLK_RS9_PCIE is not set -CONFIG_COMMON_CLK_VC5=y +# CONFIG_COMMON_CLK_SI521XX is not set +# CONFIG_COMMON_CLK_VC5 is not set # CONFIG_COMMON_CLK_VC7 is not set -CONFIG_COMMON_CLK_BD718XX=m -CONFIG_COMMON_CLK_FIXED_MMIO=y +# CONFIG_COMMON_CLK_FIXED_MMIO is not set CONFIG_COMMON_CLK_ROCKCHIP=y CONFIG_CLK_PX30=y CONFIG_CLK_RK3308=y @@ -8396,11 +8333,11 @@ CONFIG_CLK_RK3368=y CONFIG_CLK_RK3399=y CONFIG_CLK_RK3568=y CONFIG_CLK_RK3588=y -CONFIG_XILINX_VCU=m -CONFIG_COMMON_CLK_XLNX_CLKWZRD=m -CONFIG_CLK_KUNIT_TEST=m -CONFIG_CLK_GATE_KUNIT_TEST=m -CONFIG_HWSPINLOCK=y +# CONFIG_XILINX_VCU is not set +# CONFIG_COMMON_CLK_XLNX_CLKWZRD is not set +# CONFIG_CLK_KUNIT_TEST is not set +# CONFIG_CLK_GATE_KUNIT_TEST is not set +# CONFIG_HWSPINLOCK is not set # # Clock Source drivers @@ -8416,7 +8353,6 @@ CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND=y CONFIG_FSL_ERRATUM_A008585=y CONFIG_HISILICON_ERRATUM_161010101=y CONFIG_ARM64_ERRATUM_858921=y -# CONFIG_MICROCHIP_PIT64B is not set # end of Clock Source drivers CONFIG_MAILBOX=y @@ -8429,7 +8365,6 @@ CONFIG_PCC=y # CONFIG_ALTERA_MBOX is not set # CONFIG_MAILBOX_TEST is not set CONFIG_IOMMU_IOVA=y -CONFIG_IOASID=y CONFIG_IOMMU_API=y CONFIG_IOMMU_SUPPORT=y @@ -8484,6 +8419,7 @@ CONFIG_SOUNDWIRE=m # # SoundWire Devices # +# CONFIG_SOUNDWIRE_AMD is not set # CONFIG_SOUNDWIRE_INTEL is not set CONFIG_SOUNDWIRE_QCOM=m @@ -8527,9 +8463,12 @@ CONFIG_LITEX=y CONFIG_LITEX_SOC_CONTROLLER=m # end of Enable LiteX SoC Builder specific drivers +# CONFIG_WPCM450_SOC is not set + # # Qualcomm SoC drivers # +# CONFIG_QCOM_PMIC_GLINK is not set CONFIG_QCOM_QMI_HELPERS=m # end of Qualcomm SoC drivers @@ -8687,8 +8626,6 @@ CONFIG_AD7923=m CONFIG_AD7949=m CONFIG_AD799X=m # CONFIG_ADI_AXI_ADC is not set -CONFIG_AXP20X_ADC=m -CONFIG_AXP288_ADC=m # CONFIG_CC10001_ADC is not set # CONFIG_ENVELOPE_DETECTOR is not set # CONFIG_HI8435 is not set @@ -8714,7 +8651,6 @@ CONFIG_MCP3911=m # CONFIG_QCOM_SPMI_IADC is not set # CONFIG_QCOM_SPMI_VADC is not set # CONFIG_QCOM_SPMI_ADC5 is not set -CONFIG_RN5T618_ADC=m CONFIG_ROCKCHIP_SARADC=y CONFIG_RICHTEK_RTQ6056=m # CONFIG_SD_ADC_MODULATOR is not set @@ -8726,11 +8662,14 @@ CONFIG_TI_ADC108S102=m CONFIG_TI_ADC128S052=m CONFIG_TI_ADC161S626=m CONFIG_TI_ADS1015=m +# CONFIG_TI_ADS7924 is not set +# CONFIG_TI_ADS1100 is not set CONFIG_TI_ADS7950=m CONFIG_TI_ADS8344=m CONFIG_TI_ADS8688=m CONFIG_TI_ADS124S08=m CONFIG_TI_ADS131E08=m +# CONFIG_TI_LMP92064 is not set # CONFIG_TI_TLC4541 is not set CONFIG_TI_TSC2046=m # CONFIG_VF610_ADC is not set @@ -8850,6 +8789,7 @@ CONFIG_LTC1660=m # CONFIG_LTC2632 is not set # CONFIG_M62332 is not set # CONFIG_MAX517 is not set +# CONFIG_MAX5522 is not set # CONFIG_MAX5821 is not set # CONFIG_MCP4725 is not set # CONFIG_MCP4922 is not set @@ -9000,15 +8940,14 @@ CONFIG_CM36651=m CONFIG_IIO_CROS_EC_LIGHT_PROX=m CONFIG_GP2AP002=m CONFIG_GP2AP020A00F=m -CONFIG_IQS621_ALS=m CONFIG_SENSORS_ISL29018=m CONFIG_SENSORS_ISL29028=m CONFIG_ISL29125=m CONFIG_HID_SENSOR_ALS=m CONFIG_HID_SENSOR_PROX=m CONFIG_JSA1212=m +# CONFIG_ROHM_BU27034 is not set CONFIG_RPR0521=m -CONFIG_SENSORS_LM3533=m CONFIG_LTR501=m # CONFIG_LTRF216A is not set CONFIG_LV0104CS=m @@ -9060,6 +8999,7 @@ CONFIG_SENSORS_HMC5843_SPI=m CONFIG_SENSORS_RM3100=m CONFIG_SENSORS_RM3100_I2C=m CONFIG_SENSORS_RM3100_SPI=m +# CONFIG_TI_TMAG5273 is not set CONFIG_YAMAHA_YAS530=m # end of Magnetometer sensors @@ -9090,7 +9030,6 @@ CONFIG_IIO_SYSFS_TRIGGER=m # # Linear and angular position sensors # -CONFIG_IQS624_POS=m CONFIG_HID_SENSOR_CUSTOM_INTEL_HINGE=m # end of Linear and angular position sensors @@ -9175,7 +9114,6 @@ CONFIG_VL53L0X_I2C=m # # Temperature sensors # -CONFIG_IQS620AT_TEMP=m CONFIG_LTC2983=m CONFIG_MAXIM_THERMOCOUPLE=m CONFIG_HID_SENSOR_TEMP=m @@ -9200,7 +9138,6 @@ CONFIG_PWM_CLK=m CONFIG_PWM_CROS_EC=m CONFIG_PWM_DWC=m # CONFIG_PWM_FSL_FTM is not set -# CONFIG_PWM_IQS620A is not set CONFIG_PWM_NTXEC=m # CONFIG_PWM_PCA9685 is not set CONFIG_PWM_ROCKCHIP=y @@ -9234,7 +9171,6 @@ CONFIG_RESET_TI_TPS380X=m # CONFIG_GENERIC_PHY=y CONFIG_GENERIC_PHY_MIPI_DPHY=y -CONFIG_PHY_XGENE=y CONFIG_PHY_CAN_TRANSCEIVER=m # @@ -9268,6 +9204,7 @@ CONFIG_PHY_ROCKCHIP_PCIE=y CONFIG_PHY_ROCKCHIP_SNPS_PCIE3=m CONFIG_PHY_ROCKCHIP_TYPEC=y CONFIG_PHY_ROCKCHIP_USB=y +CONFIG_PHY_ROCKCHIP_USBDP=y CONFIG_PHY_SAMSUNG_USB2=y # CONFIG_PHY_TUSB1210 is not set # end of PHY Subsystem @@ -9286,6 +9223,7 @@ CONFIG_ARM_CCN=y CONFIG_ARM_PMU=y CONFIG_ARM_PMU_ACPI=y CONFIG_ARM_SMMU_V3_PMU=m +CONFIG_ARM_PMUV3=y # CONFIG_ARM_DSU_PMU is not set # CONFIG_ARM_SPE_PMU is not set CONFIG_ARM_DMC620_PMU=m @@ -9309,10 +9247,18 @@ CONFIG_RAS=y CONFIG_DAX=y CONFIG_DEV_DAX=m CONFIG_DEV_DAX_HMEM=m +CONFIG_DEV_DAX_CXL=m CONFIG_DEV_DAX_HMEM_DEVICES=y CONFIG_NVMEM=y CONFIG_NVMEM_SYSFS=y -CONFIG_NVMEM_RAVE_SP_EEPROM=m + +# +# Layout Types +# +# CONFIG_NVMEM_LAYOUT_SL28_VPD is not set +# CONFIG_NVMEM_LAYOUT_ONIE_TLV is not set +# end of Layout Types + CONFIG_NVMEM_RMEM=m CONFIG_NVMEM_ROCKCHIP_EFUSE=m CONFIG_NVMEM_ROCKCHIP_OTP=m @@ -9345,6 +9291,7 @@ CONFIG_FPGA_MGR_MICROCHIP_SPI=m # CONFIG_FSI is not set CONFIG_TEE=y CONFIG_OPTEE=y +# CONFIG_OPTEE_INSECURE_LOAD_IMAGE is not set CONFIG_MULTIPLEXER=y # @@ -9363,15 +9310,13 @@ CONFIG_SLIM_QCOM_CTRL=m CONFIG_INTERCONNECT=y CONFIG_COUNTER=m CONFIG_INTERRUPT_CNT=m -CONFIG_FTM_QUADDEC=m -# CONFIG_MICROCHIP_TCB_CAPTURE is not set -CONFIG_INTEL_QEP=m CONFIG_MOST=m # CONFIG_MOST_USB_HDM is not set # CONFIG_MOST_CDEV is not set CONFIG_MOST_SND=m # CONFIG_PECI is not set # CONFIG_HTE is not set +# CONFIG_CDX_BUS is not set # end of Device Drivers # @@ -9380,6 +9325,7 @@ CONFIG_MOST_SND=m CONFIG_DCACHE_WORD_ACCESS=y CONFIG_VALIDATE_FS_PARSER=y CONFIG_FS_IOMAP=y +CONFIG_LEGACY_DIRECT_IO=y CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y CONFIG_EXT2_FS_POSIX_ACL=y @@ -9408,6 +9354,7 @@ CONFIG_JFS_SECURITY=y CONFIG_JFS_STATISTICS=y CONFIG_XFS_FS=m CONFIG_XFS_SUPPORT_V4=y +CONFIG_XFS_SUPPORT_ASCII_CI=y CONFIG_XFS_QUOTA=y CONFIG_XFS_POSIX_ACL=y CONFIG_XFS_RT=y @@ -9453,7 +9400,6 @@ CONFIG_FILE_LOCKING=y CONFIG_FS_ENCRYPTION=y CONFIG_FS_ENCRYPTION_ALGS=y CONFIG_FS_VERITY=y -# CONFIG_FS_VERITY_DEBUG is not set CONFIG_FS_VERITY_BUILTIN_SIGNATURES=y CONFIG_FSNOTIFY=y CONFIG_DNOTIFY=y @@ -9462,7 +9408,6 @@ CONFIG_FANOTIFY=y CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y CONFIG_QUOTA=y CONFIG_QUOTA_NETLINK_INTERFACE=y -CONFIG_PRINT_QUOTA_WARNING=y # CONFIG_QUOTA_DEBUG is not set CONFIG_QUOTA_TREE=m CONFIG_QFMT_V1=m @@ -9507,19 +9452,18 @@ CONFIG_UDF_FS=m # DOS/FAT/EXFAT/NT Filesystems # CONFIG_FAT_FS=y -CONFIG_MSDOS_FS=m +# CONFIG_MSDOS_FS is not set CONFIG_VFAT_FS=y -CONFIG_FAT_DEFAULT_CODEPAGE=437 -CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" -CONFIG_FAT_DEFAULT_UTF8=y -CONFIG_FAT_KUNIT_TEST=m -CONFIG_EXFAT_FS=m -CONFIG_EXFAT_DEFAULT_IOCHARSET="utf8" -CONFIG_NTFS_FS=m +CONFIG_FAT_DEFAULT_CODEPAGE=936 +CONFIG_FAT_DEFAULT_IOCHARSET="utf8" +# CONFIG_FAT_DEFAULT_UTF8 is not set +# CONFIG_FAT_KUNIT_TEST is not set +# CONFIG_EXFAT_FS is not set +CONFIG_NTFS_FS=y # CONFIG_NTFS_DEBUG is not set CONFIG_NTFS_RW=y -CONFIG_NTFS3_FS=m -CONFIG_NTFS3_64BIT_CLUSTER=y +CONFIG_NTFS3_FS=y +# CONFIG_NTFS3_64BIT_CLUSTER is not set CONFIG_NTFS3_LZX_XPRESS=y CONFIG_NTFS3_FS_POSIX_ACL=y # end of DOS/FAT/EXFAT/NT Filesystems @@ -9529,8 +9473,6 @@ CONFIG_NTFS3_FS_POSIX_ACL=y # CONFIG_PROC_FS=y # CONFIG_PROC_KCORE is not set -CONFIG_PROC_VMCORE=y -# CONFIG_PROC_VMCORE_DEVICE_DUMP is not set CONFIG_PROC_SYSCTL=y CONFIG_PROC_PAGE_MONITOR=y CONFIG_PROC_CHILDREN=y @@ -9543,9 +9485,6 @@ CONFIG_TMPFS_XATTR=y CONFIG_ARCH_SUPPORTS_HUGETLBFS=y CONFIG_HUGETLBFS=y CONFIG_HUGETLB_PAGE=y -CONFIG_ARCH_WANT_HUGETLB_PAGE_OPTIMIZE_VMEMMAP=y -CONFIG_HUGETLB_PAGE_OPTIMIZE_VMEMMAP=y -# CONFIG_HUGETLB_PAGE_OPTIMIZE_VMEMMAP_DEFAULT_ON is not set CONFIG_MEMFD_CREATE=y CONFIG_ARCH_HAS_GIGANTIC_PAGE=y CONFIG_CONFIGFS_FS=y @@ -9695,7 +9634,12 @@ CONFIG_SUNRPC_GSS=m CONFIG_SUNRPC_BACKCHANNEL=y CONFIG_SUNRPC_SWAP=y CONFIG_RPCSEC_GSS_KRB5=m -# CONFIG_SUNRPC_DISABLE_INSECURE_ENCTYPES is not set +CONFIG_RPCSEC_GSS_KRB5_CRYPTOSYSTEM=y +# CONFIG_RPCSEC_GSS_KRB5_ENCTYPES_DES is not set +CONFIG_RPCSEC_GSS_KRB5_ENCTYPES_AES_SHA1=y +# CONFIG_RPCSEC_GSS_KRB5_ENCTYPES_CAMELLIA is not set +# CONFIG_RPCSEC_GSS_KRB5_ENCTYPES_AES_SHA2 is not set +# CONFIG_RPCSEC_GSS_KRB5_KUNIT_TEST is not set CONFIG_SUNRPC_DEBUG=y CONFIG_CEPH_FS=m CONFIG_CEPH_FSCACHE=y @@ -9716,7 +9660,7 @@ CONFIG_CIFS_FSCACHE=y CONFIG_SMB_SERVER=m CONFIG_SMB_SERVER_CHECK_CAP_NET_ADMIN=y CONFIG_SMB_SERVER_KERBEROS5=y -CONFIG_SMBFS_COMMON=m +CONFIG_SMBFS=m CONFIG_CODA_FS=m CONFIG_AFS_FS=m # CONFIG_AFS_DEBUG is not set @@ -9778,7 +9722,6 @@ CONFIG_NLS_MAC_ROMANIAN=m CONFIG_NLS_MAC_TURKISH=m CONFIG_NLS_UTF8=m CONFIG_DLM=m -CONFIG_DLM_DEPRECATED_API=y # CONFIG_DLM_DEBUG is not set CONFIG_UNICODE=y # CONFIG_UNICODE_NORMALIZATION_SELFTEST is not set @@ -9810,10 +9753,8 @@ CONFIG_FORTIFY_SOURCE=y # CONFIG_STATIC_USERMODEHELPER is not set CONFIG_SECURITY_SELINUX=y CONFIG_SECURITY_SELINUX_BOOTPARAM=y -# CONFIG_SECURITY_SELINUX_DISABLE is not set CONFIG_SECURITY_SELINUX_DEVELOP=y CONFIG_SECURITY_SELINUX_AVC_STATS=y -CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1 CONFIG_SECURITY_SELINUX_SIDTAB_HASH_BITS=9 CONFIG_SECURITY_SELINUX_SID2STR_CACHE_SIZE=256 CONFIG_SECURITY_SMACK=y @@ -10126,6 +10067,8 @@ CONFIG_CRYPTO_DEV_ATMEL_I2C=m CONFIG_CRYPTO_DEV_ATMEL_ECC=m CONFIG_CRYPTO_DEV_ATMEL_SHA204A=m # CONFIG_CRYPTO_DEV_CCP is not set +CONFIG_CRYPTO_DEV_NITROX=m +CONFIG_CRYPTO_DEV_NITROX_CNN55XX=m # CONFIG_CRYPTO_DEV_QAT_DH895xCC is not set # CONFIG_CRYPTO_DEV_QAT_C3XXX is not set # CONFIG_CRYPTO_DEV_QAT_C62X is not set @@ -10133,8 +10076,6 @@ CONFIG_CRYPTO_DEV_ATMEL_SHA204A=m # CONFIG_CRYPTO_DEV_QAT_DH895xCCVF is not set # CONFIG_CRYPTO_DEV_QAT_C3XXXVF is not set # CONFIG_CRYPTO_DEV_QAT_C62XVF is not set -CONFIG_CRYPTO_DEV_NITROX=m -CONFIG_CRYPTO_DEV_NITROX_CNN55XX=m CONFIG_CRYPTO_DEV_CAVIUM_ZIP=m CONFIG_CRYPTO_DEV_ROCKCHIP=m # CONFIG_CRYPTO_DEV_ROCKCHIP_DEBUG is not set @@ -10283,6 +10224,7 @@ CONFIG_INTERVAL_TREE=y CONFIG_XARRAY_MULTI=y CONFIG_ASSOCIATIVE_ARRAY=y CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y CONFIG_HAS_IOPORT_MAP=y CONFIG_HAS_DMA=y CONFIG_DMA_OPS=y @@ -10450,10 +10392,11 @@ CONFIG_ARCH_HAS_DEBUG_WX=y # CONFIG_DEBUG_WX is not set CONFIG_GENERIC_PTDUMP=y # CONFIG_PTDUMP_DEBUGFS is not set -# CONFIG_DEBUG_OBJECTS is not set -# CONFIG_SHRINKER_DEBUG is not set CONFIG_HAVE_DEBUG_KMEMLEAK=y # CONFIG_DEBUG_KMEMLEAK is not set +# CONFIG_PER_VMA_LOCK_STATS is not set +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_SHRINKER_DEBUG is not set # CONFIG_DEBUG_STACK_USAGE is not set # CONFIG_SCHED_STACK_END_CHECK is not set CONFIG_ARCH_HAS_DEBUG_VM_PGTABLE=y @@ -10547,6 +10490,7 @@ CONFIG_RCU_TORTURE_TEST=m # CONFIG_RCU_REF_SCALE_TEST is not set CONFIG_RCU_CPU_STALL_TIMEOUT=21 CONFIG_RCU_EXP_CPU_STALL_TIMEOUT=0 +# CONFIG_RCU_CPU_STALL_CPUTIME is not set CONFIG_RCU_TRACE=y # CONFIG_RCU_EQS_DEBUG is not set # end of RCU Debugging @@ -10592,6 +10536,7 @@ CONFIG_DYNAMIC_EVENTS=y CONFIG_PROBE_EVENTS=y # CONFIG_BPF_KPROBE_OVERRIDE is not set # CONFIG_SYNTH_EVENTS is not set +# CONFIG_USER_EVENTS is not set # CONFIG_HIST_TRIGGERS is not set # CONFIG_TRACE_EVENT_INJECT is not set # CONFIG_TRACEPOINT_BENCHMARK is not set @@ -10629,6 +10574,7 @@ CONFIG_FUNCTION_ERROR_INJECTION=y CONFIG_ARCH_HAS_KCOV=y CONFIG_CC_HAS_SANCOV_TRACE_PC=y CONFIG_RUNTIME_TESTING_MENU=y +# CONFIG_TEST_DHRY is not set # CONFIG_LKDTM is not set # CONFIG_CPUMASK_KUNIT_TEST is not set # CONFIG_TEST_LIST_SORT is not set @@ -10670,6 +10616,7 @@ CONFIG_TEST_BLACKHOLE_DEV=m CONFIG_RESOURCE_KUNIT_TEST=m # CONFIG_SYSCTL_KUNIT_TEST is not set # CONFIG_LIST_KUNIT_TEST is not set +# CONFIG_HASHTABLE_KUNIT_TEST is not set # CONFIG_LINEAR_RANGES_TEST is not set CONFIG_CMDLINE_KUNIT_TEST=m # CONFIG_BITS_TEST is not set diff --git a/patch/kernel/rockchip-rk3588-edge/0010-Introduce-RK806-Support.patch b/patch/kernel/rockchip-rk3588-edge/0010-Introduce-RK806-Support.patch new file mode 100644 index 0000000000..5887515ebd --- /dev/null +++ b/patch/kernel/rockchip-rk3588-edge/0010-Introduce-RK806-Support.patch @@ -0,0 +1,4362 @@ +From 4c89cdd103083e4af11f3cf144aa6ab5a1f2bc1b Mon Sep 17 00:00:00 2001 +From: Sebastian Reichel +Date: Tue, 12 Jul 2022 14:19:57 +0200 +Subject: [PATCH 01/17] clk: RK808: reduce 'struct rk808' usage + +Reduce usage of 'struct rk808' (driver data of the parent MFD), so +that only the chip variant field is still being accessed directly. +This allows restructuring the MFD driver to support SPI based +PMICs. + +Acked-by: Stephen Boyd +Tested-by: Diederik de Haas # Rock64, Quartz64 Model A + B +Tested-by: Vincent Legoll # Pine64 QuartzPro64 +Signed-off-by: Sebastian Reichel +--- + drivers/clk/clk-rk808.c | 34 ++++++++++++++++------------------ + 1 file changed, 16 insertions(+), 18 deletions(-) + +diff --git a/drivers/clk/clk-rk808.c b/drivers/clk/clk-rk808.c +index 32f833d732ed..f7412b137e5e 100644 +--- a/drivers/clk/clk-rk808.c ++++ b/drivers/clk/clk-rk808.c +@@ -12,10 +12,9 @@ + #include + #include + #include +-#include + + struct rk808_clkout { +- struct rk808 *rk808; ++ struct regmap *regmap; + struct clk_hw clkout1_hw; + struct clk_hw clkout2_hw; + }; +@@ -31,9 +30,8 @@ static int rk808_clkout2_enable(struct clk_hw *hw, bool enable) + struct rk808_clkout *rk808_clkout = container_of(hw, + struct rk808_clkout, + clkout2_hw); +- struct rk808 *rk808 = rk808_clkout->rk808; + +- return regmap_update_bits(rk808->regmap, RK808_CLK32OUT_REG, ++ return regmap_update_bits(rk808_clkout->regmap, RK808_CLK32OUT_REG, + CLK32KOUT2_EN, enable ? CLK32KOUT2_EN : 0); + } + +@@ -52,10 +50,9 @@ static int rk808_clkout2_is_prepared(struct clk_hw *hw) + struct rk808_clkout *rk808_clkout = container_of(hw, + struct rk808_clkout, + clkout2_hw); +- struct rk808 *rk808 = rk808_clkout->rk808; + uint32_t val; + +- int ret = regmap_read(rk808->regmap, RK808_CLK32OUT_REG, &val); ++ int ret = regmap_read(rk808_clkout->regmap, RK808_CLK32OUT_REG, &val); + + if (ret < 0) + return ret; +@@ -93,9 +90,8 @@ static int rk817_clkout2_enable(struct clk_hw *hw, bool enable) + struct rk808_clkout *rk808_clkout = container_of(hw, + struct rk808_clkout, + clkout2_hw); +- struct rk808 *rk808 = rk808_clkout->rk808; + +- return regmap_update_bits(rk808->regmap, RK817_SYS_CFG(1), ++ return regmap_update_bits(rk808_clkout->regmap, RK817_SYS_CFG(1), + RK817_CLK32KOUT2_EN, + enable ? RK817_CLK32KOUT2_EN : 0); + } +@@ -115,10 +111,9 @@ static int rk817_clkout2_is_prepared(struct clk_hw *hw) + struct rk808_clkout *rk808_clkout = container_of(hw, + struct rk808_clkout, + clkout2_hw); +- struct rk808 *rk808 = rk808_clkout->rk808; + unsigned int val; + +- int ret = regmap_read(rk808->regmap, RK817_SYS_CFG(1), &val); ++ int ret = regmap_read(rk808_clkout->regmap, RK817_SYS_CFG(1), &val); + + if (ret < 0) + return 0; +@@ -153,18 +148,21 @@ static const struct clk_ops *rkpmic_get_ops(long variant) + static int rk808_clkout_probe(struct platform_device *pdev) + { + struct rk808 *rk808 = dev_get_drvdata(pdev->dev.parent); +- struct i2c_client *client = rk808->i2c; +- struct device_node *node = client->dev.of_node; ++ struct device *dev = &pdev->dev; + struct clk_init_data init = {}; + struct rk808_clkout *rk808_clkout; + int ret; + +- rk808_clkout = devm_kzalloc(&client->dev, ++ dev->of_node = pdev->dev.parent->of_node; ++ ++ rk808_clkout = devm_kzalloc(dev, + sizeof(*rk808_clkout), GFP_KERNEL); + if (!rk808_clkout) + return -ENOMEM; + +- rk808_clkout->rk808 = rk808; ++ rk808_clkout->regmap = dev_get_regmap(pdev->dev.parent, NULL); ++ if (!rk808_clkout->regmap) ++ return -ENODEV; + + init.parent_names = NULL; + init.num_parents = 0; +@@ -173,10 +171,10 @@ static int rk808_clkout_probe(struct platform_device *pdev) + rk808_clkout->clkout1_hw.init = &init; + + /* optional override of the clockname */ +- of_property_read_string_index(node, "clock-output-names", ++ of_property_read_string_index(dev->of_node, "clock-output-names", + 0, &init.name); + +- ret = devm_clk_hw_register(&client->dev, &rk808_clkout->clkout1_hw); ++ ret = devm_clk_hw_register(dev, &rk808_clkout->clkout1_hw); + if (ret) + return ret; + +@@ -185,10 +183,10 @@ static int rk808_clkout_probe(struct platform_device *pdev) + rk808_clkout->clkout2_hw.init = &init; + + /* optional override of the clockname */ +- of_property_read_string_index(node, "clock-output-names", ++ of_property_read_string_index(dev->of_node, "clock-output-names", + 1, &init.name); + +- ret = devm_clk_hw_register(&client->dev, &rk808_clkout->clkout2_hw); ++ ret = devm_clk_hw_register(dev, &rk808_clkout->clkout2_hw); + if (ret) + return ret; + +-- +2.41.0 + + +From 0bd4e344dfa8325b345c0c2ccb3f2e2f4ad21baa Mon Sep 17 00:00:00 2001 +From: Sebastian Reichel +Date: Tue, 28 Jun 2022 18:05:55 +0200 +Subject: [PATCH 02/17] mfd: rk808: convert to device managed resources + +Fully convert the driver to device managed resources. + +Acked-for-MFD-by: Lee Jones +Tested-by: Diederik de Haas # Rock64, Quartz64 Model A + B +Tested-by: Vincent Legoll # Pine64 QuartzPro64 +Signed-off-by: Sebastian Reichel +--- + drivers/mfd/rk808.c | 64 ++++++++++++++++----------------------------- + 1 file changed, 22 insertions(+), 42 deletions(-) + +diff --git a/drivers/mfd/rk808.c b/drivers/mfd/rk808.c +index 0f22ef61e817..a996a43f9204 100644 +--- a/drivers/mfd/rk808.c ++++ b/drivers/mfd/rk808.c +@@ -548,13 +548,11 @@ static const struct regmap_irq_chip rk818_irq_chip = { + .init_ack_masked = true, + }; + +-static struct i2c_client *rk808_i2c_client; +- +-static void rk808_pm_power_off(void) ++static int rk808_power_off(struct sys_off_data *data) + { ++ struct rk808 *rk808 = data->cb_data; + int ret; + unsigned int reg, bit; +- struct rk808 *rk808 = i2c_get_clientdata(rk808_i2c_client); + + switch (rk808->variant) { + case RK805_ID: +@@ -575,16 +573,18 @@ static void rk808_pm_power_off(void) + bit = DEV_OFF; + break; + default: +- return; ++ return NOTIFY_DONE; + } + ret = regmap_update_bits(rk808->regmap, reg, bit, bit); + if (ret) +- dev_err(&rk808_i2c_client->dev, "Failed to shutdown device!\n"); ++ dev_err(&rk808->i2c->dev, "Failed to shutdown device!\n"); ++ ++ return NOTIFY_DONE; + } + +-static int rk808_restart_notify(struct notifier_block *this, unsigned long mode, void *cmd) ++static int rk808_restart(struct sys_off_data *data) + { +- struct rk808 *rk808 = i2c_get_clientdata(rk808_i2c_client); ++ struct rk808 *rk808 = data->cb_data; + unsigned int reg, bit; + int ret; + +@@ -600,16 +600,11 @@ static int rk808_restart_notify(struct notifier_block *this, unsigned long mode, + } + ret = regmap_update_bits(rk808->regmap, reg, bit, bit); + if (ret) +- dev_err(&rk808_i2c_client->dev, "Failed to restart device!\n"); ++ dev_err(&rk808->i2c->dev, "Failed to restart device!\n"); + + return NOTIFY_DONE; + } + +-static struct notifier_block rk808_restart_handler = { +- .notifier_call = rk808_restart_notify, +- .priority = 192, +-}; +- + static void rk8xx_shutdown(struct i2c_client *client) + { + struct rk808 *rk808 = i2c_get_clientdata(client); +@@ -745,9 +740,9 @@ static int rk808_probe(struct i2c_client *client) + return -EINVAL; + } + +- ret = regmap_add_irq_chip(rk808->regmap, client->irq, +- IRQF_ONESHOT, -1, +- rk808->regmap_irq_chip, &rk808->irq_data); ++ ret = devm_regmap_add_irq_chip(&client->dev, rk808->regmap, client->irq, ++ IRQF_ONESHOT, -1, ++ rk808->regmap_irq_chip, &rk808->irq_data); + if (ret) { + dev_err(&client->dev, "Failed to add irq_chip %d\n", ret); + return ret; +@@ -771,17 +766,23 @@ static int rk808_probe(struct i2c_client *client) + regmap_irq_get_domain(rk808->irq_data)); + if (ret) { + dev_err(&client->dev, "failed to add MFD devices %d\n", ret); +- goto err_irq; ++ return ret; + } + + if (of_property_read_bool(np, "rockchip,system-power-controller")) { +- rk808_i2c_client = client; +- pm_power_off = rk808_pm_power_off; ++ ret = devm_register_sys_off_handler(&client->dev, ++ SYS_OFF_MODE_POWER_OFF_PREPARE, SYS_OFF_PRIO_HIGH, ++ &rk808_power_off, rk808); ++ if (ret) ++ return dev_err_probe(&client->dev, ret, ++ "failed to register poweroff handler\n"); + + switch (rk808->variant) { + case RK809_ID: + case RK817_ID: +- ret = register_restart_handler(&rk808_restart_handler); ++ ret = devm_register_sys_off_handler(&client->dev, ++ SYS_OFF_MODE_RESTART, SYS_OFF_PRIO_HIGH, ++ &rk808_restart, rk808); + if (ret) + dev_warn(&client->dev, "failed to register rst handler, %d\n", ret); + break; +@@ -792,26 +793,6 @@ static int rk808_probe(struct i2c_client *client) + } + + return 0; +- +-err_irq: +- regmap_del_irq_chip(client->irq, rk808->irq_data); +- return ret; +-} +- +-static void rk808_remove(struct i2c_client *client) +-{ +- struct rk808 *rk808 = i2c_get_clientdata(client); +- +- regmap_del_irq_chip(client->irq, rk808->irq_data); +- +- /** +- * pm_power_off may points to a function from another module. +- * Check if the pointer is set by us and only then overwrite it. +- */ +- if (pm_power_off == rk808_pm_power_off) +- pm_power_off = NULL; +- +- unregister_restart_handler(&rk808_restart_handler); + } + + static int __maybe_unused rk8xx_suspend(struct device *dev) +@@ -868,7 +849,6 @@ static struct i2c_driver rk808_i2c_driver = { + .pm = &rk8xx_pm_ops, + }, + .probe_new = rk808_probe, +- .remove = rk808_remove, + .shutdown = rk8xx_shutdown, + }; + +-- +2.41.0 + + +From f80cd95d149c38e6112ffe0f8723d0f5eabc05ec Mon Sep 17 00:00:00 2001 +From: Sebastian Reichel +Date: Tue, 28 Jun 2022 18:12:06 +0200 +Subject: [PATCH 03/17] mfd: rk808: use dev_err_probe + +Use dev_err_probe instead of dev_err in probe function, +which simplifies code a little bit and prints the error +code. + +Also drop possibly incorrect printing of chip id registers +while touching the error message. + +Acked-for-MFD-by: Lee Jones +Tested-by: Diederik de Haas # Rock64, Quartz64 Model A + B +Tested-by: Vincent Legoll # Pine64 QuartzPro64 +Signed-off-by: Sebastian Reichel +--- + drivers/mfd/rk808.c | 48 +++++++++++++++------------------------------ + 1 file changed, 16 insertions(+), 32 deletions(-) + +diff --git a/drivers/mfd/rk808.c b/drivers/mfd/rk808.c +index a996a43f9204..f42e09e3a3f5 100644 +--- a/drivers/mfd/rk808.c ++++ b/drivers/mfd/rk808.c +@@ -670,18 +670,12 @@ static int rk808_probe(struct i2c_client *client) + + /* Read chip variant */ + msb = i2c_smbus_read_byte_data(client, pmic_id_msb); +- if (msb < 0) { +- dev_err(&client->dev, "failed to read the chip id at 0x%x\n", +- RK808_ID_MSB); +- return msb; +- } ++ if (msb < 0) ++ return dev_err_probe(&client->dev, msb, "failed to read the chip id MSB\n"); + + lsb = i2c_smbus_read_byte_data(client, pmic_id_lsb); +- if (lsb < 0) { +- dev_err(&client->dev, "failed to read the chip id at 0x%x\n", +- RK808_ID_LSB); +- return lsb; +- } ++ if (lsb < 0) ++ return dev_err_probe(&client->dev, lsb, "failed to read the chip id LSB\n"); + + rk808->variant = ((msb << 8) | lsb) & RK8XX_ID_MSK; + dev_info(&client->dev, "chip id: 0x%x\n", (unsigned int)rk808->variant); +@@ -730,44 +724,34 @@ static int rk808_probe(struct i2c_client *client) + i2c_set_clientdata(client, rk808); + + rk808->regmap = devm_regmap_init_i2c(client, rk808->regmap_cfg); +- if (IS_ERR(rk808->regmap)) { +- dev_err(&client->dev, "regmap initialization failed\n"); +- return PTR_ERR(rk808->regmap); +- } ++ if (IS_ERR(rk808->regmap)) ++ return dev_err_probe(&client->dev, PTR_ERR(rk808->regmap), ++ "regmap initialization failed\n"); + +- if (!client->irq) { +- dev_err(&client->dev, "No interrupt support, no core IRQ\n"); +- return -EINVAL; +- } ++ if (!client->irq) ++ return dev_err_probe(&client->dev, -EINVAL, "No interrupt support, no core IRQ\n"); + + ret = devm_regmap_add_irq_chip(&client->dev, rk808->regmap, client->irq, + IRQF_ONESHOT, -1, + rk808->regmap_irq_chip, &rk808->irq_data); +- if (ret) { +- dev_err(&client->dev, "Failed to add irq_chip %d\n", ret); +- return ret; +- } ++ if (ret) ++ return dev_err_probe(&client->dev, ret, "Failed to add irq_chip\n"); + + for (i = 0; i < nr_pre_init_regs; i++) { + ret = regmap_update_bits(rk808->regmap, + pre_init_reg[i].addr, + pre_init_reg[i].mask, + pre_init_reg[i].value); +- if (ret) { +- dev_err(&client->dev, +- "0x%x write err\n", +- pre_init_reg[i].addr); +- return ret; +- } ++ if (ret) ++ return dev_err_probe(&client->dev, ret, "0x%x write err\n", ++ pre_init_reg[i].addr); + } + + ret = devm_mfd_add_devices(&client->dev, PLATFORM_DEVID_NONE, + cells, nr_cells, NULL, 0, + regmap_irq_get_domain(rk808->irq_data)); +- if (ret) { +- dev_err(&client->dev, "failed to add MFD devices %d\n", ret); +- return ret; +- } ++ if (ret) ++ return dev_err_probe(&client->dev, ret, "failed to add MFD devices\n"); + + if (of_property_read_bool(np, "rockchip,system-power-controller")) { + ret = devm_register_sys_off_handler(&client->dev, +-- +2.41.0 + + +From 434f1e394f58e310e9675d0781b7c1fd81be81ec Mon Sep 17 00:00:00 2001 +From: Sebastian Reichel +Date: Tue, 12 Jul 2022 14:17:54 +0200 +Subject: [PATCH 04/17] mfd: rk808: replace 'struct i2c_client' with 'struct + device' + +Put 'struct device' pointer into the MFD platform_data instead +of the 'struct i2c_client' pointer. This simplifies the code +and prepares the MFD for SPI support. + +Acked-for-MFD-by: Lee Jones +Tested-by: Diederik de Haas # Rock64, Quartz64 Model A + B +Tested-by: Vincent Legoll # Pine64 QuartzPro64 +Signed-off-by: Sebastian Reichel +--- + drivers/mfd/rk808.c | 6 +++--- + include/linux/mfd/rk808.h | 2 +- + 2 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/mfd/rk808.c b/drivers/mfd/rk808.c +index f42e09e3a3f5..ce52307cbaea 100644 +--- a/drivers/mfd/rk808.c ++++ b/drivers/mfd/rk808.c +@@ -577,7 +577,7 @@ static int rk808_power_off(struct sys_off_data *data) + } + ret = regmap_update_bits(rk808->regmap, reg, bit, bit); + if (ret) +- dev_err(&rk808->i2c->dev, "Failed to shutdown device!\n"); ++ dev_err(rk808->dev, "Failed to shutdown device!\n"); + + return NOTIFY_DONE; + } +@@ -600,7 +600,7 @@ static int rk808_restart(struct sys_off_data *data) + } + ret = regmap_update_bits(rk808->regmap, reg, bit, bit); + if (ret) +- dev_err(&rk808->i2c->dev, "Failed to restart device!\n"); ++ dev_err(rk808->dev, "Failed to restart device!\n"); + + return NOTIFY_DONE; + } +@@ -720,7 +720,7 @@ static int rk808_probe(struct i2c_client *client) + return -EINVAL; + } + +- rk808->i2c = client; ++ rk808->dev = &client->dev; + i2c_set_clientdata(client, rk808); + + rk808->regmap = devm_regmap_init_i2c(client, rk808->regmap_cfg); +diff --git a/include/linux/mfd/rk808.h b/include/linux/mfd/rk808.h +index 9af1f3105f80..a89ddd9ba68e 100644 +--- a/include/linux/mfd/rk808.h ++++ b/include/linux/mfd/rk808.h +@@ -787,7 +787,7 @@ enum { + }; + + struct rk808 { +- struct i2c_client *i2c; ++ struct device *dev; + struct regmap_irq_chip_data *irq_data; + struct regmap *regmap; + long variant; +-- +2.41.0 + + +From 6bc5b1ab7856d87ec8dcdbf69499e589e62c8ed6 Mon Sep 17 00:00:00 2001 +From: Sebastian Reichel +Date: Wed, 29 Jun 2022 16:56:32 +0200 +Subject: [PATCH 05/17] mfd: rk808: split into core and i2c + +Split rk808 into a core and an i2c part in preparation for +SPI support. + +Acked-for-MFD-by: Lee Jones +Acked-by: Alexandre Belloni # for RTC +Tested-by: Diederik de Haas # Rock64, Quartz64 Model A + B +Tested-by: Vincent Legoll # Pine64 QuartzPro64 +Signed-off-by: Sebastian Reichel +--- + drivers/clk/Kconfig | 2 +- + drivers/input/misc/Kconfig | 2 +- + drivers/mfd/Kconfig | 7 +- + drivers/mfd/Makefile | 3 +- + drivers/mfd/{rk808.c => rk8xx-core.c} | 209 +++++--------------------- + drivers/mfd/rk8xx-i2c.c | 200 ++++++++++++++++++++++++ + drivers/pinctrl/Kconfig | 2 +- + drivers/power/supply/Kconfig | 2 +- + drivers/regulator/Kconfig | 2 +- + drivers/rtc/Kconfig | 2 +- + include/linux/mfd/rk808.h | 6 + + sound/soc/codecs/Kconfig | 2 +- + 12 files changed, 256 insertions(+), 183 deletions(-) + rename drivers/mfd/{rk808.c => rk8xx-core.c} (76%) + create mode 100644 drivers/mfd/rk8xx-i2c.c + +diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig +index 016814e15536..c0c8e526a1e9 100644 +--- a/drivers/clk/Kconfig ++++ b/drivers/clk/Kconfig +@@ -82,7 +82,7 @@ config COMMON_CLK_MAX9485 + + config COMMON_CLK_RK808 + tristate "Clock driver for RK805/RK808/RK809/RK817/RK818" +- depends on MFD_RK808 ++ depends on MFD_RK8XX + help + This driver supports RK805, RK809 and RK817, RK808 and RK818 crystal oscillator clock. + These multi-function devices have two fixed-rate oscillators, clocked at 32KHz each. +diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig +index 81a54a59e13c..8a320e6218e3 100644 +--- a/drivers/input/misc/Kconfig ++++ b/drivers/input/misc/Kconfig +@@ -609,7 +609,7 @@ config INPUT_PWM_VIBRA + + config INPUT_RK805_PWRKEY + tristate "Rockchip RK805 PMIC power key support" +- depends on MFD_RK808 ++ depends on MFD_RK8XX + help + Select this option to enable power key driver for RK805. + +diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig +index e90463c4441c..de53e6c701fd 100644 +--- a/drivers/mfd/Kconfig ++++ b/drivers/mfd/Kconfig +@@ -1183,12 +1183,17 @@ config MFD_RC5T583 + Additional drivers must be enabled in order to use the + different functionality of the device. + +-config MFD_RK808 ++config MFD_RK8XX ++ bool ++ select MFD_CORE ++ ++config MFD_RK8XX_I2C + tristate "Rockchip RK805/RK808/RK809/RK817/RK818 Power Management Chip" + depends on I2C && OF + select MFD_CORE + select REGMAP_I2C + select REGMAP_IRQ ++ select MFD_RK8XX + help + If you say yes here you get support for the RK805, RK808, RK809, + RK817 and RK818 Power Management chips. +diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile +index 1d2392f06f78..ba373193e999 100644 +--- a/drivers/mfd/Makefile ++++ b/drivers/mfd/Makefile +@@ -214,7 +214,8 @@ obj-$(CONFIG_MFD_PALMAS) += palmas.o + obj-$(CONFIG_MFD_VIPERBOARD) += viperboard.o + obj-$(CONFIG_MFD_NTXEC) += ntxec.o + obj-$(CONFIG_MFD_RC5T583) += rc5t583.o rc5t583-irq.o +-obj-$(CONFIG_MFD_RK808) += rk808.o ++obj-$(CONFIG_MFD_RK8XX) += rk8xx-core.o ++obj-$(CONFIG_MFD_RK8XX_I2C) += rk8xx-i2c.o + obj-$(CONFIG_MFD_RN5T618) += rn5t618.o + obj-$(CONFIG_MFD_SEC_CORE) += sec-core.o sec-irq.o + obj-$(CONFIG_MFD_SYSCON) += syscon.o +diff --git a/drivers/mfd/rk808.c b/drivers/mfd/rk8xx-core.c +similarity index 76% +rename from drivers/mfd/rk808.c +rename to drivers/mfd/rk8xx-core.c +index ce52307cbaea..5c0a5acef34c 100644 +--- a/drivers/mfd/rk808.c ++++ b/drivers/mfd/rk8xx-core.c +@@ -1,18 +1,15 @@ + // SPDX-License-Identifier: GPL-2.0-only + /* +- * MFD core driver for Rockchip RK808/RK818 ++ * MFD core driver for Rockchip RK8XX + * + * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd ++ * Copyright (C) 2016 PHYTEC Messtechnik GmbH + * + * Author: Chris Zhong + * Author: Zhang Qing +- * +- * Copyright (C) 2016 PHYTEC Messtechnik GmbH +- * + * Author: Wadim Egorov + */ + +-#include + #include + #include + #include +@@ -27,92 +24,6 @@ struct rk808_reg_data { + int value; + }; + +-static bool rk808_is_volatile_reg(struct device *dev, unsigned int reg) +-{ +- /* +- * Notes: +- * - Technically the ROUND_30s bit makes RTC_CTRL_REG volatile, but +- * we don't use that feature. It's better to cache. +- * - It's unlikely we care that RK808_DEVCTRL_REG is volatile since +- * bits are cleared in case when we shutoff anyway, but better safe. +- */ +- +- switch (reg) { +- case RK808_SECONDS_REG ... RK808_WEEKS_REG: +- case RK808_RTC_STATUS_REG: +- case RK808_VB_MON_REG: +- case RK808_THERMAL_REG: +- case RK808_DCDC_UV_STS_REG: +- case RK808_LDO_UV_STS_REG: +- case RK808_DCDC_PG_REG: +- case RK808_LDO_PG_REG: +- case RK808_DEVCTRL_REG: +- case RK808_INT_STS_REG1: +- case RK808_INT_STS_REG2: +- return true; +- } +- +- return false; +-} +- +-static bool rk817_is_volatile_reg(struct device *dev, unsigned int reg) +-{ +- /* +- * Notes: +- * - Technically the ROUND_30s bit makes RTC_CTRL_REG volatile, but +- * we don't use that feature. It's better to cache. +- */ +- +- switch (reg) { +- case RK817_SECONDS_REG ... RK817_WEEKS_REG: +- case RK817_RTC_STATUS_REG: +- case RK817_CODEC_DTOP_LPT_SRST: +- case RK817_GAS_GAUGE_ADC_CONFIG0 ... RK817_GAS_GAUGE_CUR_ADC_K0: +- case RK817_PMIC_CHRG_STS: +- case RK817_PMIC_CHRG_OUT: +- case RK817_PMIC_CHRG_IN: +- case RK817_INT_STS_REG0: +- case RK817_INT_STS_REG1: +- case RK817_INT_STS_REG2: +- case RK817_SYS_STS: +- return true; +- } +- +- return false; +-} +- +-static const struct regmap_config rk818_regmap_config = { +- .reg_bits = 8, +- .val_bits = 8, +- .max_register = RK818_USB_CTRL_REG, +- .cache_type = REGCACHE_RBTREE, +- .volatile_reg = rk808_is_volatile_reg, +-}; +- +-static const struct regmap_config rk805_regmap_config = { +- .reg_bits = 8, +- .val_bits = 8, +- .max_register = RK805_OFF_SOURCE_REG, +- .cache_type = REGCACHE_RBTREE, +- .volatile_reg = rk808_is_volatile_reg, +-}; +- +-static const struct regmap_config rk808_regmap_config = { +- .reg_bits = 8, +- .val_bits = 8, +- .max_register = RK808_IO_POL_REG, +- .cache_type = REGCACHE_RBTREE, +- .volatile_reg = rk808_is_volatile_reg, +-}; +- +-static const struct regmap_config rk817_regmap_config = { +- .reg_bits = 8, +- .val_bits = 8, +- .max_register = RK817_GPIO_INT_CFG, +- .cache_type = REGCACHE_NONE, +- .volatile_reg = rk817_is_volatile_reg, +-}; +- + static const struct resource rtc_resources[] = { + DEFINE_RES_IRQ(RK808_IRQ_RTC_ALARM), + }; +@@ -605,9 +516,9 @@ static int rk808_restart(struct sys_off_data *data) + return NOTIFY_DONE; + } + +-static void rk8xx_shutdown(struct i2c_client *client) ++void rk8xx_shutdown(struct device *dev) + { +- struct rk808 *rk808 = i2c_get_clientdata(client); ++ struct rk808 *rk808 = dev_get_drvdata(dev); + int ret; + + switch (rk808->variant) { +@@ -628,61 +539,31 @@ static void rk8xx_shutdown(struct i2c_client *client) + return; + } + if (ret) +- dev_warn(&client->dev, ++ dev_warn(dev, + "Cannot switch to power down function\n"); + } ++EXPORT_SYMBOL_GPL(rk8xx_shutdown); + +-static const struct of_device_id rk808_of_match[] = { +- { .compatible = "rockchip,rk805" }, +- { .compatible = "rockchip,rk808" }, +- { .compatible = "rockchip,rk809" }, +- { .compatible = "rockchip,rk817" }, +- { .compatible = "rockchip,rk818" }, +- { }, +-}; +-MODULE_DEVICE_TABLE(of, rk808_of_match); +- +-static int rk808_probe(struct i2c_client *client) ++int rk8xx_probe(struct device *dev, int variant, unsigned int irq, struct regmap *regmap) + { +- struct device_node *np = client->dev.of_node; + struct rk808 *rk808; + const struct rk808_reg_data *pre_init_reg; + const struct mfd_cell *cells; + int nr_pre_init_regs; + int nr_cells; +- int msb, lsb; +- unsigned char pmic_id_msb, pmic_id_lsb; + int ret; + int i; + +- rk808 = devm_kzalloc(&client->dev, sizeof(*rk808), GFP_KERNEL); ++ rk808 = devm_kzalloc(dev, sizeof(*rk808), GFP_KERNEL); + if (!rk808) + return -ENOMEM; +- +- if (of_device_is_compatible(np, "rockchip,rk817") || +- of_device_is_compatible(np, "rockchip,rk809")) { +- pmic_id_msb = RK817_ID_MSB; +- pmic_id_lsb = RK817_ID_LSB; +- } else { +- pmic_id_msb = RK808_ID_MSB; +- pmic_id_lsb = RK808_ID_LSB; +- } +- +- /* Read chip variant */ +- msb = i2c_smbus_read_byte_data(client, pmic_id_msb); +- if (msb < 0) +- return dev_err_probe(&client->dev, msb, "failed to read the chip id MSB\n"); +- +- lsb = i2c_smbus_read_byte_data(client, pmic_id_lsb); +- if (lsb < 0) +- return dev_err_probe(&client->dev, lsb, "failed to read the chip id LSB\n"); +- +- rk808->variant = ((msb << 8) | lsb) & RK8XX_ID_MSK; +- dev_info(&client->dev, "chip id: 0x%x\n", (unsigned int)rk808->variant); ++ rk808->dev = dev; ++ rk808->variant = variant; ++ rk808->regmap = regmap; ++ dev_set_drvdata(dev, rk808); + + switch (rk808->variant) { + case RK805_ID: +- rk808->regmap_cfg = &rk805_regmap_config; + rk808->regmap_irq_chip = &rk805_irq_chip; + pre_init_reg = rk805_pre_init_reg; + nr_pre_init_regs = ARRAY_SIZE(rk805_pre_init_reg); +@@ -690,7 +571,6 @@ static int rk808_probe(struct i2c_client *client) + nr_cells = ARRAY_SIZE(rk805s); + break; + case RK808_ID: +- rk808->regmap_cfg = &rk808_regmap_config; + rk808->regmap_irq_chip = &rk808_irq_chip; + pre_init_reg = rk808_pre_init_reg; + nr_pre_init_regs = ARRAY_SIZE(rk808_pre_init_reg); +@@ -698,7 +578,6 @@ static int rk808_probe(struct i2c_client *client) + nr_cells = ARRAY_SIZE(rk808s); + break; + case RK818_ID: +- rk808->regmap_cfg = &rk818_regmap_config; + rk808->regmap_irq_chip = &rk818_irq_chip; + pre_init_reg = rk818_pre_init_reg; + nr_pre_init_regs = ARRAY_SIZE(rk818_pre_init_reg); +@@ -707,7 +586,6 @@ static int rk808_probe(struct i2c_client *client) + break; + case RK809_ID: + case RK817_ID: +- rk808->regmap_cfg = &rk817_regmap_config; + rk808->regmap_irq_chip = &rk817_irq_chip; + pre_init_reg = rk817_pre_init_reg; + nr_pre_init_regs = ARRAY_SIZE(rk817_pre_init_reg); +@@ -715,27 +593,20 @@ static int rk808_probe(struct i2c_client *client) + nr_cells = ARRAY_SIZE(rk817s); + break; + default: +- dev_err(&client->dev, "Unsupported RK8XX ID %lu\n", +- rk808->variant); ++ dev_err(dev, "Unsupported RK8XX ID %lu\n", rk808->variant); + return -EINVAL; + } + +- rk808->dev = &client->dev; +- i2c_set_clientdata(client, rk808); +- +- rk808->regmap = devm_regmap_init_i2c(client, rk808->regmap_cfg); +- if (IS_ERR(rk808->regmap)) +- return dev_err_probe(&client->dev, PTR_ERR(rk808->regmap), +- "regmap initialization failed\n"); ++ dev_info(dev, "chip id: 0x%x\n", (unsigned int)rk808->variant); + +- if (!client->irq) +- return dev_err_probe(&client->dev, -EINVAL, "No interrupt support, no core IRQ\n"); ++ if (!irq) ++ return dev_err_probe(dev, -EINVAL, "No interrupt support, no core IRQ\n"); + +- ret = devm_regmap_add_irq_chip(&client->dev, rk808->regmap, client->irq, ++ ret = devm_regmap_add_irq_chip(dev, rk808->regmap, irq, + IRQF_ONESHOT, -1, + rk808->regmap_irq_chip, &rk808->irq_data); + if (ret) +- return dev_err_probe(&client->dev, ret, "Failed to add irq_chip\n"); ++ return dev_err_probe(dev, ret, "Failed to add irq_chip\n"); + + for (i = 0; i < nr_pre_init_regs; i++) { + ret = regmap_update_bits(rk808->regmap, +@@ -743,45 +614,46 @@ static int rk808_probe(struct i2c_client *client) + pre_init_reg[i].mask, + pre_init_reg[i].value); + if (ret) +- return dev_err_probe(&client->dev, ret, "0x%x write err\n", ++ return dev_err_probe(dev, ret, "0x%x write err\n", + pre_init_reg[i].addr); + } + +- ret = devm_mfd_add_devices(&client->dev, PLATFORM_DEVID_NONE, ++ ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE, + cells, nr_cells, NULL, 0, + regmap_irq_get_domain(rk808->irq_data)); + if (ret) +- return dev_err_probe(&client->dev, ret, "failed to add MFD devices\n"); ++ return dev_err_probe(dev, ret, "failed to add MFD devices\n"); + +- if (of_property_read_bool(np, "rockchip,system-power-controller")) { +- ret = devm_register_sys_off_handler(&client->dev, ++ if (device_property_read_bool(dev, "rockchip,system-power-controller")) { ++ ret = devm_register_sys_off_handler(dev, + SYS_OFF_MODE_POWER_OFF_PREPARE, SYS_OFF_PRIO_HIGH, + &rk808_power_off, rk808); + if (ret) +- return dev_err_probe(&client->dev, ret, ++ return dev_err_probe(dev, ret, + "failed to register poweroff handler\n"); + + switch (rk808->variant) { + case RK809_ID: + case RK817_ID: +- ret = devm_register_sys_off_handler(&client->dev, ++ ret = devm_register_sys_off_handler(dev, + SYS_OFF_MODE_RESTART, SYS_OFF_PRIO_HIGH, + &rk808_restart, rk808); + if (ret) +- dev_warn(&client->dev, "failed to register rst handler, %d\n", ret); ++ dev_warn(dev, "failed to register rst handler, %d\n", ret); + break; + default: +- dev_dbg(&client->dev, "pmic controlled board reset not supported\n"); ++ dev_dbg(dev, "pmic controlled board reset not supported\n"); + break; + } + } + + return 0; + } ++EXPORT_SYMBOL_GPL(rk8xx_probe); + +-static int __maybe_unused rk8xx_suspend(struct device *dev) ++int rk8xx_suspend(struct device *dev) + { +- struct rk808 *rk808 = i2c_get_clientdata(to_i2c_client(dev)); ++ struct rk808 *rk808 = dev_get_drvdata(dev); + int ret = 0; + + switch (rk808->variant) { +@@ -804,10 +676,11 @@ static int __maybe_unused rk8xx_suspend(struct device *dev) + + return ret; + } ++EXPORT_SYMBOL_GPL(rk8xx_suspend); + +-static int __maybe_unused rk8xx_resume(struct device *dev) ++int rk8xx_resume(struct device *dev) + { +- struct rk808 *rk808 = i2c_get_clientdata(to_i2c_client(dev)); ++ struct rk808 *rk808 = dev_get_drvdata(dev); + int ret = 0; + + switch (rk808->variant) { +@@ -824,22 +697,10 @@ static int __maybe_unused rk8xx_resume(struct device *dev) + + return ret; + } +-static SIMPLE_DEV_PM_OPS(rk8xx_pm_ops, rk8xx_suspend, rk8xx_resume); +- +-static struct i2c_driver rk808_i2c_driver = { +- .driver = { +- .name = "rk808", +- .of_match_table = rk808_of_match, +- .pm = &rk8xx_pm_ops, +- }, +- .probe_new = rk808_probe, +- .shutdown = rk8xx_shutdown, +-}; +- +-module_i2c_driver(rk808_i2c_driver); ++EXPORT_SYMBOL_GPL(rk8xx_resume); + + MODULE_LICENSE("GPL"); + MODULE_AUTHOR("Chris Zhong "); + MODULE_AUTHOR("Zhang Qing "); + MODULE_AUTHOR("Wadim Egorov "); +-MODULE_DESCRIPTION("RK808/RK818 PMIC driver"); ++MODULE_DESCRIPTION("RK8xx PMIC core"); +diff --git a/drivers/mfd/rk8xx-i2c.c b/drivers/mfd/rk8xx-i2c.c +new file mode 100644 +index 000000000000..6d121b589fec +--- /dev/null ++++ b/drivers/mfd/rk8xx-i2c.c +@@ -0,0 +1,200 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * Rockchip RK808/RK818 Core (I2C) driver ++ * ++ * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd ++ * Copyright (C) 2016 PHYTEC Messtechnik GmbH ++ * ++ * Author: Chris Zhong ++ * Author: Zhang Qing ++ * Author: Wadim Egorov ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++static bool rk808_is_volatile_reg(struct device *dev, unsigned int reg) ++{ ++ /* ++ * Notes: ++ * - Technically the ROUND_30s bit makes RTC_CTRL_REG volatile, but ++ * we don't use that feature. It's better to cache. ++ * - It's unlikely we care that RK808_DEVCTRL_REG is volatile since ++ * bits are cleared in case when we shutoff anyway, but better safe. ++ */ ++ ++ switch (reg) { ++ case RK808_SECONDS_REG ... RK808_WEEKS_REG: ++ case RK808_RTC_STATUS_REG: ++ case RK808_VB_MON_REG: ++ case RK808_THERMAL_REG: ++ case RK808_DCDC_UV_STS_REG: ++ case RK808_LDO_UV_STS_REG: ++ case RK808_DCDC_PG_REG: ++ case RK808_LDO_PG_REG: ++ case RK808_DEVCTRL_REG: ++ case RK808_INT_STS_REG1: ++ case RK808_INT_STS_REG2: ++ return true; ++ } ++ ++ return false; ++} ++ ++static bool rk817_is_volatile_reg(struct device *dev, unsigned int reg) ++{ ++ /* ++ * Notes: ++ * - Technically the ROUND_30s bit makes RTC_CTRL_REG volatile, but ++ * we don't use that feature. It's better to cache. ++ */ ++ ++ switch (reg) { ++ case RK817_SECONDS_REG ... RK817_WEEKS_REG: ++ case RK817_RTC_STATUS_REG: ++ case RK817_CODEC_DTOP_LPT_SRST: ++ case RK817_GAS_GAUGE_ADC_CONFIG0 ... RK817_GAS_GAUGE_CUR_ADC_K0: ++ case RK817_PMIC_CHRG_STS: ++ case RK817_PMIC_CHRG_OUT: ++ case RK817_PMIC_CHRG_IN: ++ case RK817_INT_STS_REG0: ++ case RK817_INT_STS_REG1: ++ case RK817_INT_STS_REG2: ++ case RK817_SYS_STS: ++ return true; ++ } ++ ++ return false; ++} ++ ++ ++static const struct regmap_config rk818_regmap_config = { ++ .reg_bits = 8, ++ .val_bits = 8, ++ .max_register = RK818_USB_CTRL_REG, ++ .cache_type = REGCACHE_RBTREE, ++ .volatile_reg = rk808_is_volatile_reg, ++}; ++ ++static const struct regmap_config rk805_regmap_config = { ++ .reg_bits = 8, ++ .val_bits = 8, ++ .max_register = RK805_OFF_SOURCE_REG, ++ .cache_type = REGCACHE_RBTREE, ++ .volatile_reg = rk808_is_volatile_reg, ++}; ++ ++static const struct regmap_config rk808_regmap_config = { ++ .reg_bits = 8, ++ .val_bits = 8, ++ .max_register = RK808_IO_POL_REG, ++ .cache_type = REGCACHE_RBTREE, ++ .volatile_reg = rk808_is_volatile_reg, ++}; ++ ++static const struct regmap_config rk817_regmap_config = { ++ .reg_bits = 8, ++ .val_bits = 8, ++ .max_register = RK817_GPIO_INT_CFG, ++ .cache_type = REGCACHE_NONE, ++ .volatile_reg = rk817_is_volatile_reg, ++}; ++ ++static int rk8xx_i2c_get_variant(struct i2c_client *client) ++{ ++ u8 pmic_id_msb, pmic_id_lsb; ++ int msb, lsb; ++ ++ if (of_device_is_compatible(client->dev.of_node, "rockchip,rk817") || ++ of_device_is_compatible(client->dev.of_node, "rockchip,rk809")) { ++ pmic_id_msb = RK817_ID_MSB; ++ pmic_id_lsb = RK817_ID_LSB; ++ } else { ++ pmic_id_msb = RK808_ID_MSB; ++ pmic_id_lsb = RK808_ID_LSB; ++ } ++ ++ /* Read chip variant */ ++ msb = i2c_smbus_read_byte_data(client, pmic_id_msb); ++ if (msb < 0) ++ return dev_err_probe(&client->dev, msb, "failed to read the chip id MSB\n"); ++ ++ lsb = i2c_smbus_read_byte_data(client, pmic_id_lsb); ++ if (lsb < 0) ++ return dev_err_probe(&client->dev, lsb, "failed to read the chip id LSB\n"); ++ ++ return ((msb << 8) | lsb) & RK8XX_ID_MSK; ++} ++ ++static int rk8xx_i2c_probe(struct i2c_client *client) ++{ ++ const struct regmap_config *regmap_cfg; ++ struct regmap *regmap; ++ int variant; ++ ++ variant = rk8xx_i2c_get_variant(client); ++ if (variant < 0) ++ return variant; ++ ++ switch (variant) { ++ case RK805_ID: ++ regmap_cfg = &rk805_regmap_config; ++ break; ++ case RK808_ID: ++ regmap_cfg = &rk808_regmap_config; ++ break; ++ case RK818_ID: ++ regmap_cfg = &rk818_regmap_config; ++ break; ++ case RK809_ID: ++ case RK817_ID: ++ regmap_cfg = &rk817_regmap_config; ++ break; ++ default: ++ return dev_err_probe(&client->dev, -EINVAL, "Unsupported RK8XX ID %x\n", variant); ++ } ++ ++ regmap = devm_regmap_init_i2c(client, regmap_cfg); ++ if (IS_ERR(regmap)) ++ return dev_err_probe(&client->dev, PTR_ERR(regmap), ++ "regmap initialization failed\n"); ++ ++ return rk8xx_probe(&client->dev, variant, client->irq, regmap); ++} ++ ++static void rk8xx_i2c_shutdown(struct i2c_client *client) ++{ ++ rk8xx_shutdown(&client->dev); ++} ++ ++static SIMPLE_DEV_PM_OPS(rk8xx_i2c_pm_ops, rk8xx_suspend, rk8xx_resume); ++ ++static const struct of_device_id rk8xx_i2c_of_match[] = { ++ { .compatible = "rockchip,rk805" }, ++ { .compatible = "rockchip,rk808" }, ++ { .compatible = "rockchip,rk809" }, ++ { .compatible = "rockchip,rk817" }, ++ { .compatible = "rockchip,rk818" }, ++ { }, ++}; ++MODULE_DEVICE_TABLE(of, rk8xx_i2c_of_match); ++ ++static struct i2c_driver rk8xx_i2c_driver = { ++ .driver = { ++ .name = "rk8xx-i2c", ++ .of_match_table = rk8xx_i2c_of_match, ++ .pm = &rk8xx_i2c_pm_ops, ++ }, ++ .probe_new = rk8xx_i2c_probe, ++ .shutdown = rk8xx_i2c_shutdown, ++}; ++module_i2c_driver(rk8xx_i2c_driver); ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Chris Zhong "); ++MODULE_AUTHOR("Zhang Qing "); ++MODULE_AUTHOR("Wadim Egorov "); ++MODULE_DESCRIPTION("RK8xx I2C PMIC driver"); +diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig +index 5787c579dcf6..77ff9a641aeb 100644 +--- a/drivers/pinctrl/Kconfig ++++ b/drivers/pinctrl/Kconfig +@@ -407,7 +407,7 @@ config PINCTRL_PISTACHIO + + config PINCTRL_RK805 + tristate "Pinctrl and GPIO driver for RK805 PMIC" +- depends on MFD_RK808 ++ depends on MFD_RK8XX + select GPIOLIB + select PINMUX + select GENERIC_PINCONF +diff --git a/drivers/power/supply/Kconfig b/drivers/power/supply/Kconfig +index c78be9f322e6..4a5e8e1d1237 100644 +--- a/drivers/power/supply/Kconfig ++++ b/drivers/power/supply/Kconfig +@@ -706,7 +706,7 @@ config CHARGER_BQ256XX + + config CHARGER_RK817 + tristate "Rockchip RK817 PMIC Battery Charger" +- depends on MFD_RK808 ++ depends on MFD_RK8XX + help + Say Y to include support for Rockchip RK817 Battery Charger. + +diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig +index e5f3613c15fa..f2881fe3e0a7 100644 +--- a/drivers/regulator/Kconfig ++++ b/drivers/regulator/Kconfig +@@ -1056,7 +1056,7 @@ config REGULATOR_RC5T583 + + config REGULATOR_RK808 + tristate "Rockchip RK805/RK808/RK809/RK817/RK818 Power regulators" +- depends on MFD_RK808 ++ depends on MFD_RK8XX + help + Select this option to enable the power regulator of ROCKCHIP + PMIC RK805,RK809&RK817,RK808 and RK818. +diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig +index 753872408615..ffca9a8bb878 100644 +--- a/drivers/rtc/Kconfig ++++ b/drivers/rtc/Kconfig +@@ -395,7 +395,7 @@ config RTC_DRV_NCT3018Y + + config RTC_DRV_RK808 + tristate "Rockchip RK805/RK808/RK809/RK817/RK818 RTC" +- depends on MFD_RK808 ++ depends on MFD_RK8XX + help + If you say yes here you will get support for the + RTC of RK805, RK809 and RK817, RK808 and RK818 PMIC. +diff --git a/include/linux/mfd/rk808.h b/include/linux/mfd/rk808.h +index a89ddd9ba68e..4183427a80fe 100644 +--- a/include/linux/mfd/rk808.h ++++ b/include/linux/mfd/rk808.h +@@ -794,4 +794,10 @@ struct rk808 { + const struct regmap_config *regmap_cfg; + const struct regmap_irq_chip *regmap_irq_chip; + }; ++ ++void rk8xx_shutdown(struct device *dev); ++int rk8xx_probe(struct device *dev, int variant, unsigned int irq, struct regmap *regmap); ++int rk8xx_suspend(struct device *dev); ++int rk8xx_resume(struct device *dev); ++ + #endif /* __LINUX_REGULATOR_RK808_H */ +diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig +index 8020097d4e4c..0c4c5cbaa809 100644 +--- a/sound/soc/codecs/Kconfig ++++ b/sound/soc/codecs/Kconfig +@@ -1313,7 +1313,7 @@ config SND_SOC_RK3328 + + config SND_SOC_RK817 + tristate "Rockchip RK817 audio CODEC" +- depends on MFD_RK808 || COMPILE_TEST ++ depends on MFD_RK8XX || COMPILE_TEST + + config SND_SOC_RL6231 + tristate +-- +2.41.0 + + +From e2c1d7f2ee6ecbeb73c90bdf3f9db7180638b2dc Mon Sep 17 00:00:00 2001 +From: Sebastian Reichel +Date: Tue, 24 Jan 2023 14:25:32 +0100 +Subject: [PATCH 06/17] mfd: rk8xx-i2c: use device_get_match_data + +Simplify the device identification logic by supplying the relevant +information via of_match_data. This also removes the dev_info() +printing the chip version, since that's supplied by the match data +now. + +Due to lack of hardware this change is compile-tested only. + +Acked-for-MFD-by: Lee Jones +Tested-by: Diederik de Haas # Rock64, Quartz64 Model A + B +Tested-by: Vincent Legoll # Pine64 QuartzPro64 +Signed-off-by: Sebastian Reichel +--- + drivers/mfd/rk8xx-core.c | 2 - + drivers/mfd/rk8xx-i2c.c | 89 +++++++++++++++++----------------------- + 2 files changed, 37 insertions(+), 54 deletions(-) + +diff --git a/drivers/mfd/rk8xx-core.c b/drivers/mfd/rk8xx-core.c +index 5c0a5acef34c..ddf2052c5190 100644 +--- a/drivers/mfd/rk8xx-core.c ++++ b/drivers/mfd/rk8xx-core.c +@@ -597,8 +597,6 @@ int rk8xx_probe(struct device *dev, int variant, unsigned int irq, struct regmap + return -EINVAL; + } + +- dev_info(dev, "chip id: 0x%x\n", (unsigned int)rk808->variant); +- + if (!irq) + return dev_err_probe(dev, -EINVAL, "No interrupt support, no core IRQ\n"); + +diff --git a/drivers/mfd/rk8xx-i2c.c b/drivers/mfd/rk8xx-i2c.c +index 6d121b589fec..2822bfa8a04a 100644 +--- a/drivers/mfd/rk8xx-i2c.c ++++ b/drivers/mfd/rk8xx-i2c.c +@@ -16,6 +16,11 @@ + #include + #include + ++struct rk8xx_i2c_platform_data { ++ const struct regmap_config *regmap_cfg; ++ int variant; ++}; ++ + static bool rk808_is_volatile_reg(struct device *dev, unsigned int reg) + { + /* +@@ -103,66 +108,46 @@ static const struct regmap_config rk817_regmap_config = { + .volatile_reg = rk817_is_volatile_reg, + }; + +-static int rk8xx_i2c_get_variant(struct i2c_client *client) +-{ +- u8 pmic_id_msb, pmic_id_lsb; +- int msb, lsb; +- +- if (of_device_is_compatible(client->dev.of_node, "rockchip,rk817") || +- of_device_is_compatible(client->dev.of_node, "rockchip,rk809")) { +- pmic_id_msb = RK817_ID_MSB; +- pmic_id_lsb = RK817_ID_LSB; +- } else { +- pmic_id_msb = RK808_ID_MSB; +- pmic_id_lsb = RK808_ID_LSB; +- } ++static const struct rk8xx_i2c_platform_data rk805_data = { ++ .regmap_cfg = &rk805_regmap_config, ++ .variant = RK805_ID, ++}; ++ ++static const struct rk8xx_i2c_platform_data rk808_data = { ++ .regmap_cfg = &rk808_regmap_config, ++ .variant = RK808_ID, ++}; + +- /* Read chip variant */ +- msb = i2c_smbus_read_byte_data(client, pmic_id_msb); +- if (msb < 0) +- return dev_err_probe(&client->dev, msb, "failed to read the chip id MSB\n"); ++static const struct rk8xx_i2c_platform_data rk809_data = { ++ .regmap_cfg = &rk817_regmap_config, ++ .variant = RK809_ID, ++}; + +- lsb = i2c_smbus_read_byte_data(client, pmic_id_lsb); +- if (lsb < 0) +- return dev_err_probe(&client->dev, lsb, "failed to read the chip id LSB\n"); ++static const struct rk8xx_i2c_platform_data rk817_data = { ++ .regmap_cfg = &rk817_regmap_config, ++ .variant = RK817_ID, ++}; + +- return ((msb << 8) | lsb) & RK8XX_ID_MSK; +-} ++static const struct rk8xx_i2c_platform_data rk818_data = { ++ .regmap_cfg = &rk818_regmap_config, ++ .variant = RK818_ID, ++}; + + static int rk8xx_i2c_probe(struct i2c_client *client) + { +- const struct regmap_config *regmap_cfg; ++ const struct rk8xx_i2c_platform_data *data; + struct regmap *regmap; +- int variant; + +- variant = rk8xx_i2c_get_variant(client); +- if (variant < 0) +- return variant; +- +- switch (variant) { +- case RK805_ID: +- regmap_cfg = &rk805_regmap_config; +- break; +- case RK808_ID: +- regmap_cfg = &rk808_regmap_config; +- break; +- case RK818_ID: +- regmap_cfg = &rk818_regmap_config; +- break; +- case RK809_ID: +- case RK817_ID: +- regmap_cfg = &rk817_regmap_config; +- break; +- default: +- return dev_err_probe(&client->dev, -EINVAL, "Unsupported RK8XX ID %x\n", variant); +- } ++ data = device_get_match_data(&client->dev); ++ if (!data) ++ return -ENODEV; + +- regmap = devm_regmap_init_i2c(client, regmap_cfg); ++ regmap = devm_regmap_init_i2c(client, data->regmap_cfg); + if (IS_ERR(regmap)) + return dev_err_probe(&client->dev, PTR_ERR(regmap), + "regmap initialization failed\n"); + +- return rk8xx_probe(&client->dev, variant, client->irq, regmap); ++ return rk8xx_probe(&client->dev, data->variant, client->irq, regmap); + } + + static void rk8xx_i2c_shutdown(struct i2c_client *client) +@@ -173,11 +158,11 @@ static void rk8xx_i2c_shutdown(struct i2c_client *client) + static SIMPLE_DEV_PM_OPS(rk8xx_i2c_pm_ops, rk8xx_suspend, rk8xx_resume); + + static const struct of_device_id rk8xx_i2c_of_match[] = { +- { .compatible = "rockchip,rk805" }, +- { .compatible = "rockchip,rk808" }, +- { .compatible = "rockchip,rk809" }, +- { .compatible = "rockchip,rk817" }, +- { .compatible = "rockchip,rk818" }, ++ { .compatible = "rockchip,rk805", .data = &rk805_data }, ++ { .compatible = "rockchip,rk808", .data = &rk808_data }, ++ { .compatible = "rockchip,rk809", .data = &rk809_data }, ++ { .compatible = "rockchip,rk817", .data = &rk817_data }, ++ { .compatible = "rockchip,rk818", .data = &rk818_data }, + { }, + }; + MODULE_DEVICE_TABLE(of, rk8xx_i2c_of_match); +-- +2.41.0 + + +From e11f727558b8979ff2ec7a5619e4e005bdee13f6 Mon Sep 17 00:00:00 2001 +From: Sebastian Reichel +Date: Fri, 19 Aug 2022 18:19:43 +0200 +Subject: [PATCH 07/17] dt-bindings: mfd: add rk806 binding + +Add DT binding document for Rockchip's RK806 PMIC. + +Reviewed-by: Rob Herring +Signed-off-by: Sebastian Reichel +--- + .../bindings/mfd/rockchip,rk806.yaml | 406 ++++++++++++++++++ + 1 file changed, 406 insertions(+) + create mode 100644 Documentation/devicetree/bindings/mfd/rockchip,rk806.yaml + +diff --git a/Documentation/devicetree/bindings/mfd/rockchip,rk806.yaml b/Documentation/devicetree/bindings/mfd/rockchip,rk806.yaml +new file mode 100644 +index 000000000000..cf2500f2e9a0 +--- /dev/null ++++ b/Documentation/devicetree/bindings/mfd/rockchip,rk806.yaml +@@ -0,0 +1,406 @@ ++# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause ++%YAML 1.2 ++--- ++$id: http://devicetree.org/schemas/mfd/rockchip,rk806.yaml# ++$schema: http://devicetree.org/meta-schemas/core.yaml# ++ ++title: RK806 Power Management Integrated Circuit ++ ++maintainers: ++ - Sebastian Reichel ++ ++description: ++ Rockchip RK806 series PMIC. This device consists of an spi or ++ i2c controlled MFD that includes multiple switchable regulators. ++ ++properties: ++ compatible: ++ enum: ++ - rockchip,rk806 ++ ++ reg: ++ maxItems: 1 ++ ++ interrupts: ++ maxItems: 1 ++ ++ gpio-controller: true ++ ++ '#gpio-cells': ++ const: 2 ++ ++ vcc1-supply: ++ description: ++ The input supply for dcdc-reg1. ++ ++ vcc2-supply: ++ description: ++ The input supply for dcdc-reg2. ++ ++ vcc3-supply: ++ description: ++ The input supply for dcdc-reg3. ++ ++ vcc4-supply: ++ description: ++ The input supply for dcdc-reg4. ++ ++ vcc5-supply: ++ description: ++ The input supply for dcdc-reg5. ++ ++ vcc6-supply: ++ description: ++ The input supply for dcdc-reg6. ++ ++ vcc7-supply: ++ description: ++ The input supply for dcdc-reg7. ++ ++ vcc8-supply: ++ description: ++ The input supply for dcdc-reg8. ++ ++ vcc9-supply: ++ description: ++ The input supply for dcdc-reg9. ++ ++ vcc10-supply: ++ description: ++ The input supply for dcdc-reg10. ++ ++ vcc11-supply: ++ description: ++ The input supply for pldo-reg1, pldo-reg2 and pldo-reg3. ++ ++ vcc12-supply: ++ description: ++ The input supply for pldo-reg4 and pldo-reg5. ++ ++ vcc13-supply: ++ description: ++ The input supply for nldo-reg1, nldo-reg2 and nldo-reg3. ++ ++ vcc14-supply: ++ description: ++ The input supply for nldo-reg4 and nldo-reg5. ++ ++ vcca-supply: ++ description: ++ The input supply for pldo-reg6. ++ ++ regulators: ++ type: object ++ additionalProperties: false ++ patternProperties: ++ "^(dcdc-reg([1-9]|10)|pldo-reg[1-6]|nldo-reg[1-5])$": ++ type: object ++ $ref: /schemas/regulator/regulator.yaml# ++ unevaluatedProperties: false ++ ++patternProperties: ++ '-pins$': ++ type: object ++ additionalProperties: false ++ $ref: /schemas/pinctrl/pinmux-node.yaml ++ ++ properties: ++ function: ++ enum: [pin_fun0, pin_fun1, pin_fun2, pin_fun3, pin_fun4, pin_fun5] ++ ++ pins: ++ $ref: /schemas/types.yaml#/definitions/string ++ enum: [gpio_pwrctrl1, gpio_pwrctrl2, gpio_pwrctrl3] ++ ++allOf: ++ - $ref: /schemas/spi/spi-peripheral-props.yaml ++ ++required: ++ - compatible ++ - reg ++ - interrupts ++ ++unevaluatedProperties: false ++ ++examples: ++ - | ++ #include ++ #include ++ #include ++ spi { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ pmic@0 { ++ compatible = "rockchip,rk806"; ++ reg = <0x0>; ++ ++ interrupts = <7 IRQ_TYPE_LEVEL_LOW>; ++ ++ vcc1-supply = <&vcc5v0_sys>; ++ vcc2-supply = <&vcc5v0_sys>; ++ vcc3-supply = <&vcc5v0_sys>; ++ vcc4-supply = <&vcc5v0_sys>; ++ vcc5-supply = <&vcc5v0_sys>; ++ vcc6-supply = <&vcc5v0_sys>; ++ vcc7-supply = <&vcc5v0_sys>; ++ vcc8-supply = <&vcc5v0_sys>; ++ vcc9-supply = <&vcc5v0_sys>; ++ vcc10-supply = <&vcc5v0_sys>; ++ vcc11-supply = <&vcc_2v0_pldo_s3>; ++ vcc12-supply = <&vcc5v0_sys>; ++ vcc13-supply = <&vcc5v0_sys>; ++ vcc14-supply = <&vcc_1v1_nldo_s3>; ++ vcca-supply = <&vcc5v0_sys>; ++ ++ regulators { ++ vdd_gpu_s0: dcdc-reg1 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <550000>; ++ regulator-max-microvolt = <950000>; ++ regulator-ramp-delay = <12500>; ++ regulator-name = "vdd_gpu_s0"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vdd_npu_s0: dcdc-reg2 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <550000>; ++ regulator-max-microvolt = <950000>; ++ regulator-ramp-delay = <12500>; ++ regulator-name = "vdd_npu_s0"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vdd_log_s0: dcdc-reg3 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <750000>; ++ regulator-max-microvolt = <750000>; ++ regulator-ramp-delay = <12500>; ++ regulator-name = "vdd_log_s0"; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <750000>; ++ }; ++ }; ++ ++ vdd_vdenc_s0: dcdc-reg4 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <550000>; ++ regulator-max-microvolt = <950000>; ++ regulator-ramp-delay = <12500>; ++ regulator-name = "vdd_vdenc_s0"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vdd_gpu_mem_s0: dcdc-reg5 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <675000>; ++ regulator-max-microvolt = <950000>; ++ regulator-ramp-delay = <12500>; ++ regulator-name = "vdd_gpu_mem_s0"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vdd_npu_mem_s0: dcdc-reg6 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <675000>; ++ regulator-max-microvolt = <950000>; ++ regulator-ramp-delay = <12500>; ++ regulator-name = "vdd_npu_mem_s0"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcc_2v0_pldo_s3: dcdc-reg7 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <2000000>; ++ regulator-max-microvolt = <2000000>; ++ regulator-ramp-delay = <12500>; ++ regulator-name = "vdd_2v0_pldo_s3"; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <2000000>; ++ }; ++ }; ++ ++ vdd_vdenc_mem_s0: dcdc-reg8 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <675000>; ++ regulator-max-microvolt = <950000>; ++ regulator-ramp-delay = <12500>; ++ regulator-name = "vdd_vdenc_mem_s0"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vdd2_ddr_s3: dcdc-reg9 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-name = "vdd2_ddr_s3"; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ }; ++ }; ++ ++ vcc_1v1_nldo_s3: dcdc-reg10 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1100000>; ++ regulator-max-microvolt = <1100000>; ++ regulator-ramp-delay = <12500>; ++ regulator-name = "vcc_1v1_nldo_s3"; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1100000>; ++ }; ++ }; ++ ++ avcc_1v8_s0: pldo-reg1 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-ramp-delay = <12500>; ++ regulator-name = "avcc_1v8_s0"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vdd1_1v8_ddr_s3: pldo-reg2 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-ramp-delay = <12500>; ++ regulator-name = "vdd1_1v8_ddr_s3"; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ vcc_1v8_s3: pldo-reg3 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-ramp-delay = <12500>; ++ regulator-name = "vcc_1v8_s3"; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ vcc_3v3_s0: pldo-reg4 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-ramp-delay = <12500>; ++ regulator-name = "vcc_3v3_s0"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vccio_sd_s0: pldo-reg5 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-ramp-delay = <12500>; ++ regulator-name = "vccio_sd_s0"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ master_pldo6_s3: pldo-reg6 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-name = "master_pldo6_s3"; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ vdd_0v75_s3: nldo-reg1 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <750000>; ++ regulator-max-microvolt = <750000>; ++ regulator-ramp-delay = <12500>; ++ regulator-name = "vdd_0v75_s3"; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <750000>; ++ }; ++ }; ++ ++ vdd2l_0v9_ddr_s3: nldo-reg2 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <900000>; ++ regulator-max-microvolt = <900000>; ++ regulator-name = "vdd2l_0v9_ddr_s3"; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <900000>; ++ }; ++ }; ++ ++ master_nldo3: nldo-reg3 { ++ regulator-name = "master_nldo3"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ avdd_0v75_s0: nldo-reg4 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <750000>; ++ regulator-max-microvolt = <750000>; ++ regulator-name = "avdd_0v75_s0"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vdd_0v85_s0: nldo-reg5 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <850000>; ++ regulator-max-microvolt = <850000>; ++ regulator-name = "vdd_0v85_s0"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ }; ++ }; ++ }; +-- +2.41.0 + + +From ece3cf25607136eeba646a67b98407f62e3ca2b6 Mon Sep 17 00:00:00 2001 +From: Sebastian Reichel +Date: Wed, 29 Jun 2022 18:35:59 +0200 +Subject: [PATCH 08/17] mfd: rk8xx: add rk806 support + +Add support for SPI connected rk806, which is used by the RK3588 +evaluation boards. The PMIC is advertised to support I2C and SPI, +but the evaluation boards all use SPI. Thus only SPI support is +added here. + +Acked-for-MFD-by: Lee Jones +Tested-by: Diederik de Haas # Rock64, Quartz64 Model A + B +Tested-by: Vincent Legoll # Pine64 QuartzPro64 +Signed-off-by: Sebastian Reichel +--- + drivers/mfd/Kconfig | 14 ++ + drivers/mfd/Makefile | 1 + + drivers/mfd/rk8xx-core.c | 69 ++++++- + drivers/mfd/rk8xx-spi.c | 124 ++++++++++++ + include/linux/mfd/rk808.h | 409 ++++++++++++++++++++++++++++++++++++++ + 5 files changed, 614 insertions(+), 3 deletions(-) + create mode 100644 drivers/mfd/rk8xx-spi.c + +diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig +index de53e6c701fd..d4879cb4e1f6 100644 +--- a/drivers/mfd/Kconfig ++++ b/drivers/mfd/Kconfig +@@ -1201,6 +1201,20 @@ config MFD_RK8XX_I2C + through I2C interface. The device supports multiple sub-devices + including interrupts, RTC, LDO & DCDC regulators, and onkey. + ++config MFD_RK8XX_SPI ++ tristate "Rockchip RK806 Power Management Chip" ++ depends on SPI && OF ++ select MFD_CORE ++ select REGMAP_SPI ++ select REGMAP_IRQ ++ select MFD_RK8XX ++ help ++ If you say yes here you get support for the RK806 Power Management ++ chip. ++ This driver provides common support for accessing the device ++ through an SPI interface. The device supports multiple sub-devices ++ including interrupts, LDO & DCDC regulators, and power on-key. ++ + config MFD_RN5T618 + tristate "Ricoh RN5T567/618 PMIC" + depends on I2C +diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile +index ba373193e999..4e666ef5b7fc 100644 +--- a/drivers/mfd/Makefile ++++ b/drivers/mfd/Makefile +@@ -216,6 +216,7 @@ obj-$(CONFIG_MFD_NTXEC) += ntxec.o + obj-$(CONFIG_MFD_RC5T583) += rc5t583.o rc5t583-irq.o + obj-$(CONFIG_MFD_RK8XX) += rk8xx-core.o + obj-$(CONFIG_MFD_RK8XX_I2C) += rk8xx-i2c.o ++obj-$(CONFIG_MFD_RK8XX_SPI) += rk8xx-spi.o + obj-$(CONFIG_MFD_RN5T618) += rn5t618.o + obj-$(CONFIG_MFD_SEC_CORE) += sec-core.o sec-irq.o + obj-$(CONFIG_MFD_SYSCON) += syscon.o +diff --git a/drivers/mfd/rk8xx-core.c b/drivers/mfd/rk8xx-core.c +index ddf2052c5190..e8fc9e2ab1d0 100644 +--- a/drivers/mfd/rk8xx-core.c ++++ b/drivers/mfd/rk8xx-core.c +@@ -37,6 +37,11 @@ static const struct resource rk805_key_resources[] = { + DEFINE_RES_IRQ(RK805_IRQ_PWRON_FALL), + }; + ++static struct resource rk806_pwrkey_resources[] = { ++ DEFINE_RES_IRQ(RK806_IRQ_PWRON_FALL), ++ DEFINE_RES_IRQ(RK806_IRQ_PWRON_RISE), ++}; ++ + static const struct resource rk817_pwrkey_resources[] = { + DEFINE_RES_IRQ(RK817_IRQ_PWRON_RISE), + DEFINE_RES_IRQ(RK817_IRQ_PWRON_FALL), +@@ -64,6 +69,17 @@ static const struct mfd_cell rk805s[] = { + }, + }; + ++static const struct mfd_cell rk806s[] = { ++ { .name = "rk805-pinctrl", .id = PLATFORM_DEVID_AUTO, }, ++ { .name = "rk808-regulator", .id = PLATFORM_DEVID_AUTO, }, ++ { ++ .name = "rk805-pwrkey", ++ .resources = rk806_pwrkey_resources, ++ .num_resources = ARRAY_SIZE(rk806_pwrkey_resources), ++ .id = PLATFORM_DEVID_AUTO, ++ }, ++}; ++ + static const struct mfd_cell rk808s[] = { + { .name = "rk808-clkout", .id = PLATFORM_DEVID_NONE, }, + { .name = "rk808-regulator", .id = PLATFORM_DEVID_NONE, }, +@@ -123,6 +139,12 @@ static const struct rk808_reg_data rk805_pre_init_reg[] = { + {RK805_THERMAL_REG, TEMP_HOTDIE_MSK, TEMP115C}, + }; + ++static const struct rk808_reg_data rk806_pre_init_reg[] = { ++ { RK806_GPIO_INT_CONFIG, RK806_INT_POL_MSK, RK806_INT_POL_L }, ++ { RK806_SYS_CFG3, RK806_SLAVE_RESTART_FUN_MSK, RK806_SLAVE_RESTART_FUN_EN }, ++ { RK806_SYS_OPTION, RK806_SYS_ENB2_2M_MSK, RK806_SYS_ENB2_2M_EN }, ++}; ++ + static const struct rk808_reg_data rk808_pre_init_reg[] = { + { RK808_BUCK3_CONFIG_REG, BUCK_ILMIN_MASK, BUCK_ILMIN_150MA }, + { RK808_BUCK4_CONFIG_REG, BUCK_ILMIN_MASK, BUCK_ILMIN_200MA }, +@@ -273,6 +295,27 @@ static const struct regmap_irq rk805_irqs[] = { + }, + }; + ++static const struct regmap_irq rk806_irqs[] = { ++ /* INT_STS0 IRQs */ ++ REGMAP_IRQ_REG(RK806_IRQ_PWRON_FALL, 0, RK806_INT_STS_PWRON_FALL), ++ REGMAP_IRQ_REG(RK806_IRQ_PWRON_RISE, 0, RK806_INT_STS_PWRON_RISE), ++ REGMAP_IRQ_REG(RK806_IRQ_PWRON, 0, RK806_INT_STS_PWRON), ++ REGMAP_IRQ_REG(RK806_IRQ_PWRON_LP, 0, RK806_INT_STS_PWRON_LP), ++ REGMAP_IRQ_REG(RK806_IRQ_HOTDIE, 0, RK806_INT_STS_HOTDIE), ++ REGMAP_IRQ_REG(RK806_IRQ_VDC_RISE, 0, RK806_INT_STS_VDC_RISE), ++ REGMAP_IRQ_REG(RK806_IRQ_VDC_FALL, 0, RK806_INT_STS_VDC_FALL), ++ REGMAP_IRQ_REG(RK806_IRQ_VB_LO, 0, RK806_INT_STS_VB_LO), ++ /* INT_STS1 IRQs */ ++ REGMAP_IRQ_REG(RK806_IRQ_REV0, 1, RK806_INT_STS_REV0), ++ REGMAP_IRQ_REG(RK806_IRQ_REV1, 1, RK806_INT_STS_REV1), ++ REGMAP_IRQ_REG(RK806_IRQ_REV2, 1, RK806_INT_STS_REV2), ++ REGMAP_IRQ_REG(RK806_IRQ_CRC_ERROR, 1, RK806_INT_STS_CRC_ERROR), ++ REGMAP_IRQ_REG(RK806_IRQ_SLP3_GPIO, 1, RK806_INT_STS_SLP3_GPIO), ++ REGMAP_IRQ_REG(RK806_IRQ_SLP2_GPIO, 1, RK806_INT_STS_SLP2_GPIO), ++ REGMAP_IRQ_REG(RK806_IRQ_SLP1_GPIO, 1, RK806_INT_STS_SLP1_GPIO), ++ REGMAP_IRQ_REG(RK806_IRQ_WDT, 1, RK806_INT_STS_WDT), ++}; ++ + static const struct regmap_irq rk808_irqs[] = { + /* INT_STS */ + [RK808_IRQ_VOUT_LO] = { +@@ -423,6 +466,18 @@ static struct regmap_irq_chip rk805_irq_chip = { + .init_ack_masked = true, + }; + ++static struct regmap_irq_chip rk806_irq_chip = { ++ .name = "rk806", ++ .irqs = rk806_irqs, ++ .num_irqs = ARRAY_SIZE(rk806_irqs), ++ .num_regs = 2, ++ .irq_reg_stride = 2, ++ .mask_base = RK806_INT_MSK0, ++ .status_base = RK806_INT_STS0, ++ .ack_base = RK806_INT_STS0, ++ .init_ack_masked = true, ++}; ++ + static const struct regmap_irq_chip rk808_irq_chip = { + .name = "rk808", + .irqs = rk808_irqs, +@@ -549,6 +604,7 @@ int rk8xx_probe(struct device *dev, int variant, unsigned int irq, struct regmap + struct rk808 *rk808; + const struct rk808_reg_data *pre_init_reg; + const struct mfd_cell *cells; ++ int dual_support = 0; + int nr_pre_init_regs; + int nr_cells; + int ret; +@@ -570,6 +626,14 @@ int rk8xx_probe(struct device *dev, int variant, unsigned int irq, struct regmap + cells = rk805s; + nr_cells = ARRAY_SIZE(rk805s); + break; ++ case RK806_ID: ++ rk808->regmap_irq_chip = &rk806_irq_chip; ++ pre_init_reg = rk806_pre_init_reg; ++ nr_pre_init_regs = ARRAY_SIZE(rk806_pre_init_reg); ++ cells = rk806s; ++ nr_cells = ARRAY_SIZE(rk806s); ++ dual_support = IRQF_SHARED; ++ break; + case RK808_ID: + rk808->regmap_irq_chip = &rk808_irq_chip; + pre_init_reg = rk808_pre_init_reg; +@@ -601,7 +665,7 @@ int rk8xx_probe(struct device *dev, int variant, unsigned int irq, struct regmap + return dev_err_probe(dev, -EINVAL, "No interrupt support, no core IRQ\n"); + + ret = devm_regmap_add_irq_chip(dev, rk808->regmap, irq, +- IRQF_ONESHOT, -1, ++ IRQF_ONESHOT | dual_support, -1, + rk808->regmap_irq_chip, &rk808->irq_data); + if (ret) + return dev_err_probe(dev, ret, "Failed to add irq_chip\n"); +@@ -616,8 +680,7 @@ int rk8xx_probe(struct device *dev, int variant, unsigned int irq, struct regmap + pre_init_reg[i].addr); + } + +- ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE, +- cells, nr_cells, NULL, 0, ++ ret = devm_mfd_add_devices(dev, 0, cells, nr_cells, NULL, 0, + regmap_irq_get_domain(rk808->irq_data)); + if (ret) + return dev_err_probe(dev, ret, "failed to add MFD devices\n"); +diff --git a/drivers/mfd/rk8xx-spi.c b/drivers/mfd/rk8xx-spi.c +new file mode 100644 +index 000000000000..fd137f38c2c4 +--- /dev/null ++++ b/drivers/mfd/rk8xx-spi.c +@@ -0,0 +1,124 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Rockchip RK806 Core (SPI) driver ++ * ++ * Copyright (c) 2021 Rockchip Electronics Co., Ltd. ++ * Copyright (c) 2023 Collabora Ltd. ++ * ++ * Author: Xu Shengfei ++ * Author: Sebastian Reichel ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define RK806_ADDR_SIZE 2 ++#define RK806_CMD_WITH_SIZE(CMD, VALUE_BYTES) \ ++ (RK806_CMD_##CMD | RK806_CMD_CRC_DIS | (VALUE_BYTES - 1)) ++ ++static const struct regmap_range rk806_volatile_ranges[] = { ++ regmap_reg_range(RK806_POWER_EN0, RK806_POWER_EN5), ++ regmap_reg_range(RK806_DVS_START_CTRL, RK806_INT_MSK1), ++}; ++ ++static const struct regmap_access_table rk806_volatile_table = { ++ .yes_ranges = rk806_volatile_ranges, ++ .n_yes_ranges = ARRAY_SIZE(rk806_volatile_ranges), ++}; ++ ++static const struct regmap_config rk806_regmap_config_spi = { ++ .reg_bits = 16, ++ .val_bits = 8, ++ .max_register = RK806_BUCK_RSERVE_REG5, ++ .cache_type = REGCACHE_RBTREE, ++ .volatile_table = &rk806_volatile_table, ++}; ++ ++static int rk806_spi_bus_write(void *context, const void *vdata, size_t count) ++{ ++ struct device *dev = context; ++ struct spi_device *spi = to_spi_device(dev); ++ struct spi_transfer xfer[2] = { 0 }; ++ /* data and thus count includes the register address */ ++ size_t val_size = count - RK806_ADDR_SIZE; ++ char cmd; ++ ++ if (val_size < 1 || val_size > (RK806_CMD_LEN_MSK + 1)) ++ return -EINVAL; ++ ++ cmd = RK806_CMD_WITH_SIZE(WRITE, val_size); ++ ++ xfer[0].tx_buf = &cmd; ++ xfer[0].len = sizeof(cmd); ++ xfer[1].tx_buf = vdata; ++ xfer[1].len = count; ++ ++ return spi_sync_transfer(spi, xfer, ARRAY_SIZE(xfer)); ++} ++ ++static int rk806_spi_bus_read(void *context, const void *vreg, size_t reg_size, ++ void *val, size_t val_size) ++{ ++ struct device *dev = context; ++ struct spi_device *spi = to_spi_device(dev); ++ char txbuf[3] = { 0 }; ++ ++ if (reg_size != RK806_ADDR_SIZE || ++ val_size < 1 || val_size > (RK806_CMD_LEN_MSK + 1)) ++ return -EINVAL; ++ ++ /* TX buffer contains command byte followed by two address bytes */ ++ txbuf[0] = RK806_CMD_WITH_SIZE(READ, val_size); ++ memcpy(txbuf+1, vreg, reg_size); ++ ++ return spi_write_then_read(spi, txbuf, sizeof(txbuf), val, val_size); ++} ++ ++static const struct regmap_bus rk806_regmap_bus_spi = { ++ .write = rk806_spi_bus_write, ++ .read = rk806_spi_bus_read, ++ .reg_format_endian_default = REGMAP_ENDIAN_LITTLE, ++}; ++ ++static int rk8xx_spi_probe(struct spi_device *spi) ++{ ++ struct regmap *regmap; ++ ++ regmap = devm_regmap_init(&spi->dev, &rk806_regmap_bus_spi, ++ &spi->dev, &rk806_regmap_config_spi); ++ if (IS_ERR(regmap)) ++ return dev_err_probe(&spi->dev, PTR_ERR(regmap), ++ "Failed to init regmap\n"); ++ ++ return rk8xx_probe(&spi->dev, RK806_ID, spi->irq, regmap); ++} ++ ++static const struct of_device_id rk8xx_spi_of_match[] = { ++ { .compatible = "rockchip,rk806", }, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, rk8xx_spi_of_match); ++ ++static const struct spi_device_id rk8xx_spi_id_table[] = { ++ { "rk806", 0 }, ++ { } ++}; ++MODULE_DEVICE_TABLE(spi, rk8xx_spi_id_table); ++ ++static struct spi_driver rk8xx_spi_driver = { ++ .driver = { ++ .name = "rk8xx-spi", ++ .of_match_table = rk8xx_spi_of_match, ++ }, ++ .probe = rk8xx_spi_probe, ++ .id_table = rk8xx_spi_id_table, ++}; ++module_spi_driver(rk8xx_spi_driver); ++ ++MODULE_AUTHOR("Xu Shengfei "); ++MODULE_DESCRIPTION("RK8xx SPI PMIC driver"); ++MODULE_LICENSE("GPL"); +diff --git a/include/linux/mfd/rk808.h b/include/linux/mfd/rk808.h +index 4183427a80fe..78e167a92483 100644 +--- a/include/linux/mfd/rk808.h ++++ b/include/linux/mfd/rk808.h +@@ -289,6 +289,414 @@ enum rk805_reg { + #define RK805_INT_ALARM_EN (1 << 3) + #define RK805_INT_TIMER_EN (1 << 2) + ++/* RK806 */ ++#define RK806_POWER_EN0 0x0 ++#define RK806_POWER_EN1 0x1 ++#define RK806_POWER_EN2 0x2 ++#define RK806_POWER_EN3 0x3 ++#define RK806_POWER_EN4 0x4 ++#define RK806_POWER_EN5 0x5 ++#define RK806_POWER_SLP_EN0 0x6 ++#define RK806_POWER_SLP_EN1 0x7 ++#define RK806_POWER_SLP_EN2 0x8 ++#define RK806_POWER_DISCHRG_EN0 0x9 ++#define RK806_POWER_DISCHRG_EN1 0xA ++#define RK806_POWER_DISCHRG_EN2 0xB ++#define RK806_BUCK_FB_CONFIG 0xC ++#define RK806_SLP_LP_CONFIG 0xD ++#define RK806_POWER_FPWM_EN0 0xE ++#define RK806_POWER_FPWM_EN1 0xF ++#define RK806_BUCK1_CONFIG 0x10 ++#define RK806_BUCK2_CONFIG 0x11 ++#define RK806_BUCK3_CONFIG 0x12 ++#define RK806_BUCK4_CONFIG 0x13 ++#define RK806_BUCK5_CONFIG 0x14 ++#define RK806_BUCK6_CONFIG 0x15 ++#define RK806_BUCK7_CONFIG 0x16 ++#define RK806_BUCK8_CONFIG 0x17 ++#define RK806_BUCK9_CONFIG 0x18 ++#define RK806_BUCK10_CONFIG 0x19 ++#define RK806_BUCK1_ON_VSEL 0x1A ++#define RK806_BUCK2_ON_VSEL 0x1B ++#define RK806_BUCK3_ON_VSEL 0x1C ++#define RK806_BUCK4_ON_VSEL 0x1D ++#define RK806_BUCK5_ON_VSEL 0x1E ++#define RK806_BUCK6_ON_VSEL 0x1F ++#define RK806_BUCK7_ON_VSEL 0x20 ++#define RK806_BUCK8_ON_VSEL 0x21 ++#define RK806_BUCK9_ON_VSEL 0x22 ++#define RK806_BUCK10_ON_VSEL 0x23 ++#define RK806_BUCK1_SLP_VSEL 0x24 ++#define RK806_BUCK2_SLP_VSEL 0x25 ++#define RK806_BUCK3_SLP_VSEL 0x26 ++#define RK806_BUCK4_SLP_VSEL 0x27 ++#define RK806_BUCK5_SLP_VSEL 0x28 ++#define RK806_BUCK6_SLP_VSEL 0x29 ++#define RK806_BUCK7_SLP_VSEL 0x2A ++#define RK806_BUCK8_SLP_VSEL 0x2B ++#define RK806_BUCK9_SLP_VSEL 0x2D ++#define RK806_BUCK10_SLP_VSEL 0x2E ++#define RK806_BUCK_DEBUG1 0x30 ++#define RK806_BUCK_DEBUG2 0x31 ++#define RK806_BUCK_DEBUG3 0x32 ++#define RK806_BUCK_DEBUG4 0x33 ++#define RK806_BUCK_DEBUG5 0x34 ++#define RK806_BUCK_DEBUG6 0x35 ++#define RK806_BUCK_DEBUG7 0x36 ++#define RK806_BUCK_DEBUG8 0x37 ++#define RK806_BUCK_DEBUG9 0x38 ++#define RK806_BUCK_DEBUG10 0x39 ++#define RK806_BUCK_DEBUG11 0x3A ++#define RK806_BUCK_DEBUG12 0x3B ++#define RK806_BUCK_DEBUG13 0x3C ++#define RK806_BUCK_DEBUG14 0x3D ++#define RK806_BUCK_DEBUG15 0x3E ++#define RK806_BUCK_DEBUG16 0x3F ++#define RK806_BUCK_DEBUG17 0x40 ++#define RK806_BUCK_DEBUG18 0x41 ++#define RK806_NLDO_IMAX 0x42 ++#define RK806_NLDO1_ON_VSEL 0x43 ++#define RK806_NLDO2_ON_VSEL 0x44 ++#define RK806_NLDO3_ON_VSEL 0x45 ++#define RK806_NLDO4_ON_VSEL 0x46 ++#define RK806_NLDO5_ON_VSEL 0x47 ++#define RK806_NLDO1_SLP_VSEL 0x48 ++#define RK806_NLDO2_SLP_VSEL 0x49 ++#define RK806_NLDO3_SLP_VSEL 0x4A ++#define RK806_NLDO4_SLP_VSEL 0x4B ++#define RK806_NLDO5_SLP_VSEL 0x4C ++#define RK806_PLDO_IMAX 0x4D ++#define RK806_PLDO1_ON_VSEL 0x4E ++#define RK806_PLDO2_ON_VSEL 0x4F ++#define RK806_PLDO3_ON_VSEL 0x50 ++#define RK806_PLDO4_ON_VSEL 0x51 ++#define RK806_PLDO5_ON_VSEL 0x52 ++#define RK806_PLDO6_ON_VSEL 0x53 ++#define RK806_PLDO1_SLP_VSEL 0x54 ++#define RK806_PLDO2_SLP_VSEL 0x55 ++#define RK806_PLDO3_SLP_VSEL 0x56 ++#define RK806_PLDO4_SLP_VSEL 0x57 ++#define RK806_PLDO5_SLP_VSEL 0x58 ++#define RK806_PLDO6_SLP_VSEL 0x59 ++#define RK806_CHIP_NAME 0x5A ++#define RK806_CHIP_VER 0x5B ++#define RK806_OTP_VER 0x5C ++#define RK806_SYS_STS 0x5D ++#define RK806_SYS_CFG0 0x5E ++#define RK806_SYS_CFG1 0x5F ++#define RK806_SYS_OPTION 0x61 ++#define RK806_SLEEP_CONFIG0 0x62 ++#define RK806_SLEEP_CONFIG1 0x63 ++#define RK806_SLEEP_CTR_SEL0 0x64 ++#define RK806_SLEEP_CTR_SEL1 0x65 ++#define RK806_SLEEP_CTR_SEL2 0x66 ++#define RK806_SLEEP_CTR_SEL3 0x67 ++#define RK806_SLEEP_CTR_SEL4 0x68 ++#define RK806_SLEEP_CTR_SEL5 0x69 ++#define RK806_DVS_CTRL_SEL0 0x6A ++#define RK806_DVS_CTRL_SEL1 0x6B ++#define RK806_DVS_CTRL_SEL2 0x6C ++#define RK806_DVS_CTRL_SEL3 0x6D ++#define RK806_DVS_CTRL_SEL4 0x6E ++#define RK806_DVS_CTRL_SEL5 0x6F ++#define RK806_DVS_START_CTRL 0x70 ++#define RK806_SLEEP_GPIO 0x71 ++#define RK806_SYS_CFG3 0x72 ++#define RK806_ON_SOURCE 0x74 ++#define RK806_OFF_SOURCE 0x75 ++#define RK806_PWRON_KEY 0x76 ++#define RK806_INT_STS0 0x77 ++#define RK806_INT_MSK0 0x78 ++#define RK806_INT_STS1 0x79 ++#define RK806_INT_MSK1 0x7A ++#define RK806_GPIO_INT_CONFIG 0x7B ++#define RK806_DATA_REG0 0x7C ++#define RK806_DATA_REG1 0x7D ++#define RK806_DATA_REG2 0x7E ++#define RK806_DATA_REG3 0x7F ++#define RK806_DATA_REG4 0x80 ++#define RK806_DATA_REG5 0x81 ++#define RK806_DATA_REG6 0x82 ++#define RK806_DATA_REG7 0x83 ++#define RK806_DATA_REG8 0x84 ++#define RK806_DATA_REG9 0x85 ++#define RK806_DATA_REG10 0x86 ++#define RK806_DATA_REG11 0x87 ++#define RK806_DATA_REG12 0x88 ++#define RK806_DATA_REG13 0x89 ++#define RK806_DATA_REG14 0x8A ++#define RK806_DATA_REG15 0x8B ++#define RK806_TM_REG 0x8C ++#define RK806_OTP_EN_REG 0x8D ++#define RK806_FUNC_OTP_EN_REG 0x8E ++#define RK806_TEST_REG1 0x8F ++#define RK806_TEST_REG2 0x90 ++#define RK806_TEST_REG3 0x91 ++#define RK806_TEST_REG4 0x92 ++#define RK806_TEST_REG5 0x93 ++#define RK806_BUCK_VSEL_OTP_REG0 0x94 ++#define RK806_BUCK_VSEL_OTP_REG1 0x95 ++#define RK806_BUCK_VSEL_OTP_REG2 0x96 ++#define RK806_BUCK_VSEL_OTP_REG3 0x97 ++#define RK806_BUCK_VSEL_OTP_REG4 0x98 ++#define RK806_BUCK_VSEL_OTP_REG5 0x99 ++#define RK806_BUCK_VSEL_OTP_REG6 0x9A ++#define RK806_BUCK_VSEL_OTP_REG7 0x9B ++#define RK806_BUCK_VSEL_OTP_REG8 0x9C ++#define RK806_BUCK_VSEL_OTP_REG9 0x9D ++#define RK806_NLDO1_VSEL_OTP_REG0 0x9E ++#define RK806_NLDO1_VSEL_OTP_REG1 0x9F ++#define RK806_NLDO1_VSEL_OTP_REG2 0xA0 ++#define RK806_NLDO1_VSEL_OTP_REG3 0xA1 ++#define RK806_NLDO1_VSEL_OTP_REG4 0xA2 ++#define RK806_PLDO_VSEL_OTP_REG0 0xA3 ++#define RK806_PLDO_VSEL_OTP_REG1 0xA4 ++#define RK806_PLDO_VSEL_OTP_REG2 0xA5 ++#define RK806_PLDO_VSEL_OTP_REG3 0xA6 ++#define RK806_PLDO_VSEL_OTP_REG4 0xA7 ++#define RK806_PLDO_VSEL_OTP_REG5 0xA8 ++#define RK806_BUCK_EN_OTP_REG1 0xA9 ++#define RK806_NLDO_EN_OTP_REG1 0xAA ++#define RK806_PLDO_EN_OTP_REG1 0xAB ++#define RK806_BUCK_FB_RES_OTP_REG1 0xAC ++#define RK806_OTP_RESEV_REG0 0xAD ++#define RK806_OTP_RESEV_REG1 0xAE ++#define RK806_OTP_RESEV_REG2 0xAF ++#define RK806_OTP_RESEV_REG3 0xB0 ++#define RK806_OTP_RESEV_REG4 0xB1 ++#define RK806_BUCK_SEQ_REG0 0xB2 ++#define RK806_BUCK_SEQ_REG1 0xB3 ++#define RK806_BUCK_SEQ_REG2 0xB4 ++#define RK806_BUCK_SEQ_REG3 0xB5 ++#define RK806_BUCK_SEQ_REG4 0xB6 ++#define RK806_BUCK_SEQ_REG5 0xB7 ++#define RK806_BUCK_SEQ_REG6 0xB8 ++#define RK806_BUCK_SEQ_REG7 0xB9 ++#define RK806_BUCK_SEQ_REG8 0xBA ++#define RK806_BUCK_SEQ_REG9 0xBB ++#define RK806_BUCK_SEQ_REG10 0xBC ++#define RK806_BUCK_SEQ_REG11 0xBD ++#define RK806_BUCK_SEQ_REG12 0xBE ++#define RK806_BUCK_SEQ_REG13 0xBF ++#define RK806_BUCK_SEQ_REG14 0xC0 ++#define RK806_BUCK_SEQ_REG15 0xC1 ++#define RK806_BUCK_SEQ_REG16 0xC2 ++#define RK806_BUCK_SEQ_REG17 0xC3 ++#define RK806_HK_TRIM_REG1 0xC4 ++#define RK806_HK_TRIM_REG2 0xC5 ++#define RK806_BUCK_REF_TRIM_REG1 0xC6 ++#define RK806_BUCK_REF_TRIM_REG2 0xC7 ++#define RK806_BUCK_REF_TRIM_REG3 0xC8 ++#define RK806_BUCK_REF_TRIM_REG4 0xC9 ++#define RK806_BUCK_REF_TRIM_REG5 0xCA ++#define RK806_BUCK_OSC_TRIM_REG1 0xCB ++#define RK806_BUCK_OSC_TRIM_REG2 0xCC ++#define RK806_BUCK_OSC_TRIM_REG3 0xCD ++#define RK806_BUCK_OSC_TRIM_REG4 0xCE ++#define RK806_BUCK_OSC_TRIM_REG5 0xCF ++#define RK806_BUCK_TRIM_ZCDIOS_REG1 0xD0 ++#define RK806_BUCK_TRIM_ZCDIOS_REG2 0xD1 ++#define RK806_NLDO_TRIM_REG1 0xD2 ++#define RK806_NLDO_TRIM_REG2 0xD3 ++#define RK806_NLDO_TRIM_REG3 0xD4 ++#define RK806_PLDO_TRIM_REG1 0xD5 ++#define RK806_PLDO_TRIM_REG2 0xD6 ++#define RK806_PLDO_TRIM_REG3 0xD7 ++#define RK806_TRIM_ICOMP_REG1 0xD8 ++#define RK806_TRIM_ICOMP_REG2 0xD9 ++#define RK806_EFUSE_CONTROL_REGH 0xDA ++#define RK806_FUSE_PROG_REG 0xDB ++#define RK806_MAIN_FSM_STS_REG 0xDD ++#define RK806_FSM_REG 0xDE ++#define RK806_TOP_RESEV_OFFR 0xEC ++#define RK806_TOP_RESEV_POR 0xED ++#define RK806_BUCK_VRSN_REG1 0xEE ++#define RK806_BUCK_VRSN_REG2 0xEF ++#define RK806_NLDO_RLOAD_SEL_REG1 0xF0 ++#define RK806_PLDO_RLOAD_SEL_REG1 0xF1 ++#define RK806_PLDO_RLOAD_SEL_REG2 0xF2 ++#define RK806_BUCK_CMIN_MX_REG1 0xF3 ++#define RK806_BUCK_CMIN_MX_REG2 0xF4 ++#define RK806_BUCK_FREQ_SET_REG1 0xF5 ++#define RK806_BUCK_FREQ_SET_REG2 0xF6 ++#define RK806_BUCK_RS_MEABS_REG1 0xF7 ++#define RK806_BUCK_RS_MEABS_REG2 0xF8 ++#define RK806_BUCK_RS_ZDLEB_REG1 0xF9 ++#define RK806_BUCK_RS_ZDLEB_REG2 0xFA ++#define RK806_BUCK_RSERVE_REG1 0xFB ++#define RK806_BUCK_RSERVE_REG2 0xFC ++#define RK806_BUCK_RSERVE_REG3 0xFD ++#define RK806_BUCK_RSERVE_REG4 0xFE ++#define RK806_BUCK_RSERVE_REG5 0xFF ++ ++/* INT_STS Register field definitions */ ++#define RK806_INT_STS_PWRON_FALL BIT(0) ++#define RK806_INT_STS_PWRON_RISE BIT(1) ++#define RK806_INT_STS_PWRON BIT(2) ++#define RK806_INT_STS_PWRON_LP BIT(3) ++#define RK806_INT_STS_HOTDIE BIT(4) ++#define RK806_INT_STS_VDC_RISE BIT(5) ++#define RK806_INT_STS_VDC_FALL BIT(6) ++#define RK806_INT_STS_VB_LO BIT(7) ++#define RK806_INT_STS_REV0 BIT(0) ++#define RK806_INT_STS_REV1 BIT(1) ++#define RK806_INT_STS_REV2 BIT(2) ++#define RK806_INT_STS_CRC_ERROR BIT(3) ++#define RK806_INT_STS_SLP3_GPIO BIT(4) ++#define RK806_INT_STS_SLP2_GPIO BIT(5) ++#define RK806_INT_STS_SLP1_GPIO BIT(6) ++#define RK806_INT_STS_WDT BIT(7) ++ ++/* SPI command */ ++#define RK806_CMD_READ 0 ++#define RK806_CMD_WRITE BIT(7) ++#define RK806_CMD_CRC_EN BIT(6) ++#define RK806_CMD_CRC_DIS 0 ++#define RK806_CMD_LEN_MSK 0x0f ++#define RK806_REG_H 0x00 ++ ++#define VERSION_AB 0x01 ++ ++enum rk806_reg_id { ++ RK806_ID_DCDC1 = 0, ++ RK806_ID_DCDC2, ++ RK806_ID_DCDC3, ++ RK806_ID_DCDC4, ++ RK806_ID_DCDC5, ++ RK806_ID_DCDC6, ++ RK806_ID_DCDC7, ++ RK806_ID_DCDC8, ++ RK806_ID_DCDC9, ++ RK806_ID_DCDC10, ++ ++ RK806_ID_NLDO1, ++ RK806_ID_NLDO2, ++ RK806_ID_NLDO3, ++ RK806_ID_NLDO4, ++ RK806_ID_NLDO5, ++ ++ RK806_ID_PLDO1, ++ RK806_ID_PLDO2, ++ RK806_ID_PLDO3, ++ RK806_ID_PLDO4, ++ RK806_ID_PLDO5, ++ RK806_ID_PLDO6, ++ RK806_ID_END, ++}; ++ ++/* Define the RK806 IRQ numbers */ ++enum rk806_irqs { ++ /* INT_STS0 registers */ ++ RK806_IRQ_PWRON_FALL, ++ RK806_IRQ_PWRON_RISE, ++ RK806_IRQ_PWRON, ++ RK806_IRQ_PWRON_LP, ++ RK806_IRQ_HOTDIE, ++ RK806_IRQ_VDC_RISE, ++ RK806_IRQ_VDC_FALL, ++ RK806_IRQ_VB_LO, ++ ++ /* INT_STS0 registers */ ++ RK806_IRQ_REV0, ++ RK806_IRQ_REV1, ++ RK806_IRQ_REV2, ++ RK806_IRQ_CRC_ERROR, ++ RK806_IRQ_SLP3_GPIO, ++ RK806_IRQ_SLP2_GPIO, ++ RK806_IRQ_SLP1_GPIO, ++ RK806_IRQ_WDT, ++}; ++ ++/* VCC1 Low Voltage Threshold */ ++enum rk806_lv_sel { ++ VB_LO_SEL_2800, ++ VB_LO_SEL_2900, ++ VB_LO_SEL_3000, ++ VB_LO_SEL_3100, ++ VB_LO_SEL_3200, ++ VB_LO_SEL_3300, ++ VB_LO_SEL_3400, ++ VB_LO_SEL_3500, ++}; ++ ++/* System Shutdown Voltage Select */ ++enum rk806_uv_sel { ++ VB_UV_SEL_2700, ++ VB_UV_SEL_2800, ++ VB_UV_SEL_2900, ++ VB_UV_SEL_3000, ++ VB_UV_SEL_3100, ++ VB_UV_SEL_3200, ++ VB_UV_SEL_3300, ++ VB_UV_SEL_3400, ++}; ++ ++/* Pin Function */ ++enum rk806_pwrctrl_fun { ++ PWRCTRL_NULL_FUN, ++ PWRCTRL_SLP_FUN, ++ PWRCTRL_POWOFF_FUN, ++ PWRCTRL_RST_FUN, ++ PWRCTRL_DVS_FUN, ++ PWRCTRL_GPIO_FUN, ++}; ++ ++/* Pin Polarity */ ++enum rk806_pin_level { ++ POL_LOW, ++ POL_HIGH, ++}; ++ ++enum rk806_vsel_ctr_sel { ++ CTR_BY_NO_EFFECT, ++ CTR_BY_PWRCTRL1, ++ CTR_BY_PWRCTRL2, ++ CTR_BY_PWRCTRL3, ++}; ++ ++enum rk806_dvs_ctr_sel { ++ CTR_SEL_NO_EFFECT, ++ CTR_SEL_DVS_START1, ++ CTR_SEL_DVS_START2, ++ CTR_SEL_DVS_START3, ++}; ++ ++enum rk806_pin_dr_sel { ++ RK806_PIN_INPUT, ++ RK806_PIN_OUTPUT, ++}; ++ ++#define RK806_INT_POL_MSK BIT(1) ++#define RK806_INT_POL_H BIT(1) ++#define RK806_INT_POL_L 0 ++ ++#define RK806_SLAVE_RESTART_FUN_MSK BIT(1) ++#define RK806_SLAVE_RESTART_FUN_EN BIT(1) ++#define RK806_SLAVE_RESTART_FUN_OFF 0 ++ ++#define RK806_SYS_ENB2_2M_MSK BIT(1) ++#define RK806_SYS_ENB2_2M_EN BIT(1) ++#define RK806_SYS_ENB2_2M_OFF 0 ++ ++enum rk806_int_fun { ++ RK806_INT_ONLY, ++ RK806_INT_ADN_WKUP, ++}; ++ ++enum rk806_dvs_mode { ++ RK806_DVS_NOT_SUPPORT, ++ RK806_DVS_START1, ++ RK806_DVS_START2, ++ RK806_DVS_START3, ++ RK806_DVS_PWRCTRL1, ++ RK806_DVS_PWRCTRL2, ++ RK806_DVS_PWRCTRL3, ++ RK806_DVS_START_PWRCTR1, ++ RK806_DVS_START_PWRCTR2, ++ RK806_DVS_START_PWRCTR3, ++ RK806_DVS_END, ++}; ++ + /* RK808 IRQ Definitions */ + #define RK808_IRQ_VOUT_LO 0 + #define RK808_IRQ_VB_LO 1 +@@ -780,6 +1188,7 @@ enum { + + enum { + RK805_ID = 0x8050, ++ RK806_ID = 0x8060, + RK808_ID = 0x0000, + RK809_ID = 0x8090, + RK817_ID = 0x8170, +-- +2.41.0 + + +From 984d12c0aa8c7ccf9757b9dcc6e7cd76c5f368dd Mon Sep 17 00:00:00 2001 +From: Sebastian Reichel +Date: Mon, 4 Jul 2022 18:56:16 +0200 +Subject: [PATCH 09/17] pinctrl: rk805: add rk806 pinctrl support + +Add support for rk806 dvs pinctrl to the existing rk805 +driver. + +This has been implemented using shengfei Xu's rk806 +specific driver from the vendor tree as reference. + +Co-developed-by: shengfei Xu +Signed-off-by: shengfei Xu +Reviewed-by: Linus Walleij +Acked-by: Linus Walleij +Tested-by: Diederik de Haas # Rock64, Quartz64 Model A + B +Tested-by: Vincent Legoll # Pine64 QuartzPro64 +Signed-off-by: Sebastian Reichel +--- + drivers/pinctrl/pinctrl-rk805.c | 189 ++++++++++++++++++++++++++++---- + 1 file changed, 168 insertions(+), 21 deletions(-) + +diff --git a/drivers/pinctrl/pinctrl-rk805.c b/drivers/pinctrl/pinctrl-rk805.c +index 7c1f7408fb9a..2639a9ee82cd 100644 +--- a/drivers/pinctrl/pinctrl-rk805.c ++++ b/drivers/pinctrl/pinctrl-rk805.c +@@ -1,10 +1,12 @@ + // SPDX-License-Identifier: GPL-2.0-or-later + /* +- * Pinctrl driver for Rockchip RK805 PMIC ++ * Pinctrl driver for Rockchip RK805/RK806 PMIC + * + * Copyright (c) 2017, Fuzhou Rockchip Electronics Co., Ltd ++ * Copyright (c) 2021 Rockchip Electronics Co., Ltd. + * + * Author: Joseph Chen ++ * Author: Xu Shengfei + * + * Based on the pinctrl-as3722 driver + */ +@@ -44,6 +46,7 @@ struct rk805_pin_group { + + /* + * @reg: gpio setting register; ++ * @fun_reg: functions select register; + * @fun_mask: functions select mask value, when set is gpio; + * @dir_mask: input or output mask value, when set is output, otherwise input; + * @val_mask: gpio set value, when set is level high, otherwise low; +@@ -56,6 +59,7 @@ struct rk805_pin_group { + */ + struct rk805_pin_config { + u8 reg; ++ u8 fun_reg; + u8 fun_msk; + u8 dir_msk; + u8 val_msk; +@@ -80,22 +84,50 @@ enum rk805_pinmux_option { + RK805_PINMUX_GPIO, + }; + ++enum rk806_pinmux_option { ++ RK806_PINMUX_FUN0 = 0, ++ RK806_PINMUX_FUN1, ++ RK806_PINMUX_FUN2, ++ RK806_PINMUX_FUN3, ++ RK806_PINMUX_FUN4, ++ RK806_PINMUX_FUN5, ++}; ++ + enum { + RK805_GPIO0, + RK805_GPIO1, + }; + ++enum { ++ RK806_GPIO_DVS1, ++ RK806_GPIO_DVS2, ++ RK806_GPIO_DVS3 ++}; ++ + static const char *const rk805_gpio_groups[] = { + "gpio0", + "gpio1", + }; + ++static const char *const rk806_gpio_groups[] = { ++ "gpio_pwrctrl1", ++ "gpio_pwrctrl2", ++ "gpio_pwrctrl3", ++}; ++ + /* RK805: 2 output only GPIOs */ + static const struct pinctrl_pin_desc rk805_pins_desc[] = { + PINCTRL_PIN(RK805_GPIO0, "gpio0"), + PINCTRL_PIN(RK805_GPIO1, "gpio1"), + }; + ++/* RK806 */ ++static const struct pinctrl_pin_desc rk806_pins_desc[] = { ++ PINCTRL_PIN(RK806_GPIO_DVS1, "gpio_pwrctrl1"), ++ PINCTRL_PIN(RK806_GPIO_DVS2, "gpio_pwrctrl2"), ++ PINCTRL_PIN(RK806_GPIO_DVS3, "gpio_pwrctrl3"), ++}; ++ + static const struct rk805_pin_function rk805_pin_functions[] = { + { + .name = "gpio", +@@ -105,6 +137,45 @@ static const struct rk805_pin_function rk805_pin_functions[] = { + }, + }; + ++static const struct rk805_pin_function rk806_pin_functions[] = { ++ { ++ .name = "pin_fun0", ++ .groups = rk806_gpio_groups, ++ .ngroups = ARRAY_SIZE(rk806_gpio_groups), ++ .mux_option = RK806_PINMUX_FUN0, ++ }, ++ { ++ .name = "pin_fun1", ++ .groups = rk806_gpio_groups, ++ .ngroups = ARRAY_SIZE(rk806_gpio_groups), ++ .mux_option = RK806_PINMUX_FUN1, ++ }, ++ { ++ .name = "pin_fun2", ++ .groups = rk806_gpio_groups, ++ .ngroups = ARRAY_SIZE(rk806_gpio_groups), ++ .mux_option = RK806_PINMUX_FUN2, ++ }, ++ { ++ .name = "pin_fun3", ++ .groups = rk806_gpio_groups, ++ .ngroups = ARRAY_SIZE(rk806_gpio_groups), ++ .mux_option = RK806_PINMUX_FUN3, ++ }, ++ { ++ .name = "pin_fun4", ++ .groups = rk806_gpio_groups, ++ .ngroups = ARRAY_SIZE(rk806_gpio_groups), ++ .mux_option = RK806_PINMUX_FUN4, ++ }, ++ { ++ .name = "pin_fun5", ++ .groups = rk806_gpio_groups, ++ .ngroups = ARRAY_SIZE(rk806_gpio_groups), ++ .mux_option = RK806_PINMUX_FUN5, ++ }, ++}; ++ + static const struct rk805_pin_group rk805_pin_groups[] = { + { + .name = "gpio0", +@@ -118,6 +189,24 @@ static const struct rk805_pin_group rk805_pin_groups[] = { + }, + }; + ++static const struct rk805_pin_group rk806_pin_groups[] = { ++ { ++ .name = "gpio_pwrctrl1", ++ .pins = { RK806_GPIO_DVS1 }, ++ .npins = 1, ++ }, ++ { ++ .name = "gpio_pwrctrl2", ++ .pins = { RK806_GPIO_DVS2 }, ++ .npins = 1, ++ }, ++ { ++ .name = "gpio_pwrctrl3", ++ .pins = { RK806_GPIO_DVS3 }, ++ .npins = 1, ++ } ++}; ++ + #define RK805_GPIO0_VAL_MSK BIT(0) + #define RK805_GPIO1_VAL_MSK BIT(1) + +@@ -132,6 +221,40 @@ static const struct rk805_pin_config rk805_gpio_cfgs[] = { + }, + }; + ++#define RK806_PWRCTRL1_DR BIT(0) ++#define RK806_PWRCTRL2_DR BIT(1) ++#define RK806_PWRCTRL3_DR BIT(2) ++#define RK806_PWRCTRL1_DATA BIT(4) ++#define RK806_PWRCTRL2_DATA BIT(5) ++#define RK806_PWRCTRL3_DATA BIT(6) ++#define RK806_PWRCTRL1_FUN GENMASK(2, 0) ++#define RK806_PWRCTRL2_FUN GENMASK(6, 4) ++#define RK806_PWRCTRL3_FUN GENMASK(2, 0) ++ ++static struct rk805_pin_config rk806_gpio_cfgs[] = { ++ { ++ .fun_reg = RK806_SLEEP_CONFIG0, ++ .fun_msk = RK806_PWRCTRL1_FUN, ++ .reg = RK806_SLEEP_GPIO, ++ .val_msk = RK806_PWRCTRL1_DATA, ++ .dir_msk = RK806_PWRCTRL1_DR, ++ }, ++ { ++ .fun_reg = RK806_SLEEP_CONFIG0, ++ .fun_msk = RK806_PWRCTRL2_FUN, ++ .reg = RK806_SLEEP_GPIO, ++ .val_msk = RK806_PWRCTRL2_DATA, ++ .dir_msk = RK806_PWRCTRL2_DR, ++ }, ++ { ++ .fun_reg = RK806_SLEEP_CONFIG1, ++ .fun_msk = RK806_PWRCTRL3_FUN, ++ .reg = RK806_SLEEP_GPIO, ++ .val_msk = RK806_PWRCTRL3_DATA, ++ .dir_msk = RK806_PWRCTRL3_DR, ++ } ++}; ++ + /* generic gpio chip */ + static int rk805_gpio_get(struct gpio_chip *chip, unsigned int offset) + { +@@ -289,19 +412,13 @@ static int _rk805_pinctrl_set_mux(struct pinctrl_dev *pctldev, + if (!pci->pin_cfg[offset].fun_msk) + return 0; + +- if (mux == RK805_PINMUX_GPIO) { +- ret = regmap_update_bits(pci->rk808->regmap, +- pci->pin_cfg[offset].reg, +- pci->pin_cfg[offset].fun_msk, +- pci->pin_cfg[offset].fun_msk); +- if (ret) { +- dev_err(pci->dev, "set gpio%d GPIO failed\n", offset); +- return ret; +- } +- } else { +- dev_err(pci->dev, "Couldn't find function mux %d\n", mux); +- return -EINVAL; +- } ++ mux <<= ffs(pci->pin_cfg[offset].fun_msk) - 1; ++ ret = regmap_update_bits(pci->rk808->regmap, ++ pci->pin_cfg[offset].fun_reg, ++ pci->pin_cfg[offset].fun_msk, mux); ++ ++ if (ret) ++ dev_err(pci->dev, "set gpio%d func%d failed\n", offset, mux); + + return 0; + } +@@ -317,6 +434,22 @@ static int rk805_pinctrl_set_mux(struct pinctrl_dev *pctldev, + return _rk805_pinctrl_set_mux(pctldev, offset, mux); + } + ++static int rk805_pinctrl_gpio_request_enable(struct pinctrl_dev *pctldev, ++ struct pinctrl_gpio_range *range, ++ unsigned int offset) ++{ ++ struct rk805_pctrl_info *pci = pinctrl_dev_get_drvdata(pctldev); ++ ++ switch (pci->rk808->variant) { ++ case RK805_ID: ++ return _rk805_pinctrl_set_mux(pctldev, offset, RK805_PINMUX_GPIO); ++ case RK806_ID: ++ return _rk805_pinctrl_set_mux(pctldev, offset, RK806_PINMUX_FUN5); ++ } ++ ++ return -ENOTSUPP; ++} ++ + static int rk805_pmx_gpio_set_direction(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned int offset, bool input) +@@ -324,13 +457,6 @@ static int rk805_pmx_gpio_set_direction(struct pinctrl_dev *pctldev, + struct rk805_pctrl_info *pci = pinctrl_dev_get_drvdata(pctldev); + int ret; + +- /* switch to gpio function */ +- ret = _rk805_pinctrl_set_mux(pctldev, offset, RK805_PINMUX_GPIO); +- if (ret) { +- dev_err(pci->dev, "set gpio%d mux failed\n", offset); +- return ret; +- } +- + /* set direction */ + if (!pci->pin_cfg[offset].dir_msk) + return 0; +@@ -352,6 +478,7 @@ static const struct pinmux_ops rk805_pinmux_ops = { + .get_function_name = rk805_pinctrl_get_func_name, + .get_function_groups = rk805_pinctrl_get_func_groups, + .set_mux = rk805_pinctrl_set_mux, ++ .gpio_request_enable = rk805_pinctrl_gpio_request_enable, + .gpio_set_direction = rk805_pmx_gpio_set_direction, + }; + +@@ -364,6 +491,7 @@ static int rk805_pinconf_get(struct pinctrl_dev *pctldev, + + switch (param) { + case PIN_CONFIG_OUTPUT: ++ case PIN_CONFIG_INPUT_ENABLE: + arg = rk805_gpio_get(&pci->gpio_chip, pin); + break; + default: +@@ -393,6 +521,12 @@ static int rk805_pinconf_set(struct pinctrl_dev *pctldev, + rk805_gpio_set(&pci->gpio_chip, pin, arg); + rk805_pmx_gpio_set_direction(pctldev, NULL, pin, false); + break; ++ case PIN_CONFIG_INPUT_ENABLE: ++ if (pci->rk808->variant != RK805_ID && arg) { ++ rk805_pmx_gpio_set_direction(pctldev, NULL, pin, true); ++ break; ++ } ++ fallthrough; + default: + dev_err(pci->dev, "Properties not supported\n"); + return -ENOTSUPP; +@@ -448,6 +582,18 @@ static int rk805_pinctrl_probe(struct platform_device *pdev) + pci->pin_cfg = rk805_gpio_cfgs; + pci->gpio_chip.ngpio = ARRAY_SIZE(rk805_gpio_cfgs); + break; ++ case RK806_ID: ++ pci->pins = rk806_pins_desc; ++ pci->num_pins = ARRAY_SIZE(rk806_pins_desc); ++ pci->functions = rk806_pin_functions; ++ pci->num_functions = ARRAY_SIZE(rk806_pin_functions); ++ pci->groups = rk806_pin_groups; ++ pci->num_pin_groups = ARRAY_SIZE(rk806_pin_groups); ++ pci->pinctrl_desc.pins = rk806_pins_desc; ++ pci->pinctrl_desc.npins = ARRAY_SIZE(rk806_pins_desc); ++ pci->pin_cfg = rk806_gpio_cfgs; ++ pci->gpio_chip.ngpio = ARRAY_SIZE(rk806_gpio_cfgs); ++ break; + default: + dev_err(&pdev->dev, "unsupported RK805 ID %lu\n", + pci->rk808->variant); +@@ -488,5 +634,6 @@ static struct platform_driver rk805_pinctrl_driver = { + module_platform_driver(rk805_pinctrl_driver); + + MODULE_DESCRIPTION("RK805 pin control and GPIO driver"); ++MODULE_AUTHOR("Xu Shengfei "); + MODULE_AUTHOR("Joseph Chen "); + MODULE_LICENSE("GPL v2"); +-- +2.41.0 + + +From ab67c69e1f4bd6286e6aa1e6075c04777c8e5853 Mon Sep 17 00:00:00 2001 +From: Sebastian Reichel +Date: Fri, 9 Sep 2022 18:24:43 +0200 +Subject: [PATCH 10/17] regulator: expose regulator_find_closest_bigger + +Expose and document the table lookup logic used by +regulator_set_ramp_delay_regmap, so that it can be +reused for devices that cannot be configured via +regulator_set_ramp_delay_regmap. + +Tested-by: Diederik de Haas # Rock64, Quartz64 Model A + B +Tested-by: Vincent Legoll # Pine64 QuartzPro64 +Signed-off-by: Sebastian Reichel +--- + drivers/regulator/helpers.c | 22 ++++++++++++++++++---- + include/linux/regulator/driver.h | 2 ++ + 2 files changed, 20 insertions(+), 4 deletions(-) + +diff --git a/drivers/regulator/helpers.c b/drivers/regulator/helpers.c +index ad2237a95572..586f42e378ee 100644 +--- a/drivers/regulator/helpers.c ++++ b/drivers/regulator/helpers.c +@@ -902,8 +902,21 @@ bool regulator_is_equal(struct regulator *reg1, struct regulator *reg2) + } + EXPORT_SYMBOL_GPL(regulator_is_equal); + +-static int find_closest_bigger(unsigned int target, const unsigned int *table, +- unsigned int num_sel, unsigned int *sel) ++/** ++ * regulator_find_closest_bigger - helper to find offset in ramp delay table ++ * ++ * @target: targeted ramp_delay ++ * @table: table with supported ramp delays ++ * @num_sel: number of entries in the table ++ * @sel: Pointer to store table offset ++ * ++ * This is the internal helper used by regulator_set_ramp_delay_regmap to ++ * map ramp delay to register value. It should only be used directly if ++ * regulator_set_ramp_delay_regmap cannot handle a specific device setup ++ * (e.g. because the value is split over multiple registers). ++ */ ++int regulator_find_closest_bigger(unsigned int target, const unsigned int *table, ++ unsigned int num_sel, unsigned int *sel) + { + unsigned int s, tmp, max, maxsel = 0; + bool found = false; +@@ -933,6 +946,7 @@ static int find_closest_bigger(unsigned int target, const unsigned int *table, + + return 0; + } ++EXPORT_SYMBOL_GPL(regulator_find_closest_bigger); + + /** + * regulator_set_ramp_delay_regmap - set_ramp_delay() helper +@@ -951,8 +965,8 @@ int regulator_set_ramp_delay_regmap(struct regulator_dev *rdev, int ramp_delay) + if (WARN_ON(!rdev->desc->n_ramp_values || !rdev->desc->ramp_delay_table)) + return -EINVAL; + +- ret = find_closest_bigger(ramp_delay, rdev->desc->ramp_delay_table, +- rdev->desc->n_ramp_values, &sel); ++ ret = regulator_find_closest_bigger(ramp_delay, rdev->desc->ramp_delay_table, ++ rdev->desc->n_ramp_values, &sel); + + if (ret) { + dev_warn(rdev_get_dev(rdev), +diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h +index d3b4a3d4514a..c6ef7d68eb9a 100644 +--- a/include/linux/regulator/driver.h ++++ b/include/linux/regulator/driver.h +@@ -758,6 +758,8 @@ int regulator_set_current_limit_regmap(struct regulator_dev *rdev, + int min_uA, int max_uA); + int regulator_get_current_limit_regmap(struct regulator_dev *rdev); + void *regulator_get_init_drvdata(struct regulator_init_data *reg_init_data); ++int regulator_find_closest_bigger(unsigned int target, const unsigned int *table, ++ unsigned int num_sel, unsigned int *sel); + int regulator_set_ramp_delay_regmap(struct regulator_dev *rdev, int ramp_delay); + int regulator_sync_voltage_rdev(struct regulator_dev *rdev); + +-- +2.41.0 + + +From 35bb06513ceaee87f043d03cfd76a85f368703e7 Mon Sep 17 00:00:00 2001 +From: Sebastian Reichel +Date: Wed, 3 May 2023 18:38:26 +0200 +Subject: [PATCH 11/17] regulator: rk808: fix asynchronous probing + +If the probe routine fails with -EPROBE_DEFER after taking over the +OF node from its parent driver, reprobing triggers pinctrl_bind_pins() +and that will fail. Fix this by setting of_node_reused, so that the +device does not try to setup pin muxing. + +For me this always happens once the driver is marked to prefer async +probing and never happens without that flag. + +Fixes: 259b93b21a9f ("regulator: Set PROBE_PREFER_ASYNCHRONOUS for drivers that existed in 4.14") +Signed-off-by: Sebastian Reichel +--- + drivers/regulator/rk808-regulator.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/regulator/rk808-regulator.c b/drivers/regulator/rk808-regulator.c +index 3637e81654a8..80ba782d8923 100644 +--- a/drivers/regulator/rk808-regulator.c ++++ b/drivers/regulator/rk808-regulator.c +@@ -1336,6 +1336,7 @@ static int rk808_regulator_probe(struct platform_device *pdev) + + config.dev = &pdev->dev; + config.dev->of_node = pdev->dev.parent->of_node; ++ config.dev->of_node_reused = true; + config.driver_data = pdata; + config.regmap = regmap; + +-- +2.41.0 + + +From c4c269e0c5c1df5a64a738229c42a7307195be51 Mon Sep 17 00:00:00 2001 +From: Sebastian Reichel +Date: Wed, 3 May 2023 19:19:42 +0200 +Subject: [PATCH 12/17] regulator: rk808: cleanup parent device usage + +By overridering the device's of_node a bit earlier we can +get the GPIOs and any other DT properties from our own +device instead of relying on the parent device. + +Signed-off-by: Sebastian Reichel +--- + drivers/regulator/rk808-regulator.c | 13 ++++++------- + 1 file changed, 6 insertions(+), 7 deletions(-) + +diff --git a/drivers/regulator/rk808-regulator.c b/drivers/regulator/rk808-regulator.c +index 80ba782d8923..71a1ca8b917e 100644 +--- a/drivers/regulator/rk808-regulator.c ++++ b/drivers/regulator/rk808-regulator.c +@@ -1245,20 +1245,19 @@ static const struct regulator_desc rk818_reg[] = { + }; + + static int rk808_regulator_dt_parse_pdata(struct device *dev, +- struct device *client_dev, + struct regmap *map, + struct rk808_regulator_data *pdata) + { + struct device_node *np; + int tmp, ret = 0, i; + +- np = of_get_child_by_name(client_dev->of_node, "regulators"); ++ np = of_get_child_by_name(dev->of_node, "regulators"); + if (!np) + return -ENXIO; + + for (i = 0; i < ARRAY_SIZE(pdata->dvs_gpio); i++) { + pdata->dvs_gpio[i] = +- devm_gpiod_get_index_optional(client_dev, "dvs", i, ++ devm_gpiod_get_index_optional(dev, "dvs", i, + GPIOD_OUT_LOW); + if (IS_ERR(pdata->dvs_gpio[i])) { + ret = PTR_ERR(pdata->dvs_gpio[i]); +@@ -1292,6 +1291,9 @@ static int rk808_regulator_probe(struct platform_device *pdev) + struct regmap *regmap; + int ret, i, nregulators; + ++ pdev->dev.of_node = pdev->dev.parent->of_node; ++ pdev->dev.of_node_reused = true; ++ + regmap = dev_get_regmap(pdev->dev.parent, NULL); + if (!regmap) + return -ENODEV; +@@ -1300,8 +1302,7 @@ static int rk808_regulator_probe(struct platform_device *pdev) + if (!pdata) + return -ENOMEM; + +- ret = rk808_regulator_dt_parse_pdata(&pdev->dev, pdev->dev.parent, +- regmap, pdata); ++ ret = rk808_regulator_dt_parse_pdata(&pdev->dev, regmap, pdata); + if (ret < 0) + return ret; + +@@ -1335,8 +1336,6 @@ static int rk808_regulator_probe(struct platform_device *pdev) + } + + config.dev = &pdev->dev; +- config.dev->of_node = pdev->dev.parent->of_node; +- config.dev->of_node_reused = true; + config.driver_data = pdata; + config.regmap = regmap; + +-- +2.41.0 + + +From 78e05e407cf16cbe6030872f4e2f4dfb538552d7 Mon Sep 17 00:00:00 2001 +From: Sebastian Reichel +Date: Thu, 4 May 2023 16:11:48 +0200 +Subject: [PATCH 13/17] regulator: rk808: revert to synchronous probing + +The rk808 driver registers a bunch of regulator devices in a loop. +If one of the later regulators fails to register (usually because +its input supply is not yet available) everything will be unrolled +(i.e. previously registered regulators will be unregistered). With +asynchronous registration there might already be consumers, though. +We do not have the necessary infrastructure to properly unregister +the consumer device, so this scenario should be avoided. + +First checking all input supplies or disallowing usage of the regulators +until all are registered does not work, since there can be +self-references (e.g. DCDC channels providing the supply of LDOs). + +The only sensible solution I found is registering the regulator devices +asynchronously, so that we do not have to unroll. Since this is a major +rework let's revert back to synchronous probing for now to fix the issue +at hand. + +Signed-off-by: Sebastian Reichel +--- + drivers/regulator/rk808-regulator.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/regulator/rk808-regulator.c b/drivers/regulator/rk808-regulator.c +index 71a1ca8b917e..5f14d6dd4593 100644 +--- a/drivers/regulator/rk808-regulator.c ++++ b/drivers/regulator/rk808-regulator.c +@@ -1355,7 +1355,7 @@ static struct platform_driver rk808_regulator_driver = { + .probe = rk808_regulator_probe, + .driver = { + .name = "rk808-regulator", +- .probe_type = PROBE_PREFER_ASYNCHRONOUS, ++ .probe_type = PROBE_FORCE_SYNCHRONOUS, + }, + }; + +-- +2.41.0 + + +From 3cca89c12b88238f62c774a01dbe1d2d78a23193 Mon Sep 17 00:00:00 2001 +From: Sebastian Reichel +Date: Thu, 20 Oct 2022 22:08:09 +0200 +Subject: [PATCH 14/17] regulator: rk808: add rk806 support + +Add rk806 support to the existing rk808 regulator +driver. + +This has been implemented using shengfei Xu's rk806 +specific driver from the vendor tree as reference. + +Co-developed-by: shengfei Xu +Signed-off-by: shengfei Xu +Reviewed-by: Matti Vaittinen +Tested-by: Diederik de Haas # Rock64, Quartz64 Model A + B +Tested-by: Vincent Legoll # Pine64 QuartzPro64 +Signed-off-by: Sebastian Reichel +--- + drivers/regulator/rk808-regulator.c | 385 ++++++++++++++++++++++++++++ + 1 file changed, 385 insertions(+) + +diff --git a/drivers/regulator/rk808-regulator.c b/drivers/regulator/rk808-regulator.c +index 5f14d6dd4593..460525ed006c 100644 +--- a/drivers/regulator/rk808-regulator.c ++++ b/drivers/regulator/rk808-regulator.c +@@ -3,9 +3,11 @@ + * Regulator driver for Rockchip RK805/RK808/RK818 + * + * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd ++ * Copyright (c) 2021 Rockchip Electronics Co., Ltd. + * + * Author: Chris Zhong + * Author: Zhang Qing ++ * Author: Xu Shengfei + * + * Copyright (C) 2016 PHYTEC Messtechnik GmbH + * +@@ -39,6 +41,13 @@ + #define RK818_LDO3_ON_VSEL_MASK 0xf + #define RK818_BOOST_ON_VSEL_MASK 0xe0 + ++#define RK806_DCDC_SLP_REG_OFFSET 0x0A ++#define RK806_NLDO_SLP_REG_OFFSET 0x05 ++#define RK806_PLDO_SLP_REG_OFFSET 0x06 ++ ++#define RK806_BUCK_SEL_CNT 0xff ++#define RK806_LDO_SEL_CNT 0xff ++ + /* Ramp rate definitions for buck1 / buck2 only */ + #define RK808_RAMP_RATE_OFFSET 3 + #define RK808_RAMP_RATE_MASK (3 << RK808_RAMP_RATE_OFFSET) +@@ -117,6 +126,34 @@ + RK8XX_DESC_COM(_id, _match, _supply, _min, _max, _step, _vreg, \ + _vmask, _ereg, _emask, 0, 0, _etime, &rk805_reg_ops) + ++#define RK806_REGULATOR(_name, _supply_name, _id, _ops,\ ++ _n_voltages, _vr, _er, _lr, ctrl_bit,\ ++ _rr, _rm, _rt)\ ++[_id] = {\ ++ .name = _name,\ ++ .supply_name = _supply_name,\ ++ .of_match = of_match_ptr(_name),\ ++ .regulators_node = of_match_ptr("regulators"),\ ++ .id = _id,\ ++ .ops = &_ops,\ ++ .type = REGULATOR_VOLTAGE,\ ++ .n_voltages = _n_voltages,\ ++ .linear_ranges = _lr,\ ++ .n_linear_ranges = ARRAY_SIZE(_lr),\ ++ .vsel_reg = _vr,\ ++ .vsel_mask = 0xff,\ ++ .enable_reg = _er,\ ++ .enable_mask = ENABLE_MASK(ctrl_bit),\ ++ .enable_val = ENABLE_MASK(ctrl_bit),\ ++ .disable_val = DISABLE_VAL(ctrl_bit),\ ++ .of_map_mode = rk8xx_regulator_of_map_mode,\ ++ .ramp_reg = _rr,\ ++ .ramp_mask = _rm,\ ++ .ramp_delay_table = _rt, \ ++ .n_ramp_values = ARRAY_SIZE(_rt), \ ++ .owner = THIS_MODULE,\ ++ } ++ + #define RK8XX_DESC(_id, _match, _supply, _min, _max, _step, _vreg, \ + _vmask, _ereg, _emask, _etime) \ + RK8XX_DESC_COM(_id, _match, _supply, _min, _max, _step, _vreg, \ +@@ -153,6 +190,17 @@ + RKXX_DESC_SWITCH_COM(_id, _match, _supply, _ereg, _emask, \ + 0, 0, &rk808_switch_ops) + ++struct rk8xx_register_bit { ++ u8 reg; ++ u8 bit; ++}; ++ ++#define RK8XX_REG_BIT(_reg, _bit) \ ++ { \ ++ .reg = _reg, \ ++ .bit = BIT(_bit), \ ++ } ++ + struct rk808_regulator_data { + struct gpio_desc *dvs_gpio[2]; + }; +@@ -216,6 +264,133 @@ static const unsigned int rk817_buck1_4_ramp_table[] = { + 3000, 6300, 12500, 25000 + }; + ++static int rk806_set_mode_dcdc(struct regulator_dev *rdev, unsigned int mode) ++{ ++ int rid = rdev_get_id(rdev); ++ int ctr_bit, reg; ++ ++ reg = RK806_POWER_FPWM_EN0 + rid / 8; ++ ctr_bit = rid % 8; ++ ++ switch (mode) { ++ case REGULATOR_MODE_FAST: ++ return regmap_update_bits(rdev->regmap, reg, ++ PWM_MODE_MSK << ctr_bit, ++ FPWM_MODE << ctr_bit); ++ case REGULATOR_MODE_NORMAL: ++ return regmap_update_bits(rdev->regmap, reg, ++ PWM_MODE_MSK << ctr_bit, ++ AUTO_PWM_MODE << ctr_bit); ++ default: ++ dev_err(rdev_get_dev(rdev), "mode unsupported: %u\n", mode); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static unsigned int rk806_get_mode_dcdc(struct regulator_dev *rdev) ++{ ++ int rid = rdev_get_id(rdev); ++ int ctr_bit, reg; ++ unsigned int val; ++ int err; ++ ++ reg = RK806_POWER_FPWM_EN0 + rid / 8; ++ ctr_bit = rid % 8; ++ ++ err = regmap_read(rdev->regmap, reg, &val); ++ if (err) ++ return err; ++ ++ if ((val >> ctr_bit) & FPWM_MODE) ++ return REGULATOR_MODE_FAST; ++ else ++ return REGULATOR_MODE_NORMAL; ++} ++ ++static const struct rk8xx_register_bit rk806_dcdc_rate2[] = { ++ RK8XX_REG_BIT(0xEB, 0), ++ RK8XX_REG_BIT(0xEB, 1), ++ RK8XX_REG_BIT(0xEB, 2), ++ RK8XX_REG_BIT(0xEB, 3), ++ RK8XX_REG_BIT(0xEB, 4), ++ RK8XX_REG_BIT(0xEB, 5), ++ RK8XX_REG_BIT(0xEB, 6), ++ RK8XX_REG_BIT(0xEB, 7), ++ RK8XX_REG_BIT(0xEA, 0), ++ RK8XX_REG_BIT(0xEA, 1), ++}; ++ ++static const unsigned int rk806_ramp_delay_table_dcdc[] = { ++ 50000, 25000, 12500, 6250, 3125, 1560, 961, 390 ++}; ++ ++static int rk806_set_ramp_delay_dcdc(struct regulator_dev *rdev, int ramp_delay) ++{ ++ int rid = rdev_get_id(rdev); ++ int regval, ramp_value, ret; ++ ++ ret = regulator_find_closest_bigger(ramp_delay, rdev->desc->ramp_delay_table, ++ rdev->desc->n_ramp_values, &ramp_value); ++ if (ret) { ++ dev_warn(rdev_get_dev(rdev), ++ "Can't set ramp-delay %u, setting %u\n", ramp_delay, ++ rdev->desc->ramp_delay_table[ramp_value]); ++ } ++ ++ regval = ramp_value << (ffs(rdev->desc->ramp_mask) - 1); ++ ++ ret = regmap_update_bits(rdev->regmap, rdev->desc->ramp_reg, ++ rdev->desc->ramp_mask, regval); ++ if (ret) ++ return ret; ++ ++ /* ++ * The above is effectively a copy of regulator_set_ramp_delay_regmap(), ++ * but that only stores the lower 2 bits for rk806 DCDC ramp. The MSB must ++ * be stored in a separate register, so this open codes the implementation ++ * to have access to the ramp_value. ++ */ ++ ++ regval = (ramp_value >> 2) & 0x1 ? rk806_dcdc_rate2[rid].bit : 0; ++ return regmap_update_bits(rdev->regmap, rk806_dcdc_rate2[rid].reg, ++ rk806_dcdc_rate2[rid].bit, ++ regval); ++} ++ ++static const unsigned int rk806_ramp_delay_table_ldo[] = { ++ 100000, 50000, 25000, 12500, 6280, 3120, 1900, 780 ++}; ++ ++static int rk806_set_suspend_voltage_range(struct regulator_dev *rdev, int reg_offset, int uv) ++{ ++ int sel = regulator_map_voltage_linear_range(rdev, uv, uv); ++ unsigned int reg; ++ ++ if (sel < 0) ++ return -EINVAL; ++ ++ reg = rdev->desc->vsel_reg + reg_offset; ++ ++ return regmap_update_bits(rdev->regmap, reg, rdev->desc->vsel_mask, sel); ++} ++ ++static int rk806_set_suspend_voltage_range_dcdc(struct regulator_dev *rdev, int uv) ++{ ++ return rk806_set_suspend_voltage_range(rdev, RK806_DCDC_SLP_REG_OFFSET, uv); ++} ++ ++static int rk806_set_suspend_voltage_range_nldo(struct regulator_dev *rdev, int uv) ++{ ++ return rk806_set_suspend_voltage_range(rdev, RK806_NLDO_SLP_REG_OFFSET, uv); ++} ++ ++static int rk806_set_suspend_voltage_range_pldo(struct regulator_dev *rdev, int uv) ++{ ++ return rk806_set_suspend_voltage_range(rdev, RK806_PLDO_SLP_REG_OFFSET, uv); ++} ++ + static int rk808_buck1_2_get_voltage_sel_regmap(struct regulator_dev *rdev) + { + struct rk808_regulator_data *pdata = rdev_get_drvdata(rdev); +@@ -393,6 +568,47 @@ static int rk805_set_suspend_disable(struct regulator_dev *rdev) + 0); + } + ++static const struct rk8xx_register_bit rk806_suspend_bits[] = { ++ RK8XX_REG_BIT(RK806_POWER_SLP_EN0, 0), ++ RK8XX_REG_BIT(RK806_POWER_SLP_EN0, 1), ++ RK8XX_REG_BIT(RK806_POWER_SLP_EN0, 2), ++ RK8XX_REG_BIT(RK806_POWER_SLP_EN0, 3), ++ RK8XX_REG_BIT(RK806_POWER_SLP_EN0, 4), ++ RK8XX_REG_BIT(RK806_POWER_SLP_EN0, 5), ++ RK8XX_REG_BIT(RK806_POWER_SLP_EN0, 6), ++ RK8XX_REG_BIT(RK806_POWER_SLP_EN0, 7), ++ RK8XX_REG_BIT(RK806_POWER_SLP_EN1, 6), ++ RK8XX_REG_BIT(RK806_POWER_SLP_EN1, 7), ++ RK8XX_REG_BIT(RK806_POWER_SLP_EN1, 0), ++ RK8XX_REG_BIT(RK806_POWER_SLP_EN1, 1), ++ RK8XX_REG_BIT(RK806_POWER_SLP_EN1, 2), ++ RK8XX_REG_BIT(RK806_POWER_SLP_EN1, 3), ++ RK8XX_REG_BIT(RK806_POWER_SLP_EN1, 4), ++ RK8XX_REG_BIT(RK806_POWER_SLP_EN2, 1), ++ RK8XX_REG_BIT(RK806_POWER_SLP_EN2, 2), ++ RK8XX_REG_BIT(RK806_POWER_SLP_EN2, 3), ++ RK8XX_REG_BIT(RK806_POWER_SLP_EN2, 4), ++ RK8XX_REG_BIT(RK806_POWER_SLP_EN2, 5), ++ RK8XX_REG_BIT(RK806_POWER_SLP_EN2, 0), ++}; ++ ++static int rk806_set_suspend_enable(struct regulator_dev *rdev) ++{ ++ int rid = rdev_get_id(rdev); ++ ++ return regmap_update_bits(rdev->regmap, rk806_suspend_bits[rid].reg, ++ rk806_suspend_bits[rid].bit, ++ rk806_suspend_bits[rid].bit); ++} ++ ++static int rk806_set_suspend_disable(struct regulator_dev *rdev) ++{ ++ int rid = rdev_get_id(rdev); ++ ++ return regmap_update_bits(rdev->regmap, rk806_suspend_bits[rid].reg, ++ rk806_suspend_bits[rid].bit, 0); ++} ++ + static int rk808_set_suspend_enable(struct regulator_dev *rdev) + { + unsigned int reg; +@@ -561,6 +777,64 @@ static const struct regulator_ops rk805_switch_ops = { + .set_suspend_disable = rk805_set_suspend_disable, + }; + ++static const struct regulator_ops rk806_ops_dcdc = { ++ .list_voltage = regulator_list_voltage_linear_range, ++ .map_voltage = regulator_map_voltage_linear_range, ++ .get_voltage_sel = regulator_get_voltage_sel_regmap, ++ .set_voltage_sel = regulator_set_voltage_sel_regmap, ++ .set_voltage_time_sel = regulator_set_voltage_time_sel, ++ .set_mode = rk806_set_mode_dcdc, ++ .get_mode = rk806_get_mode_dcdc, ++ ++ .enable = regulator_enable_regmap, ++ .disable = regulator_disable_regmap, ++ .is_enabled = rk8xx_is_enabled_wmsk_regmap, ++ ++ .set_suspend_mode = rk806_set_mode_dcdc, ++ .set_ramp_delay = rk806_set_ramp_delay_dcdc, ++ ++ .set_suspend_voltage = rk806_set_suspend_voltage_range_dcdc, ++ .set_suspend_enable = rk806_set_suspend_enable, ++ .set_suspend_disable = rk806_set_suspend_disable, ++}; ++ ++static const struct regulator_ops rk806_ops_nldo = { ++ .list_voltage = regulator_list_voltage_linear_range, ++ .map_voltage = regulator_map_voltage_linear_range, ++ .get_voltage_sel = regulator_get_voltage_sel_regmap, ++ .set_voltage_sel = regulator_set_voltage_sel_regmap, ++ .set_voltage_time_sel = regulator_set_voltage_time_sel, ++ ++ .enable = regulator_enable_regmap, ++ .disable = regulator_disable_regmap, ++ .is_enabled = regulator_is_enabled_regmap, ++ ++ .set_ramp_delay = regulator_set_ramp_delay_regmap, ++ ++ .set_suspend_voltage = rk806_set_suspend_voltage_range_nldo, ++ .set_suspend_enable = rk806_set_suspend_enable, ++ .set_suspend_disable = rk806_set_suspend_disable, ++}; ++ ++static const struct regulator_ops rk806_ops_pldo = { ++ .list_voltage = regulator_list_voltage_linear_range, ++ .map_voltage = regulator_map_voltage_linear_range, ++ ++ .get_voltage_sel = regulator_get_voltage_sel_regmap, ++ .set_voltage_sel = regulator_set_voltage_sel_regmap, ++ .set_voltage_time_sel = regulator_set_voltage_time_sel, ++ ++ .enable = regulator_enable_regmap, ++ .disable = regulator_disable_regmap, ++ .is_enabled = regulator_is_enabled_regmap, ++ ++ .set_ramp_delay = regulator_set_ramp_delay_regmap, ++ ++ .set_suspend_voltage = rk806_set_suspend_voltage_range_pldo, ++ .set_suspend_enable = rk806_set_suspend_enable, ++ .set_suspend_disable = rk806_set_suspend_disable, ++}; ++ + static const struct regulator_ops rk808_buck1_2_ops = { + .list_voltage = regulator_list_voltage_linear, + .map_voltage = regulator_map_voltage_linear, +@@ -743,6 +1017,112 @@ static const struct regulator_desc rk805_reg[] = { + BIT(2), 400), + }; + ++static const struct linear_range rk806_buck_voltage_ranges[] = { ++ REGULATOR_LINEAR_RANGE(500000, 0, 160, 6250), /* 500mV ~ 1500mV */ ++ REGULATOR_LINEAR_RANGE(1500000, 161, 237, 25000), /* 1500mV ~ 3400mV */ ++ REGULATOR_LINEAR_RANGE(3400000, 238, 255, 0), ++}; ++ ++static const struct linear_range rk806_ldo_voltage_ranges[] = { ++ REGULATOR_LINEAR_RANGE(500000, 0, 232, 12500), /* 500mV ~ 3400mV */ ++ REGULATOR_LINEAR_RANGE(3400000, 233, 255, 0), /* 500mV ~ 3400mV */ ++}; ++ ++static const struct regulator_desc rk806_reg[] = { ++ RK806_REGULATOR("dcdc-reg1", "vcc1", RK806_ID_DCDC1, rk806_ops_dcdc, ++ RK806_BUCK_SEL_CNT, RK806_BUCK1_ON_VSEL, ++ RK806_POWER_EN0, rk806_buck_voltage_ranges, 0, ++ RK806_BUCK1_CONFIG, 0xc0, rk806_ramp_delay_table_dcdc), ++ RK806_REGULATOR("dcdc-reg2", "vcc2", RK806_ID_DCDC2, rk806_ops_dcdc, ++ RK806_BUCK_SEL_CNT, RK806_BUCK2_ON_VSEL, ++ RK806_POWER_EN0, rk806_buck_voltage_ranges, 1, ++ RK806_BUCK2_CONFIG, 0xc0, rk806_ramp_delay_table_dcdc), ++ RK806_REGULATOR("dcdc-reg3", "vcc3", RK806_ID_DCDC3, rk806_ops_dcdc, ++ RK806_BUCK_SEL_CNT, RK806_BUCK3_ON_VSEL, ++ RK806_POWER_EN0, rk806_buck_voltage_ranges, 2, ++ RK806_BUCK3_CONFIG, 0xc0, rk806_ramp_delay_table_dcdc), ++ RK806_REGULATOR("dcdc-reg4", "vcc4", RK806_ID_DCDC4, rk806_ops_dcdc, ++ RK806_BUCK_SEL_CNT, RK806_BUCK4_ON_VSEL, ++ RK806_POWER_EN0, rk806_buck_voltage_ranges, 3, ++ RK806_BUCK4_CONFIG, 0xc0, rk806_ramp_delay_table_dcdc), ++ ++ RK806_REGULATOR("dcdc-reg5", "vcc5", RK806_ID_DCDC5, rk806_ops_dcdc, ++ RK806_BUCK_SEL_CNT, RK806_BUCK5_ON_VSEL, ++ RK806_POWER_EN1, rk806_buck_voltage_ranges, 0, ++ RK806_BUCK5_CONFIG, 0xc0, rk806_ramp_delay_table_dcdc), ++ RK806_REGULATOR("dcdc-reg6", "vcc6", RK806_ID_DCDC6, rk806_ops_dcdc, ++ RK806_BUCK_SEL_CNT, RK806_BUCK6_ON_VSEL, ++ RK806_POWER_EN1, rk806_buck_voltage_ranges, 1, ++ RK806_BUCK6_CONFIG, 0xc0, rk806_ramp_delay_table_dcdc), ++ RK806_REGULATOR("dcdc-reg7", "vcc7", RK806_ID_DCDC7, rk806_ops_dcdc, ++ RK806_BUCK_SEL_CNT, RK806_BUCK7_ON_VSEL, ++ RK806_POWER_EN1, rk806_buck_voltage_ranges, 2, ++ RK806_BUCK7_CONFIG, 0xc0, rk806_ramp_delay_table_dcdc), ++ RK806_REGULATOR("dcdc-reg8", "vcc8", RK806_ID_DCDC8, rk806_ops_dcdc, ++ RK806_BUCK_SEL_CNT, RK806_BUCK8_ON_VSEL, ++ RK806_POWER_EN1, rk806_buck_voltage_ranges, 3, ++ RK806_BUCK8_CONFIG, 0xc0, rk806_ramp_delay_table_dcdc), ++ ++ RK806_REGULATOR("dcdc-reg9", "vcc9", RK806_ID_DCDC9, rk806_ops_dcdc, ++ RK806_BUCK_SEL_CNT, RK806_BUCK9_ON_VSEL, ++ RK806_POWER_EN2, rk806_buck_voltage_ranges, 0, ++ RK806_BUCK9_CONFIG, 0xc0, rk806_ramp_delay_table_dcdc), ++ RK806_REGULATOR("dcdc-reg10", "vcc10", RK806_ID_DCDC10, rk806_ops_dcdc, ++ RK806_BUCK_SEL_CNT, RK806_BUCK10_ON_VSEL, ++ RK806_POWER_EN2, rk806_buck_voltage_ranges, 1, ++ RK806_BUCK10_CONFIG, 0xc0, rk806_ramp_delay_table_dcdc), ++ ++ RK806_REGULATOR("nldo-reg1", "vcc13", RK806_ID_NLDO1, rk806_ops_nldo, ++ RK806_LDO_SEL_CNT, RK806_NLDO1_ON_VSEL, ++ RK806_POWER_EN3, rk806_ldo_voltage_ranges, 0, ++ 0xEA, 0x38, rk806_ramp_delay_table_ldo), ++ RK806_REGULATOR("nldo-reg2", "vcc13", RK806_ID_NLDO2, rk806_ops_nldo, ++ RK806_LDO_SEL_CNT, RK806_NLDO2_ON_VSEL, ++ RK806_POWER_EN3, rk806_ldo_voltage_ranges, 1, ++ 0xEA, 0x38, rk806_ramp_delay_table_ldo), ++ RK806_REGULATOR("nldo-reg3", "vcc13", RK806_ID_NLDO3, rk806_ops_nldo, ++ RK806_LDO_SEL_CNT, RK806_NLDO3_ON_VSEL, ++ RK806_POWER_EN3, rk806_ldo_voltage_ranges, 2, ++ 0xEA, 0x38, rk806_ramp_delay_table_ldo), ++ RK806_REGULATOR("nldo-reg4", "vcc14", RK806_ID_NLDO4, rk806_ops_nldo, ++ RK806_LDO_SEL_CNT, RK806_NLDO4_ON_VSEL, ++ RK806_POWER_EN3, rk806_ldo_voltage_ranges, 3, ++ 0xEA, 0x38, rk806_ramp_delay_table_ldo), ++ ++ RK806_REGULATOR("nldo-reg5", "vcc14", RK806_ID_NLDO5, rk806_ops_nldo, ++ RK806_LDO_SEL_CNT, RK806_NLDO5_ON_VSEL, ++ RK806_POWER_EN5, rk806_ldo_voltage_ranges, 2, ++ 0xEA, 0x38, rk806_ramp_delay_table_ldo), ++ ++ RK806_REGULATOR("pldo-reg1", "vcc11", RK806_ID_PLDO1, rk806_ops_pldo, ++ RK806_LDO_SEL_CNT, RK806_PLDO1_ON_VSEL, ++ RK806_POWER_EN4, rk806_ldo_voltage_ranges, 1, ++ 0xEA, 0x38, rk806_ramp_delay_table_ldo), ++ RK806_REGULATOR("pldo-reg2", "vcc11", RK806_ID_PLDO2, rk806_ops_pldo, ++ RK806_LDO_SEL_CNT, RK806_PLDO2_ON_VSEL, ++ RK806_POWER_EN4, rk806_ldo_voltage_ranges, 2, ++ 0xEA, 0x38, rk806_ramp_delay_table_ldo), ++ RK806_REGULATOR("pldo-reg3", "vcc11", RK806_ID_PLDO3, rk806_ops_pldo, ++ RK806_LDO_SEL_CNT, RK806_PLDO3_ON_VSEL, ++ RK806_POWER_EN4, rk806_ldo_voltage_ranges, 3, ++ 0xEA, 0x38, rk806_ramp_delay_table_ldo), ++ ++ RK806_REGULATOR("pldo-reg4", "vcc12", RK806_ID_PLDO4, rk806_ops_pldo, ++ RK806_LDO_SEL_CNT, RK806_PLDO4_ON_VSEL, ++ RK806_POWER_EN5, rk806_ldo_voltage_ranges, 0, ++ 0xEA, 0x38, rk806_ramp_delay_table_ldo), ++ RK806_REGULATOR("pldo-reg5", "vcc12", RK806_ID_PLDO5, rk806_ops_pldo, ++ RK806_LDO_SEL_CNT, RK806_PLDO5_ON_VSEL, ++ RK806_POWER_EN5, rk806_ldo_voltage_ranges, 1, ++ 0xEA, 0x38, rk806_ramp_delay_table_ldo), ++ ++ RK806_REGULATOR("pldo-reg6", "vcca", RK806_ID_PLDO6, rk806_ops_pldo, ++ RK806_LDO_SEL_CNT, RK806_PLDO6_ON_VSEL, ++ RK806_POWER_EN4, rk806_ldo_voltage_ranges, 0, ++ 0xEA, 0x38, rk806_ramp_delay_table_ldo), ++}; ++ ++ + static const struct regulator_desc rk808_reg[] = { + { + .name = "DCDC_REG1", +@@ -1313,6 +1693,10 @@ static int rk808_regulator_probe(struct platform_device *pdev) + regulators = rk805_reg; + nregulators = RK805_NUM_REGULATORS; + break; ++ case RK806_ID: ++ regulators = rk806_reg; ++ nregulators = ARRAY_SIZE(rk806_reg); ++ break; + case RK808_ID: + regulators = rk808_reg; + nregulators = RK808_NUM_REGULATORS; +@@ -1366,5 +1750,6 @@ MODULE_AUTHOR("Tony xie "); + MODULE_AUTHOR("Chris Zhong "); + MODULE_AUTHOR("Zhang Qing "); + MODULE_AUTHOR("Wadim Egorov "); ++MODULE_AUTHOR("Xu Shengfei "); + MODULE_LICENSE("GPL"); + MODULE_ALIAS("platform:rk808-regulator"); +-- +2.41.0 + + +From 909f24f813ef921635e5d38df6ce022bc7309ba7 Mon Sep 17 00:00:00 2001 +From: Sebastian Reichel +Date: Tue, 7 Feb 2023 18:02:45 +0100 +Subject: [PATCH 15/17] arm64: defconfig: update RK8XX MFD config + +Update the defconfig for the new RK8XX MFD config name, +which got split to add SPI support. + +Reported-by: Marek Szyprowski +Fixes: c20e8c5b1203a ("mfd: rk808: Split into core and i2c") +Signed-off-by: Sebastian Reichel +--- + arch/arm64/configs/defconfig | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig +index a24609e14d50..cd69c9ced7da 100644 +--- a/arch/arm64/configs/defconfig ++++ b/arch/arm64/configs/defconfig +@@ -688,7 +688,8 @@ CONFIG_MFD_MAX77620=y + CONFIG_MFD_MT6360=y + CONFIG_MFD_MT6397=y + CONFIG_MFD_SPMI_PMIC=y +-CONFIG_MFD_RK808=y ++CONFIG_MFD_RK8XX_I2C=y ++CONFIG_MFD_RK8XX_SPI=y + CONFIG_MFD_SEC_CORE=y + CONFIG_MFD_SL28CPLD=y + CONFIG_MFD_TPS65219=y +-- +2.41.0 + + +From 9ee85a98073699bf3a995905be8b78c776b70272 Mon Sep 17 00:00:00 2001 +From: Sebastian Reichel +Date: Thu, 18 May 2023 05:11:10 +0200 +Subject: [PATCH 16/17] ARM: multi_v7_defconfig: update MFD_RK808 name + +MFD_RK808 got split into an I2C and SPI part named MFD_RK8XX_I2C and +MFD_RK8XX_SPI. Since there are no known ARMv7 boards using the SPI +connected RK8XX chips (which are new), it is enough to just enable +the I2C option. + +Reported-by: Marek Szyprowski +Fixes: c20e8c5b1203a ("mfd: rk808: Split into core and i2c") +Signed-off-by: Sebastian Reichel +--- + arch/arm/configs/multi_v7_defconfig | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig +index 871fffe92187..f0800f806b5f 100644 +--- a/arch/arm/configs/multi_v7_defconfig ++++ b/arch/arm/configs/multi_v7_defconfig +@@ -596,7 +596,7 @@ CONFIG_MFD_CPCAP=y + CONFIG_MFD_PM8XXX=y + CONFIG_MFD_QCOM_RPM=y + CONFIG_MFD_SPMI_PMIC=y +-CONFIG_MFD_RK808=y ++CONFIG_MFD_RK8XX_I2C=y + CONFIG_MFD_RN5T618=y + CONFIG_MFD_SEC_CORE=y + CONFIG_MFD_STMPE=y +-- +2.41.0 + + +From e55f6558692a546162fe740f8590719fa26ad7c9 Mon Sep 17 00:00:00 2001 +From: Sebastian Reichel +Date: Tue, 12 Jul 2022 15:17:33 +0200 +Subject: [PATCH 17/17] arm64: dts: rockchip: rk3588-evb1: add PMIC + +This adds PMIC support for the RK3588 EVB. + +Co-developed-by: shengfei Xu +Signed-off-by: shengfei Xu +Signed-off-by: Sebastian Reichel +--- + .../boot/dts/rockchip/rk3588-evb1-v10.dts | 637 ++++++++++++++++++ + 1 file changed, 637 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts b/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts +index b91af0204dbe..4b2d857ee219 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts +@@ -49,6 +49,38 @@ vcc5v0_sys: vcc5v0-sys-regulator { + }; + }; + ++&cpu_b0 { ++ cpu-supply = <&vdd_cpu_big0_s0>; ++}; ++ ++&cpu_b1 { ++ cpu-supply = <&vdd_cpu_big0_s0>; ++}; ++ ++&cpu_b2 { ++ cpu-supply = <&vdd_cpu_big1_s0>; ++}; ++ ++&cpu_b3 { ++ cpu-supply = <&vdd_cpu_big1_s0>; ++}; ++ ++&cpu_l0 { ++ cpu-supply = <&vdd_cpu_lit_s0>; ++}; ++ ++&cpu_l1 { ++ cpu-supply = <&vdd_cpu_lit_s0>; ++}; ++ ++&cpu_l2 { ++ cpu-supply = <&vdd_cpu_lit_s0>; ++}; ++ ++&cpu_l3 { ++ cpu-supply = <&vdd_cpu_lit_s0>; ++}; ++ + &gmac0 { + clock_in_out = "output"; + phy-handle = <&rgmii_phy>; +@@ -123,6 +155,611 @@ &sdhci { + status = "okay"; + }; + ++&spi2 { ++ status = "okay"; ++ assigned-clocks = <&cru CLK_SPI2>; ++ assigned-clock-rates = <200000000>; ++ num-cs = <2>; ++ ++ pmic@0 { ++ compatible = "rockchip,rk806"; ++ reg = <0x0>; ++ #gpio-cells = <2>; ++ gpio-controller; ++ interrupt-parent = <&gpio0>; ++ interrupts = <7 IRQ_TYPE_LEVEL_LOW>; ++ pinctrl-0 = <&pmic_pins>, <&rk806_dvs1_null>, ++ <&rk806_dvs2_null>, <&rk806_dvs3_null>; ++ pinctrl-names = "default"; ++ spi-max-frequency = <1000000>; ++ ++ vcc1-supply = <&vcc5v0_sys>; ++ vcc2-supply = <&vcc5v0_sys>; ++ vcc3-supply = <&vcc5v0_sys>; ++ vcc4-supply = <&vcc5v0_sys>; ++ vcc5-supply = <&vcc5v0_sys>; ++ vcc6-supply = <&vcc5v0_sys>; ++ vcc7-supply = <&vcc5v0_sys>; ++ vcc8-supply = <&vcc5v0_sys>; ++ vcc9-supply = <&vcc5v0_sys>; ++ vcc10-supply = <&vcc5v0_sys>; ++ vcc11-supply = <&vcc_2v0_pldo_s3>; ++ vcc12-supply = <&vcc5v0_sys>; ++ vcc13-supply = <&vcc5v0_sys>; ++ vcc14-supply = <&vcc_1v1_nldo_s3>; ++ vcca-supply = <&vcc5v0_sys>; ++ ++ rk806_dvs1_null: dvs1-null-pins { ++ pins = "gpio_pwrctrl1"; ++ function = "pin_fun0"; ++ }; ++ ++ rk806_dvs2_null: dvs2-null-pins { ++ pins = "gpio_pwrctrl2"; ++ function = "pin_fun0"; ++ }; ++ ++ rk806_dvs3_null: dvs3-null-pins { ++ pins = "gpio_pwrctrl3"; ++ function = "pin_fun0"; ++ }; ++ ++ ++ regulators { ++ vdd_gpu_s0: dcdc-reg1 { ++ regulator-boot-on; ++ regulator-min-microvolt = <550000>; ++ regulator-max-microvolt = <950000>; ++ regulator-ramp-delay = <12500>; ++ regulator-name = "vdd_gpu_s0"; ++ regulator-enable-ramp-delay = <400>; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vdd_npu_s0: dcdc-reg2 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <550000>; ++ regulator-max-microvolt = <950000>; ++ regulator-ramp-delay = <12500>; ++ regulator-name = "vdd_npu_s0"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vdd_log_s0: dcdc-reg3 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <675000>; ++ regulator-max-microvolt = <750000>; ++ regulator-ramp-delay = <12500>; ++ regulator-name = "vdd_log_s0"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ regulator-suspend-microvolt = <750000>; ++ }; ++ }; ++ ++ vdd_vdenc_s0: dcdc-reg4 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <550000>; ++ regulator-max-microvolt = <950000>; ++ regulator-ramp-delay = <12500>; ++ regulator-name = "vdd_vdenc_s0"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ ++ }; ++ ++ vdd_gpu_mem_s0: dcdc-reg5 { ++ regulator-boot-on; ++ regulator-min-microvolt = <675000>; ++ regulator-max-microvolt = <950000>; ++ regulator-ramp-delay = <12500>; ++ regulator-enable-ramp-delay = <400>; ++ regulator-name = "vdd_gpu_mem_s0"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ ++ }; ++ ++ vdd_npu_mem_s0: dcdc-reg6 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <675000>; ++ regulator-max-microvolt = <950000>; ++ regulator-ramp-delay = <12500>; ++ regulator-name = "vdd_npu_mem_s0"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ ++ }; ++ ++ vcc_2v0_pldo_s3: dcdc-reg7 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <2000000>; ++ regulator-max-microvolt = <2000000>; ++ regulator-ramp-delay = <12500>; ++ regulator-name = "vdd_2v0_pldo_s3"; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <2000000>; ++ }; ++ }; ++ ++ vdd_vdenc_mem_s0: dcdc-reg8 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <675000>; ++ regulator-max-microvolt = <950000>; ++ regulator-ramp-delay = <12500>; ++ regulator-name = "vdd_vdenc_mem_s0"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vdd2_ddr_s3: dcdc-reg9 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-name = "vdd2_ddr_s3"; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ }; ++ }; ++ ++ vcc_1v1_nldo_s3: dcdc-reg10 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1100000>; ++ regulator-max-microvolt = <1100000>; ++ regulator-ramp-delay = <12500>; ++ regulator-name = "vcc_1v1_nldo_s3"; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1100000>; ++ }; ++ }; ++ ++ avcc_1v8_s0: pldo-reg1 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-ramp-delay = <12500>; ++ regulator-name = "avcc_1v8_s0"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vdd1_1v8_ddr_s3: pldo-reg2 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-ramp-delay = <12500>; ++ regulator-name = "vdd1_1v8_ddr_s3"; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ avcc_1v8_codec_s0: pldo-reg3 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-ramp-delay = <12500>; ++ regulator-name = "avcc_1v8_codec_s0"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcc_3v3_s3: pldo-reg4 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-ramp-delay = <12500>; ++ regulator-name = "vcc_3v3_s3"; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <3300000>; ++ }; ++ }; ++ ++ vccio_sd_s0: pldo-reg5 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-ramp-delay = <12500>; ++ regulator-name = "vccio_sd_s0"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vccio_1v8_s3: pldo-reg6 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-ramp-delay = <12500>; ++ regulator-name = "vccio_1v8_s3"; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ vdd_0v75_s3: nldo-reg1 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <750000>; ++ regulator-max-microvolt = <750000>; ++ regulator-ramp-delay = <12500>; ++ regulator-name = "vdd_0v75_s3"; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <750000>; ++ }; ++ }; ++ ++ vdd2l_0v9_ddr_s3: nldo-reg2 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <900000>; ++ regulator-max-microvolt = <900000>; ++ regulator-name = "vdd2l_0v9_ddr_s3"; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <900000>; ++ }; ++ }; ++ ++ vdd_0v75_hdmi_edp_s0: nldo-reg3 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <750000>; ++ regulator-max-microvolt = <750000>; ++ regulator-name = "vdd_0v75_hdmi_edp_s0"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ avdd_0v75_s0: nldo-reg4 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <750000>; ++ regulator-max-microvolt = <750000>; ++ regulator-name = "avdd_0v75_s0"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vdd_0v85_s0: nldo-reg5 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <850000>; ++ regulator-max-microvolt = <850000>; ++ regulator-name = "vdd_0v85_s0"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ }; ++ }; ++ ++ pmic@1 { ++ compatible = "rockchip,rk806"; ++ reg = <0x01>; ++ #gpio-cells = <2>; ++ gpio-controller; ++ interrupt-parent = <&gpio0>; ++ interrupts = <7 IRQ_TYPE_LEVEL_LOW>; ++ pinctrl-0 = <&rk806_slave_dvs1_null>, <&rk806_slave_dvs2_null>, ++ <&rk806_slave_dvs3_null>; ++ pinctrl-names = "default"; ++ spi-max-frequency = <1000000>; ++ ++ vcc1-supply = <&vcc5v0_sys>; ++ vcc2-supply = <&vcc5v0_sys>; ++ vcc3-supply = <&vcc5v0_sys>; ++ vcc4-supply = <&vcc5v0_sys>; ++ vcc5-supply = <&vcc5v0_sys>; ++ vcc6-supply = <&vcc5v0_sys>; ++ vcc7-supply = <&vcc5v0_sys>; ++ vcc8-supply = <&vcc5v0_sys>; ++ vcc9-supply = <&vcc5v0_sys>; ++ vcc10-supply = <&vcc5v0_sys>; ++ vcc11-supply = <&vcc_2v0_pldo_s3>; ++ vcc12-supply = <&vcc5v0_sys>; ++ vcc13-supply = <&vcc_1v1_nldo_s3>; ++ vcc14-supply = <&vcc_2v0_pldo_s3>; ++ vcca-supply = <&vcc5v0_sys>; ++ ++ rk806_slave_dvs1_null: dvs1-null-pins { ++ pins = "gpio_pwrctrl1"; ++ function = "pin_fun0"; ++ }; ++ ++ rk806_slave_dvs2_null: dvs2-null-pins { ++ pins = "gpio_pwrctrl2"; ++ function = "pin_fun0"; ++ }; ++ ++ rk806_slave_dvs3_null: dvs3-null-pins { ++ pins = "gpio_pwrctrl3"; ++ function = "pin_fun0"; ++ }; ++ ++ regulators { ++ vdd_cpu_big1_s0: dcdc-reg1 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <550000>; ++ regulator-max-microvolt = <1050000>; ++ regulator-ramp-delay = <12500>; ++ regulator-name = "vdd_cpu_big1_s0"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vdd_cpu_big0_s0: dcdc-reg2 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <550000>; ++ regulator-max-microvolt = <1050000>; ++ regulator-ramp-delay = <12500>; ++ regulator-name = "vdd_cpu_big0_s0"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vdd_cpu_lit_s0: dcdc-reg3 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <550000>; ++ regulator-max-microvolt = <950000>; ++ regulator-ramp-delay = <12500>; ++ regulator-name = "vdd_cpu_lit_s0"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcc_3v3_s0: dcdc-reg4 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-ramp-delay = <12500>; ++ regulator-name = "vcc_3v3_s0"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vdd_cpu_big1_mem_s0: dcdc-reg5 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <675000>; ++ regulator-max-microvolt = <1050000>; ++ regulator-ramp-delay = <12500>; ++ regulator-name = "vdd_cpu_big1_mem_s0"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ ++ vdd_cpu_big0_mem_s0: dcdc-reg6 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <675000>; ++ regulator-max-microvolt = <1050000>; ++ regulator-ramp-delay = <12500>; ++ regulator-name = "vdd_cpu_big0_mem_s0"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcc_1v8_s0: dcdc-reg7 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-ramp-delay = <12500>; ++ regulator-name = "vcc_1v8_s0"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vdd_cpu_lit_mem_s0: dcdc-reg8 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <675000>; ++ regulator-max-microvolt = <950000>; ++ regulator-ramp-delay = <12500>; ++ regulator-name = "vdd_cpu_lit_mem_s0"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vddq_ddr_s0: dcdc-reg9 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-name = "vddq_ddr_s0"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vdd_ddr_s0: dcdc-reg10 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <675000>; ++ regulator-max-microvolt = <900000>; ++ regulator-ramp-delay = <12500>; ++ regulator-name = "vdd_ddr_s0"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcc_1v8_cam_s0: pldo-reg1 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-ramp-delay = <12500>; ++ regulator-name = "vcc_1v8_cam_s0"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ avdd1v8_ddr_pll_s0: pldo-reg2 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-ramp-delay = <12500>; ++ regulator-name = "avdd1v8_ddr_pll_s0"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vdd_1v8_pll_s0: pldo-reg3 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-ramp-delay = <12500>; ++ regulator-name = "vdd_1v8_pll_s0"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcc_3v3_sd_s0: pldo-reg4 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-ramp-delay = <12500>; ++ regulator-name = "vcc_3v3_sd_s0"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcc_2v8_cam_s0: pldo-reg5 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <2800000>; ++ regulator-max-microvolt = <2800000>; ++ regulator-ramp-delay = <12500>; ++ regulator-name = "vcc_2v8_cam_s0"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ pldo6_s3: pldo-reg6 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-name = "pldo6_s3"; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ vdd_0v75_pll_s0: nldo-reg1 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <750000>; ++ regulator-max-microvolt = <750000>; ++ regulator-ramp-delay = <12500>; ++ regulator-name = "vdd_0v75_pll_s0"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vdd_ddr_pll_s0: nldo-reg2 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <850000>; ++ regulator-max-microvolt = <850000>; ++ regulator-name = "vdd_ddr_pll_s0"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ avdd_0v85_s0: nldo-reg3 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <850000>; ++ regulator-max-microvolt = <850000>; ++ regulator-ramp-delay = <12500>; ++ regulator-name = "avdd_0v85_s0"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ avdd_1v2_cam_s0: nldo-reg4 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1200000>; ++ regulator-max-microvolt = <1200000>; ++ regulator-ramp-delay = <12500>; ++ regulator-name = "avdd_1v2_cam_s0"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ avdd_1v2_s0: nldo-reg5 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1200000>; ++ regulator-max-microvolt = <1200000>; ++ regulator-ramp-delay = <12500>; ++ regulator-name = "avdd_1v2_s0"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ }; ++ }; ++}; ++ + &uart2 { + pinctrl-0 = <&uart2m0_xfer>; + status = "okay"; +-- +2.41.0 + diff --git a/patch/kernel/rockchip-rk3588-edge/0011-arm64-dts-rockchip-rk3588-add-GIC-ITS-support.patch b/patch/kernel/rockchip-rk3588-edge/0011-arm64-dts-rockchip-rk3588-add-GIC-ITS-support.patch new file mode 100644 index 0000000000..64baf5ede4 --- /dev/null +++ b/patch/kernel/rockchip-rk3588-edge/0011-arm64-dts-rockchip-rk3588-add-GIC-ITS-support.patch @@ -0,0 +1,48 @@ +From 9572f9567627c5e80bf77248242ef2e5c90da600 Mon Sep 17 00:00:00 2001 +From: Sebastian Reichel +Date: Tue, 18 Apr 2023 16:21:09 +0200 +Subject: [PATCH 1/1] arm64: dts: rockchip: rk3588: add GIC ITS support + +Add the two Interrupt Translation Service (ITS) IPs that are part of the +GIC-600. They are mainly required for PCIe Message Signalled Interrupts +(MSI). + +Co-developed-by: Kever Yang +Signed-off-by: Kever Yang +Signed-off-by: Sebastian Reichel +--- + arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi +index b46574358dd1..05af9a0fddf4 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi +@@ -1688,7 +1688,24 @@ gic: interrupt-controller@fe600000 { + mbi-alias = <0x0 0xfe610000>; + mbi-ranges = <424 56>; + msi-controller; ++ ranges; ++ #address-cells = <2>; + #interrupt-cells = <4>; ++ #size-cells = <2>; ++ ++ its0: msi-controller@fe640000 { ++ compatible = "arm,gic-v3-its"; ++ msi-controller; ++ #msi-cells = <1>; ++ reg = <0x0 0xfe640000 0x0 0x20000>; ++ }; ++ ++ its1: msi-controller@fe660000 { ++ compatible = "arm,gic-v3-its"; ++ msi-controller; ++ #msi-cells = <1>; ++ reg = <0x0 0xfe660000 0x0 0x20000>; ++ }; + + ppi-partitions { + ppi_partition0: interrupt-partition-0 { +-- +2.41.0 + diff --git a/patch/kernel/rockchip-rk3588-edge/0012-irqchip-gic-v3-Enable-Rockchip-3588001-erratum-workaround-for-RK3588S.patch b/patch/kernel/rockchip-rk3588-edge/0012-irqchip-gic-v3-Enable-Rockchip-3588001-erratum-workaround-for-RK3588S.patch new file mode 100644 index 0000000000..594d11e9a2 --- /dev/null +++ b/patch/kernel/rockchip-rk3588-edge/0012-irqchip-gic-v3-Enable-Rockchip-3588001-erratum-workaround-for-RK3588S.patch @@ -0,0 +1,36 @@ +From 0347eabc054a1253f481ab08cc683940cd048603 Mon Sep 17 00:00:00 2001 +From: Sebastian Reichel +Date: Mon, 3 Jul 2023 18:41:29 +0200 +Subject: [PATCH 1/1] irqchip/gic-v3: Enable Rockchip 3588001 erratum + workaround for RK3588S + +Commit a8707f553884 ("irqchip/gic-v3: Add Rockchip 3588001 erratum +workaround") mentioned RK3588S (the slimmed down variant of RK3588) +being affected, but did not check for its compatible value. Thus the +quirk is not applied on RK3588S. Since the GIC ITS node got added to the +upstream DT, boards using RK3588S are no longer booting without this +quirk being applied. + +Fixes: 06cdac8e8407 ("arm64: dts: rockchip: add GIC ITS support to rk3588") +Signed-off-by: Sebastian Reichel +--- + drivers/irqchip/irq-gic-v3-its.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c +index 0ec2b1e1df75..e14b10632257 100644 +--- a/drivers/irqchip/irq-gic-v3-its.c ++++ b/drivers/irqchip/irq-gic-v3-its.c +@@ -4725,7 +4725,8 @@ static bool __maybe_unused its_enable_rk3588001(void *data) + { + struct its_node *its = data; + +- if (!of_machine_is_compatible("rockchip,rk3588")) ++ if (!of_machine_is_compatible("rockchip,rk3588") && ++ !of_machine_is_compatible("rockchip,rk3588s")) + return false; + + its->flags |= ITS_FLAGS_FORCE_NON_SHAREABLE; +-- +2.41.0 + diff --git a/patch/kernel/rockchip-rk3588-edge/0013-fix-clk-divisions.patch b/patch/kernel/rockchip-rk3588-edge/0013-fix-clk-divisions.patch new file mode 100644 index 0000000000..202ee18ed9 --- /dev/null +++ b/patch/kernel/rockchip-rk3588-edge/0013-fix-clk-divisions.patch @@ -0,0 +1,57 @@ +From 0c7ec3f97f2dd703029b8a3250d04338623aea1a Mon Sep 17 00:00:00 2001 +From: Sebastian Reichel +Date: Thu, 18 May 2023 05:19:48 +0200 +Subject: [PATCH] clk: divider: Fix divisions + +The clock framework handles clock rates as "unsigned long", so u32 on +32-bit architectures and u64 on 64-bit architectures. + +The current code pointlessly casts the dividend to u64 on 32-bit +architectures and thus pointlessly reducing the performance. + +On the other hand on 64-bit architectures the divisor is masked and only +the lower 32-bit are used. Thus requesting a frequency >= 4.3GHz results +in incorrect values. For example requesting 4300000000 (4.3 GHz) will +effectively request ca. 5 MHz. Requesting clk_round_rate(clk, ULONG_MAX) +is a bit of a special case, since that still returns correct values as +long as the parent clock is below 8.5 GHz. + +Signed-off-by: Sebastian Reichel +--- + drivers/clk/clk-divider.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c +index a2c2b5203b0a9..c38e8aa60e547 100644 +--- a/drivers/clk/clk-divider.c ++++ b/drivers/clk/clk-divider.c +@@ -220,7 +220,7 @@ static int _div_round_up(const struct clk_div_table *table, + unsigned long parent_rate, unsigned long rate, + unsigned long flags) + { +- int div = DIV_ROUND_UP_ULL((u64)parent_rate, rate); ++ int div = DIV_ROUND_UP(parent_rate, rate); + + if (flags & CLK_DIVIDER_POWER_OF_TWO) + div = __roundup_pow_of_two(div); +@@ -237,7 +237,7 @@ static int _div_round_closest(const struct clk_div_table *table, + int up, down; + unsigned long up_rate, down_rate; + +- up = DIV_ROUND_UP_ULL((u64)parent_rate, rate); ++ up = DIV_ROUND_UP(parent_rate, rate); + down = parent_rate / rate; + + if (flags & CLK_DIVIDER_POWER_OF_TWO) { +@@ -473,7 +473,7 @@ int divider_get_val(unsigned long rate, unsigned long parent_rate, + { + unsigned int div, value; + +- div = DIV_ROUND_UP_ULL((u64)parent_rate, rate); ++ div = DIV_ROUND_UP(parent_rate, rate); + + if (!_is_valid_div(table, div, flags)) + return -EINVAL; +-- +GitLab + diff --git a/patch/kernel/rockchip-rk3588-edge/0014-soc-rockchip-power-domain-add-rk3588-mem-module-supp.patch b/patch/kernel/rockchip-rk3588-edge/0014-soc-rockchip-power-domain-add-rk3588-mem-module-supp.patch new file mode 100644 index 0000000000..9aa7a13f1e --- /dev/null +++ b/patch/kernel/rockchip-rk3588-edge/0014-soc-rockchip-power-domain-add-rk3588-mem-module-supp.patch @@ -0,0 +1,266 @@ +From 9d842dbd76192184bd91f4a7abf57edc17ed5181 Mon Sep 17 00:00:00 2001 +From: Boris Brezillon +Date: Mon, 3 Apr 2023 21:32:50 +0200 +Subject: [PATCH 1/1] soc: rockchip: power-domain: add rk3588 mem module + support + +On RK3588 it's also possible to power down the memory used by the +particular power domains via PMU_MEM_PWR_GATE_SFTCON. This adds +support for this feature. + +Tested-by: Vincent Legoll +Co-Developed-by: Finley Xiao +Signed-off-by: Finley Xiao +Signed-off-by: Boris Brezillon +Signed-off-by: Sebastian Reichel +--- + drivers/soc/rockchip/pm_domains.c | 160 +++++++++++++++++++++++------- + 1 file changed, 125 insertions(+), 35 deletions(-) + +diff --git a/drivers/soc/rockchip/pm_domains.c b/drivers/soc/rockchip/pm_domains.c +index 84bc022f9e5b..e3de49e671dc 100644 +--- a/drivers/soc/rockchip/pm_domains.c ++++ b/drivers/soc/rockchip/pm_domains.c +@@ -43,8 +43,10 @@ struct rockchip_domain_info { + bool active_wakeup; + int pwr_w_mask; + int req_w_mask; ++ int mem_status_mask; + int repair_status_mask; + u32 pwr_offset; ++ u32 mem_offset; + u32 req_offset; + }; + +@@ -54,6 +56,9 @@ struct rockchip_pmu_info { + u32 req_offset; + u32 idle_offset; + u32 ack_offset; ++ u32 mem_pwr_offset; ++ u32 chain_status_offset; ++ u32 mem_status_offset; + u32 repair_status_offset; + + u32 core_pwrcnt_offset; +@@ -119,13 +124,15 @@ struct rockchip_pmu { + .active_wakeup = wakeup, \ + } + +-#define DOMAIN_M_O_R(_name, p_offset, pwr, status, r_status, r_offset, req, idle, ack, wakeup) \ ++#define DOMAIN_M_O_R(_name, p_offset, pwr, status, m_offset, m_status, r_status, r_offset, req, idle, ack, wakeup) \ + { \ + .name = _name, \ + .pwr_offset = p_offset, \ + .pwr_w_mask = (pwr) << 16, \ + .pwr_mask = (pwr), \ + .status_mask = (status), \ ++ .mem_offset = m_offset, \ ++ .mem_status_mask = (m_status), \ + .repair_status_mask = (r_status), \ + .req_offset = r_offset, \ + .req_w_mask = (req) << 16, \ +@@ -269,8 +276,8 @@ void rockchip_pmu_unblock(void) + } + EXPORT_SYMBOL_GPL(rockchip_pmu_unblock); + +-#define DOMAIN_RK3588(name, p_offset, pwr, status, r_status, r_offset, req, idle, wakeup) \ +- DOMAIN_M_O_R(name, p_offset, pwr, status, r_status, r_offset, req, idle, idle, wakeup) ++#define DOMAIN_RK3588(name, p_offset, pwr, status, m_offset, m_status, r_status, r_offset, req, idle, wakeup) \ ++ DOMAIN_M_O_R(name, p_offset, pwr, status, m_offset, m_status, r_status, r_offset, req, idle, idle, wakeup) + + static bool rockchip_pmu_domain_is_idle(struct rockchip_pm_domain *pd) + { +@@ -408,17 +415,92 @@ static bool rockchip_pmu_domain_is_on(struct rockchip_pm_domain *pd) + return !(val & pd->info->status_mask); + } + ++static bool rockchip_pmu_domain_is_mem_on(struct rockchip_pm_domain *pd) ++{ ++ struct rockchip_pmu *pmu = pd->pmu; ++ unsigned int val; ++ ++ regmap_read(pmu->regmap, ++ pmu->info->mem_status_offset + pd->info->mem_offset, &val); ++ ++ /* 1'b0: power on, 1'b1: power off */ ++ return !(val & pd->info->mem_status_mask); ++} ++ ++static bool rockchip_pmu_domain_is_chain_on(struct rockchip_pm_domain *pd) ++{ ++ struct rockchip_pmu *pmu = pd->pmu; ++ unsigned int val; ++ ++ regmap_read(pmu->regmap, ++ pmu->info->chain_status_offset + pd->info->mem_offset, &val); ++ ++ /* 1'b1: power on, 1'b0: power off */ ++ return val & pd->info->mem_status_mask; ++} ++ ++static int rockchip_pmu_domain_mem_reset(struct rockchip_pm_domain *pd) ++{ ++ struct rockchip_pmu *pmu = pd->pmu; ++ struct generic_pm_domain *genpd = &pd->genpd; ++ bool is_on; ++ int ret = 0; ++ ++ ret = readx_poll_timeout_atomic(rockchip_pmu_domain_is_chain_on, pd, is_on, ++ is_on == true, 0, 10000); ++ if (ret) { ++ dev_err(pmu->dev, ++ "failed to get chain status '%s', target_on=1, val=%d\n", ++ genpd->name, is_on); ++ goto error; ++ } ++ ++ udelay(20); ++ ++ regmap_write(pmu->regmap, pmu->info->mem_pwr_offset + pd->info->pwr_offset, ++ (pd->info->pwr_mask | pd->info->pwr_w_mask)); ++ wmb(); ++ ++ ret = readx_poll_timeout_atomic(rockchip_pmu_domain_is_mem_on, pd, is_on, ++ is_on == false, 0, 10000); ++ if (ret) { ++ dev_err(pmu->dev, ++ "failed to get mem status '%s', target_on=0, val=%d\n", ++ genpd->name, is_on); ++ goto error; ++ } ++ ++ regmap_write(pmu->regmap, pmu->info->mem_pwr_offset + pd->info->pwr_offset, ++ pd->info->pwr_w_mask); ++ wmb(); ++ ++ ret = readx_poll_timeout_atomic(rockchip_pmu_domain_is_mem_on, pd, is_on, ++ is_on == true, 0, 10000); ++ if (ret) { ++ dev_err(pmu->dev, ++ "failed to get mem status '%s', target_on=1, val=%d\n", ++ genpd->name, is_on); ++ } ++ ++error: ++ return ret; ++} ++ + static void rockchip_do_pmu_set_power_domain(struct rockchip_pm_domain *pd, + bool on) + { + struct rockchip_pmu *pmu = pd->pmu; + struct generic_pm_domain *genpd = &pd->genpd; + u32 pd_pwr_offset = pd->info->pwr_offset; +- bool is_on; ++ bool is_on, is_mem_on = false; + + if (pd->info->pwr_mask == 0) + return; +- else if (pd->info->pwr_w_mask) ++ ++ if (on && pd->info->mem_status_mask) ++ is_mem_on = rockchip_pmu_domain_is_mem_on(pd); ++ ++ if (pd->info->pwr_w_mask) + regmap_write(pmu->regmap, pmu->info->pwr_offset + pd_pwr_offset, + on ? pd->info->pwr_w_mask : + (pd->info->pwr_mask | pd->info->pwr_w_mask)); +@@ -428,6 +510,9 @@ static void rockchip_do_pmu_set_power_domain(struct rockchip_pm_domain *pd, + + wmb(); + ++ if (is_mem_on && rockchip_pmu_domain_mem_reset(pd)) ++ return; ++ + if (readx_poll_timeout_atomic(rockchip_pmu_domain_is_on, pd, is_on, + is_on == on, 0, 10000)) { + dev_err(pmu->dev, +@@ -645,7 +730,9 @@ static int rockchip_pm_add_one_domain(struct rockchip_pmu *pmu, + pd->genpd.flags = GENPD_FLAG_PM_CLK; + if (pd_info->active_wakeup) + pd->genpd.flags |= GENPD_FLAG_ACTIVE_WAKEUP; +- pm_genpd_init(&pd->genpd, NULL, !rockchip_pmu_domain_is_on(pd)); ++ pm_genpd_init(&pd->genpd, NULL, ++ !rockchip_pmu_domain_is_on(pd) || ++ (pd->info->mem_status_mask && !rockchip_pmu_domain_is_mem_on(pd))); + + pmu->genpd_data.domains[id] = &pd->genpd; + return 0; +@@ -1024,35 +1111,35 @@ static const struct rockchip_domain_info rk3568_pm_domains[] = { + }; + + static const struct rockchip_domain_info rk3588_pm_domains[] = { +- [RK3588_PD_GPU] = DOMAIN_RK3588("gpu", 0x0, BIT(0), 0, BIT(1), 0x0, BIT(0), BIT(0), false), +- [RK3588_PD_NPU] = DOMAIN_RK3588("npu", 0x0, BIT(1), BIT(1), 0, 0x0, 0, 0, false), +- [RK3588_PD_VCODEC] = DOMAIN_RK3588("vcodec", 0x0, BIT(2), BIT(2), 0, 0x0, 0, 0, false), +- [RK3588_PD_NPUTOP] = DOMAIN_RK3588("nputop", 0x0, BIT(3), 0, BIT(2), 0x0, BIT(1), BIT(1), false), +- [RK3588_PD_NPU1] = DOMAIN_RK3588("npu1", 0x0, BIT(4), 0, BIT(3), 0x0, BIT(2), BIT(2), false), +- [RK3588_PD_NPU2] = DOMAIN_RK3588("npu2", 0x0, BIT(5), 0, BIT(4), 0x0, BIT(3), BIT(3), false), +- [RK3588_PD_VENC0] = DOMAIN_RK3588("venc0", 0x0, BIT(6), 0, BIT(5), 0x0, BIT(4), BIT(4), false), +- [RK3588_PD_VENC1] = DOMAIN_RK3588("venc1", 0x0, BIT(7), 0, BIT(6), 0x0, BIT(5), BIT(5), false), +- [RK3588_PD_RKVDEC0] = DOMAIN_RK3588("rkvdec0", 0x0, BIT(8), 0, BIT(7), 0x0, BIT(6), BIT(6), false), +- [RK3588_PD_RKVDEC1] = DOMAIN_RK3588("rkvdec1", 0x0, BIT(9), 0, BIT(8), 0x0, BIT(7), BIT(7), false), +- [RK3588_PD_VDPU] = DOMAIN_RK3588("vdpu", 0x0, BIT(10), 0, BIT(9), 0x0, BIT(8), BIT(8), false), +- [RK3588_PD_RGA30] = DOMAIN_RK3588("rga30", 0x0, BIT(11), 0, BIT(10), 0x0, 0, 0, false), +- [RK3588_PD_AV1] = DOMAIN_RK3588("av1", 0x0, BIT(12), 0, BIT(11), 0x0, BIT(9), BIT(9), false), +- [RK3588_PD_VI] = DOMAIN_RK3588("vi", 0x0, BIT(13), 0, BIT(12), 0x0, BIT(10), BIT(10), false), +- [RK3588_PD_FEC] = DOMAIN_RK3588("fec", 0x0, BIT(14), 0, BIT(13), 0x0, 0, 0, false), +- [RK3588_PD_ISP1] = DOMAIN_RK3588("isp1", 0x0, BIT(15), 0, BIT(14), 0x0, BIT(11), BIT(11), false), +- [RK3588_PD_RGA31] = DOMAIN_RK3588("rga31", 0x4, BIT(0), 0, BIT(15), 0x0, BIT(12), BIT(12), false), +- [RK3588_PD_VOP] = DOMAIN_RK3588("vop", 0x4, BIT(1), 0, BIT(16), 0x0, BIT(13) | BIT(14), BIT(13) | BIT(14), false), +- [RK3588_PD_VO0] = DOMAIN_RK3588("vo0", 0x4, BIT(2), 0, BIT(17), 0x0, BIT(15), BIT(15), false), +- [RK3588_PD_VO1] = DOMAIN_RK3588("vo1", 0x4, BIT(3), 0, BIT(18), 0x4, BIT(0), BIT(16), false), +- [RK3588_PD_AUDIO] = DOMAIN_RK3588("audio", 0x4, BIT(4), 0, BIT(19), 0x4, BIT(1), BIT(17), false), +- [RK3588_PD_PHP] = DOMAIN_RK3588("php", 0x4, BIT(5), 0, BIT(20), 0x4, BIT(5), BIT(21), false), +- [RK3588_PD_GMAC] = DOMAIN_RK3588("gmac", 0x4, BIT(6), 0, BIT(21), 0x0, 0, 0, false), +- [RK3588_PD_PCIE] = DOMAIN_RK3588("pcie", 0x4, BIT(7), 0, BIT(22), 0x0, 0, 0, true), +- [RK3588_PD_NVM] = DOMAIN_RK3588("nvm", 0x4, BIT(8), BIT(24), 0, 0x4, BIT(2), BIT(18), false), +- [RK3588_PD_NVM0] = DOMAIN_RK3588("nvm0", 0x4, BIT(9), 0, BIT(23), 0x0, 0, 0, false), +- [RK3588_PD_SDIO] = DOMAIN_RK3588("sdio", 0x4, BIT(10), 0, BIT(24), 0x4, BIT(3), BIT(19), false), +- [RK3588_PD_USB] = DOMAIN_RK3588("usb", 0x4, BIT(11), 0, BIT(25), 0x4, BIT(4), BIT(20), true), +- [RK3588_PD_SDMMC] = DOMAIN_RK3588("sdmmc", 0x4, BIT(13), 0, BIT(26), 0x0, 0, 0, false), ++ [RK3588_PD_GPU] = DOMAIN_RK3588("gpu", 0x0, BIT(0), 0, 0x0, 0, BIT(1), 0x0, BIT(0), BIT(0), false), ++ [RK3588_PD_NPU] = DOMAIN_RK3588("npu", 0x0, BIT(1), BIT(1), 0x0, 0, 0, 0x0, 0, 0, false), ++ [RK3588_PD_VCODEC] = DOMAIN_RK3588("vcodec", 0x0, BIT(2), BIT(2), 0x0, 0, 0, 0x0, 0, 0, false), ++ [RK3588_PD_NPUTOP] = DOMAIN_RK3588("nputop", 0x0, BIT(3), 0, 0x0, BIT(11), BIT(2), 0x0, BIT(1), BIT(1), false), ++ [RK3588_PD_NPU1] = DOMAIN_RK3588("npu1", 0x0, BIT(4), 0, 0x0, BIT(12), BIT(3), 0x0, BIT(2), BIT(2), false), ++ [RK3588_PD_NPU2] = DOMAIN_RK3588("npu2", 0x0, BIT(5), 0, 0x0, BIT(13), BIT(4), 0x0, BIT(3), BIT(3), false), ++ [RK3588_PD_VENC0] = DOMAIN_RK3588("venc0", 0x0, BIT(6), 0, 0x0, BIT(14), BIT(5), 0x0, BIT(4), BIT(4), false), ++ [RK3588_PD_VENC1] = DOMAIN_RK3588("venc1", 0x0, BIT(7), 0, 0x0, BIT(15), BIT(6), 0x0, BIT(5), BIT(5), false), ++ [RK3588_PD_RKVDEC0] = DOMAIN_RK3588("rkvdec0", 0x0, BIT(8), 0, 0x0, BIT(16), BIT(7), 0x0, BIT(6), BIT(6), false), ++ [RK3588_PD_RKVDEC1] = DOMAIN_RK3588("rkvdec1", 0x0, BIT(9), 0, 0x0, BIT(17), BIT(8), 0x0, BIT(7), BIT(7), false), ++ [RK3588_PD_VDPU] = DOMAIN_RK3588("vdpu", 0x0, BIT(10), 0, 0x0, BIT(18), BIT(9), 0x0, BIT(8), BIT(8), false), ++ [RK3588_PD_RGA30] = DOMAIN_RK3588("rga30", 0x0, BIT(11), 0, 0x0, BIT(19), BIT(10), 0x0, 0, 0, false), ++ [RK3588_PD_AV1] = DOMAIN_RK3588("av1", 0x0, BIT(12), 0, 0x0, BIT(20), BIT(11), 0x0, BIT(9), BIT(9), false), ++ [RK3588_PD_VI] = DOMAIN_RK3588("vi", 0x0, BIT(13), 0, 0x0, BIT(21), BIT(12), 0x0, BIT(10), BIT(10), false), ++ [RK3588_PD_FEC] = DOMAIN_RK3588("fec", 0x0, BIT(14), 0, 0x0, BIT(22), BIT(13), 0x0, 0, 0, false), ++ [RK3588_PD_ISP1] = DOMAIN_RK3588("isp1", 0x0, BIT(15), 0, 0x0, BIT(23), BIT(14), 0x0, BIT(11), BIT(11), false), ++ [RK3588_PD_RGA31] = DOMAIN_RK3588("rga31", 0x4, BIT(0), 0, 0x0, BIT(24), BIT(15), 0x0, BIT(12), BIT(12), false), ++ [RK3588_PD_VOP] = DOMAIN_RK3588("vop", 0x4, BIT(1), 0, 0x0, BIT(25), BIT(16), 0x0, BIT(13) | BIT(14), BIT(13) | BIT(14), false), ++ [RK3588_PD_VO0] = DOMAIN_RK3588("vo0", 0x4, BIT(2), 0, 0x0, BIT(26), BIT(17), 0x0, BIT(15), BIT(15), false), ++ [RK3588_PD_VO1] = DOMAIN_RK3588("vo1", 0x4, BIT(3), 0, 0x0, BIT(27), BIT(18), 0x4, BIT(0), BIT(16), false), ++ [RK3588_PD_AUDIO] = DOMAIN_RK3588("audio", 0x4, BIT(4), 0, 0x0, BIT(28), BIT(19), 0x4, BIT(1), BIT(17), false), ++ [RK3588_PD_PHP] = DOMAIN_RK3588("php", 0x4, BIT(5), 0, 0x0, BIT(29), BIT(20), 0x4, BIT(5), BIT(21), false), ++ [RK3588_PD_GMAC] = DOMAIN_RK3588("gmac", 0x4, BIT(6), 0, 0x0, BIT(30), BIT(21), 0x0, 0, 0, false), ++ [RK3588_PD_PCIE] = DOMAIN_RK3588("pcie", 0x4, BIT(7), 0, 0x0, BIT(31), BIT(22), 0x0, 0, 0, true), ++ [RK3588_PD_NVM] = DOMAIN_RK3588("nvm", 0x4, BIT(8), BIT(24), 0x4, 0, 0, 0x4, BIT(2), BIT(18), false), ++ [RK3588_PD_NVM0] = DOMAIN_RK3588("nvm0", 0x4, BIT(9), 0, 0x4, BIT(1), BIT(23), 0x0, 0, 0, false), ++ [RK3588_PD_SDIO] = DOMAIN_RK3588("sdio", 0x4, BIT(10), 0, 0x4, BIT(2), BIT(24), 0x4, BIT(3), BIT(19), false), ++ [RK3588_PD_USB] = DOMAIN_RK3588("usb", 0x4, BIT(11), 0, 0x4, BIT(3), BIT(25), 0x4, BIT(4), BIT(20), true), ++ [RK3588_PD_SDMMC] = DOMAIN_RK3588("sdmmc", 0x4, BIT(13), 0, 0x4, BIT(5), BIT(26), 0x0, 0, 0, false), + }; + + static const struct rockchip_pmu_info px30_pmu = { +@@ -1207,6 +1294,9 @@ static const struct rockchip_pmu_info rk3588_pmu = { + .req_offset = 0x10c, + .idle_offset = 0x120, + .ack_offset = 0x118, ++ .mem_pwr_offset = 0x1a0, ++ .chain_status_offset = 0x1f0, ++ .mem_status_offset = 0x1f8, + .repair_status_offset = 0x290, + + .num_domains = ARRAY_SIZE(rk3588_pm_domains), +-- +2.41.0 + diff --git a/patch/kernel/rockchip-rk3588-edge/0015-arm64-dts-rockchip-Add-rk3588-timer.patch b/patch/kernel/rockchip-rk3588-edge/0015-arm64-dts-rockchip-Add-rk3588-timer.patch new file mode 100644 index 0000000000..32f34e4636 --- /dev/null +++ b/patch/kernel/rockchip-rk3588-edge/0015-arm64-dts-rockchip-Add-rk3588-timer.patch @@ -0,0 +1,34 @@ +From 63cae5a6a417199ccc1965ceb1e1915a0b3c3e10 Mon Sep 17 00:00:00 2001 +From: Cristian Ciocaltea +Date: Wed, 19 Apr 2023 21:13:09 +0300 +Subject: [PATCH 1/1] arm64: dts: rockchip: Add rk3588 timer + +Add DT node for Rockchip RK3588/RK3588S SoC timer. + +Signed-off-by: Cristian Ciocaltea +--- + arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi +index 05af9a0fddf4..96fb3a6e0c68 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi +@@ -1805,6 +1805,14 @@ i2c5: i2c@fead0000 { + status = "disabled"; + }; + ++ timer0: timer@feae0000 { ++ compatible = "rockchip,rk3588-timer", "rockchip,rk3288-timer"; ++ reg = <0x0 0xfeae0000 0x0 0x20>; ++ interrupts = ; ++ clocks = <&cru PCLK_BUSTIMER0>, <&cru CLK_BUSTIMER0>; ++ clock-names = "pclk", "timer"; ++ }; ++ + wdt: watchdog@feaf0000 { + compatible = "rockchip,rk3588-wdt", "snps,dw-wdt"; + reg = <0x0 0xfeaf0000 0x0 0x100>; +-- +2.41.0 + diff --git a/patch/kernel/rockchip-rk3588-edge/0020-RK3588-ADC-support.patch b/patch/kernel/rockchip-rk3588-edge/0020-RK3588-ADC-support.patch new file mode 100644 index 0000000000..c4c6fa4ae1 --- /dev/null +++ b/patch/kernel/rockchip-rk3588-edge/0020-RK3588-ADC-support.patch @@ -0,0 +1,684 @@ +From cd425173fe5788b5bc17cc4a3de7c68fd571d151 Mon Sep 17 00:00:00 2001 +From: Simon Xue +Date: Sun, 4 Jun 2023 00:23:33 +0530 +Subject: [PATCH 1/9] iio: adc: rockchip_saradc: Add callback functions + +Add start, read and power_down callback functions, +which will help in adding new rockchip device support +cleanly. + +Signed-off-by: Simon Xue +Signed-off-by: Shreeya Patel +--- + drivers/iio/adc/rockchip_saradc.c | 64 +++++++++++++++++++++++++------ + 1 file changed, 52 insertions(+), 12 deletions(-) + +diff --git a/drivers/iio/adc/rockchip_saradc.c b/drivers/iio/adc/rockchip_saradc.c +index 79448c5ffc2a..21f9d92a6af4 100644 +--- a/drivers/iio/adc/rockchip_saradc.c ++++ b/drivers/iio/adc/rockchip_saradc.c +@@ -38,10 +38,15 @@ + #define SARADC_TIMEOUT msecs_to_jiffies(100) + #define SARADC_MAX_CHANNELS 8 + ++struct rockchip_saradc; ++ + struct rockchip_saradc_data { + const struct iio_chan_spec *channels; + int num_channels; + unsigned long clk_rate; ++ void (*start)(struct rockchip_saradc *info, int chn); ++ int (*read)(struct rockchip_saradc *info); ++ void (*power_down)(struct rockchip_saradc *info); + }; + + struct rockchip_saradc { +@@ -60,27 +65,50 @@ struct rockchip_saradc { + struct notifier_block nb; + }; + +-static void rockchip_saradc_power_down(struct rockchip_saradc *info) ++static void rockchip_saradc_reset_controller(struct reset_control *reset); ++ ++static void rockchip_saradc_start_v1(struct rockchip_saradc *info, int chn) ++{ ++ /* 8 clock periods as delay between power up and start cmd */ ++ writel_relaxed(8, info->regs + SARADC_DLY_PU_SOC); ++ /* Select the channel to be used and trigger conversion */ ++ writel(SARADC_CTRL_POWER_CTRL | (chn & SARADC_CTRL_CHN_MASK) | ++ SARADC_CTRL_IRQ_ENABLE, info->regs + SARADC_CTRL); ++} ++ ++static void rockchip_saradc_start(struct rockchip_saradc *info, int chn) ++{ ++ info->data->start(info, chn); ++} ++ ++static int rockchip_saradc_read_v1(struct rockchip_saradc *info) ++{ ++ return readl_relaxed(info->regs + SARADC_DATA); ++} ++ ++static int rockchip_saradc_read(struct rockchip_saradc *info) ++{ ++ return info->data->read(info); ++} ++ ++static void rockchip_saradc_power_down_v1(struct rockchip_saradc *info) + { +- /* Clear irq & power down adc */ + writel_relaxed(0, info->regs + SARADC_CTRL); + } + ++static void rockchip_saradc_power_down(struct rockchip_saradc *info) ++{ ++ if (info->data->power_down) ++ info->data->power_down(info); ++} ++ + static int rockchip_saradc_conversion(struct rockchip_saradc *info, + struct iio_chan_spec const *chan) + { + reinit_completion(&info->completion); + +- /* 8 clock periods as delay between power up and start cmd */ +- writel_relaxed(8, info->regs + SARADC_DLY_PU_SOC); +- + info->last_chan = chan; +- +- /* Select the channel to be used and trigger conversion */ +- writel(SARADC_CTRL_POWER_CTRL +- | (chan->channel & SARADC_CTRL_CHN_MASK) +- | SARADC_CTRL_IRQ_ENABLE, +- info->regs + SARADC_CTRL); ++ rockchip_saradc_start(info, chan->channel); + + if (!wait_for_completion_timeout(&info->completion, SARADC_TIMEOUT)) + return -ETIMEDOUT; +@@ -123,7 +151,7 @@ static irqreturn_t rockchip_saradc_isr(int irq, void *dev_id) + struct rockchip_saradc *info = dev_id; + + /* Read value */ +- info->last_val = readl_relaxed(info->regs + SARADC_DATA); ++ info->last_val = rockchip_saradc_read(info); + info->last_val &= GENMASK(info->last_chan->scan_type.realbits - 1, 0); + + rockchip_saradc_power_down(info); +@@ -163,6 +191,9 @@ static const struct rockchip_saradc_data saradc_data = { + .channels = rockchip_saradc_iio_channels, + .num_channels = ARRAY_SIZE(rockchip_saradc_iio_channels), + .clk_rate = 1000000, ++ .start = rockchip_saradc_start_v1, ++ .read = rockchip_saradc_read_v1, ++ .power_down = rockchip_saradc_power_down_v1, + }; + + static const struct iio_chan_spec rockchip_rk3066_tsadc_iio_channels[] = { +@@ -174,6 +205,9 @@ static const struct rockchip_saradc_data rk3066_tsadc_data = { + .channels = rockchip_rk3066_tsadc_iio_channels, + .num_channels = ARRAY_SIZE(rockchip_rk3066_tsadc_iio_channels), + .clk_rate = 50000, ++ .start = rockchip_saradc_start_v1, ++ .read = rockchip_saradc_read_v1, ++ .power_down = rockchip_saradc_power_down_v1, + }; + + static const struct iio_chan_spec rockchip_rk3399_saradc_iio_channels[] = { +@@ -189,6 +223,9 @@ static const struct rockchip_saradc_data rk3399_saradc_data = { + .channels = rockchip_rk3399_saradc_iio_channels, + .num_channels = ARRAY_SIZE(rockchip_rk3399_saradc_iio_channels), + .clk_rate = 1000000, ++ .start = rockchip_saradc_start_v1, ++ .read = rockchip_saradc_read_v1, ++ .power_down = rockchip_saradc_power_down_v1, + }; + + static const struct iio_chan_spec rockchip_rk3568_saradc_iio_channels[] = { +@@ -206,6 +243,9 @@ static const struct rockchip_saradc_data rk3568_saradc_data = { + .channels = rockchip_rk3568_saradc_iio_channels, + .num_channels = ARRAY_SIZE(rockchip_rk3568_saradc_iio_channels), + .clk_rate = 1000000, ++ .start = rockchip_saradc_start_v1, ++ .read = rockchip_saradc_read_v1, ++ .power_down = rockchip_saradc_power_down_v1, + }; + + static const struct of_device_id rockchip_saradc_match[] = { +-- +2.41.0 + + +From b5d9db8b105387c66c2c44096a622c6d9adfd5e6 Mon Sep 17 00:00:00 2001 +From: Simon Xue +Date: Sun, 4 Jun 2023 00:23:34 +0530 +Subject: [PATCH 2/9] iio: adc: rockchip_saradc: Add support for RK3588 + +Add new start and read functions to support rk3588 device. +Also, add a device compatible string for the same. + +Signed-off-by: Simon Xue +Signed-off-by: Shreeya Patel +Reviewed-by: AngeloGioacchino Del Regno +--- + drivers/iio/adc/rockchip_saradc.c | 70 +++++++++++++++++++++++++++++++ + 1 file changed, 70 insertions(+) + +diff --git a/drivers/iio/adc/rockchip_saradc.c b/drivers/iio/adc/rockchip_saradc.c +index 21f9d92a6af4..312286ec91dc 100644 +--- a/drivers/iio/adc/rockchip_saradc.c ++++ b/drivers/iio/adc/rockchip_saradc.c +@@ -4,6 +4,7 @@ + * Copyright (C) 2014 ROCKCHIP, Inc. + */ + ++#include + #include + #include + #include +@@ -38,6 +39,22 @@ + #define SARADC_TIMEOUT msecs_to_jiffies(100) + #define SARADC_MAX_CHANNELS 8 + ++/* v2 registers */ ++#define SARADC2_CONV_CON 0x0 ++#define SARADC_T_PD_SOC 0x4 ++#define SARADC_T_DAS_SOC 0xc ++#define SARADC2_END_INT_EN 0x104 ++#define SARADC2_ST_CON 0x108 ++#define SARADC2_STATUS 0x10c ++#define SARADC2_END_INT_ST 0x110 ++#define SARADC2_DATA_BASE 0x120 ++ ++#define SARADC2_EN_END_INT BIT(0) ++#define SARADC2_START BIT(4) ++#define SARADC2_SINGLE_MODE BIT(5) ++ ++#define SARADC2_CONV_CHANNELS GENMASK(15, 0) ++ + struct rockchip_saradc; + + struct rockchip_saradc_data { +@@ -76,6 +93,25 @@ static void rockchip_saradc_start_v1(struct rockchip_saradc *info, int chn) + SARADC_CTRL_IRQ_ENABLE, info->regs + SARADC_CTRL); + } + ++static void rockchip_saradc_start_v2(struct rockchip_saradc *info, int chn) ++{ ++ int val; ++ ++ if (info->reset) ++ rockchip_saradc_reset_controller(info->reset); ++ ++ writel_relaxed(0xc, info->regs + SARADC_T_DAS_SOC); ++ writel_relaxed(0x20, info->regs + SARADC_T_PD_SOC); ++ val = FIELD_PREP(SARADC2_EN_END_INT, 1); ++ val |= val << 16; ++ writel_relaxed(val, info->regs + SARADC2_END_INT_EN); ++ val = FIELD_PREP(SARADC2_START, 1) | ++ FIELD_PREP(SARADC2_SINGLE_MODE, 1) | ++ FIELD_PREP(SARADC2_CONV_CHANNELS, chn); ++ val |= val << 16; ++ writel(val, info->regs + SARADC2_CONV_CON); ++} ++ + static void rockchip_saradc_start(struct rockchip_saradc *info, int chn) + { + info->data->start(info, chn); +@@ -86,6 +122,18 @@ static int rockchip_saradc_read_v1(struct rockchip_saradc *info) + return readl_relaxed(info->regs + SARADC_DATA); + } + ++static int rockchip_saradc_read_v2(struct rockchip_saradc *info) ++{ ++ int offset; ++ ++ /* Clear irq */ ++ writel_relaxed(0x1, info->regs + SARADC2_END_INT_ST); ++ ++ offset = SARADC2_DATA_BASE + info->last_chan->channel * 0x4; ++ ++ return readl_relaxed(info->regs + offset); ++} ++ + static int rockchip_saradc_read(struct rockchip_saradc *info) + { + return info->data->read(info); +@@ -248,6 +296,25 @@ static const struct rockchip_saradc_data rk3568_saradc_data = { + .power_down = rockchip_saradc_power_down_v1, + }; + ++static const struct iio_chan_spec rockchip_rk3588_saradc_iio_channels[] = { ++ SARADC_CHANNEL(0, "adc0", 12), ++ SARADC_CHANNEL(1, "adc1", 12), ++ SARADC_CHANNEL(2, "adc2", 12), ++ SARADC_CHANNEL(3, "adc3", 12), ++ SARADC_CHANNEL(4, "adc4", 12), ++ SARADC_CHANNEL(5, "adc5", 12), ++ SARADC_CHANNEL(6, "adc6", 12), ++ SARADC_CHANNEL(7, "adc7", 12), ++}; ++ ++static const struct rockchip_saradc_data rk3588_saradc_data = { ++ .channels = rockchip_rk3588_saradc_iio_channels, ++ .num_channels = ARRAY_SIZE(rockchip_rk3588_saradc_iio_channels), ++ .clk_rate = 1000000, ++ .start = rockchip_saradc_start_v2, ++ .read = rockchip_saradc_read_v2, ++}; ++ + static const struct of_device_id rockchip_saradc_match[] = { + { + .compatible = "rockchip,saradc", +@@ -261,6 +328,9 @@ static const struct of_device_id rockchip_saradc_match[] = { + }, { + .compatible = "rockchip,rk3568-saradc", + .data = &rk3568_saradc_data, ++ }, { ++ .compatible = "rockchip,rk3588-saradc", ++ .data = &rk3588_saradc_data, + }, + {}, + }; +-- +2.41.0 + + +From a0ba1f7d0b8ce5cfeff1253d99556704a4b70139 Mon Sep 17 00:00:00 2001 +From: Shreeya Patel +Date: Sun, 4 Jun 2023 00:23:35 +0530 +Subject: [PATCH 3/9] iio: adc: rockchip_saradc: Make use of + devm_clk_get_enabled + +Use devm_clk_get_enabled() to avoid manually disabling the +clock. + +Signed-off-by: Shreeya Patel +--- + drivers/iio/adc/rockchip_saradc.c | 56 +++++-------------------------- + 1 file changed, 8 insertions(+), 48 deletions(-) + +diff --git a/drivers/iio/adc/rockchip_saradc.c b/drivers/iio/adc/rockchip_saradc.c +index 312286ec91dc..ac424ea50787 100644 +--- a/drivers/iio/adc/rockchip_saradc.c ++++ b/drivers/iio/adc/rockchip_saradc.c +@@ -346,20 +346,6 @@ static void rockchip_saradc_reset_controller(struct reset_control *reset) + reset_control_deassert(reset); + } + +-static void rockchip_saradc_clk_disable(void *data) +-{ +- struct rockchip_saradc *info = data; +- +- clk_disable_unprepare(info->clk); +-} +- +-static void rockchip_saradc_pclk_disable(void *data) +-{ +- struct rockchip_saradc *info = data; +- +- clk_disable_unprepare(info->pclk); +-} +- + static void rockchip_saradc_regulator_disable(void *data) + { + struct rockchip_saradc *info = data; +@@ -493,16 +479,6 @@ static int rockchip_saradc_probe(struct platform_device *pdev) + return ret; + } + +- info->pclk = devm_clk_get(&pdev->dev, "apb_pclk"); +- if (IS_ERR(info->pclk)) +- return dev_err_probe(&pdev->dev, PTR_ERR(info->pclk), +- "failed to get pclk\n"); +- +- info->clk = devm_clk_get(&pdev->dev, "saradc"); +- if (IS_ERR(info->clk)) +- return dev_err_probe(&pdev->dev, PTR_ERR(info->clk), +- "failed to get adc clock\n"); +- + info->vref = devm_regulator_get(&pdev->dev, "vref"); + if (IS_ERR(info->vref)) + return dev_err_probe(&pdev->dev, PTR_ERR(info->vref), +@@ -540,31 +516,15 @@ static int rockchip_saradc_probe(struct platform_device *pdev) + + info->uv_vref = ret; + +- ret = clk_prepare_enable(info->pclk); +- if (ret < 0) { +- dev_err(&pdev->dev, "failed to enable pclk\n"); +- return ret; +- } +- ret = devm_add_action_or_reset(&pdev->dev, +- rockchip_saradc_pclk_disable, info); +- if (ret) { +- dev_err(&pdev->dev, "failed to register devm action, %d\n", +- ret); +- return ret; +- } ++ info->pclk = devm_clk_get_enabled(&pdev->dev, "apb_pclk"); ++ if (IS_ERR(info->pclk)) ++ return dev_err_probe(&pdev->dev, PTR_ERR(info->pclk), ++ "failed to get pclk\n"); + +- ret = clk_prepare_enable(info->clk); +- if (ret < 0) { +- dev_err(&pdev->dev, "failed to enable converter clock\n"); +- return ret; +- } +- ret = devm_add_action_or_reset(&pdev->dev, +- rockchip_saradc_clk_disable, info); +- if (ret) { +- dev_err(&pdev->dev, "failed to register devm action, %d\n", +- ret); +- return ret; +- } ++ info->clk = devm_clk_get_enabled(&pdev->dev, "saradc"); ++ if (IS_ERR(info->clk)) ++ return dev_err_probe(&pdev->dev, PTR_ERR(info->clk), ++ "failed to get adc clock\n"); + + platform_set_drvdata(pdev, indio_dev); + +-- +2.41.0 + + +From 412fdfbbfc17c588c1f9ae3ee838c29860549f8e Mon Sep 17 00:00:00 2001 +From: Shreeya Patel +Date: Sun, 4 Jun 2023 00:23:36 +0530 +Subject: [PATCH 4/9] iio: adc: rockchip_saradc: Use of_device_get_match_data + +Use of_device_get_match_data() to simplify the code. + +Signed-off-by: Shreeya Patel +Reviewed-by: AngeloGioacchino Del Regno +--- + drivers/iio/adc/rockchip_saradc.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/iio/adc/rockchip_saradc.c b/drivers/iio/adc/rockchip_saradc.c +index ac424ea50787..cbe347fe8df7 100644 +--- a/drivers/iio/adc/rockchip_saradc.c ++++ b/drivers/iio/adc/rockchip_saradc.c +@@ -415,10 +415,10 @@ static void rockchip_saradc_regulator_unreg_notifier(void *data) + + static int rockchip_saradc_probe(struct platform_device *pdev) + { ++ const struct rockchip_saradc_data *match_data; + struct rockchip_saradc *info = NULL; + struct device_node *np = pdev->dev.of_node; + struct iio_dev *indio_dev = NULL; +- const struct of_device_id *match; + int ret; + int irq; + +@@ -432,13 +432,13 @@ static int rockchip_saradc_probe(struct platform_device *pdev) + } + info = iio_priv(indio_dev); + +- match = of_match_device(rockchip_saradc_match, &pdev->dev); +- if (!match) { ++ match_data = of_device_get_match_data(&pdev->dev); ++ if (!match_data) { + dev_err(&pdev->dev, "failed to match device\n"); + return -ENODEV; + } + +- info->data = match->data; ++ info->data = match_data; + + /* Sanity check for possible later IP variants with more channels */ + if (info->data->num_channels > SARADC_MAX_CHANNELS) { +-- +2.41.0 + + +From 7706b5ab350facf848f44aa846a2d26a8fa64a65 Mon Sep 17 00:00:00 2001 +From: Shreeya Patel +Date: Sun, 4 Jun 2023 00:23:37 +0530 +Subject: [PATCH 5/9] iio: adc: rockchip_saradc: Match alignment with open + parenthesis + +Match alignment with open parenthesis for improving the code +readability. + +Signed-off-by: Shreeya Patel +Reviewed-by: AngeloGioacchino Del Regno +--- + drivers/iio/adc/rockchip_saradc.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/drivers/iio/adc/rockchip_saradc.c b/drivers/iio/adc/rockchip_saradc.c +index cbe347fe8df7..436e219984fd 100644 +--- a/drivers/iio/adc/rockchip_saradc.c ++++ b/drivers/iio/adc/rockchip_saradc.c +@@ -151,7 +151,7 @@ static void rockchip_saradc_power_down(struct rockchip_saradc *info) + } + + static int rockchip_saradc_conversion(struct rockchip_saradc *info, +- struct iio_chan_spec const *chan) ++ struct iio_chan_spec const *chan) + { + reinit_completion(&info->completion); + +@@ -394,8 +394,7 @@ static irqreturn_t rockchip_saradc_trigger_handler(int irq, void *p) + } + + static int rockchip_saradc_volt_notify(struct notifier_block *nb, +- unsigned long event, +- void *data) ++ unsigned long event, void *data) + { + struct rockchip_saradc *info = + container_of(nb, struct rockchip_saradc, nb); +-- +2.41.0 + + +From 6511ca5e340de5a0d146d86a705f839ffdeb35ec Mon Sep 17 00:00:00 2001 +From: Shreeya Patel +Date: Sun, 4 Jun 2023 00:23:38 +0530 +Subject: [PATCH 6/9] iio: adc: rockchip_saradc: Use dev_err_probe + +Use dev_err_probe instead of dev_err in probe function, +which simplifies code a little bit and prints the error +code. + +Signed-off-by: Shreeya Patel +--- + drivers/iio/adc/rockchip_saradc.c | 45 ++++++++++++++----------------- + 1 file changed, 20 insertions(+), 25 deletions(-) + +diff --git a/drivers/iio/adc/rockchip_saradc.c b/drivers/iio/adc/rockchip_saradc.c +index 436e219984fd..921844d9232d 100644 +--- a/drivers/iio/adc/rockchip_saradc.c ++++ b/drivers/iio/adc/rockchip_saradc.c +@@ -425,25 +425,23 @@ static int rockchip_saradc_probe(struct platform_device *pdev) + return -ENODEV; + + indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*info)); +- if (!indio_dev) { +- dev_err(&pdev->dev, "failed allocating iio device\n"); +- return -ENOMEM; +- } ++ if (!indio_dev) ++ return dev_err_probe(&pdev->dev, -ENOMEM, ++ "failed allocating iio device\n"); ++ + info = iio_priv(indio_dev); + + match_data = of_device_get_match_data(&pdev->dev); +- if (!match_data) { +- dev_err(&pdev->dev, "failed to match device\n"); +- return -ENODEV; +- } ++ if (!match_data) ++ return dev_err_probe(&pdev->dev, -ENODEV, ++ "failed to match device\n"); + + info->data = match_data; + + /* Sanity check for possible later IP variants with more channels */ +- if (info->data->num_channels > SARADC_MAX_CHANNELS) { +- dev_err(&pdev->dev, "max channels exceeded"); +- return -EINVAL; +- } ++ if (info->data->num_channels > SARADC_MAX_CHANNELS) ++ return dev_err_probe(&pdev->dev, -EINVAL, ++ "max channels exceeded"); + + info->regs = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(info->regs)) +@@ -491,23 +489,20 @@ static int rockchip_saradc_probe(struct platform_device *pdev) + * This may become user-configurable in the future. + */ + ret = clk_set_rate(info->clk, info->data->clk_rate); +- if (ret < 0) { +- dev_err(&pdev->dev, "failed to set adc clk rate, %d\n", ret); +- return ret; +- } ++ if (ret < 0) ++ return dev_err_probe(&pdev->dev, ret, ++ "failed to set adc clk rate\n"); + + ret = regulator_enable(info->vref); +- if (ret < 0) { +- dev_err(&pdev->dev, "failed to enable vref regulator\n"); +- return ret; +- } ++ if (ret < 0) ++ return dev_err_probe(&pdev->dev, ret, ++ "failed to enable vref regulator\n"); ++ + ret = devm_add_action_or_reset(&pdev->dev, + rockchip_saradc_regulator_disable, info); +- if (ret) { +- dev_err(&pdev->dev, "failed to register devm action, %d\n", +- ret); +- return ret; +- } ++ if (ret) ++ return dev_err_probe(&pdev->dev, ret, ++ "failed to register devm action\n"); + + ret = regulator_get_voltage(info->vref); + if (ret < 0) +-- +2.41.0 + + +From 97f4513badc89771a4823235dab215078534419a Mon Sep 17 00:00:00 2001 +From: Shreeya Patel +Date: Sun, 4 Jun 2023 00:23:39 +0530 +Subject: [PATCH 7/9] arm64: dts: rockchip: Add DT node for ADC support in + RK3588 + +Add DT node for ADC support in RK3588. + +Signed-off-by: Shreeya Patel +--- + arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi +index 977ed617f59e..e7622a44c9ea 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi +@@ -1906,6 +1906,18 @@ dmac2: dma-controller@fed10000 { + #dma-cells = <1>; + }; + ++ saradc: saradc@fec10000 { ++ compatible = "rockchip,rk3588-saradc"; ++ reg = <0x0 0xfec10000 0x0 0x10000>; ++ interrupts = ; ++ #io-channel-cells = <1>; ++ clocks = <&cru CLK_SARADC>, <&cru PCLK_SARADC>; ++ clock-names = "saradc", "apb_pclk"; ++ resets = <&cru SRST_P_SARADC>; ++ reset-names = "saradc-apb"; ++ status = "disabled"; ++ }; ++ + system_sram2: sram@ff001000 { + compatible = "mmio-sram"; + reg = <0x0 0xff001000 0x0 0xef000>; +-- +2.41.0 + + +From a4bde5a0ce8037f213cb1ede73181c55d108df6a Mon Sep 17 00:00:00 2001 +From: Shreeya Patel +Date: Sun, 4 Jun 2023 00:23:40 +0530 +Subject: [PATCH 8/9] dt-bindings: iio: adc: Add rockchip,rk3588-saradc string + +Add rockchip,rk3588-saradc compatible string. + +Signed-off-by: Shreeya Patel +Acked-by: Krzysztof Kozlowski +--- + Documentation/devicetree/bindings/iio/adc/rockchip-saradc.yaml | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/Documentation/devicetree/bindings/iio/adc/rockchip-saradc.yaml b/Documentation/devicetree/bindings/iio/adc/rockchip-saradc.yaml +index da50b529c157..11c27ea451c8 100644 +--- a/Documentation/devicetree/bindings/iio/adc/rockchip-saradc.yaml ++++ b/Documentation/devicetree/bindings/iio/adc/rockchip-saradc.yaml +@@ -21,6 +21,7 @@ properties: + - rockchip,rk3308-saradc + - rockchip,rk3328-saradc + - rockchip,rk3568-saradc ++ - rockchip,rk3588-saradc + - rockchip,rv1108-saradc + - rockchip,rv1126-saradc + - const: rockchip,rk3399-saradc +-- +2.41.0 + + +From 0bea534abbafa0f8d43fb27c65d9c9d84f3269f3 Mon Sep 17 00:00:00 2001 +From: Shreeya Patel +Date: Sun, 11 Jun 2023 00:56:47 +0530 +Subject: [PATCH 9/9] dt-bindings: iio: rockchip: Fix 'oneOf' condition failed + warning + +rk3588-saradc isn't compatible with the rk3399-saradc variant, +hence, fix the following dtbs_check warning for 'oneOf' condition +failure. + +DTC_CHK arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dtb +/home/shreeya/linux/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dtb: + saradc@fec10000: compatible: 'oneOf' conditional failed, + one must be fixed: + ['rockchip,rk3588-saradc'] is too short + 'rockchip,saradc' was expected + 'rockchip,rk3066-tsadc' was expected + 'rockchip,rk3399-saradc' was expected + +Signed-off-by: Shreeya Patel +--- + Documentation/devicetree/bindings/iio/adc/rockchip-saradc.yaml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Documentation/devicetree/bindings/iio/adc/rockchip-saradc.yaml b/Documentation/devicetree/bindings/iio/adc/rockchip-saradc.yaml +index 11c27ea451c8..aa24b841393c 100644 +--- a/Documentation/devicetree/bindings/iio/adc/rockchip-saradc.yaml ++++ b/Documentation/devicetree/bindings/iio/adc/rockchip-saradc.yaml +@@ -15,13 +15,13 @@ properties: + - const: rockchip,saradc + - const: rockchip,rk3066-tsadc + - const: rockchip,rk3399-saradc ++ - const: rockchip,rk3588-saradc + - items: + - enum: + - rockchip,px30-saradc + - rockchip,rk3308-saradc + - rockchip,rk3328-saradc + - rockchip,rk3568-saradc +- - rockchip,rk3588-saradc + - rockchip,rv1108-saradc + - rockchip,rv1126-saradc + - const: rockchip,rk3399-saradc +-- +2.41.0 + diff --git a/patch/kernel/rockchip-rk3588-edge/0021-Add-RK3588-SATA-support.patch b/patch/kernel/rockchip-rk3588-edge/0021-Add-RK3588-SATA-support.patch new file mode 100644 index 0000000000..a2a316187d --- /dev/null +++ b/patch/kernel/rockchip-rk3588-edge/0021-Add-RK3588-SATA-support.patch @@ -0,0 +1,530 @@ +From 03b582ba80822d93be46e13ca7121f99c7132da8 Mon Sep 17 00:00:00 2001 +From: Sebastian Reichel +Date: Mon, 12 Jun 2023 19:13:33 +0200 +Subject: [PATCH 1/5] dt-bindings: ata: dwc-ahci: add PHY clocks + +Add PHY transmit and receive clocks as described by the +DW SATA AHCI HW manual. + +Suggested-by: Serge Semin +Reviewed-by: Serge Semin +Reviewed-by: Krzysztof Kozlowski +Signed-off-by: Sebastian Reichel +--- + .../devicetree/bindings/ata/snps,dwc-ahci-common.yaml | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/Documentation/devicetree/bindings/ata/snps,dwc-ahci-common.yaml b/Documentation/devicetree/bindings/ata/snps,dwc-ahci-common.yaml +index c1457910520b..34c5bf65b02d 100644 +--- a/Documentation/devicetree/bindings/ata/snps,dwc-ahci-common.yaml ++++ b/Documentation/devicetree/bindings/ata/snps,dwc-ahci-common.yaml +@@ -31,11 +31,11 @@ properties: + PM-alive clock, RxOOB detection clock, embedded PHYs reference (Rx/Tx) + clock, etc. + minItems: 1 +- maxItems: 4 ++ maxItems: 6 + + clock-names: + minItems: 1 +- maxItems: 4 ++ maxItems: 6 + items: + oneOf: + - description: Application APB/AHB/AXI BIU clock +@@ -48,6 +48,10 @@ properties: + const: pmalive + - description: RxOOB detection clock + const: rxoob ++ - description: PHY Transmit Clock ++ const: asic ++ - description: PHY Receive Clock ++ const: rbc + - description: SATA Ports reference clock + const: ref + +-- +2.41.0 + + +From 81b1ff2b1b72caa5ed7776df1547bbddc83395e8 Mon Sep 17 00:00:00 2001 +From: Sebastian Reichel +Date: Mon, 12 Jun 2023 19:13:34 +0200 +Subject: [PATCH 2/5] dt-bindings: ata: dwc-ahci: add Rockchip RK3588 + +This adds Rockchip RK3588 AHCI binding. In order to narrow down the +allowed clocks without bloating the generic binding, the description +of Rockchip's AHCI controllers has been moved to its own file. + +Signed-off-by: Sebastian Reichel +Reviewed-by: Serge Semin +Reviewed-by: Krzysztof Kozlowski +--- + .../bindings/ata/rockchip,dwc-ahci.yaml | 124 ++++++++++++++++++ + .../bindings/ata/snps,dwc-ahci.yaml | 13 +- + 2 files changed, 133 insertions(+), 4 deletions(-) + create mode 100644 Documentation/devicetree/bindings/ata/rockchip,dwc-ahci.yaml + +diff --git a/Documentation/devicetree/bindings/ata/rockchip,dwc-ahci.yaml b/Documentation/devicetree/bindings/ata/rockchip,dwc-ahci.yaml +new file mode 100644 +index 000000000000..b5e5767d8698 +--- /dev/null ++++ b/Documentation/devicetree/bindings/ata/rockchip,dwc-ahci.yaml +@@ -0,0 +1,124 @@ ++# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) ++%YAML 1.2 ++--- ++$id: http://devicetree.org/schemas/ata/rockchip,dwc-ahci.yaml# ++$schema: http://devicetree.org/meta-schemas/core.yaml# ++ ++title: Synopsys DWC AHCI SATA controller for Rockchip devices ++ ++maintainers: ++ - Serge Semin ++ ++description: ++ This document defines device tree bindings for the Synopsys DWC ++ implementation of the AHCI SATA controller found in Rockchip ++ devices. ++ ++select: ++ properties: ++ compatible: ++ contains: ++ enum: ++ - rockchip,rk3568-dwc-ahci ++ - rockchip,rk3588-dwc-ahci ++ required: ++ - compatible ++ ++properties: ++ compatible: ++ items: ++ - enum: ++ - rockchip,rk3568-dwc-ahci ++ - rockchip,rk3588-dwc-ahci ++ - const: snps,dwc-ahci ++ ++ ports-implemented: ++ const: 1 ++ ++ sata-port@0: ++ $ref: /schemas/ata/snps,dwc-ahci-common.yaml#/$defs/dwc-ahci-port ++ ++ properties: ++ reg: ++ const: 0 ++ ++ unevaluatedProperties: false ++ ++patternProperties: ++ "^sata-port@[1-9a-e]$": false ++ ++required: ++ - compatible ++ - reg ++ - interrupts ++ - clocks ++ - clock-names ++ - ports-implemented ++ ++allOf: ++ - $ref: snps,dwc-ahci-common.yaml# ++ - if: ++ properties: ++ compatible: ++ contains: ++ enum: ++ - rockchip,rk3588-dwc-ahci ++ then: ++ properties: ++ clocks: ++ maxItems: 5 ++ clock-names: ++ items: ++ - const: sata ++ - const: pmalive ++ - const: rxoob ++ - const: ref ++ - const: asic ++ - if: ++ properties: ++ compatible: ++ contains: ++ enum: ++ - rockchip,rk3568-dwc-ahci ++ then: ++ properties: ++ clocks: ++ maxItems: 3 ++ clock-names: ++ items: ++ - const: sata ++ - const: pmalive ++ - const: rxoob ++ ++unevaluatedProperties: false ++ ++examples: ++ - | ++ #include ++ #include ++ #include ++ #include ++ ++ sata@fe210000 { ++ compatible = "rockchip,rk3588-dwc-ahci", "snps,dwc-ahci"; ++ reg = <0xfe210000 0x1000>; ++ clocks = <&cru ACLK_SATA0>, <&cru CLK_PMALIVE0>, ++ <&cru CLK_RXOOB0>, <&cru CLK_PIPEPHY0_REF>, ++ <&cru CLK_PIPEPHY0_PIPE_ASIC_G>; ++ clock-names = "sata", "pmalive", "rxoob", "ref", "asic"; ++ interrupts = ; ++ ports-implemented = <0x1>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ sata-port@0 { ++ reg = <0>; ++ hba-port-cap = ; ++ phys = <&combphy0_ps PHY_TYPE_SATA>; ++ phy-names = "sata-phy"; ++ snps,rx-ts-max = <32>; ++ snps,tx-ts-max = <32>; ++ }; ++ }; ++ ++... +diff --git a/Documentation/devicetree/bindings/ata/snps,dwc-ahci.yaml b/Documentation/devicetree/bindings/ata/snps,dwc-ahci.yaml +index 5afa4b57ce20..4c848fcb5a5d 100644 +--- a/Documentation/devicetree/bindings/ata/snps,dwc-ahci.yaml ++++ b/Documentation/devicetree/bindings/ata/snps,dwc-ahci.yaml +@@ -13,6 +13,15 @@ description: + This document defines device tree bindings for the generic Synopsys DWC + implementation of the AHCI SATA controller. + ++select: ++ properties: ++ compatible: ++ enum: ++ - snps,dwc-ahci ++ - snps,spear-ahci ++ required: ++ - compatible ++ + allOf: + - $ref: snps,dwc-ahci-common.yaml# + +@@ -23,10 +32,6 @@ properties: + const: snps,dwc-ahci + - description: SPEAr1340 AHCI SATA device + const: snps,spear-ahci +- - description: Rockhip RK3568 AHCI controller +- items: +- - const: rockchip,rk3568-dwc-ahci +- - const: snps,dwc-ahci + + patternProperties: + "^sata-port@[0-9a-e]$": +-- +2.41.0 + + +From 15f3049fcf0e6657c7f4c594b83f4df437a6c03c Mon Sep 17 00:00:00 2001 +From: Sebastian Reichel +Date: Mon, 12 Jun 2023 19:13:35 +0200 +Subject: [PATCH 3/5] dt-bindings: phy: rockchip: rk3588 has two reset lines + +The RK3588 has two reset lines for the combphy. One for the +APB interface and one for the actual PHY. + +Reviewed-by: Krzysztof Kozlowski +Signed-off-by: Sebastian Reichel +--- + .../phy/phy-rockchip-naneng-combphy.yaml | 34 ++++++++++++++++++- + 1 file changed, 33 insertions(+), 1 deletion(-) + +diff --git a/Documentation/devicetree/bindings/phy/phy-rockchip-naneng-combphy.yaml b/Documentation/devicetree/bindings/phy/phy-rockchip-naneng-combphy.yaml +index 9ae514fa7533..d3cd7997879f 100644 +--- a/Documentation/devicetree/bindings/phy/phy-rockchip-naneng-combphy.yaml ++++ b/Documentation/devicetree/bindings/phy/phy-rockchip-naneng-combphy.yaml +@@ -31,8 +31,14 @@ properties: + - const: pipe + + resets: ++ minItems: 1 ++ maxItems: 2 ++ ++ reset-names: ++ minItems: 1 + items: +- - description: exclusive PHY reset line ++ - const: phy ++ - const: apb + + rockchip,enable-ssc: + type: boolean +@@ -78,6 +84,32 @@ required: + - rockchip,pipe-phy-grf + - "#phy-cells" + ++allOf: ++ - if: ++ properties: ++ compatible: ++ contains: ++ const: rockchip,rk3568-naneng-combphy ++ then: ++ properties: ++ resets: ++ maxItems: 1 ++ reset-names: ++ maxItems: 1 ++ - if: ++ properties: ++ compatible: ++ contains: ++ const: rockchip,rk3588-naneng-combphy ++ then: ++ properties: ++ resets: ++ minItems: 2 ++ reset-names: ++ minItems: 2 ++ required: ++ - reset-names ++ + additionalProperties: false + + examples: +-- +2.41.0 + + +From 571fb8a07c593ddafa101138ef89d346677cc518 Mon Sep 17 00:00:00 2001 +From: Muhammed Efe Cetin +Date: Tue, 4 Jul 2023 13:11:19 +0300 +Subject: [PATCH 4/5] arm64: dts: rockchip: rk3588: add combo PHYs + +Add all 3 combo PHYs that can be found in RK3588. +They are used for SATA, PCIe or USB3. +--- + arch/arm64/boot/dts/rockchip/rk3588.dtsi | 21 ++++++++++++ + arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 42 +++++++++++++++++++++++ + 2 files changed, 63 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3588.dtsi b/arch/arm64/boot/dts/rockchip/rk3588.dtsi +index 8be75556af8f..9d8539b5309b 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3588.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3588.dtsi +@@ -7,6 +7,11 @@ + #include "rk3588-pinctrl.dtsi" + + / { ++ pipe_phy1_grf: syscon@fd5c0000 { ++ compatible = "rockchip,rk3588-pipe-phy-grf", "syscon"; ++ reg = <0x0 0xfd5c0000 0x0 0x100>; ++ }; ++ + i2s8_8ch: i2s@fddc8000 { + compatible = "rockchip,rk3588-i2s-tdm"; + reg = <0x0 0xfddc8000 0x0 0x1000>; +@@ -123,4 +128,20 @@ gmac0_mtl_tx_setup: tx-queues-config { + queue1 {}; + }; + }; ++ ++ combphy1_ps: phy@fee10000 { ++ compatible = "rockchip,rk3588-naneng-combphy"; ++ reg = <0x0 0xfee10000 0x0 0x100>; ++ #phy-cells = <1>; ++ clocks = <&cru CLK_REF_PIPE_PHY1>, <&cru PCLK_PCIE_COMBO_PIPE_PHY1>, ++ <&cru PCLK_PHP_ROOT>; ++ clock-names = "ref", "apb", "pipe"; ++ assigned-clocks = <&cru CLK_REF_PIPE_PHY1>; ++ assigned-clock-rates = <100000000>; ++ resets = <&cru SRST_REF_PIPE_PHY1>, <&cru SRST_P_PCIE2_PHY1>; ++ reset-names = "phy", "apb"; ++ rockchip,pipe-grf = <&php_grf>; ++ rockchip,pipe-phy-grf = <&pipe_phy1_grf>; ++ status = "disabled"; ++ }; + }; +diff --git a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi +index e7622a44c9ea..4aa15ce78365 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi +@@ -407,6 +407,16 @@ php_grf: syscon@fd5b0000 { + reg = <0x0 0xfd5b0000 0x0 0x1000>; + }; + ++ pipe_phy0_grf: syscon@fd5bc000 { ++ compatible = "rockchip,rk3588-pipe-phy-grf", "syscon"; ++ reg = <0x0 0xfd5bc000 0x0 0x100>; ++ }; ++ ++ pipe_phy2_grf: syscon@fd5c4000 { ++ compatible = "rockchip,rk3588-pipe-phy-grf", "syscon"; ++ reg = <0x0 0xfd5c4000 0x0 0x100>; ++ }; ++ + ioc: syscon@fd5f0000 { + compatible = "rockchip,rk3588-ioc", "syscon"; + reg = <0x0 0xfd5f0000 0x0 0x10000>; +@@ -1906,6 +1916,38 @@ dmac2: dma-controller@fed10000 { + #dma-cells = <1>; + }; + ++ combphy0_ps: phy@fee00000 { ++ compatible = "rockchip,rk3588-naneng-combphy"; ++ reg = <0x0 0xfee00000 0x0 0x100>; ++ #phy-cells = <1>; ++ clocks = <&cru CLK_REF_PIPE_PHY0>, <&cru PCLK_PCIE_COMBO_PIPE_PHY0>, ++ <&cru PCLK_PHP_ROOT>; ++ clock-names = "ref", "apb", "pipe"; ++ assigned-clocks = <&cru CLK_REF_PIPE_PHY0>; ++ assigned-clock-rates = <100000000>; ++ resets = <&cru SRST_REF_PIPE_PHY0>, <&cru SRST_P_PCIE2_PHY0>; ++ reset-names = "phy", "apb"; ++ rockchip,pipe-grf = <&php_grf>; ++ rockchip,pipe-phy-grf = <&pipe_phy0_grf>; ++ status = "disabled"; ++ }; ++ ++ combphy2_psu: phy@fee20000 { ++ compatible = "rockchip,rk3588-naneng-combphy"; ++ reg = <0x0 0xfee20000 0x0 0x100>; ++ #phy-cells = <1>; ++ clocks = <&cru CLK_REF_PIPE_PHY2>, <&cru PCLK_PCIE_COMBO_PIPE_PHY2>, ++ <&cru PCLK_PHP_ROOT>; ++ clock-names = "ref", "apb", "pipe"; ++ assigned-clocks = <&cru CLK_REF_PIPE_PHY2>; ++ assigned-clock-rates = <100000000>; ++ resets = <&cru SRST_REF_PIPE_PHY2>, <&cru SRST_P_PCIE2_PHY2>; ++ reset-names = "phy", "apb"; ++ rockchip,pipe-grf = <&php_grf>; ++ rockchip,pipe-phy-grf = <&pipe_phy2_grf>; ++ status = "disabled"; ++ }; ++ + saradc: saradc@fec10000 { + compatible = "rockchip,rk3588-saradc"; + reg = <0x0 0xfec10000 0x0 0x10000>; +-- +2.41.0 + + +From 95ad8212851df865bb4146278a7bc782bca45880 Mon Sep 17 00:00:00 2001 +From: Muhammed Efe Cetin +Date: Tue, 4 Jul 2023 13:16:57 +0300 +Subject: [PATCH 5/5] arm64: dts: rockchip: rk3588: add SATA support + +Add all three SATA IP blocks to the RK3588 DT. +--- + arch/arm64/boot/dts/rockchip/rk3588.dtsi | 23 +++++++++++ + arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 48 +++++++++++++++++++++++ + 2 files changed, 71 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3588.dtsi b/arch/arm64/boot/dts/rockchip/rk3588.dtsi +index 9d8539b5309b..b9508cea34f1 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3588.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3588.dtsi +@@ -129,6 +129,29 @@ gmac0_mtl_tx_setup: tx-queues-config { + }; + }; + ++ sata1: sata@fe220000 { ++ compatible = "rockchip,rk3588-dwc-ahci", "snps,dwc-ahci"; ++ reg = <0 0xfe220000 0 0x1000>; ++ clocks = <&cru ACLK_SATA1>, <&cru CLK_PMALIVE1>, ++ <&cru CLK_RXOOB1>, <&cru CLK_PIPEPHY1_REF>, ++ <&cru CLK_PIPEPHY1_PIPE_ASIC_G>; ++ clock-names = "sata", "pmalive", "rxoob", "ref", "asic"; ++ interrupts = ; ++ ports-implemented = <0x1>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "disabled"; ++ ++ sata-port@0 { ++ reg = <0>; ++ hba-port-cap = ; ++ phys = <&combphy1_ps PHY_TYPE_SATA>; ++ phy-names = "sata-phy"; ++ snps,rx-ts-max = <32>; ++ snps,tx-ts-max = <32>; ++ }; ++ }; ++ + combphy1_ps: phy@fee10000 { + compatible = "rockchip,rk3588-naneng-combphy"; + reg = <0x0 0xfee10000 0x0 0x100>; +diff --git a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi +index 4aa15ce78365..ee091f0a3ca3 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi +@@ -8,6 +8,8 @@ + #include + #include + #include ++#include ++#include + + / { + compatible = "rockchip,rk3588"; +@@ -1180,6 +1182,52 @@ gmac1_mtl_tx_setup: tx-queues-config { + }; + }; + ++ sata0: sata@fe210000 { ++ compatible = "rockchip,rk3588-dwc-ahci", "snps,dwc-ahci"; ++ reg = <0 0xfe210000 0 0x1000>; ++ clocks = <&cru ACLK_SATA0>, <&cru CLK_PMALIVE0>, ++ <&cru CLK_RXOOB0>, <&cru CLK_PIPEPHY0_REF>, ++ <&cru CLK_PIPEPHY0_PIPE_ASIC_G>; ++ clock-names = "sata", "pmalive", "rxoob", "ref", "asic"; ++ interrupts = ; ++ ports-implemented = <0x1>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "disabled"; ++ ++ sata-port@0 { ++ reg = <0>; ++ hba-port-cap = ; ++ phys = <&combphy0_ps PHY_TYPE_SATA>; ++ phy-names = "sata-phy"; ++ snps,rx-ts-max = <32>; ++ snps,tx-ts-max = <32>; ++ }; ++ }; ++ ++ sata2: sata@fe230000 { ++ compatible = "rockchip,rk3588-dwc-ahci", "snps,dwc-ahci"; ++ reg = <0 0xfe230000 0 0x1000>; ++ clocks = <&cru ACLK_SATA2>, <&cru CLK_PMALIVE2>, ++ <&cru CLK_RXOOB2>, <&cru CLK_PIPEPHY2_REF>, ++ <&cru CLK_PIPEPHY2_PIPE_ASIC_G>; ++ clock-names = "sata", "pmalive", "rxoob", "ref", "asic"; ++ interrupts = ; ++ ports-implemented = <0x1>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "disabled"; ++ ++ sata-port@0 { ++ reg = <0>; ++ hba-port-cap = ; ++ phys = <&combphy2_psu PHY_TYPE_SATA>; ++ phy-names = "sata-phy"; ++ snps,rx-ts-max = <32>; ++ snps,tx-ts-max = <32>; ++ }; ++ }; ++ + sdmmc: mmc@fe2c0000 { + compatible = "rockchip,rk3588-dw-mshc", "rockchip,rk3288-dw-mshc"; + reg = <0x0 0xfe2c0000 0x0 0x4000>; +-- +2.41.0 + diff --git a/patch/kernel/rockchip-rk3588-edge/0022-RK3588-PCIe2-support.patch b/patch/kernel/rockchip-rk3588-edge/0022-RK3588-PCIe2-support.patch new file mode 100644 index 0000000000..9e33123ca8 --- /dev/null +++ b/patch/kernel/rockchip-rk3588-edge/0022-RK3588-PCIe2-support.patch @@ -0,0 +1,436 @@ +From 55f62897ce675d323b81dc92e9ce9060543e61f3 Mon Sep 17 00:00:00 2001 +From: Sebastian Reichel +Date: Fri, 16 Jun 2023 19:00:19 +0200 +Subject: [PATCH 1/4] dt-bindings: PCI: dwc: rockchip: Fix interrupt-names + issue + +The RK356x (and RK3588) have 5 ganged interrupts. For example the +"legacy" interrupt combines "inta/intb/intc/intd" with a register +providing the details. + +Currently the binding is not specifying these interrupts resulting +in a bunch of errors for all rk356x boards using PCIe. + +Fix this by specifying the interrupts and add them to the example +to prevent regressions. + +Signed-off-by: Sebastian Reichel +Reviewed-by: Rob Herring +--- + .../bindings/pci/rockchip-dw-pcie.yaml | 18 ++++++++++++++++++ + .../devicetree/bindings/pci/snps,dw-pcie.yaml | 15 ++++++++++++++- + 2 files changed, 32 insertions(+), 1 deletion(-) + +diff --git a/Documentation/devicetree/bindings/pci/rockchip-dw-pcie.yaml b/Documentation/devicetree/bindings/pci/rockchip-dw-pcie.yaml +index 24c88942e59e..98e45d2d8dfe 100644 +--- a/Documentation/devicetree/bindings/pci/rockchip-dw-pcie.yaml ++++ b/Documentation/devicetree/bindings/pci/rockchip-dw-pcie.yaml +@@ -56,6 +56,17 @@ properties: + - const: pclk + - const: aux + ++ interrupts: ++ maxItems: 5 ++ ++ interrupt-names: ++ items: ++ - const: sys ++ - const: pmc ++ - const: msg ++ - const: legacy ++ - const: err ++ + msi-map: true + + num-lanes: true +@@ -98,6 +109,7 @@ unevaluatedProperties: false + + examples: + - | ++ #include + + bus { + #address-cells = <2>; +@@ -117,6 +129,12 @@ examples: + "aclk_dbi", "pclk", + "aux"; + device_type = "pci"; ++ interrupts = , ++ , ++ , ++ , ++ ; ++ interrupt-names = "sys", "pmc", "msg", "legacy", "err"; + linux,pci-domain = <2>; + max-link-speed = <2>; + msi-map = <0x2000 &its 0x2000 0x1000>; +diff --git a/Documentation/devicetree/bindings/pci/snps,dw-pcie.yaml b/Documentation/devicetree/bindings/pci/snps,dw-pcie.yaml +index 1a83f0f65f19..9f605eb297f5 100644 +--- a/Documentation/devicetree/bindings/pci/snps,dw-pcie.yaml ++++ b/Documentation/devicetree/bindings/pci/snps,dw-pcie.yaml +@@ -193,9 +193,22 @@ properties: + oneOf: + - description: See native "app" IRQ for details + enum: [ intr ] ++ - description: Combined Legacy A/B/C/D interrupt signal. ++ const: legacy ++ - description: Combined System interrupt signal. ++ const: sys ++ - description: Combined Power Management interrupt signal. ++ const: pmc ++ - description: Combined Message Received interrupt signal. ++ const: msg ++ - description: Combined Error interrupt signal. ++ const: err ++ + allOf: + - contains: +- const: msi ++ enum: ++ - msi ++ - msg + + additionalProperties: true + +-- +2.41.0 + + +From ed28eed118bb1815347fbb4ea3e4ebb2a917e2b4 Mon Sep 17 00:00:00 2001 +From: Sebastian Reichel +Date: Fri, 16 Jun 2023 19:00:20 +0200 +Subject: [PATCH 2/4] dt-bindings: PCI: dwc: rockchip: Add missing + legacy-interrupt-controller + +Rockchip RK356x and RK3588 handle legacy interrupts via a ganged +interrupts. The RK356x DT implements this via a sub-node named +"legacy-interrupt-controller", just like a couple of other PCIe +implementations. This adds proper documentation for this and updates +the example to avoid regressions. + +Signed-off-by: Sebastian Reichel +Reviewed-by: Rob Herring +--- + .../bindings/pci/rockchip-dw-pcie.yaml | 24 +++++++++++++++++++ + 1 file changed, 24 insertions(+) + +diff --git a/Documentation/devicetree/bindings/pci/rockchip-dw-pcie.yaml b/Documentation/devicetree/bindings/pci/rockchip-dw-pcie.yaml +index 98e45d2d8dfe..bf81d306cc80 100644 +--- a/Documentation/devicetree/bindings/pci/rockchip-dw-pcie.yaml ++++ b/Documentation/devicetree/bindings/pci/rockchip-dw-pcie.yaml +@@ -67,6 +67,22 @@ properties: + - const: legacy + - const: err + ++ legacy-interrupt-controller: ++ description: Interrupt controller node for handling legacy PCI interrupts. ++ type: object ++ properties: ++ "#address-cells": ++ const: 0 ++ ++ "#interrupt-cells": ++ const: 1 ++ ++ "interrupt-controller": true ++ ++ interrupts: ++ items: ++ - description: combined legacy interrupt ++ + msi-map: true + + num-lanes: true +@@ -148,6 +164,14 @@ examples: + reset-names = "pipe"; + #address-cells = <3>; + #size-cells = <2>; ++ ++ legacy-interrupt-controller { ++ interrupt-controller; ++ #address-cells = <0>; ++ #interrupt-cells = <1>; ++ interrupt-parent = <&gic>; ++ interrupts = ; ++ }; + }; + }; + ... +-- +2.41.0 + + +From 4298296463a25b9a7830001da790e8240654337a Mon Sep 17 00:00:00 2001 +From: Sebastian Reichel +Date: Fri, 16 Jun 2023 19:00:21 +0200 +Subject: [PATCH 3/4] dt-bindings: PCI: dwc: rockchip: Update for RK3588 + +The PCIe 2.0 controllers on RK3588 need one additional clock, +one additional reset line and one for ranges entry. + +Signed-off-by: Sebastian Reichel +Reviewed-by: Rob Herring +Reviewed-by: Serge Semin +--- + .../bindings/pci/rockchip-dw-pcie.yaml | 16 +++++++++++++--- + 1 file changed, 13 insertions(+), 3 deletions(-) + +diff --git a/Documentation/devicetree/bindings/pci/rockchip-dw-pcie.yaml b/Documentation/devicetree/bindings/pci/rockchip-dw-pcie.yaml +index bf81d306cc80..7897af0ec297 100644 +--- a/Documentation/devicetree/bindings/pci/rockchip-dw-pcie.yaml ++++ b/Documentation/devicetree/bindings/pci/rockchip-dw-pcie.yaml +@@ -41,20 +41,24 @@ properties: + - const: config + + clocks: ++ minItems: 5 + items: + - description: AHB clock for PCIe master + - description: AHB clock for PCIe slave + - description: AHB clock for PCIe dbi + - description: APB clock for PCIe + - description: Auxiliary clock for PCIe ++ - description: PIPE clock + + clock-names: ++ minItems: 5 + items: + - const: aclk_mst + - const: aclk_slv + - const: aclk_dbi + - const: pclk + - const: aux ++ - const: pipe + + interrupts: + maxItems: 5 +@@ -97,13 +101,19 @@ properties: + maxItems: 1 + + ranges: +- maxItems: 2 ++ minItems: 2 ++ maxItems: 3 + + resets: +- maxItems: 1 ++ minItems: 1 ++ maxItems: 2 + + reset-names: +- const: pipe ++ oneOf: ++ - const: pipe ++ - items: ++ - const: pwr ++ - const: pipe + + vpcie3v3-supply: true + +-- +2.41.0 + + +From 83fbcafeea18de93601461ffd14311ea1ef8a433 Mon Sep 17 00:00:00 2001 +From: Sebastian Reichel +Date: Fri, 16 Jun 2023 19:00:22 +0200 +Subject: [PATCH 4/4] arm64: dts: rockchip: rk3588: add PCIe2 support + +Add all three PCIe2 IP blocks to the RK3588 DT. Note, that RK3588 +also has two PCIe3 IP blocks, that will be handled separately. + +Co-developed-by: Kever Yang +Signed-off-by: Kever Yang +Signed-off-by: Sebastian Reichel +--- + arch/arm64/boot/dts/rockchip/rk3588.dtsi | 54 +++++++++++ + arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 108 ++++++++++++++++++++++ + 2 files changed, 162 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3588.dtsi b/arch/arm64/boot/dts/rockchip/rk3588.dtsi +index b9508cea34f1..40fee1367b34 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3588.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3588.dtsi +@@ -80,6 +80,60 @@ i2s10_8ch: i2s@fde00000 { + status = "disabled"; + }; + ++ pcie2x1l0: pcie@fe170000 { ++ compatible = "rockchip,rk3588-pcie", "rockchip,rk3568-pcie"; ++ #address-cells = <3>; ++ #size-cells = <2>; ++ bus-range = <0x20 0x2f>; ++ clocks = <&cru ACLK_PCIE_1L0_MSTR>, <&cru ACLK_PCIE_1L0_SLV>, ++ <&cru ACLK_PCIE_1L0_DBI>, <&cru PCLK_PCIE_1L0>, ++ <&cru CLK_PCIE_AUX2>, <&cru CLK_PCIE1L0_PIPE>; ++ clock-names = "aclk_mst", "aclk_slv", ++ "aclk_dbi", "pclk", ++ "aux", "pipe"; ++ device_type = "pci"; ++ interrupts = , ++ , ++ , ++ , ++ ; ++ interrupt-names = "sys", "pmc", "msg", "legacy", "err"; ++ #interrupt-cells = <1>; ++ interrupt-map-mask = <0 0 0 7>; ++ interrupt-map = <0 0 0 1 &pcie2x1l0_intc 0>, ++ <0 0 0 2 &pcie2x1l0_intc 1>, ++ <0 0 0 3 &pcie2x1l0_intc 2>, ++ <0 0 0 4 &pcie2x1l0_intc 3>; ++ linux,pci-domain = <2>; ++ num-ib-windows = <8>; ++ num-ob-windows = <8>; ++ num-viewport = <4>; ++ max-link-speed = <2>; ++ msi-map = <0x2000 &its0 0x2000 0x1000>; ++ num-lanes = <1>; ++ phys = <&combphy1_ps PHY_TYPE_PCIE>; ++ phy-names = "pcie-phy"; ++ power-domains = <&power RK3588_PD_PCIE>; ++ ranges = <0x01000000 0x0 0xf2100000 0x0 0xf2100000 0x0 0x00100000>, ++ <0x02000000 0x0 0xf2200000 0x0 0xf2200000 0x0 0x00e00000>, ++ <0x03000000 0x9 0x80000000 0x9 0x80000000 0x0 0x40000000>; ++ reg = <0xa 0x40800000 0x0 0x00400000>, ++ <0x0 0xfe170000 0x0 0x00010000>, ++ <0x0 0xf2000000 0x0 0x00100000>; ++ reg-names = "dbi", "apb", "config"; ++ resets = <&cru SRST_PCIE2_POWER_UP>, <&cru SRST_P_PCIE2>; ++ reset-names = "pwr", "pipe"; ++ status = "disabled"; ++ ++ pcie2x1l0_intc: legacy-interrupt-controller { ++ interrupt-controller; ++ #address-cells = <0>; ++ #interrupt-cells = <1>; ++ interrupt-parent = <&gic>; ++ interrupts = ; ++ }; ++ }; ++ + gmac0: ethernet@fe1b0000 { + compatible = "rockchip,rk3588-gmac", "snps,dwmac-4.20a"; + reg = <0x0 0xfe1b0000 0x0 0x10000>; +diff --git a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi +index ee091f0a3ca3..973fd6e8aa36 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi +@@ -1133,6 +1133,114 @@ qos_vop_m1: qos@fdf82200 { + reg = <0x0 0xfdf82200 0x0 0x20>; + }; + ++ pcie2x1l1: pcie@fe180000 { ++ compatible = "rockchip,rk3588-pcie", "rockchip,rk3568-pcie"; ++ #address-cells = <3>; ++ #size-cells = <2>; ++ bus-range = <0x30 0x3f>; ++ clocks = <&cru ACLK_PCIE_1L1_MSTR>, <&cru ACLK_PCIE_1L1_SLV>, ++ <&cru ACLK_PCIE_1L1_DBI>, <&cru PCLK_PCIE_1L1>, ++ <&cru CLK_PCIE_AUX3>, <&cru CLK_PCIE1L1_PIPE>; ++ clock-names = "aclk_mst", "aclk_slv", ++ "aclk_dbi", "pclk", ++ "aux", "pipe"; ++ device_type = "pci"; ++ interrupts = , ++ , ++ , ++ , ++ ; ++ interrupt-names = "sys", "pmc", "msg", "legacy", "err"; ++ #interrupt-cells = <1>; ++ interrupt-map-mask = <0 0 0 7>; ++ interrupt-map = <0 0 0 1 &pcie2x1l1_intc 0>, ++ <0 0 0 2 &pcie2x1l1_intc 1>, ++ <0 0 0 3 &pcie2x1l1_intc 2>, ++ <0 0 0 4 &pcie2x1l1_intc 3>; ++ linux,pci-domain = <3>; ++ num-ib-windows = <8>; ++ num-ob-windows = <8>; ++ num-viewport = <4>; ++ max-link-speed = <2>; ++ msi-map = <0x3000 &its0 0x3000 0x1000>; ++ num-lanes = <1>; ++ phys = <&combphy2_psu PHY_TYPE_PCIE>; ++ phy-names = "pcie-phy"; ++ power-domains = <&power RK3588_PD_PCIE>; ++ ranges = <0x01000000 0x0 0xf3100000 0x0 0xf3100000 0x0 0x00100000>, ++ <0x02000000 0x0 0xf3200000 0x0 0xf3200000 0x0 0x00e00000>, ++ <0x03000000 0x9 0xc0000000 0x9 0xc0000000 0x0 0x40000000>; ++ reg = <0xa 0x40c00000 0x0 0x00400000>, ++ <0x0 0xfe180000 0x0 0x00010000>, ++ <0x0 0xf3000000 0x0 0x00100000>; ++ reg-names = "dbi", "apb", "config"; ++ resets = <&cru SRST_PCIE3_POWER_UP>, <&cru SRST_P_PCIE3>; ++ reset-names = "pwr", "pipe"; ++ status = "disabled"; ++ ++ pcie2x1l1_intc: legacy-interrupt-controller { ++ interrupt-controller; ++ #address-cells = <0>; ++ #interrupt-cells = <1>; ++ interrupt-parent = <&gic>; ++ interrupts = ; ++ }; ++ }; ++ ++ pcie2x1l2: pcie@fe190000 { ++ compatible = "rockchip,rk3588-pcie", "rockchip,rk3568-pcie"; ++ #address-cells = <3>; ++ #size-cells = <2>; ++ bus-range = <0x40 0x4f>; ++ clocks = <&cru ACLK_PCIE_1L2_MSTR>, <&cru ACLK_PCIE_1L2_SLV>, ++ <&cru ACLK_PCIE_1L2_DBI>, <&cru PCLK_PCIE_1L2>, ++ <&cru CLK_PCIE_AUX4>, <&cru CLK_PCIE1L2_PIPE>; ++ clock-names = "aclk_mst", "aclk_slv", ++ "aclk_dbi", "pclk", ++ "aux", "pipe"; ++ device_type = "pci"; ++ interrupts = , ++ , ++ , ++ , ++ ; ++ interrupt-names = "sys", "pmc", "msg", "legacy", "err"; ++ #interrupt-cells = <1>; ++ interrupt-map-mask = <0 0 0 7>; ++ interrupt-map = <0 0 0 1 &pcie2x1l2_intc 0>, ++ <0 0 0 2 &pcie2x1l2_intc 1>, ++ <0 0 0 3 &pcie2x1l2_intc 2>, ++ <0 0 0 4 &pcie2x1l2_intc 3>; ++ linux,pci-domain = <4>; ++ num-ib-windows = <8>; ++ num-ob-windows = <8>; ++ num-viewport = <4>; ++ max-link-speed = <2>; ++ msi-map = <0x4000 &its0 0x4000 0x1000>; ++ num-lanes = <1>; ++ phys = <&combphy0_ps PHY_TYPE_PCIE>; ++ phy-names = "pcie-phy"; ++ power-domains = <&power RK3588_PD_PCIE>; ++ ranges = <0x01000000 0x0 0xf4100000 0x0 0xf4100000 0x0 0x00100000>, ++ <0x02000000 0x0 0xf4200000 0x0 0xf4200000 0x0 0x00e00000>, ++ <0x03000000 0xa 0x00000000 0xa 0x00000000 0x0 0x40000000>; ++ reg = <0xa 0x41000000 0x0 0x00400000>, ++ <0x0 0xfe190000 0x0 0x00010000>, ++ <0x0 0xf4000000 0x0 0x00100000>; ++ reg-names = "dbi", "apb", "config"; ++ resets = <&cru SRST_PCIE4_POWER_UP>, <&cru SRST_P_PCIE4>; ++ reset-names = "pwr", "pipe"; ++ status = "disabled"; ++ ++ pcie2x1l2_intc: legacy-interrupt-controller { ++ interrupt-controller; ++ #address-cells = <0>; ++ #interrupt-cells = <1>; ++ interrupt-parent = <&gic>; ++ interrupts = ; ++ }; ++ }; ++ + gmac1: ethernet@fe1c0000 { + compatible = "rockchip,rk3588-gmac", "snps,dwmac-4.20a"; + reg = <0x0 0xfe1c0000 0x0 0x10000>; +-- +2.41.0 + diff --git a/patch/kernel/rockchip-rk3588-edge/0023-Add-RK3588-OTP-memory-support.patch b/patch/kernel/rockchip-rk3588-edge/0023-Add-RK3588-OTP-memory-support.patch new file mode 100644 index 0000000000..5dafc98965 --- /dev/null +++ b/patch/kernel/rockchip-rk3588-edge/0023-Add-RK3588-OTP-memory-support.patch @@ -0,0 +1,847 @@ +From a71fb1ef5b28f73ef42f4becc2c3fcb944797348 Mon Sep 17 00:00:00 2001 +From: Cristian Ciocaltea +Date: Thu, 4 May 2023 23:06:41 +0300 +Subject: [PATCH 1/9] dt-bindings: nvmem: Convert rockchip-otp.txt to dt-schema + +Convert the Rockchip OTP memory bindings to dt-schema. + +Signed-off-by: Cristian Ciocaltea +Reviewed-by: Heiko Stuebner +Reviewed-by: Krzysztof Kozlowski +--- + .../bindings/nvmem/rockchip,otp.yaml | 82 +++++++++++++++++++ + .../bindings/nvmem/rockchip-otp.txt | 25 ------ + 2 files changed, 82 insertions(+), 25 deletions(-) + create mode 100644 Documentation/devicetree/bindings/nvmem/rockchip,otp.yaml + delete mode 100644 Documentation/devicetree/bindings/nvmem/rockchip-otp.txt + +diff --git a/Documentation/devicetree/bindings/nvmem/rockchip,otp.yaml b/Documentation/devicetree/bindings/nvmem/rockchip,otp.yaml +new file mode 100644 +index 000000000000..4cd425ae2823 +--- /dev/null ++++ b/Documentation/devicetree/bindings/nvmem/rockchip,otp.yaml +@@ -0,0 +1,82 @@ ++# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) ++%YAML 1.2 ++--- ++$id: http://devicetree.org/schemas/nvmem/rockchip,otp.yaml# ++$schema: http://devicetree.org/meta-schemas/core.yaml# ++ ++title: Rockchip internal OTP (One Time Programmable) memory ++ ++maintainers: ++ - Heiko Stuebner ++ ++allOf: ++ - $ref: nvmem.yaml# ++ ++properties: ++ compatible: ++ enum: ++ - rockchip,px30-otp ++ - rockchip,rk3308-otp ++ ++ reg: ++ maxItems: 1 ++ ++ clocks: ++ maxItems: 3 ++ ++ clock-names: ++ items: ++ - const: otp ++ - const: apb_pclk ++ - const: phy ++ ++ resets: ++ maxItems: 1 ++ ++ reset-names: ++ items: ++ - const: phy ++ ++required: ++ - compatible ++ - reg ++ - clocks ++ - clock-names ++ - resets ++ - reset-names ++ ++unevaluatedProperties: false ++ ++examples: ++ - | ++ #include ++ ++ soc { ++ #address-cells = <2>; ++ #size-cells = <2>; ++ ++ otp: efuse@ff290000 { ++ compatible = "rockchip,px30-otp"; ++ reg = <0x0 0xff290000 0x0 0x4000>; ++ clocks = <&cru SCLK_OTP_USR>, <&cru PCLK_OTP_NS>, ++ <&cru PCLK_OTP_PHY>; ++ clock-names = "otp", "apb_pclk", "phy"; ++ resets = <&cru SRST_OTP_PHY>; ++ reset-names = "phy"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ cpu_id: id@7 { ++ reg = <0x07 0x10>; ++ }; ++ ++ cpu_leakage: cpu-leakage@17 { ++ reg = <0x17 0x1>; ++ }; ++ ++ performance: performance@1e { ++ reg = <0x1e 0x1>; ++ bits = <4 3>; ++ }; ++ }; ++ }; +diff --git a/Documentation/devicetree/bindings/nvmem/rockchip-otp.txt b/Documentation/devicetree/bindings/nvmem/rockchip-otp.txt +deleted file mode 100644 +index 40f649f7c2e5..000000000000 +--- a/Documentation/devicetree/bindings/nvmem/rockchip-otp.txt ++++ /dev/null +@@ -1,25 +0,0 @@ +-Rockchip internal OTP (One Time Programmable) memory device tree bindings +- +-Required properties: +-- compatible: Should be one of the following. +- - "rockchip,px30-otp" - for PX30 SoCs. +- - "rockchip,rk3308-otp" - for RK3308 SoCs. +-- reg: Should contain the registers location and size +-- clocks: Must contain an entry for each entry in clock-names. +-- clock-names: Should be "otp", "apb_pclk" and "phy". +-- resets: Must contain an entry for each entry in reset-names. +- See ../../reset/reset.txt for details. +-- reset-names: Should be "phy". +- +-See nvmem.txt for more information. +- +-Example: +- otp: otp@ff290000 { +- compatible = "rockchip,px30-otp"; +- reg = <0x0 0xff290000 0x0 0x4000>; +- #address-cells = <1>; +- #size-cells = <1>; +- clocks = <&cru SCLK_OTP_USR>, <&cru PCLK_OTP_NS>, +- <&cru PCLK_OTP_PHY>; +- clock-names = "otp", "apb_pclk", "phy"; +- }; +-- +2.41.0 + + +From 3282bc8fec63200ed6a3c485bb39b3c094117209 Mon Sep 17 00:00:00 2001 +From: Cristian Ciocaltea +Date: Thu, 4 May 2023 23:06:42 +0300 +Subject: [PATCH 2/9] dt-bindings: nvmem: rockchip,otp: Add compatible for + RK3588 + +Document the OTP memory found on Rockchip RK3588 SoC. + +Since RK3588 uses different clocks & resets configurations than PX30 / +RK3308, provide the required changes in the binding to be able to handle +both variants. + +Signed-off-by: Cristian Ciocaltea +Reviewed-by: Heiko Stuebner +Reviewed-by: Krzysztof Kozlowski +--- + .../bindings/nvmem/rockchip,otp.yaml | 54 ++++++++++++++++--- + 1 file changed, 47 insertions(+), 7 deletions(-) + +diff --git a/Documentation/devicetree/bindings/nvmem/rockchip,otp.yaml b/Documentation/devicetree/bindings/nvmem/rockchip,otp.yaml +index 4cd425ae2823..9c6eff788928 100644 +--- a/Documentation/devicetree/bindings/nvmem/rockchip,otp.yaml ++++ b/Documentation/devicetree/bindings/nvmem/rockchip,otp.yaml +@@ -9,33 +9,35 @@ title: Rockchip internal OTP (One Time Programmable) memory + maintainers: + - Heiko Stuebner + +-allOf: +- - $ref: nvmem.yaml# +- + properties: + compatible: + enum: + - rockchip,px30-otp + - rockchip,rk3308-otp ++ - rockchip,rk3588-otp + + reg: + maxItems: 1 + + clocks: +- maxItems: 3 ++ minItems: 3 ++ maxItems: 4 + + clock-names: ++ minItems: 3 + items: + - const: otp + - const: apb_pclk + - const: phy ++ - const: arb + + resets: +- maxItems: 1 ++ minItems: 1 ++ maxItems: 3 + + reset-names: +- items: +- - const: phy ++ minItems: 1 ++ maxItems: 3 + + required: + - compatible +@@ -45,6 +47,44 @@ required: + - resets + - reset-names + ++allOf: ++ - $ref: nvmem.yaml# ++ ++ - if: ++ properties: ++ compatible: ++ contains: ++ enum: ++ - rockchip,px30-otp ++ - rockchip,rk3308-otp ++ then: ++ properties: ++ clocks: ++ maxItems: 3 ++ resets: ++ maxItems: 1 ++ reset-names: ++ items: ++ - const: phy ++ ++ - if: ++ properties: ++ compatible: ++ contains: ++ enum: ++ - rockchip,rk3588-otp ++ then: ++ properties: ++ clocks: ++ minItems: 4 ++ resets: ++ minItems: 3 ++ reset-names: ++ items: ++ - const: otp ++ - const: apb ++ - const: arb ++ + unevaluatedProperties: false + + examples: +-- +2.41.0 + + +From e4131e9dc168176bf647116e998f34e53cf7233f Mon Sep 17 00:00:00 2001 +From: Cristian Ciocaltea +Date: Thu, 4 May 2023 23:06:43 +0300 +Subject: [PATCH 3/9] nvmem: rockchip-otp: Add clks and reg_read to + rockchip_data + +In preparation to support new Rockchip OTP memory devices with different +clock configurations and register layout, extend rockchip_data struct +with the related members: clks, num_clks, reg_read. + +Additionally, to avoid managing redundant driver data, drop num_clks +member from rockchip_otp struct and update all references to point to +the equivalent member in rockchip_data. + +Signed-off-by: Cristian Ciocaltea +Tested-by: Vincent Legoll +Reviewed-by: Heiko Stuebner +--- + drivers/nvmem/rockchip-otp.c | 79 ++++++++++++++++++++++-------------- + 1 file changed, 49 insertions(+), 30 deletions(-) + +diff --git a/drivers/nvmem/rockchip-otp.c b/drivers/nvmem/rockchip-otp.c +index 9f53bcce2f87..b5a84b379da4 100644 +--- a/drivers/nvmem/rockchip-otp.c ++++ b/drivers/nvmem/rockchip-otp.c +@@ -54,21 +54,19 @@ + + #define OTPC_TIMEOUT 10000 + ++struct rockchip_data { ++ int size; ++ const char * const *clks; ++ int num_clks; ++ nvmem_reg_read_t reg_read; ++}; ++ + struct rockchip_otp { + struct device *dev; + void __iomem *base; +- struct clk_bulk_data *clks; +- int num_clks; ++ struct clk_bulk_data *clks; + struct reset_control *rst; +-}; +- +-/* list of required clocks */ +-static const char * const rockchip_otp_clocks[] = { +- "otp", "apb_pclk", "phy", +-}; +- +-struct rockchip_data { +- int size; ++ const struct rockchip_data *data; + }; + + static int rockchip_otp_reset(struct rockchip_otp *otp) +@@ -132,29 +130,23 @@ static int rockchip_otp_ecc_enable(struct rockchip_otp *otp, bool enable) + return ret; + } + +-static int rockchip_otp_read(void *context, unsigned int offset, +- void *val, size_t bytes) ++static int px30_otp_read(void *context, unsigned int offset, ++ void *val, size_t bytes) + { + struct rockchip_otp *otp = context; + u8 *buf = val; +- int ret = 0; +- +- ret = clk_bulk_prepare_enable(otp->num_clks, otp->clks); +- if (ret < 0) { +- dev_err(otp->dev, "failed to prepare/enable clks\n"); +- return ret; +- } ++ int ret; + + ret = rockchip_otp_reset(otp); + if (ret) { + dev_err(otp->dev, "failed to reset otp phy\n"); +- goto disable_clks; ++ return ret; + } + + ret = rockchip_otp_ecc_enable(otp, false); + if (ret < 0) { + dev_err(otp->dev, "rockchip_otp_ecc_enable err\n"); +- goto disable_clks; ++ return ret; + } + + writel(OTPC_USE_USER | OTPC_USE_USER_MASK, otp->base + OTPC_USER_CTRL); +@@ -174,8 +166,28 @@ static int rockchip_otp_read(void *context, unsigned int offset, + + read_end: + writel(0x0 | OTPC_USE_USER_MASK, otp->base + OTPC_USER_CTRL); +-disable_clks: +- clk_bulk_disable_unprepare(otp->num_clks, otp->clks); ++ ++ return ret; ++} ++ ++static int rockchip_otp_read(void *context, unsigned int offset, ++ void *val, size_t bytes) ++{ ++ struct rockchip_otp *otp = context; ++ int ret; ++ ++ if (!otp->data || !otp->data->reg_read) ++ return -EINVAL; ++ ++ ret = clk_bulk_prepare_enable(otp->data->num_clks, otp->clks); ++ if (ret < 0) { ++ dev_err(otp->dev, "failed to prepare/enable clks\n"); ++ return ret; ++ } ++ ++ ret = otp->data->reg_read(context, offset, val, bytes); ++ ++ clk_bulk_disable_unprepare(otp->data->num_clks, otp->clks); + + return ret; + } +@@ -189,8 +201,15 @@ static struct nvmem_config otp_config = { + .reg_read = rockchip_otp_read, + }; + ++static const char * const px30_otp_clocks[] = { ++ "otp", "apb_pclk", "phy", ++}; ++ + static const struct rockchip_data px30_data = { + .size = 0x40, ++ .clks = px30_otp_clocks, ++ .num_clks = ARRAY_SIZE(px30_otp_clocks), ++ .reg_read = px30_otp_read, + }; + + static const struct of_device_id rockchip_otp_match[] = { +@@ -225,21 +244,21 @@ static int rockchip_otp_probe(struct platform_device *pdev) + if (!otp) + return -ENOMEM; + ++ otp->data = data; + otp->dev = dev; + otp->base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(otp->base)) + return PTR_ERR(otp->base); + +- otp->num_clks = ARRAY_SIZE(rockchip_otp_clocks); +- otp->clks = devm_kcalloc(dev, otp->num_clks, +- sizeof(*otp->clks), GFP_KERNEL); ++ otp->clks = devm_kcalloc(dev, data->num_clks, sizeof(*otp->clks), ++ GFP_KERNEL); + if (!otp->clks) + return -ENOMEM; + +- for (i = 0; i < otp->num_clks; ++i) +- otp->clks[i].id = rockchip_otp_clocks[i]; ++ for (i = 0; i < data->num_clks; ++i) ++ otp->clks[i].id = data->clks[i]; + +- ret = devm_clk_bulk_get(dev, otp->num_clks, otp->clks); ++ ret = devm_clk_bulk_get(dev, data->num_clks, otp->clks); + if (ret) + return ret; + +-- +2.41.0 + + +From a0cad270a253d54eaea3643f9d8426dbb436ec2c Mon Sep 17 00:00:00 2001 +From: Cristian Ciocaltea +Date: Thu, 4 May 2023 23:06:44 +0300 +Subject: [PATCH 4/9] nvmem: rockchip-otp: Generalize + rockchip_otp_wait_status() + +In preparation to support additional Rockchip OTP memory devices with +different register layout, generalize rockchip_otp_wait_status() to +accept a new parameter for specifying the offset of the status register. + +Signed-off-by: Cristian Ciocaltea +Tested-by: Vincent Legoll +Reviewed-by: Heiko Stuebner +--- + drivers/nvmem/rockchip-otp.c | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +diff --git a/drivers/nvmem/rockchip-otp.c b/drivers/nvmem/rockchip-otp.c +index b5a84b379da4..b62e001f9116 100644 +--- a/drivers/nvmem/rockchip-otp.c ++++ b/drivers/nvmem/rockchip-otp.c +@@ -90,18 +90,19 @@ static int rockchip_otp_reset(struct rockchip_otp *otp) + return 0; + } + +-static int rockchip_otp_wait_status(struct rockchip_otp *otp, u32 flag) ++static int rockchip_otp_wait_status(struct rockchip_otp *otp, ++ unsigned int reg, u32 flag) + { + u32 status = 0; + int ret; + +- ret = readl_poll_timeout_atomic(otp->base + OTPC_INT_STATUS, status, ++ ret = readl_poll_timeout_atomic(otp->base + reg, status, + (status & flag), 1, OTPC_TIMEOUT); + if (ret) + return ret; + + /* clean int status */ +- writel(flag, otp->base + OTPC_INT_STATUS); ++ writel(flag, otp->base + reg); + + return 0; + } +@@ -123,7 +124,7 @@ static int rockchip_otp_ecc_enable(struct rockchip_otp *otp, bool enable) + + writel(SBPI_ENABLE_MASK | SBPI_ENABLE, otp->base + OTPC_SBPI_CTRL); + +- ret = rockchip_otp_wait_status(otp, OTPC_SBPI_DONE); ++ ret = rockchip_otp_wait_status(otp, OTPC_INT_STATUS, OTPC_SBPI_DONE); + if (ret < 0) + dev_err(otp->dev, "timeout during ecc_enable\n"); + +@@ -156,7 +157,7 @@ static int px30_otp_read(void *context, unsigned int offset, + otp->base + OTPC_USER_ADDR); + writel(OTPC_USER_FSM_ENABLE | OTPC_USER_FSM_ENABLE_MASK, + otp->base + OTPC_USER_ENABLE); +- ret = rockchip_otp_wait_status(otp, OTPC_USER_DONE); ++ ret = rockchip_otp_wait_status(otp, OTPC_INT_STATUS, OTPC_USER_DONE); + if (ret < 0) { + dev_err(otp->dev, "timeout during read setup\n"); + goto read_end; +-- +2.41.0 + + +From f993ae18db25b7033c4453225d4063775048d9e0 Mon Sep 17 00:00:00 2001 +From: Cristian Ciocaltea +Date: Thu, 4 May 2023 23:06:45 +0300 +Subject: [PATCH 5/9] nvmem: rockchip-otp: Use + devm_reset_control_array_get_exclusive() + +In preparation to support new Rockchip OTP memory devices having +specific reset configurations, switch devm_reset_control_get() to +devm_reset_control_array_get_exclusive(). + +Signed-off-by: Cristian Ciocaltea +Tested-by: Vincent Legoll +Reviewed-by: Heiko Stuebner +--- + drivers/nvmem/rockchip-otp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/nvmem/rockchip-otp.c b/drivers/nvmem/rockchip-otp.c +index b62e001f9116..439aea1f8874 100644 +--- a/drivers/nvmem/rockchip-otp.c ++++ b/drivers/nvmem/rockchip-otp.c +@@ -263,7 +263,7 @@ static int rockchip_otp_probe(struct platform_device *pdev) + if (ret) + return ret; + +- otp->rst = devm_reset_control_get(dev, "phy"); ++ otp->rst = devm_reset_control_array_get_exclusive(dev); + if (IS_ERR(otp->rst)) + return PTR_ERR(otp->rst); + +-- +2.41.0 + + +From 1db5714fc59aa0b0b829155493389429cc497ddb Mon Sep 17 00:00:00 2001 +From: Cristian Ciocaltea +Date: Thu, 4 May 2023 23:06:46 +0300 +Subject: [PATCH 6/9] nvmem: rockchip-otp: Improve probe error handling + +Enhance error handling in the probe function by making use of +dev_err_probe(), which ensures the error code is always printed, in +addition to the specified error message. + +Signed-off-by: Cristian Ciocaltea +Tested-by: Vincent Legoll +Reviewed-by: Heiko Stuebner +--- + drivers/nvmem/rockchip-otp.c | 21 ++++++++++++--------- + 1 file changed, 12 insertions(+), 9 deletions(-) + +diff --git a/drivers/nvmem/rockchip-otp.c b/drivers/nvmem/rockchip-otp.c +index 439aea1f8874..84bf956cc4e1 100644 +--- a/drivers/nvmem/rockchip-otp.c ++++ b/drivers/nvmem/rockchip-otp.c +@@ -235,10 +235,8 @@ static int rockchip_otp_probe(struct platform_device *pdev) + int ret, i; + + data = of_device_get_match_data(dev); +- if (!data) { +- dev_err(dev, "failed to get match data\n"); +- return -EINVAL; +- } ++ if (!data) ++ return dev_err_probe(dev, -EINVAL, "failed to get match data\n"); + + otp = devm_kzalloc(&pdev->dev, sizeof(struct rockchip_otp), + GFP_KERNEL); +@@ -249,7 +247,8 @@ static int rockchip_otp_probe(struct platform_device *pdev) + otp->dev = dev; + otp->base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(otp->base)) +- return PTR_ERR(otp->base); ++ return dev_err_probe(dev, PTR_ERR(otp->base), ++ "failed to ioremap resource\n"); + + otp->clks = devm_kcalloc(dev, data->num_clks, sizeof(*otp->clks), + GFP_KERNEL); +@@ -261,18 +260,22 @@ static int rockchip_otp_probe(struct platform_device *pdev) + + ret = devm_clk_bulk_get(dev, data->num_clks, otp->clks); + if (ret) +- return ret; ++ return dev_err_probe(dev, ret, "failed to get clocks\n"); + + otp->rst = devm_reset_control_array_get_exclusive(dev); + if (IS_ERR(otp->rst)) +- return PTR_ERR(otp->rst); ++ return dev_err_probe(dev, PTR_ERR(otp->rst), ++ "failed to get resets\n"); + + otp_config.size = data->size; + otp_config.priv = otp; + otp_config.dev = dev; +- nvmem = devm_nvmem_register(dev, &otp_config); + +- return PTR_ERR_OR_ZERO(nvmem); ++ nvmem = devm_nvmem_register(dev, &otp_config); ++ if (IS_ERR(nvmem)) ++ return dev_err_probe(dev, PTR_ERR(nvmem), ++ "failed to register nvmem device\n"); ++ return 0; + } + + static struct platform_driver rockchip_otp_driver = { +-- +2.41.0 + + +From a3266c7a0d896cd793a070b18fd456c9dfcf48f6 Mon Sep 17 00:00:00 2001 +From: Cristian Ciocaltea +Date: Thu, 4 May 2023 23:06:47 +0300 +Subject: [PATCH 7/9] nvmem: rockchip-otp: Add support for RK3588 + +Add support for the OTP memory device found on the Rockchip RK3588 SoC. + +While here, remove the unnecessary 'void *' casts in the OF device ID +table. + +Co-developed-by: Finley Xiao +Signed-off-by: Finley Xiao +Signed-off-by: Cristian Ciocaltea +Tested-by: Vincent Legoll +Reviewed-by: Heiko Stuebner +--- + drivers/nvmem/rockchip-otp.c | 78 +++++++++++++++++++++++++++++++++++- + 1 file changed, 76 insertions(+), 2 deletions(-) + +diff --git a/drivers/nvmem/rockchip-otp.c b/drivers/nvmem/rockchip-otp.c +index 84bf956cc4e1..cb9aa5428350 100644 +--- a/drivers/nvmem/rockchip-otp.c ++++ b/drivers/nvmem/rockchip-otp.c +@@ -54,6 +54,19 @@ + + #define OTPC_TIMEOUT 10000 + ++/* RK3588 Register */ ++#define RK3588_OTPC_AUTO_CTRL 0x04 ++#define RK3588_OTPC_AUTO_EN 0x08 ++#define RK3588_OTPC_INT_ST 0x84 ++#define RK3588_OTPC_DOUT0 0x20 ++#define RK3588_NO_SECURE_OFFSET 0x300 ++#define RK3588_NBYTES 4 ++#define RK3588_BURST_NUM 1 ++#define RK3588_BURST_SHIFT 8 ++#define RK3588_ADDR_SHIFT 16 ++#define RK3588_AUTO_EN BIT(0) ++#define RK3588_RD_DONE BIT(1) ++ + struct rockchip_data { + int size; + const char * const *clks; +@@ -171,6 +184,52 @@ static int px30_otp_read(void *context, unsigned int offset, + return ret; + } + ++static int rk3588_otp_read(void *context, unsigned int offset, ++ void *val, size_t bytes) ++{ ++ struct rockchip_otp *otp = context; ++ unsigned int addr_start, addr_end, addr_len; ++ int ret, i = 0; ++ u32 data; ++ u8 *buf; ++ ++ addr_start = round_down(offset, RK3588_NBYTES) / RK3588_NBYTES; ++ addr_end = round_up(offset + bytes, RK3588_NBYTES) / RK3588_NBYTES; ++ addr_len = addr_end - addr_start; ++ addr_start += RK3588_NO_SECURE_OFFSET; ++ ++ buf = kzalloc(array_size(addr_len, RK3588_NBYTES), GFP_KERNEL); ++ if (!buf) ++ return -ENOMEM; ++ ++ while (addr_len--) { ++ writel((addr_start << RK3588_ADDR_SHIFT) | ++ (RK3588_BURST_NUM << RK3588_BURST_SHIFT), ++ otp->base + RK3588_OTPC_AUTO_CTRL); ++ writel(RK3588_AUTO_EN, otp->base + RK3588_OTPC_AUTO_EN); ++ ++ ret = rockchip_otp_wait_status(otp, RK3588_OTPC_INT_ST, ++ RK3588_RD_DONE); ++ if (ret < 0) { ++ dev_err(otp->dev, "timeout during read setup\n"); ++ goto read_end; ++ } ++ ++ data = readl(otp->base + RK3588_OTPC_DOUT0); ++ memcpy(&buf[i], &data, RK3588_NBYTES); ++ ++ i += RK3588_NBYTES; ++ addr_start++; ++ } ++ ++ memcpy(val, buf + offset % RK3588_NBYTES, bytes); ++ ++read_end: ++ kfree(buf); ++ ++ return ret; ++} ++ + static int rockchip_otp_read(void *context, unsigned int offset, + void *val, size_t bytes) + { +@@ -213,14 +272,29 @@ static const struct rockchip_data px30_data = { + .reg_read = px30_otp_read, + }; + ++static const char * const rk3588_otp_clocks[] = { ++ "otp", "apb_pclk", "phy", "arb", ++}; ++ ++static const struct rockchip_data rk3588_data = { ++ .size = 0x400, ++ .clks = rk3588_otp_clocks, ++ .num_clks = ARRAY_SIZE(rk3588_otp_clocks), ++ .reg_read = rk3588_otp_read, ++}; ++ + static const struct of_device_id rockchip_otp_match[] = { + { + .compatible = "rockchip,px30-otp", +- .data = (void *)&px30_data, ++ .data = &px30_data, + }, + { + .compatible = "rockchip,rk3308-otp", +- .data = (void *)&px30_data, ++ .data = &px30_data, ++ }, ++ { ++ .compatible = "rockchip,rk3588-otp", ++ .data = &rk3588_data, + }, + { /* sentinel */ }, + }; +-- +2.41.0 + + +From 4e3178487898d3e21deb144dfa967b4f8c71c8f3 Mon Sep 17 00:00:00 2001 +From: Cristian Ciocaltea +Date: Thu, 4 May 2023 23:06:48 +0300 +Subject: [PATCH 8/9] arm64: dts: rockchip: Add rk3588 OTP node + +Add DT node for Rockchip RK3588/RK3588S OTP memory. + +Co-developed-by: Finley Xiao +Signed-off-by: Finley Xiao +Signed-off-by: Cristian Ciocaltea +Tested-by: Vincent Legoll +--- + arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 54 +++++++++++++++++++++++ + 1 file changed, 54 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi +index 7b93abd8f65c..977ed617f59e 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi +@@ -1841,6 +1841,60 @@ spi4: spi@fecb0000 { + status = "disabled"; + }; + ++ otp: efuse@fecc0000 { ++ compatible = "rockchip,rk3588-otp"; ++ reg = <0x0 0xfecc0000 0x0 0x400>; ++ clocks = <&cru CLK_OTPC_NS>, <&cru PCLK_OTPC_NS>, ++ <&cru CLK_OTP_PHY_G>, <&cru CLK_OTPC_ARB>; ++ clock-names = "otp", "apb_pclk", "phy", "arb"; ++ resets = <&cru SRST_OTPC_NS>, <&cru SRST_P_OTPC_NS>, ++ <&cru SRST_OTPC_ARB>; ++ reset-names = "otp", "apb", "arb"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ cpu_code: cpu-code@2 { ++ reg = <0x02 0x2>; ++ }; ++ ++ otp_id: id@7 { ++ reg = <0x07 0x10>; ++ }; ++ ++ otp_cpu_version: cpu-version@1c { ++ reg = <0x1c 0x1>; ++ bits = <3 3>; ++ }; ++ ++ cpub0_leakage: cpu-leakage@17 { ++ reg = <0x17 0x1>; ++ }; ++ ++ cpub1_leakage: cpu-leakage@18 { ++ reg = <0x18 0x1>; ++ }; ++ ++ cpul_leakage: cpu-leakage@19 { ++ reg = <0x19 0x1>; ++ }; ++ ++ log_leakage: log-leakage@1a { ++ reg = <0x1a 0x1>; ++ }; ++ ++ gpu_leakage: gpu-leakage@1b { ++ reg = <0x1b 0x1>; ++ }; ++ ++ npu_leakage: npu-leakage@28 { ++ reg = <0x28 0x1>; ++ }; ++ ++ codec_leakage: codec-leakage@29 { ++ reg = <0x29 0x1>; ++ }; ++ }; ++ + dmac2: dma-controller@fed10000 { + compatible = "arm,pl330", "arm,primecell"; + reg = <0x0 0xfed10000 0x0 0x4000>; +-- +2.41.0 + + +From 39e135bbe54da0a6ddf98d183c0b4f3f248b17b1 Mon Sep 17 00:00:00 2001 +From: Cristian Ciocaltea +Date: Sun, 4 Jun 2023 20:13:45 +0300 +Subject: [PATCH 9/9] arm64: defconfig: Enable Rockchip OTP memory driver + +The Rockchip one-time programmable memory driver provides access to +various SoC specific information, e.g. leakage currents of the +CPU/GPU/NPU components found on a RK3588 SoC. + +Enable the driver as built-in to allow client device drivers (e.g. +cpufreq) to access the required data for proper settings adjustment. + +Signed-off-by: Cristian Ciocaltea +--- + arch/arm64/configs/defconfig | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig +index a24609e14d50..6ef220d383d3 100644 +--- a/arch/arm64/configs/defconfig ++++ b/arch/arm64/configs/defconfig +@@ -1385,6 +1385,7 @@ CONFIG_NVMEM_MTK_EFUSE=y + CONFIG_NVMEM_QCOM_QFPROM=y + CONFIG_NVMEM_RMEM=m + CONFIG_NVMEM_ROCKCHIP_EFUSE=y ++CONFIG_NVMEM_ROCKCHIP_OTP=y + CONFIG_NVMEM_SNVS_LPGPR=y + CONFIG_NVMEM_SPMI_SDAM=m + CONFIG_NVMEM_SUNXI_SID=y +-- +2.41.0 + diff --git a/patch/kernel/rockchip-rk3588-edge/0024-enable-ethernet-for-rock-5b.patch b/patch/kernel/rockchip-rk3588-edge/0024-enable-ethernet-for-rock-5b.patch new file mode 100644 index 0000000000..a73fa31097 --- /dev/null +++ b/patch/kernel/rockchip-rk3588-edge/0024-enable-ethernet-for-rock-5b.patch @@ -0,0 +1,33 @@ +From 2ca760c84e3764248233fe8891133f811d16aa2e Mon Sep 17 00:00:00 2001 +From: Lucas Tanure +Date: Thu, 23 Mar 2023 12:27:19 +0000 +Subject: [PATCH] arm64: defconfig: Enable ethernet for Rock 5B + +Signed-off-by: Lucas Tanure +--- + arch/arm64/configs/defconfig | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig +index 0777bcae9104b..2982169691f31 100644 +--- a/arch/arm64/configs/defconfig ++++ b/arch/arm64/configs/defconfig +@@ -221,6 +221,7 @@ CONFIG_PCIE_ALTERA=y + CONFIG_PCIE_ALTERA_MSI=y + CONFIG_PCI_HOST_THUNDER_PEM=y + CONFIG_PCI_HOST_THUNDER_ECAM=y ++CONFIG_PCIE_ROCKCHIP_DW_HOST=y + CONFIG_PCIE_ROCKCHIP_HOST=m + CONFIG_PCIE_MEDIATEK_GEN3=m + CONFIG_PCIE_BRCMSTB=m +@@ -1385,6 +1386,7 @@ CONFIG_PHY_RCAR_GEN3_PCIE=y + CONFIG_PHY_RCAR_GEN3_USB2=y + CONFIG_PHY_RCAR_GEN3_USB3=m + CONFIG_PHY_ROCKCHIP_EMMC=y ++CONFIG_PHY_ROCKCHIP_NANENG_COMBO_PHY=y + CONFIG_PHY_ROCKCHIP_INNO_HDMI=m + CONFIG_PHY_ROCKCHIP_INNO_USB2=y + CONFIG_PHY_ROCKCHIP_INNO_DSIDPHY=m +-- +GitLab + diff --git a/patch/kernel/rockchip-rk3588-edge/0025-Add-RK3588-USB2-Support.patch b/patch/kernel/rockchip-rk3588-edge/0025-Add-RK3588-USB2-Support.patch new file mode 100644 index 0000000000..abbf66d678 --- /dev/null +++ b/patch/kernel/rockchip-rk3588-edge/0025-Add-RK3588-USB2-Support.patch @@ -0,0 +1,1082 @@ +From 0900696b9f56a0ec692d22eff3ad84bce7988f1a Mon Sep 17 00:00:00 2001 +From: Sebastian Reichel +Date: Thu, 30 Mar 2023 16:31:18 +0200 +Subject: [PATCH 01/11] dt-bindings: usb: Add RK3588 OHCI + +Add compatible for RK3588 OHCI. As far as I know it's fully +compatible with generic-ohci. + +Reviewed-by: Rob Herring +Signed-off-by: Sebastian Reichel +--- + .../devicetree/bindings/usb/generic-ohci.yaml | 17 ++++++++++++++++- + 1 file changed, 16 insertions(+), 1 deletion(-) + +diff --git a/Documentation/devicetree/bindings/usb/generic-ohci.yaml b/Documentation/devicetree/bindings/usb/generic-ohci.yaml +index d06d1e7d8876..be268e23ca79 100644 +--- a/Documentation/devicetree/bindings/usb/generic-ohci.yaml ++++ b/Documentation/devicetree/bindings/usb/generic-ohci.yaml +@@ -44,6 +44,7 @@ properties: + - hpe,gxp-ohci + - ibm,476gtr-ohci + - ingenic,jz4740-ohci ++ - rockchip,rk3588-ohci + - snps,hsdk-v1.0-ohci + - const: generic-ohci + - enum: +@@ -69,7 +70,7 @@ properties: + + clocks: + minItems: 1 +- maxItems: 3 ++ maxItems: 4 + description: | + In case the Renesas R-Car Gen3 SoCs: + - if a host only channel: first clock should be host. +@@ -147,6 +148,20 @@ allOf: + then: + properties: + transceiver: false ++ - if: ++ properties: ++ compatible: ++ contains: ++ const: rockchip,rk3588-ohci ++ then: ++ properties: ++ clocks: ++ minItems: 4 ++ else: ++ properties: ++ clocks: ++ minItems: 1 ++ maxItems: 3 + + unevaluatedProperties: false + +-- +2.41.0 + + +From 924974cf321fc4efadd8da84603b97bf80cbbeb2 Mon Sep 17 00:00:00 2001 +From: Sebastian Reichel +Date: Tue, 4 Apr 2023 15:32:54 +0200 +Subject: [PATCH 02/11] dt-bindings: usb: Add RK3588 EHCI + +Add compatible for RK3588 EHCI. As far as I know it's fully +compatible with generic-ehci. + +Acked-by: Krzysztof Kozlowski +Reviewed-by: Rob Herring +Signed-off-by: Sebastian Reichel +--- + Documentation/devicetree/bindings/usb/generic-ehci.yaml | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/Documentation/devicetree/bindings/usb/generic-ehci.yaml b/Documentation/devicetree/bindings/usb/generic-ehci.yaml +index 9445764bd8de..b956bb5fada7 100644 +--- a/Documentation/devicetree/bindings/usb/generic-ehci.yaml ++++ b/Documentation/devicetree/bindings/usb/generic-ehci.yaml +@@ -61,6 +61,7 @@ properties: + - ibm,476gtr-ehci + - nxp,lpc1850-ehci + - qca,ar7100-ehci ++ - rockchip,rk3588-ehci + - snps,hsdk-v1.0-ehci + - socionext,uniphier-ehci + - const: generic-ehci +-- +2.41.0 + + +From 1c5f2868b5fa9d48586f3e606baae4200516fd59 Mon Sep 17 00:00:00 2001 +From: Sebastian Reichel +Date: Wed, 29 Mar 2023 18:54:49 +0200 +Subject: [PATCH 03/11] usb: host: ohci-platform: increase max clock number to + 4 + +Rockchip RK3588 OHCI requires 4 clocks to be enabled. + +Acked-by: Alan Stern +Signed-off-by: Sebastian Reichel +--- + drivers/usb/host/ohci-platform.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/usb/host/ohci-platform.c b/drivers/usb/host/ohci-platform.c +index a84305091c43..dec38a845cff 100644 +--- a/drivers/usb/host/ohci-platform.c ++++ b/drivers/usb/host/ohci-platform.c +@@ -33,7 +33,7 @@ + #include "ohci.h" + + #define DRIVER_DESC "OHCI generic platform driver" +-#define OHCI_MAX_CLKS 3 ++#define OHCI_MAX_CLKS 4 + #define hcd_to_ohci_priv(h) ((struct ohci_platform_priv *)hcd_to_ohci(h)->priv) + + struct ohci_platform_priv { +-- +2.41.0 + + +From bf550631e2c027488074d56b63dca6d2837418e1 Mon Sep 17 00:00:00 2001 +From: Sebastian Reichel +Date: Thu, 30 Mar 2023 16:25:20 +0200 +Subject: [PATCH 04/11] dt-bindings: phy: rockchip,inno-usb2phy: add rk3588 + +Add compatible for the USB2 phy in the Rockchip RK3588 SoC. + +Reviewed-by: Rob Herring +Signed-off-by: Sebastian Reichel +--- + .../bindings/phy/rockchip,inno-usb2phy.yaml | 21 ++++++++++++++++--- + 1 file changed, 18 insertions(+), 3 deletions(-) + +diff --git a/Documentation/devicetree/bindings/phy/rockchip,inno-usb2phy.yaml b/Documentation/devicetree/bindings/phy/rockchip,inno-usb2phy.yaml +index 0d6b8c28be07..5254413137c6 100644 +--- a/Documentation/devicetree/bindings/phy/rockchip,inno-usb2phy.yaml ++++ b/Documentation/devicetree/bindings/phy/rockchip,inno-usb2phy.yaml +@@ -20,6 +20,7 @@ properties: + - rockchip,rk3366-usb2phy + - rockchip,rk3399-usb2phy + - rockchip,rk3568-usb2phy ++ - rockchip,rk3588-usb2phy + - rockchip,rv1108-usb2phy + + reg: +@@ -56,6 +57,14 @@ properties: + description: Muxed interrupt for both ports + maxItems: 1 + ++ resets: ++ maxItems: 2 ++ ++ reset-names: ++ items: ++ - const: phy ++ - const: apb ++ + rockchip,usbgrf: + $ref: /schemas/types.yaml#/definitions/phandle + description: +@@ -120,15 +129,21 @@ required: + - reg + - clock-output-names + - "#clock-cells" +- - host-port +- - otg-port ++ ++anyOf: ++ - required: ++ - otg-port ++ - required: ++ - host-port + + allOf: + - if: + properties: + compatible: + contains: +- const: rockchip,rk3568-usb2phy ++ enum: ++ - rockchip,rk3568-usb2phy ++ - rockchip,rk3588-usb2phy + + then: + properties: +-- +2.41.0 + + +From 8c33eb76698b4d6648e9ae51eb3160baa108c761 Mon Sep 17 00:00:00 2001 +From: Sebastian Reichel +Date: Thu, 12 Jan 2023 19:15:52 +0100 +Subject: [PATCH 05/11] phy: phy-rockchip-inno-usb2: add rk3588 support + +Add basic support for the USB2 PHY found in the Rockchip RK3588. + +Co-developed-by: William Wu +Signed-off-by: William Wu +Signed-off-by: Sebastian Reichel +--- + drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 226 ++++++++++++++++-- + 1 file changed, 211 insertions(+), 15 deletions(-) + +diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c +index a0bc10aa7961..2c4683c67a8e 100644 +--- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c ++++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c +@@ -116,6 +116,12 @@ struct rockchip_chg_det_reg { + * @bvalid_det_en: vbus valid rise detection enable register. + * @bvalid_det_st: vbus valid rise detection status register. + * @bvalid_det_clr: vbus valid rise detection clear register. ++ * @disfall_en: host disconnect fall edge detection enable. ++ * @disfall_st: host disconnect fall edge detection state. ++ * @disfall_clr: host disconnect fall edge detection clear. ++ * @disrise_en: host disconnect rise edge detection enable. ++ * @disrise_st: host disconnect rise edge detection state. ++ * @disrise_clr: host disconnect rise edge detection clear. + * @id_det_en: id detection enable register. + * @id_det_st: id detection state register. + * @id_det_clr: id detection clear register. +@@ -133,6 +139,12 @@ struct rockchip_usb2phy_port_cfg { + struct usb2phy_reg bvalid_det_en; + struct usb2phy_reg bvalid_det_st; + struct usb2phy_reg bvalid_det_clr; ++ struct usb2phy_reg disfall_en; ++ struct usb2phy_reg disfall_st; ++ struct usb2phy_reg disfall_clr; ++ struct usb2phy_reg disrise_en; ++ struct usb2phy_reg disrise_st; ++ struct usb2phy_reg disrise_clr; + struct usb2phy_reg id_det_en; + struct usb2phy_reg id_det_st; + struct usb2phy_reg id_det_clr; +@@ -168,6 +180,7 @@ struct rockchip_usb2phy_cfg { + * @port_id: flag for otg port or host port. + * @suspended: phy suspended flag. + * @vbus_attached: otg device vbus status. ++ * @host_disconnect: usb host disconnect status. + * @bvalid_irq: IRQ number assigned for vbus valid rise detection. + * @id_irq: IRQ number assigned for ID pin detection. + * @ls_irq: IRQ number assigned for linestate detection. +@@ -187,6 +200,7 @@ struct rockchip_usb2phy_port { + unsigned int port_id; + bool suspended; + bool vbus_attached; ++ bool host_disconnect; + int bvalid_irq; + int id_irq; + int ls_irq; +@@ -405,6 +419,27 @@ static int rockchip_usb2phy_extcon_register(struct rockchip_usb2phy *rphy) + return 0; + } + ++static int rockchip_usb2phy_enable_host_disc_irq(struct rockchip_usb2phy *rphy, ++ struct rockchip_usb2phy_port *rport, ++ bool en) ++{ ++ int ret; ++ ++ ret = property_enable(rphy->grf, &rport->port_cfg->disfall_clr, true); ++ if (ret) ++ return ret; ++ ++ ret = property_enable(rphy->grf, &rport->port_cfg->disfall_en, en); ++ if (ret) ++ return ret; ++ ++ ret = property_enable(rphy->grf, &rport->port_cfg->disrise_clr, true); ++ if (ret) ++ return ret; ++ ++ return property_enable(rphy->grf, &rport->port_cfg->disrise_en, en); ++} ++ + static int rockchip_usb2phy_init(struct phy *phy) + { + struct rockchip_usb2phy_port *rport = phy_get_drvdata(phy); +@@ -449,6 +484,15 @@ static int rockchip_usb2phy_init(struct phy *phy) + dev_dbg(&rport->phy->dev, "mode %d\n", rport->mode); + } + } else if (rport->port_id == USB2PHY_PORT_HOST) { ++ if (rport->port_cfg->disfall_en.offset) { ++ rport->host_disconnect = true; ++ ret = rockchip_usb2phy_enable_host_disc_irq(rphy, rport, true); ++ if (ret) { ++ dev_err(rphy->dev, "failed to enable disconnect irq\n"); ++ goto out; ++ } ++ } ++ + /* clear linestate and enable linestate detect irq */ + ret = property_enable(rphy->grf, + &rport->port_cfg->ls_det_clr, true); +@@ -810,9 +854,7 @@ static void rockchip_usb2phy_sm_work(struct work_struct *work) + struct rockchip_usb2phy_port *rport = + container_of(work, struct rockchip_usb2phy_port, sm_work.work); + struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent); +- unsigned int sh = rport->port_cfg->utmi_hstdet.bitend - +- rport->port_cfg->utmi_hstdet.bitstart + 1; +- unsigned int ul, uhd, state; ++ unsigned int sh, ul, uhd, state; + unsigned int ul_mask, uhd_mask; + int ret; + +@@ -822,18 +864,26 @@ static void rockchip_usb2phy_sm_work(struct work_struct *work) + if (ret < 0) + goto next_schedule; + +- ret = regmap_read(rphy->grf, rport->port_cfg->utmi_hstdet.offset, &uhd); +- if (ret < 0) +- goto next_schedule; +- +- uhd_mask = GENMASK(rport->port_cfg->utmi_hstdet.bitend, +- rport->port_cfg->utmi_hstdet.bitstart); + ul_mask = GENMASK(rport->port_cfg->utmi_ls.bitend, + rport->port_cfg->utmi_ls.bitstart); + +- /* stitch on utmi_ls and utmi_hstdet as phy state */ +- state = ((uhd & uhd_mask) >> rport->port_cfg->utmi_hstdet.bitstart) | +- (((ul & ul_mask) >> rport->port_cfg->utmi_ls.bitstart) << sh); ++ if (rport->port_cfg->utmi_hstdet.offset) { ++ ret = regmap_read(rphy->grf, rport->port_cfg->utmi_hstdet.offset, &uhd); ++ if (ret < 0) ++ goto next_schedule; ++ ++ uhd_mask = GENMASK(rport->port_cfg->utmi_hstdet.bitend, ++ rport->port_cfg->utmi_hstdet.bitstart); ++ ++ sh = rport->port_cfg->utmi_hstdet.bitend - ++ rport->port_cfg->utmi_hstdet.bitstart + 1; ++ /* stitch on utmi_ls and utmi_hstdet as phy state */ ++ state = ((uhd & uhd_mask) >> rport->port_cfg->utmi_hstdet.bitstart) | ++ (((ul & ul_mask) >> rport->port_cfg->utmi_ls.bitstart) << sh); ++ } else { ++ state = ((ul & ul_mask) >> rport->port_cfg->utmi_ls.bitstart) << 1 | ++ rport->host_disconnect; ++ } + + switch (state) { + case PHY_STATE_HS_ONLINE: +@@ -966,6 +1016,31 @@ static irqreturn_t rockchip_usb2phy_otg_mux_irq(int irq, void *data) + return ret; + } + ++static irqreturn_t rockchip_usb2phy_host_disc_irq(int irq, void *data) ++{ ++ struct rockchip_usb2phy_port *rport = data; ++ struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent); ++ ++ if (!property_enabled(rphy->grf, &rport->port_cfg->disfall_st) && ++ !property_enabled(rphy->grf, &rport->port_cfg->disrise_st)) ++ return IRQ_NONE; ++ ++ mutex_lock(&rport->mutex); ++ ++ /* clear disconnect fall or rise detect irq pending status */ ++ if (property_enabled(rphy->grf, &rport->port_cfg->disfall_st)) { ++ property_enable(rphy->grf, &rport->port_cfg->disfall_clr, true); ++ rport->host_disconnect = false; ++ } else if (property_enabled(rphy->grf, &rport->port_cfg->disrise_st)) { ++ property_enable(rphy->grf, &rport->port_cfg->disrise_clr, true); ++ rport->host_disconnect = true; ++ } ++ ++ mutex_unlock(&rport->mutex); ++ ++ return IRQ_HANDLED; ++} ++ + static irqreturn_t rockchip_usb2phy_irq(int irq, void *data) + { + struct rockchip_usb2phy *rphy = data; +@@ -978,6 +1053,10 @@ static irqreturn_t rockchip_usb2phy_irq(int irq, void *data) + if (!rport->phy) + continue; + ++ if (rport->port_id == USB2PHY_PORT_HOST && ++ rport->port_cfg->disfall_en.offset) ++ ret |= rockchip_usb2phy_host_disc_irq(irq, rport); ++ + switch (rport->port_id) { + case USB2PHY_PORT_OTG: + if (rport->mode != USB_DR_MODE_HOST && +@@ -1233,7 +1312,7 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev) + } + + /* support address_cells=2 */ +- if (reg == 0) { ++ if (of_property_count_u32_elems(np, "reg") > 2 && reg == 0) { + if (of_property_read_u32_index(np, "reg", 1, ®)) { + dev_err(dev, "the reg property is not assigned in %pOFn node\n", + np); +@@ -1254,14 +1333,14 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev) + + /* find out a proper config which can be matched with dt. */ + index = 0; +- while (phy_cfgs[index].reg) { ++ do { + if (phy_cfgs[index].reg == reg) { + rphy->phy_cfg = &phy_cfgs[index]; + break; + } + + ++index; +- } ++ } while (phy_cfgs[index].reg); + + if (!rphy->phy_cfg) { + dev_err(dev, "no phy-config can be matched with %pOFn node\n", +@@ -1664,6 +1743,122 @@ static const struct rockchip_usb2phy_cfg rk3568_phy_cfgs[] = { + { /* sentinel */ } + }; + ++static const struct rockchip_usb2phy_cfg rk3588_phy_cfgs[] = { ++ { ++ .reg = 0x0000, ++ .num_ports = 1, ++ .clkout_ctl = { 0x0000, 0, 0, 1, 0 }, ++ .port_cfgs = { ++ [USB2PHY_PORT_OTG] = { ++ .phy_sus = { 0x000c, 11, 11, 0, 1 }, ++ .bvalid_det_en = { 0x0080, 1, 1, 0, 1 }, ++ .bvalid_det_st = { 0x0084, 1, 1, 0, 1 }, ++ .bvalid_det_clr = { 0x0088, 1, 1, 0, 1 }, ++ .ls_det_en = { 0x0080, 0, 0, 0, 1 }, ++ .ls_det_st = { 0x0084, 0, 0, 0, 1 }, ++ .ls_det_clr = { 0x0088, 0, 0, 0, 1 }, ++ .disfall_en = { 0x0080, 6, 6, 0, 1 }, ++ .disfall_st = { 0x0084, 6, 6, 0, 1 }, ++ .disfall_clr = { 0x0088, 6, 6, 0, 1 }, ++ .disrise_en = { 0x0080, 5, 5, 0, 1 }, ++ .disrise_st = { 0x0084, 5, 5, 0, 1 }, ++ .disrise_clr = { 0x0088, 5, 5, 0, 1 }, ++ .utmi_avalid = { 0x00c0, 7, 7, 0, 1 }, ++ .utmi_bvalid = { 0x00c0, 6, 6, 0, 1 }, ++ .utmi_ls = { 0x00c0, 10, 9, 0, 1 }, ++ } ++ }, ++ .chg_det = { ++ .cp_det = { 0x00c0, 0, 0, 0, 1 }, ++ .dcp_det = { 0x00c0, 0, 0, 0, 1 }, ++ .dp_det = { 0x00c0, 1, 1, 1, 0 }, ++ .idm_sink_en = { 0x0008, 5, 5, 1, 0 }, ++ .idp_sink_en = { 0x0008, 5, 5, 0, 1 }, ++ .idp_src_en = { 0x0008, 14, 14, 0, 1 }, ++ .rdm_pdwn_en = { 0x0008, 14, 14, 0, 1 }, ++ .vdm_src_en = { 0x0008, 7, 6, 0, 3 }, ++ .vdp_src_en = { 0x0008, 7, 6, 0, 3 }, ++ }, ++ }, ++ { ++ .reg = 0x4000, ++ .num_ports = 1, ++ .clkout_ctl = { 0x0000, 0, 0, 1, 0 }, ++ .port_cfgs = { ++ [USB2PHY_PORT_OTG] = { ++ .phy_sus = { 0x000c, 11, 11, 0, 1 }, ++ .bvalid_det_en = { 0x0080, 1, 1, 0, 1 }, ++ .bvalid_det_st = { 0x0084, 1, 1, 0, 1 }, ++ .bvalid_det_clr = { 0x0088, 1, 1, 0, 1 }, ++ .ls_det_en = { 0x0080, 0, 0, 0, 1 }, ++ .ls_det_st = { 0x0084, 0, 0, 0, 1 }, ++ .ls_det_clr = { 0x0088, 0, 0, 0, 1 }, ++ .disfall_en = { 0x0080, 6, 6, 0, 1 }, ++ .disfall_st = { 0x0084, 6, 6, 0, 1 }, ++ .disfall_clr = { 0x0088, 6, 6, 0, 1 }, ++ .disrise_en = { 0x0080, 5, 5, 0, 1 }, ++ .disrise_st = { 0x0084, 5, 5, 0, 1 }, ++ .disrise_clr = { 0x0088, 5, 5, 0, 1 }, ++ .utmi_avalid = { 0x00c0, 7, 7, 0, 1 }, ++ .utmi_bvalid = { 0x00c0, 6, 6, 0, 1 }, ++ .utmi_ls = { 0x00c0, 10, 9, 0, 1 }, ++ } ++ }, ++ .chg_det = { ++ .cp_det = { 0x00c0, 0, 0, 0, 1 }, ++ .dcp_det = { 0x00c0, 0, 0, 0, 1 }, ++ .dp_det = { 0x00c0, 1, 1, 1, 0 }, ++ .idm_sink_en = { 0x0008, 5, 5, 1, 0 }, ++ .idp_sink_en = { 0x0008, 5, 5, 0, 1 }, ++ .idp_src_en = { 0x0008, 14, 14, 0, 1 }, ++ .rdm_pdwn_en = { 0x0008, 14, 14, 0, 1 }, ++ .vdm_src_en = { 0x0008, 7, 6, 0, 3 }, ++ .vdp_src_en = { 0x0008, 7, 6, 0, 3 }, ++ }, ++ }, ++ { ++ .reg = 0x8000, ++ .num_ports = 1, ++ .clkout_ctl = { 0x0000, 0, 0, 1, 0 }, ++ .port_cfgs = { ++ [USB2PHY_PORT_HOST] = { ++ .phy_sus = { 0x0008, 2, 2, 0, 1 }, ++ .ls_det_en = { 0x0080, 0, 0, 0, 1 }, ++ .ls_det_st = { 0x0084, 0, 0, 0, 1 }, ++ .ls_det_clr = { 0x0088, 0, 0, 0, 1 }, ++ .disfall_en = { 0x0080, 6, 6, 0, 1 }, ++ .disfall_st = { 0x0084, 6, 6, 0, 1 }, ++ .disfall_clr = { 0x0088, 6, 6, 0, 1 }, ++ .disrise_en = { 0x0080, 5, 5, 0, 1 }, ++ .disrise_st = { 0x0084, 5, 5, 0, 1 }, ++ .disrise_clr = { 0x0088, 5, 5, 0, 1 }, ++ .utmi_ls = { 0x00c0, 10, 9, 0, 1 }, ++ } ++ }, ++ }, ++ { ++ .reg = 0xc000, ++ .num_ports = 1, ++ .clkout_ctl = { 0x0000, 0, 0, 1, 0 }, ++ .port_cfgs = { ++ [USB2PHY_PORT_HOST] = { ++ .phy_sus = { 0x0008, 2, 2, 0, 1 }, ++ .ls_det_en = { 0x0080, 0, 0, 0, 1 }, ++ .ls_det_st = { 0x0084, 0, 0, 0, 1 }, ++ .ls_det_clr = { 0x0088, 0, 0, 0, 1 }, ++ .disfall_en = { 0x0080, 6, 6, 0, 1 }, ++ .disfall_st = { 0x0084, 6, 6, 0, 1 }, ++ .disfall_clr = { 0x0088, 6, 6, 0, 1 }, ++ .disrise_en = { 0x0080, 5, 5, 0, 1 }, ++ .disrise_st = { 0x0084, 5, 5, 0, 1 }, ++ .disrise_clr = { 0x0088, 5, 5, 0, 1 }, ++ .utmi_ls = { 0x00c0, 10, 9, 0, 1 }, ++ } ++ }, ++ }, ++ { /* sentinel */ } ++}; ++ + static const struct rockchip_usb2phy_cfg rv1108_phy_cfgs[] = { + { + .reg = 0x100, +@@ -1714,6 +1909,7 @@ static const struct of_device_id rockchip_usb2phy_dt_match[] = { + { .compatible = "rockchip,rk3366-usb2phy", .data = &rk3366_phy_cfgs }, + { .compatible = "rockchip,rk3399-usb2phy", .data = &rk3399_phy_cfgs }, + { .compatible = "rockchip,rk3568-usb2phy", .data = &rk3568_phy_cfgs }, ++ { .compatible = "rockchip,rk3588-usb2phy", .data = &rk3588_phy_cfgs }, + { .compatible = "rockchip,rv1108-usb2phy", .data = &rv1108_phy_cfgs }, + {} + }; +-- +2.41.0 + + +From 06a9d6baed9ca58eb8b79e58887bebb81deac567 Mon Sep 17 00:00:00 2001 +From: Sebastian Reichel +Date: Mon, 3 Apr 2023 20:23:14 +0200 +Subject: [PATCH 06/11] phy: phy-rockchip-inno-usb2: add reset support + +Add reset handling support, which is needed for proper +operation with RK3588. + +Signed-off-by: Sebastian Reichel +--- + drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 38 +++++++++++++++++++ + 1 file changed, 38 insertions(+) + +diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c +index 2c4683c67a8e..101b46939f0b 100644 +--- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c ++++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c +@@ -24,6 +24,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -223,6 +224,7 @@ struct rockchip_usb2phy_port { + * @clk: clock struct of phy input clk. + * @clk480m: clock struct of phy output clk. + * @clk480m_hw: clock struct of phy output clk management. ++ * @phy_reset: phy reset control. + * @chg_state: states involved in USB charger detection. + * @chg_type: USB charger types. + * @dcd_retries: The retry count used to track Data contact +@@ -239,6 +241,7 @@ struct rockchip_usb2phy { + struct clk *clk; + struct clk *clk480m; + struct clk_hw clk480m_hw; ++ struct reset_control *phy_reset; + enum usb_chg_state chg_state; + enum power_supply_type chg_type; + u8 dcd_retries; +@@ -280,6 +283,25 @@ static inline bool property_enabled(struct regmap *base, + return tmp != reg->disable; + } + ++static int rockchip_usb2phy_reset(struct rockchip_usb2phy *rphy) ++{ ++ int ret; ++ ++ ret = reset_control_assert(rphy->phy_reset); ++ if (ret) ++ return ret; ++ ++ udelay(10); ++ ++ ret = reset_control_deassert(rphy->phy_reset); ++ if (ret) ++ return ret; ++ ++ usleep_range(100, 200); ++ ++ return 0; ++} ++ + static int rockchip_usb2phy_clk480m_prepare(struct clk_hw *hw) + { + struct rockchip_usb2phy *rphy = +@@ -534,6 +556,18 @@ static int rockchip_usb2phy_power_on(struct phy *phy) + return ret; + } + ++ /* ++ * For rk3588, it needs to reset phy when exit from ++ * suspend mode with common_on_n 1'b1(aka REFCLK_LOGIC, ++ * Bias, and PLL blocks are powered down) for lower ++ * power consumption. If you don't want to reset phy, ++ * please keep the common_on_n 1'b0 to set these blocks ++ * remain powered. ++ */ ++ ret = rockchip_usb2phy_reset(rphy); ++ if (ret) ++ return ret; ++ + /* waiting for the utmi_clk to become stable */ + usleep_range(1500, 2000); + +@@ -1348,6 +1382,10 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev) + return -EINVAL; + } + ++ rphy->phy_reset = devm_reset_control_get_optional(dev, "phy"); ++ if (IS_ERR(rphy->phy_reset)) ++ return PTR_ERR(rphy->phy_reset); ++ + rphy->clk = of_clk_get_by_name(np, "phyclk"); + if (!IS_ERR(rphy->clk)) { + clk_prepare_enable(rphy->clk); +-- +2.41.0 + + +From f00308d812c063b4104214ff3d4b589f89ff96b4 Mon Sep 17 00:00:00 2001 +From: Sebastian Reichel +Date: Mon, 3 Apr 2023 20:24:06 +0200 +Subject: [PATCH 07/11] phy: phy-rockchip-inno-usb2: add rk3588 phy tuning + support + +On RK3588 some registers need to be tweaked to support waking up from +suspend when a USB device is plugged into a port from a suspended PHY. +Without this change USB devices only work when they are plugged at +boot time. + +Apart from that it optimizes settings to avoid devices toggling +between fullspeed and highspeed mode. + +Signed-off-by: Sebastian Reichel +--- + drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 63 +++++++++++++++++++ + 1 file changed, 63 insertions(+) + +diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c +index 101b46939f0b..aa8c55609c0d 100644 +--- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c ++++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c +@@ -33,6 +33,8 @@ + #define SCHEDULE_DELAY (60 * HZ) + #define OTG_SCHEDULE_DELAY (2 * HZ) + ++struct rockchip_usb2phy; ++ + enum rockchip_usb2phy_port_id { + USB2PHY_PORT_OTG, + USB2PHY_PORT_HOST, +@@ -163,6 +165,7 @@ struct rockchip_usb2phy_port_cfg { + * struct rockchip_usb2phy_cfg - usb-phy configuration. + * @reg: the address offset of grf for usb-phy config. + * @num_ports: specify how many ports that the phy has. ++ * @phy_tuning: phy default parameters tuning. + * @clkout_ctl: keep on/turn off output clk of phy. + * @port_cfgs: usb-phy port configurations. + * @chg_det: charger detection registers. +@@ -170,6 +173,7 @@ struct rockchip_usb2phy_port_cfg { + struct rockchip_usb2phy_cfg { + unsigned int reg; + unsigned int num_ports; ++ int (*phy_tuning)(struct rockchip_usb2phy *rphy); + struct usb2phy_reg clkout_ctl; + const struct rockchip_usb2phy_port_cfg port_cfgs[USB2PHY_NUM_PORTS]; + const struct rockchip_chg_det_reg chg_det; +@@ -1400,6 +1404,12 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev) + goto disable_clks; + } + ++ if (rphy->phy_cfg->phy_tuning) { ++ ret = rphy->phy_cfg->phy_tuning(rphy); ++ if (ret) ++ goto disable_clks; ++ } ++ + index = 0; + for_each_available_child_of_node(np, child_np) { + struct rockchip_usb2phy_port *rport = &rphy->ports[index]; +@@ -1468,6 +1478,55 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev) + return ret; + } + ++static int rk3588_usb2phy_tuning(struct rockchip_usb2phy *rphy) ++{ ++ int ret; ++ bool usb3otg = false; ++ /* ++ * utmi_termselect = 1'b1 (en FS terminations) ++ * utmi_xcvrselect = 2'b01 (FS transceiver) ++ */ ++ int suspend_cfg = 0x14; ++ ++ if (rphy->phy_cfg->reg == 0x0000 || rphy->phy_cfg->reg == 0x4000) { ++ /* USB2 config for USB3_0 and USB3_1 */ ++ suspend_cfg |= 0x01; /* utmi_opmode = 2'b01 (no-driving) */ ++ usb3otg = true; ++ } else if (rphy->phy_cfg->reg == 0x8000 || rphy->phy_cfg->reg == 0xc000) { ++ /* USB2 config for USB2_0 and USB2_1 */ ++ suspend_cfg |= 0x00; /* utmi_opmode = 2'b00 (normal) */ ++ } else { ++ return -EINVAL; ++ } ++ ++ /* Deassert SIDDQ to power on analog block */ ++ ret = regmap_write(rphy->grf, 0x0008, GENMASK(29, 29) | 0x0000); ++ if (ret) ++ return ret; ++ ++ /* Do reset after exit IDDQ mode */ ++ ret = rockchip_usb2phy_reset(rphy); ++ if (ret) ++ return ret; ++ ++ /* suspend configuration */ ++ ret |= regmap_write(rphy->grf, 0x000c, GENMASK(20, 16) | suspend_cfg); ++ ++ /* HS DC Voltage Level Adjustment 4'b1001 : +5.89% */ ++ ret |= regmap_write(rphy->grf, 0x0004, GENMASK(27, 24) | 0x0900); ++ ++ /* HS Transmitter Pre-Emphasis Current Control 2'b10 : 2x */ ++ ret |= regmap_write(rphy->grf, 0x0008, GENMASK(20, 19) | 0x0010); ++ ++ if (!usb3otg) ++ return ret; ++ ++ /* Pullup iddig pin for USB3_0 OTG mode */ ++ ret |= regmap_write(rphy->grf, 0x0010, GENMASK(17, 16) | 0x0003); ++ ++ return ret; ++} ++ + static const struct rockchip_usb2phy_cfg rk3228_phy_cfgs[] = { + { + .reg = 0x760, +@@ -1785,6 +1844,7 @@ static const struct rockchip_usb2phy_cfg rk3588_phy_cfgs[] = { + { + .reg = 0x0000, + .num_ports = 1, ++ .phy_tuning = rk3588_usb2phy_tuning, + .clkout_ctl = { 0x0000, 0, 0, 1, 0 }, + .port_cfgs = { + [USB2PHY_PORT_OTG] = { +@@ -1821,6 +1881,7 @@ static const struct rockchip_usb2phy_cfg rk3588_phy_cfgs[] = { + { + .reg = 0x4000, + .num_ports = 1, ++ .phy_tuning = rk3588_usb2phy_tuning, + .clkout_ctl = { 0x0000, 0, 0, 1, 0 }, + .port_cfgs = { + [USB2PHY_PORT_OTG] = { +@@ -1857,6 +1918,7 @@ static const struct rockchip_usb2phy_cfg rk3588_phy_cfgs[] = { + { + .reg = 0x8000, + .num_ports = 1, ++ .phy_tuning = rk3588_usb2phy_tuning, + .clkout_ctl = { 0x0000, 0, 0, 1, 0 }, + .port_cfgs = { + [USB2PHY_PORT_HOST] = { +@@ -1877,6 +1939,7 @@ static const struct rockchip_usb2phy_cfg rk3588_phy_cfgs[] = { + { + .reg = 0xc000, + .num_ports = 1, ++ .phy_tuning = rk3588_usb2phy_tuning, + .clkout_ctl = { 0x0000, 0, 0, 1, 0 }, + .port_cfgs = { + [USB2PHY_PORT_HOST] = { +-- +2.41.0 + + +From 656516de7b6bdce000fad36006d392bc03c4811a Mon Sep 17 00:00:00 2001 +From: Sebastian Reichel +Date: Mon, 3 Apr 2023 21:49:58 +0200 +Subject: [PATCH 08/11] phy: phy-rockchip-inno-usb2: simplify phy clock + handling + +Simplify phyclk handling by using devm_clk_get_optional_enabled to +acquire and enable the optional clock. This also fixes a resource +leak in driver remove path and adds proper error handling. + +Signed-off-by: Sebastian Reichel +--- + drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 19 ++++++------------- + 1 file changed, 6 insertions(+), 13 deletions(-) + +diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c +index aa8c55609c0d..1cf84869e78b 100644 +--- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c ++++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c +@@ -1390,24 +1390,22 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev) + if (IS_ERR(rphy->phy_reset)) + return PTR_ERR(rphy->phy_reset); + +- rphy->clk = of_clk_get_by_name(np, "phyclk"); +- if (!IS_ERR(rphy->clk)) { +- clk_prepare_enable(rphy->clk); +- } else { +- dev_info(&pdev->dev, "no phyclk specified\n"); +- rphy->clk = NULL; ++ rphy->clk = devm_clk_get_optional_enabled(dev, "phyclk"); ++ if (IS_ERR(rphy->clk)) { ++ return dev_err_probe(&pdev->dev, PTR_ERR(rphy->clk), ++ "failed to get phyclk\n"); + } + + ret = rockchip_usb2phy_clk480m_register(rphy); + if (ret) { + dev_err(dev, "failed to register 480m output clock\n"); +- goto disable_clks; ++ return ret; + } + + if (rphy->phy_cfg->phy_tuning) { + ret = rphy->phy_cfg->phy_tuning(rphy); + if (ret) +- goto disable_clks; ++ return ret; + } + + index = 0; +@@ -1470,11 +1468,6 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev) + + put_child: + of_node_put(child_np); +-disable_clks: +- if (rphy->clk) { +- clk_disable_unprepare(rphy->clk); +- clk_put(rphy->clk); +- } + return ret; + } + +-- +2.41.0 + + +From 4c7c30ae33f9c7b899672d43abba0cfe4e387d14 Mon Sep 17 00:00:00 2001 +From: Sebastian Reichel +Date: Mon, 3 Apr 2023 22:01:14 +0200 +Subject: [PATCH 09/11] phy: phy-rockchip-inno-usb2: simplify getting match + data + +Simplify the code by directly getting the match data via +device_get_match_data() instead of open coding its functionality. + +Signed-off-by: Sebastian Reichel +--- + drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 12 ++++-------- + 1 file changed, 4 insertions(+), 8 deletions(-) + +diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c +index 1cf84869e78b..f5c30f117cba 100644 +--- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c ++++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c +@@ -1305,7 +1305,6 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev) + struct phy_provider *provider; + struct rockchip_usb2phy *rphy; + const struct rockchip_usb2phy_cfg *phy_cfgs; +- const struct of_device_id *match; + unsigned int reg; + int index, ret; + +@@ -1313,12 +1312,6 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev) + if (!rphy) + return -ENOMEM; + +- match = of_match_device(dev->driver->of_match_table, dev); +- if (!match || !match->data) { +- dev_err(dev, "phy configs are not assigned!\n"); +- return -EINVAL; +- } +- + if (!dev->parent || !dev->parent->of_node) { + rphy->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,usbgrf"); + if (IS_ERR(rphy->grf)) { +@@ -1359,12 +1352,15 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev) + } + + rphy->dev = dev; +- phy_cfgs = match->data; ++ phy_cfgs = device_get_match_data(dev); + rphy->chg_state = USB_CHG_STATE_UNDEFINED; + rphy->chg_type = POWER_SUPPLY_TYPE_UNKNOWN; + rphy->irq = platform_get_irq_optional(pdev, 0); + platform_set_drvdata(pdev, rphy); + ++ if (!phy_cfgs) ++ return dev_err_probe(dev, -EINVAL, "phy configs are not assigned!\n"); ++ + ret = rockchip_usb2phy_extcon_register(rphy); + if (ret) + return ret; +-- +2.41.0 + + +From b4885b6a9f0183c270fc54326b1a3aa7b916129f Mon Sep 17 00:00:00 2001 +From: Sebastian Reichel +Date: Mon, 15 May 2023 18:40:42 +0200 +Subject: [PATCH 10/11] phy: phy-rockchip-inno-usb2: improve error message + +Printing the OF node is not useful, since we get the same information +from the device context. Instead print the reg address, that could +not be found. + +Signed-off-by: Sebastian Reichel +--- + drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c +index f5c30f117cba..b982c3f0d4b5 100644 +--- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c ++++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c +@@ -1377,8 +1377,7 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev) + } while (phy_cfgs[index].reg); + + if (!rphy->phy_cfg) { +- dev_err(dev, "no phy-config can be matched with %pOFn node\n", +- np); ++ dev_err(dev, "could not find phy config for reg=0x%08x\n", reg); + return -EINVAL; + } + +-- +2.41.0 + + +From 719bf79884297d5278f735bb08ed6a9fbaf37efa Mon Sep 17 00:00:00 2001 +From: Muhammed Efe Cetin +Date: Tue, 4 Jul 2023 13:36:35 +0300 +Subject: [PATCH 11/11] arm64: dts: rockchip: rk3588: add USB2 support + +This adds USB2 (EHCI & OHCI) ports including the related PHYs +and GRF modules to the rk3588(s) device tree. +--- + arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 94 +++++++++++++++++++++++ + 1 file changed, 94 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi +index 973fd6e8aa36..37e323ec9d74 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi +@@ -399,11 +399,105 @@ scmi_shmem: sram@0 { + }; + }; + ++ usb_host0_ehci: usb@fc800000 { ++ compatible = "rockchip,rk3588-ehci", "generic-ehci"; ++ reg = <0x0 0xfc800000 0x0 0x40000>; ++ interrupts = ; ++ clocks = <&cru HCLK_HOST0>, <&cru HCLK_HOST_ARB0>, <&cru ACLK_USB>, <&u2phy2>; ++ phys = <&u2phy2_host>; ++ phy-names = "usb"; ++ power-domains = <&power RK3588_PD_USB>; ++ status = "disabled"; ++ }; ++ ++ usb_host0_ohci: usb@fc840000 { ++ compatible = "rockchip,rk3588-ohci", "generic-ohci"; ++ reg = <0x0 0xfc840000 0x0 0x40000>; ++ interrupts = ; ++ clocks = <&cru HCLK_HOST0>, <&cru HCLK_HOST_ARB0>, <&cru ACLK_USB>, <&u2phy2>; ++ phys = <&u2phy2_host>; ++ phy-names = "usb"; ++ power-domains = <&power RK3588_PD_USB>; ++ status = "disabled"; ++ }; ++ ++ usb_host1_ehci: usb@fc880000 { ++ compatible = "rockchip,rk3588-ehci", "generic-ehci"; ++ reg = <0x0 0xfc880000 0x0 0x40000>; ++ interrupts = ; ++ clocks = <&cru HCLK_HOST1>, <&cru HCLK_HOST_ARB1>, <&cru ACLK_USB>, <&u2phy3>; ++ phys = <&u2phy3_host>; ++ phy-names = "usb"; ++ power-domains = <&power RK3588_PD_USB>; ++ status = "disabled"; ++ }; ++ ++ usb_host1_ohci: usb@fc8c0000 { ++ compatible = "rockchip,rk3588-ohci", "generic-ohci"; ++ reg = <0x0 0xfc8c0000 0x0 0x40000>; ++ interrupts = ; ++ clocks = <&cru HCLK_HOST1>, <&cru HCLK_HOST_ARB1>, <&cru ACLK_USB>, <&u2phy3>; ++ phys = <&u2phy3_host>; ++ phy-names = "usb"; ++ power-domains = <&power RK3588_PD_USB>; ++ status = "disabled"; ++ }; ++ + sys_grf: syscon@fd58c000 { + compatible = "rockchip,rk3588-sys-grf", "syscon"; + reg = <0x0 0xfd58c000 0x0 0x1000>; + }; + ++ usb2phy2_grf: syscon@fd5d8000 { ++ compatible = "rockchip,rk3588-usb2phy-grf", "syscon", "simple-mfd"; ++ reg = <0x0 0xfd5d8000 0x0 0x4000>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ u2phy2: usb2-phy@8000 { ++ compatible = "rockchip,rk3588-usb2phy"; ++ reg = <0x8000 0x10>; ++ interrupts = ; ++ resets = <&cru SRST_OTGPHY_U2_0>, <&cru SRST_P_USB2PHY_U2_0_GRF0>; ++ reset-names = "phy", "apb"; ++ clocks = <&cru CLK_USB2PHY_HDPTXRXPHY_REF>; ++ clock-names = "phyclk"; ++ clock-output-names = "usb480m_phy2"; ++ #clock-cells = <0>; ++ status = "disabled"; ++ ++ u2phy2_host: host-port { ++ #phy-cells = <0>; ++ status = "disabled"; ++ }; ++ }; ++ }; ++ ++ usb2phy3_grf: syscon@fd5dc000 { ++ compatible = "rockchip,rk3588-usb2phy-grf", "syscon", "simple-mfd"; ++ reg = <0x0 0xfd5dc000 0x0 0x4000>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ u2phy3: usb2-phy@c000 { ++ compatible = "rockchip,rk3588-usb2phy"; ++ reg = <0xc000 0x10>; ++ interrupts = ; ++ resets = <&cru SRST_OTGPHY_U2_1>, <&cru SRST_P_USB2PHY_U2_1_GRF0>; ++ reset-names = "phy", "apb"; ++ clocks = <&cru CLK_USB2PHY_HDPTXRXPHY_REF>; ++ clock-names = "phyclk"; ++ clock-output-names = "usb480m_phy3"; ++ #clock-cells = <0>; ++ status = "disabled"; ++ ++ u2phy3_host: host-port { ++ #phy-cells = <0>; ++ status = "disabled"; ++ }; ++ }; ++ }; ++ + php_grf: syscon@fd5b0000 { + compatible = "rockchip,rk3588-php-grf", "syscon"; + reg = <0x0 0xfd5b0000 0x0 0x1000>; +-- +2.41.0 + diff --git a/patch/kernel/rockchip-rk3588-edge/0026-Add-RK3588-USB3-Support.patch b/patch/kernel/rockchip-rk3588-edge/0026-Add-RK3588-USB3-Support.patch new file mode 100644 index 0000000000..279c0e4314 --- /dev/null +++ b/patch/kernel/rockchip-rk3588-edge/0026-Add-RK3588-USB3-Support.patch @@ -0,0 +1,2561 @@ +From 0a75395f2d9bac99a964668b560508daefbbd3cd Mon Sep 17 00:00:00 2001 +From: Sebastian Reichel +Date: Tue, 25 Apr 2023 17:38:57 +0200 +Subject: [PATCH 1/6] dt-bindings: phy: add rockchip usbdp combo phy document + +Add device tree binding document for Rockchip USBDP Combo PHY +with Samsung IP block. + +Co-developed-by: Frank Wang +Signed-off-by: Frank Wang +Signed-off-by: Sebastian Reichel +--- + .../bindings/phy/phy-rockchip-usbdp.yaml | 166 ++++++++++++++++++ + 1 file changed, 166 insertions(+) + create mode 100644 Documentation/devicetree/bindings/phy/phy-rockchip-usbdp.yaml + +diff --git a/Documentation/devicetree/bindings/phy/phy-rockchip-usbdp.yaml b/Documentation/devicetree/bindings/phy/phy-rockchip-usbdp.yaml +new file mode 100644 +index 000000000000..dcca84d57e99 +--- /dev/null ++++ b/Documentation/devicetree/bindings/phy/phy-rockchip-usbdp.yaml +@@ -0,0 +1,166 @@ ++# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) ++%YAML 1.2 ++--- ++$id: http://devicetree.org/schemas/phy/phy-rockchip-usbdp.yaml# ++$schema: http://devicetree.org/meta-schemas/core.yaml# ++ ++title: Rockchip USBDP Combo PHY with Samsung IP block ++ ++maintainers: ++ - Frank Wang ++ - Zhang Yubing ++ ++properties: ++ compatible: ++ enum: ++ - rockchip,rk3588-usbdp-phy ++ ++ reg: ++ maxItems: 1 ++ ++ clocks: ++ maxItems: 4 ++ ++ clock-names: ++ items: ++ - const: refclk ++ - const: immortal ++ - const: pclk ++ - const: utmi ++ ++ resets: ++ maxItems: 5 ++ ++ reset-names: ++ items: ++ - const: init ++ - const: cmn ++ - const: lane ++ - const: pcs_apb ++ - const: pma_apb ++ ++ rockchip,dp-lane-mux: ++ $ref: /schemas/types.yaml#/definitions/uint32-array ++ minItems: 2 ++ maxItems: 4 ++ description: ++ An array of physical Tyep-C lanes indexes. Position of an entry determines ++ the dp lane index, while the value of an entry indicater physical Type-C lane. ++ The support dp lanes number are 2 or 4. e.g. for 2 lanes dp lanes map, we could ++ have "rockchip,dp-lane-mux = <2, 3>;", assuming dp lane0 on Type-C phy lane2, ++ dp lane1 on Type-C phy lane3. For 4 lanes dp lanes map, we could have ++ "rockchip,dp-lane-mux = <0, 1, 2, 3>;", assuming dp lane0 on Type-C phy lane0, ++ dp lane1 on Type-C phy lane1, dp lane2 on Type-C phy lane2, dp lane3 on Type-C ++ phy lane3. If dp lane map by DisplayPort Alt mode, this property is not need. ++ ++ rockchip,u2phy-grf: ++ $ref: /schemas/types.yaml#/definitions/phandle ++ description: ++ Phandle to the syscon managing the 'usb2 phy general register files'. ++ ++ rockchip,usb-grf: ++ $ref: /schemas/types.yaml#/definitions/phandle ++ description: ++ Phandle to the syscon managing the 'usb general register files'. ++ ++ rockchip,usbdpphy-grf: ++ $ref: /schemas/types.yaml#/definitions/phandle ++ description: ++ Phandle to the syscon managing the 'usbdp phy general register files'. ++ ++ rockchip,vo-grf: ++ $ref: /schemas/types.yaml#/definitions/phandle ++ description: ++ Phandle to the syscon managing the 'video output general register files'. ++ When select the dp lane mapping will request its phandle. ++ ++ sbu1-dc-gpios: ++ description: ++ GPIO connected to the SBU1 line of the USB-C connector via a big resistor ++ (~100K) to apply a DC offset for signalling the connector orientation. ++ ++ sbu2-dc-gpios: ++ description: ++ GPIO connected to the SBU2 line of the USB-C connector via a big resistor ++ (~100K) to apply a DC offset for signalling the connector orientation. ++ ++ orientation-switch: ++ description: Flag the port as possible handler of orientation switching ++ type: boolean ++ ++ mode-switch: ++ description: Flag the port as possible handle of altmode switching ++ type: boolean ++ ++ dp-port: ++ type: object ++ additionalProperties: false ++ ++ properties: ++ "#phy-cells": ++ const: 0 ++ ++ required: ++ - "#phy-cells" ++ ++ usb3-port: ++ type: object ++ additionalProperties: false ++ ++ properties: ++ "#phy-cells": ++ const: 0 ++ ++ required: ++ - "#phy-cells" ++ ++ port: ++ $ref: /schemas/graph.yaml#/properties/port ++ description: ++ A port node to link the PHY to a TypeC controller for the purpose of ++ handling orientation switching. ++ ++required: ++ - compatible ++ - reg ++ - clocks ++ - clock-names ++ - resets ++ - reset-names ++ - dp-port ++ - usb3-port ++ ++additionalProperties: false ++ ++examples: ++ - | ++ #include ++ ++ usbdp_phy0: phy@fed80000 { ++ compatible = "rockchip,rk3588-usbdp-phy"; ++ reg = <0x0 0xfed80000 0x0 0x10000>; ++ rockchip,u2phy-grf = <&usb2phy0_grf>; ++ rockchip,usb-grf = <&usb_grf>; ++ rockchip,usbdpphy-grf = <&usbdpphy0_grf>; ++ rockchip,vo-grf = <&vo0_grf>; ++ clocks = <&cru CLK_USBDPPHY_MIPIDCPPHY_REF>, ++ <&cru CLK_USBDP_PHY0_IMMORTAL>, ++ <&cru PCLK_USBDPPHY0>; ++ clock-names = "refclk", "immortal", "pclk"; ++ resets = <&cru SRST_USBDP_COMBO_PHY0_INIT>, ++ <&cru SRST_USBDP_COMBO_PHY0_CMN>, ++ <&cru SRST_USBDP_COMBO_PHY0_LANE>, ++ <&cru SRST_USBDP_COMBO_PHY0_PCS>, ++ <&cru SRST_P_USBDPPHY0>; ++ reset-names = "init", "cmn", "lane", "pcs_apb", "pma_apb"; ++ status = "disabled"; ++ ++ usbdp_phy0_dp: dp-port { ++ #phy-cells = <0>; ++ status = "disabled"; ++ }; ++ ++ usbdp_phy0_u3: usb3-port { ++ #phy-cells = <0>; ++ status = "disabled"; ++ }; +-- +2.41.0 + + +From 22cd81086f9197d6b7f6aa851d6338625a426fd9 Mon Sep 17 00:00:00 2001 +From: Sebastian Reichel +Date: Tue, 30 May 2023 16:40:02 +0200 +Subject: [PATCH 2/6] dt-bindings: usb: rockchip,dwc3: Add RK3588 binding + +RK3588 contains three DWC3 cores. Two of them are connected to +dedicated USBDP PHY and can be used in dual-role. The third is +connected to one of the shared combo PHYs used for PCIe/SATA/USB3 +and can only be used in host mode. Since the binding is all about +the PHY glueing and involved clocks, separate compatible values +have been created for these two types. + +Signed-off-by: Sebastian Reichel +--- + .../bindings/usb/rockchip,rk3399-dwc3.yaml | 107 ++++++++++++++---- + 1 file changed, 85 insertions(+), 22 deletions(-) + +diff --git a/Documentation/devicetree/bindings/usb/rockchip,rk3399-dwc3.yaml b/Documentation/devicetree/bindings/usb/rockchip,rk3399-dwc3.yaml +index 3159f9a6a0f7..0db4dc86e506 100644 +--- a/Documentation/devicetree/bindings/usb/rockchip,rk3399-dwc3.yaml ++++ b/Documentation/devicetree/bindings/usb/rockchip,rk3399-dwc3.yaml +@@ -11,7 +11,13 @@ maintainers: + + properties: + compatible: +- const: rockchip,rk3399-dwc3 ++ oneOf: ++ - items: ++ - enum: ++ - rockchip,rk3588-dwc3-otg ++ - rockchip,rk3588-dwc3-host ++ - const: rockchip,rk3399-dwc3 ++ - const: rockchip,rk3399-dwc3 + + '#address-cells': + const: 2 +@@ -22,35 +28,37 @@ properties: + ranges: true + + clocks: +- items: +- - description: +- Controller reference clock, must to be 24 MHz +- - description: +- Controller suspend clock, must to be 24 MHz or 32 KHz +- - description: +- Master/Core clock, must to be >= 62.5 MHz for SS +- operation and >= 30MHz for HS operation +- - description: +- USB3 aclk peri +- - description: +- USB3 aclk +- - description: +- Controller grf clock ++ minItems: 3 ++ maxItems: 6 + + clock-names: + items: +- - const: ref_clk +- - const: suspend_clk +- - const: bus_clk +- - const: aclk_usb3_rksoc_axi_perf +- - const: aclk_usb3 +- - const: grf_clk ++ oneOf: ++ - enum: ++ - ref ++ - ref_clk ++ - enum: ++ - suspend ++ - suspend_clk ++ - enum: ++ - bus ++ - bus_clk ++ - const: aclk_usb3_rksoc_axi_perf ++ - const: aclk_usb3 ++ - const: grf_clk ++ - const: utmi ++ - const: php ++ - const: pipe ++ minItems: 3 ++ maxItems: 6 + + resets: + maxItems: 1 + + reset-names: +- const: usb3-otg ++ enum: ++ - usb3-host ++ - usb3-otg + + patternProperties: + '^usb@': +@@ -68,6 +76,61 @@ required: + - resets + - reset-names + ++allOf: ++ - if: ++ properties: ++ compatible: ++ const: rockchip,rk3399-dwc3 ++ then: ++ properties: ++ clocks: ++ minItems: 6 ++ clock-names: ++ items: ++ - const: ref_clk ++ - const: suspend_clk ++ - const: bus_clk ++ - const: aclk_usb3_rksoc_axi_perf ++ - const: aclk_usb3 ++ - const: grf_clk ++ reset-names: ++ const: usb3-otg ++ - if: ++ properties: ++ compatible: ++ contains: ++ const: rockchip,rk3588-dwc3-otg ++ then: ++ properties: ++ clocks: ++ maxItems: 3 ++ clock-names: ++ items: ++ - const: ref ++ - const: suspend ++ - const: bus ++ reset-names: ++ const: usb3-otg ++ - if: ++ properties: ++ compatible: ++ contains: ++ const: rockchip,rk3588-dwc3-host ++ then: ++ properties: ++ clocks: ++ minItems: 6 ++ clock-names: ++ items: ++ - const: ref ++ - const: suspend ++ - const: bus ++ - const: utmi ++ - const: php ++ - const: pipe ++ reset-names: ++ const: usb3-host ++ + examples: + - | + #include +-- +2.41.0 + + +From e8991b26f1835f53c4e318eb02bb9953949595dc Mon Sep 17 00:00:00 2001 +From: Sebastian Reichel +Date: Tue, 30 May 2023 18:49:48 +0200 +Subject: [PATCH 3/6] dt-bindings: soc: rockchip: add rk3588 USB3 syscon + +RK3588 USB3 support requires the GRF for USB, USBDP PHY and VO. + +Signed-off-by: Sebastian Reichel +--- + .../devicetree/bindings/soc/rockchip/grf.yaml | 22 +++++++++++++++++++ + 1 file changed, 22 insertions(+) + +diff --git a/Documentation/devicetree/bindings/soc/rockchip/grf.yaml b/Documentation/devicetree/bindings/soc/rockchip/grf.yaml +index 65a2d5a4f28d..8d15c10a8f7e 100644 +--- a/Documentation/devicetree/bindings/soc/rockchip/grf.yaml ++++ b/Documentation/devicetree/bindings/soc/rockchip/grf.yaml +@@ -27,6 +27,9 @@ properties: + - rockchip,rk3588-sys-grf + - rockchip,rk3588-pcie3-phy-grf + - rockchip,rk3588-pcie3-pipe-grf ++ - rockchip,rk3588-usb-grf ++ - rockchip,rk3588-usbdpphy-grf ++ - rockchip,rk3588-vo-grf + - rockchip,rv1108-usbgrf + - const: syscon + - items: +@@ -62,6 +65,9 @@ properties: + reg: + maxItems: 1 + ++ clocks: ++ maxItems: 1 ++ + "#address-cells": + const: 1 + +@@ -242,6 +248,22 @@ allOf: + + unevaluatedProperties: false + ++ - if: ++ properties: ++ compatible: ++ contains: ++ enum: ++ - rockchip,rk3588-vo-grf ++ ++ then: ++ required: ++ - clocks ++ ++ else: ++ properties: ++ clocks: false ++ ++ + examples: + - | + #include +-- +2.41.0 + + +From 50e9c28ab2696125dfef1f12db3a835b70a05b7f Mon Sep 17 00:00:00 2001 +From: Frank Wang +Date: Tue, 25 Apr 2023 15:55:54 +0200 +Subject: [PATCH 4/6] phy: rockchip: add usbdp combo phy driver + +This adds a new USBDP combo PHY with Samsung IP block driver. + +The driver get lane mux and mapping info in 2 ways, supporting +DisplayPort alternate mode or parsing from DT. When parsing from DT, +the property "rockchip,dp-lane-mux" provide the DP mux and mapping info. + +When do DP link training, need to set lane number, link rate, swing, and +pre-emphasis via PHY configure interface. + +Co-developed-by: Zhang Yubing +Signed-off-by: Zhang Yubing +Co-developed-by: Frank Wang +Signed-off-by: Frank Wang +Signed-off-by: Sebastian Reichel +--- + drivers/phy/rockchip/Kconfig | 12 + + drivers/phy/rockchip/Makefile | 1 + + drivers/phy/rockchip/phy-rockchip-usbdp.c | 1728 +++++++++++++++++++++ + 3 files changed, 1741 insertions(+) + create mode 100644 drivers/phy/rockchip/phy-rockchip-usbdp.c + +diff --git a/drivers/phy/rockchip/Kconfig b/drivers/phy/rockchip/Kconfig +index 94360fc96a6f..d21b458c1d18 100644 +--- a/drivers/phy/rockchip/Kconfig ++++ b/drivers/phy/rockchip/Kconfig +@@ -107,3 +107,15 @@ config PHY_ROCKCHIP_USB + select GENERIC_PHY + help + Enable this to support the Rockchip USB 2.0 PHY. ++ ++config PHY_ROCKCHIP_USBDP ++ tristate "Rockchip USBDP COMBO PHY Driver" ++ depends on ARCH_ROCKCHIP && OF ++ select GENERIC_PHY ++ select TYPEC ++ help ++ Enable this to support the Rockchip USB3.0/DP combo PHY with ++ Samsung IP block. This is required for USB3 support on RK3588. ++ ++ To compile this driver as a module, choose M here: the module ++ will be called phy-rockchip-usbdp +diff --git a/drivers/phy/rockchip/Makefile b/drivers/phy/rockchip/Makefile +index 7eab129230d1..25d2e1355db7 100644 +--- a/drivers/phy/rockchip/Makefile ++++ b/drivers/phy/rockchip/Makefile +@@ -11,3 +11,4 @@ obj-$(CONFIG_PHY_ROCKCHIP_PCIE) += phy-rockchip-pcie.o + obj-$(CONFIG_PHY_ROCKCHIP_SNPS_PCIE3) += phy-rockchip-snps-pcie3.o + obj-$(CONFIG_PHY_ROCKCHIP_TYPEC) += phy-rockchip-typec.o + obj-$(CONFIG_PHY_ROCKCHIP_USB) += phy-rockchip-usb.o ++obj-$(CONFIG_PHY_ROCKCHIP_USBDP) += phy-rockchip-usbdp.o +diff --git a/drivers/phy/rockchip/phy-rockchip-usbdp.c b/drivers/phy/rockchip/phy-rockchip-usbdp.c +new file mode 100644 +index 000000000000..414081b1247d +--- /dev/null ++++ b/drivers/phy/rockchip/phy-rockchip-usbdp.c +@@ -0,0 +1,1728 @@ ++// SPDX-License-Identifier: GPL-2.0-or-later ++/* ++ * Rockchip USBDP Combo PHY with Samsung IP block driver ++ * ++ * Copyright (C) 2021 Rockchip Electronics Co., Ltd ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* RK3588 USBDP PHY Register Definitions */ ++ ++#define UDPHY_PCS 0x4000 ++#define UDPHY_PMA 0x8000 ++ ++/* VO0 GRF Registers */ ++#define RK3588_GRF_VO0_CON0 0x0000 ++#define RK3588_GRF_VO0_CON2 0x0008 ++#define DP_SINK_HPD_CFG BIT(11) ++#define DP_SINK_HPD_SEL BIT(10) ++#define DP_AUX_DIN_SEL BIT(9) ++#define DP_AUX_DOUT_SEL BIT(8) ++#define DP_LANE_SEL_N(n) GENMASK(2 * (n) + 1, 2 * (n)) ++#define DP_LANE_SEL_ALL GENMASK(7, 0) ++#define PHY_AUX_DP_DATA_POL_NORMAL 0 ++#define PHY_AUX_DP_DATA_POL_INVERT 1 ++ ++/* PMA CMN Registers */ ++#define CMN_LANE_MUX_AND_EN_OFFSET 0x0288 /* cmn_reg00A2 */ ++#define CMN_DP_LANE_MUX_N(n) BIT((n) + 4) ++#define CMN_DP_LANE_EN_N(n) BIT(n) ++#define CMN_DP_LANE_MUX_ALL GENMASK(7, 4) ++#define CMN_DP_LANE_EN_ALL GENMASK(3, 0) ++#define PHY_LANE_MUX_USB 0 ++#define PHY_LANE_MUX_DP 1 ++ ++#define CMN_DP_LINK_OFFSET 0x28c /*cmn_reg00A3 */ ++#define CMN_DP_TX_LINK_BW GENMASK(6, 5) ++#define CMN_DP_TX_LANE_SWAP_EN BIT(2) ++ ++#define CMN_SSC_EN_OFFSET 0x2d0 /* cmn_reg00B4 */ ++#define CMN_ROPLL_SSC_EN BIT(1) ++#define CMN_LCPLL_SSC_EN BIT(0) ++ ++#define CMN_ANA_LCPLL_DONE_OFFSET 0x0350 /* cmn_reg00D4 */ ++#define CMN_ANA_LCPLL_LOCK_DONE BIT(7) ++#define CMN_ANA_LCPLL_AFC_DONE BIT(6) ++ ++#define CMN_ANA_ROPLL_DONE_OFFSET 0x0354 /* cmn_reg00D5 */ ++#define CMN_ANA_ROPLL_LOCK_DONE BIT(1) ++#define CMN_ANA_ROPLL_AFC_DONE BIT(0) ++ ++#define CMN_DP_RSTN_OFFSET 0x038c /* cmn_reg00E3 */ ++#define CMN_DP_INIT_RSTN BIT(3) ++#define CMN_DP_CMN_RSTN BIT(2) ++#define CMN_CDR_WTCHDG_EN BIT(1) ++#define CMN_CDR_WTCHDG_MSK_CDR_EN BIT(0) ++ ++#define TRSV_ANA_TX_CLK_OFFSET_N(n) (0x854 + (n) * 0x800) /* trsv_reg0215 */ ++#define LN_ANA_TX_SER_TXCLK_INV BIT(1) ++ ++#define TRSV_LN0_MON_RX_CDR_DONE_OFFSET 0x0b84 /* trsv_reg02E1 */ ++#define TRSV_LN0_MON_RX_CDR_LOCK_DONE BIT(0) ++ ++#define TRSV_LN2_MON_RX_CDR_DONE_OFFSET 0x1b84 /* trsv_reg06E1 */ ++#define TRSV_LN2_MON_RX_CDR_LOCK_DONE BIT(0) ++ ++ ++#define BIT_WRITEABLE_SHIFT 16 ++ ++enum { ++ DP_BW_RBR, ++ DP_BW_HBR, ++ DP_BW_HBR2, ++ DP_BW_HBR3, ++}; ++ ++enum { ++ UDPHY_MODE_NONE = 0, ++ UDPHY_MODE_USB = BIT(0), ++ UDPHY_MODE_DP = BIT(1), ++ UDPHY_MODE_DP_USB = BIT(1) | BIT(0), ++}; ++ ++struct udphy_grf_reg { ++ unsigned int offset; ++ unsigned int bitend; ++ unsigned int bitstart; ++ unsigned int disable; ++ unsigned int enable; ++}; ++ ++struct udphy_grf_cfg { ++ /* u2phy-grf */ ++ struct udphy_grf_reg bvalid_phy_con; ++ struct udphy_grf_reg bvalid_grf_con; ++ ++ /* usb-grf */ ++ struct udphy_grf_reg usb3otg0_cfg; ++ struct udphy_grf_reg usb3otg1_cfg; ++ ++ /* usbdpphy-grf */ ++ struct udphy_grf_reg low_pwrn; ++ struct udphy_grf_reg rx_lfps; ++}; ++ ++struct udphy_vogrf_cfg { ++ /* vo-grf */ ++ struct udphy_grf_reg hpd_trigger; ++}; ++ ++struct dp_tx_drv_ctrl { ++ u32 trsv_reg0204; ++ u32 trsv_reg0205; ++ u32 trsv_reg0206; ++ u32 trsv_reg0207; ++}; ++ ++struct rockchip_udphy; ++ ++struct rockchip_udphy_cfg { ++ /* resets to be requested */ ++ const char * const *rst_list; ++ int num_rsts; ++ ++ struct udphy_grf_cfg grfcfg; ++ struct udphy_vogrf_cfg vogrfcfg[2]; ++ const struct dp_tx_drv_ctrl (*dp_tx_ctrl_cfg[4])[4]; ++ const struct dp_tx_drv_ctrl (*dp_tx_ctrl_cfg_typec[4])[4]; ++ int (*combophy_init)(struct rockchip_udphy *udphy); ++ int (*dp_phy_set_rate)(struct rockchip_udphy *udphy, ++ struct phy_configure_opts_dp *dp); ++ int (*dp_phy_set_voltages)(struct rockchip_udphy *udphy, ++ struct phy_configure_opts_dp *dp); ++ int (*hpd_event_trigger)(struct rockchip_udphy *udphy, bool hpd); ++ int (*dplane_enable)(struct rockchip_udphy *udphy, int dp_lanes); ++ int (*dplane_select)(struct rockchip_udphy *udphy); ++}; ++ ++struct rockchip_udphy { ++ struct device *dev; ++ struct regmap *pma_regmap; ++ struct regmap *u2phygrf; ++ struct regmap *udphygrf; ++ struct regmap *usbgrf; ++ struct regmap *vogrf; ++ struct typec_switch_dev *sw; ++ struct typec_mux_dev *mux; ++ struct mutex mutex; /* mutex to protect access to individual PHYs */ ++ ++ /* clocks and rests */ ++ int num_clks; ++ struct clk_bulk_data *clks; ++ struct clk *refclk; ++ struct reset_control **rsts; ++ ++ /* PHY status management */ ++ bool flip; ++ bool mode_change; ++ u8 mode; ++ u8 status; ++ ++ /* utilized for USB */ ++ bool hs; /* flag for high-speed */ ++ ++ /* utilized for DP */ ++ struct gpio_desc *sbu1_dc_gpio; ++ struct gpio_desc *sbu2_dc_gpio; ++ u32 lane_mux_sel[4]; ++ u32 dp_lane_sel[4]; ++ u32 dp_aux_dout_sel; ++ u32 dp_aux_din_sel; ++ bool dp_sink_hpd_sel; ++ bool dp_sink_hpd_cfg; ++ u8 bw; ++ int id; ++ ++ /* PHY const config */ ++ const struct rockchip_udphy_cfg *cfgs; ++}; ++ ++static const struct dp_tx_drv_ctrl rk3588_dp_tx_drv_ctrl_rbr_hbr[4][4] = { ++ /* voltage swing 0, pre-emphasis 0->3 */ ++ { ++ { 0x20, 0x10, 0x42, 0xe5 }, ++ { 0x26, 0x14, 0x42, 0xe5 }, ++ { 0x29, 0x18, 0x42, 0xe5 }, ++ { 0x2b, 0x1c, 0x43, 0xe7 }, ++ }, ++ ++ /* voltage swing 1, pre-emphasis 0->2 */ ++ { ++ { 0x23, 0x10, 0x42, 0xe7 }, ++ { 0x2a, 0x17, 0x43, 0xe7 }, ++ { 0x2b, 0x1a, 0x43, 0xe7 }, ++ }, ++ ++ /* voltage swing 2, pre-emphasis 0->1 */ ++ { ++ { 0x27, 0x10, 0x42, 0xe7 }, ++ { 0x2b, 0x17, 0x43, 0xe7 }, ++ }, ++ ++ /* voltage swing 3, pre-emphasis 0 */ ++ { ++ { 0x29, 0x10, 0x43, 0xe7 }, ++ }, ++}; ++ ++static const struct dp_tx_drv_ctrl rk3588_dp_tx_drv_ctrl_rbr_hbr_typec[4][4] = { ++ /* voltage swing 0, pre-emphasis 0->3 */ ++ { ++ { 0x20, 0x10, 0x42, 0xe5 }, ++ { 0x26, 0x14, 0x42, 0xe5 }, ++ { 0x29, 0x18, 0x42, 0xe5 }, ++ { 0x2b, 0x1c, 0x43, 0xe7 }, ++ }, ++ ++ /* voltage swing 1, pre-emphasis 0->2 */ ++ { ++ { 0x23, 0x10, 0x42, 0xe7 }, ++ { 0x2a, 0x17, 0x43, 0xe7 }, ++ { 0x2b, 0x1a, 0x43, 0xe7 }, ++ }, ++ ++ /* voltage swing 2, pre-emphasis 0->1 */ ++ { ++ { 0x27, 0x10, 0x43, 0x67 }, ++ { 0x2b, 0x17, 0x43, 0xe7 }, ++ }, ++ ++ /* voltage swing 3, pre-emphasis 0 */ ++ { ++ { 0x29, 0x10, 0x43, 0xe7 }, ++ }, ++}; ++ ++static const struct dp_tx_drv_ctrl rk3588_dp_tx_drv_ctrl_hbr2[4][4] = { ++ /* voltage swing 0, pre-emphasis 0->3 */ ++ { ++ { 0x21, 0x10, 0x42, 0xe5 }, ++ { 0x26, 0x14, 0x42, 0xe5 }, ++ { 0x26, 0x16, 0x43, 0xe5 }, ++ { 0x2a, 0x19, 0x43, 0xe7 }, ++ }, ++ ++ /* voltage swing 1, pre-emphasis 0->2 */ ++ { ++ { 0x24, 0x10, 0x42, 0xe7 }, ++ { 0x2a, 0x17, 0x43, 0xe7 }, ++ { 0x2b, 0x1a, 0x43, 0xe7 }, ++ }, ++ ++ /* voltage swing 2, pre-emphasis 0->1 */ ++ { ++ { 0x28, 0x10, 0x42, 0xe7 }, ++ { 0x2b, 0x17, 0x43, 0xe7 }, ++ }, ++ ++ /* voltage swing 3, pre-emphasis 0 */ ++ { ++ { 0x28, 0x10, 0x43, 0xe7 }, ++ }, ++}; ++ ++static const struct dp_tx_drv_ctrl rk3588_dp_tx_drv_ctrl_hbr3[4][4] = { ++ /* voltage swing 0, pre-emphasis 0->3 */ ++ { ++ { 0x21, 0x10, 0x42, 0xe5 }, ++ { 0x26, 0x14, 0x42, 0xe5 }, ++ { 0x26, 0x16, 0x43, 0xe5 }, ++ { 0x29, 0x18, 0x43, 0xe7 }, ++ }, ++ ++ /* voltage swing 1, pre-emphasis 0->2 */ ++ { ++ { 0x24, 0x10, 0x42, 0xe7 }, ++ { 0x2a, 0x18, 0x43, 0xe7 }, ++ { 0x2b, 0x1b, 0x43, 0xe7 } ++ }, ++ ++ /* voltage swing 2, pre-emphasis 0->1 */ ++ { ++ { 0x27, 0x10, 0x42, 0xe7 }, ++ { 0x2b, 0x18, 0x43, 0xe7 } ++ }, ++ ++ /* voltage swing 3, pre-emphasis 0 */ ++ { ++ { 0x28, 0x10, 0x43, 0xe7 }, ++ }, ++}; ++ ++static const struct reg_sequence rk3588_udphy_24m_refclk_cfg[] = { ++ {0x0090, 0x68}, {0x0094, 0x68}, ++ {0x0128, 0x24}, {0x012c, 0x44}, ++ {0x0130, 0x3f}, {0x0134, 0x44}, ++ {0x015c, 0xa9}, {0x0160, 0x71}, ++ {0x0164, 0x71}, {0x0168, 0xa9}, ++ {0x0174, 0xa9}, {0x0178, 0x71}, ++ {0x017c, 0x71}, {0x0180, 0xa9}, ++ {0x018c, 0x41}, {0x0190, 0x00}, ++ {0x0194, 0x05}, {0x01ac, 0x2a}, ++ {0x01b0, 0x17}, {0x01b4, 0x17}, ++ {0x01b8, 0x2a}, {0x01c8, 0x04}, ++ {0x01cc, 0x08}, {0x01d0, 0x08}, ++ {0x01d4, 0x04}, {0x01d8, 0x20}, ++ {0x01dc, 0x01}, {0x01e0, 0x09}, ++ {0x01e4, 0x03}, {0x01f0, 0x29}, ++ {0x01f4, 0x02}, {0x01f8, 0x02}, ++ {0x01fc, 0x29}, {0x0208, 0x2a}, ++ {0x020c, 0x17}, {0x0210, 0x17}, ++ {0x0214, 0x2a}, {0x0224, 0x20}, ++ {0x03f0, 0x0a}, {0x03f4, 0x07}, ++ {0x03f8, 0x07}, {0x03fc, 0x0c}, ++ {0x0404, 0x12}, {0x0408, 0x1a}, ++ {0x040c, 0x1a}, {0x0410, 0x3f}, ++ {0x0ce0, 0x68}, {0x0ce8, 0xd0}, ++ {0x0cf0, 0x87}, {0x0cf8, 0x70}, ++ {0x0d00, 0x70}, {0x0d08, 0xa9}, ++ {0x1ce0, 0x68}, {0x1ce8, 0xd0}, ++ {0x1cf0, 0x87}, {0x1cf8, 0x70}, ++ {0x1d00, 0x70}, {0x1d08, 0xa9}, ++ {0x0a3c, 0xd0}, {0x0a44, 0xd0}, ++ {0x0a48, 0x01}, {0x0a4c, 0x0d}, ++ {0x0a54, 0xe0}, {0x0a5c, 0xe0}, ++ {0x0a64, 0xa8}, {0x1a3c, 0xd0}, ++ {0x1a44, 0xd0}, {0x1a48, 0x01}, ++ {0x1a4c, 0x0d}, {0x1a54, 0xe0}, ++ {0x1a5c, 0xe0}, {0x1a64, 0xa8} ++}; ++ ++static const struct reg_sequence rk3588_udphy_26m_refclk_cfg[] = { ++ {0x0830, 0x07}, {0x085c, 0x80}, ++ {0x1030, 0x07}, {0x105c, 0x80}, ++ {0x1830, 0x07}, {0x185c, 0x80}, ++ {0x2030, 0x07}, {0x205c, 0x80}, ++ {0x0228, 0x38}, {0x0104, 0x44}, ++ {0x0248, 0x44}, {0x038C, 0x02}, ++ {0x0878, 0x04}, {0x1878, 0x04}, ++ {0x0898, 0x77}, {0x1898, 0x77}, ++ {0x0054, 0x01}, {0x00e0, 0x38}, ++ {0x0060, 0x24}, {0x0064, 0x77}, ++ {0x0070, 0x76}, {0x0234, 0xE8}, ++ {0x0AF4, 0x15}, {0x1AF4, 0x15}, ++ {0x081C, 0xE5}, {0x181C, 0xE5}, ++ {0x099C, 0x48}, {0x199C, 0x48}, ++ {0x09A4, 0x07}, {0x09A8, 0x22}, ++ {0x19A4, 0x07}, {0x19A8, 0x22}, ++ {0x09B8, 0x3E}, {0x19B8, 0x3E}, ++ {0x09E4, 0x02}, {0x19E4, 0x02}, ++ {0x0A34, 0x1E}, {0x1A34, 0x1E}, ++ {0x0A98, 0x2F}, {0x1A98, 0x2F}, ++ {0x0c30, 0x0E}, {0x0C48, 0x06}, ++ {0x1C30, 0x0E}, {0x1C48, 0x06}, ++ {0x028C, 0x18}, {0x0AF0, 0x00}, ++ {0x1AF0, 0x00} ++}; ++ ++static const struct reg_sequence rk3588_udphy_init_sequence[] = { ++ {0x0104, 0x44}, {0x0234, 0xE8}, ++ {0x0248, 0x44}, {0x028C, 0x18}, ++ {0x081C, 0xE5}, {0x0878, 0x00}, ++ {0x0994, 0x1C}, {0x0AF0, 0x00}, ++ {0x181C, 0xE5}, {0x1878, 0x00}, ++ {0x1994, 0x1C}, {0x1AF0, 0x00}, ++ {0x0428, 0x60}, {0x0D58, 0x33}, ++ {0x1D58, 0x33}, {0x0990, 0x74}, ++ {0x0D64, 0x17}, {0x08C8, 0x13}, ++ {0x1990, 0x74}, {0x1D64, 0x17}, ++ {0x18C8, 0x13}, {0x0D90, 0x40}, ++ {0x0DA8, 0x40}, {0x0DC0, 0x40}, ++ {0x0DD8, 0x40}, {0x1D90, 0x40}, ++ {0x1DA8, 0x40}, {0x1DC0, 0x40}, ++ {0x1DD8, 0x40}, {0x03C0, 0x30}, ++ {0x03C4, 0x06}, {0x0E10, 0x00}, ++ {0x1E10, 0x00}, {0x043C, 0x0F}, ++ {0x0D2C, 0xFF}, {0x1D2C, 0xFF}, ++ {0x0D34, 0x0F}, {0x1D34, 0x0F}, ++ {0x08FC, 0x2A}, {0x0914, 0x28}, ++ {0x0A30, 0x03}, {0x0E38, 0x05}, ++ {0x0ECC, 0x27}, {0x0ED0, 0x22}, ++ {0x0ED4, 0x26}, {0x18FC, 0x2A}, ++ {0x1914, 0x28}, {0x1A30, 0x03}, ++ {0x1E38, 0x05}, {0x1ECC, 0x27}, ++ {0x1ED0, 0x22}, {0x1ED4, 0x26}, ++ {0x0048, 0x0F}, {0x0060, 0x3C}, ++ {0x0064, 0xF7}, {0x006C, 0x20}, ++ {0x0070, 0x7D}, {0x0074, 0x68}, ++ {0x0AF4, 0x1A}, {0x1AF4, 0x1A}, ++ {0x0440, 0x3F}, {0x10D4, 0x08}, ++ {0x20D4, 0x08}, {0x00D4, 0x30}, ++ {0x0024, 0x6e}, ++}; ++ ++static inline int grfreg_write(struct regmap *base, ++ const struct udphy_grf_reg *reg, bool en) ++{ ++ u32 val, mask, tmp; ++ ++ tmp = en ? reg->enable : reg->disable; ++ mask = GENMASK(reg->bitend, reg->bitstart); ++ val = (tmp << reg->bitstart) | (mask << BIT_WRITEABLE_SHIFT); ++ ++ return regmap_write(base, reg->offset, val); ++} ++ ++static int udphy_clk_init(struct rockchip_udphy *udphy, struct device *dev) ++{ ++ int i; ++ ++ udphy->num_clks = devm_clk_bulk_get_all(dev, &udphy->clks); ++ if (udphy->num_clks < 1) ++ return -ENODEV; ++ ++ /* used for configure phy reference clock frequency */ ++ for (i = 0; i < udphy->num_clks; i++) { ++ if (!strncmp(udphy->clks[i].id, "refclk", 6)) { ++ udphy->refclk = udphy->clks[i].clk; ++ break; ++ } ++ } ++ ++ if (!udphy->refclk) ++ dev_warn(udphy->dev, "no refclk found\n"); ++ ++ return 0; ++} ++ ++static int udphy_reset_init(struct rockchip_udphy *udphy, struct device *dev) ++{ ++ const struct rockchip_udphy_cfg *cfg = udphy->cfgs; ++ int idx; ++ ++ udphy->rsts = devm_kcalloc(dev, cfg->num_rsts, ++ sizeof(*udphy->rsts), GFP_KERNEL); ++ if (!udphy->rsts) ++ return -ENOMEM; ++ ++ for (idx = 0; idx < cfg->num_rsts; idx++) { ++ struct reset_control *rst; ++ const char *name = cfg->rst_list[idx]; ++ ++ rst = devm_reset_control_get(dev, name); ++ if (IS_ERR(rst)) { ++ dev_err(dev, "failed to get %s reset\n", name); ++ devm_kfree(dev, (void *)udphy->rsts); ++ return PTR_ERR(rst); ++ } ++ ++ udphy->rsts[idx] = rst; ++ } ++ ++ return 0; ++} ++ ++static int udphy_get_rst_idx(const char * const *list, int num, char *name) ++{ ++ int idx; ++ ++ for (idx = 0; idx < num; idx++) { ++ if (!strcmp(list[idx], name)) ++ return idx; ++ } ++ ++ return -EINVAL; ++} ++ ++static int udphy_reset_assert(struct rockchip_udphy *udphy, char *name) ++{ ++ const struct rockchip_udphy_cfg *cfg = udphy->cfgs; ++ int idx; ++ ++ idx = udphy_get_rst_idx(cfg->rst_list, cfg->num_rsts, name); ++ if (idx < 0) ++ return idx; ++ ++ return reset_control_assert(udphy->rsts[idx]); ++} ++ ++static int udphy_reset_deassert(struct rockchip_udphy *udphy, char *name) ++{ ++ const struct rockchip_udphy_cfg *cfg = udphy->cfgs; ++ int idx; ++ ++ idx = udphy_get_rst_idx(cfg->rst_list, cfg->num_rsts, name); ++ if (idx < 0) ++ return idx; ++ ++ return reset_control_deassert(udphy->rsts[idx]); ++} ++ ++static void udphy_u3_port_disable(struct rockchip_udphy *udphy, u8 disable) ++{ ++ const struct rockchip_udphy_cfg *cfg = udphy->cfgs; ++ const struct udphy_grf_reg *preg; ++ ++ preg = udphy->id ? &cfg->grfcfg.usb3otg1_cfg : &cfg->grfcfg.usb3otg0_cfg; ++ grfreg_write(udphy->usbgrf, preg, disable); ++} ++ ++static void udphy_usb_bvalid_enable(struct rockchip_udphy *udphy, u8 enable) ++{ ++ const struct rockchip_udphy_cfg *cfg = udphy->cfgs; ++ ++ grfreg_write(udphy->u2phygrf, &cfg->grfcfg.bvalid_phy_con, enable); ++ grfreg_write(udphy->u2phygrf, &cfg->grfcfg.bvalid_grf_con, enable); ++} ++ ++/* ++ * In usb/dp combo phy driver, here are 2 ways to mapping lanes. ++ * ++ * 1 Type-C Mapping table (DP_Alt_Mode V1.0b remove ABF pin mapping) ++ * --------------------------------------------------------------------------- ++ * Type-C Pin B11-B10 A2-A3 A11-A10 B2-B3 ++ * PHY Pad ln0(tx/rx) ln1(tx) ln2(tx/rx) ln3(tx) ++ * C/E(Normal) dpln3 dpln2 dpln0 dpln1 ++ * C/E(Flip ) dpln0 dpln1 dpln3 dpln2 ++ * D/F(Normal) usbrx usbtx dpln0 dpln1 ++ * D/F(Flip ) dpln0 dpln1 usbrx usbtx ++ * A(Normal ) dpln3 dpln1 dpln2 dpln0 ++ * A(Flip ) dpln2 dpln0 dpln3 dpln1 ++ * B(Normal ) usbrx usbtx dpln1 dpln0 ++ * B(Flip ) dpln1 dpln0 usbrx usbtx ++ * --------------------------------------------------------------------------- ++ * ++ * 2 Mapping the lanes in dtsi ++ * if all 4 lane assignment for dp function, define rockchip,dp-lane-mux = ; ++ * sample as follow: ++ * --------------------------------------------------------------------------- ++ * B11-B10 A2-A3 A11-A10 B2-B3 ++ * rockchip,dp-lane-mux ln0(tx/rx) ln1(tx) ln2(tx/rx) ln3(tx) ++ * <0 1 2 3> dpln0 dpln1 dpln2 dpln3 ++ * <2 3 0 1> dpln2 dpln3 dpln0 dpln1 ++ * --------------------------------------------------------------------------- ++ * if 2 lane for dp function, 2 lane for usb function, define rockchip,dp-lane-mux = ; ++ * sample as follow: ++ * --------------------------------------------------------------------------- ++ * B11-B10 A2-A3 A11-A10 B2-B3 ++ * rockchip,dp-lane-mux ln0(tx/rx) ln1(tx) ln2(tx/rx) ln3(tx) ++ * <0 1> dpln0 dpln1 usbrx usbtx ++ * <2 3> usbrx usbtx dpln0 dpln1 ++ * --------------------------------------------------------------------------- ++ */ ++ ++static int udphy_dplane_select(struct rockchip_udphy *udphy) ++{ ++ const struct rockchip_udphy_cfg *cfg = udphy->cfgs; ++ ++ if (cfg->dplane_select) ++ return cfg->dplane_select(udphy); ++ ++ return 0; ++} ++ ++static int udphy_dplane_get(struct rockchip_udphy *udphy) ++{ ++ int dp_lanes; ++ ++ switch (udphy->mode) { ++ case UDPHY_MODE_DP: ++ dp_lanes = 4; ++ break; ++ case UDPHY_MODE_DP_USB: ++ dp_lanes = 2; ++ break; ++ case UDPHY_MODE_USB: ++ fallthrough; ++ default: ++ dp_lanes = 0; ++ break; ++ } ++ ++ return dp_lanes; ++} ++ ++static int udphy_dplane_enable(struct rockchip_udphy *udphy, int dp_lanes) ++{ ++ const struct rockchip_udphy_cfg *cfg = udphy->cfgs; ++ int ret = 0; ++ ++ if (cfg->dplane_enable) ++ ret = cfg->dplane_enable(udphy, dp_lanes); ++ ++ return ret; ++} ++ ++static int upphy_set_typec_default_mapping(struct rockchip_udphy *udphy) ++{ ++ if (udphy->flip) { ++ udphy->dp_lane_sel[0] = 0; ++ udphy->dp_lane_sel[1] = 1; ++ udphy->dp_lane_sel[2] = 3; ++ udphy->dp_lane_sel[3] = 2; ++ udphy->lane_mux_sel[0] = PHY_LANE_MUX_DP; ++ udphy->lane_mux_sel[1] = PHY_LANE_MUX_DP; ++ udphy->lane_mux_sel[2] = PHY_LANE_MUX_USB; ++ udphy->lane_mux_sel[3] = PHY_LANE_MUX_USB; ++ udphy->dp_aux_dout_sel = PHY_AUX_DP_DATA_POL_INVERT; ++ udphy->dp_aux_din_sel = PHY_AUX_DP_DATA_POL_INVERT; ++ gpiod_set_value_cansleep(udphy->sbu1_dc_gpio, 1); ++ gpiod_set_value_cansleep(udphy->sbu2_dc_gpio, 0); ++ } else { ++ udphy->dp_lane_sel[0] = 2; ++ udphy->dp_lane_sel[1] = 3; ++ udphy->dp_lane_sel[2] = 1; ++ udphy->dp_lane_sel[3] = 0; ++ udphy->lane_mux_sel[0] = PHY_LANE_MUX_USB; ++ udphy->lane_mux_sel[1] = PHY_LANE_MUX_USB; ++ udphy->lane_mux_sel[2] = PHY_LANE_MUX_DP; ++ udphy->lane_mux_sel[3] = PHY_LANE_MUX_DP; ++ udphy->dp_aux_dout_sel = PHY_AUX_DP_DATA_POL_NORMAL; ++ udphy->dp_aux_din_sel = PHY_AUX_DP_DATA_POL_NORMAL; ++ gpiod_set_value_cansleep(udphy->sbu1_dc_gpio, 0); ++ gpiod_set_value_cansleep(udphy->sbu2_dc_gpio, 1); ++ } ++ ++ udphy->mode = UDPHY_MODE_DP_USB; ++ ++ return 0; ++} ++ ++static int udphy_orien_sw_set(struct typec_switch_dev *sw, ++ enum typec_orientation orien) ++{ ++ struct rockchip_udphy *udphy = typec_switch_get_drvdata(sw); ++ ++ mutex_lock(&udphy->mutex); ++ ++ if (orien == TYPEC_ORIENTATION_NONE) { ++ gpiod_set_value_cansleep(udphy->sbu1_dc_gpio, 0); ++ gpiod_set_value_cansleep(udphy->sbu2_dc_gpio, 0); ++ /* unattached */ ++ udphy_usb_bvalid_enable(udphy, false); ++ goto unlock_ret; ++ } ++ ++ udphy->flip = (orien == TYPEC_ORIENTATION_REVERSE) ? true : false; ++ upphy_set_typec_default_mapping(udphy); ++ udphy_usb_bvalid_enable(udphy, true); ++ ++unlock_ret: ++ mutex_unlock(&udphy->mutex); ++ return 0; ++} ++ ++static int udphy_setup_orien_switch(struct rockchip_udphy *udphy) ++{ ++ struct typec_switch_desc sw_desc = { }; ++ ++ sw_desc.drvdata = udphy; ++ sw_desc.fwnode = dev_fwnode(udphy->dev); ++ sw_desc.set = udphy_orien_sw_set; ++ ++ udphy->sw = typec_switch_register(udphy->dev, &sw_desc); ++ if (IS_ERR(udphy->sw)) { ++ dev_err(udphy->dev, "Error register typec orientation switch: %ld\n", ++ PTR_ERR(udphy->sw)); ++ return PTR_ERR(udphy->sw); ++ } ++ ++ return 0; ++} ++ ++static void udphy_orien_switch_unregister(void *data) ++{ ++ struct rockchip_udphy *udphy = data; ++ ++ typec_switch_unregister(udphy->sw); ++} ++ ++static int udphy_setup(struct rockchip_udphy *udphy) ++{ ++ const struct rockchip_udphy_cfg *cfg = udphy->cfgs; ++ int ret = 0; ++ ++ ret = clk_bulk_prepare_enable(udphy->num_clks, udphy->clks); ++ if (ret) { ++ dev_err(udphy->dev, "failed to enable clk\n"); ++ return ret; ++ } ++ ++ if (cfg->combophy_init) { ++ ret = cfg->combophy_init(udphy); ++ if (ret) { ++ dev_err(udphy->dev, "failed to init combophy\n"); ++ clk_bulk_disable_unprepare(udphy->num_clks, udphy->clks); ++ return ret; ++ } ++ } ++ ++ return 0; ++} ++ ++static int udphy_disable(struct rockchip_udphy *udphy) ++{ ++ const struct rockchip_udphy_cfg *cfg = udphy->cfgs; ++ int i; ++ ++ clk_bulk_disable_unprepare(udphy->num_clks, udphy->clks); ++ ++ for (i = 0; i < cfg->num_rsts; i++) ++ reset_control_assert(udphy->rsts[i]); ++ ++ return 0; ++} ++ ++static int udphy_parse_lane_mux_data(struct rockchip_udphy *udphy, struct device_node *np) ++{ ++ struct property *prop; ++ int ret, i, len, num_lanes; ++ ++ prop = of_find_property(np, "rockchip,dp-lane-mux", &len); ++ if (!prop) { ++ dev_dbg(udphy->dev, "failed to find dp lane mux, following dp alt mode\n"); ++ udphy->mode = UDPHY_MODE_USB; ++ return 0; ++ } ++ ++ num_lanes = len / sizeof(u32); ++ ++ if (num_lanes != 2 && num_lanes != 4) { ++ dev_err(udphy->dev, "invalid number of lane mux\n"); ++ return -EINVAL; ++ } ++ ++ ret = of_property_read_u32_array(np, "rockchip,dp-lane-mux", udphy->dp_lane_sel, num_lanes); ++ if (ret) { ++ dev_err(udphy->dev, "get dp lane mux failed\n"); ++ return -EINVAL; ++ } ++ ++ for (i = 0; i < num_lanes; i++) { ++ int j; ++ ++ if (udphy->dp_lane_sel[i] > 3) { ++ dev_err(udphy->dev, "lane mux between 0 and 3, exceeding the range\n"); ++ return -EINVAL; ++ } ++ ++ udphy->lane_mux_sel[udphy->dp_lane_sel[i]] = PHY_LANE_MUX_DP; ++ ++ for (j = i + 1; j < num_lanes; j++) { ++ if (udphy->dp_lane_sel[i] == udphy->dp_lane_sel[j]) { ++ dev_err(udphy->dev, "set repeat lane mux value\n"); ++ return -EINVAL; ++ } ++ } ++ } ++ ++ udphy->mode = UDPHY_MODE_DP; ++ if (num_lanes == 2) ++ udphy->mode |= UDPHY_MODE_USB; ++ ++ return 0; ++} ++ ++static int udphy_get_initial_status(struct rockchip_udphy *udphy) ++{ ++ const struct rockchip_udphy_cfg *cfg = udphy->cfgs; ++ int ret, i; ++ u32 value; ++ ++ ret = clk_bulk_prepare_enable(udphy->num_clks, udphy->clks); ++ if (ret) { ++ dev_err(udphy->dev, "failed to enable clk\n"); ++ return ret; ++ } ++ ++ for (i = 0; i < cfg->num_rsts; i++) ++ reset_control_deassert(udphy->rsts[i]); ++ ++ regmap_read(udphy->pma_regmap, CMN_LANE_MUX_AND_EN_OFFSET, &value); ++ if (FIELD_GET(CMN_DP_LANE_MUX_ALL, value) && FIELD_GET(CMN_DP_LANE_EN_ALL, value)) ++ udphy->status = UDPHY_MODE_DP; ++ else ++ udphy_disable(udphy); ++ ++ return 0; ++} ++ ++static int udphy_parse_dt(struct rockchip_udphy *udphy, struct device *dev) ++{ ++ struct device_node *np = dev->of_node; ++ enum usb_device_speed maximum_speed; ++ int ret; ++ ++ udphy->u2phygrf = syscon_regmap_lookup_by_phandle(np, "rockchip,u2phy-grf"); ++ if (IS_ERR(udphy->u2phygrf)) { ++ if (PTR_ERR(udphy->u2phygrf) == -ENODEV) { ++ dev_warn(dev, "missing u2phy-grf dt node\n"); ++ udphy->u2phygrf = NULL; ++ } else { ++ return PTR_ERR(udphy->u2phygrf); ++ } ++ } ++ ++ udphy->udphygrf = syscon_regmap_lookup_by_phandle(np, "rockchip,usbdpphy-grf"); ++ if (IS_ERR(udphy->udphygrf)) { ++ if (PTR_ERR(udphy->udphygrf) == -ENODEV) { ++ dev_warn(dev, "missing usbdpphy-grf dt node\n"); ++ udphy->udphygrf = NULL; ++ } else { ++ return PTR_ERR(udphy->udphygrf); ++ } ++ } ++ ++ udphy->usbgrf = syscon_regmap_lookup_by_phandle(np, "rockchip,usb-grf"); ++ if (IS_ERR(udphy->usbgrf)) { ++ if (PTR_ERR(udphy->usbgrf) == -ENODEV) { ++ dev_warn(dev, "missing usb-grf dt node\n"); ++ udphy->usbgrf = NULL; ++ } else { ++ return PTR_ERR(udphy->usbgrf); ++ } ++ } ++ ++ udphy->vogrf = syscon_regmap_lookup_by_phandle(np, "rockchip,vo-grf"); ++ if (IS_ERR(udphy->vogrf)) { ++ if (PTR_ERR(udphy->vogrf) == -ENODEV) { ++ dev_warn(dev, "missing vo-grf dt node\n"); ++ udphy->vogrf = NULL; ++ } else { ++ return PTR_ERR(udphy->vogrf); ++ } ++ } ++ ++ ret = udphy_parse_lane_mux_data(udphy, np); ++ if (ret) ++ return ret; ++ ++ udphy->sbu1_dc_gpio = devm_gpiod_get_optional(dev, "sbu1-dc", GPIOD_OUT_LOW); ++ if (IS_ERR(udphy->sbu1_dc_gpio)) ++ return PTR_ERR(udphy->sbu1_dc_gpio); ++ ++ udphy->sbu2_dc_gpio = devm_gpiod_get_optional(dev, "sbu2-dc", GPIOD_OUT_LOW); ++ if (IS_ERR(udphy->sbu2_dc_gpio)) ++ return PTR_ERR(udphy->sbu2_dc_gpio); ++ ++ if (device_property_present(dev, "maximum-speed")) { ++ maximum_speed = usb_get_maximum_speed(dev); ++ udphy->hs = maximum_speed <= USB_SPEED_HIGH ? true : false; ++ } ++ ++ ret = udphy_clk_init(udphy, dev); ++ if (ret) ++ return ret; ++ ++ ret = udphy_reset_init(udphy, dev); ++ if (ret) ++ return ret; ++ ++ return 0; ++} ++ ++static int udphy_power_on(struct rockchip_udphy *udphy, u8 mode) ++{ ++ int ret; ++ ++ if (!(udphy->mode & mode)) { ++ dev_info(udphy->dev, "mode 0x%02x is not support\n", mode); ++ return 0; ++ } ++ ++ if (udphy->status == UDPHY_MODE_NONE) { ++ udphy->mode_change = false; ++ ret = udphy_setup(udphy); ++ if (ret) ++ return ret; ++ ++ if (udphy->mode & UDPHY_MODE_USB) ++ udphy_u3_port_disable(udphy, false); ++ } else if (udphy->mode_change) { ++ udphy->mode_change = false; ++ udphy->status = UDPHY_MODE_NONE; ++ if (udphy->mode == UDPHY_MODE_DP) ++ udphy_u3_port_disable(udphy, true); ++ ++ ret = udphy_disable(udphy); ++ if (ret) ++ return ret; ++ ret = udphy_setup(udphy); ++ if (ret) ++ return ret; ++ } ++ ++ udphy->status |= mode; ++ ++ return 0; ++} ++ ++static int udphy_power_off(struct rockchip_udphy *udphy, u8 mode) ++{ ++ int ret; ++ ++ if (!(udphy->mode & mode)) { ++ dev_info(udphy->dev, "mode 0x%02x is not support\n", mode); ++ return 0; ++ } ++ ++ if (!udphy->status) ++ return 0; ++ ++ udphy->status &= ~mode; ++ ++ if (udphy->status == UDPHY_MODE_NONE) { ++ ret = udphy_disable(udphy); ++ if (ret) ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static int rockchip_dp_phy_power_on(struct phy *phy) ++{ ++ struct rockchip_udphy *udphy = phy_get_drvdata(phy); ++ int ret, dp_lanes; ++ ++ mutex_lock(&udphy->mutex); ++ ++ dp_lanes = udphy_dplane_get(udphy); ++ phy_set_bus_width(phy, dp_lanes); ++ ++ ret = udphy_power_on(udphy, UDPHY_MODE_DP); ++ if (ret) ++ goto unlock; ++ ++ ret = udphy_dplane_enable(udphy, dp_lanes); ++ if (ret) ++ goto unlock; ++ ++ ret = udphy_dplane_select(udphy); ++ ++unlock: ++ mutex_unlock(&udphy->mutex); ++ /* ++ * If data send by aux channel too fast after phy power on, ++ * the aux may be not ready which will cause aux error. Adding ++ * delay to avoid this issue. ++ */ ++ usleep_range(10000, 11000); ++ return ret; ++} ++ ++static int rockchip_dp_phy_power_off(struct phy *phy) ++{ ++ struct rockchip_udphy *udphy = phy_get_drvdata(phy); ++ int ret; ++ ++ mutex_lock(&udphy->mutex); ++ ret = udphy_dplane_enable(udphy, 0); ++ if (ret) ++ goto unlock; ++ ++ ret = udphy_power_off(udphy, UDPHY_MODE_DP); ++ ++unlock: ++ mutex_unlock(&udphy->mutex); ++ return ret; ++} ++ ++static int rockchip_dp_phy_verify_link_rate(unsigned int link_rate) ++{ ++ switch (link_rate) { ++ case 1620: ++ case 2700: ++ case 5400: ++ case 8100: ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static int rockchip_dp_phy_verify_config(struct rockchip_udphy *udphy, ++ struct phy_configure_opts_dp *dp) ++{ ++ int i, ret; ++ ++ /* If changing link rate was required, verify it's supported. */ ++ ret = rockchip_dp_phy_verify_link_rate(dp->link_rate); ++ if (ret) ++ return ret; ++ ++ /* Verify lane count. */ ++ switch (dp->lanes) { ++ case 1: ++ case 2: ++ case 4: ++ /* valid lane count. */ ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ /* ++ * If changing voltages is required, check swing and pre-emphasis ++ * levels, per-lane. ++ */ ++ if (dp->set_voltages) { ++ /* Lane count verified previously. */ ++ for (i = 0; i < dp->lanes; i++) { ++ if (dp->voltage[i] > 3 || dp->pre[i] > 3) ++ return -EINVAL; ++ ++ /* ++ * Sum of voltage swing and pre-emphasis levels cannot ++ * exceed 3. ++ */ ++ if (dp->voltage[i] + dp->pre[i] > 3) ++ return -EINVAL; ++ } ++ } ++ ++ return 0; ++} ++ ++static int rockchip_dp_phy_configure(struct phy *phy, ++ union phy_configure_opts *opts) ++{ ++ struct rockchip_udphy *udphy = phy_get_drvdata(phy); ++ const struct rockchip_udphy_cfg *cfg = udphy->cfgs; ++ int ret; ++ ++ ret = rockchip_dp_phy_verify_config(udphy, &opts->dp); ++ if (ret) ++ return ret; ++ ++ if (opts->dp.set_rate && cfg->dp_phy_set_rate) { ++ ret = cfg->dp_phy_set_rate(udphy, &opts->dp); ++ if (ret) { ++ dev_err(udphy->dev, ++ "rockchip_hdptx_phy_set_rate failed\n"); ++ return ret; ++ } ++ } ++ ++ if (opts->dp.set_voltages && cfg->dp_phy_set_voltages) { ++ ret = cfg->dp_phy_set_voltages(udphy, &opts->dp); ++ if (ret) { ++ dev_err(udphy->dev, ++ "rockchip_dp_phy_set_voltages failed\n"); ++ return ret; ++ } ++ } ++ ++ return 0; ++} ++ ++static const struct phy_ops rockchip_dp_phy_ops = { ++ .power_on = rockchip_dp_phy_power_on, ++ .power_off = rockchip_dp_phy_power_off, ++ .configure = rockchip_dp_phy_configure, ++ .owner = THIS_MODULE, ++}; ++ ++static int rockchip_u3phy_init(struct phy *phy) ++{ ++ struct rockchip_udphy *udphy = phy_get_drvdata(phy); ++ int ret = 0; ++ ++ mutex_lock(&udphy->mutex); ++ /* DP only or high-speed, disable U3 port */ ++ if (!(udphy->mode & UDPHY_MODE_USB) || udphy->hs) { ++ udphy_u3_port_disable(udphy, true); ++ goto unlock; ++ } ++ ++ ret = udphy_power_on(udphy, UDPHY_MODE_USB); ++ ++unlock: ++ mutex_unlock(&udphy->mutex); ++ return ret; ++} ++ ++static int rockchip_u3phy_exit(struct phy *phy) ++{ ++ struct rockchip_udphy *udphy = phy_get_drvdata(phy); ++ int ret = 0; ++ ++ mutex_lock(&udphy->mutex); ++ /* DP only or high-speed */ ++ if (!(udphy->mode & UDPHY_MODE_USB) || udphy->hs) ++ goto unlock; ++ ++ ret = udphy_power_off(udphy, UDPHY_MODE_USB); ++ ++unlock: ++ mutex_unlock(&udphy->mutex); ++ return ret; ++} ++ ++static const struct phy_ops rockchip_u3phy_ops = { ++ .init = rockchip_u3phy_init, ++ .exit = rockchip_u3phy_exit, ++ .owner = THIS_MODULE, ++}; ++ ++static int usbdp_typec_mux_set(struct typec_mux_dev *mux, ++ struct typec_mux_state *state) ++{ ++ struct rockchip_udphy *udphy = typec_mux_get_drvdata(mux); ++ const struct rockchip_udphy_cfg *cfg = udphy->cfgs; ++ u8 mode; ++ ++ mutex_lock(&udphy->mutex); ++ ++ switch (state->mode) { ++ case TYPEC_DP_STATE_C: ++ fallthrough; ++ case TYPEC_DP_STATE_E: ++ udphy->lane_mux_sel[0] = PHY_LANE_MUX_DP; ++ udphy->lane_mux_sel[1] = PHY_LANE_MUX_DP; ++ udphy->lane_mux_sel[2] = PHY_LANE_MUX_DP; ++ udphy->lane_mux_sel[3] = PHY_LANE_MUX_DP; ++ mode = UDPHY_MODE_DP; ++ break; ++ case TYPEC_DP_STATE_D: ++ fallthrough; ++ default: ++ if (udphy->flip) { ++ udphy->lane_mux_sel[0] = PHY_LANE_MUX_DP; ++ udphy->lane_mux_sel[1] = PHY_LANE_MUX_DP; ++ udphy->lane_mux_sel[2] = PHY_LANE_MUX_USB; ++ udphy->lane_mux_sel[3] = PHY_LANE_MUX_USB; ++ } else { ++ udphy->lane_mux_sel[0] = PHY_LANE_MUX_USB; ++ udphy->lane_mux_sel[1] = PHY_LANE_MUX_USB; ++ udphy->lane_mux_sel[2] = PHY_LANE_MUX_DP; ++ udphy->lane_mux_sel[3] = PHY_LANE_MUX_DP; ++ } ++ mode = UDPHY_MODE_DP_USB; ++ break; ++ } ++ ++ if (state->alt && state->alt->svid == USB_TYPEC_DP_SID) { ++ struct typec_displayport_data *data = state->data; ++ ++ if (!data) { ++ if (cfg->hpd_event_trigger) ++ cfg->hpd_event_trigger(udphy, false); ++ } else if (data->status & DP_STATUS_IRQ_HPD) { ++ if (cfg->hpd_event_trigger) { ++ cfg->hpd_event_trigger(udphy, false); ++ usleep_range(750, 800); ++ cfg->hpd_event_trigger(udphy, true); ++ } ++ } else if (data->status & DP_STATUS_HPD_STATE) { ++ if (udphy->mode != mode) { ++ udphy->mode = mode; ++ udphy->mode_change = true; ++ } ++ if (cfg->hpd_event_trigger) ++ cfg->hpd_event_trigger(udphy, true); ++ } else { ++ if (cfg->hpd_event_trigger) ++ cfg->hpd_event_trigger(udphy, false); ++ } ++ } ++ ++ mutex_unlock(&udphy->mutex); ++ return 0; ++} ++ ++static int udphy_setup_typec_mux(struct rockchip_udphy *udphy) ++{ ++ struct typec_mux_desc mux_desc = {}; ++ ++ mux_desc.drvdata = udphy; ++ mux_desc.fwnode = dev_fwnode(udphy->dev); ++ mux_desc.set = usbdp_typec_mux_set; ++ ++ udphy->mux = typec_mux_register(udphy->dev, &mux_desc); ++ if (IS_ERR(udphy->mux)) { ++ dev_err(udphy->dev, "Error register typec mux: %ld\n", ++ PTR_ERR(udphy->mux)); ++ return PTR_ERR(udphy->mux); ++ } ++ ++ return 0; ++} ++ ++static void udphy_typec_mux_unregister(void *data) ++{ ++ struct rockchip_udphy *udphy = data; ++ ++ typec_mux_unregister(udphy->mux); ++} ++ ++static u32 udphy_dp_get_max_link_rate(struct rockchip_udphy *udphy, struct device_node *np) ++{ ++ u32 max_link_rate; ++ int ret; ++ ++ ret = of_property_read_u32(np, "max-link-rate", &max_link_rate); ++ if (ret) ++ return 8100; ++ ++ ret = rockchip_dp_phy_verify_link_rate(max_link_rate); ++ if (ret) { ++ dev_warn(udphy->dev, "invalid max-link-rate value:%d\n", max_link_rate); ++ max_link_rate = 8100; ++ } ++ ++ return max_link_rate; ++} ++ ++static const struct regmap_config rockchip_udphy_pma_regmap_cfg = { ++ .reg_bits = 32, ++ .reg_stride = 4, ++ .val_bits = 32, ++ .fast_io = true, ++ .max_register = 0x20dc, ++}; ++ ++static int rockchip_udphy_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct device_node *np = dev->of_node; ++ struct device_node *child_np; ++ struct phy_provider *phy_provider; ++ struct resource *res; ++ struct rockchip_udphy *udphy; ++ const struct rockchip_udphy_cfg *phy_cfgs; ++ void __iomem *base; ++ int id, ret; ++ ++ udphy = devm_kzalloc(dev, sizeof(*udphy), GFP_KERNEL); ++ if (!udphy) ++ return -ENOMEM; ++ ++ id = of_alias_get_id(dev->of_node, "usbdp"); ++ if (id < 0) ++ id = 0; ++ udphy->id = id; ++ ++ phy_cfgs = device_get_match_data(dev); ++ if (!phy_cfgs) { ++ dev_err(dev, "no OF data can be matched with %p node\n", np); ++ return -EINVAL; ++ } ++ ++ udphy->cfgs = phy_cfgs; ++ ++ base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); ++ if (IS_ERR(base)) ++ return PTR_ERR(base); ++ ++ udphy->pma_regmap = devm_regmap_init_mmio(dev, base + UDPHY_PMA, ++ &rockchip_udphy_pma_regmap_cfg); ++ if (IS_ERR(udphy->pma_regmap)) ++ return PTR_ERR(udphy->pma_regmap); ++ ++ ret = udphy_parse_dt(udphy, dev); ++ if (ret) ++ return ret; ++ ++ ret = udphy_get_initial_status(udphy); ++ if (ret) ++ return ret; ++ ++ mutex_init(&udphy->mutex); ++ udphy->dev = dev; ++ platform_set_drvdata(pdev, udphy); ++ ++ if (device_property_present(dev, "orientation-switch")) { ++ ret = udphy_setup_orien_switch(udphy); ++ if (ret) ++ return ret; ++ ++ ret = devm_add_action_or_reset(dev, udphy_orien_switch_unregister, udphy); ++ if (ret) ++ return ret; ++ } ++ ++ if (device_property_present(dev, "mode-switch")) { ++ ret = udphy_setup_typec_mux(udphy); ++ if (ret) ++ return ret; ++ ++ ret = devm_add_action_or_reset(dev, udphy_typec_mux_unregister, udphy); ++ if (ret) ++ return ret; ++ } ++ ++ for_each_available_child_of_node(np, child_np) { ++ struct phy *phy; ++ ++ if (of_node_name_eq(child_np, "dp-port")) { ++ phy = devm_phy_create(dev, child_np, &rockchip_dp_phy_ops); ++ if (IS_ERR(phy)) { ++ dev_err(dev, "failed to create dp phy: %pOFn\n", child_np); ++ goto put_child; ++ } ++ ++ phy_set_bus_width(phy, udphy_dplane_get(udphy)); ++ phy->attrs.max_link_rate = udphy_dp_get_max_link_rate(udphy, child_np); ++ } else if (of_node_name_eq(child_np, "usb3-port")) { ++ phy = devm_phy_create(dev, child_np, &rockchip_u3phy_ops); ++ if (IS_ERR(phy)) { ++ dev_err(dev, "failed to create usb phy: %pOFn\n", child_np); ++ goto put_child; ++ } ++ } else ++ continue; ++ ++ phy_set_drvdata(phy, udphy); ++ } ++ ++ phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); ++ if (IS_ERR(phy_provider)) { ++ dev_err(dev, "failed to register phy provider\n"); ++ goto put_child; ++ } ++ ++ return 0; ++ ++put_child: ++ of_node_put(child_np); ++ return ret; ++} ++ ++static int rk3588_udphy_refclk_set(struct rockchip_udphy *udphy) ++{ ++ unsigned long rate; ++ int ret; ++ ++ /* configure phy reference clock */ ++ rate = clk_get_rate(udphy->refclk); ++ dev_dbg(udphy->dev, "refclk freq %ld\n", rate); ++ ++ switch (rate) { ++ case 24000000: ++ ret = regmap_multi_reg_write(udphy->pma_regmap, rk3588_udphy_24m_refclk_cfg, ++ ARRAY_SIZE(rk3588_udphy_24m_refclk_cfg)); ++ if (ret) ++ return ret; ++ break; ++ case 26000000: ++ /* register default is 26MHz */ ++ ret = regmap_multi_reg_write(udphy->pma_regmap, rk3588_udphy_26m_refclk_cfg, ++ ARRAY_SIZE(rk3588_udphy_26m_refclk_cfg)); ++ if (ret) ++ return ret; ++ break; ++ default: ++ dev_err(udphy->dev, "unsupported refclk freq %ld\n", rate); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static int rk3588_udphy_status_check(struct rockchip_udphy *udphy) ++{ ++ unsigned int val; ++ int ret; ++ ++ /* LCPLL check */ ++ if (udphy->mode & UDPHY_MODE_USB) { ++ ret = regmap_read_poll_timeout(udphy->pma_regmap, CMN_ANA_LCPLL_DONE_OFFSET, ++ val, (val & CMN_ANA_LCPLL_AFC_DONE) && ++ (val & CMN_ANA_LCPLL_LOCK_DONE), 200, 100000); ++ if (ret) { ++ dev_err(udphy->dev, "cmn ana lcpll lock timeout\n"); ++ return ret; ++ } ++ } ++ ++ if (udphy->mode & UDPHY_MODE_USB) { ++ if (!udphy->flip) { ++ ret = regmap_read_poll_timeout(udphy->pma_regmap, ++ TRSV_LN0_MON_RX_CDR_DONE_OFFSET, val, ++ val & TRSV_LN0_MON_RX_CDR_LOCK_DONE, ++ 200, 100000); ++ if (ret) ++ dev_err(udphy->dev, "trsv ln0 mon rx cdr lock timeout\n"); ++ } else { ++ ret = regmap_read_poll_timeout(udphy->pma_regmap, ++ TRSV_LN2_MON_RX_CDR_DONE_OFFSET, val, ++ val & TRSV_LN2_MON_RX_CDR_LOCK_DONE, ++ 200, 100000); ++ if (ret) ++ dev_err(udphy->dev, "trsv ln2 mon rx cdr lock timeout\n"); ++ } ++ } ++ ++ return 0; ++} ++ ++static int rk3588_udphy_init(struct rockchip_udphy *udphy) ++{ ++ const struct rockchip_udphy_cfg *cfg = udphy->cfgs; ++ int ret; ++ ++ /* enable rx lfps for usb */ ++ if (udphy->mode & UDPHY_MODE_USB) ++ grfreg_write(udphy->udphygrf, &cfg->grfcfg.rx_lfps, true); ++ ++ /* Step 1: power on pma and deassert apb rstn */ ++ grfreg_write(udphy->udphygrf, &cfg->grfcfg.low_pwrn, true); ++ ++ udphy_reset_deassert(udphy, "pma_apb"); ++ udphy_reset_deassert(udphy, "pcs_apb"); ++ ++ /* Step 2: set init sequence and phy refclk */ ++ ret = regmap_multi_reg_write(udphy->pma_regmap, rk3588_udphy_init_sequence, ++ ARRAY_SIZE(rk3588_udphy_init_sequence)); ++ if (ret) { ++ dev_err(udphy->dev, "init sequence set error %d\n", ret); ++ goto assert_apb; ++ } ++ ++ ret = rk3588_udphy_refclk_set(udphy); ++ if (ret) { ++ dev_err(udphy->dev, "refclk set error %d\n", ret); ++ goto assert_apb; ++ } ++ ++ /* Step 3: configure lane mux */ ++ regmap_update_bits(udphy->pma_regmap, CMN_LANE_MUX_AND_EN_OFFSET, ++ CMN_DP_LANE_MUX_ALL | CMN_DP_LANE_EN_ALL, ++ FIELD_PREP(CMN_DP_LANE_MUX_N(3), udphy->lane_mux_sel[3]) | ++ FIELD_PREP(CMN_DP_LANE_MUX_N(2), udphy->lane_mux_sel[2]) | ++ FIELD_PREP(CMN_DP_LANE_MUX_N(1), udphy->lane_mux_sel[1]) | ++ FIELD_PREP(CMN_DP_LANE_MUX_N(0), udphy->lane_mux_sel[0]) | ++ FIELD_PREP(CMN_DP_LANE_EN_ALL, 0)); ++ ++ /* Step 4: deassert init rstn and wait for 200ns from datasheet */ ++ if (udphy->mode & UDPHY_MODE_USB) ++ udphy_reset_deassert(udphy, "init"); ++ ++ if (udphy->mode & UDPHY_MODE_DP) { ++ regmap_update_bits(udphy->pma_regmap, CMN_DP_RSTN_OFFSET, ++ CMN_DP_INIT_RSTN, ++ FIELD_PREP(CMN_DP_INIT_RSTN, 0x1)); ++ } ++ ++ udelay(1); ++ ++ /* Step 5: deassert cmn/lane rstn */ ++ if (udphy->mode & UDPHY_MODE_USB) { ++ udphy_reset_deassert(udphy, "cmn"); ++ udphy_reset_deassert(udphy, "lane"); ++ } ++ ++ /* Step 6: wait for lock done of pll */ ++ ret = rk3588_udphy_status_check(udphy); ++ if (ret) ++ goto assert_phy; ++ ++ return 0; ++ ++assert_phy: ++ udphy_reset_assert(udphy, "init"); ++ udphy_reset_assert(udphy, "cmn"); ++ udphy_reset_assert(udphy, "lane"); ++ ++assert_apb: ++ udphy_reset_assert(udphy, "pma_apb"); ++ udphy_reset_assert(udphy, "pcs_apb"); ++ return ret; ++} ++ ++static int rk3588_udphy_hpd_event_trigger(struct rockchip_udphy *udphy, bool hpd) ++{ ++ const struct rockchip_udphy_cfg *cfg = udphy->cfgs; ++ ++ udphy->dp_sink_hpd_sel = true; ++ udphy->dp_sink_hpd_cfg = hpd; ++ ++ grfreg_write(udphy->vogrf, &cfg->vogrfcfg[udphy->id].hpd_trigger, hpd); ++ ++ return 0; ++} ++ ++static int rk3588_udphy_dplane_enable(struct rockchip_udphy *udphy, int dp_lanes) ++{ ++ int i; ++ u32 val = 0; ++ ++ for (i = 0; i < dp_lanes; i++) ++ val |= BIT(udphy->dp_lane_sel[i]); ++ ++ regmap_update_bits(udphy->pma_regmap, CMN_LANE_MUX_AND_EN_OFFSET, CMN_DP_LANE_EN_ALL, ++ FIELD_PREP(CMN_DP_LANE_EN_ALL, val)); ++ ++ if (!dp_lanes) ++ regmap_update_bits(udphy->pma_regmap, CMN_DP_RSTN_OFFSET, ++ CMN_DP_CMN_RSTN, FIELD_PREP(CMN_DP_CMN_RSTN, 0x0)); ++ ++ return 0; ++} ++ ++static int rk3588_udphy_dplane_select(struct rockchip_udphy *udphy) ++{ ++ u32 value = 0; ++ ++ switch (udphy->mode) { ++ case UDPHY_MODE_DP: ++ value |= 2 << udphy->dp_lane_sel[2] * 2; ++ value |= 3 << udphy->dp_lane_sel[3] * 2; ++ fallthrough; ++ case UDPHY_MODE_DP_USB: ++ value |= 0 << udphy->dp_lane_sel[0] * 2; ++ value |= 1 << udphy->dp_lane_sel[1] * 2; ++ break; ++ case UDPHY_MODE_USB: ++ break; ++ default: ++ break; ++ } ++ ++ regmap_write(udphy->vogrf, udphy->id ? RK3588_GRF_VO0_CON2 : RK3588_GRF_VO0_CON0, ++ ((DP_AUX_DIN_SEL | DP_AUX_DOUT_SEL | DP_LANE_SEL_ALL) << 16) | ++ FIELD_PREP(DP_AUX_DIN_SEL, udphy->dp_aux_din_sel) | ++ FIELD_PREP(DP_AUX_DOUT_SEL, udphy->dp_aux_dout_sel) | value); ++ ++ return 0; ++} ++ ++static int rk3588_dp_phy_set_rate(struct rockchip_udphy *udphy, ++ struct phy_configure_opts_dp *dp) ++{ ++ u32 val; ++ int ret; ++ ++ regmap_update_bits(udphy->pma_regmap, CMN_DP_RSTN_OFFSET, ++ CMN_DP_CMN_RSTN, FIELD_PREP(CMN_DP_CMN_RSTN, 0x0)); ++ ++ switch (dp->link_rate) { ++ case 1620: ++ udphy->bw = DP_BW_RBR; ++ break; ++ case 2700: ++ udphy->bw = DP_BW_HBR; ++ break; ++ case 5400: ++ udphy->bw = DP_BW_HBR2; ++ break; ++ case 8100: ++ udphy->bw = DP_BW_HBR3; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ regmap_update_bits(udphy->pma_regmap, CMN_DP_LINK_OFFSET, CMN_DP_TX_LINK_BW, ++ FIELD_PREP(CMN_DP_TX_LINK_BW, udphy->bw)); ++ regmap_update_bits(udphy->pma_regmap, CMN_SSC_EN_OFFSET, CMN_ROPLL_SSC_EN, ++ FIELD_PREP(CMN_ROPLL_SSC_EN, dp->ssc)); ++ regmap_update_bits(udphy->pma_regmap, CMN_DP_RSTN_OFFSET, CMN_DP_CMN_RSTN, ++ FIELD_PREP(CMN_DP_CMN_RSTN, 0x1)); ++ ++ ret = regmap_read_poll_timeout(udphy->pma_regmap, CMN_ANA_ROPLL_DONE_OFFSET, val, ++ FIELD_GET(CMN_ANA_ROPLL_LOCK_DONE, val) && ++ FIELD_GET(CMN_ANA_ROPLL_AFC_DONE, val), ++ 0, 1000); ++ if (ret) { ++ dev_err(udphy->dev, "ROPLL is not lock\n"); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static void rk3588_dp_phy_set_voltage(struct rockchip_udphy *udphy, u8 bw, ++ u32 voltage, u32 pre, u32 lane) ++{ ++ u32 offset = 0x800 * lane; ++ u32 val; ++ const struct rockchip_udphy_cfg *cfg = udphy->cfgs; ++ const struct dp_tx_drv_ctrl (*dp_ctrl)[4]; ++ ++ dp_ctrl = udphy->mux ? cfg->dp_tx_ctrl_cfg_typec[bw] : cfg->dp_tx_ctrl_cfg[bw]; ++ val = dp_ctrl[voltage][pre].trsv_reg0204; ++ regmap_write(udphy->pma_regmap, 0x0810 + offset, val); ++ ++ val = dp_ctrl[voltage][pre].trsv_reg0205; ++ regmap_write(udphy->pma_regmap, 0x0814 + offset, val); ++ ++ val = dp_ctrl[voltage][pre].trsv_reg0206; ++ regmap_write(udphy->pma_regmap, 0x0818 + offset, val); ++ ++ val = dp_ctrl[voltage][pre].trsv_reg0207; ++ regmap_write(udphy->pma_regmap, 0x081c + offset, val); ++} ++ ++static int rk3588_dp_phy_set_voltages(struct rockchip_udphy *udphy, ++ struct phy_configure_opts_dp *dp) ++{ ++ u32 i, lane; ++ ++ for (i = 0; i < dp->lanes; i++) { ++ lane = udphy->dp_lane_sel[i]; ++ switch (dp->link_rate) { ++ case 1620: ++ case 2700: ++ regmap_update_bits(udphy->pma_regmap, TRSV_ANA_TX_CLK_OFFSET_N(lane), ++ LN_ANA_TX_SER_TXCLK_INV, ++ FIELD_PREP(LN_ANA_TX_SER_TXCLK_INV, ++ udphy->lane_mux_sel[lane])); ++ break; ++ case 5400: ++ case 8100: ++ regmap_update_bits(udphy->pma_regmap, TRSV_ANA_TX_CLK_OFFSET_N(lane), ++ LN_ANA_TX_SER_TXCLK_INV, ++ FIELD_PREP(LN_ANA_TX_SER_TXCLK_INV, 0x0)); ++ break; ++ } ++ ++ rk3588_dp_phy_set_voltage(udphy, udphy->bw, dp->voltage[i], dp->pre[i], lane); ++ } ++ ++ return 0; ++} ++ ++static int __maybe_unused udphy_resume(struct device *dev) ++{ ++ struct rockchip_udphy *udphy = dev_get_drvdata(dev); ++ const struct rockchip_udphy_cfg *cfg = udphy->cfgs; ++ ++ if (udphy->dp_sink_hpd_sel) ++ cfg->hpd_event_trigger(udphy, udphy->dp_sink_hpd_cfg); ++ ++ return 0; ++} ++ ++static const struct dev_pm_ops udphy_pm_ops = { ++ SET_LATE_SYSTEM_SLEEP_PM_OPS(NULL, udphy_resume) ++}; ++ ++static const char * const rk3588_udphy_rst_l[] = { ++ "init", "cmn", "lane", "pcs_apb", "pma_apb" ++}; ++ ++static const struct rockchip_udphy_cfg rk3588_udphy_cfgs = { ++ .num_rsts = ARRAY_SIZE(rk3588_udphy_rst_l), ++ .rst_list = rk3588_udphy_rst_l, ++ .grfcfg = { ++ /* u2phy-grf */ ++ .bvalid_phy_con = { 0x0008, 1, 0, 0x2, 0x3 }, ++ .bvalid_grf_con = { 0x0010, 3, 2, 0x2, 0x3 }, ++ ++ /* usb-grf */ ++ .usb3otg0_cfg = { 0x001c, 15, 0, 0x1100, 0x0188 }, ++ .usb3otg1_cfg = { 0x0034, 15, 0, 0x1100, 0x0188 }, ++ ++ /* usbdpphy-grf */ ++ .low_pwrn = { 0x0004, 13, 13, 0, 1 }, ++ .rx_lfps = { 0x0004, 14, 14, 0, 1 }, ++ }, ++ .vogrfcfg = { ++ { ++ .hpd_trigger = { 0x0000, 11, 10, 1, 3 }, ++ }, ++ { ++ .hpd_trigger = { 0x0008, 11, 10, 1, 3 }, ++ }, ++ }, ++ .dp_tx_ctrl_cfg = { ++ rk3588_dp_tx_drv_ctrl_rbr_hbr, ++ rk3588_dp_tx_drv_ctrl_rbr_hbr, ++ rk3588_dp_tx_drv_ctrl_hbr2, ++ rk3588_dp_tx_drv_ctrl_hbr3, ++ }, ++ .dp_tx_ctrl_cfg_typec = { ++ rk3588_dp_tx_drv_ctrl_rbr_hbr_typec, ++ rk3588_dp_tx_drv_ctrl_rbr_hbr_typec, ++ rk3588_dp_tx_drv_ctrl_hbr2, ++ rk3588_dp_tx_drv_ctrl_hbr3, ++ }, ++ .combophy_init = rk3588_udphy_init, ++ .dp_phy_set_rate = rk3588_dp_phy_set_rate, ++ .dp_phy_set_voltages = rk3588_dp_phy_set_voltages, ++ .hpd_event_trigger = rk3588_udphy_hpd_event_trigger, ++ .dplane_enable = rk3588_udphy_dplane_enable, ++ .dplane_select = rk3588_udphy_dplane_select, ++}; ++ ++static const struct of_device_id rockchip_udphy_dt_match[] = { ++ { ++ .compatible = "rockchip,rk3588-usbdp-phy", ++ .data = &rk3588_udphy_cfgs ++ }, ++ { /* sentinel */ } ++}; ++ ++MODULE_DEVICE_TABLE(of, rockchip_udphy_dt_match); ++ ++static struct platform_driver rockchip_udphy_driver = { ++ .probe = rockchip_udphy_probe, ++ .driver = { ++ .name = "rockchip-usbdp-phy", ++ .of_match_table = rockchip_udphy_dt_match, ++ .pm = &udphy_pm_ops, ++ }, ++}; ++ ++module_platform_driver(rockchip_udphy_driver); ++ ++MODULE_AUTHOR("Frank Wang "); ++MODULE_AUTHOR("Zhang Yubing "); ++MODULE_DESCRIPTION("Rockchip USBDP Combo PHY driver"); ++MODULE_LICENSE("GPL"); +-- +2.41.0 + + +From 1a7e20bc463d7907be231c481b79bdfc5b43edd3 Mon Sep 17 00:00:00 2001 +From: Sebastian Reichel +Date: Tue, 25 Apr 2023 17:49:04 +0200 +Subject: [PATCH 5/6] arm64: dts: rockchip: rk3588s: Add USBDP phy nodes + +Add both USB3-Displayport PHYs from RK3588. + +Signed-off-by: Sebastian Reichel +--- + arch/arm64/boot/dts/rockchip/rk3588.dtsi | 63 +++++++++++++++++++ + arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 74 +++++++++++++++++++++++ + 2 files changed, 137 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3588.dtsi b/arch/arm64/boot/dts/rockchip/rk3588.dtsi +index 40fee1367b34..53a6650640ff 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3588.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3588.dtsi +@@ -12,6 +12,38 @@ pipe_phy1_grf: syscon@fd5c0000 { + reg = <0x0 0xfd5c0000 0x0 0x100>; + }; + ++ usbdpphy1_grf: syscon@fd5cc000 { ++ compatible = "rockchip,rk3588-usbdpphy-grf", "syscon"; ++ reg = <0x0 0xfd5cc000 0x0 0x4000>; ++ }; ++ ++ usb2phy1_grf: syscon@fd5d4000 { ++ compatible = "rockchip,rk3588-usb2phy-grf", "syscon", ++ "simple-mfd"; ++ reg = <0x0 0xfd5d4000 0x0 0x4000>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ u2phy1: usb2-phy@4000 { ++ compatible = "rockchip,rk3588-usb2phy"; ++ reg = <0x4000 0x10>; ++ interrupts = ; ++ resets = <&cru SRST_OTGPHY_U3_1>, <&cru SRST_P_USB2PHY_U3_1_GRF0>; ++ reset-names = "phy", "apb"; ++ clocks = <&cru CLK_USB2PHY_HDPTXRXPHY_REF>; ++ clock-names = "phyclk"; ++ clock-output-names = "usb480m_phy1"; ++ #clock-cells = <0>; ++ rockchip,usbctrl-grf = <&usb_grf>; ++ status = "disabled"; ++ ++ u2phy1_otg: otg-port { ++ #phy-cells = <0>; ++ status = "disabled"; ++ }; ++ }; ++ }; ++ + i2s8_8ch: i2s@fddc8000 { + compatible = "rockchip,rk3588-i2s-tdm"; + reg = <0x0 0xfddc8000 0x0 0x1000>; +@@ -206,6 +238,37 @@ sata-port@0 { + }; + }; + ++ usbdp_phy1: phy@fed90000 { ++ compatible = "rockchip,rk3588-usbdp-phy"; ++ reg = <0x0 0xfed90000 0x0 0x10000>; ++ rockchip,u2phy-grf = <&usb2phy1_grf>; ++ rockchip,usb-grf = <&usb_grf>; ++ rockchip,usbdpphy-grf = <&usbdpphy1_grf>; ++ rockchip,vo-grf = <&vo0_grf>; ++ clocks = <&cru CLK_USBDPPHY_MIPIDCPPHY_REF>, ++ <&cru CLK_USBDP_PHY1_IMMORTAL>, ++ <&cru PCLK_USBDPPHY1>, ++ <&u2phy1>; ++ clock-names = "refclk", "immortal", "pclk", "utmi"; ++ resets = <&cru SRST_USBDP_COMBO_PHY1_INIT>, ++ <&cru SRST_USBDP_COMBO_PHY1_CMN>, ++ <&cru SRST_USBDP_COMBO_PHY1_LANE>, ++ <&cru SRST_USBDP_COMBO_PHY1_PCS>, ++ <&cru SRST_P_USBDPPHY1>; ++ reset-names = "init", "cmn", "lane", "pcs_apb", "pma_apb"; ++ status = "disabled"; ++ ++ usbdp_phy1_dp: dp-port { ++ #phy-cells = <0>; ++ status = "disabled"; ++ }; ++ ++ usbdp_phy1_u3: usb3-port { ++ #phy-cells = <0>; ++ status = "disabled"; ++ }; ++ }; ++ + combphy1_ps: phy@fee10000 { + compatible = "rockchip,rk3588-naneng-combphy"; + reg = <0x0 0xfee10000 0x0 0x100>; +diff --git a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi +index 37e323ec9d74..a4a8ac4208b9 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi +@@ -448,6 +448,33 @@ sys_grf: syscon@fd58c000 { + reg = <0x0 0xfd58c000 0x0 0x1000>; + }; + ++ usb2phy0_grf: syscon@fd5d0000 { ++ compatible = "rockchip,rk3588-usb2phy-grf", "syscon", ++ "simple-mfd"; ++ reg = <0x0 0xfd5d0000 0x0 0x4000>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ u2phy0: usb2-phy@0 { ++ compatible = "rockchip,rk3588-usb2phy"; ++ reg = <0x0 0x10>; ++ interrupts = ; ++ resets = <&cru SRST_OTGPHY_U3_0>, <&cru SRST_P_USB2PHY_U3_0_GRF0>; ++ reset-names = "phy", "apb"; ++ clocks = <&cru CLK_USB2PHY_HDPTXRXPHY_REF>; ++ clock-names = "phyclk"; ++ clock-output-names = "usb480m_phy0"; ++ #clock-cells = <0>; ++ rockchip,usbctrl-grf = <&usb_grf>; ++ status = "disabled"; ++ ++ u2phy0_otg: otg-port { ++ #phy-cells = <0>; ++ status = "disabled"; ++ }; ++ }; ++ }; ++ + usb2phy2_grf: syscon@fd5d8000 { + compatible = "rockchip,rk3588-usb2phy-grf", "syscon", "simple-mfd"; + reg = <0x0 0xfd5d8000 0x0 0x4000>; +@@ -473,6 +500,17 @@ u2phy2_host: host-port { + }; + }; + ++ vo0_grf: syscon@fd5a6000 { ++ compatible = "rockchip,rk3588-vo-grf", "syscon"; ++ reg = <0x0 0xfd5a6000 0x0 0x2000>; ++ clocks = <&cru PCLK_VO0GRF>; ++ }; ++ ++ usb_grf: syscon@fd5ac000 { ++ compatible = "rockchip,rk3588-usb-grf", "syscon"; ++ reg = <0x0 0xfd5ac000 0x0 0x4000>; ++ }; ++ + usb2phy3_grf: syscon@fd5dc000 { + compatible = "rockchip,rk3588-usb2phy-grf", "syscon", "simple-mfd"; + reg = <0x0 0xfd5dc000 0x0 0x4000>; +@@ -513,6 +551,11 @@ pipe_phy2_grf: syscon@fd5c4000 { + reg = <0x0 0xfd5c4000 0x0 0x100>; + }; + ++ usbdpphy0_grf: syscon@fd5c8000 { ++ compatible = "rockchip,rk3588-usbdpphy-grf", "syscon"; ++ reg = <0x0 0xfd5c8000 0x0 0x4000>; ++ }; ++ + ioc: syscon@fd5f0000 { + compatible = "rockchip,rk3588-ioc", "syscon"; + reg = <0x0 0xfd5f0000 0x0 0x10000>; +@@ -2166,6 +2209,37 @@ dmac2: dma-controller@fed10000 { + #dma-cells = <1>; + }; + ++ usbdp_phy0: phy@fed80000 { ++ compatible = "rockchip,rk3588-usbdp-phy"; ++ reg = <0x0 0xfed80000 0x0 0x10000>; ++ rockchip,u2phy-grf = <&usb2phy0_grf>; ++ rockchip,usb-grf = <&usb_grf>; ++ rockchip,usbdpphy-grf = <&usbdpphy0_grf>; ++ rockchip,vo-grf = <&vo0_grf>; ++ clocks = <&cru CLK_USBDPPHY_MIPIDCPPHY_REF>, ++ <&cru CLK_USBDP_PHY0_IMMORTAL>, ++ <&cru PCLK_USBDPPHY0>, ++ <&u2phy0>; ++ clock-names = "refclk", "immortal", "pclk", "utmi"; ++ resets = <&cru SRST_USBDP_COMBO_PHY0_INIT>, ++ <&cru SRST_USBDP_COMBO_PHY0_CMN>, ++ <&cru SRST_USBDP_COMBO_PHY0_LANE>, ++ <&cru SRST_USBDP_COMBO_PHY0_PCS>, ++ <&cru SRST_P_USBDPPHY0>; ++ reset-names = "init", "cmn", "lane", "pcs_apb", "pma_apb"; ++ status = "disabled"; ++ ++ usbdp_phy0_dp: dp-port { ++ #phy-cells = <0>; ++ status = "disabled"; ++ }; ++ ++ usbdp_phy0_u3: usb3-port { ++ #phy-cells = <0>; ++ status = "disabled"; ++ }; ++ }; ++ + combphy0_ps: phy@fee00000 { + compatible = "rockchip,rk3588-naneng-combphy"; + reg = <0x0 0xfee00000 0x0 0x100>; +-- +2.41.0 + + +From aa1ed927eddcfd728bdca5dbab9e4980b7dd5085 Mon Sep 17 00:00:00 2001 +From: Sebastian Reichel +Date: Tue, 25 Apr 2023 18:17:19 +0200 +Subject: [PATCH 6/6] arm64: dts: rockchip: rk3588s: Add USB3 controllers + +Add all USB3 controllers. + +Signed-off-by: Sebastian Reichel +--- + arch/arm64/boot/dts/rockchip/rk3588.dtsi | 29 ++++++++++- + arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 60 ++++++++++++++++++++++- + 2 files changed, 87 insertions(+), 2 deletions(-) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3588.dtsi b/arch/arm64/boot/dts/rockchip/rk3588.dtsi +index 53a6650640ff..e0992662b9c6 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3588.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3588.dtsi +@@ -7,6 +7,34 @@ + #include "rk3588-pinctrl.dtsi" + + / { ++ usbdrd3_1: usb@fc400000 { ++ compatible = "rockchip,rk3588-dwc3-otg", "rockchip,rk3399-dwc3"; ++ clocks = <&cru REF_CLK_USB3OTG1>, <&cru SUSPEND_CLK_USB3OTG1>, ++ <&cru ACLK_USB3OTG1>; ++ clock-names = "ref", "suspend", "bus"; ++ ranges; ++ resets = <&cru SRST_A_USB3OTG1>; ++ reset-names = "usb3-otg"; ++ #address-cells = <2>; ++ #size-cells = <2>; ++ status = "disabled"; ++ ++ usbdrd_dwc3_1: usb@fc400000 { ++ compatible = "snps,dwc3"; ++ reg = <0x0 0xfc400000 0x0 0x400000>; ++ interrupts = ; ++ power-domains = <&power RK3588_PD_USB>; ++ dr_mode = "host"; ++ phys = <&u2phy1_otg>, <&usbdp_phy1_u3>; ++ phy-names = "usb2-phy", "usb3-phy"; ++ phy_type = "utmi_wide"; ++ snps,dis_enblslpm_quirk; ++ snps,dis-u2-freeclk-exists-quirk; ++ snps,dis-del-phy-power-chg-quirk; ++ snps,dis-tx-ipgap-linecheck-quirk; ++ }; ++ }; ++ + pipe_phy1_grf: syscon@fd5c0000 { + compatible = "rockchip,rk3588-pipe-phy-grf", "syscon"; + reg = <0x0 0xfd5c0000 0x0 0x100>; +@@ -34,7 +62,6 @@ u2phy1: usb2-phy@4000 { + clock-names = "phyclk"; + clock-output-names = "usb480m_phy1"; + #clock-cells = <0>; +- rockchip,usbctrl-grf = <&usb_grf>; + status = "disabled"; + + u2phy1_otg: otg-port { +diff --git a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi +index a4a8ac4208b9..b46574358dd1 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi +@@ -399,6 +399,36 @@ scmi_shmem: sram@0 { + }; + }; + ++ usbdrd3_0: usb@fc000000 { ++ compatible = "rockchip,rk3588-dwc3-otg", "rockchip,rk3399-dwc3"; ++ clocks = <&cru REF_CLK_USB3OTG0>, <&cru SUSPEND_CLK_USB3OTG0>, ++ <&cru ACLK_USB3OTG0>; ++ clock-names = "ref", "suspend", "bus"; ++ ranges; ++ resets = <&cru SRST_A_USB3OTG0>; ++ reset-names = "usb3-otg"; ++ #address-cells = <2>; ++ #size-cells = <2>; ++ status = "disabled"; ++ ++ usbdrd_dwc3_0: usb@fc000000 { ++ compatible = "snps,dwc3"; ++ reg = <0x0 0xfc000000 0x0 0x400000>; ++ interrupts = ; ++ power-domains = <&power RK3588_PD_USB>; ++ dr_mode = "otg"; ++ phys = <&u2phy0_otg>, <&usbdp_phy0_u3>; ++ phy-names = "usb2-phy", "usb3-phy"; ++ phy_type = "utmi_wide"; ++ snps,dis_enblslpm_quirk; ++ snps,dis-u1-entry-quirk; ++ snps,dis-u2-entry-quirk; ++ snps,dis-u2-freeclk-exists-quirk; ++ snps,dis-del-phy-power-chg-quirk; ++ snps,dis-tx-ipgap-linecheck-quirk; ++ }; ++ }; ++ + usb_host0_ehci: usb@fc800000 { + compatible = "rockchip,rk3588-ehci", "generic-ehci"; + reg = <0x0 0xfc800000 0x0 0x40000>; +@@ -443,6 +473,35 @@ usb_host1_ohci: usb@fc8c0000 { + status = "disabled"; + }; + ++ usbhost3_0: usb@fcd00000 { ++ compatible = "rockchip,rk3588-dwc3-host", "rockchip,rk3399-dwc3"; ++ clocks = <&cru REF_CLK_USB3OTG2>, <&cru SUSPEND_CLK_USB3OTG2>, ++ <&cru ACLK_USB3OTG2>, <&cru CLK_UTMI_OTG2>, ++ <&cru PCLK_PHP_ROOT>, <&cru CLK_PIPEPHY2_PIPE_U3_G>; ++ clock-names = "ref", "suspend", "bus", "utmi", "php", "pipe"; ++ ranges; ++ resets = <&cru SRST_A_USB3OTG2>; ++ reset-names = "usb3-host"; ++ #address-cells = <2>; ++ #size-cells = <2>; ++ status = "disabled"; ++ ++ usbhost_dwc3_0: usb@fcd00000 { ++ compatible = "snps,dwc3"; ++ reg = <0x0 0xfcd00000 0x0 0x400000>; ++ interrupts = ; ++ dr_mode = "host"; ++ phys = <&combphy2_psu PHY_TYPE_USB3>; ++ phy-names = "usb3-phy"; ++ phy_type = "utmi_wide"; ++ snps,dis_enblslpm_quirk; ++ snps,dis-u2-freeclk-exists-quirk; ++ snps,dis-del-phy-power-chg-quirk; ++ snps,dis-tx-ipgap-linecheck-quirk; ++ snps,dis_rxdet_inp3_quirk; ++ }; ++ }; ++ + sys_grf: syscon@fd58c000 { + compatible = "rockchip,rk3588-sys-grf", "syscon"; + reg = <0x0 0xfd58c000 0x0 0x1000>; +@@ -465,7 +524,6 @@ u2phy0: usb2-phy@0 { + clock-names = "phyclk"; + clock-output-names = "usb480m_phy0"; + #clock-cells = <0>; +- rockchip,usbctrl-grf = <&usb_grf>; + status = "disabled"; + + u2phy0_otg: otg-port { +-- +2.41.0 + diff --git a/patch/kernel/rockchip-rk3588-edge/0027-Add-Support-for-RK3588s-Indiedroid-Nova.patch b/patch/kernel/rockchip-rk3588-edge/0027-Add-Support-for-RK3588s-Indiedroid-Nova.patch new file mode 100644 index 0000000000..f933b7b9b0 --- /dev/null +++ b/patch/kernel/rockchip-rk3588-edge/0027-Add-Support-for-RK3588s-Indiedroid-Nova.patch @@ -0,0 +1,968 @@ +From 091209864a90c83e11926cf484dbc4a86c34bcfe Mon Sep 17 00:00:00 2001 +From: Chris Morgan +Date: Wed, 31 May 2023 11:12:16 -0500 +Subject: [PATCH 1/5] arm64: dts: rockchip: add default pinctrl for rk3588 emmc + +Add a default pinctrl definition for the rk3588 emmc. + +Signed-off-by: Chris Morgan +Reviewed-by: Sebastian Reichel +--- + arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi +index a3124bd2e092..03462ae13ac7 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi +@@ -1196,6 +1196,9 @@ sdhci: mmc@fe2e0000 { + <&cru TMCLK_EMMC>; + clock-names = "core", "bus", "axi", "block", "timer"; + max-frequency = <200000000>; ++ pinctrl-0 = <&emmc_rstnout>, <&emmc_bus8>, <&emmc_clk>, ++ <&emmc_cmd>, <&emmc_data_strobe>; ++ pinctrl-names = "default"; + resets = <&cru SRST_C_EMMC>, <&cru SRST_H_EMMC>, + <&cru SRST_A_EMMC>, <&cru SRST_B_EMMC>, + <&cru SRST_T_EMMC>; +-- +2.41.0 + + +From 9ac1b750fa33e5a340eaee65cf1085cad9ede25d Mon Sep 17 00:00:00 2001 +From: Chris Morgan +Date: Wed, 31 May 2023 11:12:17 -0500 +Subject: [PATCH 2/5] arm64: dts: rockchip: Add sdio node to rk3588 + +Add SDIO node for rk3588/rk3588s. + +Signed-off-by: Chris Morgan +Reviewed-by: Sebastian Reichel +--- + arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi +index 03462ae13ac7..7b93abd8f65c 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi +@@ -1185,6 +1185,21 @@ sdmmc: mmc@fe2c0000 { + status = "disabled"; + }; + ++ sdio: mmc@fe2d0000 { ++ compatible = "rockchip,rk3588-dw-mshc", "rockchip,rk3288-dw-mshc"; ++ reg = <0x00 0xfe2d0000 0x00 0x4000>; ++ interrupts = ; ++ clocks = <&cru HCLK_SDIO>, <&cru CCLK_SRC_SDIO>, ++ <&cru SCLK_SDIO_DRV>, <&cru SCLK_SDIO_SAMPLE>; ++ clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; ++ fifo-depth = <0x100>; ++ max-frequency = <200000000>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdiom1_pins>; ++ power-domains = <&power RK3588_PD_SDIO>; ++ status = "disabled"; ++ }; ++ + sdhci: mmc@fe2e0000 { + compatible = "rockchip,rk3588-dwcmshc"; + reg = <0x0 0xfe2e0000 0x0 0x10000>; +-- +2.41.0 + + +From 5799db8897382289eb29505050b6940ef5587628 Mon Sep 17 00:00:00 2001 +From: Chris Morgan +Date: Wed, 31 May 2023 11:12:18 -0500 +Subject: [PATCH 3/5] dt-bindings: vendor-prefixes: add Indiedroid + +Indiedroid is a sub-brand of Ameridroid for their line of single board +computers. +https://indiedroid.us/ + +Signed-off-by: Chris Morgan +Acked-by: Krzysztof Kozlowski +--- + Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml +index 82d39ab0231b..580f32086d55 100644 +--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml ++++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml +@@ -617,6 +617,8 @@ patternProperties: + description: Integrated Micro-Electronics Inc. + "^incircuit,.*": + description: In-Circuit GmbH ++ "^indiedroid,.*": ++ description: Indiedroid + "^inet-tek,.*": + description: Shenzhen iNet Mobile Internet Technology Co., Ltd + "^infineon,.*": +-- +2.41.0 + + +From abebfc368ca4c72ae0f789fb72a62a00fcb417f5 Mon Sep 17 00:00:00 2001 +From: Chris Morgan +Date: Wed, 31 May 2023 11:12:19 -0500 +Subject: [PATCH 4/5] dt-bindings: arm: rockchip: Add Indiedroid Nova + +Add Indiedroid Nova, an rk3588s based single board computer. + +Signed-off-by: Chris Morgan +Acked-by: Conor Dooley +--- + Documentation/devicetree/bindings/arm/rockchip.yaml | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/Documentation/devicetree/bindings/arm/rockchip.yaml b/Documentation/devicetree/bindings/arm/rockchip.yaml +index ec141c937b8b..3c5a204bcd81 100644 +--- a/Documentation/devicetree/bindings/arm/rockchip.yaml ++++ b/Documentation/devicetree/bindings/arm/rockchip.yaml +@@ -542,6 +542,11 @@ properties: + - khadas,edge-v + - const: rockchip,rk3399 + ++ - description: Indiedroid Nova SBC ++ items: ++ - const: indiedroid,nova ++ - const: rockchip,rk3588s ++ + - description: Khadas Edge2 series boards + items: + - const: khadas,edge2 +-- +2.41.0 + + +From 6b199a6dfde0f0f521d88b45df884dc3b5743571 Mon Sep 17 00:00:00 2001 +From: Chris Morgan +Date: Wed, 31 May 2023 11:12:20 -0500 +Subject: [PATCH 5/5] arm64: dts: rockchip: Add Indiedroid Nova board + +The Indiedroid Nova is an SBC from a sub-brand of Ameridroid that +includes the following hardware: + + - A 40-pin GPIO header + - 2 USB-A 3.0 ports + - 2 USB-A 2.0 ports + - A USB-C 2.0 OTG port (used for USB power delivery) + - A USB-C 3.0 port that can do display port output. + - A Micro HDMI 2.1 port. + - A 1GB ethernet port. + - An RT8821CS based WiFi/Bluetooth module. + - A user replaceable eMMC module. + - An SDMMC card slot. + - A MIPI DSI connector. + - A MIPI CSI connector. + - A 3.5mm TRRS audio jack with microphone input. + - An 2 pin socket for an RTC battery. + - A 4 pin socket for a debug port. + - A power button (connected to PMIC), a reset button (connected to SoC + reset), a boot button, and a recovery button (both connected to the + ADC). + - 4GB, 8GB, or 16GB of system RAM. + +This initial devicetree includes support for the WiFi, bluetooth, +analog audio out/in, SDMMC, eMMC, RTC, UART debugging, and has +the regulator values from the schematics. ADC, graphics output, GPU, +USB, and wired ethernet are still pending additional upstream changes. + +Analog audio will require changes to handle a difference between the +requested clock frequency of 12288000 and the actual clock freqency +of 12287999 before it will work properly. This will be done in a +subsequent patch series. + +Signed-off-by: Chris Morgan +--- + arch/arm64/boot/dts/rockchip/Makefile | 1 + + .../dts/rockchip/rk3588s-indiedroid-nova.dts | 764 ++++++++++++++++++ + 2 files changed, 765 insertions(+) + create mode 100644 arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts + +diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile +index 2d585bbb8f3a..99f11db8158d 100644 +--- a/arch/arm64/boot/dts/rockchip/Makefile ++++ b/arch/arm64/boot/dts/rockchip/Makefile +@@ -94,5 +94,6 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-rock-3a.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-edgeble-neu6a-io.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-evb1-v10.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-rock-5b.dtb ++dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-indiedroid-nova.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-khadas-edge2.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-rock-5a.dtb +diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts b/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts +new file mode 100644 +index 000000000000..add15cdafe76 +--- /dev/null ++++ b/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts +@@ -0,0 +1,764 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++ ++/dts-v1/; ++ ++#include ++#include ++#include ++#include "rk3588s.dtsi" ++ ++/ { ++ model = "Indiedroid Nova"; ++ compatible = "indiedroid,nova", "rockchip,rk3588s"; ++ ++ aliases { ++ mmc0 = &sdhci; ++ mmc1 = &sdmmc; ++ mmc2 = &sdio; ++ serial2 = &uart2; ++ }; ++ ++ chosen { ++ stdout-path = "serial2:1500000n8"; ++ }; ++ ++ sdio_pwrseq: sdio-pwrseq { ++ compatible = "mmc-pwrseq-simple"; ++ clock-names = "ext_clock"; ++ clocks = <&rtc_hym8563>; ++ pinctrl-0 = <&wifi_enable_h>; ++ pinctrl-names = "default"; ++ post-power-on-delay-ms = <200>; ++ reset-gpios = <&gpio0 RK_PC7 GPIO_ACTIVE_LOW>; ++ }; ++ ++ sound { ++ compatible = "audio-graph-card"; ++ label = "rockchip,es8388-codec"; ++ widgets = "Microphone", "Mic Jack", ++ "Headphone", "Headphones"; ++ routing = "LINPUT2", "Mic Jack", ++ "Headphones", "LOUT1", ++ "Headphones", "ROUT1"; ++ dais = <&i2s0_8ch_p0>; ++ }; ++ ++ vbus5v0_typec: vbus5v0-typec { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpio = <&gpio4 RK_PA5 GPIO_ACTIVE_HIGH>; ++ pinctrl-0 = <&typec5v_pwren>; ++ pinctrl-names = "default"; ++ regulator-name = "vbus5v0_typec"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ vin-supply = <&vcc5v0_usb>; ++ }; ++ ++ vcc_1v1_nldo_s3: vcc-1v1-nldo-s3 { ++ compatible = "regulator-fixed"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-max-microvolt = <1100000>; ++ regulator-min-microvolt = <1100000>; ++ regulator-name = "vcc_1v1_nldo_s3"; ++ vin-supply = <&vcc5v0_sys>; ++ }; ++ ++ /* Regulator is enabled whenever vcc_1v8_s0 is above 1.6v */ ++ vcc_3v3_s0: vcc-3v3-s0 { ++ compatible = "regulator-fixed"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-max-microvolt = <3300000>; ++ regulator-min-microvolt = <3300000>; ++ regulator-name = "vcc_3v3_s0"; ++ vin-supply = <&vcc_3v3_s3>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcc5v0_sys: vcc5v0-sys { ++ compatible = "regulator-fixed"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-max-microvolt = <5000000>; ++ regulator-min-microvolt = <5000000>; ++ regulator-name = "vcc5v0_sys"; ++ }; ++ ++ vcc5v0_usb: vcc5v0-usb { ++ compatible = "regulator-fixed"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-max-microvolt = <5000000>; ++ regulator-min-microvolt = <5000000>; ++ regulator-name = "vcc5v0_usb"; ++ vin-supply = <&vcc5v0_usbdcin>; ++ }; ++ ++ vcc5v0_usbdcin: vcc5v0-usbdcin { ++ compatible = "regulator-fixed"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-max-microvolt = <5000000>; ++ regulator-min-microvolt = <5000000>; ++ regulator-name = "vcc5v0_usbdcin"; ++ }; ++}; ++ ++&cpu_l0 { ++ cpu-supply = <&vdd_cpu_lit_s0>; ++}; ++ ++&cpu_l1 { ++ cpu-supply = <&vdd_cpu_lit_s0>; ++}; ++ ++&cpu_l2 { ++ cpu-supply = <&vdd_cpu_lit_s0>; ++}; ++ ++&cpu_l3 { ++ cpu-supply = <&vdd_cpu_lit_s0>; ++}; ++ ++&cpu_b0{ ++ cpu-supply = <&vdd_cpu_big0_s0>; ++}; ++ ++&cpu_b1{ ++ cpu-supply = <&vdd_cpu_big0_s0>; ++}; ++ ++&cpu_b2{ ++ cpu-supply = <&vdd_cpu_big1_s0>; ++}; ++ ++&cpu_b3{ ++ cpu-supply = <&vdd_cpu_big1_s0>; ++}; ++ ++/* ++ * Add labels for each GPIO pin exposed on the 40 pin header. Note that ++ * voltage of each GPIO pin could be either 3.3v or 1.8v (as noted by ++ * label). ++ */ ++&gpio0 { ++ gpio-line-names = /* GPIO0 A0-A7 */ ++ "", "", "", "", ++ "", "", "", "", ++ /* GPIO0 B0-B7 */ ++ "", "", "", "", ++ "", "", "", "", ++ /* GPIO0 C0-C7 */ ++ "", "", "", "", ++ "", "", "", "", ++ /* GPIO0 D0-D7 */ ++ "HEADER_12_1v8", "", "", "HEADER_24_1v8", ++ "", "", "", ""; ++}; ++ ++&gpio1 { ++ gpio-line-names = /* GPIO1 A0-A7 */ ++ "HEADER_27_3v3", "HEADER_28_3v3", "", "", ++ "HEADER_29_1v8", "", "HEADER_7_1v8", "", ++ /* GPIO1 B0-B7 */ ++ "", "HEADER_31_1v8", "HEADER_33_1v8", "", ++ "HEADER_11_1v8", "HEADER_13_1v8", "", "", ++ /* GPIO1 C0-C7 */ ++ "", "", "", "", ++ "", "", "", "", ++ /* GPIO1 D0-D7 */ ++ "", "", "", "", ++ "", "", "HEADER_5_3v3", "HEADER_3_3v3"; ++}; ++ ++&gpio3 { ++ gpio-line-names = /* GPIO3 A0-A7 */ ++ "", "", "", "", ++ "", "", "", "", ++ /* GPIO3 B0-B7 */ ++ "HEADER_16_1v8", "HEADER_18_1v8", "", "", ++ "", "", "", "HEADER_19_1v8", ++ /* GPIO3 C0-C7 */ ++ "HEADER_21_1v8", "HEADER_23_1v8", "", "HEADER_26_1v8", ++ "HEADER_15_1v8", "HEADER_22_1v8", "", "", ++ /* GPIO3 D0-D7 */ ++ "", "", "", "", ++ "", "", "", ""; ++}; ++ ++&gpio4 { ++ gpio-line-names = /* GPIO4 A0-A7 */ ++ "", "", "HEADER_37_3v3", "HEADER_32_3v3", ++ "HEADER_36_3v3", "", "HEADER_35_3v3", "HEADER_38_3v3", ++ /* GPIO4 B0-B7 */ ++ "", "", "", "HEADER_40_3v3", ++ "HEADER_8_3v3", "HEADER_10_3v3", "", "", ++ /* GPIO4 C0-C7 */ ++ "", "", "", "", ++ "", "", "", "", ++ /* GPIO4 D0-D7 */ ++ "", "", "", "", ++ "", "", "", ""; ++}; ++ ++&i2c0 { ++ pinctrl-0 = <&i2c0m2_xfer>; ++ pinctrl-names = "default"; ++ status = "okay"; ++ ++ vdd_cpu_big0_s0: regulator@42 { ++ compatible = "rockchip,rk8602"; ++ reg = <0x42>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-max-microvolt = <1050000>; ++ regulator-min-microvolt = <550000>; ++ regulator-name = "vdd_cpu_big0_s0"; ++ regulator-ramp-delay = <2300>; ++ fcs,suspend-voltage-selector = <1>; ++ vin-supply = <&vcc5v0_sys>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vdd_cpu_big1_s0: regulator@43 { ++ compatible = "rockchip,rk8603", "rockchip,rk8602"; ++ reg = <0x43>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-max-microvolt = <1050000>; ++ regulator-min-microvolt = <550000>; ++ regulator-name = "vdd_cpu_big1_s0"; ++ regulator-ramp-delay = <2300>; ++ fcs,suspend-voltage-selector = <1>; ++ vin-supply = <&vcc5v0_sys>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++}; ++ ++&i2c2 { ++ status = "okay"; ++ ++ vdd_npu_s0: regulator@42 { ++ compatible = "rockchip,rk8602"; ++ reg = <0x42>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-max-microvolt = <950000>; ++ regulator-min-microvolt = <550000>; ++ regulator-name = "vdd_npu_s0"; ++ regulator-ramp-delay = <2300>; ++ fcs,suspend-voltage-selector = <1>; ++ vin-supply = <&vcc5v0_sys>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++}; ++ ++&i2c6 { ++ pinctrl-0 = <&i2c6m3_xfer>; ++ status = "okay"; ++ ++ fusb302: typec-portc@22 { ++ compatible = "fcs,fusb302"; ++ reg = <0x22>; ++ interrupt-parent = <&gpio0>; ++ interrupts = ; ++ pinctrl-0 = <&usbc0_int>; ++ pinctrl-names = "default"; ++ vbus-supply = <&vbus5v0_typec>; ++ ++ connector { ++ compatible = "usb-c-connector"; ++ data-role = "dual"; ++ label = "USB-C"; ++ power-role = "dual"; ++ try-power-role = "sink"; ++ source-pdos = ; ++ sink-pdos = ; ++ op-sink-microwatt = <1000000>; ++ }; ++ }; ++ ++ rtc_hym8563: rtc@51 { ++ compatible = "haoyu,hym8563"; ++ reg = <0x51>; ++ #clock-cells = <0>; ++ clock-output-names = "hym8563"; ++ interrupt-parent = <&gpio0>; ++ interrupts = ; ++ pinctrl-0 = <&hym8563_int>; ++ pinctrl-names = "default"; ++ wakeup-source; ++ }; ++}; ++ ++&i2c7 { ++ pinctrl-0 = <&i2c7m0_xfer>; ++ status = "okay"; ++ ++ es8388: audio-codec@11 { ++ compatible = "everest,es8388"; ++ reg = <0x11>; ++ assigned-clock-rates = <12288000>; ++ assigned-clocks = <&cru I2S0_8CH_MCLKOUT>; ++ AVDD-supply = <&vcc_3v3_s3>; ++ clock-names = "mclk"; ++ clocks = <&cru I2S0_8CH_MCLKOUT>; ++ DVDD-supply = <&vcc_1v8_s3>; ++ HPVDD-supply = <&vcc_3v3_s3>; ++ PVDD-supply = <&vcc_1v8_s3>; ++ #sound-dai-cells = <0>; ++ ++ port { ++ es8388_p0_0: endpoint { ++ remote-endpoint = <&i2s0_8ch_p0_0>; ++ }; ++ }; ++ }; ++}; ++ ++&i2s0_8ch { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2s0_lrck ++ &i2s0_mclk ++ &i2s0_sclk ++ &i2s0_sdi0 ++ &i2s0_sdo0>; ++ status = "okay"; ++ ++ i2s0_8ch_p0: port { ++ i2s0_8ch_p0_0: endpoint { ++ dai-format = "i2s"; ++ mclk-fs = <256>; ++ remote-endpoint = <&es8388_p0_0>; ++ }; ++ }; ++}; ++ ++ ++&pinctrl { ++ bluetooth-pins { ++ bt_reset: bt-reset { ++ rockchip,pins = ++ <0 RK_PD4 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ ++ bt_wake_dev: bt-wake-dev { ++ rockchip,pins = ++ <0 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ ++ bt_wake_host: bt-wake-host { ++ rockchip,pins = ++ <0 RK_PC5 RK_FUNC_GPIO &pcfg_pull_down>; ++ }; ++ }; ++ ++ hym8563 { ++ ++ hym8563_int: hym8563-int { ++ rockchip,pins = ++ <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ sdio-pwrseq { ++ wifi_enable_h: wifi-enable-h { ++ rockchip,pins = ++ <0 RK_PC7 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ usb-typec { ++ usbc0_int: usbc0-int { ++ rockchip,pins = ++ <0 RK_PC4 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ ++ typec5v_pwren: typec5v-pwren { ++ rockchip,pins = ++ <4 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++}; ++ ++/* HS400 modes seemed to cause io errors. */ ++&sdhci { ++ bus-width = <8>; ++ no-mmc-hs400; ++ no-sd; ++ no-sdio; ++ non-removable; ++ max-frequency = <200000000>; ++ vmmc-supply = <&vcc_3v3_s0>; ++ vqmmc-supply = <&vcc_1v8_s3>; ++ status = "okay"; ++}; ++ ++&sdio { ++ bus-width = <4>; ++ cap-sd-highspeed; ++ cap-sdio-irq; ++ disable-wp; ++ keep-power-in-suspend; ++ max-frequency = <100000000>; ++ mmc-pwrseq = <&sdio_pwrseq>; ++ no-mmc; ++ no-sd; ++ non-removable; ++ sd-uhs-sdr104; ++ vmmc-supply = <&vcc_3v3_s3>; ++ vqmmc-supply = <&vcc_1v8_s3>; ++ status = "okay"; ++}; ++ ++&sdmmc { ++ bus-width = <4>; ++ cap-mmc-highspeed; ++ cap-sd-highspeed; ++ disable-wp; ++ max-frequency = <200000000>; ++ no-sdio; ++ no-mmc; ++ sd-uhs-sdr104; ++ vmmc-supply = <&vcc_3v3_s3>; ++ vqmmc-supply = <&vccio_sd_s0>; ++ status = "okay"; ++}; ++ ++&spi2 { ++ #address-cells = <1>; ++ assigned-clocks = <&cru CLK_SPI2>; ++ assigned-clock-rates = <200000000>; ++ num-cs = <1>; ++ pinctrl-0 = <&spi2m2_pins>, <&spi2m2_cs0>; ++ pinctrl-names = "default"; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ pmic@0 { ++ compatible = "rockchip,rk806"; ++ reg = <0x0>; ++ #gpio-cells = <2>; ++ gpio-controller; ++ interrupt-parent = <&gpio0>; ++ interrupts = ; ++ pinctrl-0 = <&pmic_pins>, <&rk806_dvs1_null>, ++ <&rk806_dvs2_null>, <&rk806_dvs3_null>; ++ pinctrl-names = "default"; ++ spi-max-frequency = <1000000>; ++ ++ vcc1-supply = <&vcc5v0_sys>; ++ vcc2-supply = <&vcc5v0_sys>; ++ vcc3-supply = <&vcc5v0_sys>; ++ vcc4-supply = <&vcc5v0_sys>; ++ vcc5-supply = <&vcc5v0_sys>; ++ vcc6-supply = <&vcc5v0_sys>; ++ vcc7-supply = <&vcc5v0_sys>; ++ vcc8-supply = <&vcc5v0_sys>; ++ vcc9-supply = <&vcc5v0_sys>; ++ vcc10-supply = <&vcc5v0_sys>; ++ vcc11-supply = <&vcc_2v0_pldo_s3>; ++ vcc12-supply = <&vcc5v0_sys>; ++ vcc13-supply = <&vcc_1v1_nldo_s3>; ++ vcc14-supply = <&vcc_1v1_nldo_s3>; ++ vcca-supply = <&vcc5v0_sys>; ++ ++ rk806_dvs1_null: dvs1-null-pins { ++ pins = "gpio_pwrctrl2"; ++ function = "pin_fun0"; ++ }; ++ ++ rk806_dvs2_null: dvs2-null-pins { ++ pins = "gpio_pwrctrl2"; ++ function = "pin_fun0"; ++ }; ++ ++ rk806_dvs3_null: dvs3-null-pins { ++ pins = "gpio_pwrctrl3"; ++ function = "pin_fun0"; ++ }; ++ ++ regulators { ++ vdd_gpu_s0: dcdc-reg1 { ++ regulator-boot-on; ++ regulator-enable-ramp-delay = <400>; ++ regulator-max-microvolt = <950000>; ++ regulator-min-microvolt = <550000>; ++ regulator-name = "vdd_gpu_s0"; ++ regulator-ramp-delay = <12500>; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vdd_cpu_lit_s0: dcdc-reg2 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-max-microvolt = <950000>; ++ regulator-min-microvolt = <550000>; ++ regulator-ramp-delay = <12500>; ++ regulator-name = "vdd_cpu_lit_s0"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vdd_logic_s0: dcdc-reg3 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-max-microvolt = <750000>; ++ regulator-min-microvolt = <675000>; ++ regulator-name = "vdd_logic_s0"; ++ regulator-ramp-delay = <12500>; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <750000>; ++ }; ++ }; ++ ++ vdd_vdenc_s0: dcdc-reg4 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-max-microvolt = <950000>; ++ regulator-min-microvolt = <550000>; ++ regulator-name = "vdd_vdenc_s0"; ++ regulator-ramp-delay = <12500>; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vdd_ddr_s0: dcdc-reg5 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <750000>; ++ regulator-max-microvolt = <850000>; ++ regulator-ramp-delay = <12500>; ++ regulator-name = "vdd_ddr_s0"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ regulator-suspend-microvolt = <850000>; ++ }; ++ }; ++ ++ vdd2_ddr_s3: dcdc-reg6 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-max-microvolt = <1100000>; ++ regulator-min-microvolt = <1100000>; ++ regulator-name = "vdd2_ddr_s3"; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ }; ++ }; ++ ++ vcc_2v0_pldo_s3: dcdc-reg7 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-max-microvolt = <2000000>; ++ regulator-min-microvolt = <2000000>; ++ regulator-name = "vdd_2v0_pldo_s3"; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <2000000>; ++ }; ++ }; ++ ++ vcc_3v3_s3: dcdc-reg8 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-max-microvolt = <3300000>; ++ regulator-min-microvolt = <3300000>; ++ regulator-name = "vcc_3v3_s3"; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <3300000>; ++ }; ++ }; ++ ++ vddq_ddr_s0: dcdc-reg9 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-max-microvolt = <600000>; ++ regulator-min-microvolt = <600000>; ++ regulator-name = "vddq_ddr_s0"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcc_1v8_s3: dcdc-reg10 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-max-microvolt = <1800000>; ++ regulator-min-microvolt = <1800000>; ++ regulator-name = "vcc_1v8_s3"; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ vcc_1v8_s0: pldo-reg1 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-max-microvolt = <1800000>; ++ regulator-min-microvolt = <1800000>; ++ regulator-name = "vcc_1v8_s0"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcca_1v8_s0: pldo-reg2 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-max-microvolt = <1800000>; ++ regulator-min-microvolt = <1800000>; ++ regulator-name = "vcca_1v8_s0"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ vdda_1v2_s0: pldo-reg3 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-max-microvolt = <1200000>; ++ regulator-min-microvolt = <1200000>; ++ regulator-name = "vdda_1v2_s0"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcca_3v3_s0: pldo-reg4 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-max-microvolt = <3300000>; ++ regulator-min-microvolt = <3300000>; ++ regulator-name = "vcca_3v3_s0"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vccio_sd_s0: pldo-reg5 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-max-microvolt = <3300000>; ++ regulator-min-microvolt = <1800000>; ++ regulator-name = "vccio_sd_s0"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcc_1v8_s3_pldo6: pldo-reg6 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-max-microvolt = <1800000>; ++ regulator-min-microvolt = <1800000>; ++ regulator-name = "vcc_1v8_s3_pldo6"; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ vdd_0v75_s3: nldo-reg1 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-max-microvolt = <750000>; ++ regulator-min-microvolt = <750000>; ++ regulator-name = "vdd_0v75_s3"; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <750000>; ++ }; ++ }; ++ ++ vdda_ddr_pll_s0: nldo-reg2 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-max-microvolt = <850000>; ++ regulator-min-microvolt = <850000>; ++ regulator-name = "vdda_ddr_pll_s0"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ regulator-suspend-microvolt = <850000>; ++ }; ++ }; ++ ++ avdd_0v75_s0: nldo-reg3 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-max-microvolt = <750000>; ++ regulator-min-microvolt = <750000>; ++ regulator-name = "avdd_0v75_s0"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vdda_0v85_s0: nldo-reg4 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <850000>; ++ regulator-max-microvolt = <850000>; ++ regulator-name = "vdda_0v85_s0"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ /* Schematics show not in use */ ++ nldo-reg5 { ++ }; ++ }; ++ }; ++}; ++ ++&tsadc { ++ status = "okay"; ++}; ++ ++&uart2 { ++ pinctrl-0 = <&uart2m0_xfer>; ++ status = "okay"; ++}; ++ ++/* DMA seems to interfere with bluetooth device normal operation. */ ++&uart9 { ++ pinctrl-0 = <&uart9m2_xfer>, <&uart9m2_ctsn>, <&uart9m2_rtsn>; ++ pinctrl-names = "default"; ++ /delete-property/ dma-names; ++ /delete-property/ dmas; ++ uart-has-rtscts; ++ status = "okay"; ++ ++ bluetooth { ++ compatible = "realtek,rtl8821cs-bt", ++ "realtek,rtl8723bs-bt"; ++ device-wake-gpios = <&gpio0 RK_PC6 GPIO_ACTIVE_HIGH>; ++ enable-gpios = <&gpio0 RK_PD4 GPIO_ACTIVE_HIGH>; ++ host-wake-gpios = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>; ++ pinctrl-0 = <&bt_reset>, <&bt_wake_dev>, <&bt_wake_host>; ++ pinctrl-names = "default"; ++ }; ++}; +-- +2.41.0 + diff --git a/patch/kernel/rockchip-rk3588-edge/0028-arm64-dts-rockchip-rk3588-add-sfc-node.patch b/patch/kernel/rockchip-rk3588-edge/0028-arm64-dts-rockchip-rk3588-add-sfc-node.patch new file mode 100644 index 0000000000..a9927813e6 --- /dev/null +++ b/patch/kernel/rockchip-rk3588-edge/0028-arm64-dts-rockchip-rk3588-add-sfc-node.patch @@ -0,0 +1,71 @@ +From b3fc6dde51efdb4dceb1a2fd81490b15307d5328 Mon Sep 17 00:00:00 2001 +From: Muhammed Efe Cetin +Date: Wed, 5 Jul 2023 00:18:54 +0300 +Subject: [PATCH 1/1] arm64: dts: rockchip: rk3588: add sfc node + +--- + arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 20 +++++++++++++++++--- + 1 file changed, 17 insertions(+), 3 deletions(-) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi +index 96fb3a6e0c68..d6dda0e6a5d0 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi +@@ -12,7 +12,7 @@ + #include + + / { +- compatible = "rockchip,rk3588"; ++ compatible = "rockchip,rk3588s", "rockchip,rk3588"; + + interrupt-parent = <&gic>; + #address-cells = <2>; +@@ -524,6 +524,7 @@ u2phy0: usb2-phy@0 { + clock-names = "phyclk"; + clock-output-names = "usb480m_phy0"; + #clock-cells = <0>; ++ rockchip,usbctrl-grf = <&usb_grf>; + status = "disabled"; + + u2phy0_otg: otg-port { +@@ -1573,7 +1574,7 @@ sdhci: mmc@fe2e0000 { + clock-names = "core", "bus", "axi", "block", "timer"; + max-frequency = <200000000>; + pinctrl-0 = <&emmc_rstnout>, <&emmc_bus8>, <&emmc_clk>, +- <&emmc_cmd>, <&emmc_data_strobe>; ++ <&emmc_cmd>, <&emmc_data_strobe>; + pinctrl-names = "default"; + resets = <&cru SRST_C_EMMC>, <&cru SRST_H_EMMC>, + <&cru SRST_A_EMMC>, <&cru SRST_B_EMMC>, +@@ -1812,7 +1813,7 @@ timer0: timer@feae0000 { + clocks = <&cru PCLK_BUSTIMER0>, <&cru CLK_BUSTIMER0>; + clock-names = "pclk", "timer"; + }; +- ++ + wdt: watchdog@feaf0000 { + compatible = "rockchip,rk3588-wdt", "snps,dw-wdt"; + reg = <0x0 0xfeaf0000 0x0 0x100>; +@@ -2442,6 +2443,19 @@ gpio4: gpio@fec50000 { + #interrupt-cells = <2>; + }; + }; ++ ++ sfc: spi@fe2b0000 { ++ compatible = "rockchip,sfc"; ++ reg = <0x0 0xfe2b0000 0x0 0x4000>; ++ interrupts = ; ++ clocks = <&cru SCLK_SFC>, <&cru HCLK_SFC>; ++ clock-names = "clk_sfc", "hclk_sfc"; ++ assigned-clocks = <&cru SCLK_SFC>; ++ assigned-clock-rates = <100000000>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "disabled"; ++ }; + }; + + #include "rk3588s-pinctrl.dtsi" +-- +2.41.0 + diff --git a/patch/kernel/rockchip-rk3588-edge/0029-RK3588-Add-Cpufreq-Support.patch b/patch/kernel/rockchip-rk3588-edge/0029-RK3588-Add-Cpufreq-Support.patch new file mode 100644 index 0000000000..cebf7734d6 --- /dev/null +++ b/patch/kernel/rockchip-rk3588-edge/0029-RK3588-Add-Cpufreq-Support.patch @@ -0,0 +1,1322 @@ +From cd27d0c81ffbcbff5a06c50ebf7cddf36bc02157 Mon Sep 17 00:00:00 2001 +From: Sebastian Reichel +Date: Thu, 18 Aug 2022 14:21:30 +0200 +Subject: [PATCH 1/2] cpufreq: rockchip: Introduce driver for rk3588 + +This is a heavily modified port from the downstream driver. +Downstream used it for multiple rockchip generations, while +upstream just used the generic cpufreq-dt driver so far. For +rk3588 this is no longer good enough, since two regulators +need to be controlled. + +Also during shutdown the correct frequency needs to be configured +for the big CPU cores to avoid a system hang when firmware tries +to bring them up at reboot time. + +Signed-off-by: Sebastian Reichel +Signed-off-by: Muhammed Efe Cetin +--- + drivers/cpufreq/Kconfig.arm | 10 + + drivers/cpufreq/Makefile | 1 + + drivers/cpufreq/cpufreq-dt-platdev.c | 2 + + drivers/cpufreq/rockchip-cpufreq.c | 640 +++++++++++++++++++++++++++ + 4 files changed, 653 insertions(+) + create mode 100644 drivers/cpufreq/rockchip-cpufreq.c + +diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm +index 123b4bbfcfee..6fdc2f0430bb 100644 +--- a/drivers/cpufreq/Kconfig.arm ++++ b/drivers/cpufreq/Kconfig.arm +@@ -189,6 +189,16 @@ config ARM_RASPBERRYPI_CPUFREQ + + If in doubt, say N. + ++config ARM_ROCKCHIP_CPUFREQ ++ tristate "Rockchip CPUfreq driver" ++ depends on ARCH_ROCKCHIP && CPUFREQ_DT ++ select PM_OPP ++ help ++ This adds the CPUFreq driver support for Rockchip SoCs, ++ based on cpufreq-dt. ++ ++ If in doubt, say N. ++ + config ARM_S3C64XX_CPUFREQ + bool "Samsung S3C64XX" + depends on CPU_S3C6410 +diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile +index ef8510774913..c3f8c9cd563f 100644 +--- a/drivers/cpufreq/Makefile ++++ b/drivers/cpufreq/Makefile +@@ -71,6 +71,7 @@ obj-$(CONFIG_PXA3xx) += pxa3xx-cpufreq.o + obj-$(CONFIG_ARM_QCOM_CPUFREQ_HW) += qcom-cpufreq-hw.o + obj-$(CONFIG_ARM_QCOM_CPUFREQ_NVMEM) += qcom-cpufreq-nvmem.o + obj-$(CONFIG_ARM_RASPBERRYPI_CPUFREQ) += raspberrypi-cpufreq.o ++obj-$(CONFIG_ARM_ROCKCHIP_CPUFREQ) += rockchip-cpufreq.o + obj-$(CONFIG_ARM_S3C64XX_CPUFREQ) += s3c64xx-cpufreq.o + obj-$(CONFIG_ARM_S5PV210_CPUFREQ) += s5pv210-cpufreq.o + obj-$(CONFIG_ARM_SA1110_CPUFREQ) += sa1110-cpufreq.o +diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq-dt-platdev.c +index 338cf6cc6596..64cdc6496360 100644 +--- a/drivers/cpufreq/cpufreq-dt-platdev.c ++++ b/drivers/cpufreq/cpufreq-dt-platdev.c +@@ -156,6 +156,8 @@ static const struct of_device_id blocklist[] __initconst = { + { .compatible = "qcom,sm8250", }, + { .compatible = "qcom,sm8350", }, + ++ { .compatible = "rockchip,rk3588", }, ++ + { .compatible = "st,stih407", }, + { .compatible = "st,stih410", }, + { .compatible = "st,stih418", }, +diff --git a/drivers/cpufreq/rockchip-cpufreq.c b/drivers/cpufreq/rockchip-cpufreq.c +new file mode 100644 +index 000000000000..6a60ec05d652 +--- /dev/null ++++ b/drivers/cpufreq/rockchip-cpufreq.c +@@ -0,0 +1,640 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * Rockchip CPUFreq Driver. This is similar to the generic DT ++ * cpufreq driver, but handles the following platform specific ++ * quirks: ++ * ++ * * support for two regulators - one for the CPU core and one ++ * for the memory interface ++ * * reboot handler to setup the reboot frequency ++ * * handling of read margin registers ++ * ++ * Copyright (C) 2017 Fuzhou Rockchip Electronics Co., Ltd ++ * Copyright (C) 2023 Collabora Ltd. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "cpufreq-dt.h" ++ ++#define RK3588_MEMCFG_HSSPRF_LOW 0x20 ++#define RK3588_MEMCFG_HSDPRF_LOW 0x28 ++#define RK3588_MEMCFG_HSDPRF_HIGH 0x2c ++#define RK3588_CPU_CTRL 0x30 ++ ++#define VOLT_RM_TABLE_END ~1 ++ ++static struct platform_device *cpufreq_pdev; ++static LIST_HEAD(priv_list); ++ ++struct volt_rm_table { ++ uint32_t volt; ++ uint32_t rm; ++}; ++ ++struct rockchip_opp_info { ++ const struct rockchip_opp_data *data; ++ struct volt_rm_table *volt_rm_tbl; ++ struct regmap *grf; ++ u32 current_rm; ++ u32 reboot_freq; ++}; ++ ++struct private_data { ++ struct list_head node; ++ ++ cpumask_var_t cpus; ++ struct device *cpu_dev; ++ struct cpufreq_frequency_table *freq_table; ++}; ++ ++struct rockchip_opp_data { ++ int (*set_read_margin)(struct device *dev, struct rockchip_opp_info *opp_info, ++ unsigned long volt); ++}; ++ ++struct cluster_info { ++ struct list_head list_head; ++ struct rockchip_opp_info opp_info; ++ cpumask_t cpus; ++}; ++static LIST_HEAD(cluster_info_list); ++ ++static int rk3588_cpu_set_read_margin(struct device *dev, struct rockchip_opp_info *opp_info, ++ unsigned long volt) ++{ ++ bool is_found = false; ++ u32 rm; ++ int i; ++ ++ if (!opp_info->volt_rm_tbl) ++ return 0; ++ ++ for (i = 0; opp_info->volt_rm_tbl[i].rm != VOLT_RM_TABLE_END; i++) { ++ if (volt >= opp_info->volt_rm_tbl[i].volt) { ++ rm = opp_info->volt_rm_tbl[i].rm; ++ is_found = true; ++ break; ++ } ++ } ++ ++ if (!is_found) ++ return 0; ++ if (rm == opp_info->current_rm) ++ return 0; ++ if (!opp_info->grf) ++ return 0; ++ ++ dev_dbg(dev, "set rm to %d\n", rm); ++ regmap_write(opp_info->grf, RK3588_MEMCFG_HSSPRF_LOW, 0x001c0000 | (rm << 2)); ++ regmap_write(opp_info->grf, RK3588_MEMCFG_HSDPRF_LOW, 0x003c0000 | (rm << 2)); ++ regmap_write(opp_info->grf, RK3588_MEMCFG_HSDPRF_HIGH, 0x003c0000 | (rm << 2)); ++ regmap_write(opp_info->grf, RK3588_CPU_CTRL, 0x00200020); ++ udelay(1); ++ regmap_write(opp_info->grf, RK3588_CPU_CTRL, 0x00200000); ++ ++ opp_info->current_rm = rm; ++ ++ return 0; ++} ++ ++static const struct rockchip_opp_data rk3588_cpu_opp_data = { ++ .set_read_margin = rk3588_cpu_set_read_margin, ++}; ++ ++static const struct of_device_id rockchip_cpufreq_of_match[] = { ++ { ++ .compatible = "rockchip,rk3588", ++ .data = (void *)&rk3588_cpu_opp_data, ++ }, ++ {}, ++}; ++ ++static struct cluster_info *rockchip_cluster_info_lookup(int cpu) ++{ ++ struct cluster_info *cluster; ++ ++ list_for_each_entry(cluster, &cluster_info_list, list_head) { ++ if (cpumask_test_cpu(cpu, &cluster->cpus)) ++ return cluster; ++ } ++ ++ return NULL; ++} ++ ++static int rockchip_cpufreq_set_volt(struct device *dev, ++ struct regulator *reg, ++ struct dev_pm_opp_supply *supply) ++{ ++ int ret; ++ ++ ret = regulator_set_voltage_triplet(reg, supply->u_volt_min, ++ supply->u_volt, supply->u_volt_max); ++ if (ret) ++ dev_err(dev, "%s: failed to set voltage (%lu %lu %lu uV): %d\n", ++ __func__, supply->u_volt_min, supply->u_volt, ++ supply->u_volt_max, ret); ++ ++ return ret; ++} ++ ++static int rockchip_cpufreq_set_read_margin(struct device *dev, ++ struct rockchip_opp_info *opp_info, ++ unsigned long volt) ++{ ++ if (opp_info->data && opp_info->data->set_read_margin) { ++ opp_info->data->set_read_margin(dev, opp_info, volt); ++ } ++ ++ return 0; ++} ++ ++static int rk_opp_config_regulators(struct device *dev, ++ struct dev_pm_opp *old_opp, struct dev_pm_opp *new_opp, ++ struct regulator **regulators, unsigned int count) ++{ ++ struct dev_pm_opp_supply old_supplies[2]; ++ struct dev_pm_opp_supply new_supplies[2]; ++ struct regulator *vdd_reg = regulators[0]; ++ struct regulator *mem_reg = regulators[1]; ++ struct rockchip_opp_info *opp_info; ++ struct cluster_info *cluster; ++ int ret = 0; ++ unsigned long old_freq = dev_pm_opp_get_freq(old_opp); ++ unsigned long new_freq = dev_pm_opp_get_freq(new_opp); ++ ++ /* We must have two regulators here */ ++ WARN_ON(count != 2); ++ ++ ret = dev_pm_opp_get_supplies(old_opp, old_supplies); ++ if (ret) ++ return ret; ++ ++ ret = dev_pm_opp_get_supplies(new_opp, new_supplies); ++ if (ret) ++ return ret; ++ ++ cluster = rockchip_cluster_info_lookup(dev->id); ++ if (!cluster) ++ return -EINVAL; ++ opp_info = &cluster->opp_info; ++ ++ if (new_freq >= old_freq) { ++ ret = rockchip_cpufreq_set_volt(dev, mem_reg, &new_supplies[1]); ++ if (ret) ++ goto error; ++ ret = rockchip_cpufreq_set_volt(dev, vdd_reg, &new_supplies[0]); ++ if (ret) ++ goto error; ++ rockchip_cpufreq_set_read_margin(dev, opp_info, new_supplies[0].u_volt); ++ } else { ++ rockchip_cpufreq_set_read_margin(dev, opp_info, new_supplies[0].u_volt); ++ ret = rockchip_cpufreq_set_volt(dev, vdd_reg, &new_supplies[0]); ++ if (ret) ++ goto error; ++ ret = rockchip_cpufreq_set_volt(dev, mem_reg, &new_supplies[1]); ++ if (ret) ++ goto error; ++ } ++ ++ return 0; ++ ++error: ++ rockchip_cpufreq_set_read_margin(dev, opp_info, old_supplies[0].u_volt); ++ rockchip_cpufreq_set_volt(dev, mem_reg, &old_supplies[1]); ++ rockchip_cpufreq_set_volt(dev, vdd_reg, &old_supplies[0]); ++ return ret; ++} ++ ++static void rockchip_get_opp_data(const struct of_device_id *matches, ++ struct rockchip_opp_info *info) ++{ ++ const struct of_device_id *match; ++ struct device_node *node; ++ ++ node = of_find_node_by_path("/"); ++ match = of_match_node(matches, node); ++ if (match && match->data) ++ info->data = match->data; ++ of_node_put(node); ++} ++ ++static int rockchip_get_volt_rm_table(struct device *dev, struct device_node *np, ++ char *porp_name, struct volt_rm_table **table) ++{ ++ struct volt_rm_table *rm_table; ++ const struct property *prop; ++ int count, i; ++ ++ prop = of_find_property(np, porp_name, NULL); ++ if (!prop) ++ return -EINVAL; ++ ++ if (!prop->value) ++ return -ENODATA; ++ ++ count = of_property_count_u32_elems(np, porp_name); ++ if (count < 0) ++ return -EINVAL; ++ ++ if (count % 2) ++ return -EINVAL; ++ ++ rm_table = devm_kzalloc(dev, sizeof(*rm_table) * (count / 2 + 1), ++ GFP_KERNEL); ++ if (!rm_table) ++ return -ENOMEM; ++ ++ for (i = 0; i < count / 2; i++) { ++ of_property_read_u32_index(np, porp_name, 2 * i, ++ &rm_table[i].volt); ++ of_property_read_u32_index(np, porp_name, 2 * i + 1, ++ &rm_table[i].rm); ++ } ++ ++ rm_table[i].volt = 0; ++ rm_table[i].rm = VOLT_RM_TABLE_END; ++ ++ *table = rm_table; ++ ++ return 0; ++} ++ ++static int rockchip_cpufreq_reboot(struct notifier_block *notifier, unsigned long event, void *cmd) ++{ ++ struct cluster_info *cluster; ++ struct device *dev; ++ int freq, ret, cpu; ++ ++ if (event != SYS_RESTART) ++ return NOTIFY_DONE; ++ ++ for_each_possible_cpu(cpu) { ++ cluster = rockchip_cluster_info_lookup(cpu); ++ if (!cluster) ++ continue; ++ ++ dev = get_cpu_device(cpu); ++ if (!dev) ++ continue; ++ ++ freq = cluster->opp_info.reboot_freq; ++ ++ if (freq) { ++ ret = dev_pm_opp_set_rate(dev, freq); ++ if (ret) ++ dev_err(dev, "Failed setting reboot freq for cpu %d to %d: %d\n", ++ cpu, freq, ret); ++ dev_pm_opp_remove_table(dev); ++ } ++ } ++ ++ return NOTIFY_DONE; ++} ++ ++static int rockchip_cpufreq_cluster_init(int cpu, struct cluster_info *cluster) ++{ ++ struct rockchip_opp_info *opp_info = &cluster->opp_info; ++ int reg_table_token = -EINVAL; ++ int opp_table_token = -EINVAL; ++ struct device_node *np; ++ struct device *dev; ++ const char * const reg_names[] = { "cpu", "mem", NULL }; ++ int ret = 0; ++ ++ dev = get_cpu_device(cpu); ++ if (!dev) ++ return -ENODEV; ++ ++ if (!of_find_property(dev->of_node, "cpu-supply", NULL)) ++ return -ENOENT; ++ ++ np = of_parse_phandle(dev->of_node, "operating-points-v2", 0); ++ if (!np) { ++ dev_warn(dev, "OPP-v2 not supported\n"); ++ return -ENOENT; ++ } ++ ++ reg_table_token = dev_pm_opp_set_regulators(dev, reg_names); ++ if (reg_table_token < 0) { ++ ret = reg_table_token; ++ dev_err_probe(dev, ret, "Failed to set opp regulators\n"); ++ goto np_err; ++ } ++ ++ ret = dev_pm_opp_of_get_sharing_cpus(dev, &cluster->cpus); ++ if (ret) { ++ dev_err_probe(dev, ret, "Failed to get sharing cpus\n"); ++ goto np_err; ++ } ++ ++ rockchip_get_opp_data(rockchip_cpufreq_of_match, opp_info); ++ if (opp_info->data && opp_info->data->set_read_margin) { ++ opp_info->current_rm = UINT_MAX; ++ opp_info->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf"); ++ if (IS_ERR(opp_info->grf)) ++ opp_info->grf = NULL; ++ rockchip_get_volt_rm_table(dev, np, "rockchip,volt-mem-read-margin", &opp_info->volt_rm_tbl); ++ ++ of_property_read_u32(np, "rockchip,reboot-freq", &opp_info->reboot_freq); ++ } ++ ++ opp_table_token = dev_pm_opp_set_config_regulators(dev, rk_opp_config_regulators); ++ if (opp_table_token < 0) { ++ ret = opp_table_token; ++ dev_err(dev, "Failed to set opp config regulators\n"); ++ goto reg_opp_table; ++ } ++ ++ of_node_put(np); ++ ++ return 0; ++ ++reg_opp_table: ++ if (reg_table_token >= 0) ++ dev_pm_opp_put_regulators(reg_table_token); ++np_err: ++ of_node_put(np); ++ ++ return ret; ++} ++ ++static struct notifier_block rockchip_cpufreq_reboot_notifier = { ++ .notifier_call = rockchip_cpufreq_reboot, ++ .priority = 0, ++}; ++ ++static struct freq_attr *cpufreq_rockchip_attr[] = { ++ &cpufreq_freq_attr_scaling_available_freqs, ++ NULL, ++}; ++ ++static int cpufreq_online(struct cpufreq_policy *policy) ++{ ++ /* We did light-weight tear down earlier, nothing to do here */ ++ return 0; ++} ++ ++static int cpufreq_offline(struct cpufreq_policy *policy) ++{ ++ /* ++ * Preserve policy->driver_data and don't free resources on light-weight ++ * tear down. ++ */ ++ return 0; ++} ++ ++static struct private_data *rockchip_cpufreq_find_data(int cpu) ++{ ++ struct private_data *priv; ++ ++ list_for_each_entry(priv, &priv_list, node) { ++ if (cpumask_test_cpu(cpu, priv->cpus)) ++ return priv; ++ } ++ ++ return NULL; ++} ++ ++static int cpufreq_init(struct cpufreq_policy *policy) ++{ ++ struct private_data *priv; ++ struct device *cpu_dev; ++ struct clk *cpu_clk; ++ unsigned int transition_latency; ++ int ret; ++ ++ priv = rockchip_cpufreq_find_data(policy->cpu); ++ if (!priv) { ++ pr_err("failed to find data for cpu%d\n", policy->cpu); ++ return -ENODEV; ++ } ++ cpu_dev = priv->cpu_dev; ++ ++ cpu_clk = clk_get(cpu_dev, NULL); ++ if (IS_ERR(cpu_clk)) { ++ ret = PTR_ERR(cpu_clk); ++ dev_err(cpu_dev, "%s: failed to get clk: %d\n", __func__, ret); ++ return ret; ++ } ++ ++ transition_latency = dev_pm_opp_get_max_transition_latency(cpu_dev); ++ if (!transition_latency) ++ transition_latency = CPUFREQ_ETERNAL; ++ ++ cpumask_copy(policy->cpus, priv->cpus); ++ policy->driver_data = priv; ++ policy->clk = cpu_clk; ++ policy->freq_table = priv->freq_table; ++ policy->suspend_freq = dev_pm_opp_get_suspend_opp_freq(cpu_dev) / 1000; ++ policy->cpuinfo.transition_latency = transition_latency; ++ policy->dvfs_possible_from_any_cpu = true; ++ ++ return 0; ++} ++ ++static int cpufreq_exit(struct cpufreq_policy *policy) ++{ ++ clk_put(policy->clk); ++ return 0; ++} ++ ++static int set_target(struct cpufreq_policy *policy, unsigned int index) ++{ ++ struct private_data *priv = policy->driver_data; ++ unsigned long freq = policy->freq_table[index].frequency; ++ ++ return dev_pm_opp_set_rate(priv->cpu_dev, freq * 1000); ++} ++ ++static struct cpufreq_driver rockchip_cpufreq_driver = { ++ .flags = CPUFREQ_NEED_INITIAL_FREQ_CHECK | ++ CPUFREQ_IS_COOLING_DEV | ++ CPUFREQ_HAVE_GOVERNOR_PER_POLICY, ++ .verify = cpufreq_generic_frequency_table_verify, ++ .target_index = set_target, ++ .get = cpufreq_generic_get, ++ .init = cpufreq_init, ++ .exit = cpufreq_exit, ++ .online = cpufreq_online, ++ .offline = cpufreq_offline, ++ .register_em = cpufreq_register_em_with_opp, ++ .name = "rockchip-cpufreq", ++ .attr = cpufreq_rockchip_attr, ++ .suspend = cpufreq_generic_suspend, ++}; ++ ++static int rockchip_cpufreq_init(struct device *dev, int cpu) ++{ ++ struct private_data *priv; ++ struct device *cpu_dev; ++ int ret; ++ ++ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); ++ if (!priv) ++ return -ENOMEM; ++ ++ if (!alloc_cpumask_var(&priv->cpus, GFP_KERNEL)) ++ return -ENOMEM; ++ ++ cpumask_set_cpu(cpu, priv->cpus); ++ ++ cpu_dev = get_cpu_device(cpu); ++ if (!cpu_dev) ++ return -EPROBE_DEFER; ++ priv->cpu_dev = cpu_dev; ++ ++ ret = dev_pm_opp_of_get_sharing_cpus(cpu_dev, priv->cpus); ++ if (ret) ++ return ret; ++ ++ ret = dev_pm_opp_of_cpumask_add_table(priv->cpus); ++ if (ret) ++ return ret; ++ ++ ret = dev_pm_opp_get_opp_count(cpu_dev); ++ if (ret <= 0) ++ return dev_err_probe(cpu_dev, -ENODEV, "OPP table can't be empty\n"); ++ ++ ret = dev_pm_opp_init_cpufreq_table(cpu_dev, &priv->freq_table); ++ if (ret) ++ return dev_err_probe(cpu_dev, ret, "failed to init cpufreq table\n"); ++ ++ list_add(&priv->node, &priv_list); ++ ++ return 0; ++} ++ ++static void rockchip_cpufreq_free_list(void *data) ++{ ++ struct cluster_info *cluster, *pos; ++ ++ list_for_each_entry_safe(cluster, pos, &cluster_info_list, list_head) { ++ list_del(&cluster->list_head); ++ } ++} ++ ++static int rockchip_cpufreq_init_list(struct device *dev) ++{ ++ struct cluster_info *cluster; ++ int cpu, ret; ++ ++ for_each_possible_cpu(cpu) { ++ cluster = rockchip_cluster_info_lookup(cpu); ++ if (cluster) ++ continue; ++ ++ cluster = devm_kzalloc(dev, sizeof(*cluster), GFP_KERNEL); ++ if (!cluster) { ++ ret = -ENOMEM; ++ goto release_cluster_info; ++ } ++ ++ ret = rockchip_cpufreq_cluster_init(cpu, cluster); ++ if (ret) { ++ dev_err_probe(dev, ret, "Failed to initialize dvfs info cpu%d\n", cpu); ++ goto release_cluster_info; ++ } ++ list_add(&cluster->list_head, &cluster_info_list); ++ } ++ ++ return 0; ++ ++release_cluster_info: ++ rockchip_cpufreq_free_list(NULL); ++ return ret; ++} ++ ++static void rockchip_cpufreq_unregister(void *data) ++{ ++ cpufreq_unregister_driver(&rockchip_cpufreq_driver); ++} ++ ++static int rockchip_cpufreq_probe(struct platform_device *pdev) ++{ ++ int ret, cpu; ++ ++ ret = rockchip_cpufreq_init_list(&pdev->dev); ++ if (ret) ++ return ret; ++ ++ ret = devm_add_action_or_reset(&pdev->dev, rockchip_cpufreq_free_list, NULL); ++ if (ret) ++ return ret; ++ ++ ret = devm_register_reboot_notifier(&pdev->dev, &rockchip_cpufreq_reboot_notifier); ++ if (ret) ++ return dev_err_probe(&pdev->dev, ret, "Failed to register reboot handler\n"); ++ ++ for_each_possible_cpu(cpu) { ++ ret = rockchip_cpufreq_init(&pdev->dev, cpu); ++ if (ret) ++ return ret; ++ } ++ ++ ret = cpufreq_register_driver(&rockchip_cpufreq_driver); ++ if (ret) ++ return dev_err_probe(&pdev->dev, ret, "failed register driver\n"); ++ ++ ret = devm_add_action_or_reset(&pdev->dev, rockchip_cpufreq_unregister, NULL); ++ if (ret) ++ return ret; ++ ++ return 0; ++} ++ ++static struct platform_driver rockchip_cpufreq_platdrv = { ++ .driver = { ++ .name = "rockchip-cpufreq", ++ }, ++ .probe = rockchip_cpufreq_probe, ++}; ++ ++static int __init rockchip_cpufreq_driver_init(void) ++{ ++ int ret; ++ ++ ret = platform_driver_register(&rockchip_cpufreq_platdrv); ++ if (ret) ++ return ret; ++ ++ cpufreq_pdev = platform_device_register_data(NULL, "rockchip-cpufreq", -1, ++ NULL, 0); ++ if (IS_ERR(cpufreq_pdev)) { ++ pr_err("failed to register rockchip-cpufreq platform device\n"); ++ ret = PTR_ERR(cpufreq_pdev); ++ goto unregister_platform_driver; ++ } ++ ++ return 0; ++ ++unregister_platform_driver: ++ platform_driver_unregister(&rockchip_cpufreq_platdrv); ++ return ret; ++} ++module_init(rockchip_cpufreq_driver_init); ++ ++static void __exit rockchip_cpufreq_driver_exit(void) ++{ ++ platform_device_unregister(cpufreq_pdev); ++ platform_driver_unregister(&rockchip_cpufreq_platdrv); ++} ++module_exit(rockchip_cpufreq_driver_exit) ++ ++MODULE_AUTHOR("Finley Xiao "); ++MODULE_DESCRIPTION("Rockchip cpufreq driver"); ++MODULE_LICENSE("GPL v2"); +-- +2.41.0 + + +From 5bcd240ccd436a8538d2e4c0f57773d59f632aeb Mon Sep 17 00:00:00 2001 +From: Muhammed Efe Cetin +Date: Wed, 5 Jul 2023 00:42:45 +0300 +Subject: [PATCH 2/2] arm64: dts: rockchip: rk3588: add cpu frequency scaling + support + +--- + arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 500 ++++++++++++++++++++++ + 1 file changed, 500 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi +index d6dda0e6a5d0..3a9ac4b5cd04 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi +@@ -10,6 +10,7 @@ + #include + #include + #include ++#include + + / { + compatible = "rockchip,rk3588s", "rockchip,rk3588"; +@@ -18,6 +19,263 @@ / { + #address-cells = <2>; + #size-cells = <2>; + ++ cluster0_opp_table: opp-table-cluster0 { ++ compatible = "operating-points-v2"; ++ opp-shared; ++ ++ opp-408000000 { ++ opp-hz = /bits/ 64 <408000000>; ++ opp-microvolt = <750000 750000 950000>, ++ <750000 750000 950000>; ++ clock-latency-ns = <40000>; ++ opp-suspend; ++ }; ++ opp-600000000 { ++ opp-hz = /bits/ 64 <600000000>; ++ opp-microvolt = <750000 750000 950000>, ++ <750000 750000 950000>; ++ clock-latency-ns = <40000>; ++ }; ++ opp-816000000 { ++ opp-hz = /bits/ 64 <816000000>; ++ opp-microvolt = <750000 750000 950000>, ++ <750000 750000 950000>; ++ clock-latency-ns = <40000>; ++ }; ++ opp-1008000000 { ++ opp-hz = /bits/ 64 <1008000000>; ++ opp-microvolt = <750000 750000 950000>, ++ <750000 750000 950000>; ++ clock-latency-ns = <40000>; ++ }; ++ opp-1200000000 { ++ opp-hz = /bits/ 64 <1200000000>; ++ opp-microvolt = <775000 775000 950000>, ++ <775000 775000 950000>; ++ clock-latency-ns = <40000>; ++ }; ++ opp-1416000000 { ++ opp-hz = /bits/ 64 <1416000000>; ++ opp-microvolt = <825000 825000 950000>, ++ <825000 825000 950000>; ++ clock-latency-ns = <40000>; ++ }; ++ opp-1608000000 { ++ opp-hz = /bits/ 64 <1608000000>; ++ opp-microvolt = <875000 875000 950000>, ++ <875000 875000 950000>; ++ clock-latency-ns = <40000>; ++ }; ++ opp-1800000000 { ++ opp-hz = /bits/ 64 <1800000000>; ++ opp-microvolt = <950000 950000 950000>, ++ <950000 950000 950000>; ++ clock-latency-ns = <40000>; ++ }; ++ }; ++ ++ cluster1_opp_table: opp-table-cluster1 { ++ compatible = "operating-points-v2"; ++ opp-shared; ++ ++ rockchip,grf = <&bigcore0_grf>; ++ rockchip,volt-mem-read-margin = < ++ 855000 1 ++ 765000 2 ++ 675000 3 ++ 495000 4 ++ >; ++ ++ rockchip,reboot-freq = <1800000000>; ++ ++ opp-408000000 { ++ opp-hz = /bits/ 64 <408000000>; ++ opp-microvolt = <600000 600000 1000000>, ++ <675000 675000 1000000>; ++ clock-latency-ns = <40000>; ++ opp-suspend; ++ }; ++ opp-600000000 { ++ opp-hz = /bits/ 64 <600000000>; ++ opp-microvolt = <600000 600000 1000000>, ++ <675000 675000 1000000>; ++ clock-latency-ns = <40000>; ++ }; ++ opp-816000000 { ++ opp-hz = /bits/ 64 <816000000>; ++ opp-microvolt = <600000 600000 1000000>, ++ <675000 675000 1000000>; ++ clock-latency-ns = <40000>; ++ }; ++ opp-1008000000 { ++ opp-hz = /bits/ 64 <1008000000>; ++ opp-microvolt = <625000 625000 1000000>, ++ <675000 675000 1000000>; ++ clock-latency-ns = <40000>; ++ }; ++ opp-1200000000 { ++ opp-hz = /bits/ 64 <1200000000>; ++ opp-microvolt = <650000 650000 1000000>, ++ <675000 675000 1000000>; ++ clock-latency-ns = <40000>; ++ }; ++ opp-1416000000 { ++ opp-hz = /bits/ 64 <1416000000>; ++ opp-microvolt = <675000 675000 1000000>, ++ <675000 675000 1000000>; ++ clock-latency-ns = <40000>; ++ }; ++ opp-1608000000 { ++ opp-hz = /bits/ 64 <1608000000>; ++ opp-microvolt = <700000 700000 1000000>, ++ <700000 700000 1000000>; ++ clock-latency-ns = <40000>; ++ }; ++ opp-1800000000 { ++ opp-hz = /bits/ 64 <1800000000>; ++ opp-microvolt = <775000 775000 1000000>, ++ <775000 775000 1000000>; ++ clock-latency-ns = <40000>; ++ }; ++ opp-2016000000 { ++ opp-hz = /bits/ 64 <2016000000>; ++ opp-microvolt = <850000 850000 1000000>, ++ <850000 850000 1000000>; ++ clock-latency-ns = <40000>; ++ }; ++ opp-2208000000 { ++ opp-hz = /bits/ 64 <2208000000>; ++ opp-microvolt = <925000 925000 1000000>, ++ <925000 925000 1000000>; ++ clock-latency-ns = <40000>; ++ }; ++ opp-2256000000 { ++ opp-hz = /bits/ 64 <2256000000>; ++ opp-microvolt = <1000000 1000000 1000000>, ++ <1000000 1000000 1000000>; ++ clock-latency-ns = <40000>; ++ }; ++ opp-2304000000 { ++ opp-hz = /bits/ 64 <2304000000>; ++ opp-microvolt = <1000000 1000000 1000000>, ++ <1000000 1000000 1000000>; ++ clock-latency-ns = <40000>; ++ }; ++ opp-2352000000 { ++ opp-hz = /bits/ 64 <2352000000>; ++ opp-microvolt = <1000000 1000000 1000000>, ++ <1000000 1000000 1000000>; ++ clock-latency-ns = <40000>; ++ }; ++ opp-2400000000 { ++ opp-hz = /bits/ 64 <2400000000>; ++ opp-microvolt = <1000000 1000000 1000000>, ++ <1000000 1000000 1000000>; ++ clock-latency-ns = <40000>; ++ }; ++ }; ++ ++ cluster2_opp_table: opp-table-cluster2 { ++ compatible = "operating-points-v2"; ++ opp-shared; ++ ++ rockchip,grf = <&bigcore1_grf>; ++ rockchip,volt-mem-read-margin = < ++ 855000 1 ++ 765000 2 ++ 675000 3 ++ 495000 4 ++ >; ++ ++ rockchip,reboot-freq = <1800000000>; ++ ++ opp-408000000 { ++ opp-hz = /bits/ 64 <408000000>; ++ opp-microvolt = <600000 600000 1000000>, ++ <675000 675000 1000000>; ++ clock-latency-ns = <40000>; ++ opp-suspend; ++ }; ++ opp-600000000 { ++ opp-hz = /bits/ 64 <600000000>; ++ opp-microvolt = <600000 600000 1000000>, ++ <675000 675000 1000000>; ++ clock-latency-ns = <40000>; ++ }; ++ opp-816000000 { ++ opp-hz = /bits/ 64 <816000000>; ++ opp-microvolt = <600000 600000 1000000>, ++ <675000 675000 1000000>; ++ clock-latency-ns = <40000>; ++ }; ++ opp-1008000000 { ++ opp-hz = /bits/ 64 <1008000000>; ++ opp-microvolt = <625000 625000 1000000>, ++ <675000 675000 1000000>; ++ clock-latency-ns = <40000>; ++ }; ++ opp-1200000000 { ++ opp-hz = /bits/ 64 <1200000000>; ++ opp-microvolt = <650000 650000 1000000>, ++ <675000 675000 1000000>; ++ clock-latency-ns = <40000>; ++ }; ++ opp-1416000000 { ++ opp-hz = /bits/ 64 <1416000000>; ++ opp-microvolt = <675000 675000 1000000>, ++ <675000 675000 1000000>; ++ clock-latency-ns = <40000>; ++ }; ++ opp-1608000000 { ++ opp-hz = /bits/ 64 <1608000000>; ++ opp-microvolt = <700000 700000 1000000>, ++ <700000 700000 1000000>; ++ clock-latency-ns = <40000>; ++ }; ++ opp-1800000000 { ++ opp-hz = /bits/ 64 <1800000000>; ++ opp-microvolt = <775000 775000 1000000>, ++ <775000 775000 1000000>; ++ clock-latency-ns = <40000>; ++ }; ++ opp-2016000000 { ++ opp-hz = /bits/ 64 <2016000000>; ++ opp-microvolt = <850000 850000 1000000>, ++ <850000 850000 1000000>; ++ clock-latency-ns = <40000>; ++ }; ++ opp-2208000000 { ++ opp-hz = /bits/ 64 <2208000000>; ++ opp-microvolt = <925000 925000 1000000>, ++ <925000 925000 1000000>; ++ clock-latency-ns = <40000>; ++ }; ++ opp-2256000000 { ++ opp-hz = /bits/ 64 <2256000000>; ++ opp-microvolt = <1000000 1000000 1000000>, ++ <1000000 1000000 1000000>; ++ clock-latency-ns = <40000>; ++ }; ++ opp-2304000000 { ++ opp-hz = /bits/ 64 <2304000000>; ++ opp-microvolt = <1000000 1000000 1000000>, ++ <1000000 1000000 1000000>; ++ clock-latency-ns = <40000>; ++ }; ++ opp-2352000000 { ++ opp-hz = /bits/ 64 <2352000000>; ++ opp-microvolt = <1000000 1000000 1000000>, ++ <1000000 1000000 1000000>; ++ clock-latency-ns = <40000>; ++ }; ++ opp-2400000000 { ++ opp-hz = /bits/ 64 <2400000000>; ++ opp-microvolt = <1000000 1000000 1000000>, ++ <1000000 1000000 1000000>; ++ clock-latency-ns = <40000>; ++ }; ++ }; ++ + cpus { + #address-cells = <1>; + #size-cells = <0>; +@@ -64,6 +322,7 @@ cpu_l0: cpu@0 { + clocks = <&scmi_clk SCMI_CLK_CPUL>; + assigned-clocks = <&scmi_clk SCMI_CLK_CPUL>; + assigned-clock-rates = <816000000>; ++ operating-points-v2 = <&cluster0_opp_table>; + cpu-idle-states = <&CPU_SLEEP>; + i-cache-size = <32768>; + i-cache-line-size = <64>; +@@ -83,6 +342,7 @@ cpu_l1: cpu@100 { + enable-method = "psci"; + capacity-dmips-mhz = <530>; + clocks = <&scmi_clk SCMI_CLK_CPUL>; ++ operating-points-v2 = <&cluster0_opp_table>; + cpu-idle-states = <&CPU_SLEEP>; + i-cache-size = <32768>; + i-cache-line-size = <64>; +@@ -102,6 +362,7 @@ cpu_l2: cpu@200 { + enable-method = "psci"; + capacity-dmips-mhz = <530>; + clocks = <&scmi_clk SCMI_CLK_CPUL>; ++ operating-points-v2 = <&cluster0_opp_table>; + cpu-idle-states = <&CPU_SLEEP>; + i-cache-size = <32768>; + i-cache-line-size = <64>; +@@ -121,6 +382,7 @@ cpu_l3: cpu@300 { + enable-method = "psci"; + capacity-dmips-mhz = <530>; + clocks = <&scmi_clk SCMI_CLK_CPUL>; ++ operating-points-v2 = <&cluster0_opp_table>; + cpu-idle-states = <&CPU_SLEEP>; + i-cache-size = <32768>; + i-cache-line-size = <64>; +@@ -142,6 +404,7 @@ cpu_b0: cpu@400 { + clocks = <&scmi_clk SCMI_CLK_CPUB01>; + assigned-clocks = <&scmi_clk SCMI_CLK_CPUB01>; + assigned-clock-rates = <816000000>; ++ operating-points-v2 = <&cluster1_opp_table>; + cpu-idle-states = <&CPU_SLEEP>; + i-cache-size = <65536>; + i-cache-line-size = <64>; +@@ -161,6 +424,7 @@ cpu_b1: cpu@500 { + enable-method = "psci"; + capacity-dmips-mhz = <1024>; + clocks = <&scmi_clk SCMI_CLK_CPUB01>; ++ operating-points-v2 = <&cluster1_opp_table>; + cpu-idle-states = <&CPU_SLEEP>; + i-cache-size = <65536>; + i-cache-line-size = <64>; +@@ -182,6 +446,7 @@ cpu_b2: cpu@600 { + clocks = <&scmi_clk SCMI_CLK_CPUB23>; + assigned-clocks = <&scmi_clk SCMI_CLK_CPUB23>; + assigned-clock-rates = <816000000>; ++ operating-points-v2 = <&cluster2_opp_table>; + cpu-idle-states = <&CPU_SLEEP>; + i-cache-size = <65536>; + i-cache-line-size = <64>; +@@ -201,6 +466,7 @@ cpu_b3: cpu@700 { + enable-method = "psci"; + capacity-dmips-mhz = <1024>; + clocks = <&scmi_clk SCMI_CLK_CPUB23>; ++ operating-points-v2 = <&cluster2_opp_table>; + cpu-idle-states = <&CPU_SLEEP>; + i-cache-size = <65536>; + i-cache-line-size = <64>; +@@ -362,6 +628,230 @@ spll: clock-0 { + #clock-cells = <0>; + }; + ++ thermal_zones: thermal-zones { ++ soc_thermal: soc-thermal { ++ polling-delay-passive = <20>; /* milliseconds */ ++ polling-delay = <1000>; /* milliseconds */ ++ sustainable-power = <2100>; /* milliwatts */ ++ ++ thermal-sensors = <&tsadc 0>; ++ trips { ++ trip-point-0 { ++ temperature = <75000>; ++ hysteresis = <2000>; ++ type = "passive"; ++ }; ++ soc_target: trip-point-1 { ++ temperature = <85000>; ++ hysteresis = <2000>; ++ type = "passive"; ++ }; ++ trip-point-2 { ++ /* millicelsius */ ++ temperature = <115000>; ++ /* millicelsius */ ++ hysteresis = <2000>; ++ type = "critical"; ++ }; ++ }; ++ ++ cooling-maps { ++ map0 { ++ trip = <&soc_target>; ++ cooling-device = <&cpu_l0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu_l1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu_l2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu_l3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu_b0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu_b1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu_b2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu_b3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; ++ contribution = <1024>; ++ }; ++ }; ++ }; ++ ++ bigcore0_thermal: bigcore0-thermal { ++ polling-delay-passive = <20>; /* milliseconds */ ++ polling-delay = <1000>; /* milliseconds */ ++ thermal-sensors = <&tsadc 1>; ++ ++ trips { ++ trip-point-0 { ++ temperature = <75000>; ++ hysteresis = <2000>; ++ type = "passive"; ++ }; ++ b0_target: trip-point-1 { ++ temperature = <85000>; ++ hysteresis = <2000>; ++ type = "passive"; ++ }; ++ trip-point-2 { ++ /* millicelsius */ ++ temperature = <115000>; ++ /* millicelsius */ ++ hysteresis = <2000>; ++ type = "critical"; ++ }; ++ }; ++ ++ cooling-maps { ++ map0 { ++ trip = <&b0_target>; ++ cooling-device = <&cpu_b0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu_b1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; ++ contribution = <1024>; ++ }; ++ }; ++ }; ++ ++ bigcore1_thermal: bigcore1-thermal { ++ polling-delay-passive = <20>; /* milliseconds */ ++ polling-delay = <1000>; /* milliseconds */ ++ thermal-sensors = <&tsadc 2>; ++ trips { ++ trip-point-0 { ++ temperature = <75000>; ++ hysteresis = <2000>; ++ type = "passive"; ++ }; ++ b1_target: trip-point-1 { ++ temperature = <85000>; ++ hysteresis = <2000>; ++ type = "passive"; ++ }; ++ trip-point-2 { ++ /* millicelsius */ ++ temperature = <115000>; ++ /* millicelsius */ ++ hysteresis = <2000>; ++ type = "critical"; ++ }; ++ }; ++ ++ cooling-maps { ++ map0 { ++ trip = <&b1_target>; ++ cooling-device = <&cpu_b2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu_b3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; ++ contribution = <1024>; ++ }; ++ }; ++ }; ++ ++ little_core_thermal: littlecore-thermal { ++ polling-delay-passive = <20>; /* milliseconds */ ++ polling-delay = <1000>; /* milliseconds */ ++ thermal-sensors = <&tsadc 3>; ++ trips { ++ trip-point-0 { ++ temperature = <75000>; ++ hysteresis = <2000>; ++ type = "passive"; ++ }; ++ l0_target: trip-point-1 { ++ temperature = <85000>; ++ hysteresis = <2000>; ++ type = "passive"; ++ }; ++ trip-point-2 { ++ /* millicelsius */ ++ temperature = <115000>; ++ /* millicelsius */ ++ hysteresis = <2000>; ++ type = "critical"; ++ }; ++ }; ++ ++ cooling-maps { ++ map0 { ++ trip = <&l0_target>; ++ cooling-device = <&cpu_l0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu_l1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu_l2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu_l3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; ++ contribution = <1024>; ++ }; ++ }; ++ }; ++ ++ center_thermal: center-thermal { ++ polling-delay-passive = <20>; /* milliseconds */ ++ polling-delay = <1000>; /* milliseconds */ ++ thermal-sensors = <&tsadc 4>; ++ trips { ++ trip-point-0 { ++ temperature = <75000>; ++ hysteresis = <2000>; ++ type = "passive"; ++ }; ++ trip-point-1 { ++ temperature = <85000>; ++ hysteresis = <2000>; ++ type = "passive"; ++ }; ++ trip-point-2 { ++ /* millicelsius */ ++ temperature = <115000>; ++ /* millicelsius */ ++ hysteresis = <2000>; ++ type = "critical"; ++ }; ++ }; ++ }; ++ ++ gpu_thermal: gpu-thermal { ++ polling-delay-passive = <20>; /* milliseconds */ ++ polling-delay = <1000>; /* milliseconds */ ++ thermal-sensors = <&tsadc 5>; ++ trips { ++ trip-point-0 { ++ temperature = <75000>; ++ hysteresis = <2000>; ++ type = "passive"; ++ }; ++ trip-point-1 { ++ temperature = <85000>; ++ hysteresis = <2000>; ++ type = "passive"; ++ }; ++ trip-point-2 { ++ /* millicelsius */ ++ temperature = <115000>; ++ /* millicelsius */ ++ hysteresis = <2000>; ++ type = "critical"; ++ }; ++ }; ++ }; ++ ++ npu_thermal: npu-thermal { ++ polling-delay-passive = <20>; /* milliseconds */ ++ polling-delay = <1000>; /* milliseconds */ ++ thermal-sensors = <&tsadc 6>; ++ trips { ++ trip-point-0 { ++ temperature = <75000>; ++ hysteresis = <2000>; ++ type = "passive"; ++ }; ++ trip-point-1 { ++ temperature = <85000>; ++ hysteresis = <2000>; ++ type = "passive"; ++ }; ++ trip-point-2 { ++ /* millicelsius */ ++ temperature = <115000>; ++ /* millicelsius */ ++ hysteresis = <2000>; ++ type = "critical"; ++ }; ++ }; ++ }; ++ }; ++ + timer { + compatible = "arm,armv8-timer"; + interrupts = , +@@ -506,6 +996,16 @@ sys_grf: syscon@fd58c000 { + compatible = "rockchip,rk3588-sys-grf", "syscon"; + reg = <0x0 0xfd58c000 0x0 0x1000>; + }; ++ ++ bigcore0_grf: syscon@fd590000 { ++ compatible = "rockchip,rk3588-bigcore0-grf", "syscon"; ++ reg = <0x0 0xfd590000 0x0 0x100>; ++ }; ++ ++ bigcore1_grf: syscon@fd592000 { ++ compatible = "rockchip,rk3588-bigcore1-grf", "syscon"; ++ reg = <0x0 0xfd592000 0x0 0x100>; ++ }; + + usb2phy0_grf: syscon@fd5d0000 { + compatible = "rockchip,rk3588-usb2phy-grf", "syscon", +-- +2.41.0 + diff --git a/patch/kernel/rockchip-rk3588-edge/dt/rk3588s-orangepi-5.dts b/patch/kernel/rockchip-rk3588-edge/dt/rk3588s-orangepi-5.dts new file mode 100644 index 0000000000..ba0e438381 --- /dev/null +++ b/patch/kernel/rockchip-rk3588-edge/dt/rk3588s-orangepi-5.dts @@ -0,0 +1,1128 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) + +/dts-v1/; + +#include +#include +#include "rk3588s.dtsi" + +/ { + model = "Orange Pi 5"; + compatible = "xunlong,orangepi-5", "rockchip,rk3588s"; + + aliases { + mmc0 = &sdmmc; + //mmc1 = &sdhci; + serial2 = &uart2; + }; + + chosen { + stdout-path = "serial2:1500000n8"; + }; + + gpio_leds: gpio-leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 =<&leds_gpio>; + status = "okay"; + + led@1 { + gpios = <&gpio1 RK_PA2 GPIO_ACTIVE_HIGH>; + label = "status_led"; + linux,default-trigger = "heartbeat"; + linux,default-trigger-delay-ms = <0>; + }; + }; + + sound { + compatible = "audio-graph-card"; + label = "Analog"; + + widgets = "Microphone", "Mic Jack", + "Headphone", "Headphones"; + + routing = "MIC2", "Mic Jack", + "Headphones", "HPOL", + "Headphones", "HPOR"; + + hp-det-gpio = <&gpio1 RK_PD5 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&hp_detect>; + }; + + wireless_bluetooth: wireless-bluetooth { + compatible = "bluetooth-platdata"; + clocks = <&hym8563>; + clock-names = "ext_clock"; + uart_rts_gpios = <&gpio3 RK_PD2 GPIO_ACTIVE_LOW>; + pinctrl-names = "default", "rts_gpio"; + pinctrl-0 = <&uart9m2_rtsn>, <&bt_gpio>; + pinctrl-1 = <&uart9_gpios>; + BT,reset_gpio = <&gpio3 RK_PA6 GPIO_ACTIVE_HIGH>; + BT,wake_gpio = <&gpio0 RK_PC6 GPIO_ACTIVE_HIGH>; + status = "disabled"; + }; + + wireless_wlan: wireless-wlan { + compatible = "wlan-platdata"; + wifi_chip_type = "ap6275p"; + pinctrl-names = "default"; + pinctrl-0 = <&wifi_host_wake_irq>, <&wifi_poweren_gpio>; + WIFI,host_wake_irq = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>; + WIFI,poweren_gpio = <&gpio0 RK_PD0 GPIO_ACTIVE_HIGH>; + status = "disabled"; + }; + + vcc12v_dcin: vcc12v-dcin-regulator { + compatible = "regulator-fixed"; + regulator-name = "vcc12v_dcin"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <12000000>; + regulator-max-microvolt = <12000000>; + }; + + + vcc5v0_sys: vcc5v0-sys-regulator { + compatible = "regulator-fixed"; + regulator-name = "vcc5v0_sys"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&vcc12v_dcin>; + }; + + vcc_1v1_nldo_s3: vcc-1v1-nldo-s3-regulator { + compatible = "regulator-fixed"; + regulator-name = "vcc_1v1_nldo_s3"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + vin-supply = <&vcc5v0_sys>; + }; + + vcc_3v3_sd_s0: vcc-3v3-sd-s0-regulator { + compatible = "regulator-fixed"; + regulator-name = "vcc_3v3_sd_s0"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpios = <&gpio4 RK_PB5 GPIO_ACTIVE_LOW>; + enable-active-low; + vin-supply = <&vcc_3v3_s3>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vcc5v0_usbdcin: vcc5v0-usbdcin-regulator { + compatible = "regulator-fixed"; + regulator-name = "vcc5v0_usbdcin"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&vcc12v_dcin>; + }; + + vcc5v0_usb: vcc5v0-usb-regulator { + compatible = "regulator-fixed"; + regulator-name = "vcc5v0_usb"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&vcc5v0_usbdcin>; + }; + + combophy_avdd0v85: combophy-avdd0v85-regulator { + compatible = "regulator-fixed"; + regulator-name = "combophy_avdd0v85"; + regulator-boot-on; + regulator-always-on; + regulator-min-microvolt = <850000>; + regulator-max-microvolt = <850000>; + vin-supply = <&vdd_0v85_s0>; + }; + + combophy_avdd1v8: combophy-avdd1v8-regulator { + compatible = "regulator-fixed"; + regulator-name = "combophy_avdd1v8"; + regulator-boot-on; + regulator-always-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + vin-supply = <&avcc_1v8_s0>; + }; + + vcc3v3_pcie2x1l2: vcc3v3-pcie2x1l2-regulator { + compatible = "regulator-fixed"; + regulator-name = "vcc3v3_pcie2x1l2"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + enable-active-high; + regulator-boot-on; + regulator-always-on; + gpios = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>; + startup-delay-us = <50000>; + vin-supply = <&vcc5v0_sys>; + }; + + vbus5v0_typec: vbus5v0-typec-regulator { + compatible = "regulator-fixed"; + regulator-name = "vbus5v0_typec"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + enable-active-high; + gpio = <&gpio3 RK_PC0 GPIO_ACTIVE_HIGH>; + vin-supply = <&vcc5v0_usb>; + pinctrl-names = "default"; + pinctrl-0 = <&typec5v_pwren>; + }; +}; + +&combphy0_ps { + status = "okay"; +}; + +&combphy2_psu { + status = "okay"; +}; + +&gmac1 { + /* Use rgmii-rxid mode to disable rx delay inside Soc */ + phy-mode = "rgmii-rxid"; + clock_in_out = "output"; + + snps,reset-gpio = <&gpio3 RK_PB2 GPIO_ACTIVE_LOW>; + snps,reset-active-low; + /* Reset time is 20ms, 100ms for rtl8211f */ + snps,reset-delays-us = <0 20000 100000>; + + pinctrl-names = "default"; + pinctrl-0 = <&gmac1_miim + &gmac1_tx_bus2 + &gmac1_rx_bus2 + &gmac1_rgmii_clk + &gmac1_rgmii_bus>; + + tx_delay = <0x42>; + rx_delay = <0x3f>; + + phy-handle = <&rgmii_phy1>; + status = "okay"; +}; + +&mdio1 { + rgmii_phy1: ethernet-phy@1 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <0x1>; + }; +}; + +&cpu_b0 { + cpu-supply = <&vdd_cpu_big0_s0>; + mem-supply = <&vdd_cpu_big0_mem_s0>; +}; + +&cpu_b1 { + cpu-supply = <&vdd_cpu_big0_s0>; + mem-supply = <&vdd_cpu_big0_mem_s0>; +}; + +&cpu_b2 { + cpu-supply = <&vdd_cpu_big1_s0>; + mem-supply = <&vdd_cpu_big1_mem_s0>; +}; + +&cpu_b3 { + cpu-supply = <&vdd_cpu_big1_s0>; + mem-supply = <&vdd_cpu_big1_mem_s0>; +}; + +&cpu_l0 { + cpu-supply = <&vdd_cpu_lit_s0>; + mem-supply = <&vdd_cpu_lit_mem_s0>; +}; + +&cpu_l1 { + cpu-supply = <&vdd_cpu_lit_s0>; + mem-supply = <&vdd_cpu_lit_mem_s0>; +}; + +&cpu_l2 { + cpu-supply = <&vdd_cpu_lit_s0>; + mem-supply = <&vdd_cpu_lit_mem_s0>; +}; + +&cpu_l3 { + cpu-supply = <&vdd_cpu_lit_s0>; + mem-supply = <&vdd_cpu_lit_mem_s0>; +}; + +&i2c0 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c0m2_xfer>; + status = "okay"; + + vdd_cpu_big0_s0: vdd_cpu_big0_mem_s0: regulator@42 { + compatible = "rockchip,rk8602"; + reg = <0x42>; + fcs,suspend-voltage-selector = <1>; + regulator-name = "vdd_cpu_big0_s0"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <550000>; + regulator-max-microvolt = <1050000>; + regulator-ramp-delay = <2300>; + vin-supply = <&vcc5v0_sys>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_cpu_big1_s0: vdd_cpu_big1_mem_s0: regulator@43 { + compatible = "rockchip,rk8603", "rockchip,rk8602"; + reg = <0x43>; + fcs,suspend-voltage-selector = <1>; + regulator-name = "vdd_cpu_big1_s0"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <550000>; + regulator-max-microvolt = <1050000>; + regulator-ramp-delay = <2300>; + vin-supply = <&vcc5v0_sys>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; +}; + +&i2c1 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c1m2_xfer>; + status = "disabled"; +}; + +&i2c2 { + status = "okay"; + + vdd_npu_s0: vdd_npu_mem_s0: rk8602@42 { + compatible = "rockchip,rk8602"; + reg = <0x42>; + vin-supply = <&vcc5v0_sys>; + regulator-compatible = "rk860x-reg"; + regulator-name = "vdd_npu_s0"; + regulator-min-microvolt = <550000>; + regulator-max-microvolt = <950000>; + regulator-ramp-delay = <2300>; + rockchip,suspend-voltage-selector = <1>; + regulator-boot-on; + regulator-always-on; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; +}; + + +/* + pin3: GPIO1_B7 + pin5: GPIO1_B6 +*/ +&i2c5 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c5m3_xfer>; + status = "disabled"; +}; + +&i2c6 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c6m3_xfer>; + status = "okay"; + + hym8563: rtc@51 { + compatible = "haoyu,hym8563"; + reg = <0x51>; + #clock-cells = <0>; + clock-output-names = "hym8563"; + pinctrl-names = "default"; + pinctrl-0 = <&hym8563_int>; + interrupt-parent = <&gpio0>; + interrupts = ; + wakeup-source; + }; + + es8388: audio-codec@10 { + compatible = "everest,es8388"; + reg = <0x10>; + assigned-clock-rates = <12288000>; + assigned-clocks = <&cru I2S1_8CH_MCLKOUT>; + clock-names = "mclk"; + clocks = <&cru I2S1_8CH_MCLKOUT>; + #sound-dai-cells = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&i2s1m0_mclk>; + + }; + + usbc0: fusb302@22 { + compatible = "fcs,fusb302"; + reg = <0x22>; + interrupt-parent = <&gpio0>; + interrupts = ; + pinctrl-names = "default"; + pinctrl-0 = <&usbc0_int>; + vbus-supply = <&vbus5v0_typec>; + status = "okay"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + usbc0_role_sw: endpoint@0 { + remote-endpoint = <&dwc3_0_role_switch>; + }; + }; + }; + + usb_con: connector { + compatible = "usb-c-connector"; + label = "USB-C"; + data-role = "dual"; + power-role = "dual"; + try-power-role = "sink"; + op-sink-microwatt = <1000000>; + //sink-pdos = ; + //source-pdos = ; + + altmodes { + #address-cells = <1>; + #size-cells = <0>; + + altmode@0 { + reg = <0>; + svid = <0xff01>; + vdo = <0xffffffff>; + }; + }; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + usbc0_orien_sw: endpoint { + remote-endpoint = <&usbdp_phy0_orientation_switch>; + }; + }; + + port@1 { + reg = <1>; + dp_altmode_mux: endpoint { + remote-endpoint = <&usbdp_phy0_dp_altmode_mux>; + }; + }; + }; + }; + }; +}; + +&i2s0_8ch { + pinctrl-0 = <&i2s0_lrck + &i2s0_sclk + &i2s0_sdi0 + &i2s0_sdo0>; + status = "okay"; +}; + + +&i2s1_8ch { + rockchip,i2s-tx-route = <3 2 1 0>; + rockchip,i2s-rx-route = <1 3 2 0>; + pinctrl-names = "default"; + pinctrl-0 = <&i2s1m0_sclk + &i2s1m0_lrck + &i2s1m0_sdi1 + &i2s1m0_sdo3>; + status = "okay"; +}; + +&i2s5_8ch { + status = "okay"; +}; + +&pinctrl { + hym8563 { + hym8563_int: hym8563-int { + rockchip,pins = <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + sound { + hp_detect: hp-detect { + rockchip,pins = <1 RK_PD5 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + gpio-func { + leds_gpio: leds-gpio { + rockchip,pins = <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + sata { + sata_reset:sata-reset{ + rockchip,pins = <3 RK_PD1 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + usb-typec { + usbc0_int: usbc0-int { + rockchip,pins = <0 RK_PD3 RK_FUNC_GPIO &pcfg_pull_up>; + }; + + typec5v_pwren: typec5v-pwren { + rockchip,pins = <3 RK_PC0 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + wireless-bluetooth { + uart9_gpios: uart9-gpios { + rockchip,pins = <3 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + bt_gpio: bt-gpio { + rockchip,pins = + <3 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>, + <0 RK_PC6 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + wireless-wlan { + wifi_host_wake_irq: wifi-host-wake-irq { + rockchip,pins = <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_down>; + }; + + wifi_poweren_gpio: wifi-poweren-gpio { + rockchip,pins = <0 RK_PD0 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; +}; + +&pwm0 { + pinctrl-names = "active"; + pinctrl-0 = <&pwm0m1_pins>; + status = "disabled"; +}; + +/* + pin26: GPIO1_A3 +*/ +&pwm1 { + pinctrl-names = "active"; + pinctrl-0 = <&pwm1m1_pins>; + status = "disabled"; +}; + +&pwm3 { + pinctrl-names = "active"; + pinctrl-0 = <&pwm3m2_pins>; + status = "disabled"; +}; + +&pwm13 { + pinctrl-names = "active"; + pinctrl-0 = <&pwm13m2_pins>; + status = "disabled"; +}; + +/* + pin11: GPIO4_B2 + pin13: GPIO4_B3 +*/ +&pwm14 { + pinctrl-names = "active"; + pinctrl-0 = <&pwm14m1_pins>; + status = "disabled"; +}; + +/* + pin7: GPIO1_C6 +*/ +&pwm15 { + pinctrl-names = "active"; + pinctrl-0 = <&pwm15m2_pins>; + status = "disabled"; +}; + +&saradc { + vref-supply = <&avcc_1v8_s0>; + status = "okay"; +}; + +&sdhci { + bus-width = <8>; + no-sdio; + no-sd; + non-removable; + max-frequency = <200000000>; + mmc-hs400-1_8v; + mmc-hs400-enhanced-strobe; + status = "disabled"; +}; + +&sdmmc { + max-frequency = <150000000>; + no-sdio; + no-mmc; + bus-width = <4>; + cap-mmc-highspeed; + cap-sd-highspeed; + disable-wp; + sd-uhs-sdr104; + vmmc-supply = <&vcc_3v3_sd_s0>; + vqmmc-supply = <&vccio_sd_s0>; + status = "okay"; +}; + +&spi2 { + status = "okay"; + assigned-clocks = <&cru CLK_SPI2>; + assigned-clock-rates = <200000000>; + pinctrl-names = "default"; + pinctrl-0 = <&spi2m2_cs0 &spi2m2_pins>; + num-cs = <1>; + + pmic@0 { + compatible = "rockchip,rk806"; + spi-max-frequency = <1000000>; + reg = <0x0>; + + interrupt-parent = <&gpio0>; + interrupts = <7 IRQ_TYPE_LEVEL_LOW>; + + pinctrl-names = "default"; + pinctrl-0 = <&pmic_pins>, <&rk806_dvs1_null>, + <&rk806_dvs2_null>, <&rk806_dvs3_null>; + + vcc1-supply = <&vcc5v0_sys>; + vcc2-supply = <&vcc5v0_sys>; + vcc3-supply = <&vcc5v0_sys>; + vcc4-supply = <&vcc5v0_sys>; + vcc5-supply = <&vcc5v0_sys>; + vcc6-supply = <&vcc5v0_sys>; + vcc7-supply = <&vcc5v0_sys>; + vcc8-supply = <&vcc5v0_sys>; + vcc9-supply = <&vcc5v0_sys>; + vcc10-supply = <&vcc5v0_sys>; + vcc11-supply = <&vcc_2v0_pldo_s3>; + vcc12-supply = <&vcc5v0_sys>; + vcc13-supply = <&vcc_1v1_nldo_s3>; + vcc14-supply = <&vcc_1v1_nldo_s3>; + vcca-supply = <&vcc5v0_sys>; + + gpio-controller; + #gpio-cells = <2>; + + rk806_dvs1_null: dvs1-null-pins { + pins = "gpio_pwrctrl2"; + function = "pin_fun0"; + }; + + rk806_dvs2_null: dvs2-null-pins { + pins = "gpio_pwrctrl2"; + function = "pin_fudr_moden0"; + }; + + rk806_dvs3_null: dvs3-null-pins { + pins = "gpio_pwrctrl3"; + function = "pin_fun0"; + }; + + regulators { + vdd_gpu_s0: vdd_gpu_mem_s0: dcdc-reg1 { + regulator-boot-on; + regulator-min-microvolt = <550000>; + regulator-max-microvolt = <950000>; + regulator-ramp-delay = <12500>; + regulator-name = "vdd_gpu_s0"; + regulator-enable-ramp-delay = <400>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_cpu_lit_s0: vdd_cpu_lit_mem_s0: dcdc-reg2 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <550000>; + regulator-max-microvolt = <950000>; + regulator-ramp-delay = <12500>; + regulator-name = "vdd_cpu_lit_s0"; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_log_s0: dcdc-reg3 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <675000>; + regulator-max-microvolt = <750000>; + regulator-ramp-delay = <12500>; + regulator-name = "vdd_log_s0"; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <750000>; + }; + }; + + vdd_vdenc_s0: vdd_vdenc_mem_s0: dcdc-reg4 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <550000>; + regulator-max-microvolt = <950000>; + regulator-init-microvolt = <750000>; + regulator-ramp-delay = <12500>; + regulator-name = "vdd_vdenc_s0"; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_ddr_s0: dcdc-reg5 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <675000>; + regulator-max-microvolt = <900000>; + regulator-ramp-delay = <12500>; + regulator-name = "vdd_ddr_s0"; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <850000>; + }; + }; + + vdd2_ddr_s3: dcdc-reg6 { + regulator-always-on; + regulator-boot-on; + regulator-name = "vdd2_ddr_s3"; + + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vcc_2v0_pldo_s3: dcdc-reg7 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <2000000>; + regulator-max-microvolt = <2000000>; + regulator-ramp-delay = <12500>; + regulator-name = "vdd_2v0_pldo_s3"; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <2000000>; + }; + }; + + vcc_3v3_s3: dcdc-reg8 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc_3v3_s3"; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vddq_ddr_s0: dcdc-reg9 { + regulator-always-on; + regulator-boot-on; + regulator-name = "vddq_ddr_s0"; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc_1v8_s3: dcdc-reg10 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "vcc_1v8_s3"; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + avcc_1v8_s0: pldo-reg1 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "avcc_1v8_s0"; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc_1v8_s0: pldo-reg2 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "vcc_1v8_s0"; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + avdd_1v2_s0: pldo-reg3 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-name = "avdd_1v2_s0"; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc_3v3_s0: pldo-reg4 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-ramp-delay = <12500>; + regulator-name = "vcc_3v3_s0"; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vccio_sd_s0: pldo-reg5 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-ramp-delay = <12500>; + regulator-name = "vccio_sd_s0"; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + pldo6_s3: pldo-reg6 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "pldo6_s3"; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vdd_0v75_s3: nldo-reg1 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <750000>; + regulator-name = "vdd_0v75_s3"; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <750000>; + }; + }; + + vdd_ddr_pll_s0: nldo-reg2 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <850000>; + regulator-max-microvolt = <850000>; + regulator-name = "vdd_ddr_pll_s0"; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <850000>; + }; + }; + + avdd_0v75_s0: nldo-reg3 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <750000>; + regulator-name = "avdd_0v75_s0"; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_0v85_s0: nldo-reg4 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <850000>; + regulator-max-microvolt = <850000>; + regulator-name = "vdd_0v85_s0"; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_0v75_s0: nldo-reg5 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <750000>; + regulator-name = "vdd_0v75_s0"; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + }; + }; +}; + +/* + pin19: GPIO1_C1 + pin21: GPIO1_C0 + pin23: GPIO1_C2 + pin24: GPIO1_C4 +*/ +&spi4 { + pinctrl-names = "default"; + pinctrl-0 = <&spi4m0_cs1 &spi4m0_pins>; + assigned-clocks = <&cru CLK_SPI4>; + assigned-clock-rates = <200000000>; + num-cs = <2>; + status = "disabled"; + + spi_dev@1 { + compatible = "rockchip,spidev"; + reg = <1>; + spi-max-frequency = <50000000>; + }; +}; + +/* + pin8: GPIO4_A3 + pin10: GPIO4_A4 +*/ +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0m2_xfer>; + status = "disabled"; +}; + +&uart2 { + pinctrl-0 = <&uart2m0_xfer>; + status = "okay"; +}; + +&uart3 { + pinctrl-names = "default"; + pinctrl-0 = <&uart3m0_xfer>; + status = "disabled"; +}; + +/* + pin16: GPIO1_D3 + pin18: GPIO1_D2 +*/ +&uart4 { + pinctrl-names = "default"; + pinctrl-0 = <&uart4m0_xfer>; + status = "disabled"; +}; + +&uart9 { + pinctrl-names = "default"; + pinctrl-0 = <&uart9m2_xfer &uart9m2_ctsn>; + status = "okay"; +}; + +&tsadc { + status = "okay"; +}; + +&sata0 { + pinctrl-names = "default"; + pinctrl-0 = <&sata_reset>; + status = "disabled"; +}; + +&sfc { + status = "okay"; + max-freq = <100000000>; + #address-cells = <1>; + #size-cells = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&fspim0_pins>; + + spi_flash: spi-flash@0 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "jedec,spi-nor"; + reg = <0x0>; + spi-max-frequency = <100000000>; + spi-tx-bus-width = <1>; + spi-rx-bus-width = <4>; + status = "okay"; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + loader@0 { + label = "loader"; + reg = <0x0 0x1000000>; + }; + }; + }; +}; + + +&pcie2x1l2 { + reset-gpios = <&gpio3 RK_PD1 GPIO_ACTIVE_HIGH>; + vpcie3v3-supply = <&vcc3v3_pcie2x1l2>; + rockchip,skip-scan-in-resume; + status = "okay"; +}; + +&u2phy0 { + status = "okay"; +}; + +&u2phy2 { + status = "okay"; +}; + +&u2phy3 { + status = "okay"; +}; + +&u2phy0_otg { + rockchip,typec-vbus-det; + status = "okay"; +}; + +&u2phy2_host { + status = "okay"; +}; + +&u2phy3_host { + status = "okay"; +}; + +&usb_host0_ehci { + status = "okay"; +}; + +&usb_host0_ohci { + status = "okay"; +}; + +&usb_host1_ehci { + status = "okay"; +}; + +&usb_host1_ohci { + status = "okay"; +}; + +&usbdp_phy0 { + orientation-switch; + svid = <0xff01>; + sbu1-dc-gpios = <&gpio4 RK_PA5 GPIO_ACTIVE_HIGH>; + sbu2-dc-gpios = <&gpio4 RK_PA7 GPIO_ACTIVE_HIGH>; + + port { + #address-cells = <1>; + #size-cells = <0>; + usbdp_phy0_orientation_switch: endpoint@0 { + reg = <0>; + remote-endpoint = <&usbc0_orien_sw>; + }; + + usbdp_phy0_dp_altmode_mux: endpoint@1 { + reg = <1>; + remote-endpoint = <&dp_altmode_mux>; + }; + }; +}; + +&usbdp_phy0_dp { + status = "okay"; +}; + +&usbdp_phy0_u3 { + status = "okay"; +}; + +&usbdrd3_0 { + status = "okay"; +}; + +&usbdrd_dwc3_0 { + status = "okay"; + dr_mode = "otg"; + usb-role-switch; + port { + #address-cells = <1>; + #size-cells = <0>; + dwc3_0_role_switch: endpoint@0 { + reg = <0>; + remote-endpoint = <&usbc0_role_sw>; + }; + }; +}; + +&usbhost3_0 { + dr_mode = "host"; + status = "okay"; +}; + +&usbhost_dwc3_0 { + status = "okay"; +}; + +&wdt { + status = "okay"; +};