diff --git a/config/boards/rock-3a.wip b/config/boards/rock-3a.wip index def874ae99..17f88d90cd 100644 --- a/config/boards/rock-3a.wip +++ b/config/boards/rock-3a.wip @@ -2,8 +2,9 @@ BOARD_NAME="Rock 3A" BOARDFAMILY="rk35xx" BOOTCONFIG="rock-3-a-rk3568_defconfig" -KERNEL_TARGET="legacy" +KERNEL_TARGET="legacy,edge" FULL_DESKTOP="yes" BOOT_LOGO="desktop" BOOT_FDT_FILE="rockchip/rk3568-rock-3-a.dtb" BOOT_SCENARIO="spl-blobs" +WIREGUARD="no" diff --git a/config/kernel/linux-rk35xx-edge.config b/config/kernel/linux-rk35xx-edge.config new file mode 100644 index 0000000000..3a51fdab91 --- /dev/null +++ b/config/kernel/linux-rk35xx-edge.config @@ -0,0 +1,9569 @@ +# +# Automatically generated file; DO NOT EDIT. +# Linux/arm64 5.16.3 Kernel Configuration +# +CONFIG_CC_VERSION_TEXT="aarch64-linux-gnu-gcc (Ubuntu 10.3.0-1ubuntu1) 10.3.0" +CONFIG_CC_IS_GCC=y +CONFIG_GCC_VERSION=100300 +CONFIG_CLANG_VERSION=0 +CONFIG_AS_IS_GNU=y +CONFIG_AS_VERSION=23601 +CONFIG_LD_IS_BFD=y +CONFIG_LD_VERSION=23601 +CONFIG_LLD_VERSION=0 +CONFIG_CC_CAN_LINK=y +CONFIG_CC_CAN_LINK_STATIC=y +CONFIG_CC_HAS_ASM_GOTO=y +CONFIG_CC_HAS_ASM_INLINE=y +CONFIG_CC_HAS_NO_PROFILE_FN_ATTR=y +CONFIG_IRQ_WORK=y +CONFIG_BUILDTIME_TABLE_SORT=y +CONFIG_THREAD_INFO_IN_TASK=y + +# +# General setup +# +CONFIG_INIT_ENV_ARG_LIMIT=32 +# CONFIG_COMPILE_TEST is not set +# CONFIG_WERROR is not set +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_BUILD_SALT="" +CONFIG_DEFAULT_INIT="" +CONFIG_DEFAULT_HOSTNAME="(none)" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_POSIX_MQUEUE=y +CONFIG_POSIX_MQUEUE_SYSCTL=y +# CONFIG_WATCH_QUEUE is not set +CONFIG_CROSS_MEMORY_ATTACH=y +CONFIG_USELIB=y +CONFIG_AUDIT=y +CONFIG_HAVE_ARCH_AUDITSYSCALL=y +CONFIG_AUDITSYSCALL=y + +# +# IRQ subsystem +# +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_IRQ_SHOW=y +CONFIG_GENERIC_IRQ_SHOW_LEVEL=y +CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y +CONFIG_GENERIC_IRQ_MIGRATION=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_GENERIC_IRQ_CHIP=y +CONFIG_IRQ_DOMAIN=y +CONFIG_IRQ_SIM=y +CONFIG_IRQ_DOMAIN_HIERARCHY=y +CONFIG_IRQ_FASTEOI_HIERARCHY_HANDLERS=y +CONFIG_GENERIC_IRQ_IPI=y +CONFIG_GENERIC_MSI_IRQ=y +CONFIG_GENERIC_MSI_IRQ_DOMAIN=y +CONFIG_IRQ_MSI_IOMMU=y +CONFIG_IRQ_FORCED_THREADING=y +CONFIG_SPARSE_IRQ=y +# CONFIG_GENERIC_IRQ_DEBUGFS is not set +# end of IRQ subsystem + +CONFIG_GENERIC_TIME_VSYSCALL=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_ARCH_HAS_TICK_BROADCAST=y +CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y +CONFIG_HAVE_POSIX_CPU_TIMERS_TASK_WORK=y +CONFIG_POSIX_CPU_TIMERS_TASK_WORK=y +CONFIG_TIME_KUNIT_TEST=m + +# +# Timers subsystem +# +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ_COMMON=y +# CONFIG_HZ_PERIODIC is not set +CONFIG_NO_HZ_IDLE=y +# CONFIG_NO_HZ_FULL is not set +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +# end of Timers subsystem + +CONFIG_BPF=y +CONFIG_HAVE_EBPF_JIT=y +CONFIG_ARCH_WANT_DEFAULT_BPF_JIT=y + +# +# BPF subsystem +# +CONFIG_BPF_SYSCALL=y +CONFIG_BPF_JIT=y +# CONFIG_BPF_JIT_ALWAYS_ON is not set +CONFIG_BPF_JIT_DEFAULT_ON=y +# CONFIG_BPF_UNPRIV_DEFAULT_OFF is not set +CONFIG_USERMODE_DRIVER=y +# CONFIG_BPF_PRELOAD is not set +CONFIG_BPF_LSM=y +# end of BPF subsystem + +CONFIG_PREEMPT_BUILD=y +# CONFIG_PREEMPT_NONE is not set +# CONFIG_PREEMPT_VOLUNTARY is not set +CONFIG_PREEMPT=y +CONFIG_PREEMPT_COUNT=y +CONFIG_PREEMPTION=y + +# +# CPU/Task time and stats accounting +# +CONFIG_TICK_CPU_ACCOUNTING=y +# CONFIG_VIRT_CPU_ACCOUNTING_GEN is not set +# CONFIG_IRQ_TIME_ACCOUNTING is not set +CONFIG_SCHED_THERMAL_PRESSURE=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +CONFIG_TASKSTATS=y +CONFIG_TASK_DELAY_ACCT=y +CONFIG_TASK_XACCT=y +CONFIG_TASK_IO_ACCOUNTING=y +# CONFIG_PSI is not set +# end of CPU/Task time and stats accounting + +# CONFIG_CPU_ISOLATION is not set + +# +# RCU Subsystem +# +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 +CONFIG_TASKS_RUDE_RCU=y +CONFIG_TASKS_TRACE_RCU=y +CONFIG_RCU_STALL_COMMON=y +CONFIG_RCU_NEED_SEGCBLIST=y +# end of RCU Subsystem + +CONFIG_BUILD_BIN2C=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_IKHEADERS=m +CONFIG_LOG_BUF_SHIFT=17 +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 + +# +# Scheduler features +# +# CONFIG_UCLAMP_TASK is not set +# end of Scheduler features + +CONFIG_ARCH_SUPPORTS_NUMA_BALANCING=y +CONFIG_CC_HAS_INT128=y +CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5" +CONFIG_ARCH_SUPPORTS_INT128=y +CONFIG_NUMA_BALANCING=y +CONFIG_NUMA_BALANCING_DEFAULT_ENABLED=y +CONFIG_CGROUPS=y +CONFIG_PAGE_COUNTER=y +CONFIG_MEMCG=y +CONFIG_MEMCG_SWAP=y +CONFIG_MEMCG_KMEM=y +CONFIG_BLK_CGROUP=y +CONFIG_CGROUP_WRITEBACK=y +CONFIG_CGROUP_SCHED=y +CONFIG_FAIR_GROUP_SCHED=y +CONFIG_CFS_BANDWIDTH=y +CONFIG_RT_GROUP_SCHED=y +CONFIG_CGROUP_PIDS=y +CONFIG_CGROUP_RDMA=y +CONFIG_CGROUP_FREEZER=y +CONFIG_CGROUP_HUGETLB=y +CONFIG_CPUSETS=y +CONFIG_PROC_PID_CPUSET=y +CONFIG_CGROUP_DEVICE=y +CONFIG_CGROUP_CPUACCT=y +CONFIG_CGROUP_PERF=y +CONFIG_CGROUP_BPF=y +# CONFIG_CGROUP_MISC is not set +# CONFIG_CGROUP_DEBUG is not set +CONFIG_SOCK_CGROUP_DATA=y +CONFIG_NAMESPACES=y +CONFIG_UTS_NS=y +CONFIG_TIME_NS=y +CONFIG_IPC_NS=y +CONFIG_USER_NS=y +CONFIG_PID_NS=y +CONFIG_NET_NS=y +# CONFIG_CHECKPOINT_RESTORE is not set +CONFIG_SCHED_AUTOGROUP=y +# CONFIG_SYSFS_DEPRECATED is not set +CONFIG_RELAY=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_RD_GZIP=y +CONFIG_RD_BZIP2=y +CONFIG_RD_LZMA=y +CONFIG_RD_XZ=y +CONFIG_RD_LZO=y +CONFIG_RD_LZ4=y +CONFIG_RD_ZSTD=y +CONFIG_BOOT_CONFIG=y +CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_LD_ORPHAN_WARN=y +CONFIG_SYSCTL=y +CONFIG_HAVE_UID16=y +CONFIG_SYSCTL_EXCEPTION_TRACE=y +CONFIG_EXPERT=y +CONFIG_UID16=y +CONFIG_MULTIUSER=y +# CONFIG_SGETMASK_SYSCALL is not set +CONFIG_SYSFS_SYSCALL=y +CONFIG_FHANDLE=y +CONFIG_POSIX_TIMERS=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_FUTEX_PI=y +CONFIG_HAVE_FUTEX_CMPXCHG=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_AIO=y +CONFIG_IO_URING=y +CONFIG_ADVISE_SYSCALLS=y +CONFIG_MEMBARRIER=y +CONFIG_KALLSYMS=y +CONFIG_KALLSYMS_ALL=y +CONFIG_KALLSYMS_BASE_RELATIVE=y +# CONFIG_USERFAULTFD is not set +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_HAVE_PERF_EVENTS=y +# CONFIG_PC104 is not set + +# +# Kernel Performance Events And Counters +# +CONFIG_PERF_EVENTS=y +# CONFIG_DEBUG_PERF_USE_VMALLOC is not set +# end of Kernel Performance Events And Counters + +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLUB_DEBUG=y +# CONFIG_COMPAT_BRK is not set +# CONFIG_SLAB is not set +CONFIG_SLUB=y +# CONFIG_SLOB is not set +CONFIG_SLAB_MERGE_DEFAULT=y +# CONFIG_SLAB_FREELIST_RANDOM is not set +# CONFIG_SLAB_FREELIST_HARDENED is not set +# CONFIG_SHUFFLE_PAGE_ALLOCATOR is not set +CONFIG_SLUB_CPU_PARTIAL=y +CONFIG_SYSTEM_DATA_VERIFICATION=y +CONFIG_PROFILING=y +CONFIG_TRACEPOINTS=y +# end of General setup + +CONFIG_ARM64=y +CONFIG_64BIT=y +CONFIG_MMU=y +CONFIG_ARM64_PAGE_SHIFT=12 +CONFIG_ARM64_CONT_PTE_SHIFT=4 +CONFIG_ARM64_CONT_PMD_SHIFT=4 +CONFIG_ARCH_MMAP_RND_BITS_MIN=18 +CONFIG_ARCH_MMAP_RND_BITS_MAX=33 +CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=11 +CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=16 +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000 +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_GENERIC_BUG=y +CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CSUM=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE=y +CONFIG_SMP=y +CONFIG_KERNEL_MODE_NEON=y +CONFIG_FIX_EARLYCON_MEM=y +CONFIG_PGTABLE_LEVELS=4 +CONFIG_ARCH_SUPPORTS_UPROBES=y +CONFIG_ARCH_PROC_KCORE_TEXT=y + +# +# Platform selection +# +# CONFIG_ARCH_ACTIONS is not set +CONFIG_ARCH_SUNXI=y +# CONFIG_ARCH_ALPINE is not set +# CONFIG_ARCH_APPLE is not set +# CONFIG_ARCH_BCM2835 is not set +# CONFIG_ARCH_BCM4908 is not set +# CONFIG_ARCH_BCM_IPROC is not set +# CONFIG_ARCH_BERLIN is not set +# CONFIG_ARCH_BITMAIN is not set +# CONFIG_ARCH_BRCMSTB is not set +# CONFIG_ARCH_EXYNOS is not set +# CONFIG_ARCH_SPARX5 is not set +# CONFIG_ARCH_K3 is not set +# CONFIG_ARCH_LAYERSCAPE is not set +# CONFIG_ARCH_LG1K is not set +# CONFIG_ARCH_HISI is not set +# CONFIG_ARCH_KEEMBAY is not set +# CONFIG_ARCH_MEDIATEK is not set +CONFIG_ARCH_MESON=y +# CONFIG_ARCH_MVEBU is not set +# CONFIG_ARCH_MXC is not set +# CONFIG_ARCH_QCOM is not set +# CONFIG_ARCH_REALTEK is not set +# CONFIG_ARCH_RENESAS is not set +CONFIG_ARCH_ROCKCHIP=y +CONFIG_ARCH_S32=y +# CONFIG_ARCH_SEATTLE is not set +# CONFIG_ARCH_INTEL_SOCFPGA is not set +# CONFIG_ARCH_SYNQUACER is not set +# CONFIG_ARCH_TEGRA is not set +# CONFIG_ARCH_SPRD is not set +# CONFIG_ARCH_THUNDER is not set +# CONFIG_ARCH_THUNDER2 is not set +# CONFIG_ARCH_UNIPHIER is not set +# CONFIG_ARCH_VEXPRESS is not set +# CONFIG_ARCH_VISCONTI is not set +# CONFIG_ARCH_XGENE is not set +# CONFIG_ARCH_ZYNQMP is not set +# end of Platform selection + +# +# Kernel Features +# + +# +# ARM errata workarounds via the alternatives framework +# +CONFIG_ARM64_WORKAROUND_CLEAN_CACHE=y +CONFIG_ARM64_ERRATUM_826319=y +CONFIG_ARM64_ERRATUM_827319=y +CONFIG_ARM64_ERRATUM_824069=y +CONFIG_ARM64_ERRATUM_819472=y +CONFIG_ARM64_ERRATUM_832075=y +CONFIG_ARM64_ERRATUM_834220=y +CONFIG_ARM64_ERRATUM_845719=y +CONFIG_ARM64_ERRATUM_843419=y +CONFIG_ARM64_LD_HAS_FIX_ERRATUM_843419=y +CONFIG_ARM64_ERRATUM_1024718=y +CONFIG_ARM64_ERRATUM_1418040=y +CONFIG_ARM64_WORKAROUND_SPECULATIVE_AT=y +CONFIG_ARM64_ERRATUM_1165522=y +CONFIG_ARM64_ERRATUM_1319367=y +CONFIG_ARM64_ERRATUM_1530923=y +CONFIG_ARM64_WORKAROUND_REPEAT_TLBI=y +CONFIG_ARM64_ERRATUM_1286807=y +CONFIG_ARM64_ERRATUM_1463225=y +CONFIG_ARM64_ERRATUM_1542419=y +CONFIG_ARM64_ERRATUM_1508412=y +CONFIG_ARM64_WORKAROUND_TSB_FLUSH_FAILURE=y +CONFIG_ARM64_ERRATUM_2054223=y +CONFIG_ARM64_ERRATUM_2067961=y +CONFIG_CAVIUM_ERRATUM_22375=y +CONFIG_CAVIUM_ERRATUM_23144=y +CONFIG_CAVIUM_ERRATUM_23154=y +CONFIG_CAVIUM_ERRATUM_27456=y +CONFIG_CAVIUM_ERRATUM_30115=y +CONFIG_CAVIUM_TX2_ERRATUM_219=y +CONFIG_FUJITSU_ERRATUM_010001=y +CONFIG_HISILICON_ERRATUM_161600802=y +CONFIG_QCOM_FALKOR_ERRATUM_1003=y +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_SOCIONEXT_SYNQUACER_PREITS=y +# end of ARM errata workarounds via the alternatives framework + +CONFIG_ARM64_4K_PAGES=y +# CONFIG_ARM64_16K_PAGES is not set +# CONFIG_ARM64_64K_PAGES is not set +# CONFIG_ARM64_VA_BITS_39 is not set +CONFIG_ARM64_VA_BITS_48=y +CONFIG_ARM64_VA_BITS=48 +CONFIG_ARM64_PA_BITS_48=y +CONFIG_ARM64_PA_BITS=48 +# CONFIG_CPU_BIG_ENDIAN is not set +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_SCHED_MC=y +# CONFIG_SCHED_CLUSTER is not set +# CONFIG_SCHED_SMT is not set +CONFIG_NR_CPUS=256 +CONFIG_HOTPLUG_CPU=y +CONFIG_NUMA=y +CONFIG_NODES_SHIFT=2 +CONFIG_USE_PERCPU_NUMA_NODE_ID=y +CONFIG_HAVE_SETUP_PER_CPU_AREA=y +CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y +CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_300 is not set +# CONFIG_HZ_1000 is not set +CONFIG_HZ=250 +CONFIG_SCHED_HRTICK=y +CONFIG_ARCH_SPARSEMEM_ENABLE=y +CONFIG_HW_PERF_EVENTS=y +CONFIG_ARCH_HAS_FILTER_PGPROT=y +CONFIG_PARAVIRT=y +# CONFIG_PARAVIRT_TIME_ACCOUNTING is not set +CONFIG_KEXEC=y +# CONFIG_KEXEC_FILE is not set +CONFIG_CRASH_DUMP=y +CONFIG_TRANS_TABLE=y +CONFIG_XEN_DOM0=y +CONFIG_XEN=y +CONFIG_FORCE_MAX_ZONEORDER=11 +CONFIG_UNMAP_KERNEL_AT_EL0=y +CONFIG_RODATA_FULL_DEFAULT_ENABLED=y +# CONFIG_ARM64_SW_TTBR0_PAN is not set +CONFIG_ARM64_TAGGED_ADDR_ABI=y +CONFIG_COMPAT=y +CONFIG_KUSER_HELPERS=y +CONFIG_ARMV8_DEPRECATED=y +CONFIG_SWP_EMULATION=y +CONFIG_CP15_BARRIER_EMULATION=y +CONFIG_SETEND_EMULATION=y + +# +# ARMv8.1 architectural features +# +CONFIG_ARM64_HW_AFDBM=y +CONFIG_ARM64_PAN=y +CONFIG_AS_HAS_LDAPR=y +CONFIG_AS_HAS_LSE_ATOMICS=y +CONFIG_ARM64_LSE_ATOMICS=y +CONFIG_ARM64_USE_LSE_ATOMICS=y +# end of ARMv8.1 architectural features + +# +# ARMv8.2 architectural features +# +# CONFIG_ARM64_PMEM is not set +CONFIG_ARM64_RAS_EXTN=y +CONFIG_ARM64_CNP=y +# end of ARMv8.2 architectural features + +# +# ARMv8.3 architectural features +# +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_CFI_NEGATE_RA_STATE=y +# end of ARMv8.3 architectural features + +# +# ARMv8.4 architectural features +# +CONFIG_ARM64_AMU_EXTN=y +CONFIG_AS_HAS_ARMV8_4=y +CONFIG_ARM64_TLB_RANGE=y +# end of ARMv8.4 architectural features + +# +# ARMv8.5 architectural features +# +CONFIG_AS_HAS_ARMV8_5=y +CONFIG_ARM64_BTI=y +CONFIG_ARM64_BTI_KERNEL=y +CONFIG_CC_HAS_BRANCH_PROT_PAC_RET_BTI=y +CONFIG_ARM64_E0PD=y +CONFIG_ARCH_RANDOM=y +CONFIG_ARM64_AS_HAS_MTE=y +CONFIG_ARM64_MTE=y +# end of ARMv8.5 architectural features + +# +# ARMv8.7 architectural features +# +CONFIG_ARM64_EPAN=y +# end of ARMv8.7 architectural features + +CONFIG_ARM64_SVE=y +CONFIG_ARM64_MODULE_PLTS=y +# CONFIG_ARM64_PSEUDO_NMI is not set +CONFIG_RELOCATABLE=y +# CONFIG_RANDOMIZE_BASE is not set +CONFIG_CC_HAVE_STACKPROTECTOR_SYSREG=y +CONFIG_STACKPROTECTOR_PER_TASK=y +# end of Kernel Features + +# +# Boot options +# +CONFIG_CMDLINE="" +CONFIG_EFI_STUB=y +CONFIG_EFI=y +CONFIG_DMI=y +# end of Boot options + +CONFIG_SYSVIPC_COMPAT=y + +# +# Power management options +# +CONFIG_SUSPEND=y +CONFIG_SUSPEND_FREEZER=y +# CONFIG_SUSPEND_SKIP_SYNC is not set +CONFIG_HIBERNATE_CALLBACKS=y +CONFIG_HIBERNATION=y +CONFIG_HIBERNATION_SNAPSHOT_DEV=y +CONFIG_PM_STD_PARTITION="" +CONFIG_PM_SLEEP=y +CONFIG_PM_SLEEP_SMP=y +# CONFIG_PM_AUTOSLEEP is not set +# CONFIG_PM_WAKELOCKS is not set +CONFIG_PM=y +# CONFIG_PM_DEBUG is not set +CONFIG_PM_CLK=y +CONFIG_PM_GENERIC_DOMAINS=y +# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set +CONFIG_PM_GENERIC_DOMAINS_SLEEP=y +CONFIG_PM_GENERIC_DOMAINS_OF=y +CONFIG_CPU_PM=y +# CONFIG_ENERGY_MODEL is not set +CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_ARCH_HIBERNATION_HEADER=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +# end of Power management options + +# +# CPU Power Management +# + +# +# CPU Idle +# +CONFIG_CPU_IDLE=y +CONFIG_CPU_IDLE_MULTIPLE_DRIVERS=y +# CONFIG_CPU_IDLE_GOV_LADDER is not set +CONFIG_CPU_IDLE_GOV_MENU=y +# CONFIG_CPU_IDLE_GOV_TEO is not set +CONFIG_DT_IDLE_STATES=y + +# +# ARM CPU Idle Drivers +# +CONFIG_ARM_CPUIDLE=y +# CONFIG_ARM_PSCI_CPUIDLE is not set +# end of ARM CPU Idle Drivers +# end of CPU Idle + +# +# CPU Frequency scaling +# +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_GOV_ATTR_SET=y +CONFIG_CPU_FREQ_GOV_COMMON=y +CONFIG_CPU_FREQ_STAT=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL is not set +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +CONFIG_CPU_FREQ_GOV_USERSPACE=y +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y +CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y + +# +# CPU frequency scaling drivers +# +CONFIG_CPUFREQ_DT=m +CONFIG_CPUFREQ_DT_PLATDEV=y +CONFIG_ARM_ALLWINNER_SUN50I_CPUFREQ_NVMEM=m +CONFIG_ARM_SCPI_CPUFREQ=y +# end of CPU Frequency scaling +# end of CPU Power Management + +CONFIG_ARCH_SUPPORTS_ACPI=y +# CONFIG_ACPI is not set +CONFIG_IRQ_BYPASS_MANAGER=y +CONFIG_HAVE_KVM=y +CONFIG_HAVE_KVM_IRQCHIP=y +CONFIG_HAVE_KVM_IRQFD=y +CONFIG_HAVE_KVM_IRQ_ROUTING=y +CONFIG_HAVE_KVM_EVENTFD=y +CONFIG_KVM_MMIO=y +CONFIG_HAVE_KVM_MSI=y +CONFIG_HAVE_KVM_CPU_RELAX_INTERCEPT=y +CONFIG_KVM_VFIO=y +CONFIG_HAVE_KVM_ARCH_TLB_FLUSH_ALL=y +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_VIRTUALIZATION=y +CONFIG_KVM=y +# CONFIG_NVHE_EL2_DEBUG is not set +CONFIG_ARM64_CRYPTO=y +CONFIG_CRYPTO_SHA256_ARM64=y +CONFIG_CRYPTO_SHA512_ARM64=y +CONFIG_CRYPTO_SHA1_ARM64_CE=y +CONFIG_CRYPTO_SHA2_ARM64_CE=y +# CONFIG_CRYPTO_SHA512_ARM64_CE is not set +CONFIG_CRYPTO_SHA3_ARM64=m +CONFIG_CRYPTO_SM3_ARM64_CE=m +CONFIG_CRYPTO_SM4_ARM64_CE=m +CONFIG_CRYPTO_GHASH_ARM64_CE=y +# CONFIG_CRYPTO_CRCT10DIF_ARM64_CE is not set +CONFIG_CRYPTO_AES_ARM64=y +CONFIG_CRYPTO_AES_ARM64_CE=y +CONFIG_CRYPTO_AES_ARM64_CE_CCM=y +CONFIG_CRYPTO_AES_ARM64_CE_BLK=y +CONFIG_CRYPTO_AES_ARM64_NEON_BLK=y +CONFIG_CRYPTO_CHACHA20_NEON=y +CONFIG_CRYPTO_POLY1305_NEON=m +CONFIG_CRYPTO_NHPOLY1305_NEON=m +CONFIG_CRYPTO_AES_ARM64_BS=y + +# +# General architecture-dependent options +# +CONFIG_CRASH_CORE=y +CONFIG_KEXEC_CORE=y +# CONFIG_KPROBES is not set +CONFIG_JUMP_LABEL=y +# CONFIG_STATIC_KEYS_SELFTEST is not set +CONFIG_UPROBES=y +CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +CONFIG_ARCH_CORRECT_STACKTRACE_ON_KRETPROBE=y +CONFIG_HAVE_FUNCTION_ERROR_INJECTION=y +CONFIG_HAVE_NMI=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_CONTIGUOUS=y +CONFIG_GENERIC_SMP_IDLE_THREAD=y +CONFIG_GENERIC_IDLE_POLL_SETUP=y +CONFIG_ARCH_HAS_FORTIFY_SOURCE=y +CONFIG_ARCH_HAS_KEEPINITRD=y +CONFIG_ARCH_HAS_SET_MEMORY=y +CONFIG_ARCH_HAS_SET_DIRECT_MAP=y +CONFIG_HAVE_ARCH_THREAD_STRUCT_WHITELIST=y +CONFIG_ARCH_WANTS_NO_INSTR=y +CONFIG_HAVE_ASM_MODVERSIONS=y +CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y +CONFIG_HAVE_RSEQ=y +CONFIG_HAVE_FUNCTION_ARG_ACCESS_API=y +CONFIG_HAVE_HW_BREAKPOINT=y +CONFIG_HAVE_PERF_REGS=y +CONFIG_HAVE_PERF_USER_STACK_DUMP=y +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_ARCH_HAVE_NMI_SAFE_CMPXCHG=y +CONFIG_HAVE_ALIGNED_STRUCT_PAGE=y +CONFIG_HAVE_CMPXCHG_LOCAL=y +CONFIG_HAVE_CMPXCHG_DOUBLE=y +CONFIG_ARCH_WANT_COMPAT_IPC_PARSE_VERSION=y +CONFIG_HAVE_ARCH_SECCOMP=y +CONFIG_HAVE_ARCH_SECCOMP_FILTER=y +CONFIG_SECCOMP=y +CONFIG_SECCOMP_FILTER=y +# CONFIG_SECCOMP_CACHE_DEBUG is not set +CONFIG_HAVE_ARCH_STACKLEAK=y +CONFIG_HAVE_STACKPROTECTOR=y +CONFIG_STACKPROTECTOR=y +CONFIG_STACKPROTECTOR_STRONG=y +CONFIG_ARCH_SUPPORTS_LTO_CLANG=y +CONFIG_ARCH_SUPPORTS_LTO_CLANG_THIN=y +CONFIG_LTO_NONE=y +CONFIG_ARCH_SUPPORTS_CFI_CLANG=y +CONFIG_HAVE_CONTEXT_TRACKING=y +CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y +CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y +CONFIG_HAVE_MOVE_PUD=y +CONFIG_HAVE_MOVE_PMD=y +CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE=y +CONFIG_HAVE_ARCH_HUGE_VMAP=y +CONFIG_ARCH_WANT_HUGE_PMD_SHARE=y +CONFIG_HAVE_MOD_ARCH_SPECIFIC=y +CONFIG_MODULES_USE_ELF_RELA=y +CONFIG_ARCH_HAS_ELF_RANDOMIZE=y +CONFIG_HAVE_ARCH_MMAP_RND_BITS=y +CONFIG_ARCH_MMAP_RND_BITS=18 +CONFIG_HAVE_ARCH_MMAP_RND_COMPAT_BITS=y +CONFIG_ARCH_MMAP_RND_COMPAT_BITS=11 +CONFIG_PAGE_SIZE_LESS_THAN_64KB=y +CONFIG_ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT=y +CONFIG_CLONE_BACKWARDS=y +CONFIG_OLD_SIGSUSPEND3=y +CONFIG_COMPAT_OLD_SIGACTION=y +CONFIG_COMPAT_32BIT_TIME=y +CONFIG_HAVE_ARCH_VMAP_STACK=y +CONFIG_VMAP_STACK=y +CONFIG_HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET=y +# CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT is not set +CONFIG_ARCH_HAS_STRICT_KERNEL_RWX=y +CONFIG_STRICT_KERNEL_RWX=y +CONFIG_ARCH_HAS_STRICT_MODULE_RWX=y +CONFIG_STRICT_MODULE_RWX=y +CONFIG_HAVE_ARCH_COMPILER_H=y +CONFIG_HAVE_ARCH_PREL32_RELOCATIONS=y +CONFIG_ARCH_USE_MEMREMAP_PROT=y +# CONFIG_LOCK_EVENT_COUNTS is not set +CONFIG_ARCH_HAS_RELR=y +CONFIG_ARCH_WANT_LD_ORPHAN_WARN=y +CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y +# end of GCOV-based kernel profiling + +CONFIG_HAVE_GCC_PLUGINS=y +# end of General architecture-dependent options + +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=0 +CONFIG_MODULE_SIG_FORMAT=y +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_MODULE_SIG=y +# CONFIG_MODULE_SIG_FORCE is not set +CONFIG_MODULE_SIG_ALL=y +CONFIG_MODULE_SIG_SHA1=y +# CONFIG_MODULE_SIG_SHA224 is not set +# CONFIG_MODULE_SIG_SHA256 is not set +# CONFIG_MODULE_SIG_SHA384 is not set +# CONFIG_MODULE_SIG_SHA512 is not set +CONFIG_MODULE_SIG_HASH="sha1" +# CONFIG_MODULE_COMPRESS_NONE is not set +# CONFIG_MODULE_COMPRESS_GZIP is not set +CONFIG_MODULE_COMPRESS_XZ=y +# CONFIG_MODULE_COMPRESS_ZSTD is not set +# CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS is not set +CONFIG_MODPROBE_PATH="/sbin/modprobe" +# CONFIG_TRIM_UNUSED_KSYMS is not set +CONFIG_MODULES_TREE_LOOKUP=y +CONFIG_BLOCK=y +CONFIG_BLK_CGROUP_RWSTAT=y +CONFIG_BLK_DEV_BSG_COMMON=y +CONFIG_BLK_DEV_BSGLIB=y +CONFIG_BLK_DEV_INTEGRITY=y +CONFIG_BLK_DEV_INTEGRITY_T10=y +CONFIG_BLK_DEV_ZONED=y +CONFIG_BLK_DEV_THROTTLING=y +# CONFIG_BLK_DEV_THROTTLING_LOW is not set +CONFIG_BLK_WBT=y +CONFIG_BLK_WBT_MQ=y +# CONFIG_BLK_CGROUP_IOLATENCY is not set +# CONFIG_BLK_CGROUP_FC_APPID is not set +# CONFIG_BLK_CGROUP_IOCOST is not set +# CONFIG_BLK_CGROUP_IOPRIO is not set +CONFIG_BLK_DEBUG_FS=y +CONFIG_BLK_DEBUG_FS_ZONED=y +# CONFIG_BLK_SED_OPAL is not set +# CONFIG_BLK_INLINE_ENCRYPTION is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +CONFIG_EFI_PARTITION=y +# end of Partition Types + +CONFIG_BLOCK_COMPAT=y +CONFIG_BLK_MQ_PCI=y +CONFIG_BLK_MQ_VIRTIO=y +CONFIG_BLK_PM=y +CONFIG_BLOCK_HOLDER_DEPRECATED=y + +# +# IO Schedulers +# +CONFIG_MQ_IOSCHED_DEADLINE=y +CONFIG_MQ_IOSCHED_KYBER=y +CONFIG_IOSCHED_BFQ=y +CONFIG_BFQ_GROUP_IOSCHED=y +# CONFIG_BFQ_CGROUP_DEBUG is not set +# end of IO Schedulers + +CONFIG_PREEMPT_NOTIFIERS=y +CONFIG_PADATA=y +CONFIG_ASN1=y +CONFIG_UNINLINE_SPIN_UNLOCK=y +CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y +CONFIG_MUTEX_SPIN_ON_OWNER=y +CONFIG_RWSEM_SPIN_ON_OWNER=y +CONFIG_LOCK_SPIN_ON_OWNER=y +CONFIG_ARCH_USE_QUEUED_SPINLOCKS=y +CONFIG_QUEUED_SPINLOCKS=y +CONFIG_ARCH_USE_QUEUED_RWLOCKS=y +CONFIG_QUEUED_RWLOCKS=y +CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE=y +CONFIG_ARCH_HAS_SYSCALL_WRAPPER=y +CONFIG_FREEZER=y + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +CONFIG_COMPAT_BINFMT_ELF=y +CONFIG_ARCH_BINFMT_ELF_STATE=y +CONFIG_ARCH_HAVE_ELF_PROT=y +CONFIG_ARCH_USE_GNU_PROPERTY=y +CONFIG_ELFCORE=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +CONFIG_BINFMT_SCRIPT=y +CONFIG_BINFMT_MISC=m +CONFIG_COREDUMP=y +# end of Executable file formats + +# +# Memory Management options +# +CONFIG_SPARSEMEM=y +CONFIG_SPARSEMEM_EXTREME=y +CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y +CONFIG_SPARSEMEM_VMEMMAP=y +CONFIG_HAVE_FAST_GUP=y +CONFIG_ARCH_KEEP_MEMBLOCK=y +CONFIG_MEMORY_ISOLATION=y +CONFIG_EXCLUSIVE_SYSTEM_RAM=y +CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y +# CONFIG_MEMORY_HOTPLUG is not set +CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +CONFIG_ARCH_ENABLE_SPLIT_PMD_PTLOCK=y +CONFIG_MEMORY_BALLOON=y +CONFIG_BALLOON_COMPACTION=y +CONFIG_COMPACTION=y +CONFIG_PAGE_REPORTING=y +CONFIG_MIGRATION=y +CONFIG_ARCH_ENABLE_HUGEPAGE_MIGRATION=y +CONFIG_ARCH_ENABLE_THP_MIGRATION=y +CONFIG_CONTIG_ALLOC=y +CONFIG_PHYS_ADDR_T_64BIT=y +CONFIG_MMU_NOTIFIER=y +CONFIG_KSM=y +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +CONFIG_ARCH_SUPPORTS_MEMORY_FAILURE=y +# CONFIG_MEMORY_FAILURE is not set +CONFIG_TRANSPARENT_HUGEPAGE=y +# CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS is not set +CONFIG_TRANSPARENT_HUGEPAGE_MADVISE=y +CONFIG_CLEANCACHE=y +CONFIG_FRONTSWAP=y +CONFIG_CMA=y +# CONFIG_CMA_DEBUG is not set +# CONFIG_CMA_DEBUGFS is not set +# CONFIG_CMA_SYSFS is not set +CONFIG_CMA_AREAS=7 +CONFIG_ZSWAP=y +# CONFIG_ZSWAP_COMPRESSOR_DEFAULT_DEFLATE is not set +# CONFIG_ZSWAP_COMPRESSOR_DEFAULT_LZO is not set +# CONFIG_ZSWAP_COMPRESSOR_DEFAULT_842 is not set +# CONFIG_ZSWAP_COMPRESSOR_DEFAULT_LZ4 is not set +# CONFIG_ZSWAP_COMPRESSOR_DEFAULT_LZ4HC is not set +CONFIG_ZSWAP_COMPRESSOR_DEFAULT_ZSTD=y +CONFIG_ZSWAP_COMPRESSOR_DEFAULT="zstd" +# CONFIG_ZSWAP_ZPOOL_DEFAULT_ZBUD is not set +CONFIG_ZSWAP_ZPOOL_DEFAULT_Z3FOLD=y +# CONFIG_ZSWAP_ZPOOL_DEFAULT_ZSMALLOC is not set +CONFIG_ZSWAP_ZPOOL_DEFAULT="z3fold" +CONFIG_ZSWAP_DEFAULT_ON=y +CONFIG_ZPOOL=y +CONFIG_ZBUD=y +CONFIG_Z3FOLD=y +CONFIG_ZSMALLOC=y +# CONFIG_ZSMALLOC_STAT is not set +CONFIG_GENERIC_EARLY_IOREMAP=y +# CONFIG_DEFERRED_STRUCT_PAGE_INIT is not set +# CONFIG_IDLE_PAGE_TRACKING is not set +CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y +CONFIG_ARCH_HAS_PTE_DEVMAP=y +CONFIG_ARCH_HAS_ZONE_DMA_SET=y +CONFIG_ZONE_DMA=y +CONFIG_ZONE_DMA32=y +CONFIG_ARCH_USES_HIGH_VMA_FLAGS=y +# CONFIG_PERCPU_STATS is not set +# CONFIG_GUP_TEST is not set +# CONFIG_READ_ONLY_THP_FOR_FS is not set +CONFIG_ARCH_HAS_PTE_SPECIAL=y +CONFIG_MAPPING_DIRTY_HELPERS=y +CONFIG_SECRETMEM=y + +# +# Data Access Monitoring +# +# CONFIG_DAMON is not set +# end of Data Access Monitoring +# end of Memory Management options + +CONFIG_NET=y +CONFIG_COMPAT_NETLINK_MESSAGES=y +CONFIG_NET_INGRESS=y +CONFIG_NET_EGRESS=y +CONFIG_NET_REDIRECT=y +CONFIG_SKB_EXTENSIONS=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_DIAG=m +CONFIG_UNIX=y +CONFIG_UNIX_SCM=y +CONFIG_AF_UNIX_OOB=y +CONFIG_UNIX_DIAG=m +CONFIG_TLS=m +CONFIG_TLS_DEVICE=y +# CONFIG_TLS_TOE is not set +CONFIG_XFRM=y +CONFIG_XFRM_OFFLOAD=y +CONFIG_XFRM_ALGO=m +CONFIG_XFRM_USER=m +CONFIG_XFRM_INTERFACE=m +CONFIG_XFRM_SUB_POLICY=y +CONFIG_XFRM_MIGRATE=y +CONFIG_XFRM_STATISTICS=y +CONFIG_XFRM_AH=m +CONFIG_XFRM_ESP=m +CONFIG_XFRM_IPCOMP=m +CONFIG_NET_KEY=m +CONFIG_NET_KEY_MIGRATE=y +CONFIG_XDP_SOCKETS=y +# CONFIG_XDP_SOCKETS_DIAG is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_IP_FIB_TRIE_STATS=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_ROUTE_MULTIPATH=y +CONFIG_IP_ROUTE_VERBOSE=y +CONFIG_IP_ROUTE_CLASSID=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +CONFIG_IP_PNP_RARP=y +CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE_DEMUX=m +CONFIG_NET_IP_TUNNEL=m +CONFIG_NET_IPGRE=m +CONFIG_NET_IPGRE_BROADCAST=y +CONFIG_IP_MROUTE_COMMON=y +CONFIG_IP_MROUTE=y +CONFIG_IP_MROUTE_MULTIPLE_TABLES=y +CONFIG_IP_PIMSM_V1=y +CONFIG_IP_PIMSM_V2=y +CONFIG_SYN_COOKIES=y +CONFIG_NET_IPVTI=m +CONFIG_NET_UDP_TUNNEL=m +CONFIG_NET_FOU=m +CONFIG_NET_FOU_IP_TUNNELS=y +CONFIG_INET_AH=m +CONFIG_INET_ESP=m +CONFIG_INET_ESP_OFFLOAD=m +# CONFIG_INET_ESPINTCP is not set +CONFIG_INET_IPCOMP=m +CONFIG_INET_XFRM_TUNNEL=m +CONFIG_INET_TUNNEL=m +CONFIG_INET_DIAG=m +CONFIG_INET_TCP_DIAG=m +CONFIG_INET_UDP_DIAG=m +CONFIG_INET_RAW_DIAG=m +CONFIG_INET_DIAG_DESTROY=y +CONFIG_TCP_CONG_ADVANCED=y +CONFIG_TCP_CONG_BIC=m +CONFIG_TCP_CONG_CUBIC=y +CONFIG_TCP_CONG_WESTWOOD=m +CONFIG_TCP_CONG_HTCP=m +CONFIG_TCP_CONG_HSTCP=m +CONFIG_TCP_CONG_HYBLA=m +CONFIG_TCP_CONG_VEGAS=m +CONFIG_TCP_CONG_NV=m +CONFIG_TCP_CONG_SCALABLE=m +CONFIG_TCP_CONG_LP=m +CONFIG_TCP_CONG_VENO=m +CONFIG_TCP_CONG_YEAH=m +CONFIG_TCP_CONG_ILLINOIS=m +CONFIG_TCP_CONG_DCTCP=m +CONFIG_TCP_CONG_CDG=m +CONFIG_TCP_CONG_BBR=m +# CONFIG_DEFAULT_CUBIC is not set +CONFIG_DEFAULT_RENO=y +CONFIG_DEFAULT_TCP_CONG="reno" +CONFIG_TCP_MD5SIG=y +CONFIG_IPV6=y +CONFIG_IPV6_ROUTER_PREF=y +CONFIG_IPV6_ROUTE_INFO=y +CONFIG_IPV6_OPTIMISTIC_DAD=y +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m +CONFIG_INET6_ESP_OFFLOAD=m +# CONFIG_INET6_ESPINTCP is not set +CONFIG_INET6_IPCOMP=m +CONFIG_IPV6_MIP6=m +CONFIG_IPV6_ILA=m +CONFIG_INET6_XFRM_TUNNEL=m +CONFIG_INET6_TUNNEL=m +CONFIG_IPV6_VTI=m +CONFIG_IPV6_SIT=m +CONFIG_IPV6_SIT_6RD=y +CONFIG_IPV6_NDISC_NODETYPE=y +CONFIG_IPV6_TUNNEL=m +CONFIG_IPV6_GRE=m +CONFIG_IPV6_FOU=m +CONFIG_IPV6_FOU_TUNNEL=m +CONFIG_IPV6_MULTIPLE_TABLES=y +CONFIG_IPV6_SUBTREES=y +CONFIG_IPV6_MROUTE=y +CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y +CONFIG_IPV6_PIMSM_V2=y +CONFIG_IPV6_SEG6_LWTUNNEL=y +CONFIG_IPV6_SEG6_HMAC=y +CONFIG_IPV6_SEG6_BPF=y +# CONFIG_IPV6_RPL_LWTUNNEL is not set +# CONFIG_IPV6_IOAM6_LWTUNNEL is not set +CONFIG_NETLABEL=y +# CONFIG_MPTCP is not set +CONFIG_NETWORK_SECMARK=y +CONFIG_NET_PTP_CLASSIFY=y +CONFIG_NETWORK_PHY_TIMESTAMPING=y +CONFIG_NETFILTER=y +CONFIG_NETFILTER_ADVANCED=y +CONFIG_BRIDGE_NETFILTER=m + +# +# Core Netfilter Configuration +# +CONFIG_NETFILTER_INGRESS=y +CONFIG_NETFILTER_EGRESS=y +CONFIG_NETFILTER_SKIP_EGRESS=y +CONFIG_NETFILTER_NETLINK=m +CONFIG_NETFILTER_FAMILY_BRIDGE=y +CONFIG_NETFILTER_FAMILY_ARP=y +CONFIG_NETFILTER_NETLINK_HOOK=m +CONFIG_NETFILTER_NETLINK_ACCT=m +CONFIG_NETFILTER_NETLINK_QUEUE=m +CONFIG_NETFILTER_NETLINK_LOG=m +CONFIG_NETFILTER_NETLINK_OSF=m +CONFIG_NF_CONNTRACK=m +CONFIG_NF_LOG_SYSLOG=m +CONFIG_NETFILTER_CONNCOUNT=m +CONFIG_NF_CONNTRACK_MARK=y +CONFIG_NF_CONNTRACK_SECMARK=y +CONFIG_NF_CONNTRACK_ZONES=y +# CONFIG_NF_CONNTRACK_PROCFS is not set +CONFIG_NF_CONNTRACK_EVENTS=y +CONFIG_NF_CONNTRACK_TIMEOUT=y +CONFIG_NF_CONNTRACK_TIMESTAMP=y +CONFIG_NF_CONNTRACK_LABELS=y +CONFIG_NF_CT_PROTO_DCCP=y +CONFIG_NF_CT_PROTO_GRE=y +CONFIG_NF_CT_PROTO_SCTP=y +CONFIG_NF_CT_PROTO_UDPLITE=y +CONFIG_NF_CONNTRACK_AMANDA=m +CONFIG_NF_CONNTRACK_FTP=m +CONFIG_NF_CONNTRACK_H323=m +CONFIG_NF_CONNTRACK_IRC=m +CONFIG_NF_CONNTRACK_BROADCAST=m +CONFIG_NF_CONNTRACK_NETBIOS_NS=m +CONFIG_NF_CONNTRACK_SNMP=m +CONFIG_NF_CONNTRACK_PPTP=m +CONFIG_NF_CONNTRACK_SANE=m +CONFIG_NF_CONNTRACK_SIP=m +CONFIG_NF_CONNTRACK_TFTP=m +CONFIG_NF_CT_NETLINK=m +CONFIG_NF_CT_NETLINK_TIMEOUT=m +CONFIG_NF_CT_NETLINK_HELPER=m +CONFIG_NETFILTER_NETLINK_GLUE_CT=y +CONFIG_NF_NAT=m +CONFIG_NF_NAT_AMANDA=m +CONFIG_NF_NAT_FTP=m +CONFIG_NF_NAT_IRC=m +CONFIG_NF_NAT_SIP=m +CONFIG_NF_NAT_TFTP=m +CONFIG_NF_NAT_REDIRECT=y +CONFIG_NF_NAT_MASQUERADE=y +CONFIG_NETFILTER_SYNPROXY=m +CONFIG_NF_TABLES=m +CONFIG_NF_TABLES_INET=y +CONFIG_NF_TABLES_NETDEV=y +CONFIG_NFT_NUMGEN=m +CONFIG_NFT_CT=m +CONFIG_NFT_FLOW_OFFLOAD=m +CONFIG_NFT_COUNTER=m +CONFIG_NFT_CONNLIMIT=m +CONFIG_NFT_LOG=m +CONFIG_NFT_LIMIT=m +CONFIG_NFT_MASQ=m +CONFIG_NFT_REDIR=m +CONFIG_NFT_NAT=m +CONFIG_NFT_TUNNEL=m +CONFIG_NFT_OBJREF=m +CONFIG_NFT_QUEUE=m +CONFIG_NFT_QUOTA=m +CONFIG_NFT_REJECT=m +CONFIG_NFT_REJECT_INET=m +CONFIG_NFT_COMPAT=m +CONFIG_NFT_HASH=m +CONFIG_NFT_FIB=m +CONFIG_NFT_FIB_INET=m +CONFIG_NFT_XFRM=m +CONFIG_NFT_SOCKET=m +CONFIG_NFT_OSF=m +CONFIG_NFT_TPROXY=m +CONFIG_NFT_SYNPROXY=m +CONFIG_NF_DUP_NETDEV=m +CONFIG_NFT_DUP_NETDEV=m +CONFIG_NFT_FWD_NETDEV=m +CONFIG_NFT_FIB_NETDEV=m +CONFIG_NFT_REJECT_NETDEV=m +CONFIG_NF_FLOW_TABLE_INET=m +CONFIG_NF_FLOW_TABLE=m +CONFIG_NETFILTER_XTABLES=m +CONFIG_NETFILTER_XTABLES_COMPAT=y + +# +# Xtables combined modules +# +CONFIG_NETFILTER_XT_MARK=m +CONFIG_NETFILTER_XT_CONNMARK=m +CONFIG_NETFILTER_XT_SET=m + +# +# Xtables targets +# +CONFIG_NETFILTER_XT_TARGET_AUDIT=m +CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +CONFIG_NETFILTER_XT_TARGET_CONNMARK=m +CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m +CONFIG_NETFILTER_XT_TARGET_CT=m +CONFIG_NETFILTER_XT_TARGET_DSCP=m +CONFIG_NETFILTER_XT_TARGET_HL=m +CONFIG_NETFILTER_XT_TARGET_HMARK=m +CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m +CONFIG_NETFILTER_XT_TARGET_LED=m +CONFIG_NETFILTER_XT_TARGET_LOG=m +CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_NAT=m +CONFIG_NETFILTER_XT_TARGET_NETMAP=m +CONFIG_NETFILTER_XT_TARGET_NFLOG=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +CONFIG_NETFILTER_XT_TARGET_NOTRACK=m +CONFIG_NETFILTER_XT_TARGET_RATEEST=m +CONFIG_NETFILTER_XT_TARGET_REDIRECT=m +CONFIG_NETFILTER_XT_TARGET_MASQUERADE=m +CONFIG_NETFILTER_XT_TARGET_TEE=m +CONFIG_NETFILTER_XT_TARGET_TPROXY=m +CONFIG_NETFILTER_XT_TARGET_TRACE=m +CONFIG_NETFILTER_XT_TARGET_SECMARK=m +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m + +# +# Xtables matches +# +CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m +CONFIG_NETFILTER_XT_MATCH_BPF=m +CONFIG_NETFILTER_XT_MATCH_CGROUP=m +CONFIG_NETFILTER_XT_MATCH_CLUSTER=m +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m +CONFIG_NETFILTER_XT_MATCH_CONNMARK=m +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_CPU=m +CONFIG_NETFILTER_XT_MATCH_DCCP=m +CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m +CONFIG_NETFILTER_XT_MATCH_DSCP=m +CONFIG_NETFILTER_XT_MATCH_ECN=m +CONFIG_NETFILTER_XT_MATCH_ESP=m +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m +CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_HL=m +CONFIG_NETFILTER_XT_MATCH_IPCOMP=m +CONFIG_NETFILTER_XT_MATCH_IPRANGE=m +CONFIG_NETFILTER_XT_MATCH_IPVS=m +CONFIG_NETFILTER_XT_MATCH_L2TP=m +CONFIG_NETFILTER_XT_MATCH_LENGTH=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_NETFILTER_XT_MATCH_MAC=m +CONFIG_NETFILTER_XT_MATCH_MARK=m +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_NFACCT=m +CONFIG_NETFILTER_XT_MATCH_OSF=m +CONFIG_NETFILTER_XT_MATCH_OWNER=m +CONFIG_NETFILTER_XT_MATCH_POLICY=m +CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +CONFIG_NETFILTER_XT_MATCH_QUOTA=m +CONFIG_NETFILTER_XT_MATCH_RATEEST=m +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_NETFILTER_XT_MATCH_RECENT=m +CONFIG_NETFILTER_XT_MATCH_SCTP=m +CONFIG_NETFILTER_XT_MATCH_SOCKET=m +CONFIG_NETFILTER_XT_MATCH_STATE=m +CONFIG_NETFILTER_XT_MATCH_STATISTIC=m +CONFIG_NETFILTER_XT_MATCH_STRING=m +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m +CONFIG_NETFILTER_XT_MATCH_TIME=m +CONFIG_NETFILTER_XT_MATCH_U32=m +# end of Core Netfilter Configuration + +CONFIG_IP_SET=m +CONFIG_IP_SET_MAX=256 +CONFIG_IP_SET_BITMAP_IP=m +CONFIG_IP_SET_BITMAP_IPMAC=m +CONFIG_IP_SET_BITMAP_PORT=m +CONFIG_IP_SET_HASH_IP=m +CONFIG_IP_SET_HASH_IPMARK=m +CONFIG_IP_SET_HASH_IPPORT=m +CONFIG_IP_SET_HASH_IPPORTIP=m +CONFIG_IP_SET_HASH_IPPORTNET=m +CONFIG_IP_SET_HASH_IPMAC=m +CONFIG_IP_SET_HASH_MAC=m +CONFIG_IP_SET_HASH_NETPORTNET=m +CONFIG_IP_SET_HASH_NET=m +CONFIG_IP_SET_HASH_NETNET=m +CONFIG_IP_SET_HASH_NETPORT=m +CONFIG_IP_SET_HASH_NETIFACE=m +CONFIG_IP_SET_LIST_SET=m +CONFIG_IP_VS=m +CONFIG_IP_VS_IPV6=y +# CONFIG_IP_VS_DEBUG is not set +CONFIG_IP_VS_TAB_BITS=12 + +# +# IPVS transport protocol load balancing support +# +CONFIG_IP_VS_PROTO_TCP=y +CONFIG_IP_VS_PROTO_UDP=y +CONFIG_IP_VS_PROTO_AH_ESP=y +CONFIG_IP_VS_PROTO_ESP=y +CONFIG_IP_VS_PROTO_AH=y +CONFIG_IP_VS_PROTO_SCTP=y + +# +# IPVS scheduler +# +CONFIG_IP_VS_RR=m +CONFIG_IP_VS_WRR=m +CONFIG_IP_VS_LC=m +CONFIG_IP_VS_WLC=m +CONFIG_IP_VS_FO=m +CONFIG_IP_VS_OVF=m +CONFIG_IP_VS_LBLC=m +CONFIG_IP_VS_LBLCR=m +CONFIG_IP_VS_DH=m +CONFIG_IP_VS_SH=m +CONFIG_IP_VS_MH=m +CONFIG_IP_VS_SED=m +CONFIG_IP_VS_NQ=m +CONFIG_IP_VS_TWOS=m + +# +# IPVS SH scheduler +# +CONFIG_IP_VS_SH_TAB_BITS=8 + +# +# IPVS MH scheduler +# +CONFIG_IP_VS_MH_TAB_INDEX=12 + +# +# IPVS application helper +# +CONFIG_IP_VS_FTP=m +CONFIG_IP_VS_NFCT=y +CONFIG_IP_VS_PE_SIP=m + +# +# IP: Netfilter Configuration +# +CONFIG_NF_DEFRAG_IPV4=m +CONFIG_NF_SOCKET_IPV4=m +CONFIG_NF_TPROXY_IPV4=m +CONFIG_NF_TABLES_IPV4=y +CONFIG_NFT_REJECT_IPV4=m +CONFIG_NFT_DUP_IPV4=m +CONFIG_NFT_FIB_IPV4=m +CONFIG_NF_TABLES_ARP=y +CONFIG_NF_FLOW_TABLE_IPV4=m +CONFIG_NF_DUP_IPV4=m +CONFIG_NF_LOG_ARP=m +CONFIG_NF_LOG_IPV4=m +CONFIG_NF_REJECT_IPV4=m +CONFIG_NF_NAT_SNMP_BASIC=m +CONFIG_NF_NAT_PPTP=m +CONFIG_NF_NAT_H323=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_AH=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_RPFILTER=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_SYNPROXY=m +CONFIG_IP_NF_NAT=m +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 +CONFIG_IP_NF_SECURITY=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARP_MANGLE=m +# end of IP: Netfilter Configuration + +# +# IPv6: Netfilter Configuration +# +CONFIG_NF_SOCKET_IPV6=m +CONFIG_NF_TPROXY_IPV6=m +CONFIG_NF_TABLES_IPV6=y +CONFIG_NFT_REJECT_IPV6=m +CONFIG_NFT_DUP_IPV6=m +CONFIG_NFT_FIB_IPV6=m +CONFIG_NF_FLOW_TABLE_IPV6=m +CONFIG_NF_DUP_IPV6=m +CONFIG_NF_REJECT_IPV6=m +CONFIG_NF_LOG_IPV6=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MATCH_AH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_MATCH_MH=m +CONFIG_IP6_NF_MATCH_RPFILTER=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_MATCH_SRH=m +CONFIG_IP6_NF_TARGET_HL=m +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_TARGET_REJECT=m +CONFIG_IP6_NF_TARGET_SYNPROXY=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_RAW=m +CONFIG_IP6_NF_SECURITY=m +CONFIG_IP6_NF_NAT=m +CONFIG_IP6_NF_TARGET_MASQUERADE=m +CONFIG_IP6_NF_TARGET_NPT=m +# end of IPv6: Netfilter Configuration + +CONFIG_NF_DEFRAG_IPV6=m + +# +# DECnet: Netfilter Configuration +# +CONFIG_DECNET_NF_GRABULATOR=m +# end of DECnet: Netfilter Configuration + +CONFIG_NF_TABLES_BRIDGE=m +CONFIG_NFT_BRIDGE_META=m +CONFIG_NFT_BRIDGE_REJECT=m +CONFIG_NF_CONNTRACK_BRIDGE=m +CONFIG_BRIDGE_NF_EBTABLES=m +CONFIG_BRIDGE_EBT_BROUTE=m +CONFIG_BRIDGE_EBT_T_FILTER=m +CONFIG_BRIDGE_EBT_T_NAT=m +CONFIG_BRIDGE_EBT_802_3=m +CONFIG_BRIDGE_EBT_AMONG=m +CONFIG_BRIDGE_EBT_ARP=m +CONFIG_BRIDGE_EBT_IP=m +CONFIG_BRIDGE_EBT_IP6=m +CONFIG_BRIDGE_EBT_LIMIT=m +CONFIG_BRIDGE_EBT_MARK=m +CONFIG_BRIDGE_EBT_PKTTYPE=m +CONFIG_BRIDGE_EBT_STP=m +CONFIG_BRIDGE_EBT_VLAN=m +CONFIG_BRIDGE_EBT_ARPREPLY=m +CONFIG_BRIDGE_EBT_DNAT=m +CONFIG_BRIDGE_EBT_MARK_T=m +CONFIG_BRIDGE_EBT_REDIRECT=m +CONFIG_BRIDGE_EBT_SNAT=m +CONFIG_BRIDGE_EBT_LOG=m +CONFIG_BRIDGE_EBT_NFLOG=m +CONFIG_BPFILTER=y +CONFIG_BPFILTER_UMH=m +# CONFIG_IP_DCCP is not set +CONFIG_IP_SCTP=m +CONFIG_SCTP_DBG_OBJCNT=y +CONFIG_SCTP_DEFAULT_COOKIE_HMAC_MD5=y +# CONFIG_SCTP_DEFAULT_COOKIE_HMAC_SHA1 is not set +# CONFIG_SCTP_DEFAULT_COOKIE_HMAC_NONE is not set +CONFIG_SCTP_COOKIE_HMAC_MD5=y +CONFIG_SCTP_COOKIE_HMAC_SHA1=y +CONFIG_INET_SCTP_DIAG=m +CONFIG_RDS=m +CONFIG_RDS_TCP=m +# CONFIG_RDS_DEBUG is not set +CONFIG_TIPC=m +CONFIG_TIPC_MEDIA_UDP=y +CONFIG_TIPC_CRYPTO=y +CONFIG_TIPC_DIAG=m +CONFIG_ATM=m +CONFIG_ATM_CLIP=m +CONFIG_ATM_CLIP_NO_ICMP=y +CONFIG_ATM_LANE=m +CONFIG_ATM_MPOA=m +CONFIG_ATM_BR2684=m +CONFIG_ATM_BR2684_IPFILTER=y +CONFIG_L2TP=m +CONFIG_L2TP_DEBUGFS=m +CONFIG_L2TP_V3=y +CONFIG_L2TP_IP=m +CONFIG_L2TP_ETH=m +CONFIG_STP=y +CONFIG_GARP=y +CONFIG_MRP=y +CONFIG_BRIDGE=m +CONFIG_BRIDGE_IGMP_SNOOPING=y +CONFIG_BRIDGE_VLAN_FILTERING=y +# CONFIG_BRIDGE_MRP is not set +# CONFIG_BRIDGE_CFM is not set +CONFIG_NET_DSA=m +CONFIG_NET_DSA_TAG_AR9331=m +CONFIG_NET_DSA_TAG_BRCM_COMMON=m +CONFIG_NET_DSA_TAG_BRCM=m +CONFIG_NET_DSA_TAG_BRCM_LEGACY=m +CONFIG_NET_DSA_TAG_BRCM_PREPEND=m +CONFIG_NET_DSA_TAG_HELLCREEK=m +CONFIG_NET_DSA_TAG_GSWIP=m +CONFIG_NET_DSA_TAG_DSA_COMMON=m +CONFIG_NET_DSA_TAG_DSA=m +CONFIG_NET_DSA_TAG_EDSA=m +CONFIG_NET_DSA_TAG_MTK=m +CONFIG_NET_DSA_TAG_KSZ=m +CONFIG_NET_DSA_TAG_OCELOT=m +CONFIG_NET_DSA_TAG_OCELOT_8021Q=m +CONFIG_NET_DSA_TAG_QCA=m +CONFIG_NET_DSA_TAG_RTL4_A=m +CONFIG_NET_DSA_TAG_RTL8_4=m +CONFIG_NET_DSA_TAG_LAN9303=m +CONFIG_NET_DSA_TAG_SJA1105=m +CONFIG_NET_DSA_TAG_TRAILER=m +CONFIG_NET_DSA_TAG_XRS700X=m +CONFIG_VLAN_8021Q=y +CONFIG_VLAN_8021Q_GVRP=y +CONFIG_VLAN_8021Q_MVRP=y +CONFIG_DECNET=m +CONFIG_DECNET_ROUTER=y +CONFIG_LLC=y +CONFIG_LLC2=m +CONFIG_ATALK=m +CONFIG_DEV_APPLETALK=m +CONFIG_IPDDP=m +CONFIG_IPDDP_ENCAP=y +CONFIG_X25=m +CONFIG_LAPB=m +CONFIG_PHONET=m +CONFIG_6LOWPAN=m +# CONFIG_6LOWPAN_DEBUGFS is not set +CONFIG_6LOWPAN_NHC=m +CONFIG_6LOWPAN_NHC_DEST=m +CONFIG_6LOWPAN_NHC_FRAGMENT=m +CONFIG_6LOWPAN_NHC_HOP=m +CONFIG_6LOWPAN_NHC_IPV6=m +CONFIG_6LOWPAN_NHC_MOBILITY=m +CONFIG_6LOWPAN_NHC_ROUTING=m +CONFIG_6LOWPAN_NHC_UDP=m +# CONFIG_6LOWPAN_GHC_EXT_HDR_HOP is not set +# CONFIG_6LOWPAN_GHC_UDP is not set +# CONFIG_6LOWPAN_GHC_ICMPV6 is not set +# CONFIG_6LOWPAN_GHC_EXT_HDR_DEST is not set +# CONFIG_6LOWPAN_GHC_EXT_HDR_FRAG is not set +# CONFIG_6LOWPAN_GHC_EXT_HDR_ROUTE is not set +CONFIG_IEEE802154=m +CONFIG_IEEE802154_NL802154_EXPERIMENTAL=y +CONFIG_IEEE802154_SOCKET=m +CONFIG_IEEE802154_6LOWPAN=m +CONFIG_MAC802154=m +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 +CONFIG_NET_SCH_SFB=m +CONFIG_NET_SCH_SFQ=m +CONFIG_NET_SCH_TEQL=m +CONFIG_NET_SCH_TBF=m +CONFIG_NET_SCH_CBS=m +CONFIG_NET_SCH_ETF=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 +CONFIG_NET_SCH_SKBPRIO=m +CONFIG_NET_SCH_CHOKE=m +CONFIG_NET_SCH_QFQ=m +CONFIG_NET_SCH_CODEL=m +CONFIG_NET_SCH_FQ_CODEL=m +CONFIG_NET_SCH_CAKE=m +CONFIG_NET_SCH_FQ=m +CONFIG_NET_SCH_HHF=m +CONFIG_NET_SCH_PIE=m +CONFIG_NET_SCH_FQ_PIE=m +CONFIG_NET_SCH_INGRESS=m +CONFIG_NET_SCH_PLUG=m +CONFIG_NET_SCH_ETS=m +CONFIG_NET_SCH_DEFAULT=y +# CONFIG_DEFAULT_FQ is not set +# CONFIG_DEFAULT_CODEL is not set +# CONFIG_DEFAULT_FQ_CODEL is not set +# CONFIG_DEFAULT_FQ_PIE is not set +# CONFIG_DEFAULT_SFQ is not set +CONFIG_DEFAULT_PFIFO_FAST=y +CONFIG_DEFAULT_NET_SCH="pfifo_fast" + +# +# Classification +# +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 +CONFIG_NET_CLS_FLOWER=m +CONFIG_NET_CLS_MATCHALL=m +CONFIG_NET_EMATCH=y +CONFIG_NET_EMATCH_STACK=32 +CONFIG_NET_EMATCH_CMP=m +CONFIG_NET_EMATCH_NBYTE=m +CONFIG_NET_EMATCH_U32=m +CONFIG_NET_EMATCH_META=m +CONFIG_NET_EMATCH_TEXT=m +CONFIG_NET_EMATCH_CANID=m +CONFIG_NET_EMATCH_IPSET=m +CONFIG_NET_EMATCH_IPT=m +CONFIG_NET_CLS_ACT=y +CONFIG_NET_ACT_POLICE=m +CONFIG_NET_ACT_GACT=m +CONFIG_GACT_PROB=y +CONFIG_NET_ACT_MIRRED=m +CONFIG_NET_ACT_SAMPLE=m +CONFIG_NET_ACT_IPT=m +CONFIG_NET_ACT_NAT=m +CONFIG_NET_ACT_PEDIT=m +CONFIG_NET_ACT_SIMP=m +CONFIG_NET_ACT_SKBEDIT=m +CONFIG_NET_ACT_CSUM=m +CONFIG_NET_ACT_MPLS=m +CONFIG_NET_ACT_VLAN=m +CONFIG_NET_ACT_BPF=m +CONFIG_NET_ACT_CONNMARK=m +CONFIG_NET_ACT_CTINFO=m +CONFIG_NET_ACT_SKBMOD=m +CONFIG_NET_ACT_IFE=m +CONFIG_NET_ACT_TUNNEL_KEY=m +CONFIG_NET_ACT_CT=m +# CONFIG_NET_ACT_GATE is not set +CONFIG_NET_IFE_SKBMARK=m +CONFIG_NET_IFE_SKBPRIO=m +CONFIG_NET_IFE_SKBTCINDEX=m +# CONFIG_NET_TC_SKB_EXT is not set +CONFIG_NET_SCH_FIFO=y +CONFIG_DCB=y +CONFIG_DNS_RESOLVER=y +CONFIG_BATMAN_ADV=m +CONFIG_BATMAN_ADV_BATMAN_V=y +CONFIG_BATMAN_ADV_BLA=y +CONFIG_BATMAN_ADV_DAT=y +CONFIG_BATMAN_ADV_NC=y +CONFIG_BATMAN_ADV_MCAST=y +CONFIG_BATMAN_ADV_DEBUG=y +# CONFIG_BATMAN_ADV_TRACING is not set +CONFIG_OPENVSWITCH=m +CONFIG_OPENVSWITCH_GRE=m +CONFIG_OPENVSWITCH_VXLAN=m +CONFIG_OPENVSWITCH_GENEVE=m +CONFIG_VSOCKETS=m +CONFIG_VSOCKETS_DIAG=m +CONFIG_VSOCKETS_LOOPBACK=m +CONFIG_VIRTIO_VSOCKETS=m +CONFIG_VIRTIO_VSOCKETS_COMMON=m +CONFIG_NETLINK_DIAG=m +CONFIG_MPLS=y +CONFIG_NET_MPLS_GSO=m +CONFIG_MPLS_ROUTING=m +CONFIG_MPLS_IPTUNNEL=m +CONFIG_NET_NSH=m +CONFIG_HSR=m +CONFIG_NET_SWITCHDEV=y +CONFIG_NET_L3_MASTER_DEV=y +# CONFIG_QRTR is not set +# CONFIG_NET_NCSI is not set +CONFIG_PCPU_DEV_REFCNT=y +CONFIG_RPS=y +CONFIG_RFS_ACCEL=y +CONFIG_SOCK_RX_QUEUE_MAPPING=y +CONFIG_XPS=y +CONFIG_CGROUP_NET_PRIO=y +CONFIG_CGROUP_NET_CLASSID=y +CONFIG_NET_RX_BUSY_POLL=y +CONFIG_BQL=y +# CONFIG_BPF_STREAM_PARSER is not set +CONFIG_NET_FLOW_LIMIT=y + +# +# Network testing +# +CONFIG_NET_PKTGEN=m +CONFIG_NET_DROP_MONITOR=y +# end of Network testing +# end of Networking options + +CONFIG_HAMRADIO=y + +# +# Packet Radio protocols +# +CONFIG_AX25=m +CONFIG_AX25_DAMA_SLAVE=y +CONFIG_NETROM=m +CONFIG_ROSE=m + +# +# AX.25 network device drivers +# +CONFIG_MKISS=m +CONFIG_6PACK=m +CONFIG_BPQETHER=m +CONFIG_BAYCOM_SER_FDX=m +CONFIG_BAYCOM_SER_HDX=m +CONFIG_YAM=m +# end of AX.25 network device drivers + +CONFIG_CAN=m +CONFIG_CAN_RAW=m +CONFIG_CAN_BCM=m +CONFIG_CAN_GW=m +CONFIG_CAN_J1939=m +# CONFIG_CAN_ISOTP is not set + +# +# CAN Device Drivers +# +CONFIG_CAN_VCAN=m +CONFIG_CAN_VXCAN=m +CONFIG_CAN_SLCAN=m +CONFIG_CAN_DEV=m +CONFIG_CAN_CALC_BITTIMING=y +# CONFIG_CAN_FLEXCAN is not set +CONFIG_CAN_GRCAN=m +CONFIG_CAN_KVASER_PCIEFD=m +CONFIG_CAN_XILINXCAN=m +CONFIG_CAN_C_CAN=m +CONFIG_CAN_C_CAN_PLATFORM=m +CONFIG_CAN_C_CAN_PCI=m +CONFIG_CAN_CC770=m +CONFIG_CAN_CC770_ISA=m +CONFIG_CAN_CC770_PLATFORM=m +# CONFIG_CAN_IFI_CANFD is not set +CONFIG_CAN_M_CAN=m +CONFIG_CAN_M_CAN_PCI=m +CONFIG_CAN_M_CAN_PLATFORM=m +CONFIG_CAN_M_CAN_TCAN4X5X=m +CONFIG_CAN_PEAK_PCIEFD=m +CONFIG_CAN_SJA1000=m +CONFIG_CAN_EMS_PCI=m +CONFIG_CAN_F81601=m +CONFIG_CAN_KVASER_PCI=m +CONFIG_CAN_PEAK_PCI=m +CONFIG_CAN_PEAK_PCIEC=y +CONFIG_CAN_PLX_PCI=m +CONFIG_CAN_SJA1000_ISA=m +CONFIG_CAN_SJA1000_PLATFORM=m +CONFIG_CAN_SOFTING=m + +# +# CAN SPI interfaces +# +CONFIG_CAN_HI311X=m +CONFIG_CAN_MCP251X=m +# CONFIG_CAN_MCP251XFD is not set +# end of CAN SPI interfaces + +# +# CAN USB interfaces +# +CONFIG_CAN_8DEV_USB=m +CONFIG_CAN_EMS_USB=m +CONFIG_CAN_ESD_USB2=m +CONFIG_CAN_ETAS_ES58X=m +CONFIG_CAN_GS_USB=m +CONFIG_CAN_KVASER_USB=m +CONFIG_CAN_MCBA_USB=m +CONFIG_CAN_PEAK_USB=m +CONFIG_CAN_UCAN=m +# end of CAN USB interfaces + +# CONFIG_CAN_DEBUG_DEVICES is not set +# end of CAN Device Drivers + +CONFIG_BT=m +CONFIG_BT_BREDR=y +CONFIG_BT_RFCOMM=m +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_BNEP=m +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_HIDP=m +CONFIG_BT_HS=y +CONFIG_BT_LE=y +CONFIG_BT_6LOWPAN=m +CONFIG_BT_LEDS=y +# CONFIG_BT_MSFTEXT is not set +# CONFIG_BT_AOSPEXT is not set +# CONFIG_BT_DEBUGFS is not set +# CONFIG_BT_SELFTEST is not set + +# +# Bluetooth device drivers +# +CONFIG_BT_INTEL=m +CONFIG_BT_BCM=m +CONFIG_BT_RTL=m +CONFIG_BT_QCA=m +CONFIG_BT_HCIBTUSB=m +# CONFIG_BT_HCIBTUSB_AUTOSUSPEND is not set +CONFIG_BT_HCIBTUSB_BCM=y +CONFIG_BT_HCIBTUSB_MTK=y +CONFIG_BT_HCIBTUSB_RTL=y +CONFIG_BT_HCIBTSDIO=m +CONFIG_BT_HCIUART=m +CONFIG_BT_HCIUART_SERDEV=y +CONFIG_BT_HCIUART_H4=y +CONFIG_BT_HCIUART_NOKIA=m +CONFIG_BT_HCIUART_BCSP=y +CONFIG_BT_HCIUART_ATH3K=y +CONFIG_BT_HCIUART_LL=y +CONFIG_BT_HCIUART_3WIRE=y +CONFIG_BT_HCIUART_INTEL=y +CONFIG_BT_HCIUART_BCM=y +CONFIG_BT_HCIUART_RTL=y +CONFIG_BT_HCIUART_QCA=y +CONFIG_BT_HCIUART_AG6XX=y +CONFIG_BT_HCIUART_MRVL=y +CONFIG_BT_HCIBCM203X=m +CONFIG_BT_HCIBPA10X=m +CONFIG_BT_HCIBFUSB=m +CONFIG_BT_HCIVHCI=m +CONFIG_BT_MRVL=m +CONFIG_BT_MRVL_SDIO=m +CONFIG_BT_ATH3K=m +CONFIG_BT_MTKSDIO=m +CONFIG_BT_MTKUART=m +CONFIG_BT_HCIRSI=m +CONFIG_BT_VIRTIO=m +# 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_DEBUG is not set +# CONFIG_RXKAD is not set +# CONFIG_AF_KCM is not set +CONFIG_STREAM_PARSER=y +# CONFIG_MCTP is not set +CONFIG_FIB_RULES=y +CONFIG_WIRELESS=y +CONFIG_WIRELESS_EXT=y +CONFIG_WEXT_CORE=y +CONFIG_WEXT_PROC=y +CONFIG_WEXT_SPY=y +CONFIG_WEXT_PRIV=y +CONFIG_CFG80211=m +# CONFIG_NL80211_TESTMODE is not set +# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set +# CONFIG_CFG80211_CERTIFICATION_ONUS is not set +CONFIG_CFG80211_REQUIRE_SIGNED_REGDB=y +CONFIG_CFG80211_USE_KERNEL_REGDB_KEYS=y +# CONFIG_CFG80211_DEFAULT_PS is not set +# CONFIG_CFG80211_DEBUGFS is not set +CONFIG_CFG80211_CRDA_SUPPORT=y +CONFIG_CFG80211_WEXT=y +CONFIG_LIB80211=m +CONFIG_LIB80211_CRYPT_WEP=m +CONFIG_LIB80211_CRYPT_CCMP=m +CONFIG_LIB80211_CRYPT_TKIP=m +# CONFIG_LIB80211_DEBUG is not set +CONFIG_MAC80211=m +CONFIG_MAC80211_HAS_RC=y +CONFIG_MAC80211_RC_MINSTREL=y +CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y +CONFIG_MAC80211_RC_DEFAULT="minstrel_ht" +CONFIG_MAC80211_MESH=y +CONFIG_MAC80211_LEDS=y +# CONFIG_MAC80211_DEBUGFS is not set +# CONFIG_MAC80211_MESSAGE_TRACING is not set +# CONFIG_MAC80211_DEBUG_MENU is not set +CONFIG_MAC80211_STA_HASH_MAX_SIZE=0 +CONFIG_RFKILL=m +CONFIG_RFKILL_LEDS=y +CONFIG_RFKILL_INPUT=y +CONFIG_RFKILL_GPIO=m +CONFIG_NET_9P=m +CONFIG_NET_9P_VIRTIO=m +CONFIG_NET_9P_XEN=m +# CONFIG_NET_9P_DEBUG is not set +# CONFIG_CAIF is not set +CONFIG_CEPH_LIB=m +# CONFIG_CEPH_LIB_PRETTYDEBUG is not set +CONFIG_CEPH_LIB_USE_DNS_RESOLVER=y +CONFIG_NFC=m +CONFIG_NFC_DIGITAL=m +CONFIG_NFC_NCI=m +CONFIG_NFC_NCI_SPI=m +CONFIG_NFC_NCI_UART=m +CONFIG_NFC_HCI=m +CONFIG_NFC_SHDLC=y + +# +# Near Field Communication (NFC) devices +# +CONFIG_NFC_TRF7970A=m +CONFIG_NFC_SIM=m +CONFIG_NFC_PORT100=m +CONFIG_NFC_VIRTUAL_NCI=m +CONFIG_NFC_FDP=m +CONFIG_NFC_FDP_I2C=m +CONFIG_NFC_PN544=m +CONFIG_NFC_PN544_I2C=m +CONFIG_NFC_PN533=m +CONFIG_NFC_PN533_USB=m +CONFIG_NFC_PN533_I2C=m +CONFIG_NFC_PN532_UART=m +CONFIG_NFC_MICROREAD=m +CONFIG_NFC_MICROREAD_I2C=m +CONFIG_NFC_MRVL=m +CONFIG_NFC_MRVL_USB=m +CONFIG_NFC_MRVL_UART=m +CONFIG_NFC_MRVL_I2C=m +CONFIG_NFC_MRVL_SPI=m +CONFIG_NFC_ST21NFCA=m +CONFIG_NFC_ST21NFCA_I2C=m +CONFIG_NFC_ST_NCI=m +CONFIG_NFC_ST_NCI_I2C=m +CONFIG_NFC_ST_NCI_SPI=m +CONFIG_NFC_NXP_NCI=m +CONFIG_NFC_NXP_NCI_I2C=m +CONFIG_NFC_S3FWRN5=m +CONFIG_NFC_S3FWRN5_I2C=m +CONFIG_NFC_S3FWRN82_UART=m +CONFIG_NFC_ST95HF=m +# end of Near Field Communication (NFC) devices + +CONFIG_PSAMPLE=m +CONFIG_NET_IFE=m +CONFIG_LWTUNNEL=y +CONFIG_LWTUNNEL_BPF=y +CONFIG_DST_CACHE=y +CONFIG_GRO_CELLS=y +CONFIG_SOCK_VALIDATE_XMIT=y +CONFIG_NET_SELFTESTS=y +CONFIG_NET_SOCK_MSG=y +CONFIG_NET_DEVLINK=y +CONFIG_PAGE_POOL=y +CONFIG_FAILOVER=m +CONFIG_ETHTOOL_NETLINK=y + +# +# Device Drivers +# +CONFIG_ARM_AMBA=y +CONFIG_HAVE_PCI=y +CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y +CONFIG_PCI_DOMAINS_GENERIC=y +CONFIG_PCI_SYSCALL=y +CONFIG_PCIEPORTBUS=y +# CONFIG_HOTPLUG_PCI_PCIE is not set +CONFIG_PCIEAER=y +# CONFIG_PCIEAER_INJECT is not set +# CONFIG_PCIE_ECRC is not set +CONFIG_PCIEASPM=y +# CONFIG_PCIEASPM_DEFAULT is not set +# CONFIG_PCIEASPM_POWERSAVE is not set +# CONFIG_PCIEASPM_POWER_SUPERSAVE is not set +CONFIG_PCIEASPM_PERFORMANCE=y +CONFIG_PCIE_PME=y +# CONFIG_PCIE_DPC is not set +# CONFIG_PCIE_PTM is not set +CONFIG_PCI_MSI=y +CONFIG_PCI_MSI_IRQ_DOMAIN=y +CONFIG_PCI_QUIRKS=y +# CONFIG_PCI_DEBUG is not set +# CONFIG_PCI_REALLOC_ENABLE_AUTO is not set +# CONFIG_PCI_STUB is not set +# CONFIG_PCI_PF_STUB is not set +CONFIG_PCI_ATS=y +CONFIG_PCI_IOV=y +# CONFIG_PCI_PRI is not set +# CONFIG_PCI_PASID is not set +CONFIG_PCI_LABEL=y +# CONFIG_PCIE_BUS_TUNE_OFF is not set +CONFIG_PCIE_BUS_DEFAULT=y +# CONFIG_PCIE_BUS_SAFE is not set +# CONFIG_PCIE_BUS_PERFORMANCE is not set +# CONFIG_PCIE_BUS_PEER2PEER is not set +CONFIG_HOTPLUG_PCI=y +# CONFIG_HOTPLUG_PCI_CPCI is not set +# CONFIG_HOTPLUG_PCI_SHPC is not set + +# +# PCI controller drivers +# +# CONFIG_PCI_FTPCI100 is not set +# CONFIG_PCI_HOST_GENERIC is not set +# CONFIG_PCIE_XILINX is not set +# CONFIG_PCI_XGENE is not set +# CONFIG_PCIE_ALTERA is not set +# CONFIG_PCI_HOST_THUNDER_PEM is not set +# CONFIG_PCI_HOST_THUNDER_ECAM is not set +CONFIG_PCIE_ROCKCHIP=y +CONFIG_PCIE_ROCKCHIP_HOST=y +CONFIG_PCIE_ROCKCHIP_EP=y +# CONFIG_PCIE_MICROCHIP_HOST is not set + +# +# DesignWare PCI Core Support +# +CONFIG_PCIE_DW=y +CONFIG_PCIE_DW_HOST=y +# CONFIG_PCIE_DW_PLAT_HOST is not set +# CONFIG_PCIE_DW_PLAT_EP is not set +# CONFIG_PCI_HISI is not set +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 +# +# 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 PCI controller drivers + +# +# PCI Endpoint +# +CONFIG_PCI_ENDPOINT=y +CONFIG_PCI_ENDPOINT_CONFIGFS=y +# CONFIG_PCI_EPF_TEST is not set +CONFIG_PCI_EPF_NTB=m +# end of PCI Endpoint + +# +# PCI switch controller drivers +# +# CONFIG_PCI_SW_SWITCHTEC is not set +# end of PCI switch controller drivers + +CONFIG_CXL_BUS=m +CONFIG_CXL_MEM=m +# CONFIG_CXL_MEM_RAW_COMMANDS is not set +# CONFIG_PCCARD is not set +# CONFIG_RAPIDIO is not set + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER=y +CONFIG_UEVENT_HELPER_PATH="" +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y + +# +# Firmware loader +# +CONFIG_FW_LOADER=y +CONFIG_EXTRA_FIRMWARE="" +# CONFIG_FW_LOADER_USER_HELPER is not set +# CONFIG_FW_LOADER_COMPRESS is not set +CONFIG_FW_CACHE=y +# end of Firmware loader + +CONFIG_WANT_DEV_COREDUMP=y +CONFIG_ALLOW_DEV_COREDUMP=y +CONFIG_DEV_COREDUMP=y +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_DEBUG_TEST_DRIVER_REMOVE is not set +# CONFIG_TEST_ASYNC_DRIVER_PROBE is not set +CONFIG_SYS_HYPERVISOR=y +CONFIG_GENERIC_CPU_AUTOPROBE=y +CONFIG_GENERIC_CPU_VULNERABILITIES=y +CONFIG_SOC_BUS=y +CONFIG_REGMAP=y +CONFIG_REGMAP_I2C=y +CONFIG_REGMAP_SPI=m +CONFIG_REGMAP_SPMI=m +CONFIG_REGMAP_W1=m +CONFIG_REGMAP_MMIO=y +CONFIG_REGMAP_IRQ=y +CONFIG_REGMAP_SCCB=m +CONFIG_DMA_SHARED_BUFFER=y +# CONFIG_DMA_FENCE_TRACE is not set +CONFIG_GENERIC_ARCH_TOPOLOGY=y +CONFIG_GENERIC_ARCH_NUMA=y +# end of Generic Driver Options + +# +# Bus devices +# +CONFIG_ARM_CCI=y +CONFIG_BRCMSTB_GISB_ARB=y +# CONFIG_MOXTET is not set +CONFIG_SUN50I_DE2_BUS=y +CONFIG_SUNXI_RSB=m +CONFIG_VEXPRESS_CONFIG=y +CONFIG_MHI_BUS=m +# CONFIG_MHI_BUS_DEBUG is not set +CONFIG_MHI_BUS_PCI_GENERIC=m +# end of Bus devices + +CONFIG_CONNECTOR=m + +# +# Firmware Drivers +# + +# +# ARM System Control and Management Interface Protocol +# +# CONFIG_ARM_SCMI_PROTOCOL is not set +# end of ARM System Control and Management Interface Protocol + +CONFIG_ARM_SCPI_PROTOCOL=y +CONFIG_ARM_SCPI_POWER_DOMAIN=y +# CONFIG_ARM_SDE_INTERFACE is not set +# CONFIG_FIRMWARE_MEMMAP is not set +CONFIG_DMIID=y +# CONFIG_DMI_SYSFS is not set +# CONFIG_FW_CFG_SYSFS is not set +CONFIG_SYSFB=y +# CONFIG_SYSFB_SIMPLEFB is not set +CONFIG_ARM_FFA_TRANSPORT=m +CONFIG_ARM_FFA_SMCCC=y +# CONFIG_GOOGLE_FIRMWARE is not set + +# +# EFI (Extensible Firmware Interface) Support +# +CONFIG_EFI_ESRT=y +CONFIG_EFI_VARS_PSTORE=y +# CONFIG_EFI_VARS_PSTORE_DEFAULT_DISABLE is not set +CONFIG_EFI_PARAMS_FROM_FDT=y +CONFIG_EFI_RUNTIME_WRAPPERS=y +CONFIG_EFI_GENERIC_STUB=y +CONFIG_EFI_ARMSTUB_DTB_LOADER=y +CONFIG_EFI_GENERIC_STUB_INITRD_CMDLINE_LOADER=y +# CONFIG_EFI_BOOTLOADER_CONTROL is not set +CONFIG_EFI_CAPSULE_LOADER=y +# CONFIG_EFI_TEST is not set +# CONFIG_RESET_ATTACK_MITIGATION is not set +# CONFIG_EFI_DISABLE_PCI_DMA is not set +# end of EFI (Extensible Firmware Interface) Support + +CONFIG_EFI_EARLYCON=y +CONFIG_MESON_SM=y +CONFIG_ARM_PSCI_FW=y +# CONFIG_ARM_PSCI_CHECKER is not set +CONFIG_HAVE_ARM_SMCCC=y +CONFIG_HAVE_ARM_SMCCC_DISCOVERY=y +CONFIG_ARM_SMCCC_SOC_ID=y + +# +# Tegra firmware driver +# +# end of Tegra firmware driver +# end of Firmware Drivers + +CONFIG_GNSS=m +CONFIG_GNSS_SERIAL=m +CONFIG_GNSS_MTK_SERIAL=m +CONFIG_GNSS_SIRF_SERIAL=m +CONFIG_GNSS_UBX_SERIAL=m +CONFIG_MTD=y +# CONFIG_MTD_TESTS is not set + +# +# Partition parsers +# +# CONFIG_MTD_AR7_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set +CONFIG_MTD_OF_PARTS=y +# CONFIG_MTD_AFS_PARTS is not set +# CONFIG_MTD_REDBOOT_PARTS is not set +# end of Partition parsers + +# +# User Modules And Translation Layers +# +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y + +# +# Note that in some cases UBI block is preferred. See MTD_UBI_BLOCK. +# +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set +# CONFIG_SM_FTL is not set +# CONFIG_MTD_OOPS is not set +CONFIG_MTD_PSTORE=m +# CONFIG_MTD_SWAP is not set +# CONFIG_MTD_PARTITIONED_MASTER is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=m +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=m +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_INTELEXT is not set +CONFIG_MTD_CFI_AMDSTD=m +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=m +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# end of RAM/ROM/Flash chip drivers + +# +# Mapping drivers for chip access +# +CONFIG_MTD_COMPLEX_MAPPINGS=y +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_PCI is not set +# CONFIG_MTD_INTEL_VR_NOR is not set +# CONFIG_MTD_PLATRAM is not set +# end of Mapping drivers for chip access + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_DATAFLASH is not set +# CONFIG_MTD_MCHP23K256 is not set +# CONFIG_MTD_MCHP48L640 is not set +# CONFIG_MTD_SST25L is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOCG3 is not set +# end of Self-contained MTD device drivers + +# +# NAND +# +# CONFIG_MTD_ONENAND is not set +# CONFIG_MTD_RAW_NAND is not set +# CONFIG_MTD_SPI_NAND is not set + +# +# ECC engine support +# +# CONFIG_MTD_NAND_ECC_SW_HAMMING is not set +# CONFIG_MTD_NAND_ECC_SW_BCH is not set +# end of ECC engine support +# end of NAND + +# +# LPDDR & LPDDR2 PCM memory drivers +# +# CONFIG_MTD_LPDDR is not set +# end of LPDDR & LPDDR2 PCM memory drivers + +CONFIG_MTD_SPI_NOR=y +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 is not set +CONFIG_MTD_HYPERBUS=m +CONFIG_HBMC_AM654=m +CONFIG_DTC=y +CONFIG_OF=y +# CONFIG_OF_UNITTEST is not set +CONFIG_OF_FLATTREE=y +CONFIG_OF_EARLY_FLATTREE=y +CONFIG_OF_KOBJ=y +CONFIG_OF_DYNAMIC=y +CONFIG_OF_ADDRESS=y +CONFIG_OF_IRQ=y +CONFIG_OF_RESERVED_MEM=y +CONFIG_OF_RESOLVE=y +CONFIG_OF_OVERLAY=y +CONFIG_OF_NUMA=y +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_NULL_BLK is not set +CONFIG_CDROM=m +# CONFIG_BLK_DEV_PCIESSD_MTIP32XX is not set +CONFIG_ZRAM=m +CONFIG_ZRAM_DEF_COMP_LZORLE=y +# CONFIG_ZRAM_DEF_COMP_ZSTD is not set +# CONFIG_ZRAM_DEF_COMP_LZ4 is not set +# CONFIG_ZRAM_DEF_COMP_LZO is not set +# CONFIG_ZRAM_DEF_COMP_LZ4HC is not set +# CONFIG_ZRAM_DEF_COMP_842 is not set +CONFIG_ZRAM_DEF_COMP="lzo-rle" +CONFIG_ZRAM_WRITEBACK=y +# CONFIG_ZRAM_MEMORY_TRACKING is not set +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_LOOP_MIN_COUNT=8 +CONFIG_BLK_DEV_DRBD=m +# CONFIG_DRBD_FAULT_INJECTION is not set +CONFIG_BLK_DEV_NBD=m +CONFIG_BLK_DEV_SX8=m +CONFIG_BLK_DEV_RAM=m +CONFIG_BLK_DEV_RAM_COUNT=8 +CONFIG_BLK_DEV_RAM_SIZE=4096 +# CONFIG_CDROM_PKTCDVD is not set +CONFIG_ATA_OVER_ETH=m +CONFIG_XEN_BLKDEV_FRONTEND=y +CONFIG_XEN_BLKDEV_BACKEND=m +CONFIG_VIRTIO_BLK=y +CONFIG_BLK_DEV_RBD=m +CONFIG_BLK_DEV_RSXX=m + +# +# NVME Support +# +CONFIG_NVME_CORE=y +CONFIG_BLK_DEV_NVME=y +CONFIG_NVME_MULTIPATH=y +# CONFIG_NVME_HWMON is not set +CONFIG_NVME_FABRICS=m +CONFIG_NVME_FC=m +# CONFIG_NVME_TCP is not set +CONFIG_NVME_TARGET=m +# CONFIG_NVME_TARGET_PASSTHRU is not set +CONFIG_NVME_TARGET_LOOP=m +CONFIG_NVME_TARGET_FC=m +# CONFIG_NVME_TARGET_FCLOOP is not set +# CONFIG_NVME_TARGET_TCP is not set +# end of NVME Support + +# +# Misc devices +# +# CONFIG_AD525X_DPOT is not set +# CONFIG_DUMMY_IRQ is not set +CONFIG_PHANTOM=m +CONFIG_TIFM_CORE=m +CONFIG_TIFM_7XX1=m +# CONFIG_ICS932S401 is not set +# CONFIG_ENCLOSURE_SERVICES is not set +CONFIG_HI6421V600_IRQ=m +# CONFIG_HP_ILO is not set +# CONFIG_APDS9802ALS is not set +# CONFIG_ISL29003 is not set +# CONFIG_ISL29020 is not set +# CONFIG_SENSORS_TSL2550 is not set +# CONFIG_SENSORS_BH1770 is not set +# CONFIG_SENSORS_APDS990X is not set +# CONFIG_HMC6352 is not set +# CONFIG_DS1682 is not set +# CONFIG_LATTICE_ECP3_CONFIG is not set +CONFIG_SRAM=y +CONFIG_DW_XDATA_PCIE=m +# CONFIG_PCI_ENDPOINT_TEST is not set +CONFIG_XILINX_SDFEC=m +CONFIG_MISC_RTSX=m +# CONFIG_HISI_HIKEY_USB is not set +# CONFIG_C2PORT is not set + +# +# EEPROM support +# +CONFIG_EEPROM_AT24=m +CONFIG_EEPROM_AT25=m +CONFIG_EEPROM_LEGACY=m +# CONFIG_EEPROM_MAX6875 is not set +CONFIG_EEPROM_93CX6=m +# CONFIG_EEPROM_93XX46 is not set +# CONFIG_EEPROM_IDT_89HPESX is not set +CONFIG_EEPROM_EE1004=m +# end of EEPROM support + +CONFIG_CB710_CORE=m +# CONFIG_CB710_DEBUG is not set +CONFIG_CB710_DEBUG_ASSUMPTIONS=y + +# +# Texas Instruments shared transport line discipline +# +# CONFIG_TI_ST is not set +# end of Texas Instruments shared transport line discipline + +# CONFIG_SENSORS_LIS3_SPI is not set +# CONFIG_SENSORS_LIS3_I2C is not set +# CONFIG_ALTERA_STAPL is not set +CONFIG_GENWQE=m +CONFIG_GENWQE_PLATFORM_ERROR_RECOVERY=0 +# CONFIG_ECHO is not set +CONFIG_BCM_VK=m +# CONFIG_BCM_VK_TTY is not set +CONFIG_MISC_ALCOR_PCI=m +CONFIG_MISC_RTSX_PCI=m +CONFIG_MISC_RTSX_USB=m +CONFIG_HABANA_AI=m +# CONFIG_UACCE is not set +# CONFIG_PVPANIC is not set +# end of Misc devices + +# +# SCSI device support +# +CONFIG_SCSI_MOD=y +CONFIG_RAID_ATTRS=m +CONFIG_SCSI_COMMON=y +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_PROC_FS is not set + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +CONFIG_BLK_DEV_SR=m +CONFIG_CHR_DEV_SG=m +CONFIG_BLK_DEV_BSG=y +# CONFIG_CHR_DEV_SCH is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set +# CONFIG_SCSI_SCAN_ASYNC is not set + +# +# SCSI Transports +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +CONFIG_SCSI_ISCSI_ATTRS=m +CONFIG_SCSI_SAS_ATTRS=y +CONFIG_SCSI_SAS_LIBSAS=y +CONFIG_SCSI_SAS_ATA=y +CONFIG_SCSI_SAS_HOST_SMP=y +# CONFIG_SCSI_SRP_ATTRS is not set +# end of SCSI Transports + +CONFIG_SCSI_LOWLEVEL=y +CONFIG_ISCSI_TCP=m +# CONFIG_ISCSI_BOOT_SYSFS is not set +# CONFIG_SCSI_CXGB3_ISCSI is not set +# CONFIG_SCSI_CXGB4_ISCSI is not set +# CONFIG_SCSI_BNX2_ISCSI is not set +# CONFIG_BE2ISCSI is not set +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_HPSA is not set +# CONFIG_SCSI_3W_9XXX is not set +# CONFIG_SCSI_3W_SAS is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_AIC94XX is not set +CONFIG_SCSI_HISI_SAS=y +# CONFIG_SCSI_HISI_SAS_DEBUGFS_DEFAULT_ENABLE is not set +# CONFIG_SCSI_MVSAS is not set +# CONFIG_SCSI_MVUMI is not set +# CONFIG_SCSI_ADVANSYS is not set +# CONFIG_SCSI_ARCMSR is not set +# CONFIG_SCSI_ESAS2R is not set +# CONFIG_MEGARAID_NEWGEN is not set +# CONFIG_MEGARAID_LEGACY is not set +# CONFIG_MEGARAID_SAS is not set +CONFIG_SCSI_MPT3SAS=m +CONFIG_SCSI_MPT2SAS_MAX_SGE=128 +CONFIG_SCSI_MPT3SAS_MAX_SGE=128 +CONFIG_SCSI_MPT2SAS=m +CONFIG_SCSI_MPI3MR=m +# CONFIG_SCSI_SMARTPQI is not set +# CONFIG_SCSI_UFSHCD is not set +# CONFIG_SCSI_UFS_HWMON is not set +# CONFIG_SCSI_HPTIOP is not set +# CONFIG_SCSI_MYRB is not set +# CONFIG_SCSI_MYRS is not set +# CONFIG_XEN_SCSI_FRONTEND is not set +# CONFIG_SCSI_SNIC is not set +# CONFIG_SCSI_DMX3191D is not set +CONFIG_SCSI_FDOMAIN=m +CONFIG_SCSI_FDOMAIN_PCI=m +# CONFIG_SCSI_IPS is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_STEX is not set +# CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_IPR is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +# CONFIG_SCSI_QLA_ISCSI is not set +# CONFIG_SCSI_DC395x is not set +# CONFIG_SCSI_AM53C974 is not set +# CONFIG_SCSI_WD719X is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_PMCRAID is not set +# CONFIG_SCSI_PM8001 is not set +# CONFIG_SCSI_VIRTIO is not set +# CONFIG_SCSI_DH is not set +# end of SCSI device support + +CONFIG_HAVE_PATA_PLATFORM=y +CONFIG_ATA=y +CONFIG_SATA_HOST=y +CONFIG_ATA_VERBOSE_ERROR=y +CONFIG_ATA_FORCE=y +CONFIG_SATA_PMP=y + +# +# Controllers with non-SFF native interface +# +CONFIG_SATA_AHCI=y +CONFIG_SATA_MOBILE_LPM_POLICY=0 +CONFIG_SATA_AHCI_PLATFORM=y +CONFIG_AHCI_CEVA=y +CONFIG_AHCI_SUNXI=m +CONFIG_AHCI_XGENE=y +CONFIG_AHCI_QORIQ=y +# CONFIG_SATA_INIC162X is not set +# CONFIG_SATA_ACARD_AHCI is not set +CONFIG_SATA_SIL24=y +CONFIG_ATA_SFF=y + +# +# SFF controllers with custom DMA interface +# +# CONFIG_PDC_ADMA is not set +# CONFIG_SATA_QSTOR is not set +# CONFIG_SATA_SX4 is not set +CONFIG_ATA_BMDMA=y + +# +# SATA SFF controllers with BMDMA +# +# CONFIG_ATA_PIIX is not set +# CONFIG_SATA_DWC is not set +# CONFIG_SATA_MV is not set +# CONFIG_SATA_NV is not set +# CONFIG_SATA_PROMISE is not set +# CONFIG_SATA_SIL is not set +# CONFIG_SATA_SIS is not set +# CONFIG_SATA_SVW is not set +# CONFIG_SATA_ULI is not set +# CONFIG_SATA_VIA is not set +# CONFIG_SATA_VITESSE is not set + +# +# PATA SFF controllers with BMDMA +# +# CONFIG_PATA_ALI is not set +# CONFIG_PATA_AMD is not set +# CONFIG_PATA_ARTOP is not set +# CONFIG_PATA_ATIIXP is not set +# CONFIG_PATA_ATP867X is not set +# CONFIG_PATA_CMD64X is not set +# CONFIG_PATA_CYPRESS is not set +# CONFIG_PATA_EFAR is not set +# CONFIG_PATA_HPT366 is not set +# CONFIG_PATA_HPT37X is not set +# CONFIG_PATA_HPT3X2N is not set +# CONFIG_PATA_HPT3X3 is not set +# CONFIG_PATA_IT8213 is not set +# CONFIG_PATA_IT821X is not set +# CONFIG_PATA_JMICRON is not set +# CONFIG_PATA_MARVELL is not set +# CONFIG_PATA_NETCELL is not set +# CONFIG_PATA_NINJA32 is not set +# CONFIG_PATA_NS87415 is not set +# CONFIG_PATA_OLDPIIX is not set +# CONFIG_PATA_OPTIDMA is not set +# CONFIG_PATA_PDC2027X is not set +# CONFIG_PATA_PDC_OLD is not set +# CONFIG_PATA_RADISYS is not set +# CONFIG_PATA_RDC is not set +# CONFIG_PATA_SCH is not set +# CONFIG_PATA_SERVERWORKS is not set +# CONFIG_PATA_SIL680 is not set +# CONFIG_PATA_SIS is not set +# CONFIG_PATA_TOSHIBA is not set +# CONFIG_PATA_TRIFLEX is not set +# CONFIG_PATA_VIA is not set +# CONFIG_PATA_WINBOND is not set + +# +# PIO-only SFF controllers +# +# CONFIG_PATA_CMD640_PCI is not set +# CONFIG_PATA_MPIIX is not set +# CONFIG_PATA_NS87410 is not set +# CONFIG_PATA_OPTI is not set +CONFIG_PATA_PLATFORM=y +CONFIG_PATA_OF_PLATFORM=y +# CONFIG_PATA_RZ1000 is not set + +# +# Generic fallback / legacy drivers +# +# CONFIG_ATA_GENERIC is not set +# CONFIG_PATA_LEGACY is not set +CONFIG_MD=y +CONFIG_BLK_DEV_MD=m +CONFIG_MD_LINEAR=m +CONFIG_MD_RAID0=m +CONFIG_MD_RAID1=m +CONFIG_MD_RAID10=m +CONFIG_MD_RAID456=m +CONFIG_MD_MULTIPATH=m +CONFIG_MD_FAULTY=m +CONFIG_MD_CLUSTER=m +CONFIG_BCACHE=y +# CONFIG_BCACHE_DEBUG is not set +# CONFIG_BCACHE_CLOSURES_DEBUG is not set +# CONFIG_BCACHE_ASYNC_REGISTRATION is not set +CONFIG_BLK_DEV_DM_BUILTIN=y +CONFIG_BLK_DEV_DM=m +# CONFIG_DM_DEBUG is not set +CONFIG_DM_BUFIO=m +# CONFIG_DM_DEBUG_BLOCK_MANAGER_LOCKING is not set +CONFIG_DM_BIO_PRISON=m +CONFIG_DM_PERSISTENT_DATA=m +CONFIG_DM_UNSTRIPED=m +CONFIG_DM_CRYPT=m +CONFIG_DM_SNAPSHOT=m +CONFIG_DM_THIN_PROVISIONING=m +CONFIG_DM_CACHE=m +CONFIG_DM_CACHE_SMQ=m +CONFIG_DM_WRITECACHE=m +# CONFIG_DM_EBS is not set +CONFIG_DM_ERA=m +CONFIG_DM_CLONE=m +CONFIG_DM_MIRROR=m +CONFIG_DM_LOG_USERSPACE=m +CONFIG_DM_RAID=m +CONFIG_DM_ZERO=m +CONFIG_DM_MULTIPATH=m +CONFIG_DM_MULTIPATH_QL=m +CONFIG_DM_MULTIPATH_ST=m +# CONFIG_DM_MULTIPATH_HST is not set +CONFIG_DM_MULTIPATH_IOA=m +CONFIG_DM_DELAY=m +CONFIG_DM_DUST=m +CONFIG_DM_UEVENT=y +CONFIG_DM_FLAKEY=m +CONFIG_DM_VERITY=m +# CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG is not set +CONFIG_DM_VERITY_FEC=y +CONFIG_DM_SWITCH=m +CONFIG_DM_LOG_WRITES=m +CONFIG_DM_INTEGRITY=m +CONFIG_DM_ZONED=m +CONFIG_DM_AUDIT=y +CONFIG_TARGET_CORE=m +CONFIG_TCM_IBLOCK=m +CONFIG_TCM_FILEIO=m +CONFIG_TCM_PSCSI=m +CONFIG_TCM_USER2=m +CONFIG_LOOPBACK_TARGET=m +CONFIG_ISCSI_TARGET=m +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_FIREWIRE is not set +# CONFIG_FIREWIRE_NOSY is not set +# end of IEEE 1394 (FireWire) support + +CONFIG_NETDEVICES=y +CONFIG_MII=y +CONFIG_NET_CORE=y +CONFIG_BONDING=m +CONFIG_DUMMY=m +CONFIG_WIREGUARD=m +# CONFIG_WIREGUARD_DEBUG is not set +CONFIG_EQUALIZER=m +# CONFIG_NET_FC is not set +CONFIG_IFB=m +CONFIG_NET_TEAM=m +CONFIG_NET_TEAM_MODE_BROADCAST=m +CONFIG_NET_TEAM_MODE_ROUNDROBIN=m +CONFIG_NET_TEAM_MODE_RANDOM=m +CONFIG_NET_TEAM_MODE_ACTIVEBACKUP=m +CONFIG_NET_TEAM_MODE_LOADBALANCE=m +CONFIG_MACVLAN=m +CONFIG_MACVTAP=m +CONFIG_IPVLAN_L3S=y +CONFIG_IPVLAN=m +CONFIG_IPVTAP=m +CONFIG_VXLAN=m +CONFIG_GENEVE=m +# CONFIG_BAREUDP is not set +CONFIG_GTP=m +# CONFIG_AMT is not set +CONFIG_MACSEC=m +CONFIG_NETCONSOLE=m +CONFIG_NETCONSOLE_DYNAMIC=y +CONFIG_NETPOLL=y +CONFIG_NET_POLL_CONTROLLER=y +CONFIG_TUN=y +CONFIG_TAP=m +CONFIG_TUN_VNET_CROSS_LE=y +CONFIG_VETH=m +CONFIG_VIRTIO_NET=m +CONFIG_NLMON=m +CONFIG_NET_VRF=m +CONFIG_MHI_NET=m +# CONFIG_ARCNET is not set +CONFIG_ATM_DRIVERS=y +CONFIG_ATM_DUMMY=m +CONFIG_ATM_TCP=m +CONFIG_ATM_LANAI=m +CONFIG_ATM_ENI=m +# CONFIG_ATM_ENI_DEBUG is not set +# CONFIG_ATM_ENI_TUNE_BURST is not set +CONFIG_ATM_NICSTAR=m +# CONFIG_ATM_NICSTAR_USE_SUNI is not set +# CONFIG_ATM_NICSTAR_USE_IDT77105 is not set +CONFIG_ATM_IDT77252=m +# CONFIG_ATM_IDT77252_DEBUG is not set +# CONFIG_ATM_IDT77252_RCV_ALL is not set +CONFIG_ATM_IDT77252_USE_SUNI=y +CONFIG_ATM_IA=m +# CONFIG_ATM_IA_DEBUG is not set +CONFIG_ATM_FORE200E=m +# CONFIG_ATM_FORE200E_USE_TASKLET is not set +CONFIG_ATM_FORE200E_TX_RETRY=16 +CONFIG_ATM_FORE200E_DEBUG=0 +CONFIG_ATM_HE=m +# CONFIG_ATM_HE_USE_SUNI is not set +CONFIG_ATM_SOLOS=m + +# +# Distributed Switch Architecture drivers +# +CONFIG_B53=m +CONFIG_B53_SPI_DRIVER=m +CONFIG_B53_MDIO_DRIVER=m +CONFIG_B53_MMAP_DRIVER=m +CONFIG_B53_SRAB_DRIVER=m +CONFIG_B53_SERDES=m +CONFIG_NET_DSA_BCM_SF2=m +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_MV88E6060=m +CONFIG_NET_DSA_MICROCHIP_KSZ_COMMON=m +CONFIG_NET_DSA_MICROCHIP_KSZ9477=m +CONFIG_NET_DSA_MICROCHIP_KSZ9477_I2C=m +CONFIG_NET_DSA_MICROCHIP_KSZ9477_SPI=m +CONFIG_NET_DSA_MICROCHIP_KSZ8795=m +CONFIG_NET_DSA_MICROCHIP_KSZ8795_SPI=m +CONFIG_NET_DSA_MICROCHIP_KSZ8863_SMI=m +CONFIG_NET_DSA_MV88E6XXX=m +# CONFIG_NET_DSA_MV88E6XXX_PTP is not set +# CONFIG_NET_DSA_MSCC_SEVILLE is not set +CONFIG_NET_DSA_AR9331=m +CONFIG_NET_DSA_SJA1105=m +# CONFIG_NET_DSA_SJA1105_PTP is not set +CONFIG_NET_DSA_XRS700X=m +CONFIG_NET_DSA_XRS700X_I2C=m +CONFIG_NET_DSA_XRS700X_MDIO=m +CONFIG_NET_DSA_QCA8K=m +CONFIG_NET_DSA_REALTEK_SMI=m +CONFIG_NET_DSA_SMSC_LAN9303=m +CONFIG_NET_DSA_SMSC_LAN9303_I2C=m +CONFIG_NET_DSA_SMSC_LAN9303_MDIO=m +CONFIG_NET_DSA_VITESSE_VSC73XX=m +CONFIG_NET_DSA_VITESSE_VSC73XX_SPI=m +CONFIG_NET_DSA_VITESSE_VSC73XX_PLATFORM=m +# end of Distributed Switch Architecture drivers + +CONFIG_ETHERNET=y +CONFIG_MDIO=m +CONFIG_NET_VENDOR_3COM=y +# CONFIG_VORTEX is not set +# CONFIG_TYPHOON is not set +CONFIG_NET_VENDOR_ADAPTEC=y +# CONFIG_ADAPTEC_STARFIRE is not set +CONFIG_NET_VENDOR_AGERE=y +# CONFIG_ET131X is not set +CONFIG_NET_VENDOR_ALACRITECH=y +# CONFIG_SLICOSS is not set +CONFIG_NET_VENDOR_ALLWINNER=y +CONFIG_SUN4I_EMAC=m +CONFIG_NET_VENDOR_ALTEON=y +# CONFIG_ACENIC is not set +# CONFIG_ALTERA_TSE is not set +CONFIG_NET_VENDOR_AMAZON=y +# CONFIG_ENA_ETHERNET is not set +CONFIG_NET_VENDOR_AMD=y +# CONFIG_AMD8111_ETH is not set +# CONFIG_PCNET32 is not set +CONFIG_AMD_XGBE=y +# CONFIG_AMD_XGBE_DCB is not set +CONFIG_NET_VENDOR_AQUANTIA=y +CONFIG_AQTION=m +CONFIG_NET_VENDOR_ARC=y +# CONFIG_EMAC_ROCKCHIP is not set +CONFIG_NET_VENDOR_ASIX=y +# CONFIG_SPI_AX88796C is not set +CONFIG_NET_VENDOR_ATHEROS=y +CONFIG_ATL2=m +CONFIG_ATL1=m +CONFIG_ATL1E=m +CONFIG_ATL1C=m +CONFIG_ALX=m +CONFIG_NET_VENDOR_BROADCOM=y +CONFIG_B44=m +CONFIG_B44_PCI_AUTOSELECT=y +CONFIG_B44_PCICORE_AUTOSELECT=y +CONFIG_B44_PCI=y +CONFIG_BCMGENET=m +CONFIG_BNX2=m +CONFIG_CNIC=m +CONFIG_TIGON3=m +CONFIG_TIGON3_HWMON=y +CONFIG_BNX2X=m +CONFIG_BNX2X_SRIOV=y +CONFIG_SYSTEMPORT=m +CONFIG_BNXT=m +CONFIG_BNXT_SRIOV=y +CONFIG_BNXT_FLOWER_OFFLOAD=y +# CONFIG_BNXT_DCB is not set +CONFIG_BNXT_HWMON=y +CONFIG_NET_VENDOR_BROCADE=y +CONFIG_BNA=m +CONFIG_NET_VENDOR_CADENCE=y +CONFIG_MACB=y +CONFIG_MACB_USE_HWSTAMP=y +# CONFIG_MACB_PCI is not set +CONFIG_NET_VENDOR_CAVIUM=y +CONFIG_THUNDER_NIC_PF=y +# CONFIG_THUNDER_NIC_VF is not set +CONFIG_THUNDER_NIC_BGX=y +CONFIG_THUNDER_NIC_RGX=y +CONFIG_CAVIUM_PTP=y +# CONFIG_LIQUIDIO is not set +# CONFIG_LIQUIDIO_VF is not set +CONFIG_NET_VENDOR_CHELSIO=y +# CONFIG_CHELSIO_T1 is not set +# CONFIG_CHELSIO_T3 is not set +# CONFIG_CHELSIO_T4 is not set +# CONFIG_CHELSIO_T4VF is not set +CONFIG_NET_VENDOR_CISCO=y +# CONFIG_ENIC is not set +CONFIG_NET_VENDOR_CORTINA=y +# CONFIG_GEMINI_ETHERNET is not set +# CONFIG_DNET is not set +CONFIG_NET_VENDOR_DEC=y +# CONFIG_NET_TULIP is not set +CONFIG_NET_VENDOR_DLINK=y +CONFIG_DL2K=m +# CONFIG_SUNDANCE is not set +CONFIG_NET_VENDOR_EMULEX=y +# CONFIG_BE2NET is not set +CONFIG_NET_VENDOR_EZCHIP=y +# CONFIG_EZCHIP_NPS_MANAGEMENT_ENET is not set +CONFIG_NET_VENDOR_GOOGLE=y +# CONFIG_GVE is not set +CONFIG_NET_VENDOR_HISILICON=y +CONFIG_HIX5HD2_GMAC=y +# CONFIG_HISI_FEMAC is not set +# CONFIG_HIP04_ETH is not set +CONFIG_HNS_MDIO=y +CONFIG_HNS=y +CONFIG_HNS_DSAF=y +CONFIG_HNS_ENET=y +# CONFIG_HNS3 is not set +CONFIG_NET_VENDOR_HUAWEI=y +# CONFIG_HINIC is not set +CONFIG_NET_VENDOR_I825XX=y +CONFIG_NET_VENDOR_INTEL=y +# CONFIG_E100 is not set +# CONFIG_E1000 is not set +CONFIG_E1000E=y +CONFIG_IGB=y +CONFIG_IGB_HWMON=y +CONFIG_IGBVF=y +# CONFIG_IXGB is not set +CONFIG_IXGBE=m +CONFIG_IXGBE_HWMON=y +# CONFIG_IXGBE_DCB is not set +CONFIG_IXGBE_IPSEC=y +# CONFIG_IXGBEVF is not set +# CONFIG_I40E is not set +# CONFIG_I40EVF is not set +# CONFIG_ICE is not set +# CONFIG_FM10K is not set +# CONFIG_IGC is not set +CONFIG_NET_VENDOR_MICROSOFT=y +# CONFIG_JME is not set +CONFIG_NET_VENDOR_LITEX=y +CONFIG_LITEX_LITEETH=m +CONFIG_NET_VENDOR_MARVELL=y +CONFIG_MVMDIO=y +# CONFIG_SKGE is not set +CONFIG_SKY2=y +# CONFIG_SKY2_DEBUG is not set +CONFIG_OCTEONTX2_MBOX=m +# CONFIG_OCTEONTX2_AF is not set +CONFIG_OCTEONTX2_PF=m +CONFIG_OCTEONTX2_VF=m +# CONFIG_PRESTERA is not set +CONFIG_NET_VENDOR_MELLANOX=y +# CONFIG_MLX4_EN is not set +# CONFIG_MLX5_CORE is not set +# CONFIG_MLXSW_CORE is not set +# CONFIG_MLXFW is not set +CONFIG_NET_VENDOR_MICREL=y +# CONFIG_KS8842 is not set +# CONFIG_KS8851 is not set +# CONFIG_KS8851_MLL is not set +# CONFIG_KSZ884X_PCI is not set +CONFIG_NET_VENDOR_MICROCHIP=y +CONFIG_ENC28J60=m +CONFIG_ENC28J60_WRITEVERIFY=y +# CONFIG_ENCX24J600 is not set +# CONFIG_LAN743X is not set +CONFIG_NET_VENDOR_MICROSEMI=y +CONFIG_MSCC_OCELOT_SWITCH_LIB=m +CONFIG_MSCC_OCELOT_SWITCH=m +CONFIG_NET_VENDOR_MYRI=y +# CONFIG_MYRI10GE is not set +# CONFIG_FEALNX is not set +CONFIG_NET_VENDOR_NATSEMI=y +# CONFIG_NATSEMI is not set +# CONFIG_NS83820 is not set +CONFIG_NET_VENDOR_NETERION=y +# CONFIG_S2IO is not set +# CONFIG_VXGE is not set +CONFIG_NET_VENDOR_NETRONOME=y +# CONFIG_NFP is not set +CONFIG_NET_VENDOR_NI=y +# CONFIG_NI_XGE_MANAGEMENT_ENET is not set +CONFIG_NET_VENDOR_8390=y +# CONFIG_NE2K_PCI is not set +CONFIG_NET_VENDOR_NVIDIA=y +# CONFIG_FORCEDETH is not set +CONFIG_NET_VENDOR_OKI=y +# CONFIG_ETHOC is not set +CONFIG_NET_VENDOR_PACKET_ENGINES=y +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +CONFIG_NET_VENDOR_PENSANDO=y +CONFIG_IONIC=m +CONFIG_NET_VENDOR_QLOGIC=y +# CONFIG_QLA3XXX is not set +# CONFIG_QLCNIC is not set +# CONFIG_NETXEN_NIC is not set +# CONFIG_QED is not set +CONFIG_NET_VENDOR_QUALCOMM=y +CONFIG_QCA7000=m +# CONFIG_QCA7000_SPI is not set +CONFIG_QCA7000_UART=m +CONFIG_QCOM_EMAC=m +# CONFIG_RMNET is not set +CONFIG_NET_VENDOR_RDC=y +# CONFIG_R6040 is not set +CONFIG_NET_VENDOR_REALTEK=y +# CONFIG_8139CP is not set +# CONFIG_8139TOO is not set +CONFIG_R8169=m +CONFIG_NET_VENDOR_RENESAS=y +CONFIG_NET_VENDOR_ROCKER=y +CONFIG_ROCKER=m +CONFIG_NET_VENDOR_SAMSUNG=y +# CONFIG_SXGBE_ETH is not set +CONFIG_NET_VENDOR_SEEQ=y +CONFIG_NET_VENDOR_SOLARFLARE=y +# CONFIG_SFC is not set +# CONFIG_SFC_FALCON is not set +CONFIG_NET_VENDOR_SILAN=y +# CONFIG_SC92031 is not set +CONFIG_NET_VENDOR_SIS=y +# CONFIG_SIS900 is not set +# CONFIG_SIS190 is not set +CONFIG_NET_VENDOR_SMSC=y +CONFIG_SMC91X=y +# CONFIG_EPIC100 is not set +CONFIG_SMSC911X=y +# CONFIG_SMSC9420 is not set +CONFIG_NET_VENDOR_SOCIONEXT=y +CONFIG_NET_VENDOR_STMICRO=y +CONFIG_STMMAC_ETH=m +# CONFIG_STMMAC_SELFTESTS is not set +CONFIG_STMMAC_PLATFORM=m +# CONFIG_DWMAC_DWC_QOS_ETH is not set +CONFIG_DWMAC_GENERIC=m +CONFIG_DWMAC_MESON=m +CONFIG_DWMAC_ROCKCHIP=m +CONFIG_DWMAC_SUNXI=m +CONFIG_DWMAC_SUN8I=m +# CONFIG_DWMAC_INTEL_PLAT is not set +CONFIG_DWMAC_LOONGSON=m +# CONFIG_STMMAC_PCI is not set +CONFIG_NET_VENDOR_SUN=y +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_CASSINI is not set +# CONFIG_NIU is not set +CONFIG_NET_VENDOR_SYNOPSYS=y +# CONFIG_DWC_XLGMAC is not set +CONFIG_NET_VENDOR_TEHUTI=y +# CONFIG_TEHUTI is not set +CONFIG_NET_VENDOR_TI=y +# CONFIG_TI_CPSW_PHY_SEL is not set +# CONFIG_TLAN is not set +CONFIG_NET_VENDOR_VIA=y +# CONFIG_VIA_RHINE is not set +# CONFIG_VIA_VELOCITY is not set +CONFIG_NET_VENDOR_WIZNET=y +# CONFIG_WIZNET_W5100 is not set +# CONFIG_WIZNET_W5300 is not set +CONFIG_NET_VENDOR_XILINX=y +CONFIG_XILINX_EMACLITE=m +CONFIG_XILINX_AXI_EMAC=m +CONFIG_XILINX_LL_TEMAC=m +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +CONFIG_PHYLINK=y +CONFIG_PHYLIB=y +CONFIG_SWPHY=y +CONFIG_LED_TRIGGER_PHY=y +CONFIG_FIXED_PHY=y +CONFIG_SFP=m + +# +# MII PHY device drivers +# +CONFIG_AMD_PHY=m +CONFIG_MESON_GXL_PHY=m +CONFIG_ADIN_PHY=m +CONFIG_AQUANTIA_PHY=m +CONFIG_AX88796B_PHY=m +CONFIG_BROADCOM_PHY=m +# CONFIG_BCM54140_PHY is not set +CONFIG_BCM7XXX_PHY=m +CONFIG_BCM84881_PHY=m +CONFIG_BCM87XX_PHY=m +CONFIG_BCM_NET_PHYLIB=m +CONFIG_CICADA_PHY=m +# CONFIG_CORTINA_PHY is not set +CONFIG_DAVICOM_PHY=m +CONFIG_ICPLUS_PHY=m +CONFIG_LXT_PHY=m +# CONFIG_INTEL_XWAY_PHY is not set +CONFIG_LSI_ET1011C_PHY=m +CONFIG_MARVELL_PHY=m +CONFIG_MARVELL_10G_PHY=m +CONFIG_MARVELL_88X2222_PHY=m +CONFIG_MAXLINEAR_GPHY=m +CONFIG_MEDIATEK_GE_PHY=m +CONFIG_MICREL_PHY=y +CONFIG_MICROCHIP_PHY=m +CONFIG_MICROCHIP_T1_PHY=m +# CONFIG_MICROSEMI_PHY is not set +CONFIG_MOTORCOMM_PHY=m +CONFIG_NATIONAL_PHY=m +CONFIG_NXP_C45_TJA11XX_PHY=m +# CONFIG_NXP_TJA11XX_PHY is not set +CONFIG_AT803X_PHY=m +CONFIG_QSEMI_PHY=m +CONFIG_REALTEK_PHY=m +# CONFIG_RENESAS_PHY is not set +CONFIG_ROCKCHIP_PHY=y +CONFIG_SMSC_PHY=m +# CONFIG_STE10XP is not set +# CONFIG_TERANETICS_PHY is not set +# CONFIG_DP83822_PHY is not set +CONFIG_DP83TC811_PHY=m +CONFIG_DP83848_PHY=m +# CONFIG_DP83867_PHY is not set +CONFIG_DP83869_PHY=m +CONFIG_VITESSE_PHY=m +# CONFIG_XILINX_GMII2RGMII is not set +# CONFIG_MICREL_KS8995MA is not set +CONFIG_MDIO_DEVICE=y +CONFIG_MDIO_BUS=y +CONFIG_FWNODE_MDIO=y +CONFIG_OF_MDIO=y +CONFIG_MDIO_DEVRES=y +CONFIG_MDIO_SUN4I=m +CONFIG_MDIO_BITBANG=y +CONFIG_MDIO_BCM_UNIMAC=m +CONFIG_MDIO_CAVIUM=y +# CONFIG_MDIO_GPIO is not set +# CONFIG_MDIO_HISI_FEMAC is not set +CONFIG_MDIO_I2C=m +CONFIG_MDIO_MVUSB=m +CONFIG_MDIO_MSCC_MIIM=m +# CONFIG_MDIO_OCTEON is not set +# CONFIG_MDIO_IPQ4019 is not set +CONFIG_MDIO_IPQ8064=m +CONFIG_MDIO_THUNDER=y + +# +# MDIO Multiplexers +# +CONFIG_MDIO_BUS_MUX=y +CONFIG_MDIO_BUS_MUX_MESON_G12A=m +# CONFIG_MDIO_BUS_MUX_GPIO is not set +CONFIG_MDIO_BUS_MUX_MULTIPLEXER=m +CONFIG_MDIO_BUS_MUX_MMIOREG=y + +# +# PCS device drivers +# +CONFIG_PCS_XPCS=m +# end of PCS device drivers + +CONFIG_PPP=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_FILTER=y +CONFIG_PPP_MPPE=m +CONFIG_PPP_MULTILINK=y +CONFIG_PPPOATM=m +CONFIG_PPPOE=m +CONFIG_PPTP=m +CONFIG_PPPOL2TP=m +CONFIG_PPP_ASYNC=m +CONFIG_PPP_SYNC_TTY=m +CONFIG_SLIP=m +CONFIG_SLHC=m +CONFIG_SLIP_COMPRESSED=y +CONFIG_SLIP_SMART=y +CONFIG_SLIP_MODE_SLIP6=y +CONFIG_USB_NET_DRIVERS=y +CONFIG_USB_CATC=m +CONFIG_USB_KAWETH=m +CONFIG_USB_PEGASUS=m +CONFIG_USB_RTL8150=m +CONFIG_USB_RTL8152=m +CONFIG_USB_LAN78XX=m +CONFIG_USB_USBNET=m +CONFIG_USB_NET_AX8817X=m +CONFIG_USB_NET_AX88179_178A=m +CONFIG_USB_NET_CDCETHER=m +CONFIG_USB_NET_CDC_EEM=m +CONFIG_USB_NET_CDC_NCM=m +CONFIG_USB_NET_HUAWEI_CDC_NCM=m +CONFIG_USB_NET_CDC_MBIM=m +CONFIG_USB_NET_DM9601=m +CONFIG_USB_NET_SR9700=m +CONFIG_USB_NET_SR9800=m +CONFIG_USB_NET_SMSC75XX=m +CONFIG_USB_NET_SMSC95XX=m +CONFIG_USB_NET_GL620A=m +CONFIG_USB_NET_NET1080=m +CONFIG_USB_NET_PLUSB=m +CONFIG_USB_NET_MCS7830=m +CONFIG_USB_NET_RNDIS_HOST=m +CONFIG_USB_NET_CDC_SUBSET_ENABLE=m +CONFIG_USB_NET_CDC_SUBSET=m +CONFIG_USB_ALI_M5632=y +CONFIG_USB_AN2720=y +CONFIG_USB_BELKIN=y +CONFIG_USB_ARMLINUX=y +CONFIG_USB_EPSON2888=y +CONFIG_USB_KC2190=y +CONFIG_USB_NET_ZAURUS=m +CONFIG_USB_NET_CX82310_ETH=m +CONFIG_USB_NET_KALMIA=m +CONFIG_USB_NET_QMI_WWAN=m +CONFIG_USB_HSO=m +CONFIG_USB_NET_INT51X1=m +CONFIG_USB_CDC_PHONET=m +CONFIG_USB_IPHETH=m +CONFIG_USB_SIERRA_NET=m +CONFIG_USB_VL600=m +CONFIG_USB_NET_CH9200=m +CONFIG_USB_NET_AQC111=m +# CONFIG_USB_RTL8153_ECM is not set +CONFIG_WLAN=y +# CONFIG_WLAN_VENDOR_ADMTEK is not set +CONFIG_ATH_COMMON=m +CONFIG_WLAN_VENDOR_ATH=y +# CONFIG_ATH_DEBUG is not set +# CONFIG_ATH5K is not set +# CONFIG_ATH5K_PCI is not set +CONFIG_ATH9K_HW=m +CONFIG_ATH9K_COMMON=m +CONFIG_ATH9K_BTCOEX_SUPPORT=y +CONFIG_ATH9K=m +CONFIG_ATH9K_PCI=y +CONFIG_ATH9K_AHB=y +# CONFIG_ATH9K_DEBUGFS is not set +CONFIG_ATH9K_DYNACK=y +CONFIG_ATH9K_WOW=y +CONFIG_ATH9K_RFKILL=y +# CONFIG_ATH9K_CHANNEL_CONTEXT is not set +CONFIG_ATH9K_PCOEM=y +CONFIG_ATH9K_PCI_NO_EEPROM=m +CONFIG_ATH9K_HTC=m +# CONFIG_ATH9K_HTC_DEBUGFS is not set +# CONFIG_ATH9K_HWRNG is not set +CONFIG_CARL9170=m +CONFIG_CARL9170_LEDS=y +CONFIG_CARL9170_WPC=y +# CONFIG_CARL9170_HWRNG is not set +CONFIG_ATH6KL=m +CONFIG_ATH6KL_SDIO=m +CONFIG_ATH6KL_USB=m +# CONFIG_ATH6KL_DEBUG is not set +# CONFIG_ATH6KL_TRACING is not set +CONFIG_AR5523=m +CONFIG_WIL6210=m +CONFIG_WIL6210_ISR_COR=y +# CONFIG_WIL6210_TRACING is not set +CONFIG_WIL6210_DEBUGFS=y +CONFIG_ATH10K=m +CONFIG_ATH10K_CE=y +CONFIG_ATH10K_PCI=m +CONFIG_ATH10K_AHB=y +CONFIG_ATH10K_SDIO=m +CONFIG_ATH10K_USB=m +# CONFIG_ATH10K_DEBUG is not set +# CONFIG_ATH10K_DEBUGFS is not set +# CONFIG_ATH10K_TRACING is not set +# CONFIG_WCN36XX is not set +# CONFIG_ATH11K is not set +CONFIG_WLAN_VENDOR_ATMEL=y +CONFIG_ATMEL=m +CONFIG_PCI_ATMEL=m +CONFIG_AT76C50X_USB=m +CONFIG_WLAN_VENDOR_BROADCOM=y +CONFIG_B43=m +CONFIG_B43_BCMA=y +CONFIG_B43_SSB=y +CONFIG_B43_BUSES_BCMA_AND_SSB=y +# CONFIG_B43_BUSES_BCMA is not set +# CONFIG_B43_BUSES_SSB is not set +CONFIG_B43_PCI_AUTOSELECT=y +CONFIG_B43_PCICORE_AUTOSELECT=y +# CONFIG_B43_SDIO is not set +CONFIG_B43_BCMA_PIO=y +CONFIG_B43_PIO=y +CONFIG_B43_PHY_G=y +CONFIG_B43_PHY_N=y +CONFIG_B43_PHY_LP=y +CONFIG_B43_PHY_HT=y +CONFIG_B43_LEDS=y +CONFIG_B43_HWRNG=y +# CONFIG_B43_DEBUG is not set +CONFIG_B43LEGACY=m +CONFIG_B43LEGACY_PCI_AUTOSELECT=y +CONFIG_B43LEGACY_PCICORE_AUTOSELECT=y +CONFIG_B43LEGACY_LEDS=y +CONFIG_B43LEGACY_HWRNG=y +CONFIG_B43LEGACY_DEBUG=y +CONFIG_B43LEGACY_DMA=y +CONFIG_B43LEGACY_PIO=y +CONFIG_B43LEGACY_DMA_AND_PIO_MODE=y +# CONFIG_B43LEGACY_DMA_MODE is not set +# CONFIG_B43LEGACY_PIO_MODE is not set +CONFIG_BRCMUTIL=m +CONFIG_BRCMSMAC=m +CONFIG_BRCMFMAC=m +CONFIG_BRCMFMAC_PROTO_BCDC=y +CONFIG_BRCMFMAC_PROTO_MSGBUF=y +CONFIG_BRCMFMAC_SDIO=y +CONFIG_BRCMFMAC_USB=y +CONFIG_BRCMFMAC_PCIE=y +CONFIG_BRCM_TRACING=y +CONFIG_BRCMDBG=y +CONFIG_WLAN_VENDOR_CISCO=y +CONFIG_WLAN_VENDOR_INTEL=y +CONFIG_IPW2100=m +# CONFIG_IPW2100_MONITOR is not set +# CONFIG_IPW2100_DEBUG is not set +# CONFIG_IPW2200 is not set +CONFIG_LIBIPW=m +# CONFIG_LIBIPW_DEBUG is not set +# CONFIG_IWL4965 is not set +# CONFIG_IWL3945 is not set +# CONFIG_IWLWIFI is not set +CONFIG_WLAN_VENDOR_INTERSIL=y +# CONFIG_HOSTAP is not set +# CONFIG_HERMES is not set +# CONFIG_P54_COMMON is not set +CONFIG_WLAN_VENDOR_MARVELL=y +# CONFIG_LIBERTAS is not set +CONFIG_LIBERTAS_THINFIRM=m +# CONFIG_LIBERTAS_THINFIRM_DEBUG is not set +CONFIG_LIBERTAS_THINFIRM_USB=m +# CONFIG_MWIFIEX is not set +CONFIG_MWL8K=m +CONFIG_WLAN_VENDOR_MEDIATEK=y +CONFIG_MT7601U=m +CONFIG_MT76_CORE=m +CONFIG_MT76_LEDS=y +CONFIG_MT76_USB=m +CONFIG_MT76x02_LIB=m +CONFIG_MT76x02_USB=m +CONFIG_MT76_CONNAC_LIB=m +CONFIG_MT76x0_COMMON=m +CONFIG_MT76x0U=m +CONFIG_MT76x0E=m +CONFIG_MT76x2_COMMON=m +CONFIG_MT76x2E=m +CONFIG_MT76x2U=m +CONFIG_MT7603E=m +CONFIG_MT7615_COMMON=m +CONFIG_MT7615E=m +# CONFIG_MT7663U is not set +# CONFIG_MT7663S is not set +# CONFIG_MT7915E is not set +CONFIG_MT7921_COMMON=m +CONFIG_MT7921E=m +# CONFIG_MT7921S is not set +CONFIG_WLAN_VENDOR_MICROCHIP=y +# CONFIG_WILC1000_SDIO is not set +# CONFIG_WILC1000_SPI is not set +CONFIG_WLAN_VENDOR_RALINK=y +CONFIG_RT2X00=m +CONFIG_RT2400PCI=m +CONFIG_RT2500PCI=m +CONFIG_RT61PCI=m +CONFIG_RT2800PCI=m +CONFIG_RT2800PCI_RT33XX=y +CONFIG_RT2800PCI_RT35XX=y +CONFIG_RT2800PCI_RT53XX=y +CONFIG_RT2800PCI_RT3290=y +CONFIG_RT2500USB=m +CONFIG_RT73USB=m +CONFIG_RT2800USB=m +CONFIG_RT2800USB_RT33XX=y +CONFIG_RT2800USB_RT35XX=y +CONFIG_RT2800USB_RT3573=y +CONFIG_RT2800USB_RT53XX=y +CONFIG_RT2800USB_RT55XX=y +# CONFIG_RT2800USB_UNKNOWN is not set +CONFIG_RT2800_LIB=m +CONFIG_RT2800_LIB_MMIO=m +CONFIG_RT2X00_LIB_MMIO=m +CONFIG_RT2X00_LIB_PCI=m +CONFIG_RT2X00_LIB_USB=m +CONFIG_RT2X00_LIB=m +CONFIG_RT2X00_LIB_FIRMWARE=y +CONFIG_RT2X00_LIB_CRYPTO=y +CONFIG_RT2X00_LIB_LEDS=y +# CONFIG_RT2X00_DEBUG is not set +CONFIG_WLAN_VENDOR_REALTEK=y +CONFIG_RTL8180=m +CONFIG_RTL8187=m +CONFIG_RTL8187_LEDS=y +CONFIG_RTL_CARDS=m +CONFIG_RTL8192CE=m +CONFIG_RTL8192SE=m +CONFIG_RTL8192DE=m +CONFIG_RTL8723AE=m +CONFIG_RTL8723BE=m +CONFIG_RTL8188EE=m +CONFIG_RTL8192EE=m +CONFIG_RTL8821AE=m +CONFIG_RTL8192CU=m +CONFIG_RTLWIFI=m +CONFIG_RTLWIFI_PCI=m +CONFIG_RTLWIFI_USB=m +# CONFIG_RTLWIFI_DEBUG is not set +CONFIG_RTL8192C_COMMON=m +CONFIG_RTL8723_COMMON=m +CONFIG_RTLBTCOEXIST=m +CONFIG_RTL8XXXU=m +# CONFIG_RTL8XXXU_UNTESTED is not set +CONFIG_RTW88=m +# CONFIG_RTW88_8822BE is not set +# CONFIG_RTW88_8822CE is not set +# CONFIG_RTW88_8723DE is not set +# CONFIG_RTW88_8821CE is not set +# CONFIG_RTW89 is not set +CONFIG_WLAN_VENDOR_RSI=y +CONFIG_RSI_91X=m +# CONFIG_RSI_DEBUGFS is not set +CONFIG_RSI_SDIO=m +CONFIG_RSI_USB=m +CONFIG_RSI_COEX=y +CONFIG_WLAN_VENDOR_ST=y +CONFIG_CW1200=m +CONFIG_CW1200_WLAN_SDIO=m +CONFIG_CW1200_WLAN_SPI=m +CONFIG_WLAN_VENDOR_TI=y +CONFIG_WL1251=m +CONFIG_WL1251_SPI=m +CONFIG_WL1251_SDIO=m +CONFIG_WL12XX=m +CONFIG_WL18XX=m +CONFIG_WLCORE=m +CONFIG_WLCORE_SPI=m +CONFIG_WLCORE_SDIO=m +CONFIG_WILINK_PLATFORM_DATA=y +# CONFIG_RTL8822BS is not set +CONFIG_RTL8723DU=m +CONFIG_RTL8723DS=m +CONFIG_RTL8822CS=m +CONFIG_RTL8822BU=m +CONFIG_RTL8188EU=m +CONFIG_RTL8821CU=m +CONFIG_88XXAU=m +# CONFIG_RTL8192EU is not set +CONFIG_RTL8189FS=m +CONFIG_RTL8189ES=m +CONFIG_WLAN_VENDOR_ZYDAS=y +CONFIG_USB_ZD1201=m +CONFIG_ZD1211RW=m +# CONFIG_ZD1211RW_DEBUG is not set +CONFIG_WLAN_VENDOR_QUANTENNA=y +CONFIG_QTNFMAC=m +CONFIG_QTNFMAC_PCIE=m +CONFIG_MAC80211_HWSIM=m +CONFIG_USB_NET_RNDIS_WLAN=m +CONFIG_VIRT_WIFI=m +# CONFIG_WAN is not set +CONFIG_IEEE802154_DRIVERS=m +CONFIG_IEEE802154_FAKELB=m +CONFIG_IEEE802154_AT86RF230=m +# CONFIG_IEEE802154_AT86RF230_DEBUGFS is not set +CONFIG_IEEE802154_MRF24J40=m +CONFIG_IEEE802154_CC2520=m +CONFIG_IEEE802154_ATUSB=m +CONFIG_IEEE802154_ADF7242=m +CONFIG_IEEE802154_CA8210=m +# CONFIG_IEEE802154_CA8210_DEBUGFS is not set +CONFIG_IEEE802154_MCR20A=m +CONFIG_IEEE802154_HWSIM=m + +# +# Wireless WAN +# +CONFIG_WWAN=m +CONFIG_WWAN_HWSIM=m +CONFIG_MHI_WWAN_CTRL=m +CONFIG_MHI_WWAN_MBIM=m +# end of Wireless WAN + +CONFIG_XEN_NETDEV_FRONTEND=m +CONFIG_XEN_NETDEV_BACKEND=m +CONFIG_VMXNET3=m +CONFIG_NETDEVSIM=m +CONFIG_NET_FAILOVER=m +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y +CONFIG_INPUT_LEDS=y +CONFIG_INPUT_FF_MEMLESS=m +# CONFIG_INPUT_SPARSEKMAP is not set +CONFIG_INPUT_MATRIXKMAP=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +CONFIG_INPUT_JOYDEV=m +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +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 +CONFIG_KEYBOARD_QT1050=m +# CONFIG_KEYBOARD_QT1070 is not set +# CONFIG_KEYBOARD_QT2160 is not set +# CONFIG_KEYBOARD_DLINK_DIR685 is not set +# CONFIG_KEYBOARD_LKKBD is not set +CONFIG_KEYBOARD_GPIO=y +# CONFIG_KEYBOARD_GPIO_POLLED is not set +# CONFIG_KEYBOARD_TCA6416 is not set +# CONFIG_KEYBOARD_TCA8418 is not set +# CONFIG_KEYBOARD_MATRIX is not set +# CONFIG_KEYBOARD_LM8323 is not set +# CONFIG_KEYBOARD_LM8333 is not set +# CONFIG_KEYBOARD_MAX7359 is not set +# CONFIG_KEYBOARD_MCS is not set +# CONFIG_KEYBOARD_MPR121 is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_OPENCORES is not set +# CONFIG_KEYBOARD_SAMSUNG is not set +# CONFIG_KEYBOARD_STOWAWAY is not set +# CONFIG_KEYBOARD_SUNKBD is not set +CONFIG_KEYBOARD_SUN4I_LRADC=m +CONFIG_KEYBOARD_IQS62X=m +# CONFIG_KEYBOARD_OMAP4 is not set +# CONFIG_KEYBOARD_TM2_TOUCHKEY is not set +# CONFIG_KEYBOARD_XTKBD is not set +CONFIG_KEYBOARD_CROS_EC=y +# CONFIG_KEYBOARD_CAP11XX is not set +# CONFIG_KEYBOARD_BCM is not set +# CONFIG_KEYBOARD_CYPRESS_SF is not set +CONFIG_INPUT_MOUSE=y +CONFIG_MOUSE_PS2=y +CONFIG_MOUSE_PS2_ALPS=y +CONFIG_MOUSE_PS2_BYD=y +CONFIG_MOUSE_PS2_LOGIPS2PP=y +CONFIG_MOUSE_PS2_SYNAPTICS=y +CONFIG_MOUSE_PS2_SYNAPTICS_SMBUS=y +CONFIG_MOUSE_PS2_CYPRESS=y +CONFIG_MOUSE_PS2_TRACKPOINT=y +# CONFIG_MOUSE_PS2_ELANTECH is not set +# CONFIG_MOUSE_PS2_SENTELIC is not set +# CONFIG_MOUSE_PS2_TOUCHKIT is not set +CONFIG_MOUSE_PS2_FOCALTECH=y +CONFIG_MOUSE_PS2_SMBUS=y +# CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_APPLETOUCH is not set +# CONFIG_MOUSE_BCM5974 is not set +# CONFIG_MOUSE_CYAPA is not set +# CONFIG_MOUSE_ELAN_I2C is not set +# CONFIG_MOUSE_VSXXXAA is not set +# CONFIG_MOUSE_GPIO is not set +# CONFIG_MOUSE_SYNAPTICS_I2C is not set +# CONFIG_MOUSE_SYNAPTICS_USB is not set +CONFIG_INPUT_JOYSTICK=y +# CONFIG_JOYSTICK_ANALOG is not set +# CONFIG_JOYSTICK_A3D is not set +# CONFIG_JOYSTICK_ADC is not set +# CONFIG_JOYSTICK_ADI is not set +# CONFIG_JOYSTICK_COBRA is not set +# CONFIG_JOYSTICK_GF2K is not set +# CONFIG_JOYSTICK_GRIP is not set +# CONFIG_JOYSTICK_GRIP_MP is not set +# CONFIG_JOYSTICK_GUILLEMOT is not set +# CONFIG_JOYSTICK_INTERACT is not set +# CONFIG_JOYSTICK_SIDEWINDER is not set +# CONFIG_JOYSTICK_TMDC is not set +CONFIG_JOYSTICK_IFORCE=m +CONFIG_JOYSTICK_IFORCE_USB=m +# CONFIG_JOYSTICK_IFORCE_232 is not set +# CONFIG_JOYSTICK_WARRIOR is not set +# CONFIG_JOYSTICK_MAGELLAN is not set +# CONFIG_JOYSTICK_SPACEORB is not set +# CONFIG_JOYSTICK_SPACEBALL is not set +# CONFIG_JOYSTICK_STINGER is not set +# CONFIG_JOYSTICK_TWIDJOY is not set +# CONFIG_JOYSTICK_ZHENHUA is not set +# CONFIG_JOYSTICK_AS5011 is not set +# CONFIG_JOYSTICK_JOYDUMP is not set +CONFIG_JOYSTICK_XPAD=m +CONFIG_JOYSTICK_XPAD_FF=y +CONFIG_JOYSTICK_XPAD_LEDS=y +# CONFIG_JOYSTICK_PSXPAD_SPI is not set +# CONFIG_JOYSTICK_PXRC is not set +CONFIG_JOYSTICK_QWIIC=m +# CONFIG_JOYSTICK_FSIA6B is not set +# CONFIG_INPUT_TABLET is not set +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_ADS7846=m +CONFIG_TOUCHSCREEN_AD7877=m +CONFIG_TOUCHSCREEN_AD7879=m +CONFIG_TOUCHSCREEN_AD7879_I2C=m +CONFIG_TOUCHSCREEN_AD7879_SPI=m +CONFIG_TOUCHSCREEN_ADC=m +CONFIG_TOUCHSCREEN_AR1021_I2C=m +CONFIG_TOUCHSCREEN_ATMEL_MXT=m +CONFIG_TOUCHSCREEN_ATMEL_MXT_T37=y +CONFIG_TOUCHSCREEN_AUO_PIXCIR=m +CONFIG_TOUCHSCREEN_BU21013=m +CONFIG_TOUCHSCREEN_BU21029=m +CONFIG_TOUCHSCREEN_CHIPONE_ICN8318=m +# CONFIG_TOUCHSCREEN_CY8CTMA140 is not set +CONFIG_TOUCHSCREEN_CY8CTMG110=m +CONFIG_TOUCHSCREEN_CYTTSP_CORE=m +CONFIG_TOUCHSCREEN_CYTTSP_I2C=m +CONFIG_TOUCHSCREEN_CYTTSP_SPI=m +CONFIG_TOUCHSCREEN_CYTTSP4_CORE=m +CONFIG_TOUCHSCREEN_CYTTSP4_I2C=m +CONFIG_TOUCHSCREEN_CYTTSP4_SPI=m +CONFIG_TOUCHSCREEN_DYNAPRO=m +CONFIG_TOUCHSCREEN_HAMPSHIRE=m +CONFIG_TOUCHSCREEN_EETI=m +CONFIG_TOUCHSCREEN_EGALAX=m +CONFIG_TOUCHSCREEN_EGALAX_SERIAL=m +CONFIG_TOUCHSCREEN_EXC3000=m +CONFIG_TOUCHSCREEN_FUJITSU=m +CONFIG_TOUCHSCREEN_GOODIX=m +CONFIG_TOUCHSCREEN_HIDEEP=m +CONFIG_TOUCHSCREEN_HYCON_HY46XX=m +CONFIG_TOUCHSCREEN_ILI210X=m +CONFIG_TOUCHSCREEN_ILITEK=m +CONFIG_TOUCHSCREEN_S6SY761=m +CONFIG_TOUCHSCREEN_GUNZE=m +CONFIG_TOUCHSCREEN_EKTF2127=m +CONFIG_TOUCHSCREEN_ELAN=m +CONFIG_TOUCHSCREEN_ELO=m +CONFIG_TOUCHSCREEN_WACOM_W8001=m +CONFIG_TOUCHSCREEN_WACOM_I2C=m +CONFIG_TOUCHSCREEN_MAX11801=m +CONFIG_TOUCHSCREEN_MCS5000=m +CONFIG_TOUCHSCREEN_MMS114=m +CONFIG_TOUCHSCREEN_MELFAS_MIP4=m +CONFIG_TOUCHSCREEN_MSG2638=m +CONFIG_TOUCHSCREEN_MTOUCH=m +CONFIG_TOUCHSCREEN_IMX6UL_TSC=m +CONFIG_TOUCHSCREEN_INEXIO=m +CONFIG_TOUCHSCREEN_MK712=m +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 +CONFIG_TOUCHSCREEN_WM9705=y +CONFIG_TOUCHSCREEN_WM9712=y +CONFIG_TOUCHSCREEN_WM9713=y +CONFIG_TOUCHSCREEN_USB_COMPOSITE=m +CONFIG_TOUCHSCREEN_USB_EGALAX=y +CONFIG_TOUCHSCREEN_USB_PANJIT=y +CONFIG_TOUCHSCREEN_USB_3M=y +CONFIG_TOUCHSCREEN_USB_ITM=y +CONFIG_TOUCHSCREEN_USB_ETURBO=y +CONFIG_TOUCHSCREEN_USB_GUNZE=y +CONFIG_TOUCHSCREEN_USB_DMC_TSC10=y +CONFIG_TOUCHSCREEN_USB_IRTOUCH=y +CONFIG_TOUCHSCREEN_USB_IDEALTEK=y +CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH=y +CONFIG_TOUCHSCREEN_USB_GOTOP=y +CONFIG_TOUCHSCREEN_USB_JASTEC=y +CONFIG_TOUCHSCREEN_USB_ELO=y +CONFIG_TOUCHSCREEN_USB_E2I=y +CONFIG_TOUCHSCREEN_USB_ZYTRONIC=y +CONFIG_TOUCHSCREEN_USB_ETT_TC45USB=y +CONFIG_TOUCHSCREEN_USB_NEXIO=y +CONFIG_TOUCHSCREEN_USB_EASYTOUCH=y +CONFIG_TOUCHSCREEN_TOUCHIT213=m +CONFIG_TOUCHSCREEN_TSC_SERIO=m +CONFIG_TOUCHSCREEN_TSC200X_CORE=m +CONFIG_TOUCHSCREEN_TSC2004=m +CONFIG_TOUCHSCREEN_TSC2005=m +CONFIG_TOUCHSCREEN_TSC2007=m +CONFIG_TOUCHSCREEN_TSC2007_IIO=y +CONFIG_TOUCHSCREEN_RM_TS=m +CONFIG_TOUCHSCREEN_SILEAD=m +CONFIG_TOUCHSCREEN_SIS_I2C=m +CONFIG_TOUCHSCREEN_ST1232=m +CONFIG_TOUCHSCREEN_STMFTS=m +CONFIG_TOUCHSCREEN_SUN4I=m +CONFIG_TOUCHSCREEN_SUR40=m +CONFIG_TOUCHSCREEN_SURFACE3_SPI=m +CONFIG_TOUCHSCREEN_SX8654=m +CONFIG_TOUCHSCREEN_TPS6507X=m +CONFIG_TOUCHSCREEN_ZET6223=m +CONFIG_TOUCHSCREEN_ZFORCE=m +CONFIG_TOUCHSCREEN_ROHM_BU21023=m +CONFIG_TOUCHSCREEN_IQS5XX=m +# CONFIG_TOUCHSCREEN_ZINITIX is not set +CONFIG_INPUT_MISC=y +# CONFIG_INPUT_AD714X 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 +CONFIG_INPUT_GPIO_VIBRA=m +# CONFIG_INPUT_ATI_REMOTE2 is not set +# CONFIG_INPUT_KEYSPAN_REMOTE is not set +# CONFIG_INPUT_KXTJ9 is not set +# CONFIG_INPUT_POWERMATE is not set +# 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=y +# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set +CONFIG_INPUT_DA7280_HAPTICS=m +# CONFIG_INPUT_ADXL34X is not set +# CONFIG_INPUT_IMS_PCU is not set +# CONFIG_INPUT_IQS269A is not set +CONFIG_INPUT_IQS626A=m +# CONFIG_INPUT_CMA3000 is not set +CONFIG_INPUT_XEN_KBDDEV_FRONTEND=y +# 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_RMI4_CORE=m +CONFIG_RMI4_I2C=m +CONFIG_RMI4_SPI=m +CONFIG_RMI4_SMB=m +CONFIG_RMI4_F03=y +CONFIG_RMI4_F03_SERIO=m +CONFIG_RMI4_2D_SENSOR=y +CONFIG_RMI4_F11=y +CONFIG_RMI4_F12=y +CONFIG_RMI4_F30=y +# CONFIG_RMI4_F34 is not set +# CONFIG_RMI4_F3A is not set +# CONFIG_RMI4_F54 is not set +# CONFIG_RMI4_F55 is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_SERPORT=m +CONFIG_SERIO_AMBAKMI=y +# CONFIG_SERIO_PCIPS2 is not set +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_SERIO_ALTERA_PS2 is not set +# CONFIG_SERIO_PS2MULT is not set +# CONFIG_SERIO_ARC_PS2 is not set +# CONFIG_SERIO_APBPS2 is not set +CONFIG_SERIO_SUN4I_PS2=m +# CONFIG_SERIO_GPIO_PS2 is not set +# CONFIG_USERIO is not set +# CONFIG_GAMEPORT is not set +# end of Hardware I/O ports +# end of Input device support + +# +# Character devices +# +CONFIG_TTY=y +CONFIG_VT=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_VT_CONSOLE=y +CONFIG_VT_CONSOLE_SLEEP=y +CONFIG_HW_CONSOLE=y +CONFIG_VT_HW_CONSOLE_BINDING=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=0 +CONFIG_LDISC_AUTOLOAD=y + +# +# Serial drivers +# +CONFIG_SERIAL_EARLYCON=y +CONFIG_SERIAL_8250=y +# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set +CONFIG_SERIAL_8250_16550A_VARIANTS=y +CONFIG_SERIAL_8250_FINTEK=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_DMA=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 is not set +# CONFIG_SERIAL_8250_ASPEED_VUART is not set +CONFIG_SERIAL_8250_DWLIB=y +CONFIG_SERIAL_8250_FSL=y +CONFIG_SERIAL_8250_DW=y +# CONFIG_SERIAL_8250_RT288X is not set +CONFIG_SERIAL_OF_PLATFORM=y + +# +# Non-8250 serial port support +# +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_MESON=y +CONFIG_SERIAL_MESON_CONSOLE=y +# CONFIG_SERIAL_MAX3100 is not set +# CONFIG_SERIAL_MAX310X is not set +# CONFIG_SERIAL_UARTLITE is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_SERIAL_JSM=m +CONFIG_SERIAL_SIFIVE=m +CONFIG_SERIAL_SCCNXP=y +CONFIG_SERIAL_SCCNXP_CONSOLE=y +CONFIG_SERIAL_SC16IS7XX_CORE=m +CONFIG_SERIAL_SC16IS7XX=m +CONFIG_SERIAL_SC16IS7XX_I2C=y +CONFIG_SERIAL_SC16IS7XX_SPI=y +CONFIG_SERIAL_BCM63XX=m +CONFIG_SERIAL_ALTERA_JTAGUART=m +CONFIG_SERIAL_ALTERA_UART=m +CONFIG_SERIAL_ALTERA_UART_MAXPORTS=4 +CONFIG_SERIAL_ALTERA_UART_BAUDRATE=115200 +CONFIG_SERIAL_XILINX_PS_UART=y +CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=y +CONFIG_SERIAL_ARC=m +CONFIG_SERIAL_ARC_NR_PORTS=1 +CONFIG_SERIAL_RP2=m +CONFIG_SERIAL_RP2_NR_UARTS=32 +CONFIG_SERIAL_FSL_LPUART=m +CONFIG_SERIAL_FSL_LINFLEXUART=m +CONFIG_SERIAL_CONEXANT_DIGICOLOR=m +CONFIG_SERIAL_SPRD=m +CONFIG_SERIAL_LITEUART=m +CONFIG_SERIAL_LITEUART_MAX_PORTS=1 +# end of Serial drivers + +CONFIG_SERIAL_MCTRL_GPIO=y +CONFIG_SERIAL_NONSTANDARD=y +CONFIG_MOXA_INTELLIO=m +CONFIG_MOXA_SMARTIO=m +CONFIG_SYNCLINK_GT=m +CONFIG_N_HDLC=m +CONFIG_N_GSM=m +CONFIG_NOZOMI=m +CONFIG_NULL_TTY=m +CONFIG_HVC_DRIVER=y +CONFIG_HVC_IRQ=y +CONFIG_HVC_XEN=y +CONFIG_HVC_XEN_FRONTEND=y +# CONFIG_HVC_DCC is not set +CONFIG_SERIAL_DEV_BUS=y +CONFIG_SERIAL_DEV_CTRL_TTYPORT=y +CONFIG_TTY_PRINTK=m +CONFIG_TTY_PRINTK_LEVEL=6 +CONFIG_VIRTIO_CONSOLE=y +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMB_DEVICE_INTERFACE is not set +CONFIG_HW_RANDOM=m +# CONFIG_HW_RANDOM_TIMERIOMEM is not set +# CONFIG_HW_RANDOM_BA431 is not set +# CONFIG_HW_RANDOM_VIRTIO is not set +CONFIG_HW_RANDOM_MESON=m +CONFIG_HW_RANDOM_CAVIUM=m +# CONFIG_HW_RANDOM_CCTRNG is not set +# CONFIG_HW_RANDOM_XIPHERA is not set +CONFIG_HW_RANDOM_ARM_SMCCC_TRNG=m +# CONFIG_APPLICOM is not set +CONFIG_DEVMEM=y +CONFIG_DEVPORT=y +# CONFIG_TCG_TPM is not set +CONFIG_XILLYBUS_CLASS=m +# CONFIG_XILLYBUS is not set +CONFIG_XILLYUSB=m +# CONFIG_RANDOM_TRUST_CPU is not set +# CONFIG_RANDOM_TRUST_BOOTLOADER is not set +# end of Character devices + +# +# I2C support +# +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_COMPAT=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_MUX=m + +# +# Multiplexer I2C Chip support +# +CONFIG_I2C_ARB_GPIO_CHALLENGE=m +CONFIG_I2C_MUX_GPIO=m +CONFIG_I2C_MUX_GPMUX=m +CONFIG_I2C_MUX_LTC4306=m +CONFIG_I2C_MUX_PCA9541=m +CONFIG_I2C_MUX_PCA954x=m +CONFIG_I2C_MUX_PINCTRL=m +CONFIG_I2C_MUX_REG=m +CONFIG_I2C_DEMUX_PINCTRL=m +CONFIG_I2C_MUX_MLXCPLD=m +# end of Multiplexer I2C Chip support + +CONFIG_I2C_HELPER_AUTO=y +CONFIG_I2C_SMBUS=m +CONFIG_I2C_ALGOBIT=y + +# +# I2C Hardware Bus support +# + +# +# PC SMBus host controller drivers +# +# CONFIG_I2C_ALI1535 is not set +# CONFIG_I2C_ALI1563 is not set +# CONFIG_I2C_ALI15X3 is not set +# CONFIG_I2C_AMD756 is not set +# CONFIG_I2C_AMD8111 is not set +# CONFIG_I2C_I801 is not set +# CONFIG_I2C_ISCH is not set +# CONFIG_I2C_PIIX4 is not set +# CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_NVIDIA_GPU is not set +# CONFIG_I2C_SIS5595 is not set +# CONFIG_I2C_SIS630 is not set +# CONFIG_I2C_SIS96X is not set +# CONFIG_I2C_VIA is not set +# CONFIG_I2C_VIAPRO is not set + +# +# I2C system bus drivers (mostly embedded / system-on-chip) +# +CONFIG_I2C_CADENCE=m +CONFIG_I2C_CBUS_GPIO=m +CONFIG_I2C_DESIGNWARE_CORE=y +# CONFIG_I2C_DESIGNWARE_SLAVE is not set +CONFIG_I2C_DESIGNWARE_PLATFORM=y +# CONFIG_I2C_DESIGNWARE_PCI is not set +# CONFIG_I2C_EMEV2 is not set +# CONFIG_I2C_GPIO is not set +CONFIG_I2C_MESON=m +CONFIG_I2C_MV64XXX=m +# CONFIG_I2C_NOMADIK is not set +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_PCA_PLATFORM is not set +CONFIG_I2C_RK3X=y +# CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_THUNDERX is not set +# CONFIG_I2C_XILINX is not set + +# +# External I2C/SMBus adapter drivers +# +CONFIG_I2C_DIOLAN_U2C=m +CONFIG_I2C_CP2615=m +CONFIG_I2C_ROBOTFUZZ_OSIF=m +CONFIG_I2C_TAOS_EVM=m +CONFIG_I2C_TINY_USB=m + +# +# Other I2C/SMBus bus drivers +# +CONFIG_I2C_CROS_EC_TUNNEL=y +CONFIG_I2C_VIRTIO=m +# end of I2C Hardware Bus support + +CONFIG_I2C_STUB=m +CONFIG_I2C_SLAVE=y +CONFIG_I2C_SLAVE_EEPROM=m +# CONFIG_I2C_SLAVE_TESTUNIT is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# end of I2C support + +CONFIG_I3C=m +CONFIG_CDNS_I3C_MASTER=m +CONFIG_DW_I3C_MASTER=m +CONFIG_SVC_I3C_MASTER=m +CONFIG_MIPI_I3C_HCI=m +CONFIG_SPI=y +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_MASTER=y +CONFIG_SPI_MEM=y + +# +# SPI Master Controller Drivers +# +CONFIG_SPI_ALTERA=m +CONFIG_SPI_ALTERA_CORE=m +CONFIG_SPI_AXI_SPI_ENGINE=m +CONFIG_SPI_BITBANG=m +CONFIG_SPI_CADENCE=m +# CONFIG_SPI_CADENCE_QUADSPI is not set +# CONFIG_SPI_CADENCE_XSPI is not set +CONFIG_SPI_DESIGNWARE=m +# CONFIG_SPI_DW_DMA is not set +CONFIG_SPI_DW_PCI=m +CONFIG_SPI_DW_MMIO=m +CONFIG_SPI_NXP_FLEXSPI=m +CONFIG_SPI_GPIO=m +CONFIG_SPI_FSL_LIB=m +CONFIG_SPI_FSL_SPI=m +CONFIG_SPI_MESON_SPICC=m +CONFIG_SPI_MESON_SPIFC=m +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_SC18IS602 is not set +# CONFIG_SPI_SIFIVE is not set +CONFIG_SPI_SUN4I=m +CONFIG_SPI_SUN6I=m +CONFIG_SPI_MXIC=m +# CONFIG_SPI_THUNDERX is not set +# CONFIG_SPI_XCOMM is not set +# CONFIG_SPI_XILINX is not set +# CONFIG_SPI_ZYNQMP_GQSPI is not set +# CONFIG_SPI_AMD is not set + +# +# SPI Multiplexer support +# +CONFIG_SPI_MUX=m + +# +# SPI Protocol Masters +# +CONFIG_SPI_SPIDEV=m +CONFIG_SPI_LOOPBACK_TEST=m +CONFIG_SPI_TLE62X0=m +CONFIG_SPI_SLAVE=y +CONFIG_SPI_SLAVE_TIME=m +CONFIG_SPI_SLAVE_SYSTEM_CONTROL=m +CONFIG_SPI_DYNAMIC=y +CONFIG_SPMI=y +# CONFIG_SPMI_HISI3670 is not set +# CONFIG_HSI is not set +CONFIG_PPS=y +# CONFIG_PPS_DEBUG is not set + +# +# PPS clients support +# +# CONFIG_PPS_CLIENT_KTIMER is not set +CONFIG_PPS_CLIENT_LDISC=m +CONFIG_PPS_CLIENT_GPIO=m + +# +# PPS generators support +# + +# +# PTP clock support +# +CONFIG_PTP_1588_CLOCK=y +CONFIG_PTP_1588_CLOCK_OPTIONAL=y +CONFIG_DP83640_PHY=m +CONFIG_PTP_1588_CLOCK_INES=m +CONFIG_PTP_1588_CLOCK_KVM=m +CONFIG_PTP_1588_CLOCK_IDT82P33=m +CONFIG_PTP_1588_CLOCK_IDTCM=m +CONFIG_PTP_1588_CLOCK_OCP=m +# end of PTP clock support + +CONFIG_PINCTRL=y +CONFIG_GENERIC_PINCTRL_GROUPS=y +CONFIG_PINMUX=y +CONFIG_GENERIC_PINMUX_FUNCTIONS=y +CONFIG_PINCONF=y +CONFIG_GENERIC_PINCONF=y +# CONFIG_DEBUG_PINCTRL is not set +CONFIG_PINCTRL_AS3722=m +CONFIG_PINCTRL_AXP209=m +# CONFIG_PINCTRL_MCP23S08 is not set +CONFIG_PINCTRL_ROCKCHIP=y +CONFIG_PINCTRL_SINGLE=y +CONFIG_PINCTRL_SX150X=y +CONFIG_PINCTRL_STMFX=m +CONFIG_PINCTRL_MAX77620=y +CONFIG_PINCTRL_RK805=y +# CONFIG_PINCTRL_OCELOT is not set +# CONFIG_PINCTRL_MICROCHIP_SGPIO is not set + +# +# Renesas pinctrl drivers +# +# end of Renesas pinctrl drivers + +CONFIG_PINCTRL_SUNXI=y +# CONFIG_PINCTRL_SUN4I_A10 is not set +CONFIG_PINCTRL_SUN5I=y +CONFIG_PINCTRL_SUN6I_A31=y +CONFIG_PINCTRL_SUN6I_A31_R=y +CONFIG_PINCTRL_SUN8I_A23=y +CONFIG_PINCTRL_SUN8I_A33=y +CONFIG_PINCTRL_SUN8I_A83T=y +CONFIG_PINCTRL_SUN8I_A83T_R=y +CONFIG_PINCTRL_SUN8I_A23_R=y +CONFIG_PINCTRL_SUN8I_H3=y +CONFIG_PINCTRL_SUN8I_H3_R=y +CONFIG_PINCTRL_SUN8I_V3S=y +CONFIG_PINCTRL_SUN9I_A80=y +CONFIG_PINCTRL_SUN9I_A80_R=y +CONFIG_PINCTRL_SUN50I_A64=y +CONFIG_PINCTRL_SUN50I_A64_R=y +CONFIG_PINCTRL_SUN50I_A100=y +CONFIG_PINCTRL_SUN50I_A100_R=y +CONFIG_PINCTRL_SUN50I_H5=y +CONFIG_PINCTRL_SUN50I_H6=y +CONFIG_PINCTRL_SUN50I_H6_R=y +CONFIG_PINCTRL_SUN50I_H616=y +CONFIG_PINCTRL_SUN50I_H616_R=y +CONFIG_PINCTRL_MESON=y +CONFIG_PINCTRL_MESON_GXBB=y +CONFIG_PINCTRL_MESON_GXL=y +CONFIG_PINCTRL_MESON8_PMX=y +CONFIG_PINCTRL_MESON_AXG=y +CONFIG_PINCTRL_MESON_AXG_PMX=y +CONFIG_PINCTRL_MESON_G12A=y +CONFIG_PINCTRL_MESON_A1=y +CONFIG_GPIOLIB=y +CONFIG_GPIOLIB_FASTPATH_LIMIT=512 +CONFIG_OF_GPIO=y +CONFIG_GPIOLIB_IRQCHIP=y +# CONFIG_DEBUG_GPIO is not set +CONFIG_GPIO_SYSFS=y +CONFIG_GPIO_CDEV=y +CONFIG_GPIO_CDEV_V1=y +CONFIG_GPIO_GENERIC=y +CONFIG_GPIO_MAX730X=m + +# +# Memory mapped GPIO drivers +# +CONFIG_GPIO_74XX_MMIO=m +CONFIG_GPIO_ALTERA=m +CONFIG_GPIO_CADENCE=m +CONFIG_GPIO_DWAPB=m +CONFIG_GPIO_EXAR=m +# CONFIG_GPIO_FTGPIO010 is not set +CONFIG_GPIO_GENERIC_PLATFORM=y +CONFIG_GPIO_GRGPIO=m +CONFIG_GPIO_HLWD=m +CONFIG_GPIO_LOGICVC=m +CONFIG_GPIO_MB86S7X=m +CONFIG_GPIO_PL061=y +CONFIG_GPIO_ROCKCHIP=y +CONFIG_GPIO_SAMA5D2_PIOBU=m +# CONFIG_GPIO_SIFIVE is not set +CONFIG_GPIO_SYSCON=m +# CONFIG_GPIO_XGENE is not set +CONFIG_GPIO_XILINX=y +CONFIG_GPIO_AMD_FCH=m +# end of Memory mapped GPIO drivers + +# +# I2C GPIO expanders +# +CONFIG_GPIO_ADP5588=m +CONFIG_GPIO_ADNP=m +CONFIG_GPIO_GW_PLD=m +CONFIG_GPIO_MAX7300=m +CONFIG_GPIO_MAX732X=m +CONFIG_GPIO_PCA953X=y +CONFIG_GPIO_PCA953X_IRQ=y +# CONFIG_GPIO_PCA9570 is not set +CONFIG_GPIO_PCF857X=m +CONFIG_GPIO_TPIC2810=m +# end of I2C GPIO expanders + +# +# MFD GPIO expanders +# +CONFIG_GPIO_ADP5520=m +CONFIG_GPIO_BD70528=m +CONFIG_GPIO_BD71815=m +CONFIG_GPIO_BD71828=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 + +# +# PCI GPIO expanders +# +CONFIG_GPIO_BT8XX=m +CONFIG_GPIO_PCI_IDIO_16=m +CONFIG_GPIO_PCIE_IDIO_24=m +CONFIG_GPIO_RDC321X=m +# end of PCI GPIO expanders + +# +# SPI GPIO expanders +# +CONFIG_GPIO_74X164=m +CONFIG_GPIO_MAX3191X=m +CONFIG_GPIO_MAX7301=m +CONFIG_GPIO_MC33880=m +CONFIG_GPIO_PISOSR=m +CONFIG_GPIO_XRA1403=m +# end of SPI GPIO expanders + +# +# USB GPIO expanders +# +# end of USB GPIO expanders + +# +# Virtual GPIO drivers +# +# CONFIG_GPIO_AGGREGATOR is not set +CONFIG_GPIO_MOCKUP=m +CONFIG_GPIO_VIRTIO=m +# end of Virtual GPIO drivers + +CONFIG_W1=m +CONFIG_W1_CON=y + +# +# 1-wire Bus Masters +# +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 + +# +# 1-wire Slaves +# +CONFIG_W1_SLAVE_THERM=m +CONFIG_W1_SLAVE_SMEM=m +CONFIG_W1_SLAVE_DS2405=m +CONFIG_W1_SLAVE_DS2408=m +CONFIG_W1_SLAVE_DS2408_READBACK=y +CONFIG_W1_SLAVE_DS2413=m +CONFIG_W1_SLAVE_DS2406=m +CONFIG_W1_SLAVE_DS2423=m +CONFIG_W1_SLAVE_DS2805=m +CONFIG_W1_SLAVE_DS2430=m +CONFIG_W1_SLAVE_DS2431=m +CONFIG_W1_SLAVE_DS2433=m +# CONFIG_W1_SLAVE_DS2433_CRC is not set +CONFIG_W1_SLAVE_DS2438=m +CONFIG_W1_SLAVE_DS250X=m +CONFIG_W1_SLAVE_DS2780=m +CONFIG_W1_SLAVE_DS2781=m +CONFIG_W1_SLAVE_DS28E04=m +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 is not set +# CONFIG_POWER_RESET_GPIO_RESTART is not set +# CONFIG_POWER_RESET_LTC2952 is not set +# CONFIG_POWER_RESET_REGULATOR is not set +# CONFIG_POWER_RESET_RESTART is not set +CONFIG_POWER_RESET_VEXPRESS=y +CONFIG_POWER_RESET_XGENE=y +CONFIG_POWER_RESET_SYSCON=y +# CONFIG_POWER_RESET_SYSCON_POWEROFF is not set +# CONFIG_SYSCON_REBOOT_MODE is not set +# CONFIG_NVMEM_REBOOT_MODE is not set +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_TEST_POWER is not set +CONFIG_CHARGER_ADP5061=m +CONFIG_BATTERY_CW2015=m +CONFIG_BATTERY_DS2760=m +CONFIG_BATTERY_DS2780=m +CONFIG_BATTERY_DS2781=m +CONFIG_BATTERY_DS2782=m +CONFIG_BATTERY_SBS=m +CONFIG_CHARGER_SBS=m +CONFIG_MANAGER_SBS=m +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 +CONFIG_CHARGER_ISP1704=m +# CONFIG_CHARGER_MAX8903 is not set +# CONFIG_CHARGER_LP8727 is not set +CONFIG_CHARGER_GPIO=m +# CONFIG_CHARGER_MANAGER is not set +CONFIG_CHARGER_LT3651=m +CONFIG_CHARGER_LTC4162L=m +CONFIG_CHARGER_DETECTOR_MAX14656=m +CONFIG_CHARGER_MAX77650=m +# CONFIG_CHARGER_BQ2415X is not set +# CONFIG_CHARGER_BQ24190 is not set +# CONFIG_CHARGER_BQ24257 is not set +# CONFIG_CHARGER_BQ24735 is not set +# CONFIG_CHARGER_BQ2515X is not set +# CONFIG_CHARGER_BQ25890 is not set +# CONFIG_CHARGER_BQ25980 is not set +CONFIG_CHARGER_BQ256XX=m +# CONFIG_CHARGER_SMB347 is not set +# CONFIG_BATTERY_GAUGE_LTC2941 is not set +CONFIG_BATTERY_GOLDFISH=m +CONFIG_BATTERY_RT5033=m +# CONFIG_CHARGER_RT9455 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_HWMON=y +CONFIG_HWMON_VID=m +# CONFIG_HWMON_DEBUG_CHIP is not set + +# +# Native drivers +# +CONFIG_SENSORS_AD7314=m +CONFIG_SENSORS_AD7414=m +CONFIG_SENSORS_AD7418=m +CONFIG_SENSORS_ADM1021=m +CONFIG_SENSORS_ADM1025=m +CONFIG_SENSORS_ADM1026=m +CONFIG_SENSORS_ADM1029=m +CONFIG_SENSORS_ADM1031=m +CONFIG_SENSORS_ADM1177=m +CONFIG_SENSORS_ADM9240=m +CONFIG_SENSORS_ADT7X10=m +CONFIG_SENSORS_ADT7310=m +CONFIG_SENSORS_ADT7410=m +CONFIG_SENSORS_ADT7411=m +CONFIG_SENSORS_ADT7462=m +CONFIG_SENSORS_ADT7470=m +CONFIG_SENSORS_ADT7475=m +CONFIG_SENSORS_AHT10=m +CONFIG_SENSORS_AQUACOMPUTER_D5NEXT=m +CONFIG_SENSORS_AS370=m +CONFIG_SENSORS_ASC7621=m +CONFIG_SENSORS_AXI_FAN_CONTROL=m +CONFIG_SENSORS_ARM_SCPI=m +CONFIG_SENSORS_ASPEED=m +CONFIG_SENSORS_ATXP1=m +# CONFIG_SENSORS_CORSAIR_CPRO is not set +CONFIG_SENSORS_CORSAIR_PSU=m +CONFIG_SENSORS_DRIVETEMP=m +CONFIG_SENSORS_DS620=m +CONFIG_SENSORS_DS1621=m +CONFIG_SENSORS_I5K_AMB=m +CONFIG_SENSORS_F71805F=m +CONFIG_SENSORS_F71882FG=m +CONFIG_SENSORS_F75375S=m +CONFIG_SENSORS_FTSTEUTATES=m +CONFIG_SENSORS_GL518SM=m +CONFIG_SENSORS_GL520SM=m +CONFIG_SENSORS_G760A=m +CONFIG_SENSORS_G762=m +CONFIG_SENSORS_GPIO_FAN=m +CONFIG_SENSORS_HIH6130=m +CONFIG_SENSORS_IIO_HWMON=m +CONFIG_SENSORS_IT87=m +CONFIG_SENSORS_JC42=m +CONFIG_SENSORS_POWR1220=m +CONFIG_SENSORS_LINEAGE=m +CONFIG_SENSORS_LTC2945=m +CONFIG_SENSORS_LTC2947=m +CONFIG_SENSORS_LTC2947_I2C=m +CONFIG_SENSORS_LTC2947_SPI=m +CONFIG_SENSORS_LTC2990=m +CONFIG_SENSORS_LTC2992=m +CONFIG_SENSORS_LTC4151=m +CONFIG_SENSORS_LTC4215=m +CONFIG_SENSORS_LTC4222=m +CONFIG_SENSORS_LTC4245=m +CONFIG_SENSORS_LTC4260=m +CONFIG_SENSORS_LTC4261=m +CONFIG_SENSORS_MAX1111=m +CONFIG_SENSORS_MAX127=m +CONFIG_SENSORS_MAX16065=m +CONFIG_SENSORS_MAX1619=m +CONFIG_SENSORS_MAX1668=m +CONFIG_SENSORS_MAX197=m +CONFIG_SENSORS_MAX31722=m +CONFIG_SENSORS_MAX31730=m +# CONFIG_SENSORS_MAX6620 is not set +CONFIG_SENSORS_MAX6621=m +CONFIG_SENSORS_MAX6639=m +CONFIG_SENSORS_MAX6642=m +CONFIG_SENSORS_MAX6650=m +CONFIG_SENSORS_MAX6697=m +CONFIG_SENSORS_MAX31790=m +CONFIG_SENSORS_MCP3021=m +CONFIG_SENSORS_TC654=m +CONFIG_SENSORS_TPS23861=m +# CONFIG_SENSORS_MR75203 is not set +CONFIG_SENSORS_ADCXX=m +CONFIG_SENSORS_LM63=m +CONFIG_SENSORS_LM70=m +CONFIG_SENSORS_LM73=m +CONFIG_SENSORS_LM75=m +CONFIG_SENSORS_LM77=m +CONFIG_SENSORS_LM78=m +CONFIG_SENSORS_LM80=m +CONFIG_SENSORS_LM83=m +CONFIG_SENSORS_LM85=m +CONFIG_SENSORS_LM87=m +CONFIG_SENSORS_LM90=m +CONFIG_SENSORS_LM92=m +CONFIG_SENSORS_LM93=m +CONFIG_SENSORS_LM95234=m +CONFIG_SENSORS_LM95241=m +CONFIG_SENSORS_LM95245=m +CONFIG_SENSORS_PC87360=m +CONFIG_SENSORS_PC87427=m +CONFIG_SENSORS_NTC_THERMISTOR=m +CONFIG_SENSORS_NCT6683=m +CONFIG_SENSORS_NCT6775=m +CONFIG_SENSORS_NCT7802=m +CONFIG_SENSORS_NCT7904=m +CONFIG_SENSORS_NPCM7XX=m +CONFIG_SENSORS_NZXT_KRAKEN2=m +CONFIG_SENSORS_OCC_P8_I2C=m +CONFIG_SENSORS_OCC=m +CONFIG_SENSORS_PCF8591=m +CONFIG_PMBUS=m +CONFIG_SENSORS_PMBUS=m +# CONFIG_SENSORS_ADM1266 is not set +CONFIG_SENSORS_ADM1275=m +CONFIG_SENSORS_BEL_PFE=m +CONFIG_SENSORS_BPA_RS600=m +CONFIG_SENSORS_FSP_3Y=m +CONFIG_SENSORS_IBM_CFFPS=m +CONFIG_SENSORS_DPS920AB=m +CONFIG_SENSORS_INSPUR_IPSPS=m +CONFIG_SENSORS_IR35221=m +CONFIG_SENSORS_IR36021=m +CONFIG_SENSORS_IR38064=m +CONFIG_SENSORS_IRPS5401=m +CONFIG_SENSORS_ISL68137=m +CONFIG_SENSORS_LM25066=m +CONFIG_SENSORS_LTC2978=m +CONFIG_SENSORS_LTC2978_REGULATOR=y +CONFIG_SENSORS_LTC3815=m +CONFIG_SENSORS_MAX15301=m +CONFIG_SENSORS_MAX16064=m +# CONFIG_SENSORS_MAX16601 is not set +CONFIG_SENSORS_MAX20730=m +CONFIG_SENSORS_MAX20751=m +CONFIG_SENSORS_MAX31785=m +CONFIG_SENSORS_MAX34440=m +CONFIG_SENSORS_MAX8688=m +CONFIG_SENSORS_MP2888=m +# CONFIG_SENSORS_MP2975 is not set +CONFIG_SENSORS_PIM4328=m +CONFIG_SENSORS_PM6764TR=m +CONFIG_SENSORS_PXE1610=m +CONFIG_SENSORS_Q54SJ108A2=m +CONFIG_SENSORS_STPDDC60=m +CONFIG_SENSORS_TPS40422=m +CONFIG_SENSORS_TPS53679=m +CONFIG_SENSORS_UCD9000=m +CONFIG_SENSORS_UCD9200=m +CONFIG_SENSORS_XDPE122=m +CONFIG_SENSORS_ZL6100=m +CONFIG_SENSORS_PWM_FAN=m +CONFIG_SENSORS_SBTSI=m +CONFIG_SENSORS_SBRMI=m +CONFIG_SENSORS_SHT15=m +CONFIG_SENSORS_SHT21=m +CONFIG_SENSORS_SHT3x=m +CONFIG_SENSORS_SHT4x=m +CONFIG_SENSORS_SHTC1=m +CONFIG_SENSORS_SIS5595=m +CONFIG_SENSORS_DME1737=m +CONFIG_SENSORS_EMC1403=m +CONFIG_SENSORS_EMC2103=m +CONFIG_SENSORS_EMC6W201=m +CONFIG_SENSORS_SMSC47M1=m +CONFIG_SENSORS_SMSC47M192=m +CONFIG_SENSORS_SMSC47B397=m +CONFIG_SENSORS_SCH56XX_COMMON=m +CONFIG_SENSORS_SCH5627=m +CONFIG_SENSORS_SCH5636=m +CONFIG_SENSORS_STTS751=m +CONFIG_SENSORS_SMM665=m +CONFIG_SENSORS_ADC128D818=m +CONFIG_SENSORS_ADS7828=m +CONFIG_SENSORS_ADS7871=m +CONFIG_SENSORS_AMC6821=m +CONFIG_SENSORS_INA209=m +CONFIG_SENSORS_INA2XX=m +CONFIG_SENSORS_INA3221=m +CONFIG_SENSORS_TC74=m +CONFIG_SENSORS_THMC50=m +CONFIG_SENSORS_TMP102=m +CONFIG_SENSORS_TMP103=m +CONFIG_SENSORS_TMP108=m +CONFIG_SENSORS_TMP401=m +CONFIG_SENSORS_TMP421=m +CONFIG_SENSORS_TMP513=m +CONFIG_SENSORS_VEXPRESS=m +CONFIG_SENSORS_VIA686A=m +CONFIG_SENSORS_VT1211=m +CONFIG_SENSORS_VT8231=m +CONFIG_SENSORS_W83773G=m +CONFIG_SENSORS_W83781D=m +CONFIG_SENSORS_W83791D=m +CONFIG_SENSORS_W83792D=m +CONFIG_SENSORS_W83793=m +CONFIG_SENSORS_W83795=m +# CONFIG_SENSORS_W83795_FANCTRL is not set +CONFIG_SENSORS_W83L785TS=m +CONFIG_SENSORS_W83L786NG=m +CONFIG_SENSORS_W83627HF=m +CONFIG_SENSORS_W83627EHF=m +CONFIG_THERMAL=y +# CONFIG_THERMAL_NETLINK is not set +CONFIG_THERMAL_STATISTICS=y +CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0 +CONFIG_THERMAL_HWMON=y +CONFIG_THERMAL_OF=y +CONFIG_THERMAL_WRITABLE_TRIPS=y +CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y +# CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set +# CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set +CONFIG_THERMAL_GOV_FAIR_SHARE=y +CONFIG_THERMAL_GOV_STEP_WISE=y +CONFIG_THERMAL_GOV_BANG_BANG=y +CONFIG_THERMAL_GOV_USER_SPACE=y +CONFIG_CPU_THERMAL=y +CONFIG_CPU_FREQ_THERMAL=y +CONFIG_DEVFREQ_THERMAL=y +CONFIG_THERMAL_EMULATION=y +CONFIG_THERMAL_MMIO=m +# CONFIG_MAX77620_THERMAL is not set +CONFIG_SUN8I_THERMAL=m +CONFIG_ROCKCHIP_THERMAL=y +CONFIG_AMLOGIC_THERMAL=y +# CONFIG_GENERIC_ADC_THERMAL is not set +CONFIG_WATCHDOG=y +CONFIG_WATCHDOG_CORE=y +# CONFIG_WATCHDOG_NOWAYOUT is not set +CONFIG_WATCHDOG_HANDLE_BOOT_ENABLED=y +CONFIG_WATCHDOG_OPEN_TIMEOUT=0 +CONFIG_WATCHDOG_SYSFS=y +# CONFIG_WATCHDOG_HRTIMER_PRETIMEOUT is not set + +# +# Watchdog Pretimeout Governors +# +# CONFIG_WATCHDOG_PRETIMEOUT_GOV is not set + +# +# Watchdog Device Drivers +# +CONFIG_SOFT_WATCHDOG=m +CONFIG_BD957XMUF_WATCHDOG=m +# CONFIG_GPIO_WATCHDOG is not set +# CONFIG_XILINX_WATCHDOG is not set +# CONFIG_ZIIRAVE_WATCHDOG is not set +CONFIG_RAVE_SP_WATCHDOG=m +# CONFIG_ARM_SP805_WATCHDOG is not set +# CONFIG_ARM_SBSA_WATCHDOG is not set +# CONFIG_CADENCE_WATCHDOG is not set +CONFIG_DW_WATCHDOG=y +CONFIG_RN5T618_WATCHDOG=m +CONFIG_SUNXI_WATCHDOG=m +# CONFIG_MAX63XX_WATCHDOG is not set +# CONFIG_MAX77620_WATCHDOG is not set +CONFIG_MESON_GXBB_WATCHDOG=m +CONFIG_MESON_WATCHDOG=m +# CONFIG_ARM_SMC_WATCHDOG is not set +# CONFIG_ALIM7101_WDT is not set +# CONFIG_I6300ESB_WDT is not set +# CONFIG_MEN_A21_WDT is not set +# CONFIG_XEN_WDT is not set + +# +# PCI-based Watchdog Cards +# +CONFIG_PCIPCWATCHDOG=m +CONFIG_WDTPCI=m + +# +# USB-based Watchdog Cards +# +CONFIG_USBPCWATCHDOG=m +CONFIG_SSB_POSSIBLE=y +CONFIG_SSB=m +CONFIG_SSB_SPROM=y +CONFIG_SSB_BLOCKIO=y +CONFIG_SSB_PCIHOST_POSSIBLE=y +CONFIG_SSB_PCIHOST=y +CONFIG_SSB_B43_PCI_BRIDGE=y +CONFIG_SSB_SDIOHOST_POSSIBLE=y +# CONFIG_SSB_SDIOHOST is not set +CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y +CONFIG_SSB_DRIVER_PCICORE=y +# CONFIG_SSB_DRIVER_GPIO is not set +CONFIG_BCMA_POSSIBLE=y +CONFIG_BCMA=m +CONFIG_BCMA_BLOCKIO=y +CONFIG_BCMA_HOST_PCI_POSSIBLE=y +CONFIG_BCMA_HOST_PCI=y +# CONFIG_BCMA_HOST_SOC is not set +CONFIG_BCMA_DRIVER_PCI=y +# CONFIG_BCMA_DRIVER_GMAC_CMN is not set +# CONFIG_BCMA_DRIVER_GPIO is not set +# CONFIG_BCMA_DEBUG is not set + +# +# Multifunction device drivers +# +CONFIG_MFD_CORE=y +# CONFIG_MFD_ACT8945A is not set +CONFIG_MFD_SUN4I_GPADC=m +CONFIG_MFD_AS3711=y +CONFIG_MFD_AS3722=m +CONFIG_PMIC_ADP5520=y +CONFIG_MFD_AAT2870_CORE=y +# CONFIG_MFD_ATMEL_FLEXCOM is not set +# CONFIG_MFD_ATMEL_HLCDC is not set +# CONFIG_MFD_BCM590XX is not set +# CONFIG_MFD_BD9571MWV is not set +CONFIG_MFD_AC100=m +CONFIG_MFD_AXP20X=m +# CONFIG_MFD_AXP20X_I2C is not set +CONFIG_MFD_AXP20X_RSB=m +CONFIG_MFD_CROS_EC_DEV=y +# CONFIG_MFD_MADERA is not set +# CONFIG_PMIC_DA903X is not set +# CONFIG_MFD_DA9052_SPI is not set +# CONFIG_MFD_DA9052_I2C is not set +# CONFIG_MFD_DA9055 is not set +# CONFIG_MFD_DA9062 is not set +# CONFIG_MFD_DA9063 is not set +# CONFIG_MFD_DA9150 is not set +# CONFIG_MFD_DLN2 is not set +# CONFIG_MFD_GATEWORKS_GSC is not set +# CONFIG_MFD_MC13XXX_SPI is not set +# CONFIG_MFD_MC13XXX_I2C is not set +# CONFIG_MFD_MP2629 is not set +# CONFIG_MFD_HI6421_PMIC is not set +# CONFIG_MFD_HI6421_SPMI is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_HTC_I2CPLD is not set +# CONFIG_LPC_ICH is not set +# CONFIG_LPC_SCH is not set +CONFIG_MFD_IQS62X=m +# 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_MAX77686 is not set +# CONFIG_MFD_MAX77693 is not set +# CONFIG_MFD_MAX77843 is not set +# CONFIG_MFD_MAX8907 is not set +# CONFIG_MFD_MAX8925 is not set +# CONFIG_MFD_MAX8997 is not set +# CONFIG_MFD_MAX8998 is not set +# CONFIG_MFD_MT6360 is not set +# CONFIG_MFD_MT6397 is not set +# CONFIG_MFD_MENF21BMC is not set +# CONFIG_EZX_PCAP is not set +# CONFIG_MFD_CPCAP is not set +# CONFIG_MFD_VIPERBOARD is not set +CONFIG_MFD_NTXEC=m +# CONFIG_MFD_RETU is not set +# CONFIG_MFD_PCF50633 is not set +CONFIG_UCB1400_CORE=m +CONFIG_MFD_RDC321X=m +CONFIG_MFD_RT4831=m +CONFIG_MFD_RT5033=m +CONFIG_MFD_RC5T583=y +CONFIG_MFD_RK808=y +CONFIG_MFD_RN5T618=m +CONFIG_MFD_SEC_CORE=y +# CONFIG_MFD_SI476X_CORE is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_MFD_SKY81452 is not set +# CONFIG_MFD_STMPE is not set +CONFIG_MFD_SUN6I_PRCM=y +CONFIG_MFD_SYSCON=y +# CONFIG_MFD_TI_AM335X_TSCADC is not set +# CONFIG_MFD_LP3943 is not set +# CONFIG_MFD_LP8788 is not set +# CONFIG_MFD_TI_LMU is not set +# CONFIG_MFD_PALMAS is not set +# CONFIG_TPS6105X is not set +# CONFIG_TPS65010 is not set +# CONFIG_TPS6507X is not set +# CONFIG_MFD_TPS65086 is not set +# CONFIG_MFD_TPS65090 is not set +# CONFIG_MFD_TPS65217 is not set +# CONFIG_MFD_TI_LP873X is not set +# CONFIG_MFD_TI_LP87565 is not set +# CONFIG_MFD_TPS65218 is not set +# CONFIG_MFD_TPS6586X is not set +# CONFIG_MFD_TPS65910 is not set +# CONFIG_MFD_TPS65912_I2C is not set +# CONFIG_MFD_TPS65912_SPI is not set +# CONFIG_TWL4030_CORE is not set +# CONFIG_TWL6040_CORE is not set +CONFIG_MFD_WL1273_CORE=m +CONFIG_MFD_LM3533=m +# CONFIG_MFD_TC3589X is not set +CONFIG_MFD_TQMX86=m +CONFIG_MFD_VX855=m +# CONFIG_MFD_LOCHNAGAR 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 is not set +CONFIG_MFD_ROHM_BD70528=m +CONFIG_MFD_ROHM_BD71828=m +CONFIG_MFD_ROHM_BD957XMUF=m +# CONFIG_MFD_STPMIC1 is not set +CONFIG_MFD_STMFX=m +CONFIG_MFD_ATC260X=m +CONFIG_MFD_ATC260X_I2C=m +# CONFIG_MFD_KHADAS_MCU is not set +CONFIG_MFD_QCOM_PM8008=m +CONFIG_MFD_VEXPRESS_SYSREG=y +CONFIG_RAVE_SP_CORE=m +# CONFIG_MFD_INTEL_M10_BMC is not set +CONFIG_MFD_RSMU_I2C=m +CONFIG_MFD_RSMU_SPI=m +# end of Multifunction device drivers + +CONFIG_REGULATOR=y +# CONFIG_REGULATOR_DEBUG is not set +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_AD5398 is not set +CONFIG_REGULATOR_AAT2870=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_BD957XMUF=m +# CONFIG_REGULATOR_CROS_EC is not set +CONFIG_REGULATOR_DA9121=m +# CONFIG_REGULATOR_DA9210 is not set +# CONFIG_REGULATOR_DA9211 is not set +CONFIG_REGULATOR_FAN53555=y +# CONFIG_REGULATOR_FAN53880 is not set +CONFIG_REGULATOR_GPIO=y +# CONFIG_REGULATOR_ISL9305 is not set +# CONFIG_REGULATOR_ISL6271A is not set +# CONFIG_REGULATOR_LP3971 is not set +# CONFIG_REGULATOR_LP3972 is not set +# CONFIG_REGULATOR_LP872X is not set +# CONFIG_REGULATOR_LP8755 is not set +# 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 is not set +# CONFIG_REGULATOR_MAX77826 is not set +CONFIG_REGULATOR_MCP16502=m +CONFIG_REGULATOR_MP5416=m +CONFIG_REGULATOR_MP8859=m +CONFIG_REGULATOR_MP886X=m +CONFIG_REGULATOR_MPQ7920=m +# CONFIG_REGULATOR_MT6311 is not set +CONFIG_REGULATOR_MT6315=m +# CONFIG_REGULATOR_PCA9450 is not set +CONFIG_REGULATOR_PF8X00=m +# CONFIG_REGULATOR_PFUZE100 is not set +# CONFIG_REGULATOR_PV88060 is not set +# CONFIG_REGULATOR_PV88080 is not set +# CONFIG_REGULATOR_PV88090 is not set +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_RK808=y +CONFIG_REGULATOR_RN5T618=m +CONFIG_REGULATOR_ROHM=m +# CONFIG_REGULATOR_RT4801 is not set +CONFIG_REGULATOR_RT4831=m +CONFIG_REGULATOR_RT5033=m +CONFIG_REGULATOR_RT6160=m +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_SY8106A is not set +CONFIG_REGULATOR_SY8824X=m +# CONFIG_REGULATOR_SY8827N is not set +# CONFIG_REGULATOR_TPS51632 is not set +# CONFIG_REGULATOR_TPS62360 is not set +# CONFIG_REGULATOR_TPS65023 is not set +# CONFIG_REGULATOR_TPS6507X is not set +# CONFIG_REGULATOR_TPS65132 is not set +# CONFIG_REGULATOR_TPS6524X is not set +# CONFIG_REGULATOR_VCTRL is not set +# CONFIG_REGULATOR_VEXPRESS is not set +# CONFIG_REGULATOR_QCOM_LABIBB is not set +CONFIG_RC_CORE=m +CONFIG_RC_MAP=m +CONFIG_LIRC=y +CONFIG_RC_DECODERS=y +CONFIG_IR_NEC_DECODER=m +CONFIG_IR_RC5_DECODER=m +CONFIG_IR_RC6_DECODER=m +CONFIG_IR_JVC_DECODER=m +CONFIG_IR_SONY_DECODER=m +CONFIG_IR_SANYO_DECODER=m +CONFIG_IR_SHARP_DECODER=m +CONFIG_IR_MCE_KBD_DECODER=m +CONFIG_IR_XMP_DECODER=m +CONFIG_IR_IMON_DECODER=m +CONFIG_IR_RCMM_DECODER=m +CONFIG_RC_DEVICES=y +CONFIG_RC_ATI_REMOTE=m +CONFIG_IR_HIX5HD2=m +CONFIG_IR_IMON=m +CONFIG_IR_IMON_RAW=m +CONFIG_IR_MCEUSB=m +CONFIG_IR_MESON=m +CONFIG_IR_MESON_TX=m +CONFIG_IR_REDRAT3=m +CONFIG_IR_SPI=m +CONFIG_IR_STREAMZAP=m +CONFIG_IR_IGORPLUGUSB=m +CONFIG_IR_IGUANA=m +CONFIG_IR_TTUSBIR=m +CONFIG_RC_LOOPBACK=m +CONFIG_IR_GPIO_CIR=m +CONFIG_IR_GPIO_TX=m +CONFIG_IR_PWM_TX=m +CONFIG_IR_SUNXI=m +CONFIG_IR_SERIAL=m +CONFIG_IR_SERIAL_TRANSMITTER=y +CONFIG_RC_XBOX_DVD=m +# CONFIG_IR_TOY is not set +CONFIG_CEC_CORE=y +CONFIG_CEC_NOTIFIER=y +CONFIG_CEC_PIN=y + +# +# CEC support +# +CONFIG_CEC_PIN_ERROR_INJ=y +CONFIG_MEDIA_CEC_SUPPORT=y +# CONFIG_CEC_CH7322 is not set +# CONFIG_CEC_CROS_EC is not set +# CONFIG_CEC_MESON_AO is not set +# CONFIG_CEC_MESON_G12A_AO is not set +# CONFIG_CEC_GPIO is not set +CONFIG_USB_PULSE8_CEC=m +CONFIG_USB_RAINSHADOW_CEC=m +# end of CEC support + +CONFIG_MEDIA_SUPPORT=m +# CONFIG_MEDIA_SUPPORT_FILTER is not set +CONFIG_MEDIA_SUBDRV_AUTOSELECT=y + +# +# Media device types +# +CONFIG_MEDIA_CAMERA_SUPPORT=y +CONFIG_MEDIA_ANALOG_TV_SUPPORT=y +CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y +CONFIG_MEDIA_RADIO_SUPPORT=y +CONFIG_MEDIA_SDR_SUPPORT=y +CONFIG_MEDIA_PLATFORM_SUPPORT=y +CONFIG_MEDIA_TEST_SUPPORT=y +# end of Media device types + +# +# Media core support +# +CONFIG_VIDEO_DEV=m +CONFIG_MEDIA_CONTROLLER=y +CONFIG_DVB_CORE=m +# end of Media core support + +# +# Video4Linux options +# +CONFIG_VIDEO_V4L2=m +CONFIG_VIDEO_V4L2_I2C=y +CONFIG_VIDEO_V4L2_SUBDEV_API=y +# CONFIG_VIDEO_ADV_DEBUG is not set +CONFIG_VIDEO_FIXED_MINOR_RANGES=y +CONFIG_VIDEO_TUNER=m +CONFIG_V4L2_H264=m +CONFIG_V4L2_MEM2MEM_DEV=m +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 + +# +# Media controller options +# +CONFIG_MEDIA_CONTROLLER_DVB=y +CONFIG_MEDIA_CONTROLLER_REQUEST_API=y +# end of Media controller options + +# +# Digital TV options +# +CONFIG_DVB_MMAP=y +CONFIG_DVB_NET=y +CONFIG_DVB_MAX_ADAPTERS=8 +CONFIG_DVB_DYNAMIC_MINORS=y +# CONFIG_DVB_DEMUX_SECTION_LOSS_LOG is not set +# CONFIG_DVB_ULE_DEBUG is not set +# end of Digital TV options + +# +# Media drivers +# +CONFIG_MEDIA_USB_SUPPORT=y + +# +# Webcam devices +# +CONFIG_USB_VIDEO_CLASS=m +CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y +CONFIG_USB_GSPCA=m +CONFIG_USB_M5602=m +CONFIG_USB_STV06XX=m +CONFIG_USB_GL860=m +CONFIG_USB_GSPCA_BENQ=m +CONFIG_USB_GSPCA_CONEX=m +CONFIG_USB_GSPCA_CPIA1=m +CONFIG_USB_GSPCA_DTCS033=m +CONFIG_USB_GSPCA_ETOMS=m +CONFIG_USB_GSPCA_FINEPIX=m +CONFIG_USB_GSPCA_JEILINJ=m +CONFIG_USB_GSPCA_JL2005BCD=m +CONFIG_USB_GSPCA_KINECT=m +CONFIG_USB_GSPCA_KONICA=m +CONFIG_USB_GSPCA_MARS=m +CONFIG_USB_GSPCA_MR97310A=m +CONFIG_USB_GSPCA_NW80X=m +CONFIG_USB_GSPCA_OV519=m +CONFIG_USB_GSPCA_OV534=m +CONFIG_USB_GSPCA_OV534_9=m +CONFIG_USB_GSPCA_PAC207=m +CONFIG_USB_GSPCA_PAC7302=m +CONFIG_USB_GSPCA_PAC7311=m +CONFIG_USB_GSPCA_SE401=m +CONFIG_USB_GSPCA_SN9C2028=m +CONFIG_USB_GSPCA_SN9C20X=m +CONFIG_USB_GSPCA_SONIXB=m +CONFIG_USB_GSPCA_SONIXJ=m +CONFIG_USB_GSPCA_SPCA500=m +CONFIG_USB_GSPCA_SPCA501=m +CONFIG_USB_GSPCA_SPCA505=m +CONFIG_USB_GSPCA_SPCA506=m +CONFIG_USB_GSPCA_SPCA508=m +CONFIG_USB_GSPCA_SPCA561=m +CONFIG_USB_GSPCA_SPCA1528=m +CONFIG_USB_GSPCA_SQ905=m +CONFIG_USB_GSPCA_SQ905C=m +CONFIG_USB_GSPCA_SQ930X=m +CONFIG_USB_GSPCA_STK014=m +CONFIG_USB_GSPCA_STK1135=m +CONFIG_USB_GSPCA_STV0680=m +CONFIG_USB_GSPCA_SUNPLUS=m +CONFIG_USB_GSPCA_T613=m +CONFIG_USB_GSPCA_TOPRO=m +CONFIG_USB_GSPCA_TOUPTEK=m +CONFIG_USB_GSPCA_TV8532=m +CONFIG_USB_GSPCA_VC032X=m +CONFIG_USB_GSPCA_VICAM=m +CONFIG_USB_GSPCA_XIRLINK_CIT=m +CONFIG_USB_GSPCA_ZC3XX=m +CONFIG_USB_PWC=m +# CONFIG_USB_PWC_DEBUG is not set +CONFIG_USB_PWC_INPUT_EVDEV=y +CONFIG_VIDEO_CPIA2=m +CONFIG_USB_ZR364XX=m +CONFIG_USB_STKWEBCAM=m +CONFIG_USB_S2255=m +CONFIG_VIDEO_USBTV=m + +# +# Analog TV USB devices +# +CONFIG_VIDEO_PVRUSB2=m +CONFIG_VIDEO_PVRUSB2_SYSFS=y +CONFIG_VIDEO_PVRUSB2_DVB=y +# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set +CONFIG_VIDEO_HDPVR=m +CONFIG_VIDEO_STK1160_COMMON=m +CONFIG_VIDEO_STK1160=m +CONFIG_VIDEO_GO7007=m +CONFIG_VIDEO_GO7007_USB=m +CONFIG_VIDEO_GO7007_LOADER=m +CONFIG_VIDEO_GO7007_USB_S2250_BOARD=m + +# +# Analog/digital TV USB devices +# +CONFIG_VIDEO_AU0828=m +CONFIG_VIDEO_AU0828_V4L2=y +CONFIG_VIDEO_AU0828_RC=y +CONFIG_VIDEO_CX231XX=m +CONFIG_VIDEO_CX231XX_RC=y +CONFIG_VIDEO_CX231XX_ALSA=m +CONFIG_VIDEO_CX231XX_DVB=m +CONFIG_VIDEO_TM6000=m +CONFIG_VIDEO_TM6000_ALSA=m +CONFIG_VIDEO_TM6000_DVB=m + +# +# Digital TV USB devices +# +CONFIG_DVB_USB=m +# CONFIG_DVB_USB_DEBUG is not set +CONFIG_DVB_USB_DIB3000MC=m +CONFIG_DVB_USB_A800=m +CONFIG_DVB_USB_DIBUSB_MB=m +CONFIG_DVB_USB_DIBUSB_MB_FAULTY=y +CONFIG_DVB_USB_DIBUSB_MC=m +CONFIG_DVB_USB_DIB0700=m +CONFIG_DVB_USB_UMT_010=m +CONFIG_DVB_USB_CXUSB=m +# CONFIG_DVB_USB_CXUSB_ANALOG is not set +CONFIG_DVB_USB_M920X=m +CONFIG_DVB_USB_DIGITV=m +CONFIG_DVB_USB_VP7045=m +CONFIG_DVB_USB_VP702X=m +CONFIG_DVB_USB_GP8PSK=m +CONFIG_DVB_USB_NOVA_T_USB2=m +CONFIG_DVB_USB_TTUSB2=m +CONFIG_DVB_USB_DTT200U=m +CONFIG_DVB_USB_OPERA1=m +CONFIG_DVB_USB_AF9005=m +CONFIG_DVB_USB_AF9005_REMOTE=m +CONFIG_DVB_USB_PCTV452E=m +CONFIG_DVB_USB_DW2102=m +CONFIG_DVB_USB_CINERGY_T2=m +CONFIG_DVB_USB_DTV5100=m +CONFIG_DVB_USB_AZ6027=m +CONFIG_DVB_USB_TECHNISAT_USB2=m +CONFIG_DVB_USB_V2=m +CONFIG_DVB_USB_AF9015=m +CONFIG_DVB_USB_AF9035=m +CONFIG_DVB_USB_ANYSEE=m +CONFIG_DVB_USB_AU6610=m +CONFIG_DVB_USB_AZ6007=m +CONFIG_DVB_USB_CE6230=m +CONFIG_DVB_USB_EC168=m +CONFIG_DVB_USB_GL861=m +CONFIG_DVB_USB_LME2510=m +CONFIG_DVB_USB_MXL111SF=m +CONFIG_DVB_USB_RTL28XXU=m +CONFIG_DVB_USB_DVBSKY=m +CONFIG_DVB_USB_ZD1301=m +CONFIG_DVB_TTUSB_BUDGET=m +CONFIG_DVB_TTUSB_DEC=m +CONFIG_SMS_USB_DRV=m +CONFIG_DVB_B2C2_FLEXCOP_USB=m +# CONFIG_DVB_B2C2_FLEXCOP_USB_DEBUG is not set +CONFIG_DVB_AS102=m + +# +# Webcam, TV (analog/digital) USB devices +# +CONFIG_VIDEO_EM28XX=m +CONFIG_VIDEO_EM28XX_V4L2=m +CONFIG_VIDEO_EM28XX_ALSA=m +CONFIG_VIDEO_EM28XX_DVB=m +CONFIG_VIDEO_EM28XX_RC=m + +# +# Software defined radio USB devices +# +CONFIG_USB_AIRSPY=m +CONFIG_USB_HACKRF=m +CONFIG_USB_MSI2500=m +# CONFIG_MEDIA_PCI_SUPPORT is not set +CONFIG_RADIO_ADAPTERS=y +CONFIG_RADIO_TEA575X=m +CONFIG_RADIO_SI470X=m +CONFIG_USB_SI470X=m +CONFIG_I2C_SI470X=m +CONFIG_RADIO_SI4713=m +CONFIG_USB_SI4713=m +CONFIG_PLATFORM_SI4713=m +CONFIG_I2C_SI4713=m +CONFIG_USB_MR800=m +CONFIG_USB_DSBR=m +CONFIG_RADIO_MAXIRADIO=m +CONFIG_RADIO_SHARK=m +CONFIG_RADIO_SHARK2=m +CONFIG_USB_KEENE=m +CONFIG_USB_RAREMONO=m +CONFIG_USB_MA901=m +CONFIG_RADIO_TEA5764=m +CONFIG_RADIO_SAA7706H=m +CONFIG_RADIO_TEF6862=m +CONFIG_RADIO_WL1273=m +CONFIG_MEDIA_COMMON_OPTIONS=y + +# +# common driver options +# +CONFIG_VIDEO_CX2341X=m +CONFIG_VIDEO_TVEEPROM=m +CONFIG_TTPCI_EEPROM=m +CONFIG_CYPRESS_FIRMWARE=m +CONFIG_VIDEOBUF2_CORE=m +CONFIG_VIDEOBUF2_V4L2=m +CONFIG_VIDEOBUF2_MEMOPS=m +CONFIG_VIDEOBUF2_DMA_CONTIG=m +CONFIG_VIDEOBUF2_VMALLOC=m +CONFIG_VIDEOBUF2_DMA_SG=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 +# CONFIG_V4L_PLATFORM_DRIVERS is not set +CONFIG_V4L_MEM2MEM_DRIVERS=y +# CONFIG_VIDEO_MEM2MEM_DEINTERLACE is not set +CONFIG_VIDEO_MESON_GE2D=m +CONFIG_VIDEO_ROCKCHIP_RGA=m +CONFIG_VIDEO_SUN8I_DEINTERLACE=m +CONFIG_VIDEO_SUN8I_ROTATE=m +CONFIG_DVB_PLATFORM_DRIVERS=y +CONFIG_SDR_PLATFORM_DRIVERS=y + +# +# MMC/SDIO DVB adapters +# +CONFIG_SMS_SDIO_DRV=m +# CONFIG_V4L_TEST_DRIVERS is not set +# CONFIG_DVB_TEST_DRIVERS is not set +# end of Media drivers + +# +# Media ancillary drivers +# +CONFIG_MEDIA_ATTACH=y + +# +# IR I2C driver auto-selected by 'Autoselect ancillary drivers' +# +CONFIG_VIDEO_IR_I2C=m + +# +# Audio decoders, processors and mixers +# +CONFIG_VIDEO_TVAUDIO=m +CONFIG_VIDEO_TDA7432=m +CONFIG_VIDEO_TDA9840=m +CONFIG_VIDEO_TDA1997X=m +CONFIG_VIDEO_TEA6415C=m +CONFIG_VIDEO_TEA6420=m +CONFIG_VIDEO_MSP3400=m +CONFIG_VIDEO_CS3308=m +CONFIG_VIDEO_CS5345=m +CONFIG_VIDEO_CS53L32A=m +CONFIG_VIDEO_TLV320AIC23B=m +CONFIG_VIDEO_UDA1342=m +CONFIG_VIDEO_WM8775=m +CONFIG_VIDEO_WM8739=m +CONFIG_VIDEO_VP27SMPX=m +CONFIG_VIDEO_SONY_BTF_MPX=m +# end of Audio decoders, processors and mixers + +# +# RDS decoders +# +CONFIG_VIDEO_SAA6588=m +# end of RDS decoders + +# +# Video decoders +# +CONFIG_VIDEO_ADV7180=m +CONFIG_VIDEO_ADV7183=m +CONFIG_VIDEO_ADV748X=m +CONFIG_VIDEO_ADV7604=m +CONFIG_VIDEO_ADV7604_CEC=y +CONFIG_VIDEO_ADV7842=m +CONFIG_VIDEO_ADV7842_CEC=y +CONFIG_VIDEO_BT819=m +CONFIG_VIDEO_BT856=m +CONFIG_VIDEO_BT866=m +CONFIG_VIDEO_KS0127=m +CONFIG_VIDEO_ML86V7667=m +CONFIG_VIDEO_SAA7110=m +CONFIG_VIDEO_SAA711X=m +CONFIG_VIDEO_TC358743=m +CONFIG_VIDEO_TC358743_CEC=y +CONFIG_VIDEO_TVP514X=m +CONFIG_VIDEO_TVP5150=m +CONFIG_VIDEO_TVP7002=m +CONFIG_VIDEO_TW2804=m +CONFIG_VIDEO_TW9903=m +CONFIG_VIDEO_TW9906=m +CONFIG_VIDEO_TW9910=m +CONFIG_VIDEO_VPX3220=m +# CONFIG_VIDEO_MAX9286 is not set + +# +# Video and audio decoders +# +CONFIG_VIDEO_SAA717X=m +CONFIG_VIDEO_CX25840=m +# end of Video decoders + +# +# Video encoders +# +CONFIG_VIDEO_SAA7127=m +CONFIG_VIDEO_SAA7185=m +CONFIG_VIDEO_ADV7170=m +CONFIG_VIDEO_ADV7175=m +CONFIG_VIDEO_ADV7343=m +CONFIG_VIDEO_ADV7393=m +CONFIG_VIDEO_AD9389B=m +CONFIG_VIDEO_AK881X=m +CONFIG_VIDEO_THS8200=m +# end of Video encoders + +# +# Video improvement chips +# +CONFIG_VIDEO_UPD64031A=m +CONFIG_VIDEO_UPD64083=m +# end of Video improvement chips + +# +# Audio/Video compression chips +# +CONFIG_VIDEO_SAA6752HS=m +# end of Audio/Video compression chips + +# +# SDR tuner chips +# +CONFIG_SDR_MAX2175=m +# end of SDR tuner chips + +# +# Miscellaneous helper chips +# +CONFIG_VIDEO_THS7303=m +CONFIG_VIDEO_M52790=m +CONFIG_VIDEO_I2C=m +CONFIG_VIDEO_ST_MIPID02=m +# end of Miscellaneous helper chips + +# +# Camera sensor devices +# +CONFIG_VIDEO_APTINA_PLL=m +CONFIG_VIDEO_CCS_PLL=m +CONFIG_VIDEO_HI556=m +# CONFIG_VIDEO_HI846 is not set +CONFIG_VIDEO_IMX208=m +CONFIG_VIDEO_IMX214=m +CONFIG_VIDEO_IMX219=m +CONFIG_VIDEO_IMX258=m +CONFIG_VIDEO_IMX274=m +CONFIG_VIDEO_IMX290=m +CONFIG_VIDEO_IMX319=m +CONFIG_VIDEO_IMX334=m +CONFIG_VIDEO_IMX335=m +CONFIG_VIDEO_IMX355=m +CONFIG_VIDEO_IMX412=m +CONFIG_VIDEO_OV02A10=m +CONFIG_VIDEO_OV2640=m +CONFIG_VIDEO_OV2659=m +CONFIG_VIDEO_OV2680=m +CONFIG_VIDEO_OV2685=m +CONFIG_VIDEO_OV5640=m +CONFIG_VIDEO_OV5645=m +CONFIG_VIDEO_OV5647=m +CONFIG_VIDEO_OV5648=m +CONFIG_VIDEO_OV6650=m +CONFIG_VIDEO_OV5670=m +CONFIG_VIDEO_OV5675=m +CONFIG_VIDEO_OV5695=m +CONFIG_VIDEO_OV7251=m +CONFIG_VIDEO_OV772X=m +CONFIG_VIDEO_OV7640=m +CONFIG_VIDEO_OV7670=m +CONFIG_VIDEO_OV7740=m +CONFIG_VIDEO_OV8856=m +CONFIG_VIDEO_OV8865=m +CONFIG_VIDEO_OV9282=m +CONFIG_VIDEO_OV9640=m +CONFIG_VIDEO_OV9650=m +CONFIG_VIDEO_OV13858=m +# CONFIG_VIDEO_OV13B10 is not set +CONFIG_VIDEO_VS6624=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_SR030PC30=m +CONFIG_VIDEO_NOON010PC30=m +CONFIG_VIDEO_M5MOLS=m +CONFIG_VIDEO_MAX9271_LIB=m +# CONFIG_VIDEO_RDACM20 is not set +CONFIG_VIDEO_RDACM21=m +CONFIG_VIDEO_RJ54N1=m +CONFIG_VIDEO_S5K6AA=m +CONFIG_VIDEO_S5K6A3=m +CONFIG_VIDEO_S5K4ECGX=m +CONFIG_VIDEO_S5K5BAF=m +CONFIG_VIDEO_CCS=m +CONFIG_VIDEO_ET8EK8=m +CONFIG_VIDEO_S5C73M3=m +# end of Camera sensor devices + +# +# Lens drivers +# +CONFIG_VIDEO_AD5820=m +CONFIG_VIDEO_AK7375=m +CONFIG_VIDEO_DW9714=m +# CONFIG_VIDEO_DW9768 is not set +CONFIG_VIDEO_DW9807_VCM=m +# end of Lens drivers + +# +# Flash devices +# +CONFIG_VIDEO_ADP1653=m +CONFIG_VIDEO_LM3560=m +CONFIG_VIDEO_LM3646=m +# end of Flash devices + +# +# SPI helper chips +# +CONFIG_VIDEO_GS1662=m +# end of SPI helper chips + +# +# Media SPI Adapters +# +CONFIG_CXD2880_SPI_DRV=m +# end of Media SPI Adapters + +CONFIG_MEDIA_TUNER=m + +# +# Customize TV tuners +# +CONFIG_MEDIA_TUNER_SIMPLE=m +CONFIG_MEDIA_TUNER_TDA18250=m +CONFIG_MEDIA_TUNER_TDA8290=m +CONFIG_MEDIA_TUNER_TDA827X=m +CONFIG_MEDIA_TUNER_TDA18271=m +CONFIG_MEDIA_TUNER_TDA9887=m +CONFIG_MEDIA_TUNER_TEA5761=m +CONFIG_MEDIA_TUNER_TEA5767=m +CONFIG_MEDIA_TUNER_MSI001=m +CONFIG_MEDIA_TUNER_MT20XX=m +CONFIG_MEDIA_TUNER_MT2060=m +CONFIG_MEDIA_TUNER_MT2063=m +CONFIG_MEDIA_TUNER_MT2266=m +CONFIG_MEDIA_TUNER_MT2131=m +CONFIG_MEDIA_TUNER_QT1010=m +CONFIG_MEDIA_TUNER_XC2028=m +CONFIG_MEDIA_TUNER_XC5000=m +CONFIG_MEDIA_TUNER_XC4000=m +CONFIG_MEDIA_TUNER_MXL5005S=m +CONFIG_MEDIA_TUNER_MXL5007T=m +CONFIG_MEDIA_TUNER_MC44S803=m +CONFIG_MEDIA_TUNER_MAX2165=m +CONFIG_MEDIA_TUNER_TDA18218=m +CONFIG_MEDIA_TUNER_FC0011=m +CONFIG_MEDIA_TUNER_FC0012=m +CONFIG_MEDIA_TUNER_FC0013=m +CONFIG_MEDIA_TUNER_TDA18212=m +CONFIG_MEDIA_TUNER_E4000=m +CONFIG_MEDIA_TUNER_FC2580=m +CONFIG_MEDIA_TUNER_M88RS6000T=m +CONFIG_MEDIA_TUNER_TUA9001=m +CONFIG_MEDIA_TUNER_SI2157=m +CONFIG_MEDIA_TUNER_IT913X=m +CONFIG_MEDIA_TUNER_R820T=m +CONFIG_MEDIA_TUNER_MXL301RF=m +CONFIG_MEDIA_TUNER_QM1D1C0042=m +CONFIG_MEDIA_TUNER_QM1D1B0004=m +# end of Customize TV tuners + +# +# Customise DVB Frontends +# + +# +# Multistandard (satellite) frontends +# +CONFIG_DVB_STB0899=m +CONFIG_DVB_STB6100=m +CONFIG_DVB_STV090x=m +CONFIG_DVB_STV0910=m +CONFIG_DVB_STV6110x=m +CONFIG_DVB_STV6111=m +CONFIG_DVB_MXL5XX=m +CONFIG_DVB_M88DS3103=m + +# +# Multistandard (cable + terrestrial) frontends +# +CONFIG_DVB_DRXK=m +CONFIG_DVB_TDA18271C2DD=m +CONFIG_DVB_SI2165=m +CONFIG_DVB_MN88472=m +CONFIG_DVB_MN88473=m + +# +# DVB-S (satellite) frontends +# +CONFIG_DVB_CX24110=m +CONFIG_DVB_CX24123=m +CONFIG_DVB_MT312=m +CONFIG_DVB_ZL10036=m +CONFIG_DVB_ZL10039=m +CONFIG_DVB_S5H1420=m +CONFIG_DVB_STV0288=m +CONFIG_DVB_STB6000=m +CONFIG_DVB_STV0299=m +CONFIG_DVB_STV6110=m +CONFIG_DVB_STV0900=m +CONFIG_DVB_TDA8083=m +CONFIG_DVB_TDA10086=m +CONFIG_DVB_TDA8261=m +CONFIG_DVB_VES1X93=m +CONFIG_DVB_TUNER_ITD1000=m +CONFIG_DVB_TUNER_CX24113=m +CONFIG_DVB_TDA826X=m +CONFIG_DVB_TUA6100=m +CONFIG_DVB_CX24116=m +CONFIG_DVB_CX24117=m +CONFIG_DVB_CX24120=m +CONFIG_DVB_SI21XX=m +CONFIG_DVB_TS2020=m +CONFIG_DVB_DS3000=m +CONFIG_DVB_MB86A16=m +CONFIG_DVB_TDA10071=m + +# +# DVB-T (terrestrial) frontends +# +CONFIG_DVB_SP887X=m +CONFIG_DVB_CX22700=m +CONFIG_DVB_CX22702=m +CONFIG_DVB_S5H1432=m +CONFIG_DVB_DRXD=m +CONFIG_DVB_L64781=m +CONFIG_DVB_TDA1004X=m +CONFIG_DVB_NXT6000=m +CONFIG_DVB_MT352=m +CONFIG_DVB_ZL10353=m +CONFIG_DVB_DIB3000MB=m +CONFIG_DVB_DIB3000MC=m +CONFIG_DVB_DIB7000M=m +CONFIG_DVB_DIB7000P=m +CONFIG_DVB_DIB9000=m +CONFIG_DVB_TDA10048=m +CONFIG_DVB_AF9013=m +CONFIG_DVB_EC100=m +CONFIG_DVB_STV0367=m +CONFIG_DVB_CXD2820R=m +CONFIG_DVB_CXD2841ER=m +CONFIG_DVB_RTL2830=m +CONFIG_DVB_RTL2832=m +CONFIG_DVB_RTL2832_SDR=m +CONFIG_DVB_SI2168=m +CONFIG_DVB_AS102_FE=m +CONFIG_DVB_ZD1301_DEMOD=m +CONFIG_DVB_GP8PSK_FE=m +CONFIG_DVB_CXD2880=m + +# +# DVB-C (cable) frontends +# +CONFIG_DVB_VES1820=m +CONFIG_DVB_TDA10021=m +CONFIG_DVB_TDA10023=m +CONFIG_DVB_STV0297=m + +# +# ATSC (North American/Korean Terrestrial/Cable DTV) frontends +# +CONFIG_DVB_NXT200X=m +CONFIG_DVB_OR51211=m +CONFIG_DVB_OR51132=m +CONFIG_DVB_BCM3510=m +CONFIG_DVB_LGDT330X=m +CONFIG_DVB_LGDT3305=m +CONFIG_DVB_LGDT3306A=m +CONFIG_DVB_LG2160=m +CONFIG_DVB_S5H1409=m +CONFIG_DVB_AU8522=m +CONFIG_DVB_AU8522_DTV=m +CONFIG_DVB_AU8522_V4L=m +CONFIG_DVB_S5H1411=m +CONFIG_DVB_MXL692=m + +# +# ISDB-T (terrestrial) frontends +# +CONFIG_DVB_S921=m +CONFIG_DVB_DIB8000=m +CONFIG_DVB_MB86A20S=m + +# +# ISDB-S (satellite) & ISDB-T (terrestrial) frontends +# +CONFIG_DVB_TC90522=m +CONFIG_DVB_MN88443X=m + +# +# Digital terrestrial only tuners/PLL +# +CONFIG_DVB_PLL=m +CONFIG_DVB_TUNER_DIB0070=m +CONFIG_DVB_TUNER_DIB0090=m + +# +# SEC control devices for DVB-S +# +CONFIG_DVB_DRX39XYJ=m +CONFIG_DVB_LNBH25=m +CONFIG_DVB_LNBH29=m +CONFIG_DVB_LNBP21=m +CONFIG_DVB_LNBP22=m +CONFIG_DVB_ISL6405=m +CONFIG_DVB_ISL6421=m +CONFIG_DVB_ISL6423=m +CONFIG_DVB_A8293=m +CONFIG_DVB_LGS8GL5=m +CONFIG_DVB_LGS8GXX=m +CONFIG_DVB_ATBM8830=m +CONFIG_DVB_TDA665x=m +CONFIG_DVB_IX2505V=m +CONFIG_DVB_M88RS2000=m +CONFIG_DVB_AF9033=m +CONFIG_DVB_HORUS3A=m +CONFIG_DVB_ASCOT2E=m +CONFIG_DVB_HELENE=m + +# +# Common Interface (EN50221) controller drivers +# +CONFIG_DVB_CXD2099=m +CONFIG_DVB_SP2=m +# end of Customise DVB Frontends + +# +# Tools to develop new frontends +# +CONFIG_DVB_DUMMY_FE=m +# end of Media ancillary drivers + +# +# Graphics support +# +CONFIG_VGA_ARB=y +CONFIG_VGA_ARB_MAX_GPUS=16 +CONFIG_DRM=y +CONFIG_DRM_MIPI_DBI=m +CONFIG_DRM_MIPI_DSI=y +CONFIG_DRM_DP_AUX_BUS=m +# CONFIG_DRM_DP_AUX_CHARDEV is not set +# CONFIG_DRM_DEBUG_MM is not set +# CONFIG_DRM_DEBUG_SELFTEST is not set +CONFIG_DRM_KMS_HELPER=y +# CONFIG_DRM_DEBUG_DP_MST_TOPOLOGY_REFS is not set +# CONFIG_DRM_DEBUG_MODESET_LOCK is not set +CONFIG_DRM_FBDEV_EMULATION=y +CONFIG_DRM_FBDEV_OVERALLOC=100 +# CONFIG_DRM_FBDEV_LEAK_PHYS_SMEM is not set +# CONFIG_DRM_LOAD_EDID_FIRMWARE is not set +CONFIG_DRM_DP_CEC=y +CONFIG_DRM_TTM=m +CONFIG_DRM_VRAM_HELPER=m +CONFIG_DRM_TTM_HELPER=m +CONFIG_DRM_GEM_CMA_HELPER=y +CONFIG_DRM_KMS_CMA_HELPER=y +CONFIG_DRM_GEM_SHMEM_HELPER=y +CONFIG_DRM_SCHED=m + +# +# I2C encoder or helper chips +# +CONFIG_DRM_I2C_CH7006=m +CONFIG_DRM_I2C_SIL164=m +# CONFIG_DRM_I2C_NXP_TDA998X is not set +CONFIG_DRM_I2C_NXP_TDA9950=m +# end of I2C encoder or helper chips + +# +# ARM devices +# +# CONFIG_DRM_HDLCD is not set +# CONFIG_DRM_MALI_DISPLAY is not set +CONFIG_DRM_KOMEDA=m +# end of ARM devices + +# CONFIG_DRM_RADEON is not set +# CONFIG_DRM_AMDGPU is not set +# CONFIG_DRM_NOUVEAU is not set +# CONFIG_DRM_VGEM is not set +# CONFIG_DRM_VKMS is not set +CONFIG_DRM_ROCKCHIP=y +CONFIG_ROCKCHIP_VOP=y +CONFIG_ROCKCHIP_VOP2=y +CONFIG_ROCKCHIP_ANALOGIX_DP=y +CONFIG_ROCKCHIP_CDN_DP=y +CONFIG_ROCKCHIP_DW_HDMI=y +CONFIG_ROCKCHIP_DW_MIPI_DSI=y +CONFIG_ROCKCHIP_INNO_HDMI=y +CONFIG_ROCKCHIP_LVDS=y +CONFIG_ROCKCHIP_RGB=y +CONFIG_ROCKCHIP_RK3066_HDMI=y +CONFIG_DRM_VMWGFX=m +# CONFIG_DRM_VMWGFX_FBCON is not set +# CONFIG_DRM_UDL is not set +# CONFIG_DRM_AST is not set +# CONFIG_DRM_MGAG200 is not set +# CONFIG_DRM_RCAR_DW_HDMI is not set +CONFIG_DRM_RCAR_LVDS=m +CONFIG_DRM_SUN4I=m +CONFIG_DRM_SUN4I_HDMI=m +CONFIG_DRM_SUN4I_HDMI_CEC=y +CONFIG_DRM_SUN4I_BACKEND=m +CONFIG_DRM_SUN6I_DSI=m +CONFIG_DRM_SUN8I_DW_HDMI=m +CONFIG_DRM_SUN8I_MIXER=m +CONFIG_DRM_SUN8I_TCON_TOP=m +# CONFIG_DRM_QXL is not set +CONFIG_DRM_VIRTIO_GPU=m +CONFIG_DRM_PANEL=y + +# +# Display Panels +# +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_BOE_HIMAX8279D=m +CONFIG_DRM_PANEL_BOE_TV101WUM_NL6=m +CONFIG_DRM_PANEL_DSI_CM=m +CONFIG_DRM_PANEL_LVDS=m +CONFIG_DRM_PANEL_SIMPLE=m +# CONFIG_DRM_PANEL_EDP is not set +CONFIG_DRM_PANEL_ELIDA_KD35T133=m +CONFIG_DRM_PANEL_FEIXIN_K101_IM2BA02=m +CONFIG_DRM_PANEL_FEIYANG_FY07024DI26A30D=m +CONFIG_DRM_PANEL_ILITEK_IL9322=m +CONFIG_DRM_PANEL_ILITEK_ILI9341=m +CONFIG_DRM_PANEL_ILITEK_ILI9881C=m +CONFIG_DRM_PANEL_INNOLUX_EJ030NA=m +CONFIG_DRM_PANEL_INNOLUX_P079ZCA=m +CONFIG_DRM_PANEL_JDI_LT070ME05000=m +CONFIG_DRM_PANEL_KHADAS_TS050=m +CONFIG_DRM_PANEL_KINGDISPLAY_KD097D04=m +# CONFIG_DRM_PANEL_LEADTEK_LTK050H3146W is not set +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_NEC_NL8048HL11=m +CONFIG_DRM_PANEL_NOVATEK_NT35510=m +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_OTM8009A=m +# CONFIG_DRM_PANEL_OSD_OSD101T2587_53TS is not set +CONFIG_DRM_PANEL_PANASONIC_VVX10F034N00=m +CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN=m +CONFIG_DRM_PANEL_RAYDIUM_RM67191=m +CONFIG_DRM_PANEL_RAYDIUM_RM68200=m +CONFIG_DRM_PANEL_RONBO_RB070D30=m +CONFIG_DRM_PANEL_SAMSUNG_ATNA33XC20=m +CONFIG_DRM_PANEL_SAMSUNG_DB7430=m +CONFIG_DRM_PANEL_SAMSUNG_S6D16D0=m +# CONFIG_DRM_PANEL_SAMSUNG_S6D27A1 is not set +CONFIG_DRM_PANEL_SAMSUNG_S6E3HA2=m +CONFIG_DRM_PANEL_SAMSUNG_S6E63J0X03=m +# CONFIG_DRM_PANEL_SAMSUNG_S6E63M0 is not set +CONFIG_DRM_PANEL_SAMSUNG_S6E88A0_AMS452EF01=m +# CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0 is not set +CONFIG_DRM_PANEL_SAMSUNG_SOFEF00=m +CONFIG_DRM_PANEL_SEIKO_43WVF1G=m +CONFIG_DRM_PANEL_SHARP_LQ101R1SX01=m +CONFIG_DRM_PANEL_SHARP_LS037V7DW01=m +CONFIG_DRM_PANEL_SHARP_LS043T1LE01=m +# CONFIG_DRM_PANEL_SHARP_LS060T1SX01 is not set +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_ACX424AKP=m +CONFIG_DRM_PANEL_SONY_ACX565AKM=m +CONFIG_DRM_PANEL_TDO_TL070WSH30=m +CONFIG_DRM_PANEL_TPO_TD028TTEC1=m +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_WIDECHIPS_WS2401=m +CONFIG_DRM_PANEL_XINPENG_XPP055C272=m +# end of Display Panels + +CONFIG_DRM_BRIDGE=y +CONFIG_DRM_PANEL_BRIDGE=y + +# +# Display Interface Bridges +# +CONFIG_DRM_CDNS_DSI=m +CONFIG_DRM_CHIPONE_ICN6211=m +# CONFIG_DRM_CHRONTEL_CH7033 is not set +CONFIG_DRM_CROS_EC_ANX7688=m +CONFIG_DRM_DISPLAY_CONNECTOR=m +CONFIG_DRM_LONTIUM_LT8912B=m +# CONFIG_DRM_LONTIUM_LT9611 is not set +CONFIG_DRM_LONTIUM_LT9611UXC=m +CONFIG_DRM_ITE_IT66121=m +CONFIG_DRM_LVDS_CODEC=m +# CONFIG_DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW is not set +# CONFIG_DRM_NWL_MIPI_DSI is not set +# CONFIG_DRM_NXP_PTN3460 is not set +# CONFIG_DRM_PARADE_PS8622 is not set +CONFIG_DRM_PARADE_PS8640=m +# CONFIG_DRM_SIL_SII8620 is not set +# CONFIG_DRM_SII902X is not set +CONFIG_DRM_SII9234=m +# CONFIG_DRM_SIMPLE_BRIDGE is not set +CONFIG_DRM_THINE_THC63LVD1024=m +# CONFIG_DRM_TOSHIBA_TC358762 is not set +CONFIG_DRM_TOSHIBA_TC358764=m +# CONFIG_DRM_TOSHIBA_TC358767 is not set +CONFIG_DRM_TOSHIBA_TC358768=m +# CONFIG_DRM_TOSHIBA_TC358775 is not set +# CONFIG_DRM_TI_TFP410 is not set +CONFIG_DRM_TI_SN65DSI83=m +# CONFIG_DRM_TI_SN65DSI86 is not set +CONFIG_DRM_TI_TPD12S015=m +CONFIG_DRM_ANALOGIX_ANX6345=m +CONFIG_DRM_ANALOGIX_ANX78XX=m +CONFIG_DRM_ANALOGIX_DP=y +# CONFIG_DRM_ANALOGIX_ANX7625 is not set +CONFIG_DRM_I2C_ADV7511=m +# CONFIG_DRM_I2C_ADV7511_AUDIO is not set +CONFIG_DRM_I2C_ADV7511_CEC=y +# CONFIG_DRM_CDNS_MHDP8546 is not set +CONFIG_DRM_DW_HDMI=y +# CONFIG_DRM_DW_HDMI_AHB_AUDIO is not set +CONFIG_DRM_DW_HDMI_I2S_AUDIO=m +CONFIG_DRM_DW_HDMI_CEC=m +CONFIG_DRM_DW_MIPI_DSI=y +# end of Display Interface Bridges + +CONFIG_DRM_ETNAVIV=m +CONFIG_DRM_ETNAVIV_THERMAL=y +# CONFIG_DRM_HISI_HIBMC is not set +CONFIG_DRM_HISI_KIRIN=m +# CONFIG_DRM_MXSFB is not set +CONFIG_DRM_MESON=m +CONFIG_DRM_MESON_DW_HDMI=m +# CONFIG_DRM_ARCPGU is not set +CONFIG_DRM_BOCHS=m +# CONFIG_DRM_CIRRUS_QEMU is not set +CONFIG_DRM_GM12U320=m +CONFIG_DRM_SIMPLEDRM=m +CONFIG_TINYDRM_HX8357D=m +CONFIG_TINYDRM_ILI9225=m +CONFIG_TINYDRM_ILI9341=m +CONFIG_TINYDRM_ILI9486=m +CONFIG_TINYDRM_MI0283QT=m +CONFIG_TINYDRM_REPAPER=m +CONFIG_TINYDRM_ST7586=m +CONFIG_TINYDRM_ST7735R=m +# CONFIG_DRM_PL111 is not set +CONFIG_DRM_XEN=y +CONFIG_DRM_XEN_FRONTEND=m +CONFIG_DRM_LIMA=m +CONFIG_DRM_PANFROST=m +CONFIG_DRM_TIDSS=m +CONFIG_DRM_GUD=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_PANEL_ORIENTATION_QUIRKS=y + +# +# Frame buffer Devices +# +CONFIG_FB_CMDLINE=y +CONFIG_FB_NOTIFY=y +CONFIG_FB=y +CONFIG_FIRMWARE_EDID=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +CONFIG_FB_SYS_FILLRECT=y +CONFIG_FB_SYS_COPYAREA=y +CONFIG_FB_SYS_IMAGEBLIT=y +# CONFIG_FB_FOREIGN_ENDIAN is not set +CONFIG_FB_SYS_FOPS=y +CONFIG_FB_DEFERRED_IO=y +CONFIG_FB_BACKLIGHT=m +CONFIG_FB_MODE_HELPERS=y +# CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# +# CONFIG_FB_CIRRUS is not set +# CONFIG_FB_PM2 is not set +CONFIG_FB_ARMCLCD=y +# CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_ASILIANT is not set +# CONFIG_FB_IMSTT is not set +CONFIG_FB_UVESA=m +# CONFIG_FB_EFI is not set +# CONFIG_FB_OPENCORES is not set +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_NVIDIA is not set +# CONFIG_FB_RIVA is not set +# CONFIG_FB_I740 is not set +# CONFIG_FB_MATROX is not set +# CONFIG_FB_RADEON is not set +# CONFIG_FB_ATY128 is not set +# CONFIG_FB_ATY is not set +# CONFIG_FB_S3 is not set +# CONFIG_FB_SAVAGE is not set +# CONFIG_FB_SIS is not set +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_FB_KYRO is not set +# CONFIG_FB_3DFX is not set +# CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_VT8623 is not set +# CONFIG_FB_TRIDENT is not set +# CONFIG_FB_ARK is not set +# CONFIG_FB_PM3 is not set +# CONFIG_FB_CARMINE is not set +# CONFIG_FB_SMSCUFX is not set +# CONFIG_FB_UDL is not set +# CONFIG_FB_IBM_GXT4500 is not set +# CONFIG_FB_VIRTUAL is not set +CONFIG_XEN_FBDEV_FRONTEND=y +# CONFIG_FB_METRONOME is not set +# CONFIG_FB_MB862XX is not set +# CONFIG_FB_SIMPLE is not set +# CONFIG_FB_SSD1307 is not set +# CONFIG_FB_SM712 is not set +# end of Frame buffer Devices + +# +# Backlight & LCD device support +# +CONFIG_LCD_CLASS_DEVICE=m +# CONFIG_LCD_L4F00242T03 is not set +# CONFIG_LCD_LMS283GF05 is not set +# CONFIG_LCD_LTV350QV is not set +# CONFIG_LCD_ILI922X is not set +# CONFIG_LCD_ILI9320 is not set +# CONFIG_LCD_TDO24M is not set +# CONFIG_LCD_VGG2432A4 is not set +# CONFIG_LCD_PLATFORM is not set +# CONFIG_LCD_AMS369FG06 is not set +# CONFIG_LCD_LMS501KF03 is not set +# CONFIG_LCD_HX8357 is not set +CONFIG_LCD_OTM3225A=m +CONFIG_BACKLIGHT_CLASS_DEVICE=y +# CONFIG_BACKLIGHT_KTD253 is not set +CONFIG_BACKLIGHT_LM3533=m +CONFIG_BACKLIGHT_PWM=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 + +CONFIG_VIDEOMODE_HELPERS=y +CONFIG_HDMI=y + +# +# Console display driver support +# +CONFIG_DUMMY_CONSOLE=y +CONFIG_DUMMY_CONSOLE_COLUMNS=80 +CONFIG_DUMMY_CONSOLE_ROWS=25 +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y +CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y +# CONFIG_FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER is not set +# end of Console display driver support + +CONFIG_LOGO=y +CONFIG_LOGO_LINUX_MONO=y +CONFIG_LOGO_LINUX_VGA16=y +CONFIG_LOGO_LINUX_CLUT224=y +# end of Graphics support + +CONFIG_SOUND=m +CONFIG_SND=m +CONFIG_SND_TIMER=m +CONFIG_SND_PCM=m +CONFIG_SND_PCM_ELD=y +CONFIG_SND_PCM_IEC958=y +CONFIG_SND_DMAENGINE_PCM=m +CONFIG_SND_HWDEP=m +CONFIG_SND_SEQ_DEVICE=m +CONFIG_SND_RAWMIDI=m +CONFIG_SND_JACK=y +CONFIG_SND_JACK_INPUT_DEV=y +# CONFIG_SND_OSSEMUL is not set +CONFIG_SND_PCM_TIMER=y +# CONFIG_SND_HRTIMER is not set +# CONFIG_SND_DYNAMIC_MINORS is not set +# CONFIG_SND_SUPPORT_OLD_API is not set +CONFIG_SND_PROC_FS=y +CONFIG_SND_VERBOSE_PROCFS=y +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set +CONFIG_SND_VMASTER=y +CONFIG_SND_SEQUENCER=m +CONFIG_SND_SEQ_DUMMY=m +CONFIG_SND_SEQ_MIDI_EVENT=m +CONFIG_SND_SEQ_MIDI=m +CONFIG_SND_SEQ_MIDI_EMUL=m +CONFIG_SND_SEQ_VIRMIDI=m +CONFIG_SND_MPU401_UART=m +CONFIG_SND_OPL3_LIB=m +CONFIG_SND_OPL3_LIB_SEQ=m +CONFIG_SND_AC97_CODEC=m +CONFIG_SND_DRIVERS=y +CONFIG_SND_DUMMY=m +CONFIG_SND_ALOOP=m +CONFIG_SND_VIRMIDI=m +CONFIG_SND_MTPAV=m +CONFIG_SND_SERIAL_U16550=m +CONFIG_SND_MPU401=m +# CONFIG_SND_AC97_POWER_SAVE is not set +CONFIG_SND_PCI=y +# CONFIG_SND_AD1889 is not set +CONFIG_SND_ALS300=m +CONFIG_SND_ALI5451=m +# CONFIG_SND_ATIIXP is not set +# CONFIG_SND_ATIIXP_MODEM is not set +# CONFIG_SND_AU8810 is not set +# CONFIG_SND_AU8820 is not set +# CONFIG_SND_AU8830 is not set +CONFIG_SND_AW2=m +CONFIG_SND_AZT3328=m +# CONFIG_SND_BT87X is not set +# CONFIG_SND_CA0106 is not set +# CONFIG_SND_CMIPCI is not set +# CONFIG_SND_OXYGEN is not set +# CONFIG_SND_CS4281 is not set +# CONFIG_SND_CS46XX is not set +# CONFIG_SND_CTXFI is not set +# CONFIG_SND_DARLA20 is not set +# CONFIG_SND_GINA20 is not set +# CONFIG_SND_LAYLA20 is not set +# CONFIG_SND_DARLA24 is not set +# CONFIG_SND_GINA24 is not set +# CONFIG_SND_LAYLA24 is not set +# CONFIG_SND_MONA is not set +# CONFIG_SND_MIA is not set +# CONFIG_SND_ECHO3G is not set +# CONFIG_SND_INDIGO is not set +# CONFIG_SND_INDIGOIO is not set +# CONFIG_SND_INDIGODJ is not set +# CONFIG_SND_INDIGOIOX is not set +# CONFIG_SND_INDIGODJX is not set +CONFIG_SND_EMU10K1=m +CONFIG_SND_EMU10K1_SEQ=m +CONFIG_SND_EMU10K1X=m +# CONFIG_SND_ENS1370 is not set +# CONFIG_SND_ENS1371 is not set +CONFIG_SND_ES1938=m +CONFIG_SND_ES1968=m +# CONFIG_SND_ES1968_INPUT is not set +# CONFIG_SND_ES1968_RADIO is not set +# CONFIG_SND_FM801 is not set +# CONFIG_SND_HDSP is not set +# CONFIG_SND_HDSPM is not set +CONFIG_SND_ICE1712=m +# CONFIG_SND_ICE1724 is not set +# CONFIG_SND_INTEL8X0 is not set +# CONFIG_SND_INTEL8X0M is not set +# CONFIG_SND_KORG1212 is not set +# CONFIG_SND_LOLA is not set +# CONFIG_SND_LX6464ES is not set +CONFIG_SND_MAESTRO3=m +# CONFIG_SND_MAESTRO3_INPUT is not set +# CONFIG_SND_MIXART is not set +# CONFIG_SND_NM256 is not set +# CONFIG_SND_PCXHR is not set +# CONFIG_SND_RIPTIDE is not set +# CONFIG_SND_RME32 is not set +# CONFIG_SND_RME96 is not set +# CONFIG_SND_RME9652 is not set +# CONFIG_SND_SE6X is not set +CONFIG_SND_SONICVIBES=m +CONFIG_SND_TRIDENT=m +# CONFIG_SND_VIA82XX is not set +# CONFIG_SND_VIA82XX_MODEM is not set +# CONFIG_SND_VIRTUOSO is not set +# CONFIG_SND_VX222 is not set +# CONFIG_SND_YMFPCI is not set + +# +# HD-Audio +# +# CONFIG_SND_HDA_INTEL is not set +# end of HD-Audio + +CONFIG_SND_HDA_PREALLOC_SIZE=64 +CONFIG_SND_SPI=y +CONFIG_SND_USB=y +CONFIG_SND_USB_AUDIO=m +CONFIG_SND_USB_AUDIO_USE_MEDIA_CONTROLLER=y +CONFIG_SND_USB_UA101=m +CONFIG_SND_USB_CAIAQ=m +CONFIG_SND_USB_CAIAQ_INPUT=y +CONFIG_SND_USB_6FIRE=m +CONFIG_SND_USB_HIFACE=m +CONFIG_SND_BCD2000=m +CONFIG_SND_USB_LINE6=m +CONFIG_SND_USB_POD=m +CONFIG_SND_USB_PODHD=m +CONFIG_SND_USB_TONEPORT=m +CONFIG_SND_USB_VARIAX=m +CONFIG_SND_SOC=m +CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM=y +CONFIG_SND_SOC_ADI=m +CONFIG_SND_SOC_ADI_AXI_I2S=m +CONFIG_SND_SOC_ADI_AXI_SPDIF=m +# CONFIG_SND_SOC_AMD_ACP is not set +# CONFIG_SND_ATMEL_SOC is not set +CONFIG_SND_BCM63XX_I2S_WHISTLER=m +CONFIG_SND_DESIGNWARE_I2S=m +# CONFIG_SND_DESIGNWARE_PCM is not set + +# +# SoC Audio for Freescale CPUs +# + +# +# Common SoC Audio options for Freescale CPUs: +# +# CONFIG_SND_SOC_FSL_ASRC is not set +# CONFIG_SND_SOC_FSL_SAI is not set +CONFIG_SND_SOC_FSL_AUDMIX=m +# CONFIG_SND_SOC_FSL_SSI is not set +# CONFIG_SND_SOC_FSL_SPDIF is not set +# CONFIG_SND_SOC_FSL_ESAI is not set +CONFIG_SND_SOC_FSL_MICFIL=m +CONFIG_SND_SOC_FSL_XCVR=m +# CONFIG_SND_SOC_IMX_AUDMUX is not set +# end of SoC Audio for Freescale CPUs + +# CONFIG_SND_I2S_HI6210_I2S is not set +# CONFIG_SND_SOC_IMG is not set +# CONFIG_SND_SOC_MTK_BTCVSD is not set + +# +# ASoC support for Amlogic platforms +# +CONFIG_SND_MESON_AIU=m +CONFIG_SND_MESON_AXG_FIFO=m +CONFIG_SND_MESON_AXG_FRDDR=m +CONFIG_SND_MESON_AXG_TODDR=m +CONFIG_SND_MESON_AXG_TDM_FORMATTER=m +CONFIG_SND_MESON_AXG_TDM_INTERFACE=m +CONFIG_SND_MESON_AXG_TDMIN=m +CONFIG_SND_MESON_AXG_TDMOUT=m +CONFIG_SND_MESON_AXG_SOUND_CARD=m +CONFIG_SND_MESON_AXG_SPDIFOUT=m +CONFIG_SND_MESON_AXG_SPDIFIN=m +CONFIG_SND_MESON_AXG_PDM=m +CONFIG_SND_MESON_CARD_UTILS=m +CONFIG_SND_MESON_CODEC_GLUE=m +CONFIG_SND_MESON_GX_SOUND_CARD=m +CONFIG_SND_MESON_G12A_TOACODEC=m +CONFIG_SND_MESON_G12A_TOHDMITX=m +CONFIG_SND_SOC_MESON_T9015=m +# end of ASoC support for Amlogic platforms + +CONFIG_SND_SOC_ROCKCHIP=m +CONFIG_SND_SOC_ROCKCHIP_I2S=m +CONFIG_SND_SOC_ROCKCHIP_I2S_TDM=m +CONFIG_SND_SOC_ROCKCHIP_PDM=m +CONFIG_SND_SOC_ROCKCHIP_SPDIF=m +CONFIG_SND_SOC_ROCKCHIP_MAX98090=m +CONFIG_SND_SOC_ROCKCHIP_RT5645=m +CONFIG_SND_SOC_RK3288_HDMI_ANALOG=m +CONFIG_SND_SOC_RK3399_GRU_SOUND=m +# CONFIG_SND_SOC_SOF_TOPLEVEL is not set + +# +# STMicroelectronics STM32 SOC audio support +# +# end of STMicroelectronics STM32 SOC audio support + +# +# Allwinner SoC Audio support +# +CONFIG_SND_SUN4I_CODEC=m +CONFIG_SND_SUN8I_CODEC=m +CONFIG_SND_SUN8I_CODEC_ANALOG=m +CONFIG_SND_SUN50I_CODEC_ANALOG=m +CONFIG_SND_SUN4I_I2S=m +CONFIG_SND_SUN4I_SPDIF=m +CONFIG_SND_SUN8I_ADDA_PR_REGMAP=m +# end of Allwinner SoC Audio support + +CONFIG_SND_SOC_XILINX_I2S=m +CONFIG_SND_SOC_XILINX_AUDIO_FORMATTER=m +CONFIG_SND_SOC_XILINX_SPDIF=m +# CONFIG_SND_SOC_XTFPGA_I2S is not set +CONFIG_SND_SOC_I2C_AND_SPI=m + +# +# CODEC drivers +# +# CONFIG_SND_SOC_AC97_CODEC is not set +CONFIG_SND_SOC_ADAU_UTILS=m +CONFIG_SND_SOC_ADAU1372=m +CONFIG_SND_SOC_ADAU1372_I2C=m +CONFIG_SND_SOC_ADAU1372_SPI=m +# CONFIG_SND_SOC_ADAU1701 is not set +# CONFIG_SND_SOC_ADAU1761_I2C is not set +# CONFIG_SND_SOC_ADAU1761_SPI is not set +# CONFIG_SND_SOC_ADAU7002 is not set +CONFIG_SND_SOC_ADAU7118=m +CONFIG_SND_SOC_ADAU7118_HW=m +CONFIG_SND_SOC_ADAU7118_I2C=m +# CONFIG_SND_SOC_AK4104 is not set +CONFIG_SND_SOC_AK4118=m +CONFIG_SND_SOC_AK4458=m +CONFIG_SND_SOC_AK4554=m +CONFIG_SND_SOC_AK4613=m +CONFIG_SND_SOC_AK4642=m +CONFIG_SND_SOC_AK5386=m +CONFIG_SND_SOC_AK5558=m +CONFIG_SND_SOC_ALC5623=m +CONFIG_SND_SOC_BD28623=m +# CONFIG_SND_SOC_BT_SCO is not set +CONFIG_SND_SOC_CROS_EC_CODEC=m +# CONFIG_SND_SOC_CS35L32 is not set +# CONFIG_SND_SOC_CS35L33 is not set +# CONFIG_SND_SOC_CS35L34 is not set +# CONFIG_SND_SOC_CS35L35 is not set +CONFIG_SND_SOC_CS35L36=m +# CONFIG_SND_SOC_CS35L41_SPI is not set +# CONFIG_SND_SOC_CS35L41_I2C is not set +# CONFIG_SND_SOC_CS42L42 is not set +# CONFIG_SND_SOC_CS42L51_I2C is not set +# CONFIG_SND_SOC_CS42L52 is not set +# CONFIG_SND_SOC_CS42L56 is not set +# CONFIG_SND_SOC_CS42L73 is not set +# CONFIG_SND_SOC_CS4234 is not set +# CONFIG_SND_SOC_CS4265 is not set +# CONFIG_SND_SOC_CS4270 is not set +# CONFIG_SND_SOC_CS4271_I2C is not set +# CONFIG_SND_SOC_CS4271_SPI is not set +# CONFIG_SND_SOC_CS42XX8_I2C is not set +CONFIG_SND_SOC_CS43130=m +CONFIG_SND_SOC_CS4341=m +# CONFIG_SND_SOC_CS4349 is not set +# CONFIG_SND_SOC_CS53L30 is not set +# CONFIG_SND_SOC_CX2072X is not set +CONFIG_SND_SOC_DA7213=m +CONFIG_SND_SOC_DA7219=m +CONFIG_SND_SOC_DMIC=m +CONFIG_SND_SOC_HDMI_CODEC=m +CONFIG_SND_SOC_ES7134=m +CONFIG_SND_SOC_ES7241=m +CONFIG_SND_SOC_ES8316=m +CONFIG_SND_SOC_ES8328=m +CONFIG_SND_SOC_ES8328_I2C=m +CONFIG_SND_SOC_ES8328_SPI=m +# CONFIG_SND_SOC_GTM601 is not set +CONFIG_SND_SOC_ICS43432=m +# CONFIG_SND_SOC_INNO_RK3036 is not set +# CONFIG_SND_SOC_MAX98088 is not set +CONFIG_SND_SOC_MAX98090=m +CONFIG_SND_SOC_MAX98357A=m +# CONFIG_SND_SOC_MAX98504 is not set +CONFIG_SND_SOC_MAX9867=m +# CONFIG_SND_SOC_MAX98927 is not set +# CONFIG_SND_SOC_MAX98520 is not set +# CONFIG_SND_SOC_MAX98373_I2C is not set +# CONFIG_SND_SOC_MAX98390 is not set +# CONFIG_SND_SOC_MAX9860 is not set +# CONFIG_SND_SOC_MSM8916_WCD_ANALOG is not set +# CONFIG_SND_SOC_MSM8916_WCD_DIGITAL is not set +# CONFIG_SND_SOC_PCM1681 is not set +CONFIG_SND_SOC_PCM1789=m +CONFIG_SND_SOC_PCM1789_I2C=m +# CONFIG_SND_SOC_PCM179X_I2C is not set +# CONFIG_SND_SOC_PCM179X_SPI is not set +CONFIG_SND_SOC_PCM186X=m +CONFIG_SND_SOC_PCM186X_I2C=m +CONFIG_SND_SOC_PCM186X_SPI=m +CONFIG_SND_SOC_PCM3060=m +CONFIG_SND_SOC_PCM3060_I2C=m +CONFIG_SND_SOC_PCM3060_SPI=m +CONFIG_SND_SOC_PCM3168A=m +CONFIG_SND_SOC_PCM3168A_I2C=m +CONFIG_SND_SOC_PCM3168A_SPI=m +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_RK3328=m +CONFIG_SND_SOC_RK817=m +CONFIG_SND_SOC_RL6231=m +CONFIG_SND_SOC_RT5514=m +CONFIG_SND_SOC_RT5514_SPI=m +CONFIG_SND_SOC_RT5616=m +CONFIG_SND_SOC_RT5631=m +CONFIG_SND_SOC_RT5640=m +CONFIG_SND_SOC_RT5645=m +CONFIG_SND_SOC_RT5659=m +# CONFIG_SND_SOC_RT9120 is not set +CONFIG_SND_SOC_SGTL5000=m +CONFIG_SND_SOC_SIMPLE_AMPLIFIER=m +CONFIG_SND_SOC_SIMPLE_MUX=m +CONFIG_SND_SOC_SPDIF=m +CONFIG_SND_SOC_SSM2305=m +CONFIG_SND_SOC_SSM2518=m +CONFIG_SND_SOC_SSM2602=m +CONFIG_SND_SOC_SSM2602_SPI=m +CONFIG_SND_SOC_SSM2602_I2C=m +CONFIG_SND_SOC_SSM4567=m +CONFIG_SND_SOC_STA32X=m +CONFIG_SND_SOC_STA350=m +CONFIG_SND_SOC_STI_SAS=m +CONFIG_SND_SOC_TAS2552=m +CONFIG_SND_SOC_TAS2562=m +# CONFIG_SND_SOC_TAS2764 is not set +CONFIG_SND_SOC_TAS2770=m +CONFIG_SND_SOC_TAS5086=m +CONFIG_SND_SOC_TAS571X=m +CONFIG_SND_SOC_TAS5720=m +CONFIG_SND_SOC_TAS6424=m +CONFIG_SND_SOC_TDA7419=m +CONFIG_SND_SOC_TFA9879=m +CONFIG_SND_SOC_TFA989X=m +CONFIG_SND_SOC_TLV320AIC23=m +CONFIG_SND_SOC_TLV320AIC23_I2C=m +CONFIG_SND_SOC_TLV320AIC23_SPI=m +CONFIG_SND_SOC_TLV320AIC31XX=m +CONFIG_SND_SOC_TLV320AIC32X4=m +CONFIG_SND_SOC_TLV320AIC32X4_I2C=m +CONFIG_SND_SOC_TLV320AIC32X4_SPI=m +CONFIG_SND_SOC_TLV320AIC3X=m +CONFIG_SND_SOC_TLV320AIC3X_I2C=m +CONFIG_SND_SOC_TLV320AIC3X_SPI=m +CONFIG_SND_SOC_TLV320ADCX140=m +CONFIG_SND_SOC_TS3A227E=m +CONFIG_SND_SOC_TSCS42XX=m +CONFIG_SND_SOC_TSCS454=m +CONFIG_SND_SOC_UDA1334=m +CONFIG_SND_SOC_WM8510=m +CONFIG_SND_SOC_WM8523=m +CONFIG_SND_SOC_WM8524=m +CONFIG_SND_SOC_WM8580=m +CONFIG_SND_SOC_WM8711=m +CONFIG_SND_SOC_WM8728=m +CONFIG_SND_SOC_WM8731=m +CONFIG_SND_SOC_WM8737=m +CONFIG_SND_SOC_WM8741=m +CONFIG_SND_SOC_WM8750=m +CONFIG_SND_SOC_WM8753=m +CONFIG_SND_SOC_WM8770=m +CONFIG_SND_SOC_WM8776=m +CONFIG_SND_SOC_WM8782=m +CONFIG_SND_SOC_WM8804=m +CONFIG_SND_SOC_WM8804_I2C=m +CONFIG_SND_SOC_WM8804_SPI=m +CONFIG_SND_SOC_WM8903=m +CONFIG_SND_SOC_WM8904=m +CONFIG_SND_SOC_WM8960=m +CONFIG_SND_SOC_WM8962=m +CONFIG_SND_SOC_WM8974=m +CONFIG_SND_SOC_WM8978=m +CONFIG_SND_SOC_WM8985=m +# CONFIG_SND_SOC_ZL38060 is not set +CONFIG_SND_SOC_MAX9759=m +CONFIG_SND_SOC_MT6351=m +CONFIG_SND_SOC_MT6358=m +CONFIG_SND_SOC_MT6660=m +CONFIG_SND_SOC_NAU8315=m +CONFIG_SND_SOC_NAU8540=m +CONFIG_SND_SOC_NAU8810=m +# CONFIG_SND_SOC_NAU8821 is not set +CONFIG_SND_SOC_NAU8822=m +CONFIG_SND_SOC_NAU8824=m +CONFIG_SND_SOC_TPA6130A2=m +CONFIG_SND_SOC_LPASS_WSA_MACRO=m +CONFIG_SND_SOC_LPASS_VA_MACRO=m +CONFIG_SND_SOC_LPASS_RX_MACRO=m +CONFIG_SND_SOC_LPASS_TX_MACRO=m +# end of CODEC drivers + +CONFIG_SND_SIMPLE_CARD_UTILS=m +CONFIG_SND_SIMPLE_CARD=m +CONFIG_SND_AUDIO_GRAPH_CARD=m +# CONFIG_SND_AUDIO_GRAPH_CARD2 is not set +# CONFIG_SND_TEST_COMPONENT is not set +CONFIG_SND_SYNTH_EMUX=m +CONFIG_SND_XEN_FRONTEND=m +CONFIG_SND_VIRTIO=m +CONFIG_AC97_BUS=m + +# +# HID support +# +CONFIG_HID=y +CONFIG_HID_BATTERY_STRENGTH=y +CONFIG_HIDRAW=y +CONFIG_UHID=m +CONFIG_HID_GENERIC=y + +# +# Special HID drivers +# +CONFIG_HID_A4TECH=m +CONFIG_HID_ACCUTOUCH=m +CONFIG_HID_ACRUX=m +CONFIG_HID_ACRUX_FF=y +CONFIG_HID_APPLE=m +CONFIG_HID_APPLEIR=m +# CONFIG_HID_ASUS is not set +CONFIG_HID_AUREAL=m +CONFIG_HID_BELKIN=m +CONFIG_HID_BETOP_FF=m +CONFIG_HID_BIGBEN_FF=m +CONFIG_HID_CHERRY=m +CONFIG_HID_CHICONY=m +CONFIG_HID_CORSAIR=m +CONFIG_HID_COUGAR=m +CONFIG_HID_MACALLY=m +CONFIG_HID_PRODIKEYS=m +CONFIG_HID_CMEDIA=m +CONFIG_HID_CP2112=m +CONFIG_HID_CREATIVE_SB0540=m +CONFIG_HID_CYPRESS=m +CONFIG_HID_DRAGONRISE=m +CONFIG_DRAGONRISE_FF=y +CONFIG_HID_EMS_FF=m +CONFIG_HID_ELAN=m +CONFIG_HID_ELECOM=m +CONFIG_HID_ELO=m +CONFIG_HID_EZKEY=m +CONFIG_HID_FT260=m +CONFIG_HID_GEMBIRD=m +CONFIG_HID_GFRM=m +CONFIG_HID_GLORIOUS=m +CONFIG_HID_HOLTEK=m +CONFIG_HOLTEK_FF=y +CONFIG_HID_GOOGLE_HAMMER=m +# CONFIG_HID_VIVALDI is not set +CONFIG_HID_GT683R=m +CONFIG_HID_KEYTOUCH=m +CONFIG_HID_KYE=m +CONFIG_HID_UCLOGIC=m +CONFIG_HID_WALTOP=m +CONFIG_HID_VIEWSONIC=m +# CONFIG_HID_XIAOMI is not set +CONFIG_HID_GYRATION=m +CONFIG_HID_ICADE=m +CONFIG_HID_ITE=m +CONFIG_HID_JABRA=m +CONFIG_HID_TWINHAN=m +CONFIG_HID_KENSINGTON=m +CONFIG_HID_LCPOWER=m +CONFIG_HID_LED=m +CONFIG_HID_LENOVO=m +CONFIG_HID_LOGITECH=m +CONFIG_HID_LOGITECH_DJ=m +CONFIG_HID_LOGITECH_HIDPP=m +CONFIG_LOGITECH_FF=y +CONFIG_LOGIRUMBLEPAD2_FF=y +CONFIG_LOGIG940_FF=y +CONFIG_LOGIWHEELS_FF=y +CONFIG_HID_MAGICMOUSE=m +CONFIG_HID_MALTRON=m +# CONFIG_HID_MAYFLASH is not set +CONFIG_HID_REDRAGON=m +CONFIG_HID_MICROSOFT=m +CONFIG_HID_MONTEREY=m +CONFIG_HID_MULTITOUCH=m +# CONFIG_HID_NINTENDO is not set +CONFIG_HID_NTI=m +CONFIG_HID_NTRIG=m +CONFIG_HID_ORTEK=m +CONFIG_HID_PANTHERLORD=m +CONFIG_PANTHERLORD_FF=y +CONFIG_HID_PENMOUNT=m +CONFIG_HID_PETALYNX=m +CONFIG_HID_PICOLCD=m +CONFIG_HID_PICOLCD_FB=y +CONFIG_HID_PICOLCD_BACKLIGHT=y +CONFIG_HID_PICOLCD_LCD=y +CONFIG_HID_PICOLCD_LEDS=y +CONFIG_HID_PICOLCD_CIR=y +CONFIG_HID_PLANTRONICS=m +CONFIG_HID_PRIMAX=m +CONFIG_HID_RETRODE=m +CONFIG_HID_ROCCAT=m +CONFIG_HID_SAITEK=m +CONFIG_HID_SAMSUNG=m +CONFIG_HID_SEMITEK=m +CONFIG_HID_SONY=m +CONFIG_SONY_FF=y +CONFIG_HID_SPEEDLINK=m +CONFIG_HID_STEAM=m +CONFIG_HID_STEELSERIES=m +CONFIG_HID_SUNPLUS=m +CONFIG_HID_RMI=m +CONFIG_HID_GREENASIA=m +CONFIG_GREENASIA_FF=y +CONFIG_HID_SMARTJOYPLUS=m +CONFIG_SMARTJOYPLUS_FF=y +CONFIG_HID_TIVO=m +CONFIG_HID_TOPSEED=m +CONFIG_HID_THINGM=m +CONFIG_HID_THRUSTMASTER=m +CONFIG_THRUSTMASTER_FF=y +CONFIG_HID_UDRAW_PS3=m +CONFIG_HID_U2FZERO=m +CONFIG_HID_WACOM=m +CONFIG_HID_WIIMOTE=m +CONFIG_HID_XINMO=m +CONFIG_HID_ZEROPLUS=m +CONFIG_ZEROPLUS_FF=y +CONFIG_HID_ZYDACRON=m +CONFIG_HID_SENSOR_HUB=m +CONFIG_HID_SENSOR_CUSTOM_SENSOR=m +CONFIG_HID_ALPS=m +CONFIG_HID_MCP2221=m +# end of Special HID drivers + +# +# USB HID support +# +CONFIG_USB_HID=y +CONFIG_HID_PID=y +CONFIG_USB_HIDDEV=y +# end of USB HID support + +# +# I2C HID support +# +CONFIG_I2C_HID_OF=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 +CONFIG_USB_LED_TRIG=y +CONFIG_USB_ULPI_BUS=y +CONFIG_USB_CONN_GPIO=m +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB=y +CONFIG_USB_PCI=y +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y + +# +# Miscellaneous USB options +# +CONFIG_USB_DEFAULT_PERSIST=y +# CONFIG_USB_FEW_INIT_RETRIES is not set +# CONFIG_USB_DYNAMIC_MINORS is not set +CONFIG_USB_OTG=y +# CONFIG_USB_OTG_PRODUCTLIST is not set +# CONFIG_USB_OTG_DISABLE_EXTERNAL_HUB is not set +CONFIG_USB_OTG_FSM=m +CONFIG_USB_LEDS_TRIGGER_USBPORT=y +CONFIG_USB_AUTOSUSPEND_DELAY=2 +CONFIG_USB_MON=m + +# +# USB Host Controller Drivers +# +# CONFIG_USB_C67X00_HCD is not set +CONFIG_USB_XHCI_HCD=y +# CONFIG_USB_XHCI_DBGCAP is not set +CONFIG_USB_XHCI_PCI=y +# CONFIG_USB_XHCI_PCI_RENESAS is not set +CONFIG_USB_XHCI_PLATFORM=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_EHCI_TT_NEWSCHED=y +CONFIG_USB_EHCI_PCI=y +CONFIG_USB_EHCI_FSL=m +CONFIG_USB_EHCI_HCD_PLATFORM=y +CONFIG_USB_OXU210HP_HCD=m +CONFIG_USB_ISP116X_HCD=m +CONFIG_USB_FOTG210_HCD=m +CONFIG_USB_MAX3421_HCD=m +CONFIG_USB_OHCI_HCD=y +CONFIG_USB_OHCI_HCD_PCI=y +CONFIG_USB_OHCI_HCD_PLATFORM=y +# CONFIG_USB_UHCI_HCD is not set +# CONFIG_USB_U132_HCD is not set +# CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set +CONFIG_USB_HCD_BCMA=m +CONFIG_USB_HCD_SSB=m +# CONFIG_USB_HCD_TEST_MODE is not set + +# +# USB Device Class drivers +# +CONFIG_USB_ACM=m +CONFIG_USB_PRINTER=m +CONFIG_USB_WDM=m +CONFIG_USB_TMC=m + +# +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may +# + +# +# also be needed; see USB_STORAGE Help for more info +# +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_DEBUG is not set +CONFIG_USB_STORAGE_REALTEK=m +# CONFIG_REALTEK_AUTOPM is not set +CONFIG_USB_STORAGE_DATAFAB=m +CONFIG_USB_STORAGE_FREECOM=m +CONFIG_USB_STORAGE_ISD200=m +CONFIG_USB_STORAGE_USBAT=m +CONFIG_USB_STORAGE_SDDR09=m +CONFIG_USB_STORAGE_SDDR55=m +CONFIG_USB_STORAGE_JUMPSHOT=m +CONFIG_USB_STORAGE_ALAUDA=m +CONFIG_USB_STORAGE_ONETOUCH=m +CONFIG_USB_STORAGE_KARMA=m +CONFIG_USB_STORAGE_CYPRESS_ATACB=m +CONFIG_USB_STORAGE_ENE_UB6250=m +CONFIG_USB_UAS=m + +# +# USB Imaging devices +# +CONFIG_USB_MDC800=m +CONFIG_USB_MICROTEK=m +CONFIG_USBIP_CORE=m +CONFIG_USBIP_VHCI_HCD=m +CONFIG_USBIP_VHCI_HC_PORTS=8 +CONFIG_USBIP_VHCI_NR_HCS=1 +CONFIG_USBIP_HOST=m +CONFIG_USBIP_VUDC=m +# CONFIG_USBIP_DEBUG is not set +CONFIG_USB_CDNS_SUPPORT=m +# CONFIG_USB_CDNS3 is not set +# CONFIG_USB_MUSB_HDRC is not set +CONFIG_USB_DWC3=y +# CONFIG_USB_DWC3_ULPI is not set +# CONFIG_USB_DWC3_HOST is not set +# CONFIG_USB_DWC3_GADGET is not set +CONFIG_USB_DWC3_DUAL_ROLE=y + +# +# Platform Glue Driver Support +# +CONFIG_USB_DWC3_HAPS=y +CONFIG_USB_DWC3_MESON_G12A=m +CONFIG_USB_DWC3_OF_SIMPLE=y +CONFIG_USB_DWC2=y +# CONFIG_USB_DWC2_HOST is not set + +# +# Gadget/Dual-role mode requires USB Gadget support to be enabled +# +# CONFIG_USB_DWC2_PERIPHERAL is not set +CONFIG_USB_DWC2_DUAL_ROLE=y +CONFIG_USB_DWC2_PCI=m +# CONFIG_USB_DWC2_DEBUG is not set +# CONFIG_USB_DWC2_TRACK_MISSED_SOFS is not set +CONFIG_USB_CHIPIDEA=y +CONFIG_USB_CHIPIDEA_UDC=y +CONFIG_USB_CHIPIDEA_HOST=y +CONFIG_USB_CHIPIDEA_PCI=y +CONFIG_USB_CHIPIDEA_MSM=y +CONFIG_USB_CHIPIDEA_IMX=y +CONFIG_USB_CHIPIDEA_GENERIC=y +CONFIG_USB_CHIPIDEA_TEGRA=y +CONFIG_USB_ISP1760=y +CONFIG_USB_ISP1760_HCD=y +CONFIG_USB_ISP1761_UDC=y +# CONFIG_USB_ISP1760_HOST_ROLE is not set +# CONFIG_USB_ISP1760_GADGET_ROLE is not set +CONFIG_USB_ISP1760_DUAL_ROLE=y + +# +# USB port drivers +# +CONFIG_USB_SERIAL=m +CONFIG_USB_SERIAL_GENERIC=y +CONFIG_USB_SERIAL_SIMPLE=m +CONFIG_USB_SERIAL_AIRCABLE=m +CONFIG_USB_SERIAL_ARK3116=m +CONFIG_USB_SERIAL_BELKIN=m +CONFIG_USB_SERIAL_CH341=m +CONFIG_USB_SERIAL_WHITEHEAT=m +CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m +CONFIG_USB_SERIAL_CP210X=m +CONFIG_USB_SERIAL_CYPRESS_M8=m +CONFIG_USB_SERIAL_EMPEG=m +CONFIG_USB_SERIAL_FTDI_SIO=m +CONFIG_USB_SERIAL_VISOR=m +CONFIG_USB_SERIAL_IPAQ=m +CONFIG_USB_SERIAL_IR=m +CONFIG_USB_SERIAL_EDGEPORT=m +CONFIG_USB_SERIAL_EDGEPORT_TI=m +CONFIG_USB_SERIAL_F81232=m +CONFIG_USB_SERIAL_F8153X=m +CONFIG_USB_SERIAL_GARMIN=m +CONFIG_USB_SERIAL_IPW=m +CONFIG_USB_SERIAL_IUU=m +CONFIG_USB_SERIAL_KEYSPAN_PDA=m +CONFIG_USB_SERIAL_KEYSPAN=m +CONFIG_USB_SERIAL_KLSI=m +CONFIG_USB_SERIAL_KOBIL_SCT=m +CONFIG_USB_SERIAL_MCT_U232=m +CONFIG_USB_SERIAL_METRO=m +CONFIG_USB_SERIAL_MOS7720=m +CONFIG_USB_SERIAL_MOS7840=m +CONFIG_USB_SERIAL_MXUPORT=m +CONFIG_USB_SERIAL_NAVMAN=m +CONFIG_USB_SERIAL_PL2303=m +CONFIG_USB_SERIAL_OTI6858=m +CONFIG_USB_SERIAL_QCAUX=m +CONFIG_USB_SERIAL_QUALCOMM=m +CONFIG_USB_SERIAL_SPCP8X5=m +CONFIG_USB_SERIAL_SAFE=m +# CONFIG_USB_SERIAL_SAFE_PADDED is not set +CONFIG_USB_SERIAL_SIERRAWIRELESS=m +CONFIG_USB_SERIAL_SYMBOL=m +CONFIG_USB_SERIAL_TI=m +CONFIG_USB_SERIAL_CYBERJACK=m +CONFIG_USB_SERIAL_WWAN=m +CONFIG_USB_SERIAL_OPTION=m +CONFIG_USB_SERIAL_OMNINET=m +CONFIG_USB_SERIAL_OPTICON=m +CONFIG_USB_SERIAL_XSENS_MT=m +CONFIG_USB_SERIAL_WISHBONE=m +CONFIG_USB_SERIAL_SSU100=m +CONFIG_USB_SERIAL_QT2=m +CONFIG_USB_SERIAL_UPD78F0730=m +CONFIG_USB_SERIAL_XR=m +CONFIG_USB_SERIAL_DEBUG=m + +# +# USB Miscellaneous drivers +# +CONFIG_USB_EMI62=m +CONFIG_USB_EMI26=m +CONFIG_USB_ADUTUX=m +CONFIG_USB_SEVSEG=m +CONFIG_USB_LEGOTOWER=m +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 +CONFIG_USB_LD=m +CONFIG_USB_TRANCEVIBRATOR=m +CONFIG_USB_IOWARRIOR=m +CONFIG_USB_TEST=m +CONFIG_USB_EHSET_TEST_FIXTURE=m +CONFIG_USB_ISIGHTFW=m +CONFIG_USB_YUREX=m +CONFIG_USB_EZUSB_FX2=m +CONFIG_USB_HUB_USB251XB=m +CONFIG_USB_HSIC_USB3503=y +# CONFIG_USB_HSIC_USB4604 is not set +CONFIG_USB_LINK_LAYER_TEST=m +CONFIG_USB_CHAOSKEY=m +CONFIG_USB_ATM=m +CONFIG_USB_SPEEDTOUCH=m +CONFIG_USB_CXACRU=m +CONFIG_USB_UEAGLEATM=m +CONFIG_USB_XUSBATM=m + +# +# USB Physical Layer drivers +# +CONFIG_USB_PHY=y +CONFIG_NOP_USB_XCEIV=y +# CONFIG_USB_GPIO_VBUS is not set +# CONFIG_USB_ISP1301 is not set +CONFIG_USB_ULPI=y +CONFIG_USB_ULPI_VIEWPORT=y +# end of USB Physical Layer drivers + +CONFIG_USB_GADGET=y +# CONFIG_USB_GADGET_DEBUG is not set +# CONFIG_USB_GADGET_DEBUG_FILES is not set +# CONFIG_USB_GADGET_DEBUG_FS is not set +CONFIG_USB_GADGET_VBUS_DRAW=2 +CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2 +CONFIG_U_SERIAL_CONSOLE=y + +# +# USB Peripheral Controller +# +# CONFIG_USB_FOTG210_UDC is not set +# CONFIG_USB_GR_UDC is not set +# CONFIG_USB_R8A66597 is not set +# CONFIG_USB_PXA27X is not set +# CONFIG_USB_MV_UDC is not set +# CONFIG_USB_MV_U3D is not set +CONFIG_USB_SNP_CORE=m +# CONFIG_USB_SNP_UDC_PLAT is not set +# CONFIG_USB_M66592 is not set +# CONFIG_USB_BDC_UDC is not set +CONFIG_USB_AMD5536UDC=m +# CONFIG_USB_NET2272 is not set +CONFIG_USB_NET2280=m +CONFIG_USB_GOKU=m +CONFIG_USB_EG20T=m +# CONFIG_USB_GADGET_XILINX is not set +CONFIG_USB_MAX3420_UDC=m +# CONFIG_USB_DUMMY_HCD is not set +# end of USB Peripheral Controller + +CONFIG_USB_LIBCOMPOSITE=m +CONFIG_USB_F_ACM=m +CONFIG_USB_F_SS_LB=m +CONFIG_USB_U_SERIAL=m +CONFIG_USB_U_ETHER=m +CONFIG_USB_U_AUDIO=m +CONFIG_USB_F_SERIAL=m +CONFIG_USB_F_OBEX=m +CONFIG_USB_F_NCM=m +CONFIG_USB_F_ECM=m +CONFIG_USB_F_PHONET=m +CONFIG_USB_F_EEM=m +CONFIG_USB_F_SUBSET=m +CONFIG_USB_F_RNDIS=m +CONFIG_USB_F_MASS_STORAGE=m +CONFIG_USB_F_FS=m +CONFIG_USB_F_UAC1=m +CONFIG_USB_F_UAC2=m +CONFIG_USB_F_UVC=m +CONFIG_USB_F_MIDI=m +CONFIG_USB_F_HID=m +CONFIG_USB_F_PRINTER=m +CONFIG_USB_F_TCM=m +CONFIG_USB_CONFIGFS=m +CONFIG_USB_CONFIGFS_SERIAL=y +CONFIG_USB_CONFIGFS_ACM=y +CONFIG_USB_CONFIGFS_OBEX=y +CONFIG_USB_CONFIGFS_NCM=y +CONFIG_USB_CONFIGFS_ECM=y +CONFIG_USB_CONFIGFS_ECM_SUBSET=y +CONFIG_USB_CONFIGFS_RNDIS=y +CONFIG_USB_CONFIGFS_EEM=y +# CONFIG_USB_CONFIGFS_PHONET is not set +CONFIG_USB_CONFIGFS_MASS_STORAGE=y +CONFIG_USB_CONFIGFS_F_LB_SS=y +CONFIG_USB_CONFIGFS_F_FS=y +CONFIG_USB_CONFIGFS_F_UAC1=y +# CONFIG_USB_CONFIGFS_F_UAC1_LEGACY is not set +CONFIG_USB_CONFIGFS_F_UAC2=y +CONFIG_USB_CONFIGFS_F_MIDI=y +CONFIG_USB_CONFIGFS_F_HID=y +CONFIG_USB_CONFIGFS_F_UVC=y +CONFIG_USB_CONFIGFS_F_PRINTER=y +CONFIG_USB_CONFIGFS_F_TCM=y + +# +# USB Gadget precomposed configurations +# +CONFIG_USB_ZERO=m +# CONFIG_USB_ZERO_HNPTEST is not set +CONFIG_USB_AUDIO=m +# CONFIG_GADGET_UAC1 is not set +CONFIG_USB_ETH=m +CONFIG_USB_ETH_RNDIS=y +CONFIG_USB_ETH_EEM=y +CONFIG_USB_G_NCM=m +CONFIG_USB_GADGETFS=m +CONFIG_USB_FUNCTIONFS=m +CONFIG_USB_FUNCTIONFS_ETH=y +CONFIG_USB_FUNCTIONFS_RNDIS=y +CONFIG_USB_FUNCTIONFS_GENERIC=y +CONFIG_USB_MASS_STORAGE=m +CONFIG_USB_GADGET_TARGET=m +CONFIG_USB_G_SERIAL=m +CONFIG_USB_MIDI_GADGET=m +CONFIG_USB_G_PRINTER=m +CONFIG_USB_CDC_COMPOSITE=m +CONFIG_USB_G_NOKIA=m +CONFIG_USB_G_ACM_MS=m +CONFIG_USB_G_MULTI=m +CONFIG_USB_G_MULTI_RNDIS=y +CONFIG_USB_G_MULTI_CDC=y +CONFIG_USB_G_HID=m +# CONFIG_USB_G_DBGP is not set +CONFIG_USB_G_WEBCAM=m +CONFIG_USB_RAW_GADGET=m +# end of USB Gadget precomposed configurations + +CONFIG_TYPEC=m +CONFIG_TYPEC_TCPM=m +CONFIG_TYPEC_TCPCI=m +CONFIG_TYPEC_RT1711H=m +# CONFIG_TYPEC_TCPCI_MAXIM is not set +CONFIG_TYPEC_FUSB302=m +CONFIG_TYPEC_UCSI=m +CONFIG_UCSI_CCG=m +CONFIG_TYPEC_TPS6598X=m +CONFIG_TYPEC_HD3SS3220=m +# CONFIG_TYPEC_STUSB160X is not set + +# +# USB Type-C Multiplexer/DeMultiplexer Switch support +# +CONFIG_TYPEC_MUX_PI3USB30532=m +# end of USB Type-C Multiplexer/DeMultiplexer Switch support + +# +# USB Type-C Alternate Mode drivers +# +CONFIG_TYPEC_DP_ALTMODE=m +# CONFIG_TYPEC_NVIDIA_ALTMODE is not set +# end of USB Type-C Alternate Mode drivers + +CONFIG_USB_ROLE_SWITCH=y +CONFIG_MMC=y +CONFIG_PWRSEQ_EMMC=y +CONFIG_PWRSEQ_SD8787=m +CONFIG_PWRSEQ_SIMPLE=y +CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_MINORS=32 +# CONFIG_SDIO_UART is not set +# CONFIG_MMC_TEST is not set + +# +# MMC/SD/SDIO Host Controller Drivers +# +# CONFIG_MMC_DEBUG is not set +CONFIG_MMC_ARMMMCI=y +CONFIG_MMC_STM32_SDMMC=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_IO_ACCESSORS=y +# CONFIG_MMC_SDHCI_PCI is not set +CONFIG_MMC_SDHCI_PLTFM=y +CONFIG_MMC_SDHCI_OF_ARASAN=y +CONFIG_MMC_SDHCI_OF_ASPEED=m +# CONFIG_MMC_SDHCI_OF_AT91 is not set +# CONFIG_MMC_SDHCI_OF_DWCMSHC is not set +CONFIG_MMC_SDHCI_CADENCE=y +# CONFIG_MMC_SDHCI_F_SDH30 is not set +CONFIG_MMC_SDHCI_MILBEAUT=m +CONFIG_MMC_MESON_GX=m +CONFIG_MMC_MESON_MX_SDIO=m +CONFIG_MMC_ALCOR=m +# CONFIG_MMC_TIFM_SD is not set +CONFIG_MMC_SPI=y +# CONFIG_MMC_CB710 is not set +# CONFIG_MMC_VIA_SDMMC is not set +CONFIG_MMC_DW=y +CONFIG_MMC_DW_PLTFM=y +# CONFIG_MMC_DW_BLUEFIELD is not set +CONFIG_MMC_DW_EXYNOS=y +CONFIG_MMC_DW_HI3798CV200=m +CONFIG_MMC_DW_K3=y +# CONFIG_MMC_DW_PCI is not set +CONFIG_MMC_DW_ROCKCHIP=y +# CONFIG_MMC_VUB300 is not set +# CONFIG_MMC_USHC is not set +# CONFIG_MMC_USDHI6ROL0 is not set +CONFIG_MMC_REALTEK_PCI=m +CONFIG_MMC_REALTEK_USB=m +CONFIG_MMC_SUNXI=m +CONFIG_MMC_CQHCI=y +CONFIG_MMC_HSQ=m +# CONFIG_MMC_TOSHIBA_PCI is not set +# CONFIG_MMC_MTK is not set +CONFIG_MMC_SDHCI_XENON=y +# CONFIG_MMC_SDHCI_OMAP is not set +CONFIG_MMC_SDHCI_AM654=m +# CONFIG_MEMSTICK is not set +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y +# CONFIG_LEDS_CLASS_FLASH is not set +# CONFIG_LEDS_CLASS_MULTICOLOR is not set +# CONFIG_LEDS_BRIGHTNESS_HW_CHANGED is not set + +# +# LED drivers +# +CONFIG_LEDS_AN30259A=m +# CONFIG_LEDS_AW2013 is not set +# CONFIG_LEDS_BCM6328 is not set +# CONFIG_LEDS_BCM6358 is not set +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 +CONFIG_LEDS_GPIO=y +# CONFIG_LEDS_LP3944 is not set +# CONFIG_LEDS_LP3952 is not set +# CONFIG_LEDS_LP50XX is not set +# CONFIG_LEDS_LP55XX_COMMON is not set +# CONFIG_LEDS_LP8860 is not set +# CONFIG_LEDS_PCA955X is not set +# CONFIG_LEDS_PCA963X is not set +# CONFIG_LEDS_DAC124S085 is not set +CONFIG_LEDS_PWM=m +CONFIG_LEDS_REGULATOR=m +# 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 + +# +# LED driver for blink(1) USB RGB LED is under Special HID drivers (HID_THINGM) +# +# CONFIG_LEDS_BLINKM is not set +CONFIG_LEDS_SYSCON=y +CONFIG_LEDS_MLXREG=m +CONFIG_LEDS_USER=y +# CONFIG_LEDS_SPI_BYTE is not set +# CONFIG_LEDS_TI_LMU_COMMON is not set + +# +# Flash and Torch LED drivers +# + +# +# LED Triggers +# +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_TIMER=m +CONFIG_LEDS_TRIGGER_ONESHOT=m +CONFIG_LEDS_TRIGGER_DISK=y +CONFIG_LEDS_TRIGGER_MTD=y +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 + +# +# iptables trigger is under Netfilter config (LED target) +# +CONFIG_LEDS_TRIGGER_TRANSIENT=m +CONFIG_LEDS_TRIGGER_CAMERA=m +CONFIG_LEDS_TRIGGER_PANIC=y +CONFIG_LEDS_TRIGGER_NETDEV=m +CONFIG_LEDS_TRIGGER_PATTERN=m +CONFIG_LEDS_TRIGGER_AUDIO=m +CONFIG_LEDS_TRIGGER_TTY=m +# CONFIG_ACCESSIBILITY is not set +# CONFIG_INFINIBAND is not set +CONFIG_EDAC_SUPPORT=y +CONFIG_EDAC=y +CONFIG_EDAC_LEGACY_SYSFS=y +# CONFIG_EDAC_DEBUG is not set +# CONFIG_EDAC_THUNDERX is not set +# CONFIG_EDAC_XGENE is not set +CONFIG_EDAC_DMC520=m +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +CONFIG_RTC_SYSTOHC=y +CONFIG_RTC_SYSTOHC_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set +CONFIG_RTC_LIB_KUNIT_TEST=m +CONFIG_RTC_NVMEM=y + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +# CONFIG_RTC_DRV_TEST is not set + +# +# I2C RTC drivers +# +# CONFIG_RTC_DRV_ABB5ZES3 is not set +# CONFIG_RTC_DRV_ABEOZ9 is not set +# CONFIG_RTC_DRV_ABX80X is not set +CONFIG_RTC_DRV_AC100=m +CONFIG_RTC_DRV_AS3722=m +CONFIG_RTC_DRV_DS1307=y +# CONFIG_RTC_DRV_DS1307_CENTURY 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_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_RV3032 is not set +CONFIG_RTC_DRV_RV8803=m +CONFIG_RTC_DRV_S5M=m +CONFIG_RTC_DRV_SD3078=m + +# +# 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_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 + +# +# Platform RTC drivers +# +# CONFIG_RTC_DRV_DS1286 is not set +# CONFIG_RTC_DRV_DS1511 is not set +# CONFIG_RTC_DRV_DS1553 is not set +# 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_STK17TA8 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T35 is not set +# CONFIG_RTC_DRV_M48T59 is not set +# 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_ZYNQMP is not set +# CONFIG_RTC_DRV_CROS_EC is not set +CONFIG_RTC_DRV_NTXEC=m + +# +# on-CPU RTC drivers +# +CONFIG_RTC_DRV_MESON_VRTC=m +# CONFIG_RTC_DRV_PL030 is not set +CONFIG_RTC_DRV_PL031=y +CONFIG_RTC_DRV_SUN6I=y +CONFIG_RTC_DRV_CADENCE=m +# 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_DMADEVICES=y +# CONFIG_DMADEVICES_DEBUG is not set + +# +# DMA Devices +# +CONFIG_ASYNC_TX_ENABLE_CHANNEL_SWITCH=y +CONFIG_DMA_ENGINE=y +CONFIG_DMA_VIRTUAL_CHANNELS=m +CONFIG_DMA_OF=y +CONFIG_ALTERA_MSGDMA=m +# CONFIG_AMBA_PL08X is not set +CONFIG_BCM_SBA_RAID=m +CONFIG_DMA_SUN6I=m +CONFIG_DW_AXI_DMAC=m +# CONFIG_FSL_EDMA is not set +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_ZYNQMP_DMA is not set +# CONFIG_XILINX_ZYNQMP_DPDMA is not set +CONFIG_QCOM_HIDMA_MGMT=y +CONFIG_QCOM_HIDMA=y +# CONFIG_DW_DMAC is not set +# CONFIG_DW_DMAC_PCI is not set +CONFIG_DW_EDMA=m +CONFIG_DW_EDMA_PCIE=m +CONFIG_SF_PDMA=m + +# +# DMA Clients +# +# CONFIG_ASYNC_TX_DMA is not set +# CONFIG_DMATEST is not set +CONFIG_DMA_ENGINE_RAID=y + +# +# DMABUF options +# +CONFIG_SYNC_FILE=y +# CONFIG_SW_SYNC is not set +# CONFIG_UDMABUF is not set +# CONFIG_DMABUF_MOVE_NOTIFY is not set +# CONFIG_DMABUF_DEBUG is not set +CONFIG_DMABUF_SELFTESTS=m +# CONFIG_DMABUF_HEAPS is not set +# CONFIG_DMABUF_SYSFS_STATS is not set +# end of DMABUF options + +# CONFIG_AUXDISPLAY is not set +CONFIG_UIO=m +# CONFIG_UIO_CIF is not set +# CONFIG_UIO_PDRV_GENIRQ is not set +# CONFIG_UIO_DMEM_GENIRQ is not set +# CONFIG_UIO_AEC is not set +# CONFIG_UIO_SERCOS3 is not set +# CONFIG_UIO_PCI_GENERIC is not set +# CONFIG_UIO_NETX is not set +# CONFIG_UIO_PRUSS is not set +# CONFIG_UIO_MF624 is not set +CONFIG_VFIO=y +CONFIG_VFIO_IOMMU_TYPE1=y +CONFIG_VFIO_VIRQFD=y +# CONFIG_VFIO_NOIOMMU is not set +CONFIG_VFIO_PCI_CORE=y +CONFIG_VFIO_PCI_MMAP=y +CONFIG_VFIO_PCI_INTX=y +CONFIG_VFIO_PCI=y +# CONFIG_VFIO_PLATFORM is not set +# CONFIG_VFIO_MDEV is not set +CONFIG_VIRT_DRIVERS=y +# CONFIG_NITRO_ENCLAVES is not set +CONFIG_VIRTIO=y +CONFIG_VIRTIO_PCI_LIB=y +CONFIG_VIRTIO_PCI_LIB_LEGACY=y +CONFIG_VIRTIO_MENU=y +CONFIG_VIRTIO_PCI=y +CONFIG_VIRTIO_PCI_LEGACY=y +CONFIG_VIRTIO_VDPA=m +CONFIG_VIRTIO_BALLOON=y +CONFIG_VIRTIO_INPUT=m +CONFIG_VIRTIO_MMIO=y +# CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES is not set +CONFIG_VIRTIO_DMA_SHARED_BUFFER=m +CONFIG_VDPA=m +CONFIG_VDPA_SIM=m +CONFIG_VDPA_SIM_NET=m +CONFIG_VDPA_SIM_BLOCK=m +CONFIG_VDPA_USER=m +CONFIG_IFCVF=m +CONFIG_VP_VDPA=m +CONFIG_VHOST_IOTLB=m +CONFIG_VHOST_RING=m +CONFIG_VHOST=m +CONFIG_VHOST_MENU=y +CONFIG_VHOST_NET=m +CONFIG_VHOST_SCSI=m +# CONFIG_VHOST_VSOCK is not set +CONFIG_VHOST_VDPA=m +# CONFIG_VHOST_CROSS_ENDIAN_LEGACY is not set + +# +# Microsoft Hyper-V guest support +# +# end of Microsoft Hyper-V guest support + +# +# Xen driver support +# +CONFIG_XEN_BALLOON=y +CONFIG_XEN_SCRUB_PAGES_DEFAULT=y +CONFIG_XEN_DEV_EVTCHN=y +CONFIG_XEN_BACKEND=y +CONFIG_XENFS=y +CONFIG_XEN_COMPAT_XENFS=y +CONFIG_XEN_SYS_HYPERVISOR=y +CONFIG_XEN_XENBUS_FRONTEND=y +CONFIG_XEN_GNTDEV=y +CONFIG_XEN_GRANT_DEV_ALLOC=y +# CONFIG_XEN_GRANT_DMA_ALLOC is not set +CONFIG_SWIOTLB_XEN=y +CONFIG_XEN_PCI_STUB=y +CONFIG_XEN_PCIDEV_STUB=m +# CONFIG_XEN_PVCALLS_FRONTEND is not set +# CONFIG_XEN_PVCALLS_BACKEND is not set +CONFIG_XEN_SCSI_BACKEND=m +CONFIG_XEN_PRIVCMD=y +CONFIG_XEN_EFI=y +CONFIG_XEN_AUTO_XLATE=y +CONFIG_XEN_FRONT_PGDIR_SHBUF=m +# end of Xen driver support + +# CONFIG_GREYBUS is not set +# CONFIG_COMEDI is not set +CONFIG_STAGING=y +# CONFIG_PRISM2_USB is not set +CONFIG_RTL8192U=m +CONFIG_RTLLIB=m +CONFIG_RTLLIB_CRYPTO_CCMP=m +CONFIG_RTLLIB_CRYPTO_TKIP=m +CONFIG_RTLLIB_CRYPTO_WEP=m +CONFIG_RTL8192E=m +CONFIG_RTL8723BS=m +CONFIG_R8712U=m +# CONFIG_R8188EU is not set +CONFIG_RTS5208=m +CONFIG_VT6655=m +CONFIG_VT6656=m + +# +# IIO staging drivers +# + +# +# Accelerometers +# +# CONFIG_ADIS16203 is not set +# CONFIG_ADIS16240 is not set +# end of Accelerometers + +# +# Analog to digital converters +# +# CONFIG_AD7816 is not set +# CONFIG_AD7280 is not set +# end of Analog to digital converters + +# +# Analog digital bi-direction converters +# +# CONFIG_ADT7316 is not set +# end of Analog digital bi-direction converters + +# +# Capacitance to digital converters +# +# CONFIG_AD7746 is not set +# end of Capacitance to digital converters + +# +# Direct Digital Synthesis +# +CONFIG_AD9832=m +CONFIG_AD9834=m +# end of Direct Digital Synthesis + +# +# Network Analyzer, Impedance Converters +# +# 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 +# +# CONFIG_AD2S1210 is not set +# end of Resolver to digital converters +# end of IIO staging drivers + +CONFIG_FB_SM750=m +CONFIG_STAGING_MEDIA=y +CONFIG_VIDEO_HANTRO=m +CONFIG_VIDEO_HANTRO_ROCKCHIP=y +CONFIG_VIDEO_MESON_VDEC=m +CONFIG_VIDEO_ROCKCHIP_VDEC=m +CONFIG_VIDEO_SUNXI=y +CONFIG_VIDEO_SUNXI_CEDRUS=m +# CONFIG_VIDEO_ZORAN is not set +CONFIG_DVB_AV7110_IR=y +CONFIG_DVB_AV7110=m +CONFIG_DVB_AV7110_OSD=y +CONFIG_DVB_SP8870=m + +# +# Android +# +# end of Android + +# CONFIG_STAGING_BOARD is not set +# CONFIG_LTE_GDM724X is not set +# CONFIG_GS_FPGABOOT is not set +# CONFIG_UNISYSSPAR is not set +CONFIG_COMMON_CLK_XLNX_CLKWZRD=m +CONFIG_FB_TFT=m +CONFIG_FB_TFT_AGM1264K_FL=m +CONFIG_FB_TFT_BD663474=m +CONFIG_FB_TFT_HX8340BN=m +CONFIG_FB_TFT_HX8347D=m +CONFIG_FB_TFT_HX8353D=m +CONFIG_FB_TFT_HX8357D=m +CONFIG_FB_TFT_ILI9163=m +CONFIG_FB_TFT_ILI9320=m +CONFIG_FB_TFT_ILI9325=m +CONFIG_FB_TFT_ILI9340=m +CONFIG_FB_TFT_ILI9341=m +CONFIG_FB_TFT_ILI9481=m +CONFIG_FB_TFT_ILI9486=m +CONFIG_FB_TFT_PCD8544=m +CONFIG_FB_TFT_RA8875=m +CONFIG_FB_TFT_S6D02A1=m +CONFIG_FB_TFT_S6D1121=m +CONFIG_FB_TFT_SEPS525=m +CONFIG_FB_TFT_SH1106=m +CONFIG_FB_TFT_SSD1289=m +CONFIG_FB_TFT_SSD1305=m +CONFIG_FB_TFT_SSD1306=m +CONFIG_FB_TFT_SSD1331=m +CONFIG_FB_TFT_SSD1351=m +CONFIG_FB_TFT_ST7735R=m +CONFIG_FB_TFT_ST7789V=m +CONFIG_FB_TFT_TINYLCD=m +CONFIG_FB_TFT_TLS8204=m +CONFIG_FB_TFT_UC1611=m +CONFIG_FB_TFT_UC1701=m +CONFIG_FB_TFT_UPD161704=m +CONFIG_FB_TFT_WATTEROTT=m +# CONFIG_MOST_COMPONENTS is not set +# CONFIG_KS7010 is not set +# CONFIG_PI433 is not set +# CONFIG_XIL_AXIS_FIFO is not set +CONFIG_FIELDBUS_DEV=m +CONFIG_HMS_ANYBUSS_BUS=m +# CONFIG_ARCX_ANYBUS_CONTROLLER is not set +# CONFIG_HMS_PROFINET is not set +# CONFIG_QLGE is not set +CONFIG_WFX=m +# CONFIG_GOLDFISH is not set +CONFIG_CHROME_PLATFORMS=y +CONFIG_CROS_EC=y +# CONFIG_CROS_EC_I2C is not set +# CONFIG_CROS_EC_SPI is not set +CONFIG_CROS_EC_PROTO=y +CONFIG_CROS_EC_CHARDEV=y +CONFIG_CROS_EC_LIGHTBAR=y +CONFIG_CROS_EC_VBC=y +CONFIG_CROS_EC_DEBUGFS=y +CONFIG_CROS_EC_SENSORHUB=y +CONFIG_CROS_EC_SYSFS=y +CONFIG_CROS_EC_TYPEC=m +CONFIG_CROS_USBPD_NOTIFY=y +# CONFIG_MELLANOX_PLATFORM is not set +CONFIG_HAVE_CLK=y +CONFIG_HAVE_CLK_PREPARE=y +CONFIG_COMMON_CLK=y + +# +# Clock driver for ARM Reference designs +# +# CONFIG_CLK_ICST is not set +# CONFIG_CLK_SP810 is not set +CONFIG_CLK_VEXPRESS_OSC=m +# end of Clock driver for ARM Reference designs + +CONFIG_LMK04832=m +# CONFIG_COMMON_CLK_MAX77686 is not set +# CONFIG_COMMON_CLK_MAX9485 is not set +CONFIG_COMMON_CLK_RK808=y +CONFIG_COMMON_CLK_SCPI=y +# 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_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_PWM=y +# CONFIG_COMMON_CLK_VC5 is not set +CONFIG_COMMON_CLK_BD718XX=m +# CONFIG_COMMON_CLK_FIXED_MMIO is not set + +# +# Clock support for Amlogic platforms +# +CONFIG_COMMON_CLK_MESON_REGMAP=y +CONFIG_COMMON_CLK_MESON_DUALDIV=y +CONFIG_COMMON_CLK_MESON_MPLL=y +CONFIG_COMMON_CLK_MESON_PHASE=m +CONFIG_COMMON_CLK_MESON_PLL=y +CONFIG_COMMON_CLK_MESON_SCLK_DIV=m +CONFIG_COMMON_CLK_MESON_VID_PLL_DIV=y +CONFIG_COMMON_CLK_MESON_AO_CLKC=y +CONFIG_COMMON_CLK_MESON_EE_CLKC=y +CONFIG_COMMON_CLK_MESON_CPU_DYNDIV=y +CONFIG_COMMON_CLK_GXBB=y +CONFIG_COMMON_CLK_AXG=y +CONFIG_COMMON_CLK_AXG_AUDIO=m +CONFIG_COMMON_CLK_G12A=y +# end of Clock support for Amlogic platforms + +CONFIG_COMMON_CLK_ROCKCHIP=y +CONFIG_CLK_PX30=y +CONFIG_CLK_RK3308=y +CONFIG_CLK_RK3328=y +CONFIG_CLK_RK3368=y +CONFIG_CLK_RK3399=y +CONFIG_CLK_RK3568=y +CONFIG_CLK_SUNXI=y +CONFIG_CLK_SUNXI_CLOCKS=y +CONFIG_CLK_SUNXI_PRCM_SUN6I=y +CONFIG_CLK_SUNXI_PRCM_SUN8I=y +CONFIG_CLK_SUNXI_PRCM_SUN9I=y +CONFIG_SUNXI_CCU=y +CONFIG_SUN50I_A64_CCU=y +CONFIG_SUN50I_A100_CCU=y +CONFIG_SUN50I_A100_R_CCU=y +CONFIG_SUN50I_H6_CCU=y +CONFIG_SUN50I_H616_CCU=y +CONFIG_SUN50I_H6_R_CCU=y +CONFIG_SUN8I_H3_CCU=y +CONFIG_SUN8I_DE2_CCU=y +CONFIG_SUN8I_R_CCU=y +# CONFIG_XILINX_VCU is not set +# CONFIG_HWSPINLOCK is not set + +# +# Clock Source drivers +# +CONFIG_TIMER_OF=y +CONFIG_TIMER_PROBE=y +CONFIG_CLKSRC_MMIO=y +CONFIG_ROCKCHIP_TIMER=y +CONFIG_SUN4I_TIMER=y +CONFIG_ARM_ARCH_TIMER=y +CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y +CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND=y +CONFIG_FSL_ERRATUM_A008585=y +CONFIG_HISILICON_ERRATUM_161010101=y +CONFIG_ARM64_ERRATUM_858921=y +CONFIG_SUN50I_ERRATUM_UNKNOWN1=y +# CONFIG_MICROCHIP_PIT64B is not set +# end of Clock Source drivers + +CONFIG_MAILBOX=y +CONFIG_ARM_MHU=y +CONFIG_ARM_MHU_V2=m +CONFIG_PLATFORM_MHU=y +# CONFIG_PL320_MBOX is not set +CONFIG_ROCKCHIP_MBOX=y +# CONFIG_ALTERA_MBOX is not set +# CONFIG_MAILBOX_TEST is not set +CONFIG_SUN6I_MSGBOX=y +CONFIG_IOMMU_IOVA=y +CONFIG_IOMMU_API=y +CONFIG_IOMMU_SUPPORT=y + +# +# Generic IOMMU Pagetable Support +# +CONFIG_IOMMU_IO_PGTABLE=y +CONFIG_IOMMU_IO_PGTABLE_LPAE=y +# CONFIG_IOMMU_IO_PGTABLE_LPAE_SELFTEST is not set +# CONFIG_IOMMU_IO_PGTABLE_ARMV7S is not set +# end of Generic IOMMU Pagetable Support + +# CONFIG_IOMMU_DEBUGFS is not set +CONFIG_IOMMU_DEFAULT_DMA_STRICT=y +# CONFIG_IOMMU_DEFAULT_DMA_LAZY is not set +# CONFIG_IOMMU_DEFAULT_PASSTHROUGH is not set +CONFIG_OF_IOMMU=y +CONFIG_IOMMU_DMA=y +CONFIG_ROCKCHIP_IOMMU=y +# CONFIG_SUN50I_IOMMU is not set +CONFIG_ARM_SMMU=y +# CONFIG_ARM_SMMU_LEGACY_DT_BINDINGS is not set +CONFIG_ARM_SMMU_DISABLE_BYPASS_BY_DEFAULT=y +CONFIG_ARM_SMMU_V3=y +# CONFIG_ARM_SMMU_V3_SVA is not set +# CONFIG_VIRTIO_IOMMU is not set + +# +# Remoteproc drivers +# +# CONFIG_REMOTEPROC is not set +# end of Remoteproc drivers + +# +# Rpmsg drivers +# +# CONFIG_RPMSG_QCOM_GLINK_RPM is not set +# CONFIG_RPMSG_VIRTIO is not set +# end of Rpmsg drivers + +# CONFIG_SOUNDWIRE is not set + +# +# SOC (System On Chip) specific Drivers +# + +# +# Amlogic SoC drivers +# +CONFIG_MESON_CANVAS=m +CONFIG_MESON_CLK_MEASURE=y +CONFIG_MESON_GX_SOCINFO=y +CONFIG_MESON_GX_PM_DOMAINS=y +CONFIG_MESON_EE_PM_DOMAINS=y +CONFIG_MESON_SECURE_PM_DOMAINS=y +# end of Amlogic SoC drivers + +# +# Broadcom SoC drivers +# +CONFIG_SOC_BRCMSTB=y +# end of Broadcom SoC drivers + +# +# NXP/Freescale QorIQ SoC drivers +# +# CONFIG_QUICC_ENGINE is not set +# CONFIG_FSL_RCPM is not set +# end of NXP/Freescale QorIQ SoC drivers + +# +# i.MX SoC drivers +# +# end of i.MX SoC drivers + +# +# Enable LiteX SoC Builder specific drivers +# +CONFIG_LITEX=y +CONFIG_LITEX_SOC_CONTROLLER=m +# end of Enable LiteX SoC Builder specific drivers + +# +# Qualcomm SoC drivers +# +# end of Qualcomm SoC drivers + +CONFIG_ROCKCHIP_GRF=y +CONFIG_ROCKCHIP_IODOMAIN=y +CONFIG_ROCKCHIP_PM_DOMAINS=y +CONFIG_SUNXI_MBUS=y +CONFIG_SUNXI_SRAM=y +# CONFIG_SOC_TI is not set + +# +# Xilinx SoC drivers +# +# end of Xilinx SoC drivers +# end of SOC (System On Chip) specific Drivers + +CONFIG_PM_DEVFREQ=y + +# +# DEVFREQ Governors +# +CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y +CONFIG_DEVFREQ_GOV_PERFORMANCE=m +CONFIG_DEVFREQ_GOV_POWERSAVE=m +CONFIG_DEVFREQ_GOV_USERSPACE=m +CONFIG_DEVFREQ_GOV_PASSIVE=m + +# +# DEVFREQ Drivers +# +CONFIG_ARM_RK3399_DMC_DEVFREQ=y +CONFIG_PM_DEVFREQ_EVENT=y +CONFIG_DEVFREQ_EVENT_ROCKCHIP_DFI=y +CONFIG_EXTCON=y + +# +# Extcon Device Drivers +# +# CONFIG_EXTCON_ADC_JACK is not set +# CONFIG_EXTCON_FSA9480 is not set +# CONFIG_EXTCON_GPIO is not set +# CONFIG_EXTCON_MAX3355 is not set +CONFIG_EXTCON_PTN5150=m +# CONFIG_EXTCON_RT8973A is not set +# CONFIG_EXTCON_SM5502 is not set +CONFIG_EXTCON_USB_GPIO=y +# CONFIG_EXTCON_USBC_CROS_EC is not set +CONFIG_EXTCON_USBC_TUSB320=m +# CONFIG_MEMORY is not set +CONFIG_IIO=y +CONFIG_IIO_BUFFER=y +CONFIG_IIO_BUFFER_CB=m +# CONFIG_IIO_BUFFER_DMA is not set +# CONFIG_IIO_BUFFER_DMAENGINE is not set +# CONFIG_IIO_BUFFER_HW_CONSUMER is not set +CONFIG_IIO_KFIFO_BUF=y +CONFIG_IIO_TRIGGERED_BUFFER=y +CONFIG_IIO_CONFIGFS=m +CONFIG_IIO_TRIGGER=y +CONFIG_IIO_CONSUMERS_PER_TRIGGER=2 +CONFIG_IIO_SW_DEVICE=m +CONFIG_IIO_SW_TRIGGER=m +# CONFIG_IIO_TRIGGERED_EVENT is not set + +# +# Accelerometers +# +CONFIG_ADIS16201=m +CONFIG_ADIS16209=m +# CONFIG_ADXL313_I2C is not set +# CONFIG_ADXL313_SPI is not set +CONFIG_ADXL345=m +CONFIG_ADXL345_I2C=m +CONFIG_ADXL345_SPI=m +# CONFIG_ADXL355_I2C is not set +# CONFIG_ADXL355_SPI is not set +CONFIG_ADXL372=m +CONFIG_ADXL372_SPI=m +CONFIG_ADXL372_I2C=m +CONFIG_BMA180=m +CONFIG_BMA220=m +CONFIG_BMA400=m +CONFIG_BMA400_I2C=m +CONFIG_BMA400_SPI=m +CONFIG_BMC150_ACCEL=m +CONFIG_BMC150_ACCEL_I2C=m +CONFIG_BMC150_ACCEL_SPI=m +CONFIG_BMI088_ACCEL=m +CONFIG_BMI088_ACCEL_SPI=m +CONFIG_DA280=m +CONFIG_DA311=m +CONFIG_DMARD06=m +CONFIG_DMARD09=m +CONFIG_DMARD10=m +CONFIG_FXLS8962AF=m +CONFIG_FXLS8962AF_I2C=m +CONFIG_FXLS8962AF_SPI=m +CONFIG_HID_SENSOR_ACCEL_3D=m +CONFIG_IIO_ST_ACCEL_3AXIS=m +CONFIG_IIO_ST_ACCEL_I2C_3AXIS=m +CONFIG_IIO_ST_ACCEL_SPI_3AXIS=m +CONFIG_KXSD9=m +CONFIG_KXSD9_SPI=m +CONFIG_KXSD9_I2C=m +CONFIG_KXCJK1013=m +CONFIG_MC3230=m +CONFIG_MMA7455=m +CONFIG_MMA7455_I2C=m +CONFIG_MMA7455_SPI=m +CONFIG_MMA7660=m +CONFIG_MMA8452=m +CONFIG_MMA9551_CORE=m +CONFIG_MMA9551=m +CONFIG_MMA9553=m +CONFIG_MXC4005=m +CONFIG_MXC6255=m +CONFIG_SCA3000=m +CONFIG_SCA3300=m +CONFIG_STK8312=m +CONFIG_STK8BA50=m +# end of Accelerometers + +# +# Analog to digital converters +# +CONFIG_AD_SIGMA_DELTA=m +CONFIG_AD7091R5=m +CONFIG_AD7124=m +# CONFIG_AD7192 is not set +CONFIG_AD7266=m +CONFIG_AD7291=m +CONFIG_AD7292=m +CONFIG_AD7298=m +CONFIG_AD7476=m +CONFIG_AD7606=m +CONFIG_AD7606_IFACE_PARALLEL=m +CONFIG_AD7606_IFACE_SPI=m +CONFIG_AD7766=m +CONFIG_AD7768_1=m +# CONFIG_AD7780 is not set +CONFIG_AD7791=m +CONFIG_AD7793=m +CONFIG_AD7887=m +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 +# CONFIG_HX711 is not set +# CONFIG_INA2XX_ADC is not set +# CONFIG_LTC2471 is not set +# CONFIG_LTC2485 is not set +CONFIG_LTC2496=m +# CONFIG_LTC2497 is not set +# CONFIG_MAX1027 is not set +# CONFIG_MAX11100 is not set +# CONFIG_MAX1118 is not set +# CONFIG_MAX1241 is not set +# CONFIG_MAX1363 is not set +# CONFIG_MAX9611 is not set +# CONFIG_MCP320X is not set +# CONFIG_MCP3422 is not set +# CONFIG_MCP3911 is not set +CONFIG_MESON_SARADC=y +# CONFIG_NAU7802 is not set +# 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_SD_ADC_MODULATOR is not set +CONFIG_SUN4I_GPADC=m +CONFIG_TI_ADC081C=m +CONFIG_TI_ADC0832=m +CONFIG_TI_ADC084S021=m +CONFIG_TI_ADC12138=m +CONFIG_TI_ADC108S102=m +CONFIG_TI_ADC128S052=m +CONFIG_TI_ADC161S626=m +CONFIG_TI_ADS1015=m +CONFIG_TI_ADS7950=m +CONFIG_TI_ADS8344=m +CONFIG_TI_ADS8688=m +CONFIG_TI_ADS124S08=m +CONFIG_TI_ADS131E08=m +# CONFIG_TI_TLC4541 is not set +CONFIG_TI_TSC2046=m +# CONFIG_VF610_ADC is not set +CONFIG_XILINX_XADC=m +# end of Analog to digital converters + +# +# Analog Front Ends +# +# CONFIG_IIO_RESCALE is not set +# end of Analog Front Ends + +# +# Amplifiers +# +# CONFIG_AD8366 is not set +CONFIG_HMC425=m +# end of Amplifiers + +# +# Capacitance to digital converters +# +# CONFIG_AD7150 is not set +# end of Capacitance to digital converters + +# +# Chemical Sensors +# +# CONFIG_ATLAS_PH_SENSOR is not set +# CONFIG_ATLAS_EZO_SENSOR is not set +CONFIG_BME680=m +CONFIG_BME680_I2C=m +CONFIG_BME680_SPI=m +# CONFIG_CCS811 is not set +# CONFIG_IAQCORE is not set +CONFIG_PMS7003=m +# CONFIG_SCD30_CORE is not set +# CONFIG_SCD4X is not set +CONFIG_SENSIRION_SGP30=m +CONFIG_SENSIRION_SGP40=m +CONFIG_SPS30=m +CONFIG_SPS30_I2C=m +CONFIG_SPS30_SERIAL=m +# CONFIG_SENSEAIR_SUNRISE_CO2 is not set +# CONFIG_VZ89X is not set +# end of Chemical Sensors + +# CONFIG_IIO_CROS_EC_SENSORS_CORE is not set + +# +# Hid Sensor IIO Common +# +CONFIG_HID_SENSOR_IIO_COMMON=m +CONFIG_HID_SENSOR_IIO_TRIGGER=m +# end of Hid Sensor IIO Common + +CONFIG_IIO_MS_SENSORS_I2C=m + +# +# IIO SCMI Sensors +# +# end of IIO SCMI Sensors + +# +# SSP Sensor Common +# +# CONFIG_IIO_SSP_SENSORHUB is not set +# end of SSP Sensor Common + +CONFIG_IIO_ST_SENSORS_I2C=m +CONFIG_IIO_ST_SENSORS_SPI=m +CONFIG_IIO_ST_SENSORS_CORE=m + +# +# Digital to analog converters +# +# CONFIG_AD5064 is not set +# CONFIG_AD5360 is not set +# CONFIG_AD5380 is not set +# CONFIG_AD5421 is not set +# CONFIG_AD5446 is not set +# CONFIG_AD5449 is not set +# CONFIG_AD5592R is not set +# CONFIG_AD5593R is not set +# CONFIG_AD5504 is not set +# CONFIG_AD5624R_SPI is not set +CONFIG_AD5686=m +CONFIG_AD5686_SPI=m +CONFIG_AD5696_I2C=m +# CONFIG_AD5755 is not set +CONFIG_AD5758=m +# CONFIG_AD5761 is not set +# CONFIG_AD5764 is not set +CONFIG_AD5766=m +CONFIG_AD5770R=m +# CONFIG_AD5791 is not set +# CONFIG_AD7303 is not set +# CONFIG_AD8801 is not set +# CONFIG_DPOT_DAC is not set +# CONFIG_DS4424 is not set +CONFIG_LTC1660=m +# CONFIG_LTC2632 is not set +# CONFIG_M62332 is not set +# CONFIG_MAX517 is not set +# CONFIG_MAX5821 is not set +# CONFIG_MCP4725 is not set +# CONFIG_MCP4922 is not set +# CONFIG_TI_DAC082S085 is not set +CONFIG_TI_DAC5571=m +CONFIG_TI_DAC7311=m +CONFIG_TI_DAC7612=m +# CONFIG_VF610_DAC is not set +# end of Digital to analog converters + +# +# IIO dummy driver +# +CONFIG_IIO_SIMPLE_DUMMY=m +# CONFIG_IIO_SIMPLE_DUMMY_EVENTS is not set +# CONFIG_IIO_SIMPLE_DUMMY_BUFFER is not set +# end of IIO dummy driver + +# +# Frequency Synthesizers DDS/PLL +# + +# +# Clock Generator/Distribution +# +# CONFIG_AD9523 is not set +# end of Clock Generator/Distribution + +# +# Phase-Locked Loop (PLL) frequency synthesizers +# +# CONFIG_ADF4350 is not set +CONFIG_ADF4371=m +# CONFIG_ADRF6780 is not set +# end of Phase-Locked Loop (PLL) frequency synthesizers +# end of Frequency Synthesizers DDS/PLL + +# +# Digital gyroscope sensors +# +CONFIG_ADIS16080=m +CONFIG_ADIS16130=m +CONFIG_ADIS16136=m +CONFIG_ADIS16260=m +# CONFIG_ADXRS290 is not set +CONFIG_ADXRS450=m +CONFIG_BMG160=m +CONFIG_BMG160_I2C=m +CONFIG_BMG160_SPI=m +CONFIG_FXAS21002C=m +CONFIG_FXAS21002C_I2C=m +CONFIG_FXAS21002C_SPI=m +CONFIG_HID_SENSOR_GYRO_3D=m +CONFIG_MPU3050=m +CONFIG_MPU3050_I2C=m +CONFIG_IIO_ST_GYRO_3AXIS=m +CONFIG_IIO_ST_GYRO_I2C_3AXIS=m +CONFIG_IIO_ST_GYRO_SPI_3AXIS=m +CONFIG_ITG3200=m +# end of Digital gyroscope sensors + +# +# Health Sensors +# + +# +# Heart Rate Monitors +# +# CONFIG_AFE4403 is not set +# CONFIG_AFE4404 is not set +# CONFIG_MAX30100 is not set +# CONFIG_MAX30102 is not set +# end of Heart Rate Monitors +# end of Health Sensors + +# +# Humidity sensors +# +CONFIG_AM2315=m +CONFIG_DHT11=m +CONFIG_HDC100X=m +# CONFIG_HDC2010 is not set +CONFIG_HID_SENSOR_HUMIDITY=m +CONFIG_HTS221=m +CONFIG_HTS221_I2C=m +CONFIG_HTS221_SPI=m +CONFIG_HTU21=m +CONFIG_SI7005=m +CONFIG_SI7020=m +# end of Humidity sensors + +# +# Inertial measurement units +# +# CONFIG_ADIS16400 is not set +CONFIG_ADIS16460=m +# CONFIG_ADIS16475 is not set +# CONFIG_ADIS16480 is not set +# CONFIG_BMI160_I2C is not set +# CONFIG_BMI160_SPI is not set +CONFIG_FXOS8700=m +CONFIG_FXOS8700_I2C=m +CONFIG_FXOS8700_SPI=m +# CONFIG_KMX61 is not set +# CONFIG_INV_ICM42600_I2C is not set +# CONFIG_INV_ICM42600_SPI is not set +# CONFIG_INV_MPU6050_I2C is not set +# CONFIG_INV_MPU6050_SPI is not set +# CONFIG_IIO_ST_LSM6DSX is not set +CONFIG_IIO_ST_LSM9DS0=m +CONFIG_IIO_ST_LSM9DS0_I2C=m +CONFIG_IIO_ST_LSM9DS0_SPI=m +# end of Inertial measurement units + +CONFIG_IIO_ADIS_LIB=m +CONFIG_IIO_ADIS_LIB_BUFFER=y + +# +# Light sensors +# +CONFIG_ADJD_S311=m +CONFIG_ADUX1020=m +CONFIG_AL3010=m +CONFIG_AL3320A=m +CONFIG_APDS9300=m +CONFIG_APDS9960=m +# CONFIG_AS73211 is not set +CONFIG_BH1750=m +CONFIG_BH1780=m +CONFIG_CM32181=m +CONFIG_CM3232=m +CONFIG_CM3323=m +CONFIG_CM3605=m +CONFIG_CM36651=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_RPR0521=m +CONFIG_SENSORS_LM3533=m +CONFIG_LTR501=m +CONFIG_LV0104CS=m +CONFIG_MAX44000=m +CONFIG_MAX44009=m +CONFIG_NOA1305=m +CONFIG_OPT3001=m +CONFIG_PA12203001=m +CONFIG_SI1133=m +CONFIG_SI1145=m +CONFIG_STK3310=m +CONFIG_ST_UVIS25=m +CONFIG_ST_UVIS25_I2C=m +CONFIG_ST_UVIS25_SPI=m +CONFIG_TCS3414=m +CONFIG_TCS3472=m +CONFIG_SENSORS_TSL2563=m +CONFIG_TSL2583=m +CONFIG_TSL2591=m +CONFIG_TSL2772=m +CONFIG_TSL4531=m +CONFIG_US5182D=m +CONFIG_VCNL4000=m +CONFIG_VCNL4035=m +CONFIG_VEML6030=m +CONFIG_VEML6070=m +CONFIG_VL6180=m +CONFIG_ZOPT2201=m +# end of Light sensors + +# +# Magnetometer sensors +# +CONFIG_AK8974=m +CONFIG_AK8975=m +CONFIG_AK09911=m +CONFIG_BMC150_MAGN=m +CONFIG_BMC150_MAGN_I2C=m +CONFIG_BMC150_MAGN_SPI=m +CONFIG_MAG3110=m +CONFIG_HID_SENSOR_MAGNETOMETER_3D=m +CONFIG_MMC35240=m +CONFIG_IIO_ST_MAGN_3AXIS=m +CONFIG_IIO_ST_MAGN_I2C_3AXIS=m +CONFIG_IIO_ST_MAGN_SPI_3AXIS=m +CONFIG_SENSORS_HMC5843=m +CONFIG_SENSORS_HMC5843_I2C=m +CONFIG_SENSORS_HMC5843_SPI=m +CONFIG_SENSORS_RM3100=m +CONFIG_SENSORS_RM3100_I2C=m +CONFIG_SENSORS_RM3100_SPI=m +CONFIG_YAMAHA_YAS530=m +# end of Magnetometer sensors + +# +# Multiplexers +# +# CONFIG_IIO_MUX is not set +# end of Multiplexers + +# +# Inclinometer sensors +# +CONFIG_HID_SENSOR_INCLINOMETER_3D=m +CONFIG_HID_SENSOR_DEVICE_ROTATION=m +# end of Inclinometer sensors + +# +# Triggers - standalone +# +CONFIG_IIO_HRTIMER_TRIGGER=m +CONFIG_IIO_INTERRUPT_TRIGGER=m +CONFIG_IIO_TIGHTLOOP_TRIGGER=m +CONFIG_IIO_SYSFS_TRIGGER=m +# end of Triggers - standalone + +# +# Linear and angular position sensors +# +CONFIG_IQS624_POS=m +CONFIG_HID_SENSOR_CUSTOM_INTEL_HINGE=m +# end of Linear and angular position sensors + +# +# Digital potentiometers +# +CONFIG_AD5110=m +CONFIG_AD5272=m +# CONFIG_DS1803 is not set +CONFIG_MAX5432=m +# CONFIG_MAX5481 is not set +# CONFIG_MAX5487 is not set +CONFIG_MCP4018=m +# CONFIG_MCP4131 is not set +# CONFIG_MCP4531 is not set +CONFIG_MCP41010=m +# CONFIG_TPL0102 is not set +# end of Digital potentiometers + +# +# Digital potentiostats +# +# CONFIG_LMP91000 is not set +# end of Digital potentiostats + +# +# Pressure sensors +# +# CONFIG_ABP060MG is not set +CONFIG_BMP280=m +CONFIG_BMP280_I2C=m +CONFIG_BMP280_SPI=m +CONFIG_DLHL60D=m +CONFIG_DPS310=m +CONFIG_HID_SENSOR_PRESS=m +# CONFIG_HP03 is not set +CONFIG_ICP10100=m +# CONFIG_MPL115_I2C is not set +# CONFIG_MPL115_SPI is not set +# CONFIG_MPL3115 is not set +# CONFIG_MS5611 is not set +# CONFIG_MS5637 is not set +# CONFIG_IIO_ST_PRESS is not set +# CONFIG_T5403 is not set +# CONFIG_HP206C is not set +# CONFIG_ZPA2326 is not set +# end of Pressure sensors + +# +# Lightning sensors +# +# CONFIG_AS3935 is not set +# end of Lightning sensors + +# +# Proximity and distance sensors +# +CONFIG_CROS_EC_MKBP_PROXIMITY=m +CONFIG_ISL29501=m +# CONFIG_LIDAR_LITE_V2 is not set +CONFIG_MB1232=m +CONFIG_PING=m +# CONFIG_RFD77402 is not set +# CONFIG_SRF04 is not set +# CONFIG_SX9310 is not set +# CONFIG_SX9500 is not set +# CONFIG_SRF08 is not set +# CONFIG_VCNL3020 is not set +CONFIG_VL53L0X_I2C=m +# end of Proximity and distance sensors + +# +# Resolver to digital converters +# +# CONFIG_AD2S90 is not set +# CONFIG_AD2S1200 is not set +# end of Resolver to digital converters + +# +# Temperature sensors +# +CONFIG_IQS620AT_TEMP=m +CONFIG_LTC2983=m +CONFIG_MAXIM_THERMOCOUPLE=m +CONFIG_HID_SENSOR_TEMP=m +CONFIG_MLX90614=m +CONFIG_MLX90632=m +CONFIG_TMP006=m +CONFIG_TMP007=m +CONFIG_TMP117=m +CONFIG_TSYS01=m +CONFIG_TSYS02D=m +CONFIG_MAX31856=m +# CONFIG_MAX31865 is not set +# end of Temperature sensors + +# CONFIG_NTB is not set +# CONFIG_VME_BUS is not set +CONFIG_PWM=y +CONFIG_PWM_SYSFS=y +# CONFIG_PWM_DEBUG is not set +CONFIG_PWM_ATMEL_TCB=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_MESON=m +CONFIG_PWM_NTXEC=m +# CONFIG_PWM_PCA9685 is not set +CONFIG_PWM_ROCKCHIP=y +CONFIG_PWM_SUN4I=m + +# +# IRQ chip support +# +CONFIG_IRQCHIP=y +CONFIG_ARM_GIC=y +CONFIG_ARM_GIC_MAX_NR=1 +CONFIG_ARM_GIC_V2M=y +CONFIG_ARM_GIC_V3=y +CONFIG_ARM_GIC_V3_ITS=y +CONFIG_ARM_GIC_V3_ITS_PCI=y +# CONFIG_AL_FIC is not set +CONFIG_PARTITION_PERCPU=y +CONFIG_MESON_IRQ_GPIO=y +# end of IRQ chip support + +# CONFIG_IPACK_BUS is not set +CONFIG_ARCH_HAS_RESET_CONTROLLER=y +CONFIG_RESET_CONTROLLER=y +CONFIG_RESET_MESON=y +CONFIG_RESET_MESON_AUDIO_ARB=m +CONFIG_RESET_SIMPLE=y +CONFIG_RESET_SUNXI=y +# CONFIG_RESET_TI_SYSCON is not set + +# +# PHY Subsystem +# +CONFIG_GENERIC_PHY=y +CONFIG_GENERIC_PHY_MIPI_DPHY=y +CONFIG_PHY_XGENE=y +CONFIG_PHY_CAN_TRANSCEIVER=m +CONFIG_PHY_SUN4I_USB=m +CONFIG_PHY_SUN6I_MIPI_DPHY=m +CONFIG_PHY_SUN9I_USB=m +CONFIG_PHY_SUN50I_USB3=m +CONFIG_PHY_MESON8B_USB2=m +CONFIG_PHY_MESON_GXL_USB2=m +CONFIG_PHY_MESON_G12A_USB2=m +CONFIG_PHY_MESON_G12A_USB3_PCIE=m +CONFIG_PHY_MESON_AXG_PCIE=y +CONFIG_PHY_MESON_AXG_MIPI_PCIE_ANALOG=y +CONFIG_PHY_MESON_AXG_MIPI_DPHY=m + +# +# PHY drivers for Broadcom platforms +# +# CONFIG_BCM_KONA_USB2_PHY is not set +# end of PHY drivers for Broadcom platforms + +CONFIG_PHY_CADENCE_TORRENT=m +CONFIG_PHY_CADENCE_DPHY=m +CONFIG_PHY_CADENCE_SIERRA=m +# CONFIG_PHY_CADENCE_SALVO is not set +CONFIG_PHY_FSL_IMX8MQ_USB=m +CONFIG_PHY_MIXEL_MIPI_DPHY=m +# CONFIG_PHY_PXA_28NM_HSIC is not set +# CONFIG_PHY_PXA_28NM_USB2 is not set +# CONFIG_PHY_CPCAP_USB is not set +CONFIG_PHY_MAPPHONE_MDM6600=m +# CONFIG_PHY_OCELOT_SERDES is not set +# CONFIG_PHY_QCOM_USB_HS is not set +# CONFIG_PHY_QCOM_USB_HSIC is not set +CONFIG_PHY_ROCKCHIP_DP=y +CONFIG_PHY_ROCKCHIP_DPHY_RX0=m +CONFIG_PHY_ROCKCHIP_EMMC=y +CONFIG_PHY_ROCKCHIP_INNO_HDMI=y +CONFIG_PHY_ROCKCHIP_INNO_USB2=y +CONFIG_PHY_ROCKCHIP_INNO_CSIDPHY=m +CONFIG_PHY_ROCKCHIP_INNO_DSIDPHY=y +CONFIG_PHY_ROCKCHIP_NANENG_COMBO_PHY=y +CONFIG_PHY_ROCKCHIP_PCIE=y +CONFIG_PHY_ROCKCHIP_TYPEC=y +CONFIG_PHY_ROCKCHIP_USB=y +CONFIG_PHY_SAMSUNG_USB2=y +# CONFIG_PHY_TUSB1210 is not set +# end of PHY Subsystem + +# CONFIG_POWERCAP is not set +# CONFIG_MCB is not set + +# +# Performance monitor support +# +CONFIG_ARM_CCI_PMU=m +# CONFIG_ARM_CCI400_PMU is not set +# CONFIG_ARM_CCI5xx_PMU is not set +# CONFIG_ARM_CCN is not set +# CONFIG_ARM_CMN is not set +CONFIG_ARM_PMU=y +# CONFIG_ARM_DSU_PMU is not set +# CONFIG_ARM_SPE_PMU is not set +# end of Performance monitor support + +CONFIG_RAS=y +# CONFIG_USB4 is not set + +# +# Android +# +# CONFIG_ANDROID is not set +# end of Android + +# CONFIG_LIBNVDIMM is not set +CONFIG_DAX=y +CONFIG_DEV_DAX=m +CONFIG_NVMEM=y +CONFIG_NVMEM_SYSFS=y +CONFIG_NVMEM_SPMI_SDAM=m +CONFIG_ROCKCHIP_EFUSE=y +CONFIG_ROCKCHIP_OTP=m +CONFIG_NVMEM_SUNXI_SID=m +CONFIG_MESON_EFUSE=m +CONFIG_MESON_MX_EFUSE=m +CONFIG_RAVE_SP_EEPROM=m +CONFIG_NVMEM_RMEM=m + +# +# HW tracing support +# +# CONFIG_STM is not set +# CONFIG_INTEL_TH is not set +# end of HW tracing support + +# CONFIG_FPGA is not set +# CONFIG_FSI is not set +# CONFIG_TEE is not set +CONFIG_MULTIPLEXER=m + +# +# Multiplexer drivers +# +CONFIG_MUX_ADG792A=m +CONFIG_MUX_ADGS1408=m +CONFIG_MUX_GPIO=m +CONFIG_MUX_MMIO=m +# end of Multiplexer drivers + +CONFIG_PM_OPP=y +# CONFIG_SIOX is not set +# CONFIG_SLIMBUS is not set +# CONFIG_INTERCONNECT is not set +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 +# end of Device Drivers + +# +# File systems +# +CONFIG_DCACHE_WORD_ACCESS=y +CONFIG_VALIDATE_FS_PARSER=y +CONFIG_FS_IOMAP=y +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT2_FS_POSIX_ACL=y +CONFIG_EXT2_FS_SECURITY=y +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_POSIX_ACL=y +CONFIG_EXT3_FS_SECURITY=y +CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y +# CONFIG_EXT4_DEBUG is not set +CONFIG_EXT4_KUNIT_TESTS=m +CONFIG_JBD2=y +# CONFIG_JBD2_DEBUG is not set +CONFIG_FS_MBCACHE=y +CONFIG_REISERFS_FS=m +# CONFIG_REISERFS_CHECK is not set +CONFIG_REISERFS_PROC_INFO=y +CONFIG_REISERFS_FS_XATTR=y +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y +CONFIG_JFS_FS=m +CONFIG_JFS_POSIX_ACL=y +CONFIG_JFS_SECURITY=y +# CONFIG_JFS_DEBUG is not set +CONFIG_JFS_STATISTICS=y +CONFIG_XFS_FS=m +CONFIG_XFS_SUPPORT_V4=y +CONFIG_XFS_QUOTA=y +CONFIG_XFS_POSIX_ACL=y +CONFIG_XFS_RT=y +# CONFIG_XFS_ONLINE_SCRUB is not set +# CONFIG_XFS_WARN is not set +# CONFIG_XFS_DEBUG is not set +CONFIG_GFS2_FS=m +CONFIG_GFS2_FS_LOCKING_DLM=y +CONFIG_OCFS2_FS=m +CONFIG_OCFS2_FS_O2CB=m +CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m +CONFIG_OCFS2_FS_STATS=y +CONFIG_OCFS2_DEBUG_MASKLOG=y +# CONFIG_OCFS2_DEBUG_FS is not set +CONFIG_BTRFS_FS=y +CONFIG_BTRFS_FS_POSIX_ACL=y +# CONFIG_BTRFS_FS_CHECK_INTEGRITY is not set +# CONFIG_BTRFS_FS_RUN_SANITY_TESTS is not set +# CONFIG_BTRFS_DEBUG is not set +# CONFIG_BTRFS_ASSERT is not set +# CONFIG_BTRFS_FS_REF_VERIFY is not set +CONFIG_NILFS2_FS=m +CONFIG_F2FS_FS=y +CONFIG_F2FS_STAT_FS=y +CONFIG_F2FS_FS_XATTR=y +CONFIG_F2FS_FS_POSIX_ACL=y +CONFIG_F2FS_FS_SECURITY=y +CONFIG_F2FS_CHECK_FS=y +# CONFIG_F2FS_FAULT_INJECTION is not set +# CONFIG_F2FS_FS_COMPRESSION is not set +CONFIG_F2FS_IOSTAT=y +CONFIG_ZONEFS_FS=m +CONFIG_FS_DAX=y +CONFIG_FS_POSIX_ACL=y +CONFIG_EXPORTFS=y +CONFIG_EXPORTFS_BLOCK_OPS=y +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 +CONFIG_INOTIFY_USER=y +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 +CONFIG_QFMT_V2=m +CONFIG_QUOTACTL=y +CONFIG_AUTOFS4_FS=m +CONFIG_AUTOFS_FS=m +CONFIG_FUSE_FS=y +CONFIG_CUSE=m +CONFIG_VIRTIO_FS=m +CONFIG_OVERLAY_FS=y +# CONFIG_OVERLAY_FS_REDIRECT_DIR is not set +CONFIG_OVERLAY_FS_REDIRECT_ALWAYS_FOLLOW=y +# CONFIG_OVERLAY_FS_INDEX is not set +CONFIG_OVERLAY_FS_XINO_AUTO=y +# CONFIG_OVERLAY_FS_METACOPY is not set + +# +# Caches +# +CONFIG_NETFS_SUPPORT=m +CONFIG_NETFS_STATS=y +CONFIG_FSCACHE=m +CONFIG_FSCACHE_STATS=y +# CONFIG_FSCACHE_DEBUG is not set +CONFIG_CACHEFILES=m +# CONFIG_CACHEFILES_DEBUG is not set +# end of Caches + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=m +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +CONFIG_UDF_FS=m +# end of CD-ROM/DVD Filesystems + +# +# DOS/FAT/EXFAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=m +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 is not set +CONFIG_NTFS3_FS=m +# 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 + +# +# Pseudo filesystems +# +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 +CONFIG_KERNFS=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_TMPFS_XATTR=y +# CONFIG_TMPFS_INODE64 is not set +CONFIG_ARCH_SUPPORTS_HUGETLBFS=y +CONFIG_HUGETLBFS=y +CONFIG_HUGETLB_PAGE=y +CONFIG_MEMFD_CREATE=y +CONFIG_ARCH_HAS_GIGANTIC_PAGE=y +CONFIG_CONFIGFS_FS=y +CONFIG_EFIVAR_FS=m +# end of Pseudo filesystems + +CONFIG_MISC_FILESYSTEMS=y +CONFIG_ORANGEFS_FS=m +CONFIG_ADFS_FS=m +# CONFIG_ADFS_FS_RW is not set +CONFIG_AFFS_FS=m +CONFIG_ECRYPT_FS=y +CONFIG_ECRYPT_FS_MESSAGING=y +CONFIG_HFS_FS=m +CONFIG_HFSPLUS_FS=m +CONFIG_BEFS_FS=m +# CONFIG_BEFS_DEBUG is not set +CONFIG_BFS_FS=m +CONFIG_EFS_FS=m +CONFIG_JFFS2_FS=m +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_FS_WBUF_VERIFY is not set +# CONFIG_JFFS2_SUMMARY is not set +CONFIG_JFFS2_FS_XATTR=y +CONFIG_JFFS2_FS_POSIX_ACL=y +CONFIG_JFFS2_FS_SECURITY=y +CONFIG_JFFS2_COMPRESSION_OPTIONS=y +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_LZO=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_JFFS2_CMODE_NONE is not set +# CONFIG_JFFS2_CMODE_PRIORITY is not set +# CONFIG_JFFS2_CMODE_SIZE is not set +CONFIG_JFFS2_CMODE_FAVOURLZO=y +CONFIG_CRAMFS=m +CONFIG_CRAMFS_BLOCKDEV=y +CONFIG_CRAMFS_MTD=y +CONFIG_SQUASHFS=y +# CONFIG_SQUASHFS_FILE_CACHE is not set +CONFIG_SQUASHFS_FILE_DIRECT=y +# CONFIG_SQUASHFS_DECOMP_SINGLE is not set +# CONFIG_SQUASHFS_DECOMP_MULTI is not set +CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y +CONFIG_SQUASHFS_XATTR=y +CONFIG_SQUASHFS_ZLIB=y +CONFIG_SQUASHFS_LZ4=y +CONFIG_SQUASHFS_LZO=y +CONFIG_SQUASHFS_XZ=y +CONFIG_SQUASHFS_ZSTD=y +CONFIG_SQUASHFS_4K_DEVBLK_SIZE=y +CONFIG_SQUASHFS_EMBEDDED=y +CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 +CONFIG_VXFS_FS=m +CONFIG_MINIX_FS=m +CONFIG_OMFS_FS=m +CONFIG_HPFS_FS=m +CONFIG_QNX4FS_FS=m +CONFIG_QNX6FS_FS=m +# CONFIG_QNX6FS_DEBUG is not set +CONFIG_ROMFS_FS=m +CONFIG_ROMFS_BACKED_BY_BLOCK=y +# CONFIG_ROMFS_BACKED_BY_MTD is not set +# CONFIG_ROMFS_BACKED_BY_BOTH is not set +CONFIG_ROMFS_ON_BLOCK=y +CONFIG_PSTORE=y +CONFIG_PSTORE_DEFAULT_KMSG_BYTES=10240 +CONFIG_PSTORE_DEFLATE_COMPRESS=y +# CONFIG_PSTORE_LZO_COMPRESS is not set +# CONFIG_PSTORE_LZ4_COMPRESS is not set +CONFIG_PSTORE_LZ4HC_COMPRESS=m +# CONFIG_PSTORE_842_COMPRESS is not set +# CONFIG_PSTORE_ZSTD_COMPRESS is not set +CONFIG_PSTORE_COMPRESS=y +CONFIG_PSTORE_DEFLATE_COMPRESS_DEFAULT=y +# CONFIG_PSTORE_LZ4HC_COMPRESS_DEFAULT is not set +CONFIG_PSTORE_COMPRESS_DEFAULT="deflate" +# CONFIG_PSTORE_CONSOLE is not set +# CONFIG_PSTORE_PMSG is not set +CONFIG_PSTORE_RAM=m +CONFIG_PSTORE_ZONE=m +CONFIG_PSTORE_BLK=m +CONFIG_PSTORE_BLK_BLKDEV="" +CONFIG_PSTORE_BLK_KMSG_SIZE=64 +CONFIG_PSTORE_BLK_MAX_REASON=2 +CONFIG_SYSV_FS=m +CONFIG_UFS_FS=m +CONFIG_UFS_FS_WRITE=y +# CONFIG_UFS_DEBUG is not set +CONFIG_EROFS_FS=m +# CONFIG_EROFS_FS_DEBUG is not set +CONFIG_EROFS_FS_XATTR=y +CONFIG_EROFS_FS_POSIX_ACL=y +CONFIG_EROFS_FS_SECURITY=y +# CONFIG_EROFS_FS_ZIP is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=m +CONFIG_NFS_V2=m +CONFIG_NFS_V3=m +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=m +CONFIG_NFS_SWAP=y +CONFIG_NFS_V4_1=y +CONFIG_NFS_V4_2=y +CONFIG_PNFS_FILE_LAYOUT=m +CONFIG_PNFS_BLOCK=m +CONFIG_PNFS_FLEXFILE_LAYOUT=m +CONFIG_NFS_V4_1_IMPLEMENTATION_ID_DOMAIN="kernel.org" +CONFIG_NFS_V4_1_MIGRATION=y +CONFIG_NFS_V4_SECURITY_LABEL=y +CONFIG_NFS_FSCACHE=y +# CONFIG_NFS_USE_LEGACY_DNS is not set +CONFIG_NFS_USE_KERNEL_DNS=y +CONFIG_NFS_DEBUG=y +CONFIG_NFS_DISABLE_UDP_SUPPORT=y +# CONFIG_NFS_V4_2_READ_PLUS is not set +CONFIG_NFSD=m +CONFIG_NFSD_V2_ACL=y +CONFIG_NFSD_V3=y +CONFIG_NFSD_V3_ACL=y +CONFIG_NFSD_V4=y +CONFIG_NFSD_PNFS=y +CONFIG_NFSD_BLOCKLAYOUT=y +CONFIG_NFSD_SCSILAYOUT=y +CONFIG_NFSD_FLEXFILELAYOUT=y +# CONFIG_NFSD_V4_2_INTER_SSC is not set +CONFIG_NFSD_V4_SECURITY_LABEL=y +CONFIG_GRACE_PERIOD=m +CONFIG_LOCKD=m +CONFIG_LOCKD_V4=y +CONFIG_NFS_ACL_SUPPORT=m +CONFIG_NFS_COMMON=y +CONFIG_NFS_V4_2_SSC_HELPER=y +CONFIG_SUNRPC=m +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_SUNRPC_DEBUG=y +CONFIG_CEPH_FS=m +CONFIG_CEPH_FSCACHE=y +CONFIG_CEPH_FS_POSIX_ACL=y +CONFIG_CEPH_FS_SECURITY_LABEL=y +CONFIG_CIFS=m +CONFIG_CIFS_STATS2=y +CONFIG_CIFS_ALLOW_INSECURE_LEGACY=y +CONFIG_CIFS_UPCALL=y +CONFIG_CIFS_XATTR=y +CONFIG_CIFS_POSIX=y +CONFIG_CIFS_DEBUG=y +# CONFIG_CIFS_DEBUG2 is not set +# CONFIG_CIFS_DEBUG_DUMP_KEYS is not set +CONFIG_CIFS_DFS_UPCALL=y +# CONFIG_CIFS_SWN_UPCALL is not set +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_CODA_FS=m +CONFIG_AFS_FS=m +# CONFIG_AFS_DEBUG is not set +CONFIG_AFS_FSCACHE=y +# CONFIG_AFS_DEBUG_CURSOR is not set +CONFIG_9P_FS=m +CONFIG_9P_FSCACHE=y +CONFIG_9P_FS_POSIX_ACL=y +CONFIG_9P_FS_SECURITY=y +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="utf8" +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_CODEPAGE_737=m +CONFIG_NLS_CODEPAGE_775=m +CONFIG_NLS_CODEPAGE_850=m +CONFIG_NLS_CODEPAGE_852=m +CONFIG_NLS_CODEPAGE_855=m +CONFIG_NLS_CODEPAGE_857=m +CONFIG_NLS_CODEPAGE_860=m +CONFIG_NLS_CODEPAGE_861=m +CONFIG_NLS_CODEPAGE_862=m +CONFIG_NLS_CODEPAGE_863=m +CONFIG_NLS_CODEPAGE_864=m +CONFIG_NLS_CODEPAGE_865=m +CONFIG_NLS_CODEPAGE_866=m +CONFIG_NLS_CODEPAGE_869=m +CONFIG_NLS_CODEPAGE_936=m +CONFIG_NLS_CODEPAGE_950=m +CONFIG_NLS_CODEPAGE_932=m +CONFIG_NLS_CODEPAGE_949=m +CONFIG_NLS_CODEPAGE_874=m +CONFIG_NLS_ISO8859_8=m +CONFIG_NLS_CODEPAGE_1250=m +CONFIG_NLS_CODEPAGE_1251=m +CONFIG_NLS_ASCII=y +CONFIG_NLS_ISO8859_1=m +CONFIG_NLS_ISO8859_2=m +CONFIG_NLS_ISO8859_3=m +CONFIG_NLS_ISO8859_4=m +CONFIG_NLS_ISO8859_5=m +CONFIG_NLS_ISO8859_6=m +CONFIG_NLS_ISO8859_7=m +CONFIG_NLS_ISO8859_9=m +CONFIG_NLS_ISO8859_13=m +CONFIG_NLS_ISO8859_14=m +CONFIG_NLS_ISO8859_15=m +CONFIG_NLS_KOI8_R=m +CONFIG_NLS_KOI8_U=m +CONFIG_NLS_MAC_ROMAN=m +CONFIG_NLS_MAC_CELTIC=m +CONFIG_NLS_MAC_CENTEURO=m +CONFIG_NLS_MAC_CROATIAN=m +CONFIG_NLS_MAC_CYRILLIC=m +CONFIG_NLS_MAC_GAELIC=m +CONFIG_NLS_MAC_GREEK=m +CONFIG_NLS_MAC_ICELAND=m +CONFIG_NLS_MAC_INUIT=m +CONFIG_NLS_MAC_ROMANIAN=m +CONFIG_NLS_MAC_TURKISH=m +CONFIG_NLS_UTF8=m +CONFIG_DLM=m +# CONFIG_DLM_DEBUG is not set +CONFIG_UNICODE=y +# CONFIG_UNICODE_NORMALIZATION_SELFTEST is not set +CONFIG_IO_WQ=y +# end of File systems + +# +# Security options +# +CONFIG_KEYS=y +CONFIG_KEYS_REQUEST_CACHE=y +CONFIG_PERSISTENT_KEYRINGS=y +CONFIG_ENCRYPTED_KEYS=y +CONFIG_KEY_DH_OPERATIONS=y +# CONFIG_SECURITY_DMESG_RESTRICT is not set +CONFIG_SECURITY=y +CONFIG_SECURITYFS=y +CONFIG_SECURITY_NETWORK=y +CONFIG_SECURITY_NETWORK_XFRM=y +CONFIG_SECURITY_PATH=y +CONFIG_LSM_MMAP_MIN_ADDR=0 +CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR=y +CONFIG_HARDENED_USERCOPY=y +# CONFIG_HARDENED_USERCOPY_PAGESPAN is not set +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 +# CONFIG_SECURITY_SMACK_BRINGUP is not set +CONFIG_SECURITY_SMACK_NETFILTER=y +CONFIG_SECURITY_SMACK_APPEND_SIGNALS=y +CONFIG_SECURITY_TOMOYO=y +CONFIG_SECURITY_TOMOYO_MAX_ACCEPT_ENTRY=2048 +CONFIG_SECURITY_TOMOYO_MAX_AUDIT_LOG=1024 +# CONFIG_SECURITY_TOMOYO_OMIT_USERSPACE_LOADER is not set +CONFIG_SECURITY_TOMOYO_POLICY_LOADER="/sbin/tomoyo-init" +CONFIG_SECURITY_TOMOYO_ACTIVATION_TRIGGER="/sbin/init" +# CONFIG_SECURITY_TOMOYO_INSECURE_BUILTIN_SETTING is not set +CONFIG_SECURITY_APPARMOR=y +CONFIG_SECURITY_APPARMOR_HASH=y +CONFIG_SECURITY_APPARMOR_HASH_DEFAULT=y +# CONFIG_SECURITY_APPARMOR_DEBUG is not set +# CONFIG_SECURITY_LOADPIN is not set +CONFIG_SECURITY_YAMA=y +CONFIG_SECURITY_SAFESETID=y +CONFIG_SECURITY_LOCKDOWN_LSM=y +CONFIG_SECURITY_LOCKDOWN_LSM_EARLY=y +CONFIG_LOCK_DOWN_KERNEL_FORCE_NONE=y +# CONFIG_LOCK_DOWN_KERNEL_FORCE_INTEGRITY is not set +# CONFIG_LOCK_DOWN_KERNEL_FORCE_CONFIDENTIALITY is not set +# CONFIG_SECURITY_LANDLOCK is not set +CONFIG_INTEGRITY=y +CONFIG_INTEGRITY_SIGNATURE=y +CONFIG_INTEGRITY_ASYMMETRIC_KEYS=y +CONFIG_INTEGRITY_TRUSTED_KEYRING=y +CONFIG_INTEGRITY_PLATFORM_KEYRING=y +CONFIG_LOAD_UEFI_KEYS=y +CONFIG_INTEGRITY_AUDIT=y +# CONFIG_IMA is not set +# CONFIG_IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY is not set +# CONFIG_IMA_SECURE_AND_OR_TRUSTED_BOOT is not set +# CONFIG_EVM is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_APPARMOR=y +# CONFIG_DEFAULT_SECURITY_DAC is not set +CONFIG_LSM="lockdown,yama,integrity,apparmor" + +# +# Kernel hardening options +# + +# +# Memory initialization +# +CONFIG_INIT_STACK_NONE=y +CONFIG_INIT_ON_ALLOC_DEFAULT_ON=y +# CONFIG_INIT_ON_FREE_DEFAULT_ON is not set +# end of Memory initialization +# end of Kernel hardening options +# end of Security options + +CONFIG_XOR_BLOCKS=y +CONFIG_ASYNC_CORE=m +CONFIG_ASYNC_MEMCPY=m +CONFIG_ASYNC_XOR=m +CONFIG_ASYNC_PQ=m +CONFIG_ASYNC_RAID6_RECOV=m +CONFIG_ASYNC_TX_DISABLE_PQ_VAL_DMA=y +CONFIG_ASYNC_TX_DISABLE_XOR_VAL_DMA=y +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_AEAD=y +CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_SKCIPHER=y +CONFIG_CRYPTO_SKCIPHER2=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG=y +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_RNG_DEFAULT=y +CONFIG_CRYPTO_AKCIPHER2=y +CONFIG_CRYPTO_AKCIPHER=y +CONFIG_CRYPTO_KPP2=y +CONFIG_CRYPTO_KPP=y +CONFIG_CRYPTO_ACOMP2=y +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y +CONFIG_CRYPTO_USER=m +CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y +CONFIG_CRYPTO_GF128MUL=y +CONFIG_CRYPTO_NULL=y +CONFIG_CRYPTO_NULL2=y +CONFIG_CRYPTO_PCRYPT=m +CONFIG_CRYPTO_CRYPTD=y +CONFIG_CRYPTO_AUTHENC=y +CONFIG_CRYPTO_TEST=m +CONFIG_CRYPTO_ENGINE=y + +# +# Public-key cryptography +# +CONFIG_CRYPTO_RSA=y +CONFIG_CRYPTO_DH=y +CONFIG_CRYPTO_ECC=y +CONFIG_CRYPTO_ECDH=y +CONFIG_CRYPTO_ECDSA=m +CONFIG_CRYPTO_ECRDSA=m +# CONFIG_CRYPTO_SM2 is not set +CONFIG_CRYPTO_CURVE25519=m + +# +# Authenticated Encryption with Associated Data +# +CONFIG_CRYPTO_CCM=y +CONFIG_CRYPTO_GCM=y +CONFIG_CRYPTO_CHACHA20POLY1305=y +CONFIG_CRYPTO_AEGIS128=m +CONFIG_CRYPTO_AEGIS128_SIMD=y +CONFIG_CRYPTO_SEQIV=y +CONFIG_CRYPTO_ECHAINIV=y + +# +# Block modes +# +CONFIG_CRYPTO_CBC=y +CONFIG_CRYPTO_CFB=m +CONFIG_CRYPTO_CTR=y +CONFIG_CRYPTO_CTS=y +CONFIG_CRYPTO_ECB=y +CONFIG_CRYPTO_LRW=m +CONFIG_CRYPTO_OFB=m +CONFIG_CRYPTO_PCBC=m +CONFIG_CRYPTO_XTS=y +CONFIG_CRYPTO_KEYWRAP=m +CONFIG_CRYPTO_NHPOLY1305=m +CONFIG_CRYPTO_ADIANTUM=m +CONFIG_CRYPTO_ESSIV=m + +# +# Hash modes +# +CONFIG_CRYPTO_CMAC=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_XCBC=y +CONFIG_CRYPTO_VMAC=y + +# +# Digest +# +CONFIG_CRYPTO_CRC32C=y +CONFIG_CRYPTO_CRC32=y +CONFIG_CRYPTO_XXHASH=y +CONFIG_CRYPTO_BLAKE2B=y +CONFIG_CRYPTO_BLAKE2S=m +CONFIG_CRYPTO_CRCT10DIF=y +CONFIG_CRYPTO_GHASH=y +CONFIG_CRYPTO_POLY1305=y +CONFIG_CRYPTO_MD4=y +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_MICHAEL_MIC=y +CONFIG_CRYPTO_RMD160=y +CONFIG_CRYPTO_SHA1=y +CONFIG_CRYPTO_SHA256=y +CONFIG_CRYPTO_SHA512=y +CONFIG_CRYPTO_SHA3=y +CONFIG_CRYPTO_SM3=m +CONFIG_CRYPTO_STREEBOG=m +CONFIG_CRYPTO_WP512=y + +# +# Ciphers +# +CONFIG_CRYPTO_AES=y +CONFIG_CRYPTO_AES_TI=y +CONFIG_CRYPTO_ANUBIS=y +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_BLOWFISH=y +CONFIG_CRYPTO_BLOWFISH_COMMON=y +CONFIG_CRYPTO_CAMELLIA=y +CONFIG_CRYPTO_CAST_COMMON=y +CONFIG_CRYPTO_CAST5=y +CONFIG_CRYPTO_CAST6=y +CONFIG_CRYPTO_DES=y +CONFIG_CRYPTO_FCRYPT=y +CONFIG_CRYPTO_KHAZAD=y +CONFIG_CRYPTO_CHACHA20=y +CONFIG_CRYPTO_SEED=y +CONFIG_CRYPTO_SERPENT=y +CONFIG_CRYPTO_SM4=m +CONFIG_CRYPTO_TEA=y +CONFIG_CRYPTO_TWOFISH=y +CONFIG_CRYPTO_TWOFISH_COMMON=y + +# +# Compression +# +CONFIG_CRYPTO_DEFLATE=y +CONFIG_CRYPTO_LZO=y +CONFIG_CRYPTO_842=m +CONFIG_CRYPTO_LZ4=m +CONFIG_CRYPTO_LZ4HC=m +CONFIG_CRYPTO_ZSTD=y + +# +# Random Number Generation +# +CONFIG_CRYPTO_ANSI_CPRNG=m +CONFIG_CRYPTO_DRBG_MENU=y +CONFIG_CRYPTO_DRBG_HMAC=y +CONFIG_CRYPTO_DRBG_HASH=y +CONFIG_CRYPTO_DRBG_CTR=y +CONFIG_CRYPTO_DRBG=y +CONFIG_CRYPTO_JITTERENTROPY=y +CONFIG_CRYPTO_USER_API=m +CONFIG_CRYPTO_USER_API_HASH=m +CONFIG_CRYPTO_USER_API_SKCIPHER=m +CONFIG_CRYPTO_USER_API_RNG=m +# CONFIG_CRYPTO_USER_API_RNG_CAVP is not set +CONFIG_CRYPTO_USER_API_AEAD=m +CONFIG_CRYPTO_USER_API_ENABLE_OBSOLETE=y +CONFIG_CRYPTO_STATS=y +CONFIG_CRYPTO_HASH_INFO=y + +# +# Crypto library routines +# +CONFIG_CRYPTO_LIB_AES=y +CONFIG_CRYPTO_LIB_ARC4=m +CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=m +CONFIG_CRYPTO_LIB_BLAKE2S=m +CONFIG_CRYPTO_ARCH_HAVE_LIB_CHACHA=y +CONFIG_CRYPTO_LIB_CHACHA_GENERIC=y +CONFIG_CRYPTO_LIB_CHACHA=m +CONFIG_CRYPTO_LIB_CURVE25519_GENERIC=m +CONFIG_CRYPTO_LIB_CURVE25519=m +CONFIG_CRYPTO_LIB_DES=y +CONFIG_CRYPTO_LIB_POLY1305_RSIZE=9 +CONFIG_CRYPTO_ARCH_HAVE_LIB_POLY1305=m +CONFIG_CRYPTO_LIB_POLY1305_GENERIC=y +CONFIG_CRYPTO_LIB_POLY1305=m +CONFIG_CRYPTO_LIB_CHACHA20POLY1305=m +CONFIG_CRYPTO_LIB_SHA256=y +CONFIG_CRYPTO_LIB_SM4=m +CONFIG_CRYPTO_HW=y +CONFIG_CRYPTO_DEV_ALLWINNER=y +CONFIG_CRYPTO_DEV_SUN4I_SS=m +# CONFIG_CRYPTO_DEV_SUN4I_SS_PRNG is not set +# CONFIG_CRYPTO_DEV_SUN4I_SS_DEBUG is not set +CONFIG_CRYPTO_DEV_SUN8I_CE=m +# CONFIG_CRYPTO_DEV_SUN8I_CE_DEBUG is not set +# CONFIG_CRYPTO_DEV_SUN8I_CE_HASH is not set +# CONFIG_CRYPTO_DEV_SUN8I_CE_PRNG is not set +# CONFIG_CRYPTO_DEV_SUN8I_CE_TRNG is not set +CONFIG_CRYPTO_DEV_SUN8I_SS=m +# CONFIG_CRYPTO_DEV_SUN8I_SS_DEBUG is not set +# CONFIG_CRYPTO_DEV_SUN8I_SS_PRNG is not set +# CONFIG_CRYPTO_DEV_SUN8I_SS_HASH is not set +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_CAVIUM_ZIP=m +CONFIG_CRYPTO_DEV_ROCKCHIP=m +CONFIG_CRYPTO_DEV_VIRTIO=m +CONFIG_CRYPTO_DEV_SAFEXCEL=m +CONFIG_CRYPTO_DEV_CCREE=m +CONFIG_CRYPTO_DEV_HISI_SEC=m +CONFIG_CRYPTO_DEV_AMLOGIC_GXL=y +CONFIG_CRYPTO_DEV_AMLOGIC_GXL_DEBUG=y +CONFIG_ASYMMETRIC_KEY_TYPE=y +CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=y +CONFIG_X509_CERTIFICATE_PARSER=y +CONFIG_PKCS8_PRIVATE_KEY_PARSER=m +CONFIG_PKCS7_MESSAGE_PARSER=y +CONFIG_PKCS7_TEST_KEY=m +CONFIG_SIGNED_PE_FILE_VERIFICATION=y + +# +# Certificates for signature checking +# +CONFIG_MODULE_SIG_KEY="certs/signing_key.pem" +CONFIG_MODULE_SIG_KEY_TYPE_RSA=y +# CONFIG_MODULE_SIG_KEY_TYPE_ECDSA is not set +CONFIG_SYSTEM_TRUSTED_KEYRING=y +CONFIG_SYSTEM_TRUSTED_KEYS="" +CONFIG_SYSTEM_EXTRA_CERTIFICATE=y +CONFIG_SYSTEM_EXTRA_CERTIFICATE_SIZE=4096 +CONFIG_SECONDARY_TRUSTED_KEYRING=y +CONFIG_SYSTEM_BLACKLIST_KEYRING=y +CONFIG_SYSTEM_BLACKLIST_HASH_LIST="" +# CONFIG_SYSTEM_REVOCATION_LIST is not set +# end of Certificates for signature checking + +CONFIG_BINARY_PRINTF=y + +# +# Library routines +# +CONFIG_RAID6_PQ=y +CONFIG_RAID6_PQ_BENCHMARK=y +CONFIG_LINEAR_RANGES=y +CONFIG_PACKING=y +CONFIG_BITREVERSE=y +CONFIG_HAVE_ARCH_BITREVERSE=y +CONFIG_GENERIC_STRNCPY_FROM_USER=y +CONFIG_GENERIC_STRNLEN_USER=y +CONFIG_GENERIC_NET_UTILS=y +CONFIG_GENERIC_FIND_FIRST_BIT=y +CONFIG_CORDIC=m +# CONFIG_PRIME_NUMBERS is not set +CONFIG_RATIONAL=y +CONFIG_GENERIC_PCI_IOMAP=y +CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y +CONFIG_ARCH_HAS_FAST_MULTIPLIER=y +CONFIG_ARCH_USE_SYM_ANNOTATIONS=y +# CONFIG_INDIRECT_PIO is not set +CONFIG_CRC_CCITT=y +CONFIG_CRC16=y +CONFIG_CRC_T10DIF=y +CONFIG_CRC_ITU_T=y +CONFIG_CRC32=y +# CONFIG_CRC32_SELFTEST is not set +CONFIG_CRC32_SLICEBY8=y +# CONFIG_CRC32_SLICEBY4 is not set +# CONFIG_CRC32_SARWATE is not set +# CONFIG_CRC32_BIT is not set +CONFIG_CRC64=y +CONFIG_CRC4=m +CONFIG_CRC7=y +CONFIG_LIBCRC32C=y +CONFIG_CRC8=m +CONFIG_XXHASH=y +CONFIG_AUDIT_GENERIC=y +CONFIG_AUDIT_ARCH_COMPAT_GENERIC=y +CONFIG_AUDIT_COMPAT_GENERIC=y +# CONFIG_RANDOM32_SELFTEST is not set +CONFIG_842_COMPRESS=m +CONFIG_842_DECOMPRESS=m +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_LZO_COMPRESS=y +CONFIG_LZO_DECOMPRESS=y +CONFIG_LZ4_COMPRESS=m +CONFIG_LZ4HC_COMPRESS=m +CONFIG_LZ4_DECOMPRESS=y +CONFIG_ZSTD_COMPRESS=y +CONFIG_ZSTD_DECOMPRESS=y +CONFIG_XZ_DEC=y +CONFIG_XZ_DEC_X86=y +CONFIG_XZ_DEC_POWERPC=y +CONFIG_XZ_DEC_IA64=y +CONFIG_XZ_DEC_ARM=y +CONFIG_XZ_DEC_ARMTHUMB=y +CONFIG_XZ_DEC_SPARC=y +# CONFIG_XZ_DEC_MICROLZMA is not set +CONFIG_XZ_DEC_BCJ=y +CONFIG_XZ_DEC_TEST=m +CONFIG_DECOMPRESS_GZIP=y +CONFIG_DECOMPRESS_BZIP2=y +CONFIG_DECOMPRESS_LZMA=y +CONFIG_DECOMPRESS_XZ=y +CONFIG_DECOMPRESS_LZO=y +CONFIG_DECOMPRESS_LZ4=y +CONFIG_DECOMPRESS_ZSTD=y +CONFIG_GENERIC_ALLOCATOR=y +CONFIG_REED_SOLOMON=m +CONFIG_REED_SOLOMON_ENC8=y +CONFIG_REED_SOLOMON_DEC8=y +CONFIG_REED_SOLOMON_ENC16=y +CONFIG_REED_SOLOMON_DEC16=y +CONFIG_TEXTSEARCH=y +CONFIG_TEXTSEARCH_KMP=m +CONFIG_TEXTSEARCH_BM=m +CONFIG_TEXTSEARCH_FSM=m +CONFIG_INTERVAL_TREE=y +CONFIG_XARRAY_MULTI=y +CONFIG_ASSOCIATIVE_ARRAY=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT_MAP=y +CONFIG_HAS_DMA=y +CONFIG_DMA_OPS=y +CONFIG_NEED_SG_DMA_LENGTH=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_ARCH_DMA_ADDR_T_64BIT=y +CONFIG_DMA_DECLARE_COHERENT=y +CONFIG_ARCH_HAS_SETUP_DMA_OPS=y +CONFIG_ARCH_HAS_TEARDOWN_DMA_OPS=y +CONFIG_ARCH_HAS_SYNC_DMA_FOR_DEVICE=y +CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU=y +CONFIG_ARCH_HAS_DMA_PREP_COHERENT=y +CONFIG_SWIOTLB=y +# CONFIG_DMA_RESTRICTED_POOL is not set +CONFIG_DMA_NONCOHERENT_MMAP=y +CONFIG_DMA_COHERENT_POOL=y +CONFIG_DMA_REMAP=y +CONFIG_DMA_DIRECT_REMAP=y +CONFIG_DMA_CMA=y +CONFIG_DMA_PERNUMA_CMA=y + +# +# Default contiguous memory area size: +# +CONFIG_CMA_SIZE_MBYTES=128 +CONFIG_CMA_SIZE_SEL_MBYTES=y +# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set +# CONFIG_CMA_SIZE_SEL_MIN is not set +# CONFIG_CMA_SIZE_SEL_MAX is not set +CONFIG_CMA_ALIGNMENT=8 +# CONFIG_DMA_API_DEBUG is not set +# CONFIG_DMA_MAP_BENCHMARK is not set +CONFIG_SGL_ALLOC=y +CONFIG_CPU_RMAP=y +CONFIG_DQL=y +CONFIG_GLOB=y +CONFIG_GLOB_SELFTEST=m +CONFIG_NLATTR=y +CONFIG_LRU_CACHE=m +CONFIG_CLZ_TAB=y +CONFIG_IRQ_POLL=y +CONFIG_MPILIB=y +CONFIG_SIGNATURE=y +CONFIG_DIMLIB=y +CONFIG_LIBFDT=y +CONFIG_OID_REGISTRY=y +CONFIG_UCS2_STRING=y +CONFIG_HAVE_GENERIC_VDSO=y +CONFIG_GENERIC_GETTIMEOFDAY=y +CONFIG_GENERIC_VDSO_TIME_NS=y +CONFIG_FONT_SUPPORT=y +CONFIG_FONTS=y +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +# CONFIG_FONT_6x11 is not set +# CONFIG_FONT_7x14 is not set +# CONFIG_FONT_PEARL_8x8 is not set +CONFIG_FONT_ACORN_8x8=y +# CONFIG_FONT_MINI_4x6 is not set +CONFIG_FONT_6x10=y +# CONFIG_FONT_10x18 is not set +# CONFIG_FONT_SUN8x16 is not set +# CONFIG_FONT_SUN12x22 is not set +CONFIG_FONT_TER16x32=y +# CONFIG_FONT_6x8 is not set +CONFIG_SG_SPLIT=y +CONFIG_SG_POOL=y +CONFIG_ARCH_STACKWALK=y +CONFIG_SBITMAP=y +# end of Library routines + +CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED=y + +# +# Kernel hacking +# + +# +# printk and dmesg options +# +CONFIG_PRINTK_TIME=y +# CONFIG_PRINTK_CALLER is not set +# CONFIG_STACKTRACE_BUILD_ID is not set +CONFIG_CONSOLE_LOGLEVEL_DEFAULT=7 +CONFIG_CONSOLE_LOGLEVEL_QUIET=4 +CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4 +# CONFIG_BOOT_PRINTK_DELAY is not set +CONFIG_DYNAMIC_DEBUG=y +CONFIG_DYNAMIC_DEBUG_CORE=y +CONFIG_SYMBOLIC_ERRNAME=y +CONFIG_DEBUG_BUGVERBOSE=y +# end of printk and dmesg options + +# +# Compile-time checks and compiler options +# +# CONFIG_DEBUG_INFO is not set +CONFIG_FRAME_WARN=2048 +# CONFIG_STRIP_ASM_SYMS is not set +# CONFIG_READABLE_ASM is not set +# CONFIG_HEADERS_INSTALL is not set +# CONFIG_DEBUG_SECTION_MISMATCH is not set +CONFIG_SECTION_MISMATCH_WARN_ONLY=y +# CONFIG_DEBUG_FORCE_FUNCTION_ALIGN_64B is not set +CONFIG_ARCH_WANT_FRAME_POINTERS=y +CONFIG_FRAME_POINTER=y +# CONFIG_VMLINUX_MAP is not set +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set +# end of Compile-time checks and compiler options + +# +# Generic Kernel Debugging Instruments +# +CONFIG_MAGIC_SYSRQ=y +CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0x1 +CONFIG_MAGIC_SYSRQ_SERIAL=y +CONFIG_MAGIC_SYSRQ_SERIAL_SEQUENCE="" +CONFIG_DEBUG_FS=y +CONFIG_DEBUG_FS_ALLOW_ALL=y +# CONFIG_DEBUG_FS_DISALLOW_MOUNT is not set +# CONFIG_DEBUG_FS_ALLOW_NONE is not set +CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_KGDB is not set +CONFIG_ARCH_HAS_UBSAN_SANITIZE_ALL=y +# CONFIG_UBSAN is not set +# end of Generic Kernel Debugging Instruments + +CONFIG_DEBUG_KERNEL=y +CONFIG_DEBUG_MISC=y + +# +# Memory Debugging +# +# CONFIG_PAGE_EXTENSION is not set +# CONFIG_DEBUG_PAGEALLOC is not set +# CONFIG_PAGE_OWNER is not set +# CONFIG_PAGE_POISONING is not set +# CONFIG_DEBUG_PAGE_REF is not set +# CONFIG_DEBUG_RODATA_TEST is not set +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_SLUB_DEBUG_ON is not set +# CONFIG_SLUB_STATS is not set +CONFIG_HAVE_DEBUG_KMEMLEAK=y +# CONFIG_DEBUG_KMEMLEAK 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 +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_VM_PGTABLE is not set +CONFIG_ARCH_HAS_DEBUG_VIRTUAL=y +# CONFIG_DEBUG_VIRTUAL is not set +CONFIG_DEBUG_MEMORY_INIT=y +# CONFIG_DEBUG_PER_CPU_MAPS is not set +CONFIG_HAVE_ARCH_KASAN=y +CONFIG_HAVE_ARCH_KASAN_SW_TAGS=y +CONFIG_HAVE_ARCH_KASAN_HW_TAGS=y +CONFIG_HAVE_ARCH_KASAN_VMALLOC=y +CONFIG_CC_HAS_KASAN_GENERIC=y +CONFIG_CC_HAS_WORKING_NOSANITIZE_ADDRESS=y +# CONFIG_KASAN is not set +CONFIG_HAVE_ARCH_KFENCE=y +# CONFIG_KFENCE is not set +# end of Memory Debugging + +# CONFIG_DEBUG_SHIRQ is not set + +# +# Debug Oops, Lockups and Hangs +# +# CONFIG_PANIC_ON_OOPS is not set +CONFIG_PANIC_ON_OOPS_VALUE=0 +CONFIG_PANIC_TIMEOUT=0 +# CONFIG_SOFTLOCKUP_DETECTOR is not set +# CONFIG_DETECT_HUNG_TASK is not set +# CONFIG_WQ_WATCHDOG is not set +CONFIG_TEST_LOCKUP=m +# end of Debug Oops, Lockups and Hangs + +# +# Scheduler Debugging +# +CONFIG_SCHED_DEBUG=y +CONFIG_SCHED_INFO=y +# CONFIG_SCHEDSTATS is not set +# end of Scheduler Debugging + +# CONFIG_DEBUG_TIMEKEEPING is not set +CONFIG_DEBUG_PREEMPT=y + +# +# Lock Debugging (spinlocks, mutexes, etc...) +# +CONFIG_LOCK_DEBUGGING_SUPPORT=y +# CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set +# CONFIG_DEBUG_RWSEMS is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_DEBUG_ATOMIC_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_LOCK_TORTURE_TEST is not set +# CONFIG_WW_MUTEX_SELFTEST is not set +# CONFIG_SCF_TORTURE_TEST is not set +# CONFIG_CSD_LOCK_WAIT_DEBUG is not set +# end of Lock Debugging (spinlocks, mutexes, etc...) + +# CONFIG_DEBUG_IRQFLAGS is not set +CONFIG_STACKTRACE=y +# CONFIG_WARN_ALL_UNSEEDED_RANDOM is not set +# CONFIG_DEBUG_KOBJECT is not set + +# +# Debug kernel data structures +# +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_PLIST is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_BUG_ON_DATA_CORRUPTION is not set +# end of Debug kernel data structures + +# CONFIG_DEBUG_CREDENTIALS is not set + +# +# RCU Debugging +# +CONFIG_TORTURE_TEST=m +# CONFIG_RCU_SCALE_TEST is not set +CONFIG_RCU_TORTURE_TEST=m +# CONFIG_RCU_REF_SCALE_TEST is not set +CONFIG_RCU_CPU_STALL_TIMEOUT=60 +CONFIG_RCU_TRACE=y +# CONFIG_RCU_EQS_DEBUG is not set +# end of RCU Debugging + +# CONFIG_DEBUG_WQ_FORCE_RR_CPU is not set +# CONFIG_CPU_HOTPLUG_STATE_CONTROL is not set +# CONFIG_LATENCYTOP is not set +CONFIG_NOP_TRACER=y +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS=y +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_HAVE_SYSCALL_TRACEPOINTS=y +CONFIG_HAVE_C_RECORDMCOUNT=y +CONFIG_TRACE_CLOCK=y +CONFIG_RING_BUFFER=y +CONFIG_EVENT_TRACING=y +CONFIG_CONTEXT_SWITCH_TRACER=y +CONFIG_TRACING=y +CONFIG_TRACING_SUPPORT=y +CONFIG_FTRACE=y +# CONFIG_BOOTTIME_TRACING is not set +# CONFIG_FUNCTION_TRACER is not set +# CONFIG_STACK_TRACER is not set +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_PREEMPT_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_HWLAT_TRACER is not set +# CONFIG_OSNOISE_TRACER is not set +# CONFIG_TIMERLAT_TRACER is not set +# CONFIG_ENABLE_DEFAULT_TRACERS is not set +# CONFIG_FTRACE_SYSCALLS is not set +# CONFIG_TRACER_SNAPSHOT is not set +CONFIG_BRANCH_PROFILE_NONE=y +# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +CONFIG_UPROBE_EVENTS=y +CONFIG_BPF_EVENTS=y +CONFIG_DYNAMIC_EVENTS=y +CONFIG_PROBE_EVENTS=y +# CONFIG_SYNTH_EVENTS is not set +# CONFIG_HIST_TRIGGERS is not set +# CONFIG_TRACE_EVENT_INJECT is not set +# CONFIG_TRACEPOINT_BENCHMARK is not set +# CONFIG_RING_BUFFER_BENCHMARK is not set +# CONFIG_TRACE_EVAL_MAP_FILE is not set +# CONFIG_RING_BUFFER_STARTUP_TEST is not set +# CONFIG_RING_BUFFER_VALIDATE_TIME_DELTAS is not set +# CONFIG_PREEMPTIRQ_DELAY_TEST is not set +# CONFIG_SAMPLES is not set +CONFIG_STRICT_DEVMEM=y +# CONFIG_IO_STRICT_DEVMEM is not set + +# +# arm64 Debugging +# +# CONFIG_PID_IN_CONTEXTIDR is not set +# CONFIG_ARM64_RELOC_TEST is not set +# CONFIG_CORESIGHT is not set +# end of arm64 Debugging + +# +# Kernel Testing and Coverage +# +CONFIG_KUNIT=m +# CONFIG_KUNIT_DEBUGFS is not set +# CONFIG_KUNIT_TEST is not set +# CONFIG_KUNIT_EXAMPLE_TEST is not set +# CONFIG_KUNIT_ALL_TESTS is not set +# CONFIG_NOTIFIER_ERROR_INJECTION is not set +# CONFIG_FAULT_INJECTION is not set +CONFIG_ARCH_HAS_KCOV=y +CONFIG_CC_HAS_SANCOV_TRACE_PC=y +# CONFIG_KCOV is not set +CONFIG_RUNTIME_TESTING_MENU=y +# CONFIG_LKDTM is not set +# CONFIG_TEST_LIST_SORT is not set +# CONFIG_TEST_MIN_HEAP is not set +# CONFIG_TEST_SORT is not set +CONFIG_TEST_DIV64=m +CONFIG_BACKTRACE_SELF_TEST=m +CONFIG_RBTREE_TEST=m +CONFIG_REED_SOLOMON_TEST=m +CONFIG_INTERVAL_TREE_TEST=m +CONFIG_PERCPU_TEST=m +# CONFIG_ATOMIC64_SELFTEST is not set +CONFIG_ASYNC_RAID6_TEST=m +# CONFIG_TEST_HEXDUMP is not set +# CONFIG_STRING_SELFTEST is not set +# CONFIG_TEST_STRING_HELPERS is not set +CONFIG_TEST_STRSCPY=m +# CONFIG_TEST_KSTRTOX is not set +# CONFIG_TEST_PRINTF is not set +CONFIG_TEST_SCANF=m +# CONFIG_TEST_BITMAP is not set +# CONFIG_TEST_UUID is not set +CONFIG_TEST_XARRAY=m +# CONFIG_TEST_OVERFLOW is not set +# CONFIG_TEST_RHASHTABLE is not set +# CONFIG_TEST_HASH is not set +# CONFIG_TEST_IDA is not set +# CONFIG_TEST_LKM is not set +# CONFIG_TEST_BITOPS is not set +CONFIG_TEST_VMALLOC=m +# CONFIG_TEST_USER_COPY is not set +CONFIG_TEST_BPF=m +CONFIG_TEST_BLACKHOLE_DEV=m +# CONFIG_FIND_BIT_BENCHMARK is not set +# CONFIG_TEST_FIRMWARE is not set +# CONFIG_TEST_SYSCTL is not set +# CONFIG_BITFIELD_KUNIT is not set +CONFIG_RESOURCE_KUNIT_TEST=m +# CONFIG_SYSCTL_KUNIT_TEST is not set +# CONFIG_LIST_KUNIT_TEST is not set +# CONFIG_LINEAR_RANGES_TEST is not set +CONFIG_CMDLINE_KUNIT_TEST=m +# CONFIG_BITS_TEST is not set +CONFIG_SLUB_KUNIT_TEST=m +CONFIG_RATIONAL_KUNIT_TEST=m +# CONFIG_MEMCPY_KUNIT_TEST is not set +# CONFIG_TEST_UDELAY is not set +# CONFIG_TEST_STATIC_KEYS is not set +# CONFIG_TEST_KMOD is not set +CONFIG_TEST_MEMCAT_P=m +CONFIG_TEST_STACKINIT=m +# CONFIG_TEST_MEMINIT is not set +# CONFIG_TEST_FREE_PAGES is not set +CONFIG_ARCH_USE_MEMTEST=y +CONFIG_MEMTEST=y +# end of Kernel Testing and Coverage +# end of Kernel hacking diff --git a/config/sources/families/rk35xx.conf b/config/sources/families/rk35xx.conf index e46222283c..36601123a3 100644 --- a/config/sources/families/rk35xx.conf +++ b/config/sources/families/rk35xx.conf @@ -5,16 +5,6 @@ BOOTBRANCH='branch:stable-4.19-rock3' BOOTPATCHDIR="u-boot-rk35xx" OVERLAY_PREFIX='rk35xx' -if [[ "${BOOT_SOC}" == rk3566 ]]; then - CPUMAX=1800000 - DDR_BLOB='rk35/rk3566_ddr_1056MHz_v1.10.bin' - BL31_BLOB='rk35/rk3568_bl31_v1.29.elf' -elif [[ "${BOOT_SOC}" == rk3568 ]]; then - CPUMAX=1992000 - DDR_BLOB='rk35/rk3568_ddr_1056MHz_v1.10.bin' - BL31_BLOB='rk35/rk3568_bl31_v1.29.elf' -fi - case $BRANCH in legacy) @@ -27,16 +17,20 @@ case $BRANCH in KERNELPATCHDIR='rk35xx-legacy' ;; + + # temporary until kernel 5.16 is well supported for rockchip64 + edge) + KERNELBRANCH="branch:linux-5.16.y" + KERNELPATCHDIR='rk35xx-'$BRANCH + SKIP_BOOTSPLASH="yes" + LINUXCONFIG='linux-rk35xx-'$BRANCH + + ;; esac prepare_boot_configuration -uboot_custom_postprocess() -{ - tools/mkimage -n rk3568 -T rksd -d $RKBIN_DIR/$DDR_BLOB:spl/u-boot-spl.bin idbloader.img -} - family_tweaks_bsp() { : diff --git a/config/targets-cli-beta.conf b/config/targets-cli-beta.conf index 248a636771..59d7966ebe 100644 --- a/config/targets-cli-beta.conf +++ b/config/targets-cli-beta.conf @@ -66,6 +66,8 @@ rk322x-box edge jammy cli # Radxa rock-3a rock-3a legacy jammy cli beta yes +rock-3a legacy focal cli beta yes +rock-3a edge jammy cli beta yes # Raspberry Pi4 diff --git a/patch/kernel/archive/rk35xx-4.19/general-remove-wireguard.patch b/patch/kernel/archive/rk35xx-4.19/general-remove-wireguard.patch deleted file mode 100644 index 50361caa76..0000000000 --- a/patch/kernel/archive/rk35xx-4.19/general-remove-wireguard.patch +++ /dev/null @@ -1,7252 +0,0 @@ -This removes wireguard bundled in Rockchip's Android kernel - -diff --git a/Documentation/core-api/timekeeping.rst b/Documentation/core-api/timekeeping.rst -index c3bd8a6f309c9..491a93c574a06 100644 ---- a/Documentation/core-api/timekeeping.rst -+++ b/Documentation/core-api/timekeeping.rst -@@ -105,7 +105,7 @@ Some additional variants exist for more specialized cases: - ktime_t ktime_get_coarse_clocktai( void ) - - .. c:function:: u64 ktime_get_coarse_ns( void ) -- u64 ktime_get_coarse_boottime_ns( void ) -+ u64 ktime_get_coarse_boot_ns( void ) - u64 ktime_get_coarse_real_ns( void ) - u64 ktime_get_coarse_clocktai_ns( void ) - -diff --git a/include/linux/timekeeping.h b/include/linux/timekeeping.h -index 727582302f0e8..992fa3dc1cd5f 100644 ---- a/include/linux/timekeeping.h -+++ b/include/linux/timekeeping.h -@@ -131,7 +131,7 @@ static inline u64 ktime_get_coarse_real_ns(void) - return ktime_to_ns(ktime_get_coarse_real()); - } - --static inline u64 ktime_get_coarse_boottime_ns(void) -+static inline u64 ktime_get_coarse_boot_ns(void) - { - return ktime_to_ns(ktime_get_coarse_boottime()); - } -diff --git a/drivers/net/wireguard/Makefile b/drivers/net/wireguard/Makefile -deleted file mode 100644 -index fc52b2cb5..000000000 ---- a/drivers/net/wireguard/Makefile -+++ /dev/null -@@ -1,18 +0,0 @@ --ccflags-y := -O3 --ccflags-y += -D'pr_fmt(fmt)=KBUILD_MODNAME ": " fmt' --ccflags-$(CONFIG_WIREGUARD_DEBUG) += -DDEBUG --wireguard-y := main.o --wireguard-y += noise.o --wireguard-y += device.o --wireguard-y += peer.o --wireguard-y += timers.o --wireguard-y += queueing.o --wireguard-y += send.o --wireguard-y += receive.o --wireguard-y += socket.o --wireguard-y += peerlookup.o --wireguard-y += allowedips.o --wireguard-y += ratelimiter.o --wireguard-y += cookie.o --wireguard-y += netlink.o --obj-$(CONFIG_WIREGUARD) := wireguard.o -diff --git a/drivers/net/wireguard/allowedips.c b/drivers/net/wireguard/allowedips.c -deleted file mode 100644 -index 3725e9cd8..000000000 ---- a/drivers/net/wireguard/allowedips.c -+++ /dev/null -@@ -1,377 +0,0 @@ --// SPDX-License-Identifier: GPL-2.0 --/* -- * Copyright (C) 2015-2019 Jason A. Donenfeld . All Rights Reserved. -- */ -- --#include "allowedips.h" --#include "peer.h" -- --static void swap_endian(u8 *dst, const u8 *src, u8 bits) --{ -- if (bits == 32) { -- *(u32 *)dst = be32_to_cpu(*(const __be32 *)src); -- } else if (bits == 128) { -- ((u64 *)dst)[0] = be64_to_cpu(((const __be64 *)src)[0]); -- ((u64 *)dst)[1] = be64_to_cpu(((const __be64 *)src)[1]); -- } --} -- --static void copy_and_assign_cidr(struct allowedips_node *node, const u8 *src, -- u8 cidr, u8 bits) --{ -- node->cidr = cidr; -- node->bit_at_a = cidr / 8U; --#ifdef __LITTLE_ENDIAN -- node->bit_at_a ^= (bits / 8U - 1U) % 8U; --#endif -- node->bit_at_b = 7U - (cidr % 8U); -- node->bitlen = bits; -- memcpy(node->bits, src, bits / 8U); --} --#define CHOOSE_NODE(parent, key) \ -- parent->bit[(key[parent->bit_at_a] >> parent->bit_at_b) & 1] -- --static void push_rcu(struct allowedips_node **stack, -- struct allowedips_node __rcu *p, unsigned int *len) --{ -- if (rcu_access_pointer(p)) { -- WARN_ON(IS_ENABLED(DEBUG) && *len >= 128); -- stack[(*len)++] = rcu_dereference_raw(p); -- } --} -- --static void root_free_rcu(struct rcu_head *rcu) --{ -- struct allowedips_node *node, *stack[128] = { -- container_of(rcu, struct allowedips_node, rcu) }; -- unsigned int len = 1; -- -- while (len > 0 && (node = stack[--len])) { -- push_rcu(stack, node->bit[0], &len); -- push_rcu(stack, node->bit[1], &len); -- kfree(node); -- } --} -- --static void root_remove_peer_lists(struct allowedips_node *root) --{ -- struct allowedips_node *node, *stack[128] = { root }; -- unsigned int len = 1; -- -- while (len > 0 && (node = stack[--len])) { -- push_rcu(stack, node->bit[0], &len); -- push_rcu(stack, node->bit[1], &len); -- if (rcu_access_pointer(node->peer)) -- list_del(&node->peer_list); -- } --} -- --static void walk_remove_by_peer(struct allowedips_node __rcu **top, -- struct wg_peer *peer, struct mutex *lock) --{ --#define REF(p) rcu_access_pointer(p) --#define DEREF(p) rcu_dereference_protected(*(p), lockdep_is_held(lock)) --#define PUSH(p) ({ \ -- WARN_ON(IS_ENABLED(DEBUG) && len >= 128); \ -- stack[len++] = p; \ -- }) -- -- struct allowedips_node __rcu **stack[128], **nptr; -- struct allowedips_node *node, *prev; -- unsigned int len; -- -- if (unlikely(!peer || !REF(*top))) -- return; -- -- for (prev = NULL, len = 0, PUSH(top); len > 0; prev = node) { -- nptr = stack[len - 1]; -- node = DEREF(nptr); -- if (!node) { -- --len; -- continue; -- } -- if (!prev || REF(prev->bit[0]) == node || -- REF(prev->bit[1]) == node) { -- if (REF(node->bit[0])) -- PUSH(&node->bit[0]); -- else if (REF(node->bit[1])) -- PUSH(&node->bit[1]); -- } else if (REF(node->bit[0]) == prev) { -- if (REF(node->bit[1])) -- PUSH(&node->bit[1]); -- } else { -- if (rcu_dereference_protected(node->peer, -- lockdep_is_held(lock)) == peer) { -- RCU_INIT_POINTER(node->peer, NULL); -- list_del_init(&node->peer_list); -- if (!node->bit[0] || !node->bit[1]) { -- rcu_assign_pointer(*nptr, DEREF( -- &node->bit[!REF(node->bit[0])])); -- kfree_rcu(node, rcu); -- node = DEREF(nptr); -- } -- } -- --len; -- } -- } -- --#undef REF --#undef DEREF --#undef PUSH --} -- --static unsigned int fls128(u64 a, u64 b) --{ -- return a ? fls64(a) + 64U : fls64(b); --} -- --static u8 common_bits(const struct allowedips_node *node, const u8 *key, -- u8 bits) --{ -- if (bits == 32) -- return 32U - fls(*(const u32 *)node->bits ^ *(const u32 *)key); -- else if (bits == 128) -- return 128U - fls128( -- *(const u64 *)&node->bits[0] ^ *(const u64 *)&key[0], -- *(const u64 *)&node->bits[8] ^ *(const u64 *)&key[8]); -- return 0; --} -- --static bool prefix_matches(const struct allowedips_node *node, const u8 *key, -- u8 bits) --{ -- /* This could be much faster if it actually just compared the common -- * bits properly, by precomputing a mask bswap(~0 << (32 - cidr)), and -- * the rest, but it turns out that common_bits is already super fast on -- * modern processors, even taking into account the unfortunate bswap. -- * So, we just inline it like this instead. -- */ -- return common_bits(node, key, bits) >= node->cidr; --} -- --static struct allowedips_node *find_node(struct allowedips_node *trie, u8 bits, -- const u8 *key) --{ -- struct allowedips_node *node = trie, *found = NULL; -- -- while (node && prefix_matches(node, key, bits)) { -- if (rcu_access_pointer(node->peer)) -- found = node; -- if (node->cidr == bits) -- break; -- node = rcu_dereference_bh(CHOOSE_NODE(node, key)); -- } -- return found; --} -- --/* Returns a strong reference to a peer */ --static struct wg_peer *lookup(struct allowedips_node __rcu *root, u8 bits, -- const void *be_ip) --{ -- /* Aligned so it can be passed to fls/fls64 */ -- u8 ip[16] __aligned(__alignof(u64)); -- struct allowedips_node *node; -- struct wg_peer *peer = NULL; -- -- swap_endian(ip, be_ip, bits); -- -- rcu_read_lock_bh(); --retry: -- node = find_node(rcu_dereference_bh(root), bits, ip); -- if (node) { -- peer = wg_peer_get_maybe_zero(rcu_dereference_bh(node->peer)); -- if (!peer) -- goto retry; -- } -- rcu_read_unlock_bh(); -- return peer; --} -- --static bool node_placement(struct allowedips_node __rcu *trie, const u8 *key, -- u8 cidr, u8 bits, struct allowedips_node **rnode, -- struct mutex *lock) --{ -- struct allowedips_node *node = rcu_dereference_protected(trie, -- lockdep_is_held(lock)); -- struct allowedips_node *parent = NULL; -- bool exact = false; -- -- while (node && node->cidr <= cidr && prefix_matches(node, key, bits)) { -- parent = node; -- if (parent->cidr == cidr) { -- exact = true; -- break; -- } -- node = rcu_dereference_protected(CHOOSE_NODE(parent, key), -- lockdep_is_held(lock)); -- } -- *rnode = parent; -- return exact; --} -- --static int add(struct allowedips_node __rcu **trie, u8 bits, const u8 *key, -- u8 cidr, struct wg_peer *peer, struct mutex *lock) --{ -- struct allowedips_node *node, *parent, *down, *newnode; -- -- if (unlikely(cidr > bits || !peer)) -- return -EINVAL; -- -- if (!rcu_access_pointer(*trie)) { -- node = kzalloc(sizeof(*node), GFP_KERNEL); -- if (unlikely(!node)) -- return -ENOMEM; -- RCU_INIT_POINTER(node->peer, peer); -- list_add_tail(&node->peer_list, &peer->allowedips_list); -- copy_and_assign_cidr(node, key, cidr, bits); -- rcu_assign_pointer(*trie, node); -- return 0; -- } -- if (node_placement(*trie, key, cidr, bits, &node, lock)) { -- rcu_assign_pointer(node->peer, peer); -- list_move_tail(&node->peer_list, &peer->allowedips_list); -- return 0; -- } -- -- newnode = kzalloc(sizeof(*newnode), GFP_KERNEL); -- if (unlikely(!newnode)) -- return -ENOMEM; -- RCU_INIT_POINTER(newnode->peer, peer); -- list_add_tail(&newnode->peer_list, &peer->allowedips_list); -- copy_and_assign_cidr(newnode, key, cidr, bits); -- -- if (!node) { -- down = rcu_dereference_protected(*trie, lockdep_is_held(lock)); -- } else { -- down = rcu_dereference_protected(CHOOSE_NODE(node, key), -- lockdep_is_held(lock)); -- if (!down) { -- rcu_assign_pointer(CHOOSE_NODE(node, key), newnode); -- return 0; -- } -- } -- cidr = min(cidr, common_bits(down, key, bits)); -- parent = node; -- -- if (newnode->cidr == cidr) { -- rcu_assign_pointer(CHOOSE_NODE(newnode, down->bits), down); -- if (!parent) -- rcu_assign_pointer(*trie, newnode); -- else -- rcu_assign_pointer(CHOOSE_NODE(parent, newnode->bits), -- newnode); -- } else { -- node = kzalloc(sizeof(*node), GFP_KERNEL); -- if (unlikely(!node)) { -- list_del(&newnode->peer_list); -- kfree(newnode); -- return -ENOMEM; -- } -- INIT_LIST_HEAD(&node->peer_list); -- copy_and_assign_cidr(node, newnode->bits, cidr, bits); -- -- rcu_assign_pointer(CHOOSE_NODE(node, down->bits), down); -- rcu_assign_pointer(CHOOSE_NODE(node, newnode->bits), newnode); -- if (!parent) -- rcu_assign_pointer(*trie, node); -- else -- rcu_assign_pointer(CHOOSE_NODE(parent, node->bits), -- node); -- } -- return 0; --} -- --void wg_allowedips_init(struct allowedips *table) --{ -- table->root4 = table->root6 = NULL; -- table->seq = 1; --} -- --void wg_allowedips_free(struct allowedips *table, struct mutex *lock) --{ -- struct allowedips_node __rcu *old4 = table->root4, *old6 = table->root6; -- -- ++table->seq; -- RCU_INIT_POINTER(table->root4, NULL); -- RCU_INIT_POINTER(table->root6, NULL); -- if (rcu_access_pointer(old4)) { -- struct allowedips_node *node = rcu_dereference_protected(old4, -- lockdep_is_held(lock)); -- -- root_remove_peer_lists(node); -- call_rcu(&node->rcu, root_free_rcu); -- } -- if (rcu_access_pointer(old6)) { -- struct allowedips_node *node = rcu_dereference_protected(old6, -- lockdep_is_held(lock)); -- -- root_remove_peer_lists(node); -- call_rcu(&node->rcu, root_free_rcu); -- } --} -- --int wg_allowedips_insert_v4(struct allowedips *table, const struct in_addr *ip, -- u8 cidr, struct wg_peer *peer, struct mutex *lock) --{ -- /* Aligned so it can be passed to fls */ -- u8 key[4] __aligned(__alignof(u32)); -- -- ++table->seq; -- swap_endian(key, (const u8 *)ip, 32); -- return add(&table->root4, 32, key, cidr, peer, lock); --} -- --int wg_allowedips_insert_v6(struct allowedips *table, const struct in6_addr *ip, -- u8 cidr, struct wg_peer *peer, struct mutex *lock) --{ -- /* Aligned so it can be passed to fls64 */ -- u8 key[16] __aligned(__alignof(u64)); -- -- ++table->seq; -- swap_endian(key, (const u8 *)ip, 128); -- return add(&table->root6, 128, key, cidr, peer, lock); --} -- --void wg_allowedips_remove_by_peer(struct allowedips *table, -- struct wg_peer *peer, struct mutex *lock) --{ -- ++table->seq; -- walk_remove_by_peer(&table->root4, peer, lock); -- walk_remove_by_peer(&table->root6, peer, lock); --} -- --int wg_allowedips_read_node(struct allowedips_node *node, u8 ip[16], u8 *cidr) --{ -- const unsigned int cidr_bytes = DIV_ROUND_UP(node->cidr, 8U); -- swap_endian(ip, node->bits, node->bitlen); -- memset(ip + cidr_bytes, 0, node->bitlen / 8U - cidr_bytes); -- if (node->cidr) -- ip[cidr_bytes - 1U] &= ~0U << (-node->cidr % 8U); -- -- *cidr = node->cidr; -- return node->bitlen == 32 ? AF_INET : AF_INET6; --} -- --/* Returns a strong reference to a peer */ --struct wg_peer *wg_allowedips_lookup_dst(struct allowedips *table, -- struct sk_buff *skb) --{ -- if (skb->protocol == htons(ETH_P_IP)) -- return lookup(table->root4, 32, &ip_hdr(skb)->daddr); -- else if (skb->protocol == htons(ETH_P_IPV6)) -- return lookup(table->root6, 128, &ipv6_hdr(skb)->daddr); -- return NULL; --} -- --/* Returns a strong reference to a peer */ --struct wg_peer *wg_allowedips_lookup_src(struct allowedips *table, -- struct sk_buff *skb) --{ -- if (skb->protocol == htons(ETH_P_IP)) -- return lookup(table->root4, 32, &ip_hdr(skb)->saddr); -- else if (skb->protocol == htons(ETH_P_IPV6)) -- return lookup(table->root6, 128, &ipv6_hdr(skb)->saddr); -- return NULL; --} -- --#include "selftest/allowedips.c" -diff --git a/drivers/net/wireguard/allowedips.h b/drivers/net/wireguard/allowedips.h -deleted file mode 100644 -index e5c83cafc..000000000 ---- a/drivers/net/wireguard/allowedips.h -+++ /dev/null -@@ -1,59 +0,0 @@ --/* SPDX-License-Identifier: GPL-2.0 */ --/* -- * Copyright (C) 2015-2019 Jason A. Donenfeld . All Rights Reserved. -- */ -- --#ifndef _WG_ALLOWEDIPS_H --#define _WG_ALLOWEDIPS_H -- --#include --#include --#include -- --struct wg_peer; -- --struct allowedips_node { -- struct wg_peer __rcu *peer; -- struct allowedips_node __rcu *bit[2]; -- /* While it may seem scandalous that we waste space for v4, -- * we're alloc'ing to the nearest power of 2 anyway, so this -- * doesn't actually make a difference. -- */ -- u8 bits[16] __aligned(__alignof(u64)); -- u8 cidr, bit_at_a, bit_at_b, bitlen; -- -- /* Keep rarely used list at bottom to be beyond cache line. */ -- union { -- struct list_head peer_list; -- struct rcu_head rcu; -- }; --}; -- --struct allowedips { -- struct allowedips_node __rcu *root4; -- struct allowedips_node __rcu *root6; -- u64 seq; --}; -- --void wg_allowedips_init(struct allowedips *table); --void wg_allowedips_free(struct allowedips *table, struct mutex *mutex); --int wg_allowedips_insert_v4(struct allowedips *table, const struct in_addr *ip, -- u8 cidr, struct wg_peer *peer, struct mutex *lock); --int wg_allowedips_insert_v6(struct allowedips *table, const struct in6_addr *ip, -- u8 cidr, struct wg_peer *peer, struct mutex *lock); --void wg_allowedips_remove_by_peer(struct allowedips *table, -- struct wg_peer *peer, struct mutex *lock); --/* The ip input pointer should be __aligned(__alignof(u64))) */ --int wg_allowedips_read_node(struct allowedips_node *node, u8 ip[16], u8 *cidr); -- --/* These return a strong reference to a peer: */ --struct wg_peer *wg_allowedips_lookup_dst(struct allowedips *table, -- struct sk_buff *skb); --struct wg_peer *wg_allowedips_lookup_src(struct allowedips *table, -- struct sk_buff *skb); -- --#ifdef DEBUG --bool wg_allowedips_selftest(void); --#endif -- --#endif /* _WG_ALLOWEDIPS_H */ -diff --git a/drivers/net/wireguard/cookie.c b/drivers/net/wireguard/cookie.c -deleted file mode 100644 -index 4956f0499..000000000 ---- a/drivers/net/wireguard/cookie.c -+++ /dev/null -@@ -1,236 +0,0 @@ --// SPDX-License-Identifier: GPL-2.0 --/* -- * Copyright (C) 2015-2019 Jason A. Donenfeld . All Rights Reserved. -- */ -- --#include "cookie.h" --#include "peer.h" --#include "device.h" --#include "messages.h" --#include "ratelimiter.h" --#include "timers.h" -- --#include --#include -- --#include --#include -- --void wg_cookie_checker_init(struct cookie_checker *checker, -- struct wg_device *wg) --{ -- init_rwsem(&checker->secret_lock); -- checker->secret_birthdate = ktime_get_coarse_boottime_ns(); -- get_random_bytes(checker->secret, NOISE_HASH_LEN); -- checker->device = wg; --} -- --enum { COOKIE_KEY_LABEL_LEN = 8 }; --static const u8 mac1_key_label[COOKIE_KEY_LABEL_LEN] = "mac1----"; --static const u8 cookie_key_label[COOKIE_KEY_LABEL_LEN] = "cookie--"; -- --static void precompute_key(u8 key[NOISE_SYMMETRIC_KEY_LEN], -- const u8 pubkey[NOISE_PUBLIC_KEY_LEN], -- const u8 label[COOKIE_KEY_LABEL_LEN]) --{ -- struct blake2s_state blake; -- -- blake2s_init(&blake, NOISE_SYMMETRIC_KEY_LEN); -- blake2s_update(&blake, label, COOKIE_KEY_LABEL_LEN); -- blake2s_update(&blake, pubkey, NOISE_PUBLIC_KEY_LEN); -- blake2s_final(&blake, key); --} -- --/* Must hold peer->handshake.static_identity->lock */ --void wg_cookie_checker_precompute_device_keys(struct cookie_checker *checker) --{ -- if (likely(checker->device->static_identity.has_identity)) { -- precompute_key(checker->cookie_encryption_key, -- checker->device->static_identity.static_public, -- cookie_key_label); -- precompute_key(checker->message_mac1_key, -- checker->device->static_identity.static_public, -- mac1_key_label); -- } else { -- memset(checker->cookie_encryption_key, 0, -- NOISE_SYMMETRIC_KEY_LEN); -- memset(checker->message_mac1_key, 0, NOISE_SYMMETRIC_KEY_LEN); -- } --} -- --void wg_cookie_checker_precompute_peer_keys(struct wg_peer *peer) --{ -- precompute_key(peer->latest_cookie.cookie_decryption_key, -- peer->handshake.remote_static, cookie_key_label); -- precompute_key(peer->latest_cookie.message_mac1_key, -- peer->handshake.remote_static, mac1_key_label); --} -- --void wg_cookie_init(struct cookie *cookie) --{ -- memset(cookie, 0, sizeof(*cookie)); -- init_rwsem(&cookie->lock); --} -- --static void compute_mac1(u8 mac1[COOKIE_LEN], const void *message, size_t len, -- const u8 key[NOISE_SYMMETRIC_KEY_LEN]) --{ -- len = len - sizeof(struct message_macs) + -- offsetof(struct message_macs, mac1); -- blake2s(mac1, message, key, COOKIE_LEN, len, NOISE_SYMMETRIC_KEY_LEN); --} -- --static void compute_mac2(u8 mac2[COOKIE_LEN], const void *message, size_t len, -- const u8 cookie[COOKIE_LEN]) --{ -- len = len - sizeof(struct message_macs) + -- offsetof(struct message_macs, mac2); -- blake2s(mac2, message, cookie, COOKIE_LEN, len, COOKIE_LEN); --} -- --static void make_cookie(u8 cookie[COOKIE_LEN], struct sk_buff *skb, -- struct cookie_checker *checker) --{ -- struct blake2s_state state; -- -- if (wg_birthdate_has_expired(checker->secret_birthdate, -- COOKIE_SECRET_MAX_AGE)) { -- down_write(&checker->secret_lock); -- checker->secret_birthdate = ktime_get_coarse_boottime_ns(); -- get_random_bytes(checker->secret, NOISE_HASH_LEN); -- up_write(&checker->secret_lock); -- } -- -- down_read(&checker->secret_lock); -- -- blake2s_init_key(&state, COOKIE_LEN, checker->secret, NOISE_HASH_LEN); -- if (skb->protocol == htons(ETH_P_IP)) -- blake2s_update(&state, (u8 *)&ip_hdr(skb)->saddr, -- sizeof(struct in_addr)); -- else if (skb->protocol == htons(ETH_P_IPV6)) -- blake2s_update(&state, (u8 *)&ipv6_hdr(skb)->saddr, -- sizeof(struct in6_addr)); -- blake2s_update(&state, (u8 *)&udp_hdr(skb)->source, sizeof(__be16)); -- blake2s_final(&state, cookie); -- -- up_read(&checker->secret_lock); --} -- --enum cookie_mac_state wg_cookie_validate_packet(struct cookie_checker *checker, -- struct sk_buff *skb, -- bool check_cookie) --{ -- struct message_macs *macs = (struct message_macs *) -- (skb->data + skb->len - sizeof(*macs)); -- enum cookie_mac_state ret; -- u8 computed_mac[COOKIE_LEN]; -- u8 cookie[COOKIE_LEN]; -- -- ret = INVALID_MAC; -- compute_mac1(computed_mac, skb->data, skb->len, -- checker->message_mac1_key); -- if (crypto_memneq(computed_mac, macs->mac1, COOKIE_LEN)) -- goto out; -- -- ret = VALID_MAC_BUT_NO_COOKIE; -- -- if (!check_cookie) -- goto out; -- -- make_cookie(cookie, skb, checker); -- -- compute_mac2(computed_mac, skb->data, skb->len, cookie); -- if (crypto_memneq(computed_mac, macs->mac2, COOKIE_LEN)) -- goto out; -- -- ret = VALID_MAC_WITH_COOKIE_BUT_RATELIMITED; -- if (!wg_ratelimiter_allow(skb, dev_net(checker->device->dev))) -- goto out; -- -- ret = VALID_MAC_WITH_COOKIE; -- --out: -- return ret; --} -- --void wg_cookie_add_mac_to_packet(void *message, size_t len, -- struct wg_peer *peer) --{ -- struct message_macs *macs = (struct message_macs *) -- ((u8 *)message + len - sizeof(*macs)); -- -- down_write(&peer->latest_cookie.lock); -- compute_mac1(macs->mac1, message, len, -- peer->latest_cookie.message_mac1_key); -- memcpy(peer->latest_cookie.last_mac1_sent, macs->mac1, COOKIE_LEN); -- peer->latest_cookie.have_sent_mac1 = true; -- up_write(&peer->latest_cookie.lock); -- -- down_read(&peer->latest_cookie.lock); -- if (peer->latest_cookie.is_valid && -- !wg_birthdate_has_expired(peer->latest_cookie.birthdate, -- COOKIE_SECRET_MAX_AGE - COOKIE_SECRET_LATENCY)) -- compute_mac2(macs->mac2, message, len, -- peer->latest_cookie.cookie); -- else -- memset(macs->mac2, 0, COOKIE_LEN); -- up_read(&peer->latest_cookie.lock); --} -- --void wg_cookie_message_create(struct message_handshake_cookie *dst, -- struct sk_buff *skb, __le32 index, -- struct cookie_checker *checker) --{ -- struct message_macs *macs = (struct message_macs *) -- ((u8 *)skb->data + skb->len - sizeof(*macs)); -- u8 cookie[COOKIE_LEN]; -- -- dst->header.type = cpu_to_le32(MESSAGE_HANDSHAKE_COOKIE); -- dst->receiver_index = index; -- get_random_bytes_wait(dst->nonce, COOKIE_NONCE_LEN); -- -- make_cookie(cookie, skb, checker); -- xchacha20poly1305_encrypt(dst->encrypted_cookie, cookie, COOKIE_LEN, -- macs->mac1, COOKIE_LEN, dst->nonce, -- checker->cookie_encryption_key); --} -- --void wg_cookie_message_consume(struct message_handshake_cookie *src, -- struct wg_device *wg) --{ -- struct wg_peer *peer = NULL; -- u8 cookie[COOKIE_LEN]; -- bool ret; -- -- if (unlikely(!wg_index_hashtable_lookup(wg->index_hashtable, -- INDEX_HASHTABLE_HANDSHAKE | -- INDEX_HASHTABLE_KEYPAIR, -- src->receiver_index, &peer))) -- return; -- -- down_read(&peer->latest_cookie.lock); -- if (unlikely(!peer->latest_cookie.have_sent_mac1)) { -- up_read(&peer->latest_cookie.lock); -- goto out; -- } -- ret = xchacha20poly1305_decrypt( -- cookie, src->encrypted_cookie, sizeof(src->encrypted_cookie), -- peer->latest_cookie.last_mac1_sent, COOKIE_LEN, src->nonce, -- peer->latest_cookie.cookie_decryption_key); -- up_read(&peer->latest_cookie.lock); -- -- if (ret) { -- down_write(&peer->latest_cookie.lock); -- memcpy(peer->latest_cookie.cookie, cookie, COOKIE_LEN); -- peer->latest_cookie.birthdate = ktime_get_coarse_boottime_ns(); -- peer->latest_cookie.is_valid = true; -- peer->latest_cookie.have_sent_mac1 = false; -- up_write(&peer->latest_cookie.lock); -- } else { -- net_dbg_ratelimited("%s: Could not decrypt invalid cookie response\n", -- wg->dev->name); -- } -- --out: -- wg_peer_put(peer); --} -diff --git a/drivers/net/wireguard/cookie.h b/drivers/net/wireguard/cookie.h -deleted file mode 100644 -index c4bd61ca0..000000000 ---- a/drivers/net/wireguard/cookie.h -+++ /dev/null -@@ -1,59 +0,0 @@ --/* SPDX-License-Identifier: GPL-2.0 */ --/* -- * Copyright (C) 2015-2019 Jason A. Donenfeld . All Rights Reserved. -- */ -- --#ifndef _WG_COOKIE_H --#define _WG_COOKIE_H -- --#include "messages.h" --#include -- --struct wg_peer; -- --struct cookie_checker { -- u8 secret[NOISE_HASH_LEN]; -- u8 cookie_encryption_key[NOISE_SYMMETRIC_KEY_LEN]; -- u8 message_mac1_key[NOISE_SYMMETRIC_KEY_LEN]; -- u64 secret_birthdate; -- struct rw_semaphore secret_lock; -- struct wg_device *device; --}; -- --struct cookie { -- u64 birthdate; -- bool is_valid; -- u8 cookie[COOKIE_LEN]; -- bool have_sent_mac1; -- u8 last_mac1_sent[COOKIE_LEN]; -- u8 cookie_decryption_key[NOISE_SYMMETRIC_KEY_LEN]; -- u8 message_mac1_key[NOISE_SYMMETRIC_KEY_LEN]; -- struct rw_semaphore lock; --}; -- --enum cookie_mac_state { -- INVALID_MAC, -- VALID_MAC_BUT_NO_COOKIE, -- VALID_MAC_WITH_COOKIE_BUT_RATELIMITED, -- VALID_MAC_WITH_COOKIE --}; -- --void wg_cookie_checker_init(struct cookie_checker *checker, -- struct wg_device *wg); --void wg_cookie_checker_precompute_device_keys(struct cookie_checker *checker); --void wg_cookie_checker_precompute_peer_keys(struct wg_peer *peer); --void wg_cookie_init(struct cookie *cookie); -- --enum cookie_mac_state wg_cookie_validate_packet(struct cookie_checker *checker, -- struct sk_buff *skb, -- bool check_cookie); --void wg_cookie_add_mac_to_packet(void *message, size_t len, -- struct wg_peer *peer); -- --void wg_cookie_message_create(struct message_handshake_cookie *src, -- struct sk_buff *skb, __le32 index, -- struct cookie_checker *checker); --void wg_cookie_message_consume(struct message_handshake_cookie *src, -- struct wg_device *wg); -- --#endif /* _WG_COOKIE_H */ -diff --git a/drivers/net/wireguard/device.c b/drivers/net/wireguard/device.c -deleted file mode 100644 -index de8a4fad4..000000000 ---- a/drivers/net/wireguard/device.c -+++ /dev/null -@@ -1,455 +0,0 @@ --// SPDX-License-Identifier: GPL-2.0 --/* -- * Copyright (C) 2015-2019 Jason A. Donenfeld . All Rights Reserved. -- */ -- --#include "queueing.h" --#include "socket.h" --#include "timers.h" --#include "device.h" --#include "ratelimiter.h" --#include "peer.h" --#include "messages.h" -- --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include -- --static LIST_HEAD(device_list); -- --static int wg_open(struct net_device *dev) --{ -- struct in_device *dev_v4 = __in_dev_get_rtnl(dev); -- struct inet6_dev *dev_v6 = __in6_dev_get(dev); -- struct wg_device *wg = netdev_priv(dev); -- struct wg_peer *peer; -- int ret; -- -- if (dev_v4) { -- /* At some point we might put this check near the ip_rt_send_ -- * redirect call of ip_forward in net/ipv4/ip_forward.c, similar -- * to the current secpath check. -- */ -- IN_DEV_CONF_SET(dev_v4, SEND_REDIRECTS, false); -- IPV4_DEVCONF_ALL(dev_net(dev), SEND_REDIRECTS) = false; -- } -- if (dev_v6) -- dev_v6->cnf.addr_gen_mode = IN6_ADDR_GEN_MODE_NONE; -- -- mutex_lock(&wg->device_update_lock); -- ret = wg_socket_init(wg, wg->incoming_port); -- if (ret < 0) -- goto out; -- list_for_each_entry(peer, &wg->peer_list, peer_list) { -- wg_packet_send_staged_packets(peer); -- if (peer->persistent_keepalive_interval) -- wg_packet_send_keepalive(peer); -- } --out: -- mutex_unlock(&wg->device_update_lock); -- return ret; --} -- --#ifdef CONFIG_PM_SLEEP --static int wg_pm_notification(struct notifier_block *nb, unsigned long action, -- void *data) --{ -- struct wg_device *wg; -- struct wg_peer *peer; -- -- /* If the machine is constantly suspending and resuming, as part of -- * its normal operation rather than as a somewhat rare event, then we -- * don't actually want to clear keys. -- */ -- if (IS_ENABLED(CONFIG_PM_AUTOSLEEP) || IS_ENABLED(CONFIG_ANDROID)) -- return 0; -- -- if (action != PM_HIBERNATION_PREPARE && action != PM_SUSPEND_PREPARE) -- return 0; -- -- rtnl_lock(); -- list_for_each_entry(wg, &device_list, device_list) { -- mutex_lock(&wg->device_update_lock); -- list_for_each_entry(peer, &wg->peer_list, peer_list) { -- del_timer(&peer->timer_zero_key_material); -- wg_noise_handshake_clear(&peer->handshake); -- wg_noise_keypairs_clear(&peer->keypairs); -- } -- mutex_unlock(&wg->device_update_lock); -- } -- rtnl_unlock(); -- rcu_barrier(); -- return 0; --} -- --static struct notifier_block pm_notifier = { .notifier_call = wg_pm_notification }; --#endif -- --static int wg_stop(struct net_device *dev) --{ -- struct wg_device *wg = netdev_priv(dev); -- struct wg_peer *peer; -- -- mutex_lock(&wg->device_update_lock); -- list_for_each_entry(peer, &wg->peer_list, peer_list) { -- wg_packet_purge_staged_packets(peer); -- wg_timers_stop(peer); -- wg_noise_handshake_clear(&peer->handshake); -- wg_noise_keypairs_clear(&peer->keypairs); -- wg_noise_reset_last_sent_handshake(&peer->last_sent_handshake); -- } -- mutex_unlock(&wg->device_update_lock); -- skb_queue_purge(&wg->incoming_handshakes); -- wg_socket_reinit(wg, NULL, NULL); -- return 0; --} -- --static netdev_tx_t wg_xmit(struct sk_buff *skb, struct net_device *dev) --{ -- struct wg_device *wg = netdev_priv(dev); -- struct sk_buff_head packets; -- struct wg_peer *peer; -- struct sk_buff *next; -- sa_family_t family; -- u32 mtu; -- int ret; -- -- if (unlikely(!wg_check_packet_protocol(skb))) { -- ret = -EPROTONOSUPPORT; -- net_dbg_ratelimited("%s: Invalid IP packet\n", dev->name); -- goto err; -- } -- -- peer = wg_allowedips_lookup_dst(&wg->peer_allowedips, skb); -- if (unlikely(!peer)) { -- ret = -ENOKEY; -- if (skb->protocol == htons(ETH_P_IP)) -- net_dbg_ratelimited("%s: No peer has allowed IPs matching %pI4\n", -- dev->name, &ip_hdr(skb)->daddr); -- else if (skb->protocol == htons(ETH_P_IPV6)) -- net_dbg_ratelimited("%s: No peer has allowed IPs matching %pI6\n", -- dev->name, &ipv6_hdr(skb)->daddr); -- goto err; -- } -- -- family = READ_ONCE(peer->endpoint.addr.sa_family); -- if (unlikely(family != AF_INET && family != AF_INET6)) { -- ret = -EDESTADDRREQ; -- net_dbg_ratelimited("%s: No valid endpoint has been configured or discovered for peer %llu\n", -- dev->name, peer->internal_id); -- goto err_peer; -- } -- -- mtu = skb_dst(skb) ? dst_mtu(skb_dst(skb)) : dev->mtu; -- -- __skb_queue_head_init(&packets); -- if (!skb_is_gso(skb)) { -- skb_mark_not_on_list(skb); -- } else { -- struct sk_buff *segs = skb_gso_segment(skb, 0); -- -- if (unlikely(IS_ERR(segs))) { -- ret = PTR_ERR(segs); -- goto err_peer; -- } -- dev_kfree_skb(skb); -- skb = segs; -- } -- -- skb_list_walk_safe(skb, skb, next) { -- skb_mark_not_on_list(skb); -- -- skb = skb_share_check(skb, GFP_ATOMIC); -- if (unlikely(!skb)) -- continue; -- -- /* We only need to keep the original dst around for icmp, -- * so at this point we're in a position to drop it. -- */ -- skb_dst_drop(skb); -- -- PACKET_CB(skb)->mtu = mtu; -- -- __skb_queue_tail(&packets, skb); -- } -- -- spin_lock_bh(&peer->staged_packet_queue.lock); -- /* If the queue is getting too big, we start removing the oldest packets -- * until it's small again. We do this before adding the new packet, so -- * we don't remove GSO segments that are in excess. -- */ -- while (skb_queue_len(&peer->staged_packet_queue) > MAX_STAGED_PACKETS) { -- dev_kfree_skb(__skb_dequeue(&peer->staged_packet_queue)); -- ++dev->stats.tx_dropped; -- } -- skb_queue_splice_tail(&packets, &peer->staged_packet_queue); -- spin_unlock_bh(&peer->staged_packet_queue.lock); -- -- wg_packet_send_staged_packets(peer); -- -- wg_peer_put(peer); -- return NETDEV_TX_OK; -- --err_peer: -- wg_peer_put(peer); --err: -- ++dev->stats.tx_errors; -- if (skb->protocol == htons(ETH_P_IP)) -- icmp_ndo_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0); -- else if (skb->protocol == htons(ETH_P_IPV6)) -- icmpv6_ndo_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_ADDR_UNREACH, 0); -- kfree_skb(skb); -- return ret; --} -- --static const struct net_device_ops netdev_ops = { -- .ndo_open = wg_open, -- .ndo_stop = wg_stop, -- .ndo_start_xmit = wg_xmit, -- .ndo_get_stats64 = ip_tunnel_get_stats64 --}; -- --static void wg_destruct(struct net_device *dev) --{ -- struct wg_device *wg = netdev_priv(dev); -- -- rtnl_lock(); -- list_del(&wg->device_list); -- rtnl_unlock(); -- mutex_lock(&wg->device_update_lock); -- rcu_assign_pointer(wg->creating_net, NULL); -- wg->incoming_port = 0; -- wg_socket_reinit(wg, NULL, NULL); -- /* The final references are cleared in the below calls to destroy_workqueue. */ -- wg_peer_remove_all(wg); -- destroy_workqueue(wg->handshake_receive_wq); -- destroy_workqueue(wg->handshake_send_wq); -- destroy_workqueue(wg->packet_crypt_wq); -- wg_packet_queue_free(&wg->decrypt_queue, true); -- wg_packet_queue_free(&wg->encrypt_queue, true); -- rcu_barrier(); /* Wait for all the peers to be actually freed. */ -- wg_ratelimiter_uninit(); -- memzero_explicit(&wg->static_identity, sizeof(wg->static_identity)); -- skb_queue_purge(&wg->incoming_handshakes); -- free_percpu(dev->tstats); -- free_percpu(wg->incoming_handshakes_worker); -- kvfree(wg->index_hashtable); -- kvfree(wg->peer_hashtable); -- mutex_unlock(&wg->device_update_lock); -- -- pr_debug("%s: Interface destroyed\n", dev->name); -- free_netdev(dev); --} -- --static const struct device_type device_type = { .name = KBUILD_MODNAME }; -- --static void wg_setup(struct net_device *dev) --{ -- struct wg_device *wg = netdev_priv(dev); -- enum { WG_NETDEV_FEATURES = NETIF_F_HW_CSUM | NETIF_F_RXCSUM | -- NETIF_F_SG | NETIF_F_GSO | -- NETIF_F_GSO_SOFTWARE | NETIF_F_HIGHDMA }; -- const int overhead = MESSAGE_MINIMUM_LENGTH + sizeof(struct udphdr) + -- max(sizeof(struct ipv6hdr), sizeof(struct iphdr)); -- -- dev->netdev_ops = &netdev_ops; -- dev->hard_header_len = 0; -- dev->addr_len = 0; -- dev->needed_headroom = DATA_PACKET_HEAD_ROOM; -- dev->needed_tailroom = noise_encrypted_len(MESSAGE_PADDING_MULTIPLE); -- dev->type = ARPHRD_NONE; -- dev->flags = IFF_POINTOPOINT | IFF_NOARP; -- dev->priv_flags |= IFF_NO_QUEUE; -- dev->features |= NETIF_F_LLTX; -- dev->features |= WG_NETDEV_FEATURES; -- dev->hw_features |= WG_NETDEV_FEATURES; -- dev->hw_enc_features |= WG_NETDEV_FEATURES; -- dev->mtu = ETH_DATA_LEN - overhead; -- dev->max_mtu = round_down(INT_MAX, MESSAGE_PADDING_MULTIPLE) - overhead; -- -- SET_NETDEV_DEVTYPE(dev, &device_type); -- -- /* We need to keep the dst around in case of icmp replies. */ -- netif_keep_dst(dev); -- -- memset(wg, 0, sizeof(*wg)); -- wg->dev = dev; --} -- --static int wg_newlink(struct net *src_net, struct net_device *dev, -- struct nlattr *tb[], struct nlattr *data[], -- struct netlink_ext_ack *extack) --{ -- struct wg_device *wg = netdev_priv(dev); -- int ret = -ENOMEM; -- -- rcu_assign_pointer(wg->creating_net, src_net); -- init_rwsem(&wg->static_identity.lock); -- mutex_init(&wg->socket_update_lock); -- mutex_init(&wg->device_update_lock); -- skb_queue_head_init(&wg->incoming_handshakes); -- wg_allowedips_init(&wg->peer_allowedips); -- wg_cookie_checker_init(&wg->cookie_checker, wg); -- INIT_LIST_HEAD(&wg->peer_list); -- wg->device_update_gen = 1; -- -- wg->peer_hashtable = wg_pubkey_hashtable_alloc(); -- if (!wg->peer_hashtable) -- return ret; -- -- wg->index_hashtable = wg_index_hashtable_alloc(); -- if (!wg->index_hashtable) -- goto err_free_peer_hashtable; -- -- dev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats); -- if (!dev->tstats) -- goto err_free_index_hashtable; -- -- wg->incoming_handshakes_worker = -- wg_packet_percpu_multicore_worker_alloc( -- wg_packet_handshake_receive_worker, wg); -- if (!wg->incoming_handshakes_worker) -- goto err_free_tstats; -- -- wg->handshake_receive_wq = alloc_workqueue("wg-kex-%s", -- WQ_CPU_INTENSIVE | WQ_FREEZABLE, 0, dev->name); -- if (!wg->handshake_receive_wq) -- goto err_free_incoming_handshakes; -- -- wg->handshake_send_wq = alloc_workqueue("wg-kex-%s", -- WQ_UNBOUND | WQ_FREEZABLE, 0, dev->name); -- if (!wg->handshake_send_wq) -- goto err_destroy_handshake_receive; -- -- wg->packet_crypt_wq = alloc_workqueue("wg-crypt-%s", -- WQ_CPU_INTENSIVE | WQ_MEM_RECLAIM, 0, dev->name); -- if (!wg->packet_crypt_wq) -- goto err_destroy_handshake_send; -- -- ret = wg_packet_queue_init(&wg->encrypt_queue, wg_packet_encrypt_worker, -- true, MAX_QUEUED_PACKETS); -- if (ret < 0) -- goto err_destroy_packet_crypt; -- -- ret = wg_packet_queue_init(&wg->decrypt_queue, wg_packet_decrypt_worker, -- true, MAX_QUEUED_PACKETS); -- if (ret < 0) -- goto err_free_encrypt_queue; -- -- ret = wg_ratelimiter_init(); -- if (ret < 0) -- goto err_free_decrypt_queue; -- -- ret = register_netdevice(dev); -- if (ret < 0) -- goto err_uninit_ratelimiter; -- -- list_add(&wg->device_list, &device_list); -- -- /* We wait until the end to assign priv_destructor, so that -- * register_netdevice doesn't call it for us if it fails. -- */ -- dev->priv_destructor = wg_destruct; -- -- pr_debug("%s: Interface created\n", dev->name); -- return ret; -- --err_uninit_ratelimiter: -- wg_ratelimiter_uninit(); --err_free_decrypt_queue: -- wg_packet_queue_free(&wg->decrypt_queue, true); --err_free_encrypt_queue: -- wg_packet_queue_free(&wg->encrypt_queue, true); --err_destroy_packet_crypt: -- destroy_workqueue(wg->packet_crypt_wq); --err_destroy_handshake_send: -- destroy_workqueue(wg->handshake_send_wq); --err_destroy_handshake_receive: -- destroy_workqueue(wg->handshake_receive_wq); --err_free_incoming_handshakes: -- free_percpu(wg->incoming_handshakes_worker); --err_free_tstats: -- free_percpu(dev->tstats); --err_free_index_hashtable: -- kvfree(wg->index_hashtable); --err_free_peer_hashtable: -- kvfree(wg->peer_hashtable); -- return ret; --} -- --static struct rtnl_link_ops link_ops __read_mostly = { -- .kind = KBUILD_MODNAME, -- .priv_size = sizeof(struct wg_device), -- .setup = wg_setup, -- .newlink = wg_newlink, --}; -- --static void wg_netns_exit(struct net *net) --{ -- struct wg_device *wg; -- -- rtnl_lock(); -- list_for_each_entry(wg, &device_list, device_list) { -- if (rcu_access_pointer(wg->creating_net) == net) { -- pr_debug("%s: Creating namespace exiting\n", wg->dev->name); -- netif_carrier_off(wg->dev); -- mutex_lock(&wg->device_update_lock); -- rcu_assign_pointer(wg->creating_net, NULL); -- wg_socket_reinit(wg, NULL, NULL); -- mutex_unlock(&wg->device_update_lock); -- } -- } -- rtnl_unlock(); --} -- --static struct pernet_operations pernet_ops = { -- .exit = wg_netns_exit --}; -- --int __init wg_device_init(void) --{ -- int ret; -- --#ifdef CONFIG_PM_SLEEP -- ret = register_pm_notifier(&pm_notifier); -- if (ret) -- return ret; --#endif -- -- ret = register_pernet_device(&pernet_ops); -- if (ret) -- goto error_pm; -- -- ret = rtnl_link_register(&link_ops); -- if (ret) -- goto error_pernet; -- -- return 0; -- --error_pernet: -- unregister_pernet_device(&pernet_ops); --error_pm: --#ifdef CONFIG_PM_SLEEP -- unregister_pm_notifier(&pm_notifier); --#endif -- return ret; --} -- --void wg_device_uninit(void) --{ -- rtnl_link_unregister(&link_ops); -- unregister_pernet_device(&pernet_ops); --#ifdef CONFIG_PM_SLEEP -- unregister_pm_notifier(&pm_notifier); --#endif -- rcu_barrier(); --} -diff --git a/drivers/net/wireguard/device.h b/drivers/net/wireguard/device.h -deleted file mode 100644 -index 4d0144e16..000000000 ---- a/drivers/net/wireguard/device.h -+++ /dev/null -@@ -1,64 +0,0 @@ --/* SPDX-License-Identifier: GPL-2.0 */ --/* -- * Copyright (C) 2015-2019 Jason A. Donenfeld . All Rights Reserved. -- */ -- --#ifndef _WG_DEVICE_H --#define _WG_DEVICE_H -- --#include "noise.h" --#include "allowedips.h" --#include "peerlookup.h" --#include "cookie.h" -- --#include --#include --#include --#include --#include --#include -- --struct wg_device; -- --struct multicore_worker { -- void *ptr; -- struct work_struct work; --}; -- --struct crypt_queue { -- struct ptr_ring ring; -- union { -- struct { -- struct multicore_worker __percpu *worker; -- int last_cpu; -- }; -- struct work_struct work; -- }; --}; -- --struct wg_device { -- struct net_device *dev; -- struct crypt_queue encrypt_queue, decrypt_queue; -- struct sock __rcu *sock4, *sock6; -- struct net __rcu *creating_net; -- struct noise_static_identity static_identity; -- struct workqueue_struct *handshake_receive_wq, *handshake_send_wq; -- struct workqueue_struct *packet_crypt_wq; -- struct sk_buff_head incoming_handshakes; -- int incoming_handshake_cpu; -- struct multicore_worker __percpu *incoming_handshakes_worker; -- struct cookie_checker cookie_checker; -- struct pubkey_hashtable *peer_hashtable; -- struct index_hashtable *index_hashtable; -- struct allowedips peer_allowedips; -- struct mutex device_update_lock, socket_update_lock; -- struct list_head device_list, peer_list; -- unsigned int num_peers, device_update_gen; -- u32 fwmark; -- u16 incoming_port; --}; -- --int wg_device_init(void); --void wg_device_uninit(void); -- --#endif /* _WG_DEVICE_H */ -diff --git a/drivers/net/wireguard/main.c b/drivers/net/wireguard/main.c -deleted file mode 100644 -index 7a7d5f1a8..000000000 ---- a/drivers/net/wireguard/main.c -+++ /dev/null -@@ -1,63 +0,0 @@ --// SPDX-License-Identifier: GPL-2.0 --/* -- * Copyright (C) 2015-2019 Jason A. Donenfeld . All Rights Reserved. -- */ -- --#include "version.h" --#include "device.h" --#include "noise.h" --#include "queueing.h" --#include "ratelimiter.h" --#include "netlink.h" -- --#include -- --#include --#include --#include --#include -- --static int __init mod_init(void) --{ -- int ret; -- --#ifdef DEBUG -- if (!wg_allowedips_selftest() || !wg_packet_counter_selftest() || -- !wg_ratelimiter_selftest()) -- return -ENOTRECOVERABLE; --#endif -- wg_noise_init(); -- -- ret = wg_device_init(); -- if (ret < 0) -- goto err_device; -- -- ret = wg_genetlink_init(); -- if (ret < 0) -- goto err_netlink; -- -- pr_info("WireGuard " WIREGUARD_VERSION " loaded. See www.wireguard.com for information.\n"); -- pr_info("Copyright (C) 2015-2019 Jason A. Donenfeld . All Rights Reserved.\n"); -- -- return 0; -- --err_netlink: -- wg_device_uninit(); --err_device: -- return ret; --} -- --static void __exit mod_exit(void) --{ -- wg_genetlink_uninit(); -- wg_device_uninit(); --} -- --module_init(mod_init); --module_exit(mod_exit); --MODULE_LICENSE("GPL v2"); --MODULE_DESCRIPTION("WireGuard secure network tunnel"); --MODULE_AUTHOR("Jason A. Donenfeld "); --MODULE_VERSION(WIREGUARD_VERSION); --MODULE_ALIAS_RTNL_LINK(KBUILD_MODNAME); --MODULE_ALIAS_GENL_FAMILY(WG_GENL_NAME); -diff --git a/drivers/net/wireguard/messages.h b/drivers/net/wireguard/messages.h -deleted file mode 100644 -index 208da7267..000000000 ---- a/drivers/net/wireguard/messages.h -+++ /dev/null -@@ -1,128 +0,0 @@ --/* SPDX-License-Identifier: GPL-2.0 */ --/* -- * Copyright (C) 2015-2019 Jason A. Donenfeld . All Rights Reserved. -- */ -- --#ifndef _WG_MESSAGES_H --#define _WG_MESSAGES_H -- --#include --#include --#include -- --#include --#include --#include -- --enum noise_lengths { -- NOISE_PUBLIC_KEY_LEN = CURVE25519_KEY_SIZE, -- NOISE_SYMMETRIC_KEY_LEN = CHACHA20POLY1305_KEY_SIZE, -- NOISE_TIMESTAMP_LEN = sizeof(u64) + sizeof(u32), -- NOISE_AUTHTAG_LEN = CHACHA20POLY1305_AUTHTAG_SIZE, -- NOISE_HASH_LEN = BLAKE2S_HASH_SIZE --}; -- --#define noise_encrypted_len(plain_len) ((plain_len) + NOISE_AUTHTAG_LEN) -- --enum cookie_values { -- COOKIE_SECRET_MAX_AGE = 2 * 60, -- COOKIE_SECRET_LATENCY = 5, -- COOKIE_NONCE_LEN = XCHACHA20POLY1305_NONCE_SIZE, -- COOKIE_LEN = 16 --}; -- --enum counter_values { -- COUNTER_BITS_TOTAL = 8192, -- COUNTER_REDUNDANT_BITS = BITS_PER_LONG, -- COUNTER_WINDOW_SIZE = COUNTER_BITS_TOTAL - COUNTER_REDUNDANT_BITS --}; -- --enum limits { -- REKEY_AFTER_MESSAGES = 1ULL << 60, -- REJECT_AFTER_MESSAGES = U64_MAX - COUNTER_WINDOW_SIZE - 1, -- REKEY_TIMEOUT = 5, -- REKEY_TIMEOUT_JITTER_MAX_JIFFIES = HZ / 3, -- REKEY_AFTER_TIME = 120, -- REJECT_AFTER_TIME = 180, -- INITIATIONS_PER_SECOND = 50, -- MAX_PEERS_PER_DEVICE = 1U << 20, -- KEEPALIVE_TIMEOUT = 10, -- MAX_TIMER_HANDSHAKES = 90 / REKEY_TIMEOUT, -- MAX_QUEUED_INCOMING_HANDSHAKES = 4096, /* TODO: replace this with DQL */ -- MAX_STAGED_PACKETS = 128, -- MAX_QUEUED_PACKETS = 1024 /* TODO: replace this with DQL */ --}; -- --enum message_type { -- MESSAGE_INVALID = 0, -- MESSAGE_HANDSHAKE_INITIATION = 1, -- MESSAGE_HANDSHAKE_RESPONSE = 2, -- MESSAGE_HANDSHAKE_COOKIE = 3, -- MESSAGE_DATA = 4 --}; -- --struct message_header { -- /* The actual layout of this that we want is: -- * u8 type -- * u8 reserved_zero[3] -- * -- * But it turns out that by encoding this as little endian, -- * we achieve the same thing, and it makes checking faster. -- */ -- __le32 type; --}; -- --struct message_macs { -- u8 mac1[COOKIE_LEN]; -- u8 mac2[COOKIE_LEN]; --}; -- --struct message_handshake_initiation { -- struct message_header header; -- __le32 sender_index; -- u8 unencrypted_ephemeral[NOISE_PUBLIC_KEY_LEN]; -- u8 encrypted_static[noise_encrypted_len(NOISE_PUBLIC_KEY_LEN)]; -- u8 encrypted_timestamp[noise_encrypted_len(NOISE_TIMESTAMP_LEN)]; -- struct message_macs macs; --}; -- --struct message_handshake_response { -- struct message_header header; -- __le32 sender_index; -- __le32 receiver_index; -- u8 unencrypted_ephemeral[NOISE_PUBLIC_KEY_LEN]; -- u8 encrypted_nothing[noise_encrypted_len(0)]; -- struct message_macs macs; --}; -- --struct message_handshake_cookie { -- struct message_header header; -- __le32 receiver_index; -- u8 nonce[COOKIE_NONCE_LEN]; -- u8 encrypted_cookie[noise_encrypted_len(COOKIE_LEN)]; --}; -- --struct message_data { -- struct message_header header; -- __le32 key_idx; -- __le64 counter; -- u8 encrypted_data[]; --}; -- --#define message_data_len(plain_len) \ -- (noise_encrypted_len(plain_len) + sizeof(struct message_data)) -- --enum message_alignments { -- MESSAGE_PADDING_MULTIPLE = 16, -- MESSAGE_MINIMUM_LENGTH = message_data_len(0) --}; -- --#define SKB_HEADER_LEN \ -- (max(sizeof(struct iphdr), sizeof(struct ipv6hdr)) + \ -- sizeof(struct udphdr) + NET_SKB_PAD) --#define DATA_PACKET_HEAD_ROOM \ -- ALIGN(sizeof(struct message_data) + SKB_HEADER_LEN, 4) -- --enum { HANDSHAKE_DSCP = 0x88 /* AF41, plus 00 ECN */ }; -- --#endif /* _WG_MESSAGES_H */ -diff --git a/drivers/net/wireguard/netlink.c b/drivers/net/wireguard/netlink.c -deleted file mode 100644 -index a4377add6..000000000 ---- a/drivers/net/wireguard/netlink.c -+++ /dev/null -@@ -1,651 +0,0 @@ --// SPDX-License-Identifier: GPL-2.0 --/* -- * Copyright (C) 2015-2019 Jason A. Donenfeld . All Rights Reserved. -- */ -- --#include "netlink.h" --#include "device.h" --#include "peer.h" --#include "socket.h" --#include "queueing.h" --#include "messages.h" -- --#include -- --#include --#include --#include --#include -- --struct __uapi_kernel_timespec { -- int64_t tv_sec, tv_nsec; --}; -- --static struct genl_family genl_family; -- --static const struct nla_policy device_policy[WGDEVICE_A_MAX + 1] = { -- [WGDEVICE_A_IFINDEX] = { .type = NLA_U32 }, -- [WGDEVICE_A_IFNAME] = { .type = NLA_NUL_STRING, .len = IFNAMSIZ - 1 }, -- [WGDEVICE_A_PRIVATE_KEY] = { .len = NOISE_PUBLIC_KEY_LEN }, -- [WGDEVICE_A_PUBLIC_KEY] = { .len = NOISE_PUBLIC_KEY_LEN }, -- [WGDEVICE_A_FLAGS] = { .type = NLA_U32 }, -- [WGDEVICE_A_LISTEN_PORT] = { .type = NLA_U16 }, -- [WGDEVICE_A_FWMARK] = { .type = NLA_U32 }, -- [WGDEVICE_A_PEERS] = { .type = NLA_NESTED } --}; -- --static const struct nla_policy peer_policy[WGPEER_A_MAX + 1] = { -- [WGPEER_A_PUBLIC_KEY] = { .len = NOISE_PUBLIC_KEY_LEN }, -- [WGPEER_A_PRESHARED_KEY] = { .len = NOISE_SYMMETRIC_KEY_LEN }, -- [WGPEER_A_FLAGS] = { .type = NLA_U32 }, -- [WGPEER_A_ENDPOINT] = { .len = sizeof(struct sockaddr) }, -- [WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL] = { .type = NLA_U16 }, -- [WGPEER_A_LAST_HANDSHAKE_TIME] = { .len = sizeof(struct __uapi_kernel_timespec) }, -- [WGPEER_A_RX_BYTES] = { .type = NLA_U64 }, -- [WGPEER_A_TX_BYTES] = { .type = NLA_U64 }, -- [WGPEER_A_ALLOWEDIPS] = { .type = NLA_NESTED }, -- [WGPEER_A_PROTOCOL_VERSION] = { .type = NLA_U32 } --}; -- --static const struct nla_policy allowedip_policy[WGALLOWEDIP_A_MAX + 1] = { -- [WGALLOWEDIP_A_FAMILY] = { .type = NLA_U16 }, -- [WGALLOWEDIP_A_IPADDR] = { .len = sizeof(struct in_addr) }, -- [WGALLOWEDIP_A_CIDR_MASK] = { .type = NLA_U8 } --}; -- --static struct wg_device *lookup_interface(struct nlattr **attrs, -- struct sk_buff *skb) --{ -- struct net_device *dev = NULL; -- -- if (!attrs[WGDEVICE_A_IFINDEX] == !attrs[WGDEVICE_A_IFNAME]) -- return ERR_PTR(-EBADR); -- if (attrs[WGDEVICE_A_IFINDEX]) -- dev = dev_get_by_index(sock_net(skb->sk), -- nla_get_u32(attrs[WGDEVICE_A_IFINDEX])); -- else if (attrs[WGDEVICE_A_IFNAME]) -- dev = dev_get_by_name(sock_net(skb->sk), -- nla_data(attrs[WGDEVICE_A_IFNAME])); -- if (!dev) -- return ERR_PTR(-ENODEV); -- if (!dev->rtnl_link_ops || !dev->rtnl_link_ops->kind || -- strcmp(dev->rtnl_link_ops->kind, KBUILD_MODNAME)) { -- dev_put(dev); -- return ERR_PTR(-EOPNOTSUPP); -- } -- return netdev_priv(dev); --} -- --static int get_allowedips(struct sk_buff *skb, const u8 *ip, u8 cidr, -- int family) --{ -- struct nlattr *allowedip_nest; -- -- allowedip_nest = nla_nest_start(skb, 0); -- if (!allowedip_nest) -- return -EMSGSIZE; -- -- if (nla_put_u8(skb, WGALLOWEDIP_A_CIDR_MASK, cidr) || -- nla_put_u16(skb, WGALLOWEDIP_A_FAMILY, family) || -- nla_put(skb, WGALLOWEDIP_A_IPADDR, family == AF_INET6 ? -- sizeof(struct in6_addr) : sizeof(struct in_addr), ip)) { -- nla_nest_cancel(skb, allowedip_nest); -- return -EMSGSIZE; -- } -- -- nla_nest_end(skb, allowedip_nest); -- return 0; --} -- --struct dump_ctx { -- struct wg_device *wg; -- struct wg_peer *next_peer; -- u64 allowedips_seq; -- struct allowedips_node *next_allowedip; --}; -- --#define DUMP_CTX(cb) ((struct dump_ctx *)(cb)->args) -- --static int --get_peer(struct wg_peer *peer, struct sk_buff *skb, struct dump_ctx *ctx) --{ -- -- struct nlattr *allowedips_nest, *peer_nest = nla_nest_start(skb, 0); -- struct allowedips_node *allowedips_node = ctx->next_allowedip; -- bool fail; -- -- if (!peer_nest) -- return -EMSGSIZE; -- -- down_read(&peer->handshake.lock); -- fail = nla_put(skb, WGPEER_A_PUBLIC_KEY, NOISE_PUBLIC_KEY_LEN, -- peer->handshake.remote_static); -- up_read(&peer->handshake.lock); -- if (fail) -- goto err; -- -- if (!allowedips_node) { -- const struct __uapi_kernel_timespec last_handshake = { -- .tv_sec = peer->walltime_last_handshake.tv_sec, -- .tv_nsec = peer->walltime_last_handshake.tv_nsec -- }; -- -- down_read(&peer->handshake.lock); -- fail = nla_put(skb, WGPEER_A_PRESHARED_KEY, -- NOISE_SYMMETRIC_KEY_LEN, -- peer->handshake.preshared_key); -- up_read(&peer->handshake.lock); -- if (fail) -- goto err; -- -- if (nla_put(skb, WGPEER_A_LAST_HANDSHAKE_TIME, -- sizeof(last_handshake), &last_handshake) || -- nla_put_u16(skb, WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL, -- peer->persistent_keepalive_interval) || -- nla_put_u64_64bit(skb, WGPEER_A_TX_BYTES, peer->tx_bytes, -- WGPEER_A_UNSPEC) || -- nla_put_u64_64bit(skb, WGPEER_A_RX_BYTES, peer->rx_bytes, -- WGPEER_A_UNSPEC) || -- nla_put_u32(skb, WGPEER_A_PROTOCOL_VERSION, 1)) -- goto err; -- -- read_lock_bh(&peer->endpoint_lock); -- if (peer->endpoint.addr.sa_family == AF_INET) -- fail = nla_put(skb, WGPEER_A_ENDPOINT, -- sizeof(peer->endpoint.addr4), -- &peer->endpoint.addr4); -- else if (peer->endpoint.addr.sa_family == AF_INET6) -- fail = nla_put(skb, WGPEER_A_ENDPOINT, -- sizeof(peer->endpoint.addr6), -- &peer->endpoint.addr6); -- read_unlock_bh(&peer->endpoint_lock); -- if (fail) -- goto err; -- allowedips_node = -- list_first_entry_or_null(&peer->allowedips_list, -- struct allowedips_node, peer_list); -- } -- if (!allowedips_node) -- goto no_allowedips; -- if (!ctx->allowedips_seq) -- ctx->allowedips_seq = peer->device->peer_allowedips.seq; -- else if (ctx->allowedips_seq != peer->device->peer_allowedips.seq) -- goto no_allowedips; -- -- allowedips_nest = nla_nest_start(skb, WGPEER_A_ALLOWEDIPS); -- if (!allowedips_nest) -- goto err; -- -- list_for_each_entry_from(allowedips_node, &peer->allowedips_list, -- peer_list) { -- u8 cidr, ip[16] __aligned(__alignof(u64)); -- int family; -- -- family = wg_allowedips_read_node(allowedips_node, ip, &cidr); -- if (get_allowedips(skb, ip, cidr, family)) { -- nla_nest_end(skb, allowedips_nest); -- nla_nest_end(skb, peer_nest); -- ctx->next_allowedip = allowedips_node; -- return -EMSGSIZE; -- } -- } -- nla_nest_end(skb, allowedips_nest); --no_allowedips: -- nla_nest_end(skb, peer_nest); -- ctx->next_allowedip = NULL; -- ctx->allowedips_seq = 0; -- return 0; --err: -- nla_nest_cancel(skb, peer_nest); -- return -EMSGSIZE; --} -- --static int wg_get_device_start(struct netlink_callback *cb) --{ -- struct nlattr **attrs = genl_family_attrbuf(&genl_family); -- struct wg_device *wg; -- int ret; -- -- ret = nlmsg_parse(cb->nlh, GENL_HDRLEN + genl_family.hdrsize, attrs, -- genl_family.maxattr, device_policy, NULL); -- if (ret < 0) -- return ret; -- wg = lookup_interface(attrs, cb->skb); -- if (IS_ERR(wg)) -- return PTR_ERR(wg); -- DUMP_CTX(cb)->wg = wg; -- return 0; --} -- --static int wg_get_device_dump(struct sk_buff *skb, struct netlink_callback *cb) --{ -- struct wg_peer *peer, *next_peer_cursor; -- struct dump_ctx *ctx = DUMP_CTX(cb); -- struct wg_device *wg = ctx->wg; -- struct nlattr *peers_nest; -- int ret = -EMSGSIZE; -- bool done = true; -- void *hdr; -- -- rtnl_lock(); -- mutex_lock(&wg->device_update_lock); -- cb->seq = wg->device_update_gen; -- next_peer_cursor = ctx->next_peer; -- -- hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq, -- &genl_family, NLM_F_MULTI, WG_CMD_GET_DEVICE); -- if (!hdr) -- goto out; -- genl_dump_check_consistent(cb, hdr); -- -- if (!ctx->next_peer) { -- if (nla_put_u16(skb, WGDEVICE_A_LISTEN_PORT, -- wg->incoming_port) || -- nla_put_u32(skb, WGDEVICE_A_FWMARK, wg->fwmark) || -- nla_put_u32(skb, WGDEVICE_A_IFINDEX, wg->dev->ifindex) || -- nla_put_string(skb, WGDEVICE_A_IFNAME, wg->dev->name)) -- goto out; -- -- down_read(&wg->static_identity.lock); -- if (wg->static_identity.has_identity) { -- if (nla_put(skb, WGDEVICE_A_PRIVATE_KEY, -- NOISE_PUBLIC_KEY_LEN, -- wg->static_identity.static_private) || -- nla_put(skb, WGDEVICE_A_PUBLIC_KEY, -- NOISE_PUBLIC_KEY_LEN, -- wg->static_identity.static_public)) { -- up_read(&wg->static_identity.lock); -- goto out; -- } -- } -- up_read(&wg->static_identity.lock); -- } -- -- peers_nest = nla_nest_start(skb, WGDEVICE_A_PEERS); -- if (!peers_nest) -- goto out; -- ret = 0; -- /* If the last cursor was removed via list_del_init in peer_remove, then -- * we just treat this the same as there being no more peers left. The -- * reason is that seq_nr should indicate to userspace that this isn't a -- * coherent dump anyway, so they'll try again. -- */ -- if (list_empty(&wg->peer_list) || -- (ctx->next_peer && list_empty(&ctx->next_peer->peer_list))) { -- nla_nest_cancel(skb, peers_nest); -- goto out; -- } -- lockdep_assert_held(&wg->device_update_lock); -- peer = list_prepare_entry(ctx->next_peer, &wg->peer_list, peer_list); -- list_for_each_entry_continue(peer, &wg->peer_list, peer_list) { -- if (get_peer(peer, skb, ctx)) { -- done = false; -- break; -- } -- next_peer_cursor = peer; -- } -- nla_nest_end(skb, peers_nest); -- --out: -- if (!ret && !done && next_peer_cursor) -- wg_peer_get(next_peer_cursor); -- wg_peer_put(ctx->next_peer); -- mutex_unlock(&wg->device_update_lock); -- rtnl_unlock(); -- -- if (ret) { -- genlmsg_cancel(skb, hdr); -- return ret; -- } -- genlmsg_end(skb, hdr); -- if (done) { -- ctx->next_peer = NULL; -- return 0; -- } -- ctx->next_peer = next_peer_cursor; -- return skb->len; -- -- /* At this point, we can't really deal ourselves with safely zeroing out -- * the private key material after usage. This will need an additional API -- * in the kernel for marking skbs as zero_on_free. -- */ --} -- --static int wg_get_device_done(struct netlink_callback *cb) --{ -- struct dump_ctx *ctx = DUMP_CTX(cb); -- -- if (ctx->wg) -- dev_put(ctx->wg->dev); -- wg_peer_put(ctx->next_peer); -- return 0; --} -- --static int set_port(struct wg_device *wg, u16 port) --{ -- struct wg_peer *peer; -- -- if (wg->incoming_port == port) -- return 0; -- list_for_each_entry(peer, &wg->peer_list, peer_list) -- wg_socket_clear_peer_endpoint_src(peer); -- if (!netif_running(wg->dev)) { -- wg->incoming_port = port; -- return 0; -- } -- return wg_socket_init(wg, port); --} -- --static int set_allowedip(struct wg_peer *peer, struct nlattr **attrs) --{ -- int ret = -EINVAL; -- u16 family; -- u8 cidr; -- -- if (!attrs[WGALLOWEDIP_A_FAMILY] || !attrs[WGALLOWEDIP_A_IPADDR] || -- !attrs[WGALLOWEDIP_A_CIDR_MASK]) -- return ret; -- family = nla_get_u16(attrs[WGALLOWEDIP_A_FAMILY]); -- cidr = nla_get_u8(attrs[WGALLOWEDIP_A_CIDR_MASK]); -- -- if (family == AF_INET && cidr <= 32 && -- nla_len(attrs[WGALLOWEDIP_A_IPADDR]) == sizeof(struct in_addr)) -- ret = wg_allowedips_insert_v4( -- &peer->device->peer_allowedips, -- nla_data(attrs[WGALLOWEDIP_A_IPADDR]), cidr, peer, -- &peer->device->device_update_lock); -- else if (family == AF_INET6 && cidr <= 128 && -- nla_len(attrs[WGALLOWEDIP_A_IPADDR]) == sizeof(struct in6_addr)) -- ret = wg_allowedips_insert_v6( -- &peer->device->peer_allowedips, -- nla_data(attrs[WGALLOWEDIP_A_IPADDR]), cidr, peer, -- &peer->device->device_update_lock); -- -- return ret; --} -- --static int set_peer(struct wg_device *wg, struct nlattr **attrs) --{ -- u8 *public_key = NULL, *preshared_key = NULL; -- struct wg_peer *peer = NULL; -- u32 flags = 0; -- int ret; -- -- ret = -EINVAL; -- if (attrs[WGPEER_A_PUBLIC_KEY] && -- nla_len(attrs[WGPEER_A_PUBLIC_KEY]) == NOISE_PUBLIC_KEY_LEN) -- public_key = nla_data(attrs[WGPEER_A_PUBLIC_KEY]); -- else -- goto out; -- if (attrs[WGPEER_A_PRESHARED_KEY] && -- nla_len(attrs[WGPEER_A_PRESHARED_KEY]) == NOISE_SYMMETRIC_KEY_LEN) -- preshared_key = nla_data(attrs[WGPEER_A_PRESHARED_KEY]); -- -- if (attrs[WGPEER_A_FLAGS]) -- flags = nla_get_u32(attrs[WGPEER_A_FLAGS]); -- ret = -EOPNOTSUPP; -- if (flags & ~__WGPEER_F_ALL) -- goto out; -- -- ret = -EPFNOSUPPORT; -- if (attrs[WGPEER_A_PROTOCOL_VERSION]) { -- if (nla_get_u32(attrs[WGPEER_A_PROTOCOL_VERSION]) != 1) -- goto out; -- } -- -- peer = wg_pubkey_hashtable_lookup(wg->peer_hashtable, -- nla_data(attrs[WGPEER_A_PUBLIC_KEY])); -- ret = 0; -- if (!peer) { /* Peer doesn't exist yet. Add a new one. */ -- if (flags & (WGPEER_F_REMOVE_ME | WGPEER_F_UPDATE_ONLY)) -- goto out; -- -- /* The peer is new, so there aren't allowed IPs to remove. */ -- flags &= ~WGPEER_F_REPLACE_ALLOWEDIPS; -- -- down_read(&wg->static_identity.lock); -- if (wg->static_identity.has_identity && -- !memcmp(nla_data(attrs[WGPEER_A_PUBLIC_KEY]), -- wg->static_identity.static_public, -- NOISE_PUBLIC_KEY_LEN)) { -- /* We silently ignore peers that have the same public -- * key as the device. The reason we do it silently is -- * that we'd like for people to be able to reuse the -- * same set of API calls across peers. -- */ -- up_read(&wg->static_identity.lock); -- ret = 0; -- goto out; -- } -- up_read(&wg->static_identity.lock); -- -- peer = wg_peer_create(wg, public_key, preshared_key); -- if (IS_ERR(peer)) { -- ret = PTR_ERR(peer); -- peer = NULL; -- goto out; -- } -- /* Take additional reference, as though we've just been -- * looked up. -- */ -- wg_peer_get(peer); -- } -- -- if (flags & WGPEER_F_REMOVE_ME) { -- wg_peer_remove(peer); -- goto out; -- } -- -- if (preshared_key) { -- down_write(&peer->handshake.lock); -- memcpy(&peer->handshake.preshared_key, preshared_key, -- NOISE_SYMMETRIC_KEY_LEN); -- up_write(&peer->handshake.lock); -- } -- -- if (attrs[WGPEER_A_ENDPOINT]) { -- struct sockaddr *addr = nla_data(attrs[WGPEER_A_ENDPOINT]); -- size_t len = nla_len(attrs[WGPEER_A_ENDPOINT]); -- -- if ((len == sizeof(struct sockaddr_in) && -- addr->sa_family == AF_INET) || -- (len == sizeof(struct sockaddr_in6) && -- addr->sa_family == AF_INET6)) { -- struct endpoint endpoint = { { { 0 } } }; -- -- memcpy(&endpoint.addr, addr, len); -- wg_socket_set_peer_endpoint(peer, &endpoint); -- } -- } -- -- if (flags & WGPEER_F_REPLACE_ALLOWEDIPS) -- wg_allowedips_remove_by_peer(&wg->peer_allowedips, peer, -- &wg->device_update_lock); -- -- if (attrs[WGPEER_A_ALLOWEDIPS]) { -- struct nlattr *attr, *allowedip[WGALLOWEDIP_A_MAX + 1]; -- int rem; -- -- nla_for_each_nested(attr, attrs[WGPEER_A_ALLOWEDIPS], rem) { -- ret = nla_parse_nested(allowedip, WGALLOWEDIP_A_MAX, -- attr, allowedip_policy, NULL); -- if (ret < 0) -- goto out; -- ret = set_allowedip(peer, allowedip); -- if (ret < 0) -- goto out; -- } -- } -- -- if (attrs[WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL]) { -- const u16 persistent_keepalive_interval = nla_get_u16( -- attrs[WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL]); -- const bool send_keepalive = -- !peer->persistent_keepalive_interval && -- persistent_keepalive_interval && -- netif_running(wg->dev); -- -- peer->persistent_keepalive_interval = persistent_keepalive_interval; -- if (send_keepalive) -- wg_packet_send_keepalive(peer); -- } -- -- if (netif_running(wg->dev)) -- wg_packet_send_staged_packets(peer); -- --out: -- wg_peer_put(peer); -- if (attrs[WGPEER_A_PRESHARED_KEY]) -- memzero_explicit(nla_data(attrs[WGPEER_A_PRESHARED_KEY]), -- nla_len(attrs[WGPEER_A_PRESHARED_KEY])); -- return ret; --} -- --static int wg_set_device(struct sk_buff *skb, struct genl_info *info) --{ -- struct wg_device *wg = lookup_interface(info->attrs, skb); -- u32 flags = 0; -- int ret; -- -- if (IS_ERR(wg)) { -- ret = PTR_ERR(wg); -- goto out_nodev; -- } -- -- rtnl_lock(); -- mutex_lock(&wg->device_update_lock); -- -- if (info->attrs[WGDEVICE_A_FLAGS]) -- flags = nla_get_u32(info->attrs[WGDEVICE_A_FLAGS]); -- ret = -EOPNOTSUPP; -- if (flags & ~__WGDEVICE_F_ALL) -- goto out; -- -- if (info->attrs[WGDEVICE_A_LISTEN_PORT] || info->attrs[WGDEVICE_A_FWMARK]) { -- struct net *net; -- rcu_read_lock(); -- net = rcu_dereference(wg->creating_net); -- ret = !net || !ns_capable(net->user_ns, CAP_NET_ADMIN) ? -EPERM : 0; -- rcu_read_unlock(); -- if (ret) -- goto out; -- } -- -- ++wg->device_update_gen; -- -- if (info->attrs[WGDEVICE_A_FWMARK]) { -- struct wg_peer *peer; -- -- wg->fwmark = nla_get_u32(info->attrs[WGDEVICE_A_FWMARK]); -- list_for_each_entry(peer, &wg->peer_list, peer_list) -- wg_socket_clear_peer_endpoint_src(peer); -- } -- -- if (info->attrs[WGDEVICE_A_LISTEN_PORT]) { -- ret = set_port(wg, -- nla_get_u16(info->attrs[WGDEVICE_A_LISTEN_PORT])); -- if (ret) -- goto out; -- } -- -- if (flags & WGDEVICE_F_REPLACE_PEERS) -- wg_peer_remove_all(wg); -- -- if (info->attrs[WGDEVICE_A_PRIVATE_KEY] && -- nla_len(info->attrs[WGDEVICE_A_PRIVATE_KEY]) == -- NOISE_PUBLIC_KEY_LEN) { -- u8 *private_key = nla_data(info->attrs[WGDEVICE_A_PRIVATE_KEY]); -- u8 public_key[NOISE_PUBLIC_KEY_LEN]; -- struct wg_peer *peer, *temp; -- -- if (!crypto_memneq(wg->static_identity.static_private, -- private_key, NOISE_PUBLIC_KEY_LEN)) -- goto skip_set_private_key; -- -- /* We remove before setting, to prevent race, which means doing -- * two 25519-genpub ops. -- */ -- if (curve25519_generate_public(public_key, private_key)) { -- peer = wg_pubkey_hashtable_lookup(wg->peer_hashtable, -- public_key); -- if (peer) { -- wg_peer_put(peer); -- wg_peer_remove(peer); -- } -- } -- -- down_write(&wg->static_identity.lock); -- wg_noise_set_static_identity_private_key(&wg->static_identity, -- private_key); -- list_for_each_entry_safe(peer, temp, &wg->peer_list, -- peer_list) { -- wg_noise_precompute_static_static(peer); -- wg_noise_expire_current_peer_keypairs(peer); -- } -- wg_cookie_checker_precompute_device_keys(&wg->cookie_checker); -- up_write(&wg->static_identity.lock); -- } --skip_set_private_key: -- -- if (info->attrs[WGDEVICE_A_PEERS]) { -- struct nlattr *attr, *peer[WGPEER_A_MAX + 1]; -- int rem; -- -- nla_for_each_nested(attr, info->attrs[WGDEVICE_A_PEERS], rem) { -- ret = nla_parse_nested(peer, WGPEER_A_MAX, attr, -- peer_policy, NULL); -- if (ret < 0) -- goto out; -- ret = set_peer(wg, peer); -- if (ret < 0) -- goto out; -- } -- } -- ret = 0; -- --out: -- mutex_unlock(&wg->device_update_lock); -- rtnl_unlock(); -- dev_put(wg->dev); --out_nodev: -- if (info->attrs[WGDEVICE_A_PRIVATE_KEY]) -- memzero_explicit(nla_data(info->attrs[WGDEVICE_A_PRIVATE_KEY]), -- nla_len(info->attrs[WGDEVICE_A_PRIVATE_KEY])); -- return ret; --} -- --static const struct genl_ops genl_ops[] = { -- { -- .cmd = WG_CMD_GET_DEVICE, -- .start = wg_get_device_start, -- .dumpit = wg_get_device_dump, -- .done = wg_get_device_done, -- .flags = GENL_UNS_ADMIN_PERM, -- .policy = device_policy -- }, { -- .cmd = WG_CMD_SET_DEVICE, -- .doit = wg_set_device, -- .flags = GENL_UNS_ADMIN_PERM, -- .policy = device_policy -- } --}; -- --static struct genl_family genl_family __ro_after_init = { -- .ops = genl_ops, -- .n_ops = ARRAY_SIZE(genl_ops), -- .name = WG_GENL_NAME, -- .version = WG_GENL_VERSION, -- .maxattr = WGDEVICE_A_MAX, -- .module = THIS_MODULE, -- .netnsok = true --}; -- --int __init wg_genetlink_init(void) --{ -- return genl_register_family(&genl_family); --} -- --void __exit wg_genetlink_uninit(void) --{ -- genl_unregister_family(&genl_family); --} -diff --git a/drivers/net/wireguard/netlink.h b/drivers/net/wireguard/netlink.h -deleted file mode 100644 -index 15100d92e..000000000 ---- a/drivers/net/wireguard/netlink.h -+++ /dev/null -@@ -1,12 +0,0 @@ --/* SPDX-License-Identifier: GPL-2.0 */ --/* -- * Copyright (C) 2015-2019 Jason A. Donenfeld . All Rights Reserved. -- */ -- --#ifndef _WG_NETLINK_H --#define _WG_NETLINK_H -- --int wg_genetlink_init(void); --void wg_genetlink_uninit(void); -- --#endif /* _WG_NETLINK_H */ -diff --git a/drivers/net/wireguard/noise.c b/drivers/net/wireguard/noise.c -deleted file mode 100644 -index 27cb5045b..000000000 ---- a/drivers/net/wireguard/noise.c -+++ /dev/null -@@ -1,828 +0,0 @@ --// SPDX-License-Identifier: GPL-2.0 --/* -- * Copyright (C) 2015-2019 Jason A. Donenfeld . All Rights Reserved. -- */ -- --#include "noise.h" --#include "device.h" --#include "peer.h" --#include "messages.h" --#include "queueing.h" --#include "peerlookup.h" -- --#include --#include --#include --#include --#include --#include -- --/* This implements Noise_IKpsk2: -- * -- * <- s -- * ****** -- * -> e, es, s, ss, {t} -- * <- e, ee, se, psk, {} -- */ -- --static const u8 handshake_name[37] = "Noise_IKpsk2_25519_ChaChaPoly_BLAKE2s"; --static const u8 identifier_name[34] = "WireGuard v1 zx2c4 Jason@zx2c4.com"; --static u8 handshake_init_hash[NOISE_HASH_LEN] __ro_after_init; --static u8 handshake_init_chaining_key[NOISE_HASH_LEN] __ro_after_init; --static atomic64_t keypair_counter = ATOMIC64_INIT(0); -- --void __init wg_noise_init(void) --{ -- struct blake2s_state blake; -- -- blake2s(handshake_init_chaining_key, handshake_name, NULL, -- NOISE_HASH_LEN, sizeof(handshake_name), 0); -- blake2s_init(&blake, NOISE_HASH_LEN); -- blake2s_update(&blake, handshake_init_chaining_key, NOISE_HASH_LEN); -- blake2s_update(&blake, identifier_name, sizeof(identifier_name)); -- blake2s_final(&blake, handshake_init_hash); --} -- --/* Must hold peer->handshake.static_identity->lock */ --void wg_noise_precompute_static_static(struct wg_peer *peer) --{ -- down_write(&peer->handshake.lock); -- if (!peer->handshake.static_identity->has_identity || -- !curve25519(peer->handshake.precomputed_static_static, -- peer->handshake.static_identity->static_private, -- peer->handshake.remote_static)) -- memset(peer->handshake.precomputed_static_static, 0, -- NOISE_PUBLIC_KEY_LEN); -- up_write(&peer->handshake.lock); --} -- --void wg_noise_handshake_init(struct noise_handshake *handshake, -- struct noise_static_identity *static_identity, -- const u8 peer_public_key[NOISE_PUBLIC_KEY_LEN], -- const u8 peer_preshared_key[NOISE_SYMMETRIC_KEY_LEN], -- struct wg_peer *peer) --{ -- memset(handshake, 0, sizeof(*handshake)); -- init_rwsem(&handshake->lock); -- handshake->entry.type = INDEX_HASHTABLE_HANDSHAKE; -- handshake->entry.peer = peer; -- memcpy(handshake->remote_static, peer_public_key, NOISE_PUBLIC_KEY_LEN); -- if (peer_preshared_key) -- memcpy(handshake->preshared_key, peer_preshared_key, -- NOISE_SYMMETRIC_KEY_LEN); -- handshake->static_identity = static_identity; -- handshake->state = HANDSHAKE_ZEROED; -- wg_noise_precompute_static_static(peer); --} -- --static void handshake_zero(struct noise_handshake *handshake) --{ -- memset(&handshake->ephemeral_private, 0, NOISE_PUBLIC_KEY_LEN); -- memset(&handshake->remote_ephemeral, 0, NOISE_PUBLIC_KEY_LEN); -- memset(&handshake->hash, 0, NOISE_HASH_LEN); -- memset(&handshake->chaining_key, 0, NOISE_HASH_LEN); -- handshake->remote_index = 0; -- handshake->state = HANDSHAKE_ZEROED; --} -- --void wg_noise_handshake_clear(struct noise_handshake *handshake) --{ -- down_write(&handshake->lock); -- wg_index_hashtable_remove( -- handshake->entry.peer->device->index_hashtable, -- &handshake->entry); -- handshake_zero(handshake); -- up_write(&handshake->lock); --} -- --static struct noise_keypair *keypair_create(struct wg_peer *peer) --{ -- struct noise_keypair *keypair = kzalloc(sizeof(*keypair), GFP_KERNEL); -- -- if (unlikely(!keypair)) -- return NULL; -- spin_lock_init(&keypair->receiving_counter.lock); -- keypair->internal_id = atomic64_inc_return(&keypair_counter); -- keypair->entry.type = INDEX_HASHTABLE_KEYPAIR; -- keypair->entry.peer = peer; -- kref_init(&keypair->refcount); -- return keypair; --} -- --static void keypair_free_rcu(struct rcu_head *rcu) --{ -- kzfree(container_of(rcu, struct noise_keypair, rcu)); --} -- --static void keypair_free_kref(struct kref *kref) --{ -- struct noise_keypair *keypair = -- container_of(kref, struct noise_keypair, refcount); -- -- net_dbg_ratelimited("%s: Keypair %llu destroyed for peer %llu\n", -- keypair->entry.peer->device->dev->name, -- keypair->internal_id, -- keypair->entry.peer->internal_id); -- wg_index_hashtable_remove(keypair->entry.peer->device->index_hashtable, -- &keypair->entry); -- call_rcu(&keypair->rcu, keypair_free_rcu); --} -- --void wg_noise_keypair_put(struct noise_keypair *keypair, bool unreference_now) --{ -- if (unlikely(!keypair)) -- return; -- if (unlikely(unreference_now)) -- wg_index_hashtable_remove( -- keypair->entry.peer->device->index_hashtable, -- &keypair->entry); -- kref_put(&keypair->refcount, keypair_free_kref); --} -- --struct noise_keypair *wg_noise_keypair_get(struct noise_keypair *keypair) --{ -- RCU_LOCKDEP_WARN(!rcu_read_lock_bh_held(), -- "Taking noise keypair reference without holding the RCU BH read lock"); -- if (unlikely(!keypair || !kref_get_unless_zero(&keypair->refcount))) -- return NULL; -- return keypair; --} -- --void wg_noise_keypairs_clear(struct noise_keypairs *keypairs) --{ -- struct noise_keypair *old; -- -- spin_lock_bh(&keypairs->keypair_update_lock); -- -- /* We zero the next_keypair before zeroing the others, so that -- * wg_noise_received_with_keypair returns early before subsequent ones -- * are zeroed. -- */ -- old = rcu_dereference_protected(keypairs->next_keypair, -- lockdep_is_held(&keypairs->keypair_update_lock)); -- RCU_INIT_POINTER(keypairs->next_keypair, NULL); -- wg_noise_keypair_put(old, true); -- -- old = rcu_dereference_protected(keypairs->previous_keypair, -- lockdep_is_held(&keypairs->keypair_update_lock)); -- RCU_INIT_POINTER(keypairs->previous_keypair, NULL); -- wg_noise_keypair_put(old, true); -- -- old = rcu_dereference_protected(keypairs->current_keypair, -- lockdep_is_held(&keypairs->keypair_update_lock)); -- RCU_INIT_POINTER(keypairs->current_keypair, NULL); -- wg_noise_keypair_put(old, true); -- -- spin_unlock_bh(&keypairs->keypair_update_lock); --} -- --void wg_noise_expire_current_peer_keypairs(struct wg_peer *peer) --{ -- struct noise_keypair *keypair; -- -- wg_noise_handshake_clear(&peer->handshake); -- wg_noise_reset_last_sent_handshake(&peer->last_sent_handshake); -- -- spin_lock_bh(&peer->keypairs.keypair_update_lock); -- keypair = rcu_dereference_protected(peer->keypairs.next_keypair, -- lockdep_is_held(&peer->keypairs.keypair_update_lock)); -- if (keypair) -- keypair->sending.is_valid = false; -- keypair = rcu_dereference_protected(peer->keypairs.current_keypair, -- lockdep_is_held(&peer->keypairs.keypair_update_lock)); -- if (keypair) -- keypair->sending.is_valid = false; -- spin_unlock_bh(&peer->keypairs.keypair_update_lock); --} -- --static void add_new_keypair(struct noise_keypairs *keypairs, -- struct noise_keypair *new_keypair) --{ -- struct noise_keypair *previous_keypair, *next_keypair, *current_keypair; -- -- spin_lock_bh(&keypairs->keypair_update_lock); -- previous_keypair = rcu_dereference_protected(keypairs->previous_keypair, -- lockdep_is_held(&keypairs->keypair_update_lock)); -- next_keypair = rcu_dereference_protected(keypairs->next_keypair, -- lockdep_is_held(&keypairs->keypair_update_lock)); -- current_keypair = rcu_dereference_protected(keypairs->current_keypair, -- lockdep_is_held(&keypairs->keypair_update_lock)); -- if (new_keypair->i_am_the_initiator) { -- /* If we're the initiator, it means we've sent a handshake, and -- * received a confirmation response, which means this new -- * keypair can now be used. -- */ -- if (next_keypair) { -- /* If there already was a next keypair pending, we -- * demote it to be the previous keypair, and free the -- * existing current. Note that this means KCI can result -- * in this transition. It would perhaps be more sound to -- * always just get rid of the unused next keypair -- * instead of putting it in the previous slot, but this -- * might be a bit less robust. Something to think about -- * for the future. -- */ -- RCU_INIT_POINTER(keypairs->next_keypair, NULL); -- rcu_assign_pointer(keypairs->previous_keypair, -- next_keypair); -- wg_noise_keypair_put(current_keypair, true); -- } else /* If there wasn't an existing next keypair, we replace -- * the previous with the current one. -- */ -- rcu_assign_pointer(keypairs->previous_keypair, -- current_keypair); -- /* At this point we can get rid of the old previous keypair, and -- * set up the new keypair. -- */ -- wg_noise_keypair_put(previous_keypair, true); -- rcu_assign_pointer(keypairs->current_keypair, new_keypair); -- } else { -- /* If we're the responder, it means we can't use the new keypair -- * until we receive confirmation via the first data packet, so -- * we get rid of the existing previous one, the possibly -- * existing next one, and slide in the new next one. -- */ -- rcu_assign_pointer(keypairs->next_keypair, new_keypair); -- wg_noise_keypair_put(next_keypair, true); -- RCU_INIT_POINTER(keypairs->previous_keypair, NULL); -- wg_noise_keypair_put(previous_keypair, true); -- } -- spin_unlock_bh(&keypairs->keypair_update_lock); --} -- --bool wg_noise_received_with_keypair(struct noise_keypairs *keypairs, -- struct noise_keypair *received_keypair) --{ -- struct noise_keypair *old_keypair; -- bool key_is_new; -- -- /* We first check without taking the spinlock. */ -- key_is_new = received_keypair == -- rcu_access_pointer(keypairs->next_keypair); -- if (likely(!key_is_new)) -- return false; -- -- spin_lock_bh(&keypairs->keypair_update_lock); -- /* After locking, we double check that things didn't change from -- * beneath us. -- */ -- if (unlikely(received_keypair != -- rcu_dereference_protected(keypairs->next_keypair, -- lockdep_is_held(&keypairs->keypair_update_lock)))) { -- spin_unlock_bh(&keypairs->keypair_update_lock); -- return false; -- } -- -- /* When we've finally received the confirmation, we slide the next -- * into the current, the current into the previous, and get rid of -- * the old previous. -- */ -- old_keypair = rcu_dereference_protected(keypairs->previous_keypair, -- lockdep_is_held(&keypairs->keypair_update_lock)); -- rcu_assign_pointer(keypairs->previous_keypair, -- rcu_dereference_protected(keypairs->current_keypair, -- lockdep_is_held(&keypairs->keypair_update_lock))); -- wg_noise_keypair_put(old_keypair, true); -- rcu_assign_pointer(keypairs->current_keypair, received_keypair); -- RCU_INIT_POINTER(keypairs->next_keypair, NULL); -- -- spin_unlock_bh(&keypairs->keypair_update_lock); -- return true; --} -- --/* Must hold static_identity->lock */ --void wg_noise_set_static_identity_private_key( -- struct noise_static_identity *static_identity, -- const u8 private_key[NOISE_PUBLIC_KEY_LEN]) --{ -- memcpy(static_identity->static_private, private_key, -- NOISE_PUBLIC_KEY_LEN); -- curve25519_clamp_secret(static_identity->static_private); -- static_identity->has_identity = curve25519_generate_public( -- static_identity->static_public, private_key); --} -- --/* This is Hugo Krawczyk's HKDF: -- * - https://eprint.iacr.org/2010/264.pdf -- * - https://tools.ietf.org/html/rfc5869 -- */ --static void kdf(u8 *first_dst, u8 *second_dst, u8 *third_dst, const u8 *data, -- size_t first_len, size_t second_len, size_t third_len, -- size_t data_len, const u8 chaining_key[NOISE_HASH_LEN]) --{ -- u8 output[BLAKE2S_HASH_SIZE + 1]; -- u8 secret[BLAKE2S_HASH_SIZE]; -- -- WARN_ON(IS_ENABLED(DEBUG) && -- (first_len > BLAKE2S_HASH_SIZE || -- second_len > BLAKE2S_HASH_SIZE || -- third_len > BLAKE2S_HASH_SIZE || -- ((second_len || second_dst || third_len || third_dst) && -- (!first_len || !first_dst)) || -- ((third_len || third_dst) && (!second_len || !second_dst)))); -- -- /* Extract entropy from data into secret */ -- blake2s256_hmac(secret, data, chaining_key, data_len, NOISE_HASH_LEN); -- -- if (!first_dst || !first_len) -- goto out; -- -- /* Expand first key: key = secret, data = 0x1 */ -- output[0] = 1; -- blake2s256_hmac(output, output, secret, 1, BLAKE2S_HASH_SIZE); -- memcpy(first_dst, output, first_len); -- -- if (!second_dst || !second_len) -- goto out; -- -- /* Expand second key: key = secret, data = first-key || 0x2 */ -- output[BLAKE2S_HASH_SIZE] = 2; -- blake2s256_hmac(output, output, secret, BLAKE2S_HASH_SIZE + 1, -- BLAKE2S_HASH_SIZE); -- memcpy(second_dst, output, second_len); -- -- if (!third_dst || !third_len) -- goto out; -- -- /* Expand third key: key = secret, data = second-key || 0x3 */ -- output[BLAKE2S_HASH_SIZE] = 3; -- blake2s256_hmac(output, output, secret, BLAKE2S_HASH_SIZE + 1, -- BLAKE2S_HASH_SIZE); -- memcpy(third_dst, output, third_len); -- --out: -- /* Clear sensitive data from stack */ -- memzero_explicit(secret, BLAKE2S_HASH_SIZE); -- memzero_explicit(output, BLAKE2S_HASH_SIZE + 1); --} -- --static void derive_keys(struct noise_symmetric_key *first_dst, -- struct noise_symmetric_key *second_dst, -- const u8 chaining_key[NOISE_HASH_LEN]) --{ -- u64 birthdate = ktime_get_coarse_boottime_ns(); -- kdf(first_dst->key, second_dst->key, NULL, NULL, -- NOISE_SYMMETRIC_KEY_LEN, NOISE_SYMMETRIC_KEY_LEN, 0, 0, -- chaining_key); -- first_dst->birthdate = second_dst->birthdate = birthdate; -- first_dst->is_valid = second_dst->is_valid = true; --} -- --static bool __must_check mix_dh(u8 chaining_key[NOISE_HASH_LEN], -- u8 key[NOISE_SYMMETRIC_KEY_LEN], -- const u8 private[NOISE_PUBLIC_KEY_LEN], -- const u8 public[NOISE_PUBLIC_KEY_LEN]) --{ -- u8 dh_calculation[NOISE_PUBLIC_KEY_LEN]; -- -- if (unlikely(!curve25519(dh_calculation, private, public))) -- return false; -- kdf(chaining_key, key, NULL, dh_calculation, NOISE_HASH_LEN, -- NOISE_SYMMETRIC_KEY_LEN, 0, NOISE_PUBLIC_KEY_LEN, chaining_key); -- memzero_explicit(dh_calculation, NOISE_PUBLIC_KEY_LEN); -- return true; --} -- --static bool __must_check mix_precomputed_dh(u8 chaining_key[NOISE_HASH_LEN], -- u8 key[NOISE_SYMMETRIC_KEY_LEN], -- const u8 precomputed[NOISE_PUBLIC_KEY_LEN]) --{ -- static u8 zero_point[NOISE_PUBLIC_KEY_LEN]; -- if (unlikely(!crypto_memneq(precomputed, zero_point, NOISE_PUBLIC_KEY_LEN))) -- return false; -- kdf(chaining_key, key, NULL, precomputed, NOISE_HASH_LEN, -- NOISE_SYMMETRIC_KEY_LEN, 0, NOISE_PUBLIC_KEY_LEN, -- chaining_key); -- return true; --} -- --static void mix_hash(u8 hash[NOISE_HASH_LEN], const u8 *src, size_t src_len) --{ -- struct blake2s_state blake; -- -- blake2s_init(&blake, NOISE_HASH_LEN); -- blake2s_update(&blake, hash, NOISE_HASH_LEN); -- blake2s_update(&blake, src, src_len); -- blake2s_final(&blake, hash); --} -- --static void mix_psk(u8 chaining_key[NOISE_HASH_LEN], u8 hash[NOISE_HASH_LEN], -- u8 key[NOISE_SYMMETRIC_KEY_LEN], -- const u8 psk[NOISE_SYMMETRIC_KEY_LEN]) --{ -- u8 temp_hash[NOISE_HASH_LEN]; -- -- kdf(chaining_key, temp_hash, key, psk, NOISE_HASH_LEN, NOISE_HASH_LEN, -- NOISE_SYMMETRIC_KEY_LEN, NOISE_SYMMETRIC_KEY_LEN, chaining_key); -- mix_hash(hash, temp_hash, NOISE_HASH_LEN); -- memzero_explicit(temp_hash, NOISE_HASH_LEN); --} -- --static void handshake_init(u8 chaining_key[NOISE_HASH_LEN], -- u8 hash[NOISE_HASH_LEN], -- const u8 remote_static[NOISE_PUBLIC_KEY_LEN]) --{ -- memcpy(hash, handshake_init_hash, NOISE_HASH_LEN); -- memcpy(chaining_key, handshake_init_chaining_key, NOISE_HASH_LEN); -- mix_hash(hash, remote_static, NOISE_PUBLIC_KEY_LEN); --} -- --static void message_encrypt(u8 *dst_ciphertext, const u8 *src_plaintext, -- size_t src_len, u8 key[NOISE_SYMMETRIC_KEY_LEN], -- u8 hash[NOISE_HASH_LEN]) --{ -- chacha20poly1305_encrypt(dst_ciphertext, src_plaintext, src_len, hash, -- NOISE_HASH_LEN, -- 0 /* Always zero for Noise_IK */, key); -- mix_hash(hash, dst_ciphertext, noise_encrypted_len(src_len)); --} -- --static bool message_decrypt(u8 *dst_plaintext, const u8 *src_ciphertext, -- size_t src_len, u8 key[NOISE_SYMMETRIC_KEY_LEN], -- u8 hash[NOISE_HASH_LEN]) --{ -- if (!chacha20poly1305_decrypt(dst_plaintext, src_ciphertext, src_len, -- hash, NOISE_HASH_LEN, -- 0 /* Always zero for Noise_IK */, key)) -- return false; -- mix_hash(hash, src_ciphertext, src_len); -- return true; --} -- --static void message_ephemeral(u8 ephemeral_dst[NOISE_PUBLIC_KEY_LEN], -- const u8 ephemeral_src[NOISE_PUBLIC_KEY_LEN], -- u8 chaining_key[NOISE_HASH_LEN], -- u8 hash[NOISE_HASH_LEN]) --{ -- if (ephemeral_dst != ephemeral_src) -- memcpy(ephemeral_dst, ephemeral_src, NOISE_PUBLIC_KEY_LEN); -- mix_hash(hash, ephemeral_src, NOISE_PUBLIC_KEY_LEN); -- kdf(chaining_key, NULL, NULL, ephemeral_src, NOISE_HASH_LEN, 0, 0, -- NOISE_PUBLIC_KEY_LEN, chaining_key); --} -- --static void tai64n_now(u8 output[NOISE_TIMESTAMP_LEN]) --{ -- struct timespec64 now; -- -- ktime_get_real_ts64(&now); -- -- /* In order to prevent some sort of infoleak from precise timers, we -- * round down the nanoseconds part to the closest rounded-down power of -- * two to the maximum initiations per second allowed anyway by the -- * implementation. -- */ -- now.tv_nsec = ALIGN_DOWN(now.tv_nsec, -- rounddown_pow_of_two(NSEC_PER_SEC / INITIATIONS_PER_SECOND)); -- -- /* https://cr.yp.to/libtai/tai64.html */ -- *(__be64 *)output = cpu_to_be64(0x400000000000000aULL + now.tv_sec); -- *(__be32 *)(output + sizeof(__be64)) = cpu_to_be32(now.tv_nsec); --} -- --bool --wg_noise_handshake_create_initiation(struct message_handshake_initiation *dst, -- struct noise_handshake *handshake) --{ -- u8 timestamp[NOISE_TIMESTAMP_LEN]; -- u8 key[NOISE_SYMMETRIC_KEY_LEN]; -- bool ret = false; -- -- /* We need to wait for crng _before_ taking any locks, since -- * curve25519_generate_secret uses get_random_bytes_wait. -- */ -- wait_for_random_bytes(); -- -- down_read(&handshake->static_identity->lock); -- down_write(&handshake->lock); -- -- if (unlikely(!handshake->static_identity->has_identity)) -- goto out; -- -- dst->header.type = cpu_to_le32(MESSAGE_HANDSHAKE_INITIATION); -- -- handshake_init(handshake->chaining_key, handshake->hash, -- handshake->remote_static); -- -- /* e */ -- curve25519_generate_secret(handshake->ephemeral_private); -- if (!curve25519_generate_public(dst->unencrypted_ephemeral, -- handshake->ephemeral_private)) -- goto out; -- message_ephemeral(dst->unencrypted_ephemeral, -- dst->unencrypted_ephemeral, handshake->chaining_key, -- handshake->hash); -- -- /* es */ -- if (!mix_dh(handshake->chaining_key, key, handshake->ephemeral_private, -- handshake->remote_static)) -- goto out; -- -- /* s */ -- message_encrypt(dst->encrypted_static, -- handshake->static_identity->static_public, -- NOISE_PUBLIC_KEY_LEN, key, handshake->hash); -- -- /* ss */ -- if (!mix_precomputed_dh(handshake->chaining_key, key, -- handshake->precomputed_static_static)) -- goto out; -- -- /* {t} */ -- tai64n_now(timestamp); -- message_encrypt(dst->encrypted_timestamp, timestamp, -- NOISE_TIMESTAMP_LEN, key, handshake->hash); -- -- dst->sender_index = wg_index_hashtable_insert( -- handshake->entry.peer->device->index_hashtable, -- &handshake->entry); -- -- handshake->state = HANDSHAKE_CREATED_INITIATION; -- ret = true; -- --out: -- up_write(&handshake->lock); -- up_read(&handshake->static_identity->lock); -- memzero_explicit(key, NOISE_SYMMETRIC_KEY_LEN); -- return ret; --} -- --struct wg_peer * --wg_noise_handshake_consume_initiation(struct message_handshake_initiation *src, -- struct wg_device *wg) --{ -- struct wg_peer *peer = NULL, *ret_peer = NULL; -- struct noise_handshake *handshake; -- bool replay_attack, flood_attack; -- u8 key[NOISE_SYMMETRIC_KEY_LEN]; -- u8 chaining_key[NOISE_HASH_LEN]; -- u8 hash[NOISE_HASH_LEN]; -- u8 s[NOISE_PUBLIC_KEY_LEN]; -- u8 e[NOISE_PUBLIC_KEY_LEN]; -- u8 t[NOISE_TIMESTAMP_LEN]; -- u64 initiation_consumption; -- -- down_read(&wg->static_identity.lock); -- if (unlikely(!wg->static_identity.has_identity)) -- goto out; -- -- handshake_init(chaining_key, hash, wg->static_identity.static_public); -- -- /* e */ -- message_ephemeral(e, src->unencrypted_ephemeral, chaining_key, hash); -- -- /* es */ -- if (!mix_dh(chaining_key, key, wg->static_identity.static_private, e)) -- goto out; -- -- /* s */ -- if (!message_decrypt(s, src->encrypted_static, -- sizeof(src->encrypted_static), key, hash)) -- goto out; -- -- /* Lookup which peer we're actually talking to */ -- peer = wg_pubkey_hashtable_lookup(wg->peer_hashtable, s); -- if (!peer) -- goto out; -- handshake = &peer->handshake; -- -- /* ss */ -- if (!mix_precomputed_dh(chaining_key, key, -- handshake->precomputed_static_static)) -- goto out; -- -- /* {t} */ -- if (!message_decrypt(t, src->encrypted_timestamp, -- sizeof(src->encrypted_timestamp), key, hash)) -- goto out; -- -- down_read(&handshake->lock); -- replay_attack = memcmp(t, handshake->latest_timestamp, -- NOISE_TIMESTAMP_LEN) <= 0; -- flood_attack = (s64)handshake->last_initiation_consumption + -- NSEC_PER_SEC / INITIATIONS_PER_SECOND > -- (s64)ktime_get_coarse_boottime_ns(); -- up_read(&handshake->lock); -- if (replay_attack || flood_attack) -- goto out; -- -- /* Success! Copy everything to peer */ -- down_write(&handshake->lock); -- memcpy(handshake->remote_ephemeral, e, NOISE_PUBLIC_KEY_LEN); -- if (memcmp(t, handshake->latest_timestamp, NOISE_TIMESTAMP_LEN) > 0) -- memcpy(handshake->latest_timestamp, t, NOISE_TIMESTAMP_LEN); -- memcpy(handshake->hash, hash, NOISE_HASH_LEN); -- memcpy(handshake->chaining_key, chaining_key, NOISE_HASH_LEN); -- handshake->remote_index = src->sender_index; -- initiation_consumption = ktime_get_coarse_boottime_ns(); -- if ((s64)(handshake->last_initiation_consumption - initiation_consumption) < 0) -- handshake->last_initiation_consumption = initiation_consumption; -- handshake->state = HANDSHAKE_CONSUMED_INITIATION; -- up_write(&handshake->lock); -- ret_peer = peer; -- --out: -- memzero_explicit(key, NOISE_SYMMETRIC_KEY_LEN); -- memzero_explicit(hash, NOISE_HASH_LEN); -- memzero_explicit(chaining_key, NOISE_HASH_LEN); -- up_read(&wg->static_identity.lock); -- if (!ret_peer) -- wg_peer_put(peer); -- return ret_peer; --} -- --bool wg_noise_handshake_create_response(struct message_handshake_response *dst, -- struct noise_handshake *handshake) --{ -- u8 key[NOISE_SYMMETRIC_KEY_LEN]; -- bool ret = false; -- -- /* We need to wait for crng _before_ taking any locks, since -- * curve25519_generate_secret uses get_random_bytes_wait. -- */ -- wait_for_random_bytes(); -- -- down_read(&handshake->static_identity->lock); -- down_write(&handshake->lock); -- -- if (handshake->state != HANDSHAKE_CONSUMED_INITIATION) -- goto out; -- -- dst->header.type = cpu_to_le32(MESSAGE_HANDSHAKE_RESPONSE); -- dst->receiver_index = handshake->remote_index; -- -- /* e */ -- curve25519_generate_secret(handshake->ephemeral_private); -- if (!curve25519_generate_public(dst->unencrypted_ephemeral, -- handshake->ephemeral_private)) -- goto out; -- message_ephemeral(dst->unencrypted_ephemeral, -- dst->unencrypted_ephemeral, handshake->chaining_key, -- handshake->hash); -- -- /* ee */ -- if (!mix_dh(handshake->chaining_key, NULL, handshake->ephemeral_private, -- handshake->remote_ephemeral)) -- goto out; -- -- /* se */ -- if (!mix_dh(handshake->chaining_key, NULL, handshake->ephemeral_private, -- handshake->remote_static)) -- goto out; -- -- /* psk */ -- mix_psk(handshake->chaining_key, handshake->hash, key, -- handshake->preshared_key); -- -- /* {} */ -- message_encrypt(dst->encrypted_nothing, NULL, 0, key, handshake->hash); -- -- dst->sender_index = wg_index_hashtable_insert( -- handshake->entry.peer->device->index_hashtable, -- &handshake->entry); -- -- handshake->state = HANDSHAKE_CREATED_RESPONSE; -- ret = true; -- --out: -- up_write(&handshake->lock); -- up_read(&handshake->static_identity->lock); -- memzero_explicit(key, NOISE_SYMMETRIC_KEY_LEN); -- return ret; --} -- --struct wg_peer * --wg_noise_handshake_consume_response(struct message_handshake_response *src, -- struct wg_device *wg) --{ -- enum noise_handshake_state state = HANDSHAKE_ZEROED; -- struct wg_peer *peer = NULL, *ret_peer = NULL; -- struct noise_handshake *handshake; -- u8 key[NOISE_SYMMETRIC_KEY_LEN]; -- u8 hash[NOISE_HASH_LEN]; -- u8 chaining_key[NOISE_HASH_LEN]; -- u8 e[NOISE_PUBLIC_KEY_LEN]; -- u8 ephemeral_private[NOISE_PUBLIC_KEY_LEN]; -- u8 static_private[NOISE_PUBLIC_KEY_LEN]; -- u8 preshared_key[NOISE_SYMMETRIC_KEY_LEN]; -- -- down_read(&wg->static_identity.lock); -- -- if (unlikely(!wg->static_identity.has_identity)) -- goto out; -- -- handshake = (struct noise_handshake *)wg_index_hashtable_lookup( -- wg->index_hashtable, INDEX_HASHTABLE_HANDSHAKE, -- src->receiver_index, &peer); -- if (unlikely(!handshake)) -- goto out; -- -- down_read(&handshake->lock); -- state = handshake->state; -- memcpy(hash, handshake->hash, NOISE_HASH_LEN); -- memcpy(chaining_key, handshake->chaining_key, NOISE_HASH_LEN); -- memcpy(ephemeral_private, handshake->ephemeral_private, -- NOISE_PUBLIC_KEY_LEN); -- memcpy(preshared_key, handshake->preshared_key, -- NOISE_SYMMETRIC_KEY_LEN); -- up_read(&handshake->lock); -- -- if (state != HANDSHAKE_CREATED_INITIATION) -- goto fail; -- -- /* e */ -- message_ephemeral(e, src->unencrypted_ephemeral, chaining_key, hash); -- -- /* ee */ -- if (!mix_dh(chaining_key, NULL, ephemeral_private, e)) -- goto fail; -- -- /* se */ -- if (!mix_dh(chaining_key, NULL, wg->static_identity.static_private, e)) -- goto fail; -- -- /* psk */ -- mix_psk(chaining_key, hash, key, preshared_key); -- -- /* {} */ -- if (!message_decrypt(NULL, src->encrypted_nothing, -- sizeof(src->encrypted_nothing), key, hash)) -- goto fail; -- -- /* Success! Copy everything to peer */ -- down_write(&handshake->lock); -- /* It's important to check that the state is still the same, while we -- * have an exclusive lock. -- */ -- if (handshake->state != state) { -- up_write(&handshake->lock); -- goto fail; -- } -- memcpy(handshake->remote_ephemeral, e, NOISE_PUBLIC_KEY_LEN); -- memcpy(handshake->hash, hash, NOISE_HASH_LEN); -- memcpy(handshake->chaining_key, chaining_key, NOISE_HASH_LEN); -- handshake->remote_index = src->sender_index; -- handshake->state = HANDSHAKE_CONSUMED_RESPONSE; -- up_write(&handshake->lock); -- ret_peer = peer; -- goto out; -- --fail: -- wg_peer_put(peer); --out: -- memzero_explicit(key, NOISE_SYMMETRIC_KEY_LEN); -- memzero_explicit(hash, NOISE_HASH_LEN); -- memzero_explicit(chaining_key, NOISE_HASH_LEN); -- memzero_explicit(ephemeral_private, NOISE_PUBLIC_KEY_LEN); -- memzero_explicit(static_private, NOISE_PUBLIC_KEY_LEN); -- memzero_explicit(preshared_key, NOISE_SYMMETRIC_KEY_LEN); -- up_read(&wg->static_identity.lock); -- return ret_peer; --} -- --bool wg_noise_handshake_begin_session(struct noise_handshake *handshake, -- struct noise_keypairs *keypairs) --{ -- struct noise_keypair *new_keypair; -- bool ret = false; -- -- down_write(&handshake->lock); -- if (handshake->state != HANDSHAKE_CREATED_RESPONSE && -- handshake->state != HANDSHAKE_CONSUMED_RESPONSE) -- goto out; -- -- new_keypair = keypair_create(handshake->entry.peer); -- if (!new_keypair) -- goto out; -- new_keypair->i_am_the_initiator = handshake->state == -- HANDSHAKE_CONSUMED_RESPONSE; -- new_keypair->remote_index = handshake->remote_index; -- -- if (new_keypair->i_am_the_initiator) -- derive_keys(&new_keypair->sending, &new_keypair->receiving, -- handshake->chaining_key); -- else -- derive_keys(&new_keypair->receiving, &new_keypair->sending, -- handshake->chaining_key); -- -- handshake_zero(handshake); -- rcu_read_lock_bh(); -- if (likely(!READ_ONCE(container_of(handshake, struct wg_peer, -- handshake)->is_dead))) { -- add_new_keypair(keypairs, new_keypair); -- net_dbg_ratelimited("%s: Keypair %llu created for peer %llu\n", -- handshake->entry.peer->device->dev->name, -- new_keypair->internal_id, -- handshake->entry.peer->internal_id); -- ret = wg_index_hashtable_replace( -- handshake->entry.peer->device->index_hashtable, -- &handshake->entry, &new_keypair->entry); -- } else { -- kzfree(new_keypair); -- } -- rcu_read_unlock_bh(); -- --out: -- up_write(&handshake->lock); -- return ret; --} -diff --git a/drivers/net/wireguard/noise.h b/drivers/net/wireguard/noise.h -deleted file mode 100644 -index c527253db..000000000 ---- a/drivers/net/wireguard/noise.h -+++ /dev/null -@@ -1,135 +0,0 @@ --/* SPDX-License-Identifier: GPL-2.0 */ --/* -- * Copyright (C) 2015-2019 Jason A. Donenfeld . All Rights Reserved. -- */ --#ifndef _WG_NOISE_H --#define _WG_NOISE_H -- --#include "messages.h" --#include "peerlookup.h" -- --#include --#include --#include --#include --#include --#include -- --struct noise_replay_counter { -- u64 counter; -- spinlock_t lock; -- unsigned long backtrack[COUNTER_BITS_TOTAL / BITS_PER_LONG]; --}; -- --struct noise_symmetric_key { -- u8 key[NOISE_SYMMETRIC_KEY_LEN]; -- u64 birthdate; -- bool is_valid; --}; -- --struct noise_keypair { -- struct index_hashtable_entry entry; -- struct noise_symmetric_key sending; -- atomic64_t sending_counter; -- struct noise_symmetric_key receiving; -- struct noise_replay_counter receiving_counter; -- __le32 remote_index; -- bool i_am_the_initiator; -- struct kref refcount; -- struct rcu_head rcu; -- u64 internal_id; --}; -- --struct noise_keypairs { -- struct noise_keypair __rcu *current_keypair; -- struct noise_keypair __rcu *previous_keypair; -- struct noise_keypair __rcu *next_keypair; -- spinlock_t keypair_update_lock; --}; -- --struct noise_static_identity { -- u8 static_public[NOISE_PUBLIC_KEY_LEN]; -- u8 static_private[NOISE_PUBLIC_KEY_LEN]; -- struct rw_semaphore lock; -- bool has_identity; --}; -- --enum noise_handshake_state { -- HANDSHAKE_ZEROED, -- HANDSHAKE_CREATED_INITIATION, -- HANDSHAKE_CONSUMED_INITIATION, -- HANDSHAKE_CREATED_RESPONSE, -- HANDSHAKE_CONSUMED_RESPONSE --}; -- --struct noise_handshake { -- struct index_hashtable_entry entry; -- -- enum noise_handshake_state state; -- u64 last_initiation_consumption; -- -- struct noise_static_identity *static_identity; -- -- u8 ephemeral_private[NOISE_PUBLIC_KEY_LEN]; -- u8 remote_static[NOISE_PUBLIC_KEY_LEN]; -- u8 remote_ephemeral[NOISE_PUBLIC_KEY_LEN]; -- u8 precomputed_static_static[NOISE_PUBLIC_KEY_LEN]; -- -- u8 preshared_key[NOISE_SYMMETRIC_KEY_LEN]; -- -- u8 hash[NOISE_HASH_LEN]; -- u8 chaining_key[NOISE_HASH_LEN]; -- -- u8 latest_timestamp[NOISE_TIMESTAMP_LEN]; -- __le32 remote_index; -- -- /* Protects all members except the immutable (after noise_handshake_ -- * init): remote_static, precomputed_static_static, static_identity. -- */ -- struct rw_semaphore lock; --}; -- --struct wg_device; -- --void wg_noise_init(void); --void wg_noise_handshake_init(struct noise_handshake *handshake, -- struct noise_static_identity *static_identity, -- const u8 peer_public_key[NOISE_PUBLIC_KEY_LEN], -- const u8 peer_preshared_key[NOISE_SYMMETRIC_KEY_LEN], -- struct wg_peer *peer); --void wg_noise_handshake_clear(struct noise_handshake *handshake); --static inline void wg_noise_reset_last_sent_handshake(atomic64_t *handshake_ns) --{ -- atomic64_set(handshake_ns, ktime_get_coarse_boottime_ns() - -- (u64)(REKEY_TIMEOUT + 1) * NSEC_PER_SEC); --} -- --void wg_noise_keypair_put(struct noise_keypair *keypair, bool unreference_now); --struct noise_keypair *wg_noise_keypair_get(struct noise_keypair *keypair); --void wg_noise_keypairs_clear(struct noise_keypairs *keypairs); --bool wg_noise_received_with_keypair(struct noise_keypairs *keypairs, -- struct noise_keypair *received_keypair); --void wg_noise_expire_current_peer_keypairs(struct wg_peer *peer); -- --void wg_noise_set_static_identity_private_key( -- struct noise_static_identity *static_identity, -- const u8 private_key[NOISE_PUBLIC_KEY_LEN]); --void wg_noise_precompute_static_static(struct wg_peer *peer); -- --bool --wg_noise_handshake_create_initiation(struct message_handshake_initiation *dst, -- struct noise_handshake *handshake); --struct wg_peer * --wg_noise_handshake_consume_initiation(struct message_handshake_initiation *src, -- struct wg_device *wg); -- --bool wg_noise_handshake_create_response(struct message_handshake_response *dst, -- struct noise_handshake *handshake); --struct wg_peer * --wg_noise_handshake_consume_response(struct message_handshake_response *src, -- struct wg_device *wg); -- --bool wg_noise_handshake_begin_session(struct noise_handshake *handshake, -- struct noise_keypairs *keypairs); -- --#endif /* _WG_NOISE_H */ -diff --git a/drivers/net/wireguard/peer.c b/drivers/net/wireguard/peer.c -deleted file mode 100644 -index 1d634bd30..000000000 ---- a/drivers/net/wireguard/peer.c -+++ /dev/null -@@ -1,237 +0,0 @@ --// SPDX-License-Identifier: GPL-2.0 --/* -- * Copyright (C) 2015-2019 Jason A. Donenfeld . All Rights Reserved. -- */ -- --#include "peer.h" --#include "device.h" --#include "queueing.h" --#include "timers.h" --#include "peerlookup.h" --#include "noise.h" -- --#include --#include --#include --#include -- --static atomic64_t peer_counter = ATOMIC64_INIT(0); -- --struct wg_peer *wg_peer_create(struct wg_device *wg, -- const u8 public_key[NOISE_PUBLIC_KEY_LEN], -- const u8 preshared_key[NOISE_SYMMETRIC_KEY_LEN]) --{ -- struct wg_peer *peer; -- int ret = -ENOMEM; -- -- lockdep_assert_held(&wg->device_update_lock); -- -- if (wg->num_peers >= MAX_PEERS_PER_DEVICE) -- return ERR_PTR(ret); -- -- peer = kzalloc(sizeof(*peer), GFP_KERNEL); -- if (unlikely(!peer)) -- return ERR_PTR(ret); -- peer->device = wg; -- -- wg_noise_handshake_init(&peer->handshake, &wg->static_identity, -- public_key, preshared_key, peer); -- if (dst_cache_init(&peer->endpoint_cache, GFP_KERNEL)) -- goto err_1; -- if (wg_packet_queue_init(&peer->tx_queue, wg_packet_tx_worker, false, -- MAX_QUEUED_PACKETS)) -- goto err_2; -- if (wg_packet_queue_init(&peer->rx_queue, NULL, false, -- MAX_QUEUED_PACKETS)) -- goto err_3; -- -- peer->internal_id = atomic64_inc_return(&peer_counter); -- peer->serial_work_cpu = nr_cpumask_bits; -- wg_cookie_init(&peer->latest_cookie); -- wg_timers_init(peer); -- wg_cookie_checker_precompute_peer_keys(peer); -- spin_lock_init(&peer->keypairs.keypair_update_lock); -- INIT_WORK(&peer->transmit_handshake_work, -- wg_packet_handshake_send_worker); -- rwlock_init(&peer->endpoint_lock); -- kref_init(&peer->refcount); -- skb_queue_head_init(&peer->staged_packet_queue); -- wg_noise_reset_last_sent_handshake(&peer->last_sent_handshake); -- set_bit(NAPI_STATE_NO_BUSY_POLL, &peer->napi.state); -- netif_napi_add(wg->dev, &peer->napi, wg_packet_rx_poll, -- NAPI_POLL_WEIGHT); -- napi_enable(&peer->napi); -- list_add_tail(&peer->peer_list, &wg->peer_list); -- INIT_LIST_HEAD(&peer->allowedips_list); -- wg_pubkey_hashtable_add(wg->peer_hashtable, peer); -- ++wg->num_peers; -- pr_debug("%s: Peer %llu created\n", wg->dev->name, peer->internal_id); -- return peer; -- --err_3: -- wg_packet_queue_free(&peer->tx_queue, false); --err_2: -- dst_cache_destroy(&peer->endpoint_cache); --err_1: -- kfree(peer); -- return ERR_PTR(ret); --} -- --struct wg_peer *wg_peer_get_maybe_zero(struct wg_peer *peer) --{ -- RCU_LOCKDEP_WARN(!rcu_read_lock_bh_held(), -- "Taking peer reference without holding the RCU read lock"); -- if (unlikely(!peer || !kref_get_unless_zero(&peer->refcount))) -- return NULL; -- return peer; --} -- --static void peer_make_dead(struct wg_peer *peer) --{ -- /* Remove from configuration-time lookup structures. */ -- list_del_init(&peer->peer_list); -- wg_allowedips_remove_by_peer(&peer->device->peer_allowedips, peer, -- &peer->device->device_update_lock); -- wg_pubkey_hashtable_remove(peer->device->peer_hashtable, peer); -- -- /* Mark as dead, so that we don't allow jumping contexts after. */ -- WRITE_ONCE(peer->is_dead, true); -- -- /* The caller must now synchronize_rcu() for this to take effect. */ --} -- --static void peer_remove_after_dead(struct wg_peer *peer) --{ -- WARN_ON(!peer->is_dead); -- -- /* No more keypairs can be created for this peer, since is_dead protects -- * add_new_keypair, so we can now destroy existing ones. -- */ -- wg_noise_keypairs_clear(&peer->keypairs); -- -- /* Destroy all ongoing timers that were in-flight at the beginning of -- * this function. -- */ -- wg_timers_stop(peer); -- -- /* The transition between packet encryption/decryption queues isn't -- * guarded by is_dead, but each reference's life is strictly bounded by -- * two generations: once for parallel crypto and once for serial -- * ingestion, so we can simply flush twice, and be sure that we no -- * longer have references inside these queues. -- */ -- -- /* a) For encrypt/decrypt. */ -- flush_workqueue(peer->device->packet_crypt_wq); -- /* b.1) For send (but not receive, since that's napi). */ -- flush_workqueue(peer->device->packet_crypt_wq); -- /* b.2.1) For receive (but not send, since that's wq). */ -- napi_disable(&peer->napi); -- /* b.2.1) It's now safe to remove the napi struct, which must be done -- * here from process context. -- */ -- netif_napi_del(&peer->napi); -- -- /* Ensure any workstructs we own (like transmit_handshake_work or -- * clear_peer_work) no longer are in use. -- */ -- flush_workqueue(peer->device->handshake_send_wq); -- -- /* After the above flushes, a peer might still be active in a few -- * different contexts: 1) from xmit(), before hitting is_dead and -- * returning, 2) from wg_packet_consume_data(), before hitting is_dead -- * and returning, 3) from wg_receive_handshake_packet() after a point -- * where it has processed an incoming handshake packet, but where -- * all calls to pass it off to timers fails because of is_dead. We won't -- * have new references in (1) eventually, because we're removed from -- * allowedips; we won't have new references in (2) eventually, because -- * wg_index_hashtable_lookup will always return NULL, since we removed -- * all existing keypairs and no more can be created; we won't have new -- * references in (3) eventually, because we're removed from the pubkey -- * hash table, which allows for a maximum of one handshake response, -- * via the still-uncleared index hashtable entry, but not more than one, -- * and in wg_cookie_message_consume, the lookup eventually gets a peer -- * with a refcount of zero, so no new reference is taken. -- */ -- -- --peer->device->num_peers; -- wg_peer_put(peer); --} -- --/* We have a separate "remove" function make sure that all active places where -- * a peer is currently operating will eventually come to an end and not pass -- * their reference onto another context. -- */ --void wg_peer_remove(struct wg_peer *peer) --{ -- if (unlikely(!peer)) -- return; -- lockdep_assert_held(&peer->device->device_update_lock); -- -- peer_make_dead(peer); -- synchronize_rcu(); -- peer_remove_after_dead(peer); --} -- --void wg_peer_remove_all(struct wg_device *wg) --{ -- struct wg_peer *peer, *temp; -- LIST_HEAD(dead_peers); -- -- lockdep_assert_held(&wg->device_update_lock); -- -- /* Avoid having to traverse individually for each one. */ -- wg_allowedips_free(&wg->peer_allowedips, &wg->device_update_lock); -- -- list_for_each_entry_safe(peer, temp, &wg->peer_list, peer_list) { -- peer_make_dead(peer); -- list_add_tail(&peer->peer_list, &dead_peers); -- } -- synchronize_rcu(); -- list_for_each_entry_safe(peer, temp, &dead_peers, peer_list) -- peer_remove_after_dead(peer); --} -- --static void rcu_release(struct rcu_head *rcu) --{ -- struct wg_peer *peer = container_of(rcu, struct wg_peer, rcu); -- -- dst_cache_destroy(&peer->endpoint_cache); -- wg_packet_queue_free(&peer->rx_queue, false); -- wg_packet_queue_free(&peer->tx_queue, false); -- -- /* The final zeroing takes care of clearing any remaining handshake key -- * material and other potentially sensitive information. -- */ -- kzfree(peer); --} -- --static void kref_release(struct kref *refcount) --{ -- struct wg_peer *peer = container_of(refcount, struct wg_peer, refcount); -- -- pr_debug("%s: Peer %llu (%pISpfsc) destroyed\n", -- peer->device->dev->name, peer->internal_id, -- &peer->endpoint.addr); -- -- /* Remove ourself from dynamic runtime lookup structures, now that the -- * last reference is gone. -- */ -- wg_index_hashtable_remove(peer->device->index_hashtable, -- &peer->handshake.entry); -- -- /* Remove any lingering packets that didn't have a chance to be -- * transmitted. -- */ -- wg_packet_purge_staged_packets(peer); -- -- /* Free the memory used. */ -- call_rcu(&peer->rcu, rcu_release); --} -- --void wg_peer_put(struct wg_peer *peer) --{ -- if (unlikely(!peer)) -- return; -- kref_put(&peer->refcount, kref_release); --} -diff --git a/drivers/net/wireguard/peer.h b/drivers/net/wireguard/peer.h -deleted file mode 100644 -index 23af40922..000000000 ---- a/drivers/net/wireguard/peer.h -+++ /dev/null -@@ -1,83 +0,0 @@ --/* SPDX-License-Identifier: GPL-2.0 */ --/* -- * Copyright (C) 2015-2019 Jason A. Donenfeld . All Rights Reserved. -- */ -- --#ifndef _WG_PEER_H --#define _WG_PEER_H -- --#include "device.h" --#include "noise.h" --#include "cookie.h" -- --#include --#include --#include --#include --#include -- --struct wg_device; -- --struct endpoint { -- union { -- struct sockaddr addr; -- struct sockaddr_in addr4; -- struct sockaddr_in6 addr6; -- }; -- union { -- struct { -- struct in_addr src4; -- /* Essentially the same as addr6->scope_id */ -- int src_if4; -- }; -- struct in6_addr src6; -- }; --}; -- --struct wg_peer { -- struct wg_device *device; -- struct crypt_queue tx_queue, rx_queue; -- struct sk_buff_head staged_packet_queue; -- int serial_work_cpu; -- struct noise_keypairs keypairs; -- struct endpoint endpoint; -- struct dst_cache endpoint_cache; -- rwlock_t endpoint_lock; -- struct noise_handshake handshake; -- atomic64_t last_sent_handshake; -- struct work_struct transmit_handshake_work, clear_peer_work; -- struct cookie latest_cookie; -- struct hlist_node pubkey_hash; -- u64 rx_bytes, tx_bytes; -- struct timer_list timer_retransmit_handshake, timer_send_keepalive; -- struct timer_list timer_new_handshake, timer_zero_key_material; -- struct timer_list timer_persistent_keepalive; -- unsigned int timer_handshake_attempts; -- u16 persistent_keepalive_interval; -- bool timer_need_another_keepalive; -- bool sent_lastminute_handshake; -- struct timespec64 walltime_last_handshake; -- struct kref refcount; -- struct rcu_head rcu; -- struct list_head peer_list; -- struct list_head allowedips_list; -- u64 internal_id; -- struct napi_struct napi; -- bool is_dead; --}; -- --struct wg_peer *wg_peer_create(struct wg_device *wg, -- const u8 public_key[NOISE_PUBLIC_KEY_LEN], -- const u8 preshared_key[NOISE_SYMMETRIC_KEY_LEN]); -- --struct wg_peer *__must_check wg_peer_get_maybe_zero(struct wg_peer *peer); --static inline struct wg_peer *wg_peer_get(struct wg_peer *peer) --{ -- kref_get(&peer->refcount); -- return peer; --} --void wg_peer_put(struct wg_peer *peer); --void wg_peer_remove(struct wg_peer *peer); --void wg_peer_remove_all(struct wg_device *wg); -- --#endif /* _WG_PEER_H */ -diff --git a/drivers/net/wireguard/peerlookup.c b/drivers/net/wireguard/peerlookup.c -deleted file mode 100644 -index f2783aa7a..000000000 ---- a/drivers/net/wireguard/peerlookup.c -+++ /dev/null -@@ -1,226 +0,0 @@ --// SPDX-License-Identifier: GPL-2.0 --/* -- * Copyright (C) 2015-2019 Jason A. Donenfeld . All Rights Reserved. -- */ -- --#include "peerlookup.h" --#include "peer.h" --#include "noise.h" -- --static struct hlist_head *pubkey_bucket(struct pubkey_hashtable *table, -- const u8 pubkey[NOISE_PUBLIC_KEY_LEN]) --{ -- /* siphash gives us a secure 64bit number based on a random key. Since -- * the bits are uniformly distributed, we can then mask off to get the -- * bits we need. -- */ -- const u64 hash = siphash(pubkey, NOISE_PUBLIC_KEY_LEN, &table->key); -- -- return &table->hashtable[hash & (HASH_SIZE(table->hashtable) - 1)]; --} -- --struct pubkey_hashtable *wg_pubkey_hashtable_alloc(void) --{ -- struct pubkey_hashtable *table = kvmalloc(sizeof(*table), GFP_KERNEL); -- -- if (!table) -- return NULL; -- -- get_random_bytes(&table->key, sizeof(table->key)); -- hash_init(table->hashtable); -- mutex_init(&table->lock); -- return table; --} -- --void wg_pubkey_hashtable_add(struct pubkey_hashtable *table, -- struct wg_peer *peer) --{ -- mutex_lock(&table->lock); -- hlist_add_head_rcu(&peer->pubkey_hash, -- pubkey_bucket(table, peer->handshake.remote_static)); -- mutex_unlock(&table->lock); --} -- --void wg_pubkey_hashtable_remove(struct pubkey_hashtable *table, -- struct wg_peer *peer) --{ -- mutex_lock(&table->lock); -- hlist_del_init_rcu(&peer->pubkey_hash); -- mutex_unlock(&table->lock); --} -- --/* Returns a strong reference to a peer */ --struct wg_peer * --wg_pubkey_hashtable_lookup(struct pubkey_hashtable *table, -- const u8 pubkey[NOISE_PUBLIC_KEY_LEN]) --{ -- struct wg_peer *iter_peer, *peer = NULL; -- -- rcu_read_lock_bh(); -- hlist_for_each_entry_rcu_bh(iter_peer, pubkey_bucket(table, pubkey), -- pubkey_hash) { -- if (!memcmp(pubkey, iter_peer->handshake.remote_static, -- NOISE_PUBLIC_KEY_LEN)) { -- peer = iter_peer; -- break; -- } -- } -- peer = wg_peer_get_maybe_zero(peer); -- rcu_read_unlock_bh(); -- return peer; --} -- --static struct hlist_head *index_bucket(struct index_hashtable *table, -- const __le32 index) --{ -- /* Since the indices are random and thus all bits are uniformly -- * distributed, we can find its bucket simply by masking. -- */ -- return &table->hashtable[(__force u32)index & -- (HASH_SIZE(table->hashtable) - 1)]; --} -- --struct index_hashtable *wg_index_hashtable_alloc(void) --{ -- struct index_hashtable *table = kvmalloc(sizeof(*table), GFP_KERNEL); -- -- if (!table) -- return NULL; -- -- hash_init(table->hashtable); -- spin_lock_init(&table->lock); -- return table; --} -- --/* At the moment, we limit ourselves to 2^20 total peers, which generally might -- * amount to 2^20*3 items in this hashtable. The algorithm below works by -- * picking a random number and testing it. We can see that these limits mean we -- * usually succeed pretty quickly: -- * -- * >>> def calculation(tries, size): -- * ... return (size / 2**32)**(tries - 1) * (1 - (size / 2**32)) -- * ... -- * >>> calculation(1, 2**20 * 3) -- * 0.999267578125 -- * >>> calculation(2, 2**20 * 3) -- * 0.0007318854331970215 -- * >>> calculation(3, 2**20 * 3) -- * 5.360489012673497e-07 -- * >>> calculation(4, 2**20 * 3) -- * 3.9261394135792216e-10 -- * -- * At the moment, we don't do any masking, so this algorithm isn't exactly -- * constant time in either the random guessing or in the hash list lookup. We -- * could require a minimum of 3 tries, which would successfully mask the -- * guessing. this would not, however, help with the growing hash lengths, which -- * is another thing to consider moving forward. -- */ -- --__le32 wg_index_hashtable_insert(struct index_hashtable *table, -- struct index_hashtable_entry *entry) --{ -- struct index_hashtable_entry *existing_entry; -- -- spin_lock_bh(&table->lock); -- hlist_del_init_rcu(&entry->index_hash); -- spin_unlock_bh(&table->lock); -- -- rcu_read_lock_bh(); -- --search_unused_slot: -- /* First we try to find an unused slot, randomly, while unlocked. */ -- entry->index = (__force __le32)get_random_u32(); -- hlist_for_each_entry_rcu_bh(existing_entry, -- index_bucket(table, entry->index), -- index_hash) { -- if (existing_entry->index == entry->index) -- /* If it's already in use, we continue searching. */ -- goto search_unused_slot; -- } -- -- /* Once we've found an unused slot, we lock it, and then double-check -- * that nobody else stole it from us. -- */ -- spin_lock_bh(&table->lock); -- hlist_for_each_entry_rcu_bh(existing_entry, -- index_bucket(table, entry->index), -- index_hash) { -- if (existing_entry->index == entry->index) { -- spin_unlock_bh(&table->lock); -- /* If it was stolen, we start over. */ -- goto search_unused_slot; -- } -- } -- /* Otherwise, we know we have it exclusively (since we're locked), -- * so we insert. -- */ -- hlist_add_head_rcu(&entry->index_hash, -- index_bucket(table, entry->index)); -- spin_unlock_bh(&table->lock); -- -- rcu_read_unlock_bh(); -- -- return entry->index; --} -- --bool wg_index_hashtable_replace(struct index_hashtable *table, -- struct index_hashtable_entry *old, -- struct index_hashtable_entry *new) --{ -- bool ret; -- -- spin_lock_bh(&table->lock); -- ret = !hlist_unhashed(&old->index_hash); -- if (unlikely(!ret)) -- goto out; -- -- new->index = old->index; -- hlist_replace_rcu(&old->index_hash, &new->index_hash); -- -- /* Calling init here NULLs out index_hash, and in fact after this -- * function returns, it's theoretically possible for this to get -- * reinserted elsewhere. That means the RCU lookup below might either -- * terminate early or jump between buckets, in which case the packet -- * simply gets dropped, which isn't terrible. -- */ -- INIT_HLIST_NODE(&old->index_hash); --out: -- spin_unlock_bh(&table->lock); -- return ret; --} -- --void wg_index_hashtable_remove(struct index_hashtable *table, -- struct index_hashtable_entry *entry) --{ -- spin_lock_bh(&table->lock); -- hlist_del_init_rcu(&entry->index_hash); -- spin_unlock_bh(&table->lock); --} -- --/* Returns a strong reference to a entry->peer */ --struct index_hashtable_entry * --wg_index_hashtable_lookup(struct index_hashtable *table, -- const enum index_hashtable_type type_mask, -- const __le32 index, struct wg_peer **peer) --{ -- struct index_hashtable_entry *iter_entry, *entry = NULL; -- -- rcu_read_lock_bh(); -- hlist_for_each_entry_rcu_bh(iter_entry, index_bucket(table, index), -- index_hash) { -- if (iter_entry->index == index) { -- if (likely(iter_entry->type & type_mask)) -- entry = iter_entry; -- break; -- } -- } -- if (likely(entry)) { -- entry->peer = wg_peer_get_maybe_zero(entry->peer); -- if (likely(entry->peer)) -- *peer = entry->peer; -- else -- entry = NULL; -- } -- rcu_read_unlock_bh(); -- return entry; --} -diff --git a/drivers/net/wireguard/peerlookup.h b/drivers/net/wireguard/peerlookup.h -deleted file mode 100644 -index ced811797..000000000 ---- a/drivers/net/wireguard/peerlookup.h -+++ /dev/null -@@ -1,64 +0,0 @@ --/* SPDX-License-Identifier: GPL-2.0 */ --/* -- * Copyright (C) 2015-2019 Jason A. Donenfeld . All Rights Reserved. -- */ -- --#ifndef _WG_PEERLOOKUP_H --#define _WG_PEERLOOKUP_H -- --#include "messages.h" -- --#include --#include --#include -- --struct wg_peer; -- --struct pubkey_hashtable { -- /* TODO: move to rhashtable */ -- DECLARE_HASHTABLE(hashtable, 11); -- siphash_key_t key; -- struct mutex lock; --}; -- --struct pubkey_hashtable *wg_pubkey_hashtable_alloc(void); --void wg_pubkey_hashtable_add(struct pubkey_hashtable *table, -- struct wg_peer *peer); --void wg_pubkey_hashtable_remove(struct pubkey_hashtable *table, -- struct wg_peer *peer); --struct wg_peer * --wg_pubkey_hashtable_lookup(struct pubkey_hashtable *table, -- const u8 pubkey[NOISE_PUBLIC_KEY_LEN]); -- --struct index_hashtable { -- /* TODO: move to rhashtable */ -- DECLARE_HASHTABLE(hashtable, 13); -- spinlock_t lock; --}; -- --enum index_hashtable_type { -- INDEX_HASHTABLE_HANDSHAKE = 1U << 0, -- INDEX_HASHTABLE_KEYPAIR = 1U << 1 --}; -- --struct index_hashtable_entry { -- struct wg_peer *peer; -- struct hlist_node index_hash; -- enum index_hashtable_type type; -- __le32 index; --}; -- --struct index_hashtable *wg_index_hashtable_alloc(void); --__le32 wg_index_hashtable_insert(struct index_hashtable *table, -- struct index_hashtable_entry *entry); --bool wg_index_hashtable_replace(struct index_hashtable *table, -- struct index_hashtable_entry *old, -- struct index_hashtable_entry *new); --void wg_index_hashtable_remove(struct index_hashtable *table, -- struct index_hashtable_entry *entry); --struct index_hashtable_entry * --wg_index_hashtable_lookup(struct index_hashtable *table, -- const enum index_hashtable_type type_mask, -- const __le32 index, struct wg_peer **peer); -- --#endif /* _WG_PEERLOOKUP_H */ -diff --git a/drivers/net/wireguard/queueing.c b/drivers/net/wireguard/queueing.c -deleted file mode 100644 -index 71b8e80b5..000000000 ---- a/drivers/net/wireguard/queueing.c -+++ /dev/null -@@ -1,55 +0,0 @@ --// SPDX-License-Identifier: GPL-2.0 --/* -- * Copyright (C) 2015-2019 Jason A. Donenfeld . All Rights Reserved. -- */ -- --#include "queueing.h" -- --struct multicore_worker __percpu * --wg_packet_percpu_multicore_worker_alloc(work_func_t function, void *ptr) --{ -- int cpu; -- struct multicore_worker __percpu *worker = -- alloc_percpu(struct multicore_worker); -- -- if (!worker) -- return NULL; -- -- for_each_possible_cpu(cpu) { -- per_cpu_ptr(worker, cpu)->ptr = ptr; -- INIT_WORK(&per_cpu_ptr(worker, cpu)->work, function); -- } -- return worker; --} -- --int wg_packet_queue_init(struct crypt_queue *queue, work_func_t function, -- bool multicore, unsigned int len) --{ -- int ret; -- -- memset(queue, 0, sizeof(*queue)); -- ret = ptr_ring_init(&queue->ring, len, GFP_KERNEL); -- if (ret) -- return ret; -- if (function) { -- if (multicore) { -- queue->worker = wg_packet_percpu_multicore_worker_alloc( -- function, queue); -- if (!queue->worker) { -- ptr_ring_cleanup(&queue->ring, NULL); -- return -ENOMEM; -- } -- } else { -- INIT_WORK(&queue->work, function); -- } -- } -- return 0; --} -- --void wg_packet_queue_free(struct crypt_queue *queue, bool multicore) --{ -- if (multicore) -- free_percpu(queue->worker); -- WARN_ON(!__ptr_ring_empty(&queue->ring)); -- ptr_ring_cleanup(&queue->ring, NULL); --} -diff --git a/drivers/net/wireguard/queueing.h b/drivers/net/wireguard/queueing.h -deleted file mode 100644 -index 866d46865..000000000 ---- a/drivers/net/wireguard/queueing.h -+++ /dev/null -@@ -1,193 +0,0 @@ --/* SPDX-License-Identifier: GPL-2.0 */ --/* -- * Copyright (C) 2015-2019 Jason A. Donenfeld . All Rights Reserved. -- */ -- --#ifndef _WG_QUEUEING_H --#define _WG_QUEUEING_H -- --#include "peer.h" --#include --#include --#include --#include --#include -- --struct wg_device; --struct wg_peer; --struct multicore_worker; --struct crypt_queue; --struct sk_buff; -- --/* queueing.c APIs: */ --int wg_packet_queue_init(struct crypt_queue *queue, work_func_t function, -- bool multicore, unsigned int len); --void wg_packet_queue_free(struct crypt_queue *queue, bool multicore); --struct multicore_worker __percpu * --wg_packet_percpu_multicore_worker_alloc(work_func_t function, void *ptr); -- --/* receive.c APIs: */ --void wg_packet_receive(struct wg_device *wg, struct sk_buff *skb); --void wg_packet_handshake_receive_worker(struct work_struct *work); --/* NAPI poll function: */ --int wg_packet_rx_poll(struct napi_struct *napi, int budget); --/* Workqueue worker: */ --void wg_packet_decrypt_worker(struct work_struct *work); -- --/* send.c APIs: */ --void wg_packet_send_queued_handshake_initiation(struct wg_peer *peer, -- bool is_retry); --void wg_packet_send_handshake_response(struct wg_peer *peer); --void wg_packet_send_handshake_cookie(struct wg_device *wg, -- struct sk_buff *initiating_skb, -- __le32 sender_index); --void wg_packet_send_keepalive(struct wg_peer *peer); --void wg_packet_purge_staged_packets(struct wg_peer *peer); --void wg_packet_send_staged_packets(struct wg_peer *peer); --/* Workqueue workers: */ --void wg_packet_handshake_send_worker(struct work_struct *work); --void wg_packet_tx_worker(struct work_struct *work); --void wg_packet_encrypt_worker(struct work_struct *work); -- --enum packet_state { -- PACKET_STATE_UNCRYPTED, -- PACKET_STATE_CRYPTED, -- PACKET_STATE_DEAD --}; -- --struct packet_cb { -- u64 nonce; -- struct noise_keypair *keypair; -- atomic_t state; -- u32 mtu; -- u8 ds; --}; -- --#define PACKET_CB(skb) ((struct packet_cb *)((skb)->cb)) --#define PACKET_PEER(skb) (PACKET_CB(skb)->keypair->entry.peer) -- --static inline bool wg_check_packet_protocol(struct sk_buff *skb) --{ -- __be16 real_protocol = ip_tunnel_parse_protocol(skb); -- return real_protocol && skb->protocol == real_protocol; --} -- --static inline void wg_reset_packet(struct sk_buff *skb, bool encapsulating) --{ -- u8 l4_hash = skb->l4_hash; -- u8 sw_hash = skb->sw_hash; -- u32 hash = skb->hash; -- skb_scrub_packet(skb, true); -- memset(&skb->headers_start, 0, -- offsetof(struct sk_buff, headers_end) - -- offsetof(struct sk_buff, headers_start)); -- if (encapsulating) { -- skb->l4_hash = l4_hash; -- skb->sw_hash = sw_hash; -- skb->hash = hash; -- } -- skb->queue_mapping = 0; -- skb->nohdr = 0; -- skb->peeked = 0; -- skb->mac_len = 0; -- skb->dev = NULL; --#ifdef CONFIG_NET_SCHED -- skb->tc_index = 0; -- skb_reset_tc(skb); --#endif -- skb->hdr_len = skb_headroom(skb); -- skb_reset_mac_header(skb); -- skb_reset_network_header(skb); -- skb_reset_transport_header(skb); -- skb_probe_transport_header(skb, 0); -- skb_reset_inner_headers(skb); --} -- --static inline int wg_cpumask_choose_online(int *stored_cpu, unsigned int id) --{ -- unsigned int cpu = *stored_cpu, cpu_index, i; -- -- if (unlikely(cpu == nr_cpumask_bits || -- !cpumask_test_cpu(cpu, cpu_online_mask))) { -- cpu_index = id % cpumask_weight(cpu_online_mask); -- cpu = cpumask_first(cpu_online_mask); -- for (i = 0; i < cpu_index; ++i) -- cpu = cpumask_next(cpu, cpu_online_mask); -- *stored_cpu = cpu; -- } -- return cpu; --} -- --/* This function is racy, in the sense that next is unlocked, so it could return -- * the same CPU twice. A race-free version of this would be to instead store an -- * atomic sequence number, do an increment-and-return, and then iterate through -- * every possible CPU until we get to that index -- choose_cpu. However that's -- * a bit slower, and it doesn't seem like this potential race actually -- * introduces any performance loss, so we live with it. -- */ --static inline int wg_cpumask_next_online(int *next) --{ -- int cpu = *next; -- -- while (unlikely(!cpumask_test_cpu(cpu, cpu_online_mask))) -- cpu = cpumask_next(cpu, cpu_online_mask) % nr_cpumask_bits; -- *next = cpumask_next(cpu, cpu_online_mask) % nr_cpumask_bits; -- return cpu; --} -- --static inline int wg_queue_enqueue_per_device_and_peer( -- struct crypt_queue *device_queue, struct crypt_queue *peer_queue, -- struct sk_buff *skb, struct workqueue_struct *wq, int *next_cpu) --{ -- int cpu; -- -- atomic_set_release(&PACKET_CB(skb)->state, PACKET_STATE_UNCRYPTED); -- /* We first queue this up for the peer ingestion, but the consumer -- * will wait for the state to change to CRYPTED or DEAD before. -- */ -- if (unlikely(ptr_ring_produce_bh(&peer_queue->ring, skb))) -- return -ENOSPC; -- /* Then we queue it up in the device queue, which consumes the -- * packet as soon as it can. -- */ -- cpu = wg_cpumask_next_online(next_cpu); -- if (unlikely(ptr_ring_produce_bh(&device_queue->ring, skb))) -- return -EPIPE; -- queue_work_on(cpu, wq, &per_cpu_ptr(device_queue->worker, cpu)->work); -- return 0; --} -- --static inline void wg_queue_enqueue_per_peer(struct crypt_queue *queue, -- struct sk_buff *skb, -- enum packet_state state) --{ -- /* We take a reference, because as soon as we call atomic_set, the -- * peer can be freed from below us. -- */ -- struct wg_peer *peer = wg_peer_get(PACKET_PEER(skb)); -- -- atomic_set_release(&PACKET_CB(skb)->state, state); -- queue_work_on(wg_cpumask_choose_online(&peer->serial_work_cpu, -- peer->internal_id), -- peer->device->packet_crypt_wq, &queue->work); -- wg_peer_put(peer); --} -- --static inline void wg_queue_enqueue_per_peer_napi(struct sk_buff *skb, -- enum packet_state state) --{ -- /* We take a reference, because as soon as we call atomic_set, the -- * peer can be freed from below us. -- */ -- struct wg_peer *peer = wg_peer_get(PACKET_PEER(skb)); -- -- atomic_set_release(&PACKET_CB(skb)->state, state); -- napi_schedule(&peer->napi); -- wg_peer_put(peer); --} -- --#ifdef DEBUG --bool wg_packet_counter_selftest(void); --#endif -- --#endif /* _WG_QUEUEING_H */ -diff --git a/drivers/net/wireguard/ratelimiter.c b/drivers/net/wireguard/ratelimiter.c -deleted file mode 100644 -index 9baa930c8..000000000 ---- a/drivers/net/wireguard/ratelimiter.c -+++ /dev/null -@@ -1,223 +0,0 @@ --// SPDX-License-Identifier: GPL-2.0 --/* -- * Copyright (C) 2015-2019 Jason A. Donenfeld . All Rights Reserved. -- */ -- --#include "ratelimiter.h" --#include --#include --#include --#include -- --static struct kmem_cache *entry_cache; --static hsiphash_key_t key; --static spinlock_t table_lock = __SPIN_LOCK_UNLOCKED("ratelimiter_table_lock"); --static DEFINE_MUTEX(init_lock); --static u64 init_refcnt; /* Protected by init_lock, hence not atomic. */ --static atomic_t total_entries = ATOMIC_INIT(0); --static unsigned int max_entries, table_size; --static void wg_ratelimiter_gc_entries(struct work_struct *); --static DECLARE_DEFERRABLE_WORK(gc_work, wg_ratelimiter_gc_entries); --static struct hlist_head *table_v4; --#if IS_ENABLED(CONFIG_IPV6) --static struct hlist_head *table_v6; --#endif -- --struct ratelimiter_entry { -- u64 last_time_ns, tokens, ip; -- void *net; -- spinlock_t lock; -- struct hlist_node hash; -- struct rcu_head rcu; --}; -- --enum { -- PACKETS_PER_SECOND = 20, -- PACKETS_BURSTABLE = 5, -- PACKET_COST = NSEC_PER_SEC / PACKETS_PER_SECOND, -- TOKEN_MAX = PACKET_COST * PACKETS_BURSTABLE --}; -- --static void entry_free(struct rcu_head *rcu) --{ -- kmem_cache_free(entry_cache, -- container_of(rcu, struct ratelimiter_entry, rcu)); -- atomic_dec(&total_entries); --} -- --static void entry_uninit(struct ratelimiter_entry *entry) --{ -- hlist_del_rcu(&entry->hash); -- call_rcu(&entry->rcu, entry_free); --} -- --/* Calling this function with a NULL work uninits all entries. */ --static void wg_ratelimiter_gc_entries(struct work_struct *work) --{ -- const u64 now = ktime_get_coarse_boottime_ns(); -- struct ratelimiter_entry *entry; -- struct hlist_node *temp; -- unsigned int i; -- -- for (i = 0; i < table_size; ++i) { -- spin_lock(&table_lock); -- hlist_for_each_entry_safe(entry, temp, &table_v4[i], hash) { -- if (unlikely(!work) || -- now - entry->last_time_ns > NSEC_PER_SEC) -- entry_uninit(entry); -- } --#if IS_ENABLED(CONFIG_IPV6) -- hlist_for_each_entry_safe(entry, temp, &table_v6[i], hash) { -- if (unlikely(!work) || -- now - entry->last_time_ns > NSEC_PER_SEC) -- entry_uninit(entry); -- } --#endif -- spin_unlock(&table_lock); -- if (likely(work)) -- cond_resched(); -- } -- if (likely(work)) -- queue_delayed_work(system_power_efficient_wq, &gc_work, HZ); --} -- --bool wg_ratelimiter_allow(struct sk_buff *skb, struct net *net) --{ -- /* We only take the bottom half of the net pointer, so that we can hash -- * 3 words in the end. This way, siphash's len param fits into the final -- * u32, and we don't incur an extra round. -- */ -- const u32 net_word = (unsigned long)net; -- struct ratelimiter_entry *entry; -- struct hlist_head *bucket; -- u64 ip; -- -- if (skb->protocol == htons(ETH_P_IP)) { -- ip = (u64 __force)ip_hdr(skb)->saddr; -- bucket = &table_v4[hsiphash_2u32(net_word, ip, &key) & -- (table_size - 1)]; -- } --#if IS_ENABLED(CONFIG_IPV6) -- else if (skb->protocol == htons(ETH_P_IPV6)) { -- /* Only use 64 bits, so as to ratelimit the whole /64. */ -- memcpy(&ip, &ipv6_hdr(skb)->saddr, sizeof(ip)); -- bucket = &table_v6[hsiphash_3u32(net_word, ip >> 32, ip, &key) & -- (table_size - 1)]; -- } --#endif -- else -- return false; -- rcu_read_lock(); -- hlist_for_each_entry_rcu(entry, bucket, hash) { -- if (entry->net == net && entry->ip == ip) { -- u64 now, tokens; -- bool ret; -- /* Quasi-inspired by nft_limit.c, but this is actually a -- * slightly different algorithm. Namely, we incorporate -- * the burst as part of the maximum tokens, rather than -- * as part of the rate. -- */ -- spin_lock(&entry->lock); -- now = ktime_get_coarse_boottime_ns(); -- tokens = min_t(u64, TOKEN_MAX, -- entry->tokens + now - -- entry->last_time_ns); -- entry->last_time_ns = now; -- ret = tokens >= PACKET_COST; -- entry->tokens = ret ? tokens - PACKET_COST : tokens; -- spin_unlock(&entry->lock); -- rcu_read_unlock(); -- return ret; -- } -- } -- rcu_read_unlock(); -- -- if (atomic_inc_return(&total_entries) > max_entries) -- goto err_oom; -- -- entry = kmem_cache_alloc(entry_cache, GFP_KERNEL); -- if (unlikely(!entry)) -- goto err_oom; -- -- entry->net = net; -- entry->ip = ip; -- INIT_HLIST_NODE(&entry->hash); -- spin_lock_init(&entry->lock); -- entry->last_time_ns = ktime_get_coarse_boottime_ns(); -- entry->tokens = TOKEN_MAX - PACKET_COST; -- spin_lock(&table_lock); -- hlist_add_head_rcu(&entry->hash, bucket); -- spin_unlock(&table_lock); -- return true; -- --err_oom: -- atomic_dec(&total_entries); -- return false; --} -- --int wg_ratelimiter_init(void) --{ -- mutex_lock(&init_lock); -- if (++init_refcnt != 1) -- goto out; -- -- entry_cache = KMEM_CACHE(ratelimiter_entry, 0); -- if (!entry_cache) -- goto err; -- -- /* xt_hashlimit.c uses a slightly different algorithm for ratelimiting, -- * but what it shares in common is that it uses a massive hashtable. So, -- * we borrow their wisdom about good table sizes on different systems -- * dependent on RAM. This calculation here comes from there. -- */ -- table_size = (totalram_pages > (1U << 30) / PAGE_SIZE) ? 8192 : -- max_t(unsigned long, 16, roundup_pow_of_two( -- (totalram_pages << PAGE_SHIFT) / -- (1U << 14) / sizeof(struct hlist_head))); -- max_entries = table_size * 8; -- -- table_v4 = kvzalloc(table_size * sizeof(*table_v4), GFP_KERNEL); -- if (unlikely(!table_v4)) -- goto err_kmemcache; -- --#if IS_ENABLED(CONFIG_IPV6) -- table_v6 = kvzalloc(table_size * sizeof(*table_v6), GFP_KERNEL); -- if (unlikely(!table_v6)) { -- kvfree(table_v4); -- goto err_kmemcache; -- } --#endif -- -- queue_delayed_work(system_power_efficient_wq, &gc_work, HZ); -- get_random_bytes(&key, sizeof(key)); --out: -- mutex_unlock(&init_lock); -- return 0; -- --err_kmemcache: -- kmem_cache_destroy(entry_cache); --err: -- --init_refcnt; -- mutex_unlock(&init_lock); -- return -ENOMEM; --} -- --void wg_ratelimiter_uninit(void) --{ -- mutex_lock(&init_lock); -- if (!init_refcnt || --init_refcnt) -- goto out; -- -- cancel_delayed_work_sync(&gc_work); -- wg_ratelimiter_gc_entries(NULL); -- rcu_barrier(); -- kvfree(table_v4); --#if IS_ENABLED(CONFIG_IPV6) -- kvfree(table_v6); --#endif -- kmem_cache_destroy(entry_cache); --out: -- mutex_unlock(&init_lock); --} -- --#include "selftest/ratelimiter.c" -diff --git a/drivers/net/wireguard/ratelimiter.h b/drivers/net/wireguard/ratelimiter.h -deleted file mode 100644 -index 83067f71e..000000000 ---- a/drivers/net/wireguard/ratelimiter.h -+++ /dev/null -@@ -1,19 +0,0 @@ --/* SPDX-License-Identifier: GPL-2.0 */ --/* -- * Copyright (C) 2015-2019 Jason A. Donenfeld . All Rights Reserved. -- */ -- --#ifndef _WG_RATELIMITER_H --#define _WG_RATELIMITER_H -- --#include -- --int wg_ratelimiter_init(void); --void wg_ratelimiter_uninit(void); --bool wg_ratelimiter_allow(struct sk_buff *skb, struct net *net); -- --#ifdef DEBUG --bool wg_ratelimiter_selftest(void); --#endif -- --#endif /* _WG_RATELIMITER_H */ -diff --git a/drivers/net/wireguard/receive.c b/drivers/net/wireguard/receive.c -deleted file mode 100644 -index 2c9551ea6..000000000 ---- a/drivers/net/wireguard/receive.c -+++ /dev/null -@@ -1,590 +0,0 @@ --// SPDX-License-Identifier: GPL-2.0 --/* -- * Copyright (C) 2015-2019 Jason A. Donenfeld . All Rights Reserved. -- */ -- --#include "queueing.h" --#include "device.h" --#include "peer.h" --#include "timers.h" --#include "messages.h" --#include "cookie.h" --#include "socket.h" -- --#include --#include --#include --#include -- --/* Must be called with bh disabled. */ --static void update_rx_stats(struct wg_peer *peer, size_t len) --{ -- struct pcpu_sw_netstats *tstats = -- get_cpu_ptr(peer->device->dev->tstats); -- -- u64_stats_update_begin(&tstats->syncp); -- ++tstats->rx_packets; -- tstats->rx_bytes += len; -- peer->rx_bytes += len; -- u64_stats_update_end(&tstats->syncp); -- put_cpu_ptr(tstats); --} -- --#define SKB_TYPE_LE32(skb) (((struct message_header *)(skb)->data)->type) -- --static size_t validate_header_len(struct sk_buff *skb) --{ -- if (unlikely(skb->len < sizeof(struct message_header))) -- return 0; -- if (SKB_TYPE_LE32(skb) == cpu_to_le32(MESSAGE_DATA) && -- skb->len >= MESSAGE_MINIMUM_LENGTH) -- return sizeof(struct message_data); -- if (SKB_TYPE_LE32(skb) == cpu_to_le32(MESSAGE_HANDSHAKE_INITIATION) && -- skb->len == sizeof(struct message_handshake_initiation)) -- return sizeof(struct message_handshake_initiation); -- if (SKB_TYPE_LE32(skb) == cpu_to_le32(MESSAGE_HANDSHAKE_RESPONSE) && -- skb->len == sizeof(struct message_handshake_response)) -- return sizeof(struct message_handshake_response); -- if (SKB_TYPE_LE32(skb) == cpu_to_le32(MESSAGE_HANDSHAKE_COOKIE) && -- skb->len == sizeof(struct message_handshake_cookie)) -- return sizeof(struct message_handshake_cookie); -- return 0; --} -- --static int prepare_skb_header(struct sk_buff *skb, struct wg_device *wg) --{ -- size_t data_offset, data_len, header_len; -- struct udphdr *udp; -- -- if (unlikely(!wg_check_packet_protocol(skb) || -- skb_transport_header(skb) < skb->head || -- (skb_transport_header(skb) + sizeof(struct udphdr)) > -- skb_tail_pointer(skb))) -- return -EINVAL; /* Bogus IP header */ -- udp = udp_hdr(skb); -- data_offset = (u8 *)udp - skb->data; -- if (unlikely(data_offset > U16_MAX || -- data_offset + sizeof(struct udphdr) > skb->len)) -- /* Packet has offset at impossible location or isn't big enough -- * to have UDP fields. -- */ -- return -EINVAL; -- data_len = ntohs(udp->len); -- if (unlikely(data_len < sizeof(struct udphdr) || -- data_len > skb->len - data_offset)) -- /* UDP packet is reporting too small of a size or lying about -- * its size. -- */ -- return -EINVAL; -- data_len -= sizeof(struct udphdr); -- data_offset = (u8 *)udp + sizeof(struct udphdr) - skb->data; -- if (unlikely(!pskb_may_pull(skb, -- data_offset + sizeof(struct message_header)) || -- pskb_trim(skb, data_len + data_offset) < 0)) -- return -EINVAL; -- skb_pull(skb, data_offset); -- if (unlikely(skb->len != data_len)) -- /* Final len does not agree with calculated len */ -- return -EINVAL; -- header_len = validate_header_len(skb); -- if (unlikely(!header_len)) -- return -EINVAL; -- __skb_push(skb, data_offset); -- if (unlikely(!pskb_may_pull(skb, data_offset + header_len))) -- return -EINVAL; -- __skb_pull(skb, data_offset); -- return 0; --} -- --static void wg_receive_handshake_packet(struct wg_device *wg, -- struct sk_buff *skb) --{ -- enum cookie_mac_state mac_state; -- struct wg_peer *peer = NULL; -- /* This is global, so that our load calculation applies to the whole -- * system. We don't care about races with it at all. -- */ -- static u64 last_under_load; -- bool packet_needs_cookie; -- bool under_load; -- -- if (SKB_TYPE_LE32(skb) == cpu_to_le32(MESSAGE_HANDSHAKE_COOKIE)) { -- net_dbg_skb_ratelimited("%s: Receiving cookie response from %pISpfsc\n", -- wg->dev->name, skb); -- wg_cookie_message_consume( -- (struct message_handshake_cookie *)skb->data, wg); -- return; -- } -- -- under_load = skb_queue_len(&wg->incoming_handshakes) >= -- MAX_QUEUED_INCOMING_HANDSHAKES / 8; -- if (under_load) { -- last_under_load = ktime_get_coarse_boottime_ns(); -- } else if (last_under_load) { -- under_load = !wg_birthdate_has_expired(last_under_load, 1); -- if (!under_load) -- last_under_load = 0; -- } -- mac_state = wg_cookie_validate_packet(&wg->cookie_checker, skb, -- under_load); -- if ((under_load && mac_state == VALID_MAC_WITH_COOKIE) || -- (!under_load && mac_state == VALID_MAC_BUT_NO_COOKIE)) { -- packet_needs_cookie = false; -- } else if (under_load && mac_state == VALID_MAC_BUT_NO_COOKIE) { -- packet_needs_cookie = true; -- } else { -- net_dbg_skb_ratelimited("%s: Invalid MAC of handshake, dropping packet from %pISpfsc\n", -- wg->dev->name, skb); -- return; -- } -- -- switch (SKB_TYPE_LE32(skb)) { -- case cpu_to_le32(MESSAGE_HANDSHAKE_INITIATION): { -- struct message_handshake_initiation *message = -- (struct message_handshake_initiation *)skb->data; -- -- if (packet_needs_cookie) { -- wg_packet_send_handshake_cookie(wg, skb, -- message->sender_index); -- return; -- } -- peer = wg_noise_handshake_consume_initiation(message, wg); -- if (unlikely(!peer)) { -- net_dbg_skb_ratelimited("%s: Invalid handshake initiation from %pISpfsc\n", -- wg->dev->name, skb); -- return; -- } -- wg_socket_set_peer_endpoint_from_skb(peer, skb); -- net_dbg_ratelimited("%s: Receiving handshake initiation from peer %llu (%pISpfsc)\n", -- wg->dev->name, peer->internal_id, -- &peer->endpoint.addr); -- wg_packet_send_handshake_response(peer); -- break; -- } -- case cpu_to_le32(MESSAGE_HANDSHAKE_RESPONSE): { -- struct message_handshake_response *message = -- (struct message_handshake_response *)skb->data; -- -- if (packet_needs_cookie) { -- wg_packet_send_handshake_cookie(wg, skb, -- message->sender_index); -- return; -- } -- peer = wg_noise_handshake_consume_response(message, wg); -- if (unlikely(!peer)) { -- net_dbg_skb_ratelimited("%s: Invalid handshake response from %pISpfsc\n", -- wg->dev->name, skb); -- return; -- } -- wg_socket_set_peer_endpoint_from_skb(peer, skb); -- net_dbg_ratelimited("%s: Receiving handshake response from peer %llu (%pISpfsc)\n", -- wg->dev->name, peer->internal_id, -- &peer->endpoint.addr); -- if (wg_noise_handshake_begin_session(&peer->handshake, -- &peer->keypairs)) { -- wg_timers_session_derived(peer); -- wg_timers_handshake_complete(peer); -- /* Calling this function will either send any existing -- * packets in the queue and not send a keepalive, which -- * is the best case, Or, if there's nothing in the -- * queue, it will send a keepalive, in order to give -- * immediate confirmation of the session. -- */ -- wg_packet_send_keepalive(peer); -- } -- break; -- } -- } -- -- if (unlikely(!peer)) { -- WARN(1, "Somehow a wrong type of packet wound up in the handshake queue!\n"); -- return; -- } -- -- local_bh_disable(); -- update_rx_stats(peer, skb->len); -- local_bh_enable(); -- -- wg_timers_any_authenticated_packet_received(peer); -- wg_timers_any_authenticated_packet_traversal(peer); -- wg_peer_put(peer); --} -- --void wg_packet_handshake_receive_worker(struct work_struct *work) --{ -- struct wg_device *wg = container_of(work, struct multicore_worker, -- work)->ptr; -- struct sk_buff *skb; -- -- while ((skb = skb_dequeue(&wg->incoming_handshakes)) != NULL) { -- wg_receive_handshake_packet(wg, skb); -- dev_kfree_skb(skb); -- cond_resched(); -- } --} -- --static void keep_key_fresh(struct wg_peer *peer) --{ -- struct noise_keypair *keypair; -- bool send; -- -- if (peer->sent_lastminute_handshake) -- return; -- -- rcu_read_lock_bh(); -- keypair = rcu_dereference_bh(peer->keypairs.current_keypair); -- send = keypair && READ_ONCE(keypair->sending.is_valid) && -- keypair->i_am_the_initiator && -- wg_birthdate_has_expired(keypair->sending.birthdate, -- REJECT_AFTER_TIME - KEEPALIVE_TIMEOUT - REKEY_TIMEOUT); -- rcu_read_unlock_bh(); -- -- if (unlikely(send)) { -- peer->sent_lastminute_handshake = true; -- wg_packet_send_queued_handshake_initiation(peer, false); -- } --} -- --static bool decrypt_packet(struct sk_buff *skb, struct noise_keypair *keypair) --{ -- struct scatterlist sg[MAX_SKB_FRAGS + 8]; -- struct sk_buff *trailer; -- unsigned int offset; -- int num_frags; -- -- if (unlikely(!keypair)) -- return false; -- -- if (unlikely(!READ_ONCE(keypair->receiving.is_valid) || -- wg_birthdate_has_expired(keypair->receiving.birthdate, REJECT_AFTER_TIME) || -- keypair->receiving_counter.counter >= REJECT_AFTER_MESSAGES)) { -- WRITE_ONCE(keypair->receiving.is_valid, false); -- return false; -- } -- -- PACKET_CB(skb)->nonce = -- le64_to_cpu(((struct message_data *)skb->data)->counter); -- -- /* We ensure that the network header is part of the packet before we -- * call skb_cow_data, so that there's no chance that data is removed -- * from the skb, so that later we can extract the original endpoint. -- */ -- offset = skb->data - skb_network_header(skb); -- skb_push(skb, offset); -- num_frags = skb_cow_data(skb, 0, &trailer); -- offset += sizeof(struct message_data); -- skb_pull(skb, offset); -- if (unlikely(num_frags < 0 || num_frags > ARRAY_SIZE(sg))) -- return false; -- -- sg_init_table(sg, num_frags); -- if (skb_to_sgvec(skb, sg, 0, skb->len) <= 0) -- return false; -- -- if (!chacha20poly1305_decrypt_sg_inplace(sg, skb->len, NULL, 0, -- PACKET_CB(skb)->nonce, -- keypair->receiving.key)) -- return false; -- -- /* Another ugly situation of pushing and pulling the header so as to -- * keep endpoint information intact. -- */ -- skb_push(skb, offset); -- if (pskb_trim(skb, skb->len - noise_encrypted_len(0))) -- return false; -- skb_pull(skb, offset); -- -- return true; --} -- --/* This is RFC6479, a replay detection bitmap algorithm that avoids bitshifts */ --static bool counter_validate(struct noise_replay_counter *counter, u64 their_counter) --{ -- unsigned long index, index_current, top, i; -- bool ret = false; -- -- spin_lock_bh(&counter->lock); -- -- if (unlikely(counter->counter >= REJECT_AFTER_MESSAGES + 1 || -- their_counter >= REJECT_AFTER_MESSAGES)) -- goto out; -- -- ++their_counter; -- -- if (unlikely((COUNTER_WINDOW_SIZE + their_counter) < -- counter->counter)) -- goto out; -- -- index = their_counter >> ilog2(BITS_PER_LONG); -- -- if (likely(their_counter > counter->counter)) { -- index_current = counter->counter >> ilog2(BITS_PER_LONG); -- top = min_t(unsigned long, index - index_current, -- COUNTER_BITS_TOTAL / BITS_PER_LONG); -- for (i = 1; i <= top; ++i) -- counter->backtrack[(i + index_current) & -- ((COUNTER_BITS_TOTAL / BITS_PER_LONG) - 1)] = 0; -- counter->counter = their_counter; -- } -- -- index &= (COUNTER_BITS_TOTAL / BITS_PER_LONG) - 1; -- ret = !test_and_set_bit(their_counter & (BITS_PER_LONG - 1), -- &counter->backtrack[index]); -- --out: -- spin_unlock_bh(&counter->lock); -- return ret; --} -- --#include "selftest/counter.c" -- --static void wg_packet_consume_data_done(struct wg_peer *peer, -- struct sk_buff *skb, -- struct endpoint *endpoint) --{ -- struct net_device *dev = peer->device->dev; -- unsigned int len, len_before_trim; -- struct wg_peer *routed_peer; -- -- wg_socket_set_peer_endpoint(peer, endpoint); -- -- if (unlikely(wg_noise_received_with_keypair(&peer->keypairs, -- PACKET_CB(skb)->keypair))) { -- wg_timers_handshake_complete(peer); -- wg_packet_send_staged_packets(peer); -- } -- -- keep_key_fresh(peer); -- -- wg_timers_any_authenticated_packet_received(peer); -- wg_timers_any_authenticated_packet_traversal(peer); -- -- /* A packet with length 0 is a keepalive packet */ -- if (unlikely(!skb->len)) { -- update_rx_stats(peer, message_data_len(0)); -- net_dbg_ratelimited("%s: Receiving keepalive packet from peer %llu (%pISpfsc)\n", -- dev->name, peer->internal_id, -- &peer->endpoint.addr); -- goto packet_processed; -- } -- -- wg_timers_data_received(peer); -- -- if (unlikely(skb_network_header(skb) < skb->head)) -- goto dishonest_packet_size; -- if (unlikely(!(pskb_network_may_pull(skb, sizeof(struct iphdr)) && -- (ip_hdr(skb)->version == 4 || -- (ip_hdr(skb)->version == 6 && -- pskb_network_may_pull(skb, sizeof(struct ipv6hdr))))))) -- goto dishonest_packet_type; -- -- skb->dev = dev; -- /* We've already verified the Poly1305 auth tag, which means this packet -- * was not modified in transit. We can therefore tell the networking -- * stack that all checksums of every layer of encapsulation have already -- * been checked "by the hardware" and therefore is unnecessary to check -- * again in software. -- */ -- skb->ip_summed = CHECKSUM_UNNECESSARY; -- skb->csum_level = ~0; /* All levels */ -- skb->protocol = ip_tunnel_parse_protocol(skb); -- if (skb->protocol == htons(ETH_P_IP)) { -- len = ntohs(ip_hdr(skb)->tot_len); -- if (unlikely(len < sizeof(struct iphdr))) -- goto dishonest_packet_size; -- INET_ECN_decapsulate(skb, PACKET_CB(skb)->ds, ip_hdr(skb)->tos); -- } else if (skb->protocol == htons(ETH_P_IPV6)) { -- len = ntohs(ipv6_hdr(skb)->payload_len) + -- sizeof(struct ipv6hdr); -- INET_ECN_decapsulate(skb, PACKET_CB(skb)->ds, ipv6_get_dsfield(ipv6_hdr(skb))); -- } else { -- goto dishonest_packet_type; -- } -- -- if (unlikely(len > skb->len)) -- goto dishonest_packet_size; -- len_before_trim = skb->len; -- if (unlikely(pskb_trim(skb, len))) -- goto packet_processed; -- -- routed_peer = wg_allowedips_lookup_src(&peer->device->peer_allowedips, -- skb); -- wg_peer_put(routed_peer); /* We don't need the extra reference. */ -- -- if (unlikely(routed_peer != peer)) -- goto dishonest_packet_peer; -- -- napi_gro_receive(&peer->napi, skb); -- update_rx_stats(peer, message_data_len(len_before_trim)); -- return; -- --dishonest_packet_peer: -- net_dbg_skb_ratelimited("%s: Packet has unallowed src IP (%pISc) from peer %llu (%pISpfsc)\n", -- dev->name, skb, peer->internal_id, -- &peer->endpoint.addr); -- ++dev->stats.rx_errors; -- ++dev->stats.rx_frame_errors; -- goto packet_processed; --dishonest_packet_type: -- net_dbg_ratelimited("%s: Packet is neither ipv4 nor ipv6 from peer %llu (%pISpfsc)\n", -- dev->name, peer->internal_id, &peer->endpoint.addr); -- ++dev->stats.rx_errors; -- ++dev->stats.rx_frame_errors; -- goto packet_processed; --dishonest_packet_size: -- net_dbg_ratelimited("%s: Packet has incorrect size from peer %llu (%pISpfsc)\n", -- dev->name, peer->internal_id, &peer->endpoint.addr); -- ++dev->stats.rx_errors; -- ++dev->stats.rx_length_errors; -- goto packet_processed; --packet_processed: -- dev_kfree_skb(skb); --} -- --int wg_packet_rx_poll(struct napi_struct *napi, int budget) --{ -- struct wg_peer *peer = container_of(napi, struct wg_peer, napi); -- struct crypt_queue *queue = &peer->rx_queue; -- struct noise_keypair *keypair; -- struct endpoint endpoint; -- enum packet_state state; -- struct sk_buff *skb; -- int work_done = 0; -- bool free; -- -- if (unlikely(budget <= 0)) -- return 0; -- -- while ((skb = __ptr_ring_peek(&queue->ring)) != NULL && -- (state = atomic_read_acquire(&PACKET_CB(skb)->state)) != -- PACKET_STATE_UNCRYPTED) { -- __ptr_ring_discard_one(&queue->ring); -- peer = PACKET_PEER(skb); -- keypair = PACKET_CB(skb)->keypair; -- free = true; -- -- if (unlikely(state != PACKET_STATE_CRYPTED)) -- goto next; -- -- if (unlikely(!counter_validate(&keypair->receiving_counter, -- PACKET_CB(skb)->nonce))) { -- net_dbg_ratelimited("%s: Packet has invalid nonce %llu (max %llu)\n", -- peer->device->dev->name, -- PACKET_CB(skb)->nonce, -- keypair->receiving_counter.counter); -- goto next; -- } -- -- if (unlikely(wg_socket_endpoint_from_skb(&endpoint, skb))) -- goto next; -- -- wg_reset_packet(skb, false); -- wg_packet_consume_data_done(peer, skb, &endpoint); -- free = false; -- --next: -- wg_noise_keypair_put(keypair, false); -- wg_peer_put(peer); -- if (unlikely(free)) -- dev_kfree_skb(skb); -- -- if (++work_done >= budget) -- break; -- } -- -- if (work_done < budget) -- napi_complete_done(napi, work_done); -- -- return work_done; --} -- --void wg_packet_decrypt_worker(struct work_struct *work) --{ -- struct crypt_queue *queue = container_of(work, struct multicore_worker, -- work)->ptr; -- struct sk_buff *skb; -- -- while ((skb = ptr_ring_consume_bh(&queue->ring)) != NULL) { -- enum packet_state state = -- likely(decrypt_packet(skb, PACKET_CB(skb)->keypair)) ? -- PACKET_STATE_CRYPTED : PACKET_STATE_DEAD; -- wg_queue_enqueue_per_peer_napi(skb, state); -- if (need_resched()) -- cond_resched(); -- } --} -- --static void wg_packet_consume_data(struct wg_device *wg, struct sk_buff *skb) --{ -- __le32 idx = ((struct message_data *)skb->data)->key_idx; -- struct wg_peer *peer = NULL; -- int ret; -- -- rcu_read_lock_bh(); -- PACKET_CB(skb)->keypair = -- (struct noise_keypair *)wg_index_hashtable_lookup( -- wg->index_hashtable, INDEX_HASHTABLE_KEYPAIR, idx, -- &peer); -- if (unlikely(!wg_noise_keypair_get(PACKET_CB(skb)->keypair))) -- goto err_keypair; -- -- if (unlikely(READ_ONCE(peer->is_dead))) -- goto err; -- -- ret = wg_queue_enqueue_per_device_and_peer(&wg->decrypt_queue, -- &peer->rx_queue, skb, -- wg->packet_crypt_wq, -- &wg->decrypt_queue.last_cpu); -- if (unlikely(ret == -EPIPE)) -- wg_queue_enqueue_per_peer_napi(skb, PACKET_STATE_DEAD); -- if (likely(!ret || ret == -EPIPE)) { -- rcu_read_unlock_bh(); -- return; -- } --err: -- wg_noise_keypair_put(PACKET_CB(skb)->keypair, false); --err_keypair: -- rcu_read_unlock_bh(); -- wg_peer_put(peer); -- dev_kfree_skb(skb); --} -- --void wg_packet_receive(struct wg_device *wg, struct sk_buff *skb) --{ -- if (unlikely(prepare_skb_header(skb, wg) < 0)) -- goto err; -- switch (SKB_TYPE_LE32(skb)) { -- case cpu_to_le32(MESSAGE_HANDSHAKE_INITIATION): -- case cpu_to_le32(MESSAGE_HANDSHAKE_RESPONSE): -- case cpu_to_le32(MESSAGE_HANDSHAKE_COOKIE): { -- int cpu; -- -- if (skb_queue_len(&wg->incoming_handshakes) > -- MAX_QUEUED_INCOMING_HANDSHAKES || -- unlikely(!rng_is_initialized())) { -- net_dbg_skb_ratelimited("%s: Dropping handshake packet from %pISpfsc\n", -- wg->dev->name, skb); -- goto err; -- } -- skb_queue_tail(&wg->incoming_handshakes, skb); -- /* Queues up a call to packet_process_queued_handshake_ -- * packets(skb): -- */ -- cpu = wg_cpumask_next_online(&wg->incoming_handshake_cpu); -- queue_work_on(cpu, wg->handshake_receive_wq, -- &per_cpu_ptr(wg->incoming_handshakes_worker, cpu)->work); -- break; -- } -- case cpu_to_le32(MESSAGE_DATA): -- PACKET_CB(skb)->ds = ip_tunnel_get_dsfield(ip_hdr(skb), skb); -- wg_packet_consume_data(wg, skb); -- break; -- default: -- WARN(1, "Non-exhaustive parsing of packet header lead to unknown packet type!\n"); -- goto err; -- } -- return; -- --err: -- dev_kfree_skb(skb); --} -diff --git a/drivers/net/wireguard/selftest/allowedips.c b/drivers/net/wireguard/selftest/allowedips.c -deleted file mode 100644 -index 846db14cb..000000000 ---- a/drivers/net/wireguard/selftest/allowedips.c -+++ /dev/null -@@ -1,683 +0,0 @@ --// SPDX-License-Identifier: GPL-2.0 --/* -- * Copyright (C) 2015-2019 Jason A. Donenfeld . All Rights Reserved. -- * -- * This contains some basic static unit tests for the allowedips data structure. -- * It also has two additional modes that are disabled and meant to be used by -- * folks directly playing with this file. If you define the macro -- * DEBUG_PRINT_TRIE_GRAPHVIZ to be 1, then every time there's a full tree in -- * memory, it will be printed out as KERN_DEBUG in a format that can be passed -- * to graphviz (the dot command) to visualize it. If you define the macro -- * DEBUG_RANDOM_TRIE to be 1, then there will be an extremely costly set of -- * randomized tests done against a trivial implementation, which may take -- * upwards of a half-hour to complete. There's no set of users who should be -- * enabling these, and the only developers that should go anywhere near these -- * nobs are the ones who are reading this comment. -- */ -- --#ifdef DEBUG -- --#include -- --static __init void swap_endian_and_apply_cidr(u8 *dst, const u8 *src, u8 bits, -- u8 cidr) --{ -- swap_endian(dst, src, bits); -- memset(dst + (cidr + 7) / 8, 0, bits / 8 - (cidr + 7) / 8); -- if (cidr) -- dst[(cidr + 7) / 8 - 1] &= ~0U << ((8 - (cidr % 8)) % 8); --} -- --static __init void print_node(struct allowedips_node *node, u8 bits) --{ -- char *fmt_connection = KERN_DEBUG "\t\"%p/%d\" -> \"%p/%d\";\n"; -- char *fmt_declaration = KERN_DEBUG -- "\t\"%p/%d\"[style=%s, color=\"#%06x\"];\n"; -- char *style = "dotted"; -- u8 ip1[16], ip2[16]; -- u32 color = 0; -- -- if (bits == 32) { -- fmt_connection = KERN_DEBUG "\t\"%pI4/%d\" -> \"%pI4/%d\";\n"; -- fmt_declaration = KERN_DEBUG -- "\t\"%pI4/%d\"[style=%s, color=\"#%06x\"];\n"; -- } else if (bits == 128) { -- fmt_connection = KERN_DEBUG "\t\"%pI6/%d\" -> \"%pI6/%d\";\n"; -- fmt_declaration = KERN_DEBUG -- "\t\"%pI6/%d\"[style=%s, color=\"#%06x\"];\n"; -- } -- if (node->peer) { -- hsiphash_key_t key = { { 0 } }; -- -- memcpy(&key, &node->peer, sizeof(node->peer)); -- color = hsiphash_1u32(0xdeadbeef, &key) % 200 << 16 | -- hsiphash_1u32(0xbabecafe, &key) % 200 << 8 | -- hsiphash_1u32(0xabad1dea, &key) % 200; -- style = "bold"; -- } -- swap_endian_and_apply_cidr(ip1, node->bits, bits, node->cidr); -- printk(fmt_declaration, ip1, node->cidr, style, color); -- if (node->bit[0]) { -- swap_endian_and_apply_cidr(ip2, -- rcu_dereference_raw(node->bit[0])->bits, bits, -- node->cidr); -- printk(fmt_connection, ip1, node->cidr, ip2, -- rcu_dereference_raw(node->bit[0])->cidr); -- print_node(rcu_dereference_raw(node->bit[0]), bits); -- } -- if (node->bit[1]) { -- swap_endian_and_apply_cidr(ip2, -- rcu_dereference_raw(node->bit[1])->bits, -- bits, node->cidr); -- printk(fmt_connection, ip1, node->cidr, ip2, -- rcu_dereference_raw(node->bit[1])->cidr); -- print_node(rcu_dereference_raw(node->bit[1]), bits); -- } --} -- --static __init void print_tree(struct allowedips_node __rcu *top, u8 bits) --{ -- printk(KERN_DEBUG "digraph trie {\n"); -- print_node(rcu_dereference_raw(top), bits); -- printk(KERN_DEBUG "}\n"); --} -- --enum { -- NUM_PEERS = 2000, -- NUM_RAND_ROUTES = 400, -- NUM_MUTATED_ROUTES = 100, -- NUM_QUERIES = NUM_RAND_ROUTES * NUM_MUTATED_ROUTES * 30 --}; -- --struct horrible_allowedips { -- struct hlist_head head; --}; -- --struct horrible_allowedips_node { -- struct hlist_node table; -- union nf_inet_addr ip; -- union nf_inet_addr mask; -- u8 ip_version; -- void *value; --}; -- --static __init void horrible_allowedips_init(struct horrible_allowedips *table) --{ -- INIT_HLIST_HEAD(&table->head); --} -- --static __init void horrible_allowedips_free(struct horrible_allowedips *table) --{ -- struct horrible_allowedips_node *node; -- struct hlist_node *h; -- -- hlist_for_each_entry_safe(node, h, &table->head, table) { -- hlist_del(&node->table); -- kfree(node); -- } --} -- --static __init inline union nf_inet_addr horrible_cidr_to_mask(u8 cidr) --{ -- union nf_inet_addr mask; -- -- memset(&mask, 0x00, 128 / 8); -- memset(&mask, 0xff, cidr / 8); -- if (cidr % 32) -- mask.all[cidr / 32] = (__force u32)htonl( -- (0xFFFFFFFFUL << (32 - (cidr % 32))) & 0xFFFFFFFFUL); -- return mask; --} -- --static __init inline u8 horrible_mask_to_cidr(union nf_inet_addr subnet) --{ -- return hweight32(subnet.all[0]) + hweight32(subnet.all[1]) + -- hweight32(subnet.all[2]) + hweight32(subnet.all[3]); --} -- --static __init inline void --horrible_mask_self(struct horrible_allowedips_node *node) --{ -- if (node->ip_version == 4) { -- node->ip.ip &= node->mask.ip; -- } else if (node->ip_version == 6) { -- node->ip.ip6[0] &= node->mask.ip6[0]; -- node->ip.ip6[1] &= node->mask.ip6[1]; -- node->ip.ip6[2] &= node->mask.ip6[2]; -- node->ip.ip6[3] &= node->mask.ip6[3]; -- } --} -- --static __init inline bool --horrible_match_v4(const struct horrible_allowedips_node *node, -- struct in_addr *ip) --{ -- return (ip->s_addr & node->mask.ip) == node->ip.ip; --} -- --static __init inline bool --horrible_match_v6(const struct horrible_allowedips_node *node, -- struct in6_addr *ip) --{ -- return (ip->in6_u.u6_addr32[0] & node->mask.ip6[0]) == -- node->ip.ip6[0] && -- (ip->in6_u.u6_addr32[1] & node->mask.ip6[1]) == -- node->ip.ip6[1] && -- (ip->in6_u.u6_addr32[2] & node->mask.ip6[2]) == -- node->ip.ip6[2] && -- (ip->in6_u.u6_addr32[3] & node->mask.ip6[3]) == node->ip.ip6[3]; --} -- --static __init void --horrible_insert_ordered(struct horrible_allowedips *table, -- struct horrible_allowedips_node *node) --{ -- struct horrible_allowedips_node *other = NULL, *where = NULL; -- u8 my_cidr = horrible_mask_to_cidr(node->mask); -- -- hlist_for_each_entry(other, &table->head, table) { -- if (!memcmp(&other->mask, &node->mask, -- sizeof(union nf_inet_addr)) && -- !memcmp(&other->ip, &node->ip, -- sizeof(union nf_inet_addr)) && -- other->ip_version == node->ip_version) { -- other->value = node->value; -- kfree(node); -- return; -- } -- where = other; -- if (horrible_mask_to_cidr(other->mask) <= my_cidr) -- break; -- } -- if (!other && !where) -- hlist_add_head(&node->table, &table->head); -- else if (!other) -- hlist_add_behind(&node->table, &where->table); -- else -- hlist_add_before(&node->table, &where->table); --} -- --static __init int --horrible_allowedips_insert_v4(struct horrible_allowedips *table, -- struct in_addr *ip, u8 cidr, void *value) --{ -- struct horrible_allowedips_node *node = kzalloc(sizeof(*node), -- GFP_KERNEL); -- -- if (unlikely(!node)) -- return -ENOMEM; -- node->ip.in = *ip; -- node->mask = horrible_cidr_to_mask(cidr); -- node->ip_version = 4; -- node->value = value; -- horrible_mask_self(node); -- horrible_insert_ordered(table, node); -- return 0; --} -- --static __init int --horrible_allowedips_insert_v6(struct horrible_allowedips *table, -- struct in6_addr *ip, u8 cidr, void *value) --{ -- struct horrible_allowedips_node *node = kzalloc(sizeof(*node), -- GFP_KERNEL); -- -- if (unlikely(!node)) -- return -ENOMEM; -- node->ip.in6 = *ip; -- node->mask = horrible_cidr_to_mask(cidr); -- node->ip_version = 6; -- node->value = value; -- horrible_mask_self(node); -- horrible_insert_ordered(table, node); -- return 0; --} -- --static __init void * --horrible_allowedips_lookup_v4(struct horrible_allowedips *table, -- struct in_addr *ip) --{ -- struct horrible_allowedips_node *node; -- void *ret = NULL; -- -- hlist_for_each_entry(node, &table->head, table) { -- if (node->ip_version != 4) -- continue; -- if (horrible_match_v4(node, ip)) { -- ret = node->value; -- break; -- } -- } -- return ret; --} -- --static __init void * --horrible_allowedips_lookup_v6(struct horrible_allowedips *table, -- struct in6_addr *ip) --{ -- struct horrible_allowedips_node *node; -- void *ret = NULL; -- -- hlist_for_each_entry(node, &table->head, table) { -- if (node->ip_version != 6) -- continue; -- if (horrible_match_v6(node, ip)) { -- ret = node->value; -- break; -- } -- } -- return ret; --} -- --static __init bool randomized_test(void) --{ -- unsigned int i, j, k, mutate_amount, cidr; -- u8 ip[16], mutate_mask[16], mutated[16]; -- struct wg_peer **peers, *peer; -- struct horrible_allowedips h; -- DEFINE_MUTEX(mutex); -- struct allowedips t; -- bool ret = false; -- -- mutex_init(&mutex); -- -- wg_allowedips_init(&t); -- horrible_allowedips_init(&h); -- -- peers = kcalloc(NUM_PEERS, sizeof(*peers), GFP_KERNEL); -- if (unlikely(!peers)) { -- pr_err("allowedips random self-test malloc: FAIL\n"); -- goto free; -- } -- for (i = 0; i < NUM_PEERS; ++i) { -- peers[i] = kzalloc(sizeof(*peers[i]), GFP_KERNEL); -- if (unlikely(!peers[i])) { -- pr_err("allowedips random self-test malloc: FAIL\n"); -- goto free; -- } -- kref_init(&peers[i]->refcount); -- } -- -- mutex_lock(&mutex); -- -- for (i = 0; i < NUM_RAND_ROUTES; ++i) { -- prandom_bytes(ip, 4); -- cidr = prandom_u32_max(32) + 1; -- peer = peers[prandom_u32_max(NUM_PEERS)]; -- if (wg_allowedips_insert_v4(&t, (struct in_addr *)ip, cidr, -- peer, &mutex) < 0) { -- pr_err("allowedips random self-test malloc: FAIL\n"); -- goto free_locked; -- } -- if (horrible_allowedips_insert_v4(&h, (struct in_addr *)ip, -- cidr, peer) < 0) { -- pr_err("allowedips random self-test malloc: FAIL\n"); -- goto free_locked; -- } -- for (j = 0; j < NUM_MUTATED_ROUTES; ++j) { -- memcpy(mutated, ip, 4); -- prandom_bytes(mutate_mask, 4); -- mutate_amount = prandom_u32_max(32); -- for (k = 0; k < mutate_amount / 8; ++k) -- mutate_mask[k] = 0xff; -- mutate_mask[k] = 0xff -- << ((8 - (mutate_amount % 8)) % 8); -- for (; k < 4; ++k) -- mutate_mask[k] = 0; -- for (k = 0; k < 4; ++k) -- mutated[k] = (mutated[k] & mutate_mask[k]) | -- (~mutate_mask[k] & -- prandom_u32_max(256)); -- cidr = prandom_u32_max(32) + 1; -- peer = peers[prandom_u32_max(NUM_PEERS)]; -- if (wg_allowedips_insert_v4(&t, -- (struct in_addr *)mutated, -- cidr, peer, &mutex) < 0) { -- pr_err("allowedips random malloc: FAIL\n"); -- goto free_locked; -- } -- if (horrible_allowedips_insert_v4(&h, -- (struct in_addr *)mutated, cidr, peer)) { -- pr_err("allowedips random self-test malloc: FAIL\n"); -- goto free_locked; -- } -- } -- } -- -- for (i = 0; i < NUM_RAND_ROUTES; ++i) { -- prandom_bytes(ip, 16); -- cidr = prandom_u32_max(128) + 1; -- peer = peers[prandom_u32_max(NUM_PEERS)]; -- if (wg_allowedips_insert_v6(&t, (struct in6_addr *)ip, cidr, -- peer, &mutex) < 0) { -- pr_err("allowedips random self-test malloc: FAIL\n"); -- goto free_locked; -- } -- if (horrible_allowedips_insert_v6(&h, (struct in6_addr *)ip, -- cidr, peer) < 0) { -- pr_err("allowedips random self-test malloc: FAIL\n"); -- goto free_locked; -- } -- for (j = 0; j < NUM_MUTATED_ROUTES; ++j) { -- memcpy(mutated, ip, 16); -- prandom_bytes(mutate_mask, 16); -- mutate_amount = prandom_u32_max(128); -- for (k = 0; k < mutate_amount / 8; ++k) -- mutate_mask[k] = 0xff; -- mutate_mask[k] = 0xff -- << ((8 - (mutate_amount % 8)) % 8); -- for (; k < 4; ++k) -- mutate_mask[k] = 0; -- for (k = 0; k < 4; ++k) -- mutated[k] = (mutated[k] & mutate_mask[k]) | -- (~mutate_mask[k] & -- prandom_u32_max(256)); -- cidr = prandom_u32_max(128) + 1; -- peer = peers[prandom_u32_max(NUM_PEERS)]; -- if (wg_allowedips_insert_v6(&t, -- (struct in6_addr *)mutated, -- cidr, peer, &mutex) < 0) { -- pr_err("allowedips random self-test malloc: FAIL\n"); -- goto free_locked; -- } -- if (horrible_allowedips_insert_v6( -- &h, (struct in6_addr *)mutated, cidr, -- peer)) { -- pr_err("allowedips random self-test malloc: FAIL\n"); -- goto free_locked; -- } -- } -- } -- -- mutex_unlock(&mutex); -- -- if (IS_ENABLED(DEBUG_PRINT_TRIE_GRAPHVIZ)) { -- print_tree(t.root4, 32); -- print_tree(t.root6, 128); -- } -- -- for (i = 0; i < NUM_QUERIES; ++i) { -- prandom_bytes(ip, 4); -- if (lookup(t.root4, 32, ip) != -- horrible_allowedips_lookup_v4(&h, (struct in_addr *)ip)) { -- pr_err("allowedips random self-test: FAIL\n"); -- goto free; -- } -- } -- -- for (i = 0; i < NUM_QUERIES; ++i) { -- prandom_bytes(ip, 16); -- if (lookup(t.root6, 128, ip) != -- horrible_allowedips_lookup_v6(&h, (struct in6_addr *)ip)) { -- pr_err("allowedips random self-test: FAIL\n"); -- goto free; -- } -- } -- ret = true; -- --free: -- mutex_lock(&mutex); --free_locked: -- wg_allowedips_free(&t, &mutex); -- mutex_unlock(&mutex); -- horrible_allowedips_free(&h); -- if (peers) { -- for (i = 0; i < NUM_PEERS; ++i) -- kfree(peers[i]); -- } -- kfree(peers); -- return ret; --} -- --static __init inline struct in_addr *ip4(u8 a, u8 b, u8 c, u8 d) --{ -- static struct in_addr ip; -- u8 *split = (u8 *)&ip; -- -- split[0] = a; -- split[1] = b; -- split[2] = c; -- split[3] = d; -- return &ip; --} -- --static __init inline struct in6_addr *ip6(u32 a, u32 b, u32 c, u32 d) --{ -- static struct in6_addr ip; -- __be32 *split = (__be32 *)&ip; -- -- split[0] = cpu_to_be32(a); -- split[1] = cpu_to_be32(b); -- split[2] = cpu_to_be32(c); -- split[3] = cpu_to_be32(d); -- return &ip; --} -- --static __init struct wg_peer *init_peer(void) --{ -- struct wg_peer *peer = kzalloc(sizeof(*peer), GFP_KERNEL); -- -- if (!peer) -- return NULL; -- kref_init(&peer->refcount); -- INIT_LIST_HEAD(&peer->allowedips_list); -- return peer; --} -- --#define insert(version, mem, ipa, ipb, ipc, ipd, cidr) \ -- wg_allowedips_insert_v##version(&t, ip##version(ipa, ipb, ipc, ipd), \ -- cidr, mem, &mutex) -- --#define maybe_fail() do { \ -- ++i; \ -- if (!_s) { \ -- pr_info("allowedips self-test %zu: FAIL\n", i); \ -- success = false; \ -- } \ -- } while (0) -- --#define test(version, mem, ipa, ipb, ipc, ipd) do { \ -- bool _s = lookup(t.root##version, (version) == 4 ? 32 : 128, \ -- ip##version(ipa, ipb, ipc, ipd)) == (mem); \ -- maybe_fail(); \ -- } while (0) -- --#define test_negative(version, mem, ipa, ipb, ipc, ipd) do { \ -- bool _s = lookup(t.root##version, (version) == 4 ? 32 : 128, \ -- ip##version(ipa, ipb, ipc, ipd)) != (mem); \ -- maybe_fail(); \ -- } while (0) -- --#define test_boolean(cond) do { \ -- bool _s = (cond); \ -- maybe_fail(); \ -- } while (0) -- --bool __init wg_allowedips_selftest(void) --{ -- bool found_a = false, found_b = false, found_c = false, found_d = false, -- found_e = false, found_other = false; -- struct wg_peer *a = init_peer(), *b = init_peer(), *c = init_peer(), -- *d = init_peer(), *e = init_peer(), *f = init_peer(), -- *g = init_peer(), *h = init_peer(); -- struct allowedips_node *iter_node; -- bool success = false; -- struct allowedips t; -- DEFINE_MUTEX(mutex); -- struct in6_addr ip; -- size_t i = 0, count = 0; -- __be64 part; -- -- mutex_init(&mutex); -- mutex_lock(&mutex); -- wg_allowedips_init(&t); -- -- if (!a || !b || !c || !d || !e || !f || !g || !h) { -- pr_err("allowedips self-test malloc: FAIL\n"); -- goto free; -- } -- -- insert(4, a, 192, 168, 4, 0, 24); -- insert(4, b, 192, 168, 4, 4, 32); -- insert(4, c, 192, 168, 0, 0, 16); -- insert(4, d, 192, 95, 5, 64, 27); -- /* replaces previous entry, and maskself is required */ -- insert(4, c, 192, 95, 5, 65, 27); -- insert(6, d, 0x26075300, 0x60006b00, 0, 0xc05f0543, 128); -- insert(6, c, 0x26075300, 0x60006b00, 0, 0, 64); -- insert(4, e, 0, 0, 0, 0, 0); -- insert(6, e, 0, 0, 0, 0, 0); -- /* replaces previous entry */ -- insert(6, f, 0, 0, 0, 0, 0); -- insert(6, g, 0x24046800, 0, 0, 0, 32); -- /* maskself is required */ -- insert(6, h, 0x24046800, 0x40040800, 0xdeadbeef, 0xdeadbeef, 64); -- insert(6, a, 0x24046800, 0x40040800, 0xdeadbeef, 0xdeadbeef, 128); -- insert(6, c, 0x24446800, 0x40e40800, 0xdeaebeef, 0xdefbeef, 128); -- insert(6, b, 0x24446800, 0xf0e40800, 0xeeaebeef, 0, 98); -- insert(4, g, 64, 15, 112, 0, 20); -- /* maskself is required */ -- insert(4, h, 64, 15, 123, 211, 25); -- insert(4, a, 10, 0, 0, 0, 25); -- insert(4, b, 10, 0, 0, 128, 25); -- insert(4, a, 10, 1, 0, 0, 30); -- insert(4, b, 10, 1, 0, 4, 30); -- insert(4, c, 10, 1, 0, 8, 29); -- insert(4, d, 10, 1, 0, 16, 29); -- -- if (IS_ENABLED(DEBUG_PRINT_TRIE_GRAPHVIZ)) { -- print_tree(t.root4, 32); -- print_tree(t.root6, 128); -- } -- -- success = true; -- -- test(4, a, 192, 168, 4, 20); -- test(4, a, 192, 168, 4, 0); -- test(4, b, 192, 168, 4, 4); -- test(4, c, 192, 168, 200, 182); -- test(4, c, 192, 95, 5, 68); -- test(4, e, 192, 95, 5, 96); -- test(6, d, 0x26075300, 0x60006b00, 0, 0xc05f0543); -- test(6, c, 0x26075300, 0x60006b00, 0, 0xc02e01ee); -- test(6, f, 0x26075300, 0x60006b01, 0, 0); -- test(6, g, 0x24046800, 0x40040806, 0, 0x1006); -- test(6, g, 0x24046800, 0x40040806, 0x1234, 0x5678); -- test(6, f, 0x240467ff, 0x40040806, 0x1234, 0x5678); -- test(6, f, 0x24046801, 0x40040806, 0x1234, 0x5678); -- test(6, h, 0x24046800, 0x40040800, 0x1234, 0x5678); -- test(6, h, 0x24046800, 0x40040800, 0, 0); -- test(6, h, 0x24046800, 0x40040800, 0x10101010, 0x10101010); -- test(6, a, 0x24046800, 0x40040800, 0xdeadbeef, 0xdeadbeef); -- test(4, g, 64, 15, 116, 26); -- test(4, g, 64, 15, 127, 3); -- test(4, g, 64, 15, 123, 1); -- test(4, h, 64, 15, 123, 128); -- test(4, h, 64, 15, 123, 129); -- test(4, a, 10, 0, 0, 52); -- test(4, b, 10, 0, 0, 220); -- test(4, a, 10, 1, 0, 2); -- test(4, b, 10, 1, 0, 6); -- test(4, c, 10, 1, 0, 10); -- test(4, d, 10, 1, 0, 20); -- -- insert(4, a, 1, 0, 0, 0, 32); -- insert(4, a, 64, 0, 0, 0, 32); -- insert(4, a, 128, 0, 0, 0, 32); -- insert(4, a, 192, 0, 0, 0, 32); -- insert(4, a, 255, 0, 0, 0, 32); -- wg_allowedips_remove_by_peer(&t, a, &mutex); -- test_negative(4, a, 1, 0, 0, 0); -- test_negative(4, a, 64, 0, 0, 0); -- test_negative(4, a, 128, 0, 0, 0); -- test_negative(4, a, 192, 0, 0, 0); -- test_negative(4, a, 255, 0, 0, 0); -- -- wg_allowedips_free(&t, &mutex); -- wg_allowedips_init(&t); -- insert(4, a, 192, 168, 0, 0, 16); -- insert(4, a, 192, 168, 0, 0, 24); -- wg_allowedips_remove_by_peer(&t, a, &mutex); -- test_negative(4, a, 192, 168, 0, 1); -- -- /* These will hit the WARN_ON(len >= 128) in free_node if something -- * goes wrong. -- */ -- for (i = 0; i < 128; ++i) { -- part = cpu_to_be64(~(1LLU << (i % 64))); -- memset(&ip, 0xff, 16); -- memcpy((u8 *)&ip + (i < 64) * 8, &part, 8); -- wg_allowedips_insert_v6(&t, &ip, 128, a, &mutex); -- } -- -- wg_allowedips_free(&t, &mutex); -- -- wg_allowedips_init(&t); -- insert(4, a, 192, 95, 5, 93, 27); -- insert(6, a, 0x26075300, 0x60006b00, 0, 0xc05f0543, 128); -- insert(4, a, 10, 1, 0, 20, 29); -- insert(6, a, 0x26075300, 0x6d8a6bf8, 0xdab1f1df, 0xc05f1523, 83); -- insert(6, a, 0x26075300, 0x6d8a6bf8, 0xdab1f1df, 0xc05f1523, 21); -- list_for_each_entry(iter_node, &a->allowedips_list, peer_list) { -- u8 cidr, ip[16] __aligned(__alignof(u64)); -- int family = wg_allowedips_read_node(iter_node, ip, &cidr); -- -- count++; -- -- if (cidr == 27 && family == AF_INET && -- !memcmp(ip, ip4(192, 95, 5, 64), sizeof(struct in_addr))) -- found_a = true; -- else if (cidr == 128 && family == AF_INET6 && -- !memcmp(ip, ip6(0x26075300, 0x60006b00, 0, 0xc05f0543), -- sizeof(struct in6_addr))) -- found_b = true; -- else if (cidr == 29 && family == AF_INET && -- !memcmp(ip, ip4(10, 1, 0, 16), sizeof(struct in_addr))) -- found_c = true; -- else if (cidr == 83 && family == AF_INET6 && -- !memcmp(ip, ip6(0x26075300, 0x6d8a6bf8, 0xdab1e000, 0), -- sizeof(struct in6_addr))) -- found_d = true; -- else if (cidr == 21 && family == AF_INET6 && -- !memcmp(ip, ip6(0x26075000, 0, 0, 0), -- sizeof(struct in6_addr))) -- found_e = true; -- else -- found_other = true; -- } -- test_boolean(count == 5); -- test_boolean(found_a); -- test_boolean(found_b); -- test_boolean(found_c); -- test_boolean(found_d); -- test_boolean(found_e); -- test_boolean(!found_other); -- -- if (IS_ENABLED(DEBUG_RANDOM_TRIE) && success) -- success = randomized_test(); -- -- if (success) -- pr_info("allowedips self-tests: pass\n"); -- --free: -- wg_allowedips_free(&t, &mutex); -- kfree(a); -- kfree(b); -- kfree(c); -- kfree(d); -- kfree(e); -- kfree(f); -- kfree(g); -- kfree(h); -- mutex_unlock(&mutex); -- -- return success; --} -- --#undef test_negative --#undef test --#undef remove --#undef insert --#undef init_peer -- --#endif -diff --git a/drivers/net/wireguard/selftest/counter.c b/drivers/net/wireguard/selftest/counter.c -deleted file mode 100644 -index ec3c156bf..000000000 ---- a/drivers/net/wireguard/selftest/counter.c -+++ /dev/null -@@ -1,111 +0,0 @@ --// SPDX-License-Identifier: GPL-2.0 --/* -- * Copyright (C) 2015-2019 Jason A. Donenfeld . All Rights Reserved. -- */ -- --#ifdef DEBUG --bool __init wg_packet_counter_selftest(void) --{ -- struct noise_replay_counter *counter; -- unsigned int test_num = 0, i; -- bool success = true; -- -- counter = kmalloc(sizeof(*counter), GFP_KERNEL); -- if (unlikely(!counter)) { -- pr_err("nonce counter self-test malloc: FAIL\n"); -- return false; -- } -- --#define T_INIT do { \ -- memset(counter, 0, sizeof(*counter)); \ -- spin_lock_init(&counter->lock); \ -- } while (0) --#define T_LIM (COUNTER_WINDOW_SIZE + 1) --#define T(n, v) do { \ -- ++test_num; \ -- if (counter_validate(counter, n) != (v)) { \ -- pr_err("nonce counter self-test %u: FAIL\n", \ -- test_num); \ -- success = false; \ -- } \ -- } while (0) -- -- T_INIT; -- /* 1 */ T(0, true); -- /* 2 */ T(1, true); -- /* 3 */ T(1, false); -- /* 4 */ T(9, true); -- /* 5 */ T(8, true); -- /* 6 */ T(7, true); -- /* 7 */ T(7, false); -- /* 8 */ T(T_LIM, true); -- /* 9 */ T(T_LIM - 1, true); -- /* 10 */ T(T_LIM - 1, false); -- /* 11 */ T(T_LIM - 2, true); -- /* 12 */ T(2, true); -- /* 13 */ T(2, false); -- /* 14 */ T(T_LIM + 16, true); -- /* 15 */ T(3, false); -- /* 16 */ T(T_LIM + 16, false); -- /* 17 */ T(T_LIM * 4, true); -- /* 18 */ T(T_LIM * 4 - (T_LIM - 1), true); -- /* 19 */ T(10, false); -- /* 20 */ T(T_LIM * 4 - T_LIM, false); -- /* 21 */ T(T_LIM * 4 - (T_LIM + 1), false); -- /* 22 */ T(T_LIM * 4 - (T_LIM - 2), true); -- /* 23 */ T(T_LIM * 4 + 1 - T_LIM, false); -- /* 24 */ T(0, false); -- /* 25 */ T(REJECT_AFTER_MESSAGES, false); -- /* 26 */ T(REJECT_AFTER_MESSAGES - 1, true); -- /* 27 */ T(REJECT_AFTER_MESSAGES, false); -- /* 28 */ T(REJECT_AFTER_MESSAGES - 1, false); -- /* 29 */ T(REJECT_AFTER_MESSAGES - 2, true); -- /* 30 */ T(REJECT_AFTER_MESSAGES + 1, false); -- /* 31 */ T(REJECT_AFTER_MESSAGES + 2, false); -- /* 32 */ T(REJECT_AFTER_MESSAGES - 2, false); -- /* 33 */ T(REJECT_AFTER_MESSAGES - 3, true); -- /* 34 */ T(0, false); -- -- T_INIT; -- for (i = 1; i <= COUNTER_WINDOW_SIZE; ++i) -- T(i, true); -- T(0, true); -- T(0, false); -- -- T_INIT; -- for (i = 2; i <= COUNTER_WINDOW_SIZE + 1; ++i) -- T(i, true); -- T(1, true); -- T(0, false); -- -- T_INIT; -- for (i = COUNTER_WINDOW_SIZE + 1; i-- > 0;) -- T(i, true); -- -- T_INIT; -- for (i = COUNTER_WINDOW_SIZE + 2; i-- > 1;) -- T(i, true); -- T(0, false); -- -- T_INIT; -- for (i = COUNTER_WINDOW_SIZE + 1; i-- > 1;) -- T(i, true); -- T(COUNTER_WINDOW_SIZE + 1, true); -- T(0, false); -- -- T_INIT; -- for (i = COUNTER_WINDOW_SIZE + 1; i-- > 1;) -- T(i, true); -- T(0, true); -- T(COUNTER_WINDOW_SIZE + 1, true); -- --#undef T --#undef T_LIM --#undef T_INIT -- -- if (success) -- pr_info("nonce counter self-tests: pass\n"); -- kfree(counter); -- return success; --} --#endif -diff --git a/drivers/net/wireguard/selftest/ratelimiter.c b/drivers/net/wireguard/selftest/ratelimiter.c -deleted file mode 100644 -index 007cd4457..000000000 ---- a/drivers/net/wireguard/selftest/ratelimiter.c -+++ /dev/null -@@ -1,226 +0,0 @@ --// SPDX-License-Identifier: GPL-2.0 --/* -- * Copyright (C) 2015-2019 Jason A. Donenfeld . All Rights Reserved. -- */ -- --#ifdef DEBUG -- --#include -- --static const struct { -- bool result; -- unsigned int msec_to_sleep_before; --} expected_results[] __initconst = { -- [0 ... PACKETS_BURSTABLE - 1] = { true, 0 }, -- [PACKETS_BURSTABLE] = { false, 0 }, -- [PACKETS_BURSTABLE + 1] = { true, MSEC_PER_SEC / PACKETS_PER_SECOND }, -- [PACKETS_BURSTABLE + 2] = { false, 0 }, -- [PACKETS_BURSTABLE + 3] = { true, (MSEC_PER_SEC / PACKETS_PER_SECOND) * 2 }, -- [PACKETS_BURSTABLE + 4] = { true, 0 }, -- [PACKETS_BURSTABLE + 5] = { false, 0 } --}; -- --static __init unsigned int maximum_jiffies_at_index(int index) --{ -- unsigned int total_msecs = 2 * MSEC_PER_SEC / PACKETS_PER_SECOND / 3; -- int i; -- -- for (i = 0; i <= index; ++i) -- total_msecs += expected_results[i].msec_to_sleep_before; -- return msecs_to_jiffies(total_msecs); --} -- --static __init int timings_test(struct sk_buff *skb4, struct iphdr *hdr4, -- struct sk_buff *skb6, struct ipv6hdr *hdr6, -- int *test) --{ -- unsigned long loop_start_time; -- int i; -- -- wg_ratelimiter_gc_entries(NULL); -- rcu_barrier(); -- loop_start_time = jiffies; -- -- for (i = 0; i < ARRAY_SIZE(expected_results); ++i) { -- if (expected_results[i].msec_to_sleep_before) -- msleep(expected_results[i].msec_to_sleep_before); -- -- if (time_is_before_jiffies(loop_start_time + -- maximum_jiffies_at_index(i))) -- return -ETIMEDOUT; -- if (wg_ratelimiter_allow(skb4, &init_net) != -- expected_results[i].result) -- return -EXFULL; -- ++(*test); -- -- hdr4->saddr = htonl(ntohl(hdr4->saddr) + i + 1); -- if (time_is_before_jiffies(loop_start_time + -- maximum_jiffies_at_index(i))) -- return -ETIMEDOUT; -- if (!wg_ratelimiter_allow(skb4, &init_net)) -- return -EXFULL; -- ++(*test); -- -- hdr4->saddr = htonl(ntohl(hdr4->saddr) - i - 1); -- --#if IS_ENABLED(CONFIG_IPV6) -- hdr6->saddr.in6_u.u6_addr32[2] = htonl(i); -- hdr6->saddr.in6_u.u6_addr32[3] = htonl(i); -- if (time_is_before_jiffies(loop_start_time + -- maximum_jiffies_at_index(i))) -- return -ETIMEDOUT; -- if (wg_ratelimiter_allow(skb6, &init_net) != -- expected_results[i].result) -- return -EXFULL; -- ++(*test); -- -- hdr6->saddr.in6_u.u6_addr32[0] = -- htonl(ntohl(hdr6->saddr.in6_u.u6_addr32[0]) + i + 1); -- if (time_is_before_jiffies(loop_start_time + -- maximum_jiffies_at_index(i))) -- return -ETIMEDOUT; -- if (!wg_ratelimiter_allow(skb6, &init_net)) -- return -EXFULL; -- ++(*test); -- -- hdr6->saddr.in6_u.u6_addr32[0] = -- htonl(ntohl(hdr6->saddr.in6_u.u6_addr32[0]) - i - 1); -- -- if (time_is_before_jiffies(loop_start_time + -- maximum_jiffies_at_index(i))) -- return -ETIMEDOUT; --#endif -- } -- return 0; --} -- --static __init int capacity_test(struct sk_buff *skb4, struct iphdr *hdr4, -- int *test) --{ -- int i; -- -- wg_ratelimiter_gc_entries(NULL); -- rcu_barrier(); -- -- if (atomic_read(&total_entries)) -- return -EXFULL; -- ++(*test); -- -- for (i = 0; i <= max_entries; ++i) { -- hdr4->saddr = htonl(i); -- if (wg_ratelimiter_allow(skb4, &init_net) != (i != max_entries)) -- return -EXFULL; -- ++(*test); -- } -- return 0; --} -- --bool __init wg_ratelimiter_selftest(void) --{ -- enum { TRIALS_BEFORE_GIVING_UP = 5000 }; -- bool success = false; -- int test = 0, trials; -- struct sk_buff *skb4, *skb6 = NULL; -- struct iphdr *hdr4; -- struct ipv6hdr *hdr6 = NULL; -- -- if (IS_ENABLED(CONFIG_KASAN) || IS_ENABLED(CONFIG_UBSAN)) -- return true; -- -- BUILD_BUG_ON(MSEC_PER_SEC % PACKETS_PER_SECOND != 0); -- -- if (wg_ratelimiter_init()) -- goto out; -- ++test; -- if (wg_ratelimiter_init()) { -- wg_ratelimiter_uninit(); -- goto out; -- } -- ++test; -- if (wg_ratelimiter_init()) { -- wg_ratelimiter_uninit(); -- wg_ratelimiter_uninit(); -- goto out; -- } -- ++test; -- -- skb4 = alloc_skb(sizeof(struct iphdr), GFP_KERNEL); -- if (unlikely(!skb4)) -- goto err_nofree; -- skb4->protocol = htons(ETH_P_IP); -- hdr4 = (struct iphdr *)skb_put(skb4, sizeof(*hdr4)); -- hdr4->saddr = htonl(8182); -- skb_reset_network_header(skb4); -- ++test; -- --#if IS_ENABLED(CONFIG_IPV6) -- skb6 = alloc_skb(sizeof(struct ipv6hdr), GFP_KERNEL); -- if (unlikely(!skb6)) { -- kfree_skb(skb4); -- goto err_nofree; -- } -- skb6->protocol = htons(ETH_P_IPV6); -- hdr6 = (struct ipv6hdr *)skb_put(skb6, sizeof(*hdr6)); -- hdr6->saddr.in6_u.u6_addr32[0] = htonl(1212); -- hdr6->saddr.in6_u.u6_addr32[1] = htonl(289188); -- skb_reset_network_header(skb6); -- ++test; --#endif -- -- for (trials = TRIALS_BEFORE_GIVING_UP;;) { -- int test_count = 0, ret; -- -- ret = timings_test(skb4, hdr4, skb6, hdr6, &test_count); -- if (ret == -ETIMEDOUT) { -- if (!trials--) { -- test += test_count; -- goto err; -- } -- msleep(500); -- continue; -- } else if (ret < 0) { -- test += test_count; -- goto err; -- } else { -- test += test_count; -- break; -- } -- } -- -- for (trials = TRIALS_BEFORE_GIVING_UP;;) { -- int test_count = 0; -- -- if (capacity_test(skb4, hdr4, &test_count) < 0) { -- if (!trials--) { -- test += test_count; -- goto err; -- } -- msleep(50); -- continue; -- } -- test += test_count; -- break; -- } -- -- success = true; -- --err: -- kfree_skb(skb4); --#if IS_ENABLED(CONFIG_IPV6) -- kfree_skb(skb6); --#endif --err_nofree: -- wg_ratelimiter_uninit(); -- wg_ratelimiter_uninit(); -- wg_ratelimiter_uninit(); -- /* Uninit one extra time to check underflow detection. */ -- wg_ratelimiter_uninit(); --out: -- if (success) -- pr_info("ratelimiter self-tests: pass\n"); -- else -- pr_err("ratelimiter self-test %d: FAIL\n", test); -- -- return success; --} --#endif -diff --git a/drivers/net/wireguard/send.c b/drivers/net/wireguard/send.c -deleted file mode 100644 -index f74b9341a..000000000 ---- a/drivers/net/wireguard/send.c -+++ /dev/null -@@ -1,422 +0,0 @@ --// SPDX-License-Identifier: GPL-2.0 --/* -- * Copyright (C) 2015-2019 Jason A. Donenfeld . All Rights Reserved. -- */ -- --#include "queueing.h" --#include "timers.h" --#include "device.h" --#include "peer.h" --#include "socket.h" --#include "messages.h" --#include "cookie.h" -- --#include --#include --#include --#include --#include --#include -- --static void wg_packet_send_handshake_initiation(struct wg_peer *peer) --{ -- struct message_handshake_initiation packet; -- -- if (!wg_birthdate_has_expired(atomic64_read(&peer->last_sent_handshake), -- REKEY_TIMEOUT)) -- return; /* This function is rate limited. */ -- -- atomic64_set(&peer->last_sent_handshake, ktime_get_coarse_boottime_ns()); -- net_dbg_ratelimited("%s: Sending handshake initiation to peer %llu (%pISpfsc)\n", -- peer->device->dev->name, peer->internal_id, -- &peer->endpoint.addr); -- -- if (wg_noise_handshake_create_initiation(&packet, &peer->handshake)) { -- wg_cookie_add_mac_to_packet(&packet, sizeof(packet), peer); -- wg_timers_any_authenticated_packet_traversal(peer); -- wg_timers_any_authenticated_packet_sent(peer); -- atomic64_set(&peer->last_sent_handshake, -- ktime_get_coarse_boottime_ns()); -- wg_socket_send_buffer_to_peer(peer, &packet, sizeof(packet), -- HANDSHAKE_DSCP); -- wg_timers_handshake_initiated(peer); -- } --} -- --void wg_packet_handshake_send_worker(struct work_struct *work) --{ -- struct wg_peer *peer = container_of(work, struct wg_peer, -- transmit_handshake_work); -- -- wg_packet_send_handshake_initiation(peer); -- wg_peer_put(peer); --} -- --void wg_packet_send_queued_handshake_initiation(struct wg_peer *peer, -- bool is_retry) --{ -- if (!is_retry) -- peer->timer_handshake_attempts = 0; -- -- rcu_read_lock_bh(); -- /* We check last_sent_handshake here in addition to the actual function -- * we're queueing up, so that we don't queue things if not strictly -- * necessary: -- */ -- if (!wg_birthdate_has_expired(atomic64_read(&peer->last_sent_handshake), -- REKEY_TIMEOUT) || -- unlikely(READ_ONCE(peer->is_dead))) -- goto out; -- -- wg_peer_get(peer); -- /* Queues up calling packet_send_queued_handshakes(peer), where we do a -- * peer_put(peer) after: -- */ -- if (!queue_work(peer->device->handshake_send_wq, -- &peer->transmit_handshake_work)) -- /* If the work was already queued, we want to drop the -- * extra reference: -- */ -- wg_peer_put(peer); --out: -- rcu_read_unlock_bh(); --} -- --void wg_packet_send_handshake_response(struct wg_peer *peer) --{ -- struct message_handshake_response packet; -- -- atomic64_set(&peer->last_sent_handshake, ktime_get_coarse_boottime_ns()); -- net_dbg_ratelimited("%s: Sending handshake response to peer %llu (%pISpfsc)\n", -- peer->device->dev->name, peer->internal_id, -- &peer->endpoint.addr); -- -- if (wg_noise_handshake_create_response(&packet, &peer->handshake)) { -- wg_cookie_add_mac_to_packet(&packet, sizeof(packet), peer); -- if (wg_noise_handshake_begin_session(&peer->handshake, -- &peer->keypairs)) { -- wg_timers_session_derived(peer); -- wg_timers_any_authenticated_packet_traversal(peer); -- wg_timers_any_authenticated_packet_sent(peer); -- atomic64_set(&peer->last_sent_handshake, -- ktime_get_coarse_boottime_ns()); -- wg_socket_send_buffer_to_peer(peer, &packet, -- sizeof(packet), -- HANDSHAKE_DSCP); -- } -- } --} -- --void wg_packet_send_handshake_cookie(struct wg_device *wg, -- struct sk_buff *initiating_skb, -- __le32 sender_index) --{ -- struct message_handshake_cookie packet; -- -- net_dbg_skb_ratelimited("%s: Sending cookie response for denied handshake message for %pISpfsc\n", -- wg->dev->name, initiating_skb); -- wg_cookie_message_create(&packet, initiating_skb, sender_index, -- &wg->cookie_checker); -- wg_socket_send_buffer_as_reply_to_skb(wg, initiating_skb, &packet, -- sizeof(packet)); --} -- --static void keep_key_fresh(struct wg_peer *peer) --{ -- struct noise_keypair *keypair; -- bool send; -- -- rcu_read_lock_bh(); -- keypair = rcu_dereference_bh(peer->keypairs.current_keypair); -- send = keypair && READ_ONCE(keypair->sending.is_valid) && -- (atomic64_read(&keypair->sending_counter) > REKEY_AFTER_MESSAGES || -- (keypair->i_am_the_initiator && -- wg_birthdate_has_expired(keypair->sending.birthdate, REKEY_AFTER_TIME))); -- rcu_read_unlock_bh(); -- -- if (unlikely(send)) -- wg_packet_send_queued_handshake_initiation(peer, false); --} -- --static unsigned int calculate_skb_padding(struct sk_buff *skb) --{ -- unsigned int padded_size, last_unit = skb->len; -- -- if (unlikely(!PACKET_CB(skb)->mtu)) -- return ALIGN(last_unit, MESSAGE_PADDING_MULTIPLE) - last_unit; -- -- /* We do this modulo business with the MTU, just in case the networking -- * layer gives us a packet that's bigger than the MTU. In that case, we -- * wouldn't want the final subtraction to overflow in the case of the -- * padded_size being clamped. Fortunately, that's very rarely the case, -- * so we optimize for that not happening. -- */ -- if (unlikely(last_unit > PACKET_CB(skb)->mtu)) -- last_unit %= PACKET_CB(skb)->mtu; -- -- padded_size = min(PACKET_CB(skb)->mtu, -- ALIGN(last_unit, MESSAGE_PADDING_MULTIPLE)); -- return padded_size - last_unit; --} -- --static bool encrypt_packet(struct sk_buff *skb, struct noise_keypair *keypair) --{ -- unsigned int padding_len, plaintext_len, trailer_len; -- struct scatterlist sg[MAX_SKB_FRAGS + 8]; -- struct message_data *header; -- struct sk_buff *trailer; -- int num_frags; -- -- /* Force hash calculation before encryption so that flow analysis is -- * consistent over the inner packet. -- */ -- skb_get_hash(skb); -- -- /* Calculate lengths. */ -- padding_len = calculate_skb_padding(skb); -- trailer_len = padding_len + noise_encrypted_len(0); -- plaintext_len = skb->len + padding_len; -- -- /* Expand data section to have room for padding and auth tag. */ -- num_frags = skb_cow_data(skb, trailer_len, &trailer); -- if (unlikely(num_frags < 0 || num_frags > ARRAY_SIZE(sg))) -- return false; -- -- /* Set the padding to zeros, and make sure it and the auth tag are part -- * of the skb. -- */ -- memset(skb_tail_pointer(trailer), 0, padding_len); -- -- /* Expand head section to have room for our header and the network -- * stack's headers. -- */ -- if (unlikely(skb_cow_head(skb, DATA_PACKET_HEAD_ROOM) < 0)) -- return false; -- -- /* Finalize checksum calculation for the inner packet, if required. */ -- if (unlikely(skb->ip_summed == CHECKSUM_PARTIAL && -- skb_checksum_help(skb))) -- return false; -- -- /* Only after checksumming can we safely add on the padding at the end -- * and the header. -- */ -- skb_set_inner_network_header(skb, 0); -- header = (struct message_data *)skb_push(skb, sizeof(*header)); -- header->header.type = cpu_to_le32(MESSAGE_DATA); -- header->key_idx = keypair->remote_index; -- header->counter = cpu_to_le64(PACKET_CB(skb)->nonce); -- pskb_put(skb, trailer, trailer_len); -- -- /* Now we can encrypt the scattergather segments */ -- sg_init_table(sg, num_frags); -- if (skb_to_sgvec(skb, sg, sizeof(struct message_data), -- noise_encrypted_len(plaintext_len)) <= 0) -- return false; -- return chacha20poly1305_encrypt_sg_inplace(sg, plaintext_len, NULL, 0, -- PACKET_CB(skb)->nonce, -- keypair->sending.key); --} -- --void wg_packet_send_keepalive(struct wg_peer *peer) --{ -- struct sk_buff *skb; -- -- if (skb_queue_empty(&peer->staged_packet_queue)) { -- skb = alloc_skb(DATA_PACKET_HEAD_ROOM + MESSAGE_MINIMUM_LENGTH, -- GFP_ATOMIC); -- if (unlikely(!skb)) -- return; -- skb_reserve(skb, DATA_PACKET_HEAD_ROOM); -- skb->dev = peer->device->dev; -- PACKET_CB(skb)->mtu = skb->dev->mtu; -- skb_queue_tail(&peer->staged_packet_queue, skb); -- net_dbg_ratelimited("%s: Sending keepalive packet to peer %llu (%pISpfsc)\n", -- peer->device->dev->name, peer->internal_id, -- &peer->endpoint.addr); -- } -- -- wg_packet_send_staged_packets(peer); --} -- --static void wg_packet_create_data_done(struct sk_buff *first, -- struct wg_peer *peer) --{ -- struct sk_buff *skb, *next; -- bool is_keepalive, data_sent = false; -- -- wg_timers_any_authenticated_packet_traversal(peer); -- wg_timers_any_authenticated_packet_sent(peer); -- skb_list_walk_safe(first, skb, next) { -- is_keepalive = skb->len == message_data_len(0); -- if (likely(!wg_socket_send_skb_to_peer(peer, skb, -- PACKET_CB(skb)->ds) && !is_keepalive)) -- data_sent = true; -- } -- -- if (likely(data_sent)) -- wg_timers_data_sent(peer); -- -- keep_key_fresh(peer); --} -- --void wg_packet_tx_worker(struct work_struct *work) --{ -- struct crypt_queue *queue = container_of(work, struct crypt_queue, -- work); -- struct noise_keypair *keypair; -- enum packet_state state; -- struct sk_buff *first; -- struct wg_peer *peer; -- -- while ((first = __ptr_ring_peek(&queue->ring)) != NULL && -- (state = atomic_read_acquire(&PACKET_CB(first)->state)) != -- PACKET_STATE_UNCRYPTED) { -- __ptr_ring_discard_one(&queue->ring); -- peer = PACKET_PEER(first); -- keypair = PACKET_CB(first)->keypair; -- -- if (likely(state == PACKET_STATE_CRYPTED)) -- wg_packet_create_data_done(first, peer); -- else -- kfree_skb_list(first); -- -- wg_noise_keypair_put(keypair, false); -- wg_peer_put(peer); -- if (need_resched()) -- cond_resched(); -- } --} -- --void wg_packet_encrypt_worker(struct work_struct *work) --{ -- struct crypt_queue *queue = container_of(work, struct multicore_worker, -- work)->ptr; -- struct sk_buff *first, *skb, *next; -- -- while ((first = ptr_ring_consume_bh(&queue->ring)) != NULL) { -- enum packet_state state = PACKET_STATE_CRYPTED; -- -- skb_list_walk_safe(first, skb, next) { -- if (likely(encrypt_packet(skb, -- PACKET_CB(first)->keypair))) { -- wg_reset_packet(skb, true); -- } else { -- state = PACKET_STATE_DEAD; -- break; -- } -- } -- wg_queue_enqueue_per_peer(&PACKET_PEER(first)->tx_queue, first, -- state); -- if (need_resched()) -- cond_resched(); -- } --} -- --static void wg_packet_create_data(struct sk_buff *first) --{ -- struct wg_peer *peer = PACKET_PEER(first); -- struct wg_device *wg = peer->device; -- int ret = -EINVAL; -- -- rcu_read_lock_bh(); -- if (unlikely(READ_ONCE(peer->is_dead))) -- goto err; -- -- ret = wg_queue_enqueue_per_device_and_peer(&wg->encrypt_queue, -- &peer->tx_queue, first, -- wg->packet_crypt_wq, -- &wg->encrypt_queue.last_cpu); -- if (unlikely(ret == -EPIPE)) -- wg_queue_enqueue_per_peer(&peer->tx_queue, first, -- PACKET_STATE_DEAD); --err: -- rcu_read_unlock_bh(); -- if (likely(!ret || ret == -EPIPE)) -- return; -- wg_noise_keypair_put(PACKET_CB(first)->keypair, false); -- wg_peer_put(peer); -- kfree_skb_list(first); --} -- --void wg_packet_purge_staged_packets(struct wg_peer *peer) --{ -- spin_lock_bh(&peer->staged_packet_queue.lock); -- peer->device->dev->stats.tx_dropped += peer->staged_packet_queue.qlen; -- __skb_queue_purge(&peer->staged_packet_queue); -- spin_unlock_bh(&peer->staged_packet_queue.lock); --} -- --void wg_packet_send_staged_packets(struct wg_peer *peer) --{ -- struct noise_keypair *keypair; -- struct sk_buff_head packets; -- struct sk_buff *skb; -- -- /* Steal the current queue into our local one. */ -- __skb_queue_head_init(&packets); -- spin_lock_bh(&peer->staged_packet_queue.lock); -- skb_queue_splice_init(&peer->staged_packet_queue, &packets); -- spin_unlock_bh(&peer->staged_packet_queue.lock); -- if (unlikely(skb_queue_empty(&packets))) -- return; -- -- /* First we make sure we have a valid reference to a valid key. */ -- rcu_read_lock_bh(); -- keypair = wg_noise_keypair_get( -- rcu_dereference_bh(peer->keypairs.current_keypair)); -- rcu_read_unlock_bh(); -- if (unlikely(!keypair)) -- goto out_nokey; -- if (unlikely(!READ_ONCE(keypair->sending.is_valid))) -- goto out_nokey; -- if (unlikely(wg_birthdate_has_expired(keypair->sending.birthdate, -- REJECT_AFTER_TIME))) -- goto out_invalid; -- -- /* After we know we have a somewhat valid key, we now try to assign -- * nonces to all of the packets in the queue. If we can't assign nonces -- * for all of them, we just consider it a failure and wait for the next -- * handshake. -- */ -- skb_queue_walk(&packets, skb) { -- /* 0 for no outer TOS: no leak. TODO: at some later point, we -- * might consider using flowi->tos as outer instead. -- */ -- PACKET_CB(skb)->ds = ip_tunnel_ecn_encap(0, ip_hdr(skb), skb); -- PACKET_CB(skb)->nonce = -- atomic64_inc_return(&keypair->sending_counter) - 1; -- if (unlikely(PACKET_CB(skb)->nonce >= REJECT_AFTER_MESSAGES)) -- goto out_invalid; -- } -- -- packets.prev->next = NULL; -- wg_peer_get(keypair->entry.peer); -- PACKET_CB(packets.next)->keypair = keypair; -- wg_packet_create_data(packets.next); -- return; -- --out_invalid: -- WRITE_ONCE(keypair->sending.is_valid, false); --out_nokey: -- wg_noise_keypair_put(keypair, false); -- -- /* We orphan the packets if we're waiting on a handshake, so that they -- * don't block a socket's pool. -- */ -- skb_queue_walk(&packets, skb) -- skb_orphan(skb); -- /* Then we put them back on the top of the queue. We're not too -- * concerned about accidentally getting things a little out of order if -- * packets are being added really fast, because this queue is for before -- * packets can even be sent and it's small anyway. -- */ -- spin_lock_bh(&peer->staged_packet_queue.lock); -- skb_queue_splice(&packets, &peer->staged_packet_queue); -- spin_unlock_bh(&peer->staged_packet_queue.lock); -- -- /* If we're exiting because there's something wrong with the key, it -- * means we should initiate a new handshake. -- */ -- wg_packet_send_queued_handshake_initiation(peer, false); --} -diff --git a/drivers/net/wireguard/socket.c b/drivers/net/wireguard/socket.c -deleted file mode 100644 -index c33e2c816..000000000 ---- a/drivers/net/wireguard/socket.c -+++ /dev/null -@@ -1,436 +0,0 @@ --// SPDX-License-Identifier: GPL-2.0 --/* -- * Copyright (C) 2015-2019 Jason A. Donenfeld . All Rights Reserved. -- */ -- --#include "device.h" --#include "peer.h" --#include "socket.h" --#include "queueing.h" --#include "messages.h" -- --#include --#include --#include --#include --#include --#include --#include -- --static int send4(struct wg_device *wg, struct sk_buff *skb, -- struct endpoint *endpoint, u8 ds, struct dst_cache *cache) --{ -- struct flowi4 fl = { -- .saddr = endpoint->src4.s_addr, -- .daddr = endpoint->addr4.sin_addr.s_addr, -- .fl4_dport = endpoint->addr4.sin_port, -- .flowi4_mark = wg->fwmark, -- .flowi4_proto = IPPROTO_UDP -- }; -- struct rtable *rt = NULL; -- struct sock *sock; -- int ret = 0; -- -- skb_mark_not_on_list(skb); -- skb->dev = wg->dev; -- skb->mark = wg->fwmark; -- -- rcu_read_lock_bh(); -- sock = rcu_dereference_bh(wg->sock4); -- -- if (unlikely(!sock)) { -- ret = -ENONET; -- goto err; -- } -- -- fl.fl4_sport = inet_sk(sock)->inet_sport; -- -- if (cache) -- rt = dst_cache_get_ip4(cache, &fl.saddr); -- -- if (!rt) { -- security_sk_classify_flow(sock, flowi4_to_flowi(&fl)); -- if (unlikely(!inet_confirm_addr(sock_net(sock), NULL, 0, -- fl.saddr, RT_SCOPE_HOST))) { -- endpoint->src4.s_addr = 0; -- *(__force __be32 *)&endpoint->src_if4 = 0; -- fl.saddr = 0; -- if (cache) -- dst_cache_reset(cache); -- } -- rt = ip_route_output_flow(sock_net(sock), &fl, sock); -- if (unlikely(endpoint->src_if4 && ((IS_ERR(rt) && -- PTR_ERR(rt) == -EINVAL) || (!IS_ERR(rt) && -- rt->dst.dev->ifindex != endpoint->src_if4)))) { -- endpoint->src4.s_addr = 0; -- *(__force __be32 *)&endpoint->src_if4 = 0; -- fl.saddr = 0; -- if (cache) -- dst_cache_reset(cache); -- if (!IS_ERR(rt)) -- ip_rt_put(rt); -- rt = ip_route_output_flow(sock_net(sock), &fl, sock); -- } -- if (unlikely(IS_ERR(rt))) { -- ret = PTR_ERR(rt); -- net_dbg_ratelimited("%s: No route to %pISpfsc, error %d\n", -- wg->dev->name, &endpoint->addr, ret); -- goto err; -- } -- if (cache) -- dst_cache_set_ip4(cache, &rt->dst, fl.saddr); -- } -- -- skb->ignore_df = 1; -- udp_tunnel_xmit_skb(rt, sock, skb, fl.saddr, fl.daddr, ds, -- ip4_dst_hoplimit(&rt->dst), 0, fl.fl4_sport, -- fl.fl4_dport, false, false); -- goto out; -- --err: -- kfree_skb(skb); --out: -- rcu_read_unlock_bh(); -- return ret; --} -- --static int send6(struct wg_device *wg, struct sk_buff *skb, -- struct endpoint *endpoint, u8 ds, struct dst_cache *cache) --{ --#if IS_ENABLED(CONFIG_IPV6) -- struct flowi6 fl = { -- .saddr = endpoint->src6, -- .daddr = endpoint->addr6.sin6_addr, -- .fl6_dport = endpoint->addr6.sin6_port, -- .flowi6_mark = wg->fwmark, -- .flowi6_oif = endpoint->addr6.sin6_scope_id, -- .flowi6_proto = IPPROTO_UDP -- /* TODO: addr->sin6_flowinfo */ -- }; -- struct dst_entry *dst = NULL; -- struct sock *sock; -- int ret = 0; -- -- skb_mark_not_on_list(skb); -- skb->dev = wg->dev; -- skb->mark = wg->fwmark; -- -- rcu_read_lock_bh(); -- sock = rcu_dereference_bh(wg->sock6); -- -- if (unlikely(!sock)) { -- ret = -ENONET; -- goto err; -- } -- -- fl.fl6_sport = inet_sk(sock)->inet_sport; -- -- if (cache) -- dst = dst_cache_get_ip6(cache, &fl.saddr); -- -- if (!dst) { -- security_sk_classify_flow(sock, flowi6_to_flowi(&fl)); -- if (unlikely(!ipv6_addr_any(&fl.saddr) && -- !ipv6_chk_addr(sock_net(sock), &fl.saddr, NULL, 0))) { -- endpoint->src6 = fl.saddr = in6addr_any; -- if (cache) -- dst_cache_reset(cache); -- } -- dst = ipv6_stub->ipv6_dst_lookup_flow(sock_net(sock), sock, &fl, -- NULL); -- if (unlikely(IS_ERR(dst))) { -- ret = PTR_ERR(dst); -- net_dbg_ratelimited("%s: No route to %pISpfsc, error %d\n", -- wg->dev->name, &endpoint->addr, ret); -- goto err; -- } -- if (cache) -- dst_cache_set_ip6(cache, dst, &fl.saddr); -- } -- -- skb->ignore_df = 1; -- udp_tunnel6_xmit_skb(dst, sock, skb, skb->dev, &fl.saddr, &fl.daddr, ds, -- ip6_dst_hoplimit(dst), 0, fl.fl6_sport, -- fl.fl6_dport, false); -- goto out; -- --err: -- kfree_skb(skb); --out: -- rcu_read_unlock_bh(); -- return ret; --#else -- return -EAFNOSUPPORT; --#endif --} -- --int wg_socket_send_skb_to_peer(struct wg_peer *peer, struct sk_buff *skb, u8 ds) --{ -- size_t skb_len = skb->len; -- int ret = -EAFNOSUPPORT; -- -- read_lock_bh(&peer->endpoint_lock); -- if (peer->endpoint.addr.sa_family == AF_INET) -- ret = send4(peer->device, skb, &peer->endpoint, ds, -- &peer->endpoint_cache); -- else if (peer->endpoint.addr.sa_family == AF_INET6) -- ret = send6(peer->device, skb, &peer->endpoint, ds, -- &peer->endpoint_cache); -- else -- dev_kfree_skb(skb); -- if (likely(!ret)) -- peer->tx_bytes += skb_len; -- read_unlock_bh(&peer->endpoint_lock); -- -- return ret; --} -- --int wg_socket_send_buffer_to_peer(struct wg_peer *peer, void *buffer, -- size_t len, u8 ds) --{ -- struct sk_buff *skb = alloc_skb(len + SKB_HEADER_LEN, GFP_ATOMIC); -- -- if (unlikely(!skb)) -- return -ENOMEM; -- -- skb_reserve(skb, SKB_HEADER_LEN); -- skb_set_inner_network_header(skb, 0); -- skb_put_data(skb, buffer, len); -- return wg_socket_send_skb_to_peer(peer, skb, ds); --} -- --int wg_socket_send_buffer_as_reply_to_skb(struct wg_device *wg, -- struct sk_buff *in_skb, void *buffer, -- size_t len) --{ -- int ret = 0; -- struct sk_buff *skb; -- struct endpoint endpoint; -- -- if (unlikely(!in_skb)) -- return -EINVAL; -- ret = wg_socket_endpoint_from_skb(&endpoint, in_skb); -- if (unlikely(ret < 0)) -- return ret; -- -- skb = alloc_skb(len + SKB_HEADER_LEN, GFP_ATOMIC); -- if (unlikely(!skb)) -- return -ENOMEM; -- skb_reserve(skb, SKB_HEADER_LEN); -- skb_set_inner_network_header(skb, 0); -- skb_put_data(skb, buffer, len); -- -- if (endpoint.addr.sa_family == AF_INET) -- ret = send4(wg, skb, &endpoint, 0, NULL); -- else if (endpoint.addr.sa_family == AF_INET6) -- ret = send6(wg, skb, &endpoint, 0, NULL); -- /* No other possibilities if the endpoint is valid, which it is, -- * as we checked above. -- */ -- -- return ret; --} -- --int wg_socket_endpoint_from_skb(struct endpoint *endpoint, -- const struct sk_buff *skb) --{ -- memset(endpoint, 0, sizeof(*endpoint)); -- if (skb->protocol == htons(ETH_P_IP)) { -- endpoint->addr4.sin_family = AF_INET; -- endpoint->addr4.sin_port = udp_hdr(skb)->source; -- endpoint->addr4.sin_addr.s_addr = ip_hdr(skb)->saddr; -- endpoint->src4.s_addr = ip_hdr(skb)->daddr; -- endpoint->src_if4 = skb->skb_iif; -- } else if (skb->protocol == htons(ETH_P_IPV6)) { -- endpoint->addr6.sin6_family = AF_INET6; -- endpoint->addr6.sin6_port = udp_hdr(skb)->source; -- endpoint->addr6.sin6_addr = ipv6_hdr(skb)->saddr; -- endpoint->addr6.sin6_scope_id = ipv6_iface_scope_id( -- &ipv6_hdr(skb)->saddr, skb->skb_iif); -- endpoint->src6 = ipv6_hdr(skb)->daddr; -- } else { -- return -EINVAL; -- } -- return 0; --} -- --static bool endpoint_eq(const struct endpoint *a, const struct endpoint *b) --{ -- return (a->addr.sa_family == AF_INET && b->addr.sa_family == AF_INET && -- a->addr4.sin_port == b->addr4.sin_port && -- a->addr4.sin_addr.s_addr == b->addr4.sin_addr.s_addr && -- a->src4.s_addr == b->src4.s_addr && a->src_if4 == b->src_if4) || -- (a->addr.sa_family == AF_INET6 && -- b->addr.sa_family == AF_INET6 && -- a->addr6.sin6_port == b->addr6.sin6_port && -- ipv6_addr_equal(&a->addr6.sin6_addr, &b->addr6.sin6_addr) && -- a->addr6.sin6_scope_id == b->addr6.sin6_scope_id && -- ipv6_addr_equal(&a->src6, &b->src6)) || -- unlikely(!a->addr.sa_family && !b->addr.sa_family); --} -- --void wg_socket_set_peer_endpoint(struct wg_peer *peer, -- const struct endpoint *endpoint) --{ -- /* First we check unlocked, in order to optimize, since it's pretty rare -- * that an endpoint will change. If we happen to be mid-write, and two -- * CPUs wind up writing the same thing or something slightly different, -- * it doesn't really matter much either. -- */ -- if (endpoint_eq(endpoint, &peer->endpoint)) -- return; -- write_lock_bh(&peer->endpoint_lock); -- if (endpoint->addr.sa_family == AF_INET) { -- peer->endpoint.addr4 = endpoint->addr4; -- peer->endpoint.src4 = endpoint->src4; -- peer->endpoint.src_if4 = endpoint->src_if4; -- } else if (endpoint->addr.sa_family == AF_INET6) { -- peer->endpoint.addr6 = endpoint->addr6; -- peer->endpoint.src6 = endpoint->src6; -- } else { -- goto out; -- } -- dst_cache_reset(&peer->endpoint_cache); --out: -- write_unlock_bh(&peer->endpoint_lock); --} -- --void wg_socket_set_peer_endpoint_from_skb(struct wg_peer *peer, -- const struct sk_buff *skb) --{ -- struct endpoint endpoint; -- -- if (!wg_socket_endpoint_from_skb(&endpoint, skb)) -- wg_socket_set_peer_endpoint(peer, &endpoint); --} -- --void wg_socket_clear_peer_endpoint_src(struct wg_peer *peer) --{ -- write_lock_bh(&peer->endpoint_lock); -- memset(&peer->endpoint.src6, 0, sizeof(peer->endpoint.src6)); -- dst_cache_reset(&peer->endpoint_cache); -- write_unlock_bh(&peer->endpoint_lock); --} -- --static int wg_receive(struct sock *sk, struct sk_buff *skb) --{ -- struct wg_device *wg; -- -- if (unlikely(!sk)) -- goto err; -- wg = sk->sk_user_data; -- if (unlikely(!wg)) -- goto err; -- skb_mark_not_on_list(skb); -- wg_packet_receive(wg, skb); -- return 0; -- --err: -- kfree_skb(skb); -- return 0; --} -- --static void sock_free(struct sock *sock) --{ -- if (unlikely(!sock)) -- return; -- sk_clear_memalloc(sock); -- udp_tunnel_sock_release(sock->sk_socket); --} -- --static void set_sock_opts(struct socket *sock) --{ -- sock->sk->sk_allocation = GFP_ATOMIC; -- sock->sk->sk_sndbuf = INT_MAX; -- sk_set_memalloc(sock->sk); --} -- --int wg_socket_init(struct wg_device *wg, u16 port) --{ -- struct net *net; -- int ret; -- struct udp_tunnel_sock_cfg cfg = { -- .sk_user_data = wg, -- .encap_type = 1, -- .encap_rcv = wg_receive -- }; -- struct socket *new4 = NULL, *new6 = NULL; -- struct udp_port_cfg port4 = { -- .family = AF_INET, -- .local_ip.s_addr = htonl(INADDR_ANY), -- .local_udp_port = htons(port), -- .use_udp_checksums = true -- }; --#if IS_ENABLED(CONFIG_IPV6) -- int retries = 0; -- struct udp_port_cfg port6 = { -- .family = AF_INET6, -- .local_ip6 = IN6ADDR_ANY_INIT, -- .use_udp6_tx_checksums = true, -- .use_udp6_rx_checksums = true, -- .ipv6_v6only = true -- }; --#endif -- -- rcu_read_lock(); -- net = rcu_dereference(wg->creating_net); -- net = net ? maybe_get_net(net) : NULL; -- rcu_read_unlock(); -- if (unlikely(!net)) -- return -ENONET; -- --#if IS_ENABLED(CONFIG_IPV6) --retry: --#endif -- -- ret = udp_sock_create(net, &port4, &new4); -- if (ret < 0) { -- pr_err("%s: Could not create IPv4 socket\n", wg->dev->name); -- goto out; -- } -- set_sock_opts(new4); -- setup_udp_tunnel_sock(net, new4, &cfg); -- --#if IS_ENABLED(CONFIG_IPV6) -- if (ipv6_mod_enabled()) { -- port6.local_udp_port = inet_sk(new4->sk)->inet_sport; -- ret = udp_sock_create(net, &port6, &new6); -- if (ret < 0) { -- udp_tunnel_sock_release(new4); -- if (ret == -EADDRINUSE && !port && retries++ < 100) -- goto retry; -- pr_err("%s: Could not create IPv6 socket\n", -- wg->dev->name); -- goto out; -- } -- set_sock_opts(new6); -- setup_udp_tunnel_sock(net, new6, &cfg); -- } --#endif -- -- wg_socket_reinit(wg, new4->sk, new6 ? new6->sk : NULL); -- ret = 0; --out: -- put_net(net); -- return ret; --} -- --void wg_socket_reinit(struct wg_device *wg, struct sock *new4, -- struct sock *new6) --{ -- struct sock *old4, *old6; -- -- mutex_lock(&wg->socket_update_lock); -- old4 = rcu_dereference_protected(wg->sock4, -- lockdep_is_held(&wg->socket_update_lock)); -- old6 = rcu_dereference_protected(wg->sock6, -- lockdep_is_held(&wg->socket_update_lock)); -- rcu_assign_pointer(wg->sock4, new4); -- rcu_assign_pointer(wg->sock6, new6); -- if (new4) -- wg->incoming_port = ntohs(inet_sk(new4)->inet_sport); -- mutex_unlock(&wg->socket_update_lock); -- synchronize_rcu(); -- sock_free(old4); -- sock_free(old6); --} -diff --git a/drivers/net/wireguard/socket.h b/drivers/net/wireguard/socket.h -deleted file mode 100644 -index bab5848ef..000000000 ---- a/drivers/net/wireguard/socket.h -+++ /dev/null -@@ -1,44 +0,0 @@ --/* SPDX-License-Identifier: GPL-2.0 */ --/* -- * Copyright (C) 2015-2019 Jason A. Donenfeld . All Rights Reserved. -- */ -- --#ifndef _WG_SOCKET_H --#define _WG_SOCKET_H -- --#include --#include --#include --#include -- --int wg_socket_init(struct wg_device *wg, u16 port); --void wg_socket_reinit(struct wg_device *wg, struct sock *new4, -- struct sock *new6); --int wg_socket_send_buffer_to_peer(struct wg_peer *peer, void *data, -- size_t len, u8 ds); --int wg_socket_send_skb_to_peer(struct wg_peer *peer, struct sk_buff *skb, -- u8 ds); --int wg_socket_send_buffer_as_reply_to_skb(struct wg_device *wg, -- struct sk_buff *in_skb, -- void *out_buffer, size_t len); -- --int wg_socket_endpoint_from_skb(struct endpoint *endpoint, -- const struct sk_buff *skb); --void wg_socket_set_peer_endpoint(struct wg_peer *peer, -- const struct endpoint *endpoint); --void wg_socket_set_peer_endpoint_from_skb(struct wg_peer *peer, -- const struct sk_buff *skb); --void wg_socket_clear_peer_endpoint_src(struct wg_peer *peer); -- --#if defined(CONFIG_DYNAMIC_DEBUG) || defined(DEBUG) --#define net_dbg_skb_ratelimited(fmt, dev, skb, ...) do { \ -- struct endpoint __endpoint; \ -- wg_socket_endpoint_from_skb(&__endpoint, skb); \ -- net_dbg_ratelimited(fmt, dev, &__endpoint.addr, \ -- ##__VA_ARGS__); \ -- } while (0) --#else --#define net_dbg_skb_ratelimited(fmt, skb, ...) --#endif -- --#endif /* _WG_SOCKET_H */ -diff --git a/drivers/net/wireguard/timers.c b/drivers/net/wireguard/timers.c -deleted file mode 100644 -index d54d32ac9..000000000 ---- a/drivers/net/wireguard/timers.c -+++ /dev/null -@@ -1,243 +0,0 @@ --// SPDX-License-Identifier: GPL-2.0 --/* -- * Copyright (C) 2015-2019 Jason A. Donenfeld . All Rights Reserved. -- */ -- --#include "timers.h" --#include "device.h" --#include "peer.h" --#include "queueing.h" --#include "socket.h" -- --/* -- * - Timer for retransmitting the handshake if we don't hear back after -- * `REKEY_TIMEOUT + jitter` ms. -- * -- * - Timer for sending empty packet if we have received a packet but after have -- * not sent one for `KEEPALIVE_TIMEOUT` ms. -- * -- * - Timer for initiating new handshake if we have sent a packet but after have -- * not received one (even empty) for `(KEEPALIVE_TIMEOUT + REKEY_TIMEOUT) + -- * jitter` ms. -- * -- * - Timer for zeroing out all ephemeral keys after `(REJECT_AFTER_TIME * 3)` ms -- * if no new keys have been received. -- * -- * - Timer for, if enabled, sending an empty authenticated packet every user- -- * specified seconds. -- */ -- --static inline void mod_peer_timer(struct wg_peer *peer, -- struct timer_list *timer, -- unsigned long expires) --{ -- rcu_read_lock_bh(); -- if (likely(netif_running(peer->device->dev) && -- !READ_ONCE(peer->is_dead))) -- mod_timer(timer, expires); -- rcu_read_unlock_bh(); --} -- --static void wg_expired_retransmit_handshake(struct timer_list *timer) --{ -- struct wg_peer *peer = from_timer(peer, timer, -- timer_retransmit_handshake); -- -- if (peer->timer_handshake_attempts > MAX_TIMER_HANDSHAKES) { -- pr_debug("%s: Handshake for peer %llu (%pISpfsc) did not complete after %d attempts, giving up\n", -- peer->device->dev->name, peer->internal_id, -- &peer->endpoint.addr, MAX_TIMER_HANDSHAKES + 2); -- -- del_timer(&peer->timer_send_keepalive); -- /* We drop all packets without a keypair and don't try again, -- * if we try unsuccessfully for too long to make a handshake. -- */ -- wg_packet_purge_staged_packets(peer); -- -- /* We set a timer for destroying any residue that might be left -- * of a partial exchange. -- */ -- if (!timer_pending(&peer->timer_zero_key_material)) -- mod_peer_timer(peer, &peer->timer_zero_key_material, -- jiffies + REJECT_AFTER_TIME * 3 * HZ); -- } else { -- ++peer->timer_handshake_attempts; -- pr_debug("%s: Handshake for peer %llu (%pISpfsc) did not complete after %d seconds, retrying (try %d)\n", -- peer->device->dev->name, peer->internal_id, -- &peer->endpoint.addr, REKEY_TIMEOUT, -- peer->timer_handshake_attempts + 1); -- -- /* We clear the endpoint address src address, in case this is -- * the cause of trouble. -- */ -- wg_socket_clear_peer_endpoint_src(peer); -- -- wg_packet_send_queued_handshake_initiation(peer, true); -- } --} -- --static void wg_expired_send_keepalive(struct timer_list *timer) --{ -- struct wg_peer *peer = from_timer(peer, timer, timer_send_keepalive); -- -- wg_packet_send_keepalive(peer); -- if (peer->timer_need_another_keepalive) { -- peer->timer_need_another_keepalive = false; -- mod_peer_timer(peer, &peer->timer_send_keepalive, -- jiffies + KEEPALIVE_TIMEOUT * HZ); -- } --} -- --static void wg_expired_new_handshake(struct timer_list *timer) --{ -- struct wg_peer *peer = from_timer(peer, timer, timer_new_handshake); -- -- pr_debug("%s: Retrying handshake with peer %llu (%pISpfsc) because we stopped hearing back after %d seconds\n", -- peer->device->dev->name, peer->internal_id, -- &peer->endpoint.addr, KEEPALIVE_TIMEOUT + REKEY_TIMEOUT); -- /* We clear the endpoint address src address, in case this is the cause -- * of trouble. -- */ -- wg_socket_clear_peer_endpoint_src(peer); -- wg_packet_send_queued_handshake_initiation(peer, false); --} -- --static void wg_expired_zero_key_material(struct timer_list *timer) --{ -- struct wg_peer *peer = from_timer(peer, timer, timer_zero_key_material); -- -- rcu_read_lock_bh(); -- if (!READ_ONCE(peer->is_dead)) { -- wg_peer_get(peer); -- if (!queue_work(peer->device->handshake_send_wq, -- &peer->clear_peer_work)) -- /* If the work was already on the queue, we want to drop -- * the extra reference. -- */ -- wg_peer_put(peer); -- } -- rcu_read_unlock_bh(); --} -- --static void wg_queued_expired_zero_key_material(struct work_struct *work) --{ -- struct wg_peer *peer = container_of(work, struct wg_peer, -- clear_peer_work); -- -- pr_debug("%s: Zeroing out all keys for peer %llu (%pISpfsc), since we haven't received a new one in %d seconds\n", -- peer->device->dev->name, peer->internal_id, -- &peer->endpoint.addr, REJECT_AFTER_TIME * 3); -- wg_noise_handshake_clear(&peer->handshake); -- wg_noise_keypairs_clear(&peer->keypairs); -- wg_peer_put(peer); --} -- --static void wg_expired_send_persistent_keepalive(struct timer_list *timer) --{ -- struct wg_peer *peer = from_timer(peer, timer, -- timer_persistent_keepalive); -- -- if (likely(peer->persistent_keepalive_interval)) -- wg_packet_send_keepalive(peer); --} -- --/* Should be called after an authenticated data packet is sent. */ --void wg_timers_data_sent(struct wg_peer *peer) --{ -- if (!timer_pending(&peer->timer_new_handshake)) -- mod_peer_timer(peer, &peer->timer_new_handshake, -- jiffies + (KEEPALIVE_TIMEOUT + REKEY_TIMEOUT) * HZ + -- prandom_u32_max(REKEY_TIMEOUT_JITTER_MAX_JIFFIES)); --} -- --/* Should be called after an authenticated data packet is received. */ --void wg_timers_data_received(struct wg_peer *peer) --{ -- if (likely(netif_running(peer->device->dev))) { -- if (!timer_pending(&peer->timer_send_keepalive)) -- mod_peer_timer(peer, &peer->timer_send_keepalive, -- jiffies + KEEPALIVE_TIMEOUT * HZ); -- else -- peer->timer_need_another_keepalive = true; -- } --} -- --/* Should be called after any type of authenticated packet is sent, whether -- * keepalive, data, or handshake. -- */ --void wg_timers_any_authenticated_packet_sent(struct wg_peer *peer) --{ -- del_timer(&peer->timer_send_keepalive); --} -- --/* Should be called after any type of authenticated packet is received, whether -- * keepalive, data, or handshake. -- */ --void wg_timers_any_authenticated_packet_received(struct wg_peer *peer) --{ -- del_timer(&peer->timer_new_handshake); --} -- --/* Should be called after a handshake initiation message is sent. */ --void wg_timers_handshake_initiated(struct wg_peer *peer) --{ -- mod_peer_timer(peer, &peer->timer_retransmit_handshake, -- jiffies + REKEY_TIMEOUT * HZ + -- prandom_u32_max(REKEY_TIMEOUT_JITTER_MAX_JIFFIES)); --} -- --/* Should be called after a handshake response message is received and processed -- * or when getting key confirmation via the first data message. -- */ --void wg_timers_handshake_complete(struct wg_peer *peer) --{ -- del_timer(&peer->timer_retransmit_handshake); -- peer->timer_handshake_attempts = 0; -- peer->sent_lastminute_handshake = false; -- ktime_get_real_ts64(&peer->walltime_last_handshake); --} -- --/* Should be called after an ephemeral key is created, which is before sending a -- * handshake response or after receiving a handshake response. -- */ --void wg_timers_session_derived(struct wg_peer *peer) --{ -- mod_peer_timer(peer, &peer->timer_zero_key_material, -- jiffies + REJECT_AFTER_TIME * 3 * HZ); --} -- --/* Should be called before a packet with authentication, whether -- * keepalive, data, or handshakem is sent, or after one is received. -- */ --void wg_timers_any_authenticated_packet_traversal(struct wg_peer *peer) --{ -- if (peer->persistent_keepalive_interval) -- mod_peer_timer(peer, &peer->timer_persistent_keepalive, -- jiffies + peer->persistent_keepalive_interval * HZ); --} -- --void wg_timers_init(struct wg_peer *peer) --{ -- timer_setup(&peer->timer_retransmit_handshake, -- wg_expired_retransmit_handshake, 0); -- timer_setup(&peer->timer_send_keepalive, wg_expired_send_keepalive, 0); -- timer_setup(&peer->timer_new_handshake, wg_expired_new_handshake, 0); -- timer_setup(&peer->timer_zero_key_material, -- wg_expired_zero_key_material, 0); -- timer_setup(&peer->timer_persistent_keepalive, -- wg_expired_send_persistent_keepalive, 0); -- INIT_WORK(&peer->clear_peer_work, wg_queued_expired_zero_key_material); -- peer->timer_handshake_attempts = 0; -- peer->sent_lastminute_handshake = false; -- peer->timer_need_another_keepalive = false; --} -- --void wg_timers_stop(struct wg_peer *peer) --{ -- del_timer_sync(&peer->timer_retransmit_handshake); -- del_timer_sync(&peer->timer_send_keepalive); -- del_timer_sync(&peer->timer_new_handshake); -- del_timer_sync(&peer->timer_zero_key_material); -- del_timer_sync(&peer->timer_persistent_keepalive); -- flush_work(&peer->clear_peer_work); --} -diff --git a/drivers/net/wireguard/timers.h b/drivers/net/wireguard/timers.h -deleted file mode 100644 -index f0653dcb1..000000000 ---- a/drivers/net/wireguard/timers.h -+++ /dev/null -@@ -1,31 +0,0 @@ --/* SPDX-License-Identifier: GPL-2.0 */ --/* -- * Copyright (C) 2015-2019 Jason A. Donenfeld . All Rights Reserved. -- */ -- --#ifndef _WG_TIMERS_H --#define _WG_TIMERS_H -- --#include -- --struct wg_peer; -- --void wg_timers_init(struct wg_peer *peer); --void wg_timers_stop(struct wg_peer *peer); --void wg_timers_data_sent(struct wg_peer *peer); --void wg_timers_data_received(struct wg_peer *peer); --void wg_timers_any_authenticated_packet_sent(struct wg_peer *peer); --void wg_timers_any_authenticated_packet_received(struct wg_peer *peer); --void wg_timers_handshake_initiated(struct wg_peer *peer); --void wg_timers_handshake_complete(struct wg_peer *peer); --void wg_timers_session_derived(struct wg_peer *peer); --void wg_timers_any_authenticated_packet_traversal(struct wg_peer *peer); -- --static inline bool wg_birthdate_has_expired(u64 birthday_nanoseconds, -- u64 expiration_seconds) --{ -- return (s64)(birthday_nanoseconds + expiration_seconds * NSEC_PER_SEC) -- <= (s64)ktime_get_coarse_boottime_ns(); --} -- --#endif /* _WG_TIMERS_H */ -diff --git a/drivers/net/wireguard/version.h b/drivers/net/wireguard/version.h -deleted file mode 100644 -index a1a269a11..000000000 ---- a/drivers/net/wireguard/version.h -+++ /dev/null -@@ -1 +0,0 @@ --#define WIREGUARD_VERSION "1.0.0" -diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig -index 63be9a5d7..ec752a693 100644 ---- a/drivers/net/Kconfig -+++ b/drivers/net/Kconfig -@@ -70,49 +70,6 @@ config DUMMY - To compile this driver as a module, choose M here: the module - will be called dummy. - --config WIREGUARD -- tristate "WireGuard secure network tunnel" -- depends on NET && INET -- depends on IPV6 || !IPV6 -- select NET_UDP_TUNNEL -- select DST_CACHE -- select CRYPTO -- select CRYPTO_LIB_CURVE25519 -- select CRYPTO_LIB_CHACHA20POLY1305 -- select CRYPTO_LIB_BLAKE2S -- select CRYPTO_CHACHA20_X86_64 if X86 && 64BIT -- select CRYPTO_POLY1305_X86_64 if X86 && 64BIT -- select CRYPTO_BLAKE2S_X86 if X86 && 64BIT -- select CRYPTO_CURVE25519_X86 if X86 && 64BIT -- select ARM_CRYPTO if ARM -- select ARM64_CRYPTO if ARM64 -- select CRYPTO_CHACHA20_NEON if (ARM || ARM64) && KERNEL_MODE_NEON -- select CRYPTO_POLY1305_NEON if ARM64 && KERNEL_MODE_NEON -- select CRYPTO_POLY1305_ARM if ARM -- select CRYPTO_CURVE25519_NEON if ARM && KERNEL_MODE_NEON -- select CRYPTO_CHACHA_MIPS if CPU_MIPS32_R2 -- select CRYPTO_POLY1305_MIPS if CPU_MIPS32 || (CPU_MIPS64 && 64BIT) -- help -- WireGuard is a secure, fast, and easy to use replacement for IPSec -- that uses modern cryptography and clever networking tricks. It's -- designed to be fairly general purpose and abstract enough to fit most -- use cases, while at the same time remaining extremely simple to -- configure. See www.wireguard.com for more info. -- -- It's safe to say Y or M here, as the driver is very lightweight and -- is only in use when an administrator chooses to add an interface. -- --config WIREGUARD_DEBUG -- bool "Debugging checks and verbose messages" -- depends on WIREGUARD -- help -- This will write log messages for handshake and other events -- that occur for a WireGuard interface. It will also perform some -- extra validation checks and unit tests at various points. This is -- only useful for debugging. -- -- Say N here unless you know what you're doing. -- - config EQUALIZER - tristate "EQL (serial line load balancing) support" - ---help--- -diff --git a/drivers/net/Makefile b/drivers/net/Makefile -index 557564cc0..ccd0345ae 100644 ---- a/drivers/net/Makefile -+++ b/drivers/net/Makefile -@@ -10,7 +10,6 @@ obj-$(CONFIG_BONDING) += bonding/ - obj-$(CONFIG_IPVLAN) += ipvlan/ - obj-$(CONFIG_IPVTAP) += ipvlan/ - obj-$(CONFIG_DUMMY) += dummy.o --obj-$(CONFIG_WIREGUARD) += wireguard/ - obj-$(CONFIG_EQUALIZER) += eql.o - obj-$(CONFIG_IFB) += ifb.o - obj-$(CONFIG_MACSEC) += macsec.o diff --git a/patch/kernel/archive/rk35xx-5.16/0001-Revert-net-Remove-net-ipx.h-and-uapi-linux-ipx.h-hea.patch b/patch/kernel/archive/rk35xx-5.16/0001-Revert-net-Remove-net-ipx.h-and-uapi-linux-ipx.h-hea.patch new file mode 100644 index 0000000000..8fe8cd6434 --- /dev/null +++ b/patch/kernel/archive/rk35xx-5.16/0001-Revert-net-Remove-net-ipx.h-and-uapi-linux-ipx.h-hea.patch @@ -0,0 +1,287 @@ +From 3ec70749ae3cb072f19d886981a217121f776415 Mon Sep 17 00:00:00 2001 +From: Igor Pecovnik +Date: Sat, 6 Nov 2021 19:15:23 +0100 +Subject: [PATCH] Revert "net: Remove net/ipx.h and uapi/linux/ipx.h header + files" + +This reverts commit 6c9b40844751ea30c72f7a2f92f4d704bc6b2927. +--- + include/net/ipx.h | 171 +++++++++++++++++++++++++++++++++++++++ + include/uapi/linux/ipx.h | 87 ++++++++++++++++++++ + 2 files changed, 258 insertions(+) + create mode 100644 include/net/ipx.h + create mode 100644 include/uapi/linux/ipx.h + +diff --git a/include/net/ipx.h b/include/net/ipx.h +new file mode 100644 +index 000000000000..9d1342807b59 +--- /dev/null ++++ b/include/net/ipx.h +@@ -0,0 +1,171 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++#ifndef _NET_INET_IPX_H_ ++#define _NET_INET_IPX_H_ ++/* ++ * The following information is in its entirety obtained from: ++ * ++ * Novell 'IPX Router Specification' Version 1.10 ++ * Part No. 107-000029-001 ++ * ++ * Which is available from ftp.novell.com ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++struct ipx_address { ++ __be32 net; ++ __u8 node[IPX_NODE_LEN]; ++ __be16 sock; ++}; ++ ++#define ipx_broadcast_node "\377\377\377\377\377\377" ++#define ipx_this_node "\0\0\0\0\0\0" ++ ++#define IPX_MAX_PPROP_HOPS 8 ++ ++struct ipxhdr { ++ __be16 ipx_checksum __packed; ++#define IPX_NO_CHECKSUM cpu_to_be16(0xFFFF) ++ __be16 ipx_pktsize __packed; ++ __u8 ipx_tctrl; ++ __u8 ipx_type; ++#define IPX_TYPE_UNKNOWN 0x00 ++#define IPX_TYPE_RIP 0x01 /* may also be 0 */ ++#define IPX_TYPE_SAP 0x04 /* may also be 0 */ ++#define IPX_TYPE_SPX 0x05 /* SPX protocol */ ++#define IPX_TYPE_NCP 0x11 /* $lots for docs on this (SPIT) */ ++#define IPX_TYPE_PPROP 0x14 /* complicated flood fill brdcast */ ++ struct ipx_address ipx_dest __packed; ++ struct ipx_address ipx_source __packed; ++}; ++ ++/* From af_ipx.c */ ++extern int sysctl_ipx_pprop_broadcasting; ++ ++struct ipx_interface { ++ /* IPX address */ ++ __be32 if_netnum; ++ unsigned char if_node[IPX_NODE_LEN]; ++ refcount_t refcnt; ++ ++ /* physical device info */ ++ struct net_device *if_dev; ++ struct datalink_proto *if_dlink; ++ __be16 if_dlink_type; ++ ++ /* socket support */ ++ unsigned short if_sknum; ++ struct hlist_head if_sklist; ++ spinlock_t if_sklist_lock; ++ ++ /* administrative overhead */ ++ int if_ipx_offset; ++ unsigned char if_internal; ++ unsigned char if_primary; ++ ++ struct list_head node; /* node in ipx_interfaces list */ ++}; ++ ++struct ipx_route { ++ __be32 ir_net; ++ struct ipx_interface *ir_intrfc; ++ unsigned char ir_routed; ++ unsigned char ir_router_node[IPX_NODE_LEN]; ++ struct list_head node; /* node in ipx_routes list */ ++ refcount_t refcnt; ++}; ++ ++struct ipx_cb { ++ u8 ipx_tctrl; ++ __be32 ipx_dest_net; ++ __be32 ipx_source_net; ++ struct { ++ __be32 netnum; ++ int index; ++ } last_hop; ++}; ++ ++#include ++ ++struct ipx_sock { ++ /* struct sock has to be the first member of ipx_sock */ ++ struct sock sk; ++ struct ipx_address dest_addr; ++ struct ipx_interface *intrfc; ++ __be16 port; ++#ifdef CONFIG_IPX_INTERN ++ unsigned char node[IPX_NODE_LEN]; ++#endif ++ unsigned short type; ++ /* ++ * To handle special ncp connection-handling sockets for mars_nwe, ++ * the connection number must be stored in the socket. ++ */ ++ unsigned short ipx_ncp_conn; ++}; ++ ++static inline struct ipx_sock *ipx_sk(struct sock *sk) ++{ ++ return (struct ipx_sock *)sk; ++} ++ ++#define IPX_SKB_CB(__skb) ((struct ipx_cb *)&((__skb)->cb[0])) ++ ++#define IPX_MIN_EPHEMERAL_SOCKET 0x4000 ++#define IPX_MAX_EPHEMERAL_SOCKET 0x7fff ++ ++extern struct list_head ipx_routes; ++extern rwlock_t ipx_routes_lock; ++ ++extern struct list_head ipx_interfaces; ++struct ipx_interface *ipx_interfaces_head(void); ++extern spinlock_t ipx_interfaces_lock; ++ ++extern struct ipx_interface *ipx_primary_net; ++ ++int ipx_proc_init(void); ++void ipx_proc_exit(void); ++ ++const char *ipx_frame_name(__be16); ++const char *ipx_device_name(struct ipx_interface *intrfc); ++ ++static __inline__ void ipxitf_hold(struct ipx_interface *intrfc) ++{ ++ refcount_inc(&intrfc->refcnt); ++} ++ ++void ipxitf_down(struct ipx_interface *intrfc); ++struct ipx_interface *ipxitf_find_using_net(__be32 net); ++int ipxitf_send(struct ipx_interface *intrfc, struct sk_buff *skb, char *node); ++__be16 ipx_cksum(struct ipxhdr *packet, int length); ++int ipxrtr_add_route(__be32 network, struct ipx_interface *intrfc, ++ unsigned char *node); ++void ipxrtr_del_routes(struct ipx_interface *intrfc); ++int ipxrtr_route_packet(struct sock *sk, struct sockaddr_ipx *usipx, ++ struct msghdr *msg, size_t len, int noblock); ++int ipxrtr_route_skb(struct sk_buff *skb); ++struct ipx_route *ipxrtr_lookup(__be32 net); ++int ipxrtr_ioctl(unsigned int cmd, void __user *arg); ++ ++static __inline__ void ipxitf_put(struct ipx_interface *intrfc) ++{ ++ if (refcount_dec_and_test(&intrfc->refcnt)) ++ ipxitf_down(intrfc); ++} ++ ++static __inline__ void ipxrtr_hold(struct ipx_route *rt) ++{ ++ refcount_inc(&rt->refcnt); ++} ++ ++static __inline__ void ipxrtr_put(struct ipx_route *rt) ++{ ++ if (refcount_dec_and_test(&rt->refcnt)) ++ kfree(rt); ++} ++#endif /* _NET_INET_IPX_H_ */ +diff --git a/include/uapi/linux/ipx.h b/include/uapi/linux/ipx.h +new file mode 100644 +index 000000000000..3168137adae8 +--- /dev/null ++++ b/include/uapi/linux/ipx.h +@@ -0,0 +1,87 @@ ++/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ ++#ifndef _IPX_H_ ++#define _IPX_H_ ++#include /* for compatibility with glibc netipx/ipx.h */ ++#include ++#include ++#include ++#define IPX_NODE_LEN 6 ++#define IPX_MTU 576 ++ ++#if __UAPI_DEF_SOCKADDR_IPX ++struct sockaddr_ipx { ++ __kernel_sa_family_t sipx_family; ++ __be16 sipx_port; ++ __be32 sipx_network; ++ unsigned char sipx_node[IPX_NODE_LEN]; ++ __u8 sipx_type; ++ unsigned char sipx_zero; /* 16 byte fill */ ++}; ++#endif /* __UAPI_DEF_SOCKADDR_IPX */ ++ ++/* ++ * So we can fit the extra info for SIOCSIFADDR into the address nicely ++ */ ++#define sipx_special sipx_port ++#define sipx_action sipx_zero ++#define IPX_DLTITF 0 ++#define IPX_CRTITF 1 ++ ++#if __UAPI_DEF_IPX_ROUTE_DEFINITION ++struct ipx_route_definition { ++ __be32 ipx_network; ++ __be32 ipx_router_network; ++ unsigned char ipx_router_node[IPX_NODE_LEN]; ++}; ++#endif /* __UAPI_DEF_IPX_ROUTE_DEFINITION */ ++ ++#if __UAPI_DEF_IPX_INTERFACE_DEFINITION ++struct ipx_interface_definition { ++ __be32 ipx_network; ++ unsigned char ipx_device[16]; ++ unsigned char ipx_dlink_type; ++#define IPX_FRAME_NONE 0 ++#define IPX_FRAME_SNAP 1 ++#define IPX_FRAME_8022 2 ++#define IPX_FRAME_ETHERII 3 ++#define IPX_FRAME_8023 4 ++#define IPX_FRAME_TR_8022 5 /* obsolete */ ++ unsigned char ipx_special; ++#define IPX_SPECIAL_NONE 0 ++#define IPX_PRIMARY 1 ++#define IPX_INTERNAL 2 ++ unsigned char ipx_node[IPX_NODE_LEN]; ++}; ++#endif /* __UAPI_DEF_IPX_INTERFACE_DEFINITION */ ++ ++#if __UAPI_DEF_IPX_CONFIG_DATA ++struct ipx_config_data { ++ unsigned char ipxcfg_auto_select_primary; ++ unsigned char ipxcfg_auto_create_interfaces; ++}; ++#endif /* __UAPI_DEF_IPX_CONFIG_DATA */ ++ ++/* ++ * OLD Route Definition for backward compatibility. ++ */ ++ ++#if __UAPI_DEF_IPX_ROUTE_DEF ++struct ipx_route_def { ++ __be32 ipx_network; ++ __be32 ipx_router_network; ++#define IPX_ROUTE_NO_ROUTER 0 ++ unsigned char ipx_router_node[IPX_NODE_LEN]; ++ unsigned char ipx_device[16]; ++ unsigned short ipx_flags; ++#define IPX_RT_SNAP 8 ++#define IPX_RT_8022 4 ++#define IPX_RT_BLUEBOOK 2 ++#define IPX_RT_ROUTED 1 ++}; ++#endif /* __UAPI_DEF_IPX_ROUTE_DEF */ ++ ++#define SIOCAIPXITFCRT (SIOCPROTOPRIVATE) ++#define SIOCAIPXPRISLT (SIOCPROTOPRIVATE + 1) ++#define SIOCIPXCFGDATA (SIOCPROTOPRIVATE + 2) ++#define SIOCIPXNCPCONN (SIOCPROTOPRIVATE + 3) ++#endif /* _IPX_H_ */ +-- +2.25.1 + diff --git a/patch/kernel/archive/rk35xx-5.16/rk3568-dts-radxa-rock3a-support.patch b/patch/kernel/archive/rk35xx-5.16/rk3568-dts-radxa-rock3a-support.patch new file mode 100644 index 0000000000..6b517574cb --- /dev/null +++ b/patch/kernel/archive/rk35xx-5.16/rk3568-dts-radxa-rock3a-support.patch @@ -0,0 +1,618 @@ +diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile +index 479906f3ad7b..bf2a58e3a871 100644 +--- a/arch/arm64/boot/dts/rockchip/Makefile ++++ b/arch/arm64/boot/dts/rockchip/Makefile +@@ -58,3 +58,4 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-sapphire-excavator.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399pro-rock-pi-n10.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-quartz64-a.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-evb1-v10.dtb ++dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-rock-3-a.dtb +diff --git a/arch/arm64/boot/dts/rockchip/rk3568-rock-3-a.dts b/arch/arm64/boot/dts/rockchip/rk3568-rock-3-a.dts +new file mode 100644 +index 000000000000..7ee3574a338d +--- /dev/null ++++ b/arch/arm64/boot/dts/rockchip/rk3568-rock-3-a.dts +@@ -0,0 +1,602 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++/* ++ * Copyright (c) 2021 Rockchip Electronics Co., Ltd. ++ * ++ */ ++ ++/dts-v1/; ++ ++#include ++#include ++#include ++#include "rk3568.dtsi" ++ ++/ { ++ model = "Radxa Rock3A"; ++ compatible = "radxa,rk3568-rock-3a", "rockchip,rk3568"; ++ ++ aliases { ++ ethernet1 = &gmac1; ++ mmc0 = &sdmmc0; ++ mmc1 = &sdhci; ++ }; ++ ++ chosen: chosen { ++ stdout-path = "serial2:1500000n8"; ++ }; ++ ++ gmac1_clkin: external-gmac1-clock { ++ compatible = "fixed-clock"; ++ clock-frequency = <125000000>; ++ clock-output-names = "gmac1_clkin"; ++ #clock-cells = <0>; ++ }; ++ ++ hdmi-con { ++ compatible = "hdmi-connector"; ++ type = "c"; ++ ++ port { ++ hdmi_con_in: endpoint { ++ remote-endpoint = <&hdmi_out_con>; ++ }; ++ }; ++ }; ++ ++ leds { ++ compatible = "gpio-leds"; ++ ++ led-user { ++ label = "user-led"; ++ default-state = "on"; ++ gpios = <&gpio0 RK_PB7 GPIO_ACTIVE_HIGH>; ++ linux,default-trigger = "heartbeat"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&user_led_enable_h>; ++ retain-state-suspended; ++ }; ++ }; ++ ++ sdio_pwrseq: sdio-pwrseq { ++ status = "okay"; ++ compatible = "mmc-pwrseq-simple"; ++ clocks = <&rk809 1>; ++ clock-names = "ext_clock"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&wifi_enable_h>; ++ reset-gpios = <&gpio3 RK_PD4 GPIO_ACTIVE_LOW>; ++ }; ++ ++ dc_12v: dc-12v { ++ compatible = "regulator-fixed"; ++ regulator-name = "dc_12v"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <12000000>; ++ regulator-max-microvolt = <12000000>; ++ }; ++ ++ vcc3v3_sys: vcc3v3-sys { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc3v3_sys"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ vin-supply = <&dc_12v>; ++ }; ++ ++ vcc5v0_sys: vcc5v0-sys { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc5v0_sys"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ vin-supply = <&dc_12v>; ++ }; ++ ++ vcc5v0_usb: vcc5v0-usb { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc5v0_usb"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ vin-supply = <&vcc5v0_sys>; ++ }; ++ ++ vcc5v0_host: vcc5v0-host { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc5v0_host"; ++ enable-active-high; ++ gpio = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&vcc5v0_host_en>; ++ regulator-always-on; ++ vin-supply = <&vcc5v0_usb>; ++ }; ++ ++ vcc5v0_otg: vcc5v0-otg { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc5v0_otg"; ++ enable-active-high; ++ gpio = <&gpio0 RK_PA5 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&vcc5v0_otg_en>; ++ vin-supply = <&vcc5v0_usb>; ++ }; ++ ++ vcc3v3_lcd0_n: vcc3v3-lcd0-n { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc3v3_lcd0_n"; ++ regulator-boot-on; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcc3v3_lcd1_n: vcc3v3-lcd1-n { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc3v3_lcd1_n"; ++ regulator-boot-on; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ ++}; ++ ++&combphy1 { ++ status = "okay"; ++}; ++ ++&combphy2 { ++ status = "okay"; ++}; ++ ++&gmac1 { ++ phy-mode = "rgmii"; ++ clock_in_out = "input"; ++ ++ snps,reset-gpio = <&gpio3 RK_PB0 GPIO_ACTIVE_LOW>; ++ snps,reset-active-low; ++ /* Reset time is 20ms, 100ms for rtl8211f */ ++ snps,reset-delays-us = <0 20000 100000>; ++ ++ assigned-clocks = <&cru SCLK_GMAC1_RX_TX>, <&cru SCLK_GMAC1>; ++ assigned-clock-parents = <&cru SCLK_GMAC1_RGMII_SPEED>, <&gmac1_clkin>; ++ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&gmac1m1_miim ++ &gmac1m1_tx_bus2 ++ &gmac1m1_rx_bus2 ++ &gmac1m1_rgmii_clk ++ &gmac1m1_rgmii_bus ++ &gmac1m1_clkinout>; ++ ++ tx_delay = <0x4f>; ++ rx_delay = <0x26>; ++ ++ phy-handle = <&rgmii_phy1>; ++ status = "okay"; ++}; ++ ++&hdmi { ++ avdd-0v9-supply = <&vdda0v9_image>; ++ avdd-1v8-supply = <&vcca1v8_image>; ++ status = "okay"; ++}; ++ ++&hdmi_in { ++ hdmi_in_vp0: endpoint@0 { ++ reg = <0>; ++ remote-endpoint = <&vp0_out_hdmi>; ++ }; ++}; ++ ++&hdmi_out { ++ hdmi_out_con: endpoint { ++ remote-endpoint = <&hdmi_con_in>; ++ }; ++}; ++ ++&i2c0 { ++ status = "okay"; ++ ++ vdd_cpu: regulator@1c { ++ compatible = "tcs,tcs4525"; ++ reg = <0x1c>; ++ fcs,suspend-voltage-selector = <1>; ++ regulator-name = "vdd_cpu"; ++ regulator-min-microvolt = <800000>; ++ regulator-max-microvolt = <1150000>; ++ regulator-ramp-delay = <2300>; ++ regulator-always-on; ++ regulator-boot-on; ++ vin-supply = <&vcc5v0_sys>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ ++ rk809: pmic@20 { ++ compatible = "rockchip,rk809"; ++ reg = <0x20>; ++ interrupt-parent = <&gpio0>; ++ interrupts = ; ++ #clock-cells = <1>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pmic_int>; ++ rockchip,system-power-controller; ++ vcc1-supply = <&vcc3v3_sys>; ++ vcc2-supply = <&vcc3v3_sys>; ++ vcc3-supply = <&vcc3v3_sys>; ++ vcc4-supply = <&vcc3v3_sys>; ++ vcc5-supply = <&vcc3v3_sys>; ++ vcc6-supply = <&vcc3v3_sys>; ++ vcc7-supply = <&vcc3v3_sys>; ++ vcc8-supply = <&vcc3v3_sys>; ++ vcc9-supply = <&vcc3v3_sys>; ++ wakeup-source; ++ ++ regulators { ++ vdd_logic: DCDC_REG1 { ++ regulator-name = "vdd_logic"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-init-microvolt = <900000>; ++ regulator-initial-mode = <0x2>; ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <1350000>; ++ regulator-ramp-delay = <6001>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vdd_gpu: DCDC_REG2 { ++ regulator-name = "vdd_gpu"; ++ regulator-init-microvolt = <900000>; ++ regulator-initial-mode = <0x2>; ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <1350000>; ++ regulator-ramp-delay = <6001>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcc_ddr: DCDC_REG3 { ++ regulator-name = "vcc_ddr"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-initial-mode = <0x2>; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ }; ++ }; ++ ++ vdd_npu: DCDC_REG4 { ++ regulator-name = "vdd_npu"; ++ regulator-init-microvolt = <900000>; ++ regulator-initial-mode = <0x2>; ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <1350000>; ++ regulator-ramp-delay = <6001>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcc_1v8: DCDC_REG5 { ++ regulator-name = "vcc_1v8"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vdda0v9_image: LDO_REG1 { ++ regulator-name = "vdda0v9_image"; ++ regulator-min-microvolt = <900000>; ++ regulator-max-microvolt = <900000>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vdda_0v9: LDO_REG2 { ++ regulator-name = "vdda_0v9"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <900000>; ++ regulator-max-microvolt = <900000>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vdda0v9_pmu: LDO_REG3 { ++ regulator-name = "vdda0v9_pmu"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <900000>; ++ regulator-max-microvolt = <900000>; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <900000>; ++ }; ++ }; ++ ++ vccio_acodec: LDO_REG4 { ++ regulator-name = "vccio_acodec"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vccio_sd: LDO_REG5 { ++ regulator-name = "vccio_sd"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <3300000>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcc3v3_pmu: LDO_REG6 { ++ regulator-name = "vcc3v3_pmu"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <3300000>; ++ }; ++ }; ++ ++ vcca_1v8: LDO_REG7 { ++ regulator-name = "vcca_1v8"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcca1v8_pmu: LDO_REG8 { ++ regulator-name = "vcca1v8_pmu"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ vcca1v8_image: LDO_REG9 { ++ regulator-name = "vcca1v8_image"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcc_3v3: SWITCH_REG1 { ++ regulator-name = "vcc_3v3"; ++ regulator-always-on; ++ regulator-boot-on; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcc3v3_sd: SWITCH_REG2 { ++ regulator-name = "vcc3v3_sd"; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ }; ++ }; ++}; ++ ++ ++&mdio1 { ++ rgmii_phy1: phy@0 { ++ compatible = "ethernet-phy-ieee802.3-c22"; ++ reg = <0x0>; ++ }; ++}; ++ ++&pinctrl { ++ leds { ++ user_led_enable_h: user-led-enable-h { ++ rockchip,pins = <0 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ sdio-pwrseq { ++ wifi_enable_h: wifi-enable-h { ++ rockchip,pins = <3 RK_PD4 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ usb { ++ vcc5v0_host_en: vcc5v0-host-en { ++ rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ vcc5v0_otg_en: vcc5v0-otg-en { ++ rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ pmic { ++ pmic_int: pmic_int { ++ rockchip,pins = ++ <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ }; ++}; ++ ++&i2s0_8ch { ++ status = "okay"; ++}; ++ ++&pmu_io_domains { ++ pmuio1-supply = <&vcc3v3_pmu>; ++ pmuio2-supply = <&vcc3v3_pmu>; ++ vccio1-supply = <&vccio_acodec>; ++ vccio2-supply = <&vcc_1v8>; ++ vccio3-supply = <&vccio_sd>; ++ vccio4-supply = <&vcc_1v8>; ++ vccio5-supply = <&vcc_3v3>; ++ vccio6-supply = <&vcc_1v8>; ++ vccio7-supply = <&vcc_3v3>; ++ status = "okay"; ++}; ++ ++&saradc { ++ vref-supply = <&vcca_1v8>; ++ status = "okay"; ++}; ++ ++&sdhci { ++ bus-width = <8>; ++ max-frequency = <200000000>; ++ non-removable; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&emmc_bus8 &emmc_clk &emmc_cmd &emmc_datastrobe>; ++ status = "okay"; ++}; ++ ++&sdmmc0 { ++ bus-width = <4>; ++ cap-sd-highspeed; ++ cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>; ++ disable-wp; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdmmc0_bus4 &sdmmc0_clk &sdmmc0_cmd &sdmmc0_det>; ++ sd-uhs-sdr104; ++ vmmc-supply = <&vcc3v3_sd>; ++ vqmmc-supply = <&vccio_sd>; ++ status = "okay"; ++}; ++ ++&tsadc { ++ status = "okay"; ++}; ++ ++&uart2 { ++ status = "okay"; ++}; ++ ++&vop { ++ status = "okay"; ++ assigned-clocks = <&cru DCLK_VOP0>, <&cru DCLK_VOP1>; ++ assigned-clock-parents = <&pmucru PLL_HPLL>, <&cru PLL_VPLL>; ++}; ++ ++&vop_mmu { ++ status = "okay"; ++}; ++ ++&vp0 { ++ vp0_out_hdmi: endpoint@RK3568_VOP2_EP_HDMI { ++ reg = ; ++ remote-endpoint = <&hdmi_in_vp0>; ++ }; ++}; ++ ++&hdmi_sound { ++ status = "okay"; ++}; ++ ++&gpu { ++ mali-supply = <&vdd_gpu>; ++ status = "okay"; ++}; ++ ++&u2phy0_host { ++ phy-supply = <&vcc5v0_host>; ++ status = "okay"; ++}; ++ ++&u2phy0_otg { ++ status = "okay"; ++}; ++ ++&u2phy1_host { ++ phy-supply = <&vcc5v0_host>; ++ status = "okay"; ++}; ++ ++&u2phy1_otg { ++ phy-supply = <&vcc5v0_host>; ++ status = "okay"; ++}; ++ ++&u2phy0 { ++ status = "okay"; ++}; ++ ++&u2phy1 { ++ status = "okay"; ++}; ++ ++&usbdrd_dwc3 { ++ status = "okay"; ++}; ++ ++&usbdrd30 { ++ status = "okay"; ++}; ++ ++&usbhost_dwc3 { ++ status = "okay"; ++}; ++ ++&usbhost30 { ++ status = "okay"; ++}; ++ ++&usb_host0_ehci { ++ status = "okay"; ++}; ++ ++&usb_host0_ohci { ++ status = "okay"; ++}; +\ No newline at end of file diff --git a/patch/kernel/archive/rk35xx-5.16/rk356x-drm-rockchip-VOP2-support.patch b/patch/kernel/archive/rk35xx-5.16/rk356x-drm-rockchip-VOP2-support.patch new file mode 100644 index 0000000000..cc85a29dcd --- /dev/null +++ b/patch/kernel/archive/rk35xx-5.16/rk356x-drm-rockchip-VOP2-support.patch @@ -0,0 +1,6245 @@ +diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +index 830bdd5e9b7ce..8677c82716784 100644 +--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c ++++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +@@ -529,13 +529,6 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master, + return ret; + } + +- ret = clk_prepare_enable(hdmi->vpll_clk); +- if (ret) { +- DRM_DEV_ERROR(hdmi->dev, "Failed to enable HDMI vpll: %d\n", +- ret); +- return ret; +- } +- + hdmi->phy = devm_phy_optional_get(dev, "hdmi"); + if (IS_ERR(hdmi->phy)) { + ret = PTR_ERR(hdmi->phy); +@@ -544,6 +537,13 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master, + return ret; + } + ++ ret = clk_prepare_enable(hdmi->vpll_clk); ++ if (ret) { ++ DRM_DEV_ERROR(hdmi->dev, "Failed to enable HDMI vpll: %d\n", ++ ret); ++ return ret; ++ } ++ + drm_encoder_helper_add(encoder, &dw_hdmi_rockchip_encoder_helper_funcs); + drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_TMDS); + +diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +index 8677c82716784..e352e0404f772 100644 +--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c ++++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +@@ -69,7 +69,7 @@ struct rockchip_hdmi { + struct regmap *regmap; + struct drm_encoder encoder; + const struct rockchip_hdmi_chip_data *chip_data; +- struct clk *vpll_clk; ++ struct clk *ref_clk; + struct clk *grf_clk; + struct dw_hdmi *hdmi; + struct phy *phy; +@@ -196,14 +196,17 @@ static int rockchip_hdmi_parse_dt(struct rockchip_hdmi *hdmi) + return PTR_ERR(hdmi->regmap); + } + +- hdmi->vpll_clk = devm_clk_get(hdmi->dev, "vpll"); +- if (PTR_ERR(hdmi->vpll_clk) == -ENOENT) { +- hdmi->vpll_clk = NULL; +- } else if (PTR_ERR(hdmi->vpll_clk) == -EPROBE_DEFER) { ++ hdmi->ref_clk = devm_clk_get(hdmi->dev, "ref"); ++ if (PTR_ERR(hdmi->ref_clk) == -ENOENT) ++ hdmi->ref_clk = devm_clk_get(hdmi->dev, "vpll"); ++ ++ if (PTR_ERR(hdmi->ref_clk) == -ENOENT) { ++ hdmi->ref_clk = NULL; ++ } else if (PTR_ERR(hdmi->ref_clk) == -EPROBE_DEFER) { + return -EPROBE_DEFER; +- } else if (IS_ERR(hdmi->vpll_clk)) { +- DRM_DEV_ERROR(hdmi->dev, "failed to get vpll clock\n"); +- return PTR_ERR(hdmi->vpll_clk); ++ } else if (IS_ERR(hdmi->ref_clk)) { ++ DRM_DEV_ERROR(hdmi->dev, "failed to get reference clock\n"); ++ return PTR_ERR(hdmi->ref_clk); + } + + hdmi->grf_clk = devm_clk_get(hdmi->dev, "grf"); +@@ -257,7 +260,7 @@ static void dw_hdmi_rockchip_encoder_mode_set(struct drm_encoder *encoder, + { + struct rockchip_hdmi *hdmi = to_rockchip_hdmi(encoder); + +- clk_set_rate(hdmi->vpll_clk, adj_mode->clock * 1000); ++ clk_set_rate(hdmi->ref_clk, adj_mode->clock * 1000); + } + + static void dw_hdmi_rockchip_encoder_enable(struct drm_encoder *encoder) +@@ -537,9 +540,9 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master, + return ret; + } + +- ret = clk_prepare_enable(hdmi->vpll_clk); ++ ret = clk_prepare_enable(hdmi->ref_clk); + if (ret) { +- DRM_DEV_ERROR(hdmi->dev, "Failed to enable HDMI vpll: %d\n", ++ DRM_DEV_ERROR(hdmi->dev, "Failed to enable HDMI reference clock: %d\n", + ret); + return ret; + } +@@ -558,7 +561,7 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master, + if (IS_ERR(hdmi->hdmi)) { + ret = PTR_ERR(hdmi->hdmi); + drm_encoder_cleanup(encoder); +- clk_disable_unprepare(hdmi->vpll_clk); ++ clk_disable_unprepare(hdmi->ref_clk); + } + + return ret; +@@ -570,7 +573,7 @@ static void dw_hdmi_rockchip_unbind(struct device *dev, struct device *master, + struct rockchip_hdmi *hdmi = dev_get_drvdata(dev); + + dw_hdmi_unbind(hdmi->hdmi); +- clk_disable_unprepare(hdmi->vpll_clk); ++ clk_disable_unprepare(hdmi->ref_clk); + } + + static const struct component_ops dw_hdmi_rockchip_ops = { +diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +index e352e0404f772..262eef614cb12 100644 +--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c ++++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +@@ -50,6 +50,10 @@ + #define RK3399_GRF_SOC_CON20 0x6250 + #define RK3399_HDMI_LCDC_SEL BIT(6) + ++#define RK3568_GRF_VO_CON1 0x0364 ++#define RK3568_HDMI_SDAIN_MSK BIT(15) ++#define RK3568_HDMI_SCLIN_MSK BIT(14) ++ + #define HIWORD_UPDATE(val, mask) (val | (mask) << 16) + + /** +@@ -470,6 +474,19 @@ static const struct dw_hdmi_plat_data rk3399_hdmi_drv_data = { + .use_drm_infoframe = true, + }; + ++static struct rockchip_hdmi_chip_data rk3568_chip_data = { ++ .lcdsel_grf_reg = -1, ++}; ++ ++static const struct dw_hdmi_plat_data rk3568_hdmi_drv_data = { ++ .mode_valid = dw_hdmi_rockchip_mode_valid, ++ .mpll_cfg = rockchip_mpll_cfg, ++ .cur_ctr = rockchip_cur_ctr, ++ .phy_config = rockchip_phy_config, ++ .phy_data = &rk3568_chip_data, ++ .use_drm_infoframe = true, ++}; ++ + static const struct of_device_id dw_hdmi_rockchip_dt_ids[] = { + { .compatible = "rockchip,rk3228-dw-hdmi", + .data = &rk3228_hdmi_drv_data +@@ -483,6 +500,9 @@ static const struct of_device_id dw_hdmi_rockchip_dt_ids[] = { + { .compatible = "rockchip,rk3399-dw-hdmi", + .data = &rk3399_hdmi_drv_data + }, ++ { .compatible = "rockchip,rk3568-dw-hdmi", ++ .data = &rk3568_hdmi_drv_data ++ }, + {}, + }; + MODULE_DEVICE_TABLE(of, dw_hdmi_rockchip_dt_ids); +@@ -517,6 +537,9 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master, + encoder = &hdmi->encoder; + + encoder->possible_crtcs = drm_of_find_possible_crtcs(drm, dev->of_node); ++ ++ encoder->port = of_graph_get_port_by_id(dev->of_node, 0); ++ + /* + * If we failed to find the CRTC(s) which this encoder is + * supposed to be connected to, it's because the CRTC has +@@ -547,6 +570,14 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master, + return ret; + } + ++ if (hdmi->chip_data == &rk3568_chip_data) { ++ regmap_write(hdmi->regmap, RK3568_GRF_VO_CON1, ++ HIWORD_UPDATE(RK3568_HDMI_SDAIN_MSK | ++ RK3568_HDMI_SCLIN_MSK, ++ RK3568_HDMI_SDAIN_MSK | ++ RK3568_HDMI_SCLIN_MSK)); ++ } ++ + drm_encoder_helper_add(encoder, &dw_hdmi_rockchip_encoder_helper_funcs); + drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_TMDS); + +diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +index 262eef614cb12..3d7c3f6fdf223 100644 +--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c ++++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +@@ -9,6 +9,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -76,6 +77,8 @@ struct rockchip_hdmi { + struct clk *ref_clk; + struct clk *grf_clk; + struct dw_hdmi *hdmi; ++ struct regulator *avdd_0v9; ++ struct regulator *avdd_1v8; + struct phy *phy; + }; + +@@ -223,6 +226,14 @@ static int rockchip_hdmi_parse_dt(struct rockchip_hdmi *hdmi) + return PTR_ERR(hdmi->grf_clk); + } + ++ hdmi->avdd_0v9 = devm_regulator_get(hdmi->dev, "avdd-0v9"); ++ if (IS_ERR(hdmi->avdd_0v9)) ++ return PTR_ERR(hdmi->avdd_0v9); ++ ++ hdmi->avdd_1v8 = devm_regulator_get(hdmi->dev, "avdd-1v8"); ++ if (IS_ERR(hdmi->avdd_1v8)) ++ return PTR_ERR(hdmi->avdd_1v8); ++ + return 0; + } + +@@ -563,11 +574,23 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master, + return ret; + } + ++ ret = regulator_enable(hdmi->avdd_0v9); ++ if (ret) { ++ DRM_DEV_ERROR(hdmi->dev, "failed to enable avdd0v9: %d\n", ret); ++ goto err_avdd_0v9; ++ } ++ ++ ret = regulator_enable(hdmi->avdd_1v8); ++ if (ret) { ++ DRM_DEV_ERROR(hdmi->dev, "failed to enable avdd1v8: %d\n", ret); ++ goto err_avdd_1v8; ++ } ++ + ret = clk_prepare_enable(hdmi->ref_clk); + if (ret) { + DRM_DEV_ERROR(hdmi->dev, "Failed to enable HDMI reference clock: %d\n", + ret); +- return ret; ++ goto err_clk; + } + + if (hdmi->chip_data == &rk3568_chip_data) { +@@ -591,10 +614,19 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master, + */ + if (IS_ERR(hdmi->hdmi)) { + ret = PTR_ERR(hdmi->hdmi); +- drm_encoder_cleanup(encoder); +- clk_disable_unprepare(hdmi->ref_clk); ++ goto err_bind; + } + ++ return 0; ++ ++err_bind: ++ clk_disable_unprepare(hdmi->ref_clk); ++ drm_encoder_cleanup(encoder); ++err_clk: ++ regulator_disable(hdmi->avdd_1v8); ++err_avdd_1v8: ++ regulator_disable(hdmi->avdd_0v9); ++err_avdd_0v9: + return ret; + } + +@@ -605,6 +637,9 @@ static void dw_hdmi_rockchip_unbind(struct device *dev, struct device *master, + + dw_hdmi_unbind(hdmi->hdmi); + clk_disable_unprepare(hdmi->ref_clk); ++ ++ regulator_disable(hdmi->avdd_1v8); ++ regulator_disable(hdmi->avdd_0v9); + } + + static const struct component_ops dw_hdmi_rockchip_ops = { +diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +index 3d7c3f6fdf223..b9928e622adf5 100644 +--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c ++++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +@@ -76,6 +76,7 @@ struct rockchip_hdmi { + const struct rockchip_hdmi_chip_data *chip_data; + struct clk *ref_clk; + struct clk *grf_clk; ++ struct clk *hclk_clk; + struct dw_hdmi *hdmi; + struct regulator *avdd_0v9; + struct regulator *avdd_1v8; +@@ -226,6 +227,16 @@ static int rockchip_hdmi_parse_dt(struct rockchip_hdmi *hdmi) + return PTR_ERR(hdmi->grf_clk); + } + ++ hdmi->hclk_clk = devm_clk_get(hdmi->dev, "hclk"); ++ if (PTR_ERR(hdmi->hclk_clk) == -ENOENT) { ++ hdmi->hclk_clk = NULL; ++ } else if (PTR_ERR(hdmi->hclk_clk) == -EPROBE_DEFER) { ++ return -EPROBE_DEFER; ++ } else if (IS_ERR(hdmi->hclk_clk)) { ++ DRM_DEV_ERROR(hdmi->dev, "failed to get hclk_clk clock\n"); ++ return PTR_ERR(hdmi->hclk_clk); ++ } ++ + hdmi->avdd_0v9 = devm_regulator_get(hdmi->dev, "avdd-0v9"); + if (IS_ERR(hdmi->avdd_0v9)) + return PTR_ERR(hdmi->avdd_0v9); +@@ -593,6 +604,13 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master, + goto err_clk; + } + ++ ret = clk_prepare_enable(hdmi->hclk_clk); ++ if (ret) { ++ DRM_DEV_ERROR(hdmi->dev, "Failed to enable HDMI hclk clock: %d\n", ++ ret); ++ goto err_clk; ++ } ++ + if (hdmi->chip_data == &rk3568_chip_data) { + regmap_write(hdmi->regmap, RK3568_GRF_VO_CON1, + HIWORD_UPDATE(RK3568_HDMI_SDAIN_MSK | +diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi.yaml b/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi.yaml +index da3b889ad8fcd..45cae4f57a1c1 100644 +--- a/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi.yaml ++++ b/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi.yaml +@@ -23,6 +23,7 @@ properties: + - rockchip,rk3288-dw-hdmi + - rockchip,rk3328-dw-hdmi + - rockchip,rk3399-dw-hdmi ++ - rockchip,rk3568-dw-hdmi + + reg-io-width: + const: 4 +diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi.yaml b/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi.yaml +index 45cae4f57a1c1..6e09dd2ee05ac 100644 +--- a/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi.yaml ++++ b/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi.yaml +@@ -73,6 +73,7 @@ properties: + The unwedge pinctrl entry shall drive the DDC SDA line low. This is + intended to work around a hardware errata that can cause the DDC I2C + bus to be wedged. ++ minItems: 1 + items: + - const: default + - const: unwedge +From patchwork Mon Dec 20 11:06:16 2021 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +X-Patchwork-Submitter: Sascha Hauer +X-Patchwork-Id: 12687625 +Return-Path: + +X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on + aws-us-west-2-korg-lkml-1.web.codeaurora.org +Received: from bombadil.infradead.org (bombadil.infradead.org + [198.137.202.133]) + (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) + (No client certificate requested) + by smtp.lore.kernel.org (Postfix) with ESMTPS id 7D787C4332F + for ; + Mon, 20 Dec 2021 11:21:43 +0000 (UTC) +DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; + d=lists.infradead.org; s=bombadil.20210309; h=Sender: + Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: + List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: + Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: + Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: + List-Owner; bh=dPAqJXapcobg6sEdWol3+UOIIBgXZYUh6ue5+adn5MY=; b=QyVZSelYHNkM7g + GAOX659fBRm9mX0hK4dAGOQeENMZR5pJ60Ye9Kmw+wOarTbkL5dgtXWAu6cFJISjlv03Pe3QQKuNo + 9oaKPa5myV35GYXOcL/UNnN9lnGdnhketCZdvsXdhr/0FGNOBYb+eL4KdLMpYSt7mBKg3S+/iSh+u + BEaGRMRcXD+cR4/QReVjT33bACLC9Nsnf9vYKj73PcOGQ4n1ZDScswkbpyWk9E8HH2qHs7xSSQ+Vy + sIK576UWpqb3sgnRm62/JSvR9lFSA99n1+Tig9fMEIKI2HNpeAhOi5/kCCT04qHAMOSkf9mcLUmZB + f1OPbk3GvRCHsGpisD5A==; +Received: from localhost ([::1] helo=bombadil.infradead.org) + by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) + id 1mzGjb-001wBg-DV; Mon, 20 Dec 2021 11:21:39 +0000 +Received: from metis.ext.pengutronix.de ([85.220.165.71]) + by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) + id 1mzGVi-001oUQ-Er + for linux-rockchip@lists.infradead.org; Mon, 20 Dec 2021 11:07:19 +0000 +Received: from dude02.hi.pengutronix.de ([2001:67c:670:100:1d::28]) + by metis.ext.pengutronix.de with esmtps + (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) + (envelope-from ) + id 1mzGVH-0004x7-7m; Mon, 20 Dec 2021 12:06:51 +0100 +Received: from sha by dude02.hi.pengutronix.de with local (Exim 4.94.2) + (envelope-from ) + id 1mzGVA-00EmEJ-Kw; Mon, 20 Dec 2021 12:06:44 +0100 +From: Sascha Hauer +To: dri-devel@lists.freedesktop.org +Cc: linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, + devicetree@vger.kernel.org, kernel@pengutronix.de, + Andy Yan , + Benjamin Gaignard , + Michael Riesch , + Sandy Huang , + =?utf-8?q?Heiko_St=C3=BCbner?= , + Peter Geis , Sascha Hauer +Subject: [PATCH 08/22] dt-bindings: display: rockchip: dw-hdmi: use "ref" as + clock name +Date: Mon, 20 Dec 2021 12:06:16 +0100 +Message-Id: <20211220110630.3521121-9-s.hauer@pengutronix.de> +X-Mailer: git-send-email 2.30.2 +In-Reply-To: <20211220110630.3521121-1-s.hauer@pengutronix.de> +References: <20211220110630.3521121-1-s.hauer@pengutronix.de> +MIME-Version: 1.0 +X-SA-Exim-Connect-IP: 2001:67c:670:100:1d::28 +X-SA-Exim-Mail-From: sha@pengutronix.de +X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); + SAEximRunCond expanded to false +X-PTX-Original-Recipient: linux-rockchip@lists.infradead.org +X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 +X-CRM114-CacheID: sfid-20211220_030718_534274_9B6345AC +X-CRM114-Status: GOOD ( 10.57 ) +X-BeenThere: linux-rockchip@lists.infradead.org +X-Mailman-Version: 2.1.34 +Precedence: list +List-Id: Upstream kernel work for Rockchip platforms + +List-Unsubscribe: , + +List-Archive: +List-Post: +List-Help: +List-Subscribe: , + +Sender: "Linux-rockchip" +Errors-To: + linux-rockchip-bounces+linux-rockchip=archiver.kernel.org@lists.infradead.org + +"vpll" is a misnomer. A clock input to a device should be named after +the usage in the device, not after the clock that drives it. On the +rk3568 the same clock is driven by the HPLL. +To fix that, this patch renames the vpll clock to ref clock. + +Signed-off-by: Sascha Hauer +--- + .../bindings/display/rockchip/rockchip,dw-hdmi.yaml | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi.yaml b/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi.yaml +index 6e09dd2ee05ac..3b40219e3ea60 100644 +--- a/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi.yaml ++++ b/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi.yaml +@@ -47,11 +47,12 @@ properties: + - enum: + - cec + - grf +- - vpll ++ - ref + - enum: + - grf +- - vpll +- - const: vpll ++ - ref ++ - const: ++ - ref + + ddc-i2c-bus: + $ref: /schemas/types.yaml#/definitions/phandle +From patchwork Mon Dec 20 11:06:17 2021 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +X-Patchwork-Submitter: Sascha Hauer +X-Patchwork-Id: 12687591 +Return-Path: + +X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on + aws-us-west-2-korg-lkml-1.web.codeaurora.org +Received: from bombadil.infradead.org (bombadil.infradead.org + [198.137.202.133]) + (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) + (No client certificate requested) + by smtp.lore.kernel.org (Postfix) with ESMTPS id 28BBEC433F5 + for ; + Mon, 20 Dec 2021 11:12:14 +0000 (UTC) +DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; + d=lists.infradead.org; s=bombadil.20210309; h=Sender: + Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: + List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: + Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: + Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: + List-Owner; bh=56JaLhOg7xaiSLxORRzgZeFeO4IZvpjDMoqQDuErR9U=; b=ADAhLg2W0pJFTA + d3j7siBTG6wH4NBip6zU2KQ5a8z0LawfOiExjTBzMGOvdgPzYKEK09xCDDVWqaHOTVv76c6VKSZK8 + zxUvrSC5spdI7tWZpbgl8OJs9V/i1sj/MSaBUE+EieIYeREq/nrqt4FB9fKS/Eq2vXrWCLWxMAAGD + Vtfvu/43aRrsDFe0iR+5etl7DStcZjvPeAcwqEtp0Epl0dGBMZH0uGebTuIT31cEvHEBNNQLoJTaW + pt8Z5zjowpPdYkOhx+29dXF30KUeIlqbYL79v8YC/wBTgjLDFfp6/WxX/0DUQQVDyQ+L/0oVk3WX/ + h6csdv8bTdzvmWj4cCVg==; +Received: from localhost ([::1] helo=bombadil.infradead.org) + by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) + id 1mzGaQ-001rIu-OL; Mon, 20 Dec 2021 11:12:10 +0000 +Received: from metis.ext.pengutronix.de + ([2001:67c:670:201:290:27ff:fe1d:cc33]) + by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) + id 1mzGVQ-001oHz-4c + for linux-rockchip@lists.infradead.org; Mon, 20 Dec 2021 11:07:05 +0000 +Received: from dude02.hi.pengutronix.de ([2001:67c:670:100:1d::28]) + by metis.ext.pengutronix.de with esmtps + (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) + (envelope-from ) + id 1mzGVE-0004x8-DL; Mon, 20 Dec 2021 12:06:48 +0100 +Received: from sha by dude02.hi.pengutronix.de with local (Exim 4.94.2) + (envelope-from ) + id 1mzGVA-00EmEM-LY; Mon, 20 Dec 2021 12:06:44 +0100 +From: Sascha Hauer +To: dri-devel@lists.freedesktop.org +Cc: linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, + devicetree@vger.kernel.org, kernel@pengutronix.de, + Andy Yan , + Benjamin Gaignard , + Michael Riesch , + Sandy Huang , + =?utf-8?q?Heiko_St=C3=BCbner?= , + Peter Geis , Sascha Hauer +Subject: [PATCH 09/22] dt-bindings: display: rockchip: dw-hdmi: Add regulator + support +Date: Mon, 20 Dec 2021 12:06:17 +0100 +Message-Id: <20211220110630.3521121-10-s.hauer@pengutronix.de> +X-Mailer: git-send-email 2.30.2 +In-Reply-To: <20211220110630.3521121-1-s.hauer@pengutronix.de> +References: <20211220110630.3521121-1-s.hauer@pengutronix.de> +MIME-Version: 1.0 +X-SA-Exim-Connect-IP: 2001:67c:670:100:1d::28 +X-SA-Exim-Mail-From: sha@pengutronix.de +X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); + SAEximRunCond expanded to false +X-PTX-Original-Recipient: linux-rockchip@lists.infradead.org +X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 +X-CRM114-CacheID: sfid-20211220_030700_208701_F758DB20 +X-CRM114-Status: UNSURE ( 9.66 ) +X-CRM114-Notice: Please train this message. +X-BeenThere: linux-rockchip@lists.infradead.org +X-Mailman-Version: 2.1.34 +Precedence: list +List-Id: Upstream kernel work for Rockchip platforms + +List-Unsubscribe: , + +List-Archive: +List-Post: +List-Help: +List-Subscribe: , + +Sender: "Linux-rockchip" +Errors-To: + linux-rockchip-bounces+linux-rockchip=archiver.kernel.org@lists.infradead.org + +Signed-off-by: Sascha Hauer +--- + .../bindings/display/rockchip/rockchip,dw-hdmi.yaml | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi.yaml b/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi.yaml +index 3b40219e3ea60..bf8618b26721a 100644 +--- a/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi.yaml ++++ b/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi.yaml +@@ -28,6 +28,17 @@ properties: + reg-io-width: + const: 4 + ++ avdd-0v9-supply: ++ description: ++ A 0.9V supply that powers up the SoC internal circuitry. The actual pin name ++ varies between the different SoCs and is usually HDMI_TX_AVDD_0V9 or sometimes ++ HDMI_AVDD_1V0. ++ ++ avdd-1v8-supply: ++ description: ++ A 1.8V supply that powers up the SoC internal circuitry. The pin name on the ++ SoC usually is HDMI_TX_AVDD_1V8. ++ + clocks: + minItems: 2 + items: +From patchwork Mon Dec 20 11:06:18 2021 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +X-Patchwork-Submitter: Sascha Hauer +X-Patchwork-Id: 12687537 +Return-Path: + +X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on + aws-us-west-2-korg-lkml-1.web.codeaurora.org +Received: from bombadil.infradead.org (bombadil.infradead.org + [198.137.202.133]) + (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) + (No client certificate requested) + by smtp.lore.kernel.org (Postfix) with ESMTPS id 0A241C433FE + for ; + Mon, 20 Dec 2021 11:10:07 +0000 (UTC) +DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; + d=lists.infradead.org; s=bombadil.20210309; h=Sender: + Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: + List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: + Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: + Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: + List-Owner; bh=fY+M3vGuTLqVh74WL8nYlyPpbZJM9TtgyZaYbCyenxk=; b=NjuZ30XD/Czmyo + fUyxU7JjhCWJCcBFm6HUM9DkdVo1WX97hWvDK1YNNlL66pyQZgTzmX2grOE+qavakTyH3QX/zW9Xz + Ogwdco5SEaKMKpu8xz29KbwYDrCFw64zBARFQJd3vmTy9S194xdCIuXtde8Um+FcdSqSyapj9gL0l + Iiyjn2i3eM5/qS19Hgc72yVor8TBBUvefvBYQJpHVzqmBpOJb4HBIvZbQvW1mawzReHugiI1eFVVz + EOuoe2bITxje+2JvEN4jGlVfnlf5uogN2gdGZlrdKSOOeXeYVSXqLe5/6twO0YDhCk8wT6jS/CyUj + NUW0sGF79YxbBRcpQ38g==; +Received: from localhost ([::1] helo=bombadil.infradead.org) + by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) + id 1mzGYO-001pyg-1p; Mon, 20 Dec 2021 11:10:04 +0000 +Received: from metis.ext.pengutronix.de + ([2001:67c:670:201:290:27ff:fe1d:cc33]) + by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) + id 1mzGVK-001oDJ-9J + for linux-rockchip@lists.infradead.org; Mon, 20 Dec 2021 11:06:57 +0000 +Received: from dude02.hi.pengutronix.de ([2001:67c:670:100:1d::28]) + by metis.ext.pengutronix.de with esmtps + (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) + (envelope-from ) + id 1mzGVH-0004x9-7l; Mon, 20 Dec 2021 12:06:51 +0100 +Received: from sha by dude02.hi.pengutronix.de with local (Exim 4.94.2) + (envelope-from ) + id 1mzGVA-00EmEP-MA; Mon, 20 Dec 2021 12:06:44 +0100 +From: Sascha Hauer +To: dri-devel@lists.freedesktop.org +Cc: linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, + devicetree@vger.kernel.org, kernel@pengutronix.de, + Andy Yan , + Benjamin Gaignard , + Michael Riesch , + Sandy Huang , + =?utf-8?q?Heiko_St=C3=BCbner?= , + Peter Geis , Sascha Hauer +Subject: [PATCH 10/22] dt-bindings: display: rockchip: dw-hdmi: Add additional + clock +Date: Mon, 20 Dec 2021 12:06:18 +0100 +Message-Id: <20211220110630.3521121-11-s.hauer@pengutronix.de> +X-Mailer: git-send-email 2.30.2 +In-Reply-To: <20211220110630.3521121-1-s.hauer@pengutronix.de> +References: <20211220110630.3521121-1-s.hauer@pengutronix.de> +MIME-Version: 1.0 +X-SA-Exim-Connect-IP: 2001:67c:670:100:1d::28 +X-SA-Exim-Mail-From: sha@pengutronix.de +X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); + SAEximRunCond expanded to false +X-PTX-Original-Recipient: linux-rockchip@lists.infradead.org +X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 +X-CRM114-CacheID: sfid-20211220_030654_389202_A66FCD61 +X-CRM114-Status: GOOD ( 12.28 ) +X-BeenThere: linux-rockchip@lists.infradead.org +X-Mailman-Version: 2.1.34 +Precedence: list +List-Id: Upstream kernel work for Rockchip platforms + +List-Unsubscribe: , + +List-Archive: +List-Post: +List-Help: +List-Subscribe: , + +Sender: "Linux-rockchip" +Errors-To: + linux-rockchip-bounces+linux-rockchip=archiver.kernel.org@lists.infradead.org + +The rk3568 HDMI has an additional clock that needs to be enabled for the +HDMI controller to work. The purpose of that clock is not clear. It is +named "hclk" in the downstream driver, so use the same name. + +Signed-off-by: Sascha Hauer +--- + .../bindings/display/rockchip/rockchip,dw-hdmi.yaml | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi.yaml b/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi.yaml +index bf8618b26721a..a50ebf24b7f93 100644 +--- a/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi.yaml ++++ b/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi.yaml +@@ -44,11 +44,12 @@ properties: + items: + - {} + - {} +- # The next three clocks are all optional, but shall be specified in this ++ # The next four clocks are all optional, but shall be specified in this + # order when present. + - description: The HDMI CEC controller main clock + - description: Power for GRF IO + - description: External clock for some HDMI PHY ++ - description: hclk + + clock-names: + minItems: 2 +@@ -59,11 +60,16 @@ properties: + - cec + - grf + - ref ++ - hclk + - enum: + - grf + - ref +- - const: ++ - hclk ++ - enum: + - ref ++ - hclk ++ - const: ++ - hclk + + ddc-i2c-bus: + $ref: /schemas/types.yaml#/definitions/phandle +From patchwork Mon Dec 20 11:06:19 2021 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +X-Patchwork-Submitter: Sascha Hauer +X-Patchwork-Id: 12687623 +Return-Path: + +X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on + aws-us-west-2-korg-lkml-1.web.codeaurora.org +Received: from bombadil.infradead.org (bombadil.infradead.org + [198.137.202.133]) + (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) + (No client certificate requested) + by smtp.lore.kernel.org (Postfix) with ESMTPS id 90D56C433EF + for ; + Mon, 20 Dec 2021 11:20:46 +0000 (UTC) +DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; + d=lists.infradead.org; s=bombadil.20210309; h=Sender: + Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: + List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: + Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: + Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: + List-Owner; bh=nF+ZZntZCkFTWHmFaNNgGVf7N4Kgyyg+/X3VfDBodio=; b=Fcyp6TSx1zDGED + u6Mqw6ZoKHTm/RvZOofCX0BX2vnQ//1OK2HxkcfnAan6f/0KJYIFxd7v9bjK2PaV1yULeQp43L4uv + xYFSCLwvOYpbFHKl9Jjqj1L5fR81Gm1K1dkc3n7J0DV4VW4WzWqLQJGWgUqQyVbdAhzZRrFtQtwpS + PIGNWX32e15ug3RLoaqYhkj3tyrUujVYDhtRNfZX+/mkbC1dNcqOYRQ/oJ9opXTwRU6Z3UDYGFzPN + YYyTh4jkbAjyl86cwChFrSrhCcropjcAN4T7nk45DY06XAsWg49CXRj/FKJYSlvgSVc/CPQCgxzjq + dtz1u9LiHt53w+I3BH5g==; +Received: from localhost ([::1] helo=bombadil.infradead.org) + by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) + id 1mzGig-001vgX-Dc; Mon, 20 Dec 2021 11:20:42 +0000 +Received: from desiato.infradead.org ([2001:8b0:10b:1:d65d:64ff:fe57:4e05]) + by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) + id 1mzGVj-001oUy-35 + for linux-rockchip@bombadil.infradead.org; Mon, 20 Dec 2021 11:07:19 +0000 +DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; + d=infradead.org; s=desiato.20200630; h=Content-Transfer-Encoding:MIME-Version + :References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: + Content-Type:Content-ID:Content-Description; + bh=2pRfvj/Ei+9lP5V82MUX1TmN3XuakcA+yUYlRHVUizQ=; b=Qp2++mTquJKBXAaAjnTyQXs6iD + q5ZeHCCSUT3+IwAeTK8Npyuh0RNVLRIc6znTp59/iSXnwE0C2eBviRSwdLFgPI1hPtCFQ93mGV2i0 + 7rZYEy0vub8n4F/mXHAbxkUXsX6IyZ87XdGbKKHQLf+LWKbassPZx2rDGfmMBJfRBchMk71EJU+bw + DLgJH8G8CRIXrlhbObfYqSKNdU8GEdBSaJrPj+V05G1pPq8M69trLq2QtG7bBOsbO+AGTg+GHyaB6 + XkZQwlYVxpEj48JdhmUavZyUZOWyGlYwSa8spJvE7K9BwVfor0LQluWD6WDNgqytn/VQ/NIIsmFVa + Ypmj8O8Q==; +Received: from metis.ext.pengutronix.de + ([2001:67c:670:201:290:27ff:fe1d:cc33]) + by desiato.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) + id 1mzGVf-002UGB-4L + for linux-rockchip@lists.infradead.org; Mon, 20 Dec 2021 11:07:17 +0000 +Received: from dude02.hi.pengutronix.de ([2001:67c:670:100:1d::28]) + by metis.ext.pengutronix.de with esmtps + (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) + (envelope-from ) + id 1mzGVE-0004xA-DT; Mon, 20 Dec 2021 12:06:48 +0100 +Received: from sha by dude02.hi.pengutronix.de with local (Exim 4.94.2) + (envelope-from ) + id 1mzGVA-00EmES-Mt; Mon, 20 Dec 2021 12:06:44 +0100 +From: Sascha Hauer +To: dri-devel@lists.freedesktop.org +Cc: linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, + devicetree@vger.kernel.org, kernel@pengutronix.de, + Andy Yan , + Benjamin Gaignard , + Michael Riesch , + Sandy Huang , + =?utf-8?q?Heiko_St=C3=BCbner?= , + Peter Geis , Sascha Hauer +Subject: [PATCH 11/22] dt-bindings: display: rockchip: Add binding for VOP2 +Date: Mon, 20 Dec 2021 12:06:19 +0100 +Message-Id: <20211220110630.3521121-12-s.hauer@pengutronix.de> +X-Mailer: git-send-email 2.30.2 +In-Reply-To: <20211220110630.3521121-1-s.hauer@pengutronix.de> +References: <20211220110630.3521121-1-s.hauer@pengutronix.de> +MIME-Version: 1.0 +X-SA-Exim-Connect-IP: 2001:67c:670:100:1d::28 +X-SA-Exim-Mail-From: sha@pengutronix.de +X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); + SAEximRunCond expanded to false +X-PTX-Original-Recipient: linux-rockchip@lists.infradead.org +X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 +X-CRM114-CacheID: sfid-20211220_110715_583359_1820B567 +X-CRM114-Status: GOOD ( 15.76 ) +X-BeenThere: linux-rockchip@lists.infradead.org +X-Mailman-Version: 2.1.34 +Precedence: list +List-Id: Upstream kernel work for Rockchip platforms + +List-Unsubscribe: , + +List-Archive: +List-Post: +List-Help: +List-Subscribe: , + +Sender: "Linux-rockchip" +Errors-To: + linux-rockchip-bounces+linux-rockchip=archiver.kernel.org@lists.infradead.org + +The VOP2 is found on newer Rockchip SoCs like the rk3568 or the rk3566. +The binding differs slightly from the existing VOP binding, so add a new +binding file for it. + +Signed-off-by: Sascha Hauer +--- + .../display/rockchip/rockchip-vop2.yaml | 146 ++++++++++++++++++ + 1 file changed, 146 insertions(+) + create mode 100644 Documentation/devicetree/bindings/display/rockchip/rockchip-vop2.yaml + +diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip-vop2.yaml b/Documentation/devicetree/bindings/display/rockchip/rockchip-vop2.yaml +new file mode 100644 +index 0000000000000..df14d5aa85c85 +--- /dev/null ++++ b/Documentation/devicetree/bindings/display/rockchip/rockchip-vop2.yaml +@@ -0,0 +1,146 @@ ++# SPDX-License-Identifier: GPL-2.0-only or BSD-2-Clause ++%YAML 1.2 ++--- ++$id: http://devicetree.org/schemas/display/rockchip/rockchip-vop2.yaml# ++$schema: http://devicetree.org/meta-schemas/core.yaml# ++ ++title: Rockchip SoC display controller (VOP2) ++ ++description: ++ VOP2 (Video Output Processor v2) is the display controller for the Rockchip ++ series of SoCs which transfers the image data from a video memory ++ buffer to an external LCD interface. ++ ++maintainers: ++ - Sandy Huang ++ - Heiko Stuebner ++ ++properties: ++ compatible: ++ enum: ++ - rockchip,rk3566-vop ++ - rockchip,rk3568-vop ++ ++ reg: ++ minItems: 1 ++ items: ++ - description: ++ Must contain one entry corresponding to the base address and length ++ of the register space. ++ - description: ++ Can optionally contain a second entry corresponding to ++ the CRTC gamma LUT address. ++ ++ interrupts: ++ maxItems: 1 ++ description: ++ The VOP interrupt is shared by several interrupt sources, such as ++ frame start (VSYNC), line flag and other status interrupts. ++ ++ clocks: ++ items: ++ - description: Clock for ddr buffer transfer. ++ - description: Clock for the ahb bus to R/W the phy regs. ++ - description: Pixel clock for video port 0. ++ - description: Pixel clock for video port 1. ++ - description: Pixel clock for video port 2. ++ ++ clock-names: ++ items: ++ - const: aclk_vop ++ - const: hclk_vop ++ - const: dclk_vp0 ++ - const: dclk_vp1 ++ - const: dclk_vp2 ++ ++ rockchip,grf: ++ $ref: /schemas/types.yaml#/definitions/phandle ++ description: ++ Phandle to GRF regs used for misc control ++ ++ ports: ++ $ref: /schemas/graph.yaml#/properties/port ++ ++ properties: ++ port@0: ++ $ref: /schemas/graph.yaml#/properties/port ++ description: ++ Output endpoint of VP0 ++ ++ port@1: ++ $ref: /schemas/graph.yaml#/properties/port ++ description: ++ Output endpoint of VP1 ++ ++ port@: ++ $ref: /schemas/graph.yaml#/properties/port ++ description: ++ Output endpoint of VP2 ++ ++ assigned-clocks: true ++ ++ assigned-clock-rates: true ++ ++ assigned-clock-parents: true ++ ++ iommus: ++ maxItems: 1 ++ ++ power-domains: ++ maxItems: 1 ++ ++required: ++ - compatible ++ - reg ++ - interrupts ++ - clocks ++ - clock-names ++ - ports ++ ++additionalProperties: false ++ ++examples: ++ - | ++ #include ++ #include ++ #include ++ bus { ++ #address-cells = <2>; ++ #size-cells = <2>; ++ vop: vop@fe040000 { ++ compatible = "rockchip,rk3568-vop"; ++ reg = <0x0 0xfe040000 0x0 0x3000>, <0x0 0xfe044000 0x0 0x1000>; ++ interrupts = ; ++ clocks = <&cru ACLK_VOP>, ++ <&cru HCLK_VOP>, ++ <&cru DCLK_VOP0>, ++ <&cru DCLK_VOP1>, ++ <&cru DCLK_VOP2>; ++ clock-names = "aclk_vop", ++ "hclk_vop", ++ "dclk_vp0", ++ "dclk_vp1", ++ "dclk_vp2"; ++ power-domains = <&power RK3568_PD_VO>; ++ iommus = <&vop_mmu>; ++ vop_out: ports { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ vp0: port@0 { ++ reg = <0>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ }; ++ vp1: port@1 { ++ reg = <1>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ }; ++ vp2: port@2 { ++ reg = <2>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ }; ++ }; ++ }; ++ }; +From patchwork Mon Dec 20 11:06:20 2021 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +X-Patchwork-Submitter: Sascha Hauer +X-Patchwork-Id: 12687627 +Return-Path: + +X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on + aws-us-west-2-korg-lkml-1.web.codeaurora.org +Received: from bombadil.infradead.org (bombadil.infradead.org + [198.137.202.133]) + (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) + (No client certificate requested) + by smtp.lore.kernel.org (Postfix) with ESMTPS id 1EA65C433F5 + for ; + Mon, 20 Dec 2021 11:22:51 +0000 (UTC) +DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; + d=lists.infradead.org; s=bombadil.20210309; h=Sender: + Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: + List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: + Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: + Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: + List-Owner; bh=hJzi0XcGjHA9VFX4kq1NPnW929Kww+63Uvr0HLYwkQM=; b=d/FKmFum7PoTCB + P7hTNzQF65+cQor5wkXY01ebYlmUS+DALVvVED2iwmEWwKNK2lZts8JVKdWITohPM0xYr/UUv68Gr + 5BS00MKaOhYXsP5vpsaeWlnpSsQxQYzXwbKfoHeBalndwOx/lGfptr33JqJ/kwfZXN3zB6bWXrUIL + EEu9Xbn/fPHuKlitsNI/NVmRM9vKWUgx+zCnvv2sBEdk1+gbuItAu5EbqyZt0Zy9+RAxkaM2FJTAD + H9mkOoOara6tTFdATo7j0GXHfjNWeSDrSx3gHr1cPg03Z0YCjE7jfl/FOOrx4Kp9I8qXhT7iifXo2 + 83CRlHWSD0FUXlvA7rbg==; +Received: from localhost ([::1] helo=bombadil.infradead.org) + by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) + id 1mzGkh-001wpZ-4f; Mon, 20 Dec 2021 11:22:47 +0000 +Received: from desiato.infradead.org ([2001:8b0:10b:1:d65d:64ff:fe57:4e05]) + by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) + id 1mzGVq-001oYV-5C + for linux-rockchip@bombadil.infradead.org; Mon, 20 Dec 2021 11:07:26 +0000 +DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; + d=infradead.org; s=desiato.20200630; h=Content-Transfer-Encoding:MIME-Version + :References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: + Content-Type:Content-ID:Content-Description; + bh=uNA1iFcZ5tn4VZT/AL4rwhPRPOpqL/rUQIxtx+PGWE4=; b=TGbIm0cJYKKY6ruI02UgXsPDqS + UPP89GMTwvuggr7VwgxlEjRgBp7hgEsM79X69qazGiIvwRMfRdfC9fVlXnXXNJ+RY0c/evwEUqrv6 + Psmcia82IKG3wsEHnXyRItwjvTg8uI3rpeswsqi8rZg4iObXNAMr6dzWlU90FmtE38xJAvLMScQr/ + OL7tuMp0wTaXD2l4QlARUKSR7vcncNDIeltRBkSqSHoiKWaPUdXHFubMkHMmRqBbDWJJwH+pOBGAg + +hs7ODho3A18GIeIDKKVak5ABQFvScWxO6VU9ilwO+sJzAdI0evXuNVXZqEXYdgdKrLI6PxE0SZ6H + +iFFACeg==; +Received: from metis.ext.pengutronix.de + ([2001:67c:670:201:290:27ff:fe1d:cc33]) + by desiato.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) + id 1mzGVm-002UHM-QZ + for linux-rockchip@lists.infradead.org; Mon, 20 Dec 2021 11:07:24 +0000 +Received: from dude02.hi.pengutronix.de ([2001:67c:670:100:1d::28]) + by metis.ext.pengutronix.de with esmtps + (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) + (envelope-from ) + id 1mzGVE-0004xB-DX; Mon, 20 Dec 2021 12:06:48 +0100 +Received: from sha by dude02.hi.pengutronix.de with local (Exim 4.94.2) + (envelope-from ) + id 1mzGVA-00EmEV-NS; Mon, 20 Dec 2021 12:06:44 +0100 +From: Sascha Hauer +To: dri-devel@lists.freedesktop.org +Cc: linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, + devicetree@vger.kernel.org, kernel@pengutronix.de, + Andy Yan , + Benjamin Gaignard , + Michael Riesch , + Sandy Huang , + =?utf-8?q?Heiko_St=C3=BCbner?= , + Peter Geis , Sascha Hauer +Subject: [PATCH 12/22] arm64: dts: rockchip: rk3399: reorder hmdi clocks +Date: Mon, 20 Dec 2021 12:06:20 +0100 +Message-Id: <20211220110630.3521121-13-s.hauer@pengutronix.de> +X-Mailer: git-send-email 2.30.2 +In-Reply-To: <20211220110630.3521121-1-s.hauer@pengutronix.de> +References: <20211220110630.3521121-1-s.hauer@pengutronix.de> +MIME-Version: 1.0 +X-SA-Exim-Connect-IP: 2001:67c:670:100:1d::28 +X-SA-Exim-Mail-From: sha@pengutronix.de +X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); + SAEximRunCond expanded to false +X-PTX-Original-Recipient: linux-rockchip@lists.infradead.org +X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 +X-CRM114-CacheID: sfid-20211220_110723_153685_D07DE51E +X-CRM114-Status: GOOD ( 10.45 ) +X-BeenThere: linux-rockchip@lists.infradead.org +X-Mailman-Version: 2.1.34 +Precedence: list +List-Id: Upstream kernel work for Rockchip platforms + +List-Unsubscribe: , + +List-Archive: +List-Post: +List-Help: +List-Subscribe: , + +Sender: "Linux-rockchip" +Errors-To: + linux-rockchip-bounces+linux-rockchip=archiver.kernel.org@lists.infradead.org + +The binding specifies the clock order to "cec", "grf", "vpll". Reorder +the clocks accordingly. + +Signed-off-by: Sascha Hauer +--- + arch/arm64/boot/dts/rockchip/rk3399.dtsi | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi b/arch/arm64/boot/dts/rockchip/rk3399.dtsi +index d3cdf6f42a303..080457a68e3c7 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi +@@ -1881,10 +1881,10 @@ hdmi: hdmi@ff940000 { + interrupts = ; + clocks = <&cru PCLK_HDMI_CTRL>, + <&cru SCLK_HDMI_SFR>, +- <&cru PLL_VPLL>, ++ <&cru SCLK_HDMI_CEC>, + <&cru PCLK_VIO_GRF>, +- <&cru SCLK_HDMI_CEC>; +- clock-names = "iahb", "isfr", "vpll", "grf", "cec"; ++ <&cru PLL_VPLL>; ++ clock-names = "iahb", "isfr", "cec", "grf", "vpll"; + power-domains = <&power RK3399_PD_HDCP>; + reg-io-width = <4>; + rockchip,grf = <&grf>; +From patchwork Mon Dec 20 11:06:21 2021 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +X-Patchwork-Submitter: Sascha Hauer +X-Patchwork-Id: 12687603 +Return-Path: + +X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on + aws-us-west-2-korg-lkml-1.web.codeaurora.org +Received: from bombadil.infradead.org (bombadil.infradead.org + [198.137.202.133]) + (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) + (No client certificate requested) + by smtp.lore.kernel.org (Postfix) with ESMTPS id 9D131C433F5 + for ; + Mon, 20 Dec 2021 11:14:28 +0000 (UTC) +DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; + d=lists.infradead.org; s=bombadil.20210309; h=Sender: + Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: + List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: + Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: + Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: + List-Owner; bh=4cOYvVHtNZyGYE9OPQsf/gLYHaA+LpxvkweP0ooXpww=; b=qPV0KtJGuQUFiu + rt8okOgKHfzGytE3BNvuV4w6FzSWg/dKVFhkkVsLzvDebUPr9K0XTfcOSWJ5iKyNQIanW2zBr6UpS + mYgQ4V4CDiTuHtfvEuO/HtWUqmkFoj1GTELAaIK9SOAt/6qQ9lFP5VHJbbcrE+1QsgXOQ9VG7P3e1 + A3sFjrVAATAN9U0n9cK5QG5fL4/kUjKAEtjgC1oZyrVFBPaVJHylpXZ8e9PxW404BJiRMomnidANa + GlySapYJRWStPVrXH0nhR1ShCT1EY/nhDyeCF2jN8RLyw+e7VisQi97als2b2/kEVmOu/P70Ro7ty + 9crVq9UBHrCZMndANvfw==; +Received: from localhost ([::1] helo=bombadil.infradead.org) + by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) + id 1mzGcZ-001sbN-Ni; Mon, 20 Dec 2021 11:14:23 +0000 +Received: from metis.ext.pengutronix.de + ([2001:67c:670:201:290:27ff:fe1d:cc33]) + by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) + id 1mzGVS-001oJz-AQ + for linux-rockchip@lists.infradead.org; Mon, 20 Dec 2021 11:07:09 +0000 +Received: from dude02.hi.pengutronix.de ([2001:67c:670:100:1d::28]) + by metis.ext.pengutronix.de with esmtps + (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) + (envelope-from ) + id 1mzGVH-0004xC-7t; Mon, 20 Dec 2021 12:06:51 +0100 +Received: from sha by dude02.hi.pengutronix.de with local (Exim 4.94.2) + (envelope-from ) + id 1mzGVA-00EmEY-O0; Mon, 20 Dec 2021 12:06:44 +0100 +From: Sascha Hauer +To: dri-devel@lists.freedesktop.org +Cc: linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, + devicetree@vger.kernel.org, kernel@pengutronix.de, + Andy Yan , + Benjamin Gaignard , + Michael Riesch , + Sandy Huang , + =?utf-8?q?Heiko_St=C3=BCbner?= , + Peter Geis , Sascha Hauer +Subject: [PATCH 13/22] arm64: dts: rockchip: rk3399: rename HDMI ref clock to + 'ref' +Date: Mon, 20 Dec 2021 12:06:21 +0100 +Message-Id: <20211220110630.3521121-14-s.hauer@pengutronix.de> +X-Mailer: git-send-email 2.30.2 +In-Reply-To: <20211220110630.3521121-1-s.hauer@pengutronix.de> +References: <20211220110630.3521121-1-s.hauer@pengutronix.de> +MIME-Version: 1.0 +X-SA-Exim-Connect-IP: 2001:67c:670:100:1d::28 +X-SA-Exim-Mail-From: sha@pengutronix.de +X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); + SAEximRunCond expanded to false +X-PTX-Original-Recipient: linux-rockchip@lists.infradead.org +X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 +X-CRM114-CacheID: sfid-20211220_030702_396354_9A505BE5 +X-CRM114-Status: GOOD ( 12.24 ) +X-BeenThere: linux-rockchip@lists.infradead.org +X-Mailman-Version: 2.1.34 +Precedence: list +List-Id: Upstream kernel work for Rockchip platforms + +List-Unsubscribe: , + +List-Archive: +List-Post: +List-Help: +List-Subscribe: , + +Sender: "Linux-rockchip" +Errors-To: + linux-rockchip-bounces+linux-rockchip=archiver.kernel.org@lists.infradead.org + +The reference clock for the HDMI controller has been renamed to 'ref', +the previous 'vpll' name is only left for compatibility in the driver. +Rename the clock to the new name. + +Signed-off-by: Sascha Hauer +--- + arch/arm64/boot/dts/rockchip/rk3399.dtsi | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi b/arch/arm64/boot/dts/rockchip/rk3399.dtsi +index 080457a68e3c7..d0add619b0d22 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi +@@ -1884,7 +1884,7 @@ hdmi: hdmi@ff940000 { + <&cru SCLK_HDMI_CEC>, + <&cru PCLK_VIO_GRF>, + <&cru PLL_VPLL>; +- clock-names = "iahb", "isfr", "cec", "grf", "vpll"; ++ clock-names = "iahb", "isfr", "cec", "grf", "ref"; + power-domains = <&power RK3399_PD_HDCP>; + reg-io-width = <4>; + rockchip,grf = <&grf>; +From patchwork Mon Dec 20 11:06:22 2021 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +X-Patchwork-Submitter: Sascha Hauer +X-Patchwork-Id: 12687601 +Return-Path: + +X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on + aws-us-west-2-korg-lkml-1.web.codeaurora.org +Received: from bombadil.infradead.org (bombadil.infradead.org + [198.137.202.133]) + (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) + (No client certificate requested) + by smtp.lore.kernel.org (Postfix) with ESMTPS id D8D28C433EF + for ; + Mon, 20 Dec 2021 11:14:22 +0000 (UTC) +DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; + d=lists.infradead.org; s=bombadil.20210309; h=Sender: + Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: + List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: + Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: + Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: + List-Owner; bh=tiUXT9Eykora6aTIrYE1Rb0Za7gST7EW2I1LDHZsYiM=; b=UqM6lT6YITE4WU + g1WDuLlvKYNrpSZUeDUcyqHvNaY1HiHSH/cE6JXJPf5tnYdRjOZDK1A3pdclD57y+5i4pe4oxtaJp + F+EQN6CEsXxSF14pBAxcEVDVrsdcqSJrv6jkVbXf9u2g7x4LCKn4wlCauGpfY6M4ERjRQqLA2WBKk + DPxK+rYga+Mgp+qNPsJxbRsEe9Ki806rzZu/I8oiUkd55WFE5PwNTToVj8x3yXm3UNcIMHLec/eEh + xYG7ILGXJEZex2YxlWHGUGRrcE6Iscy8/b5A613/oz2fMWCblWdnAnSOMGf+rLDEEqj8kTNDzmW6w + T3E5Qth75+PEFgJrf6DQ==; +Received: from localhost ([::1] helo=bombadil.infradead.org) + by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) + id 1mzGcT-001sWk-FY; Mon, 20 Dec 2021 11:14:17 +0000 +Received: from metis.ext.pengutronix.de + ([2001:67c:670:201:290:27ff:fe1d:cc33]) + by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) + id 1mzGVQ-001oHy-8A + for linux-rockchip@lists.infradead.org; Mon, 20 Dec 2021 11:07:07 +0000 +Received: from dude02.hi.pengutronix.de ([2001:67c:670:100:1d::28]) + by metis.ext.pengutronix.de with esmtps + (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) + (envelope-from ) + id 1mzGVE-0004xD-DJ; Mon, 20 Dec 2021 12:06:48 +0100 +Received: from sha by dude02.hi.pengutronix.de with local (Exim 4.94.2) + (envelope-from ) + id 1mzGVA-00EmEb-Oi; Mon, 20 Dec 2021 12:06:44 +0100 +From: Sascha Hauer +To: dri-devel@lists.freedesktop.org +Cc: linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, + devicetree@vger.kernel.org, kernel@pengutronix.de, + Andy Yan , + Benjamin Gaignard , + Michael Riesch , + Sandy Huang , + =?utf-8?q?Heiko_St=C3=BCbner?= , + Peter Geis , Sascha Hauer +Subject: [PATCH 14/22] arm64: dts: rockchip: rk356x: Add VOP2 nodes +Date: Mon, 20 Dec 2021 12:06:22 +0100 +Message-Id: <20211220110630.3521121-15-s.hauer@pengutronix.de> +X-Mailer: git-send-email 2.30.2 +In-Reply-To: <20211220110630.3521121-1-s.hauer@pengutronix.de> +References: <20211220110630.3521121-1-s.hauer@pengutronix.de> +MIME-Version: 1.0 +X-SA-Exim-Connect-IP: 2001:67c:670:100:1d::28 +X-SA-Exim-Mail-From: sha@pengutronix.de +X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); + SAEximRunCond expanded to false +X-PTX-Original-Recipient: linux-rockchip@lists.infradead.org +X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 +X-CRM114-CacheID: sfid-20211220_030700_333528_4AD47181 +X-CRM114-Status: GOOD ( 16.00 ) +X-BeenThere: linux-rockchip@lists.infradead.org +X-Mailman-Version: 2.1.34 +Precedence: list +List-Id: Upstream kernel work for Rockchip platforms + +List-Unsubscribe: , + +List-Archive: +List-Post: +List-Help: +List-Subscribe: , + +Sender: "Linux-rockchip" +Errors-To: + linux-rockchip-bounces+linux-rockchip=archiver.kernel.org@lists.infradead.org + +The VOP2 is the display output controller on the RK3568. Add the node +for it to the dtsi file along with the required display-subsystem node +and the iommu node. + +Signed-off-by: Sascha Hauer +--- + arch/arm64/boot/dts/rockchip/rk3566.dtsi | 4 ++ + arch/arm64/boot/dts/rockchip/rk3568.dtsi | 4 ++ + arch/arm64/boot/dts/rockchip/rk356x.dtsi | 50 ++++++++++++++++++++++++ + include/dt-bindings/soc/rockchip,vop2.h | 14 +++++++ + 4 files changed, 72 insertions(+) + create mode 100644 include/dt-bindings/soc/rockchip,vop2.h + +diff --git a/arch/arm64/boot/dts/rockchip/rk3566.dtsi b/arch/arm64/boot/dts/rockchip/rk3566.dtsi +index 3839eef5e4f76..595fa2562cb8e 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3566.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3566.dtsi +@@ -18,3 +18,7 @@ power-domain@RK3568_PD_PIPE { + #power-domain-cells = <0>; + }; + }; ++ ++&vop { ++ compatible = "rockchip,rk3566-vop"; ++}; +diff --git a/arch/arm64/boot/dts/rockchip/rk3568.dtsi b/arch/arm64/boot/dts/rockchip/rk3568.dtsi +index 2fd313a295f8a..1e55efb6fcfde 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3568.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3568.dtsi +@@ -95,3 +95,7 @@ power-domain@RK3568_PD_PIPE { + #power-domain-cells = <0>; + }; + }; ++ ++&vop { ++ compatible = "rockchip,rk3568-vop"; ++}; +diff --git a/arch/arm64/boot/dts/rockchip/rk356x.dtsi b/arch/arm64/boot/dts/rockchip/rk356x.dtsi +index 46d9552f60284..7c62ad921cf7b 100644 +--- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi +@@ -10,6 +10,7 @@ + #include + #include + #include ++#include + #include + + / { +@@ -125,6 +126,11 @@ opp-1800000000 { + }; + }; + ++ display_subsystem: display-subsystem { ++ compatible = "rockchip,display-subsystem"; ++ ports = <&vop_out>; ++ }; ++ + firmware { + scmi: scmi { + compatible = "arm,scmi-smc"; +@@ -447,6 +453,50 @@ gmac1_mtl_tx_setup: tx-queues-config { + }; + }; + ++ vop: vop@fe040000 { ++ reg = <0x0 0xfe040000 0x0 0x5000>; ++ interrupts = ; ++ clocks = <&cru ACLK_VOP>, <&cru HCLK_VOP>, <&cru DCLK_VOP0>, <&cru DCLK_VOP1>, <&cru DCLK_VOP2>; ++ clock-names = "aclk_vop", "hclk_vop", "dclk_vp0", "dclk_vp1", "dclk_vp2"; ++ iommus = <&vop_mmu>; ++ power-domains = <&power RK3568_PD_VO>; ++ rockchip,grf = <&grf>; ++ status = "disabled"; ++ ++ vop_out: ports { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ vp0: port@0 { ++ reg = <0>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ }; ++ ++ vp1: port@1 { ++ reg = <1>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ }; ++ ++ vp2: port@2 { ++ reg = <2>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ }; ++ }; ++ }; ++ ++ vop_mmu: iommu@fe043e00 { ++ compatible = "rockchip,rk3568-iommu"; ++ reg = <0x0 0xfe043e00 0x0 0x100>, <0x0 0xfe043f00 0x0 0x100>; ++ interrupts = ; ++ clocks = <&cru ACLK_VOP>, <&cru HCLK_VOP>; ++ clock-names = "aclk", "iface"; ++ #iommu-cells = <0>; ++ status = "disabled"; ++ }; ++ + qos_gpu: qos@fe128000 { + compatible = "rockchip,rk3568-qos", "syscon"; + reg = <0x0 0xfe128000 0x0 0x20>; +diff --git a/include/dt-bindings/soc/rockchip,vop2.h b/include/dt-bindings/soc/rockchip,vop2.h +new file mode 100644 +index 0000000000000..0a87bc90564a7 +--- /dev/null ++++ b/include/dt-bindings/soc/rockchip,vop2.h +@@ -0,0 +1,14 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */ ++ ++#ifndef __DT_BINDINGS_ROCKCHIP_VOP2_H ++#define __DT_BINDINGS_ROCKCHIP_VOP2_H ++ ++#define RK3568_VOP2_EP_RGB 0 ++#define RK3568_VOP2_EP_HDMI 1 ++#define RK3568_VOP2_EP_EDP 2 ++#define RK3568_VOP2_EP_MIPI0 3 ++#define RK3568_VOP2_EP_LVDS0 4 ++#define RK3568_VOP2_EP_MIPI1 5 ++#define RK3568_VOP2_EP_LVDS1 6 ++ ++#endif /* __DT_BINDINGS_ROCKCHIP_VOP2_H */ +From patchwork Mon Dec 20 11:06:23 2021 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +X-Patchwork-Submitter: Sascha Hauer +X-Patchwork-Id: 12687629 +Return-Path: + +X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on + aws-us-west-2-korg-lkml-1.web.codeaurora.org +Received: from bombadil.infradead.org (bombadil.infradead.org + [198.137.202.133]) + (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) + (No client certificate requested) + by smtp.lore.kernel.org (Postfix) with ESMTPS id 671DBC433F5 + for ; + Mon, 20 Dec 2021 11:22:55 +0000 (UTC) +DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; + d=lists.infradead.org; s=bombadil.20210309; h=Sender: + Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: + List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: + Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: + Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: + List-Owner; bh=HMHlJQ8u79tVuC2DDafCMXqpz/p+uDn5trxuKYa1RXc=; b=CAM8PwvJwaV2K9 + d9U1BgvNiIpCMxhqj5XofkGbEY/0AFCcmr0RzBqACAlbANq7j87mIlXk+YBDkjWYM93B+L+2xc3hB + veDGmkTVmYDhv9acTFHlCg4x+w92vW5LF9i93Etfyc/GXlYA2PygqZlsuM95BJKECJyr1PYStMa82 + 0OA64Q8tIZ97vL7dwpA3jxy+6x5ZLHiWhgfjwHrO/CDDK+EN9PQgGjEm8LSMKxxdSIi+xH1enezTL + BU5QltY9HP+240LSOpymYkit1CwxcqOlItY8NREECm47oNFvBZ+aGfQyhd+uTst6Wq4TPn8+o+Wrx + IiqP0MHOfr50J8JGLnIQ==; +Received: from localhost ([::1] helo=bombadil.infradead.org) + by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) + id 1mzGkl-001wrp-1a; Mon, 20 Dec 2021 11:22:51 +0000 +Received: from desiato.infradead.org ([2001:8b0:10b:1:d65d:64ff:fe57:4e05]) + by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) + id 1mzGWN-001oo4-H7 + for linux-rockchip@bombadil.infradead.org; Mon, 20 Dec 2021 11:07:59 +0000 +DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; + d=infradead.org; s=desiato.20200630; h=Content-Transfer-Encoding:MIME-Version + :References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: + Content-Type:Content-ID:Content-Description; + bh=oBPhlDkstGCts+LEGaOt0DD2BrDLVLW6WblxGev/Cro=; b=f74+REs6IhJzXsqz2TaadXxjC6 + jKCr3/4XVECfa39hutL1cDL/jqRkauWwyAisq/ASTikMe/6jwGwUSL4pfHq8oAmfiiBuE3bztBQqD + PDHaPGVQuqF1svXcEzDvgsU5IPjky5Ltqa7rhvbZGStOgOwi+ZKB9LuYEhQAndUBeW6ByXApqmz2D + SH6Q3BaemlKfLobHUca4MTOlH0PJisXp24hdgt/6QtRfFdvyRyCeCU7D8zxxJlz+Dlu6NG0ikAn78 + gg+7rSw9oATwqO36haqPLsG2Fj5UWIUih3LfsS/UGrl7DGQV1gm7BqqNdV2EzPmXiRB5wWTQYxtHH + 6PH48rNQ==; +Received: from metis.ext.pengutronix.de + ([2001:67c:670:201:290:27ff:fe1d:cc33]) + by desiato.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) + id 1mzGVf-002UGD-KM + for linux-rockchip@lists.infradead.org; Mon, 20 Dec 2021 11:07:58 +0000 +Received: from dude02.hi.pengutronix.de ([2001:67c:670:100:1d::28]) + by metis.ext.pengutronix.de with esmtps + (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) + (envelope-from ) + id 1mzGVE-0004xE-DO; Mon, 20 Dec 2021 12:06:48 +0100 +Received: from sha by dude02.hi.pengutronix.de with local (Exim 4.94.2) + (envelope-from ) + id 1mzGVA-00EmEe-PK; Mon, 20 Dec 2021 12:06:44 +0100 +From: Sascha Hauer +To: dri-devel@lists.freedesktop.org +Cc: linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, + devicetree@vger.kernel.org, kernel@pengutronix.de, + Andy Yan , + Benjamin Gaignard , + Michael Riesch , + Sandy Huang , + =?utf-8?q?Heiko_St=C3=BCbner?= , + Peter Geis , Sascha Hauer +Subject: [PATCH 15/22] arm64: dts: rockchip: rk356x: Add HDMI nodes +Date: Mon, 20 Dec 2021 12:06:23 +0100 +Message-Id: <20211220110630.3521121-16-s.hauer@pengutronix.de> +X-Mailer: git-send-email 2.30.2 +In-Reply-To: <20211220110630.3521121-1-s.hauer@pengutronix.de> +References: <20211220110630.3521121-1-s.hauer@pengutronix.de> +MIME-Version: 1.0 +X-SA-Exim-Connect-IP: 2001:67c:670:100:1d::28 +X-SA-Exim-Mail-From: sha@pengutronix.de +X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); + SAEximRunCond expanded to false +X-PTX-Original-Recipient: linux-rockchip@lists.infradead.org +X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 +X-CRM114-CacheID: sfid-20211220_110715_699469_0B58CEC6 +X-CRM114-Status: GOOD ( 12.33 ) +X-BeenThere: linux-rockchip@lists.infradead.org +X-Mailman-Version: 2.1.34 +Precedence: list +List-Id: Upstream kernel work for Rockchip platforms + +List-Unsubscribe: , + +List-Archive: +List-Post: +List-Help: +List-Subscribe: , + +Sender: "Linux-rockchip" +Errors-To: + linux-rockchip-bounces+linux-rockchip=archiver.kernel.org@lists.infradead.org + +Add support for the HDMI port found on RK3568. + +Signed-off-by: Sascha Hauer +--- + arch/arm64/boot/dts/rockchip/rk356x.dtsi | 37 +++++++++++++++++++++++- + 1 file changed, 36 insertions(+), 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/rockchip/rk356x.dtsi b/arch/arm64/boot/dts/rockchip/rk356x.dtsi +index 7c62ad921cf7b..6d93b8fcee179 100644 +--- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi +@@ -10,7 +10,6 @@ + #include + #include + #include +-#include + #include + + / { +@@ -497,6 +496,42 @@ vop_mmu: iommu@fe043e00 { + status = "disabled"; + }; + ++ hdmi: hdmi@fe0a0000 { ++ compatible = "rockchip,rk3568-dw-hdmi"; ++ reg = <0x0 0xfe0a0000 0x0 0x20000>; ++ interrupts = ; ++ clocks = <&cru PCLK_HDMI_HOST>, ++ <&cru CLK_HDMI_SFR>, ++ <&cru CLK_HDMI_CEC>, ++ <&pmucru CLK_HDMI_REF>, ++ <&cru HCLK_VOP>; ++ clock-names = "iahb", "isfr", "cec", "ref", "hclk"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&hdmitx_scl &hdmitx_sda &hdmitxm0_cec>; ++ power-domains = <&power RK3568_PD_VO>; ++ reg-io-width = <4>; ++ rockchip,grf = <&grf>; ++ #sound-dai-cells = <0>; ++ status = "disabled"; ++ ++ ports { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ hdmi_in: port@0 { ++ reg = <0>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ }; ++ ++ hdmi_out: port@1 { ++ reg = <1>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ }; ++ }; ++ }; ++ + qos_gpu: qos@fe128000 { + compatible = "rockchip,rk3568-qos", "syscon"; + reg = <0x0 0xfe128000 0x0 0x20>; +From patchwork Mon Dec 20 11:06:24 2021 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +X-Patchwork-Submitter: Sascha Hauer +X-Patchwork-Id: 12687535 +Return-Path: + +X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on + aws-us-west-2-korg-lkml-1.web.codeaurora.org +Received: from bombadil.infradead.org (bombadil.infradead.org + [198.137.202.133]) + (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) + (No client certificate requested) + by smtp.lore.kernel.org (Postfix) with ESMTPS id CDFD2C433EF + for ; + Mon, 20 Dec 2021 11:08:34 +0000 (UTC) +DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; + d=lists.infradead.org; s=bombadil.20210309; h=Sender: + Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: + List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: + Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: + Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: + List-Owner; bh=+ahobp+/hXsH/yU21q1TAqI2dNH3E8owWCk+giNv2gQ=; b=hEhNXfBVCAu1/T + 6UHFTsOS00dSyv7p2jwZ1E4ky11jxJ04LUAUAUw25jpqhxlXJ1DaIuipkwo2GxKXytqI90UGKbD7f + 0hkUExcZyD5dM0I0auAKqF32mtrhbUOdLDrP1WIapdJpgsWEvjKrN+JK69+b63FudiHlE2EhZhFRy + UTa/uALNF3Tc9yoDM+4GRTI1Y51j1lLPQqlS/WJo/CwHT6CG8YDAgxdlkX2JE6ELwnBvBkNiQLeDq + LK4C2Ua9Th+vzCT+5rFXF3PyrCH6XpVxnG8l+JoIvnl/7gCc9u3DNn3qjqafsWFzhp0eoFo5gtYWZ + YM0c/vyKQScAuTvpKEuw==; +Received: from localhost ([::1] helo=bombadil.infradead.org) + by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) + id 1mzGWt-001p4E-7y; Mon, 20 Dec 2021 11:08:31 +0000 +Received: from metis.ext.pengutronix.de + ([2001:67c:670:201:290:27ff:fe1d:cc33]) + by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) + id 1mzGVI-001oAu-1Y + for linux-rockchip@lists.infradead.org; Mon, 20 Dec 2021 11:06:54 +0000 +Received: from dude02.hi.pengutronix.de ([2001:67c:670:100:1d::28]) + by metis.ext.pengutronix.de with esmtps + (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) + (envelope-from ) + id 1mzGVE-0004xF-DY; Mon, 20 Dec 2021 12:06:48 +0100 +Received: from sha by dude02.hi.pengutronix.de with local (Exim 4.94.2) + (envelope-from ) + id 1mzGVA-00EmEh-Ps; Mon, 20 Dec 2021 12:06:44 +0100 +From: Sascha Hauer +To: dri-devel@lists.freedesktop.org +Cc: linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, + devicetree@vger.kernel.org, kernel@pengutronix.de, + Andy Yan , + Benjamin Gaignard , + Michael Riesch , + Sandy Huang , + =?utf-8?q?Heiko_St=C3=BCbner?= , + Peter Geis , Sascha Hauer +Subject: [PATCH 16/22] arm64: dts: rockchip: rk3568-evb: Enable VOP2 and hdmi +Date: Mon, 20 Dec 2021 12:06:24 +0100 +Message-Id: <20211220110630.3521121-17-s.hauer@pengutronix.de> +X-Mailer: git-send-email 2.30.2 +In-Reply-To: <20211220110630.3521121-1-s.hauer@pengutronix.de> +References: <20211220110630.3521121-1-s.hauer@pengutronix.de> +MIME-Version: 1.0 +X-SA-Exim-Connect-IP: 2001:67c:670:100:1d::28 +X-SA-Exim-Mail-From: sha@pengutronix.de +X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); + SAEximRunCond expanded to false +X-PTX-Original-Recipient: linux-rockchip@lists.infradead.org +X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 +X-CRM114-CacheID: sfid-20211220_030652_125345_05F20D59 +X-CRM114-Status: GOOD ( 12.02 ) +X-BeenThere: linux-rockchip@lists.infradead.org +X-Mailman-Version: 2.1.34 +Precedence: list +List-Id: Upstream kernel work for Rockchip platforms + +List-Unsubscribe: , + +List-Archive: +List-Post: +List-Help: +List-Subscribe: , + +Sender: "Linux-rockchip" +Errors-To: + linux-rockchip-bounces+linux-rockchip=archiver.kernel.org@lists.infradead.org + +This enabled the VOP2 display controller along with hdmi and the +required port routes which is enough to get a picture out of the +hdmi port of the board. + +Signed-off-by: Sascha Hauer +--- + .../boot/dts/rockchip/rk3568-evb1-v10.dts | 48 +++++++++++++++++++ + 1 file changed, 48 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts b/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts +index 184e2aa2416af..3fa0e654d7cf6 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts +@@ -7,6 +7,7 @@ + /dts-v1/; + #include + #include ++#include + #include "rk3568.dtsi" + + / { +@@ -33,6 +34,17 @@ dc_12v: dc-12v { + regulator-max-microvolt = <12000000>; + }; + ++ hdmi-con { ++ compatible = "hdmi-connector"; ++ type = "c"; ++ ++ port { ++ hdmi_con_in: endpoint { ++ remote-endpoint = <&hdmi_out_con>; ++ }; ++ }; ++ }; ++ + vcc3v3_sys: vcc3v3-sys { + compatible = "regulator-fixed"; + regulator-name = "vcc3v3_sys"; +@@ -106,6 +118,12 @@ &gmac1m1_rgmii_clk + status = "okay"; + }; + ++&hdmi { ++ avdd-0v9-supply = <&vdda0v9_image>; ++ avdd-1v8-supply = <&vcca1v8_image>; ++ status = "okay"; ++}; ++ + &i2c0 { + status = "okay"; + +@@ -390,3 +408,33 @@ &sdmmc0 { + &uart2 { + status = "okay"; + }; ++ ++&vop { ++ assigned-clocks = <&cru DCLK_VOP0>, <&cru DCLK_VOP1>; ++ assigned-clock-parents = <&pmucru PLL_HPLL>, <&cru PLL_VPLL>; ++ status = "okay"; ++}; ++ ++&vop_mmu { ++ status = "okay"; ++}; ++ ++&hdmi_in { ++ hdmi_in_vp0: endpoint@0 { ++ reg = <0>; ++ remote-endpoint = <&vp0_out_hdmi>; ++ }; ++}; ++ ++&hdmi_out { ++ hdmi_out_con: endpoint { ++ remote-endpoint = <&hdmi_con_in>; ++ }; ++}; ++ ++&vp0 { ++ vp0_out_hdmi: endpoint@RK3568_VOP2_EP_HDMI { ++ reg = ; ++ remote-endpoint = <&hdmi_in_vp0>; ++ }; ++}; +From patchwork Mon Dec 20 11:06:25 2021 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +X-Patchwork-Submitter: Sascha Hauer +X-Patchwork-Id: 12687611 +Return-Path: + +X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on + aws-us-west-2-korg-lkml-1.web.codeaurora.org +Received: from bombadil.infradead.org (bombadil.infradead.org + [198.137.202.133]) + (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) + (No client certificate requested) + by smtp.lore.kernel.org (Postfix) with ESMTPS id B9015C433F5 + for ; + Mon, 20 Dec 2021 11:19:17 +0000 (UTC) +DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; + d=lists.infradead.org; s=bombadil.20210309; h=Sender: + Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: + List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: + Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: + Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: + List-Owner; bh=HxIKdqJENoVAfiyzjTBgI861OntE+fFR5iMsFqavQQk=; b=l6onUNXfztGEpM + 9m/BEZFJHv3iX4DxGlN/G5kmo3fPuwDc8cNAieNhZKNmyIWCE7dXop9vkCpJS4BWQHX8MaVXrM9YA + nAeLIXyh0UYkASoJHpV1j5mN2vnB7rw3yYzkN6i3bj33WWtwFgZxPOgB2hMLYgdJC4nlAjJF2v9Fj + hoyPCsq5sqNPp/eE/N+GrcsSBsAgvp/ZICR/QY/VRzNPk/Dwvfg85pWcresERCmBX6xSSZXpokXbj + 4Hh/lhueJinYUUWwIo1uhynMtV5fEh5BDnlnqoFgoeFg24mGHr38B1+cTcCVMQ94f2nh/W1Q+SHfa + eMhMWFkQSAt9L8hNLKFA==; +Received: from localhost ([::1] helo=bombadil.infradead.org) + by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) + id 1mzGhF-001uty-1A; Mon, 20 Dec 2021 11:19:13 +0000 +Received: from metis.ext.pengutronix.de + ([2001:67c:670:201:290:27ff:fe1d:cc33]) + by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) + id 1mzGVa-001oQ4-FL + for linux-rockchip@lists.infradead.org; Mon, 20 Dec 2021 11:07:16 +0000 +Received: from dude02.hi.pengutronix.de ([2001:67c:670:100:1d::28]) + by metis.ext.pengutronix.de with esmtps + (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) + (envelope-from ) + id 1mzGVH-0004xG-7k; Mon, 20 Dec 2021 12:06:51 +0100 +Received: from sha by dude02.hi.pengutronix.de with local (Exim 4.94.2) + (envelope-from ) + id 1mzGVA-00EmEk-QX; Mon, 20 Dec 2021 12:06:44 +0100 +From: Sascha Hauer +To: dri-devel@lists.freedesktop.org +Cc: linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, + devicetree@vger.kernel.org, kernel@pengutronix.de, + Andy Yan , + Benjamin Gaignard , + Michael Riesch , + Sandy Huang , + =?utf-8?q?Heiko_St=C3=BCbner?= , + Peter Geis , Sascha Hauer +Subject: [PATCH 17/22] arm64: dts: rockchip: enable vop2 and hdmi tx on + quartz64a +Date: Mon, 20 Dec 2021 12:06:25 +0100 +Message-Id: <20211220110630.3521121-18-s.hauer@pengutronix.de> +X-Mailer: git-send-email 2.30.2 +In-Reply-To: <20211220110630.3521121-1-s.hauer@pengutronix.de> +References: <20211220110630.3521121-1-s.hauer@pengutronix.de> +MIME-Version: 1.0 +X-SA-Exim-Connect-IP: 2001:67c:670:100:1d::28 +X-SA-Exim-Mail-From: sha@pengutronix.de +X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); + SAEximRunCond expanded to false +X-PTX-Original-Recipient: linux-rockchip@lists.infradead.org +X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 +X-CRM114-CacheID: sfid-20211220_030710_555253_6B9A03C5 +X-CRM114-Status: GOOD ( 11.67 ) +X-BeenThere: linux-rockchip@lists.infradead.org +X-Mailman-Version: 2.1.34 +Precedence: list +List-Id: Upstream kernel work for Rockchip platforms + +List-Unsubscribe: , + +List-Archive: +List-Post: +List-Help: +List-Subscribe: , + +Sender: "Linux-rockchip" +Errors-To: + linux-rockchip-bounces+linux-rockchip=archiver.kernel.org@lists.infradead.org + +From: Michael Riesch + +Enable the RK356x Video Output Processor (VOP) 2 on the Pine64 +Quartz64 Model A. + +Signed-off-by: Michael Riesch +Signed-off-by: Sascha Hauer +--- + .../boot/dts/rockchip/rk3566-quartz64-a.dts | 48 +++++++++++++++++++ + 1 file changed, 48 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts +index 4d4b2a301b1a4..29748537cdbd0 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts +@@ -4,6 +4,7 @@ + + #include + #include ++#include + #include "rk3566.dtsi" + + / { +@@ -35,6 +36,17 @@ fan: gpio_fan { + #cooling-cells = <2>; + }; + ++ hdmi-con { ++ compatible = "hdmi-connector"; ++ type = "c"; ++ ++ port { ++ hdmi_con_in: endpoint { ++ remote-endpoint = <&hdmi_out_con>; ++ }; ++ }; ++ }; ++ + leds { + compatible = "gpio-leds"; + +@@ -205,6 +217,18 @@ &gmac1m0_clkinout + status = "okay"; + }; + ++&hdmi { ++ avdd-0v9-supply = <&vdda_0v9>; ++ avdd-1v8-supply = <&vcc_1v8>; ++ status = "okay"; ++}; ++ ++&hdmi_out { ++ hdmi_out_con: endpoint { ++ remote-endpoint = <&hdmi_con_in>; ++ }; ++}; ++ + &i2c0 { + status = "okay"; + +@@ -546,3 +570,27 @@ bluetooth { + &uart2 { + status = "okay"; + }; ++ ++&vop { ++ assigned-clocks = <&cru DCLK_VOP0>, <&cru DCLK_VOP1>; ++ assigned-clock-parents = <&pmucru PLL_HPLL>, <&cru PLL_VPLL>; ++ status = "okay"; ++}; ++ ++&vop_mmu { ++ status = "okay"; ++}; ++ ++&hdmi_in { ++ hdmi_in_vp0: endpoint@0 { ++ reg = <0>; ++ remote-endpoint = <&vp0_out_hdmi>; ++ }; ++}; ++ ++&vp0 { ++ vp0_out_hdmi: endpoint@RK3568_VOP2_EP_HDMI { ++ reg = ; ++ remote-endpoint = <&hdmi_in_vp0>; ++ }; ++}; +From patchwork Mon Dec 20 11:06:26 2021 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +X-Patchwork-Submitter: Sascha Hauer +X-Patchwork-Id: 12687543 +Return-Path: + +X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on + aws-us-west-2-korg-lkml-1.web.codeaurora.org +Received: from bombadil.infradead.org (bombadil.infradead.org + [198.137.202.133]) + (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) + (No client certificate requested) + by smtp.lore.kernel.org (Postfix) with ESMTPS id 88567C433F5 + for ; + Mon, 20 Dec 2021 11:10:11 +0000 (UTC) +DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; + d=lists.infradead.org; s=bombadil.20210309; h=Sender: + Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: + List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: + Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: + Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: + List-Owner; bh=6O3IHzivIlfbXfxo3cnjWUtMtrtJ8gWJpB2yON+x6WQ=; b=Hmwkm/sBH5UxKg + NerPJoUeITxGNKDqCLznd6uTBB409ilx5zR6FyoEGTEDu5M0Z/Z133EwRfDJrbDaU/45KNmQAenl0 + C4rENubcQ1CNZI6pa8HCNvF15RzzA9QL/2jTiGf9nUKuc6Nd+pq1BwAwUjqBfxWYWRTQnCCJNkZnd + JTzDU3r8rubPe4m6FG8+YRwqIfR8TdLOWt1KFhfvFazufbGl6xyI3xr0Uwp4XIZcov69gI/7MWtYo + c0Pn5Na1Aczn70oatPxCTMefQNab+EC4Kjh/hZiTeTTOHbdnzpCQsNHdI9ooWtDXN8QE0RwrA7fny + WO9SG1PYfjGzcTklaJOw==; +Received: from localhost ([::1] helo=bombadil.infradead.org) + by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) + id 1mzGYP-001pzH-6c; Mon, 20 Dec 2021 11:10:05 +0000 +Received: from metis.ext.pengutronix.de + ([2001:67c:670:201:290:27ff:fe1d:cc33]) + by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) + id 1mzGVK-001oDM-Be + for linux-rockchip@lists.infradead.org; Mon, 20 Dec 2021 11:06:57 +0000 +Received: from dude02.hi.pengutronix.de ([2001:67c:670:100:1d::28]) + by metis.ext.pengutronix.de with esmtps + (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) + (envelope-from ) + id 1mzGVH-0004xH-CI; Mon, 20 Dec 2021 12:06:51 +0100 +Received: from sha by dude02.hi.pengutronix.de with local (Exim 4.94.2) + (envelope-from ) + id 1mzGVA-00EmEn-RE; Mon, 20 Dec 2021 12:06:44 +0100 +From: Sascha Hauer +To: dri-devel@lists.freedesktop.org +Cc: linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, + devicetree@vger.kernel.org, kernel@pengutronix.de, + Andy Yan , + Benjamin Gaignard , + Michael Riesch , + Sandy Huang , + =?utf-8?q?Heiko_St=C3=BCbner?= , + Peter Geis , Sascha Hauer +Subject: [PATCH 18/22] clk: rk3568: drop CLK_SET_RATE_PARENT from dclk_vop* +Date: Mon, 20 Dec 2021 12:06:26 +0100 +Message-Id: <20211220110630.3521121-19-s.hauer@pengutronix.de> +X-Mailer: git-send-email 2.30.2 +In-Reply-To: <20211220110630.3521121-1-s.hauer@pengutronix.de> +References: <20211220110630.3521121-1-s.hauer@pengutronix.de> +MIME-Version: 1.0 +X-SA-Exim-Connect-IP: 2001:67c:670:100:1d::28 +X-SA-Exim-Mail-From: sha@pengutronix.de +X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); + SAEximRunCond expanded to false +X-PTX-Original-Recipient: linux-rockchip@lists.infradead.org +X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 +X-CRM114-CacheID: sfid-20211220_030654_440482_4563C31D +X-CRM114-Status: GOOD ( 13.46 ) +X-BeenThere: linux-rockchip@lists.infradead.org +X-Mailman-Version: 2.1.34 +Precedence: list +List-Id: Upstream kernel work for Rockchip platforms + +List-Unsubscribe: , + +List-Archive: +List-Post: +List-Help: +List-Subscribe: , + +Sender: "Linux-rockchip" +Errors-To: + linux-rockchip-bounces+linux-rockchip=archiver.kernel.org@lists.infradead.org + +The pixel clocks dclk_vop[012] can be clocked from hpll, vpll, gpll or +cpll. gpll and cpll also drive many other clocks, so changing the +dclk_vop[012] clocks could change these other clocks as well. Drop +CLK_SET_RATE_PARENT to fix that. With this change the VOP2 driver can +only adjust the pixel clocks with the divider between the PLL and the +dclk_vop[012] which means the user may have to adjust the PLL clock to a +suitable rate using the assigned-clock-rate device tree property. + +Signed-off-by: Sascha Hauer +--- + drivers/clk/rockchip/clk-rk3568.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/clk/rockchip/clk-rk3568.c b/drivers/clk/rockchip/clk-rk3568.c +index 69a9e8069a486..604a367bc498a 100644 +--- a/drivers/clk/rockchip/clk-rk3568.c ++++ b/drivers/clk/rockchip/clk-rk3568.c +@@ -1038,13 +1038,13 @@ static struct rockchip_clk_branch rk3568_clk_branches[] __initdata = { + RK3568_CLKGATE_CON(20), 8, GFLAGS), + GATE(HCLK_VOP, "hclk_vop", "hclk_vo", 0, + RK3568_CLKGATE_CON(20), 9, GFLAGS), +- COMPOSITE(DCLK_VOP0, "dclk_vop0", hpll_vpll_gpll_cpll_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT, ++ COMPOSITE(DCLK_VOP0, "dclk_vop0", hpll_vpll_gpll_cpll_p, CLK_SET_RATE_NO_REPARENT, + RK3568_CLKSEL_CON(39), 10, 2, MFLAGS, 0, 8, DFLAGS, + RK3568_CLKGATE_CON(20), 10, GFLAGS), +- COMPOSITE(DCLK_VOP1, "dclk_vop1", hpll_vpll_gpll_cpll_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT, ++ COMPOSITE(DCLK_VOP1, "dclk_vop1", hpll_vpll_gpll_cpll_p, CLK_SET_RATE_NO_REPARENT, + RK3568_CLKSEL_CON(40), 10, 2, MFLAGS, 0, 8, DFLAGS, + RK3568_CLKGATE_CON(20), 11, GFLAGS), +- COMPOSITE(DCLK_VOP2, "dclk_vop2", hpll_vpll_gpll_cpll_p, 0, ++ COMPOSITE(DCLK_VOP2, "dclk_vop2", hpll_vpll_gpll_cpll_p, CLK_SET_RATE_NO_REPARENT, + RK3568_CLKSEL_CON(41), 10, 2, MFLAGS, 0, 8, DFLAGS, + RK3568_CLKGATE_CON(20), 12, GFLAGS), + GATE(CLK_VOP_PWM, "clk_vop_pwm", "xin24m", 0, +From patchwork Mon Dec 20 11:06:27 2021 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 8bit +X-Patchwork-Submitter: Sascha Hauer +X-Patchwork-Id: 12687621 +Return-Path: + +X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on + aws-us-west-2-korg-lkml-1.web.codeaurora.org +Received: from bombadil.infradead.org (bombadil.infradead.org + [198.137.202.133]) + (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) + (No client certificate requested) + by smtp.lore.kernel.org (Postfix) with ESMTPS id 4A1D9C433EF + for ; + Mon, 20 Dec 2021 11:20:44 +0000 (UTC) +DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; + d=lists.infradead.org; s=bombadil.20210309; h=Sender: + Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: + List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: + Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: + Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: + List-Owner; bh=Ub0qGw0PqplMhINqrVtsuQSqDfkYw7mDoJvMK9+Elts=; b=rYSZPO9/WthWlN + hr6xdzfoC6LA9cK0IMMm5l3MBYiGqoBSCwZ3KSD6oUp1vJnLmC2pDpbMRa7wgwjZJOVvH5AcxQZyx + uotli4m1tTrYjafRBqDlSm7CePIniOqNAAjidY+C9YNqCoszxtgtBfvDWW/F9+na+37LghDC9sbsi + A38zoUCODwU71V7Z9hf2kpouF45N4sTS5CaDbgc+Lb9PER0fh/+tguocmstpylPd9vAmbRbzRKns9 + aG5vozDyV4Xi397F70LftSdjdQ5V2+TaQ+ahvywwZkRfwsBvfO1B6s+8K1QtbO3no8d7NEFAvgIIc + yVwXqL8i5SrxcBfMUe0g==; +Received: from localhost ([::1] helo=bombadil.infradead.org) + by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) + id 1mzGie-001vfp-SS; Mon, 20 Dec 2021 11:20:40 +0000 +Received: from desiato.infradead.org ([2001:8b0:10b:1:d65d:64ff:fe57:4e05]) + by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) + id 1mzGVi-001oUP-80 + for linux-rockchip@bombadil.infradead.org; Mon, 20 Dec 2021 11:07:18 +0000 +DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; + d=infradead.org; s=desiato.20200630; h=Content-Transfer-Encoding:Content-Type + :MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From: + Sender:Reply-To:Content-ID:Content-Description; + bh=0qQl+IWgo1flydZn8pAekyNQAKvvkf3MEkBg3RCDFo8=; b=Vgwbcf2E5gH45epObbX8cWWwKJ + ym22rXUzOkeMFDoIXn2a24dtm3LC3pVefbTY7fD5oZLkqjZX29qTH1SVvfd2b42IzICEPdLn76kbU + SOgRpAer7ZND4YegupZBJznyLwxgkp8D8LNUsddU44ok0zixHGzQhEXcjDU9Sj/HJs+1euF6KpHWq + 7qNqA6WikzEJR+NHGOpMIO7BzWuPsNyJGLoCwxAclvCFnuQMacGCqrAzBsyF3m0vkpVU5qK2BTBzt + gxw1mTcRb9P4FkxOZKnpsMqOWe9fl5u17m0z1ajYyiCP47uBeFRt6qRNyHgyVUSP17tiCdniQIM58 + mPsYs+1w==; +Received: from metis.ext.pengutronix.de + ([2001:67c:670:201:290:27ff:fe1d:cc33]) + by desiato.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) + id 1mzGVX-002UEN-FA + for linux-rockchip@lists.infradead.org; Mon, 20 Dec 2021 11:07:16 +0000 +Received: from dude02.hi.pengutronix.de ([2001:67c:670:100:1d::28]) + by metis.ext.pengutronix.de with esmtps + (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) + (envelope-from ) + id 1mzGVE-0004xI-DS; Mon, 20 Dec 2021 12:06:48 +0100 +Received: from sha by dude02.hi.pengutronix.de with local (Exim 4.94.2) + (envelope-from ) + id 1mzGVA-00EmEq-Rw; Mon, 20 Dec 2021 12:06:44 +0100 +From: Sascha Hauer +To: dri-devel@lists.freedesktop.org +Cc: linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, + devicetree@vger.kernel.org, kernel@pengutronix.de, + Andy Yan , + Benjamin Gaignard , + Michael Riesch , + Sandy Huang , + =?utf-8?q?Heiko_St=C3=BCbner?= , + Peter Geis , Sascha Hauer +Subject: [PATCH 19/22] clk: rk3568: Add CLK_SET_RATE_PARENT to the HDMI + reference clock +Date: Mon, 20 Dec 2021 12:06:27 +0100 +Message-Id: <20211220110630.3521121-20-s.hauer@pengutronix.de> +X-Mailer: git-send-email 2.30.2 +In-Reply-To: <20211220110630.3521121-1-s.hauer@pengutronix.de> +References: <20211220110630.3521121-1-s.hauer@pengutronix.de> +MIME-Version: 1.0 +X-SA-Exim-Connect-IP: 2001:67c:670:100:1d::28 +X-SA-Exim-Mail-From: sha@pengutronix.de +X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); + SAEximRunCond expanded to false +X-PTX-Original-Recipient: linux-rockchip@lists.infradead.org +X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 +X-CRM114-CacheID: sfid-20211220_110713_894163_3C0C0EB3 +X-CRM114-Status: GOOD ( 15.63 ) +X-BeenThere: linux-rockchip@lists.infradead.org +X-Mailman-Version: 2.1.34 +Precedence: list +List-Id: Upstream kernel work for Rockchip platforms + +List-Unsubscribe: , + +List-Archive: +List-Post: +List-Help: +List-Subscribe: , + +Sender: "Linux-rockchip" +Errors-To: + linux-rockchip-bounces+linux-rockchip=archiver.kernel.org@lists.infradead.org + +On the rk3568 we have this (simplified) situation: + + .--------. .-----. .---------. +-| hpll |--.--| /n |----|dclk_vop0|- + `--------´ | `-----´ `---------´ + | .-----. .---------. + `--| /m |----|dclk_vop1|- + | `-----´ `---------´ + | .---------. + `-------------|hdmi_ref |- + `---------´ + +For the HDMI to work the HDMI reference clock needs to be the same as the +pixel clock which means the dividers have be set to one. The last patch removed +the CLK_SET_RATE_PARENT flag from the pixel clocks which means the hpll is not +changed on pixel clock changes. In order to allow the HDMI controller to +set a suitable PLL rate we now add the CLK_SET_RATE_PARENT flag to the +HDMI reference clock. With this the flow becomes: + +1) HDMI controller driver sets the rate to its pixel clock which means + hpll is set to the pixel clock +2) VOP2 driver sets dclk_vop[012] to the pixel clock. As this can't change + the hpll clock anymore this means only the divider is adjusted to the + desired value of dividing by one. + +Signed-off-by: Sascha Hauer +--- + drivers/clk/rockchip/clk-rk3568.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/clk/rockchip/clk-rk3568.c b/drivers/clk/rockchip/clk-rk3568.c +index 604a367bc498a..1fe78a58010ea 100644 +--- a/drivers/clk/rockchip/clk-rk3568.c ++++ b/drivers/clk/rockchip/clk-rk3568.c +@@ -1562,7 +1562,7 @@ static struct rockchip_clk_branch rk3568_clk_pmu_branches[] __initdata = { + RK3568_PMU_CLKGATE_CON(2), 14, GFLAGS), + GATE(XIN_OSC0_EDPPHY_G, "xin_osc0_edpphy_g", "xin24m", 0, + RK3568_PMU_CLKGATE_CON(2), 15, GFLAGS), +- MUX(CLK_HDMI_REF, "clk_hdmi_ref", clk_hdmi_ref_p, 0, ++ MUX(CLK_HDMI_REF, "clk_hdmi_ref", clk_hdmi_ref_p, CLK_SET_RATE_PARENT, + RK3568_PMU_CLKSEL_CON(8), 7, 1, MFLAGS), + }; + +From patchwork Mon Dec 20 11:06:28 2021 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +X-Patchwork-Submitter: Sascha Hauer +X-Patchwork-Id: 12687595 +Return-Path: + +X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on + aws-us-west-2-korg-lkml-1.web.codeaurora.org +Received: from bombadil.infradead.org (bombadil.infradead.org + [198.137.202.133]) + (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) + (No client certificate requested) + by smtp.lore.kernel.org (Postfix) with ESMTPS id 507B2C433EF + for ; + Mon, 20 Dec 2021 11:12:18 +0000 (UTC) +DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; + d=lists.infradead.org; s=bombadil.20210309; h=Sender: + Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: + List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: + Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: + Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: + List-Owner; bh=xcRr2lHpy54EWjATBxZ7nZDTFcqsNCZL/QHTI4fod6w=; b=numRFiiMPIExcr + EpUhRwHKF7mzObkcVvTAX7gsYMwIF7z/3qV35jI7SH3BW4X2C0jA0ilg/bwhRotHVRuM7QboaksDM + FOBh+Tq4CLBadnHGTm1z1cOV7wZLcnza5Ca6Aai8Zo7g+6BR26jOBYx3mkH6BpBJvhzsnTwUHzKsJ + E250f2aDO9G8drPRR4wIcaE2CDScwvjazF7tLefd6vuYnSEv/5e6sQHKUriGJBE9YM35T3VJoOIx3 + H7al2VJ02luZT2NiwcYW/lE3HF3ctlg8+yU5sNi5jj1Ck3meC2HmG06vwynMRM96YscVgj3FfIYcc + uxM6F8JHCQvxaW2gXjew==; +Received: from localhost ([::1] helo=bombadil.infradead.org) + by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) + id 1mzGaV-001rLa-1c; Mon, 20 Dec 2021 11:12:15 +0000 +Received: from desiato.infradead.org ([2001:8b0:10b:1:d65d:64ff:fe57:4e05]) + by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) + id 1mzGVW-001oMU-VD + for linux-rockchip@bombadil.infradead.org; Mon, 20 Dec 2021 11:07:06 +0000 +DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; + d=infradead.org; s=desiato.20200630; h=Content-Transfer-Encoding:MIME-Version + :References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: + Content-Type:Content-ID:Content-Description; + bh=5y0rsOrGd2fqJNZsrH73akV5YMUESh6vZZ+10OaGzN4=; b=TX1fqZrBoiYBbZAHWu84SutHmb + CjCucVCavOjpw/9M6T2OBJUP3Y1z8JHdjPXEzUiZ0/JCw1A+0Vha5ENPqR4jUCCdBnrm3Oxh6o9U5 + 4FuSaY6mpzy2xONXy3sR5OLvUr/UUWAZAEFhh7BkqbqDJf0uJjUBiyf0NR1klv6cXbtWPSjT1rqUb + +o8cNwjoarqvGAiuInX5b+LBzHuinb8zDRej/lsxb9mN9HpIb8tBoOOjntSSDl32P/j4KlZkWTSvz + bxSzTF2UPNS/UeZbF7Pkk1920Wvb6iSMS82OCDXUnLFdAn00+LvTX9Q1I40NaRD27Xv/dxE2ZoPsb + HblXCNCw==; +Received: from metis.ext.pengutronix.de + ([2001:67c:670:201:290:27ff:fe1d:cc33]) + by desiato.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) + id 1mzGVT-002UE0-Ln + for linux-rockchip@lists.infradead.org; Mon, 20 Dec 2021 11:07:05 +0000 +Received: from dude02.hi.pengutronix.de ([2001:67c:670:100:1d::28]) + by metis.ext.pengutronix.de with esmtps + (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) + (envelope-from ) + id 1mzGVH-0004xJ-BS; Mon, 20 Dec 2021 12:06:51 +0100 +Received: from sha by dude02.hi.pengutronix.de with local (Exim 4.94.2) + (envelope-from ) + id 1mzGVA-00EmEt-SW; Mon, 20 Dec 2021 12:06:44 +0100 +From: Sascha Hauer +To: dri-devel@lists.freedesktop.org +Cc: linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, + devicetree@vger.kernel.org, kernel@pengutronix.de, + Andy Yan , + Benjamin Gaignard , + Michael Riesch , + Sandy Huang , + =?utf-8?q?Heiko_St=C3=BCbner?= , + Peter Geis , Sascha Hauer +Subject: [PATCH 20/22] drm/encoder: Add of_graph port to struct drm_encoder +Date: Mon, 20 Dec 2021 12:06:28 +0100 +Message-Id: <20211220110630.3521121-21-s.hauer@pengutronix.de> +X-Mailer: git-send-email 2.30.2 +In-Reply-To: <20211220110630.3521121-1-s.hauer@pengutronix.de> +References: <20211220110630.3521121-1-s.hauer@pengutronix.de> +MIME-Version: 1.0 +X-SA-Exim-Connect-IP: 2001:67c:670:100:1d::28 +X-SA-Exim-Mail-From: sha@pengutronix.de +X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); + SAEximRunCond expanded to false +X-PTX-Original-Recipient: linux-rockchip@lists.infradead.org +X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 +X-CRM114-CacheID: sfid-20211220_110703_798471_E6CDC5BA +X-CRM114-Status: GOOD ( 11.42 ) +X-BeenThere: linux-rockchip@lists.infradead.org +X-Mailman-Version: 2.1.34 +Precedence: list +List-Id: Upstream kernel work for Rockchip platforms + +List-Unsubscribe: , + +List-Archive: +List-Post: +List-Help: +List-Subscribe: , + +Sender: "Linux-rockchip" +Errors-To: + linux-rockchip-bounces+linux-rockchip=archiver.kernel.org@lists.infradead.org + +Add a device node to drm_encoder which corresponds with the port node +in the DT description of the encoder. This allows drivers to find the +of_graph link between a crtc and an encoder. + +Signed-off-by: Sascha Hauer +--- + include/drm/drm_encoder.h | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/include/drm/drm_encoder.h b/include/drm/drm_encoder.h +index 6e91a0280f31b..3acd054b1eb3e 100644 +--- a/include/drm/drm_encoder.h ++++ b/include/drm/drm_encoder.h +@@ -99,6 +99,8 @@ struct drm_encoder { + struct drm_device *dev; + struct list_head head; + ++ struct device_node *port; ++ + struct drm_mode_object base; + char *name; + /** +From patchwork Mon Dec 20 11:06:29 2021 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +X-Patchwork-Submitter: Sascha Hauer +X-Patchwork-Id: 12687539 +Return-Path: + +X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on + aws-us-west-2-korg-lkml-1.web.codeaurora.org +Received: from bombadil.infradead.org (bombadil.infradead.org + [198.137.202.133]) + (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) + (No client certificate requested) + by smtp.lore.kernel.org (Postfix) with ESMTPS id 1B3C4C433EF + for ; + Mon, 20 Dec 2021 11:10:09 +0000 (UTC) +DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; + d=lists.infradead.org; s=bombadil.20210309; h=Sender: + Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: + List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: + Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: + Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: + List-Owner; bh=OJ3jvXcc4uCKEz2/3vAQEz5Wz/aVD17hJIdPkE4H4CE=; b=f4hMeQnCXp20tF + p2r9W7UXNf3UwdeiTqJceVwW11Z4Gi2qdMr57/uODGSdxyG+GIqwMML65xfpOKoN+e+DXvtgCYPNb + Nimmd0agbHyO1uWbCVQZs7tY/uof8rqwJV79mXmiwzf6HnDMPtFeUEnysEic3sYW6Ek3/fOOZp8YR + Mx169c4ax9BnwUNZO8FkjTouzq9NWj9N1eAD3wmfwyXMRot0vsezqMuNC/tGHbqmF85NElQdk7mxY + TRyGPHeFgIvbV3RTUNy9qS/4645iWBmH4hLLLwppudgtSMWfOhKmmdXUZFsDGBKU7aNAE/vU5/9KA + 3Dtd0/LSEXhf+2/DEnBQ==; +Received: from localhost ([::1] helo=bombadil.infradead.org) + by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) + id 1mzGYQ-001pzr-BH; Mon, 20 Dec 2021 11:10:06 +0000 +Received: from metis.ext.pengutronix.de + ([2001:67c:670:201:290:27ff:fe1d:cc33]) + by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) + id 1mzGVK-001oDg-LU + for linux-rockchip@lists.infradead.org; Mon, 20 Dec 2021 11:06:58 +0000 +Received: from dude02.hi.pengutronix.de ([2001:67c:670:100:1d::28]) + by metis.ext.pengutronix.de with esmtps + (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) + (envelope-from ) + id 1mzGVH-0004xK-CJ; Mon, 20 Dec 2021 12:06:51 +0100 +Received: from sha by dude02.hi.pengutronix.de with local (Exim 4.94.2) + (envelope-from ) + id 1mzGVA-00EmEw-T4; Mon, 20 Dec 2021 12:06:44 +0100 +From: Sascha Hauer +To: dri-devel@lists.freedesktop.org +Cc: linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, + devicetree@vger.kernel.org, kernel@pengutronix.de, + Andy Yan , + Benjamin Gaignard , + Michael Riesch , + Sandy Huang , + =?utf-8?q?Heiko_St=C3=BCbner?= , + Peter Geis , Sascha Hauer +Subject: [PATCH 21/22] drm/rockchip: Make VOP driver optional +Date: Mon, 20 Dec 2021 12:06:29 +0100 +Message-Id: <20211220110630.3521121-22-s.hauer@pengutronix.de> +X-Mailer: git-send-email 2.30.2 +In-Reply-To: <20211220110630.3521121-1-s.hauer@pengutronix.de> +References: <20211220110630.3521121-1-s.hauer@pengutronix.de> +MIME-Version: 1.0 +X-SA-Exim-Connect-IP: 2001:67c:670:100:1d::28 +X-SA-Exim-Mail-From: sha@pengutronix.de +X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); + SAEximRunCond expanded to false +X-PTX-Original-Recipient: linux-rockchip@lists.infradead.org +X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 +X-CRM114-CacheID: sfid-20211220_030654_725855_55F01FB7 +X-CRM114-Status: GOOD ( 13.98 ) +X-BeenThere: linux-rockchip@lists.infradead.org +X-Mailman-Version: 2.1.34 +Precedence: list +List-Id: Upstream kernel work for Rockchip platforms + +List-Unsubscribe: , + +List-Archive: +List-Post: +List-Help: +List-Subscribe: , + +Sender: "Linux-rockchip" +Errors-To: + linux-rockchip-bounces+linux-rockchip=archiver.kernel.org@lists.infradead.org + +With upcoming VOP2 support VOP won't be the only choice anymore, so make +the VOP driver optional. + +Signed-off-by: Sascha Hauer +--- + drivers/gpu/drm/rockchip/Kconfig | 8 ++++++++ + drivers/gpu/drm/rockchip/Makefile | 3 ++- + drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 2 +- + 3 files changed, 11 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/rockchip/Kconfig b/drivers/gpu/drm/rockchip/Kconfig +index 9f1ecefc39332..b9b156308460a 100644 +--- a/drivers/gpu/drm/rockchip/Kconfig ++++ b/drivers/gpu/drm/rockchip/Kconfig +@@ -21,8 +21,16 @@ config DRM_ROCKCHIP + + if DRM_ROCKCHIP + ++config ROCKCHIP_VOP ++ bool "Rockchip VOP driver" ++ default y ++ help ++ This selects support for the VOP driver. You should enable it ++ on all older SoCs up to RK3399. ++ + config ROCKCHIP_ANALOGIX_DP + bool "Rockchip specific extensions for Analogix DP driver" ++ depends on ROCKCHIP_VOP + help + This selects support for Rockchip SoC specific extensions + for the Analogix Core DP driver. If you want to enable DP +diff --git a/drivers/gpu/drm/rockchip/Makefile b/drivers/gpu/drm/rockchip/Makefile +index 17a9e7eb2130d..cd6e7bb5ce9c5 100644 +--- a/drivers/gpu/drm/rockchip/Makefile ++++ b/drivers/gpu/drm/rockchip/Makefile +@@ -4,9 +4,10 @@ + # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. + + rockchipdrm-y := rockchip_drm_drv.o rockchip_drm_fb.o \ +- rockchip_drm_gem.o rockchip_drm_vop.o rockchip_vop_reg.o ++ rockchip_drm_gem.o + rockchipdrm-$(CONFIG_DRM_FBDEV_EMULATION) += rockchip_drm_fbdev.o + ++rockchipdrm-$(CONFIG_ROCKCHIP_VOP) += rockchip_drm_vop.o rockchip_vop_reg.o + rockchipdrm-$(CONFIG_ROCKCHIP_ANALOGIX_DP) += analogix_dp-rockchip.o + rockchipdrm-$(CONFIG_ROCKCHIP_CDN_DP) += cdn-dp-core.o cdn-dp-reg.o + rockchipdrm-$(CONFIG_ROCKCHIP_DW_HDMI) += dw_hdmi-rockchip.o +diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c +index e4ebe60b3cc1a..64fa5fd62c01a 100644 +--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c +@@ -473,7 +473,7 @@ static int __init rockchip_drm_init(void) + int ret; + + num_rockchip_sub_drivers = 0; +- ADD_ROCKCHIP_SUB_DRIVER(vop_platform_driver, CONFIG_DRM_ROCKCHIP); ++ ADD_ROCKCHIP_SUB_DRIVER(vop_platform_driver, CONFIG_ROCKCHIP_VOP); + ADD_ROCKCHIP_SUB_DRIVER(rockchip_lvds_driver, + CONFIG_ROCKCHIP_LVDS); + ADD_ROCKCHIP_SUB_DRIVER(rockchip_dp_driver, +From patchwork Mon Dec 20 11:06:30 2021 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +X-Patchwork-Submitter: Sascha Hauer +X-Patchwork-Id: 12687605 +Return-Path: + +X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on + aws-us-west-2-korg-lkml-1.web.codeaurora.org +Received: from bombadil.infradead.org (bombadil.infradead.org + [198.137.202.133]) + (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) + (No client certificate requested) + by smtp.lore.kernel.org (Postfix) with ESMTPS id B50DCC433EF + for ; + Mon, 20 Dec 2021 11:14:24 +0000 (UTC) +DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; + d=lists.infradead.org; s=bombadil.20210309; h=Sender: + Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: + List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: + Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: + Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: + List-Owner; bh=K3W1lpMFsmRq3kP5jPDqgar3d9/M+yrEvHm3wF3JjyQ=; b=cyoIKZq/c9G1ia + gOOCTh7cREtbYmmKNI//9z5A916gRbdhS2J+W08GaL0fAEXSMywFea6rlFsyHR5R6rp1zMTrecxgC + 5n3gr09KRJAA1UJeKYlVthKH2/Pmhhuqmb6rVZ3WI2SowvaVNMcISfbQj1Kk9Tf9m/UmKmNwzDDVX + NSmYwz+Kbr7DlON2x9/M/wJcsPacPW4gZp6pjEs7iA4b5+dawiOZDe1/1191+HWIEyCdTU7DwjXDI + cjyxKSCRj4hUKIovUw5/UPM61zhvGB6U9E/kzLLH7p89UWIvMJ7+d2Hs2+ioJq5x81pUSTU/IWUir + rVF6e8/hhR/81pbNq7Ag==; +Received: from localhost ([::1] helo=bombadil.infradead.org) + by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) + id 1mzGcW-001sYq-3w; Mon, 20 Dec 2021 11:14:20 +0000 +Received: from metis.ext.pengutronix.de + ([2001:67c:670:201:290:27ff:fe1d:cc33]) + by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) + id 1mzGVL-001oE0-2x + for linux-rockchip@lists.infradead.org; Mon, 20 Dec 2021 11:07:08 +0000 +Received: from dude02.hi.pengutronix.de ([2001:67c:670:100:1d::28]) + by metis.ext.pengutronix.de with esmtps + (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) + (envelope-from ) + id 1mzGVH-0004xL-BS; Mon, 20 Dec 2021 12:06:51 +0100 +Received: from sha by dude02.hi.pengutronix.de with local (Exim 4.94.2) + (envelope-from ) + id 1mzGVA-00EmF0-U2; Mon, 20 Dec 2021 12:06:44 +0100 +From: Sascha Hauer +To: dri-devel@lists.freedesktop.org +Cc: linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, + devicetree@vger.kernel.org, kernel@pengutronix.de, + Andy Yan , + Benjamin Gaignard , + Michael Riesch , + Sandy Huang , + =?utf-8?q?Heiko_St=C3=BCbner?= , + Peter Geis , Sascha Hauer +Subject: [PATCH 22/22] drm: rockchip: Add VOP2 driver +Date: Mon, 20 Dec 2021 12:06:30 +0100 +Message-Id: <20211220110630.3521121-23-s.hauer@pengutronix.de> +X-Mailer: git-send-email 2.30.2 +In-Reply-To: <20211220110630.3521121-1-s.hauer@pengutronix.de> +References: <20211220110630.3521121-1-s.hauer@pengutronix.de> +MIME-Version: 1.0 +X-SA-Exim-Connect-IP: 2001:67c:670:100:1d::28 +X-SA-Exim-Mail-From: sha@pengutronix.de +X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); + SAEximRunCond expanded to false +X-PTX-Original-Recipient: linux-rockchip@lists.infradead.org +X-BeenThere: linux-rockchip@lists.infradead.org +X-Mailman-Version: 2.1.34 +Precedence: list +List-Id: Upstream kernel work for Rockchip platforms + +List-Unsubscribe: , + +List-Archive: +List-Post: +List-Help: +List-Subscribe: , + +Sender: "Linux-rockchip" +Errors-To: + linux-rockchip-bounces+linux-rockchip=archiver.kernel.org@lists.infradead.org + +From: Andy Yan + +The VOP2 unit is found on Rockchip SoCs beginning with rk3566/rk3568. +It replaces the VOP unit found in the older Rockchip SoCs. + +This driver has been derived from the downstream Rockchip Kernel and +heavily modified: + +- All nonstandard DRM properties have been removed +- dropped struct vop2_plane_state and pass around less data between + functions +- Dropped all DRM_FORMAT_* not known on upstream +- rework register access to get rid of excessively used macros +- Drop all waiting for framesyncs + +The driver is tested with HDMI and MIPI-DSI display on a RK3568-EVB +board. Overlay support is tested with the modetest utility. AFBC support +on the cluster windows is tested with weston-simple-dmabuf-egl on +weston using the (yet to be upstreamed) panfrost driver support. + +Signed-off-by: Sascha Hauer +Reported-by: kernel test robot +--- + drivers/gpu/drm/rockchip/Kconfig | 6 + + drivers/gpu/drm/rockchip/Makefile | 1 + + drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 1 + + drivers/gpu/drm/rockchip/rockchip_drm_drv.h | 7 +- + drivers/gpu/drm/rockchip/rockchip_drm_fb.c | 2 + + drivers/gpu/drm/rockchip/rockchip_drm_vop.h | 15 + + drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 2768 ++++++++++++++++++ + drivers/gpu/drm/rockchip/rockchip_drm_vop2.h | 480 +++ + drivers/gpu/drm/rockchip/rockchip_vop2_reg.c | 285 ++ + 9 files changed, 3564 insertions(+), 1 deletion(-) + create mode 100644 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c + create mode 100644 drivers/gpu/drm/rockchip/rockchip_drm_vop2.h + create mode 100644 drivers/gpu/drm/rockchip/rockchip_vop2_reg.c + +diff --git a/drivers/gpu/drm/rockchip/Kconfig b/drivers/gpu/drm/rockchip/Kconfig +index b9b156308460a..4ff0043f0ee70 100644 +--- a/drivers/gpu/drm/rockchip/Kconfig ++++ b/drivers/gpu/drm/rockchip/Kconfig +@@ -28,6 +28,12 @@ config ROCKCHIP_VOP + This selects support for the VOP driver. You should enable it + on all older SoCs up to RK3399. + ++config ROCKCHIP_VOP2 ++ bool "Rockchip VOP2 driver" ++ help ++ This selects support for the VOP2 driver. You should enable it ++ on all newer SoCs beginning form RK3568. ++ + config ROCKCHIP_ANALOGIX_DP + bool "Rockchip specific extensions for Analogix DP driver" + depends on ROCKCHIP_VOP +diff --git a/drivers/gpu/drm/rockchip/Makefile b/drivers/gpu/drm/rockchip/Makefile +index cd6e7bb5ce9c5..29848caef5c21 100644 +--- a/drivers/gpu/drm/rockchip/Makefile ++++ b/drivers/gpu/drm/rockchip/Makefile +@@ -7,6 +7,7 @@ rockchipdrm-y := rockchip_drm_drv.o rockchip_drm_fb.o \ + rockchip_drm_gem.o + rockchipdrm-$(CONFIG_DRM_FBDEV_EMULATION) += rockchip_drm_fbdev.o + ++rockchipdrm-$(CONFIG_ROCKCHIP_VOP2) += rockchip_drm_vop2.o rockchip_vop2_reg.o + rockchipdrm-$(CONFIG_ROCKCHIP_VOP) += rockchip_drm_vop.o rockchip_vop_reg.o + rockchipdrm-$(CONFIG_ROCKCHIP_ANALOGIX_DP) += analogix_dp-rockchip.o + rockchipdrm-$(CONFIG_ROCKCHIP_CDN_DP) += cdn-dp-core.o cdn-dp-reg.o +diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c +index 64fa5fd62c01a..2bd9acb265e5a 100644 +--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c +@@ -474,6 +474,7 @@ static int __init rockchip_drm_init(void) + + num_rockchip_sub_drivers = 0; + ADD_ROCKCHIP_SUB_DRIVER(vop_platform_driver, CONFIG_ROCKCHIP_VOP); ++ ADD_ROCKCHIP_SUB_DRIVER(vop2_platform_driver, CONFIG_ROCKCHIP_VOP2); + ADD_ROCKCHIP_SUB_DRIVER(rockchip_lvds_driver, + CONFIG_ROCKCHIP_LVDS); + ADD_ROCKCHIP_SUB_DRIVER(rockchip_dp_driver, +diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h +index aa0909e8edf93..fd6994f21817e 100644 +--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h +@@ -18,7 +18,7 @@ + + #define ROCKCHIP_MAX_FB_BUFFER 3 + #define ROCKCHIP_MAX_CONNECTOR 2 +-#define ROCKCHIP_MAX_CRTC 2 ++#define ROCKCHIP_MAX_CRTC 4 + + struct drm_device; + struct drm_connector; +@@ -31,6 +31,9 @@ struct rockchip_crtc_state { + int output_bpc; + int output_flags; + bool enable_afbc; ++ uint32_t bus_format; ++ u32 bus_flags; ++ int color_space; + }; + #define to_rockchip_crtc_state(s) \ + container_of(s, struct rockchip_crtc_state, base) +@@ -65,4 +68,6 @@ extern struct platform_driver rockchip_dp_driver; + extern struct platform_driver rockchip_lvds_driver; + extern struct platform_driver vop_platform_driver; + extern struct platform_driver rk3066_hdmi_driver; ++extern struct platform_driver vop2_platform_driver; ++ + #endif /* _ROCKCHIP_DRM_DRV_H_ */ +diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c +index 3aa37e177667e..0d2cb4f3922b8 100644 +--- a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c +@@ -134,4 +134,6 @@ void rockchip_drm_mode_config_init(struct drm_device *dev) + + dev->mode_config.funcs = &rockchip_drm_mode_config_funcs; + dev->mode_config.helper_private = &rockchip_mode_config_helpers; ++ ++ dev->mode_config.normalize_zpos = true; + } +diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h +index 857d97cdc67c6..1e364d7b50e69 100644 +--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h +@@ -54,9 +54,23 @@ struct vop_afbc { + struct vop_reg enable; + struct vop_reg win_sel; + struct vop_reg format; ++ struct vop_reg rb_swap; ++ struct vop_reg uv_swap; ++ struct vop_reg auto_gating_en; ++ struct vop_reg block_split_en; ++ struct vop_reg pic_vir_width; ++ struct vop_reg tile_num; + struct vop_reg hreg_block_split; ++ struct vop_reg pic_offset; + struct vop_reg pic_size; ++ struct vop_reg dsp_offset; ++ struct vop_reg transform_offset; + struct vop_reg hdr_ptr; ++ struct vop_reg half_block_en; ++ struct vop_reg xmirror; ++ struct vop_reg ymirror; ++ struct vop_reg rotate_270; ++ struct vop_reg rotate_90; + struct vop_reg rstn; + }; + +@@ -410,4 +424,5 @@ static inline int scl_vop_cal_lb_mode(int width, bool is_yuv) + } + + extern const struct component_ops vop_component_ops; ++ + #endif /* _ROCKCHIP_DRM_VOP_H */ +diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +new file mode 100644 +index 0000000000000..7d39ba90061d1 +--- /dev/null ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +@@ -0,0 +1,2768 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++/* ++ * Copyright (c) 2020 Rockchip Electronics Co., Ltd. ++ * Author: Andy Yan ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "rockchip_drm_drv.h" ++#include "rockchip_drm_gem.h" ++#include "rockchip_drm_fb.h" ++#include "rockchip_drm_vop2.h" ++ ++/* ++ * VOP2 architecture ++ * ++ +----------+ +-------------+ +-----------+ ++ | Cluster | | Sel 1 from 6| | 1 from 3 | ++ | window0 | | Layer0 | | RGB | ++ +----------+ +-------------+ +---------------+ +-------------+ +-----------+ ++ +----------+ +-------------+ |N from 6 layers| | | ++ | Cluster | | Sel 1 from 6| | Overlay0 +--->| Video Port0 | +-----------+ ++ | window1 | | Layer1 | | | | | | 1 from 3 | ++ +----------+ +-------------+ +---------------+ +-------------+ | LVDS | ++ +----------+ +-------------+ +-----------+ ++ | Esmart | | Sel 1 from 6| ++ | window0 | | Layer2 | +---------------+ +-------------+ +-----------+ ++ +----------+ +-------------+ |N from 6 Layers| | | +--> | 1 from 3 | ++ +----------+ +-------------+ --------> | Overlay1 +--->| Video Port1 | | MIPI | ++ | Esmart | | Sel 1 from 6| --------> | | | | +-----------+ ++ | Window1 | | Layer3 | +---------------+ +-------------+ ++ +----------+ +-------------+ +-----------+ ++ +----------+ +-------------+ | 1 from 3 | ++ | Smart | | Sel 1 from 6| +---------------+ +-------------+ | HDMI | ++ | Window0 | | Layer4 | |N from 6 Layers| | | +-----------+ ++ +----------+ +-------------+ | Overlay2 +--->| Video Port2 | ++ +----------+ +-------------+ | | | | +-----------+ ++ | Smart | | Sel 1 from 6| +---------------+ +-------------+ | 1 from 3 | ++ | Window1 | | Layer5 | | eDP | ++ +----------+ +-------------+ +-----------+ ++ * ++ */ ++ ++enum vop2_data_format { ++ VOP2_FMT_ARGB8888 = 0, ++ VOP2_FMT_RGB888, ++ VOP2_FMT_RGB565, ++ VOP2_FMT_XRGB101010, ++ VOP2_FMT_YUV420SP, ++ VOP2_FMT_YUV422SP, ++ VOP2_FMT_YUV444SP, ++ VOP2_FMT_YUYV422 = 8, ++ VOP2_FMT_YUYV420, ++ VOP2_FMT_VYUY422, ++ VOP2_FMT_VYUY420, ++ VOP2_FMT_YUV420SP_TILE_8x4 = 0x10, ++ VOP2_FMT_YUV420SP_TILE_16x2, ++ VOP2_FMT_YUV422SP_TILE_8x4, ++ VOP2_FMT_YUV422SP_TILE_16x2, ++ VOP2_FMT_YUV420SP_10, ++ VOP2_FMT_YUV422SP_10, ++ VOP2_FMT_YUV444SP_10, ++}; ++ ++enum vop2_afbc_format { ++ VOP2_AFBC_FMT_RGB565, ++ VOP2_AFBC_FMT_ARGB2101010 = 2, ++ VOP2_AFBC_FMT_YUV420_10BIT, ++ VOP2_AFBC_FMT_RGB888, ++ VOP2_AFBC_FMT_ARGB8888, ++ VOP2_AFBC_FMT_YUV420 = 9, ++ VOP2_AFBC_FMT_YUV422 = 0xb, ++ VOP2_AFBC_FMT_YUV422_10BIT = 0xe, ++ VOP2_AFBC_FMT_INVALID = -1, ++}; ++ ++union vop2_alpha_ctrl { ++ uint32_t val; ++ struct { ++ /* [0:1] */ ++ uint32_t color_mode:1; ++ uint32_t alpha_mode:1; ++ /* [2:3] */ ++ uint32_t blend_mode:2; ++ uint32_t alpha_cal_mode:1; ++ /* [5:7] */ ++ uint32_t factor_mode:3; ++ /* [8:9] */ ++ uint32_t alpha_en:1; ++ uint32_t src_dst_swap:1; ++ uint32_t reserved:6; ++ /* [16:23] */ ++ uint32_t glb_alpha:8; ++ } bits; ++}; ++ ++struct vop2_alpha { ++ union vop2_alpha_ctrl src_color_ctrl; ++ union vop2_alpha_ctrl dst_color_ctrl; ++ union vop2_alpha_ctrl src_alpha_ctrl; ++ union vop2_alpha_ctrl dst_alpha_ctrl; ++}; ++ ++struct vop2_alpha_config { ++ bool src_premulti_en; ++ bool dst_premulti_en; ++ bool src_pixel_alpha_en; ++ bool dst_pixel_alpha_en; ++ uint16_t src_glb_alpha_value; ++ uint16_t dst_glb_alpha_value; ++}; ++ ++struct vop2_win { ++ struct vop2 *vop2; ++ struct drm_plane base; ++ const struct vop2_win_data *data; ++ struct regmap_field *reg[VOP2_WIN_MAX_REG]; ++ ++ /** ++ * @win_id: graphic window id, a cluster maybe split into two ++ * graphics windows. ++ */ ++ uint8_t win_id; ++ ++ uint32_t offset; ++ ++ uint8_t delay; ++ enum drm_plane_type type; ++}; ++ ++struct vop2_video_port { ++ struct drm_crtc crtc; ++ struct vop2 *vop2; ++ struct clk *dclk; ++ uint8_t id; ++ const struct vop2_video_port_regs *regs; ++ const struct vop2_video_port_data *data; ++ ++ struct completion dsp_hold_completion; ++ ++ /** ++ * @win_mask: Bitmask of wins attached to the video port; ++ */ ++ uint32_t win_mask; ++ ++ struct vop2_win *primary_plane; ++ struct drm_pending_vblank_event *event; ++ ++ int nlayers; ++}; ++ ++struct vop2 { ++ struct device *dev; ++ struct drm_device *drm; ++ struct vop2_video_port vps[ROCKCHIP_MAX_CRTC]; ++ ++ const struct vop2_data *data; ++ /* Number of win that registered as plane, ++ * maybe less than the total number of hardware ++ * win. ++ */ ++ uint32_t registered_num_wins; ++ ++ void __iomem *regs; ++ struct regmap *map; ++ ++ struct regmap *grf; ++ ++ /* physical map length of vop2 register */ ++ uint32_t len; ++ ++ void __iomem *lut_regs; ++ /* one time only one process allowed to config the register */ ++ spinlock_t reg_lock; ++ ++ /* protects crtc enable/disable */ ++ struct mutex vop2_lock; ++ ++ int irq; ++ ++ /* ++ * Some globle resource are shared between all ++ * the vidoe ports(crtcs), so we need a ref counter here. ++ */ ++ unsigned int enable_count; ++ struct clk *hclk; ++ struct clk *aclk; ++ ++ /* must put at the end of the struct */ ++ struct vop2_win win[]; ++}; ++ ++static struct vop2_video_port *to_vop2_video_port(struct drm_crtc *crtc) ++{ ++ return container_of(crtc, struct vop2_video_port, crtc); ++} ++ ++static struct vop2_win *to_vop2_win(struct drm_plane *p) ++{ ++ return container_of(p, struct vop2_win, base); ++} ++ ++static void vop2_lock(struct vop2 *vop2) ++{ ++ mutex_lock(&vop2->vop2_lock); ++} ++ ++static void vop2_unlock(struct vop2 *vop2) ++{ ++ mutex_unlock(&vop2->vop2_lock); ++} ++ ++static void vop2_writel(struct vop2 *vop2, uint32_t offset, uint32_t v) ++{ ++ regmap_write(vop2->map, offset, v); ++} ++ ++static void vop2_vp_write(struct vop2_video_port *vp, uint32_t offset, ++ uint32_t v) ++{ ++ regmap_write(vp->vop2->map, vp->data->offset + offset, v); ++} ++ ++static uint32_t vop2_readl(struct vop2 *vop2, uint32_t offset) ++{ ++ uint32_t val; ++ ++ regmap_read(vop2->map, offset, &val); ++ ++ return val; ++} ++ ++static void vop2_win_write(const struct vop2_win *win, unsigned int reg, ++ uint32_t v) ++{ ++ regmap_field_write(win->reg[reg], v); ++} ++ ++static bool vop2_cluster_window(const struct vop2_win *win) ++{ ++ return win->data->feature & WIN_FEATURE_CLUSTER; ++} ++ ++static void vop2_cfg_done(struct vop2_video_port *vp) ++{ ++ struct vop2 *vop2 = vp->vop2; ++ uint32_t val; ++ ++ val = vop2_readl(vop2, RK3568_REG_CFG_DONE); ++ ++ val &= 0x7; ++ ++ vop2_writel(vop2, RK3568_REG_CFG_DONE, ++ val | BIT(vp->id) | RK3568_REG_CFG_DONE__GLB_CFG_DONE_EN); ++} ++ ++static void vop2_win_disable(struct vop2_win *win) ++{ ++ vop2_win_write(win, VOP2_WIN_ENABLE, 0); ++ ++ if (vop2_cluster_window(win)) ++ vop2_win_write(win, VOP2_WIN_CLUSTER_ENABLE, 0); ++} ++ ++static enum vop2_data_format vop2_convert_format(uint32_t format) ++{ ++ switch (format) { ++ case DRM_FORMAT_XRGB8888: ++ case DRM_FORMAT_ARGB8888: ++ case DRM_FORMAT_XBGR8888: ++ case DRM_FORMAT_ABGR8888: ++ return VOP2_FMT_ARGB8888; ++ case DRM_FORMAT_RGB888: ++ case DRM_FORMAT_BGR888: ++ return VOP2_FMT_RGB888; ++ case DRM_FORMAT_RGB565: ++ case DRM_FORMAT_BGR565: ++ return VOP2_FMT_RGB565; ++ case DRM_FORMAT_NV12: ++ return VOP2_FMT_YUV420SP; ++ case DRM_FORMAT_NV16: ++ return VOP2_FMT_YUV422SP; ++ case DRM_FORMAT_NV24: ++ return VOP2_FMT_YUV444SP; ++ case DRM_FORMAT_YUYV: ++ case DRM_FORMAT_YVYU: ++ return VOP2_FMT_VYUY422; ++ case DRM_FORMAT_VYUY: ++ case DRM_FORMAT_UYVY: ++ return VOP2_FMT_YUYV422; ++ default: ++ DRM_ERROR("unsupported format[%08x]\n", format); ++ return -EINVAL; ++ } ++} ++ ++static enum vop2_afbc_format vop2_convert_afbc_format(uint32_t format) ++{ ++ switch (format) { ++ case DRM_FORMAT_XRGB8888: ++ case DRM_FORMAT_ARGB8888: ++ case DRM_FORMAT_XBGR8888: ++ case DRM_FORMAT_ABGR8888: ++ return VOP2_AFBC_FMT_ARGB8888; ++ case DRM_FORMAT_RGB888: ++ case DRM_FORMAT_BGR888: ++ return VOP2_AFBC_FMT_RGB888; ++ case DRM_FORMAT_RGB565: ++ case DRM_FORMAT_BGR565: ++ return VOP2_AFBC_FMT_RGB565; ++ case DRM_FORMAT_NV12: ++ return VOP2_AFBC_FMT_YUV420; ++ case DRM_FORMAT_NV16: ++ return VOP2_AFBC_FMT_YUV422; ++ default: ++ return VOP2_AFBC_FMT_INVALID; ++ } ++ ++ return VOP2_AFBC_FMT_INVALID; ++} ++ ++static bool vop2_win_rb_swap(uint32_t format) ++{ ++ switch (format) { ++ case DRM_FORMAT_XBGR8888: ++ case DRM_FORMAT_ABGR8888: ++ case DRM_FORMAT_BGR888: ++ case DRM_FORMAT_BGR565: ++ return true; ++ default: ++ return false; ++ } ++} ++ ++static bool vop2_afbc_rb_swap(uint32_t format) ++{ ++ switch (format) { ++ case DRM_FORMAT_NV24: ++ return true; ++ default: ++ return false; ++ } ++} ++ ++static bool vop2_afbc_uv_swap(uint32_t format) ++{ ++ switch (format) { ++ case DRM_FORMAT_NV12: ++ case DRM_FORMAT_NV16: ++ return true; ++ default: ++ return false; ++ } ++} ++ ++static bool vop2_win_uv_swap(uint32_t format) ++{ ++ switch (format) { ++ case DRM_FORMAT_NV12: ++ case DRM_FORMAT_NV16: ++ case DRM_FORMAT_NV24: ++ return true; ++ default: ++ return false; ++ } ++} ++ ++static bool vop2_win_dither_up(uint32_t format) ++{ ++ switch (format) { ++ case DRM_FORMAT_BGR565: ++ case DRM_FORMAT_RGB565: ++ return true; ++ default: ++ return false; ++ } ++} ++ ++static bool vop2_output_uv_swap(uint32_t bus_format, uint32_t output_mode) ++{ ++ /* ++ * FIXME: ++ * ++ * There is no media type for YUV444 output, ++ * so when out_mode is AAAA or P888, assume output is YUV444 on ++ * yuv format. ++ * ++ * From H/W testing, YUV444 mode need a rb swap. ++ */ ++ if (bus_format == MEDIA_BUS_FMT_YVYU8_1X16 || ++ bus_format == MEDIA_BUS_FMT_VYUY8_1X16 || ++ bus_format == MEDIA_BUS_FMT_YVYU8_2X8 || ++ bus_format == MEDIA_BUS_FMT_VYUY8_2X8 || ++ ((bus_format == MEDIA_BUS_FMT_YUV8_1X24 || ++ bus_format == MEDIA_BUS_FMT_YUV10_1X30) && ++ (output_mode == ROCKCHIP_OUT_MODE_AAAA || ++ output_mode == ROCKCHIP_OUT_MODE_P888))) ++ return true; ++ else ++ return false; ++} ++ ++static bool is_yuv_output(uint32_t bus_format) ++{ ++ switch (bus_format) { ++ case MEDIA_BUS_FMT_YUV8_1X24: ++ case MEDIA_BUS_FMT_YUV10_1X30: ++ case MEDIA_BUS_FMT_UYYVYY8_0_5X24: ++ case MEDIA_BUS_FMT_UYYVYY10_0_5X30: ++ case MEDIA_BUS_FMT_YUYV8_2X8: ++ case MEDIA_BUS_FMT_YVYU8_2X8: ++ case MEDIA_BUS_FMT_UYVY8_2X8: ++ case MEDIA_BUS_FMT_VYUY8_2X8: ++ case MEDIA_BUS_FMT_YUYV8_1X16: ++ case MEDIA_BUS_FMT_YVYU8_1X16: ++ case MEDIA_BUS_FMT_UYVY8_1X16: ++ case MEDIA_BUS_FMT_VYUY8_1X16: ++ return true; ++ default: ++ return false; ++ } ++} ++ ++static bool rockchip_afbc(struct drm_plane *plane, u64 modifier) ++{ ++ int i; ++ ++ if (modifier == DRM_FORMAT_MOD_LINEAR) ++ return false; ++ ++ for (i = 0 ; i < plane->modifier_count; i++) ++ if (plane->modifiers[i] == modifier) ++ break; ++ ++ return (i < plane->modifier_count) ? true : false; ++ ++} ++ ++static bool rockchip_vop2_mod_supported(struct drm_plane *plane, uint32_t format, u64 modifier) ++{ ++ struct vop2_win *win = to_vop2_win(plane); ++ struct vop2 *vop2 = win->vop2; ++ ++ if (modifier == DRM_FORMAT_MOD_INVALID) ++ return false; ++ ++ if (modifier == DRM_FORMAT_MOD_LINEAR) ++ return true; ++ ++ if (!rockchip_afbc(plane, modifier)) { ++ drm_err(vop2->drm, "Unsupported format modifier 0x%llx\n", modifier); ++ ++ return false; ++ } ++ ++ return vop2_convert_afbc_format(format) >= 0; ++} ++ ++static int vop2_afbc_half_block_enable(struct drm_plane_state *pstate) ++{ ++ if ((pstate->rotation & DRM_MODE_ROTATE_270) || (pstate->rotation & DRM_MODE_ROTATE_90)) ++ return 0; ++ else ++ return 1; ++} ++ ++static uint32_t vop2_afbc_transform_offset(struct drm_plane_state *pstate, ++ bool afbc_half_block_en) ++{ ++ struct drm_rect *src = &pstate->src; ++ struct drm_framebuffer *fb = pstate->fb; ++ uint32_t bpp = fb->format->cpp[0] * 8; ++ uint32_t vir_width = (fb->pitches[0] << 3) / bpp; ++ uint32_t width = drm_rect_width(src) >> 16; ++ uint32_t height = drm_rect_height(src) >> 16; ++ uint32_t act_xoffset = src->x1 >> 16; ++ uint32_t act_yoffset = src->y1 >> 16; ++ uint32_t align16_crop = 0; ++ uint32_t align64_crop = 0; ++ uint32_t height_tmp = 0; ++ uint32_t transform_tmp = 0; ++ uint8_t transform_xoffset = 0; ++ uint8_t transform_yoffset = 0; ++ uint8_t top_crop = 0; ++ uint8_t top_crop_line_num = 0; ++ uint8_t bottom_crop_line_num = 0; ++ ++ /* 16 pixel align */ ++ if (height & 0xf) ++ align16_crop = 16 - (height & 0xf); ++ ++ height_tmp = height + align16_crop; ++ ++ /* 64 pixel align */ ++ if (height_tmp & 0x3f) ++ align64_crop = 64 - (height_tmp & 0x3f); ++ ++ top_crop_line_num = top_crop << 2; ++ if (top_crop == 0) ++ bottom_crop_line_num = align16_crop + align64_crop; ++ else if (top_crop == 1) ++ bottom_crop_line_num = align16_crop + align64_crop + 12; ++ else if (top_crop == 2) ++ bottom_crop_line_num = align16_crop + align64_crop + 8; ++ ++ switch (pstate->rotation & ++ (DRM_MODE_REFLECT_X | ++ DRM_MODE_REFLECT_Y | ++ DRM_MODE_ROTATE_90 | ++ DRM_MODE_ROTATE_270)) { ++ case DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y: ++ transform_tmp = act_xoffset + width; ++ transform_xoffset = 16 - (transform_tmp & 0xf); ++ transform_tmp = bottom_crop_line_num - act_yoffset; ++ ++ if (afbc_half_block_en) ++ transform_yoffset = transform_tmp & 0x7; ++ else ++ transform_yoffset = (transform_tmp & 0xf); ++ ++ break; ++ case DRM_MODE_REFLECT_X | DRM_MODE_ROTATE_90: ++ transform_tmp = bottom_crop_line_num - act_yoffset; ++ transform_xoffset = transform_tmp & 0xf; ++ transform_tmp = vir_width - width - act_xoffset; ++ transform_yoffset = transform_tmp & 0xf; ++ break; ++ case DRM_MODE_REFLECT_X | DRM_MODE_ROTATE_270: ++ transform_tmp = top_crop_line_num + act_yoffset; ++ transform_xoffset = transform_tmp & 0xf; ++ transform_tmp = act_xoffset; ++ transform_yoffset = transform_tmp & 0xf; ++ break; ++ case DRM_MODE_REFLECT_X: ++ transform_tmp = act_xoffset + width; ++ transform_xoffset = 16 - (transform_tmp & 0xf); ++ transform_tmp = top_crop_line_num + act_yoffset; ++ ++ if (afbc_half_block_en) ++ transform_yoffset = transform_tmp & 0x7; ++ else ++ transform_yoffset = transform_tmp & 0xf; ++ ++ break; ++ case DRM_MODE_REFLECT_Y: ++ transform_tmp = act_xoffset; ++ transform_xoffset = transform_tmp & 0xf; ++ transform_tmp = bottom_crop_line_num - act_yoffset; ++ ++ if (afbc_half_block_en) ++ transform_yoffset = transform_tmp & 0x7; ++ else ++ transform_yoffset = transform_tmp & 0xf; ++ ++ break; ++ case DRM_MODE_ROTATE_90: ++ transform_tmp = bottom_crop_line_num - act_yoffset; ++ transform_xoffset = transform_tmp & 0xf; ++ transform_tmp = act_xoffset; ++ transform_yoffset = transform_tmp & 0xf; ++ break; ++ case DRM_MODE_ROTATE_270: ++ transform_tmp = top_crop_line_num + act_yoffset; ++ transform_xoffset = transform_tmp & 0xf; ++ transform_tmp = vir_width - width - act_xoffset; ++ transform_yoffset = transform_tmp & 0xf; ++ break; ++ case 0: ++ transform_tmp = act_xoffset; ++ transform_xoffset = transform_tmp & 0xf; ++ transform_tmp = top_crop_line_num + act_yoffset; ++ ++ if (afbc_half_block_en) ++ transform_yoffset = transform_tmp & 0x7; ++ else ++ transform_yoffset = transform_tmp & 0xf; ++ ++ break; ++ } ++ ++ return (transform_xoffset & 0xf) | ((transform_yoffset & 0xf) << 16); ++} ++ ++/* ++ * A Cluster window has 2048 x 16 line buffer, which can ++ * works at 2048 x 16(Full) or 4096 x 8 (Half) mode. ++ * for Cluster_lb_mode register: ++ * 0: half mode, for plane input width range 2048 ~ 4096 ++ * 1: half mode, for cluster work at 2 * 2048 plane mode ++ * 2: half mode, for rotate_90/270 mode ++ * ++ */ ++static int vop2_get_cluster_lb_mode(struct vop2_win *win, struct drm_plane_state *pstate) ++{ ++ if ((pstate->rotation & DRM_MODE_ROTATE_270) || (pstate->rotation & DRM_MODE_ROTATE_90)) ++ return 2; ++ else ++ return 0; ++} ++ ++/* ++ * bli_sd_factor = (src - 1) / (dst - 1) << 12; ++ * avg_sd_factor: ++ * bli_su_factor: ++ * bic_su_factor: ++ * = (src - 1) / (dst - 1) << 16; ++ * ++ * gt2 enable: dst get one line from two line of the src ++ * gt4 enable: dst get one line from four line of the src. ++ * ++ */ ++static uint16_t vop2_scale_factor(enum scale_mode mode, ++ int32_t filter_mode, ++ uint32_t src, uint32_t dst) ++{ ++ uint32_t fac; ++ int i; ++ ++ if (mode == SCALE_NONE) ++ return 0; ++ ++ /* ++ * A workaround to avoid zero div. ++ */ ++ if (dst == 1 || src == 1) { ++ dst++; ++ src++; ++ } ++ ++ if ((mode == SCALE_DOWN) && (filter_mode == VOP2_SCALE_DOWN_BIL)) { ++ fac = ((src - 1) << 12) / (dst - 1); ++ for (i = 0; i < 100; i++) { ++ if (fac * (dst - 1) >> 12 < (src - 1)) ++ break; ++ fac -= 1; ++ DRM_DEBUG("down fac cali: src:%d, dst:%d, fac:0x%x\n", src, dst, fac); ++ } ++ } else { ++ fac = ((src - 1) << 16) / (dst - 1); ++ for (i = 0; i < 100; i++) { ++ if (fac * (dst - 1) >> 16 < (src - 1)) ++ break; ++ fac -= 1; ++ DRM_DEBUG("up fac cali: src:%d, dst:%d, fac:0x%x\n", src, dst, fac); ++ } ++ } ++ ++ return fac; ++} ++ ++static void vop2_setup_scale(struct vop2 *vop2, const struct vop2_win *win, ++ uint32_t src_w, uint32_t src_h, uint32_t dst_w, ++ uint32_t dst_h, uint32_t pixel_format) ++{ ++ const struct drm_format_info *info; ++ uint16_t cbcr_src_w; ++ uint16_t cbcr_src_h; ++ uint16_t yrgb_hor_scl_mode, yrgb_ver_scl_mode; ++ uint16_t cbcr_hor_scl_mode, cbcr_ver_scl_mode; ++ uint16_t hscl_filter_mode, vscl_filter_mode; ++ uint8_t gt2 = 0; ++ uint8_t gt4 = 0; ++ uint32_t val; ++ ++ info = drm_format_info(pixel_format); ++ ++ cbcr_src_w = src_w / info->hsub; ++ cbcr_src_h = src_h / info->vsub; ++ ++ if (src_h >= (4 * dst_h)) { ++ gt4 = 1; ++ src_h >>= 2; ++ } else if (src_h >= (2 * dst_h)) { ++ gt2 = 1; ++ src_h >>= 1; ++ } ++ ++ yrgb_hor_scl_mode = scl_get_scl_mode(src_w, dst_w); ++ yrgb_ver_scl_mode = scl_get_scl_mode(src_h, dst_h); ++ ++ if (yrgb_hor_scl_mode == SCALE_UP) ++ hscl_filter_mode = VOP2_SCALE_UP_BIC; ++ else ++ hscl_filter_mode = VOP2_SCALE_DOWN_BIL; ++ ++ if (yrgb_ver_scl_mode == SCALE_UP) ++ vscl_filter_mode = VOP2_SCALE_UP_BIL; ++ else ++ vscl_filter_mode = VOP2_SCALE_DOWN_BIL; ++ ++ /* ++ * RK3568 VOP Esmart/Smart dsp_w should be even pixel ++ * at scale down mode ++ */ ++ if (!(win->data->feature & WIN_FEATURE_AFBDC)) { ++ if ((yrgb_hor_scl_mode == SCALE_DOWN) && (dst_w & 0x1)) { ++ drm_dbg(vop2->drm, "%s dst_w[%d] should align as 2 pixel\n", ++ win->data->name, dst_w); ++ dst_w += 1; ++ } ++ } ++ ++ val = vop2_scale_factor(yrgb_hor_scl_mode, hscl_filter_mode, ++ src_w, dst_w); ++ vop2_win_write(win, VOP2_WIN_SCALE_YRGB_X, val); ++ val = vop2_scale_factor(yrgb_ver_scl_mode, vscl_filter_mode, ++ src_h, dst_h); ++ vop2_win_write(win, VOP2_WIN_SCALE_YRGB_Y, val); ++ ++ vop2_win_write(win, VOP2_WIN_VSD_YRGB_GT4, gt4); ++ vop2_win_write(win, VOP2_WIN_VSD_YRGB_GT2, gt2); ++ ++ vop2_win_write(win, VOP2_WIN_YRGB_HOR_SCL_MODE, yrgb_hor_scl_mode); ++ vop2_win_write(win, VOP2_WIN_YRGB_VER_SCL_MODE, yrgb_ver_scl_mode); ++ ++ if (vop2_cluster_window(win)) ++ return; ++ ++ vop2_win_write(win, VOP2_WIN_YRGB_HSCL_FILTER_MODE, hscl_filter_mode); ++ vop2_win_write(win, VOP2_WIN_YRGB_VSCL_FILTER_MODE, vscl_filter_mode); ++ ++ if (info->is_yuv) { ++ gt4 = gt2 = 0; ++ ++ if (cbcr_src_h >= (4 * dst_h)) ++ gt4 = 1; ++ else if (cbcr_src_h >= (2 * dst_h)) ++ gt2 = 1; ++ ++ if (gt4) ++ cbcr_src_h >>= 2; ++ else if (gt2) ++ cbcr_src_h >>= 1; ++ ++ cbcr_hor_scl_mode = scl_get_scl_mode(cbcr_src_w, dst_w); ++ cbcr_ver_scl_mode = scl_get_scl_mode(cbcr_src_h, dst_h); ++ ++ val = vop2_scale_factor(cbcr_hor_scl_mode, hscl_filter_mode, ++ cbcr_src_w, dst_w); ++ vop2_win_write(win, VOP2_WIN_SCALE_CBCR_X, val); ++ ++ val = vop2_scale_factor(cbcr_ver_scl_mode, vscl_filter_mode, ++ cbcr_src_h, dst_h); ++ vop2_win_write(win, VOP2_WIN_SCALE_CBCR_Y, val); ++ ++ vop2_win_write(win, VOP2_WIN_VSD_CBCR_GT4, gt4); ++ vop2_win_write(win, VOP2_WIN_VSD_CBCR_GT2, gt2); ++ vop2_win_write(win, VOP2_WIN_CBCR_HOR_SCL_MODE, cbcr_hor_scl_mode); ++ vop2_win_write(win, VOP2_WIN_CBCR_VER_SCL_MODE, cbcr_ver_scl_mode); ++ vop2_win_write(win, VOP2_WIN_CBCR_HSCL_FILTER_MODE, hscl_filter_mode); ++ vop2_win_write(win, VOP2_WIN_CBCR_VSCL_FILTER_MODE, vscl_filter_mode); ++ } ++} ++ ++static int vop2_convert_csc_mode(int csc_mode) ++{ ++ switch (csc_mode) { ++ case V4L2_COLORSPACE_SMPTE170M: ++ case V4L2_COLORSPACE_470_SYSTEM_M: ++ case V4L2_COLORSPACE_470_SYSTEM_BG: ++ return CSC_BT601L; ++ case V4L2_COLORSPACE_REC709: ++ case V4L2_COLORSPACE_SMPTE240M: ++ case V4L2_COLORSPACE_DEFAULT: ++ return CSC_BT709L; ++ case V4L2_COLORSPACE_JPEG: ++ return CSC_BT601F; ++ case V4L2_COLORSPACE_BT2020: ++ return CSC_BT2020; ++ default: ++ return CSC_BT709L; ++ } ++} ++ ++/* ++ * colorspace path: ++ * Input Win csc Output ++ * 1. YUV(2020) --> Y2R->2020To709->R2Y --> YUV_OUTPUT(601/709) ++ * RGB --> R2Y __/ ++ * ++ * 2. YUV(2020) --> bypasss --> YUV_OUTPUT(2020) ++ * RGB --> 709To2020->R2Y __/ ++ * ++ * 3. YUV(2020) --> Y2R->2020To709 --> RGB_OUTPUT(709) ++ * RGB --> R2Y __/ ++ * ++ * 4. YUV(601/709)-> Y2R->709To2020->R2Y --> YUV_OUTPUT(2020) ++ * RGB --> 709To2020->R2Y __/ ++ * ++ * 5. YUV(601/709)-> bypass --> YUV_OUTPUT(709) ++ * RGB --> R2Y __/ ++ * ++ * 6. YUV(601/709)-> bypass --> YUV_OUTPUT(601) ++ * RGB --> R2Y(601) __/ ++ * ++ * 7. YUV --> Y2R(709) --> RGB_OUTPUT(709) ++ * RGB --> bypass __/ ++ * ++ * 8. RGB --> 709To2020->R2Y --> YUV_OUTPUT(2020) ++ * ++ * 9. RGB --> R2Y(709) --> YUV_OUTPUT(709) ++ * ++ * 10. RGB --> R2Y(601) --> YUV_OUTPUT(601) ++ * ++ * 11. RGB --> bypass --> RGB_OUTPUT(709) ++ */ ++ ++static void vop2_setup_csc_mode(struct vop2_video_port *vp, ++ struct vop2_win *win, ++ struct drm_plane_state *pstate) ++{ ++ struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(vp->crtc.state); ++ int is_input_yuv = pstate->fb->format->is_yuv; ++ int is_output_yuv = is_yuv_output(vcstate->bus_format); ++ int input_csc = V4L2_COLORSPACE_DEFAULT; ++ int output_csc = vcstate->color_space; ++ bool r2y_en, y2r_en; ++ int csc_mode; ++ ++ if (is_input_yuv && !is_output_yuv) { ++ y2r_en = 1; ++ r2y_en = 0; ++ csc_mode = vop2_convert_csc_mode(input_csc); ++ } else if (!is_input_yuv && is_output_yuv) { ++ y2r_en = 0; ++ r2y_en = 1; ++ csc_mode = vop2_convert_csc_mode(output_csc); ++ } else { ++ y2r_en = 0; ++ r2y_en = 0; ++ csc_mode = 0; ++ } ++ ++ vop2_win_write(win, VOP2_WIN_Y2R_EN, y2r_en); ++ vop2_win_write(win, VOP2_WIN_R2Y_EN, r2y_en); ++ vop2_win_write(win, VOP2_WIN_CSC_MODE, csc_mode); ++} ++ ++static void vop2_crtc_enable_irq(struct vop2_video_port *vp, uint32_t irq) ++{ ++ struct vop2 *vop2 = vp->vop2; ++ ++ vop2_writel(vop2, RK3568_VP_INT_CLR(vp->id), irq << 16 | irq); ++ vop2_writel(vop2, RK3568_VP_INT_EN(vp->id), irq << 16 | irq); ++} ++ ++static void vop2_crtc_disable_irq(struct vop2_video_port *vp, uint32_t irq) ++{ ++ struct vop2 *vop2 = vp->vop2; ++ ++ vop2_writel(vop2, RK3568_VP_INT_EN(vp->id), irq << 16); ++} ++ ++static int vop2_core_clks_prepare_enable(struct vop2 *vop2) ++{ ++ int ret; ++ ++ ret = clk_prepare_enable(vop2->hclk); ++ if (ret < 0) { ++ drm_err(vop2->drm, "failed to enable hclk - %d\n", ret); ++ return ret; ++ } ++ ++ ret = clk_prepare_enable(vop2->aclk); ++ if (ret < 0) { ++ drm_err(vop2->drm, "failed to enable aclk - %d\n", ret); ++ goto err; ++ } ++ ++ return 0; ++err: ++ clk_disable_unprepare(vop2->hclk); ++ ++ return ret; ++} ++ ++static void vop2_enable(struct vop2 *vop2) ++{ ++ int ret; ++ uint32_t v; ++ ++ ret = pm_runtime_get_sync(vop2->dev); ++ if (ret < 0) { ++ drm_err(vop2->drm, "failed to get pm runtime: %d\n", ret); ++ return; ++ } ++ ++ ret = vop2_core_clks_prepare_enable(vop2); ++ if (ret) { ++ pm_runtime_put_sync(vop2->dev); ++ return; ++ } ++ ++ if (vop2->data->soc_id == 3566) ++ vop2_writel(vop2, RK3568_OTP_WIN_EN, 1); ++ ++ vop2_writel(vop2, RK3568_REG_CFG_DONE, RK3568_REG_CFG_DONE__GLB_CFG_DONE_EN); ++ ++ /* ++ * Disable auto gating, this is a workaround to ++ * avoid display image shift when a window enabled. ++ */ ++ v = vop2_readl(vop2, RK3568_SYS_AUTO_GATING_CTRL); ++ v &= ~RK3568_SYS_AUTO_GATING_CTRL__AUTO_GATING_EN; ++ vop2_writel(vop2, RK3568_SYS_AUTO_GATING_CTRL, v); ++ ++ vop2_writel(vop2, RK3568_SYS0_INT_CLR, ++ VOP2_INT_BUS_ERRPR << 16 | VOP2_INT_BUS_ERRPR); ++ vop2_writel(vop2, RK3568_SYS0_INT_EN, ++ VOP2_INT_BUS_ERRPR << 16 | VOP2_INT_BUS_ERRPR); ++ vop2_writel(vop2, RK3568_SYS1_INT_CLR, ++ VOP2_INT_BUS_ERRPR << 16 | VOP2_INT_BUS_ERRPR); ++ vop2_writel(vop2, RK3568_SYS1_INT_EN, ++ VOP2_INT_BUS_ERRPR << 16 | VOP2_INT_BUS_ERRPR); ++} ++ ++static void vop2_disable(struct vop2 *vop2) ++{ ++ pm_runtime_put_sync(vop2->dev); ++ ++ clk_disable_unprepare(vop2->aclk); ++ clk_disable_unprepare(vop2->hclk); ++} ++ ++static void vop2_crtc_atomic_disable(struct drm_crtc *crtc, ++ struct drm_atomic_state *state) ++{ ++ struct vop2_video_port *vp = to_vop2_video_port(crtc); ++ struct vop2 *vop2 = vp->vop2; ++ int ret; ++ ++ vop2_lock(vop2); ++ ++ drm_crtc_vblank_off(crtc); ++ ++ /* ++ * Vop standby will take effect at end of current frame, ++ * if dsp hold valid irq happen, it means standby complete. ++ * ++ * we must wait standby complete when we want to disable aclk, ++ * if not, memory bus maybe dead. ++ */ ++ reinit_completion(&vp->dsp_hold_completion); ++ ++ vop2_crtc_enable_irq(vp, VP_INT_DSP_HOLD_VALID); ++ spin_lock(&vop2->reg_lock); ++ ++ vop2_writel(vop2, RK3568_VP_DSP_CTRL, 1); ++ ++ spin_unlock(&vop2->reg_lock); ++ ++ ret = wait_for_completion_timeout(&vp->dsp_hold_completion, msecs_to_jiffies(50)); ++ if (!ret) ++ drm_info(vop2->drm, "wait for vp%d dsp_hold timeout\n", vp->id); ++ ++ vop2_crtc_disable_irq(vp, VP_INT_DSP_HOLD_VALID); ++ ++ clk_disable_unprepare(vp->dclk); ++ ++ vop2->enable_count--; ++ ++ if (!vop2->enable_count) ++ vop2_disable(vop2); ++ ++ vop2_unlock(vop2); ++ ++ if (crtc->state->event && !crtc->state->active) { ++ spin_lock_irq(&crtc->dev->event_lock); ++ drm_crtc_send_vblank_event(crtc, crtc->state->event); ++ spin_unlock_irq(&crtc->dev->event_lock); ++ ++ crtc->state->event = NULL; ++ } ++} ++ ++static int vop2_plane_atomic_check(struct drm_plane *plane, struct drm_atomic_state *astate) ++{ ++ struct drm_plane_state *pstate = drm_atomic_get_new_plane_state(astate, plane); ++ struct drm_framebuffer *fb = pstate->fb; ++ struct drm_crtc *crtc = pstate->crtc; ++ struct drm_crtc_state *cstate; ++ struct vop2_video_port *vp; ++ struct vop2 *vop2; ++ const struct vop2_data *vop2_data; ++ struct drm_rect *dest = &pstate->dst; ++ struct drm_rect *src = &pstate->src; ++ int min_scale = FRAC_16_16(1, 8); ++ int max_scale = FRAC_16_16(8, 1); ++ int format; ++ int ret; ++ ++ if (!crtc) ++ return 0; ++ ++ vp = to_vop2_video_port(crtc); ++ vop2 = vp->vop2; ++ vop2_data = vop2->data; ++ ++ cstate = drm_atomic_get_existing_crtc_state(pstate->state, crtc); ++ if (WARN_ON(!cstate)) ++ return -EINVAL; ++ ++ ret = drm_atomic_helper_check_plane_state(pstate, cstate, ++ min_scale, max_scale, ++ true, true); ++ if (ret) ++ return ret; ++ ++ if (!pstate->visible) ++ return 0; ++ ++ format = vop2_convert_format(fb->format->format); ++ if (format < 0) ++ return format; ++ ++ if (drm_rect_width(src) >> 16 < 4 || drm_rect_height(src) >> 16 < 4 || ++ drm_rect_width(dest) < 4 || drm_rect_width(dest) < 4) { ++ drm_err(vop2->drm, "Invalid size: %dx%d->%dx%d, min size is 4x4\n", ++ drm_rect_width(src) >> 16, drm_rect_height(src) >> 16, ++ drm_rect_width(dest), drm_rect_height(dest)); ++ pstate->visible = false; ++ return 0; ++ } ++ ++ if (drm_rect_width(src) >> 16 > vop2_data->max_input.width || ++ drm_rect_height(src) >> 16 > vop2_data->max_input.height) { ++ drm_err(vop2->drm, "Invalid source: %dx%d. max input: %dx%d\n", ++ drm_rect_width(src) >> 16, ++ drm_rect_height(src) >> 16, ++ vop2_data->max_input.width, ++ vop2_data->max_input.height); ++ return -EINVAL; ++ } ++ ++ /* ++ * Src.x1 can be odd when do clip, but yuv plane start point ++ * need align with 2 pixel. ++ */ ++ if (fb->format->is_yuv && ((pstate->src.x1 >> 16) % 2)) { ++ drm_err(vop2->drm, "Invalid Source: Yuv format not support odd xpos\n"); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static void vop2_plane_atomic_disable(struct drm_plane *plane, struct drm_atomic_state *state) ++{ ++ struct drm_plane_state *old_pstate = drm_atomic_get_old_plane_state(state, plane); ++ struct vop2_win *win = to_vop2_win(plane); ++ struct vop2 *vop2 = win->vop2; ++ ++ drm_dbg(vop2->drm, "%s disable\n", win->data->name); ++ ++ if (!old_pstate->crtc) ++ return; ++ ++ spin_lock(&vop2->reg_lock); ++ ++ vop2_win_disable(win); ++ vop2_win_write(win, VOP2_WIN_YUV_CLIP, 0); ++ ++ spin_unlock(&vop2->reg_lock); ++} ++ ++/* ++ * The color key is 10 bit, so all format should ++ * convert to 10 bit here. ++ */ ++static void vop2_plane_setup_color_key(struct drm_plane *plane, uint32_t color_key) ++{ ++ struct drm_plane_state *pstate = plane->state; ++ struct drm_framebuffer *fb = pstate->fb; ++ struct vop2_win *win = to_vop2_win(plane); ++ uint32_t color_key_en = 0; ++ uint32_t r = 0; ++ uint32_t g = 0; ++ uint32_t b = 0; ++ ++ if (!(color_key & VOP2_COLOR_KEY_MASK) || fb->format->is_yuv) { ++ vop2_win_write(win, VOP2_WIN_COLOR_KEY_EN, 0); ++ return; ++ } ++ ++ switch (fb->format->format) { ++ case DRM_FORMAT_RGB565: ++ case DRM_FORMAT_BGR565: ++ r = (color_key & 0xf800) >> 11; ++ g = (color_key & 0x7e0) >> 5; ++ b = (color_key & 0x1f); ++ r <<= 5; ++ g <<= 4; ++ b <<= 5; ++ color_key_en = 1; ++ break; ++ case DRM_FORMAT_XRGB8888: ++ case DRM_FORMAT_ARGB8888: ++ case DRM_FORMAT_XBGR8888: ++ case DRM_FORMAT_ABGR8888: ++ case DRM_FORMAT_RGB888: ++ case DRM_FORMAT_BGR888: ++ r = (color_key & 0xff0000) >> 16; ++ g = (color_key & 0xff00) >> 8; ++ b = (color_key & 0xff); ++ r <<= 2; ++ g <<= 2; ++ b <<= 2; ++ color_key_en = 1; ++ break; ++ } ++ ++ vop2_win_write(win, VOP2_WIN_COLOR_KEY_EN, color_key_en); ++ vop2_win_write(win, VOP2_WIN_COLOR_KEY, (r << 20) | (g << 10) | b); ++} ++ ++static void vop2_plane_atomic_update(struct drm_plane *plane, struct drm_atomic_state *state) ++{ ++ struct drm_plane_state *pstate = plane->state; ++ struct drm_crtc *crtc = pstate->crtc; ++ struct vop2_win *win = to_vop2_win(plane); ++ struct vop2_video_port *vp = to_vop2_video_port(crtc); ++ struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode; ++ struct vop2 *vop2 = win->vop2; ++ struct drm_framebuffer *fb = pstate->fb; ++ uint32_t bpp = fb->format->cpp[0] * 8; ++ uint32_t actual_w, actual_h, dsp_w, dsp_h; ++ uint32_t act_info, dsp_info; ++ uint32_t format; ++ uint32_t afbc_format; ++ uint32_t rb_swap; ++ uint32_t uv_swap; ++ struct drm_rect *src = &pstate->src; ++ struct drm_rect *dest = &pstate->dst; ++ uint32_t afbc_tile_num; ++ uint32_t afbc_half_block_en; ++ uint32_t transform_offset; ++ bool dither_up; ++ bool xmirror = pstate->rotation & DRM_MODE_REFLECT_X; ++ bool ymirror = pstate->rotation & DRM_MODE_REFLECT_Y; ++ bool rotate_270 = pstate->rotation & DRM_MODE_ROTATE_270; ++ bool rotate_90 = pstate->rotation & DRM_MODE_ROTATE_90; ++ struct rockchip_gem_object *rk_obj; ++ unsigned long offset; ++ bool afbc_en; ++ dma_addr_t yrgb_mst; ++ dma_addr_t uv_mst; ++ ++ /* ++ * can't update plane when vop2 is disabled. ++ */ ++ if (WARN_ON(!crtc)) ++ return; ++ ++ if (!pstate->visible) { ++ vop2_plane_atomic_disable(plane, state); ++ return; ++ } ++ ++ afbc_en = rockchip_afbc(plane, fb->modifier); ++ ++ offset = (src->x1 >> 16) * fb->format->cpp[0]; ++ ++ /* ++ * AFBC HDR_PTR must set to the zero offset of the framebuffer. ++ */ ++ if (afbc_en) ++ offset = 0; ++ else if (pstate->rotation & DRM_MODE_REFLECT_Y) ++ offset += ((src->y2 >> 16) - 1) * fb->pitches[0]; ++ else ++ offset += (src->y1 >> 16) * fb->pitches[0]; ++ ++ rk_obj = to_rockchip_obj(fb->obj[0]); ++ ++ yrgb_mst = rk_obj->dma_addr + offset + fb->offsets[0]; ++ if (fb->format->is_yuv) { ++ int hsub = fb->format->hsub; ++ int vsub = fb->format->vsub; ++ ++ offset = (src->x1 >> 16) * fb->format->cpp[1] / hsub; ++ offset += (src->y1 >> 16) * fb->pitches[1] / vsub; ++ ++ if ((pstate->rotation & DRM_MODE_REFLECT_Y) && !afbc_en) ++ offset += fb->pitches[1] * ((pstate->src_h >> 16) - 2) / vsub; ++ ++ rk_obj = to_rockchip_obj(fb->obj[0]); ++ uv_mst = rk_obj->dma_addr + offset + fb->offsets[1]; ++ } ++ ++ actual_w = drm_rect_width(src) >> 16; ++ actual_h = drm_rect_height(src) >> 16; ++ dsp_w = drm_rect_width(dest); ++ ++ if (dest->x1 + dsp_w > adjusted_mode->hdisplay) { ++ drm_err(vop2->drm, "vp%d %s dest->x1[%d] + dsp_w[%d] exceed mode hdisplay[%d]\n", ++ vp->id, win->data->name, dest->x1, dsp_w, adjusted_mode->hdisplay); ++ dsp_w = adjusted_mode->hdisplay - dest->x1; ++ if (dsp_w < 4) ++ dsp_w = 4; ++ actual_w = dsp_w * actual_w / drm_rect_width(dest); ++ } ++ ++ dsp_h = drm_rect_height(dest); ++ ++ if (dest->y1 + dsp_h > adjusted_mode->vdisplay) { ++ drm_err(vop2->drm, "vp%d %s dest->y1[%d] + dsp_h[%d] exceed mode vdisplay[%d]\n", ++ vp->id, win->data->name, dest->y1, dsp_h, adjusted_mode->vdisplay); ++ dsp_h = adjusted_mode->vdisplay - dest->y1; ++ if (dsp_h < 4) ++ dsp_h = 4; ++ actual_h = dsp_h * actual_h / drm_rect_height(dest); ++ } ++ ++ /* ++ * This is workaround solution for IC design: ++ * esmart can't support scale down when actual_w % 16 == 1. ++ */ ++ if (!(win->data->feature & WIN_FEATURE_AFBDC)) { ++ if (actual_w > dsp_w && (actual_w & 0xf) == 1) { ++ drm_err(vop2->drm, "vp%d %s act_w[%d] MODE 16 == 1\n", vp->id, win->data->name, actual_w); ++ actual_w -= 1; ++ } ++ } ++ ++ if (afbc_en && actual_w % 4) { ++ drm_err(vop2->drm, "vp%d %s actual_w[%d] should align as 4 pixel when enable afbc\n", ++ vp->id, win->data->name, actual_w); ++ actual_w = ALIGN_DOWN(actual_w, 4); ++ } ++ ++ act_info = (actual_h - 1) << 16 | ((actual_w - 1) & 0xffff); ++ dsp_info = (dsp_h - 1) << 16 | ((dsp_w - 1) & 0xffff); ++ ++ format = vop2_convert_format(fb->format->format); ++ ++ spin_lock(&vop2->reg_lock); ++ drm_dbg(vop2->drm, "vp%d update %s[%dx%d->%dx%d@%dx%d] fmt[%p4cc_%s] addr[%pad]\n", ++ vp->id, win->data->name, actual_w, actual_h, dsp_w, dsp_h, ++ dest->x1, dest->y1, ++ &fb->format->format, ++ afbc_en ? "AFBC" : "", &yrgb_mst); ++ ++ if (afbc_en) { ++ uint32_t stride; ++ ++ /* the afbc superblock is 16 x 16 */ ++ afbc_format = vop2_convert_afbc_format(fb->format->format); ++ ++ /* Enable color transform for YTR */ ++ if (fb->modifier & AFBC_FORMAT_MOD_YTR) ++ afbc_format |= (1 << 4); ++ ++ afbc_tile_num = ALIGN(actual_w, 16) >> 4; ++ ++ /* ++ * AFBC pic_vir_width is count by pixel, this is different ++ * with WIN_VIR_STRIDE. ++ */ ++ stride = (fb->pitches[0] << 3) / bpp; ++ if ((stride & 0x3f) && (xmirror || rotate_90 || rotate_270)) ++ drm_err(vop2->drm, "vp%d %s stride[%d] must align as 64 pixel when enable xmirror/rotate_90/rotate_270[0x%x]\n", ++ vp->id, win->data->name, stride, pstate->rotation); ++ ++ rb_swap = vop2_afbc_rb_swap(fb->format->format); ++ uv_swap = vop2_afbc_uv_swap(fb->format->format); ++ /* ++ * This is a workaround for crazy IC design, Cluster ++ * and Esmart/Smart use different format configuration map: ++ * YUV420_10BIT: 0x10 for Cluster, 0x14 for Esmart/Smart. ++ * ++ * This is one thing we can make the convert simple: ++ * AFBCD decode all the YUV data to YUV444. So we just ++ * set all the yuv 10 bit to YUV444_10. ++ */ ++ if (fb->format->is_yuv && (bpp == 10)) ++ format = VOP2_CLUSTER_YUV444_10; ++ ++ afbc_half_block_en = vop2_afbc_half_block_enable(pstate); ++ transform_offset = vop2_afbc_transform_offset(pstate, afbc_half_block_en); ++ if (vop2_cluster_window(win)) ++ vop2_win_write(win, VOP2_WIN_AFBC_ENABLE, 1); ++ vop2_win_write(win, VOP2_WIN_AFBC_FORMAT, afbc_format); ++ vop2_win_write(win, VOP2_WIN_AFBC_RB_SWAP, rb_swap); ++ vop2_win_write(win, VOP2_WIN_AFBC_UV_SWAP, uv_swap); ++ vop2_win_write(win, VOP2_WIN_AFBC_AUTO_GATING_EN, 0); ++ vop2_win_write(win, VOP2_WIN_AFBC_BLOCK_SPLIT_EN, 0); ++ vop2_win_write(win, VOP2_WIN_AFBC_HALF_BLOCK_EN, afbc_half_block_en); ++ vop2_win_write(win, VOP2_WIN_AFBC_HDR_PTR, yrgb_mst); ++ vop2_win_write(win, VOP2_WIN_AFBC_PIC_SIZE, act_info); ++ vop2_win_write(win, VOP2_WIN_AFBC_TRANSFORM_OFFSET, transform_offset); ++ vop2_win_write(win, VOP2_WIN_AFBC_PIC_OFFSET, ((src->x1 >> 16) | src->y1)); ++ vop2_win_write(win, VOP2_WIN_AFBC_DSP_OFFSET, (dest->x1 | (dest->y1 << 16))); ++ vop2_win_write(win, VOP2_WIN_AFBC_PIC_VIR_WIDTH, stride); ++ vop2_win_write(win, VOP2_WIN_AFBC_TILE_NUM, afbc_tile_num); ++ vop2_win_write(win, VOP2_WIN_XMIRROR, xmirror); ++ vop2_win_write(win, VOP2_WIN_AFBC_ROTATE_270, rotate_270); ++ vop2_win_write(win, VOP2_WIN_AFBC_ROTATE_90, rotate_90); ++ } else { ++ vop2_win_write(win, VOP2_WIN_YRGB_VIR, DIV_ROUND_UP(fb->pitches[0], 4)); ++ } ++ ++ vop2_win_write(win, VOP2_WIN_YMIRROR, ymirror); ++ ++ if (rotate_90 || rotate_270) { ++ act_info = swahw32(act_info); ++ actual_w = drm_rect_height(src) >> 16; ++ actual_h = drm_rect_width(src) >> 16; ++ } ++ ++ vop2_win_write(win, VOP2_WIN_FORMAT, format); ++ vop2_win_write(win, VOP2_WIN_YRGB_MST, yrgb_mst); ++ ++ rb_swap = vop2_win_rb_swap(fb->format->format); ++ vop2_win_write(win, VOP2_WIN_RB_SWAP, rb_swap); ++ if (!vop2_cluster_window(win)) { ++ uv_swap = vop2_win_uv_swap(fb->format->format); ++ vop2_win_write(win, VOP2_WIN_UV_SWAP, uv_swap); ++ } ++ ++ if (fb->format->is_yuv) { ++ vop2_win_write(win, VOP2_WIN_UV_VIR, DIV_ROUND_UP(fb->pitches[1], 4)); ++ vop2_win_write(win, VOP2_WIN_UV_MST, uv_mst); ++ } ++ ++ vop2_setup_scale(vop2, win, actual_w, actual_h, dsp_w, dsp_h, fb->format->format); ++ if (!vop2_cluster_window(win)) ++ vop2_plane_setup_color_key(plane, 0); ++ vop2_win_write(win, VOP2_WIN_ACT_INFO, act_info); ++ vop2_win_write(win, VOP2_WIN_DSP_INFO, dsp_info); ++ vop2_win_write(win, VOP2_WIN_DSP_ST, dest->y1 << 16 | (dest->x1 & 0xffff)); ++ ++ vop2_setup_csc_mode(vp, win, pstate); ++ ++ dither_up = vop2_win_dither_up(fb->format->format); ++ vop2_win_write(win, VOP2_WIN_DITHER_UP, dither_up); ++ ++ vop2_win_write(win, VOP2_WIN_ENABLE, 1); ++ ++ if (vop2_cluster_window(win)) { ++ int lb_mode = vop2_get_cluster_lb_mode(win, pstate); ++ ++ vop2_win_write(win, VOP2_WIN_CLUSTER_LB_MODE, lb_mode); ++ vop2_win_write(win, VOP2_WIN_CLUSTER_ENABLE, 1); ++ } ++ ++ spin_unlock(&vop2->reg_lock); ++} ++ ++static const struct drm_plane_helper_funcs vop2_plane_helper_funcs = { ++ .atomic_check = vop2_plane_atomic_check, ++ .atomic_update = vop2_plane_atomic_update, ++ .atomic_disable = vop2_plane_atomic_disable, ++}; ++ ++static const struct drm_plane_funcs vop2_plane_funcs = { ++ .update_plane = drm_atomic_helper_update_plane, ++ .disable_plane = drm_atomic_helper_disable_plane, ++ .destroy = drm_plane_cleanup, ++ .reset = drm_atomic_helper_plane_reset, ++ .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, ++ .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, ++ .format_mod_supported = rockchip_vop2_mod_supported, ++}; ++ ++static int vop2_crtc_enable_vblank(struct drm_crtc *crtc) ++{ ++ struct vop2_video_port *vp = to_vop2_video_port(crtc); ++ ++ vop2_crtc_enable_irq(vp, VP_INT_FS_FIELD); ++ ++ return 0; ++} ++ ++static void vop2_crtc_disable_vblank(struct drm_crtc *crtc) ++{ ++ struct vop2_video_port *vp = to_vop2_video_port(crtc); ++ ++ vop2_crtc_disable_irq(vp, VP_INT_FS_FIELD); ++} ++ ++static bool vop2_crtc_mode_fixup(struct drm_crtc *crtc, ++ const struct drm_display_mode *mode, ++ struct drm_display_mode *adj_mode) ++{ ++ drm_mode_set_crtcinfo(adj_mode, CRTC_INTERLACE_HALVE_V | CRTC_STEREO_DOUBLE); ++ ++ return true; ++} ++ ++static void vop2_dither_setup(struct drm_crtc *crtc, uint32_t *dsp_ctrl) ++{ ++ struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state); ++ ++ switch (vcstate->bus_format) { ++ case MEDIA_BUS_FMT_RGB565_1X16: ++ *dsp_ctrl |= RK3568_VP_DSP_CTRL__DITHER_DOWN_EN; ++ break; ++ case MEDIA_BUS_FMT_RGB666_1X18: ++ case MEDIA_BUS_FMT_RGB666_1X24_CPADHI: ++ case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG: ++ *dsp_ctrl |= RK3568_VP_DSP_CTRL__DITHER_DOWN_EN; ++ *dsp_ctrl |= RGB888_TO_RGB666; ++ break; ++ case MEDIA_BUS_FMT_YUV8_1X24: ++ case MEDIA_BUS_FMT_UYYVYY8_0_5X24: ++ *dsp_ctrl |= RK3568_VP_DSP_CTRL__PRE_DITHER_DOWN_EN; ++ break; ++ default: ++ break; ++ } ++ ++ if (vcstate->output_mode != ROCKCHIP_OUT_MODE_AAAA) ++ *dsp_ctrl |= RK3568_VP_DSP_CTRL__PRE_DITHER_DOWN_EN; ++ ++ *dsp_ctrl |= FIELD_PREP(RK3568_VP_DSP_CTRL__DITHER_DOWN_SEL, ++ DITHER_DOWN_ALLEGRO); ++} ++ ++static void vop2_post_config(struct drm_crtc *crtc) ++{ ++ struct vop2_video_port *vp = to_vop2_video_port(crtc); ++ struct vop2 *vop2 = vp->vop2; ++ struct drm_display_mode *mode = &crtc->state->adjusted_mode; ++ uint16_t vtotal = mode->crtc_vtotal; ++ uint16_t hdisplay = mode->crtc_hdisplay; ++ uint16_t hact_st = mode->crtc_htotal - mode->crtc_hsync_start; ++ uint16_t vdisplay = mode->crtc_vdisplay; ++ uint16_t vact_st = mode->crtc_vtotal - mode->crtc_vsync_start; ++ uint32_t left_margin = 100, right_margin = 100, top_margin = 100, bottom_margin = 100; ++ uint16_t hsize = hdisplay * (left_margin + right_margin) / 200; ++ uint16_t vsize = vdisplay * (top_margin + bottom_margin) / 200; ++ uint16_t hact_end, vact_end; ++ uint32_t val; ++ ++ vsize = rounddown(vsize, 2); ++ hsize = rounddown(hsize, 2); ++ hact_st += hdisplay * (100 - left_margin) / 200; ++ hact_end = hact_st + hsize; ++ val = hact_st << 16; ++ val |= hact_end; ++ vop2_vp_write(vp, RK3568_VP_POST_DSP_HACT_INFO, val); ++ vact_st += vdisplay * (100 - top_margin) / 200; ++ vact_end = vact_st + vsize; ++ val = vact_st << 16; ++ val |= vact_end; ++ vop2_vp_write(vp, RK3568_VP_POST_DSP_VACT_INFO, val); ++ val = scl_cal_scale2(vdisplay, vsize) << 16; ++ val |= scl_cal_scale2(hdisplay, hsize); ++ vop2_vp_write(vp, RK3568_VP_POST_SCL_FACTOR_YRGB, val); ++ ++ val = 0; ++ if (hdisplay != hsize) ++ val |= RK3568_VP_POST_SCL_CTRL__HSCALEDOWN; ++ if (vdisplay != vsize) ++ val |= RK3568_VP_POST_SCL_CTRL__VSCALEDOWN; ++ vop2_writel(vop2, RK3568_VP_POST_SCL_CTRL, val); ++ ++ if (mode->flags & DRM_MODE_FLAG_INTERLACE) { ++ uint16_t vact_st_f1 = vtotal + vact_st + 1; ++ uint16_t vact_end_f1 = vact_st_f1 + vsize; ++ ++ val = vact_st_f1 << 16 | vact_end_f1; ++ vop2_vp_write(vp, RK3568_VP_POST_DSP_VACT_INFO_F1, val); ++ } ++ ++ vop2_vp_write(vp, RK3568_VP_DSP_BG, 0); ++} ++ ++static void rk3568_set_intf_mux(struct vop2_video_port *vp, int id, ++ uint32_t polflags) ++{ ++ struct vop2 *vop2 = vp->vop2; ++ uint32_t die, dip; ++ ++ die = vop2_readl(vop2, RK3568_DSP_IF_EN); ++ dip = vop2_readl(vop2, RK3568_DSP_IF_POL); ++ ++ switch (id) { ++ case RK3568_VOP2_EP_RGB: ++ die &= ~RK3568_SYS_DSP_INFACE_EN_RGB_MUX; ++ die |= RK3568_SYS_DSP_INFACE_EN_RGB | ++ FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_RGB_MUX, vp->id); ++ if (polflags & POLFLAG_DCLK_INV) ++ regmap_write(vop2->grf, RK3568_GRF_VO_CON1, BIT(3 + 16) | BIT(3)); ++ else ++ regmap_write(vop2->grf, RK3568_GRF_VO_CON1, BIT(3 + 16)); ++ break; ++ case RK3568_VOP2_EP_HDMI: ++ die &= ~RK3568_SYS_DSP_INFACE_EN_HDMI_MUX; ++ die |= RK3568_SYS_DSP_INFACE_EN_HDMI | ++ FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_HDMI_MUX, vp->id); ++ break; ++ case RK3568_VOP2_EP_EDP: ++ die &= ~RK3568_SYS_DSP_INFACE_EN_EDP_MUX; ++ die |= RK3568_SYS_DSP_INFACE_EN_EDP | ++ FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_EDP_MUX, vp->id); ++ break; ++ case RK3568_VOP2_EP_MIPI0: ++ die &= ~RK3568_SYS_DSP_INFACE_EN_MIPI0_MUX; ++ die |= RK3568_SYS_DSP_INFACE_EN_MIPI0 | ++ FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_MIPI0_MUX, vp->id); ++ dip &= ~RK3568_DSP_IF_POL__MIPI_PIN_POL; ++ dip |= FIELD_PREP(RK3568_DSP_IF_POL__MIPI_PIN_POL, polflags); ++ break; ++ case RK3568_VOP2_EP_MIPI1: ++ die &= ~RK3568_SYS_DSP_INFACE_EN_MIPI1_MUX; ++ die |= RK3568_SYS_DSP_INFACE_EN_MIPI1 | ++ FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_MIPI1_MUX, vp->id); ++ dip &= ~RK3568_DSP_IF_POL__MIPI_PIN_POL; ++ dip |= FIELD_PREP(RK3568_DSP_IF_POL__MIPI_PIN_POL, polflags); ++ break; ++ case RK3568_VOP2_EP_LVDS0: ++ die &= ~RK3568_SYS_DSP_INFACE_EN_LVDS0_MUX; ++ die |= RK3568_SYS_DSP_INFACE_EN_LVDS0 | ++ FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_LVDS0_MUX, vp->id); ++ dip &= ~RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL; ++ dip |= FIELD_PREP(RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL, polflags); ++ break; ++ case RK3568_VOP2_EP_LVDS1: ++ die &= ~RK3568_SYS_DSP_INFACE_EN_LVDS1_MUX; ++ die |= RK3568_SYS_DSP_INFACE_EN_LVDS1 | ++ FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_LVDS1_MUX, vp->id); ++ dip &= ~RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL; ++ dip |= FIELD_PREP(RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL, polflags); ++ break; ++ default: ++ return; ++ }; ++ ++ dip |= RK3568_DSP_IF_POL__CFG_DONE_IMD; ++ ++ vop2_writel(vop2, RK3568_DSP_IF_EN, die); ++ vop2_writel(vop2, RK3568_DSP_IF_POL, dip); ++} ++ ++static int us_to_vertical_line(struct drm_display_mode *mode, int us) ++{ ++ return us * mode->clock / mode->htotal / 1000; ++} ++ ++static void vop2_crtc_atomic_enable(struct drm_crtc *crtc, struct drm_atomic_state *state) ++{ ++ struct vop2_video_port *vp = to_vop2_video_port(crtc); ++ struct vop2 *vop2 = vp->vop2; ++ const struct vop2_data *vop2_data = vop2->data; ++ const struct vop2_video_port_data *vp_data = &vop2_data->vp[vp->id]; ++ struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc); ++ struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state); ++ struct drm_display_mode *mode = &crtc->state->adjusted_mode; ++ unsigned long clock = mode->crtc_clock * 1000; ++ uint16_t hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start; ++ uint16_t hdisplay = mode->crtc_hdisplay; ++ uint16_t htotal = mode->crtc_htotal; ++ uint16_t hact_st = mode->crtc_htotal - mode->crtc_hsync_start; ++ uint16_t hact_end = hact_st + hdisplay; ++ uint16_t vdisplay = mode->crtc_vdisplay; ++ uint16_t vtotal = mode->crtc_vtotal; ++ uint16_t vsync_len = mode->crtc_vsync_end - mode->crtc_vsync_start; ++ uint16_t vact_st = mode->crtc_vtotal - mode->crtc_vsync_start; ++ uint16_t vact_end = vact_st + vdisplay; ++ uint8_t out_mode; ++ uint32_t dsp_ctrl = 0; ++ int act_end; ++ uint32_t val, polflags; ++ int ret; ++ struct drm_encoder *encoder; ++ ++ drm_dbg(vop2->drm, "Update mode to %dx%d%s%d, type: %d for vp%d\n", ++ hdisplay, vdisplay, mode->flags & DRM_MODE_FLAG_INTERLACE ? "i" : "p", ++ drm_mode_vrefresh(mode), vcstate->output_type, vp->id); ++ ++ vop2_lock(vop2); ++ ++ ret = clk_prepare_enable(vp->dclk); ++ if (ret < 0) { ++ drm_err(vop2->drm, "failed to enable dclk for video port%d - %d\n", ++ vp->id, ret); ++ return; ++ } ++ ++ if (!vop2->enable_count) ++ vop2_enable(vop2); ++ ++ vop2->enable_count++; ++ ++ vop2_crtc_enable_irq(vp, VP_INT_POST_BUF_EMPTY); ++ ++ polflags = 0; ++ if (vcstate->bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE) ++ polflags |= POLFLAG_DCLK_INV; ++ if (mode->flags & DRM_MODE_FLAG_PHSYNC) ++ polflags |= BIT(HSYNC_POSITIVE); ++ if (mode->flags & DRM_MODE_FLAG_PVSYNC) ++ polflags |= BIT(VSYNC_POSITIVE); ++ ++ drm_for_each_encoder_mask(encoder, crtc->dev, crtc_state->encoder_mask) { ++ struct device_node *node, *parent; ++ ++ parent = of_get_parent(encoder->port); ++ ++ for_each_endpoint_of_node(parent, node) { ++ struct device_node *crtc_port = of_graph_get_remote_port(node); ++ struct device_node *epn; ++ struct of_endpoint endpoint; ++ ++ if (crtc->port != crtc_port) { ++ of_node_put(crtc_port); ++ continue; ++ } ++ ++ of_node_put(crtc_port); ++ ++ epn = of_graph_get_remote_endpoint(node); ++ of_graph_parse_endpoint(epn, &endpoint); ++ of_node_put(epn); ++ ++ drm_dbg(vop2->drm, "vp%d is connected to %s, id %d\n", ++ vp->id, encoder->name, endpoint.id); ++ rk3568_set_intf_mux(vp, endpoint.id, polflags); ++ } ++ of_node_put(parent); ++ } ++ ++ if (vcstate->output_mode == ROCKCHIP_OUT_MODE_AAAA && ++ !(vp_data->feature & VOP_FEATURE_OUTPUT_10BIT)) ++ out_mode = ROCKCHIP_OUT_MODE_P888; ++ else ++ out_mode = vcstate->output_mode; ++ ++ dsp_ctrl |= FIELD_PREP(RK3568_VP_DSP_CTRL__OUT_MODE, out_mode); ++ ++ if (vop2_output_uv_swap(vcstate->bus_format, vcstate->output_mode)) ++ dsp_ctrl |= RK3568_VP_DSP_CTRL__DSP_RB_SWAP; ++ ++ if (is_yuv_output(vcstate->bus_format)) ++ dsp_ctrl |= RK3568_VP_DSP_CTRL__POST_DSP_OUT_R2Y; ++ ++ vop2_dither_setup(crtc, &dsp_ctrl); ++ ++ vop2_vp_write(vp, RK3568_VP_DSP_HTOTAL_HS_END, (htotal << 16) | hsync_len); ++ val = hact_st << 16; ++ val |= hact_end; ++ vop2_vp_write(vp, RK3568_VP_DSP_HACT_ST_END, val); ++ ++ val = vact_st << 16; ++ val |= vact_end; ++ vop2_vp_write(vp, RK3568_VP_DSP_VACT_ST_END, val); ++ ++ if (mode->flags & DRM_MODE_FLAG_INTERLACE) { ++ uint16_t vact_st_f1 = vtotal + vact_st + 1; ++ uint16_t vact_end_f1 = vact_st_f1 + vdisplay; ++ ++ val = vact_st_f1 << 16 | vact_end_f1; ++ vop2_vp_write(vp, RK3568_VP_DSP_VACT_ST_END_F1, val); ++ ++ val = vtotal << 16 | (vtotal + vsync_len); ++ vop2_vp_write(vp, RK3568_VP_DSP_VS_ST_END_F1, val); ++ dsp_ctrl |= RK3568_VP_DSP_CTRL__DSP_INTERLACE; ++ dsp_ctrl |= RK3568_VP_DSP_CTRL__DSP_FILED_POL; ++ dsp_ctrl |= RK3568_VP_DSP_CTRL__P2I_EN; ++ vtotal += vtotal + 1; ++ act_end = vact_end_f1; ++ } else { ++ act_end = vact_end; ++ } ++ ++ vop2_writel(vop2, RK3568_VP_LINE_FLAG(vp->id), ++ (act_end - us_to_vertical_line(mode, 0)) << 16 | act_end); ++ ++ vop2_vp_write(vp, RK3568_VP_DSP_VTOTAL_VS_END, vtotal << 16 | vsync_len); ++ ++ if (mode->flags & DRM_MODE_FLAG_DBLCLK) { ++ dsp_ctrl |= RK3568_VP_DSP_CTRL__CORE_DCLK_DIV; ++ clock *= 2; ++ } ++ ++ vop2_vp_write(vp, RK3568_VP_MIPI_CTRL, 0); ++ ++ clk_set_rate(vp->dclk, clock); ++ ++ vop2_post_config(crtc); ++ ++ vop2_cfg_done(vp); ++ ++ vop2_vp_write(vp, RK3568_VP_DSP_CTRL, dsp_ctrl); ++ ++ drm_crtc_vblank_on(crtc); ++ ++ vop2_unlock(vop2); ++} ++ ++static int vop2_crtc_atomic_check(struct drm_crtc *crtc, ++ struct drm_atomic_state *state) ++{ ++ struct vop2_video_port *vp = to_vop2_video_port(crtc); ++ struct drm_plane *plane; ++ int nplanes = 0; ++ struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc); ++ ++ drm_atomic_crtc_state_for_each_plane(plane, crtc_state) ++ nplanes++; ++ ++ if (nplanes > vp->nlayers) ++ return -EINVAL; ++ ++ return 0; ++} ++ ++static bool is_opaque(uint16_t alpha) ++{ ++ return (alpha >> 8) == 0xff; ++} ++ ++static void vop2_parse_alpha(struct vop2_alpha_config *alpha_config, ++ struct vop2_alpha *alpha) ++{ ++ int src_glb_alpha_en = is_opaque(alpha_config->src_glb_alpha_value) ? 0 : 1; ++ int dst_glb_alpha_en = is_opaque(alpha_config->dst_glb_alpha_value) ? 0 : 1; ++ int src_color_mode = alpha_config->src_premulti_en ? ALPHA_SRC_PRE_MUL : ALPHA_SRC_NO_PRE_MUL; ++ int dst_color_mode = alpha_config->dst_premulti_en ? ALPHA_SRC_PRE_MUL : ALPHA_SRC_NO_PRE_MUL; ++ ++ alpha->src_color_ctrl.val = 0; ++ alpha->dst_color_ctrl.val = 0; ++ alpha->src_alpha_ctrl.val = 0; ++ alpha->dst_alpha_ctrl.val = 0; ++ ++ if (!alpha_config->src_pixel_alpha_en) ++ alpha->src_color_ctrl.bits.blend_mode = ALPHA_GLOBAL; ++ else if (alpha_config->src_pixel_alpha_en && !src_glb_alpha_en) ++ alpha->src_color_ctrl.bits.blend_mode = ALPHA_PER_PIX; ++ else ++ alpha->src_color_ctrl.bits.blend_mode = ALPHA_PER_PIX_GLOBAL; ++ ++ alpha->src_color_ctrl.bits.alpha_en = 1; ++ ++ if (alpha->src_color_ctrl.bits.blend_mode == ALPHA_GLOBAL) { ++ alpha->src_color_ctrl.bits.color_mode = src_color_mode; ++ alpha->src_color_ctrl.bits.factor_mode = SRC_FAC_ALPHA_SRC_GLOBAL; ++ } else if (alpha->src_color_ctrl.bits.blend_mode == ALPHA_PER_PIX) { ++ alpha->src_color_ctrl.bits.color_mode = src_color_mode; ++ alpha->src_color_ctrl.bits.factor_mode = SRC_FAC_ALPHA_ONE; ++ } else { ++ alpha->src_color_ctrl.bits.color_mode = ALPHA_SRC_PRE_MUL; ++ alpha->src_color_ctrl.bits.factor_mode = SRC_FAC_ALPHA_SRC_GLOBAL; ++ } ++ alpha->src_color_ctrl.bits.glb_alpha = alpha_config->src_glb_alpha_value >> 8; ++ alpha->src_color_ctrl.bits.alpha_mode = ALPHA_STRAIGHT; ++ alpha->src_color_ctrl.bits.alpha_cal_mode = ALPHA_SATURATION; ++ ++ alpha->dst_color_ctrl.bits.alpha_mode = ALPHA_STRAIGHT; ++ alpha->dst_color_ctrl.bits.alpha_cal_mode = ALPHA_SATURATION; ++ alpha->dst_color_ctrl.bits.blend_mode = ALPHA_GLOBAL; ++ alpha->dst_color_ctrl.bits.glb_alpha = alpha_config->dst_glb_alpha_value >> 8; ++ alpha->dst_color_ctrl.bits.color_mode = dst_color_mode; ++ alpha->dst_color_ctrl.bits.factor_mode = ALPHA_SRC_INVERSE; ++ ++ alpha->src_alpha_ctrl.bits.alpha_mode = ALPHA_STRAIGHT; ++ alpha->src_alpha_ctrl.bits.blend_mode = alpha->src_color_ctrl.bits.blend_mode; ++ alpha->src_alpha_ctrl.bits.alpha_cal_mode = ALPHA_SATURATION; ++ alpha->src_alpha_ctrl.bits.factor_mode = ALPHA_ONE; ++ ++ alpha->dst_alpha_ctrl.bits.alpha_mode = ALPHA_STRAIGHT; ++ if (alpha_config->dst_pixel_alpha_en && !dst_glb_alpha_en) ++ alpha->dst_alpha_ctrl.bits.blend_mode = ALPHA_PER_PIX; ++ else ++ alpha->dst_alpha_ctrl.bits.blend_mode = ALPHA_PER_PIX_GLOBAL; ++ alpha->dst_alpha_ctrl.bits.alpha_cal_mode = ALPHA_NO_SATURATION; ++ alpha->dst_alpha_ctrl.bits.factor_mode = ALPHA_SRC_INVERSE; ++} ++ ++static int vop2_find_start_mixer_id_for_vp(struct vop2 *vop2, uint8_t port_id) ++{ ++ struct vop2_video_port *vp; ++ int used_layer = 0; ++ int i; ++ ++ for (i = 0; i < port_id; i++) { ++ vp = &vop2->vps[i]; ++ used_layer += hweight32(vp->win_mask); ++ } ++ ++ return used_layer; ++} ++ ++static void vop2_setup_cluster_alpha(struct vop2 *vop2, struct vop2_win *main_win) ++{ ++ uint32_t offset = (main_win->data->phys_id * 0x10); ++ struct vop2_alpha_config alpha_config; ++ struct vop2_alpha alpha; ++ struct drm_plane_state *bottom_win_pstate; ++ bool src_pixel_alpha_en = false; ++ uint16_t src_glb_alpha_val, dst_glb_alpha_val; ++ bool premulti_en = false; ++ bool swap = false; ++ ++ /* At one win mode, win0 is dst/bottom win, and win1 is a all zero src/top win */ ++ bottom_win_pstate = main_win->base.state; ++ src_glb_alpha_val = 0; ++ dst_glb_alpha_val = main_win->base.state->alpha; ++ ++ if (!bottom_win_pstate->fb) ++ return; ++ ++ alpha_config.src_premulti_en = premulti_en; ++ alpha_config.dst_premulti_en = false; ++ alpha_config.src_pixel_alpha_en = src_pixel_alpha_en; ++ alpha_config.dst_pixel_alpha_en = true; /* alpha value need transfer to next mix */ ++ alpha_config.src_glb_alpha_value = src_glb_alpha_val; ++ alpha_config.dst_glb_alpha_value = dst_glb_alpha_val; ++ vop2_parse_alpha(&alpha_config, &alpha); ++ ++ alpha.src_color_ctrl.bits.src_dst_swap = swap; ++ vop2_writel(vop2, RK3568_CLUSTER0_MIX_SRC_COLOR_CTRL + offset, ++ alpha.src_color_ctrl.val); ++ vop2_writel(vop2, RK3568_CLUSTER0_MIX_DST_COLOR_CTRL + offset, ++ alpha.dst_color_ctrl.val); ++ vop2_writel(vop2, RK3568_CLUSTER0_MIX_SRC_ALPHA_CTRL + offset, ++ alpha.src_alpha_ctrl.val); ++ vop2_writel(vop2, RK3568_CLUSTER0_MIX_DST_ALPHA_CTRL + offset, ++ alpha.dst_alpha_ctrl.val); ++} ++ ++static void vop2_setup_alpha(struct vop2_video_port *vp) ++{ ++ struct vop2 *vop2 = vp->vop2; ++ struct drm_framebuffer *fb; ++ struct vop2_alpha_config alpha_config; ++ struct vop2_alpha alpha; ++ struct drm_plane *plane; ++ int pixel_alpha_en; ++ int premulti_en, gpremulti_en = 0; ++ int mixer_id; ++ uint32_t offset; ++ bool bottom_layer_alpha_en = false; ++ uint32_t dst_global_alpha = DRM_BLEND_ALPHA_OPAQUE; ++ ++ mixer_id = vop2_find_start_mixer_id_for_vp(vop2, vp->id); ++ alpha_config.dst_pixel_alpha_en = true; /* alpha value need transfer to next mix */ ++ ++ drm_atomic_crtc_for_each_plane(plane, &vp->crtc) { ++ struct vop2_win *win = to_vop2_win(plane); ++ ++ if (plane->state->normalized_zpos == 0 && ++ !is_opaque(plane->state->alpha) && ++ !vop2_cluster_window(win)) { ++ /* ++ * If bottom layer have global alpha effect [except cluster layer, ++ * because cluster have deal with bottom layer global alpha value ++ * at cluster mix], bottom layer mix need deal with global alpha. ++ */ ++ bottom_layer_alpha_en = true; ++ dst_global_alpha = plane->state->alpha; ++ } ++ } ++ ++ drm_atomic_crtc_for_each_plane(plane, &vp->crtc) { ++ struct vop2_win *win = to_vop2_win(plane); ++ int zpos = plane->state->normalized_zpos; ++ ++ if (plane->state->pixel_blend_mode == DRM_MODE_BLEND_PREMULTI) ++ premulti_en = 1; ++ else ++ premulti_en = 0; ++ ++ plane = &win->base; ++ fb = plane->state->fb; ++ ++ pixel_alpha_en = fb->format->has_alpha; ++ ++ alpha_config.src_premulti_en = premulti_en; ++ ++ if (bottom_layer_alpha_en && zpos == 1) { ++ gpremulti_en = premulti_en; ++ /* Cd = Cs + (1 - As) * Cd * Agd */ ++ alpha_config.dst_premulti_en = false; ++ alpha_config.src_pixel_alpha_en = pixel_alpha_en; ++ alpha_config.src_glb_alpha_value = plane->state->alpha; ++ alpha_config.dst_glb_alpha_value = dst_global_alpha; ++ } else if (vop2_cluster_window(win)) { ++ /* Mix output data only have pixel alpha */ ++ alpha_config.dst_premulti_en = true; ++ alpha_config.src_pixel_alpha_en = true; ++ alpha_config.src_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE; ++ alpha_config.dst_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE; ++ } else { ++ /* Cd = Cs + (1 - As) * Cd */ ++ alpha_config.dst_premulti_en = true; ++ alpha_config.src_pixel_alpha_en = pixel_alpha_en; ++ alpha_config.src_glb_alpha_value = plane->state->alpha; ++ alpha_config.dst_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE; ++ } ++ ++ vop2_parse_alpha(&alpha_config, &alpha); ++ ++ offset = (mixer_id + zpos - 1) * 0x10; ++ vop2_writel(vop2, RK3568_MIX0_SRC_COLOR_CTRL + offset, ++ alpha.src_color_ctrl.val); ++ vop2_writel(vop2, RK3568_MIX0_DST_COLOR_CTRL + offset, ++ alpha.dst_color_ctrl.val); ++ vop2_writel(vop2, RK3568_MIX0_SRC_ALPHA_CTRL + offset, ++ alpha.src_alpha_ctrl.val); ++ vop2_writel(vop2, RK3568_MIX0_DST_ALPHA_CTRL + offset, ++ alpha.dst_alpha_ctrl.val); ++ } ++ ++ if (vp->id == 0) { ++ if (bottom_layer_alpha_en) { ++ /* Transfer pixel alpha to hdr mix */ ++ alpha_config.src_premulti_en = gpremulti_en; ++ alpha_config.dst_premulti_en = true; ++ alpha_config.src_pixel_alpha_en = true; ++ alpha_config.src_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE; ++ alpha_config.dst_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE; ++ vop2_parse_alpha(&alpha_config, &alpha); ++ ++ vop2_writel(vop2, RK3568_HDR0_SRC_COLOR_CTRL, ++ alpha.src_color_ctrl.val); ++ vop2_writel(vop2, RK3568_HDR0_DST_COLOR_CTRL, ++ alpha.dst_color_ctrl.val); ++ vop2_writel(vop2, RK3568_HDR0_SRC_ALPHA_CTRL, ++ alpha.src_alpha_ctrl.val); ++ vop2_writel(vop2, RK3568_HDR0_DST_ALPHA_CTRL, ++ alpha.dst_alpha_ctrl.val); ++ } else { ++ vop2_writel(vop2, RK3568_HDR0_SRC_COLOR_CTRL, 0); ++ } ++ } ++} ++ ++#define NR_VPS 3 ++#define NR_MIXERS 6 ++ ++static void vop2_setup_layer_mixer(struct vop2_video_port *vp) ++{ ++ struct vop2 *vop2 = vp->vop2; ++ struct drm_plane *plane; ++ uint32_t layer_sel = 0; ++ uint32_t port_sel; ++ int nlayer, ofs; ++ struct drm_display_mode *adjusted_mode; ++ uint16_t hsync_len; ++ uint16_t hdisplay; ++ uint32_t bg_dly; ++ uint32_t pre_scan_dly; ++ int i; ++ struct vop2_video_port *vp0 = &vop2->vps[0]; ++ struct vop2_video_port *vp1 = &vop2->vps[1]; ++ struct vop2_video_port *vp2 = &vop2->vps[2]; ++ ++ adjusted_mode = &vp->crtc.state->adjusted_mode; ++ hsync_len = adjusted_mode->crtc_hsync_end - adjusted_mode->crtc_hsync_start; ++ hdisplay = adjusted_mode->crtc_hdisplay; ++ ++ bg_dly = vp->data->pre_scan_max_dly[3]; ++ vop2_writel(vop2, RK3568_VP_BG_MIX_CTRL(vp->id), ++ FIELD_PREP(RK3568_VP_BG_MIX_CTRL__BG_DLY, bg_dly)); ++ ++ pre_scan_dly = ((bg_dly + (hdisplay >> 1) - 1) << 16) | hsync_len; ++ vop2_vp_write(vp, RK3568_VP_PRE_SCAN_HTIMING, pre_scan_dly); ++ ++ vop2_writel(vop2, RK3568_OVL_CTRL, 0); ++ port_sel = vop2_readl(vop2, RK3568_OVL_PORT_SEL); ++ port_sel &= RK3568_OVL_PORT_SEL__SEL_PORT; ++ ++ if (vp0->nlayers) ++ port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT0_MUX, ++ vp0->nlayers - 1); ++ else ++ port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT0_MUX, 8); ++ ++ if (vp1->nlayers) ++ port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT1_MUX, ++ (vp0->nlayers + vp1->nlayers - 1)); ++ else ++ port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT1_MUX, 8); ++ ++ if (vp2->nlayers) ++ port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT2_MUX, ++ (vp2->nlayers + vp1->nlayers + vp0->nlayers - 1)); ++ else ++ port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT1_MUX, 8); ++ ++ layer_sel = vop2_readl(vop2, RK3568_OVL_LAYER_SEL); ++ ++ ofs = 0; ++ for (i = 0; i < vp->id; i++) ++ ofs += vop2->vps[i].nlayers; ++ ++ nlayer = 0; ++ drm_atomic_crtc_for_each_plane(plane, &vp->crtc) { ++ struct vop2_win *win = to_vop2_win(plane); ++ ++ switch (win->data->phys_id) { ++ case ROCKCHIP_VOP2_CLUSTER0: ++ port_sel &= ~RK3568_OVL_PORT_SEL__CLUSTER0; ++ port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__CLUSTER0, vp->id); ++ break; ++ case ROCKCHIP_VOP2_CLUSTER1: ++ port_sel &= ~RK3568_OVL_PORT_SEL__CLUSTER1; ++ port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__CLUSTER1, vp->id); ++ break; ++ case ROCKCHIP_VOP2_ESMART0: ++ port_sel &= ~RK3568_OVL_PORT_SEL__ESMART0; ++ port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__ESMART0, vp->id); ++ break; ++ case ROCKCHIP_VOP2_ESMART1: ++ port_sel &= ~RK3568_OVL_PORT_SEL__ESMART1; ++ port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__ESMART1, vp->id); ++ break; ++ case ROCKCHIP_VOP2_SMART0: ++ port_sel &= ~RK3568_OVL_PORT_SEL__SMART0; ++ port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__SMART0, vp->id); ++ break; ++ case ROCKCHIP_VOP2_SMART1: ++ port_sel &= ~RK3568_OVL_PORT_SEL__SMART1; ++ port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__SMART1, vp->id); ++ break; ++ } ++ ++ layer_sel &= ~RK3568_OVL_LAYER_SEL__LAYER(nlayer + ofs, 0x7); ++ layer_sel |= RK3568_OVL_LAYER_SEL__LAYER(nlayer + ofs, win->data->layer_sel_id); ++ nlayer++; ++ } ++ ++ /* configure unused layers to 0x5 (reserved) */ ++ for (; nlayer < 3; nlayer++) { ++ layer_sel &= ~RK3568_OVL_LAYER_SEL__LAYER(nlayer + ofs, 0x7); ++ layer_sel |= RK3568_OVL_LAYER_SEL__LAYER(nlayer + ofs, 5); ++ } ++ ++ vop2_writel(vop2, RK3568_OVL_LAYER_SEL, layer_sel); ++ vop2_writel(vop2, RK3568_OVL_PORT_SEL, port_sel); ++ vop2_writel(vop2, RK3568_OVL_CTRL, RK3568_OVL_CTRL__LAYERSEL_REGDONE_IMD); ++} ++ ++static void vop2_setup_dly_for_windows(struct vop2 *vop2) ++{ ++ struct vop2_win *win; ++ int i = 0; ++ uint32_t cdly = 0, sdly = 0; ++ ++ for (i = 0; i < vop2->data->win_size; i++) { ++ uint32_t dly; ++ ++ win = &vop2->win[i]; ++ dly = win->delay; ++ ++ switch (win->data->phys_id) { ++ case ROCKCHIP_VOP2_CLUSTER0: ++ cdly |= FIELD_PREP(RK3568_CLUSTER_DLY_NUM__CLUSTER0_0, dly); ++ cdly |= FIELD_PREP(RK3568_CLUSTER_DLY_NUM__CLUSTER0_1, dly); ++ break; ++ case ROCKCHIP_VOP2_CLUSTER1: ++ cdly |= FIELD_PREP(RK3568_CLUSTER_DLY_NUM__CLUSTER1_0, dly); ++ cdly |= FIELD_PREP(RK3568_CLUSTER_DLY_NUM__CLUSTER1_1, dly); ++ break; ++ case ROCKCHIP_VOP2_ESMART0: ++ sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__ESMART0, dly); ++ break; ++ case ROCKCHIP_VOP2_ESMART1: ++ sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__ESMART1, dly); ++ break; ++ case ROCKCHIP_VOP2_SMART0: ++ sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__SMART1, dly); ++ break; ++ case ROCKCHIP_VOP2_SMART1: ++ sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__SMART0, dly); ++ break; ++ } ++ } ++ ++ vop2_writel(vop2, RK3568_CLUSTER_DLY_NUM, cdly); ++ vop2_writel(vop2, RK3568_SMART_DLY_NUM, sdly); ++} ++ ++static void vop2_crtc_atomic_begin(struct drm_crtc *crtc, struct drm_atomic_state *state) ++{ ++ struct vop2_video_port *vp = to_vop2_video_port(crtc); ++ struct vop2 *vop2 = vp->vop2; ++ struct drm_plane *plane; ++ ++ vp->win_mask = 0; ++ ++ drm_atomic_crtc_for_each_plane(plane, crtc) { ++ struct vop2_win *win = to_vop2_win(plane); ++ ++ win->delay = win->data->dly[VOP2_DLY_MODE_DEFAULT]; ++ ++ vp->win_mask |= BIT(win->data->phys_id); ++ ++ if (vop2_cluster_window(win)) ++ vop2_setup_cluster_alpha(vop2, win); ++ } ++ ++ if (!vp->win_mask) ++ return; ++ ++ vop2_setup_layer_mixer(vp); ++ vop2_setup_alpha(vp); ++ vop2_setup_dly_for_windows(vop2); ++} ++ ++static void vop2_crtc_atomic_flush(struct drm_crtc *crtc, struct drm_atomic_state *state) ++{ ++ struct vop2_video_port *vp = to_vop2_video_port(crtc); ++ struct vop2 *vop2 = vp->vop2; ++ ++ spin_lock(&vop2->reg_lock); ++ ++ vop2_post_config(crtc); ++ ++ spin_unlock(&vop2->reg_lock); ++ ++ vop2_cfg_done(vp); ++ ++ spin_lock_irq(&crtc->dev->event_lock); ++ ++ if (crtc->state->event) { ++ WARN_ON(drm_crtc_vblank_get(crtc)); ++ vp->event = crtc->state->event; ++ crtc->state->event = NULL; ++ } ++ ++ spin_unlock_irq(&crtc->dev->event_lock); ++} ++ ++static const struct drm_crtc_helper_funcs vop2_crtc_helper_funcs = { ++ .mode_fixup = vop2_crtc_mode_fixup, ++ .atomic_check = vop2_crtc_atomic_check, ++ .atomic_begin = vop2_crtc_atomic_begin, ++ .atomic_flush = vop2_crtc_atomic_flush, ++ .atomic_enable = vop2_crtc_atomic_enable, ++ .atomic_disable = vop2_crtc_atomic_disable, ++}; ++ ++static void vop2_crtc_reset(struct drm_crtc *crtc) ++{ ++ struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state); ++ ++ if (crtc->state) { ++ __drm_atomic_helper_crtc_destroy_state(crtc->state); ++ kfree(vcstate); ++ } ++ ++ vcstate = kzalloc(sizeof(*vcstate), GFP_KERNEL); ++ if (!vcstate) ++ return; ++ ++ crtc->state = &vcstate->base; ++ crtc->state->crtc = crtc; ++} ++ ++static struct drm_crtc_state *vop2_crtc_duplicate_state(struct drm_crtc *crtc) ++{ ++ struct rockchip_crtc_state *vcstate, *old_vcstate; ++ ++ old_vcstate = to_rockchip_crtc_state(crtc->state); ++ ++ vcstate = kmemdup(old_vcstate, sizeof(*old_vcstate), GFP_KERNEL); ++ if (!vcstate) ++ return NULL; ++ ++ __drm_atomic_helper_crtc_duplicate_state(crtc, &vcstate->base); ++ ++ return &vcstate->base; ++} ++ ++static void vop2_crtc_destroy_state(struct drm_crtc *crtc, ++ struct drm_crtc_state *state) ++{ ++ struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(state); ++ ++ __drm_atomic_helper_crtc_destroy_state(&vcstate->base); ++ kfree(vcstate); ++} ++ ++static const struct drm_crtc_funcs vop2_crtc_funcs = { ++ .set_config = drm_atomic_helper_set_config, ++ .page_flip = drm_atomic_helper_page_flip, ++ .destroy = drm_crtc_cleanup, ++ .reset = vop2_crtc_reset, ++ .atomic_duplicate_state = vop2_crtc_duplicate_state, ++ .atomic_destroy_state = vop2_crtc_destroy_state, ++ .enable_vblank = vop2_crtc_enable_vblank, ++ .disable_vblank = vop2_crtc_disable_vblank, ++}; ++ ++static irqreturn_t vop2_isr(int irq, void *data) ++{ ++ struct vop2 *vop2 = data; ++ const struct vop2_data *vop2_data = vop2->data; ++ uint32_t axi_irqs[VOP2_SYS_AXI_BUS_NUM]; ++ int ret = IRQ_NONE; ++ int i; ++ ++ /* ++ * The irq is shared with the iommu. If the runtime-pm state of the ++ * vop2-device is disabled the irq has to be targeted at the iommu. ++ */ ++ if (!pm_runtime_get_if_in_use(vop2->dev)) ++ return IRQ_NONE; ++ ++ for (i = 0; i < vop2_data->nr_vps; i++) { ++ struct vop2_video_port *vp = &vop2->vps[i]; ++ struct drm_crtc *crtc = &vp->crtc; ++ uint32_t irqs; ++ ++ irqs = vop2_readl(vop2, RK3568_VP_INT_STATUS(vp->id)); ++ vop2_writel(vop2, RK3568_VP_INT_CLR(vp->id), irqs << 16 | irqs); ++ ++ if (irqs & VP_INT_DSP_HOLD_VALID) { ++ complete(&vp->dsp_hold_completion); ++ ret = IRQ_HANDLED; ++ } ++ ++ if (irqs & VP_INT_FS_FIELD) { ++ unsigned long flags; ++ ++ drm_crtc_handle_vblank(crtc); ++ spin_lock_irqsave(&crtc->dev->event_lock, flags); ++ if (vp->event) { ++ uint32_t val = vop2_readl(vop2, RK3568_REG_CFG_DONE); ++ if (!(val & BIT(vp->id))) { ++ drm_crtc_send_vblank_event(crtc, vp->event); ++ vp->event = NULL; ++ drm_crtc_vblank_put(crtc); ++ } ++ } ++ spin_unlock_irqrestore(&crtc->dev->event_lock, flags); ++ ++ ret = IRQ_HANDLED; ++ } ++ ++ if (irqs & VP_INT_POST_BUF_EMPTY) { ++ drm_err_ratelimited(vop2->drm, ++ "POST_BUF_EMPTY irq err at vp%d\n", ++ vp->id); ++ ret = IRQ_HANDLED; ++ } ++ } ++ ++ axi_irqs[0] = vop2_readl(vop2, RK3568_SYS0_INT_STATUS); ++ vop2_writel(vop2, RK3568_SYS0_INT_CLR, axi_irqs[0] << 16 | axi_irqs[0]); ++ axi_irqs[1] = vop2_readl(vop2, RK3568_SYS1_INT_STATUS); ++ vop2_writel(vop2, RK3568_SYS1_INT_CLR, axi_irqs[1] << 16 | axi_irqs[1]); ++ ++ for (i = 0; i < ARRAY_SIZE(axi_irqs); i++) { ++ if (axi_irqs[i] & VOP2_INT_BUS_ERRPR) { ++ drm_err_ratelimited(vop2->drm, "BUS_ERROR irq err\n"); ++ ret = IRQ_HANDLED; ++ } ++ } ++ ++ pm_runtime_put(vop2->dev); ++ ++ return ret; ++} ++ ++static int vop2_plane_init(struct vop2 *vop2, struct vop2_win *win, unsigned long possible_crtcs) ++{ ++ const struct vop2_win_data *win_data = win->data; ++ unsigned int blend_caps = BIT(DRM_MODE_BLEND_PIXEL_NONE) | BIT(DRM_MODE_BLEND_PREMULTI) | ++ BIT(DRM_MODE_BLEND_COVERAGE); ++ int ret; ++ ++ ret = drm_universal_plane_init(vop2->drm, &win->base, possible_crtcs, ++ &vop2_plane_funcs, win_data->formats, win_data->nformats, ++ win_data->format_modifiers, win->type, win_data->name); ++ if (ret) { ++ drm_err(vop2->drm, "failed to initialize plane %d\n", ret); ++ return ret; ++ } ++ ++ drm_plane_helper_add(&win->base, &vop2_plane_helper_funcs); ++ ++ if (win->data->supported_rotations) ++ drm_plane_create_rotation_property(&win->base, DRM_MODE_ROTATE_0, ++ DRM_MODE_ROTATE_0 | ++ win->data->supported_rotations); ++ drm_plane_create_alpha_property(&win->base); ++ drm_plane_create_blend_mode_property(&win->base, blend_caps); ++ drm_plane_create_zpos_property(&win->base, win->win_id, 0, ++ vop2->registered_num_wins - 1); ++ ++ return 0; ++} ++ ++static struct vop2_video_port *get_activated_vp(struct vop2 *vop2, int n) ++{ ++ int i, id = 0; ++ ++ for (i = 0; i < vop2->data->nr_vps; i++) { ++ struct vop2_video_port *vp = &vop2->vps[i]; ++ ++ if (!vp->crtc.port) ++ continue; ++ ++ if (n == id) ++ return vp; ++ id++; ++ } ++ ++ return NULL; ++} ++ ++static int vop2_create_crtc(struct vop2 *vop2) ++{ ++ const struct vop2_data *vop2_data = vop2->data; ++ struct drm_device *drm = vop2->drm; ++ struct device *dev = vop2->dev; ++ struct drm_plane *plane; ++ struct device_node *port; ++ struct vop2_video_port *vp; ++ uint32_t possible_crtcs; ++ int i, nvp, nvps = 0; ++ int ret; ++ ++ for (i = 0; i < vop2_data->nr_vps; i++) { ++ const struct vop2_video_port_data *vp_data; ++ struct device_node *np; ++ char dclk_name[9]; ++ ++ vp_data = &vop2_data->vp[i]; ++ vp = &vop2->vps[i]; ++ vp->vop2 = vop2; ++ vp->id = vp_data->id; ++ vp->regs = vp_data->regs; ++ vp->data = vp_data; ++ ++ snprintf(dclk_name, sizeof(dclk_name), "dclk_vp%d", vp->id); ++ vp->dclk = devm_clk_get(vop2->dev, dclk_name); ++ if (IS_ERR(vp->dclk)) { ++ drm_err(vop2->drm, "failed to get %s\n", dclk_name); ++ return PTR_ERR(vp->dclk); ++ } ++ ++ np = of_graph_get_remote_node(dev->of_node, i, -1); ++ if (!np) { ++ printk("%s: No remote for vp%d\n", __func__, i); ++ continue; ++ } ++ of_node_put(np); ++ ++ port = of_graph_get_port_by_id(dev->of_node, i); ++ if (!port) { ++ drm_err(vop2->drm, "no port node found for video_port%d\n", i); ++ return -ENOENT; ++ } ++ ++ vp->crtc.port = port; ++ nvps++; ++ } ++ ++ nvp = 0; ++ for (i = 0; i < vop2->registered_num_wins; i++) { ++ struct vop2_win *win = &vop2->win[i]; ++ ++ if (win->type == DRM_PLANE_TYPE_PRIMARY) { ++ vp = get_activated_vp(vop2, nvp); ++ ++ if (vp) { ++ possible_crtcs = BIT(nvp); ++ vp->primary_plane = win; ++ ++ nvp++; ++ } else { ++ /* change the unused primary window to overlay window */ ++ win->type = DRM_PLANE_TYPE_OVERLAY; ++ } ++ } ++ ++ if (win->type == DRM_PLANE_TYPE_OVERLAY) ++ possible_crtcs = (1 << vop2_data->nr_vps) - 1; ++ ++ ret = vop2_plane_init(vop2, win, possible_crtcs); ++ ++ if (ret) { ++ drm_err(vop2->drm, "failed to init plane %s: %d\n", win->data->name, ret); ++ return ret; ++ } ++ } ++ ++ for (i = 0; i < vop2_data->nr_vps; i++) { ++ vp = &vop2->vps[i]; ++ ++ if (!vp->crtc.port) ++ continue; ++ ++ plane = &vp->primary_plane->base; ++ ++ ret = drm_crtc_init_with_planes(drm, &vp->crtc, plane, NULL, &vop2_crtc_funcs, ++ "video_port%d", vp->id); ++ if (ret) { ++ drm_err(vop2->drm, "crtc init for video_port%d failed\n", i); ++ return ret; ++ } ++ ++ drm_crtc_helper_add(&vp->crtc, &vop2_crtc_helper_funcs); ++ ++ init_completion(&vp->dsp_hold_completion); ++ } ++ ++ for (i = 0; i < vop2->data->nr_vps; i++) { ++ struct vop2_video_port *vp = &vop2->vps[i]; ++ if (vp->crtc.port) ++ vp->nlayers = NR_MIXERS / nvps; ++ } ++ ++ return 0; ++} ++ ++static void vop2_destroy_crtc(struct drm_crtc *crtc) ++{ ++ of_node_put(crtc->port); ++ ++ /* ++ * Destroy CRTC after vop2_plane_destroy() since vop2_disable_plane() ++ * references the CRTC. ++ */ ++ drm_crtc_cleanup(crtc); ++} ++ ++static int vop2_cluster_init(struct vop2_win *win) ++{ ++ struct vop2 *vop2 = win->vop2; ++ int i; ++ struct reg_field vop2_cluster_regs[VOP2_WIN_MAX_REG] = { ++ [VOP2_WIN_ENABLE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 0, 0), ++ [VOP2_WIN_FORMAT] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 1, 5), ++ [VOP2_WIN_RB_SWAP] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 14, 14), ++ [VOP2_WIN_DITHER_UP] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 18, 18), ++ [VOP2_WIN_ACT_INFO] = REG_FIELD(RK3568_CLUSTER_WIN_ACT_INFO, 0, 31), ++ [VOP2_WIN_DSP_INFO] = REG_FIELD(RK3568_CLUSTER_WIN_DSP_INFO, 0, 31), ++ [VOP2_WIN_DSP_ST] = REG_FIELD(RK3568_CLUSTER_WIN_DSP_ST, 0, 31), ++ [VOP2_WIN_YRGB_MST] = REG_FIELD(RK3568_CLUSTER_WIN_YRGB_MST, 0, 31), ++ [VOP2_WIN_UV_MST] = REG_FIELD(RK3568_CLUSTER_WIN_CBR_MST, 0, 31), ++ [VOP2_WIN_YUV_CLIP] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 19, 19), ++ [VOP2_WIN_YRGB_VIR] = REG_FIELD(RK3568_CLUSTER_WIN_VIR, 0, 15), ++ [VOP2_WIN_UV_VIR] = REG_FIELD(RK3568_CLUSTER_WIN_VIR, 16, 31), ++ [VOP2_WIN_Y2R_EN] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 8, 8), ++ [VOP2_WIN_R2Y_EN] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 9, 9), ++ [VOP2_WIN_CSC_MODE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 10, 11), ++ ++ /* Scale */ ++ [VOP2_WIN_SCALE_YRGB_X] = REG_FIELD(RK3568_CLUSTER_WIN_SCL_FACTOR_YRGB, 0, 15), ++ [VOP2_WIN_SCALE_YRGB_Y] = REG_FIELD(RK3568_CLUSTER_WIN_SCL_FACTOR_YRGB, 16, 31), ++ [VOP2_WIN_YRGB_VER_SCL_MODE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 14, 15), ++ [VOP2_WIN_YRGB_HOR_SCL_MODE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 12, 13), ++ [VOP2_WIN_BIC_COE_SEL] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 2, 3), ++ [VOP2_WIN_VSD_YRGB_GT2] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 28, 28), ++ [VOP2_WIN_VSD_YRGB_GT4] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 29, 29), ++ ++ /* cluster regs */ ++ [VOP2_WIN_AFBC_ENABLE] = REG_FIELD(RK3568_CLUSTER_CTRL, 1, 1), ++ [VOP2_WIN_CLUSTER_ENABLE] = REG_FIELD(RK3568_CLUSTER_CTRL, 0, 0), ++ [VOP2_WIN_CLUSTER_LB_MODE] = REG_FIELD(RK3568_CLUSTER_CTRL, 4, 7), ++ ++ /* afbc regs */ ++ [VOP2_WIN_AFBC_FORMAT] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 2, 6), ++ [VOP2_WIN_AFBC_RB_SWAP] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 9, 9), ++ [VOP2_WIN_AFBC_UV_SWAP] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 10, 10), ++ [VOP2_WIN_AFBC_AUTO_GATING_EN] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_OUTPUT_CTRL, 4, 4), ++ [VOP2_WIN_AFBC_HALF_BLOCK_EN] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 7, 7), ++ [VOP2_WIN_AFBC_BLOCK_SPLIT_EN] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 8, 8), ++ [VOP2_WIN_AFBC_HDR_PTR] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_HDR_PTR, 0, 31), ++ [VOP2_WIN_AFBC_PIC_SIZE] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_PIC_SIZE, 0, 31), ++ [VOP2_WIN_AFBC_PIC_VIR_WIDTH] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_VIR_WIDTH, 0, 15), ++ [VOP2_WIN_AFBC_TILE_NUM] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_VIR_WIDTH, 16, 31), ++ [VOP2_WIN_AFBC_PIC_OFFSET] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_PIC_OFFSET, 0, 31), ++ [VOP2_WIN_AFBC_DSP_OFFSET] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_DSP_OFFSET, 0, 31), ++ [VOP2_WIN_AFBC_TRANSFORM_OFFSET] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_TRANSFORM_OFFSET, 0, 31), ++ [VOP2_WIN_AFBC_ROTATE_90] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 0, 0), ++ [VOP2_WIN_AFBC_ROTATE_270] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 1, 1), ++ [VOP2_WIN_XMIRROR] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 2, 2), ++ [VOP2_WIN_YMIRROR] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 3, 3), ++ [VOP2_WIN_UV_SWAP] = { .reg = 0xffffffff }, ++ [VOP2_WIN_COLOR_KEY] = { .reg = 0xffffffff }, ++ [VOP2_WIN_COLOR_KEY_EN] = { .reg = 0xffffffff }, ++ [VOP2_WIN_SCALE_CBCR_X] = { .reg = 0xffffffff }, ++ [VOP2_WIN_SCALE_CBCR_Y] = { .reg = 0xffffffff }, ++ [VOP2_WIN_YRGB_HSCL_FILTER_MODE] = { .reg = 0xffffffff }, ++ [VOP2_WIN_YRGB_VSCL_FILTER_MODE] = { .reg = 0xffffffff }, ++ [VOP2_WIN_CBCR_VER_SCL_MODE] = { .reg = 0xffffffff }, ++ [VOP2_WIN_CBCR_HSCL_FILTER_MODE] = { .reg = 0xffffffff }, ++ [VOP2_WIN_CBCR_HOR_SCL_MODE] = { .reg = 0xffffffff }, ++ [VOP2_WIN_CBCR_VSCL_FILTER_MODE] = { .reg = 0xffffffff }, ++ [VOP2_WIN_VSD_CBCR_GT2] = { .reg = 0xffffffff }, ++ [VOP2_WIN_VSD_CBCR_GT4] = { .reg = 0xffffffff }, ++ }; ++ ++ for (i = 0; i < ARRAY_SIZE(vop2_cluster_regs); i++) ++ vop2_cluster_regs[i].reg += win->offset; ++ ++ return devm_regmap_field_bulk_alloc(vop2->dev, vop2->map, win->reg, ++ vop2_cluster_regs, ++ ARRAY_SIZE(vop2_cluster_regs)); ++}; ++ ++static int vop2_esmart_init(struct vop2_win *win) ++{ ++ struct vop2 *vop2 = win->vop2; ++ int i; ++ struct reg_field vop2_esmart_regs[VOP2_WIN_MAX_REG] = { ++ [VOP2_WIN_ENABLE] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 0, 0), ++ [VOP2_WIN_FORMAT] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 1, 5), ++ [VOP2_WIN_DITHER_UP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 12, 12), ++ [VOP2_WIN_RB_SWAP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 14, 14), ++ [VOP2_WIN_UV_SWAP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 16, 16), ++ [VOP2_WIN_ACT_INFO] = REG_FIELD(RK3568_SMART_REGION0_ACT_INFO, 0, 31), ++ [VOP2_WIN_DSP_INFO] = REG_FIELD(RK3568_SMART_REGION0_DSP_INFO, 0, 31), ++ [VOP2_WIN_DSP_ST] = REG_FIELD(RK3568_SMART_REGION0_DSP_ST, 0, 28), ++ [VOP2_WIN_YRGB_MST] = REG_FIELD(RK3568_SMART_REGION0_YRGB_MST, 0, 31), ++ [VOP2_WIN_UV_MST] = REG_FIELD(RK3568_SMART_REGION0_CBR_MST, 0, 31), ++ [VOP2_WIN_YUV_CLIP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 17, 17), ++ [VOP2_WIN_YRGB_VIR] = REG_FIELD(RK3568_SMART_REGION0_VIR, 0, 15), ++ [VOP2_WIN_UV_VIR] = REG_FIELD(RK3568_SMART_REGION0_VIR, 16, 31), ++ [VOP2_WIN_Y2R_EN] = REG_FIELD(RK3568_SMART_CTRL0, 0, 0), ++ [VOP2_WIN_R2Y_EN] = REG_FIELD(RK3568_SMART_CTRL0, 1, 1), ++ [VOP2_WIN_CSC_MODE] = REG_FIELD(RK3568_SMART_CTRL0, 2, 3), ++ [VOP2_WIN_YMIRROR] = REG_FIELD(RK3568_SMART_CTRL1, 31, 31), ++ [VOP2_WIN_COLOR_KEY] = REG_FIELD(RK3568_SMART_COLOR_KEY_CTRL, 0, 29), ++ [VOP2_WIN_COLOR_KEY_EN] = REG_FIELD(RK3568_SMART_COLOR_KEY_CTRL, 31, 31), ++ ++ /* Scale */ ++ [VOP2_WIN_SCALE_YRGB_X] = REG_FIELD(RK3568_SMART_REGION0_SCL_FACTOR_YRGB, 0, 15), ++ [VOP2_WIN_SCALE_YRGB_Y] = REG_FIELD(RK3568_SMART_REGION0_SCL_FACTOR_YRGB, 16, 31), ++ [VOP2_WIN_SCALE_CBCR_X] = REG_FIELD(RK3568_SMART_REGION0_SCL_FACTOR_CBR, 0, 15), ++ [VOP2_WIN_SCALE_CBCR_Y] = REG_FIELD(RK3568_SMART_REGION0_SCL_FACTOR_CBR, 16, 31), ++ [VOP2_WIN_YRGB_HOR_SCL_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 0, 1), ++ [VOP2_WIN_YRGB_HSCL_FILTER_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 2, 3), ++ [VOP2_WIN_YRGB_VER_SCL_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 4, 5), ++ [VOP2_WIN_YRGB_VSCL_FILTER_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 6, 7), ++ [VOP2_WIN_CBCR_HOR_SCL_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 8, 9), ++ [VOP2_WIN_CBCR_HSCL_FILTER_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 10, 11), ++ [VOP2_WIN_CBCR_VER_SCL_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 12, 13), ++ [VOP2_WIN_CBCR_VSCL_FILTER_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 14, 15), ++ [VOP2_WIN_BIC_COE_SEL] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 16, 17), ++ [VOP2_WIN_VSD_YRGB_GT2] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 8, 8), ++ [VOP2_WIN_VSD_YRGB_GT4] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 9, 9), ++ [VOP2_WIN_VSD_CBCR_GT2] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 10, 10), ++ [VOP2_WIN_VSD_CBCR_GT4] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 11, 11), ++ [VOP2_WIN_XMIRROR] = { .reg = 0xffffffff }, ++ [VOP2_WIN_CLUSTER_ENABLE] = { .reg = 0xffffffff }, ++ [VOP2_WIN_AFBC_ENABLE] = { .reg = 0xffffffff }, ++ [VOP2_WIN_CLUSTER_LB_MODE] = { .reg = 0xffffffff }, ++ [VOP2_WIN_AFBC_FORMAT] = { .reg = 0xffffffff }, ++ [VOP2_WIN_AFBC_RB_SWAP] = { .reg = 0xffffffff }, ++ [VOP2_WIN_AFBC_UV_SWAP] = { .reg = 0xffffffff }, ++ [VOP2_WIN_AFBC_AUTO_GATING_EN] = { .reg = 0xffffffff }, ++ [VOP2_WIN_AFBC_BLOCK_SPLIT_EN] = { .reg = 0xffffffff }, ++ [VOP2_WIN_AFBC_PIC_VIR_WIDTH] = { .reg = 0xffffffff }, ++ [VOP2_WIN_AFBC_TILE_NUM] = { .reg = 0xffffffff }, ++ [VOP2_WIN_AFBC_PIC_OFFSET] = { .reg = 0xffffffff }, ++ [VOP2_WIN_AFBC_PIC_SIZE] = { .reg = 0xffffffff }, ++ [VOP2_WIN_AFBC_DSP_OFFSET] = { .reg = 0xffffffff }, ++ [VOP2_WIN_AFBC_TRANSFORM_OFFSET] = { .reg = 0xffffffff }, ++ [VOP2_WIN_AFBC_HDR_PTR] = { .reg = 0xffffffff }, ++ [VOP2_WIN_AFBC_HALF_BLOCK_EN] = { .reg = 0xffffffff }, ++ [VOP2_WIN_AFBC_ROTATE_270] = { .reg = 0xffffffff }, ++ [VOP2_WIN_AFBC_ROTATE_90] = { .reg = 0xffffffff }, ++ }; ++ ++ for (i = 0; i < ARRAY_SIZE(vop2_esmart_regs); i++) ++ vop2_esmart_regs[i].reg += win->offset; ++ ++ return devm_regmap_field_bulk_alloc(vop2->dev, vop2->map, win->reg, ++ vop2_esmart_regs, ++ ARRAY_SIZE(vop2_esmart_regs)); ++}; ++ ++static int vop2_win_init(struct vop2 *vop2) ++{ ++ const struct vop2_data *vop2_data = vop2->data; ++ struct vop2_win *win; ++ int i, ret; ++ ++ for (i = 0; i < vop2_data->win_size; i++) { ++ const struct vop2_win_data *win_data = &vop2_data->win[i]; ++ ++ win = &vop2->win[i]; ++ win->data = win_data; ++ win->type = win_data->type; ++ win->offset = win_data->base; ++ win->win_id = i; ++ win->vop2 = vop2; ++ if (vop2_cluster_window(win)) ++ ret = vop2_cluster_init(win); ++ else ++ ret = vop2_esmart_init(win); ++ if (ret) ++ return ret; ++ } ++ ++ vop2->registered_num_wins = vop2_data->win_size; ++ ++ return 0; ++} ++ ++/* ++ * The window registers are only updated when config done is written. ++ * Until that they read back the old value. As we read-modify-write ++ * these registers mark them as non-volatile. This makes sure we read ++ * the new values from the regmap register cache. ++ */ ++static const struct regmap_range vop2_nonvolatile_range[] = { ++ regmap_reg_range(0x1000, 0x23ff), ++}; ++ ++static const struct regmap_access_table vop2_volatile_table = { ++ .no_ranges = vop2_nonvolatile_range, ++ .n_no_ranges = ARRAY_SIZE(vop2_nonvolatile_range), ++}; ++ ++static const struct regmap_config vop2_regmap_config = { ++ .reg_bits = 32, ++ .val_bits = 32, ++ .reg_stride = 4, ++ .max_register = 0x3000, ++ .name = "vop2", ++ .volatile_table = &vop2_volatile_table, ++ .cache_type = REGCACHE_RBTREE, ++}; ++ ++static int vop2_bind(struct device *dev, struct device *master, void *data) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ const struct vop2_data *vop2_data; ++ struct drm_device *drm = data; ++ struct vop2 *vop2; ++ struct resource *res; ++ size_t alloc_size; ++ int ret; ++ ++ vop2_data = of_device_get_match_data(dev); ++ if (!vop2_data) ++ return -ENODEV; ++ ++ /* Allocate vop2 struct and its vop2_win array */ ++ alloc_size = sizeof(*vop2) + sizeof(*vop2->win) * vop2_data->win_size; ++ vop2 = devm_kzalloc(dev, alloc_size, GFP_KERNEL); ++ if (!vop2) ++ return -ENOMEM; ++ ++ vop2->dev = dev; ++ vop2->data = vop2_data; ++ vop2->drm = drm; ++ ++ dev_set_drvdata(dev, vop2); ++ ++ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs"); ++ if (!res) { ++ drm_err(vop2->drm, "failed to get vop2 register byname\n"); ++ return -EINVAL; ++ } ++ ++ vop2->regs = devm_ioremap_resource(dev, res); ++ if (IS_ERR(vop2->regs)) ++ return PTR_ERR(vop2->regs); ++ vop2->len = resource_size(res); ++ ++ vop2->map = devm_regmap_init_mmio(dev, vop2->regs, &vop2_regmap_config); ++ ++ ret = vop2_win_init(vop2); ++ if (ret) ++ return ret; ++ ++ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "gamma_lut"); ++ if (res) { ++ vop2->lut_regs = devm_ioremap_resource(dev, res); ++ if (IS_ERR(vop2->lut_regs)) ++ return PTR_ERR(vop2->lut_regs); ++ } ++ ++ vop2->grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,grf"); ++ ++ vop2->hclk = devm_clk_get(vop2->dev, "hclk_vop"); ++ if (IS_ERR(vop2->hclk)) { ++ drm_err(vop2->drm, "failed to get hclk source\n"); ++ return PTR_ERR(vop2->hclk); ++ } ++ ++ vop2->aclk = devm_clk_get(vop2->dev, "aclk_vop"); ++ if (IS_ERR(vop2->aclk)) { ++ drm_err(vop2->drm, "failed to get aclk source\n"); ++ return PTR_ERR(vop2->aclk); ++ } ++ ++ vop2->irq = platform_get_irq(pdev, 0); ++ if (vop2->irq < 0) { ++ drm_err(vop2->drm, "cannot find irq for vop2\n"); ++ return vop2->irq; ++ } ++ ++ spin_lock_init(&vop2->reg_lock); ++ mutex_init(&vop2->vop2_lock); ++ ++ ret = devm_request_irq(dev, vop2->irq, vop2_isr, IRQF_SHARED, dev_name(dev), vop2); ++ if (ret) ++ return ret; ++ ++ ret = rockchip_drm_dma_attach_device(vop2->drm, vop2->dev); ++ if (ret) { ++ drm_err(vop2->drm, "failed to attach dma mapping, %d\n", ret); ++ return ret; ++ } ++ ++ ret = vop2_create_crtc(vop2); ++ if (ret) ++ return ret; ++ ++ pm_runtime_enable(&pdev->dev); ++ ++ return 0; ++} ++ ++static void vop2_unbind(struct device *dev, struct device *master, void *data) ++{ ++ struct vop2 *vop2 = dev_get_drvdata(dev); ++ struct drm_device *drm = vop2->drm; ++ struct list_head *plane_list = &drm->mode_config.plane_list; ++ struct list_head *crtc_list = &drm->mode_config.crtc_list; ++ struct drm_crtc *crtc, *tmpc; ++ struct drm_plane *plane, *tmpp; ++ ++ rockchip_drm_dma_detach_device(vop2->drm, vop2->dev); ++ ++ pm_runtime_disable(dev); ++ ++ list_for_each_entry_safe(plane, tmpp, plane_list, head) ++ drm_plane_cleanup(plane); ++ ++ list_for_each_entry_safe(crtc, tmpc, crtc_list, head) ++ vop2_destroy_crtc(crtc); ++} ++ ++const struct component_ops vop2_component_ops = { ++ .bind = vop2_bind, ++ .unbind = vop2_unbind, ++}; ++EXPORT_SYMBOL_GPL(vop2_component_ops); +diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h +new file mode 100644 +index 0000000000000..bb5677ff00e93 +--- /dev/null ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h +@@ -0,0 +1,480 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++/* ++ * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd ++ * Author:Mark Yao ++ */ ++ ++#ifndef _ROCKCHIP_DRM_VOP2_H ++#define _ROCKCHIP_DRM_VOP2_H ++ ++#include "rockchip_drm_vop.h" ++ ++#include ++#include ++ ++#define VOP_FEATURE_OUTPUT_10BIT BIT(0) ++ ++#define WIN_FEATURE_AFBDC BIT(0) ++#define WIN_FEATURE_CLUSTER BIT(1) ++ ++/* ++ * the delay number of a window in different mode. ++ */ ++enum win_dly_mode { ++ VOP2_DLY_MODE_DEFAULT, /**< default mode */ ++ VOP2_DLY_MODE_HISO_S, /** HDR in SDR out mode, as a SDR window */ ++ VOP2_DLY_MODE_HIHO_H, /** HDR in HDR out mode, as a HDR window */ ++ VOP2_DLY_MODE_MAX, ++}; ++ ++struct vop_rect { ++ int width; ++ int height; ++}; ++ ++enum vop2_scale_up_mode { ++ VOP2_SCALE_UP_NRST_NBOR, ++ VOP2_SCALE_UP_BIL, ++ VOP2_SCALE_UP_BIC, ++}; ++ ++enum vop2_scale_down_mode { ++ VOP2_SCALE_DOWN_NRST_NBOR, ++ VOP2_SCALE_DOWN_BIL, ++ VOP2_SCALE_DOWN_AVG, ++}; ++ ++enum vop2_win_regs { ++ VOP2_WIN_ENABLE, ++ VOP2_WIN_FORMAT, ++ VOP2_WIN_CSC_MODE, ++ VOP2_WIN_XMIRROR, ++ VOP2_WIN_YMIRROR, ++ VOP2_WIN_RB_SWAP, ++ VOP2_WIN_UV_SWAP, ++ VOP2_WIN_ACT_INFO, ++ VOP2_WIN_DSP_INFO, ++ VOP2_WIN_DSP_ST, ++ VOP2_WIN_YRGB_MST, ++ VOP2_WIN_UV_MST, ++ VOP2_WIN_YRGB_VIR, ++ VOP2_WIN_UV_VIR, ++ VOP2_WIN_YUV_CLIP, ++ VOP2_WIN_Y2R_EN, ++ VOP2_WIN_R2Y_EN, ++ VOP2_WIN_COLOR_KEY, ++ VOP2_WIN_COLOR_KEY_EN, ++ VOP2_WIN_DITHER_UP, ++ ++ /* scale regs */ ++ VOP2_WIN_SCALE_YRGB_X, ++ VOP2_WIN_SCALE_YRGB_Y, ++ VOP2_WIN_SCALE_CBCR_X, ++ VOP2_WIN_SCALE_CBCR_Y, ++ VOP2_WIN_YRGB_HOR_SCL_MODE, ++ VOP2_WIN_YRGB_HSCL_FILTER_MODE, ++ VOP2_WIN_YRGB_VER_SCL_MODE, ++ VOP2_WIN_YRGB_VSCL_FILTER_MODE, ++ VOP2_WIN_CBCR_VER_SCL_MODE, ++ VOP2_WIN_CBCR_HSCL_FILTER_MODE, ++ VOP2_WIN_CBCR_HOR_SCL_MODE, ++ VOP2_WIN_CBCR_VSCL_FILTER_MODE, ++ VOP2_WIN_VSD_CBCR_GT2, ++ VOP2_WIN_VSD_CBCR_GT4, ++ VOP2_WIN_VSD_YRGB_GT2, ++ VOP2_WIN_VSD_YRGB_GT4, ++ VOP2_WIN_BIC_COE_SEL, ++ ++ /* cluster regs */ ++ VOP2_WIN_CLUSTER_ENABLE, ++ VOP2_WIN_AFBC_ENABLE, ++ VOP2_WIN_CLUSTER_LB_MODE, ++ ++ /* afbc regs */ ++ VOP2_WIN_AFBC_FORMAT, ++ VOP2_WIN_AFBC_RB_SWAP, ++ VOP2_WIN_AFBC_UV_SWAP, ++ VOP2_WIN_AFBC_AUTO_GATING_EN, ++ VOP2_WIN_AFBC_BLOCK_SPLIT_EN, ++ VOP2_WIN_AFBC_PIC_VIR_WIDTH, ++ VOP2_WIN_AFBC_TILE_NUM, ++ VOP2_WIN_AFBC_PIC_OFFSET, ++ VOP2_WIN_AFBC_PIC_SIZE, ++ VOP2_WIN_AFBC_DSP_OFFSET, ++ VOP2_WIN_AFBC_TRANSFORM_OFFSET, ++ VOP2_WIN_AFBC_HDR_PTR, ++ VOP2_WIN_AFBC_HALF_BLOCK_EN, ++ VOP2_WIN_AFBC_ROTATE_270, ++ VOP2_WIN_AFBC_ROTATE_90, ++ VOP2_WIN_MAX_REG, ++}; ++ ++struct vop2_win_data { ++ const char *name; ++ uint8_t phys_id; ++ ++ uint32_t base; ++ enum drm_plane_type type; ++ ++ uint32_t nformats; ++ const uint32_t *formats; ++ const uint64_t *format_modifiers; ++ const unsigned int supported_rotations; ++ ++ /** ++ * @layer_sel_id: defined by register OVERLAY_LAYER_SEL of VOP2 ++ */ ++ int layer_sel_id; ++ uint64_t feature; ++ ++ unsigned int max_upscale_factor; ++ unsigned int max_downscale_factor; ++ const uint8_t dly[VOP2_DLY_MODE_MAX]; ++}; ++ ++struct vop2_video_port_data { ++ char id; ++ uint32_t feature; ++ uint16_t gamma_lut_len; ++ uint16_t cubic_lut_len; ++ struct vop_rect max_output; ++ const u8 pre_scan_max_dly[4]; ++ const struct vop2_video_port_regs *regs; ++ int offset; ++}; ++ ++struct vop2_data { ++ uint8_t nr_vps; ++ uint8_t nr_mixers; ++ uint8_t nr_layers; ++ uint8_t nr_gammas; ++ const struct vop2_ctrl *ctrl; ++ const struct vop2_win_data *win; ++ const struct vop2_video_port_data *vp; ++ const struct vop_csc_table *csc_table; ++ struct vop_rect max_input; ++ struct vop_rect max_output; ++ ++ unsigned int win_size; ++ unsigned int soc_id; ++}; ++ ++/* interrupt define */ ++#define FS_NEW_INTR BIT(4) ++#define ADDR_SAME_INTR BIT(5) ++#define LINE_FLAG1_INTR BIT(6) ++#define WIN0_EMPTY_INTR BIT(7) ++#define WIN1_EMPTY_INTR BIT(8) ++#define WIN2_EMPTY_INTR BIT(9) ++#define WIN3_EMPTY_INTR BIT(10) ++#define HWC_EMPTY_INTR BIT(11) ++#define POST_BUF_EMPTY_INTR BIT(12) ++#define PWM_GEN_INTR BIT(13) ++#define DMA_FINISH_INTR BIT(14) ++#define FS_FIELD_INTR BIT(15) ++#define FE_INTR BIT(16) ++#define WB_UV_FIFO_FULL_INTR BIT(17) ++#define WB_YRGB_FIFO_FULL_INTR BIT(18) ++#define WB_COMPLETE_INTR BIT(19) ++ ++/* ++ * display output interface supported by rockchip lcdc ++ */ ++#define ROCKCHIP_OUT_MODE_P888 0 ++#define ROCKCHIP_OUT_MODE_BT1120 0 ++#define ROCKCHIP_OUT_MODE_P666 1 ++#define ROCKCHIP_OUT_MODE_P565 2 ++#define ROCKCHIP_OUT_MODE_BT656 5 ++#define ROCKCHIP_OUT_MODE_S888 8 ++#define ROCKCHIP_OUT_MODE_S888_DUMMY 12 ++#define ROCKCHIP_OUT_MODE_YUV420 14 ++/* for use special outface */ ++#define ROCKCHIP_OUT_MODE_AAAA 15 ++ ++enum vop_csc_format { ++ CSC_BT601L, ++ CSC_BT709L, ++ CSC_BT601F, ++ CSC_BT2020, ++}; ++ ++enum src_factor_mode { ++ SRC_FAC_ALPHA_ZERO, ++ SRC_FAC_ALPHA_ONE, ++ SRC_FAC_ALPHA_DST, ++ SRC_FAC_ALPHA_DST_INVERSE, ++ SRC_FAC_ALPHA_SRC, ++ SRC_FAC_ALPHA_SRC_GLOBAL, ++}; ++ ++enum dst_factor_mode { ++ DST_FAC_ALPHA_ZERO, ++ DST_FAC_ALPHA_ONE, ++ DST_FAC_ALPHA_SRC, ++ DST_FAC_ALPHA_SRC_INVERSE, ++ DST_FAC_ALPHA_DST, ++ DST_FAC_ALPHA_DST_GLOBAL, ++}; ++ ++#define RK3568_GRF_VO_CON1 0x0364 ++/* System registers definition */ ++#define RK3568_REG_CFG_DONE 0x000 ++#define RK3568_VERSION_INFO 0x004 ++#define RK3568_SYS_AUTO_GATING_CTRL 0x008 ++#define RK3568_SYS_AXI_LUT_CTRL 0x024 ++#define RK3568_DSP_IF_EN 0x028 ++#define RK3568_DSP_IF_CTRL 0x02c ++#define RK3568_DSP_IF_POL 0x030 ++#define RK3568_WB_CTRL 0x40 ++#define RK3568_WB_XSCAL_FACTOR 0x44 ++#define RK3568_WB_YRGB_MST 0x48 ++#define RK3568_WB_CBR_MST 0x4C ++#define RK3568_OTP_WIN_EN 0x050 ++#define RK3568_LUT_PORT_SEL 0x058 ++#define RK3568_SYS_STATUS0 0x060 ++#define RK3568_VP_LINE_FLAG(vp) (0x70 + (vp) * 0x4) ++#define RK3568_SYS0_INT_EN 0x80 ++#define RK3568_SYS0_INT_CLR 0x84 ++#define RK3568_SYS0_INT_STATUS 0x88 ++#define RK3568_SYS1_INT_EN 0x90 ++#define RK3568_SYS1_INT_CLR 0x94 ++#define RK3568_SYS1_INT_STATUS 0x98 ++#define RK3568_VP_INT_EN(vp) (0xA0 + (vp) * 0x10) ++#define RK3568_VP_INT_CLR(vp) (0xA4 + (vp) * 0x10) ++#define RK3568_VP_INT_STATUS(vp) (0xA8 + (vp) * 0x10) ++#define RK3568_VP_INT_RAW_STATUS(vp) (0xAC + (vp) * 0x10) ++ ++/* Video Port registers definition */ ++#define RK3568_VP_DSP_CTRL 0x00 ++#define RK3568_VP_MIPI_CTRL 0x04 ++#define RK3568_VP_COLOR_BAR_CTRL 0x08 ++#define RK3568_VP_3D_LUT_CTRL 0x10 ++#define RK3568_VP_3D_LUT_MST 0x20 ++#define RK3568_VP_DSP_BG 0x2C ++#define RK3568_VP_PRE_SCAN_HTIMING 0x30 ++#define RK3568_VP_POST_DSP_HACT_INFO 0x34 ++#define RK3568_VP_POST_DSP_VACT_INFO 0x38 ++#define RK3568_VP_POST_SCL_FACTOR_YRGB 0x3C ++#define RK3568_VP_POST_SCL_CTRL 0x40 ++#define RK3568_VP_POST_DSP_VACT_INFO_F1 0x44 ++#define RK3568_VP_DSP_HTOTAL_HS_END 0x48 ++#define RK3568_VP_DSP_HACT_ST_END 0x4C ++#define RK3568_VP_DSP_VTOTAL_VS_END 0x50 ++#define RK3568_VP_DSP_VACT_ST_END 0x54 ++#define RK3568_VP_DSP_VS_ST_END_F1 0x58 ++#define RK3568_VP_DSP_VACT_ST_END_F1 0x5C ++#define RK3568_VP_BCSH_CTRL 0x60 ++#define RK3568_VP_BCSH_BCS 0x64 ++#define RK3568_VP_BCSH_H 0x68 ++#define RK3568_VP_BCSH_COLOR_BAR 0x6C ++ ++/* Overlay registers definition */ ++#define RK3568_OVL_CTRL 0x600 ++#define RK3568_OVL_LAYER_SEL 0x604 ++#define RK3568_OVL_PORT_SEL 0x608 ++#define RK3568_CLUSTER0_MIX_SRC_COLOR_CTRL 0x610 ++#define RK3568_CLUSTER0_MIX_DST_COLOR_CTRL 0x614 ++#define RK3568_CLUSTER0_MIX_SRC_ALPHA_CTRL 0x618 ++#define RK3568_CLUSTER0_MIX_DST_ALPHA_CTRL 0x61C ++#define RK3568_MIX0_SRC_COLOR_CTRL 0x650 ++#define RK3568_MIX0_DST_COLOR_CTRL 0x654 ++#define RK3568_MIX0_SRC_ALPHA_CTRL 0x658 ++#define RK3568_MIX0_DST_ALPHA_CTRL 0x65C ++#define RK3568_HDR0_SRC_COLOR_CTRL 0x6C0 ++#define RK3568_HDR0_DST_COLOR_CTRL 0x6C4 ++#define RK3568_HDR0_SRC_ALPHA_CTRL 0x6C8 ++#define RK3568_HDR0_DST_ALPHA_CTRL 0x6CC ++#define RK3568_VP_BG_MIX_CTRL(vp) (0x6E0 + (vp) * 4) ++#define RK3568_CLUSTER_DLY_NUM 0x6F0 ++#define RK3568_SMART_DLY_NUM 0x6F8 ++ ++/* Cluster register definition, offset relative to window base */ ++#define RK3568_CLUSTER_WIN_CTRL0 0x00 ++#define RK3568_CLUSTER_WIN_CTRL1 0x04 ++#define RK3568_CLUSTER_WIN_YRGB_MST 0x10 ++#define RK3568_CLUSTER_WIN_CBR_MST 0x14 ++#define RK3568_CLUSTER_WIN_VIR 0x18 ++#define RK3568_CLUSTER_WIN_ACT_INFO 0x20 ++#define RK3568_CLUSTER_WIN_DSP_INFO 0x24 ++#define RK3568_CLUSTER_WIN_DSP_ST 0x28 ++#define RK3568_CLUSTER_WIN_SCL_FACTOR_YRGB 0x30 ++#define RK3568_CLUSTER_WIN_AFBCD_TRANSFORM_OFFSET 0x3C ++#define RK3568_CLUSTER_WIN_AFBCD_OUTPUT_CTRL 0x50 ++#define RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE 0x54 ++#define RK3568_CLUSTER_WIN_AFBCD_HDR_PTR 0x58 ++#define RK3568_CLUSTER_WIN_AFBCD_VIR_WIDTH 0x5C ++#define RK3568_CLUSTER_WIN_AFBCD_PIC_SIZE 0x60 ++#define RK3568_CLUSTER_WIN_AFBCD_PIC_OFFSET 0x64 ++#define RK3568_CLUSTER_WIN_AFBCD_DSP_OFFSET 0x68 ++#define RK3568_CLUSTER_WIN_AFBCD_CTRL 0x6C ++ ++#define RK3568_CLUSTER_CTRL 0x100 ++ ++/* (E)smart register definition, offset relative to window base */ ++#define RK3568_SMART_CTRL0 0x00 ++#define RK3568_SMART_CTRL1 0x04 ++#define RK3568_SMART_REGION0_CTRL 0x10 ++#define RK3568_SMART_REGION0_YRGB_MST 0x14 ++#define RK3568_SMART_REGION0_CBR_MST 0x18 ++#define RK3568_SMART_REGION0_VIR 0x1C ++#define RK3568_SMART_REGION0_ACT_INFO 0x20 ++#define RK3568_SMART_REGION0_DSP_INFO 0x24 ++#define RK3568_SMART_REGION0_DSP_ST 0x28 ++#define RK3568_SMART_REGION0_SCL_CTRL 0x30 ++#define RK3568_SMART_REGION0_SCL_FACTOR_YRGB 0x34 ++#define RK3568_SMART_REGION0_SCL_FACTOR_CBR 0x38 ++#define RK3568_SMART_REGION0_SCL_OFFSET 0x3C ++#define RK3568_SMART_REGION1_CTRL 0x40 ++#define RK3568_SMART_REGION1_YRGB_MST 0x44 ++#define RK3568_SMART_REGION1_CBR_MST 0x48 ++#define RK3568_SMART_REGION1_VIR 0x4C ++#define RK3568_SMART_REGION1_ACT_INFO 0x50 ++#define RK3568_SMART_REGION1_DSP_INFO 0x54 ++#define RK3568_SMART_REGION1_DSP_ST 0x58 ++#define RK3568_SMART_REGION1_SCL_CTRL 0x60 ++#define RK3568_SMART_REGION1_SCL_FACTOR_YRGB 0x64 ++#define RK3568_SMART_REGION1_SCL_FACTOR_CBR 0x68 ++#define RK3568_SMART_REGION1_SCL_OFFSET 0x6C ++#define RK3568_SMART_REGION2_CTRL 0x70 ++#define RK3568_SMART_REGION2_YRGB_MST 0x74 ++#define RK3568_SMART_REGION2_CBR_MST 0x78 ++#define RK3568_SMART_REGION2_VIR 0x7C ++#define RK3568_SMART_REGION2_ACT_INFO 0x80 ++#define RK3568_SMART_REGION2_DSP_INFO 0x84 ++#define RK3568_SMART_REGION2_DSP_ST 0x88 ++#define RK3568_SMART_REGION2_SCL_CTRL 0x90 ++#define RK3568_SMART_REGION2_SCL_FACTOR_YRGB 0x94 ++#define RK3568_SMART_REGION2_SCL_FACTOR_CBR 0x98 ++#define RK3568_SMART_REGION2_SCL_OFFSET 0x9C ++#define RK3568_SMART_REGION3_CTRL 0xA0 ++#define RK3568_SMART_REGION3_YRGB_MST 0xA4 ++#define RK3568_SMART_REGION3_CBR_MST 0xA8 ++#define RK3568_SMART_REGION3_VIR 0xAC ++#define RK3568_SMART_REGION3_ACT_INFO 0xB0 ++#define RK3568_SMART_REGION3_DSP_INFO 0xB4 ++#define RK3568_SMART_REGION3_DSP_ST 0xB8 ++#define RK3568_SMART_REGION3_SCL_CTRL 0xC0 ++#define RK3568_SMART_REGION3_SCL_FACTOR_YRGB 0xC4 ++#define RK3568_SMART_REGION3_SCL_FACTOR_CBR 0xC8 ++#define RK3568_SMART_REGION3_SCL_OFFSET 0xCC ++#define RK3568_SMART_COLOR_KEY_CTRL 0xD0 ++ ++/* HDR register definition */ ++#define RK3568_HDR_LUT_CTRL 0x2000 ++#define RK3568_HDR_LUT_MST 0x2004 ++#define RK3568_SDR2HDR_CTRL 0x2010 ++#define RK3568_HDR2SDR_CTRL 0x2020 ++#define RK3568_HDR2SDR_SRC_RANGE 0x2024 ++#define RK3568_HDR2SDR_NORMFACEETF 0x2028 ++#define RK3568_HDR2SDR_DST_RANGE 0x202C ++#define RK3568_HDR2SDR_NORMFACCGAMMA 0x2030 ++#define RK3568_HDR_EETF_OETF_Y0 0x203C ++#define RK3568_HDR_SAT_Y0 0x20C0 ++#define RK3568_HDR_EOTF_OETF_Y0 0x20F0 ++#define RK3568_HDR_OETF_DX_POW1 0x2200 ++#define RK3568_HDR_OETF_XN1 0x2300 ++ ++#define RK3568_REG_CFG_DONE__GLB_CFG_DONE_EN BIT(15) ++ ++#define RK3568_VP_DSP_CTRL__STANDBY BIT(31) ++#define RK3568_VP_DSP_CTRL__DITHER_DOWN_MODE BIT(20) ++#define RK3568_VP_DSP_CTRL__DITHER_DOWN_SEL GENMASK(19, 18) ++#define RK3568_VP_DSP_CTRL__DITHER_DOWN_EN BIT(17) ++#define RK3568_VP_DSP_CTRL__PRE_DITHER_DOWN_EN BIT(16) ++#define RK3568_VP_DSP_CTRL__POST_DSP_OUT_R2Y BIT(15) ++#define RK3568_VP_DSP_CTRL__DSP_RB_SWAP BIT(9) ++#define RK3568_VP_DSP_CTRL__DSP_INTERLACE BIT(7) ++#define RK3568_VP_DSP_CTRL__DSP_FILED_POL BIT(6) ++#define RK3568_VP_DSP_CTRL__P2I_EN BIT(5) ++#define RK3568_VP_DSP_CTRL__CORE_DCLK_DIV BIT(4) ++#define RK3568_VP_DSP_CTRL__OUT_MODE GENMASK(3, 0) ++ ++#define RK3568_VP_POST_SCL_CTRL__VSCALEDOWN BIT(1) ++#define RK3568_VP_POST_SCL_CTRL__HSCALEDOWN BIT(0) ++ ++#define RK3568_SYS_DSP_INFACE_EN_LVDS1_MUX GENMASK(26, 25) ++#define RK3568_SYS_DSP_INFACE_EN_LVDS1 BIT(24) ++#define RK3568_SYS_DSP_INFACE_EN_MIPI1_MUX GENMASK(22, 21) ++#define RK3568_SYS_DSP_INFACE_EN_MIPI1 BIT(20) ++#define RK3568_SYS_DSP_INFACE_EN_LVDS0_MUX GENMASK(19, 18) ++#define RK3568_SYS_DSP_INFACE_EN_MIPI0_MUX GENMASK(17, 16) ++#define RK3568_SYS_DSP_INFACE_EN_EDP_MUX GENMASK(15, 14) ++#define RK3568_SYS_DSP_INFACE_EN_HDMI_MUX GENMASK(11, 10) ++#define RK3568_SYS_DSP_INFACE_EN_RGB_MUX GENMASK(9, 8) ++#define RK3568_SYS_DSP_INFACE_EN_LVDS0 BIT(5) ++#define RK3568_SYS_DSP_INFACE_EN_MIPI0 BIT(4) ++#define RK3568_SYS_DSP_INFACE_EN_EDP BIT(3) ++#define RK3568_SYS_DSP_INFACE_EN_HDMI BIT(1) ++#define RK3568_SYS_DSP_INFACE_EN_RGB BIT(0) ++ ++#define RK3568_DSP_IF_POL__MIPI_PIN_POL GENMASK(19, 16) ++#define RK3568_DSP_IF_POL__EDP_PIN_POL GENMASK(15, 12) ++#define RK3568_DSP_IF_POL__HDMI_PIN_POL GENMASK(7, 4) ++#define RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL GENMASK(3, 0) ++ ++#define RK3568_VP0_MIPI_CTRL__DCLK_DIV2_PHASE_LOCK BIT(5) ++#define RK3568_VP0_MIPI_CTRL__DCLK_DIV2 BIT(4) ++ ++#define RK3568_SYS_AUTO_GATING_CTRL__AUTO_GATING_EN BIT(31) ++ ++#define RK3568_DSP_IF_POL__CFG_DONE_IMD BIT(28) ++ ++#define VOP2_SYS_AXI_BUS_NUM 2 ++ ++#define VOP2_CLUSTER_YUV444_10 0x12 ++ ++#define VOP2_COLOR_KEY_MASK BIT(31) ++ ++#define RK3568_OVL_CTRL__LAYERSEL_REGDONE_IMD BIT(28) ++ ++#define RK3568_VP_BG_MIX_CTRL__BG_DLY GENMASK(31, 24) ++ ++#define RK3568_OVL_PORT_SEL__SEL_PORT GENMASK(31, 16) ++#define RK3568_OVL_PORT_SEL__SMART1 GENMASK(31, 30) ++#define RK3568_OVL_PORT_SEL__SMART0 GENMASK(29, 28) ++#define RK3568_OVL_PORT_SEL__ESMART1 GENMASK(27, 26) ++#define RK3568_OVL_PORT_SEL__ESMART0 GENMASK(25, 24) ++#define RK3568_OVL_PORT_SEL__CLUSTER1 GENMASK(19, 18) ++#define RK3568_OVL_PORT_SEL__CLUSTER0 GENMASK(17, 16) ++#define RK3568_OVL_PORT_SET__PORT2_MUX GENMASK(11, 8) ++#define RK3568_OVL_PORT_SET__PORT1_MUX GENMASK(7, 4) ++#define RK3568_OVL_PORT_SET__PORT0_MUX GENMASK(3, 0) ++#define RK3568_OVL_LAYER_SEL__LAYER(layer, x) ((x) << ((layer) * 4)) ++ ++#define RK3568_CLUSTER_DLY_NUM__CLUSTER1_1 GENMASK(31, 24) ++#define RK3568_CLUSTER_DLY_NUM__CLUSTER1_0 GENMASK(23, 16) ++#define RK3568_CLUSTER_DLY_NUM__CLUSTER0_1 GENMASK(15, 8) ++#define RK3568_CLUSTER_DLY_NUM__CLUSTER0_0 GENMASK(7, 0) ++ ++#define RK3568_SMART_DLY_NUM__SMART1 GENMASK(31, 24) ++#define RK3568_SMART_DLY_NUM__SMART0 GENMASK(23, 16) ++#define RK3568_SMART_DLY_NUM__ESMART1 GENMASK(15, 8) ++#define RK3568_SMART_DLY_NUM__ESMART0 GENMASK(7, 0) ++ ++#define VP_INT_DSP_HOLD_VALID BIT(6) ++#define VP_INT_FS_FIELD BIT(5) ++#define VP_INT_POST_BUF_EMPTY BIT(4) ++#define VP_INT_LINE_FLAG1 BIT(3) ++#define VP_INT_LINE_FLAG0 BIT(2) ++#define VOP2_INT_BUS_ERRPR BIT(1) ++#define VP_INT_FS BIT(0) ++ ++#define POLFLAG_DCLK_INV BIT(3) ++ ++enum vop2_layer_phy_id { ++ ROCKCHIP_VOP2_CLUSTER0 = 0, ++ ROCKCHIP_VOP2_CLUSTER1, ++ ROCKCHIP_VOP2_ESMART0, ++ ROCKCHIP_VOP2_ESMART1, ++ ROCKCHIP_VOP2_SMART0, ++ ROCKCHIP_VOP2_SMART1, ++ ROCKCHIP_VOP2_CLUSTER2, ++ ROCKCHIP_VOP2_CLUSTER3, ++ ROCKCHIP_VOP2_ESMART2, ++ ROCKCHIP_VOP2_ESMART3, ++ ROCKCHIP_VOP2_PHY_ID_INVALID = -1, ++}; ++ ++extern const struct component_ops vop2_component_ops; ++ ++#endif /* _ROCKCHIP_DRM_VOP2_H */ +diff --git a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c +new file mode 100644 +index 0000000000000..2376e63d9478f +--- /dev/null ++++ b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c +@@ -0,0 +1,285 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * Copyright (C) Rockchip Electronics Co.Ltd ++ * Author: Andy Yan ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "rockchip_drm_vop2.h" ++ ++static const uint32_t formats_win_full_10bit[] = { ++ DRM_FORMAT_XRGB8888, ++ DRM_FORMAT_ARGB8888, ++ DRM_FORMAT_XBGR8888, ++ DRM_FORMAT_ABGR8888, ++ DRM_FORMAT_RGB888, ++ DRM_FORMAT_BGR888, ++ DRM_FORMAT_RGB565, ++ DRM_FORMAT_BGR565, ++ DRM_FORMAT_NV12, ++ DRM_FORMAT_NV16, ++ DRM_FORMAT_NV24, ++}; ++ ++static const uint32_t formats_win_full_10bit_yuyv[] = { ++ DRM_FORMAT_XRGB8888, ++ DRM_FORMAT_ARGB8888, ++ DRM_FORMAT_XBGR8888, ++ DRM_FORMAT_ABGR8888, ++ DRM_FORMAT_RGB888, ++ DRM_FORMAT_BGR888, ++ DRM_FORMAT_RGB565, ++ DRM_FORMAT_BGR565, ++ DRM_FORMAT_NV12, ++ DRM_FORMAT_NV16, ++ DRM_FORMAT_NV24, ++ DRM_FORMAT_YVYU, ++ DRM_FORMAT_VYUY, ++}; ++ ++static const uint32_t formats_win_lite[] = { ++ DRM_FORMAT_XRGB8888, ++ DRM_FORMAT_ARGB8888, ++ DRM_FORMAT_XBGR8888, ++ DRM_FORMAT_ABGR8888, ++ DRM_FORMAT_RGB888, ++ DRM_FORMAT_BGR888, ++ DRM_FORMAT_RGB565, ++ DRM_FORMAT_BGR565, ++}; ++ ++static const uint64_t format_modifiers[] = { ++ DRM_FORMAT_MOD_LINEAR, ++ DRM_FORMAT_MOD_INVALID, ++}; ++ ++static const uint64_t format_modifiers_afbc[] = { ++ DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16), ++ ++ DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 | ++ AFBC_FORMAT_MOD_SPARSE), ++ ++ DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 | ++ AFBC_FORMAT_MOD_YTR), ++ ++ DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 | ++ AFBC_FORMAT_MOD_CBR), ++ ++ DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 | ++ AFBC_FORMAT_MOD_YTR | ++ AFBC_FORMAT_MOD_SPARSE), ++ ++ DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 | ++ AFBC_FORMAT_MOD_CBR | ++ AFBC_FORMAT_MOD_SPARSE), ++ ++ DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 | ++ AFBC_FORMAT_MOD_YTR | ++ AFBC_FORMAT_MOD_CBR), ++ ++ DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 | ++ AFBC_FORMAT_MOD_YTR | ++ AFBC_FORMAT_MOD_CBR | ++ AFBC_FORMAT_MOD_SPARSE), ++ ++ /* SPLIT mandates SPARSE, RGB modes mandates YTR */ ++ DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 | ++ AFBC_FORMAT_MOD_YTR | ++ AFBC_FORMAT_MOD_SPARSE | ++ AFBC_FORMAT_MOD_SPLIT), ++ DRM_FORMAT_MOD_INVALID, ++}; ++ ++static const struct vop2_video_port_data rk3568_vop_video_ports[] = { ++ { ++ .id = 0, ++ .feature = VOP_FEATURE_OUTPUT_10BIT, ++ .gamma_lut_len = 1024, ++ .cubic_lut_len = 9 * 9 * 9, ++ .max_output = { 4096, 2304 }, ++ .pre_scan_max_dly = { 69, 53, 53, 42 }, ++ .offset = 0xc00, ++ }, { ++ .id = 1, ++ .gamma_lut_len = 1024, ++ .max_output = { 2048, 1536 }, ++ .pre_scan_max_dly = { 40, 40, 40, 40 }, ++ .offset = 0xd00, ++ }, { ++ .id = 2, ++ .gamma_lut_len = 1024, ++ .max_output = { 1920, 1080 }, ++ .pre_scan_max_dly = { 40, 40, 40, 40 }, ++ .offset = 0xe00, ++ }, ++}; ++ ++/* ++ * rk3568 vop with 2 cluster, 2 esmart win, 2 smart win. ++ * Every cluster can work as 4K win or split into two win. ++ * All win in cluster support AFBCD. ++ * ++ * Every esmart win and smart win support 4 Multi-region. ++ * ++ * Scale filter mode: ++ * ++ * * Cluster: bicubic for horizontal scale up, others use bilinear ++ * * ESmart: ++ * * nearest-neighbor/bilinear/bicubic for scale up ++ * * nearest-neighbor/bilinear/average for scale down ++ * ++ * ++ * @TODO describe the wind like cpu-map dt nodes; ++ */ ++static const struct vop2_win_data rk3568_vop_win_data[] = { ++ { ++ .name = "Smart0-win0", ++ .phys_id = ROCKCHIP_VOP2_SMART0, ++ .base = 0x1c00, ++ .formats = formats_win_lite, ++ .nformats = ARRAY_SIZE(formats_win_lite), ++ .format_modifiers = format_modifiers, ++ .layer_sel_id = 3, ++ .supported_rotations = DRM_MODE_REFLECT_Y, ++ .type = DRM_PLANE_TYPE_PRIMARY, ++ .max_upscale_factor = 8, ++ .max_downscale_factor = 8, ++ .dly = { 20, 47, 41 }, ++ }, { ++ .name = "Smart1-win0", ++ .phys_id = ROCKCHIP_VOP2_SMART1, ++ .formats = formats_win_lite, ++ .nformats = ARRAY_SIZE(formats_win_lite), ++ .format_modifiers = format_modifiers, ++ .base = 0x1e00, ++ .layer_sel_id = 7, ++ .supported_rotations = DRM_MODE_REFLECT_Y, ++ .type = DRM_PLANE_TYPE_PRIMARY, ++ .max_upscale_factor = 8, ++ .max_downscale_factor = 8, ++ .dly = { 20, 47, 41 }, ++ }, { ++ .name = "Esmart1-win0", ++ .phys_id = ROCKCHIP_VOP2_ESMART1, ++ .formats = formats_win_full_10bit_yuyv, ++ .nformats = ARRAY_SIZE(formats_win_full_10bit_yuyv), ++ .format_modifiers = format_modifiers, ++ .base = 0x1a00, ++ .layer_sel_id = 6, ++ .supported_rotations = DRM_MODE_REFLECT_Y, ++ .type = DRM_PLANE_TYPE_PRIMARY, ++ .max_upscale_factor = 8, ++ .max_downscale_factor = 8, ++ .dly = { 20, 47, 41 }, ++ }, { ++ .name = "Esmart0-win0", ++ .phys_id = ROCKCHIP_VOP2_ESMART0, ++ .formats = formats_win_full_10bit_yuyv, ++ .nformats = ARRAY_SIZE(formats_win_full_10bit_yuyv), ++ .format_modifiers = format_modifiers, ++ .base = 0x1800, ++ .layer_sel_id = 2, ++ .supported_rotations = DRM_MODE_REFLECT_Y, ++ .type = DRM_PLANE_TYPE_OVERLAY, ++ .max_upscale_factor = 8, ++ .max_downscale_factor = 8, ++ .dly = { 20, 47, 41 }, ++ }, { ++ .name = "Cluster0-win0", ++ .phys_id = ROCKCHIP_VOP2_CLUSTER0, ++ .base = 0x1000, ++ .formats = formats_win_full_10bit, ++ .nformats = ARRAY_SIZE(formats_win_full_10bit), ++ .format_modifiers = format_modifiers_afbc, ++ .layer_sel_id = 0, ++ .supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 | ++ DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y, ++ .max_upscale_factor = 4, ++ .max_downscale_factor = 4, ++ .dly = { 0, 27, 21 }, ++ .type = DRM_PLANE_TYPE_OVERLAY, ++ .feature = WIN_FEATURE_AFBDC | WIN_FEATURE_CLUSTER, ++ }, { ++ .name = "Cluster1-win0", ++ .phys_id = ROCKCHIP_VOP2_CLUSTER1, ++ .base = 0x1200, ++ .formats = formats_win_full_10bit, ++ .nformats = ARRAY_SIZE(formats_win_full_10bit), ++ .format_modifiers = format_modifiers_afbc, ++ .layer_sel_id = 1, ++ .supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 | ++ DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y, ++ .type = DRM_PLANE_TYPE_OVERLAY, ++ .max_upscale_factor = 4, ++ .max_downscale_factor = 4, ++ .dly = { 0, 27, 21 }, ++ .feature = WIN_FEATURE_AFBDC | WIN_FEATURE_CLUSTER, ++ }, ++}; ++ ++static const struct vop2_data rk3566_vop = { ++ .nr_vps = 3, ++ .nr_mixers = 5, ++ .nr_gammas = 1, ++ .max_input = { 4096, 2304 }, ++ .max_output = { 4096, 2304 }, ++ .vp = rk3568_vop_video_ports, ++ .win = rk3568_vop_win_data, ++ .win_size = ARRAY_SIZE(rk3568_vop_win_data), ++ .soc_id = 3566, ++}; ++ ++static const struct vop2_data rk3568_vop = { ++ .nr_vps = 3, ++ .nr_mixers = 5, ++ .nr_gammas = 1, ++ .max_input = { 4096, 2304 }, ++ .max_output = { 4096, 2304 }, ++ .vp = rk3568_vop_video_ports, ++ .win = rk3568_vop_win_data, ++ .win_size = ARRAY_SIZE(rk3568_vop_win_data), ++ .soc_id = 3568, ++}; ++ ++static const struct of_device_id vop2_dt_match[] = { ++ { ++ .compatible = "rockchip,rk3566-vop", ++ .data = &rk3566_vop, ++ }, { ++ .compatible = "rockchip,rk3568-vop", ++ .data = &rk3568_vop, ++ }, { ++ }, ++}; ++MODULE_DEVICE_TABLE(of, vop2_dt_match); ++ ++static int vop2_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ ++ return component_add(dev, &vop2_component_ops); ++} ++ ++static int vop2_remove(struct platform_device *pdev) ++{ ++ component_del(&pdev->dev, &vop2_component_ops); ++ ++ return 0; ++} ++ ++struct platform_driver vop2_platform_driver = { ++ .probe = vop2_probe, ++ .remove = vop2_remove, ++ .driver = { ++ .name = "rockchip-vop2", ++ .of_match_table = of_match_ptr(vop2_dt_match), ++ }, ++}; diff --git a/patch/kernel/archive/rk35xx-5.16/rk356x-gpu-GPU.patch b/patch/kernel/archive/rk35xx-5.16/rk356x-gpu-GPU.patch new file mode 100644 index 0000000000..e238f4ea3c --- /dev/null +++ b/patch/kernel/archive/rk35xx-5.16/rk356x-gpu-GPU.patch @@ -0,0 +1,215 @@ +Commit b681af0bc1cc ("drm: panfrost: add optional bus_clock") +added an optional bus_clock to support Allwinner H6 T-720 GPU. +Increase the max clock items in the dt-binding to reflect this. + +Bifrost GPU in Rockchip RK3568 SoCs also has a core and a bus clock +and it gets added here in a (very) similar way it was done for +allwinner,sun50i-h6-mali compatible in arm,mali-midgard binding. + +Signed-off-by: Alex Bee +--- + .../bindings/gpu/arm,mali-bifrost.yaml | 20 ++++++++++++++++++- + 1 file changed, 19 insertions(+), 1 deletion(-) + +diff --git a/Documentation/devicetree/bindings/gpu/arm,mali-bifrost.yaml b/Documentation/devicetree/bindings/gpu/arm,mali-bifrost.yaml +index 6f98dd55fb4c..2849a7a97d73 100644 +--- a/Documentation/devicetree/bindings/gpu/arm,mali-bifrost.yaml ++++ b/Documentation/devicetree/bindings/gpu/arm,mali-bifrost.yaml +@@ -39,7 +39,14 @@ properties: + - const: gpu + + clocks: +- maxItems: 1 ++ minItems: 1 ++ maxItems: 2 ++ ++ clock-names: ++ minItems: 1 ++ items: ++ - const: core ++ - const: bus + + mali-supply: true + +@@ -118,6 +125,17 @@ allOf: + power-domains: + maxItems: 1 + sram-supply: false ++ - if: ++ properties: ++ compatible: ++ contains: ++ const: rockchip,rk3568-mali ++ then: ++ properties: ++ clocks: ++ minItems: 2 ++ required: ++ - clock-names + + examples: + - | + +From: Ezequiel Garcia + +Rockchip SoCs RK3566 and RK3568 have a Mali Gondul core +which is based on the Bifrost architecture. It has +one shader core and two execution engines. + +Quoting the datasheet: + +Mali-G52 1-Core-2EE +* Support 1600Mpix/s fill rate when 800MHz clock frequency +* Support 38.4GLOPs when 800MHz clock frequency + +Signed-off-by: Ezequiel Garcia +Signed-off-by: Alex Bee +--- + arch/arm64/boot/dts/rockchip/rk356x.dtsi | 50 ++++++++++++++++++++++++ + 1 file changed, 50 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk356x.dtsi b/arch/arm64/boot/dts/rockchip/rk356x.dtsi +index 46d9552f6028..3b314ccd6c94 100644 +--- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi +@@ -125,6 +125,40 @@ opp-1800000000 { + }; + }; + ++ gpu_opp_table: opp-table-1 { ++ compatible = "operating-points-v2"; ++ ++ opp-200000000 { ++ opp-hz = /bits/ 64 <200000000>; ++ opp-microvolt = <825000>; ++ }; ++ ++ opp-300000000 { ++ opp-hz = /bits/ 64 <300000000>; ++ opp-microvolt = <825000>; ++ }; ++ ++ opp-400000000 { ++ opp-hz = /bits/ 64 <400000000>; ++ opp-microvolt = <825000>; ++ }; ++ ++ opp-600000000 { ++ opp-hz = /bits/ 64 <600000000>; ++ opp-microvolt = <825000>; ++ }; ++ ++ opp-700000000 { ++ opp-hz = /bits/ 64 <700000000>; ++ opp-microvolt = <900000>; ++ }; ++ ++ opp-800000000 { ++ opp-hz = /bits/ 64 <800000000>; ++ opp-microvolt = <1000000>; ++ }; ++ }; ++ + firmware { + scmi: scmi { + compatible = "arm,scmi-smc"; +@@ -386,6 +420,22 @@ power-domain@RK3568_PD_RKVENC { + }; + }; + ++ gpu: gpu@fde60000 { ++ compatible = "rockchip,rk3568-mali", "arm,mali-bifrost"; ++ reg = <0x0 0xfde60000 0x0 0x4000>; ++ ++ interrupts = , ++ , ++ ; ++ interrupt-names = "job", "mmu", "gpu"; ++ clocks = <&scmi_clk 1>, <&cru CLK_GPU>; ++ clock-names = "core", "bus"; ++ operating-points-v2 = <&gpu_opp_table>; ++ #cooling-cells = <2>; ++ power-domains = <&power RK3568_PD_GPU>; ++ status = "disabled"; ++ }; ++ + sdmmc2: mmc@fe000000 { + compatible = "rockchip,rk3568-dw-mshc", "rockchip,rk3288-dw-mshc"; + reg = <0x0 0xfe000000 0x0 0x4000>; + + +RK356x SoCs have a second thermal sensor for the GPU: +This adds the cooling map / trip points for it to make use of it's +contribution as a cooling device. + +Signed-off-by: Alex Bee +--- + arch/arm64/boot/dts/rockchip/rk356x.dtsi | 27 ++++++++++++++++++++++++ + 1 file changed, 27 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk356x.dtsi b/arch/arm64/boot/dts/rockchip/rk356x.dtsi +index 3b314ccd6c94..a67c279c164d 100644 +--- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi +@@ -960,6 +960,33 @@ gpu_thermal: gpu-thermal { + polling-delay = <1000>; /* milliseconds */ + + thermal-sensors = <&tsadc 1>; ++ ++ trips { ++ gpu_threshold: gpu-threshold { ++ temperature = <70000>; ++ hysteresis = <2000>; ++ type = "passive"; ++ }; ++ gpu_target: gpu-target { ++ temperature = <75000>; ++ hysteresis = <2000>; ++ type = "passive"; ++ }; ++ gpu_crit: gpu-crit { ++ temperature = <95000>; ++ hysteresis = <2000>; ++ type = "critical"; ++ }; ++ }; ++ ++ cooling-maps { ++ map0 { ++ trip = <&gpu_target>; ++ cooling-device = ++ <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; ++ }; ++ }; ++ + }; + }; + + + +From: Ezequiel Garcia + +Enable the GPU core on the Pine64 Quartz64 Model A. + +Signed-off-by: Ezequiel Garcia +Signed-off-by: Alex Bee +--- + arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts +index 4d4b2a301b1a..625489c60622 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts +@@ -205,6 +205,11 @@ &gmac1m0_clkinout + status = "okay"; + }; + ++&gpu { ++ mali-supply = <&vdd_gpu>; ++ status = "okay"; ++}; ++ + &i2c0 { + status = "okay"; + diff --git a/patch/kernel/archive/rk35xx-5.16/rk356x-hdmi-audio.patch b/patch/kernel/archive/rk35xx-5.16/rk356x-hdmi-audio.patch new file mode 100644 index 0000000000..1aec35d1cc --- /dev/null +++ b/patch/kernel/archive/rk35xx-5.16/rk356x-hdmi-audio.patch @@ -0,0 +1,103 @@ +This adds the i2s0 node and an hdmi-sound sound device to the +rk356x device tree. On the rk356[68], the i2s0 controller is +connected to HDMI audio. + +Tested-by: Michael Riesch +Signed-off-by: Nicolas Frattaroli +--- + +Changes in v2: + - reordered nodes to conform + - reordered properties to conform + - add Michael Riesch's Tested-by + + arch/arm64/boot/dts/rockchip/rk356x.dtsi | 33 ++++++++++++++++++++++++ + 1 file changed, 33 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk356x.dtsi b/arch/arm64/boot/dts/rockchip/rk356x.dtsi +index 3c09cf6d4c37..aafb622dfa83 100644 +--- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi +@@ -174,6 +174,22 @@ scmi_clk: protocol@14 { + }; + }; + ++ hdmi_sound: hdmi-sound { ++ compatible = "simple-audio-card"; ++ simple-audio-card,name = "HDMI"; ++ simple-audio-card,format = "i2s"; ++ simple-audio-card,mclk-fs = <256>; ++ status = "disabled"; ++ ++ simple-audio-card,codec { ++ sound-dai = <&hdmi>; ++ }; ++ ++ simple-audio-card,cpu { ++ sound-dai = <&i2s0_8ch>; ++ }; ++ }; ++ + pmu { + compatible = "arm,cortex-a55-pmu"; + interrupts = , +@@ -789,6 +805,23 @@ spdif: spdif@fe460000 { + status = "disabled"; + }; + ++ i2s0_8ch: i2s@fe400000 { ++ compatible = "rockchip,rk3568-i2s-tdm"; ++ reg = <0x0 0xfe400000 0x0 0x1000>; ++ interrupts = ; ++ assigned-clocks = <&cru CLK_I2S0_8CH_TX_SRC>, <&cru CLK_I2S0_8CH_RX_SRC>; ++ assigned-clock-rates = <1188000000>, <1188000000>; ++ clocks = <&cru MCLK_I2S0_8CH_TX>, <&cru MCLK_I2S0_8CH_RX>, <&cru HCLK_I2S0_8CH>; ++ clock-names = "mclk_tx", "mclk_rx", "hclk"; ++ dmas = <&dmac1 0>; ++ dma-names = "tx"; ++ resets = <&cru SRST_M_I2S0_8CH_TX>, <&cru SRST_M_I2S0_8CH_RX>; ++ reset-names = "tx-m", "rx-m"; ++ rockchip,grf = <&grf>; ++ #sound-dai-cells = <0>; ++ status = "disabled"; ++ }; ++ + i2s1_8ch: i2s@fe410000 { + compatible = "rockchip,rk3568-i2s-tdm"; + reg = <0x0 0xfe410000 0x0 0x1000>; + + +This enables the i2s0 controller and the hdmi-sound node on +the PINE64 Quartz64 Model A single-board computer. + +Signed-off-by: Nicolas Frattaroli +--- + arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts +index a4453c82b03d..0598510dce58 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts +@@ -215,6 +215,10 @@ &hdmi_in_vp0 { + status = "okay"; + }; + ++&hdmi_sound { ++ status = "okay"; ++}; ++ + &gpu { + mali-supply = <&vdd_gpu>; + status = "okay"; +@@ -444,6 +448,10 @@ regulator-state-mem { + }; + }; + ++&i2s0_8ch { ++ status = "okay"; ++}; ++ + &i2s1_8ch { + pinctrl-names = "default"; + pinctrl-0 = <&i2s1m0_sclktx diff --git a/patch/kernel/archive/rk35xx-5.16/rk356x-mfd-rk808-add-reboot-support-to-rk808.c.patch b/patch/kernel/archive/rk35xx-5.16/rk356x-mfd-rk808-add-reboot-support-to-rk808.c.patch new file mode 100644 index 0000000000..24f4dbe32f --- /dev/null +++ b/patch/kernel/archive/rk35xx-5.16/rk356x-mfd-rk808-add-reboot-support-to-rk808.c.patch @@ -0,0 +1,95 @@ +diff --git a/drivers/mfd/rk808.c b/drivers/mfd/rk808.c +index b181fe401330..874d461dda44 100644 +--- a/drivers/mfd/rk808.c ++++ b/drivers/mfd/rk808.c +@@ -19,6 +19,7 @@ + #include + #include + #include ++#include + + struct rk808_reg_data { + int addr; +@@ -543,6 +544,7 @@ static void rk808_pm_power_off(void) + reg = RK808_DEVCTRL_REG, + bit = DEV_OFF_RST; + break; ++ case RK809_ID: + case RK817_ID: + reg = RK817_SYS_CFG(3); + bit = DEV_OFF; +@@ -559,6 +561,34 @@ static void rk808_pm_power_off(void) + dev_err(&rk808_i2c_client->dev, "Failed to shutdown device!\n"); + } + ++static int rk808_restart_notify(struct notifier_block *this, unsigned long mode, void *cmd) ++{ ++ struct rk808 *rk808 = i2c_get_clientdata(rk808_i2c_client); ++ unsigned int reg, bit; ++ int ret; ++ ++ switch (rk808->variant) { ++ case RK809_ID: ++ case RK817_ID: ++ reg = RK817_SYS_CFG(3); ++ bit = DEV_RST; ++ break; ++ ++ default: ++ return NOTIFY_DONE; ++ } ++ ret = regmap_update_bits(rk808->regmap, reg, bit, bit); ++ if (ret) ++ dev_err(&rk808_i2c_client->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); +@@ -727,6 +757,18 @@ static int rk808_probe(struct i2c_client *client, + if (of_property_read_bool(np, "rockchip,system-power-controller")) { + rk808_i2c_client = client; + pm_power_off = rk808_pm_power_off; ++ ++ switch (rk808->variant) { ++ case RK809_ID: ++ case RK817_ID: ++ ret = register_restart_handler(&rk808_restart_handler); ++ if (ret) ++ dev_warn(&client->dev, "failed to register restart handler, %d\n", ret); ++ break; ++ default: ++ dev_dbg(&client->dev, "pmic controlled board reset not supported\n"); ++ break; ++ } + } + + return 0; +@@ -749,6 +791,8 @@ static int rk808_remove(struct i2c_client *client) + if (pm_power_off == rk808_pm_power_off) + pm_power_off = NULL; + ++ unregister_restart_handler(&rk808_restart_handler); ++ + return 0; + } + +diff --git a/include/linux/mfd/rk808.h b/include/linux/mfd/rk808.h +index a96e6d43ca06..58602032e642 100644 +--- a/include/linux/mfd/rk808.h ++++ b/include/linux/mfd/rk808.h +@@ -373,6 +373,7 @@ enum rk805_reg { + #define SWITCH2_EN BIT(6) + #define SWITCH1_EN BIT(5) + #define DEV_OFF_RST BIT(3) ++#define DEV_RST BIT(2) + #define DEV_OFF BIT(0) + #define RTC_STOP BIT(0) + diff --git a/patch/kernel/archive/rk35xx-5.16/rk356x-naneng-combo-phy.patch b/patch/kernel/archive/rk35xx-5.16/rk356x-naneng-combo-phy.patch new file mode 100644 index 0000000000..404ab5a9c3 --- /dev/null +++ b/patch/kernel/archive/rk35xx-5.16/rk356x-naneng-combo-phy.patch @@ -0,0 +1,987 @@ +From: Johan Jonker + +Add naneng combo phy register compatible. + +Acked-by: Rob Herring +Signed-off-by: Johan Jonker +Signed-off-by: Yifeng Zhao +--- + +Changes in v7: None +Changes in v5: None +Changes in v4: None +Changes in v3: None +Changes in v2: None + + Documentation/devicetree/bindings/mfd/syscon.yaml | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/Documentation/devicetree/bindings/mfd/syscon.yaml b/Documentation/devicetree/bindings/mfd/syscon.yaml +index fdd96e378df0..e9bb96ab9446 100644 +--- a/Documentation/devicetree/bindings/mfd/syscon.yaml ++++ b/Documentation/devicetree/bindings/mfd/syscon.yaml +@@ -52,6 +52,8 @@ properties: + - rockchip,rk3288-qos + - rockchip,rk3368-qos + - rockchip,rk3399-qos ++ - rockchip,rk3568-pipe-grf ++ - rockchip,rk3568-pipe-phy-grf + - rockchip,rk3568-qos + - samsung,exynos3-sysreg + - samsung,exynos4-sysreg + +Add the compatible strings for the Naneng combo PHY found on rockchip SoC. + +Reviewed-by: Rob Herring +Signed-off-by: Yifeng Zhao +Signed-off-by: Johan Jonker +--- + +Changes in v7: +- remove u3otg0_port_en, u3otg1_port_en and pipe_sgmii_mac_sel + +Changes in v5: +- modify description for ssc and ext-refclk +- remove apb reset + +Changes in v4: +- restyle +- remove some minItems +- add more properties +- remove reset-names +- move #phy-cells +- add rockchip,rk3568-pipe-grf +- add rockchip,rk3568-pipe-phy-grf + +Changes in v3: None +Changes in v2: +- Fix dtschema/dtc warnings/errors + + .../phy/phy-rockchip-naneng-combphy.yaml | 109 ++++++++++++++++++ + 1 file changed, 109 insertions(+) + create mode 100644 Documentation/devicetree/bindings/phy/phy-rockchip-naneng-combphy.yaml + +diff --git a/Documentation/devicetree/bindings/phy/phy-rockchip-naneng-combphy.yaml b/Documentation/devicetree/bindings/phy/phy-rockchip-naneng-combphy.yaml +new file mode 100644 +index 000000000000..f14454401419 +--- /dev/null ++++ b/Documentation/devicetree/bindings/phy/phy-rockchip-naneng-combphy.yaml +@@ -0,0 +1,109 @@ ++# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) ++%YAML 1.2 ++--- ++$id: http://devicetree.org/schemas/phy/phy-rockchip-naneng-combphy.yaml# ++$schema: http://devicetree.org/meta-schemas/core.yaml# ++ ++title: Rockchip SoC Naneng Combo Phy Device Tree Bindings ++ ++maintainers: ++ - Heiko Stuebner ++ ++properties: ++ compatible: ++ enum: ++ - rockchip,rk3568-naneng-combphy ++ ++ reg: ++ maxItems: 1 ++ ++ clocks: ++ items: ++ - description: reference clock ++ - description: apb clock ++ - description: pipe clock ++ ++ clock-names: ++ items: ++ - const: ref ++ - const: apb ++ - const: pipe ++ ++ resets: ++ items: ++ - description: exclusive PHY reset line ++ ++ rockchip,enable-ssc: ++ type: boolean ++ description: ++ The option SSC can be enabled for U3, SATA and PCIE. ++ Most commercially available platforms use SSC to reduce EMI. ++ ++ rockchip,ext-refclk: ++ type: boolean ++ description: ++ Many PCIe connections, especially backplane connections, ++ require a synchronous reference clock between the two link partners. ++ To achieve this a common clock source, referred to as REFCLK in ++ the PCI Express Card Electromechanical Specification, ++ should be used by both ends of the PCIe link. ++ In PCIe mode one can choose to use an internal or an external reference ++ clock. ++ By default the internal clock is selected. The PCIe PHY provides a 100MHz ++ differential clock output(optional with SSC) for system applications. ++ When selecting this option an externally 100MHz differential ++ reference clock needs to be provided to the PCIe PHY. ++ ++ rockchip,pipe-grf: ++ $ref: /schemas/types.yaml#/definitions/phandle ++ description: ++ Some additional phy settings are accessed through GRF regs. ++ ++ rockchip,pipe-phy-grf: ++ $ref: /schemas/types.yaml#/definitions/phandle ++ description: ++ Some additional pipe settings are accessed through GRF regs. ++ ++ "#phy-cells": ++ const: 1 ++ ++required: ++ - compatible ++ - reg ++ - clocks ++ - clock-names ++ - resets ++ - rockchip,pipe-grf ++ - rockchip,pipe-phy-grf ++ - "#phy-cells" ++ ++additionalProperties: false ++ ++examples: ++ - | ++ #include ++ ++ pipegrf: syscon@fdc50000 { ++ compatible = "rockchip,rk3568-pipe-grf", "syscon"; ++ reg = <0xfdc50000 0x1000>; ++ }; ++ ++ pipe_phy_grf0: syscon@fdc70000 { ++ compatible = "rockchip,rk3568-pipe-phy-grf", "syscon"; ++ reg = <0xfdc70000 0x1000>; ++ }; ++ ++ combphy0: phy@fe820000 { ++ compatible = "rockchip,rk3568-naneng-combphy"; ++ reg = <0xfe820000 0x100>; ++ clocks = <&pmucru CLK_PCIEPHY0_REF>, ++ <&cru PCLK_PIPEPHY0>, ++ <&cru PCLK_PIPE>; ++ clock-names = "ref", "apb", "pipe"; ++ assigned-clocks = <&pmucru CLK_PCIEPHY0_REF>; ++ assigned-clock-rates = <100000000>; ++ resets = <&cru SRST_PIPEPHY0>; ++ rockchip,pipe-grf = <&pipegrf>; ++ rockchip,pipe-phy-grf = <&pipe_phy_grf0>; ++ #phy-cells = <1>; ++ }; + +This patch implements a combo phy driver for Rockchip SoCs +with NaNeng IP block. This phy can be used as pcie-phy, usb3-phy, +sata-phy or sgmii-phy. + +Signed-off-by: Yifeng Zhao +Signed-off-by: Johan Jonker +--- + +Changes in v7: +- rename regs +- remove pipe_sgmii_mac_sel, u3otg0_port_en and u3otg1_port_en + +Changes in v5: +- add rockchip_combphy_updatel() +- restyle + +Changes in v4: +- restyle +- add devm_reset_control_array_get() +- remove clk structure +- change refclk DT parse +- change dev_err message +- add dot to phrase +- add ext_refclk variable +- add enable_ssc variable +- rename rockchip_combphy_param_write +- remove param_read +- replace rockchip-naneng-combphy driver name + +Changes in v3: +- Using api devm_reset_control_get_optional_exclusive and dev_err_probe. +- Remove apb_rst. +- Redefine registers address. + +Changes in v2: +- Using api devm_platform_get_and_ioremap_resource. +- Modify rockchip_combphy_set_Mode. +- Add some PHY registers definition. + + drivers/phy/rockchip/Kconfig | 8 + + drivers/phy/rockchip/Makefile | 1 + + .../rockchip/phy-rockchip-naneng-combphy.c | 589 ++++++++++++++++++ + 3 files changed, 598 insertions(+) + create mode 100644 drivers/phy/rockchip/phy-rockchip-naneng-combphy.c + +diff --git a/drivers/phy/rockchip/Kconfig b/drivers/phy/rockchip/Kconfig +index e812adad7242..9022e395c056 100644 +--- a/drivers/phy/rockchip/Kconfig ++++ b/drivers/phy/rockchip/Kconfig +@@ -66,6 +66,14 @@ config PHY_ROCKCHIP_INNO_DSIDPHY + Enable this to support the Rockchip MIPI/LVDS/TTL PHY with + Innosilicon IP block. + ++config PHY_ROCKCHIP_NANENG_COMBO_PHY ++ tristate "Rockchip NANENG COMBO PHY Driver" ++ depends on ARCH_ROCKCHIP && OF ++ select GENERIC_PHY ++ help ++ Enable this to support the Rockchip PCIe/USB3.0/SATA/QSGMII ++ combo PHY with NaNeng IP block. ++ + config PHY_ROCKCHIP_PCIE + tristate "Rockchip PCIe PHY Driver" + depends on (ARCH_ROCKCHIP && OF) || COMPILE_TEST +diff --git a/drivers/phy/rockchip/Makefile b/drivers/phy/rockchip/Makefile +index f0eec212b2aa..a5041efb5b8f 100644 +--- a/drivers/phy/rockchip/Makefile ++++ b/drivers/phy/rockchip/Makefile +@@ -6,6 +6,7 @@ obj-$(CONFIG_PHY_ROCKCHIP_INNO_CSIDPHY) += phy-rockchip-inno-csidphy.o + obj-$(CONFIG_PHY_ROCKCHIP_INNO_DSIDPHY) += phy-rockchip-inno-dsidphy.o + obj-$(CONFIG_PHY_ROCKCHIP_INNO_HDMI) += phy-rockchip-inno-hdmi.o + obj-$(CONFIG_PHY_ROCKCHIP_INNO_USB2) += phy-rockchip-inno-usb2.o ++obj-$(CONFIG_PHY_ROCKCHIP_NANENG_COMBO_PHY) += phy-rockchip-naneng-combphy.o + obj-$(CONFIG_PHY_ROCKCHIP_PCIE) += phy-rockchip-pcie.o + obj-$(CONFIG_PHY_ROCKCHIP_TYPEC) += phy-rockchip-typec.o + obj-$(CONFIG_PHY_ROCKCHIP_USB) += phy-rockchip-usb.o +diff --git a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c +new file mode 100644 +index 000000000000..47137a5c448a +--- /dev/null ++++ b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c +@@ -0,0 +1,589 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Rockchip PIPE USB3.0 PCIE SATA Combo Phy driver ++ * ++ * Copyright (C) 2021 Rockchip Electronics Co., Ltd. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define BIT_WRITEABLE_SHIFT 16 ++#define REF_CLOCK_24MHz (24 * HZ_PER_MHZ) ++#define REF_CLOCK_25MHz (25 * HZ_PER_MHZ) ++#define REF_CLOCK_100MHz (100 * HZ_PER_MHZ) ++ ++/* COMBO PHY REG */ ++#define PHYREG6 0x14 ++#define PHYREG6_PLL_DIV_MASK GENMASK(7, 6) ++#define PHYREG6_PLL_DIV_SHIFT 6 ++#define PHYREG6_PLL_DIV_2 1 ++ ++#define PHYREG7 0x18 ++#define PHYREG7_TX_RTERM_MASK GENMASK(7, 4) ++#define PHYREG7_TX_RTERM_SHIFT 4 ++#define PHYREG7_TX_RTERM_50OHM 8 ++#define PHYREG7_RX_RTERM_MASK GENMASK(3, 0) ++#define PHYREG7_RX_RTERM_SHIFT 0 ++#define PHYREG7_RX_RTERM_44OHM 15 ++ ++#define PHYREG8 0x1C ++#define PHYREG8_SSC_EN BIT(4) ++ ++#define PHYREG11 0x28 ++#define PHYREG11_SU_TRIM_0_7 0xF0 ++ ++#define PHYREG12 0x2C ++#define PHYREG12_PLL_LPF_ADJ_VALUE 4 ++ ++#define PHYREG13 0x30 ++#define PHYREG13_RESISTER_MASK GENMASK(5, 4) ++#define PHYREG13_RESISTER_SHIFT 0x4 ++#define PHYREG13_RESISTER_HIGH_Z 3 ++#define PHYREG13_CKRCV_AMP0 BIT(7) ++ ++#define PHYREG14 0x34 ++#define PHYREG14_CKRCV_AMP1 BIT(0) ++ ++#define PHYREG15 0x38 ++#define PHYREG15_CTLE_EN BIT(0) ++#define PHYREG15_SSC_CNT_MASK GENMASK(7, 6) ++#define PHYREG15_SSC_CNT_SHIFT 6 ++#define PHYREG15_SSC_CNT_VALUE 1 ++ ++#define PHYREG16 0x3C ++#define PHYREG16_SSC_CNT_VALUE 0x5f ++ ++#define PHYREG18 0x44 ++#define PHYREG18_PLL_LOOP 0x32 ++ ++#define PHYREG32 0x7C ++#define PHYREG32_SSC_MASK GENMASK(7, 4) ++#define PHYREG32_SSC_DIR_SHIFT 4 ++#define PHYREG32_SSC_UPWARD 0 ++#define PHYREG32_SSC_DOWNWARD 1 ++#define PHYREG32_SSC_OFFSET_SHIFT 6 ++#define PHYREG32_SSC_OFFSET_500PPM 1 ++ ++#define PHYREG33 0x80 ++#define PHYREG33_PLL_KVCO_MASK GENMASK(4, 2) ++#define PHYREG33_PLL_KVCO_SHIFT 2 ++#define PHYREG33_PLL_KVCO_VALUE 2 ++ ++struct rockchip_combphy_priv; ++ ++struct combphy_reg { ++ u16 offset; ++ u16 bitend; ++ u16 bitstart; ++ u16 disable; ++ u16 enable; ++}; ++ ++struct rockchip_combphy_grfcfg { ++ struct combphy_reg pcie_mode_set; ++ struct combphy_reg usb_mode_set; ++ struct combphy_reg sgmii_mode_set; ++ struct combphy_reg qsgmii_mode_set; ++ struct combphy_reg pipe_rxterm_set; ++ struct combphy_reg pipe_txelec_set; ++ struct combphy_reg pipe_txcomp_set; ++ struct combphy_reg pipe_clk_25m; ++ struct combphy_reg pipe_clk_100m; ++ struct combphy_reg pipe_phymode_sel; ++ struct combphy_reg pipe_rate_sel; ++ struct combphy_reg pipe_rxterm_sel; ++ struct combphy_reg pipe_txelec_sel; ++ struct combphy_reg pipe_txcomp_sel; ++ struct combphy_reg pipe_clk_ext; ++ struct combphy_reg pipe_sel_usb; ++ struct combphy_reg pipe_sel_qsgmii; ++ struct combphy_reg pipe_phy_status; ++ struct combphy_reg con0_for_pcie; ++ struct combphy_reg con1_for_pcie; ++ struct combphy_reg con2_for_pcie; ++ struct combphy_reg con3_for_pcie; ++ struct combphy_reg con0_for_sata; ++ struct combphy_reg con1_for_sata; ++ struct combphy_reg con2_for_sata; ++ struct combphy_reg con3_for_sata; ++ struct combphy_reg pipe_con0_for_sata; ++ struct combphy_reg pipe_xpcs_phy_ready; ++}; ++ ++struct rockchip_combphy_cfg { ++ const struct rockchip_combphy_grfcfg *grfcfg; ++ int (*combphy_cfg)(struct rockchip_combphy_priv *priv); ++}; ++ ++struct rockchip_combphy_priv { ++ u8 mode; ++ void __iomem *mmio; ++ int num_clks; ++ struct clk_bulk_data *clks; ++ struct device *dev; ++ struct regmap *pipe_grf; ++ struct regmap *phy_grf; ++ struct phy *phy; ++ struct reset_control *phy_rst; ++ const struct rockchip_combphy_cfg *cfg; ++ bool enable_ssc; ++ bool ext_refclk; ++ struct clk *refclk; ++}; ++ ++static void rockchip_combphy_updatel(struct rockchip_combphy_priv *priv, ++ int mask, int val, int reg) ++{ ++ unsigned int temp; ++ ++ temp = readl(priv->mmio + reg); ++ temp = (temp & ~(mask)) | val; ++ writel(temp, priv->mmio + reg); ++} ++ ++static int rockchip_combphy_param_write(struct regmap *base, ++ const struct combphy_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 u32 rockchip_combphy_is_ready(struct rockchip_combphy_priv *priv) ++{ ++ const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg; ++ u32 mask, val; ++ ++ mask = GENMASK(cfg->pipe_phy_status.bitend, ++ cfg->pipe_phy_status.bitstart); ++ ++ regmap_read(priv->phy_grf, cfg->pipe_phy_status.offset, &val); ++ val = (val & mask) >> cfg->pipe_phy_status.bitstart; ++ ++ return val; ++} ++ ++static int rockchip_combphy_set_mode(struct rockchip_combphy_priv *priv) ++{ ++ int ret = 0; ++ ++ switch (priv->mode) { ++ case PHY_TYPE_PCIE: ++ case PHY_TYPE_USB3: ++ case PHY_TYPE_SATA: ++ case PHY_TYPE_SGMII: ++ case PHY_TYPE_QSGMII: ++ if (priv->cfg->combphy_cfg) ++ ret = priv->cfg->combphy_cfg(priv); ++ break; ++ default: ++ dev_err(priv->dev, "incompatible PHY type\n"); ++ return -EINVAL; ++ } ++ ++ if (ret) ++ dev_err(priv->dev, "failed to init phy for phy mode %x\n", priv->mode); ++ ++ return ret; ++} ++ ++static int rockchip_combphy_init(struct phy *phy) ++{ ++ struct rockchip_combphy_priv *priv = phy_get_drvdata(phy); ++ const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg; ++ u32 val; ++ int ret; ++ ++ ret = clk_bulk_prepare_enable(priv->num_clks, priv->clks); ++ if (ret) { ++ dev_err(priv->dev, "failed to enable clks\n"); ++ return ret; ++ } ++ ++ ret = rockchip_combphy_set_mode(priv); ++ if (ret) ++ goto err_clk; ++ ++ ret = reset_control_deassert(priv->phy_rst); ++ if (ret) ++ goto err_clk; ++ ++ if (priv->mode == PHY_TYPE_USB3) { ++ ret = readx_poll_timeout_atomic(rockchip_combphy_is_ready, ++ priv, val, ++ val == cfg->pipe_phy_status.enable, ++ 10, 1000); ++ if (ret) ++ dev_warn(priv->dev, "wait phy status ready timeout\n"); ++ } ++ ++ return 0; ++ ++err_clk: ++ clk_bulk_disable_unprepare(priv->num_clks, priv->clks); ++ ++ return ret; ++} ++ ++static int rockchip_combphy_exit(struct phy *phy) ++{ ++ struct rockchip_combphy_priv *priv = phy_get_drvdata(phy); ++ ++ clk_bulk_disable_unprepare(priv->num_clks, priv->clks); ++ reset_control_assert(priv->phy_rst); ++ ++ return 0; ++} ++ ++static const struct phy_ops rochchip_combphy_ops = { ++ .init = rockchip_combphy_init, ++ .exit = rockchip_combphy_exit, ++ .owner = THIS_MODULE, ++}; ++ ++static struct phy *rockchip_combphy_xlate(struct device *dev, struct of_phandle_args *args) ++{ ++ struct rockchip_combphy_priv *priv = dev_get_drvdata(dev); ++ ++ if (args->args_count != 1) { ++ dev_err(dev, "invalid number of arguments\n"); ++ return ERR_PTR(-EINVAL); ++ } ++ ++ if (priv->mode != PHY_NONE && priv->mode != args->args[0]) ++ dev_warn(dev, "phy type select %d overwriting type %d\n", ++ args->args[0], priv->mode); ++ ++ priv->mode = args->args[0]; ++ ++ return priv->phy; ++} ++ ++static int rockchip_combphy_parse_dt(struct device *dev, struct rockchip_combphy_priv *priv) ++{ ++ int i; ++ ++ priv->num_clks = devm_clk_bulk_get_all(dev, &priv->clks); ++ if (priv->num_clks < 1) ++ return -EINVAL; ++ ++ priv->refclk = NULL; ++ for (i = 0; i < priv->num_clks; i++) { ++ if (!strncmp(priv->clks[i].id, "ref", 3)) { ++ priv->refclk = priv->clks[i].clk; ++ break; ++ } ++ } ++ ++ if (!priv->refclk) { ++ dev_err(dev, "no refclk found\n"); ++ return -EINVAL; ++ } ++ ++ priv->pipe_grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,pipe-grf"); ++ if (IS_ERR(priv->pipe_grf)) { ++ dev_err(dev, "failed to find peri_ctrl pipe-grf regmap\n"); ++ return PTR_ERR(priv->pipe_grf); ++ } ++ ++ priv->phy_grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,pipe-phy-grf"); ++ if (IS_ERR(priv->phy_grf)) { ++ dev_err(dev, "failed to find peri_ctrl pipe-phy-grf regmap\n"); ++ return PTR_ERR(priv->phy_grf); ++ } ++ ++ priv->enable_ssc = device_property_present(dev, "rockchip,enable-ssc"); ++ ++ priv->ext_refclk = device_property_present(dev, "rockchip,ext-refclk"); ++ ++ priv->phy_rst = devm_reset_control_array_get(dev, false, false); ++ if (IS_ERR(priv->phy_rst)) ++ return dev_err_probe(dev, PTR_ERR(priv->phy_rst), "failed to get phy reset\n"); ++ ++ return 0; ++} ++ ++static int rockchip_combphy_probe(struct platform_device *pdev) ++{ ++ struct phy_provider *phy_provider; ++ struct device *dev = &pdev->dev; ++ struct rockchip_combphy_priv *priv; ++ const struct rockchip_combphy_cfg *phy_cfg; ++ struct resource *res; ++ int ret; ++ ++ phy_cfg = of_device_get_match_data(dev); ++ if (!phy_cfg) { ++ dev_err(dev, "no OF match data provided\n"); ++ return -EINVAL; ++ } ++ ++ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); ++ if (!priv) ++ return -ENOMEM; ++ ++ priv->mmio = devm_platform_get_and_ioremap_resource(pdev, 0, &res); ++ if (IS_ERR(priv->mmio)) { ++ ret = PTR_ERR(priv->mmio); ++ return ret; ++ } ++ ++ priv->dev = dev; ++ priv->mode = PHY_NONE; ++ priv->cfg = phy_cfg; ++ ++ ret = rockchip_combphy_parse_dt(dev, priv); ++ if (ret) ++ return ret; ++ ++ ret = reset_control_assert(priv->phy_rst); ++ if (ret) { ++ dev_err(dev, "failed to reset phy\n"); ++ return ret; ++ } ++ ++ priv->phy = devm_phy_create(dev, NULL, &rochchip_combphy_ops); ++ if (IS_ERR(priv->phy)) { ++ dev_err(dev, "failed to create combphy\n"); ++ return PTR_ERR(priv->phy); ++ } ++ ++ dev_set_drvdata(dev, priv); ++ phy_set_drvdata(priv->phy, priv); ++ ++ phy_provider = devm_of_phy_provider_register(dev, rockchip_combphy_xlate); ++ ++ return PTR_ERR_OR_ZERO(phy_provider); ++} ++ ++static int rk3568_combphy_cfg(struct rockchip_combphy_priv *priv) ++{ ++ const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg; ++ unsigned long rate; ++ u32 val; ++ ++ switch (priv->mode) { ++ case PHY_TYPE_PCIE: ++ /* Set SSC downward spread spectrum. */ ++ rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK, ++ PHYREG32_SSC_DOWNWARD << PHYREG32_SSC_DIR_SHIFT, ++ PHYREG32); ++ ++ rockchip_combphy_param_write(priv->phy_grf, &cfg->con0_for_pcie, true); ++ rockchip_combphy_param_write(priv->phy_grf, &cfg->con1_for_pcie, true); ++ rockchip_combphy_param_write(priv->phy_grf, &cfg->con2_for_pcie, true); ++ rockchip_combphy_param_write(priv->phy_grf, &cfg->con3_for_pcie, true); ++ break; ++ ++ case PHY_TYPE_USB3: ++ /* Set SSC downward spread spectrum. */ ++ rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK, ++ PHYREG32_SSC_DOWNWARD << PHYREG32_SSC_DIR_SHIFT, ++ PHYREG32); ++ ++ /* Enable adaptive CTLE for USB3.0 Rx. */ ++ val = readl(priv->mmio + PHYREG15); ++ val |= PHYREG15_CTLE_EN; ++ writel(val, priv->mmio + PHYREG15); ++ ++ /* Set PLL KVCO fine tuning signals. */ ++ rockchip_combphy_updatel(priv, PHYREG33_PLL_KVCO_MASK, ++ PHYREG33_PLL_KVCO_VALUE << PHYREG33_PLL_KVCO_SHIFT, ++ PHYREG33); ++ ++ /* Enable controlling random jitter. */ ++ writel(PHYREG12_PLL_LPF_ADJ_VALUE, priv->mmio + PHYREG12); ++ ++ /* Set PLL input clock divider 1/2. */ ++ rockchip_combphy_updatel(priv, PHYREG6_PLL_DIV_MASK, ++ PHYREG6_PLL_DIV_2 << PHYREG6_PLL_DIV_SHIFT, ++ PHYREG6); ++ ++ writel(PHYREG18_PLL_LOOP, priv->mmio + PHYREG18); ++ writel(PHYREG11_SU_TRIM_0_7, priv->mmio + PHYREG11); ++ ++ rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_sel_usb, true); ++ rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txcomp_sel, false); ++ rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txelec_sel, false); ++ rockchip_combphy_param_write(priv->phy_grf, &cfg->usb_mode_set, true); ++ break; ++ ++ case PHY_TYPE_SATA: ++ /* Enable adaptive CTLE for SATA Rx. */ ++ val = readl(priv->mmio + PHYREG15); ++ val |= PHYREG15_CTLE_EN; ++ writel(val, priv->mmio + PHYREG15); ++ /* ++ * Set tx_rterm=50ohm and rx_rterm=44ohm for SATA. ++ * 0: 60ohm, 8: 50ohm 15: 44ohm (by step abort 1ohm) ++ */ ++ val = PHYREG7_TX_RTERM_50OHM << PHYREG7_TX_RTERM_SHIFT; ++ val |= PHYREG7_RX_RTERM_44OHM << PHYREG7_RX_RTERM_SHIFT; ++ writel(val, priv->mmio + PHYREG7); ++ ++ rockchip_combphy_param_write(priv->phy_grf, &cfg->con0_for_sata, true); ++ rockchip_combphy_param_write(priv->phy_grf, &cfg->con1_for_sata, true); ++ rockchip_combphy_param_write(priv->phy_grf, &cfg->con2_for_sata, true); ++ rockchip_combphy_param_write(priv->phy_grf, &cfg->con3_for_sata, true); ++ rockchip_combphy_param_write(priv->pipe_grf, &cfg->pipe_con0_for_sata, true); ++ break; ++ ++ case PHY_TYPE_SGMII: ++ rockchip_combphy_param_write(priv->pipe_grf, &cfg->pipe_xpcs_phy_ready, true); ++ rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_phymode_sel, true); ++ rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_sel_qsgmii, true); ++ rockchip_combphy_param_write(priv->phy_grf, &cfg->sgmii_mode_set, true); ++ break; ++ ++ case PHY_TYPE_QSGMII: ++ rockchip_combphy_param_write(priv->pipe_grf, &cfg->pipe_xpcs_phy_ready, true); ++ rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_phymode_sel, true); ++ rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_rate_sel, true); ++ rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_sel_qsgmii, true); ++ rockchip_combphy_param_write(priv->phy_grf, &cfg->qsgmii_mode_set, true); ++ break; ++ ++ default: ++ dev_err(priv->dev, "incompatible PHY type\n"); ++ return -EINVAL; ++ } ++ ++ rate = clk_get_rate(priv->refclk); ++ ++ switch (rate) { ++ case REF_CLOCK_24MHz: ++ if (priv->mode == PHY_TYPE_USB3 || priv->mode == PHY_TYPE_SATA) { ++ /* Set ssc_cnt[9:0]=0101111101 & 31.5KHz. */ ++ val = PHYREG15_SSC_CNT_VALUE << PHYREG15_SSC_CNT_SHIFT; ++ rockchip_combphy_updatel(priv, PHYREG15_SSC_CNT_MASK, ++ val, PHYREG15); ++ ++ writel(PHYREG16_SSC_CNT_VALUE, priv->mmio + PHYREG16); ++ } ++ break; ++ ++ case REF_CLOCK_25MHz: ++ rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_25m, true); ++ break; ++ ++ case REF_CLOCK_100MHz: ++ rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_100m, true); ++ if (priv->mode == PHY_TYPE_PCIE) { ++ /* PLL KVCO fine tuning. */ ++ val = PHYREG33_PLL_KVCO_VALUE << PHYREG33_PLL_KVCO_SHIFT; ++ rockchip_combphy_updatel(priv, PHYREG33_PLL_KVCO_MASK, ++ val, PHYREG33); ++ ++ /* Enable controlling random jitter. */ ++ writel(PHYREG12_PLL_LPF_ADJ_VALUE, priv->mmio + PHYREG12); ++ ++ val = PHYREG6_PLL_DIV_2 << PHYREG6_PLL_DIV_SHIFT; ++ rockchip_combphy_updatel(priv, PHYREG6_PLL_DIV_MASK, ++ val, PHYREG6); ++ ++ writel(PHYREG18_PLL_LOOP, priv->mmio + PHYREG18); ++ writel(PHYREG11_SU_TRIM_0_7, priv->mmio + PHYREG11); ++ } else if (priv->mode == PHY_TYPE_SATA) { ++ /* downward spread spectrum +500ppm */ ++ val = PHYREG32_SSC_DOWNWARD << PHYREG32_SSC_DIR_SHIFT; ++ val |= PHYREG32_SSC_OFFSET_500PPM << PHYREG32_SSC_OFFSET_SHIFT; ++ rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK, val, PHYREG32); ++ } ++ break; ++ ++ default: ++ dev_err(priv->dev, "unsupported rate: %lu\n", rate); ++ return -EINVAL; ++ } ++ ++ if (priv->ext_refclk) { ++ rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_ext, true); ++ if (priv->mode == PHY_TYPE_PCIE && rate == REF_CLOCK_100MHz) { ++ val = PHYREG13_RESISTER_HIGH_Z << PHYREG13_RESISTER_SHIFT; ++ val |= PHYREG13_CKRCV_AMP0; ++ rockchip_combphy_updatel(priv, PHYREG13_RESISTER_MASK, val, PHYREG13); ++ ++ val = readl(priv->mmio + PHYREG14); ++ val |= PHYREG14_CKRCV_AMP1; ++ writel(val, priv->mmio + PHYREG14); ++ } ++ } ++ ++ if (priv->enable_ssc) { ++ val = readl(priv->mmio + PHYREG8); ++ val |= PHYREG8_SSC_EN; ++ writel(val, priv->mmio + PHYREG8); ++ } ++ ++ return 0; ++} ++ ++static const struct rockchip_combphy_grfcfg rk3568_combphy_grfcfgs = { ++ /* pipe-phy-grf */ ++ .pcie_mode_set = { 0x0000, 5, 0, 0x00, 0x11 }, ++ .usb_mode_set = { 0x0000, 5, 0, 0x00, 0x04 }, ++ .sgmii_mode_set = { 0x0000, 5, 0, 0x00, 0x01 }, ++ .qsgmii_mode_set = { 0x0000, 5, 0, 0x00, 0x21 }, ++ .pipe_rxterm_set = { 0x0000, 12, 12, 0x00, 0x01 }, ++ .pipe_txelec_set = { 0x0004, 1, 1, 0x00, 0x01 }, ++ .pipe_txcomp_set = { 0x0004, 4, 4, 0x00, 0x01 }, ++ .pipe_clk_25m = { 0x0004, 14, 13, 0x00, 0x01 }, ++ .pipe_clk_100m = { 0x0004, 14, 13, 0x00, 0x02 }, ++ .pipe_phymode_sel = { 0x0008, 1, 1, 0x00, 0x01 }, ++ .pipe_rate_sel = { 0x0008, 2, 2, 0x00, 0x01 }, ++ .pipe_rxterm_sel = { 0x0008, 8, 8, 0x00, 0x01 }, ++ .pipe_txelec_sel = { 0x0008, 12, 12, 0x00, 0x01 }, ++ .pipe_txcomp_sel = { 0x0008, 15, 15, 0x00, 0x01 }, ++ .pipe_clk_ext = { 0x000c, 9, 8, 0x02, 0x01 }, ++ .pipe_sel_usb = { 0x000c, 14, 13, 0x00, 0x01 }, ++ .pipe_sel_qsgmii = { 0x000c, 15, 13, 0x00, 0x07 }, ++ .pipe_phy_status = { 0x0034, 6, 6, 0x01, 0x00 }, ++ .con0_for_pcie = { 0x0000, 15, 0, 0x00, 0x1000 }, ++ .con1_for_pcie = { 0x0004, 15, 0, 0x00, 0x0000 }, ++ .con2_for_pcie = { 0x0008, 15, 0, 0x00, 0x0101 }, ++ .con3_for_pcie = { 0x000c, 15, 0, 0x00, 0x0200 }, ++ .con0_for_sata = { 0x0000, 15, 0, 0x00, 0x0119 }, ++ .con1_for_sata = { 0x0004, 15, 0, 0x00, 0x0040 }, ++ .con2_for_sata = { 0x0008, 15, 0, 0x00, 0x80c3 }, ++ .con3_for_sata = { 0x000c, 15, 0, 0x00, 0x4407 }, ++ /* pipe-grf */ ++ .pipe_con0_for_sata = { 0x0000, 15, 0, 0x00, 0x2220 }, ++ .pipe_xpcs_phy_ready = { 0x0040, 2, 2, 0x00, 0x01 }, ++}; ++ ++static const struct rockchip_combphy_cfg rk3568_combphy_cfgs = { ++ .grfcfg = &rk3568_combphy_grfcfgs, ++ .combphy_cfg = rk3568_combphy_cfg, ++}; ++ ++static const struct of_device_id rockchip_combphy_of_match[] = { ++ { ++ .compatible = "rockchip,rk3568-naneng-combphy", ++ .data = &rk3568_combphy_cfgs, ++ }, ++ { }, ++}; ++MODULE_DEVICE_TABLE(of, rockchip_combphy_of_match); ++ ++static struct platform_driver rockchip_combphy_driver = { ++ .probe = rockchip_combphy_probe, ++ .driver = { ++ .name = "rockchip-naneng-combphy", ++ .of_match_table = rockchip_combphy_of_match, ++ }, ++}; ++module_platform_driver(rockchip_combphy_driver); ++ ++MODULE_DESCRIPTION("Rockchip NANENG COMBPHY driver"); ++MODULE_LICENSE("GPL v2"); + +Add the core dt-node for the rk3568's naneng combo phys. + +Signed-off-by: Yifeng Zhao +Signed-off-by: Johan Jonker +--- + +Changes in v7: None +Changes in v5: +- remove apb reset + +Changes in v4: +- rename node name +- remove reset-names +- move #phy-cells +- add rockchip,rk3568-pipe-grf +- add rockchip,rk3568-pipe-phy-grf + +Changes in v3: +- Move pipe_phy_grf0 to rk3568.dtsi + +Changes in v2: +- Move phy0 to rk3568.dtsi + + arch/arm64/boot/dts/rockchip/rk3568.dtsi | 21 +++++++++++ + arch/arm64/boot/dts/rockchip/rk356x.dtsi | 47 ++++++++++++++++++++++++ + 2 files changed, 68 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3568.dtsi b/arch/arm64/boot/dts/rockchip/rk3568.dtsi +index 2fd313a295f8..91a0b798b857 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3568.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3568.dtsi +@@ -8,6 +8,11 @@ + / { + compatible = "rockchip,rk3568"; + ++ pipe_phy_grf0: syscon@fdc70000 { ++ compatible = "rockchip,rk3568-pipe-phy-grf", "syscon"; ++ reg = <0x0 0xfdc70000 0x0 0x1000>; ++ }; ++ + qos_pcie3x1: qos@fe190080 { + compatible = "rockchip,rk3568-qos", "syscon"; + reg = <0x0 0xfe190080 0x0 0x20>; +@@ -71,6 +76,22 @@ + queue0 {}; + }; + }; ++ ++ combphy0: phy@fe820000 { ++ compatible = "rockchip,rk3568-naneng-combphy"; ++ reg = <0x0 0xfe820000 0x0 0x100>; ++ clocks = <&pmucru CLK_PCIEPHY0_REF>, ++ <&cru PCLK_PIPEPHY0>, ++ <&cru PCLK_PIPE>; ++ clock-names = "ref", "apb", "pipe"; ++ assigned-clocks = <&pmucru CLK_PCIEPHY0_REF>; ++ assigned-clock-rates = <100000000>; ++ resets = <&cru SRST_PIPEPHY0>; ++ rockchip,pipe-grf = <&pipegrf>; ++ rockchip,pipe-phy-grf = <&pipe_phy_grf0>; ++ #phy-cells = <1>; ++ status = "disabled"; ++ }; + }; + + &cpu0_opp_table { +diff --git a/arch/arm64/boot/dts/rockchip/rk356x.dtsi b/arch/arm64/boot/dts/rockchip/rk356x.dtsi +index a68033a23975..93f230f799f1 100644 +--- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi +@@ -218,11 +218,26 @@ + }; + }; + ++ pipegrf: syscon@fdc50000 { ++ compatible = "rockchip,rk3568-pipe-grf", "syscon"; ++ reg = <0x0 0xfdc50000 0x0 0x1000>; ++ }; ++ + grf: syscon@fdc60000 { + compatible = "rockchip,rk3568-grf", "syscon", "simple-mfd"; + reg = <0x0 0xfdc60000 0x0 0x10000>; + }; + ++ pipe_phy_grf1: syscon@fdc80000 { ++ compatible = "rockchip,rk3568-pipe-phy-grf", "syscon"; ++ reg = <0x0 0xfdc80000 0x0 0x1000>; ++ }; ++ ++ pipe_phy_grf2: syscon@fdc90000 { ++ compatible = "rockchip,rk3568-pipe-phy-grf", "syscon"; ++ reg = <0x0 0xfdc90000 0x0 0x1000>; ++ }; ++ + pmucru: clock-controller@fdd00000 { + compatible = "rockchip,rk3568-pmucru"; + reg = <0x0 0xfdd00000 0x0 0x1000>; +@@ -1141,6 +1156,38 @@ + status = "disabled"; + }; + ++ combphy1: phy@fe830000 { ++ compatible = "rockchip,rk3568-naneng-combphy"; ++ reg = <0x0 0xfe830000 0x0 0x100>; ++ clocks = <&pmucru CLK_PCIEPHY1_REF>, ++ <&cru PCLK_PIPEPHY1>, ++ <&cru PCLK_PIPE>; ++ clock-names = "ref", "apb", "pipe"; ++ assigned-clocks = <&pmucru CLK_PCIEPHY1_REF>; ++ assigned-clock-rates = <100000000>; ++ resets = <&cru SRST_PIPEPHY1>; ++ rockchip,pipe-grf = <&pipegrf>; ++ rockchip,pipe-phy-grf = <&pipe_phy_grf1>; ++ #phy-cells = <1>; ++ status = "disabled"; ++ }; ++ ++ combphy2: phy@fe840000 { ++ compatible = "rockchip,rk3568-naneng-combphy"; ++ reg = <0x0 0xfe840000 0x0 0x100>; ++ clocks = <&pmucru CLK_PCIEPHY2_REF>, ++ <&cru PCLK_PIPEPHY2>, ++ <&cru PCLK_PIPE>; ++ clock-names = "ref", "apb", "pipe"; ++ assigned-clocks = <&pmucru CLK_PCIEPHY2_REF>; ++ assigned-clock-rates = <100000000>; ++ resets = <&cru SRST_PIPEPHY2>; ++ rockchip,pipe-grf = <&pipegrf>; ++ rockchip,pipe-phy-grf = <&pipe_phy_grf2>; ++ #phy-cells = <1>; ++ status = "disabled"; ++ }; ++ + pinctrl: pinctrl { + compatible = "rockchip,rk3568-pinctrl"; + rockchip,grf = <&grf>; diff --git a/patch/kernel/archive/rk35xx-5.16/rk356x-usb2-support.patch b/patch/kernel/archive/rk35xx-5.16/rk356x-usb2-support.patch new file mode 100644 index 0000000000..1a96ac91dc --- /dev/null +++ b/patch/kernel/archive/rk35xx-5.16/rk356x-usb2-support.patch @@ -0,0 +1,770 @@ +Add the documentation for the rk3568-usb2phy-grf node, which is separate +from the usb2phy node on this chip. + +Signed-off-by: Peter Geis +Acked-by: Rob Herring +--- + Documentation/devicetree/bindings/soc/rockchip/grf.yaml | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/Documentation/devicetree/bindings/soc/rockchip/grf.yaml b/Documentation/devicetree/bindings/soc/rockchip/grf.yaml +index dfebf425ca49..b2ba7bed89b2 100644 +--- a/Documentation/devicetree/bindings/soc/rockchip/grf.yaml ++++ b/Documentation/devicetree/bindings/soc/rockchip/grf.yaml +@@ -15,6 +15,7 @@ properties: + - items: + - enum: + - rockchip,rk3288-sgrf ++ - rockchip,rk3568-usb2phy-grf + - rockchip,rv1108-usbgrf + - const: syscon + - items: + +The rk3568 usb2phy node is a standalone node with a single muxed +interrupt. +Add documentation for it to phy-rockchip-inno-usb2. + +Signed-off-by: Peter Geis +--- + +This was the best solution I've come up with for this. +I avoided creating another binding since this is such a simple change to +the actual driver and would likely require renaming the existing +binding. +I've tested that this correctly flags if the interrupts are missing or +incorrectly assigned on both rk356x and rk3399. + +Thank you Johan and Rob for your constructive feedback. + + .../bindings/phy/phy-rockchip-inno-usb2.yaml | 44 +++++++++++++++++-- + 1 file changed, 40 insertions(+), 4 deletions(-) + +diff --git a/Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb2.yaml b/Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb2.yaml +index 5bebd86bf8b6..4b75289735eb 100644 +--- a/Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb2.yaml ++++ b/Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb2.yaml +@@ -18,6 +18,7 @@ properties: + - rockchip,rk3328-usb2phy + - rockchip,rk3366-usb2phy + - rockchip,rk3399-usb2phy ++ - rockchip,rk3568-usb2phy + - rockchip,rv1108-usb2phy + + reg: +@@ -50,6 +51,10 @@ properties: + description: + Phandle to the extcon device providing the cable state for the otg phy. + ++ interrupts: ++ description: Muxed interrupt for both ports ++ maxItems: 1 ++ + rockchip,usbgrf: + $ref: /schemas/types.yaml#/definitions/phandle + description: +@@ -67,6 +72,7 @@ properties: + + interrupts: + description: host linestate interrupt ++ maxItems: 1 + + interrupt-names: + const: linestate +@@ -78,8 +84,6 @@ properties: + + required: + - "#phy-cells" +- - interrupts +- - interrupt-names + + otg-port: + type: object +@@ -109,8 +113,6 @@ properties: + + required: + - "#phy-cells" +- - interrupts +- - interrupt-names + + required: + - compatible +@@ -120,6 +122,40 @@ required: + - host-port + - otg-port + ++allOf: ++ - if: ++ properties: ++ compatible: ++ contains: ++ const: rockchip,rk3568-usb2phy ++ ++ then: ++ properties: ++ host-port: ++ properties: ++ interrupts: false ++ ++ otg-port: ++ properties: ++ interrupts: false ++ ++ required: ++ - interrupts ++ ++ else: ++ properties: ++ interrupts: false ++ ++ host-port: ++ required: ++ - interrupts ++ - interrupt-names ++ ++ otg-port: ++ required: ++ - interrupts ++ - interrupt-names ++ + additionalProperties: false + + examples: + + +New Rockchip devices have the usb phy nodes as standalone devices. +These nodes have register nodes with #address_cells = 2, but only use 32 +bit addresses. + +Adjust the driver to check if the returned address is "0", and adjust +the index in that case. + +Signed-off-by: Peter Geis +Tested-by: Michael Riesch +--- + drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) + +diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c +index 1938365abbb3..5cfa7169d879 100644 +--- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c ++++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c +@@ -1091,12 +1091,21 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev) + rphy->usbgrf = NULL; + } + +- if (of_property_read_u32(np, "reg", ®)) { ++ if (of_property_read_u32_index(np, "reg", 0, ®)) { + dev_err(dev, "the reg property is not assigned in %pOFn node\n", + np); + return -EINVAL; + } + ++ /* support address_cells=2 */ ++ if (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); ++ return -EINVAL; ++ } ++ } ++ + rphy->dev = dev; + phy_cfgs = match->data; + rphy->chg_state = USB_CHG_STATE_UNDEFINED; + + +New Rockchip devices have the usb2 phy devices as standalone nodes +instead of children of the grf node. +Allow the driver to find the grf node from a phandle. + +Signed-off-by: Peter Geis +Tested-by: Michael Riesch +--- + drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 17 ++++++++++++----- + 1 file changed, 12 insertions(+), 5 deletions(-) + +diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c +index 5cfa7169d879..29e3a0da8c26 100644 +--- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c ++++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c +@@ -1074,12 +1074,19 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev) + return -EINVAL; + } + +- if (!dev->parent || !dev->parent->of_node) +- return -EINVAL; ++ if (!dev->parent || !dev->parent->of_node) { ++ rphy->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,usbgrf"); ++ if (IS_ERR(rphy->grf)) { ++ dev_err(dev, "failed to locate usbgrf\n"); ++ return PTR_ERR(rphy->grf); ++ } ++ } + +- rphy->grf = syscon_node_to_regmap(dev->parent->of_node); +- if (IS_ERR(rphy->grf)) +- return PTR_ERR(rphy->grf); ++ else { ++ rphy->grf = syscon_node_to_regmap(dev->parent->of_node); ++ if (IS_ERR(rphy->grf)) ++ return PTR_ERR(rphy->grf); ++ } + + if (of_device_is_compatible(np, "rockchip,rv1108-usb2phy")) { + rphy->usbgrf = + + +The rk3568 usb2phy has a single muxed interrupt that handles all +interrupts. +Allow the driver to plug in only a single interrupt as necessary. + +Signed-off-by: Peter Geis +Tested-by: Michael Riesch +--- + drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 168 +++++++++++++----- + 1 file changed, 119 insertions(+), 49 deletions(-) + +diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c +index 29e3a0da8c26..285958fdab38 100644 +--- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c ++++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c +@@ -204,6 +204,7 @@ struct rockchip_usb2phy_port { + * @dcd_retries: The retry count used to track Data contact + * detection process. + * @edev: extcon device for notification registration ++ * @irq: muxed interrupt for single irq configuration + * @phy_cfg: phy register configuration, assigned by driver data. + * @ports: phy port instance. + */ +@@ -218,6 +219,7 @@ struct rockchip_usb2phy { + enum power_supply_type chg_type; + u8 dcd_retries; + struct extcon_dev *edev; ++ int irq; + const struct rockchip_usb2phy_cfg *phy_cfg; + struct rockchip_usb2phy_port ports[USB2PHY_NUM_PORTS]; + }; +@@ -927,6 +929,102 @@ static irqreturn_t rockchip_usb2phy_otg_mux_irq(int irq, void *data) + return IRQ_NONE; + } + ++static irqreturn_t rockchip_usb2phy_irq(int irq, void *data) ++{ ++ struct rockchip_usb2phy *rphy = data; ++ struct rockchip_usb2phy_port *rport; ++ irqreturn_t ret = IRQ_NONE; ++ unsigned int index; ++ ++ for (index = 0; index < rphy->phy_cfg->num_ports; index++) { ++ rport = &rphy->ports[index]; ++ if (!rport->phy) ++ continue; ++ ++ /* Handle linestate irq for both otg port and host port */ ++ ret = rockchip_usb2phy_linestate_irq(irq, rport); ++ } ++ ++ return ret; ++} ++ ++static int rockchip_usb2phy_port_irq_init(struct rockchip_usb2phy *rphy, ++ struct rockchip_usb2phy_port *rport, ++ struct device_node *child_np) ++{ ++ int ret; ++ ++ /* ++ * If the usb2 phy used combined irq for otg and host port, ++ * don't need to init otg and host port irq separately. ++ */ ++ if (rphy->irq > 0) ++ return 0; ++ ++ switch (rport->port_id) { ++ case USB2PHY_PORT_HOST: ++ rport->ls_irq = of_irq_get_byname(child_np, "linestate"); ++ if (rport->ls_irq < 0) { ++ dev_err(rphy->dev, "no linestate irq provided\n"); ++ return rport->ls_irq; ++ } ++ ++ ret = devm_request_threaded_irq(rphy->dev, rport->ls_irq, NULL, ++ rockchip_usb2phy_linestate_irq, ++ IRQF_ONESHOT, ++ "rockchip_usb2phy", rport); ++ if (ret) { ++ dev_err(rphy->dev, "failed to request linestate irq handle\n"); ++ return ret; ++ } ++ break; ++ case USB2PHY_PORT_OTG: ++ /* ++ * Some SoCs use one interrupt with otg-id/otg-bvalid/linestate ++ * interrupts muxed together, so probe the otg-mux interrupt first, ++ * if not found, then look for the regular interrupts one by one. ++ */ ++ rport->otg_mux_irq = of_irq_get_byname(child_np, "otg-mux"); ++ if (rport->otg_mux_irq > 0) { ++ ret = devm_request_threaded_irq(rphy->dev, rport->otg_mux_irq, ++ NULL, ++ rockchip_usb2phy_otg_mux_irq, ++ IRQF_ONESHOT, ++ "rockchip_usb2phy_otg", ++ rport); ++ if (ret) { ++ dev_err(rphy->dev, ++ "failed to request otg-mux irq handle\n"); ++ return ret; ++ } ++ } else { ++ rport->bvalid_irq = of_irq_get_byname(child_np, "otg-bvalid"); ++ if (rport->bvalid_irq < 0) { ++ dev_err(rphy->dev, "no vbus valid irq provided\n"); ++ ret = rport->bvalid_irq; ++ return ret; ++ } ++ ++ ret = devm_request_threaded_irq(rphy->dev, rport->bvalid_irq, ++ NULL, ++ rockchip_usb2phy_bvalid_irq, ++ IRQF_ONESHOT, ++ "rockchip_usb2phy_bvalid", ++ rport); ++ if (ret) { ++ dev_err(rphy->dev, ++ "failed to request otg-bvalid irq handle\n"); ++ return ret; ++ } ++ } ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ + static int rockchip_usb2phy_host_port_init(struct rockchip_usb2phy *rphy, + struct rockchip_usb2phy_port *rport, + struct device_node *child_np) +@@ -940,18 +1038,9 @@ static int rockchip_usb2phy_host_port_init(struct rockchip_usb2phy *rphy, + mutex_init(&rport->mutex); + INIT_DELAYED_WORK(&rport->sm_work, rockchip_usb2phy_sm_work); + +- rport->ls_irq = of_irq_get_byname(child_np, "linestate"); +- if (rport->ls_irq < 0) { +- dev_err(rphy->dev, "no linestate irq provided\n"); +- return rport->ls_irq; +- } +- +- ret = devm_request_threaded_irq(rphy->dev, rport->ls_irq, NULL, +- rockchip_usb2phy_linestate_irq, +- IRQF_ONESHOT, +- "rockchip_usb2phy", rport); ++ ret = rockchip_usb2phy_port_irq_init(rphy, rport, child_np); + if (ret) { +- dev_err(rphy->dev, "failed to request linestate irq handle\n"); ++ dev_err(rphy->dev, "failed to setup host irq\n"); + return ret; + } + +@@ -1000,44 +1089,10 @@ static int rockchip_usb2phy_otg_port_init(struct rockchip_usb2phy *rphy, + INIT_DELAYED_WORK(&rport->chg_work, rockchip_chg_detect_work); + INIT_DELAYED_WORK(&rport->otg_sm_work, rockchip_usb2phy_otg_sm_work); + +- /* +- * Some SoCs use one interrupt with otg-id/otg-bvalid/linestate +- * interrupts muxed together, so probe the otg-mux interrupt first, +- * if not found, then look for the regular interrupts one by one. +- */ +- rport->otg_mux_irq = of_irq_get_byname(child_np, "otg-mux"); +- if (rport->otg_mux_irq > 0) { +- ret = devm_request_threaded_irq(rphy->dev, rport->otg_mux_irq, +- NULL, +- rockchip_usb2phy_otg_mux_irq, +- IRQF_ONESHOT, +- "rockchip_usb2phy_otg", +- rport); +- if (ret) { +- dev_err(rphy->dev, +- "failed to request otg-mux irq handle\n"); +- goto out; +- } +- } else { +- rport->bvalid_irq = of_irq_get_byname(child_np, "otg-bvalid"); +- if (rport->bvalid_irq < 0) { +- dev_err(rphy->dev, "no vbus valid irq provided\n"); +- ret = rport->bvalid_irq; +- goto out; +- } +- +- ret = devm_request_threaded_irq(rphy->dev, rport->bvalid_irq, +- NULL, +- rockchip_usb2phy_bvalid_irq, +- IRQF_ONESHOT, +- "rockchip_usb2phy_bvalid", +- rport); +- if (ret) { +- dev_err(rphy->dev, +- "failed to request otg-bvalid irq handle\n"); +- goto out; +- } +- } ++ ret = rockchip_usb2phy_port_irq_init(rphy, rport, child_np); ++ if (ret) { ++ dev_err(rphy->dev, "failed to init irq for host port\n"); ++ goto out; + + if (!IS_ERR(rphy->edev)) { + rport->event_nb.notifier_call = rockchip_otg_event; +@@ -1117,6 +1172,7 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev) + phy_cfgs = match->data; + 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); + + ret = rockchip_usb2phy_extcon_register(rphy); +@@ -1196,6 +1252,20 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev) + } + + provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); ++ ++ if (rphy->irq > 0) { ++ ret = devm_request_threaded_irq(rphy->dev, rphy->irq, NULL, ++ rockchip_usb2phy_irq, ++ IRQF_ONESHOT, ++ "rockchip_usb2phy", ++ rphy); ++ if (ret) { ++ dev_err(rphy->dev, ++ "failed to request usb2phy irq handle\n"); ++ goto put_child; ++ } ++ } ++ + return PTR_ERR_OR_ZERO(provider); + + put_child: + + +The rk3568 usb2phy is a standalone device with a single muxed interrupt. +Add support for the registers to the usb2phy driver. + +Signed-off-by: Peter Geis +Tested-by: Michael Riesch +--- + drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 65 +++++++++++++++++++ + 1 file changed, 65 insertions(+) + +diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c +index 285958fdab38..bdc5a861891c 100644 +--- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c ++++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c +@@ -1093,6 +1093,7 @@ static int rockchip_usb2phy_otg_port_init(struct rockchip_usb2phy *rphy, + if (ret) { + dev_err(rphy->dev, "failed to init irq for host port\n"); + goto out; ++ } + + if (!IS_ERR(rphy->edev)) { + rport->event_nb.notifier_call = rockchip_otg_event; +@@ -1504,6 +1505,69 @@ static const struct rockchip_usb2phy_cfg rk3399_phy_cfgs[] = { + { /* sentinel */ } + }; + ++static const struct rockchip_usb2phy_cfg rk3568_phy_cfgs[] = { ++ { ++ .reg = 0xfe8a0000, ++ .num_ports = 2, ++ .clkout_ctl = { 0x0008, 4, 4, 1, 0 }, ++ .port_cfgs = { ++ [USB2PHY_PORT_OTG] = { ++ .phy_sus = { 0x0000, 8, 0, 0, 0x1d1 }, ++ .bvalid_det_en = { 0x0080, 2, 2, 0, 1 }, ++ .bvalid_det_st = { 0x0084, 2, 2, 0, 1 }, ++ .bvalid_det_clr = { 0x0088, 2, 2, 0, 1 }, ++ .utmi_avalid = { 0x00c0, 10, 10, 0, 1 }, ++ .utmi_bvalid = { 0x00c0, 9, 9, 0, 1 }, ++ }, ++ [USB2PHY_PORT_HOST] = { ++ /* Select suspend control from controller */ ++ .phy_sus = { 0x0004, 8, 0, 0x1d2, 0x1d2 }, ++ .ls_det_en = { 0x0080, 1, 1, 0, 1 }, ++ .ls_det_st = { 0x0084, 1, 1, 0, 1 }, ++ .ls_det_clr = { 0x0088, 1, 1, 0, 1 }, ++ .utmi_ls = { 0x00c0, 17, 16, 0, 1 }, ++ .utmi_hstdet = { 0x00c0, 19, 19, 0, 1 } ++ } ++ }, ++ .chg_det = { ++ .opmode = { 0x0000, 3, 0, 5, 1 }, ++ .cp_det = { 0x00c0, 24, 24, 0, 1 }, ++ .dcp_det = { 0x00c0, 23, 23, 0, 1 }, ++ .dp_det = { 0x00c0, 25, 25, 0, 1 }, ++ .idm_sink_en = { 0x0008, 8, 8, 0, 1 }, ++ .idp_sink_en = { 0x0008, 7, 7, 0, 1 }, ++ .idp_src_en = { 0x0008, 9, 9, 0, 1 }, ++ .rdm_pdwn_en = { 0x0008, 10, 10, 0, 1 }, ++ .vdm_src_en = { 0x0008, 12, 12, 0, 1 }, ++ .vdp_src_en = { 0x0008, 11, 11, 0, 1 }, ++ }, ++ }, ++ { ++ .reg = 0xfe8b0000, ++ .num_ports = 2, ++ .clkout_ctl = { 0x0008, 4, 4, 1, 0 }, ++ .port_cfgs = { ++ [USB2PHY_PORT_OTG] = { ++ .phy_sus = { 0x0000, 8, 0, 0x1d2, 0x1d1 }, ++ .ls_det_en = { 0x0080, 0, 0, 0, 1 }, ++ .ls_det_st = { 0x0084, 0, 0, 0, 1 }, ++ .ls_det_clr = { 0x0088, 0, 0, 0, 1 }, ++ .utmi_ls = { 0x00c0, 5, 4, 0, 1 }, ++ .utmi_hstdet = { 0x00c0, 7, 7, 0, 1 } ++ }, ++ [USB2PHY_PORT_HOST] = { ++ .phy_sus = { 0x0004, 8, 0, 0x1d2, 0x1d1 }, ++ .ls_det_en = { 0x0080, 1, 1, 0, 1 }, ++ .ls_det_st = { 0x0084, 1, 1, 0, 1 }, ++ .ls_det_clr = { 0x0088, 1, 1, 0, 1 }, ++ .utmi_ls = { 0x00c0, 17, 16, 0, 1 }, ++ .utmi_hstdet = { 0x00c0, 19, 19, 0, 1 } ++ } ++ }, ++ }, ++ { /* sentinel */ } ++}; ++ + static const struct rockchip_usb2phy_cfg rv1108_phy_cfgs[] = { + { + .reg = 0x100, +@@ -1553,6 +1617,7 @@ static const struct of_device_id rockchip_usb2phy_dt_match[] = { + { .compatible = "rockchip,rk3328-usb2phy", .data = &rk3328_phy_cfgs }, + { .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,rv1108-usb2phy", .data = &rv1108_phy_cfgs }, + {} + }; + + +Add the requisite nodes to the rk3568 device tree to enable the usb2 +device controllers. +Includes the usb2phy nodes, usb2phy grf nodes, and usb2 controller +nodes. + +Signed-off-by: Peter Geis +Tested-by: Michael Riesch +--- + arch/arm64/boot/dts/rockchip/rk356x.dtsi | 98 ++++++++++++++++++++++++ + 1 file changed, 98 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk356x.dtsi b/arch/arm64/boot/dts/rockchip/rk356x.dtsi +index 46d9552f6028..2c2b1014e53b 100644 +--- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi +@@ -204,6 +204,50 @@ gic: interrupt-controller@fd400000 { + msi-controller; + }; + ++ usb_host0_ehci: usb@fd800000 { ++ compatible = "generic-ehci"; ++ reg = <0x0 0xfd800000 0x0 0x40000>; ++ interrupts = ; ++ clocks = <&cru HCLK_USB2HOST0>, <&cru HCLK_USB2HOST0_ARB>, ++ <&cru PCLK_USB>; ++ phys = <&u2phy1_otg>; ++ phy-names = "usb"; ++ status = "disabled"; ++ }; ++ ++ usb_host0_ohci: usb@fd840000 { ++ compatible = "generic-ohci"; ++ reg = <0x0 0xfd840000 0x0 0x40000>; ++ interrupts = ; ++ clocks = <&cru HCLK_USB2HOST0>, <&cru HCLK_USB2HOST0_ARB>, ++ <&cru PCLK_USB>; ++ phys = <&u2phy1_otg>; ++ phy-names = "usb"; ++ status = "disabled"; ++ }; ++ ++ usb_host1_ehci: usb@fd880000 { ++ compatible = "generic-ehci"; ++ reg = <0x0 0xfd880000 0x0 0x40000>; ++ interrupts = ; ++ clocks = <&cru HCLK_USB2HOST1>, <&cru HCLK_USB2HOST1_ARB>, ++ <&cru PCLK_USB>; ++ phys = <&u2phy1_host>; ++ phy-names = "usb"; ++ status = "disabled"; ++ }; ++ ++ usb_host1_ohci: usb@fd8c0000 { ++ compatible = "generic-ohci"; ++ reg = <0x0 0xfd8c0000 0x0 0x40000>; ++ interrupts = ; ++ clocks = <&cru HCLK_USB2HOST1>, <&cru HCLK_USB2HOST1_ARB>, ++ <&cru PCLK_USB>; ++ phys = <&u2phy1_host>; ++ phy-names = "usb"; ++ status = "disabled"; ++ }; ++ + pmugrf: syscon@fdc20000 { + compatible = "rockchip,rk3568-pmugrf", "syscon", "simple-mfd"; + reg = <0x0 0xfdc20000 0x0 0x10000>; +@@ -219,6 +263,16 @@ grf: syscon@fdc60000 { + reg = <0x0 0xfdc60000 0x0 0x10000>; + }; + ++ usb2phy0_grf: syscon@fdca0000 { ++ compatible = "rockchip,rk3568-usb2phy-grf", "syscon"; ++ reg = <0x0 0xfdca0000 0x0 0x8000>; ++ }; ++ ++ usb2phy1_grf: syscon@fdca8000 { ++ compatible = "rockchip,rk3568-usb2phy-grf", "syscon"; ++ reg = <0x0 0xfdca8000 0x0 0x8000>; ++ }; ++ + pmucru: clock-controller@fdd00000 { + compatible = "rockchip,rk3568-pmucru"; + reg = <0x0 0xfdd00000 0x0 0x1000>; +@@ -1077,6 +1131,50 @@ pwm15: pwm@fe700030 { + status = "disabled"; + }; + ++ u2phy0: usb2phy@fe8a0000 { ++ compatible = "rockchip,rk3568-usb2phy"; ++ reg = <0x0 0xfe8a0000 0x0 0x10000>; ++ clocks = <&pmucru CLK_USBPHY0_REF>; ++ clock-names = "phyclk"; ++ clock-output-names = "clk_usbphy0_480m"; ++ interrupts = ; ++ rockchip,usbgrf = <&usb2phy0_grf>; ++ #clock-cells = <0>; ++ status = "disabled"; ++ ++ u2phy0_host: host-port { ++ #phy-cells = <0>; ++ status = "disabled"; ++ }; ++ ++ u2phy0_otg: otg-port { ++ #phy-cells = <0>; ++ status = "disabled"; ++ }; ++ }; ++ ++ u2phy1: usb2phy@fe8b0000 { ++ compatible = "rockchip,rk3568-usb2phy"; ++ reg = <0x0 0xfe8b0000 0x0 0x10000>; ++ clocks = <&pmucru CLK_USBPHY1_REF>; ++ clock-names = "phyclk"; ++ clock-output-names = "clk_usbphy1_480m"; ++ interrupts = ; ++ rockchip,usbgrf = <&usb2phy1_grf>; ++ #clock-cells = <0>; ++ status = "disabled"; ++ ++ u2phy1_host: host-port { ++ #phy-cells = <0>; ++ status = "disabled"; ++ }; ++ ++ u2phy1_otg: otg-port { ++ #phy-cells = <0>; ++ status = "disabled"; ++ }; ++ }; ++ + pinctrl: pinctrl { + compatible = "rockchip,rk3568-pinctrl"; + rockchip,grf = <&grf>; + + +Add the nodes and regulators to enable usb2 support on the Quartz64 +Model A. + +Signed-off-by: Peter Geis +Tested-by: Michael Riesch +--- + .../boot/dts/rockchip/rk3566-quartz64-a.dts | 52 +++++++++++++++++++ + 1 file changed, 52 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts +index 4d4b2a301b1a..e5a70ff4e920 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts +@@ -124,6 +124,22 @@ vcc5v0_usb: vcc5v0_usb { + vin-supply = <&vcc12v_dcin>; + }; + ++ /* all four ports are controlled by one gpio ++ * the host ports are sourced from vcc5v0_usb ++ * the otg port is sourced from vcc5v0_midu ++ */ ++ vcc5v0_usb20_host: vcc5v0_usb20_host { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc5v0_usb20_host"; ++ enable-active-high; ++ gpio = <&gpio4 RK_PB5 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&vcc5v0_usb20_host_en>; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ vin-supply = <&vcc5v0_usb>; ++ }; ++ + vcc3v3_sd: vcc3v3_sd { + compatible = "regulator-fixed"; + enable-active-low; +@@ -477,6 +493,12 @@ pmic_int_l: pmic-int-l { + }; + }; + ++ usb2 { ++ vcc5v0_usb20_host_en: vcc5v0-usb20-host-en { ++ rockchip,pins = <4 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ + vcc_sd { + vcc_sd_h: vcc-sd-h { + rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>; +@@ -546,3 +568,33 @@ bluetooth { + &uart2 { + status = "okay"; + }; ++ ++&u2phy1_host { ++ phy-supply = <&vcc5v0_usb20_host>; ++ status = "okay"; ++}; ++ ++&u2phy1_otg { ++ phy-supply = <&vcc5v0_usb20_host>; ++ status = "okay"; ++}; ++ ++&u2phy1 { ++ status = "okay"; ++}; ++ ++&usb_host0_ehci { ++ status = "okay"; ++}; ++ ++&usb_host0_ohci { ++ status = "okay"; ++}; ++ ++&usb_host1_ehci { ++ status = "okay"; ++}; ++ ++&usb_host1_ohci { ++ status = "okay"; ++}; diff --git a/patch/kernel/archive/rk35xx-5.16/rk356x-usb3.patch b/patch/kernel/archive/rk35xx-5.16/rk356x-usb3.patch new file mode 100644 index 0000000000..5b3106157b --- /dev/null +++ b/patch/kernel/archive/rk35xx-5.16/rk356x-usb3.patch @@ -0,0 +1,516 @@ +--- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi +@@ -247,6 +247,98 @@ + }; + }; + ++ sata1: sata@fc400000 { ++ compatible = "snps,dwc-ahci"; ++ reg = <0 0xfc400000 0 0x1000>; ++ clocks = <&cru ACLK_SATA1>, <&cru CLK_SATA1_PMALIVE>, ++ <&cru CLK_SATA1_RXOOB>; ++ clock-names = "sata", "pmalive", "rxoob"; ++ interrupts = ; ++ interrupt-names = "hostc"; ++ phys = <&combphy1 PHY_TYPE_SATA>; ++ phy-names = "sata-phy"; ++ ports-implemented = <0x1>; ++ power-domains = <&power RK3568_PD_PIPE>; ++ status = "disabled"; ++ }; ++ ++ sata2: sata@fc800000 { ++ compatible = "snps,dwc-ahci"; ++ reg = <0 0xfc800000 0 0x1000>; ++ clocks = <&cru ACLK_SATA2>, <&cru CLK_SATA2_PMALIVE>, ++ <&cru CLK_SATA2_RXOOB>; ++ clock-names = "sata", "pmalive", "rxoob"; ++ interrupts = ; ++ interrupt-names = "hostc"; ++ phys = <&combphy2 PHY_TYPE_SATA>; ++ phy-names = "sata-phy"; ++ ports-implemented = <0x1>; ++ power-domains = <&power RK3568_PD_PIPE>; ++ status = "disabled"; ++ }; ++ ++ usbdrd30: usbdrd { ++ compatible = "rockchip,rk3399-dwc3", "snps,dwc3"; ++ clocks = <&cru CLK_USB3OTG0_REF>, <&cru CLK_USB3OTG0_SUSPEND>, ++ <&cru ACLK_USB3OTG0>, <&cru PCLK_PIPE>; ++ clock-names = "ref_clk", "suspend_clk", ++ "bus_clk", "pipe_clk"; ++ #address-cells = <2>; ++ #size-cells = <2>; ++ ranges; ++ status = "disabled"; ++ ++ usbdrd_dwc3: dwc3@fcc00000 { ++ compatible = "snps,dwc3"; ++ reg = <0x0 0xfcc00000 0x0 0x400000>; ++ interrupts = ; ++ dr_mode = "host"; ++ phy_type = "utmi_wide"; ++ power-domains = <&power RK3568_PD_PIPE>; ++ resets = <&cru SRST_USB3OTG0>; ++ reset-names = "usb3-otg"; ++ snps,dis_enblslpm_quirk; ++ snps,dis-u2-freeclk-exists-quirk; ++ snps,dis-del-phy-power-chg-quirk; ++ snps,dis-tx-ipgap-linecheck-quirk; ++ snps,xhci-trb-ent-quirk; ++ status = "disabled"; ++ }; ++ }; ++ ++ usbhost30: usbhost { ++ compatible = "rockchip,rk3399-dwc3", "snps,dwc3"; ++ clocks = <&cru CLK_USB3OTG1_REF>, <&cru CLK_USB3OTG1_SUSPEND>, ++ <&cru ACLK_USB3OTG1>, <&cru PCLK_PIPE>; ++ clock-names = "ref_clk", "suspend_clk", ++ "bus_clk", "pipe_clk"; ++ #address-cells = <2>; ++ #size-cells = <2>; ++ assigned-clocks = <&cru CLK_PCIEPHY1_REF>; ++ assigned-clock-rates = <25000000>; ++ ranges; ++ status = "disabled"; ++ ++ usbhost_dwc3: dwc3@fd000000 { ++ compatible = "snps,dwc3"; ++ reg = <0x0 0xfd000000 0x0 0x400000>; ++ interrupts = ; ++ dr_mode = "host"; ++ phys = <&u2phy0_host>, <&combphy1 PHY_TYPE_USB3>; ++ phy-names = "usb2-phy", "usb3-phy"; ++ phy_type = "utmi_wide"; ++ power-domains = <&power RK3568_PD_PIPE>; ++ resets = <&cru SRST_USB3OTG1>; ++ reset-names = "usb3-host"; ++ snps,dis_enblslpm_quirk; ++ snps,dis-u2-freeclk-exists-quirk; ++ snps,dis_u2_susphy_quirk; ++ snps,dis-del-phy-power-chg-quirk; ++ snps,dis-tx-ipgap-linecheck-quirk; ++ status = "disabled"; ++ }; ++ }; ++ + gic: interrupt-controller@fd400000 { + compatible = "arm,gic-v3"; + reg = <0x0 0xfd400000 0 0x10000>, /* GICD */ +@@ -365,6 +472,7 @@ + clocks = <&pmucru SCLK_UART0>, <&pmucru PCLK_UART0>; + clock-names = "baudclk", "apb_pclk"; + dmas = <&dmac0 0>, <&dmac0 1>; ++ dma-names = "tx", "rx"; + pinctrl-0 = <&uart0_xfer>; + pinctrl-names = "default"; + reg-io-width = <4>; +@@ -573,7 +681,8 @@ + }; + + vop: vop@fe040000 { +- reg = <0x0 0xfe040000 0x0 0x5000>; ++ reg = <0x0 0xfe040000 0x0 0x3000>, <0x0 0xfe044000 0x0 0x1000>; ++ reg-names = "regs", "gamma_lut"; + interrupts = ; + clocks = <&cru ACLK_VOP>, <&cru HCLK_VOP>, <&cru DCLK_VOP0>, <&cru DCLK_VOP1>, <&cru DCLK_VOP2>; + clock-names = "aclk_vop", "hclk_vop", "dclk_vp0", "dclk_vp1", "dclk_vp2"; +@@ -770,6 +879,61 @@ + qos_vop_m1: qos@fe1a8100 { + compatible = "rockchip,rk3568-qos", "syscon"; + reg = <0x0 0xfe1a8100 0x0 0x20>; ++ }; ++ ++ pcie2x1: pcie@fe260000 { ++ compatible = "rockchip,rk3568-pcie"; ++ #address-cells = <3>; ++ #size-cells = <2>; ++ bus-range = <0x0 0xf>; ++ assigned-clocks = <&cru ACLK_PCIE20_MST>, <&cru ACLK_PCIE20_SLV>, ++ <&cru ACLK_PCIE20_DBI>, <&cru PCLK_PCIE20>, ++ <&cru CLK_PCIE20_AUX_NDFT>; ++ clocks = <&cru ACLK_PCIE20_MST>, <&cru ACLK_PCIE20_SLV>, ++ <&cru ACLK_PCIE20_DBI>, <&cru PCLK_PCIE20>, ++ <&cru CLK_PCIE20_AUX_NDFT>; ++ clock-names = "aclk_mst", "aclk_slv", ++ "aclk_dbi", "pclk", "aux"; ++ device_type = "pci"; ++ interrupts = , ++ , ++ , ++ , ++ ; ++ interrupt-names = "sys", "pmc", "msi", "legacy", "err"; ++ #interrupt-cells = <1>; ++ interrupt-map-mask = <0 0 0 7>; ++ interrupt-map = <0 0 0 1 &pcie_intc 0>, ++ <0 0 0 2 &pcie_intc 1>, ++ <0 0 0 3 &pcie_intc 2>, ++ <0 0 0 4 &pcie_intc 3>; ++ linux,pci-domain = <0>; ++ num-ib-windows = <6>; ++ num-ob-windows = <2>; ++ max-link-speed = <2>; ++ msi-map = <0x0 &gic 0x0 0x1000>; ++ num-lanes = <1>; ++ phys = <&combphy2 PHY_TYPE_PCIE>; ++ phy-names = "pcie-phy"; ++ power-domains = <&power RK3568_PD_PIPE>; ++ reg = <0x3 0xc0000000 0x0 0x400000>, ++ <0x0 0xfe260000 0x0 0x10000>, ++ <0x3 0x3f800000 0x0 0x800000>; ++ ranges = <0x1000000 0x0 0x7f700000 0x3 0x3f700000 0x0 0x00100000 ++ 0x2000000 0x0 0x40000000 0x3 0x00000000 0x0 0x3f700000>; ++ reg-names = "dbi", "apb", "config"; ++ resets = <&cru SRST_PCIE20_POWERUP>; ++ reset-names = "pipe"; ++ status = "disabled"; ++ ++ pcie_intc: legacy-interrupt-controller { ++ #address-cells = <0>; ++ #interrupt-cells = <1>; ++ interrupt-controller; ++ interrupt-parent = <&gic>; ++ interrupts = ; ++ }; ++ + }; + + sdmmc0: mmc@fe2b0000 { +@@ -797,6 +961,17 @@ + max-frequency = <150000000>; + resets = <&cru SRST_SDMMC1>; + reset-names = "reset"; ++ status = "disabled"; ++ }; ++ ++ sfc: spi@fe300000 { ++ compatible = "rockchip,sfc"; ++ reg = <0x0 0xfe300000 0x0 0x4000>; ++ interrupts = ; ++ clocks = <&cru SCLK_SFC>, <&cru HCLK_SFC>; ++ clock-names = "clk_sfc", "hclk_sfc"; ++ pinctrl-0 = <&fspi_pins>; ++ pinctrl-names = "default"; + status = "disabled"; + }; + +@@ -971,6 +1146,7 @@ + clocks = <&cru SCLK_UART1>, <&cru PCLK_UART1>; + clock-names = "baudclk", "apb_pclk"; + dmas = <&dmac0 2>, <&dmac0 3>; ++ dma-names = "tx", "rx"; + pinctrl-0 = <&uart1m0_xfer>; + pinctrl-names = "default"; + reg-io-width = <4>; +@@ -985,6 +1161,7 @@ + clocks = <&cru SCLK_UART2>, <&cru PCLK_UART2>; + clock-names = "baudclk", "apb_pclk"; + dmas = <&dmac0 4>, <&dmac0 5>; ++ dma-names = "tx", "rx"; + pinctrl-0 = <&uart2m0_xfer>; + pinctrl-names = "default"; + reg-io-width = <4>; +@@ -999,6 +1176,7 @@ + clocks = <&cru SCLK_UART3>, <&cru PCLK_UART3>; + clock-names = "baudclk", "apb_pclk"; + dmas = <&dmac0 6>, <&dmac0 7>; ++ dma-names = "tx", "rx"; + pinctrl-0 = <&uart3m0_xfer>; + pinctrl-names = "default"; + reg-io-width = <4>; +@@ -1013,6 +1191,7 @@ + clocks = <&cru SCLK_UART4>, <&cru PCLK_UART4>; + clock-names = "baudclk", "apb_pclk"; + dmas = <&dmac0 8>, <&dmac0 9>; ++ dma-names = "tx", "rx"; + pinctrl-0 = <&uart4m0_xfer>; + pinctrl-names = "default"; + reg-io-width = <4>; +@@ -1027,6 +1206,7 @@ + clocks = <&cru SCLK_UART5>, <&cru PCLK_UART5>; + clock-names = "baudclk", "apb_pclk"; + dmas = <&dmac0 10>, <&dmac0 11>; ++ dma-names = "tx", "rx"; + pinctrl-0 = <&uart5m0_xfer>; + pinctrl-names = "default"; + reg-io-width = <4>; +@@ -1041,6 +1221,7 @@ + clocks = <&cru SCLK_UART6>, <&cru PCLK_UART6>; + clock-names = "baudclk", "apb_pclk"; + dmas = <&dmac0 12>, <&dmac0 13>; ++ dma-names = "tx", "rx"; + pinctrl-0 = <&uart6m0_xfer>; + pinctrl-names = "default"; + reg-io-width = <4>; +@@ -1055,6 +1236,7 @@ + clocks = <&cru SCLK_UART7>, <&cru PCLK_UART7>; + clock-names = "baudclk", "apb_pclk"; + dmas = <&dmac0 14>, <&dmac0 15>; ++ dma-names = "tx", "rx"; + pinctrl-0 = <&uart7m0_xfer>; + pinctrl-names = "default"; + reg-io-width = <4>; +@@ -1069,6 +1251,7 @@ + clocks = <&cru SCLK_UART8>, <&cru PCLK_UART8>; + clock-names = "baudclk", "apb_pclk"; + dmas = <&dmac0 16>, <&dmac0 17>; ++ dma-names = "tx", "rx"; + pinctrl-0 = <&uart8m0_xfer>; + pinctrl-names = "default"; + reg-io-width = <4>; +@@ -1083,6 +1266,7 @@ + clocks = <&cru SCLK_UART9>, <&cru PCLK_UART9>; + clock-names = "baudclk", "apb_pclk"; + dmas = <&dmac0 18>, <&dmac0 19>; ++ dma-names = "tx", "rx"; + pinctrl-0 = <&uart9m0_xfer>; + pinctrl-names = "default"; + reg-io-width = <4>; + +--- a/arch/arm64/boot/dts/rockchip/rk3568.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3568.dtsi +@@ -7,6 +7,21 @@ + + / { + compatible = "rockchip,rk3568"; ++ ++ sata0: sata@fc000000 { ++ compatible = "snps,dwc-ahci"; ++ reg = <0 0xfc000000 0 0x1000>; ++ clocks = <&cru ACLK_SATA0>, <&cru CLK_SATA0_PMALIVE>, ++ <&cru CLK_SATA0_RXOOB>; ++ clock-names = "sata", "pmalive", "rxoob"; ++ interrupts = ; ++ interrupt-names = "hostc"; ++ phys = <&combphy0 PHY_TYPE_SATA>; ++ phy-names = "sata-phy"; ++ ports-implemented = <0x1>; ++ power-domains = <&power RK3568_PD_PIPE>; ++ status = "disabled"; ++ }; + + qos_pcie3x1: qos@fe190080 { + compatible = "rockchip,rk3568-qos", "syscon"; +@@ -78,6 +109,10 @@ + opp-hz = /bits/ 64 <1992000000>; + opp-microvolt = <1150000 1150000 1150000>; + }; ++}; ++ ++&pipegrf { ++ compatible = "rockchip,rk3568-pipegrf", "syscon"; + }; + + &power { +@@ -95,3 +130,8 @@ + #power-domain-cells = <0>; + }; + }; ++ ++&usbdrd_dwc3 { ++ phys = <&u2phy0_otg>, <&combphy0 PHY_TYPE_USB3>; ++ phy-names = "usb2-phy", "usb3-phy"; ++}; + +--- a/arch/arm64/boot/dts/rockchip/rk3566.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3566.dtsi +@@ -4,6 +4,10 @@ + + / { + compatible = "rockchip,rk3566"; ++}; ++ ++&pipegrf { ++ compatible = "rockchip,rk3566-pipegrf", "syscon"; + }; + + &power { +@@ -18,3 +22,11 @@ + #power-domain-cells = <0>; + }; + }; ++ ++&usbdrd_dwc3 { ++ phys = <&u2phy0_otg>; ++ phy-names = "usb2-phy"; ++ extcon = <&u2phy0>; ++ maximum-speed = "high-speed"; ++ snps,dis_u2_susphy_quirk; ++}; + +--- a/drivers/usb/dwc3/core.h ++++ b/drivers/usb/dwc3/core.h +@@ -258,6 +258,7 @@ + /* Global User Control 1 Register */ + #define DWC3_GUCTL1_DEV_DECOUPLE_L1L2_EVT BIT(31) + #define DWC3_GUCTL1_TX_IPGAP_LINECHECK_DIS BIT(28) ++#define DWC3_GUCTL1_DEV_FORCE_20_CLK_FOR_30_CLK BIT(26) + #define DWC3_GUCTL1_DEV_L1_EXIT_BY_HW BIT(24) + #define DWC3_GUCTL1_PARKMODE_DISABLE_SS BIT(17) + + +--- a/drivers/usb/dwc3/core.c ++++ b/drivers/usb/dwc3/core.c +@@ -1087,6 +1087,10 @@ + + if (dwc->parkmode_disable_ss_quirk) + reg |= DWC3_GUCTL1_PARKMODE_DISABLE_SS; ++ ++ if (dwc->maximum_speed == USB_SPEED_HIGH || ++ dwc->maximum_speed == USB_SPEED_FULL) ++ reg |= DWC3_GUCTL1_DEV_FORCE_20_CLK_FOR_30_CLK; + + dwc3_writel(dwc->regs, DWC3_GUCTL1, reg); + } + +--- a/drivers/pci/controller/dwc/pcie-dw-rockchip.c ++++ b/drivers/pci/controller/dwc/pcie-dw-rockchip.c +@@ -10,9 +10,12 @@ + + #include + #include ++#include ++#include + #include + #include + #include ++#include + #include + #include + #include +@@ -36,10 +39,12 @@ + #define PCIE_LINKUP (PCIE_SMLH_LINKUP | PCIE_RDLH_LINKUP) + #define PCIE_L0S_ENTRY 0x11 + #define PCIE_CLIENT_GENERAL_CONTROL 0x0 ++#define PCIE_CLIENT_INTR_MASK_LEGACY 0x1c + #define PCIE_CLIENT_GENERAL_DEBUG 0x104 +-#define PCIE_CLIENT_HOT_RESET_CTRL 0x180 ++#define PCIE_CLIENT_HOT_RESET_CTRL 0x180 + #define PCIE_CLIENT_LTSSM_STATUS 0x300 +-#define PCIE_LTSSM_ENABLE_ENHANCE BIT(4) ++#define PCIE_LEGACY_INT_ENABLE GENMASK(7, 0) ++#define PCIE_LTSSM_ENABLE_ENHANCE BIT(4) + #define PCIE_LTSSM_STATUS_MASK GENMASK(5, 0) + + struct rockchip_pcie { +@@ -51,6 +56,7 @@ + struct reset_control *rst; + struct gpio_desc *rst_gpio; + struct regulator *vpcie3v3; ++ struct irq_domain *irq_domain; + }; + + static int rockchip_pcie_readl_apb(struct rockchip_pcie *rockchip, +@@ -63,6 +69,68 @@ + u32 val, u32 reg) + { + writel_relaxed(val, rockchip->apb_base + reg); ++} ++ ++static void rockchip_pcie_legacy_int_handler(struct irq_desc *desc) ++{ ++ struct irq_chip *chip = irq_desc_get_chip(desc); ++ struct rockchip_pcie *rockchip = irq_desc_get_handler_data(desc); ++ struct device *dev = rockchip->pci.dev; ++ u32 reg; ++ u32 hwirq; ++ u32 virq; ++ ++ chained_irq_enter(chip, desc); ++ ++ reg = rockchip_pcie_readl_apb(rockchip, 0x8); ++ ++ while (reg) { ++ hwirq = ffs(reg) - 1; ++ reg &= ~BIT(hwirq); ++ ++ virq = irq_find_mapping(rockchip->irq_domain, hwirq); ++ if (virq) ++ generic_handle_irq(virq); ++ else ++ dev_err(dev, "unexpected IRQ, INT%d\n", hwirq); ++ } ++ ++ chained_irq_exit(chip, desc); ++} ++ ++static int rockchip_pcie_intx_map(struct irq_domain *domain, unsigned int irq, ++ irq_hw_number_t hwirq) ++{ ++ irq_set_chip_and_handler(irq, &dummy_irq_chip, handle_simple_irq); ++ irq_set_chip_data(irq, domain->host_data); ++ ++ return 0; ++} ++ ++static const struct irq_domain_ops intx_domain_ops = { ++ .map = rockchip_pcie_intx_map, ++}; ++ ++static int rockchip_pcie_init_irq_domain(struct rockchip_pcie *rockchip) ++{ ++ struct device *dev = rockchip->pci.dev; ++ struct device_node *intc; ++ ++ intc = of_get_child_by_name(dev->of_node, "legacy-interrupt-controller"); ++ if (!intc) { ++ dev_err(dev, "missing child interrupt-controller node\n"); ++ return -EINVAL; ++ } ++ ++ rockchip->irq_domain = irq_domain_add_linear(intc, PCI_NUM_INTX, ++ &intx_domain_ops, rockchip); ++ of_node_put(intc); ++ if (!rockchip->irq_domain) { ++ dev_err(dev, "failed to get a INTx IRQ domain\n"); ++ return -EINVAL; ++ } ++ ++ return 0; + } + + static void rockchip_pcie_enable_ltssm(struct rockchip_pcie *rockchip) +@@ -111,9 +179,27 @@ + { + struct dw_pcie *pci = to_dw_pcie_from_pp(pp); + struct rockchip_pcie *rockchip = to_rockchip_pcie(pci); +- u32 val = HIWORD_UPDATE_BIT(PCIE_LTSSM_ENABLE_ENHANCE); ++ struct device *dev = rockchip->pci.dev; ++ int irq, ret; ++ u32 val; ++ ++ irq = of_irq_get_byname(dev->of_node, "legacy"); ++ if (irq < 0) ++ return irq; ++ ++ irq_set_chained_handler_and_data(irq, rockchip_pcie_legacy_int_handler, rockchip); ++ ++ ret = rockchip_pcie_init_irq_domain(rockchip); ++ if (ret < 0) ++ dev_err(dev, "failed to init irq domain\n"); ++ ++ /* enable legacy interrupts */ ++ val = HIWORD_UPDATE_BIT(PCIE_LEGACY_INT_ENABLE); ++ val &= ~PCIE_LEGACY_INT_ENABLE; ++ rockchip_pcie_writel_apb(rockchip, val, PCIE_CLIENT_INTR_MASK_LEGACY); + + /* LTSSM enable control mode */ ++ val = HIWORD_UPDATE_BIT(PCIE_LTSSM_ENABLE_ENHANCE); + rockchip_pcie_writel_apb(rockchip, val, PCIE_CLIENT_HOT_RESET_CTRL); + + rockchip_pcie_writel_apb(rockchip, PCIE_CLIENT_RC_MODE, +@@ -214,6 +300,10 @@ + + rockchip->pci.dev = dev; + rockchip->pci.ops = &dw_pcie_ops; ++ ++ ret = dma_set_mask(rockchip->pci.dev, DMA_BIT_MASK(32)); ++ if (ret) ++ dev_warn(rockchip->pci.dev, "Failed to set DMA mask to 32-bit. Devices with only 32-bit MSI support may not work properly\n"); + + pp = &rockchip->pci.pp; + pp->ops = &rockchip_pcie_host_ops; + diff --git a/patch/kernel/archive/rk35xx-5.16/rk356x-vpu.patch b/patch/kernel/archive/rk35xx-5.16/rk356x-vpu.patch new file mode 100644 index 0000000000..491f196ab9 --- /dev/null +++ b/patch/kernel/archive/rk35xx-5.16/rk356x-vpu.patch @@ -0,0 +1,32 @@ +--- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi +@@ -617,6 +617,28 @@ + #cooling-cells = <2>; + power-domains = <&power RK3568_PD_GPU>; + status = "disabled"; ++ }; ++ ++ vpu: video-codec@fdea0400 { ++ compatible = "rockchip,rk3328-vpu"; ++ reg = <0x0 0xfdea0000 0x0 0x800>; ++ interrupts = ; ++ interrupt-names = "vdpu"; ++ clocks = <&cru ACLK_VPU>, <&cru HCLK_VPU>; ++ clock-names = "aclk", "hclk"; ++ iommus = <&vdpu_mmu>; ++ power-domains = <&power RK3568_PD_VPU>; ++ }; ++ ++ vdpu_mmu: iommu@fdea0800 { ++ compatible = "rockchip,rk3568-iommu"; ++ reg = <0x0 0xfdea0800 0x0 0x40>; ++ interrupts = ; ++ interrupt-names = "vdpu_mmu"; ++ clock-names = "aclk", "iface"; ++ clocks = <&cru ACLK_VPU>, <&cru HCLK_VPU>; ++ power-domains = <&power RK3568_PD_VPU>; ++ #iommu-cells = <0>; + }; + + sdmmc2: mmc@fe000000 { + diff --git a/patch/kernel/rk35xx-edge b/patch/kernel/rk35xx-edge new file mode 120000 index 0000000000..725efd44a4 --- /dev/null +++ b/patch/kernel/rk35xx-edge @@ -0,0 +1 @@ +archive/rk35xx-5.16 \ No newline at end of file