diff --git a/config/boards/rk322x-box.tvb b/config/boards/rk322x-box.tvb new file mode 100644 index 0000000000..e41a10d1b9 --- /dev/null +++ b/config/boards/rk322x-box.tvb @@ -0,0 +1,8 @@ +# RK322X TVBox quad core 1GB/2GB DDR2/DDR3 eMMC/NAND SoC FE WiFi +BOARD_NAME="rk322x-box" +BOARDFAMILY="rk322x" +BOOTCONFIG="rk322x-box_defconfig" +BOOT_FDT_FILE="rk322x-box.dtb" +MODULES_LEGACY="hci_uart rfcomm hidp" +MODULES_BLACKLIST_LEGACY="ssv6051 8723cs r8188eu" +KERNEL_TARGET="legacy,current" diff --git a/config/bootenv/rk322x-default.txt b/config/bootenv/rk322x-default.txt new file mode 100644 index 0000000000..4ad0e401c7 --- /dev/null +++ b/config/bootenv/rk322x-default.txt @@ -0,0 +1,2 @@ +verbosity=1 +extraargs=coherent_pool=2M diff --git a/config/bootscripts/boot-rk322x.cmd b/config/bootscripts/boot-rk322x.cmd new file mode 100644 index 0000000000..68ac3b55e2 --- /dev/null +++ b/config/bootscripts/boot-rk322x.cmd @@ -0,0 +1,68 @@ +# DO NOT EDIT THIS FILE +# +# Please edit /boot/armbianEnv.txt to set supported parameters +# + +setenv ramdisk_addr_r "0x64000000" +setenv load_addr "0x600f0000" +setenv overlay_error "false" +# default values +setenv rootdev "/dev/mmcblk0p1" +setenv verbosity "1" +setenv console "both" +setenv rootfstype "ext4" +setenv docker_optimizations "on" + +echo "Boot script loaded from ${devtype} ${devnum}" + +if test -e ${devtype} ${devnum} ${prefix}armbianEnv.txt; then + load ${devtype} ${devnum} ${load_addr} ${prefix}armbianEnv.txt + env import -t ${load_addr} ${filesize} +fi + +if test "${logo}" = "disabled"; then setenv logo "logo.nologo"; fi + +# get PARTUUID of first partition on SD/eMMC the boot script was loaded from +if test "${devtype}" = "mmc"; then part uuid mmc ${devnum}:1 partuuid; fi + +setenv bootargs "earlyprintk root=${rootdev} console=ttyS2,115200n8 console=tty1 rootwait rootfstype=${rootfstype} ${consoleargs} consoleblank=0 loglevel=${verbosity} ubootpart=${partuuid} usb-storage.quirks=${usbstoragequirks} ${extraargs} ${extraboardargs}" + +if test "${docker_optimizations}" = "on"; then setenv bootargs "${bootargs} cgroup_enable=cpuset cgroup_memory=1 cgroup_enable=memory swapaccount=1"; fi + +load ${devtype} ${devnum} ${ramdisk_addr_r} ${prefix}uInitrd +load ${devtype} ${devnum} ${kernel_addr_r} ${prefix}zImage + +load ${devtype} ${devnum} ${fdt_addr_r} ${prefix}dtb/${fdtfile} +fdt addr ${fdt_addr_r} +fdt resize 65536 +for overlay_file in ${overlays}; do + if load ${devtype} ${devnum} ${load_addr} ${prefix}dtb/overlay/${overlay_prefix}-${overlay_file}.dtbo; then + echo "Applying kernel provided DT overlay ${overlay_prefix}-${overlay_file}.dtbo" + fdt apply ${load_addr} || setenv overlay_error "true" + fi +done +for overlay_file in ${user_overlays}; do + if load ${devtype} ${devnum} ${load_addr} ${prefix}overlay-user/${overlay_file}.dtbo; then + echo "Applying user provided DT overlay ${overlay_file}.dtbo" + fdt apply ${load_addr} || setenv overlay_error "true" + fi +done +if test "${overlay_error}" = "true"; then + echo "Error applying DT overlays, restoring original DT" + load ${devtype} ${devnum} ${fdt_addr_r} ${prefix}dtb/${fdtfile} +else + if load ${devtype} ${devnum} ${load_addr} ${prefix}dtb/overlay/${overlay_prefix}-fixup.scr; then + echo "Applying kernel provided DT fixup script (${overlay_prefix}-fixup.scr)" + source ${load_addr} + fi + if test -e ${devtype} ${devnum} ${prefix}fixup.scr; then + load ${devtype} ${devnum} ${load_addr} ${prefix}fixup.scr + echo "Applying user provided fixup script (fixup.scr)" + source ${load_addr} + fi +fi + +bootz ${kernel_addr_r} ${ramdisk_addr_r} ${fdt_addr_r} + +# Recompile with: +# mkimage -C none -A arm -T script -d /boot/boot.cmd /boot/boot.scr diff --git a/config/kernel/linux-rk322x-current.config b/config/kernel/linux-rk322x-current.config new file mode 100644 index 0000000000..c90f9a1d5f --- /dev/null +++ b/config/kernel/linux-rk322x-current.config @@ -0,0 +1,6975 @@ +# +# Automatically generated file; DO NOT EDIT. +# Linux/arm 5.6.4 Kernel Configuration +# + +# +# Compiler: arm-linux-gnueabihf-gcc (GNU Toolchain for the A-profile Architecture 8.3-2019.03 (arm-rel-8.36)) 8.3.0 +# +CONFIG_CC_IS_GCC=y +CONFIG_GCC_VERSION=80300 +CONFIG_CLANG_VERSION=0 +CONFIG_CC_CAN_LINK=y +CONFIG_CC_HAS_ASM_GOTO=y +CONFIG_CC_HAS_ASM_INLINE=y +CONFIG_CC_HAS_WARN_MAYBE_UNINITIALIZED=y +CONFIG_IRQ_WORK=y +CONFIG_BUILDTIME_TABLE_SORT=y + +# +# General setup +# +CONFIG_INIT_ENV_ARG_LIMIT=32 +# CONFIG_COMPILE_TEST is not set +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_BUILD_SALT="" +CONFIG_HAVE_KERNEL_GZIP=y +CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_XZ=y +CONFIG_HAVE_KERNEL_LZO=y +CONFIG_HAVE_KERNEL_LZ4=y +CONFIG_KERNEL_GZIP=y +# CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_XZ is not set +# CONFIG_KERNEL_LZO is not set +# CONFIG_KERNEL_LZ4 is not set +CONFIG_DEFAULT_HOSTNAME="localhost" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_POSIX_MQUEUE=y +CONFIG_POSIX_MQUEUE_SYSCTL=y +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_DOMAIN_HIERARCHY=y +CONFIG_HANDLE_DOMAIN_IRQ=y +CONFIG_IRQ_FORCED_THREADING=y +CONFIG_SPARSE_IRQ=y +# CONFIG_GENERIC_IRQ_DEBUGFS is not set +# end of IRQ subsystem + +CONFIG_GENERIC_IRQ_MULTI_HANDLER=y +CONFIG_ARCH_CLOCKSOURCE_DATA=y +CONFIG_GENERIC_TIME_VSYSCALL=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_ARCH_HAS_TICK_BROADCAST=y +CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y + +# +# 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_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_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_PSI is not set +# end of CPU/Task time and stats accounting + +CONFIG_CPU_ISOLATION=y + +# +# 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=y +CONFIG_RCU_STALL_COMMON=y +CONFIG_RCU_NEED_SEGCBLIST=y +# end of RCU Subsystem + +CONFIG_IKCONFIG=m +CONFIG_IKCONFIG_PROC=y +CONFIG_IKHEADERS=m +CONFIG_LOG_BUF_SHIFT=18 +CONFIG_LOG_CPU_MAX_BUF_SHIFT=12 +CONFIG_PRINTK_SAFE_LOG_BUF_SHIFT=13 +CONFIG_GENERIC_SCHED_CLOCK=y + +# +# Scheduler features +# +# CONFIG_UCLAMP_TASK is not set +# end of Scheduler features + +CONFIG_CGROUPS=y +CONFIG_PAGE_COUNTER=y +CONFIG_MEMCG=y +CONFIG_MEMCG_SWAP=y +CONFIG_MEMCG_SWAP_ENABLED=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_CPUSETS=y +CONFIG_PROC_PID_CPUSET=y +CONFIG_CGROUP_DEVICE=y +CONFIG_CGROUP_CPUACCT=y +CONFIG_CGROUP_PERF=y +# CONFIG_CGROUP_DEBUG is not set +CONFIG_SOCK_CGROUP_DATA=y +CONFIG_NAMESPACES=y +CONFIG_UTS_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 is not set +# 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_BOOT_CONFIG is not set +CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SYSCTL=y +CONFIG_HAVE_UID16=y +CONFIG_BPF=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_PRINTK_NMI=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_FUTEX_PI=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 is not set +CONFIG_KALLSYMS_BASE_RELATIVE=y +# CONFIG_BPF_SYSCALL is not set +# CONFIG_USERFAULTFD is not set +CONFIG_ARCH_HAS_MEMBARRIER_SYNC_CORE=y +CONFIG_RSEQ=y +# CONFIG_DEBUG_RSEQ is not set +CONFIG_EMBEDDED=y +CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=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_SLUB_MEMCG_SYSFS_ON is not set +# 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_ARM=y +CONFIG_ARM_HAS_SG_CHAIN=y +CONFIG_ARM_DMA_USE_IOMMU=y +CONFIG_ARM_DMA_IOMMU_ALIGNMENT=8 +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_HAVE_PROC_CPU=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_FIX_EARLYCON_MEM=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_ARCH_SUPPORTS_UPROBES=y +CONFIG_ARM_PATCH_PHYS_VIRT=y +CONFIG_GENERIC_BUG=y +CONFIG_PGTABLE_LEVELS=2 + +# +# System Type +# +CONFIG_MMU=y +CONFIG_ARCH_MMAP_RND_BITS_MIN=8 +CONFIG_ARCH_MMAP_RND_BITS_MAX=16 +CONFIG_ARCH_MULTIPLATFORM=y +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_DOVE is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C24XX is not set +# CONFIG_ARCH_OMAP1 is not set + +# +# Multiple platform selection +# + +# +# CPU Core family selection +# +# CONFIG_ARCH_MULTI_V6 is not set +CONFIG_ARCH_MULTI_V7=y +CONFIG_ARCH_MULTI_V6_V7=y +# end of Multiple platform selection + +# CONFIG_ARCH_VIRT is not set +# CONFIG_ARCH_ACTIONS is not set +# CONFIG_ARCH_ALPINE is not set +# CONFIG_ARCH_ARTPEC is not set +# CONFIG_ARCH_ASPEED is not set +# CONFIG_ARCH_AT91 is not set +# CONFIG_ARCH_BCM is not set +# CONFIG_ARCH_BERLIN is not set +# CONFIG_ARCH_DIGICOLOR is not set +# CONFIG_ARCH_EXYNOS is not set +# CONFIG_ARCH_HIGHBANK is not set +# CONFIG_ARCH_HISI is not set +# CONFIG_ARCH_MXC is not set +# CONFIG_ARCH_KEYSTONE is not set +# CONFIG_ARCH_MEDIATEK is not set +# CONFIG_ARCH_MESON is not set +# CONFIG_ARCH_MILBEAUT is not set +# CONFIG_ARCH_MMP is not set +# CONFIG_ARCH_MVEBU is not set +# CONFIG_ARCH_NPCM is not set + +# +# TI OMAP/AM/DM/DRA Family +# +# CONFIG_ARCH_OMAP3 is not set +# CONFIG_ARCH_OMAP4 is not set +# CONFIG_SOC_OMAP5 is not set +# CONFIG_SOC_AM33XX is not set +# CONFIG_SOC_AM43XX is not set +# CONFIG_SOC_DRA7XX is not set +# end of TI OMAP/AM/DM/DRA Family + +# CONFIG_ARCH_SIRF is not set +# CONFIG_ARCH_QCOM is not set +# CONFIG_ARCH_RDA is not set +# CONFIG_ARCH_REALVIEW is not set +CONFIG_ARCH_ROCKCHIP=y +# CONFIG_ARCH_S5PV210 is not set +# CONFIG_ARCH_RENESAS is not set +# CONFIG_ARCH_SOCFPGA is not set +# CONFIG_PLAT_SPEAR is not set +# CONFIG_ARCH_STI is not set +# CONFIG_ARCH_STM32 is not set +# CONFIG_ARCH_SUNXI is not set +# CONFIG_ARCH_TANGO is not set +# CONFIG_ARCH_TEGRA is not set +# CONFIG_ARCH_UNIPHIER is not set +# CONFIG_ARCH_U8500 is not set +# CONFIG_ARCH_VEXPRESS is not set +# CONFIG_ARCH_WM8850 is not set +# CONFIG_ARCH_ZX is not set +# CONFIG_ARCH_ZYNQ is not set + +# +# Processor Type +# +CONFIG_CPU_V7=y +CONFIG_CPU_THUMB_CAPABLE=y +CONFIG_CPU_32v6K=y +CONFIG_CPU_32v7=y +CONFIG_CPU_ABRT_EV7=y +CONFIG_CPU_PABRT_V7=y +CONFIG_CPU_CACHE_V7=y +CONFIG_CPU_CACHE_VIPT=y +CONFIG_CPU_COPY_V6=y +CONFIG_CPU_TLB_V7=y +CONFIG_CPU_HAS_ASID=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y + +# +# Processor Features +# +# CONFIG_ARM_LPAE is not set +CONFIG_ARM_THUMB=y +CONFIG_ARM_THUMBEE=y +CONFIG_ARM_VIRT_EXT=y +CONFIG_SWP_EMULATE=y +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_ICACHE_MISMATCH_WORKAROUND is not set +# CONFIG_CPU_BPREDICT_DISABLE is not set +CONFIG_CPU_SPECTRE=y +CONFIG_HARDEN_BRANCH_PREDICTOR=y +CONFIG_KUSER_HELPERS=y +CONFIG_VDSO=y +CONFIG_OUTER_CACHE=y +CONFIG_OUTER_CACHE_SYNC=y +CONFIG_MIGHT_HAVE_CACHE_L2X0=y +CONFIG_CACHE_L2X0=y +# CONFIG_CACHE_L2X0_PMU is not set +# CONFIG_PL310_ERRATA_588369 is not set +# CONFIG_PL310_ERRATA_727915 is not set +# CONFIG_PL310_ERRATA_753970 is not set +# CONFIG_PL310_ERRATA_769419 is not set +CONFIG_ARM_L1_CACHE_SHIFT_6=y +CONFIG_ARM_L1_CACHE_SHIFT=6 +CONFIG_ARM_DMA_MEM_BUFFERABLE=y +CONFIG_ARM_HEAVY_MB=y +CONFIG_DEBUG_ALIGN_RODATA=y +# CONFIG_ARM_ERRATA_430973 is not set +# CONFIG_ARM_ERRATA_643719 is not set +# CONFIG_ARM_ERRATA_720789 is not set +# CONFIG_ARM_ERRATA_754322 is not set +# CONFIG_ARM_ERRATA_754327 is not set +# CONFIG_ARM_ERRATA_764369 is not set +# CONFIG_ARM_ERRATA_775420 is not set +# CONFIG_ARM_ERRATA_798181 is not set +# CONFIG_ARM_ERRATA_773022 is not set +# CONFIG_ARM_ERRATA_818325_852422 is not set +# CONFIG_ARM_ERRATA_821420 is not set +# CONFIG_ARM_ERRATA_825619 is not set +# CONFIG_ARM_ERRATA_857271 is not set +# CONFIG_ARM_ERRATA_852421 is not set +# CONFIG_ARM_ERRATA_852423 is not set +# CONFIG_ARM_ERRATA_857272 is not set +# end of System Type + +# +# Bus support +# +# CONFIG_ARM_ERRATA_814220 is not set +# end of Bus support + +# +# Kernel Features +# +CONFIG_HAVE_SMP=y +CONFIG_SMP=y +CONFIG_SMP_ON_UP=y +CONFIG_ARM_CPU_TOPOLOGY=y +# CONFIG_SCHED_MC is not set +# CONFIG_SCHED_SMT is not set +CONFIG_HAVE_ARM_SCU=y +CONFIG_HAVE_ARM_ARCH_TIMER=y +CONFIG_HAVE_ARM_TWD=y +# CONFIG_MCPM is not set +# CONFIG_BIG_LITTLE is not set +# CONFIG_VMSPLIT_3G is not set +CONFIG_VMSPLIT_3G_OPT=y +# CONFIG_VMSPLIT_2G is not set +# CONFIG_VMSPLIT_1G is not set +CONFIG_PAGE_OFFSET=0xB0000000 +CONFIG_NR_CPUS=4 +CONFIG_HOTPLUG_CPU=y +CONFIG_ARM_PSCI=y +CONFIG_ARCH_NR_GPIO=288 +CONFIG_HZ_FIXED=0 +# CONFIG_HZ_100 is not set +# CONFIG_HZ_200 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_300 is not set +# CONFIG_HZ_500 is not set +# CONFIG_HZ_1000 is not set +CONFIG_HZ=250 +CONFIG_SCHED_HRTICK=y +# CONFIG_THUMB2_KERNEL is not set +CONFIG_ARM_PATCH_IDIV=y +CONFIG_AEABI=y +# CONFIG_OABI_COMPAT is not set +CONFIG_HAVE_ARCH_PFN_VALID=y +CONFIG_HIGHMEM=y +# CONFIG_HIGHPTE is not set +CONFIG_CPU_SW_DOMAIN_PAN=y +CONFIG_HW_PERF_EVENTS=y +CONFIG_ARCH_WANT_GENERAL_HUGETLB=y +# CONFIG_ARM_MODULE_PLTS is not set +CONFIG_FORCE_MAX_ZONEORDER=11 +CONFIG_ALIGNMENT_TRAP=y +# CONFIG_UACCESS_WITH_MEMCPY is not set +CONFIG_SECCOMP=y +# CONFIG_PARAVIRT is not set +# CONFIG_PARAVIRT_TIME_ACCOUNTING is not set +# CONFIG_XEN is not set +# end of Kernel Features + +# +# Boot options +# +CONFIG_USE_OF=y +CONFIG_ATAGS=y +# CONFIG_DEPRECATED_PARAM_STRUCT is not set +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +# CONFIG_ARM_APPENDED_DTB is not set +CONFIG_CMDLINE="" +# CONFIG_KEXEC is not set +# CONFIG_CRASH_DUMP is not set +CONFIG_AUTO_ZRELADDR=y +# CONFIG_EFI is not set +# end of Boot options + +# +# CPU Power Management +# + +# +# 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_QORIQ_CPUFREQ is not set +# end of CPU Frequency scaling + +# +# CPU Idle +# +CONFIG_CPU_IDLE=y +CONFIG_CPU_IDLE_MULTIPLE_DRIVERS=y +CONFIG_CPU_IDLE_GOV_LADDER=y +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=y +# CONFIG_ARM_HIGHBANK_CPUIDLE is not set +# end of ARM CPU Idle Drivers +# end of CPU Idle +# end of CPU Power Management + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_VFP=y +CONFIG_VFPv3=y +CONFIG_NEON=y +CONFIG_KERNEL_MODE_NEON=y +# end of Floating point emulation + +# +# Power management options +# +CONFIG_SUSPEND=y +CONFIG_SUSPEND_FREEZER=y +# CONFIG_SUSPEND_SKIP_SYNC is not set +# CONFIG_HIBERNATION is not set +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=y +CONFIG_PM_ADVANCED_DEBUG=y +# CONFIG_PM_TEST_SUSPEND is not set +CONFIG_PM_SLEEP_DEBUG=y +# CONFIG_DPM_WATCHDOG is not set +# CONFIG_APM_EMULATION 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_SUSPEND_POSSIBLE=y +CONFIG_ARM_CPU_SUSPEND=y +CONFIG_ARCH_HIBERNATION_POSSIBLE=y +# end of Power management options + +# +# Firmware Drivers +# +# CONFIG_ARM_SCMI_PROTOCOL is not set +# CONFIG_ARM_SCPI_PROTOCOL is not set +# CONFIG_FIRMWARE_MEMMAP is not set +# CONFIG_FW_CFG_SYSFS is not set +# CONFIG_TRUSTED_FOUNDATIONS is not set +CONFIG_HAVE_ARM_SMCCC=y +CONFIG_ARM_PSCI_FW=y +# CONFIG_ARM_PSCI_CHECKER is not set +# CONFIG_GOOGLE_FIRMWARE is not set + +# +# Tegra firmware driver +# +# end of Tegra firmware driver +# end of Firmware Drivers + +CONFIG_ARM_CRYPTO=y +CONFIG_CRYPTO_SHA1_ARM=m +CONFIG_CRYPTO_SHA1_ARM_NEON=m +CONFIG_CRYPTO_SHA1_ARM_CE=m +CONFIG_CRYPTO_SHA2_ARM_CE=m +CONFIG_CRYPTO_SHA256_ARM=m +CONFIG_CRYPTO_SHA512_ARM=m +CONFIG_CRYPTO_AES_ARM=m +CONFIG_CRYPTO_AES_ARM_BS=m +CONFIG_CRYPTO_AES_ARM_CE=m +CONFIG_CRYPTO_GHASH_ARM_CE=m +CONFIG_CRYPTO_CRCT10DIF_ARM_CE=m +CONFIG_CRYPTO_CRC32_ARM_CE=m +CONFIG_CRYPTO_CHACHA20_NEON=m +CONFIG_CRYPTO_POLY1305_ARM=m +CONFIG_CRYPTO_NHPOLY1305_NEON=m +CONFIG_CRYPTO_CURVE25519_NEON=m +# CONFIG_VIRTUALIZATION is not set + +# +# General architecture-dependent options +# +# CONFIG_OPROFILE is not set +CONFIG_HAVE_OPROFILE=y +# CONFIG_KPROBES is not set +# CONFIG_JUMP_LABEL is not set +CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y +CONFIG_ARCH_USE_BUILTIN_BSWAP=y +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +CONFIG_HAVE_OPTPROBES=y +CONFIG_HAVE_NMI=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_HAVE_ARCH_THREAD_STRUCT_WHITELIST=y +CONFIG_ARCH_32BIT_OFF_T=y +CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y +CONFIG_HAVE_RSEQ=y +CONFIG_HAVE_CLK=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_ARCH_WANT_IPC_PARSE_VERSION=y +CONFIG_HAVE_ARCH_SECCOMP_FILTER=y +CONFIG_SECCOMP_FILTER=y +CONFIG_HAVE_STACKPROTECTOR=y +CONFIG_CC_HAS_STACKPROTECTOR_NONE=y +CONFIG_STACKPROTECTOR=y +CONFIG_STACKPROTECTOR_STRONG=y +CONFIG_HAVE_CONTEXT_TRACKING=y +CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y +CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y +CONFIG_HAVE_MOD_ARCH_SPECIFIC=y +CONFIG_MODULES_USE_ELF_REL=y +CONFIG_ARCH_HAS_ELF_RANDOMIZE=y +CONFIG_HAVE_ARCH_MMAP_RND_BITS=y +CONFIG_HAVE_EXIT_THREAD=y +CONFIG_ARCH_MMAP_RND_BITS=8 +CONFIG_ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT=y +CONFIG_HAVE_COPY_THREAD_TLS=y +CONFIG_CLONE_BACKWARDS=y +CONFIG_OLD_SIGSUSPEND3=y +CONFIG_OLD_SIGACTION=y +CONFIG_COMPAT_32BIT_TIME=y +CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y +CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y +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_ARCH_HAS_PHYS_TO_DMA=y +# CONFIG_LOCK_EVENT_COUNTS is not set + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y +# end of GCOV-based kernel profiling + +CONFIG_PLUGIN_HOSTCC="" +CONFIG_HAVE_GCC_PLUGINS=y +# end of General architecture-dependent options + +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +CONFIG_MODULE_FORCE_LOAD=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +# CONFIG_MODULE_SIG is not set +# CONFIG_MODULE_COMPRESS is not set +# CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS is not set +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_TRIM_UNUSED_KSYMS is not set +CONFIG_MODULES_TREE_LOOKUP=y +CONFIG_BLOCK=y +CONFIG_BLK_SCSI_REQUEST=y +CONFIG_BLK_CGROUP_RWSTAT=y +CONFIG_BLK_DEV_BSG=y +# CONFIG_BLK_DEV_BSGLIB is not set +# CONFIG_BLK_DEV_INTEGRITY is not set +# CONFIG_BLK_DEV_ZONED is not set +CONFIG_BLK_DEV_THROTTLING=y +# CONFIG_BLK_DEV_THROTTLING_LOW is not set +# CONFIG_BLK_CMDLINE_PARSER is not set +# CONFIG_BLK_WBT is not set +# CONFIG_BLK_CGROUP_IOLATENCY is not set +# CONFIG_BLK_CGROUP_IOCOST is not set +CONFIG_BLK_DEBUG_FS=y +# CONFIG_BLK_SED_OPAL is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_AIX_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +CONFIG_MAC_PARTITION=y +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_KARMA_PARTITION is not set +CONFIG_EFI_PARTITION=y +# CONFIG_SYSV68_PARTITION is not set +# CONFIG_CMDLINE_PARTITION is not set +# end of Partition Types + +CONFIG_BLK_MQ_VIRTIO=y +CONFIG_BLK_PM=y + +# +# IO Schedulers +# +CONFIG_MQ_IOSCHED_DEADLINE=y +CONFIG_MQ_IOSCHED_KYBER=y +CONFIG_IOSCHED_BFQ=y +# CONFIG_BFQ_GROUP_IOSCHED is not set +# end of IO Schedulers + +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_FREEZER=y + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_ELF_FDPIC is not set +CONFIG_ELFCORE=y +CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y +CONFIG_BINFMT_SCRIPT=y +CONFIG_ARCH_HAS_BINFMT_FLAT=y +CONFIG_BINFMT_FLAT=y +CONFIG_BINFMT_FLAT_ARGVP_ENVP_ON_STACK=y +# CONFIG_BINFMT_FLAT_OLD is not set +CONFIG_BINFMT_ZFLAT=y +CONFIG_BINFMT_SHARED_FLAT=y +CONFIG_BINFMT_MISC=m +CONFIG_COREDUMP=y +# end of Executable file formats + +# +# Memory Management options +# +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_ARCH_KEEP_MEMBLOCK=y +CONFIG_MEMORY_ISOLATION=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +CONFIG_COMPACTION=y +CONFIG_MIGRATION=y +CONFIG_CONTIG_ALLOC=y +CONFIG_BOUNCE=y +CONFIG_KSM=y +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +CONFIG_CLEANCACHE=y +CONFIG_FRONTSWAP=y +CONFIG_CMA=y +# CONFIG_CMA_DEBUG is not set +# CONFIG_CMA_DEBUGFS is not set +CONFIG_CMA_AREAS=7 +CONFIG_ZSWAP=y +CONFIG_ZPOOL=y +CONFIG_ZBUD=y +CONFIG_Z3FOLD=y +CONFIG_ZSMALLOC=y +# CONFIG_PGTABLE_MAPPING is not set +# CONFIG_ZSMALLOC_STAT is not set +CONFIG_GENERIC_EARLY_IOREMAP=y +CONFIG_IDLE_PAGE_TRACKING=y +CONFIG_FRAME_VECTOR=y +# CONFIG_PERCPU_STATS is not set +# CONFIG_GUP_BENCHMARK is not set +# end of Memory Management options + +CONFIG_NET=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_UNIX_DIAG=m +CONFIG_TLS=m +# CONFIG_TLS_DEVICE is not set +# CONFIG_TLS_TOE is not set +CONFIG_XFRM=y +CONFIG_XFRM_OFFLOAD=y +CONFIG_XFRM_ALGO=m +CONFIG_XFRM_USER=m +# CONFIG_XFRM_INTERFACE is not set +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_STATISTICS is not set +CONFIG_XFRM_IPCOMP=m +CONFIG_NET_KEY=m +# CONFIG_NET_KEY_MIGRATE 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=y +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=y +CONFIG_NET_FOU=y +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=y +CONFIG_INET_DIAG=m +CONFIG_INET_TCP_DIAG=m +CONFIG_INET_UDP_DIAG=m +CONFIG_INET_RAW_DIAG=m +# CONFIG_INET_DIAG_DESTROY is not set +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=y +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=y +# CONFIG_DEFAULT_RENO is not set +CONFIG_DEFAULT_TCP_CONG="cubic" +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_IPCOMP=m +CONFIG_IPV6_MIP6=m +CONFIG_IPV6_ILA=m +CONFIG_INET6_XFRM_TUNNEL=m +CONFIG_INET6_TUNNEL=y +# CONFIG_IPV6_VTI is not set +CONFIG_IPV6_SIT=y +# CONFIG_IPV6_SIT_6RD is not set +CONFIG_IPV6_NDISC_NODETYPE=y +CONFIG_IPV6_TUNNEL=y +# CONFIG_IPV6_GRE is not set +CONFIG_IPV6_FOU=y +CONFIG_IPV6_FOU_TUNNEL=y +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 is not set +# CONFIG_IPV6_SEG6_HMAC 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_NETLINK=m +CONFIG_NETFILTER_FAMILY_BRIDGE=y +CONFIG_NETFILTER_FAMILY_ARP=y +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_COMMON=m +CONFIG_NF_LOG_NETDEV=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_SET=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 is not set +CONFIG_NF_DUP_NETDEV=m +CONFIG_NFT_DUP_NETDEV=m +CONFIG_NFT_FWD_NETDEV=m +CONFIG_NFT_FIB_NETDEV=m +CONFIG_NF_FLOW_TABLE_INET=m +CONFIG_NF_FLOW_TABLE=m +CONFIG_NETFILTER_XTABLES=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 is not set +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=y +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 + +# +# 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=y +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=y +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 +CONFIG_NF_TABLES_BRIDGE=m +# CONFIG_NFT_BRIDGE_META is not set +CONFIG_NFT_BRIDGE_REJECT=m +CONFIG_NF_LOG_BRIDGE=m +# CONFIG_NF_CONNTRACK_BRIDGE is not set +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 is not set +CONFIG_IP_DCCP=m +CONFIG_INET_DCCP_DIAG=m + +# +# DCCP CCIDs Configuration +# +# CONFIG_IP_DCCP_CCID2_DEBUG is not set +CONFIG_IP_DCCP_CCID3=y +# CONFIG_IP_DCCP_CCID3_DEBUG is not set +CONFIG_IP_DCCP_TFRC_LIB=y +# end of DCCP CCIDs Configuration + +# +# DCCP Kernel Hacking +# +# CONFIG_IP_DCCP_DEBUG is not set +# end of DCCP Kernel Hacking + +CONFIG_IP_SCTP=m +# CONFIG_SCTP_DBG_OBJCNT is not set +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 is not set +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 is not set +CONFIG_ATM_BR2684=m +CONFIG_ATM_BR2684_IPFILTER=y +CONFIG_L2TP=m +# CONFIG_L2TP_DEBUGFS is not set +CONFIG_L2TP_V3=y +CONFIG_L2TP_IP=m +CONFIG_L2TP_ETH=m +CONFIG_STP=y +CONFIG_GARP=y +CONFIG_MRP=y +CONFIG_BRIDGE=y +CONFIG_BRIDGE_IGMP_SNOOPING=y +CONFIG_BRIDGE_VLAN_FILTERING=y +CONFIG_HAVE_NET_DSA=y +CONFIG_NET_DSA=m +CONFIG_NET_DSA_TAG_8021Q=m +# CONFIG_NET_DSA_TAG_AR9331 is not set +CONFIG_NET_DSA_TAG_BRCM_COMMON=m +CONFIG_NET_DSA_TAG_BRCM=m +CONFIG_NET_DSA_TAG_BRCM_PREPEND=m +CONFIG_NET_DSA_TAG_GSWIP=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 is not set +CONFIG_NET_DSA_TAG_QCA=m +CONFIG_NET_DSA_TAG_LAN9303=m +CONFIG_NET_DSA_TAG_SJA1105=m +CONFIG_NET_DSA_TAG_TRAILER=m +CONFIG_VLAN_8021Q=y +CONFIG_VLAN_8021Q_GVRP=y +CONFIG_VLAN_8021Q_MVRP=y +# CONFIG_DECNET is not set +CONFIG_LLC=y +# CONFIG_LLC2 is not set +CONFIG_ATALK=m +CONFIG_DEV_APPLETALK=m +CONFIG_IPDDP=m +CONFIG_IPDDP_ENCAP=y +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_PHONET is not set +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 is not set +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 is not set +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 is not set +CONFIG_NET_SCH_INGRESS=m +CONFIG_NET_SCH_PLUG=m +# CONFIG_NET_SCH_ETS is not set +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_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 is not set +CONFIG_NET_ACT_VLAN=m +CONFIG_NET_ACT_BPF=m +CONFIG_NET_ACT_CONNMARK=m +# CONFIG_NET_ACT_CTINFO is not set +CONFIG_NET_ACT_SKBMOD=m +CONFIG_NET_ACT_IFE=m +CONFIG_NET_ACT_TUNNEL_KEY=m +# CONFIG_NET_ACT_CT 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_DEBUGFS is not set +# CONFIG_BATMAN_ADV_DEBUG is not set +CONFIG_BATMAN_ADV_SYSFS=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 is not set +CONFIG_NETLINK_DIAG=m +CONFIG_MPLS=y +CONFIG_NET_MPLS_GSO=m +# CONFIG_MPLS_ROUTING is not set +CONFIG_NET_NSH=m +CONFIG_HSR=m +CONFIG_NET_SWITCHDEV=y +CONFIG_NET_L3_MASTER_DEV=y +# CONFIG_NET_NCSI is not set +CONFIG_RPS=y +CONFIG_RFS_ACCEL=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_JIT is not set +CONFIG_NET_FLOW_LIMIT=y + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NET_DROP_MONITOR is not set +# end of Network testing +# end of Networking options + +# CONFIG_HAMRADIO is not set +CONFIG_CAN=y +CONFIG_CAN_RAW=m +CONFIG_CAN_BCM=m +CONFIG_CAN_GW=m +CONFIG_CAN_J1939=m + +# +# CAN Device Drivers +# +CONFIG_CAN_VCAN=m +CONFIG_CAN_VXCAN=m +CONFIG_CAN_SLCAN=m +CONFIG_CAN_DEV=y +CONFIG_CAN_CALC_BITTIMING=y +CONFIG_CAN_FLEXCAN=m +CONFIG_CAN_GRCAN=m +CONFIG_CAN_TI_HECC=m +CONFIG_CAN_C_CAN=m +CONFIG_CAN_C_CAN_PLATFORM=m +CONFIG_CAN_CC770=m +CONFIG_CAN_CC770_ISA=m +CONFIG_CAN_CC770_PLATFORM=m +CONFIG_CAN_IFI_CANFD=m +CONFIG_CAN_M_CAN=m +CONFIG_CAN_M_CAN_PLATFORM=m +CONFIG_CAN_M_CAN_TCAN4X5X=m +CONFIG_CAN_RCAR=m +CONFIG_CAN_RCAR_CANFD=m +CONFIG_CAN_SJA1000=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=y +# 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_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=y +CONFIG_BT_BREDR=y +CONFIG_BT_RFCOMM=y +# CONFIG_BT_RFCOMM_TTY is not set +# CONFIG_BT_BNEP is not set +CONFIG_BT_HIDP=y +CONFIG_BT_HS=y +CONFIG_BT_LE=y +CONFIG_BT_6LOWPAN=m +# CONFIG_BT_LEDS is not set +# CONFIG_BT_SELFTEST is not set +CONFIG_BT_DEBUGFS=y + +# +# Bluetooth device drivers +# +CONFIG_BT_INTEL=y +CONFIG_BT_BCM=y +CONFIG_BT_RTL=y +CONFIG_BT_HCIBTUSB=y +# CONFIG_BT_HCIBTUSB_AUTOSUSPEND is not set +CONFIG_BT_HCIBTUSB_BCM=y +# CONFIG_BT_HCIBTUSB_MTK is not set +CONFIG_BT_HCIBTUSB_RTL=y +CONFIG_BT_HCIBTSDIO=y +CONFIG_BT_HCIUART=y +CONFIG_BT_HCIUART_SERDEV=y +CONFIG_BT_HCIUART_H4=y +# CONFIG_BT_HCIUART_NOKIA is not set +# CONFIG_BT_HCIUART_BCSP is not set +CONFIG_BT_HCIUART_ATH3K=y +# CONFIG_BT_HCIUART_LL is not set +CONFIG_BT_HCIUART_3WIRE=y +# CONFIG_BT_HCIUART_INTEL is not set +# CONFIG_BT_HCIUART_BCM is not set +# CONFIG_BT_HCIUART_QCA is not set +# CONFIG_BT_HCIUART_AG6XX is not set +# CONFIG_BT_HCIUART_MRVL is not set +# CONFIG_BT_HCIBCM203X is not set +# CONFIG_BT_HCIBPA10X is not set +CONFIG_BT_HCIBFUSB=y +CONFIG_BT_HCIVHCI=y +CONFIG_BT_MRVL=y +CONFIG_BT_MRVL_SDIO=y +# CONFIG_BT_ATH3K is not set +CONFIG_BT_MTKSDIO=m +CONFIG_BT_MTKUART=m +# end of Bluetooth device drivers + +# CONFIG_AF_RXRPC is not set +# CONFIG_AF_KCM is not set +CONFIG_STREAM_PARSER=y +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=y +CONFIG_NL80211_TESTMODE=y +# 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=y +CONFIG_CFG80211_DEBUGFS=y +CONFIG_CFG80211_CRDA_SUPPORT=y +CONFIG_CFG80211_WEXT=y +CONFIG_LIB80211=y +CONFIG_LIB80211_CRYPT_WEP=y +CONFIG_LIB80211_CRYPT_CCMP=y +CONFIG_LIB80211_CRYPT_TKIP=y +# CONFIG_LIB80211_DEBUG is not set +CONFIG_MAC80211=y +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=y +# CONFIG_MAC80211_MESSAGE_TRACING is not set +CONFIG_MAC80211_DEBUG_MENU=y +# CONFIG_MAC80211_NOINLINE is not set +CONFIG_MAC80211_VERBOSE_DEBUG=y +# CONFIG_MAC80211_MLME_DEBUG is not set +# CONFIG_MAC80211_STA_DEBUG is not set +# CONFIG_MAC80211_HT_DEBUG is not set +# CONFIG_MAC80211_OCB_DEBUG is not set +# CONFIG_MAC80211_IBSS_DEBUG is not set +# CONFIG_MAC80211_PS_DEBUG is not set +# CONFIG_MAC80211_MPL_DEBUG is not set +# CONFIG_MAC80211_MPATH_DEBUG is not set +# CONFIG_MAC80211_MHWMP_DEBUG is not set +# CONFIG_MAC80211_MESH_SYNC_DEBUG is not set +# CONFIG_MAC80211_MESH_CSA_DEBUG is not set +# CONFIG_MAC80211_MESH_PS_DEBUG is not set +# CONFIG_MAC80211_TDLS_DEBUG is not set +# CONFIG_MAC80211_DEBUG_COUNTERS is not set +CONFIG_MAC80211_STA_HASH_MAX_SIZE=0 +# CONFIG_WIMAX is not set +CONFIG_RFKILL=y +CONFIG_RFKILL_LEDS=y +# CONFIG_RFKILL_INPUT is not set +# CONFIG_RFKILL_GPIO is not set +# CONFIG_NET_9P 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 is not set +# CONFIG_NFC is not set +CONFIG_PSAMPLE=m +CONFIG_NET_IFE=m +CONFIG_LWTUNNEL=y +CONFIG_LWTUNNEL_BPF=y +CONFIG_DST_CACHE=y +CONFIG_GRO_CELLS=y +CONFIG_NET_SOCK_MSG=y +CONFIG_NET_DEVLINK=y +CONFIG_PAGE_POOL=y +CONFIG_FAILOVER=m +CONFIG_ETHTOOL_NETLINK=y +CONFIG_HAVE_EBPF_JIT=y + +# +# Device Drivers +# +CONFIG_ARM_AMBA=y +CONFIG_HAVE_PCI=y +# CONFIG_PCI is not set +# CONFIG_PCCARD 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=y +# CONFIG_DEBUG_TEST_DRIVER_REMOVE is not set +# CONFIG_TEST_ASYNC_DRIVER_PROBE is not set +CONFIG_GENERIC_CPU_AUTOPROBE=y +CONFIG_REGMAP=y +CONFIG_REGMAP_I2C=y +CONFIG_REGMAP_SPI=m +CONFIG_REGMAP_MMIO=y +CONFIG_REGMAP_IRQ=y +CONFIG_DMA_SHARED_BUFFER=y +# CONFIG_DMA_FENCE_TRACE is not set +CONFIG_GENERIC_ARCH_TOPOLOGY=y +# end of Generic Driver Options + +# +# Bus devices +# +CONFIG_ARM_CCI=y +# CONFIG_BRCMSTB_GISB_ARB is not set +# CONFIG_MOXTET is not set +# CONFIG_SIMPLE_PM_BUS is not set +# CONFIG_VEXPRESS_CONFIG is not set +# end of Bus devices + +CONFIG_CONNECTOR=y +CONFIG_PROC_EVENTS=y +CONFIG_GNSS=m +# CONFIG_GNSS_MTK_SERIAL is not set +CONFIG_GNSS_SIRF_SERIAL=m +# CONFIG_GNSS_UBX_SERIAL is not set +# CONFIG_MTD is not set +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_NET=y +CONFIG_OF_MDIO=y +CONFIG_OF_RESERVED_MEM=y +CONFIG_OF_RESOLVE=y +CONFIG_OF_OVERLAY=y +CONFIG_OF_CONFIGFS=y +CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_NULL_BLK is not set +CONFIG_CDROM=y +CONFIG_ZRAM=m +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_CRYPTOLOOP is not set +CONFIG_BLK_DEV_DRBD=m +# CONFIG_DRBD_FAULT_INJECTION is not set +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=1 +CONFIG_BLK_DEV_RAM_SIZE=4096 +# CONFIG_CDROM_PKTCDVD is not set +CONFIG_ATA_OVER_ETH=m +CONFIG_VIRTIO_BLK=m +# CONFIG_BLK_DEV_RBD is not set + +# +# NVME Support +# +# CONFIG_NVME_FC is not set +# CONFIG_NVME_TARGET is not set +# end of NVME Support + +# +# Misc devices +# +# CONFIG_AD525X_DPOT is not set +# CONFIG_DUMMY_IRQ is not set +# CONFIG_ICS932S401 is not set +# CONFIG_ENCLOSURE_SERVICES 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 is not set +# CONFIG_XILINX_SDFEC is not set +CONFIG_MISC_RTSX=m +# CONFIG_PVPANIC is not set +# CONFIG_C2PORT is not set + +# +# EEPROM support +# +CONFIG_EEPROM_AT24=m +# CONFIG_EEPROM_AT25 is not set +# CONFIG_EEPROM_LEGACY is not set +# 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 is not set +# end of EEPROM support + +# +# 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 + +# +# Intel MIC & related support +# +# CONFIG_VOP_BUS is not set +# end of Intel MIC & related support + +# CONFIG_ECHO is not set +CONFIG_MISC_RTSX_USB=m +# end of Misc devices + +# +# SCSI device support +# +CONFIG_SCSI_MOD=y +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +CONFIG_BLK_DEV_SR=y +# CONFIG_BLK_DEV_SR_VENDOR is not set +# CONFIG_CHR_DEV_SG is not set +# 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=y +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +# CONFIG_SCSI_SRP_ATTRS is not set +# end of SCSI Transports + +CONFIG_SCSI_LOWLEVEL=y +# CONFIG_ISCSI_TCP is not set +# CONFIG_ISCSI_BOOT_SYSFS is not set +# CONFIG_SCSI_UFSHCD is not set +# CONFIG_SCSI_DEBUG is not set +CONFIG_SCSI_VIRTIO=m +# CONFIG_SCSI_DH is not set +# end of SCSI device support + +# CONFIG_ATA is not set +CONFIG_MD=y +CONFIG_BLK_DEV_MD=y +CONFIG_MD_AUTODETECT=y +# CONFIG_MD_LINEAR is not set +CONFIG_MD_RAID0=y +CONFIG_MD_RAID1=y +CONFIG_MD_RAID10=y +CONFIG_MD_RAID456=y +# CONFIG_MD_MULTIPATH is not set +# CONFIG_MD_FAULTY is not set +# CONFIG_BCACHE is not set +CONFIG_BLK_DEV_DM_BUILTIN=y +CONFIG_BLK_DEV_DM=y +# CONFIG_DM_DEBUG is not set +CONFIG_DM_BUFIO=y +# CONFIG_DM_DEBUG_BLOCK_MANAGER_LOCKING is not set +CONFIG_DM_BIO_PRISON=y +CONFIG_DM_PERSISTENT_DATA=y +# CONFIG_DM_UNSTRIPED is not set +CONFIG_DM_CRYPT=y +# CONFIG_DM_SNAPSHOT is not set +CONFIG_DM_THIN_PROVISIONING=y +# CONFIG_DM_CACHE is not set +CONFIG_DM_WRITECACHE=m +# CONFIG_DM_ERA is not set +CONFIG_DM_CLONE=m +CONFIG_DM_MIRROR=y +# CONFIG_DM_LOG_USERSPACE is not set +CONFIG_DM_RAID=y +# CONFIG_DM_ZERO is not set +# CONFIG_DM_MULTIPATH is not set +# CONFIG_DM_DELAY is not set +CONFIG_DM_DUST=m +# CONFIG_DM_INIT is not set +# CONFIG_DM_UEVENT is not set +# CONFIG_DM_FLAKEY is not set +CONFIG_DM_VERITY=y +# CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG is not set +# CONFIG_DM_VERITY_FEC is not set +# CONFIG_DM_SWITCH is not set +# CONFIG_DM_LOG_WRITES is not set +# CONFIG_DM_INTEGRITY is not set +# CONFIG_TARGET_CORE is not set +CONFIG_NETDEVICES=y +CONFIG_MII=y +CONFIG_NET_CORE=y +CONFIG_BONDING=m +CONFIG_DUMMY=y +# CONFIG_WIREGUARD is not set +# CONFIG_EQUALIZER is not set +CONFIG_IFB=m +# CONFIG_NET_TEAM is not set +CONFIG_MACVLAN=m +CONFIG_MACVTAP=m +CONFIG_IPVLAN_L3S=y +CONFIG_IPVLAN=m +CONFIG_IPVTAP=m +CONFIG_VXLAN=m +CONFIG_GENEVE=m +CONFIG_GTP=m +CONFIG_MACSEC=m +# CONFIG_NETCONSOLE is not set +CONFIG_TUN=y +CONFIG_TAP=m +# CONFIG_TUN_VNET_CROSS_LE is not set +CONFIG_VETH=m +CONFIG_VIRTIO_NET=m +# CONFIG_NLMON is not set +CONFIG_NET_VRF=m +CONFIG_ATM_DRIVERS=y +# CONFIG_ATM_DUMMY is not set +# CONFIG_ATM_TCP is not set + +# +# 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 is not set +CONFIG_NET_DSA_BCM_SF2=m +CONFIG_NET_DSA_LOOP=m +# CONFIG_NET_DSA_LANTIQ_GSWIP is not set +CONFIG_NET_DSA_MT7530=m +CONFIG_NET_DSA_MV88E6060=m +CONFIG_NET_DSA_MICROCHIP_KSZ_COMMON=m +# CONFIG_NET_DSA_MICROCHIP_KSZ9477 is not set +CONFIG_NET_DSA_MICROCHIP_KSZ8795=m +CONFIG_NET_DSA_MICROCHIP_KSZ8795_SPI=m +CONFIG_NET_DSA_MV88E6XXX=m +CONFIG_NET_DSA_MV88E6XXX_GLOBAL2=y +# CONFIG_NET_DSA_MV88E6XXX_PTP is not set +# CONFIG_NET_DSA_AR9331 is not set +CONFIG_NET_DSA_SJA1105=m +# CONFIG_NET_DSA_SJA1105_PTP is not set +# CONFIG_NET_DSA_QCA8K is not set +CONFIG_NET_DSA_REALTEK_SMI=m +CONFIG_NET_DSA_SMSC_LAN9303=m +# CONFIG_NET_DSA_SMSC_LAN9303_I2C is not set +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 is not set +# end of Distributed Switch Architecture drivers + +CONFIG_ETHERNET=y +# CONFIG_NET_VENDOR_ALACRITECH is not set +# CONFIG_ALTERA_TSE is not set +# CONFIG_NET_VENDOR_AMAZON is not set +# CONFIG_NET_VENDOR_AQUANTIA is not set +CONFIG_NET_VENDOR_ARC=y +CONFIG_ARC_EMAC_CORE=y +CONFIG_EMAC_ROCKCHIP=y +# CONFIG_NET_VENDOR_AURORA is not set +# CONFIG_NET_VENDOR_BROADCOM is not set +CONFIG_NET_VENDOR_CADENCE=y +# CONFIG_MACB is not set +CONFIG_NET_VENDOR_CAVIUM=y +# CONFIG_NET_VENDOR_CIRRUS is not set +# CONFIG_NET_VENDOR_CORTINA is not set +# CONFIG_DM9000 is not set +# CONFIG_DNET is not set +# CONFIG_NET_VENDOR_EZCHIP is not set +# CONFIG_NET_VENDOR_FARADAY is not set +CONFIG_NET_VENDOR_GOOGLE=y +# CONFIG_NET_VENDOR_HISILICON is not set +# CONFIG_NET_VENDOR_HUAWEI is not set +# CONFIG_NET_VENDOR_INTEL is not set +# CONFIG_NET_VENDOR_MARVELL is not set +# CONFIG_NET_VENDOR_MELLANOX is not set +# CONFIG_NET_VENDOR_MICREL is not set +# CONFIG_NET_VENDOR_MICROCHIP is not set +CONFIG_NET_VENDOR_MICROSEMI=y +CONFIG_MSCC_OCELOT_SWITCH=m +CONFIG_MSCC_OCELOT_SWITCH_OCELOT=m +# CONFIG_NET_VENDOR_NATSEMI is not set +# CONFIG_NET_VENDOR_NETRONOME is not set +CONFIG_NET_VENDOR_NI=y +# CONFIG_NI_XGE_MANAGEMENT_ENET is not set +# CONFIG_ETHOC is not set +CONFIG_NET_VENDOR_PENSANDO=y +# CONFIG_NET_VENDOR_QUALCOMM is not set +# CONFIG_NET_VENDOR_RENESAS is not set +# CONFIG_NET_VENDOR_ROCKER is not set +# CONFIG_NET_VENDOR_SAMSUNG is not set +# CONFIG_NET_VENDOR_SEEQ is not set +# CONFIG_NET_VENDOR_SOLARFLARE is not set +# CONFIG_NET_VENDOR_SMSC is not set +# CONFIG_NET_VENDOR_SOCIONEXT is not set +CONFIG_NET_VENDOR_STMICRO=y +CONFIG_STMMAC_ETH=y +# CONFIG_STMMAC_SELFTESTS is not set +CONFIG_STMMAC_PLATFORM=y +# CONFIG_DWMAC_DWC_QOS_ETH is not set +CONFIG_DWMAC_GENERIC=y +CONFIG_DWMAC_ROCKCHIP=y +# CONFIG_NET_VENDOR_SYNOPSYS is not set +# CONFIG_NET_VENDOR_VIA is not set +# CONFIG_NET_VENDOR_WIZNET is not set +CONFIG_NET_VENDOR_XILINX=y +# CONFIG_XILINX_AXI_EMAC is not set +CONFIG_MDIO_DEVICE=y +CONFIG_MDIO_BUS=y +CONFIG_MDIO_BCM_UNIMAC=m +# CONFIG_MDIO_BITBANG is not set +CONFIG_MDIO_BUS_MUX=m +# CONFIG_MDIO_BUS_MUX_GPIO is not set +# CONFIG_MDIO_BUS_MUX_MMIOREG is not set +CONFIG_MDIO_BUS_MUX_MULTIPLEXER=m +# CONFIG_MDIO_HISI_FEMAC is not set +CONFIG_MDIO_MSCC_MIIM=m +CONFIG_PHYLINK=y +CONFIG_PHYLIB=y +CONFIG_SWPHY=y +CONFIG_LED_TRIGGER_PHY=y + +# +# MII PHY device drivers +# +# CONFIG_SFP is not set +CONFIG_ADIN_PHY=m +# CONFIG_AMD_PHY is not set +# CONFIG_AQUANTIA_PHY is not set +CONFIG_AX88796B_PHY=m +CONFIG_BCM7XXX_PHY=m +# CONFIG_BCM87XX_PHY is not set +CONFIG_BCM_NET_PHYLIB=m +# CONFIG_BROADCOM_PHY is not set +# CONFIG_BCM84881_PHY is not set +# CONFIG_CICADA_PHY is not set +# CONFIG_CORTINA_PHY is not set +# CONFIG_DAVICOM_PHY is not set +# CONFIG_DP83822_PHY is not set +CONFIG_DP83TC811_PHY=m +# CONFIG_DP83848_PHY is not set +# CONFIG_DP83867_PHY is not set +# CONFIG_DP83869_PHY is not set +CONFIG_FIXED_PHY=y +# CONFIG_ICPLUS_PHY is not set +# CONFIG_INTEL_XWAY_PHY is not set +# CONFIG_LSI_ET1011C_PHY is not set +# CONFIG_LXT_PHY is not set +# CONFIG_MARVELL_PHY is not set +# CONFIG_MARVELL_10G_PHY is not set +# CONFIG_MICREL_PHY is not set +CONFIG_MICROCHIP_PHY=m +CONFIG_MICROCHIP_T1_PHY=m +# CONFIG_MICROSEMI_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_NXP_TJA11XX_PHY is not set +# CONFIG_AT803X_PHY is not set +# CONFIG_QSEMI_PHY is not set +CONFIG_REALTEK_PHY=m +# CONFIG_RENESAS_PHY is not set +CONFIG_ROCKCHIP_PHY=y +# CONFIG_SMSC_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_TERANETICS_PHY is not set +CONFIG_VITESSE_PHY=m +# CONFIG_XILINX_GMII2RGMII is not set +# CONFIG_MICREL_KS8995MA is not set +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 is not set +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=y +CONFIG_USB_NET_AX8817X=m +CONFIG_USB_NET_AX88179_178A=m +CONFIG_USB_NET_CDCETHER=y +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=y +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_IPHETH=m +CONFIG_USB_SIERRA_NET=m +CONFIG_USB_VL600=m +CONFIG_USB_NET_CH9200=m +CONFIG_USB_NET_AQC111=m +CONFIG_WLAN=y +# CONFIG_WIRELESS_WDS is not set +CONFIG_WLAN_VENDOR_ADMTEK=y +CONFIG_ATH_COMMON=m +CONFIG_WLAN_VENDOR_ATH=y +# CONFIG_ATH_DEBUG is not set +CONFIG_ATH9K_HW=m +CONFIG_ATH9K_COMMON=m +CONFIG_ATH9K_BTCOEX_SUPPORT=y +CONFIG_ATH9K=m +# CONFIG_ATH9K_AHB is not set +# CONFIG_ATH9K_DEBUGFS is not set +# CONFIG_ATH9K_DYNACK is not set +# CONFIG_ATH9K_WOW is not set +CONFIG_ATH9K_RFKILL=y +# CONFIG_ATH9K_CHANNEL_CONTEXT is not set +CONFIG_ATH9K_PCOEM=y +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_DEBUGFS is not set +CONFIG_CARL9170_WPC=y +# CONFIG_CARL9170_HWRNG is not set +# CONFIG_ATH6KL is not set +CONFIG_AR5523=m +CONFIG_ATH10K=m +CONFIG_ATH10K_CE=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=m +# CONFIG_WCN36XX_DEBUGFS is not set +CONFIG_WLAN_VENDOR_ATMEL=y +CONFIG_AT76C50X_USB=m +CONFIG_WLAN_VENDOR_BROADCOM=y +# CONFIG_B43 is not set +# CONFIG_B43LEGACY is not set +CONFIG_BRCMUTIL=m +# CONFIG_BRCMSMAC is not set +CONFIG_BRCMFMAC=m +CONFIG_BRCMFMAC_PROTO_BCDC=y +CONFIG_BRCMFMAC_SDIO=y +# CONFIG_BRCMFMAC_USB is not set +# CONFIG_BRCM_TRACING is not set +# CONFIG_BRCMDBG is not set +CONFIG_WLAN_VENDOR_CISCO=y +CONFIG_WLAN_VENDOR_INTEL=y +CONFIG_WLAN_VENDOR_INTERSIL=y +CONFIG_HOSTAP=y +CONFIG_HOSTAP_FIRMWARE=y +CONFIG_HOSTAP_FIRMWARE_NVRAM=y +# CONFIG_P54_COMMON is not set +CONFIG_WLAN_VENDOR_MARVELL=y +CONFIG_LIBERTAS=m +CONFIG_LIBERTAS_USB=m +CONFIG_LIBERTAS_SDIO=m +CONFIG_LIBERTAS_SPI=m +# CONFIG_LIBERTAS_DEBUG is not set +# CONFIG_LIBERTAS_MESH is not set +CONFIG_LIBERTAS_THINFIRM=y +# CONFIG_LIBERTAS_THINFIRM_DEBUG is not set +CONFIG_LIBERTAS_THINFIRM_USB=m +CONFIG_MWIFIEX=y +CONFIG_MWIFIEX_SDIO=y +CONFIG_MWIFIEX_USB=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_MT76x0_COMMON=m +CONFIG_MT76x0U=m +CONFIG_MT76x2_COMMON=m +CONFIG_MT76x2U=m +CONFIG_WLAN_VENDOR_RALINK=y +CONFIG_RT2X00=y +CONFIG_RT2500USB=y +CONFIG_RT73USB=y +CONFIG_RT2800USB=y +CONFIG_RT2800USB_RT33XX=y +CONFIG_RT2800USB_RT35XX=y +CONFIG_RT2800USB_RT3573=y +CONFIG_RT2800USB_RT53XX=y +CONFIG_RT2800USB_RT55XX=y +CONFIG_RT2800USB_UNKNOWN=y +CONFIG_RT2800_LIB=y +CONFIG_RT2X00_LIB_USB=y +CONFIG_RT2X00_LIB=y +CONFIG_RT2X00_LIB_FIRMWARE=y +CONFIG_RT2X00_LIB_CRYPTO=y +CONFIG_RT2X00_LIB_LEDS=y +# CONFIG_RT2X00_LIB_DEBUGFS is not set +# CONFIG_RT2X00_DEBUG is not set +CONFIG_WLAN_VENDOR_REALTEK=y +CONFIG_RTL8187=m +CONFIG_RTL8187_LEDS=y +CONFIG_RTL_CARDS=m +CONFIG_RTL8192CU=m +CONFIG_RTLWIFI=m +CONFIG_RTLWIFI_USB=m +# CONFIG_RTLWIFI_DEBUG is not set +CONFIG_RTL8192C_COMMON=m +CONFIG_RTL8XXXU=y +# CONFIG_RTL8XXXU_UNTESTED is not set +CONFIG_RTW88=m +CONFIG_WLAN_VENDOR_RSI=y +# CONFIG_RSI_91X is not set +CONFIG_WLAN_VENDOR_ST=y +# CONFIG_CW1200 is not set +CONFIG_WLAN_VENDOR_TI=y +# CONFIG_WL1251 is not set +# CONFIG_WL12XX is not set +# CONFIG_WL18XX is not set +# CONFIG_WLCORE is not set +CONFIG_RTL8723DS=m +CONFIG_RTL8822BU=m +# CONFIG_RTL8188EU is not set +CONFIG_RTL8821CU=m +CONFIG_88XXAU=m +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_MAC80211_HWSIM is not set +CONFIG_USB_NET_RNDIS_WLAN=y +CONFIG_VIRT_WIFI=m + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# +# CONFIG_WAN is not set +# CONFIG_NETDEVSIM is not set +CONFIG_NET_FAILOVER=m +# CONFIG_ISDN is not set +# CONFIG_NVM is not set + +# +# Input device support +# +CONFIG_INPUT=y +CONFIG_INPUT_LEDS=y +CONFIG_INPUT_FF_MEMLESS=y +CONFIG_INPUT_POLLDEV=y +# CONFIG_INPUT_SPARSEKMAP is not set +CONFIG_INPUT_MATRIXKMAP=y + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +CONFIG_INPUT_JOYDEV=y +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +# CONFIG_KEYBOARD_ADC is not set +# 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=m +CONFIG_KEYBOARD_GPIO_POLLED=m +# CONFIG_KEYBOARD_TCA6416 is not set +# CONFIG_KEYBOARD_TCA8418 is not set +CONFIG_KEYBOARD_MATRIX=m +# 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=y +# CONFIG_KEYBOARD_OMAP4 is not set +CONFIG_KEYBOARD_TM2_TOUCHKEY=m +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_CAP11XX is not set +# CONFIG_KEYBOARD_BCM is not set +CONFIG_INPUT_MOUSE=y +# CONFIG_MOUSE_PS2 is not set +# CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_APPLETOUCH is not set +# CONFIG_MOUSE_BCM5974 is not set +CONFIG_MOUSE_CYAPA=y +CONFIG_MOUSE_ELAN_I2C=y +CONFIG_MOUSE_ELAN_I2C_I2C=y +# CONFIG_MOUSE_ELAN_I2C_SMBUS 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_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=y +CONFIG_JOYSTICK_IFORCE_USB=y +# 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=y +CONFIG_JOYSTICK_XPAD_FF=y +CONFIG_JOYSTICK_XPAD_LEDS=y +# CONFIG_JOYSTICK_PSXPAD_SPI is not set +CONFIG_JOYSTICK_PXRC=m +CONFIG_JOYSTICK_FSIA6B=m +CONFIG_INPUT_TABLET=y +# CONFIG_TABLET_USB_ACECAD is not set +# CONFIG_TABLET_USB_AIPTEK is not set +# CONFIG_TABLET_USB_GTCO is not set +# CONFIG_TABLET_USB_HANWANG is not set +# CONFIG_TABLET_USB_KBTAB is not set +# CONFIG_TABLET_USB_PEGASUS is not set +# CONFIG_TABLET_SERIAL_WACOM4 is not set +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_PROPERTIES=y +CONFIG_TOUCHSCREEN_ADS7846=m +# CONFIG_TOUCHSCREEN_AD7877 is not set +# CONFIG_TOUCHSCREEN_AD7879 is not set +CONFIG_TOUCHSCREEN_ADC=m +# CONFIG_TOUCHSCREEN_AR1021_I2C is not set +CONFIG_TOUCHSCREEN_ATMEL_MXT=y +# CONFIG_TOUCHSCREEN_ATMEL_MXT_T37 is not set +# CONFIG_TOUCHSCREEN_AUO_PIXCIR is not set +# CONFIG_TOUCHSCREEN_BU21013 is not set +CONFIG_TOUCHSCREEN_BU21029=m +# CONFIG_TOUCHSCREEN_CHIPONE_ICN8318 is not set +# CONFIG_TOUCHSCREEN_CY8CTMG110 is not set +# CONFIG_TOUCHSCREEN_CYTTSP_CORE is not set +# CONFIG_TOUCHSCREEN_CYTTSP4_CORE is not set +# CONFIG_TOUCHSCREEN_DYNAPRO is not set +# CONFIG_TOUCHSCREEN_HAMPSHIRE is not set +# CONFIG_TOUCHSCREEN_EETI is not set +# CONFIG_TOUCHSCREEN_EGALAX is not set +# CONFIG_TOUCHSCREEN_EGALAX_SERIAL is not set +# CONFIG_TOUCHSCREEN_EXC3000 is not set +# CONFIG_TOUCHSCREEN_FUJITSU is not set +# CONFIG_TOUCHSCREEN_GOODIX is not set +# CONFIG_TOUCHSCREEN_HIDEEP is not set +# CONFIG_TOUCHSCREEN_ILI210X is not set +# CONFIG_TOUCHSCREEN_S6SY761 is not set +# CONFIG_TOUCHSCREEN_GUNZE is not set +# CONFIG_TOUCHSCREEN_EKTF2127 is not set +CONFIG_TOUCHSCREEN_ELAN=y +# CONFIG_TOUCHSCREEN_ELO is not set +# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set +# CONFIG_TOUCHSCREEN_WACOM_I2C is not set +# CONFIG_TOUCHSCREEN_MAX11801 is not set +# CONFIG_TOUCHSCREEN_MCS5000 is not set +# CONFIG_TOUCHSCREEN_MMS114 is not set +# CONFIG_TOUCHSCREEN_MELFAS_MIP4 is not set +# CONFIG_TOUCHSCREEN_MTOUCH is not set +# CONFIG_TOUCHSCREEN_IMX6UL_TSC is not set +# CONFIG_TOUCHSCREEN_INEXIO is not set +# CONFIG_TOUCHSCREEN_MK712 is not set +# CONFIG_TOUCHSCREEN_PENMOUNT is not set +# CONFIG_TOUCHSCREEN_EDT_FT5X06 is not set +# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set +# CONFIG_TOUCHSCREEN_TOUCHWIN is not set +# CONFIG_TOUCHSCREEN_PIXCIR is not set +# CONFIG_TOUCHSCREEN_WDT87XX_I2C is not set +CONFIG_TOUCHSCREEN_USB_COMPOSITE=y +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 is not set +# CONFIG_TOUCHSCREEN_TSC_SERIO is not set +# CONFIG_TOUCHSCREEN_TSC2004 is not set +# CONFIG_TOUCHSCREEN_TSC2005 is not set +# CONFIG_TOUCHSCREEN_TSC2007 is not set +# CONFIG_TOUCHSCREEN_RM_TS is not set +# CONFIG_TOUCHSCREEN_SILEAD is not set +# CONFIG_TOUCHSCREEN_SIS_I2C is not set +# CONFIG_TOUCHSCREEN_ST1232 is not set +# CONFIG_TOUCHSCREEN_STMFTS is not set +# CONFIG_TOUCHSCREEN_SUR40 is not set +# CONFIG_TOUCHSCREEN_SURFACE3_SPI is not set +# CONFIG_TOUCHSCREEN_SX8654 is not set +# CONFIG_TOUCHSCREEN_TPS6507X is not set +CONFIG_TOUCHSCREEN_ZET6223=m +# CONFIG_TOUCHSCREEN_ZFORCE is not set +# CONFIG_TOUCHSCREEN_ROHM_BU21023 is not set +CONFIG_TOUCHSCREEN_IQS5XX=m +CONFIG_INPUT_MISC=y +# CONFIG_INPUT_AD714X is not set +# CONFIG_INPUT_ATMEL_CAPTOUCH is not set +# CONFIG_INPUT_BMA150 is not set +# CONFIG_INPUT_E3X0_BUTTON is not set +# CONFIG_INPUT_MSM_VIBRATOR is not set +CONFIG_INPUT_MAX77650_ONKEY=m +# CONFIG_INPUT_MMA8450 is not set +# CONFIG_INPUT_GP2A is not set +# CONFIG_INPUT_GPIO_BEEPER is not set +# CONFIG_INPUT_GPIO_DECODER is not set +CONFIG_INPUT_GPIO_VIBRA=m +# CONFIG_INPUT_CPCAP_PWRBUTTON is not set +# 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_UINPUT=y +# CONFIG_INPUT_PCF8574 is not set +# CONFIG_INPUT_PWM_BEEPER is not set +# CONFIG_INPUT_PWM_VIBRA is not set +# CONFIG_INPUT_RK805_PWRKEY is not set +# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set +# CONFIG_INPUT_ADXL34X is not set +# CONFIG_INPUT_IMS_PCU is not set +# CONFIG_INPUT_CMA3000 is not set +# CONFIG_INPUT_DRV260X_HAPTICS is not set +# CONFIG_INPUT_DRV2665_HAPTICS is not set +# CONFIG_INPUT_DRV2667_HAPTICS is not set +# CONFIG_INPUT_STPMIC1_ONKEY is not set +CONFIG_RMI4_CORE=y +# CONFIG_RMI4_I2C is not set +# CONFIG_RMI4_SPI is not set +# CONFIG_RMI4_SMB is not set +CONFIG_RMI4_F03=y +CONFIG_RMI4_F03_SERIO=y +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_F54 is not set +# CONFIG_RMI4_F55 is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_AMBAKMI is not set +CONFIG_SERIO_LIBPS2=y +CONFIG_SERIO_RAW=y +# 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_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 is not set +# CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_N_GSM is not set +# CONFIG_TRACE_SINK is not set +CONFIG_NULL_TTY=m +CONFIG_LDISC_AUTOLOAD=y +CONFIG_DEVMEM=y +# CONFIG_DEVKMEM is not set + +# +# Serial drivers +# +CONFIG_SERIAL_EARLYCON=y +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=y +# CONFIG_SERIAL_8250_16550A_VARIANTS is not set +# CONFIG_SERIAL_8250_FINTEK is not set +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_DMA=y +CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +# 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_EM is not set +# CONFIG_SERIAL_8250_RT288X is not set +CONFIG_SERIAL_OF_PLATFORM=y + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_AMBA_PL010 is not set +# CONFIG_SERIAL_AMBA_PL011 is not set +# CONFIG_SERIAL_EARLYCON_ARM_SEMIHOST is not set +# 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_SIFIVE=m +# CONFIG_SERIAL_SCCNXP is not set +# CONFIG_SERIAL_SC16IS7XX is not set +# CONFIG_SERIAL_BCM63XX is not set +# CONFIG_SERIAL_ALTERA_JTAGUART is not set +# CONFIG_SERIAL_ALTERA_UART is not set +# CONFIG_SERIAL_IFX6X60 is not set +# CONFIG_SERIAL_XILINX_PS_UART is not set +# CONFIG_SERIAL_ARC is not set +# CONFIG_SERIAL_FSL_LPUART is not set +CONFIG_SERIAL_FSL_LINFLEXUART=m +# CONFIG_SERIAL_CONEXANT_DIGICOLOR is not set +# CONFIG_SERIAL_ST_ASC is not set +# end of Serial drivers + +CONFIG_SERIAL_MCTRL_GPIO=y +CONFIG_SERIAL_DEV_BUS=y +# CONFIG_SERIAL_DEV_CTRL_TTYPORT is not set +# CONFIG_TTY_PRINTK is not set +CONFIG_HVC_DRIVER=y +# CONFIG_HVC_DCC is not set +CONFIG_VIRTIO_CONSOLE=m +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMB_DEVICE_INTERFACE is not set +CONFIG_HW_RANDOM=y +# CONFIG_HW_RANDOM_TIMERIOMEM is not set +CONFIG_HW_RANDOM_VIRTIO=m +CONFIG_HW_RANDOM_OPTEE=m +# CONFIG_RAW_DRIVER is not set +CONFIG_TCG_TPM=y +CONFIG_HW_RANDOM_TPM=y +# CONFIG_TCG_TIS is not set +# CONFIG_TCG_TIS_SPI is not set +# CONFIG_TCG_TIS_I2C_ATMEL is not set +CONFIG_TCG_TIS_I2C_INFINEON=y +# CONFIG_TCG_TIS_I2C_NUVOTON is not set +# CONFIG_TCG_ATMEL is not set +# CONFIG_TCG_VTPM_PROXY is not set +# CONFIG_TCG_FTPM_TEE is not set +# CONFIG_TCG_TIS_ST33ZP24_I2C is not set +# CONFIG_TCG_TIS_ST33ZP24_SPI is not set +# CONFIG_XILLYBUS is not set +# end of Character devices + +# CONFIG_RANDOM_TRUST_BOOTLOADER is not set + +# +# I2C support +# +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_COMPAT=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_MUX=y + +# +# Multiplexer I2C Chip support +# +CONFIG_I2C_ARB_GPIO_CHALLENGE=m +CONFIG_I2C_MUX_GPIO=m +# CONFIG_I2C_MUX_GPMUX is not set +# CONFIG_I2C_MUX_LTC4306 is not set +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 is not set +# end of Multiplexer I2C Chip support + +CONFIG_I2C_HELPER_AUTO=y +CONFIG_I2C_ALGOBIT=y + +# +# I2C Hardware Bus support +# + +# +# I2C system bus drivers (mostly embedded / system-on-chip) +# +# CONFIG_I2C_CBUS_GPIO is not set +# CONFIG_I2C_DESIGNWARE_PLATFORM is not set +# CONFIG_I2C_EMEV2 is not set +# CONFIG_I2C_GPIO is not set +# 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_XILINX is not set + +# +# External I2C/SMBus adapter drivers +# +# CONFIG_I2C_DIOLAN_U2C is not set +# CONFIG_I2C_ROBOTFUZZ_OSIF is not set +# CONFIG_I2C_TAOS_EVM is not set +# CONFIG_I2C_TINY_USB is not set + +# +# Other I2C/SMBus bus drivers +# +# end of I2C Hardware Bus support + +CONFIG_I2C_STUB=m +CONFIG_I2C_SLAVE=y +# CONFIG_I2C_SLAVE_EEPROM 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 is not set +CONFIG_SPI=y +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_MASTER=y +# CONFIG_SPI_MEM is not set + +# +# SPI Master Controller Drivers +# +# CONFIG_SPI_ALTERA is not set +# CONFIG_SPI_AXI_SPI_ENGINE is not set +CONFIG_SPI_BITBANG=y +# CONFIG_SPI_CADENCE is not set +# CONFIG_SPI_DESIGNWARE is not set +# CONFIG_SPI_NXP_FLEXSPI is not set +# CONFIG_SPI_GPIO is not set +# CONFIG_SPI_FSL_SPI is not set +# CONFIG_SPI_OC_TINY is not set +# CONFIG_SPI_PL022 is not set +CONFIG_SPI_ROCKCHIP=y +# CONFIG_SPI_SC18IS602 is not set +# CONFIG_SPI_SIFIVE is not set +# CONFIG_SPI_MXIC is not set +# CONFIG_SPI_XCOMM is not set +# CONFIG_SPI_XILINX is not set +# CONFIG_SPI_ZYNQMP_GQSPI is not set + +# +# SPI Protocol Masters +# +CONFIG_SPI_SPIDEV=y +# CONFIG_SPI_LOOPBACK_TEST is not set +# CONFIG_SPI_TLE62X0 is not set +# CONFIG_SPI_SLAVE is not set +# CONFIG_SPMI 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_DP83640_PHY=m +# CONFIG_PTP_1588_CLOCK_INES is not set +# CONFIG_PTP_1588_CLOCK_IDTCM is not set +# end of PTP clock support + +CONFIG_PINCTRL=y +CONFIG_PINMUX=y +CONFIG_PINCONF=y +CONFIG_GENERIC_PINCONF=y +# CONFIG_DEBUG_PINCTRL is not set +# CONFIG_PINCTRL_AMD is not set +# CONFIG_PINCTRL_MCP23S08 is not set +CONFIG_PINCTRL_ROCKCHIP=y +# CONFIG_PINCTRL_SINGLE is not set +# CONFIG_PINCTRL_SX150X is not set +# CONFIG_PINCTRL_STMFX is not set +# CONFIG_PINCTRL_RK805 is not set +# CONFIG_PINCTRL_OCELOT is not set +CONFIG_PINCTRL_MADERA=m +# CONFIG_PINCTRL_EQUILIBRIUM is not set +CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y +CONFIG_GPIOLIB=y +CONFIG_GPIOLIB_FASTPATH_LIMIT=512 +CONFIG_OF_GPIO=y +CONFIG_GPIOLIB_IRQCHIP=y +CONFIG_DEBUG_GPIO=y +CONFIG_GPIO_SYSFS=y +CONFIG_GPIO_GENERIC=y + +# +# Memory mapped GPIO drivers +# +# CONFIG_GPIO_74XX_MMIO is not set +# CONFIG_GPIO_ALTERA is not set +# CONFIG_GPIO_CADENCE is not set +# CONFIG_GPIO_DWAPB is not set +# CONFIG_GPIO_FTGPIO010 is not set +CONFIG_GPIO_GENERIC_PLATFORM=y +# CONFIG_GPIO_GRGPIO is not set +# CONFIG_GPIO_HLWD is not set +# CONFIG_GPIO_LOGICVC is not set +# CONFIG_GPIO_MB86S7X is not set +# CONFIG_GPIO_MPC8XXX is not set +# CONFIG_GPIO_PL061 is not set +# CONFIG_GPIO_SAMA5D2_PIOBU is not set +# CONFIG_GPIO_SIFIVE is not set +# CONFIG_GPIO_SYSCON is not set +# CONFIG_GPIO_XILINX is not set +# CONFIG_GPIO_ZEVIO is not set +# CONFIG_GPIO_AMD_FCH is not set +# end of Memory mapped GPIO drivers + +# +# I2C GPIO expanders +# +# CONFIG_GPIO_ADP5588 is not set +# CONFIG_GPIO_ADNP is not set +# CONFIG_GPIO_GW_PLD is not set +# CONFIG_GPIO_MAX7300 is not set +# CONFIG_GPIO_MAX732X is not set +# CONFIG_GPIO_PCA953X is not set +# CONFIG_GPIO_PCF857X is not set +# CONFIG_GPIO_TPIC2810 is not set +# end of I2C GPIO expanders + +# +# MFD GPIO expanders +# +# CONFIG_HTC_EGPIO is not set +# CONFIG_GPIO_MADERA is not set +CONFIG_GPIO_MAX77650=m +# CONFIG_GPIO_TPS6586X is not set +# CONFIG_GPIO_TQMX86 is not set +# end of MFD GPIO expanders + +# +# SPI GPIO expanders +# +# CONFIG_GPIO_74X164 is not set +# CONFIG_GPIO_MAX3191X is not set +# CONFIG_GPIO_MAX7301 is not set +# CONFIG_GPIO_MC33880 is not set +# CONFIG_GPIO_PISOSR is not set +# CONFIG_GPIO_XRA1403 is not set +# end of SPI GPIO expanders + +# +# USB GPIO expanders +# +# end of USB GPIO expanders + +# CONFIG_GPIO_MOCKUP is not set +CONFIG_W1=m +CONFIG_W1_CON=y + +# +# 1-wire Bus Masters +# +# CONFIG_W1_MASTER_DS2490 is not set +# CONFIG_W1_MASTER_DS2482 is not set +# CONFIG_W1_MASTER_DS1WM is not set +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 is not set +# CONFIG_W1_SLAVE_DS2430 is not set +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 is not set +# CONFIG_W1_SLAVE_DS28E17 is not set +# end of 1-wire Slaves + +CONFIG_POWER_AVS=y +# CONFIG_QCOM_CPR is not set +CONFIG_ROCKCHIP_IODOMAIN=y +CONFIG_POWER_RESET=y +# CONFIG_POWER_RESET_BRCMKONA is not set +# CONFIG_POWER_RESET_BRCMSTB is not set +# CONFIG_POWER_RESET_GPIO is not set +CONFIG_POWER_RESET_GPIO_RESTART=y +# CONFIG_POWER_RESET_LTC2952 is not set +# CONFIG_POWER_RESET_RESTART is not set +# CONFIG_POWER_RESET_VERSATILE is not set +CONFIG_POWER_RESET_SYSCON=y +CONFIG_POWER_RESET_SYSCON_POWEROFF=y +CONFIG_REBOOT_MODE=m +CONFIG_SYSCON_REBOOT_MODE=m +# 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 is not set +# CONFIG_TEST_POWER is not set +# CONFIG_CHARGER_ADP5061 is not set +# CONFIG_BATTERY_CPCAP is not set +# CONFIG_BATTERY_DS2760 is not set +# CONFIG_BATTERY_DS2780 is not set +# CONFIG_BATTERY_DS2781 is not set +# CONFIG_BATTERY_DS2782 is not set +# CONFIG_BATTERY_LEGO_EV3 is not set +CONFIG_BATTERY_SBS=y +# CONFIG_CHARGER_SBS is not set +# CONFIG_MANAGER_SBS is not set +# CONFIG_BATTERY_BQ27XXX is not set +# CONFIG_BATTERY_MAX17040 is not set +# CONFIG_BATTERY_MAX17042 is not set +# CONFIG_BATTERY_MAX1721X is not set +# 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 is not set +# CONFIG_CHARGER_DETECTOR_MAX14656 is not set +# CONFIG_CHARGER_MAX77650 is not set +# 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_BQ25890 is not set +# CONFIG_CHARGER_SMB347 is not set +# CONFIG_BATTERY_GAUGE_LTC2941 is not set +# CONFIG_CHARGER_RT9455 is not set +# CONFIG_CHARGER_UCS1002 is not set +CONFIG_HWMON=y +# CONFIG_HWMON_DEBUG_CHIP is not set + +# +# Native drivers +# +# CONFIG_SENSORS_AD7314 is not set +# CONFIG_SENSORS_AD7414 is not set +# CONFIG_SENSORS_AD7418 is not set +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1029 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ADM1177 is not set +# CONFIG_SENSORS_ADM9240 is not set +# CONFIG_SENSORS_ADT7310 is not set +# CONFIG_SENSORS_ADT7410 is not set +# CONFIG_SENSORS_ADT7411 is not set +# CONFIG_SENSORS_ADT7462 is not set +# CONFIG_SENSORS_ADT7470 is not set +# CONFIG_SENSORS_ADT7475 is not set +# CONFIG_SENSORS_AS370 is not set +# CONFIG_SENSORS_ASC7621 is not set +# CONFIG_SENSORS_ASPEED is not set +# CONFIG_SENSORS_ATXP1 is not set +# CONFIG_SENSORS_DS620 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_F71805F is not set +# CONFIG_SENSORS_F71882FG is not set +# CONFIG_SENSORS_F75375S is not set +# CONFIG_SENSORS_FTSTEUTATES is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_G760A is not set +# CONFIG_SENSORS_G762 is not set +CONFIG_SENSORS_GPIO_FAN=y +# CONFIG_SENSORS_HIH6130 is not set +# CONFIG_SENSORS_IIO_HWMON is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_JC42 is not set +# CONFIG_SENSORS_POWR1220 is not set +# CONFIG_SENSORS_LINEAGE is not set +# CONFIG_SENSORS_LTC2945 is not set +# CONFIG_SENSORS_LTC2947_I2C is not set +# CONFIG_SENSORS_LTC2947_SPI is not set +# CONFIG_SENSORS_LTC2990 is not set +# CONFIG_SENSORS_LTC4151 is not set +# CONFIG_SENSORS_LTC4215 is not set +# CONFIG_SENSORS_LTC4222 is not set +# CONFIG_SENSORS_LTC4245 is not set +# CONFIG_SENSORS_LTC4260 is not set +# CONFIG_SENSORS_LTC4261 is not set +# CONFIG_SENSORS_MAX1111 is not set +# CONFIG_SENSORS_MAX16065 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_MAX1668 is not set +# CONFIG_SENSORS_MAX197 is not set +# CONFIG_SENSORS_MAX31722 is not set +# CONFIG_SENSORS_MAX31730 is not set +# CONFIG_SENSORS_MAX6621 is not set +# CONFIG_SENSORS_MAX6639 is not set +# CONFIG_SENSORS_MAX6642 is not set +# CONFIG_SENSORS_MAX6650 is not set +# CONFIG_SENSORS_MAX6697 is not set +# CONFIG_SENSORS_MAX31790 is not set +# CONFIG_SENSORS_MCP3021 is not set +# CONFIG_SENSORS_TC654 is not set +# CONFIG_SENSORS_ADCXX is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM70 is not set +# CONFIG_SENSORS_LM73 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set +# CONFIG_SENSORS_LM93 is not set +# CONFIG_SENSORS_LM95234 is not set +# CONFIG_SENSORS_LM95241 is not set +# CONFIG_SENSORS_LM95245 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_PC87427 is not set +# CONFIG_SENSORS_NTC_THERMISTOR is not set +# CONFIG_SENSORS_NCT6683 is not set +# CONFIG_SENSORS_NCT6775 is not set +# CONFIG_SENSORS_NCT7802 is not set +# CONFIG_SENSORS_NCT7904 is not set +# CONFIG_SENSORS_NPCM7XX is not set +# CONFIG_SENSORS_OCC_P8_I2C is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_PMBUS is not set +CONFIG_SENSORS_PWM_FAN=y +# CONFIG_SENSORS_SHT15 is not set +# CONFIG_SENSORS_SHT21 is not set +# CONFIG_SENSORS_SHT3x is not set +# CONFIG_SENSORS_SHTC1 is not set +# CONFIG_SENSORS_DME1737 is not set +# CONFIG_SENSORS_EMC1403 is not set +# CONFIG_SENSORS_EMC2103 is not set +# CONFIG_SENSORS_EMC6W201 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47M192 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_SCH5627 is not set +# CONFIG_SENSORS_SCH5636 is not set +# CONFIG_SENSORS_STTS751 is not set +# CONFIG_SENSORS_SMM665 is not set +# CONFIG_SENSORS_ADC128D818 is not set +# CONFIG_SENSORS_ADS7828 is not set +# CONFIG_SENSORS_ADS7871 is not set +# CONFIG_SENSORS_AMC6821 is not set +# CONFIG_SENSORS_INA209 is not set +# CONFIG_SENSORS_INA2XX is not set +# CONFIG_SENSORS_INA3221 is not set +# CONFIG_SENSORS_TC74 is not set +# CONFIG_SENSORS_THMC50 is not set +# CONFIG_SENSORS_TMP102 is not set +# CONFIG_SENSORS_TMP103 is not set +# CONFIG_SENSORS_TMP108 is not set +# CONFIG_SENSORS_TMP401 is not set +# CONFIG_SENSORS_TMP421 is not set +# CONFIG_SENSORS_TMP513 is not set +# CONFIG_SENSORS_VT1211 is not set +# CONFIG_SENSORS_W83773G is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83791D is not set +# CONFIG_SENSORS_W83792D is not set +# CONFIG_SENSORS_W83793 is not set +# CONFIG_SENSORS_W83795 is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83L786NG is not set +# CONFIG_SENSORS_W83627HF is not set +# CONFIG_SENSORS_W83627EHF is not set +CONFIG_THERMAL=y +# CONFIG_THERMAL_STATISTICS is not set +CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0 +CONFIG_THERMAL_HWMON=y +CONFIG_THERMAL_OF=y +# CONFIG_THERMAL_WRITABLE_TRIPS is not set +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 is not set +CONFIG_THERMAL_GOV_STEP_WISE=y +# CONFIG_THERMAL_GOV_BANG_BANG is not set +# CONFIG_THERMAL_GOV_USER_SPACE is not set +CONFIG_CPU_THERMAL=y +CONFIG_CPU_FREQ_THERMAL=y +# CONFIG_CLOCK_THERMAL is not set +# CONFIG_DEVFREQ_THERMAL is not set +# CONFIG_THERMAL_EMULATION is not set +CONFIG_THERMAL_MMIO=m +# CONFIG_QORIQ_THERMAL is not set +CONFIG_ROCKCHIP_THERMAL=m +# 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 is not set + +# +# Watchdog Pretimeout Governors +# +# CONFIG_WATCHDOG_PRETIMEOUT_GOV is not set + +# +# Watchdog Device Drivers +# +CONFIG_SOFT_WATCHDOG=m +# CONFIG_GPIO_WATCHDOG is not set +# CONFIG_XILINX_WATCHDOG is not set +# CONFIG_ZIIRAVE_WATCHDOG is not set +# CONFIG_ARM_SP805_WATCHDOG is not set +# CONFIG_CADENCE_WATCHDOG is not set +# CONFIG_FTWDT010_WATCHDOG is not set +CONFIG_DW_WATCHDOG=m +# CONFIG_MAX63XX_WATCHDOG is not set +# CONFIG_STPMIC1_WATCHDOG is not set +# CONFIG_MEN_A21_WDT is not set + +# +# USB-based Watchdog Cards +# +# CONFIG_USBPCWATCHDOG is not set +CONFIG_SSB_POSSIBLE=y +# CONFIG_SSB is not set +CONFIG_BCMA_POSSIBLE=y +# CONFIG_BCMA is not set + +# +# Multifunction device drivers +# +CONFIG_MFD_CORE=y +# CONFIG_MFD_ACT8945A is not set +# CONFIG_MFD_AS3711 is not set +# CONFIG_MFD_AS3722 is not set +# CONFIG_PMIC_ADP5520 is not set +# CONFIG_MFD_AAT2870_CORE is not set +# CONFIG_MFD_ATMEL_FLEXCOM is not set +# CONFIG_MFD_ATMEL_HLCDC is not set +# CONFIG_MFD_BCM590XX is not set +# CONFIG_MFD_BD9571MWV is not set +# CONFIG_MFD_AXP20X_I2C is not set +CONFIG_MFD_MADERA=m +CONFIG_MFD_MADERA_I2C=m +# CONFIG_MFD_MADERA_SPI is not set +# CONFIG_MFD_CS47L15 is not set +# CONFIG_MFD_CS47L35 is not set +# CONFIG_MFD_CS47L85 is not set +# CONFIG_MFD_CS47L90 is not set +# CONFIG_MFD_CS47L92 is not set +# CONFIG_MFD_ASIC3 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_MC13XXX_SPI is not set +# CONFIG_MFD_MC13XXX_I2C is not set +# CONFIG_MFD_HI6421_PMIC is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_HTC_I2CPLD 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 is not set +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_MT6397 is not set +# CONFIG_MFD_MENF21BMC is not set +# CONFIG_EZX_PCAP is not set +CONFIG_MFD_CPCAP=m +# CONFIG_MFD_VIPERBOARD is not set +# CONFIG_MFD_RETU is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_MFD_PM8XXX is not set +# CONFIG_MFD_RT5033 is not set +# CONFIG_MFD_RC5T583 is not set +CONFIG_MFD_RK808=y +# CONFIG_MFD_RN5T618 is not set +# CONFIG_MFD_SEC_CORE is not set +# CONFIG_MFD_SI476X_CORE is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_MFD_SKY81452 is not set +# CONFIG_MFD_SMSC is not set +# CONFIG_ABX500_CORE is not set +# CONFIG_MFD_STMPE is not set +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=y +# CONFIG_MFD_TPS65910 is not set +# CONFIG_MFD_TPS65912_I2C is not set +# CONFIG_MFD_TPS65912_SPI is not set +# CONFIG_MFD_TPS80031 is not set +# CONFIG_TWL4030_CORE is not set +# CONFIG_TWL6040_CORE is not set +CONFIG_MFD_WL1273_CORE=m +# CONFIG_MFD_LM3533 is not set +# CONFIG_MFD_TC3589X is not set +# CONFIG_MFD_T7L66XB is not set +# CONFIG_MFD_TC6387XB is not set +# CONFIG_MFD_TC6393XB is not set +CONFIG_MFD_TQMX86=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=m +# CONFIG_MFD_ROHM_BD70528 is not set +# CONFIG_MFD_ROHM_BD71828 is not set +CONFIG_MFD_STPMIC1=m +CONFIG_MFD_STMFX=m +# CONFIG_RAVE_SP_CORE is not set +# 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 is not set +# CONFIG_REGULATOR_ACT8865 is not set +# CONFIG_REGULATOR_AD5398 is not set +# CONFIG_REGULATOR_ANATOP is not set +# CONFIG_REGULATOR_ARIZONA_LDO1 is not set +# CONFIG_REGULATOR_ARIZONA_MICSUPP is not set +# CONFIG_REGULATOR_BD718XX is not set +# CONFIG_REGULATOR_CPCAP is not set +# CONFIG_REGULATOR_DA9210 is not set +# CONFIG_REGULATOR_DA9211 is not set +# CONFIG_REGULATOR_FAN53555 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_MAX77650 is not set +# CONFIG_REGULATOR_MAX8649 is not set +# CONFIG_REGULATOR_MAX8660 is not set +# CONFIG_REGULATOR_MAX8952 is not set +# CONFIG_REGULATOR_MAX8973 is not set +# CONFIG_REGULATOR_MCP16502 is not set +# CONFIG_REGULATOR_MP8859 is not set +# CONFIG_REGULATOR_MPQ7920 is not set +# CONFIG_REGULATOR_MT6311 is not set +# 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_RK808=y +# CONFIG_REGULATOR_SLG51000 is not set +# CONFIG_REGULATOR_STPMIC1 is not set +# CONFIG_REGULATOR_SY8106A is not set +# CONFIG_REGULATOR_SY8824X 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_TPS6586X=y +# CONFIG_REGULATOR_VCTRL is not set +CONFIG_CEC_CORE=y +CONFIG_CEC_NOTIFIER=y +CONFIG_RC_CORE=y +CONFIG_RC_MAP=y +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 is not set +# CONFIG_IR_HIX5HD2 is not set +# CONFIG_IR_IMON is not set +# CONFIG_IR_IMON_RAW is not set +# CONFIG_IR_MCEUSB is not set +# CONFIG_IR_REDRAT3 is not set +CONFIG_IR_SPI=m +# CONFIG_IR_STREAMZAP is not set +# CONFIG_IR_IGORPLUGUSB is not set +# CONFIG_IR_IGUANA is not set +# CONFIG_IR_TTUSBIR is not set +# CONFIG_RC_LOOPBACK is not set +CONFIG_IR_GPIO_CIR=m +# CONFIG_IR_GPIO_TX is not set +# CONFIG_IR_PWM_TX is not set +# CONFIG_IR_SERIAL is not set +# CONFIG_IR_SIR is not set +# CONFIG_RC_XBOX_DVD is not set +CONFIG_MEDIA_SUPPORT=y + +# +# Multimedia core support +# +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_CEC_SUPPORT is not set +# CONFIG_MEDIA_CEC_RC is not set +CONFIG_MEDIA_CONTROLLER=y +CONFIG_MEDIA_CONTROLLER_DVB=y +CONFIG_MEDIA_CONTROLLER_REQUEST_API=y +CONFIG_VIDEO_DEV=y +CONFIG_VIDEO_V4L2_SUBDEV_API=y +CONFIG_VIDEO_V4L2=y +CONFIG_VIDEO_V4L2_I2C=y +# CONFIG_VIDEO_ADV_DEBUG is not set +CONFIG_VIDEO_FIXED_MINOR_RANGES=y +CONFIG_VIDEO_TUNER=m +CONFIG_V4L2_MEM2MEM_DEV=m +CONFIG_V4L2_FWNODE=m +CONFIG_VIDEOBUF_GEN=m +CONFIG_VIDEOBUF_VMALLOC=m +CONFIG_DVB_CORE=y +# CONFIG_DVB_MMAP is not set +CONFIG_DVB_NET=y +CONFIG_TTPCI_EEPROM=m +CONFIG_DVB_MAX_ADAPTERS=16 +CONFIG_DVB_DYNAMIC_MINORS=y +# CONFIG_DVB_DEMUX_SECTION_LOSS_LOG is not set +# CONFIG_DVB_ULE_DEBUG is not set + +# +# 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_USBVISION=m +CONFIG_VIDEO_STK1160_COMMON=m +CONFIG_VIDEO_STK1160=m +# CONFIG_VIDEO_GO7007 is not set + +# +# Analog/digital TV USB devices +# +CONFIG_VIDEO_AU0828=m +CONFIG_VIDEO_AU0828_V4L2=y +# CONFIG_VIDEO_AU0828_RC is not set +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=y +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_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_V4L_PLATFORM_DRIVERS=y +# CONFIG_VIDEO_CADENCE is not set +# CONFIG_VIDEO_ASPEED is not set +CONFIG_VIDEO_MUX=m +CONFIG_VIDEO_XILINX=m +CONFIG_VIDEO_XILINX_TPG=m +CONFIG_VIDEO_XILINX_VTC=m +CONFIG_V4L_MEM2MEM_DRIVERS=y +# CONFIG_VIDEO_MEM2MEM_DEINTERLACE is not set +# CONFIG_VIDEO_SH_VEU is not set +CONFIG_VIDEO_ROCKCHIP_RGA=m +CONFIG_V4L_TEST_DRIVERS=y +# CONFIG_VIDEO_VIMC is not set +CONFIG_VIDEO_VIVID=m +# CONFIG_VIDEO_VIVID_CEC is not set +CONFIG_VIDEO_VIVID_MAX_DEVS=64 +CONFIG_VIDEO_VIM2M=m +CONFIG_VIDEO_VICODEC=m +CONFIG_DVB_PLATFORM_DRIVERS=y +CONFIG_DVB_C8SECTPFE=m +# CONFIG_SDR_PLATFORM_DRIVERS is not set + +# +# Supported MMC/SDIO adapters +# +# CONFIG_SMS_SDIO_DRV is not set +# CONFIG_RADIO_ADAPTERS is not set +CONFIG_MEDIA_COMMON_OPTIONS=y + +# +# common driver options +# +CONFIG_VIDEO_CX2341X=m +CONFIG_VIDEO_TVEEPROM=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_SMS_SIANO_MDTV=m +CONFIG_SMS_SIANO_RC=y +CONFIG_VIDEO_V4L2_TPG=m + +# +# Media ancillary drivers (tuners, sensors, i2c, spi, frontends) +# +# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set +CONFIG_MEDIA_ATTACH=y +CONFIG_VIDEO_IR_I2C=m + +# +# I2C Encoders, decoders, sensors and other helper chips +# + +# +# Audio decoders, processors and mixers +# +CONFIG_VIDEO_TVAUDIO=m +# CONFIG_VIDEO_TDA7432 is not set +# CONFIG_VIDEO_TDA9840 is not set +# CONFIG_VIDEO_TDA1997X is not set +# CONFIG_VIDEO_TEA6415C is not set +# CONFIG_VIDEO_TEA6420 is not set +CONFIG_VIDEO_MSP3400=m +# CONFIG_VIDEO_CS3308 is not set +# CONFIG_VIDEO_CS5345 is not set +CONFIG_VIDEO_CS53L32A=m +# CONFIG_VIDEO_TLV320AIC23B is not set +# CONFIG_VIDEO_UDA1342 is not set +CONFIG_VIDEO_WM8775=m +# CONFIG_VIDEO_WM8739 is not set +# CONFIG_VIDEO_VP27SMPX is not set +# CONFIG_VIDEO_SONY_BTF_MPX is not set + +# +# RDS decoders +# +# CONFIG_VIDEO_SAA6588 is not set + +# +# Video decoders +# +# CONFIG_VIDEO_ADV7180 is not set +# CONFIG_VIDEO_ADV7183 is not set +# CONFIG_VIDEO_ADV748X is not set +# CONFIG_VIDEO_ADV7604 is not set +# CONFIG_VIDEO_ADV7842 is not set +# CONFIG_VIDEO_BT819 is not set +# CONFIG_VIDEO_BT856 is not set +# CONFIG_VIDEO_BT866 is not set +# CONFIG_VIDEO_KS0127 is not set +# CONFIG_VIDEO_ML86V7667 is not set +# CONFIG_VIDEO_SAA7110 is not set +CONFIG_VIDEO_SAA711X=m +# CONFIG_VIDEO_TC358743 is not set +# CONFIG_VIDEO_TVP514X is not set +# CONFIG_VIDEO_TVP5150 is not set +# CONFIG_VIDEO_TVP7002 is not set +# CONFIG_VIDEO_TW2804 is not set +# CONFIG_VIDEO_TW9903 is not set +# CONFIG_VIDEO_TW9906 is not set +# CONFIG_VIDEO_TW9910 is not set +# CONFIG_VIDEO_VPX3220 is not set + +# +# Video and audio decoders +# +# CONFIG_VIDEO_SAA717X is not set +CONFIG_VIDEO_CX25840=m + +# +# Video encoders +# +# CONFIG_VIDEO_SAA7127 is not set +# CONFIG_VIDEO_SAA7185 is not set +# CONFIG_VIDEO_ADV7170 is not set +# CONFIG_VIDEO_ADV7175 is not set +# CONFIG_VIDEO_ADV7343 is not set +# CONFIG_VIDEO_ADV7393 is not set +# CONFIG_VIDEO_ADV7511 is not set +# CONFIG_VIDEO_AD9389B is not set +# CONFIG_VIDEO_AK881X is not set +# CONFIG_VIDEO_THS8200 is not set + +# +# Camera sensor devices +# +# CONFIG_VIDEO_HI556 is not set +# CONFIG_VIDEO_IMX214 is not set +# CONFIG_VIDEO_IMX258 is not set +# CONFIG_VIDEO_IMX274 is not set +# CONFIG_VIDEO_IMX290 is not set +# CONFIG_VIDEO_IMX319 is not set +# CONFIG_VIDEO_IMX355 is not set +# CONFIG_VIDEO_OV2640 is not set +# CONFIG_VIDEO_OV2659 is not set +# CONFIG_VIDEO_OV2680 is not set +# CONFIG_VIDEO_OV2685 is not set +# CONFIG_VIDEO_OV5640 is not set +# CONFIG_VIDEO_OV5645 is not set +# CONFIG_VIDEO_OV5647 is not set +# CONFIG_VIDEO_OV6650 is not set +# CONFIG_VIDEO_OV5670 is not set +# CONFIG_VIDEO_OV5675 is not set +# CONFIG_VIDEO_OV5695 is not set +# CONFIG_VIDEO_OV7251 is not set +# CONFIG_VIDEO_OV772X is not set +# CONFIG_VIDEO_OV7640 is not set +# CONFIG_VIDEO_OV7670 is not set +# CONFIG_VIDEO_OV7740 is not set +# CONFIG_VIDEO_OV8856 is not set +# CONFIG_VIDEO_OV9640 is not set +# CONFIG_VIDEO_OV9650 is not set +# CONFIG_VIDEO_OV13858 is not set +# CONFIG_VIDEO_VS6624 is not set +# CONFIG_VIDEO_MT9M001 is not set +# CONFIG_VIDEO_MT9M032 is not set +# CONFIG_VIDEO_MT9M111 is not set +# CONFIG_VIDEO_MT9P031 is not set +# CONFIG_VIDEO_MT9T001 is not set +# CONFIG_VIDEO_MT9T112 is not set +# CONFIG_VIDEO_MT9V011 is not set +# CONFIG_VIDEO_MT9V032 is not set +# CONFIG_VIDEO_MT9V111 is not set +# CONFIG_VIDEO_SR030PC30 is not set +# CONFIG_VIDEO_NOON010PC30 is not set +# CONFIG_VIDEO_M5MOLS is not set +# CONFIG_VIDEO_RJ54N1 is not set +# CONFIG_VIDEO_S5K6AA is not set +# CONFIG_VIDEO_S5K6A3 is not set +# CONFIG_VIDEO_S5K4ECGX is not set +# CONFIG_VIDEO_S5K5BAF is not set +# CONFIG_VIDEO_SMIAPP is not set +# CONFIG_VIDEO_ET8EK8 is not set +# CONFIG_VIDEO_S5C73M3 is not set + +# +# Lens drivers +# +# CONFIG_VIDEO_AD5820 is not set +# CONFIG_VIDEO_AK7375 is not set +# CONFIG_VIDEO_DW9714 is not set +# CONFIG_VIDEO_DW9807_VCM is not set + +# +# Flash devices +# +# CONFIG_VIDEO_ADP1653 is not set +# CONFIG_VIDEO_LM3560 is not set +# CONFIG_VIDEO_LM3646 is not set + +# +# Video improvement chips +# +# CONFIG_VIDEO_UPD64031A is not set +# CONFIG_VIDEO_UPD64083 is not set + +# +# Audio/Video compression chips +# +# CONFIG_VIDEO_SAA6752HS is not set + +# +# SDR tuner chips +# +# CONFIG_SDR_MAX2175 is not set + +# +# Miscellaneous helper chips +# +# CONFIG_VIDEO_THS7303 is not set +# CONFIG_VIDEO_M52790 is not set +# CONFIG_VIDEO_I2C is not set +# CONFIG_VIDEO_ST_MIPID02 is not set +# end of I2C Encoders, decoders, sensors and other helper chips + +# +# SPI helper chips +# +# CONFIG_VIDEO_GS1662 is not set +# end of SPI helper chips + +# +# Media SPI Adapters +# +# CONFIG_CXD2880_SPI_DRV is not set +# end of Media SPI Adapters + +CONFIG_MEDIA_TUNER=y + +# +# Customize TV tuners +# +CONFIG_MEDIA_TUNER_SIMPLE=y +CONFIG_MEDIA_TUNER_TDA18250=m +CONFIG_MEDIA_TUNER_TDA8290=y +CONFIG_MEDIA_TUNER_TDA827X=y +CONFIG_MEDIA_TUNER_TDA18271=y +CONFIG_MEDIA_TUNER_TDA9887=y +CONFIG_MEDIA_TUNER_TEA5761=m +CONFIG_MEDIA_TUNER_TEA5767=m +CONFIG_MEDIA_TUNER_MSI001=m +CONFIG_MEDIA_TUNER_MT20XX=y +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=y +CONFIG_MEDIA_TUNER_XC5000=y +CONFIG_MEDIA_TUNER_XC4000=y +CONFIG_MEDIA_TUNER_MXL5005S=m +CONFIG_MEDIA_TUNER_MXL5007T=m +CONFIG_MEDIA_TUNER_MC44S803=y +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 is not set +# CONFIG_DVB_STB6100 is not set +# CONFIG_DVB_STV090x is not set +# CONFIG_DVB_STV0910 is not set +# CONFIG_DVB_STV6110x is not set +# CONFIG_DVB_STV6111 is not set +# CONFIG_DVB_MXL5XX is not set +# CONFIG_DVB_M88DS3103 is not set + +# +# Multistandard (cable + terrestrial) frontends +# +# CONFIG_DVB_DRXK is not set +# CONFIG_DVB_TDA18271C2DD is not set +# CONFIG_DVB_SI2165 is not set +# CONFIG_DVB_MN88472 is not set +# CONFIG_DVB_MN88473 is not set + +# +# DVB-S (satellite) frontends +# +# CONFIG_DVB_CX24110 is not set +# CONFIG_DVB_CX24123 is not set +# CONFIG_DVB_MT312 is not set +# CONFIG_DVB_ZL10036 is not set +# CONFIG_DVB_ZL10039 is not set +# CONFIG_DVB_S5H1420 is not set +# CONFIG_DVB_STV0288 is not set +# CONFIG_DVB_STB6000 is not set +# CONFIG_DVB_STV0299 is not set +# CONFIG_DVB_STV6110 is not set +# CONFIG_DVB_STV0900 is not set +CONFIG_DVB_TDA8083=y +# CONFIG_DVB_TDA10086 is not set +# CONFIG_DVB_TDA8261 is not set +# CONFIG_DVB_VES1X93 is not set +# CONFIG_DVB_TUNER_ITD1000 is not set +# CONFIG_DVB_TUNER_CX24113 is not set +# CONFIG_DVB_TDA826X is not set +# CONFIG_DVB_TUA6100 is not set +# CONFIG_DVB_CX24116 is not set +# CONFIG_DVB_CX24117 is not set +# CONFIG_DVB_CX24120 is not set +# CONFIG_DVB_SI21XX is not set +# CONFIG_DVB_TS2020 is not set +# CONFIG_DVB_DS3000 is not set +# CONFIG_DVB_MB86A16 is not set +# CONFIG_DVB_TDA10071 is not set + +# +# DVB-T (terrestrial) frontends +# +# CONFIG_DVB_SP8870 is not set +# CONFIG_DVB_SP887X is not set +# CONFIG_DVB_CX22700 is not set +# CONFIG_DVB_CX22702 is not set +# CONFIG_DVB_S5H1432 is not set +# CONFIG_DVB_DRXD is not set +# CONFIG_DVB_L64781 is not set +# CONFIG_DVB_TDA1004X is not set +# CONFIG_DVB_NXT6000 is not set +# CONFIG_DVB_MT352 is not set +CONFIG_DVB_ZL10353=m +CONFIG_DVB_DIB3000MB=m +CONFIG_DVB_DIB3000MC=m +# CONFIG_DVB_DIB7000M is not set +# CONFIG_DVB_DIB7000P is not set +# CONFIG_DVB_DIB9000 is not set +# CONFIG_DVB_TDA10048 is not set +CONFIG_DVB_AF9013=m +CONFIG_DVB_EC100=m +# CONFIG_DVB_STV0367 is not set +# CONFIG_DVB_CXD2820R is not set +# CONFIG_DVB_CXD2841ER is not set +CONFIG_DVB_RTL2830=m +CONFIG_DVB_RTL2832=m +# CONFIG_DVB_RTL2832_SDR is not set +# CONFIG_DVB_SI2168 is not set +CONFIG_DVB_AS102_FE=m +# CONFIG_DVB_ZD1301_DEMOD is not set +CONFIG_DVB_GP8PSK_FE=m +# CONFIG_DVB_CXD2880 is not set + +# +# DVB-C (cable) frontends +# +# CONFIG_DVB_VES1820 is not set +# CONFIG_DVB_TDA10021 is not set +# CONFIG_DVB_TDA10023 is not set +# CONFIG_DVB_STV0297 is not set + +# +# ATSC (North American/Korean Terrestrial/Cable DTV) frontends +# +# CONFIG_DVB_NXT200X is not set +# CONFIG_DVB_OR51211 is not set +# CONFIG_DVB_OR51132 is not set +# CONFIG_DVB_BCM3510 is not set +# CONFIG_DVB_LGDT330X is not set +# CONFIG_DVB_LGDT3305 is not set +# CONFIG_DVB_LGDT3306A is not set +# CONFIG_DVB_LG2160 is not set +# CONFIG_DVB_S5H1409 is not set +# CONFIG_DVB_AU8522_DTV is not set +# CONFIG_DVB_AU8522_V4L is not set +# CONFIG_DVB_S5H1411 is not set + +# +# ISDB-T (terrestrial) frontends +# +# CONFIG_DVB_S921 is not set +# CONFIG_DVB_DIB8000 is not set +# CONFIG_DVB_MB86A20S is not set + +# +# ISDB-S (satellite) & ISDB-T (terrestrial) frontends +# +# CONFIG_DVB_TC90522 is not set +# CONFIG_DVB_MN88443X is not set + +# +# Digital terrestrial only tuners/PLL +# +# CONFIG_DVB_PLL is not set +# CONFIG_DVB_TUNER_DIB0070 is not set +# CONFIG_DVB_TUNER_DIB0090 is not set + +# +# SEC control devices for DVB-S +# +# CONFIG_DVB_DRX39XYJ is not set +# CONFIG_DVB_LNBH25 is not set +# CONFIG_DVB_LNBH29 is not set +# CONFIG_DVB_LNBP21 is not set +# CONFIG_DVB_LNBP22 is not set +# CONFIG_DVB_ISL6405 is not set +# CONFIG_DVB_ISL6421 is not set +# CONFIG_DVB_ISL6423 is not set +# CONFIG_DVB_A8293 is not set +# CONFIG_DVB_LGS8GL5 is not set +# CONFIG_DVB_LGS8GXX is not set +# CONFIG_DVB_ATBM8830 is not set +# CONFIG_DVB_TDA665x is not set +# CONFIG_DVB_IX2505V is not set +# CONFIG_DVB_M88RS2000 is not set +CONFIG_DVB_AF9033=m +# CONFIG_DVB_HORUS3A is not set +# CONFIG_DVB_ASCOT2E is not set +# CONFIG_DVB_HELENE is not set + +# +# Common Interface (EN50221) controller drivers +# +# CONFIG_DVB_CXD2099 is not set +# CONFIG_DVB_SP2 is not set + +# +# Tools to develop new frontends +# +# CONFIG_DVB_DUMMY_FE is not set +# end of Customise DVB Frontends + +# +# Graphics support +# +# CONFIG_IMX_IPUV3_CORE is not set +CONFIG_DRM=y +# 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_KMS_FB_HELPER=y +# CONFIG_DRM_DEBUG_DP_MST_TOPOLOGY_REFS 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 is not set +CONFIG_DRM_GEM_CMA_HELPER=y +CONFIG_DRM_GEM_SHMEM_HELPER=y +CONFIG_DRM_SCHED=m + +# +# I2C encoder or helper chips +# +# CONFIG_DRM_I2C_CH7006 is not set +# CONFIG_DRM_I2C_SIL164 is not set +# CONFIG_DRM_I2C_NXP_TDA998X is not set +# CONFIG_DRM_I2C_NXP_TDA9950 is not set +# 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 is not set +# end of ARM devices + +# +# ACP (Audio CoProcessor) Configuration +# +# end of ACP (Audio CoProcessor) Configuration + +# CONFIG_DRM_VGEM is not set +# CONFIG_DRM_VKMS is not set +# CONFIG_DRM_EXYNOS is not set +CONFIG_DRM_ROCKCHIP=y +# CONFIG_ROCKCHIP_ANALOGIX_DP is not set +# CONFIG_ROCKCHIP_CDN_DP is not set +CONFIG_ROCKCHIP_DW_HDMI=y +# CONFIG_ROCKCHIP_DW_MIPI_DSI is not set +CONFIG_ROCKCHIP_INNO_HDMI=y +# CONFIG_ROCKCHIP_LVDS is not set +CONFIG_ROCKCHIP_RGB=y +# CONFIG_ROCKCHIP_RK3066_HDMI is not set +CONFIG_DRM_UDL=y +# CONFIG_DRM_ARMADA is not set +# CONFIG_DRM_RCAR_DW_HDMI is not set +# CONFIG_DRM_RCAR_LVDS is not set +# CONFIG_DRM_OMAP is not set +# CONFIG_DRM_TILCDC is not set +# CONFIG_DRM_VIRTIO_GPU is not set +# CONFIG_DRM_FSL_DCU is not set +# CONFIG_DRM_STM is not set +CONFIG_DRM_PANEL=y + +# +# Display Panels +# +# CONFIG_DRM_PANEL_ARM_VERSATILE is not set +# CONFIG_DRM_PANEL_LVDS is not set +CONFIG_DRM_PANEL_SIMPLE=m +# CONFIG_DRM_PANEL_ILITEK_IL9322 is not set +# CONFIG_DRM_PANEL_SAMSUNG_LD9040 is not set +# CONFIG_DRM_PANEL_LG_LB035Q02 is not set +# CONFIG_DRM_PANEL_LG_LG4573 is not set +# CONFIG_DRM_PANEL_NEC_NL8048HL11 is not set +# CONFIG_DRM_PANEL_NOVATEK_NT39016 is not set +# CONFIG_DRM_PANEL_OLIMEX_LCD_OLINUXINO is not set +# CONFIG_DRM_PANEL_SAMSUNG_S6E63M0 is not set +# CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0 is not set +# CONFIG_DRM_PANEL_SEIKO_43WVF1G is not set +# CONFIG_DRM_PANEL_SHARP_LS037V7DW01 is not set +# CONFIG_DRM_PANEL_SITRONIX_ST7789V is not set +# CONFIG_DRM_PANEL_SONY_ACX565AKM is not set +# CONFIG_DRM_PANEL_TPO_TD028TTEC1 is not set +# CONFIG_DRM_PANEL_TPO_TD043MTEA1 is not set +# CONFIG_DRM_PANEL_TPO_TPG110 is not set +# end of Display Panels + +CONFIG_DRM_BRIDGE=y +CONFIG_DRM_PANEL_BRIDGE=y + +# +# Display Interface Bridges +# +# CONFIG_DRM_CDNS_DSI is not set +# CONFIG_DRM_DUMB_VGA_DAC is not set +# CONFIG_DRM_LVDS_CODEC is not set +# CONFIG_DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW is not set +# CONFIG_DRM_NXP_PTN3460 is not set +# CONFIG_DRM_PARADE_PS8622 is not set +# CONFIG_DRM_SIL_SII8620 is not set +# CONFIG_DRM_SII902X is not set +# CONFIG_DRM_SII9234 is not set +# CONFIG_DRM_THINE_THC63LVD1024 is not set +# CONFIG_DRM_TOSHIBA_TC358764 is not set +# CONFIG_DRM_TOSHIBA_TC358767 is not set +# CONFIG_DRM_TI_TFP410 is not set +# CONFIG_DRM_TI_SN65DSI86 is not set +# CONFIG_DRM_ANALOGIX_ANX6345 is not set +# CONFIG_DRM_ANALOGIX_ANX78XX is not set +# CONFIG_DRM_I2C_ADV7511 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=y +# end of Display Interface Bridges + +# CONFIG_DRM_STI is not set +# CONFIG_DRM_ETNAVIV is not set +# CONFIG_DRM_ARCPGU is not set +# CONFIG_DRM_MXSFB is not set +# CONFIG_DRM_GM12U320 is not set +# CONFIG_TINYDRM_HX8357D is not set +# CONFIG_TINYDRM_ILI9225 is not set +# CONFIG_TINYDRM_ILI9341 is not set +# CONFIG_TINYDRM_MI0283QT is not set +# CONFIG_TINYDRM_REPAPER is not set +# CONFIG_TINYDRM_ST7586 is not set +# CONFIG_TINYDRM_ST7735R is not set +# CONFIG_DRM_PL111 is not set +# CONFIG_DRM_TVE200 is not set +CONFIG_DRM_LIMA=m +# CONFIG_DRM_PANFROST is not set +# CONFIG_DRM_MCDE is not set +# CONFIG_DRM_LEGACY 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 is not set +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_ARMCLCD is not set +# CONFIG_FB_UVESA is not set +# CONFIG_FB_OPENCORES is not set +# CONFIG_FB_S1D13XXX 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_FB_METRONOME is not set +# CONFIG_FB_SIMPLE is not set +# CONFIG_FB_SSD1307 is not set +# end of Frame buffer Devices + +# +# Backlight & LCD device support +# +# CONFIG_LCD_CLASS_DEVICE is not set +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_GENERIC=y +CONFIG_BACKLIGHT_PWM=y +# CONFIG_BACKLIGHT_QCOM_WLED is not set +# CONFIG_BACKLIGHT_ADP8860 is not set +# CONFIG_BACKLIGHT_ADP8870 is not set +# CONFIG_BACKLIGHT_LM3630A is not set +# CONFIG_BACKLIGHT_LM3639 is not set +# CONFIG_BACKLIGHT_LP855X is not set +# CONFIG_BACKLIGHT_GPIO is not set +# CONFIG_BACKLIGHT_LV5207LP is not set +# CONFIG_BACKLIGHT_BD6107 is not set +# CONFIG_BACKLIGHT_ARCXCNN is not set +# CONFIG_BACKLIGHT_LED is not set +# end of Backlight & LCD device support + +CONFIG_VIDEOMODE_HELPERS=y +CONFIG_HDMI=y + +# +# Console display driver support +# +CONFIG_DUMMY_CONSOLE=y +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 is not set +# CONFIG_LOGO_LINUX_VGA16 is not set +# CONFIG_LOGO_LINUX_CLUT224 is not set +# 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=m +CONFIG_SND_DYNAMIC_MINORS=y +CONFIG_SND_MAX_CARDS=32 +CONFIG_SND_SUPPORT_OLD_API=y +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_SEQUENCER=m +CONFIG_SND_SEQ_DUMMY=m +CONFIG_SND_SEQ_HRTIMER_DEFAULT=y +CONFIG_SND_SEQ_MIDI_EVENT=m +CONFIG_SND_SEQ_MIDI=m +CONFIG_SND_DRIVERS=y +CONFIG_SND_DUMMY=m +CONFIG_SND_ALOOP=m +# CONFIG_SND_VIRMIDI is not set +# CONFIG_SND_MTPAV is not set +# CONFIG_SND_SERIAL_U16550 is not set +# CONFIG_SND_MPU401 is not set + +# +# HD-Audio +# +# end of HD-Audio + +CONFIG_SND_HDA_PREALLOC_SIZE=64 +# CONFIG_SND_ARM is not set +# CONFIG_SND_SPI is not set +CONFIG_SND_USB=y +CONFIG_SND_USB_AUDIO=m +CONFIG_SND_USB_AUDIO_USE_MEDIA_CONTROLLER=y +# CONFIG_SND_USB_UA101 is not set +# CONFIG_SND_USB_CAIAQ is not set +# CONFIG_SND_USB_6FIRE is not set +# CONFIG_SND_USB_HIFACE is not set +# CONFIG_SND_BCD2000 is not set +# CONFIG_SND_USB_POD is not set +# CONFIG_SND_USB_PODHD is not set +# CONFIG_SND_USB_TONEPORT is not set +# CONFIG_SND_USB_VARIAX is not set +CONFIG_SND_SOC=m +CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM=y +# CONFIG_SND_SOC_AMD_ACP is not set +# CONFIG_SND_ATMEL_SOC is not set +# CONFIG_SND_DESIGNWARE_I2S 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 is not set +# 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=m +CONFIG_SND_SOC_ROCKCHIP=m +CONFIG_SND_SOC_ROCKCHIP_I2S=m +# CONFIG_SND_SOC_ROCKCHIP_PDM is not set +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 is not set +# CONFIG_SND_SOC_SOF_TOPLEVEL is not set + +# +# STMicroelectronics STM32 SOC audio support +# +# end of STMicroelectronics STM32 SOC audio support + +# CONFIG_SND_SOC_XILINX_I2S is not set +CONFIG_SND_SOC_XILINX_AUDIO_FORMATTER=m +CONFIG_SND_SOC_XILINX_SPDIF=m +# CONFIG_SND_SOC_XTFPGA_I2S is not set +# CONFIG_ZX_TDM is not set +CONFIG_SND_SOC_I2C_AND_SPI=m + +# +# CODEC drivers +# +# CONFIG_SND_SOC_AC97_CODEC is not set +# 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_HW is not set +# CONFIG_SND_SOC_ADAU7118_I2C is not set +# CONFIG_SND_SOC_AK4104 is not set +# CONFIG_SND_SOC_AK4118 is not set +CONFIG_SND_SOC_AK4458=m +# CONFIG_SND_SOC_AK4554 is not set +# CONFIG_SND_SOC_AK4613 is not set +# CONFIG_SND_SOC_AK4642 is not set +# CONFIG_SND_SOC_AK5386 is not set +CONFIG_SND_SOC_AK5558=m +# CONFIG_SND_SOC_ALC5623 is not set +CONFIG_SND_SOC_BD28623=m +# CONFIG_SND_SOC_BT_SCO is not set +CONFIG_SND_SOC_CPCAP=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_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_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 is not set +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 is not set +# CONFIG_SND_SOC_DMIC is not set +CONFIG_SND_SOC_HDMI_CODEC=m +# CONFIG_SND_SOC_ES7134 is not set +CONFIG_SND_SOC_ES7241=m +# CONFIG_SND_SOC_ES8316 is not set +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_INNO_RK3036 is not set +# CONFIG_SND_SOC_MAX98088 is not set +CONFIG_SND_SOC_MAX98090=m +# CONFIG_SND_SOC_MAX98357A is not set +# CONFIG_SND_SOC_MAX98504 is not set +CONFIG_SND_SOC_MAX9867=m +# CONFIG_SND_SOC_MAX98927 is not set +# CONFIG_SND_SOC_MAX98373 is not set +# CONFIG_SND_SOC_MAX9860 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_I2C is not set +# CONFIG_SND_SOC_PCM186X_SPI is not set +# CONFIG_SND_SOC_PCM3060_I2C is not set +# CONFIG_SND_SOC_PCM3060_SPI is not set +# CONFIG_SND_SOC_PCM3168A_I2C is not set +# CONFIG_SND_SOC_PCM3168A_SPI is not set +# CONFIG_SND_SOC_PCM512x_I2C is not set +# CONFIG_SND_SOC_PCM512x_SPI is not set +CONFIG_SND_SOC_RK3328=m +CONFIG_SND_SOC_RL6231=m +CONFIG_SND_SOC_RT5616=m +# CONFIG_SND_SOC_RT5631 is not set +CONFIG_SND_SOC_RT5645=m +# CONFIG_SND_SOC_SGTL5000 is not set +CONFIG_SND_SOC_SIMPLE_AMPLIFIER=m +# CONFIG_SND_SOC_SIRF_AUDIO_CODEC is not set +CONFIG_SND_SOC_SPDIF=m +CONFIG_SND_SOC_SSM2305=m +# CONFIG_SND_SOC_SSM2602_SPI is not set +# CONFIG_SND_SOC_SSM2602_I2C is not set +# CONFIG_SND_SOC_SSM4567 is not set +# CONFIG_SND_SOC_STA32X is not set +# CONFIG_SND_SOC_STA350 is not set +# CONFIG_SND_SOC_STI_SAS is not set +# CONFIG_SND_SOC_TAS2552 is not set +# CONFIG_SND_SOC_TAS2562 is not set +# CONFIG_SND_SOC_TAS2770 is not set +# CONFIG_SND_SOC_TAS5086 is not set +# CONFIG_SND_SOC_TAS571X is not set +# CONFIG_SND_SOC_TAS5720 is not set +# CONFIG_SND_SOC_TAS6424 is not set +CONFIG_SND_SOC_TDA7419=m +# CONFIG_SND_SOC_TFA9879 is not set +# CONFIG_SND_SOC_TLV320AIC23_I2C is not set +# CONFIG_SND_SOC_TLV320AIC23_SPI is not set +# CONFIG_SND_SOC_TLV320AIC31XX is not set +# CONFIG_SND_SOC_TLV320AIC32X4_I2C is not set +# CONFIG_SND_SOC_TLV320AIC32X4_SPI is not set +# CONFIG_SND_SOC_TLV320AIC3X is not set +CONFIG_SND_SOC_TS3A227E=m +# CONFIG_SND_SOC_TSCS42XX is not set +CONFIG_SND_SOC_TSCS454=m +CONFIG_SND_SOC_UDA1334=m +# CONFIG_SND_SOC_WM8510 is not set +# CONFIG_SND_SOC_WM8523 is not set +# CONFIG_SND_SOC_WM8524 is not set +# CONFIG_SND_SOC_WM8580 is not set +# CONFIG_SND_SOC_WM8711 is not set +# CONFIG_SND_SOC_WM8728 is not set +# CONFIG_SND_SOC_WM8731 is not set +# CONFIG_SND_SOC_WM8737 is not set +# CONFIG_SND_SOC_WM8741 is not set +# CONFIG_SND_SOC_WM8750 is not set +# CONFIG_SND_SOC_WM8753 is not set +# CONFIG_SND_SOC_WM8770 is not set +# CONFIG_SND_SOC_WM8776 is not set +CONFIG_SND_SOC_WM8782=m +# CONFIG_SND_SOC_WM8804_I2C is not set +# CONFIG_SND_SOC_WM8804_SPI is not set +# CONFIG_SND_SOC_WM8903 is not set +CONFIG_SND_SOC_WM8904=m +# CONFIG_SND_SOC_WM8960 is not set +# CONFIG_SND_SOC_WM8962 is not set +# CONFIG_SND_SOC_WM8974 is not set +# CONFIG_SND_SOC_WM8978 is not set +# CONFIG_SND_SOC_WM8985 is not set +# CONFIG_SND_SOC_ZX_AUD96P22 is not set +CONFIG_SND_SOC_MAX9759=m +CONFIG_SND_SOC_MT6351=m +CONFIG_SND_SOC_MT6358=m +# CONFIG_SND_SOC_MT6660 is not set +CONFIG_SND_SOC_NAU8540=m +# CONFIG_SND_SOC_NAU8810 is not set +# CONFIG_SND_SOC_NAU8822 is not set +# CONFIG_SND_SOC_NAU8824 is not set +# CONFIG_SND_SOC_TPA6130A2 is not set +# end of CODEC drivers + +CONFIG_SND_SIMPLE_CARD_UTILS=m +CONFIG_SND_SIMPLE_CARD=m +# CONFIG_SND_AUDIO_GRAPH_CARD is not set + +# +# HID support +# +CONFIG_HID=y +CONFIG_HID_BATTERY_STRENGTH=y +CONFIG_HIDRAW=y +CONFIG_UHID=y +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 is not set +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 is not set +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_GEMBIRD=m +CONFIG_HID_GFRM=m +CONFIG_HID_HOLTEK=m +CONFIG_HOLTEK_FF=y +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_GYRATION=m +CONFIG_HID_ICADE=m +# CONFIG_HID_ITE is not set +# CONFIG_HID_JABRA is not set +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 is not set +CONFIG_HID_MICROSOFT=m +CONFIG_HID_MONTEREY=m +CONFIG_HID_MULTITOUCH=m +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_LEDS=y +CONFIG_HID_PICOLCD_CIR=y +CONFIG_HID_PLANTRONICS=m +CONFIG_HID_PRIMAX=m +# CONFIG_HID_RETRODE is not set +CONFIG_HID_ROCCAT=m +CONFIG_HID_SAITEK=m +CONFIG_HID_SAMSUNG=m +CONFIG_HID_SONY=m +CONFIG_SONY_FF=y +CONFIG_HID_SPEEDLINK=m +# CONFIG_HID_STEAM is not set +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 is not set +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 +# end of Special HID drivers + +# +# USB HID support +# +CONFIG_USB_HID=y +# CONFIG_HID_PID is not set +CONFIG_USB_HIDDEV=y +# end of USB HID support + +# +# I2C HID support +# +CONFIG_I2C_HID=y +# end of I2C HID support +# end of HID support + +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +CONFIG_USB_SUPPORT=y +CONFIG_USB_COMMON=y +# CONFIG_USB_LED_TRIG is not set +# CONFIG_USB_ULPI_BUS is not set +CONFIG_USB_CONN_GPIO=m +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB=y +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y + +# +# Miscellaneous USB options +# +# CONFIG_USB_DEFAULT_PERSIST is not set +# CONFIG_USB_DYNAMIC_MINORS is not set +CONFIG_USB_OTG=y +# CONFIG_USB_OTG_WHITELIST is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set +# CONFIG_USB_OTG_FSM is not set +# CONFIG_USB_LEDS_TRIGGER_USBPORT is not set +CONFIG_USB_AUTOSUSPEND_DELAY=2 +CONFIG_USB_MON=y + +# +# USB Host Controller Drivers +# +# CONFIG_USB_C67X00_HCD is not set +# CONFIG_USB_XHCI_HCD is not set +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_EHCI_TT_NEWSCHED=y +# CONFIG_USB_EHCI_FSL is not set +CONFIG_USB_EHCI_HCD_PLATFORM=y +# CONFIG_USB_OXU210HP_HCD is not set +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_FOTG210_HCD is not set +# CONFIG_USB_MAX3421_HCD is not set +CONFIG_USB_OHCI_HCD=y +CONFIG_USB_OHCI_HCD_PLATFORM=y +# CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set +# 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 is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_USBAT is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_STORAGE_ALAUDA is not set +# CONFIG_USB_STORAGE_ONETOUCH is not set +# CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set +# CONFIG_USB_STORAGE_ENE_UB6250 is not set +CONFIG_USB_UAS=m + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set +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_CDNS3 is not set +# CONFIG_USB_MUSB_HDRC is not set +# CONFIG_USB_DWC3 is not set +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_DEBUG is not set +# CONFIG_USB_DWC2_TRACK_MISSED_SOFS is not set +# CONFIG_USB_CHIPIDEA is not set +# CONFIG_USB_ISP1760 is not set + +# +# 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 is not set +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_XIRCOM=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_DEBUG=m + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_SEVSEG is not set +# CONFIG_USB_LEGOTOWER is not set +CONFIG_USB_LCD=m +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_SISUSBVGA is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set +# CONFIG_USB_TEST is not set +# CONFIG_USB_EHSET_TEST_FIXTURE is not set +# CONFIG_USB_ISIGHTFW is not set +# CONFIG_USB_YUREX is not set +CONFIG_USB_EZUSB_FX2=y +# CONFIG_USB_HUB_USB251XB is not set +# CONFIG_USB_HSIC_USB3503 is not set +# CONFIG_USB_HSIC_USB4604 is not set +# CONFIG_USB_LINK_LAYER_TEST is not set +# CONFIG_USB_CHAOSKEY is not set +CONFIG_USB_ATM=m +# CONFIG_USB_SPEEDTOUCH is not set +# CONFIG_USB_CXACRU is not set +# CONFIG_USB_UEAGLEATM is not set +# CONFIG_USB_XUSBATM is not set + +# +# USB Physical Layer drivers +# +# CONFIG_NOP_USB_XCEIV is not set +# CONFIG_USB_GPIO_VBUS is not set +# CONFIG_USB_ISP1301 is not set +# CONFIG_USB_ULPI is not set +# 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 is not set + +# +# USB Peripheral Controller +# +# CONFIG_USB_FUSB300 is not set +# 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_UDC_PLAT is not set +# CONFIG_USB_M66592 is not set +# CONFIG_USB_BDC_UDC is not set +# CONFIG_USB_NET2272 is not set +# CONFIG_USB_GADGET_XILINX is not set +# CONFIG_USB_DUMMY_HCD is not set +# end of USB Peripheral Controller + +CONFIG_USB_LIBCOMPOSITE=y +CONFIG_USB_F_ACM=m +CONFIG_USB_U_SERIAL=m +CONFIG_USB_F_SERIAL=m +CONFIG_USB_F_OBEX=m +CONFIG_USB_F_MASS_STORAGE=y +CONFIG_USB_F_FS=y +CONFIG_USB_F_HID=m +CONFIG_USB_CONFIGFS=y +# CONFIG_USB_CONFIGFS_SERIAL is not set +# CONFIG_USB_CONFIGFS_ACM is not set +# CONFIG_USB_CONFIGFS_OBEX is not set +# CONFIG_USB_CONFIGFS_NCM is not set +# CONFIG_USB_CONFIGFS_ECM is not set +# CONFIG_USB_CONFIGFS_ECM_SUBSET is not set +# CONFIG_USB_CONFIGFS_RNDIS is not set +# CONFIG_USB_CONFIGFS_EEM is not set +CONFIG_USB_CONFIGFS_MASS_STORAGE=y +# CONFIG_USB_CONFIGFS_F_LB_SS is not set +CONFIG_USB_CONFIGFS_F_FS=y +# CONFIG_USB_CONFIGFS_F_UAC1 is not set +# CONFIG_USB_CONFIGFS_F_UAC1_LEGACY is not set +# CONFIG_USB_CONFIGFS_F_UAC2 is not set +# CONFIG_USB_CONFIGFS_F_MIDI is not set +# CONFIG_USB_CONFIGFS_F_HID is not set +# CONFIG_USB_CONFIGFS_F_UVC is not set +# CONFIG_USB_CONFIGFS_F_PRINTER is not set +# CONFIG_USB_ZERO is not set +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_ETH is not set +# CONFIG_USB_G_NCM is not set +CONFIG_USB_GADGETFS=m +# CONFIG_USB_FUNCTIONFS is not set +CONFIG_USB_MASS_STORAGE=m +CONFIG_USB_G_SERIAL=m +# CONFIG_USB_MIDI_GADGET is not set +# CONFIG_USB_G_PRINTER is not set +# CONFIG_USB_CDC_COMPOSITE is not set +# CONFIG_USB_G_ACM_MS is not set +# CONFIG_USB_G_MULTI is not set +CONFIG_USB_G_HID=m +# CONFIG_USB_G_DBGP is not set +# CONFIG_USB_G_WEBCAM is not set +# CONFIG_TYPEC is not set +CONFIG_USB_ROLE_SWITCH=m +CONFIG_MMC=y +CONFIG_PWRSEQ_EMMC=y +CONFIG_PWRSEQ_SD8787=m +CONFIG_PWRSEQ_SIMPLE=y +CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_MINORS=16 +# CONFIG_SDIO_UART is not set +CONFIG_MMC_TEST=y + +# +# MMC/SD/SDIO Host Controller Drivers +# +# CONFIG_MMC_DEBUG is not set +# CONFIG_MMC_ARMMMCI is not set +# CONFIG_MMC_SDHCI is not set +# CONFIG_MMC_SPI is not set +CONFIG_MMC_DW=y +CONFIG_MMC_DW_PLTFM=y +# CONFIG_MMC_DW_BLUEFIELD is not set +# CONFIG_MMC_DW_EXYNOS is not set +# CONFIG_MMC_DW_HI3798CV200 is not set +# CONFIG_MMC_DW_K3 is not set +CONFIG_MMC_DW_ROCKCHIP=y +# CONFIG_MMC_VUB300 is not set +# CONFIG_MMC_USHC is not set +# CONFIG_MMC_USDHI6ROL0 is not set +# CONFIG_MMC_REALTEK_USB is not set +# CONFIG_MMC_CQHCI is not set +# CONFIG_MMC_MTK is not set +# CONFIG_MEMSTICK is not set +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y +# CONFIG_LEDS_CLASS_FLASH is not set +# CONFIG_LEDS_BRIGHTNESS_HW_CHANGED is not set + +# +# LED drivers +# +# CONFIG_LEDS_AN30259A is not set +# CONFIG_LEDS_BCM6328 is not set +# CONFIG_LEDS_BCM6358 is not set +# CONFIG_LEDS_CPCAP is not set +CONFIG_LEDS_CR0014114=m +# CONFIG_LEDS_EL15203000 is not set +# CONFIG_LEDS_LM3530 is not set +CONFIG_LEDS_LM3532=m +# CONFIG_LEDS_LM3642 is not set +# CONFIG_LEDS_LM3692X is not set +# CONFIG_LEDS_PCA9532 is not set +CONFIG_LEDS_GPIO=y +# CONFIG_LEDS_LP3944 is not set +# CONFIG_LEDS_LP3952 is not set +# CONFIG_LEDS_LP5521 is not set +# CONFIG_LEDS_LP5523 is not set +# CONFIG_LEDS_LP5562 is not set +# CONFIG_LEDS_LP8501 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 is not set +# CONFIG_LEDS_REGULATOR is not set +# CONFIG_LEDS_BD2802 is not set +# CONFIG_LEDS_LT3593 is not set +# 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 is not set +CONFIG_LEDS_MLXREG=m +CONFIG_LEDS_USER=m +# CONFIG_LEDS_SPI_BYTE is not set +# CONFIG_LEDS_TI_LMU_COMMON is not set + +# +# LED Triggers +# +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_TIMER=y +CONFIG_LEDS_TRIGGER_ONESHOT=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +CONFIG_LEDS_TRIGGER_BACKLIGHT=y +CONFIG_LEDS_TRIGGER_CPU=y +CONFIG_LEDS_TRIGGER_ACTIVITY=y +CONFIG_LEDS_TRIGGER_GPIO=y +CONFIG_LEDS_TRIGGER_DEFAULT_ON=y + +# +# iptables trigger is under Netfilter config (LED target) +# +CONFIG_LEDS_TRIGGER_TRANSIENT=y +# CONFIG_LEDS_TRIGGER_CAMERA is not set +# CONFIG_LEDS_TRIGGER_PANIC is not set +# CONFIG_LEDS_TRIGGER_NETDEV is not set +# CONFIG_LEDS_TRIGGER_PATTERN is not set +# CONFIG_LEDS_TRIGGER_AUDIO is not set +# CONFIG_ACCESSIBILITY is not set +# CONFIG_INFINIBAND is not set +CONFIG_EDAC_ATOMIC_SCRUB=y +CONFIG_EDAC_SUPPORT=y +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_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=m +CONFIG_RTC_DRV_ABX80X=m +CONFIG_RTC_DRV_DS1307=m +# CONFIG_RTC_DRV_DS1307_CENTURY is not set +CONFIG_RTC_DRV_DS1374=m +CONFIG_RTC_DRV_DS1374_WDT=y +CONFIG_RTC_DRV_DS1672=m +CONFIG_RTC_DRV_HYM8563=m +CONFIG_RTC_DRV_MAX6900=m +CONFIG_RTC_DRV_RK808=y +CONFIG_RTC_DRV_RS5C372=m +CONFIG_RTC_DRV_ISL1208=m +CONFIG_RTC_DRV_ISL12022=m +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_BQ32K=m +CONFIG_RTC_DRV_TPS6586X=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_RV8803=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_RX6110=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 + +# +# Platform RTC drivers +# +# CONFIG_RTC_DRV_CMOS is not set +# 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_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 + +# +# on-CPU RTC drivers +# +# CONFIG_RTC_DRV_PL030 is not set +# CONFIG_RTC_DRV_PL031 is not set +CONFIG_RTC_DRV_CADENCE=m +# CONFIG_RTC_DRV_FTRTC010 is not set +# CONFIG_RTC_DRV_SNVS is not set +# CONFIG_RTC_DRV_R7301 is not set +# CONFIG_RTC_DRV_CPCAP is not set + +# +# HID Sensor RTC drivers +# +# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set +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 is not set +# CONFIG_AMBA_PL08X is not set +CONFIG_DW_AXI_DMAC=m +# CONFIG_FSL_EDMA is not set +CONFIG_FSL_QDMA=m +# CONFIG_INTEL_IDMA64 is not set +# CONFIG_NBPFAXI_DMA is not set +CONFIG_PL330_DMA=y +# CONFIG_QCOM_HIDMA_MGMT is not set +# CONFIG_QCOM_HIDMA is not set +CONFIG_DW_DMAC_CORE=m +CONFIG_DW_DMAC=m +# CONFIG_SF_PDMA is not set + +# +# 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_SELFTESTS=m +# CONFIG_DMABUF_HEAPS is not set +# end of DMABUF options + +# CONFIG_AUXDISPLAY is not set +# CONFIG_UIO is not set +# CONFIG_VFIO is not set +# CONFIG_VIRT_DRIVERS is not set +CONFIG_VIRTIO=m +# CONFIG_VIRTIO_MENU is not set + +# +# Microsoft Hyper-V guest support +# +# end of Microsoft Hyper-V guest support + +# CONFIG_GREYBUS is not set +CONFIG_STAGING=y +# CONFIG_PRISM2_USB is not set +# CONFIG_COMEDI is not set +# CONFIG_RTLLIB is not set +CONFIG_RTL8723BS=m +CONFIG_R8712U=m +CONFIG_R8188EU=m +CONFIG_88EU_AP_MODE=y +# CONFIG_VT6656 is not set + +# +# 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_AD7192 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_AD7150 is not set +# CONFIG_AD7746 is not set +# end of Capacitance to digital converters + +# +# Direct Digital Synthesis +# +# CONFIG_AD9832 is not set +# CONFIG_AD9834 is not set +# 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 + +# +# Speakup console speech +# +# CONFIG_SPEAKUP is not set +# end of Speakup console speech + +CONFIG_STAGING_MEDIA=y +CONFIG_VIDEO_HANTRO=m +CONFIG_VIDEO_HANTRO_ROCKCHIP=y + +# +# soc_camera sensor drivers +# +# CONFIG_PHY_ROCKCHIP_DPHY_RX0 is not set +# CONFIG_VIDEO_ROCKCHIP_ISP1 is not set + +# +# Android +# +CONFIG_ASHMEM=y +# CONFIG_ION is not set +# 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 is not set +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 is not set +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_WILC1000_SDIO is not set +# CONFIG_WILC1000_SPI is not set +CONFIG_MOST=m +# CONFIG_MOST_CDEV is not set +# CONFIG_MOST_NET is not set +# CONFIG_MOST_SOUND is not set +# CONFIG_MOST_VIDEO is not set +# CONFIG_MOST_DIM2 is not set +# CONFIG_MOST_I2C is not set +# CONFIG_MOST_USB is not set +# CONFIG_KS7010 is not set +# CONFIG_PI433 is not set + +# +# Gasket devices +# +# end of Gasket devices + +# CONFIG_XIL_AXIS_FIFO is not set +CONFIG_FIELDBUS_DEV=m +CONFIG_HMS_ANYBUSS_BUS=m +CONFIG_ARCX_ANYBUS_CONTROLLER=m +CONFIG_HMS_PROFINET=m +# CONFIG_USB_WUSB_CBAF is not set +# CONFIG_UWB is not set +# CONFIG_STAGING_EXFAT_FS is not set +# CONFIG_WFX is not set +# CONFIG_GOLDFISH is not set +# CONFIG_MFD_CROS_EC is not set +# CONFIG_CHROME_PLATFORMS is not set +# CONFIG_MELLANOX_PLATFORM is not set +CONFIG_CLKDEV_LOOKUP=y +CONFIG_HAVE_CLK_PREPARE=y +CONFIG_COMMON_CLK=y + +# +# Common Clock Framework +# +# CONFIG_CLK_HSDK is not set +CONFIG_COMMON_CLK_MAX9485=m +CONFIG_COMMON_CLK_RK808=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 is not set +# CONFIG_CLK_QORIQ is not set +# CONFIG_COMMON_CLK_PWM is not set +CONFIG_COMMON_CLK_VC5=m +# CONFIG_COMMON_CLK_BD718XX is not set +# CONFIG_COMMON_CLK_FIXED_MMIO is not set +# end of Common Clock Framework + +# CONFIG_HWSPINLOCK is not set + +# +# Clock Source drivers +# +CONFIG_TIMER_OF=y +CONFIG_TIMER_PROBE=y +CONFIG_CLKSRC_MMIO=y +CONFIG_DW_APB_TIMER=y +CONFIG_DW_APB_TIMER_OF=y +CONFIG_ROCKCHIP_TIMER=y +CONFIG_ARM_ARCH_TIMER=y +CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y +CONFIG_ARM_GLOBAL_TIMER=y +CONFIG_CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK=y +# CONFIG_MICROCHIP_PIT64B is not set +# end of Clock Source drivers + +CONFIG_MAILBOX=y +# CONFIG_ARM_MHU is not set +# CONFIG_PLATFORM_MHU is not set +# CONFIG_PL320_MBOX is not set +CONFIG_ROCKCHIP_MBOX=y +# CONFIG_ALTERA_MBOX is not set +# CONFIG_MAILBOX_TEST is not set +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_PASSTHROUGH is not set +CONFIG_OF_IOMMU=y +CONFIG_ROCKCHIP_IOMMU=y +# CONFIG_ARM_SMMU 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 +# +# end of Amlogic SoC drivers + +# +# Aspeed SoC drivers +# +# end of Aspeed SoC drivers + +# +# Broadcom SoC drivers +# +# CONFIG_SOC_BRCMSTB is not set +# 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 + +# +# Qualcomm SoC drivers +# +# end of Qualcomm SoC drivers + +CONFIG_ROCKCHIP_GRF=y +CONFIG_ROCKCHIP_PM_DOMAINS=y +# CONFIG_SOC_TI is not set + +# +# Xilinx SoC drivers +# +# CONFIG_XILINX_VCU is not set +# 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=y +# CONFIG_DEVFREQ_GOV_POWERSAVE is not set +CONFIG_DEVFREQ_GOV_USERSPACE=y +# CONFIG_DEVFREQ_GOV_PASSIVE is not set + +# +# DEVFREQ Drivers +# +# CONFIG_ARM_RK3399_DMC_DEVFREQ is not set +# CONFIG_PM_DEVFREQ_EVENT is not set +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 is not set +# CONFIG_EXTCON_RT8973A is not set +# CONFIG_EXTCON_SM5502 is not set +# CONFIG_EXTCON_USB_GPIO is not set +CONFIG_MEMORY=y +# CONFIG_ARM_PL172_MPMC is not set +CONFIG_PL353_SMC=y +CONFIG_IIO=y +CONFIG_IIO_BUFFER=y +CONFIG_IIO_BUFFER_CB=m +# CONFIG_IIO_BUFFER_HW_CONSUMER is not set +CONFIG_IIO_KFIFO_BUF=y +CONFIG_IIO_TRIGGERED_BUFFER=y +# CONFIG_IIO_CONFIGFS is not set +CONFIG_IIO_TRIGGER=y +CONFIG_IIO_CONSUMERS_PER_TRIGGER=2 +# CONFIG_IIO_SW_DEVICE is not set +# CONFIG_IIO_SW_TRIGGER is not set + +# +# Accelerometers +# +# CONFIG_ADIS16201 is not set +# CONFIG_ADIS16209 is not set +CONFIG_ADXL345=m +CONFIG_ADXL345_I2C=m +CONFIG_ADXL345_SPI=m +# CONFIG_ADXL372_SPI is not set +# CONFIG_ADXL372_I2C is not set +# CONFIG_BMA180 is not set +# CONFIG_BMA220 is not set +# CONFIG_BMA400 is not set +# CONFIG_BMC150_ACCEL is not set +# CONFIG_DA280 is not set +# CONFIG_DA311 is not set +# CONFIG_DMARD06 is not set +# CONFIG_DMARD09 is not set +# CONFIG_DMARD10 is not set +CONFIG_HID_SENSOR_ACCEL_3D=m +# CONFIG_IIO_ST_ACCEL_3AXIS is not set +# CONFIG_KXSD9 is not set +# CONFIG_KXCJK1013 is not set +# CONFIG_MC3230 is not set +# CONFIG_MMA7455_I2C is not set +# CONFIG_MMA7455_SPI is not set +# CONFIG_MMA7660 is not set +# CONFIG_MMA8452 is not set +# CONFIG_MMA9551 is not set +# CONFIG_MMA9553 is not set +# CONFIG_MXC4005 is not set +# CONFIG_MXC6255 is not set +# CONFIG_SCA3000 is not set +# CONFIG_STK8312 is not set +# CONFIG_STK8BA50 is not set +# end of Accelerometers + +# +# Analog to digital converters +# +# CONFIG_AD7091R5 is not set +# CONFIG_AD7124 is not set +# CONFIG_AD7266 is not set +# CONFIG_AD7291 is not set +# CONFIG_AD7292 is not set +# CONFIG_AD7298 is not set +# CONFIG_AD7476 is not set +CONFIG_AD7606=m +# CONFIG_AD7606_IFACE_PARALLEL is not set +CONFIG_AD7606_IFACE_SPI=m +# CONFIG_AD7766 is not set +CONFIG_AD7768_1=m +# CONFIG_AD7780 is not set +# CONFIG_AD7791 is not set +# CONFIG_AD7793 is not set +# CONFIG_AD7887 is not set +# CONFIG_AD7923 is not set +# CONFIG_AD7949 is not set +# CONFIG_AD799X is not set +# CONFIG_CC10001_ADC is not set +# CONFIG_CPCAP_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 is not set +# CONFIG_LTC2497 is not set +# CONFIG_MAX1027 is not set +# CONFIG_MAX11100 is not set +# CONFIG_MAX1118 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_NAU7802 is not set +CONFIG_ROCKCHIP_SARADC=y +# CONFIG_SD_ADC_MODULATOR is not set +# CONFIG_TI_ADC081C is not set +# CONFIG_TI_ADC0832 is not set +# CONFIG_TI_ADC084S021 is not set +# CONFIG_TI_ADC12138 is not set +# CONFIG_TI_ADC108S102 is not set +# CONFIG_TI_ADC128S052 is not set +# CONFIG_TI_ADC161S626 is not set +# CONFIG_TI_ADS1015 is not set +# CONFIG_TI_ADS7950 is not set +CONFIG_TI_ADS8344=m +# CONFIG_TI_ADS8688 is not set +CONFIG_TI_ADS124S08=m +# CONFIG_TI_TLC4541 is not set +# CONFIG_VF610_ADC is not set +# CONFIG_XILINX_XADC is not set +# end of Analog to digital converters + +# +# Analog Front Ends +# +CONFIG_IIO_RESCALE=m +# end of Analog Front Ends + +# +# Amplifiers +# +# CONFIG_AD8366 is not set +# end of Amplifiers + +# +# Chemical Sensors +# +# CONFIG_ATLAS_PH_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_SENSIRION_SGP30=m +CONFIG_SPS30=m +# CONFIG_VZ89X is not set +# end of Chemical Sensors + +# +# Hid Sensor IIO Common +# +CONFIG_HID_SENSOR_IIO_COMMON=m +CONFIG_HID_SENSOR_IIO_TRIGGER=m +# end of Hid Sensor IIO Common + +# +# SSP Sensor Common +# +# CONFIG_IIO_SSP_SENSORHUB is not set +# end of SSP Sensor Common + +# +# 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_LTC1660 is not set +# CONFIG_LTC2632 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_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_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 is not set +CONFIG_TI_DAC7612=m +# CONFIG_VF610_DAC is not set +# end of Digital to analog converters + +# +# IIO dummy driver +# +# 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 is not set +# end of Phase-Locked Loop (PLL) frequency synthesizers +# end of Frequency Synthesizers DDS/PLL + +# +# Digital gyroscope sensors +# +# CONFIG_ADIS16080 is not set +# CONFIG_ADIS16130 is not set +# CONFIG_ADIS16136 is not set +# CONFIG_ADIS16260 is not set +# CONFIG_ADXRS450 is not set +# CONFIG_BMG160 is not set +CONFIG_FXAS21002C=m +CONFIG_FXAS21002C_I2C=m +CONFIG_FXAS21002C_SPI=m +CONFIG_HID_SENSOR_GYRO_3D=m +# CONFIG_MPU3050_I2C is not set +# CONFIG_IIO_ST_GYRO_3AXIS is not set +# CONFIG_ITG3200 is not set +# 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=m +# end of Heart Rate Monitors +# end of Health Sensors + +# +# Humidity sensors +# +# CONFIG_AM2315 is not set +# CONFIG_DHT11 is not set +# CONFIG_HDC100X is not set +CONFIG_HID_SENSOR_HUMIDITY=m +# CONFIG_HTS221 is not set +# CONFIG_HTU21 is not set +# CONFIG_SI7005 is not set +CONFIG_SI7020=m +# end of Humidity sensors + +# +# Inertial measurement units +# +# CONFIG_ADIS16400 is not set +CONFIG_ADIS16460=m +# CONFIG_ADIS16480 is not set +# CONFIG_BMI160_I2C is not set +# CONFIG_BMI160_SPI is not set +# CONFIG_FXOS8700_I2C is not set +# CONFIG_FXOS8700_SPI is not set +# CONFIG_KMX61 is not set +# CONFIG_INV_MPU6050_I2C is not set +# CONFIG_INV_MPU6050_SPI is not set +# CONFIG_IIO_ST_LSM6DSX is not set +# end of Inertial measurement units + +CONFIG_IIO_ADIS_LIB=m +CONFIG_IIO_ADIS_LIB_BUFFER=y + +# +# Light sensors +# +# CONFIG_ADJD_S311 is not set +# CONFIG_ADUX1020 is not set +# CONFIG_AL3320A is not set +# CONFIG_APDS9300 is not set +# CONFIG_APDS9960 is not set +# CONFIG_BH1750 is not set +# CONFIG_BH1780 is not set +# CONFIG_CM32181 is not set +# CONFIG_CM3232 is not set +# CONFIG_CM3323 is not set +CONFIG_CM3605=m +# CONFIG_CM36651 is not set +# CONFIG_GP2AP020A00F is not set +CONFIG_SENSORS_ISL29018=y +# CONFIG_SENSORS_ISL29028 is not set +# CONFIG_ISL29125 is not set +CONFIG_HID_SENSOR_ALS=m +CONFIG_HID_SENSOR_PROX=m +# CONFIG_JSA1212 is not set +# CONFIG_RPR0521 is not set +# CONFIG_LTR501 is not set +CONFIG_LV0104CS=m +# CONFIG_MAX44000 is not set +CONFIG_MAX44009=m +CONFIG_NOA1305=m +# CONFIG_OPT3001 is not set +# CONFIG_PA12203001 is not set +CONFIG_SI1133=m +# CONFIG_SI1145 is not set +# CONFIG_STK3310 is not set +# CONFIG_ST_UVIS25 is not set +# CONFIG_TCS3414 is not set +# CONFIG_TCS3472 is not set +CONFIG_SENSORS_TSL2563=y +CONFIG_TSL2583=y +CONFIG_TSL2772=m +# CONFIG_TSL4531 is not set +# CONFIG_US5182D is not set +# CONFIG_VCNL4000 is not set +# CONFIG_VCNL4035 is not set +# CONFIG_VEML6030 is not set +# CONFIG_VEML6070 is not set +# CONFIG_VL6180 is not set +# CONFIG_ZOPT2201 is not set +# end of Light sensors + +# +# Magnetometer sensors +# +# CONFIG_AK8974 is not set +# CONFIG_AK8975 is not set +# CONFIG_AK09911 is not set +# CONFIG_BMC150_MAGN_I2C is not set +# CONFIG_BMC150_MAGN_SPI is not set +# CONFIG_MAG3110 is not set +CONFIG_HID_SENSOR_MAGNETOMETER_3D=m +# CONFIG_MMC35240 is not set +# CONFIG_IIO_ST_MAGN_3AXIS is not set +# CONFIG_SENSORS_HMC5843_I2C is not set +# CONFIG_SENSORS_HMC5843_SPI is not set +# CONFIG_SENSORS_RM3100_I2C is not set +# CONFIG_SENSORS_RM3100_SPI is not set +# 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_INTERRUPT_TRIGGER is not set +CONFIG_IIO_SYSFS_TRIGGER=y +# end of Triggers - standalone + +# +# Digital potentiometers +# +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 is not set +# 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 is not set +# CONFIG_DLHL60D is not set +# CONFIG_DPS310 is not set +CONFIG_HID_SENSOR_PRESS=m +# CONFIG_HP03 is not set +# 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_ISL29501=m +# CONFIG_LIDAR_LITE_V2 is not set +CONFIG_MB1232=m +# CONFIG_PING is not set +# CONFIG_RFD77402 is not set +# CONFIG_SRF04 is not set +# CONFIG_SX9500 is not set +# CONFIG_SRF08 is not set +# CONFIG_VL53L0X_I2C is not set +# 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_LTC2983 is not set +# CONFIG_MAXIM_THERMOCOUPLE is not set +CONFIG_HID_SENSOR_TEMP=m +# CONFIG_MLX90614 is not set +CONFIG_MLX90632=m +# CONFIG_TMP006 is not set +# CONFIG_TMP007 is not set +# CONFIG_TSYS01 is not set +# CONFIG_TSYS02D is not set +CONFIG_MAX31856=m +# end of Temperature sensors + +CONFIG_PWM=y +CONFIG_PWM_SYSFS=y +# CONFIG_PWM_FSL_FTM is not set +# CONFIG_PWM_PCA9685 is not set +CONFIG_PWM_ROCKCHIP=y + +# +# IRQ chip support +# +CONFIG_IRQCHIP=y +CONFIG_ARM_GIC=y +CONFIG_ARM_GIC_MAX_NR=1 +# CONFIG_AL_FIC is not set +CONFIG_MADERA_IRQ=m +# end of IRQ chip support + +# CONFIG_IPACK_BUS is not set +CONFIG_ARCH_HAS_RESET_CONTROLLER=y +CONFIG_RESET_CONTROLLER=y +# CONFIG_RESET_BRCMSTB_RESCAL is not set +# CONFIG_RESET_INTEL_GW is not set +# CONFIG_RESET_TI_SYSCON is not set + +# +# PHY Subsystem +# +CONFIG_GENERIC_PHY=y +# CONFIG_BCM_KONA_USB2_PHY is not set +# CONFIG_PHY_CADENCE_DP is not set +# CONFIG_PHY_CADENCE_DPHY is not set +# CONFIG_PHY_CADENCE_SIERRA is not set +# CONFIG_PHY_FSL_IMX8MQ_USB is not set +# CONFIG_PHY_MIXEL_MIPI_DPHY is not set +# 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 is not set +# CONFIG_PHY_OCELOT_SERDES is not set +CONFIG_PHY_ROCKCHIP_DP=y +CONFIG_PHY_ROCKCHIP_EMMC=y +CONFIG_PHY_ROCKCHIP_INNO_HDMI=y +CONFIG_PHY_ROCKCHIP_INNO_USB2=y +# CONFIG_PHY_ROCKCHIP_INNO_DSIDPHY is not set +# CONFIG_PHY_ROCKCHIP_PCIE is not set +# CONFIG_PHY_ROCKCHIP_TYPEC is not set +CONFIG_PHY_ROCKCHIP_USB=y +# CONFIG_PHY_SAMSUNG_USB2 is not set +# CONFIG_PHY_INTEL_EMMC 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_PMU=y +# end of Performance monitor support + +# CONFIG_RAS is not set + +# +# Android +# +CONFIG_ANDROID=y +# CONFIG_ANDROID_BINDER_IPC is not set +# end of Android + +CONFIG_DAX=y +CONFIG_NVMEM=y +CONFIG_NVMEM_SYSFS=y +CONFIG_ROCKCHIP_EFUSE=y +CONFIG_ROCKCHIP_OTP=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=m + +# +# TEE drivers +# +CONFIG_OPTEE=m +CONFIG_OPTEE_SHM_NUM_PRIV_PAGES=1 +# end of TEE drivers + +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=m +# CONFIG_COUNTER is not set +# 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 is not set +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_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 is not set +# CONFIG_REISERFS_FS_XATTR is not set +CONFIG_JFS_FS=m +# CONFIG_JFS_POSIX_ACL is not set +# CONFIG_JFS_SECURITY is not set +# CONFIG_JFS_DEBUG is not set +# CONFIG_JFS_STATISTICS is not set +CONFIG_XFS_FS=y +CONFIG_XFS_QUOTA=y +CONFIG_XFS_POSIX_ACL=y +CONFIG_XFS_RT=y +CONFIG_XFS_ONLINE_SCRUB=y +# CONFIG_XFS_ONLINE_REPAIR is not set +# CONFIG_XFS_WARN is not set +# CONFIG_XFS_DEBUG is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_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 is not set +CONFIG_F2FS_FS=y +CONFIG_F2FS_STAT_FS=y +CONFIG_F2FS_FS_XATTR=y +CONFIG_F2FS_FS_POSIX_ACL=y +# CONFIG_F2FS_FS_SECURITY is not set +# CONFIG_F2FS_CHECK_FS is not set +# CONFIG_F2FS_IO_TRACE is not set +# CONFIG_F2FS_FAULT_INJECTION is not set +# CONFIG_F2FS_FS_COMPRESSION is not set +CONFIG_FS_POSIX_ACL=y +CONFIG_EXPORTFS=y +# CONFIG_EXPORTFS_BLOCK_OPS is not set +CONFIG_FILE_LOCKING=y +CONFIG_MANDATORY_FILE_LOCKING=y +CONFIG_FS_ENCRYPTION=y +CONFIG_FS_ENCRYPTION_ALGS=y +# CONFIG_FS_VERITY is not set +CONFIG_FSNOTIFY=y +CONFIG_DNOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_FANOTIFY is not set +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=y +CONFIG_AUTOFS_FS=y +CONFIG_FUSE_FS=m +CONFIG_CUSE=m +CONFIG_VIRTIO_FS=m +CONFIG_OVERLAY_FS=m +# 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_METACOPY is not set + +# +# Caches +# +CONFIG_FSCACHE=y +CONFIG_FSCACHE_STATS=y +CONFIG_FSCACHE_HISTOGRAM=y +# CONFIG_FSCACHE_DEBUG is not set +# CONFIG_FSCACHE_OBJECT_LIST is not set +CONFIG_CACHEFILES=y +# CONFIG_CACHEFILES_DEBUG is not set +# CONFIG_CACHEFILES_HISTOGRAM 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/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_FAT_DEFAULT_UTF8 is not set +CONFIG_NTFS_FS=m +# CONFIG_NTFS_DEBUG is not set +CONFIG_NTFS_RW=y +# end of DOS/FAT/NT Filesystems + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y +# CONFIG_PROC_CHILDREN is not set +CONFIG_KERNFS=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_TMPFS_XATTR=y +CONFIG_MEMFD_CREATE=y +CONFIG_CONFIGFS_FS=y +# end of Pseudo filesystems + +CONFIG_MISC_FILESYSTEMS=y +# CONFIG_ORANGEFS_FS is not set +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +CONFIG_ECRYPT_FS=m +# CONFIG_ECRYPT_FS_MESSAGING is not set +CONFIG_HFS_FS=m +CONFIG_HFSPLUS_FS=m +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_CRAMFS is not set +CONFIG_SQUASHFS=m +CONFIG_SQUASHFS_FILE_CACHE=y +# CONFIG_SQUASHFS_FILE_DIRECT is not set +# CONFIG_SQUASHFS_DECOMP_SINGLE is not set +CONFIG_SQUASHFS_DECOMP_MULTI=y +# CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU is not set +CONFIG_SQUASHFS_XATTR=y +CONFIG_SQUASHFS_ZLIB=y +# CONFIG_SQUASHFS_LZ4 is not set +CONFIG_SQUASHFS_LZO=y +CONFIG_SQUASHFS_XZ=y +# CONFIG_SQUASHFS_ZSTD is not set +CONFIG_SQUASHFS_4K_DEVBLK_SIZE=y +CONFIG_SQUASHFS_EMBEDDED=y +CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 +# CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_OMFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX6FS_FS is not set +# CONFIG_ROMFS_FS is not set +CONFIG_PSTORE=y +CONFIG_PSTORE_DEFLATE_COMPRESS=m +# 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=y +# CONFIG_PSTORE_PMSG is not set +# CONFIG_PSTORE_FTRACE is not set +CONFIG_PSTORE_RAM=y +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +# CONFIG_EROFS_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V2=y +CONFIG_NFS_V3=y +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=y +CONFIG_NFS_SWAP=y +CONFIG_NFS_V4_1=y +CONFIG_NFS_V4_2=y +CONFIG_PNFS_FILE_LAYOUT=y +CONFIG_PNFS_BLOCK=y +CONFIG_PNFS_FLEXFILE_LAYOUT=m +CONFIG_NFS_V4_1_IMPLEMENTATION_ID_DOMAIN="kernel.org" +# CONFIG_NFS_V4_1_MIGRATION is not set +CONFIG_NFS_V4_SECURITY_LABEL=y +CONFIG_ROOT_NFS=y +CONFIG_NFS_FSCACHE=y +# CONFIG_NFS_USE_LEGACY_DNS is not set +CONFIG_NFS_USE_KERNEL_DNS=y +CONFIG_NFS_DISABLE_UDP_SUPPORT=y +CONFIG_NFSD=m +CONFIG_NFSD_V2_ACL=y +CONFIG_NFSD_V3=y +CONFIG_NFSD_V3_ACL=y +CONFIG_NFSD_V4=y +# CONFIG_NFSD_BLOCKLAYOUT is not set +# CONFIG_NFSD_SCSILAYOUT is not set +# CONFIG_NFSD_FLEXFILELAYOUT is not set +# CONFIG_NFSD_V4_2_INTER_SSC is not set +CONFIG_NFSD_V4_SECURITY_LABEL=y +CONFIG_GRACE_PERIOD=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_ACL_SUPPORT=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +CONFIG_SUNRPC_GSS=y +CONFIG_SUNRPC_BACKCHANNEL=y +CONFIG_SUNRPC_SWAP=y +CONFIG_RPCSEC_GSS_KRB5=m +# CONFIG_SUNRPC_DISABLE_INSECURE_ENCTYPES is not set +# CONFIG_SUNRPC_DEBUG is not set +CONFIG_CEPH_FS=m +CONFIG_CEPH_FSCACHE=y +CONFIG_CEPH_FS_POSIX_ACL=y +# CONFIG_CEPH_FS_SECURITY_LABEL is not set +CONFIG_CIFS=m +# CONFIG_CIFS_STATS2 is not set +CONFIG_CIFS_ALLOW_INSECURE_LEGACY=y +# CONFIG_CIFS_WEAK_PW_HASH is not set +CONFIG_CIFS_UPCALL=y +CONFIG_CIFS_XATTR=y +CONFIG_CIFS_POSIX=y +# CONFIG_CIFS_DEBUG is not set +# CONFIG_CIFS_DFS_UPCALL is not set +CONFIG_CIFS_FSCACHE=y +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="utf8" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +CONFIG_NLS_CODEPAGE_850=y +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +CONFIG_NLS_ASCII=y +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_MAC_ROMAN is not set +# CONFIG_NLS_MAC_CELTIC is not set +# CONFIG_NLS_MAC_CENTEURO is not set +# CONFIG_NLS_MAC_CROATIAN is not set +# CONFIG_NLS_MAC_CYRILLIC is not set +# CONFIG_NLS_MAC_GAELIC is not set +# CONFIG_NLS_MAC_GREEK is not set +# CONFIG_NLS_MAC_ICELAND is not set +# CONFIG_NLS_MAC_INUIT is not set +# CONFIG_NLS_MAC_ROMANIAN is not set +# CONFIG_NLS_MAC_TURKISH is not set +CONFIG_NLS_UTF8=y +# CONFIG_DLM is not set +# CONFIG_UNICODE is not set +CONFIG_IO_WQ=y +# end of File systems + +# +# Security options +# +CONFIG_KEYS=y +# CONFIG_KEYS_REQUEST_CACHE is not set +# CONFIG_PERSISTENT_KEYRINGS is not set +# CONFIG_BIG_KEYS is not set +# CONFIG_TRUSTED_KEYS is not set +# CONFIG_ENCRYPTED_KEYS is not set +# CONFIG_KEY_DH_OPERATIONS is not set +# CONFIG_SECURITY_DMESG_RESTRICT is not set +CONFIG_SECURITY=y +CONFIG_SECURITYFS=y +CONFIG_SECURITY_NETWORK=y +# CONFIG_SECURITY_NETWORK_XFRM is not set +CONFIG_SECURITY_PATH=y +CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR=y +# CONFIG_HARDENED_USERCOPY is not set +# CONFIG_FORTIFY_SOURCE is not set +# CONFIG_STATIC_USERMODEHELPER is not set +# CONFIG_SECURITY_SELINUX is not set +# CONFIG_SECURITY_SMACK is not set +# CONFIG_SECURITY_TOMOYO is not set +# CONFIG_SECURITY_APPARMOR is not set +# CONFIG_SECURITY_LOADPIN is not set +CONFIG_SECURITY_YAMA=y +# CONFIG_SECURITY_SAFESETID is not set +# CONFIG_SECURITY_LOCKDOWN_LSM is not set +CONFIG_INTEGRITY=y +# CONFIG_INTEGRITY_SIGNATURE is not set +CONFIG_INTEGRITY_AUDIT=y +# CONFIG_IMA is not set +# CONFIG_EVM is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_LSM="yama,loadpin,safesetid,integrity" + +# +# Kernel hardening options +# + +# +# Memory initialization +# +CONFIG_INIT_STACK_NONE=y +# CONFIG_INIT_ON_ALLOC_DEFAULT_ON is not set +# 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=y +CONFIG_ASYNC_MEMCPY=y +CONFIG_ASYNC_XOR=y +CONFIG_ASYNC_PQ=y +CONFIG_ASYNC_RAID6_RECOV=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=m +CONFIG_CRYPTO_AUTHENC=y +CONFIG_CRYPTO_TEST=m +CONFIG_CRYPTO_SIMD=m +CONFIG_CRYPTO_ENGINE=m + +# +# Public-key cryptography +# +CONFIG_CRYPTO_RSA=y +CONFIG_CRYPTO_DH=m +CONFIG_CRYPTO_ECC=y +CONFIG_CRYPTO_ECDH=y +CONFIG_CRYPTO_ECRDSA=m +CONFIG_CRYPTO_CURVE25519=m + +# +# Authenticated Encryption with Associated Data +# +CONFIG_CRYPTO_CCM=y +CONFIG_CRYPTO_GCM=y +CONFIG_CRYPTO_CHACHA20POLY1305=m +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 is not set +CONFIG_CRYPTO_PCBC=m +CONFIG_CRYPTO_XTS=y +CONFIG_CRYPTO_KEYWRAP=m +CONFIG_CRYPTO_NHPOLY1305=m +# CONFIG_CRYPTO_ADIANTUM is not set +CONFIG_CRYPTO_ESSIV=y + +# +# Hash modes +# +CONFIG_CRYPTO_CMAC=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_XCBC=m +CONFIG_CRYPTO_VMAC=m + +# +# 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=m +CONFIG_CRYPTO_MD4=y +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_MICHAEL_MIC=y +CONFIG_CRYPTO_RMD128=m +CONFIG_CRYPTO_RMD160=m +CONFIG_CRYPTO_RMD256=m +CONFIG_CRYPTO_RMD320=m +CONFIG_CRYPTO_SHA1=y +CONFIG_CRYPTO_SHA256=y +CONFIG_CRYPTO_SHA512=y +CONFIG_CRYPTO_SHA3=m +CONFIG_CRYPTO_SM3=m +CONFIG_CRYPTO_STREEBOG=m +CONFIG_CRYPTO_TGR192=m +CONFIG_CRYPTO_WP512=m + +# +# Ciphers +# +CONFIG_CRYPTO_AES=y +CONFIG_CRYPTO_AES_TI=m +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_ARC4=y +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_BLOWFISH_COMMON=m +CONFIG_CRYPTO_CAMELLIA=m +CONFIG_CRYPTO_CAST_COMMON=m +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_DES=y +CONFIG_CRYPTO_FCRYPT=m +CONFIG_CRYPTO_KHAZAD=m +CONFIG_CRYPTO_SALSA20=m +CONFIG_CRYPTO_CHACHA20=m +CONFIG_CRYPTO_SEED=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_SM4=m +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_TWOFISH_COMMON=m + +# +# Compression +# +CONFIG_CRYPTO_DEFLATE=y +CONFIG_CRYPTO_LZO=y +CONFIG_CRYPTO_842=m +CONFIG_CRYPTO_LZ4=m +CONFIG_CRYPTO_LZ4HC=m +CONFIG_CRYPTO_ZSTD=m + +# +# Random Number Generation +# +CONFIG_CRYPTO_ANSI_CPRNG=y +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_AEAD=m +# CONFIG_CRYPTO_STATS is not set +CONFIG_CRYPTO_HASH_INFO=y + +# +# Crypto library routines +# +CONFIG_CRYPTO_LIB_AES=y +CONFIG_CRYPTO_LIB_ARC4=y +CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=m +CONFIG_CRYPTO_LIB_BLAKE2S=m +CONFIG_CRYPTO_ARCH_HAVE_LIB_CHACHA=m +CONFIG_CRYPTO_LIB_CHACHA_GENERIC=m +CONFIG_CRYPTO_LIB_CHACHA=m +CONFIG_CRYPTO_ARCH_HAVE_LIB_CURVE25519=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=m +CONFIG_CRYPTO_LIB_POLY1305=m +CONFIG_CRYPTO_LIB_CHACHA20POLY1305=m +CONFIG_CRYPTO_LIB_SHA256=y +CONFIG_CRYPTO_HW=y +# CONFIG_CRYPTO_DEV_ATMEL_ECC is not set +# CONFIG_CRYPTO_DEV_ATMEL_SHA204A is not set +CONFIG_CRYPTO_DEV_ROCKCHIP=m +CONFIG_CRYPTO_DEV_VIRTIO=m +CONFIG_CRYPTO_DEV_SAFEXCEL=m +CONFIG_CRYPTO_DEV_CCREE=m +# CONFIG_CRYPTO_DEV_AMLOGIC_GXL is not set +CONFIG_ASYMMETRIC_KEY_TYPE=y +CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=y +CONFIG_X509_CERTIFICATE_PARSER=y +# CONFIG_PKCS8_PRIVATE_KEY_PARSER is not set +CONFIG_PKCS7_MESSAGE_PARSER=y +# CONFIG_PKCS7_TEST_KEY is not set +# CONFIG_SIGNED_PE_FILE_VERIFICATION is not set + +# +# Certificates for signature checking +# +CONFIG_SYSTEM_TRUSTED_KEYRING=y +CONFIG_SYSTEM_TRUSTED_KEYS="" +# CONFIG_SYSTEM_EXTRA_CERTIFICATE is not set +# CONFIG_SECONDARY_TRUSTED_KEYRING is not set +# CONFIG_SYSTEM_BLACKLIST_KEYRING 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_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_CORDIC is not set +CONFIG_RATIONAL=y +CONFIG_GENERIC_PCI_IOMAP=y +CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y +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=m +CONFIG_CRC4=m +CONFIG_CRC7=m +CONFIG_LIBCRC32C=y +CONFIG_CRC8=m +CONFIG_XXHASH=y +CONFIG_AUDIT_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_BCJ=y +# CONFIG_XZ_DEC_TEST is not set +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_GENERIC_ALLOCATOR=y +CONFIG_REED_SOLOMON=y +CONFIG_REED_SOLOMON_ENC8=y +CONFIG_REED_SOLOMON_DEC8=y +CONFIG_TEXTSEARCH=y +CONFIG_TEXTSEARCH_KMP=m +CONFIG_TEXTSEARCH_BM=m +CONFIG_TEXTSEARCH_FSM=m +CONFIG_ASSOCIATIVE_ARRAY=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT_MAP=y +CONFIG_HAS_DMA=y +CONFIG_NEED_SG_DMA_LENGTH=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_DMA_DECLARE_COHERENT=y +CONFIG_ARCH_HAS_SETUP_DMA_OPS=y +CONFIG_ARCH_HAS_TEARDOWN_DMA_OPS=y +CONFIG_DMA_NONCOHERENT_MMAP=y +CONFIG_DMA_REMAP=y +CONFIG_DMA_CMA=y + +# +# Default contiguous memory area size: +# +CONFIG_CMA_SIZE_MBYTES=16 +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_SGL_ALLOC=y +CONFIG_CPU_RMAP=y +CONFIG_DQL=y +CONFIG_GLOB=y +# CONFIG_GLOB_SELFTEST is not set +CONFIG_NLATTR=y +CONFIG_LRU_CACHE=m +CONFIG_CLZ_TAB=y +CONFIG_IRQ_POLL=y +CONFIG_MPILIB=y +CONFIG_LIBFDT=y +CONFIG_OID_REGISTRY=y +CONFIG_HAVE_GENERIC_VDSO=y +CONFIG_GENERIC_GETTIMEOFDAY=y +CONFIG_GENERIC_VDSO_32=y +CONFIG_FONT_SUPPORT=y +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +CONFIG_SG_POOL=y +CONFIG_SBITMAP=y +# CONFIG_STRING_SELFTEST is not set +# end of Library routines + +# +# Kernel hacking +# + +# +# printk and dmesg options +# +CONFIG_PRINTK_TIME=y +# CONFIG_PRINTK_CALLER 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 is not set +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_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 +# CONFIG_STRIP_ASM_SYMS is not set +# CONFIG_READABLE_ASM is not set +# CONFIG_HEADERS_INSTALL is not set +CONFIG_OPTIMIZE_INLINING=y +# CONFIG_DEBUG_SECTION_MISMATCH is not set +CONFIG_SECTION_MISMATCH_WARN_ONLY=y +CONFIG_ARCH_WANT_FRAME_POINTERS=y +CONFIG_FRAME_POINTER=y +# 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=0 +CONFIG_MAGIC_SYSRQ_SERIAL=y +CONFIG_DEBUG_FS=y +CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_KGDB is not set +# CONFIG_UBSAN is not set +CONFIG_UBSAN_ALIGNMENT=y +# end of Generic Kernel Debugging Instruments + +CONFIG_DEBUG_KERNEL=y +CONFIG_DEBUG_MISC=y + +# +# Memory Debugging +# +CONFIG_PAGE_EXTENSION=y +# 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_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_DEBUG_VM is not set +CONFIG_ARCH_HAS_DEBUG_VIRTUAL=y +# CONFIG_DEBUG_VIRTUAL is not set +# CONFIG_DEBUG_MEMORY_INIT is not set +# CONFIG_DEBUG_PER_CPU_MAPS is not set +# CONFIG_DEBUG_HIGHMEM is not set +CONFIG_CC_HAS_KASAN_GENERIC=y +CONFIG_KASAN_STACK=1 +# 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=y +CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=120 +CONFIG_BOOTPARAM_HUNG_TASK_PANIC=y +CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=1 +# CONFIG_WQ_WATCHDOG is not set +# end of Debug Oops, Lockups and Hangs + +# +# Scheduler Debugging +# +CONFIG_SCHED_DEBUG=y +CONFIG_SCHED_INFO=y +CONFIG_SCHEDSTATS=y +# 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=y +# 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 +# end of Lock Debugging (spinlocks, mutexes, etc...) + +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=y + +# +# RCU Debugging +# +# CONFIG_RCU_PERF_TEST is not set +# CONFIG_RCU_TORTURE_TEST is not set +CONFIG_RCU_CPU_STALL_TIMEOUT=60 +# CONFIG_RCU_TRACE is not set +# CONFIG_RCU_EQS_DEBUG is not set +# end of RCU Debugging + +# CONFIG_DEBUG_WQ_FORCE_RR_CPU is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT 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_GENERIC_TRACER=y +CONFIG_TRACING_SUPPORT=y +CONFIG_FTRACE=y +# CONFIG_BOOTTIME_TRACING is not set +CONFIG_FUNCTION_TRACER=y +CONFIG_FUNCTION_GRAPH_TRACER=y +CONFIG_DYNAMIC_FTRACE=y +CONFIG_DYNAMIC_FTRACE_WITH_REGS=y +# CONFIG_FUNCTION_PROFILER is not set +# CONFIG_STACK_TRACER is not set +# CONFIG_PREEMPTIRQ_EVENTS 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_FTRACE_SYSCALLS is not set +# CONFIG_TRACER_SNAPSHOT is not set +CONFIG_BRANCH_PROFILE_NONE=y +# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set +# CONFIG_PROFILE_ALL_BRANCHES is not set +CONFIG_BLK_DEV_IO_TRACE=y +# CONFIG_UPROBE_EVENTS is not set +CONFIG_FTRACE_MCOUNT_RECORD=y +# 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_FTRACE_STARTUP_TEST is not set +# CONFIG_RING_BUFFER_STARTUP_TEST is not set +# CONFIG_PREEMPTIRQ_DELAY_TEST is not set +# CONFIG_SAMPLES is not set +CONFIG_ARCH_HAS_DEVMEM_IS_ALLOWED=y +CONFIG_STRICT_DEVMEM=y +# CONFIG_IO_STRICT_DEVMEM is not set + +# +# arm Debugging +# +# CONFIG_ARM_PTDUMP_DEBUGFS is not set +# CONFIG_DEBUG_WX is not set +CONFIG_UNWINDER_FRAME_POINTER=y +# CONFIG_DEBUG_USER is not set +# CONFIG_DEBUG_LL is not set +CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S" +CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h" +# CONFIG_PID_IN_CONTEXTIDR is not set +# CONFIG_CORESIGHT is not set +# end of arm Debugging + +# +# Kernel Testing and Coverage +# +# CONFIG_KUNIT 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 is not set +# CONFIG_MEMTEST is not set +# end of Kernel Testing and Coverage +# end of Kernel hacking diff --git a/config/kernel/linux-rk322x-legacy.config b/config/kernel/linux-rk322x-legacy.config new file mode 100644 index 0000000000..a9b5480138 --- /dev/null +++ b/config/kernel/linux-rk322x-legacy.config @@ -0,0 +1,5642 @@ +# +# Automatically generated file; DO NOT EDIT. +# Linux/arm 4.4.194 Kernel Configuration +# +CONFIG_ARM=y +CONFIG_ARM_HAS_SG_CHAIN=y +CONFIG_NEED_SG_DMA_LENGTH=y +CONFIG_ARM_DMA_USE_IOMMU=y +CONFIG_MIGHT_HAVE_PCI=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_HAVE_PROC_CPU=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_FIX_EARLYCON_MEM=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_ARCH_SUPPORTS_UPROBES=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_ARM_PATCH_PHYS_VIRT=y +CONFIG_GENERIC_BUG=y +CONFIG_PGTABLE_LEVELS=2 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_IRQ_WORK=y +CONFIG_BUILDTIME_EXTABLE_SORT=y + +# +# General setup +# +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_CROSS_COMPILE="" +# CONFIG_COMPILE_TEST is not set +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_HAVE_KERNEL_GZIP=y +CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_XZ=y +CONFIG_HAVE_KERNEL_LZO=y +CONFIG_HAVE_KERNEL_LZ4=y +CONFIG_KERNEL_GZIP=y +# CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_XZ is not set +# CONFIG_KERNEL_LZO is not set +# CONFIG_KERNEL_LZ4 is not set +CONFIG_DEFAULT_HOSTNAME="localhost" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_POSIX_MQUEUE=y +CONFIG_POSIX_MQUEUE_SYSCTL=y +CONFIG_CROSS_MEMORY_ATTACH=y +CONFIG_FHANDLE=y +CONFIG_USELIB=y +# CONFIG_AUDIT is not set +CONFIG_HAVE_ARCH_AUDITSYSCALL=y + +# +# IRQ subsystem +# +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_IRQ_SHOW=y +CONFIG_GENERIC_IRQ_SHOW_LEVEL=y +CONFIG_GENERIC_IRQ_MIGRATION=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_GENERIC_IRQ_CHIP=y +CONFIG_IRQ_DOMAIN=y +CONFIG_IRQ_DOMAIN_HIERARCHY=y +CONFIG_HANDLE_DOMAIN_IRQ=y +# CONFIG_IRQ_DOMAIN_DEBUG is not set +CONFIG_IRQ_FORCED_THREADING=y +CONFIG_SPARSE_IRQ=y +CONFIG_GENERIC_TIME_VSYSCALL=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_ARCH_HAS_TICK_BROADCAST=y +CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y + +# +# 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 + +# +# 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_WALT is not set +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_TASKSTATS=y +CONFIG_TASK_DELAY_ACCT=y +CONFIG_TASK_XACCT=y +CONFIG_TASK_IO_ACCOUNTING=y + +# +# RCU Subsystem +# +CONFIG_TREE_RCU=y +# CONFIG_RCU_EXPERT is not set +CONFIG_SRCU=y +# CONFIG_TASKS_RCU is not set +CONFIG_RCU_STALL_COMMON=y +# CONFIG_TREE_RCU_TRACE is not set +# CONFIG_RCU_EXPEDITE_BOOT is not set +CONFIG_BUILD_BIN2C=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=18 +CONFIG_LOG_CPU_MAX_BUF_SHIFT=12 +CONFIG_GENERIC_SCHED_CLOCK=y +CONFIG_CGROUPS=y +# CONFIG_CGROUP_DEBUG is not set +CONFIG_CGROUP_FREEZER=y +CONFIG_CGROUP_PIDS=y +CONFIG_CGROUP_DEVICE=y +CONFIG_CPUSETS=y +CONFIG_PROC_PID_CPUSET=y +CONFIG_CGROUP_CPUACCT=y +CONFIG_PAGE_COUNTER=y +CONFIG_MEMCG=y +CONFIG_MEMCG_SWAP=y +CONFIG_MEMCG_SWAP_ENABLED=y +CONFIG_MEMCG_KMEM=y +CONFIG_CGROUP_PERF=y +CONFIG_CGROUP_SCHED=y +CONFIG_FAIR_GROUP_SCHED=y +CONFIG_CFS_BANDWIDTH=y +CONFIG_RT_GROUP_SCHED=y +CONFIG_BLK_CGROUP=y +# CONFIG_DEBUG_BLK_CGROUP is not set +CONFIG_CGROUP_WRITEBACK=y +# CONFIG_CHECKPOINT_RESTORE is not set +CONFIG_NAMESPACES=y +CONFIG_UTS_NS=y +CONFIG_IPC_NS=y +CONFIG_USER_NS=y +CONFIG_PID_NS=y +CONFIG_NET_NS=y +# CONFIG_SCHED_AUTOGROUP is not set +# CONFIG_SCHED_TUNE is not set +# CONFIG_DEFAULT_USE_ENERGY_AWARE is not set +# CONFIG_SYSFS_DEPRECATED is not set +CONFIG_RELAY=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_RD_GZIP=y +# CONFIG_RD_BZIP2 is not set +# CONFIG_RD_LZMA is not set +CONFIG_RD_XZ=y +# CONFIG_RD_LZO is not set +CONFIG_RD_LZ4=y +# CONFIG_INITRD_ASYNC is not set +CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +CONFIG_HAVE_UID16=y +CONFIG_BPF=y +CONFIG_EXPERT=y +CONFIG_UID16=y +CONFIG_MULTIUSER=y +# CONFIG_SGETMASK_SYSCALL is not set +CONFIG_SYSFS_SYSCALL=y +# CONFIG_SYSCTL_SYSCALL is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +# CONFIG_BPF_SYSCALL is not set +CONFIG_SHMEM=y +CONFIG_AIO=y +CONFIG_ADVISE_SYSCALLS=y +# CONFIG_USERFAULTFD is not set +CONFIG_MEMBARRIER=y +CONFIG_EMBEDDED=y +CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y + +# +# Kernel Performance Events And Counters +# +CONFIG_PERF_EVENTS=y +# CONFIG_DEBUG_PERF_USE_VMALLOC is not set +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLUB_SYSFS=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_SLUB_CPU_PARTIAL=y +# CONFIG_SYSTEM_DATA_VERIFICATION is not set +CONFIG_PROFILING=y +CONFIG_TRACEPOINTS=y +# CONFIG_OPROFILE is not set +CONFIG_HAVE_OPROFILE=y +# CONFIG_KPROBES is not set +# CONFIG_JUMP_LABEL is not set +# CONFIG_UPROBES is not set +# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set +CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y +CONFIG_ARCH_USE_BUILTIN_BSWAP=y +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +CONFIG_HAVE_OPTPROBES=y +CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_ATTRS=y +CONFIG_HAVE_DMA_CONTIGUOUS=y +CONFIG_GENERIC_SMP_IDLE_THREAD=y +CONFIG_GENERIC_IDLE_POLL_SETUP=y +CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y +CONFIG_HAVE_CLK=y +CONFIG_HAVE_DMA_API_DEBUG=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_ARCH_WANT_IPC_PARSE_VERSION=y +CONFIG_HAVE_ARCH_SECCOMP_FILTER=y +CONFIG_SECCOMP_FILTER=y +CONFIG_HAVE_CC_STACKPROTECTOR=y +# CONFIG_CC_STACKPROTECTOR is not set +CONFIG_CC_STACKPROTECTOR_NONE=y +# CONFIG_CC_STACKPROTECTOR_REGULAR is not set +# CONFIG_CC_STACKPROTECTOR_STRONG is not set +CONFIG_HAVE_CONTEXT_TRACKING=y +CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y +CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y +CONFIG_HAVE_MOD_ARCH_SPECIFIC=y +CONFIG_MODULES_USE_ELF_REL=y +CONFIG_ARCH_HAS_ELF_RANDOMIZE=y +CONFIG_HAVE_ARCH_MMAP_RND_BITS=y +CONFIG_HAVE_EXIT_THREAD=y +CONFIG_ARCH_MMAP_RND_BITS_MIN=8 +CONFIG_ARCH_MMAP_RND_BITS_MAX=16 +CONFIG_ARCH_MMAP_RND_BITS=8 +CONFIG_CLONE_BACKWARDS=y +CONFIG_OLD_SIGSUSPEND3=y +CONFIG_OLD_SIGACTION=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +CONFIG_MODULE_FORCE_LOAD=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +# CONFIG_MODULE_SIG is not set +# CONFIG_MODULE_COMPRESS is not set +CONFIG_MODULES_TREE_LOOKUP=y +CONFIG_BLOCK=y +CONFIG_LBDAF=y +CONFIG_BLK_DEV_BSG=y +# CONFIG_BLK_DEV_BSGLIB is not set +# CONFIG_BLK_DEV_INTEGRITY is not set +CONFIG_BLK_DEV_THROTTLING=y +# CONFIG_BLK_CMDLINE_PARSER is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_AIX_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +CONFIG_MAC_PARTITION=y +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_KARMA_PARTITION is not set +CONFIG_EFI_PARTITION=y +# CONFIG_SYSV68_PARTITION is not set +CONFIG_RK_PARTITION=y +# CONFIG_CMDLINE_PARTITION is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +CONFIG_CFQ_GROUP_IOSCHED=y +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="cfq" +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_FREEZER=y + +# +# System Type +# +CONFIG_MMU=y +CONFIG_ARCH_MULTIPLATFORM=y +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_GEMINI is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_IOP13XX is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IOP33X is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_DOVE is not set +# CONFIG_ARCH_MV78XX0 is not set +# CONFIG_ARCH_ORION5X is not set +# CONFIG_ARCH_MMP is not set +# CONFIG_ARCH_KS8695 is not set +# CONFIG_ARCH_W90X900 is not set +# CONFIG_ARCH_LPC32XX is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C24XX is not set +# CONFIG_ARCH_S3C64XX is not set +# CONFIG_ARCH_DAVINCI is not set +# CONFIG_ARCH_OMAP1 is not set + +# +# Multiple platform selection +# + +# +# CPU Core family selection +# +# CONFIG_ARCH_MULTI_V6 is not set +CONFIG_ARCH_MULTI_V7=y +CONFIG_ARCH_MULTI_V6_V7=y +# CONFIG_ARCH_MULTI_CPU_AUTO is not set +# CONFIG_ARCH_VIRT is not set +# CONFIG_ARCH_MVEBU is not set +# CONFIG_ARCH_ALPINE is not set +# CONFIG_ARCH_AT91 is not set +# CONFIG_ARCH_BCM is not set +# CONFIG_ARCH_BERLIN is not set +# CONFIG_ARCH_DIGICOLOR is not set +# CONFIG_ARCH_HIGHBANK is not set +# CONFIG_ARCH_HISI is not set +# CONFIG_ARCH_KEYSTONE is not set +# CONFIG_ARCH_MESON is not set +# CONFIG_ARCH_MXC is not set +# CONFIG_ARCH_MEDIATEK is not set + +# +# TI OMAP/AM/DM/DRA Family +# +# CONFIG_ARCH_OMAP3 is not set +# CONFIG_ARCH_OMAP4 is not set +# CONFIG_SOC_OMAP5 is not set +# CONFIG_SOC_AM33XX is not set +# CONFIG_SOC_AM43XX is not set +# CONFIG_SOC_DRA7XX is not set +# CONFIG_ARCH_QCOM is not set +CONFIG_ARCH_ROCKCHIP=y +# CONFIG_ARCH_SOCFPGA is not set +# CONFIG_PLAT_SPEAR is not set +# CONFIG_ARCH_STI is not set +# CONFIG_ARCH_S5PV210 is not set +# CONFIG_ARCH_EXYNOS is not set +# CONFIG_ARCH_SHMOBILE_MULTI is not set +# CONFIG_ARCH_SUNXI is not set +# CONFIG_ARCH_SIRF is not set +# CONFIG_ARCH_TEGRA is not set +# CONFIG_ARCH_UNIPHIER is not set +# CONFIG_ARCH_U8500 is not set +# CONFIG_ARCH_VEXPRESS is not set +# CONFIG_ARCH_WM8850 is not set +# CONFIG_ARCH_ZX is not set +# CONFIG_ARCH_ZYNQ is not set + +# +# Processor Type +# +CONFIG_CPU_V7=y +CONFIG_CPU_32v6K=y +CONFIG_CPU_32v7=y +CONFIG_CPU_ABRT_EV7=y +CONFIG_CPU_PABRT_V7=y +CONFIG_CPU_CACHE_V7=y +CONFIG_CPU_CACHE_VIPT=y +CONFIG_CPU_COPY_V6=y +CONFIG_CPU_TLB_V7=y +CONFIG_CPU_HAS_ASID=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y + +# +# Processor Features +# +# CONFIG_ARM_LPAE is not set +# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set +CONFIG_ARM_THUMB=y +# CONFIG_ARM_THUMBEE is not set +CONFIG_ARM_VIRT_EXT=y +CONFIG_SWP_EMULATE=y +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_BPREDICT_DISABLE is not set +CONFIG_CPU_SPECTRE=y +CONFIG_KUSER_HELPERS=y +CONFIG_VDSO=y +CONFIG_OUTER_CACHE=y +CONFIG_OUTER_CACHE_SYNC=y +CONFIG_MIGHT_HAVE_CACHE_L2X0=y +CONFIG_CACHE_L2X0=y +# CONFIG_PL310_ERRATA_588369 is not set +# CONFIG_PL310_ERRATA_727915 is not set +# CONFIG_PL310_ERRATA_753970 is not set +# CONFIG_PL310_ERRATA_769419 is not set +CONFIG_ARM_L1_CACHE_SHIFT_6=y +CONFIG_ARM_L1_CACHE_SHIFT=6 +CONFIG_ARM_DMA_MEM_BUFFERABLE=y +CONFIG_ARM_HEAVY_MB=y +# CONFIG_ARM_KERNMEM_PERMS is not set +CONFIG_MULTI_IRQ_HANDLER=y +# CONFIG_ARM_ERRATA_430973 is not set +CONFIG_ARM_ERRATA_643719=y +# CONFIG_ARM_ERRATA_720789 is not set +# CONFIG_ARM_ERRATA_754322 is not set +# CONFIG_ARM_ERRATA_754327 is not set +# CONFIG_ARM_ERRATA_764369 is not set +# CONFIG_ARM_ERRATA_775420 is not set +# CONFIG_ARM_ERRATA_798181 is not set +# CONFIG_ARM_ERRATA_773022 is not set + +# +# Bus support +# +# CONFIG_PCI is not set +# CONFIG_PCI_DOMAINS_GENERIC is not set +# CONFIG_PCI_SYSCALL is not set +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +CONFIG_HAVE_SMP=y +CONFIG_SMP=y +CONFIG_SMP_ON_UP=y +CONFIG_ARM_CPU_TOPOLOGY=y +# CONFIG_SCHED_MC is not set +# CONFIG_SCHED_SMT is not set +CONFIG_HAVE_ARM_SCU=y +CONFIG_HAVE_ARM_ARCH_TIMER=y +CONFIG_HAVE_ARM_TWD=y +# CONFIG_MCPM is not set +# CONFIG_BIG_LITTLE is not set +# CONFIG_VMSPLIT_3G is not set +CONFIG_VMSPLIT_3G_OPT=y +# CONFIG_VMSPLIT_2G is not set +# CONFIG_VMSPLIT_1G is not set +CONFIG_PAGE_OFFSET=0xB0000000 +CONFIG_NR_CPUS=4 +CONFIG_HOTPLUG_CPU=y +CONFIG_ARM_PSCI=y +CONFIG_ARCH_NR_GPIO=288 +# CONFIG_PREEMPT_NONE is not set +CONFIG_PREEMPT_VOLUNTARY=y +# CONFIG_PREEMPT is not set +CONFIG_HZ_FIXED=0 +# CONFIG_HZ_100 is not set +# CONFIG_HZ_200 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_300 is not set +# CONFIG_HZ_500 is not set +# CONFIG_HZ_1000 is not set +CONFIG_HZ=250 +CONFIG_SCHED_HRTICK=y +# CONFIG_THUMB2_KERNEL is not set +CONFIG_AEABI=y +# CONFIG_OABI_COMPAT is not set +# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set +# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set +CONFIG_HAVE_ARCH_PFN_VALID=y +CONFIG_HIGHMEM=y +# CONFIG_HIGHPTE is not set +CONFIG_CPU_SW_DOMAIN_PAN=y +CONFIG_HW_PERF_EVENTS=y +CONFIG_ARCH_WANT_GENERAL_HUGETLB=y +# CONFIG_ARM_MODULE_PLTS is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_HAVE_MEMBLOCK=y +CONFIG_NO_BOOTMEM=y +CONFIG_MEMORY_ISOLATION=y +# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_COMPACTION is not set +CONFIG_MIGRATION=y +# CONFIG_PHYS_ADDR_T_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_BOUNCE=y +# CONFIG_KSM is not set +CONFIG_DEFAULT_MMAP_MIN_ADDR=32768 +# CONFIG_CLEANCACHE is not set +# CONFIG_FRONTSWAP is not set +CONFIG_CMA=y +# CONFIG_CMA_DEBUG is not set +# CONFIG_CMA_DEBUGFS is not set +CONFIG_CMA_AREAS=7 +# CONFIG_ZPOOL is not set +# CONFIG_ZBUD is not set +CONFIG_ZSMALLOC=y +# CONFIG_PGTABLE_MAPPING is not set +# CONFIG_ZSMALLOC_STAT is not set +# CONFIG_IDLE_PAGE_TRACKING is not set +CONFIG_FRAME_VECTOR=y +CONFIG_FORCE_MAX_ZONEORDER=11 +CONFIG_ALIGNMENT_TRAP=y +# CONFIG_UACCESS_WITH_MEMCPY is not set +CONFIG_SECCOMP=y +CONFIG_SWIOTLB=y +CONFIG_IOMMU_HELPER=y +# CONFIG_XEN is not set +# CONFIG_ARM_FLUSH_CONSOLE_ON_RESTART is not set + +# +# Boot options +# +CONFIG_USE_OF=y +CONFIG_ATAGS=y +# CONFIG_DEPRECATED_PARAM_STRUCT is not set +# CONFIG_BUILD_ARM_APPENDED_DTB_IMAGE is not set +CONFIG_ZBOOT_ROM_TEXT=0 +CONFIG_ZBOOT_ROM_BSS=0 +# CONFIG_ARM_APPENDED_DTB is not set +CONFIG_CMDLINE="" +# CONFIG_KEXEC is not set +# CONFIG_CRASH_DUMP is not set +CONFIG_AUTO_ZRELADDR=y + +# +# CPU Power Management +# + +# +# CPU Frequency scaling +# +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_GOV_COMMON=y +CONFIG_CPU_FREQ_STAT=y +CONFIG_CPU_FREQ_STAT_DETAILS=y +CONFIG_CPU_FREQ_TIMES=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_INTERACTIVE 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_INTERACTIVE=y +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y +# CONFIG_CPU_FREQ_GOV_SCHEDUTIL is not set + +# +# CPU frequency scaling drivers +# +CONFIG_CPUFREQ_DT=y +# CONFIG_ARM_BIG_LITTLE_CPUFREQ is not set +# CONFIG_ARM_KIRKWOOD_CPUFREQ is not set +CONFIG_ARM_ROCKCHIP_CPUFREQ=y +# CONFIG_QORIQ_CPUFREQ is not set + +# +# CPU Idle +# +CONFIG_CPU_IDLE=y +CONFIG_CPU_IDLE_GOV_LADDER=y +CONFIG_CPU_IDLE_GOV_MENU=y + +# +# ARM CPU Idle Drivers +# +# CONFIG_ARM_CPUIDLE is not set +# CONFIG_ARM_HIGHBANK_CPUIDLE is not set +# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_VFP=y +CONFIG_VFPv3=y +CONFIG_NEON=y +CONFIG_KERNEL_MODE_NEON=y + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y +CONFIG_BINFMT_SCRIPT=y +# CONFIG_HAVE_AOUT is not set +# CONFIG_BINFMT_MISC is not set +CONFIG_COREDUMP=y + +# +# Power management options +# +CONFIG_SUSPEND=y +CONFIG_SUSPEND_FREEZER=y +# CONFIG_SUSPEND_SKIP_SYNC is not set +CONFIG_HAS_WAKELOCK=y +CONFIG_WAKELOCK=y +# CONFIG_HIBERNATION is not set +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=y +CONFIG_PM_ADVANCED_DEBUG=y +# CONFIG_PM_TEST_SUSPEND is not set +CONFIG_PM_SLEEP_DEBUG=y +# CONFIG_DPM_WATCHDOG is not set +# CONFIG_APM_EMULATION is not set +CONFIG_PM_OPP=y +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_ARCH_SUSPEND_POSSIBLE=y +CONFIG_ARM_CPU_SUSPEND=y +CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_NET=y +CONFIG_NET_INGRESS=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_DIAG=m +CONFIG_UNIX=y +CONFIG_UNIX_DIAG=m +CONFIG_XFRM=y +CONFIG_XFRM_ALGO=y +CONFIG_XFRM_USER=y +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_STATISTICS is not set +CONFIG_XFRM_IPCOMP=y +CONFIG_NET_KEY=y +# CONFIG_NET_KEY_MIGRATE is not set +CONFIG_INET=y +CONFIG_WIREGUARD=m +# CONFIG_WIREGUARD_DEBUG is not set +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +# CONFIG_IP_FIB_TRIE_STATS is not set +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=y +CONFIG_NET_IPGRE=m +CONFIG_NET_IPGRE_BROADCAST=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=y +CONFIG_NET_FOU=y +CONFIG_NET_FOU_IP_TUNNELS=y +CONFIG_INET_AH=y +CONFIG_INET_ESP=y +CONFIG_INET_IPCOMP=y +CONFIG_INET_XFRM_TUNNEL=y +CONFIG_INET_TUNNEL=y +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y +CONFIG_INET_LRO=y +CONFIG_INET_DIAG=m +CONFIG_INET_TCP_DIAG=m +CONFIG_INET_UDP_DIAG=m +# CONFIG_INET_DIAG_DESTROY is not set +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_SCALABLE=m +CONFIG_TCP_CONG_LP=y +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_DEFAULT_CUBIC=y +# CONFIG_DEFAULT_RENO is not set +CONFIG_DEFAULT_TCP_CONG="cubic" +CONFIG_TCP_MD5SIG=y +CONFIG_IPV6=y +# CONFIG_IPV6_ROUTER_PREF is not set +# CONFIG_IPV6_OPTIMISTIC_DAD is not set +CONFIG_INET6_AH=y +CONFIG_INET6_ESP=y +# CONFIG_INET6_IPCOMP is not set +# CONFIG_IPV6_MIP6 is not set +# CONFIG_IPV6_ILA is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set +CONFIG_INET6_XFRM_MODE_TRANSPORT=y +CONFIG_INET6_XFRM_MODE_TUNNEL=y +CONFIG_INET6_XFRM_MODE_BEET=y +# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set +# CONFIG_IPV6_VTI is not set +CONFIG_IPV6_SIT=y +# CONFIG_IPV6_SIT_6RD is not set +CONFIG_IPV6_NDISC_NODETYPE=y +# CONFIG_IPV6_TUNNEL is not set +# CONFIG_IPV6_GRE is not set +CONFIG_IPV6_MULTIPLE_TABLES=y +CONFIG_IPV6_SUBTREES=y +# CONFIG_IPV6_MROUTE is not set +CONFIG_NETLABEL=y +# CONFIG_ANDROID_PARANOID_NETWORK is not set +CONFIG_NETWORK_SECMARK=y +CONFIG_NET_PTP_CLASSIFY=y +# CONFIG_NETWORK_PHY_TIMESTAMPING is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_NETFILTER_ADVANCED=y +CONFIG_BRIDGE_NETFILTER=y + +# +# Core Netfilter Configuration +# +CONFIG_NETFILTER_INGRESS=y +CONFIG_NETFILTER_NETLINK=y +CONFIG_NETFILTER_NETLINK_ACCT=y +CONFIG_NETFILTER_NETLINK_QUEUE=y +CONFIG_NETFILTER_NETLINK_LOG=y +CONFIG_NF_CONNTRACK=y +CONFIG_NF_LOG_COMMON=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=m +CONFIG_NF_CT_PROTO_GRE=m +CONFIG_NF_CT_PROTO_SCTP=m +CONFIG_NF_CT_PROTO_UDPLITE=m +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=y +CONFIG_NF_NAT_NEEDED=y +CONFIG_NF_NAT_PROTO_DCCP=m +CONFIG_NF_NAT_PROTO_UDPLITE=m +CONFIG_NF_NAT_PROTO_SCTP=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=m +CONFIG_NETFILTER_SYNPROXY=m +CONFIG_NF_TABLES=m +CONFIG_NF_TABLES_INET=m +CONFIG_NF_TABLES_NETDEV=m +CONFIG_NFT_EXTHDR=m +CONFIG_NFT_META=m +CONFIG_NFT_CT=m +CONFIG_NFT_RBTREE=m +CONFIG_NFT_HASH=m +CONFIG_NFT_COUNTER=m +CONFIG_NFT_LOG=m +CONFIG_NFT_LIMIT=m +CONFIG_NFT_MASQ=m +CONFIG_NFT_REDIR=m +CONFIG_NFT_NAT=m +CONFIG_NFT_QUEUE=m +CONFIG_NFT_REJECT=m +CONFIG_NFT_REJECT_INET=m +CONFIG_NFT_COMPAT=m +CONFIG_NETFILTER_XTABLES=y + +# +# Xtables combined modules +# +CONFIG_NETFILTER_XT_MARK=y +CONFIG_NETFILTER_XT_CONNMARK=m +CONFIG_NETFILTER_XT_SET=m + +# +# Xtables targets +# +CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y +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=y +CONFIG_NETFILTER_XT_TARGET_NETMAP=m +CONFIG_NETFILTER_XT_TARGET_NFLOG=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +# CONFIG_NETFILTER_XT_TARGET_NOTRACK is not set +CONFIG_NETFILTER_XT_TARGET_RATEEST=m +CONFIG_NETFILTER_XT_TARGET_REDIRECT=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_QUOTA2=m +CONFIG_NETFILTER_XT_MATCH_QUOTA2_LOG=y +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 +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_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_SED=m +CONFIG_IP_VS_NQ=m + +# +# IPVS SH scheduler +# +CONFIG_IP_VS_SH_TAB_BITS=8 + +# +# 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_CONNTRACK_IPV4=m +CONFIG_NF_TABLES_IPV4=m +CONFIG_NFT_CHAIN_ROUTE_IPV4=m +CONFIG_NFT_REJECT_IPV4=m +CONFIG_NFT_DUP_IPV4=m +CONFIG_NF_TABLES_ARP=m +CONFIG_NF_DUP_IPV4=m +CONFIG_NF_LOG_ARP=m +CONFIG_NF_LOG_IPV4=m +CONFIG_NF_REJECT_IPV4=m +CONFIG_NF_NAT_IPV4=m +CONFIG_NFT_CHAIN_NAT_IPV4=m +CONFIG_NF_NAT_MASQUERADE_IPV4=m +CONFIG_NFT_MASQ_IPV4=m +CONFIG_NFT_REDIR_IPV4=m +CONFIG_NF_NAT_SNMP_BASIC=m +CONFIG_NF_NAT_PROTO_GRE=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 + +# +# IPv6: Netfilter Configuration +# +CONFIG_NF_DEFRAG_IPV6=y +CONFIG_NF_CONNTRACK_IPV6=y +CONFIG_NF_TABLES_IPV6=m +CONFIG_NFT_CHAIN_ROUTE_IPV6=m +CONFIG_NFT_REJECT_IPV6=m +CONFIG_NFT_DUP_IPV6=m +CONFIG_NF_DUP_IPV6=m +CONFIG_NF_REJECT_IPV6=y +CONFIG_NF_LOG_IPV6=m +CONFIG_NF_NAT_IPV6=y +CONFIG_NFT_CHAIN_NAT_IPV6=m +CONFIG_NF_NAT_MASQUERADE_IPV6=m +CONFIG_NFT_MASQ_IPV6=m +CONFIG_NFT_REDIR_IPV6=m +CONFIG_IP6_NF_IPTABLES=y +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=y +CONFIG_IP6_NF_MATCH_MH=m +CONFIG_IP6_NF_MATCH_RPFILTER=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_TARGET_HL=m +CONFIG_IP6_NF_FILTER=y +CONFIG_IP6_NF_TARGET_REJECT=y +CONFIG_IP6_NF_TARGET_SYNPROXY=m +CONFIG_IP6_NF_MANGLE=y +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 +CONFIG_NF_TABLES_BRIDGE=m +CONFIG_NFT_BRIDGE_META=m +CONFIG_NFT_BRIDGE_REJECT=m +CONFIG_NF_LOG_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_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_RDS is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_L2TP is not set +CONFIG_STP=y +CONFIG_BRIDGE=y +CONFIG_BRIDGE_IGMP_SNOOPING=y +# CONFIG_BRIDGE_VLAN_FILTERING is not set +CONFIG_HAVE_NET_DSA=y +CONFIG_NET_DSA=m +CONFIG_NET_DSA_HWMON=y +CONFIG_NET_DSA_TAG_BRCM=y +CONFIG_NET_DSA_TAG_DSA=y +CONFIG_NET_DSA_TAG_EDSA=y +CONFIG_NET_DSA_TAG_TRAILER=y +CONFIG_VLAN_8021Q=y +# CONFIG_VLAN_8021Q_GVRP is not set +# CONFIG_VLAN_8021Q_MVRP is not set +# CONFIG_DECNET is not set +CONFIG_LLC=y +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_PHONET is not set +# CONFIG_6LOWPAN is not set +# CONFIG_IEEE802154 is not set +CONFIG_NET_SCHED=y + +# +# Queueing/Scheduling +# +CONFIG_NET_SCH_CBQ=m +CONFIG_NET_SCH_HTB=y +CONFIG_NET_SCH_HFSC=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_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_CHOKE=m +CONFIG_NET_SCH_QFQ=m +CONFIG_NET_SCH_CODEL=m +CONFIG_NET_SCH_FQ_CODEL=m +CONFIG_NET_SCH_FQ=m +CONFIG_NET_SCH_HHF=m +CONFIG_NET_SCH_PIE=m +# CONFIG_NET_SCH_INGRESS is not set +CONFIG_NET_SCH_PLUG=m + +# +# 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=y +# CONFIG_CLS_U32_PERF is not set +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_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 is not set +CONFIG_NET_EMATCH_IPSET=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_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_VLAN=m +CONFIG_NET_ACT_BPF=m +CONFIG_NET_ACT_CONNMARK=m +CONFIG_NET_CLS_IND=y +CONFIG_NET_SCH_FIFO=y +# CONFIG_DCB is not set +CONFIG_DNS_RESOLVER=y +# CONFIG_BATMAN_ADV is not set +# CONFIG_OPENVSWITCH is not set +CONFIG_VSOCKETS=m +CONFIG_NETLINK_DIAG=m +# CONFIG_MPLS is not set +# CONFIG_HSR is not set +CONFIG_NET_SWITCHDEV=y +# CONFIG_NET_L3_MASTER_DEV is not set +CONFIG_RPS=y +CONFIG_RFS_ACCEL=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_JIT is not set +CONFIG_NET_FLOW_LIMIT=y + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NET_DROP_MONITOR is not set +# CONFIG_HAMRADIO is not set +CONFIG_CAN=y +CONFIG_CAN_RAW=y +CONFIG_CAN_BCM=y +CONFIG_CAN_GW=y + +# +# CAN Device Drivers +# +# CONFIG_CAN_VCAN is not set +# CONFIG_CAN_SLCAN is not set +CONFIG_CAN_DEV=y +CONFIG_CAN_CALC_BITTIMING=y +# CONFIG_CAN_LEDS is not set +# CONFIG_CAN_TI_HECC is not set +# CONFIG_CAN_FLEXCAN is not set +# CONFIG_CAN_GRCAN is not set +# CONFIG_CAN_RCAR is not set +# CONFIG_CAN_SJA1000 is not set +# CONFIG_CAN_C_CAN is not set +# CONFIG_CAN_M_CAN is not set +# CONFIG_CAN_CC770 is not set + +# +# CAN SPI interfaces +# +CONFIG_CAN_MCP251X=y + +# +# CAN USB interfaces +# +# CONFIG_CAN_EMS_USB is not set +# CONFIG_CAN_ESD_USB2 is not set +# CONFIG_CAN_GS_USB is not set +# CONFIG_CAN_KVASER_USB is not set +# CONFIG_CAN_PEAK_USB is not set +# CONFIG_CAN_8DEV_USB is not set +# CONFIG_CAN_SOFTING is not set +# CONFIG_CAN_DEBUG_DEVICES is not set +# CONFIG_IRDA is not set +CONFIG_BT=y +CONFIG_BT_BREDR=y +CONFIG_BT_RFCOMM=y +CONFIG_BT_RFCOMM_TTY=y +# CONFIG_BT_BNEP is not set +CONFIG_BT_HIDP=y +CONFIG_BT_HS=y +CONFIG_BT_LE=y +# CONFIG_BT_SELFTEST is not set +CONFIG_BT_DEBUGFS=y + +# +# Bluetooth device drivers +# +CONFIG_BT_INTEL=y +CONFIG_BT_BCM=y +CONFIG_BT_RTL=y +CONFIG_BT_RTKBTUSB=m +CONFIG_BT_HCIBTUSB=y +CONFIG_BT_HCIBTUSB_BCM=y +CONFIG_BT_HCIBTUSB_RTL=y +CONFIG_BT_HCIBTSDIO=y +CONFIG_BT_HCIUART=y +CONFIG_BT_HCIUART_H4=y +# CONFIG_BT_HCIUART_BCSP is not set +CONFIG_BT_HCIUART_ATH3K=y +CONFIG_BT_HCIUART_LL=y +CONFIG_BT_HCIUART_3WIRE=y +# CONFIG_BT_HCIUART_INTEL is not set +CONFIG_BT_HCIUART_BCM=y +# CONFIG_BT_HCIUART_QCA is not set +CONFIG_BT_HCIBCM203X=m +CONFIG_BT_HCIBPA10X=m +CONFIG_BT_HCIBFUSB=y +CONFIG_BT_HCIVHCI=y +CONFIG_BT_MRVL=y +CONFIG_BT_MRVL_SDIO=y +CONFIG_BT_ATH3K=m +# CONFIG_AF_RXRPC 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=y +CONFIG_NL80211_TESTMODE=y +# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set +# CONFIG_CFG80211_REG_DEBUG is not set +# CONFIG_CFG80211_CERTIFICATION_ONUS is not set +CONFIG_CFG80211_DEFAULT_PS=y +CONFIG_CFG80211_DEBUGFS=y +# CONFIG_CFG80211_INTERNAL_REGDB is not set +CONFIG_CFG80211_CRDA_SUPPORT=y +CONFIG_CFG80211_WEXT=y +CONFIG_LIB80211=y +CONFIG_LIB80211_CRYPT_WEP=y +CONFIG_LIB80211_CRYPT_CCMP=y +CONFIG_LIB80211_CRYPT_TKIP=y +# CONFIG_LIB80211_DEBUG is not set +CONFIG_MAC80211=y +CONFIG_MAC80211_HAS_RC=y +CONFIG_MAC80211_RC_MINSTREL=y +CONFIG_MAC80211_RC_MINSTREL_HT=y +# CONFIG_MAC80211_RC_MINSTREL_VHT is not set +CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y +CONFIG_MAC80211_RC_DEFAULT="minstrel_ht" +CONFIG_MAC80211_MESH=y +CONFIG_MAC80211_LEDS=y +CONFIG_MAC80211_DEBUGFS=y +# CONFIG_MAC80211_MESSAGE_TRACING is not set +CONFIG_MAC80211_DEBUG_MENU=y +# CONFIG_MAC80211_NOINLINE is not set +CONFIG_MAC80211_VERBOSE_DEBUG=y +# CONFIG_MAC80211_MLME_DEBUG is not set +# CONFIG_MAC80211_STA_DEBUG is not set +# CONFIG_MAC80211_HT_DEBUG is not set +# CONFIG_MAC80211_OCB_DEBUG is not set +# CONFIG_MAC80211_IBSS_DEBUG is not set +# CONFIG_MAC80211_PS_DEBUG is not set +# CONFIG_MAC80211_MPL_DEBUG is not set +# CONFIG_MAC80211_MPATH_DEBUG is not set +# CONFIG_MAC80211_MHWMP_DEBUG is not set +# CONFIG_MAC80211_MESH_SYNC_DEBUG is not set +# CONFIG_MAC80211_MESH_CSA_DEBUG is not set +# CONFIG_MAC80211_MESH_PS_DEBUG is not set +# CONFIG_MAC80211_TDLS_DEBUG is not set +# CONFIG_MAC80211_DEBUG_COUNTERS is not set +CONFIG_MAC80211_STA_HASH_MAX_SIZE=0 +# CONFIG_WIMAX is not set +CONFIG_RFKILL=y +CONFIG_RFKILL_PM=y +CONFIG_RFKILL_LEDS=y +# CONFIG_RFKILL_INPUT is not set +# CONFIG_RFKILL_REGULATOR is not set +# CONFIG_RFKILL_GPIO is not set +# CONFIG_NET_9P 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 is not set +# CONFIG_NFC is not set +# CONFIG_LWTUNNEL is not set +CONFIG_DST_CACHE=y +CONFIG_HAVE_BPF_JIT=y + +# +# Device Drivers +# +CONFIG_ARM_AMBA=y +# CONFIG_TEGRA_AHB 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 +CONFIG_FW_LOADER=y +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_EXTRA_FIRMWARE="" +# CONFIG_FW_LOADER_USER_HELPER_FALLBACK is not set +CONFIG_WANT_DEV_COREDUMP=y +CONFIG_ALLOW_DEV_COREDUMP=y +CONFIG_DEV_COREDUMP=y +# CONFIG_DEBUG_DRIVER is not set +CONFIG_DEBUG_DEVRES=y +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_GENERIC_CPU_DEVICES is not set +CONFIG_REGMAP=y +CONFIG_REGMAP_I2C=y +CONFIG_REGMAP_SPI=y +CONFIG_REGMAP_MMIO=y +CONFIG_REGMAP_IRQ=y +CONFIG_DMA_SHARED_BUFFER=y +# CONFIG_FENCE_TRACE is not set +CONFIG_DMA_CMA=y + +# +# Default contiguous memory area size: +# +CONFIG_CMA_SIZE_MBYTES=16 +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 + +# +# Bus devices +# +# CONFIG_ARM_CCI400_PMU is not set +# CONFIG_ARM_CCI500_PMU is not set +# CONFIG_ARM_CCN is not set +# CONFIG_BRCMSTB_GISB_ARB is not set +# CONFIG_VEXPRESS_CONFIG is not set +CONFIG_CONNECTOR=y +CONFIG_PROC_EVENTS=y +# CONFIG_MTD is not set +CONFIG_DTC=y +CONFIG_OF=y +# CONFIG_OF_UNITTEST is not set +CONFIG_OF_FLATTREE=y +CONFIG_OF_EARLY_FLATTREE=y +CONFIG_OF_DYNAMIC=y +CONFIG_OF_ADDRESS=y +CONFIG_OF_IRQ=y +CONFIG_OF_NET=y +CONFIG_OF_MDIO=y +CONFIG_OF_RESERVED_MEM=y +CONFIG_OF_RESOLVE=y +CONFIG_OF_OVERLAY=y +# CONFIG_OF_CONFIGFS is not set +CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_NULL_BLK is not set +CONFIG_ZRAM=m +# CONFIG_ZRAM_WRITEBACK is not set +# CONFIG_ZRAM_MEMORY_TRACKING is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_LOOP_MIN_COUNT=8 +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_DRBD is not set +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=1 +CONFIG_BLK_DEV_RAM_SIZE=4096 +# CONFIG_CDROM_PKTCDVD is not set +CONFIG_ATA_OVER_ETH=m +# CONFIG_MG_DISK is not set +# CONFIG_BLK_DEV_RBD is not set + +# +# Misc devices +# +# CONFIG_ROCKCHIP_SCR is not set +# CONFIG_SENSORS_LIS3LV02D is not set +# CONFIG_AD525X_DPOT is not set +# CONFIG_DUMMY_IRQ is not set +# CONFIG_ICS932S401 is not set +# CONFIG_ENCLOSURE_SERVICES 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_BH1780 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_TI_DAC7512 is not set +# CONFIG_BMP085_I2C is not set +# CONFIG_BMP085_SPI is not set +# CONFIG_USB_SWITCH_FSA9480 is not set +# CONFIG_LATTICE_ECP3_CONFIG is not set +# CONFIG_SRAM is not set +# CONFIG_UID_SYS_STATS is not set +# CONFIG_MEMORY_STATE_TIME is not set +# CONFIG_USB_CAM_GPIO is not set +# CONFIG_GPIO_DET is not set +# CONFIG_C2PORT is not set + +# +# EEPROM support +# +CONFIG_EEPROM_AT24=y +# CONFIG_EEPROM_AT25 is not set +# CONFIG_EEPROM_LEGACY is not set +# CONFIG_EEPROM_MAX6875 is not set +CONFIG_EEPROM_93CX6=y +# CONFIG_EEPROM_93XX46 is not set + +# +# Texas Instruments shared transport line discipline +# +# CONFIG_TI_ST is not set +# CONFIG_SENSORS_LIS3_SPI is not set +# CONFIG_SENSORS_LIS3_I2C is not set + +# +# Altera FPGA firmware download module +# +# CONFIG_ALTERA_STAPL is not set + +# +# Intel MIC Bus Driver +# + +# +# SCIF Bus Driver +# + +# +# Intel MIC Host Driver +# + +# +# Intel MIC Card Driver +# + +# +# SCIF Driver +# + +# +# Intel MIC Coprocessor State Management (COSM) Drivers +# +# CONFIG_ECHO is not set +# CONFIG_CXL_BASE is not set +# CONFIG_CXL_KERNEL_API is not set +# CONFIG_CXL_EEH is not set + +# +# SCSI device support +# +CONFIG_SCSI_MOD=y +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_NETLINK is not set +# CONFIG_SCSI_MQ_DEFAULT is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +CONFIG_BLK_DEV_SR=y +# CONFIG_BLK_DEV_SR_VENDOR is not set +# CONFIG_CHR_DEV_SG is not set +# 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=y +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +# CONFIG_SCSI_SRP_ATTRS is not set +CONFIG_SCSI_LOWLEVEL=y +# CONFIG_ISCSI_TCP is not set +# CONFIG_ISCSI_BOOT_SYSFS is not set +# CONFIG_SCSI_UFSHCD is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_DH is not set +# CONFIG_SCSI_OSD_INITIATOR is not set +# CONFIG_ATA is not set +CONFIG_MD=y +# CONFIG_BLK_DEV_MD is not set +# CONFIG_BCACHE is not set +CONFIG_BLK_DEV_DM_BUILTIN=y +CONFIG_BLK_DEV_DM=y +# CONFIG_DM_MQ_DEFAULT is not set +# CONFIG_DM_DEBUG is not set +CONFIG_DM_BUFIO=y +CONFIG_DM_BIO_PRISON=y +CONFIG_DM_PERSISTENT_DATA=y +# CONFIG_DM_DEBUG_BLOCK_STACK_TRACING is not set +CONFIG_DM_CRYPT=y +# CONFIG_DM_SNAPSHOT is not set +CONFIG_DM_THIN_PROVISIONING=y +# CONFIG_DM_CACHE is not set +# CONFIG_DM_ERA is not set +# CONFIG_DM_MIRROR is not set +# CONFIG_DM_RAID is not set +# CONFIG_DM_ZERO is not set +# CONFIG_DM_MULTIPATH is not set +# CONFIG_DM_DELAY is not set +# CONFIG_DM_UEVENT is not set +# CONFIG_DM_FLAKEY is not set +CONFIG_DM_VERITY=y +# CONFIG_DM_VERITY_FEC is not set +# CONFIG_DM_SWITCH is not set +# CONFIG_DM_LOG_WRITES is not set +# CONFIG_DM_VERITY_AVB is not set +# CONFIG_DM_ANDROID_VERITY_AT_MOST_ONCE_DEFAULT_ENABLED is not set +# CONFIG_TARGET_CORE is not set +CONFIG_NETDEVICES=y +CONFIG_MII=y +CONFIG_NET_CORE=y +CONFIG_BONDING=m +CONFIG_DUMMY=y +# CONFIG_EQUALIZER is not set +# CONFIG_IFB is not set +# CONFIG_NET_TEAM is not set +CONFIG_MACVLAN=y +CONFIG_MACVTAP=m +CONFIG_IPVLAN=y +CONFIG_VXLAN=y +CONFIG_GENEVE=m +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +CONFIG_TUN=y +# CONFIG_TUN_VNET_CROSS_LE is not set +CONFIG_VETH=y +# CONFIG_NLMON is not set + +# +# CAIF transport drivers +# + +# +# Distributed Switch Architecture drivers +# +CONFIG_NET_DSA_MV88E6XXX=m +CONFIG_NET_DSA_MV88E6060=m +CONFIG_NET_DSA_MV88E6XXX_NEED_PPU=y +CONFIG_NET_DSA_MV88E6131=m +CONFIG_NET_DSA_MV88E6123_61_65=m +CONFIG_NET_DSA_MV88E6171=m +CONFIG_NET_DSA_MV88E6352=m +CONFIG_NET_DSA_BCM_SF2=m +CONFIG_ETHERNET=y +# CONFIG_ALTERA_TSE is not set +CONFIG_NET_VENDOR_ARC=y +CONFIG_ARC_EMAC_CORE=y +# CONFIG_ARC_EMAC is not set +CONFIG_EMAC_ROCKCHIP=y +# CONFIG_NET_VENDOR_AURORA is not set +CONFIG_NET_CADENCE=y +# CONFIG_MACB is not set +CONFIG_NET_VENDOR_BROADCOM=y +# CONFIG_B44 is not set +# CONFIG_BCMGENET is not set +# CONFIG_SYSTEMPORT is not set +CONFIG_NET_VENDOR_CIRRUS=y +# CONFIG_CS89x0 is not set +# CONFIG_DM9000 is not set +# CONFIG_DNET is not set +CONFIG_NET_VENDOR_EZCHIP=y +# CONFIG_EZCHIP_NPS_MANAGEMENT_ENET is not set +CONFIG_NET_VENDOR_FARADAY=y +# CONFIG_FTMAC100 is not set +# CONFIG_FTGMAC100 is not set +CONFIG_NET_VENDOR_HISILICON=y +# CONFIG_HIX5HD2_GMAC is not set +# CONFIG_HIP04_ETH is not set +# CONFIG_HNS is not set +# CONFIG_HNS_DSAF is not set +# CONFIG_HNS_ENET is not set +CONFIG_NET_VENDOR_INTEL=y +CONFIG_NET_VENDOR_I825XX=y +CONFIG_NET_VENDOR_MARVELL=y +# CONFIG_MVMDIO 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_NET_VENDOR_MICROCHIP=y +# CONFIG_ENC28J60 is not set +# CONFIG_ENCX24J600 is not set +CONFIG_NET_VENDOR_NATSEMI=y +CONFIG_NET_VENDOR_8390=y +# CONFIG_AX88796 is not set +# CONFIG_ETHOC is not set +CONFIG_NET_VENDOR_QUALCOMM=y +# CONFIG_QCA7000 is not set +CONFIG_NET_VENDOR_RENESAS=y +CONFIG_NET_VENDOR_ROCKER=y +CONFIG_NET_VENDOR_SAMSUNG=y +# CONFIG_SXGBE_ETH is not set +CONFIG_NET_VENDOR_SEEQ=y +CONFIG_NET_VENDOR_SMSC=y +# CONFIG_SMC91X is not set +# CONFIG_SMC911X is not set +# CONFIG_SMSC911X is not set +CONFIG_NET_VENDOR_STMICRO=y +CONFIG_STMMAC_ETH=y +CONFIG_STMMAC_PLATFORM=y +CONFIG_DWMAC_GENERIC=y +# CONFIG_DWMAC_IPQ806X is not set +# CONFIG_DWMAC_LPC18XX is not set +# CONFIG_DWMAC_MESON is not set +CONFIG_DWMAC_ROCKCHIP=y +# CONFIG_DWMAC_SOCFPGA is not set +# CONFIG_DWMAC_STI is not set +# CONFIG_DWMAC_SUNXI is not set +CONFIG_NET_VENDOR_SYNOPSYS=y +# CONFIG_SYNOPSYS_DWC_ETH_QOS 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_PHYLIB=y + +# +# MII PHY device drivers +# +# CONFIG_AQUANTIA_PHY is not set +# CONFIG_AT803X_PHY is not set +# CONFIG_AMD_PHY is not set +# CONFIG_MARVELL_PHY is not set +# CONFIG_DAVICOM_PHY is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_LXT_PHY is not set +# CONFIG_CICADA_PHY is not set +# CONFIG_VITESSE_PHY is not set +# CONFIG_TERANETICS_PHY is not set +CONFIG_ROCKCHIP_PHY=y +# CONFIG_SMSC_PHY is not set +CONFIG_BCM_NET_PHYLIB=m +# CONFIG_BROADCOM_PHY is not set +CONFIG_BCM7XXX_PHY=m +# CONFIG_BCM87XX_PHY is not set +# CONFIG_ICPLUS_PHY is not set +# CONFIG_REALTEK_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set +# CONFIG_MICREL_PHY is not set +# CONFIG_DP83848_PHY is not set +# CONFIG_DP83867_PHY is not set +CONFIG_MICROCHIP_PHY=m +CONFIG_FIXED_PHY=y +# CONFIG_MDIO_BITBANG is not set +# CONFIG_MDIO_BUS_MUX_GPIO is not set +# CONFIG_MDIO_BUS_MUX_MMIOREG is not set +CONFIG_MDIO_BCM_UNIMAC=m +# CONFIG_MICREL_KS8995MA is not set +CONFIG_PPP=y +# CONFIG_PPP_BSDCOMP is not set +# CONFIG_PPP_DEFLATE is not set +# CONFIG_PPP_FILTER is not set +# CONFIG_PPP_MPPE is not set +# CONFIG_PPP_MULTILINK is not set +# CONFIG_PPPOE is not set +# CONFIG_PPTP is not set +# CONFIG_PPPOLAC is not set +# CONFIG_PPPOPNS is not set +CONFIG_PPP_ASYNC=y +# CONFIG_PPP_SYNC_TTY is not set +# CONFIG_SLIP is not set +CONFIG_SLHC=y +CONFIG_USB_NET_DRIVERS=y +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +CONFIG_USB_PEGASUS=y +CONFIG_USB_RTL8150=y +CONFIG_USB_RTL8152=y +CONFIG_USB_LAN78XX=m +CONFIG_USB_USBNET=y +CONFIG_USB_NET_AX8817X=y +CONFIG_USB_NET_AX88179_178A=y +CONFIG_USB_NET_CDCETHER=y +# CONFIG_USB_NET_CDC_EEM is not set +CONFIG_USB_NET_CDC_NCM=y +# CONFIG_USB_NET_HUAWEI_CDC_NCM is not set +CONFIG_USB_NET_CDC_MBIM=y +CONFIG_USB_NET_DM9601=y +# CONFIG_USB_NET_SR9700 is not set +# CONFIG_USB_NET_SR9800 is not set +CONFIG_USB_NET_SMSC75XX=y +CONFIG_USB_NET_SMSC95XX=y +# CONFIG_USB_NET_GL620A is not set +CONFIG_USB_NET_NET1080=y +# CONFIG_USB_NET_PLUSB is not set +CONFIG_USB_NET_MCS7830=y +CONFIG_USB_NET_RNDIS_HOST=y +# CONFIG_USB_NET_CDC_SUBSET is not set +# CONFIG_USB_NET_ZAURUS is not set +# CONFIG_USB_NET_CX82310_ETH is not set +# CONFIG_USB_NET_KALMIA is not set +# CONFIG_USB_NET_QMI_WWAN is not set +# CONFIG_USB_HSO is not set +# CONFIG_USB_NET_INT51X1 is not set +# CONFIG_USB_IPHETH is not set +# CONFIG_USB_SIERRA_NET is not set +# CONFIG_USB_VL600 is not set +# CONFIG_USB_NET_CH9200 is not set +CONFIG_WLAN=y +CONFIG_LIBERTAS_THINFIRM=y +# CONFIG_LIBERTAS_THINFIRM_DEBUG is not set +# CONFIG_LIBERTAS_THINFIRM_USB is not set +CONFIG_AT76C50X_USB=y +CONFIG_USB_ZD1201=y +CONFIG_USB_NET_RNDIS_WLAN=y +CONFIG_RTL8187=y +CONFIG_RTL8187_LEDS=y +# CONFIG_MAC80211_HWSIM is not set +# CONFIG_VIRT_WIFI is not set +CONFIG_ATH_COMMON=m +CONFIG_ATH_CARDS=y +# CONFIG_ATH_DEBUG is not set +CONFIG_ATH9K_HW=m +CONFIG_ATH9K_COMMON=m +CONFIG_ATH9K_BTCOEX_SUPPORT=y +CONFIG_ATH9K=m +# CONFIG_ATH9K_AHB is not set +# CONFIG_ATH9K_DEBUGFS is not set +# CONFIG_ATH9K_DYNACK is not set +# CONFIG_ATH9K_WOW is not set +CONFIG_ATH9K_RFKILL=y +# CONFIG_ATH9K_CHANNEL_CONTEXT is not set +CONFIG_ATH9K_PCOEM=y +CONFIG_ATH9K_HTC=m +# CONFIG_ATH9K_HTC_DEBUGFS is not set +CONFIG_CARL9170=m +CONFIG_CARL9170_LEDS=y +# CONFIG_CARL9170_DEBUGFS is not set +CONFIG_CARL9170_WPC=y +CONFIG_CARL9170_HWRNG=y +CONFIG_ATH6KL=m +# CONFIG_ATH6KL_SDIO is not set +CONFIG_ATH6KL_USB=m +# CONFIG_ATH6KL_DEBUG is not set +# CONFIG_ATH6KL_TRACING is not set +CONFIG_AR5523=m +CONFIG_ATH10K=m +# CONFIG_ATH10K_DEBUG is not set +# CONFIG_ATH10K_DEBUGFS is not set +# CONFIG_ATH10K_TRACING is not set +CONFIG_WCN36XX=m +# CONFIG_WCN36XX_DEBUGFS is not set +# CONFIG_B43 is not set +# CONFIG_B43LEGACY is not set +CONFIG_BRCMUTIL=m +# CONFIG_BRCMSMAC is not set +CONFIG_BRCMFMAC=m +CONFIG_BRCMFMAC_PROTO_BCDC=y +CONFIG_BRCMFMAC_SDIO=y +# CONFIG_BRCMFMAC_USB is not set +# CONFIG_BRCM_TRACING is not set +# CONFIG_BRCMDBG is not set +CONFIG_HOSTAP=y +CONFIG_HOSTAP_FIRMWARE=y +CONFIG_HOSTAP_FIRMWARE_NVRAM=y +# CONFIG_LIBERTAS is not set +# CONFIG_P54_COMMON is not set +CONFIG_RT2X00=y +CONFIG_RT2500USB=m +CONFIG_RT73USB=m +CONFIG_RT2800USB=y +CONFIG_RT2800USB_RT33XX=y +CONFIG_RT2800USB_RT35XX=y +CONFIG_RT2800USB_RT3573=y +CONFIG_RT2800USB_RT53XX=y +CONFIG_RT2800USB_RT55XX=y +CONFIG_RT2800USB_UNKNOWN=y +CONFIG_RT2800_LIB=y +CONFIG_RT2X00_LIB_USB=y +CONFIG_RT2X00_LIB=y +CONFIG_RT2X00_LIB_FIRMWARE=y +CONFIG_RT2X00_LIB_CRYPTO=y +CONFIG_RT2X00_LIB_LEDS=y +# CONFIG_RT2X00_LIB_DEBUGFS is not set +# CONFIG_RT2X00_DEBUG is not set +CONFIG_WL_MEDIATEK=y +CONFIG_MT7601U=m +CONFIG_RTL_CARDS=m +CONFIG_RTL8192CU=m +CONFIG_RTLWIFI=m +CONFIG_RTLWIFI_USB=m +CONFIG_RTLWIFI_DEBUG=y +CONFIG_RTL8192C_COMMON=m +CONFIG_RTL8XXXU=m +CONFIG_RTL8XXXU_UNTESTED=y +CONFIG_WL_ROCKCHIP=y +CONFIG_WIFI_BUILD_MODULE=y +# CONFIG_WIFI_LOAD_DRIVER_WHEN_KERNEL_BOOTUP is not set +# CONFIG_WIFI_GENERATE_RANDOM_MAC_ADDR is not set +# CONFIG_AP6XXX is not set +CONFIG_CYW_BCMDHD=m +CONFIG_RTL_WIRELESS_SOLUTION=y +CONFIG_RTL8188EU=m +# CONFIG_RTL8188FU is not set +CONFIG_RTL8189ES=m +# CONFIG_RTL8189FS is not set +# CONFIG_RTL8723BS is not set +# CONFIG_RTL8723BU is not set +CONFIG_RTL8723CS=m +# CONFIG_RTL8723DS is not set +CONFIG_MVL88W8977=m + +# +# SouthSV 6XXX WLAN support +# +CONFIG_SSV6051=m +# CONFIG_WL_TI is not set +CONFIG_RTL8822BU=m +# CONFIG_RTL8821CU is not set +CONFIG_88XXAU=m +CONFIG_ZD1211RW=m +# CONFIG_ZD1211RW_DEBUG is not set +CONFIG_MWIFIEX=y +CONFIG_MWIFIEX_SDIO=y +# CONFIG_MWIFIEX_USB is not set +# CONFIG_CW1200 is not set +# CONFIG_RSI_91X is not set + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# +# CONFIG_WAN is not set +# CONFIG_LTE is not set +# CONFIG_ISDN is not set +# CONFIG_NVM is not set + +# +# Input device support +# +CONFIG_INPUT=y +CONFIG_INPUT_LEDS=y +CONFIG_INPUT_FF_MEMLESS=y +CONFIG_INPUT_POLLDEV=y +# CONFIG_INPUT_SPARSEKMAP is not set +CONFIG_INPUT_MATRIXKMAP=y + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +CONFIG_INPUT_JOYDEV=y +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set +# CONFIG_INPUT_KEYRESET is not set +# CONFIG_INPUT_KEYCOMBO is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +# CONFIG_KEYBOARD_ADC is not set +# CONFIG_KEYBOARD_ADP5588 is not set +# CONFIG_KEYBOARD_ADP5589 is not set +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_QT1070 is not set +# CONFIG_KEYBOARD_QT2160 is not set +# CONFIG_KEYBOARD_LKKBD is not set +CONFIG_KEYBOARD_GPIO=y +CONFIG_KEYBOARD_GPIO_POLLED=y +# 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_OMAP4 is not set +# CONFIG_KEYBOARD_ROCKCHIP 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_INPUT_MOUSE=y +# CONFIG_MOUSE_PS2 is not set +# CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_APPLETOUCH is not set +# CONFIG_MOUSE_BCM5974 is not set +CONFIG_MOUSE_CYAPA=y +CONFIG_MOUSE_ELAN_I2C=y +CONFIG_MOUSE_ELAN_I2C_I2C=y +# CONFIG_MOUSE_ELAN_I2C_SMBUS 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_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=y +CONFIG_JOYSTICK_IFORCE_USB=y +# 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=y +CONFIG_JOYSTICK_XPAD_FF=y +CONFIG_JOYSTICK_XPAD_LEDS=y +CONFIG_INPUT_TABLET=y +# CONFIG_TABLET_USB_ACECAD is not set +# CONFIG_TABLET_USB_AIPTEK is not set +# CONFIG_TABLET_USB_GTCO is not set +# CONFIG_TABLET_USB_HANWANG is not set +# CONFIG_TABLET_USB_KBTAB is not set +# CONFIG_TABLET_SERIAL_WACOM4 is not set +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_PROPERTIES=y +CONFIG_TOUCHSCREEN_ADS7846=m +# CONFIG_TOUCHSCREEN_AD7877 is not set +# CONFIG_TOUCHSCREEN_AD7879 is not set +# CONFIG_TOUCHSCREEN_AR1021_I2C is not set +CONFIG_TOUCHSCREEN_ATMEL_MXT=y +# CONFIG_TOUCHSCREEN_AUO_PIXCIR is not set +# CONFIG_TOUCHSCREEN_BU21013 is not set +# CONFIG_TOUCHSCREEN_CHIPONE_ICN8318 is not set +# CONFIG_TOUCHSCREEN_CY8C40XX is not set +# CONFIG_TOUCHSCREEN_CY8CTMG110 is not set +# CONFIG_TOUCHSCREEN_CYTTSP_CORE is not set +# CONFIG_TOUCHSCREEN_CYTTSP4_CORE is not set +# CONFIG_TOUCHSCREEN_DYNAPRO is not set +# CONFIG_TOUCHSCREEN_HAMPSHIRE is not set +# CONFIG_TOUCHSCREEN_EETI is not set +# CONFIG_TOUCHSCREEN_EGALAX is not set +# CONFIG_TOUCHSCREEN_FT6236 is not set +# CONFIG_TOUCHSCREEN_FUJITSU is not set +# CONFIG_TOUCHSCREEN_GOODIX is not set +# CONFIG_TOUCHSCREEN_GSLX6801 is not set +# CONFIG_TOUCHSCREEN_GSLX680A is not set +# CONFIG_TOUCHSCREEN_GSLX680_D708 is not set +# CONFIG_TOUCHSCREEN_GSLX680_PAD is not set +# CONFIG_TOUCHSCREEN_GSLX680_VR is not set +# CONFIG_TOUCHSCREEN_GSLX680_FIREFLY is not set +# CONFIG_TOUCHSCREEN_GSL3673 is not set +# CONFIG_TOUCHSCREEN_GSL3673_800X1280 is not set +# CONFIG_TOUCHSCREEN_GT9XX is not set +# CONFIG_TOUCHSCREEN_ILI210X is not set +# CONFIG_TOUCHSCREEN_GUNZE is not set +CONFIG_TOUCHSCREEN_ELAN=y +# CONFIG_TOUCHSCREEN_ELO is not set +# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set +# CONFIG_TOUCHSCREEN_WACOM_I2C is not set +# CONFIG_TOUCHSCREEN_MAX11801 is not set +# CONFIG_TOUCHSCREEN_MCS5000 is not set +# CONFIG_TOUCHSCREEN_MMS114 is not set +# CONFIG_TOUCHSCREEN_MTOUCH is not set +# CONFIG_TOUCHSCREEN_IMX6UL_TSC is not set +# CONFIG_TOUCHSCREEN_INEXIO is not set +# CONFIG_TOUCHSCREEN_MK712 is not set +# CONFIG_TOUCHSCREEN_PENMOUNT is not set +# CONFIG_TOUCHSCREEN_EDT_FT5X06 is not set +# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set +# CONFIG_TOUCHSCREEN_TOUCHWIN is not set +# CONFIG_TOUCHSCREEN_PIXCIR is not set +# CONFIG_TOUCHSCREEN_WDT87XX_I2C is not set +CONFIG_TOUCHSCREEN_USB_COMPOSITE=y +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 is not set +# CONFIG_TOUCHSCREEN_TSC_SERIO is not set +# CONFIG_TOUCHSCREEN_TSC2004 is not set +# CONFIG_TOUCHSCREEN_TSC2005 is not set +# CONFIG_TOUCHSCREEN_TSC2007 is not set +# CONFIG_TOUCHSCREEN_ST1232 is not set +# CONFIG_TOUCHSCREEN_SUR40 is not set +# CONFIG_TOUCHSCREEN_SX8654 is not set +# CONFIG_TOUCHSCREEN_TPS6507X is not set +# CONFIG_TOUCHSCREEN_ZFORCE is not set +# CONFIG_TOUCHSCREEN_ROHM_BU21023 is not set +# CONFIG_TOUCHSCREEN_VTL_CT36X is not set +# CONFIG_TOUCHSCREEN_GT1X is not set +CONFIG_ROCKCHIP_REMOTECTL=y +CONFIG_ROCKCHIP_REMOTECTL_PWM=y + +# +# handle all sensors +# +# CONFIG_SENSOR_DEVICE is not set +CONFIG_INPUT_MISC=y +# CONFIG_INPUT_AD714X is not set +# CONFIG_INPUT_BMA150 is not set +# CONFIG_INPUT_E3X0_BUTTON is not set +# CONFIG_INPUT_MMA8450 is not set +# CONFIG_INPUT_MPU3050 is not set +# CONFIG_INPUT_GP2A is not set +# CONFIG_INPUT_GPIO_BEEPER is not set +# CONFIG_INPUT_GPIO_TILT_POLLED is not set +# CONFIG_INPUT_ATI_REMOTE2 is not set +# CONFIG_INPUT_KEYCHORD 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_RK8XX_PWRKEY=m +CONFIG_INPUT_UINPUT=y +# CONFIG_INPUT_GPIO is not set +# CONFIG_INPUT_PCF8574 is not set +# CONFIG_INPUT_PWM_BEEPER is not set +# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set +# CONFIG_INPUT_ADXL34X is not set +# CONFIG_INPUT_IMS_PCU is not set +# CONFIG_INPUT_CMA3000 is not set +# CONFIG_INPUT_SOC_BUTTON_ARRAY is not set +# CONFIG_INPUT_DRV260X_HAPTICS is not set +# CONFIG_INPUT_DRV2665_HAPTICS is not set +# CONFIG_INPUT_DRV2667_HAPTICS is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_AMBAKMI is not set +CONFIG_SERIO_LIBPS2=y +CONFIG_SERIO_RAW=y +# 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_USERIO is not set +# CONFIG_GAMEPORT is not set + +# +# 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_DEVPTS_MULTIPLE_INSTANCES=y +# CONFIG_LEGACY_PTYS is not set +# CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_N_GSM is not set +# CONFIG_TRACE_SINK is not set +CONFIG_LDISC_AUTOLOAD=y +CONFIG_DEVMEM=y +# CONFIG_DEVKMEM is not set + +# +# Serial drivers +# +CONFIG_SERIAL_EARLYCON=y +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_DMA=y +CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +# CONFIG_SERIAL_8250_EXTENDED is not set +CONFIG_SERIAL_8250_FSL=y +CONFIG_SERIAL_8250_DW=y +# CONFIG_SERIAL_8250_EM is not set +# CONFIG_SERIAL_8250_RT288X is not set +# CONFIG_SERIAL_8250_INGENIC is not set + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_AMBA_PL010 is not set +# CONFIG_SERIAL_AMBA_PL011 is not set +# CONFIG_SERIAL_EARLYCON_ARM_SEMIHOST is not set +# 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_OF_PLATFORM=y +# CONFIG_SERIAL_SCCNXP is not set +# CONFIG_SERIAL_SC16IS7XX is not set +# CONFIG_SERIAL_BCM63XX is not set +# CONFIG_SERIAL_ALTERA_JTAGUART is not set +# CONFIG_SERIAL_ALTERA_UART is not set +# CONFIG_SERIAL_IFX6X60 is not set +# CONFIG_SERIAL_XILINX_PS_UART is not set +# CONFIG_SERIAL_ARC is not set +# CONFIG_SERIAL_FSL_LPUART is not set +# CONFIG_SERIAL_CONEXANT_DIGICOLOR is not set +# CONFIG_SERIAL_ST_ASC is not set +# CONFIG_SERIAL_STM32 is not set +# CONFIG_TTY_PRINTK is not set +# CONFIG_HVC_DCC is not set +# CONFIG_IPMI_HANDLER is not set +CONFIG_HW_RANDOM=y +# CONFIG_HW_RANDOM_TIMERIOMEM is not set +CONFIG_HW_RANDOM_TPM=y +CONFIG_HW_RANDOM_ROCKCHIP=m +# CONFIG_RAW_DRIVER is not set +CONFIG_TCG_TPM=y +# CONFIG_TCG_TIS_I2C_ATMEL is not set +CONFIG_TCG_TIS_I2C_INFINEON=y +# CONFIG_TCG_TIS_I2C_NUVOTON is not set +# CONFIG_TCG_ATMEL is not set +# CONFIG_TCG_TIS_ST33ZP24 is not set +# CONFIG_XILLYBUS is not set + +# +# I2C support +# +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_COMPAT=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_MUX=y + +# +# Multiplexer I2C Chip support +# +# CONFIG_I2C_ARB_GPIO_CHALLENGE is not set +# CONFIG_I2C_MUX_GPIO is not set +# CONFIG_I2C_MUX_PCA9541 is not set +# CONFIG_I2C_MUX_PCA954x is not set +# CONFIG_I2C_MUX_PINCTRL is not set +# CONFIG_I2C_MUX_REG is not set +CONFIG_I2C_HELPER_AUTO=y +CONFIG_I2C_ALGOBIT=y + +# +# I2C Hardware Bus support +# + +# +# I2C system bus drivers (mostly embedded / system-on-chip) +# +# CONFIG_I2C_CBUS_GPIO is not set +# CONFIG_I2C_DESIGNWARE_PLATFORM is not set +# CONFIG_I2C_EMEV2 is not set +# CONFIG_I2C_GPIO is not set +# CONFIG_I2C_NOMADIK is not set +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_PCA_PLATFORM is not set +# CONFIG_I2C_PXA_PCI is not set +CONFIG_I2C_RK3X=y +# CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_XILINX is not set + +# +# External I2C/SMBus adapter drivers +# +# CONFIG_I2C_DIOLAN_U2C is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_ROBOTFUZZ_OSIF is not set +# CONFIG_I2C_TAOS_EVM is not set +# CONFIG_I2C_TINY_USB is not set + +# +# Other I2C/SMBus bus drivers +# +CONFIG_I2C_CROS_EC_TUNNEL=y +CONFIG_I2C_STUB=m +# CONFIG_I2C_SLAVE is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +CONFIG_SPI=y +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +# CONFIG_SPI_ALTERA is not set +CONFIG_SPI_BITBANG=y +# CONFIG_SPI_CADENCE is not set +# CONFIG_SPI_GPIO is not set +# CONFIG_SPI_FSL_SPI is not set +# CONFIG_SPI_OC_TINY is not set +# CONFIG_SPI_PL022 is not set +# CONFIG_SPI_PXA2XX_PCI is not set +CONFIG_SPI_ROCKCHIP=y +# CONFIG_SPI_SC18IS602 is not set +# CONFIG_SPI_XCOMM is not set +# CONFIG_SPI_XILINX is not set +# CONFIG_SPI_ZYNQMP_GQSPI is not set +# CONFIG_SPI_DESIGNWARE is not set + +# +# SPI Protocol Masters +# +CONFIG_SPI_SPIDEV=y +# CONFIG_SPI_TLE62X0 is not set +# CONFIG_SPMI is not set +# CONFIG_HSI is not set + +# +# PPS support +# +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 + +# +# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks. +# +CONFIG_PINCTRL=y + +# +# Pin controllers +# +CONFIG_PINMUX=y +CONFIG_PINCONF=y +CONFIG_GENERIC_PINCONF=y +# CONFIG_DEBUG_PINCTRL is not set +# CONFIG_PINCTRL_AMD is not set +CONFIG_PINCTRL_ROCKCHIP=y +# CONFIG_PINCTRL_SINGLE is not set +CONFIG_PINCTRL_RK805=m +CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y +CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y +CONFIG_ARCH_REQUIRE_GPIOLIB=y +CONFIG_GPIOLIB=y +CONFIG_GPIO_DEVRES=y +CONFIG_OF_GPIO=y +CONFIG_DEBUG_GPIO=y +CONFIG_GPIO_SYSFS=y +CONFIG_GPIO_GENERIC=y + +# +# Memory mapped GPIO drivers +# +# CONFIG_GPIO_74XX_MMIO is not set +# CONFIG_GPIO_ALTERA is not set +# CONFIG_GPIO_DWAPB is not set +# CONFIG_GPIO_EM is not set +CONFIG_GPIO_GENERIC_PLATFORM=y +# CONFIG_GPIO_GRGPIO is not set +# CONFIG_GPIO_PL061 is not set +# CONFIG_GPIO_SYSCON is not set +# CONFIG_GPIO_XILINX is not set +# CONFIG_GPIO_ZEVIO is not set +# CONFIG_GPIO_ZX is not set + +# +# I2C GPIO expanders +# +# CONFIG_GPIO_ADP5588 is not set +# CONFIG_GPIO_ADNP is not set +# CONFIG_GPIO_MAX7300 is not set +# CONFIG_GPIO_MAX732X is not set +# CONFIG_GPIO_PCA953X is not set +# CONFIG_GPIO_PCF857X is not set +# CONFIG_GPIO_SX150X is not set + +# +# MFD GPIO expanders +# +CONFIG_GPIO_RK8XX=m +# CONFIG_GPIO_TPS6586X is not set + +# +# SPI GPIO expanders +# +# CONFIG_GPIO_74X164 is not set +# CONFIG_GPIO_MAX7301 is not set +# CONFIG_GPIO_MC33880 is not set + +# +# SPI or I2C GPIO expanders +# +# CONFIG_GPIO_MCP23S08 is not set + +# +# USB GPIO expanders +# +# CONFIG_W1 is not set +CONFIG_POWER_SUPPLY=y +# CONFIG_POWER_SUPPLY_DEBUG is not set +# CONFIG_PDA_POWER is not set +# CONFIG_GENERIC_ADC_BATTERY is not set +# CONFIG_TEST_POWER is not set +# CONFIG_BATTERY_DS2780 is not set +# CONFIG_BATTERY_DS2781 is not set +# CONFIG_BATTERY_DS2782 is not set +CONFIG_BATTERY_SBS=y +# CONFIG_BATTERY_BQ27XXX is not set +# CONFIG_BATTERY_MAX17040 is not set +# CONFIG_BATTERY_MAX17042 is not set +# CONFIG_CHARGER_MAX8903 is not set +# CONFIG_CHARGER_LP8727 is not set +CONFIG_CHARGER_GPIO=y +# CONFIG_CHARGER_MANAGER is not set +# CONFIG_CHARGER_BQ2415X is not set +# CONFIG_CHARGER_BQ24190 is not set +# CONFIG_CHARGER_BQ24257 is not set +CONFIG_CHARGER_BQ24735=y +# CONFIG_CHARGER_BQ25700 is not set +# CONFIG_CHARGER_BQ25890 is not set +# CONFIG_CHARGER_SMB347 is not set +# CONFIG_CHARGER_SY6982C is not set +# CONFIG_CHARGER_UNIVERSAL is not set +# CONFIG_BATTERY_GAUGE_LTC2941 is not set +# CONFIG_BATTERY_EC is not set +# CONFIG_BATTERY_CW2015 is not set +# CONFIG_BATTERY_RK816 is not set +# CONFIG_BATTERY_RK817 is not set +# CONFIG_CHARGER_RK817 is not set +# CONFIG_BATTERY_RK818 is not set +# CONFIG_CHARGER_RK818 is not set +# CONFIG_CHARGER_RT9455 is not set +CONFIG_POWER_RESET=y +# CONFIG_POWER_RESET_BRCMSTB is not set +# CONFIG_POWER_RESET_GPIO is not set +CONFIG_POWER_RESET_GPIO_RESTART=y +# CONFIG_POWER_RESET_LTC2952 is not set +# CONFIG_POWER_RESET_RESTART is not set +# CONFIG_POWER_RESET_VERSATILE is not set +# CONFIG_POWER_RESET_SYSCON is not set +# CONFIG_POWER_RESET_SYSCON_POWEROFF is not set +CONFIG_REBOOT_MODE=y +CONFIG_SYSCON_REBOOT_MODE=y +CONFIG_POWER_AVS=y +CONFIG_ROCKCHIP_IODOMAIN=y +CONFIG_HWMON=y +# CONFIG_HWMON_VID is not set +# CONFIG_HWMON_DEBUG_CHIP is not set + +# +# Native drivers +# +# CONFIG_SENSORS_AD7314 is not set +# CONFIG_SENSORS_AD7414 is not set +# CONFIG_SENSORS_AD7418 is not set +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1029 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ADM9240 is not set +# CONFIG_SENSORS_ADT7310 is not set +# CONFIG_SENSORS_ADT7410 is not set +# CONFIG_SENSORS_ADT7411 is not set +# CONFIG_SENSORS_ADT7462 is not set +# CONFIG_SENSORS_ADT7470 is not set +# CONFIG_SENSORS_ADT7475 is not set +# CONFIG_SENSORS_ASC7621 is not set +# CONFIG_SENSORS_ATXP1 is not set +# CONFIG_SENSORS_DS620 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_F71805F is not set +# CONFIG_SENSORS_F71882FG is not set +# CONFIG_SENSORS_F75375S is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_G760A is not set +# CONFIG_SENSORS_G762 is not set +# CONFIG_SENSORS_GPIO_FAN is not set +# CONFIG_SENSORS_HIH6130 is not set +# CONFIG_SENSORS_IIO_HWMON is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_JC42 is not set +# CONFIG_SENSORS_POWR1220 is not set +# CONFIG_SENSORS_LINEAGE is not set +# CONFIG_SENSORS_LTC2945 is not set +# CONFIG_SENSORS_LTC4151 is not set +# CONFIG_SENSORS_LTC4215 is not set +# CONFIG_SENSORS_LTC4222 is not set +# CONFIG_SENSORS_LTC4245 is not set +# CONFIG_SENSORS_LTC4260 is not set +# CONFIG_SENSORS_LTC4261 is not set +# CONFIG_SENSORS_MAX1111 is not set +# CONFIG_SENSORS_MAX16065 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_MAX1668 is not set +# CONFIG_SENSORS_MAX197 is not set +# CONFIG_SENSORS_MAX6639 is not set +# CONFIG_SENSORS_MAX6642 is not set +# CONFIG_SENSORS_MAX6650 is not set +# CONFIG_SENSORS_MAX6697 is not set +# CONFIG_SENSORS_MAX31790 is not set +# CONFIG_SENSORS_HTU21 is not set +# CONFIG_SENSORS_MCP3021 is not set +# CONFIG_SENSORS_ADCXX is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM70 is not set +# CONFIG_SENSORS_LM73 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set +# CONFIG_SENSORS_LM93 is not set +# CONFIG_SENSORS_LM95234 is not set +# CONFIG_SENSORS_LM95241 is not set +# CONFIG_SENSORS_LM95245 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_PC87427 is not set +# CONFIG_SENSORS_NTC_THERMISTOR is not set +# CONFIG_SENSORS_NCT6683 is not set +# CONFIG_SENSORS_NCT6775 is not set +# CONFIG_SENSORS_NCT7802 is not set +# CONFIG_SENSORS_NCT7904 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_PMBUS is not set +# CONFIG_SENSORS_PWM_FAN is not set +# CONFIG_SENSORS_SHT15 is not set +# CONFIG_SENSORS_SHT21 is not set +# CONFIG_SENSORS_SHTC1 is not set +# CONFIG_SENSORS_DME1737 is not set +# CONFIG_SENSORS_EMC1403 is not set +# CONFIG_SENSORS_EMC2103 is not set +# CONFIG_SENSORS_EMC6W201 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47M192 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_SCH56XX_COMMON is not set +# CONFIG_SENSORS_SCH5627 is not set +# CONFIG_SENSORS_SCH5636 is not set +# CONFIG_SENSORS_SMM665 is not set +# CONFIG_SENSORS_ADC128D818 is not set +# CONFIG_SENSORS_ADS1015 is not set +# CONFIG_SENSORS_ADS7828 is not set +# CONFIG_SENSORS_ADS7871 is not set +# CONFIG_SENSORS_AMC6821 is not set +# CONFIG_SENSORS_INA209 is not set +# CONFIG_SENSORS_INA2XX is not set +# CONFIG_SENSORS_TC74 is not set +# CONFIG_SENSORS_THMC50 is not set +# CONFIG_SENSORS_TMP102 is not set +# CONFIG_SENSORS_TMP103 is not set +# CONFIG_SENSORS_TMP401 is not set +# CONFIG_SENSORS_TMP421 is not set +# CONFIG_SENSORS_VT1211 is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83791D is not set +# CONFIG_SENSORS_W83792D is not set +# CONFIG_SENSORS_W83793 is not set +# CONFIG_SENSORS_W83795 is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83L786NG is not set +# CONFIG_SENSORS_W83627HF is not set +# CONFIG_SENSORS_W83627EHF is not set +CONFIG_THERMAL=y +CONFIG_THERMAL_HWMON=y +CONFIG_THERMAL_OF=y +# CONFIG_THERMAL_WRITABLE_TRIPS is not set +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_DEFAULT_GOV_POWER_ALLOCATOR is not set +# CONFIG_THERMAL_GOV_FAIR_SHARE is not set +CONFIG_THERMAL_GOV_STEP_WISE=y +# CONFIG_THERMAL_GOV_BANG_BANG is not set +# CONFIG_THERMAL_GOV_USER_SPACE is not set +# CONFIG_THERMAL_GOV_POWER_ALLOCATOR is not set +CONFIG_CPU_THERMAL=y +# CONFIG_CLOCK_THERMAL is not set +CONFIG_DEVFREQ_THERMAL=y +# CONFIG_THERMAL_EMULATION is not set +# CONFIG_IMX_THERMAL is not set +CONFIG_ROCKCHIP_THERMAL=y +# CONFIG_RK_VIRTUAL_THERMAL is not set +# CONFIG_RK3368_THERMAL is not set +CONFIG_WATCHDOG=y +CONFIG_WATCHDOG_CORE=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +CONFIG_SOFT_WATCHDOG=m +# CONFIG_GPIO_WATCHDOG is not set +# CONFIG_XILINX_WATCHDOG is not set +# CONFIG_ARM_SP805_WATCHDOG is not set +# CONFIG_CADENCE_WATCHDOG is not set +CONFIG_DW_WATCHDOG=y +# CONFIG_MAX63XX_WATCHDOG is not set +# CONFIG_BCM7038_WDT is not set +# CONFIG_MEN_A21_WDT is not set + +# +# USB-based Watchdog Cards +# +# CONFIG_USBPCWATCHDOG is not set +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +# CONFIG_SSB is not set +CONFIG_BCMA_POSSIBLE=y + +# +# Broadcom specific AMBA +# +# CONFIG_BCMA is not set + +# +# Multifunction device drivers +# +CONFIG_MFD_CORE=y +# CONFIG_MFD_AS3711 is not set +# CONFIG_MFD_AS3722 is not set +# CONFIG_PMIC_ADP5520 is not set +# CONFIG_MFD_AAT2870_CORE is not set +# CONFIG_MFD_ATMEL_FLEXCOM is not set +# CONFIG_MFD_ATMEL_HLCDC is not set +# CONFIG_MFD_BCM590XX is not set +# CONFIG_MFD_AXP20X is not set +CONFIG_MFD_CROS_EC=y +# CONFIG_MFD_CROS_EC_I2C is not set +CONFIG_MFD_CROS_EC_SPI=y +# CONFIG_MFD_ASIC3 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_MC13XXX_SPI is not set +# CONFIG_MFD_MC13XXX_I2C is not set +# CONFIG_MFD_HI6421_PMIC is not set +# CONFIG_HTC_EGPIO is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_HTC_I2CPLD is not set +# CONFIG_INTEL_SOC_PMIC 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_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_MT6397 is not set +# CONFIG_MFD_MENF21BMC is not set +# CONFIG_EZX_PCAP is not set +# CONFIG_MFD_VIPERBOARD is not set +# CONFIG_MFD_RETU is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_MFD_PM8921_CORE is not set +# CONFIG_MFD_RT5033 is not set +# CONFIG_MFD_RTSX_USB is not set +# CONFIG_MFD_RC5T583 is not set +# CONFIG_MFD_RK618 is not set +CONFIG_MFD_RK808=y +# CONFIG_MFD_RN5T618 is not set +# CONFIG_MFD_SEC_CORE is not set +# CONFIG_MFD_SI476X_CORE is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_MFD_SKY81452 is not set +# CONFIG_MFD_SMSC is not set +# CONFIG_ABX500_CORE is not set +# CONFIG_MFD_STMPE is not set +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_PALMAS is not set +# CONFIG_TPS6105X is not set +# CONFIG_TPS65010 is not set +# CONFIG_TPS6507X is not set +# CONFIG_MFD_TPS65090 is not set +# CONFIG_MFD_TPS65217 is not set +# CONFIG_MFD_TPS65218 is not set +CONFIG_MFD_TPS6586X=y +# CONFIG_MFD_TPS65910 is not set +# CONFIG_MFD_TPS65912 is not set +# CONFIG_MFD_TPS65912_I2C is not set +# CONFIG_MFD_TPS65912_SPI is not set +# CONFIG_MFD_TPS80031 is not set +# CONFIG_TWL4030_CORE is not set +# CONFIG_TWL6040_CORE is not set +# CONFIG_MFD_WL1273_CORE is not set +# CONFIG_MFD_LM3533 is not set +# CONFIG_MFD_TC3589X is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_MFD_T7L66XB is not set +# CONFIG_MFD_TC6387XB is not set +# CONFIG_MFD_TC6393XB 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_RK1000 is not set +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_WM8994 is not set +# CONFIG_FUSB_30X is not set +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_ACT8865=y +# CONFIG_REGULATOR_AD5398 is not set +# CONFIG_REGULATOR_ANATOP is not set +# CONFIG_REGULATOR_DA9210 is not set +# CONFIG_REGULATOR_DA9211 is not set +CONFIG_REGULATOR_FAN53555=y +# CONFIG_REGULATOR_GPIO is not set +# 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_LP8752 is not set +# CONFIG_REGULATOR_LP8755 is not set +# CONFIG_REGULATOR_LTC3589 is not set +# CONFIG_REGULATOR_MAX1586 is not set +# CONFIG_REGULATOR_MAX8649 is not set +# CONFIG_REGULATOR_MAX8660 is not set +# CONFIG_REGULATOR_MAX8952 is not set +# CONFIG_REGULATOR_MAX8973 is not set +# CONFIG_REGULATOR_MP8865 is not set +# CONFIG_REGULATOR_MT6311 is not set +# CONFIG_REGULATOR_PFUZE100 is not set +CONFIG_REGULATOR_PWM=y +CONFIG_REGULATOR_RK808=y +# CONFIG_REGULATOR_RK818 is not set +# CONFIG_REGULATOR_SYR82X is not set +# CONFIG_REGULATOR_TPS51632 is not set +CONFIG_REGULATOR_TPS549B22=m +# 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_TPS6586X=y +# CONFIG_REGULATOR_XZ3216 is not set +CONFIG_CEC_CORE=y +CONFIG_CEC_NOTIFIER=y +CONFIG_MEDIA_SUPPORT=y + +# +# Multimedia core support +# +CONFIG_MEDIA_CAMERA_SUPPORT=y +# CONFIG_MEDIA_ANALOG_TV_SUPPORT is not set +CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y +# CONFIG_MEDIA_RADIO_SUPPORT is not set +# CONFIG_MEDIA_SDR_SUPPORT is not set +# CONFIG_MEDIA_RC_SUPPORT is not set +CONFIG_MEDIA_CEC_SUPPORT=y +CONFIG_MEDIA_CONTROLLER=y +CONFIG_VIDEO_DEV=y +CONFIG_VIDEO_V4L2_SUBDEV_API=y +CONFIG_VIDEO_V4L2=y +# CONFIG_VIDEO_ADV_DEBUG is not set +# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set +CONFIG_VIDEO_TUNER=m +CONFIG_V4L2_MEM2MEM_DEV=y +CONFIG_V4L2_FWNODE=y +CONFIG_VIDEOBUF_GEN=y +CONFIG_VIDEOBUF2_CORE=y +CONFIG_VIDEOBUF2_MEMOPS=y +CONFIG_VIDEOBUF2_DMA_CONTIG=y +CONFIG_VIDEOBUF2_VMALLOC=y +CONFIG_VIDEOBUF2_DMA_SG=y +CONFIG_DVB_CORE=y +CONFIG_DVB_NET=y +# CONFIG_TTPCI_EEPROM is not set +CONFIG_DVB_MAX_ADAPTERS=8 +# CONFIG_DVB_DYNAMIC_MINORS is not set + +# +# Media drivers +# +CONFIG_MEDIA_USB_SUPPORT=y + +# +# Webcam devices +# +CONFIG_USB_VIDEO_CLASS=y +# CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV is not set +# CONFIG_USB_GSPCA is not set +# CONFIG_USB_PWC is not set +# CONFIG_VIDEO_CPIA2 is not set +# CONFIG_USB_ZR364XX is not set +# CONFIG_USB_STKWEBCAM is not set +# CONFIG_USB_S2255 is not set +# CONFIG_VIDEO_USBTV is not set +# CONFIG_NPU_USB_ACM is not set + +# +# Analog/digital TV USB devices +# +CONFIG_VIDEO_AU0828=m +CONFIG_VIDEO_AU0828_V4L2=y + +# +# Digital TV USB devices +# +CONFIG_DVB_USB_V2=y +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_MXL111SF=m +CONFIG_DVB_USB_RTL28XXU=m +CONFIG_DVB_USB_DVBSKY=m +# CONFIG_SMS_USB_DRV is not set +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 is not set + +# +# USB HDMI CEC adapters +# +CONFIG_USB_PULSE8_CEC=m +# CONFIG_USB_RAINSHADOW_CEC is not set +CONFIG_V4L_PLATFORM_DRIVERS=y +CONFIG_SOC_CAMERA=y +CONFIG_SOC_CAMERA_PLATFORM=m +# CONFIG_VIDEO_XILINX is not set +CONFIG_VIDEO_RK_CIF_ISP10=y +CONFIG_VIDEO_ROCKCHIP_CIF=y +CONFIG_ROCKCHIP_CIF_WORKMODE_PINGPONG=y +# CONFIG_ROCKCHIP_CIF_WORKMODE_ONEFRAME is not set +CONFIG_VIDEO_ROCKCHIP_ISP1=y +CONFIG_V4L_MEM2MEM_DRIVERS=y +# CONFIG_VIDEO_MEM2MEM_DEINTERLACE is not set +# CONFIG_VIDEO_SH_VEU is not set +CONFIG_VIDEO_ROCKCHIP_RGA=y +CONFIG_VIDEO_ROCKCHIP_VPU=y +CONFIG_V4L_TEST_DRIVERS=y +# CONFIG_VIDEO_VIVID is not set +# CONFIG_VIDEO_VIM2M is not set +CONFIG_DVB_PLATFORM_DRIVERS=y +# CONFIG_DVB_C8SECTPFE is not set +# CONFIG_ROCKCHIP_TSP is not set + +# +# Supported MMC/SDIO adapters +# +# CONFIG_SMS_SDIO_DRV is not set +CONFIG_VIDEO_TVEEPROM=m +CONFIG_CYPRESS_FIRMWARE=m +CONFIG_DVB_B2C2_FLEXCOP=m + +# +# Media ancillary drivers (tuners, sensors, i2c, spi, frontends) +# +# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set +CONFIG_MEDIA_ATTACH=y + +# +# I2C Encoders, decoders, sensors and other helper chips +# + +# +# Audio decoders, processors and mixers +# +# CONFIG_VIDEO_TVAUDIO is not set +# CONFIG_VIDEO_TDA7432 is not set +# CONFIG_VIDEO_TDA9840 is not set +# CONFIG_VIDEO_TEA6415C is not set +# CONFIG_VIDEO_TEA6420 is not set +# CONFIG_VIDEO_MSP3400 is not set +# CONFIG_VIDEO_CS5345 is not set +# CONFIG_VIDEO_CS53L32A is not set +# CONFIG_VIDEO_TLV320AIC23B is not set +# CONFIG_VIDEO_UDA1342 is not set +# CONFIG_VIDEO_WM8775 is not set +# CONFIG_VIDEO_WM8739 is not set +# CONFIG_VIDEO_VP27SMPX is not set +# CONFIG_VIDEO_SONY_BTF_MPX is not set + +# +# RDS decoders +# +# CONFIG_VIDEO_SAA6588 is not set + +# +# Video decoders +# +# CONFIG_VIDEO_ADV7180 is not set +# CONFIG_VIDEO_ADV7181D is not set +# CONFIG_VIDEO_ADV7183 is not set +# CONFIG_VIDEO_ADV7604 is not set +# CONFIG_VIDEO_ADV7842 is not set +# CONFIG_VIDEO_BT819 is not set +# CONFIG_VIDEO_BT856 is not set +# CONFIG_VIDEO_BT866 is not set +# CONFIG_VIDEO_KS0127 is not set +# CONFIG_VIDEO_ML86V7667 is not set +# CONFIG_VIDEO_SAA7110 is not set +# CONFIG_VIDEO_SAA711X is not set +# CONFIG_VIDEO_TC35874X is not set +# CONFIG_VIDEO_TVP514X is not set +# CONFIG_VIDEO_TVP5150 is not set +# CONFIG_VIDEO_TVP7002 is not set +# CONFIG_VIDEO_TW2804 is not set +# CONFIG_VIDEO_TW9903 is not set +# CONFIG_VIDEO_TW9906 is not set +# CONFIG_VIDEO_VPX3220 is not set + +# +# Video and audio decoders +# +# CONFIG_VIDEO_SAA717X is not set +# CONFIG_VIDEO_CX25840 is not set + +# +# Video encoders +# +# CONFIG_VIDEO_SAA7127 is not set +# CONFIG_VIDEO_SAA7185 is not set +# CONFIG_VIDEO_ADV7170 is not set +# CONFIG_VIDEO_ADV7175 is not set +# CONFIG_VIDEO_ADV7343 is not set +# CONFIG_VIDEO_ADV7393 is not set +# CONFIG_VIDEO_ADV7511 is not set +# CONFIG_VIDEO_AD9389B is not set +# CONFIG_VIDEO_AK881X is not set +# CONFIG_VIDEO_THS8200 is not set + +# +# Camera sensor devices +# +# CONFIG_VIDEO_IMX214 is not set +CONFIG_VIDEO_IMX219=y +# CONFIG_VIDEO_IMX258 is not set +# CONFIG_VIDEO_IMX291 is not set +# CONFIG_VIDEO_IMX307 is not set +# CONFIG_VIDEO_IMX317 is not set +# CONFIG_VIDEO_IMX323 is not set +# CONFIG_VIDEO_IMX327 is not set +# CONFIG_VIDEO_VIRT_CAMERA is not set +# CONFIG_VIDEO_OV2659 is not set +# CONFIG_VIDEO_OV2680 is not set +# CONFIG_VIDEO_OV2685 is not set +# CONFIG_VIDEO_OV2718 is not set +# CONFIG_VIDEO_OV2735 is not set +# CONFIG_VIDEO_OV4689 is not set +# CONFIG_VIDEO_OV5640 is not set +CONFIG_VIDEO_OV5647=y +# CONFIG_VIDEO_OV5648 is not set +# CONFIG_VIDEO_OV5670 is not set +# CONFIG_VIDEO_OV5695 is not set +# CONFIG_VIDEO_OV7251 is not set +# CONFIG_VIDEO_OV7640 is not set +# CONFIG_VIDEO_OV7670 is not set +# CONFIG_VIDEO_OV7725 is not set +# CONFIG_VIDEO_OV7750 is not set +# CONFIG_VIDEO_OV8858 is not set +# CONFIG_VIDEO_OV9281 is not set +# CONFIG_VIDEO_OV9650 is not set +# CONFIG_VIDEO_OV9750 is not set +# CONFIG_VIDEO_OV13850 is not set +# CONFIG_VIDEO_VS6624 is not set +# CONFIG_VIDEO_MT9M032 is not set +# CONFIG_VIDEO_MT9P031 is not set +# CONFIG_VIDEO_MT9T001 is not set +# CONFIG_VIDEO_MT9V011 is not set +# CONFIG_VIDEO_MT9V032 is not set +# CONFIG_VIDEO_AR0144 is not set +# CONFIG_VIDEO_AR0230 is not set +# CONFIG_VIDEO_SR030PC30 is not set +# CONFIG_VIDEO_NOON010PC30 is not set +# CONFIG_VIDEO_M5MOLS is not set +# CONFIG_VIDEO_S5K4H8 is not set +# CONFIG_VIDEO_S5K6AA is not set +# CONFIG_VIDEO_S5K6A3 is not set +# CONFIG_VIDEO_S5K4ECGX is not set +# CONFIG_VIDEO_S5K5BAF is not set +# CONFIG_VIDEO_SMIAPP is not set +# CONFIG_VIDEO_S5C73M3 is not set +# CONFIG_VIDEO_GC0403 is not set +# CONFIG_VIDEO_GC2155 is not set +# CONFIG_VIDEO_GC0312 is not set +# CONFIG_VIDEO_GC2053 is not set +# CONFIG_VIDEO_GC2145 is not set +CONFIG_VIDEO_GC2355=y +# CONFIG_VIDEO_GC2385 is not set +# CONFIG_VIDEO_GC5025 is not set +# CONFIG_VIDEO_GC5035 is not set +# CONFIG_VIDEO_GC8034 is not set +CONFIG_VIDEO_SC031GS=y +# CONFIG_VIDEO_SC132GS is not set +# CONFIG_VIDEO_GC0329 is not set +# CONFIG_VIDEO_GC2035 is not set +# CONFIG_VIDEO_BF20A2 is not set +# CONFIG_VIDEO_BF3925 is not set +# CONFIG_VIDEO_JX_H65 is not set +# CONFIG_VIDEO_XC7080_XC530 is not set +# CONFIG_VIDEO_PREISP_DUMMY_SENSOR is not set + +# +# Flash devices +# +# CONFIG_VIDEO_ADP1653 is not set +# CONFIG_VIDEO_AS3645A is not set +# CONFIG_VIDEO_LM3560 is not set +# CONFIG_VIDEO_LM3646 is not set +# CONFIG_VIDEO_SGM3784 is not set + +# +# Video improvement chips +# +# CONFIG_VIDEO_UPD64031A is not set +# CONFIG_VIDEO_UPD64083 is not set + +# +# Camera lens devices +# +# CONFIG_VIDEO_VM149C is not set +# CONFIG_VIDEO_DW9714 is not set +# CONFIG_VIDEO_FP5510 is not set + +# +# Audio/Video compression chips +# +# CONFIG_VIDEO_SAA6752HS is not set + +# +# Miscellaneous helper chips +# +# CONFIG_VIDEO_THS7303 is not set +# CONFIG_VIDEO_M52790 is not set +# CONFIG_VIDEO_NVP6324 is not set + +# +# Sensors used on soc_camera driver +# + +# +# soc_camera sensor drivers +# +# CONFIG_SOC_CAMERA_IMX074 is not set +# CONFIG_SOC_CAMERA_MT9M001 is not set +# CONFIG_SOC_CAMERA_MT9M111 is not set +# CONFIG_SOC_CAMERA_MT9T031 is not set +# CONFIG_SOC_CAMERA_MT9T112 is not set +# CONFIG_SOC_CAMERA_MT9V022 is not set +# CONFIG_SOC_CAMERA_OV2640 is not set +# CONFIG_SOC_CAMERA_OV5642 is not set +# CONFIG_SOC_CAMERA_OV6650 is not set +# CONFIG_SOC_CAMERA_OV772X is not set +# CONFIG_SOC_CAMERA_OV9640 is not set +# CONFIG_SOC_CAMERA_OV9740 is not set +# CONFIG_SOC_CAMERA_RJ54N1 is not set +# CONFIG_SOC_CAMERA_TW9910 is not set +# CONFIG_VIDEO_OV2710 is not set +# CONFIG_VIDEO_TC358749XBG is not set +# CONFIG_VIDEO_ADV7181 is not set +# CONFIG_VIDEO_OV7675 is not set +# CONFIG_VIDEO_NT99230 is not set +# CONFIG_VIDEO_ov5640 is not set +# CONFIG_VIDEO_SC2232 is not set +# CONFIG_VIDEO_ISL79987 is not set + +# +# SPI helper chips +# +# CONFIG_VIDEO_GS1662 is not set +# CONFIG_VIDEO_IMX327_SPI is not set +# CONFIG_VIDEO_ROCKCHIP_PREISP is not set +CONFIG_MEDIA_TUNER=y + +# +# Customize TV tuners +# +CONFIG_MEDIA_TUNER_SIMPLE=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 + +# +# Customise DVB Frontends +# + +# +# Multistandard (satellite) frontends +# +CONFIG_DVB_STB0899=m +CONFIG_DVB_STB6100=m +CONFIG_DVB_STV090x=m +CONFIG_DVB_STV6110x=m +CONFIG_DVB_M88DS3103=m + +# +# Multistandard (cable + terrestrial) frontends +# +CONFIG_DVB_DRXK=m +CONFIG_DVB_TDA18271C2DD=m +CONFIG_DVB_SI2165=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_SP8870=m +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_HD29L2=m +CONFIG_DVB_STV0367=m +CONFIG_DVB_CXD2820R=m +CONFIG_DVB_CXD2841ER=m +CONFIG_DVB_RTL2830=m +CONFIG_DVB_RTL2832=m +CONFIG_DVB_SI2168=m +CONFIG_DVB_AS102_FE=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 + +# +# 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 + +# +# 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_LNBP21=m +CONFIG_DVB_LNBP22=m +CONFIG_DVB_ISL6405=m +CONFIG_DVB_ISL6421=m +CONFIG_DVB_ISL6423=m +CONFIG_DVB_A8293=m +CONFIG_DVB_SP2=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 + +# +# Tools to develop new frontends +# +# CONFIG_DVB_DUMMY_FE is not set +# CONFIG_CAMSYS_DRV is not set +# CONFIG_ROCK_CHIP_SOC_CAMERA is not set + +# +# RockChip preisp driver +# +# CONFIG_RKPREISP_DRV is not set + +# +# Graphics support +# +# CONFIG_IMX_IPUV3_CORE is not set +CONFIG_DRM=y +CONFIG_DRM_IGNORE_IOTCL_PERMIT=y +CONFIG_DRM_KMS_HELPER=y +CONFIG_DRM_KMS_FB_HELPER=y +CONFIG_DRM_FBDEV_EMULATION=y +# CONFIG_DRM_LOAD_EDID_FIRMWARE is not set +# CONFIG_DRM_DP_CEC is not set +# CONFIG_DRM_SCDC_HELPER is not set +CONFIG_DRM_DMA_SYNC=y + +# +# I2C encoder or helper chips +# +# CONFIG_DRM_I2C_ADV7511 is not set +# CONFIG_DRM_I2C_CH7006 is not set +# CONFIG_DRM_I2C_SIL164 is not set +# CONFIG_DRM_I2C_NXP_TDA998X is not set +# CONFIG_DRM_VGEM is not set +# CONFIG_DRM_EXYNOS is not set +CONFIG_DRM_ROCKCHIP=y +# CONFIG_ROCKCHIP_DRM_DEBUG is not set +CONFIG_ROCKCHIP_DW_HDMI=y +# CONFIG_ROCKCHIP_DW_MIPI_DSI is not set +# CONFIG_ROCKCHIP_MIPI_CSI_TX is not set +# CONFIG_ROCKCHIP_ANALOGIX_DP is not set +CONFIG_ROCKCHIP_INNO_HDMI=y +CONFIG_ROCKCHIP_LVDS=y +CONFIG_ROCKCHIP_DRM_TVE=m +# CONFIG_ROCKCHIP_RGB is not set +# CONFIG_ROCKCHIP_DRM_BACKLIGHT is not set +# CONFIG_ROCKCHIP_RK3066_HDMI is not set +# CONFIG_DRM_UDL is not set +# CONFIG_DRM_ARMADA is not set +# CONFIG_DRM_TILCDC is not set +# CONFIG_DRM_FSL_DCU is not set +CONFIG_DRM_PANEL=y + +# +# Display Panels +# +CONFIG_DRM_PANEL_SIMPLE=y +# CONFIG_DRM_PANEL_SAMSUNG_LD9040 is not set +# CONFIG_DRM_PANEL_LG_LG4573 is not set +# CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0 is not set +CONFIG_DRM_BRIDGE=y + +# +# Display Interface Bridges +# +# CONFIG_DRM_NXP_PTN3460 is not set +# CONFIG_DRM_PARADE_PS8622 is not set +# CONFIG_DRM_RK1000 is not set +# CONFIG_DRM_DUMB_VGA_DAC is not set +# CONFIG_DRM_LONTIUM_LT8912 is not set +# CONFIG_DRM_CHIPONE_ICN6211 is not set +# CONFIG_DRM_ANALOGIX_ANX78XX is not set +# CONFIG_DRM_ANALOGIX_ANX6345 is not set +CONFIG_DRM_DW_HDMI=y +# CONFIG_DRM_DW_HDMI_AHB_AUDIO is not set +CONFIG_DRM_DW_HDMI_I2S_AUDIO=y +CONFIG_DRM_DW_HDMI_CEC=y +# CONFIG_DRM_STI is not set +# CONFIG_POWERVR_ROGUE_M is not set +CONFIG_MALI400=m +# CONFIG_MALI450 is not set +# CONFIG_MALI470 is not set +# CONFIG_MALI400_DEBUG is not set +# CONFIG_MALI400_PROFILING is not set +# CONFIG_MALI400_UMP is not set +CONFIG_MALI_DMA_BUF_MAP_ON_ATTACH=y +CONFIG_MALI_SHARED_INTERRUPTS=y +# CONFIG_MALI_PMU_PARALLEL_POWER_UP is not set +CONFIG_MALI_DT=y +CONFIG_MALI_DEVFREQ=y +# CONFIG_MALI_QUIET is not set +# CONFIG_MALI_MIDGARD_FOR_ANDROID is not set +CONFIG_MALI_MIDGARD_FOR_LINUX=y +# CONFIG_MALI_MIDGARD is not set +# CONFIG_MALI_KUTF is not set +# CONFIG_MALI_BIFROST_FOR_ANDROID is not set +CONFIG_MALI_BIFROST_FOR_LINUX=y +# CONFIG_MALI_BIFROST is not set + +# +# Frame buffer Devices +# +CONFIG_FB=y +# CONFIG_FIRMWARE_EDID is not set +CONFIG_FB_CMDLINE=y +# CONFIG_FB_DDC is not set +# CONFIG_FB_BOOT_VESA_SUPPORT is not set +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +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_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +CONFIG_FB_MODE_HELPERS=y +# CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# +# CONFIG_FB_ARMCLCD is not set +# CONFIG_FB_UVESA is not set +# CONFIG_FB_OPENCORES is not set +# CONFIG_FB_S1D13XXX 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_FB_METRONOME is not set +# CONFIG_FB_BROADSHEET is not set +# CONFIG_FB_AUO_K190X is not set +# CONFIG_FB_SIMPLE is not set +# CONFIG_FB_SSD1307 is not set +CONFIG_BACKLIGHT_LCD_SUPPORT=y +# CONFIG_LCD_CLASS_DEVICE is not set +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_GENERIC=y +CONFIG_BACKLIGHT_PWM=y +# CONFIG_BACKLIGHT_PM8941_WLED is not set +# CONFIG_BACKLIGHT_ADP8860 is not set +# CONFIG_BACKLIGHT_ADP8870 is not set +# CONFIG_BACKLIGHT_LM3630A is not set +# CONFIG_BACKLIGHT_LM3639 is not set +# CONFIG_BACKLIGHT_LP855X is not set +# CONFIG_BACKLIGHT_GPIO is not set +# CONFIG_BACKLIGHT_LV5207LP is not set +# CONFIG_BACKLIGHT_BD6107 is not set + +# +# Rockchip Misc Video driver +# +# CONFIG_FB_ROCKCHIP is not set +# CONFIG_LCDC_RK3188 is not set +# CONFIG_LCDC_RK3288 is not set +# CONFIG_LCDC_RK3036 is not set +# CONFIG_LCDC_RK312X is not set +CONFIG_LCD_GENERAL=y +# CONFIG_LCD_MIPI is not set +# CONFIG_RK_TRSM is not set +# CONFIG_RK_HDMI is not set + +# +# RGA +# +# CONFIG_ROCKCHIP_RGA is not set + +# +# RGA2 +# +CONFIG_ROCKCHIP_RGA2=y + +# +# VCODEC +# +CONFIG_RK_VCODEC=y + +# +# IEP +# +# CONFIG_IEP is not set +# CONFIG_IEP_MMU is not set + +# +# DP +# + +# +# ROCKCHIP_MPP +# +CONFIG_ROCKCHIP_MPP_SERVICE=y +# CONFIG_ROCKCHIP_MPP_DEVICE is not set +# CONFIG_VGASTATE is not set +CONFIG_VIDEOMODE_HELPERS=y +CONFIG_HDMI=y +CONFIG_HDMI_NOTIFIERS=y + +# +# Console display driver support +# +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +# CONFIG_LOGO is not set +CONFIG_SOUND=y +# CONFIG_SOUND_OSS_CORE is not set +CONFIG_SND=y +CONFIG_SND_TIMER=y +CONFIG_SND_PCM=y +CONFIG_SND_PCM_ELD=y +CONFIG_SND_PCM_IEC958=y +CONFIG_SND_DMAENGINE_PCM=y +CONFIG_SND_HWDEP=y +CONFIG_SND_RAWMIDI=y +CONFIG_SND_JACK=y +CONFIG_SND_SEQUENCER=y +CONFIG_SND_SEQ_DUMMY=y +# CONFIG_SND_MIXER_OSS is not set +# CONFIG_SND_PCM_OSS is not set +CONFIG_SND_PCM_TIMER=y +# CONFIG_SND_SEQUENCER_OSS is not set +CONFIG_SND_HRTIMER=y +CONFIG_SND_SEQ_HRTIMER_DEFAULT=y +CONFIG_SND_DYNAMIC_MINORS=y +CONFIG_SND_MAX_CARDS=32 +CONFIG_SND_SUPPORT_OLD_API=y +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_RAWMIDI_SEQ=y +# CONFIG_SND_OPL3_LIB_SEQ is not set +# CONFIG_SND_OPL4_LIB_SEQ is not set +# CONFIG_SND_SBAWE_SEQ is not set +# CONFIG_SND_EMU10K1_SEQ is not set +CONFIG_SND_DRIVERS=y +CONFIG_SND_DUMMY=m +CONFIG_SND_ALOOP=m +# CONFIG_SND_VIRMIDI is not set +# CONFIG_SND_MTPAV is not set +# CONFIG_SND_SERIAL_U16550 is not set +# CONFIG_SND_MPU401 is not set + +# +# HD-Audio +# +CONFIG_SND_HDA_PREALLOC_SIZE=2048 +CONFIG_SND_ARM=y +# CONFIG_SND_ARMAACI is not set +# CONFIG_SND_SPI is not set +CONFIG_SND_USB=y +CONFIG_SND_USB_AUDIO=y +CONFIG_SND_USB_UA101=y +CONFIG_SND_USB_CAIAQ=y +CONFIG_SND_USB_CAIAQ_INPUT=y +CONFIG_SND_USB_6FIRE=y +CONFIG_SND_USB_HIFACE=y +CONFIG_SND_BCD2000=y +CONFIG_SND_USB_LINE6=y +CONFIG_SND_USB_POD=y +CONFIG_SND_USB_PODHD=y +CONFIG_SND_USB_TONEPORT=y +CONFIG_SND_USB_VARIAX=y +CONFIG_SND_SOC=y +CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM=y +# CONFIG_SND_ATMEL_SOC is not set +# CONFIG_SND_DESIGNWARE_I2S 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_SSI is not set +# CONFIG_SND_SOC_FSL_SPDIF is not set +# CONFIG_SND_SOC_FSL_ESAI is not set +# CONFIG_SND_SOC_IMX_AUDMUX is not set +CONFIG_SND_SOC_ROCKCHIP=y +CONFIG_SND_SOC_ROCKCHIP_FORCE_SRAM=y +CONFIG_SND_SOC_ROCKCHIP_I2S=y +# CONFIG_SND_SOC_ROCKCHIP_I2S_TDM is not set +# CONFIG_SND_SOC_ROCKCHIP_MULTI_DAIS is not set +# CONFIG_SND_SOC_ROCKCHIP_PDM is not set +CONFIG_SND_SOC_ROCKCHIP_SPDIF=y +# CONFIG_SND_SOC_ROCKCHIP_SPDIFRX is not set +# CONFIG_SND_SOC_ROCKCHIP_VAD is not set +# CONFIG_SND_SOC_ROCKCHIP_DA7219 is not set +# CONFIG_SND_SOC_ROCKCHIP_HDMI_ANALOG is not set +# CONFIG_SND_SOC_ROCKCHIP_HDMI_DP is not set +CONFIG_SND_SOC_ROCKCHIP_MAX98090=y +# CONFIG_SND_SOC_ROCKCHIP_MULTICODECS is not set +CONFIG_SND_SOC_ROCKCHIP_RT5645=y +# CONFIG_SND_SOC_ROCKCHIP_RT5651_TC358749 is not set +# CONFIG_SND_SOC_ROCKCHIP_CDNDP is not set + +# +# Allwinner SoC Audio support +# +# CONFIG_SND_SUN4I_CODEC is not set +# CONFIG_SND_SOC_XTFPGA_I2S is not set +CONFIG_SND_SOC_I2C_AND_SPI=y + +# +# CODEC drivers +# +# CONFIG_SND_SOC_AC97_CODEC is not set +# CONFIG_SND_SOC_ADAU1701 is not set +# CONFIG_SND_SOC_AK4104 is not set +# CONFIG_SND_SOC_AK4554 is not set +# CONFIG_SND_SOC_AK4613 is not set +# CONFIG_SND_SOC_AK4642 is not set +# CONFIG_SND_SOC_AK5386 is not set +# CONFIG_SND_SOC_ALC5623 is not set +# CONFIG_SND_SOC_CS35L32 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_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_CS4349 is not set +# CONFIG_SND_SOC_CX2072X is not set +# CONFIG_SND_SOC_CX20810 is not set +# CONFIG_SND_SOC_DUMMY_CODEC is not set +# CONFIG_SND_SOC_BT_SCO is not set +# CONFIG_SND_SOC_ES8316 is not set +CONFIG_SND_SOC_ES8323=y +CONFIG_SND_SOC_HDMI_CODEC=y +# CONFIG_SND_SOC_ES8328 is not set +# CONFIG_SND_SOC_ES8328_I2C is not set +# CONFIG_SND_SOC_ES8396 is not set +# CONFIG_SND_SOC_GTM601 is not set +# CONFIG_SND_SOC_GVA_CODEC is not set +# CONFIG_SND_SOC_FM1288 is not set +CONFIG_SND_SOC_MAX98090=y +# CONFIG_SND_SOC_PCM1681 is not set +# CONFIG_SND_SOC_PCM1792A is not set +# CONFIG_SND_SOC_PCM512x_I2C is not set +# CONFIG_SND_SOC_PCM512x_SPI is not set +# CONFIG_SND_SOC_RK312X is not set +CONFIG_SND_SOC_RK3228=m +# CONFIG_SND_SOC_RK3308 is not set +# CONFIG_SND_SOC_RK3328 is not set +# CONFIG_SND_SOC_RK817 is not set +CONFIG_SND_SOC_RL6231=y +CONFIG_SND_SOC_RT5616=y +# CONFIG_SND_SOC_RT5631 is not set +CONFIG_SND_SOC_RT5640=y +CONFIG_SND_SOC_RT5645=y +# CONFIG_SND_SOC_RT5651 is not set +# CONFIG_SND_SOC_RT5677_SPI is not set +# CONFIG_SND_SOC_SGTL5000 is not set +# CONFIG_SND_SOC_SIRF_AUDIO_CODEC is not set +CONFIG_SND_SOC_SPDIF=y +# CONFIG_SND_SOC_SSM2602_SPI is not set +# CONFIG_SND_SOC_SSM2602_I2C is not set +# CONFIG_SND_SOC_SSM4567 is not set +# CONFIG_SND_SOC_STA32X is not set +# CONFIG_SND_SOC_STA350 is not set +# CONFIG_SND_SOC_STI_SAS is not set +# CONFIG_SND_SOC_TAS2552 is not set +# CONFIG_SND_SOC_TAS5086 is not set +# CONFIG_SND_SOC_TAS571X is not set +CONFIG_SND_SOC_TC358749X=m +# CONFIG_SND_SOC_TFA9879 is not set +# CONFIG_SND_SOC_TLV320AIC23_I2C is not set +# CONFIG_SND_SOC_TLV320AIC23_SPI is not set +# CONFIG_SND_SOC_TLV320AIC31XX is not set +# CONFIG_SND_SOC_TLV320AIC3X is not set +CONFIG_SND_SOC_TS3A227E=y +# CONFIG_SND_SOC_WM8510 is not set +# CONFIG_SND_SOC_WM8523 is not set +# CONFIG_SND_SOC_WM8580 is not set +# CONFIG_SND_SOC_WM8711 is not set +# CONFIG_SND_SOC_WM8728 is not set +# CONFIG_SND_SOC_WM8731 is not set +# CONFIG_SND_SOC_WM8737 is not set +# CONFIG_SND_SOC_WM8741 is not set +# CONFIG_SND_SOC_WM8750 is not set +# CONFIG_SND_SOC_WM8753 is not set +# CONFIG_SND_SOC_WM8770 is not set +# CONFIG_SND_SOC_WM8776 is not set +# CONFIG_SND_SOC_WM8804_I2C is not set +# CONFIG_SND_SOC_WM8804_SPI is not set +# CONFIG_SND_SOC_WM8903 is not set +# CONFIG_SND_SOC_WM8962 is not set +# CONFIG_SND_SOC_WM8978 is not set +# CONFIG_SND_SOC_TPA6130A2 is not set +CONFIG_SND_SIMPLE_CARD=y +# CONFIG_SOUND_PRIME is not set + +# +# HID support +# +CONFIG_HID=y +CONFIG_HID_BATTERY_STRENGTH=y +CONFIG_HIDRAW=y +CONFIG_UHID=y +CONFIG_HID_GENERIC=y + +# +# Special HID drivers +# +CONFIG_HID_A4TECH=m +CONFIG_HID_ACRUX=m +CONFIG_HID_ACRUX_FF=y +CONFIG_HID_APPLE=m +CONFIG_HID_APPLEIR=m +CONFIG_HID_AUREAL=m +CONFIG_HID_BELKIN=m +CONFIG_HID_BETOP_FF=m +CONFIG_HID_CHERRY=m +CONFIG_HID_CHICONY=m +CONFIG_HID_CORSAIR=m +CONFIG_HID_PRODIKEYS=m +CONFIG_HID_CP2112=m +CONFIG_HID_CYPRESS=m +CONFIG_HID_DRAGONRISE=m +CONFIG_DRAGONRISE_FF=y +CONFIG_HID_EMS_FF=m +CONFIG_HID_ELECOM=m +CONFIG_HID_ELO=m +CONFIG_HID_EZKEY=m +CONFIG_HID_GEMBIRD=m +CONFIG_HID_GFRM=m +CONFIG_HID_HOLTEK=m +CONFIG_HOLTEK_FF=y +CONFIG_HID_GT683R=m +CONFIG_HID_KEYTOUCH=m +CONFIG_HID_KYE=m +CONFIG_HID_UCLOGIC=m +CONFIG_HID_WALTOP=m +CONFIG_HID_GYRATION=m +CONFIG_HID_ICADE=m +CONFIG_HID_TWINHAN=m +CONFIG_HID_KENSINGTON=m +CONFIG_HID_LCPOWER=m +# CONFIG_HID_LENOVO is not set +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_MICROSOFT=m +CONFIG_HID_MONTEREY=m +CONFIG_HID_MULTITOUCH=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_LEDS=y +CONFIG_HID_PLANTRONICS=m +CONFIG_HID_PRIMAX=m +CONFIG_HID_ROCCAT=m +CONFIG_HID_SAITEK=m +CONFIG_HID_SAMSUNG=m +CONFIG_HID_SONY=m +CONFIG_SONY_FF=y +CONFIG_HID_SPEEDLINK=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_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_RKVR is not set +CONFIG_HID_ALPS=m + +# +# USB HID support +# +CONFIG_USB_HID=y +# CONFIG_HID_PID is not set +CONFIG_USB_HIDDEV=y + +# +# I2C HID support +# +CONFIG_I2C_HID=y +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +CONFIG_USB_SUPPORT=y +CONFIG_USB_COMMON=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB=y +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y + +# +# Miscellaneous USB options +# +# CONFIG_USB_DEFAULT_PERSIST is not set +# CONFIG_USB_DYNAMIC_MINORS is not set +CONFIG_USB_OTG=y +# CONFIG_USB_OTG_WHITELIST is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set +# CONFIG_USB_OTG_FSM is not set +# CONFIG_USB_ULPI_BUS is not set +CONFIG_USB_MON=y +# CONFIG_USB_WUSB_CBAF is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_C67X00_HCD is not set +# CONFIG_USB_XHCI_HCD is not set +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_EHCI_TT_NEWSCHED=y +CONFIG_USB_EHCI_HCD_PLATFORM=y +# CONFIG_USB_OXU210HP_HCD is not set +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_ISP1362_HCD is not set +# CONFIG_USB_FOTG210_HCD is not set +# CONFIG_USB_MAX3421_HCD is not set +CONFIG_USB_OHCI_HCD=y +CONFIG_USB_OHCI_HCD_PLATFORM=y +# CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set +# CONFIG_USB_HCD_TEST_MODE is not set + +# +# USB Device Class drivers +# +CONFIG_USB_ACM=y +# CONFIG_USB_PRINTER is not set +CONFIG_USB_WDM=y +# CONFIG_USB_TMC is not set + +# +# 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 is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_USBAT is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_STORAGE_ALAUDA is not set +# CONFIG_USB_STORAGE_ONETOUCH is not set +# CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set +# CONFIG_USB_STORAGE_ENE_UB6250 is not set +CONFIG_USB_UAS=m + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USBIP_CORE is not set +# CONFIG_USB_MUSB_HDRC is not set +# CONFIG_USB_DWC3 is not set +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_DEBUG is not set +# CONFIG_USB_DWC2_TRACK_MISSED_SOFS is not set +# CONFIG_USB_CHIPIDEA is not set +# CONFIG_USB_ISP1760 is not set + +# +# USB port drivers +# +CONFIG_USB_SERIAL=y +# CONFIG_USB_SERIAL_CONSOLE is not set +CONFIG_USB_SERIAL_GENERIC=y +# CONFIG_USB_SERIAL_SIMPLE is not set +# CONFIG_USB_SERIAL_AIRCABLE is not set +# CONFIG_USB_SERIAL_ARK3116 is not set +# CONFIG_USB_SERIAL_BELKIN is not set +CONFIG_USB_SERIAL_CH341=m +# CONFIG_USB_SERIAL_WHITEHEAT is not set +# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set +CONFIG_USB_SERIAL_CP210X=m +# CONFIG_USB_SERIAL_CYPRESS_M8 is not set +# CONFIG_USB_SERIAL_EMPEG is not set +CONFIG_USB_SERIAL_FTDI_SIO=m +# CONFIG_USB_SERIAL_VISOR is not set +# CONFIG_USB_SERIAL_IPAQ is not set +# CONFIG_USB_SERIAL_IR is not set +# CONFIG_USB_SERIAL_EDGEPORT is not set +# CONFIG_USB_SERIAL_EDGEPORT_TI is not set +# CONFIG_USB_SERIAL_F81232 is not set +# CONFIG_USB_SERIAL_GARMIN is not set +# CONFIG_USB_SERIAL_IPW is not set +# CONFIG_USB_SERIAL_IUU is not set +# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set +CONFIG_USB_SERIAL_KEYSPAN=y +# CONFIG_USB_SERIAL_KEYSPAN_MPR is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19QW is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19QI is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA49WLC is not set +# CONFIG_USB_SERIAL_KLSI is not set +# CONFIG_USB_SERIAL_KOBIL_SCT is not set +# CONFIG_USB_SERIAL_MCT_U232 is not set +# CONFIG_USB_SERIAL_METRO is not set +# CONFIG_USB_SERIAL_MOS7720 is not set +# CONFIG_USB_SERIAL_MOS7840 is not set +# CONFIG_USB_SERIAL_MXUPORT is not set +# CONFIG_USB_SERIAL_NAVMAN is not set +CONFIG_USB_SERIAL_PL2303=m +CONFIG_USB_SERIAL_OTI6858=y +# CONFIG_USB_SERIAL_QCAUX is not set +CONFIG_USB_SERIAL_QUALCOMM=y +# CONFIG_USB_SERIAL_SPCP8X5 is not set +# CONFIG_USB_SERIAL_SAFE is not set +CONFIG_USB_SERIAL_SIERRAWIRELESS=y +# CONFIG_USB_SERIAL_SYMBOL is not set +# CONFIG_USB_SERIAL_TI is not set +# CONFIG_USB_SERIAL_CYBERJACK is not set +# CONFIG_USB_SERIAL_XIRCOM is not set +CONFIG_USB_SERIAL_WWAN=y +CONFIG_USB_SERIAL_OPTION=y +# CONFIG_USB_SERIAL_OMNINET is not set +# CONFIG_USB_SERIAL_OPTICON is not set +# CONFIG_USB_SERIAL_XSENS_MT is not set +# CONFIG_USB_SERIAL_WISHBONE is not set +# CONFIG_USB_SERIAL_SSU100 is not set +# CONFIG_USB_SERIAL_QT2 is not set +# CONFIG_USB_SERIAL_DEBUG is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_SEVSEG is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_SISUSBVGA is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set +# CONFIG_USB_TEST is not set +# CONFIG_USB_EHSET_TEST_FIXTURE is not set +# CONFIG_USB_ISIGHTFW is not set +# CONFIG_USB_YUREX is not set +CONFIG_USB_EZUSB_FX2=y +# CONFIG_USB_HSIC_USB3503 is not set +# CONFIG_USB_LINK_LAYER_TEST is not set +# CONFIG_USB_CHAOSKEY is not set + +# +# USB Physical Layer drivers +# +# CONFIG_USB_PHY is not set +# CONFIG_USB_OTG_WAKELOCK is not set +# CONFIG_NOP_USB_XCEIV is not set +# CONFIG_USB_GPIO_VBUS is not set +# CONFIG_USB_ISP1301 is not set +# CONFIG_USB_ULPI is not set +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 + +# +# USB Peripheral Controller +# +# CONFIG_USB_FUSB300 is not set +# 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_M66592 is not set +# CONFIG_USB_BDC_UDC is not set +# CONFIG_USB_NET2272 is not set +# CONFIG_USB_GADGET_XILINX is not set +# CONFIG_USB_DUMMY_HCD is not set +CONFIG_USB_LIBCOMPOSITE=m +CONFIG_USB_F_FS=m +CONFIG_USB_CONFIGFS=m +# CONFIG_USB_CONFIGFS_SERIAL is not set +# CONFIG_USB_CONFIGFS_ACM is not set +# CONFIG_USB_CONFIGFS_OBEX is not set +# CONFIG_USB_CONFIGFS_NCM is not set +# CONFIG_USB_CONFIGFS_ECM is not set +# CONFIG_USB_CONFIGFS_ECM_SUBSET is not set +# CONFIG_USB_CONFIGFS_RNDIS is not set +# CONFIG_USB_CONFIGFS_EEM is not set +# CONFIG_USB_CONFIGFS_MASS_STORAGE is not set +# CONFIG_USB_CONFIGFS_F_LB_SS is not set +CONFIG_USB_CONFIGFS_F_FS=y +# CONFIG_USB_CONFIGFS_F_MTP is not set +# CONFIG_USB_CONFIGFS_F_ACC is not set +# CONFIG_USB_CONFIGFS_UEVENT is not set +# CONFIG_USB_CONFIGFS_F_UAC1 is not set +# CONFIG_USB_CONFIGFS_F_UAC1_LEGACY is not set +# CONFIG_USB_CONFIGFS_F_UAC2 is not set +# CONFIG_USB_CONFIGFS_F_MIDI is not set +# CONFIG_USB_CONFIGFS_F_HID is not set +# CONFIG_USB_CONFIGFS_F_UVC is not set +# CONFIG_USB_CONFIGFS_F_PRINTER is not set +# CONFIG_USB_ZERO is not set +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_ETH is not set +# CONFIG_USB_G_NCM is not set +# CONFIG_USB_GADGETFS is not set +# CONFIG_USB_FUNCTIONFS is not set +# CONFIG_USB_MASS_STORAGE is not set +# CONFIG_USB_G_SERIAL is not set +# CONFIG_USB_MIDI_GADGET is not set +# CONFIG_USB_G_PRINTER is not set +# CONFIG_USB_CDC_COMPOSITE is not set +# CONFIG_USB_G_ACM_MS is not set +# CONFIG_USB_G_MULTI is not set +# CONFIG_USB_G_HID is not set +# CONFIG_USB_G_DBGP is not set +# CONFIG_USB_G_WEBCAM is not set + +# +# ROCKCHIP USB Support +# +# CONFIG_USB20_HOST is not set +# CONFIG_USB20_OTG is not set +# CONFIG_USB_LED_TRIG is not set +# CONFIG_UWB is not set +CONFIG_MMC=y +# CONFIG_MMC_DEBUG is not set +# CONFIG_MMC_EMBEDDED_SDIO is not set +# CONFIG_MMC_PARANOID_SD_INIT is not set +CONFIG_PWRSEQ_EMMC=y +CONFIG_PWRSEQ_SIMPLE=y + +# +# MMC/SD/SDIO Card Drivers +# +CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_MINORS=16 +CONFIG_MMC_BLOCK_BOUNCE=y +# CONFIG_SDIO_UART is not set +CONFIG_MMC_TEST=y +# CONFIG_MMC_SIMULATE_MAX_SPEED is not set + +# +# MMC/SD/SDIO Host Controller Drivers +# +# CONFIG_MMC_ARMMMCI is not set +# CONFIG_MMC_SDHCI is not set +CONFIG_MMC_DW=y +CONFIG_MMC_DW_PLTFM=y +# CONFIG_MMC_DW_EXYNOS is not set +# CONFIG_MMC_DW_K3 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_MTK is not set +# CONFIG_MEMSTICK is not set +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y +# CONFIG_LEDS_CLASS_FLASH is not set + +# +# LED drivers +# +# CONFIG_LEDS_BCM6328 is not set +# CONFIG_LEDS_BCM6358 is not set +# CONFIG_LEDS_LM3530 is not set +# CONFIG_LEDS_LM3642 is not set +# CONFIG_LEDS_PCA9532 is not set +CONFIG_LEDS_GPIO=y +# CONFIG_LEDS_LP3944 is not set +# CONFIG_LEDS_LP5521 is not set +# CONFIG_LEDS_LP5523 is not set +# CONFIG_LEDS_LP5562 is not set +# CONFIG_LEDS_LP8501 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 is not set +# CONFIG_LEDS_REGULATOR is not set +# CONFIG_LEDS_BD2802 is not set +# CONFIG_LEDS_LT3593 is not set +# CONFIG_LEDS_TCA6507 is not set +# CONFIG_LEDS_TLC591XX is not set +# CONFIG_LEDS_LM355x 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 is not set + +# +# LED Triggers +# +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_TIMER=y +CONFIG_LEDS_TRIGGER_ONESHOT=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +CONFIG_LEDS_TRIGGER_BACKLIGHT=y +CONFIG_LEDS_TRIGGER_CPU=y +CONFIG_LEDS_TRIGGER_GPIO=y +CONFIG_LEDS_TRIGGER_DEFAULT_ON=y + +# +# iptables trigger is under Netfilter config (LED target) +# +CONFIG_LEDS_TRIGGER_TRANSIENT=y +# CONFIG_LEDS_TRIGGER_CAMERA is not set +CONFIG_LEDS_TRIGGER_MULTI_CTRL=m +# CONFIG_SWITCH is not set +# CONFIG_ACCESSIBILITY is not set +CONFIG_EDAC_ATOMIC_SCRUB=y +CONFIG_EDAC_SUPPORT=y +# CONFIG_EDAC is not set +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 + +# +# 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_ABX80X=y +CONFIG_RTC_DRV_DS1307=y +# CONFIG_RTC_DRV_DS1374 is not set +# CONFIG_RTC_DRV_DS1672 is not set +CONFIG_RTC_DRV_DS3232=y +CONFIG_RTC_DRV_FAKE=m +CONFIG_RTC_DRV_HYM8563=y +# CONFIG_RTC_DRV_MAX6900 is not set +CONFIG_RTC_DRV_RK808=y +# CONFIG_RTC_DRV_RK_TIMER is not set +# CONFIG_RTC_DRV_RS5C372 is not set +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_ISL12022 is not set +# CONFIG_RTC_DRV_ISL12057 is not set +# CONFIG_RTC_DRV_X1205 is not set +CONFIG_RTC_DRV_PCF2127=y +CONFIG_RTC_DRV_PCF8523=y +CONFIG_RTC_DRV_PCF8563=y +# CONFIG_RTC_DRV_PCF85063 is not set +CONFIG_RTC_DRV_PCF8583=y +CONFIG_RTC_DRV_M41T80=y +CONFIG_RTC_DRV_M41T80_WDT=y +# CONFIG_RTC_DRV_BQ32K is not set +# CONFIG_RTC_DRV_TPS6586X is not set +# CONFIG_RTC_DRV_S35390A is not set +# CONFIG_RTC_DRV_FM3130 is not set +# CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_RX8025 is not set +# CONFIG_RTC_DRV_EM3027 is not set +# CONFIG_RTC_DRV_RV3029C2 is not set +# CONFIG_RTC_DRV_RV8803 is not set + +# +# SPI RTC drivers +# +# CONFIG_RTC_DRV_M41T93 is not set +# CONFIG_RTC_DRV_M41T94 is not set +# CONFIG_RTC_DRV_DS1305 is not set +# CONFIG_RTC_DRV_DS1343 is not set +# CONFIG_RTC_DRV_DS1347 is not set +# CONFIG_RTC_DRV_DS1390 is not set +# CONFIG_RTC_DRV_MAX6902 is not set +# CONFIG_RTC_DRV_R9701 is not set +# CONFIG_RTC_DRV_RS5C348 is not set +# CONFIG_RTC_DRV_DS3234 is not set +# CONFIG_RTC_DRV_PCF2123 is not set +# CONFIG_RTC_DRV_RX4581 is not set +# CONFIG_RTC_DRV_MCP795 is not set + +# +# Platform RTC drivers +# +# CONFIG_RTC_DRV_CMOS is not set +# 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_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 + +# +# on-CPU RTC drivers +# +# CONFIG_RTC_DRV_PL030 is not set +# CONFIG_RTC_DRV_PL031 is not set +# CONFIG_RTC_DRV_SNVS is not set + +# +# HID Sensor RTC drivers +# +# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set +CONFIG_DMADEVICES=y +# CONFIG_DMADEVICES_DEBUG is not set + +# +# DMA Devices +# +CONFIG_DMA_ENGINE=y +CONFIG_DMA_OF=y +# CONFIG_AMBA_PL08X is not set +# CONFIG_FSL_EDMA is not set +# CONFIG_INTEL_IDMA64 is not set +# CONFIG_NBPFAXI_DMA is not set +CONFIG_PL330_DMA=y +# CONFIG_DW_DMAC is not set + +# +# DMA Clients +# +# CONFIG_ASYNC_TX_DMA is not set +# CONFIG_DMATEST is not set +# CONFIG_AUXDISPLAY is not set +# CONFIG_UIO is not set +# CONFIG_VFIO is not set +# CONFIG_VIRT_DRIVERS is not set + +# +# Virtio drivers +# +# CONFIG_VIRTIO_MMIO is not set + +# +# Microsoft Hyper-V guest support +# +CONFIG_STAGING=y +# CONFIG_PRISM2_USB is not set +# CONFIG_COMEDI is not set +# CONFIG_RTLLIB is not set +CONFIG_R8712U=m +CONFIG_R8188EU=m +CONFIG_88EU_AP_MODE=y +CONFIG_R8723AU=m +CONFIG_8723AU_AP_MODE=y +CONFIG_8723AU_BT_COEXIST=y +CONFIG_VT6656=m + +# +# IIO staging drivers +# + +# +# Accelerometers +# +# CONFIG_ADIS16201 is not set +# CONFIG_ADIS16203 is not set +# CONFIG_ADIS16204 is not set +# CONFIG_ADIS16209 is not set +# CONFIG_ADIS16220 is not set +# CONFIG_ADIS16240 is not set +# CONFIG_LIS3L02DQ is not set +# CONFIG_SCA3000 is not set + +# +# Analog to digital converters +# +# CONFIG_AD7606 is not set +# CONFIG_AD7780 is not set +# CONFIG_AD7816 is not set +# CONFIG_AD7192 is not set +# CONFIG_AD7280 is not set + +# +# Analog digital bi-direction converters +# +# CONFIG_ADT7316 is not set + +# +# Capacitance to digital converters +# +# CONFIG_AD7150 is not set +# CONFIG_AD7152 is not set +# CONFIG_AD7746 is not set + +# +# Direct Digital Synthesis +# +# CONFIG_AD9832 is not set +# CONFIG_AD9834 is not set + +# +# Digital gyroscope sensors +# +# CONFIG_ADIS16060 is not set + +# +# Network Analyzer, Impedance Converters +# +# CONFIG_AD5933 is not set +# CONFIG_INV_MPU_IIO is not set + +# +# Light sensors +# +CONFIG_SENSORS_ISL29018=y +# CONFIG_SENSORS_ISL29028 is not set +CONFIG_TSL2583=y +# CONFIG_TSL2x7x is not set + +# +# Magnetometer sensors +# +# CONFIG_SENSORS_HMC5843_I2C is not set +# CONFIG_SENSORS_HMC5843_SPI is not set + +# +# Active energy metering IC +# +# CONFIG_ADE7753 is not set +# CONFIG_ADE7754 is not set +# CONFIG_ADE7758 is not set +# CONFIG_ADE7759 is not set +# CONFIG_ADE7854 is not set + +# +# Resolver to digital converters +# +# CONFIG_AD2S90 is not set +# CONFIG_AD2S1200 is not set +# CONFIG_AD2S1210 is not set + +# +# Triggers - standalone +# +# CONFIG_IIO_PERIODIC_RTC_TRIGGER is not set +# CONFIG_IIO_SIMPLE_DUMMY is not set + +# +# Speakup console speech +# +# CONFIG_SPEAKUP is not set +# CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4 is not set +# CONFIG_STAGING_MEDIA is not set + +# +# Android +# +CONFIG_ASHMEM=y +# CONFIG_ANDROID_TIMED_OUTPUT is not set +# CONFIG_ANDROID_LOW_MEMORY_KILLER is not set +# CONFIG_SYNC is not set +# CONFIG_ION is not set +# CONFIG_FIQ_DEBUGGER is not set +# CONFIG_FIQ_WATCHDOG is not set +# CONFIG_RK_CONSOLE_THREAD is not set +# CONFIG_STAGING_BOARD is not set +# CONFIG_WIMAX_GDM72XX is not set +# CONFIG_LTE_GDM724X is not set +# CONFIG_LUSTRE_FS is not set +# CONFIG_DGAP is not set +# CONFIG_GS_FPGABOOT is not set +# CONFIG_COMMON_CLK_XLNX_CLKWZRD is not set +# CONFIG_FB_TFT is not set +# CONFIG_WILC1000_DRIVER is not set +# CONFIG_MOST is not set +# CONFIG_POWERVR_ROGUE_N is not set +# CONFIG_GOLDFISH is not set +CONFIG_CHROME_PLATFORMS=y +# CONFIG_CROS_EC_CHARDEV is not set +CONFIG_CROS_EC_PROTO=y +CONFIG_CLKDEV_LOOKUP=y +CONFIG_HAVE_CLK_PREPARE=y +CONFIG_COMMON_CLK=y + +# +# Common Clock Framework +# +CONFIG_COMMON_CLK_DEBUGFS=y +CONFIG_COMMON_CLK_RK808=y +# CONFIG_COMMON_CLK_SI5351 is not set +# CONFIG_COMMON_CLK_SI514 is not set +# CONFIG_COMMON_CLK_SI570 is not set +# CONFIG_COMMON_CLK_CDCE925 is not set +# CONFIG_CLK_QORIQ is not set +# CONFIG_COMMON_CLK_PWM is not set +# CONFIG_COMMON_CLK_PXA is not set +# CONFIG_COMMON_CLK_CDCE706 is not set +CONFIG_HWSPINLOCK=m + +# +# Hardware Spinlock drivers +# +CONFIG_HWSPINLOCK_ROCKCHIP=m + +# +# Clock Source drivers +# +CONFIG_CLKSRC_OF=y +CONFIG_CLKSRC_PROBE=y +CONFIG_DW_APB_TIMER=y +CONFIG_DW_APB_TIMER_OF=y +CONFIG_ROCKCHIP_TIMER=y +CONFIG_ARM_ARCH_TIMER=y +CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y +CONFIG_ARM_ARCH_TIMER_VCT_ACCESS=y +CONFIG_ARM_GLOBAL_TIMER=y +# CONFIG_ARM_TIMER_SP804 is not set +CONFIG_CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK=y +# CONFIG_ATMEL_PIT is not set +# CONFIG_SH_TIMER_CMT is not set +# CONFIG_SH_TIMER_MTU2 is not set +# CONFIG_SH_TIMER_TMU is not set +# CONFIG_EM_TIMER_STI is not set +CONFIG_MAILBOX=y +# CONFIG_ARM_MHU is not set +# CONFIG_PL320_MBOX is not set +# CONFIG_ALTERA_MBOX is not set +# CONFIG_MAILBOX_TEST is not set +# CONFIG_RK3368_MBOX is not set +CONFIG_IOMMU_API=y +CONFIG_IOMMU_SUPPORT=y + +# +# Generic IOMMU Pagetable Support +# +# CONFIG_IOMMU_IO_PGTABLE_LPAE is not set +CONFIG_IOMMU_IOVA=y +CONFIG_OF_IOMMU=y +CONFIG_IOMMU_DMA=y +CONFIG_ROCKCHIP_IOMMU=y +# CONFIG_RK_IOMMU is not set +# CONFIG_ARM_SMMU is not set + +# +# Remoteproc drivers +# +# CONFIG_STE_MODEM_RPROC is not set + +# +# Rpmsg drivers +# + +# +# SOC (System On Chip) specific Drivers +# +# CONFIG_SOC_BRCMSTB is not set + +# +# Rockchip CPU selection +# +CONFIG_CPU_RK312X=y +CONFIG_CPU_RK3036=y +CONFIG_CPU_RK30XX=y +CONFIG_CPU_RK3188=y +CONFIG_CPU_RK3288=y +CONFIG_CPU_RK322X=y +# CONFIG_CPU_RV110X is not set +# CONFIG_CPU_PX30 is not set +# CONFIG_CPU_RK1808 is not set +# CONFIG_CPU_RK3308 is not set +# CONFIG_CPU_RK3328 is not set +# CONFIG_CPU_RK3366 is not set +# CONFIG_CPU_RK3368 is not set +# CONFIG_CPU_RK3399 is not set +CONFIG_ANDROID_VERSION=0x07010000 +CONFIG_ROCKCHIP_CPUINFO=y +# CONFIG_ROCKCHIP_DEVICEINFO is not set +CONFIG_ROCKCHIP_IPA=y +CONFIG_ROCKCHIP_OPP=y +# CONFIG_ROCKCHIP_PM_TEST is not set +CONFIG_ROCKCHIP_GRF=y +CONFIG_ROCKCHIP_PM_DOMAINS=y +CONFIG_ROCKCHIP_PVTM=y +CONFIG_ROCKCHIP_SUSPEND_MODE=y +CONFIG_ROCKCHIP_SYSTEM_MONITOR=y +CONFIG_ROCKCHIP_VENDOR_STORAGE_UPDATE_LOADER=y +# CONFIG_SUNXI_SRAM is not set +# CONFIG_SOC_TI is not set +CONFIG_PM_DEVFREQ=y + +# +# DEVFREQ Governors +# +CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y +CONFIG_DEVFREQ_GOV_PERFORMANCE=y +CONFIG_DEVFREQ_GOV_POWERSAVE=y +CONFIG_DEVFREQ_GOV_USERSPACE=y + +# +# DEVFREQ Drivers +# +CONFIG_ARM_ROCKCHIP_BUS_DEVFREQ=y +CONFIG_ARM_ROCKCHIP_DMC_DEVFREQ=y +CONFIG_PM_DEVFREQ_EVENT=y +CONFIG_DEVFREQ_EVENT_ROCKCHIP_DFI=y +CONFIG_DEVFREQ_EVENT_ROCKCHIP_NOCP=y +CONFIG_EXTCON=y + +# +# Extcon Device Drivers +# +# CONFIG_EXTCON_ADC_JACK is not set +# CONFIG_EXTCON_GPIO is not set +# CONFIG_EXTCON_RT8973A is not set +# CONFIG_EXTCON_SM5502 is not set +# CONFIG_EXTCON_USB_GPIO is not set +CONFIG_MEMORY=y +# CONFIG_ARM_PL172_MPMC is not set +CONFIG_IIO=y +CONFIG_IIO_BUFFER=y +# CONFIG_IIO_BUFFER_CB is not set +CONFIG_IIO_KFIFO_BUF=y +CONFIG_IIO_TRIGGER=y +CONFIG_IIO_CONSUMERS_PER_TRIGGER=2 + +# +# Accelerometers +# +# CONFIG_BMA180 is not set +# CONFIG_BMC150_ACCEL is not set +# CONFIG_HID_SENSOR_ACCEL_3D is not set +# CONFIG_IIO_ST_ACCEL_3AXIS is not set +# CONFIG_KXSD9 is not set +# CONFIG_KXCJK1013 is not set +# CONFIG_MMA8452 is not set +# CONFIG_MMA9551 is not set +# CONFIG_MMA9553 is not set +# CONFIG_MXC4005 is not set +# CONFIG_STK8312 is not set +# CONFIG_STK8BA50 is not set + +# +# Analog to digital converters +# +# CONFIG_AD7266 is not set +# CONFIG_AD7291 is not set +# CONFIG_AD7298 is not set +# CONFIG_AD7476 is not set +# CONFIG_AD7791 is not set +# CONFIG_AD7793 is not set +# CONFIG_AD7887 is not set +# CONFIG_AD7923 is not set +# CONFIG_AD799X is not set +# CONFIG_CC10001_ADC is not set +# CONFIG_GPIO_MUXADC is not set +# CONFIG_HI8435 is not set +# CONFIG_MAX1027 is not set +# CONFIG_MAX1363 is not set +# CONFIG_MCP320X is not set +# CONFIG_MCP3422 is not set +# CONFIG_NAU7802 is not set +CONFIG_ROCKCHIP_SARADC=y +# CONFIG_TI_ADC081C is not set +# CONFIG_TI_ADC128S052 is not set +# CONFIG_VF610_ADC is not set + +# +# Amplifiers +# +# CONFIG_AD8366 is not set + +# +# Chemical Sensors +# +# CONFIG_VZ89X is not set + +# +# Hid Sensor IIO Common +# +# CONFIG_HID_SENSOR_IIO_COMMON is not set + +# +# SSP Sensor Common +# +# CONFIG_IIO_SSP_SENSORHUB is not set + +# +# 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_AD5504 is not set +# CONFIG_AD5624R_SPI is not set +# CONFIG_AD5686 is not set +# CONFIG_AD5755 is not set +# CONFIG_AD5764 is not set +# CONFIG_AD5791 is not set +# CONFIG_AD7303 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 + +# +# Frequency Synthesizers DDS/PLL +# + +# +# Clock Generator/Distribution +# +# CONFIG_AD9523 is not set + +# +# Phase-Locked Loop (PLL) frequency synthesizers +# +# CONFIG_ADF4350 is not set + +# +# Digital gyroscope sensors +# +# CONFIG_ADIS16080 is not set +# CONFIG_ADIS16130 is not set +# CONFIG_ADIS16136 is not set +# CONFIG_ADIS16260 is not set +# CONFIG_ADXRS450 is not set +# CONFIG_BMG160 is not set +# CONFIG_HID_SENSOR_GYRO_3D is not set +# CONFIG_IIO_ST_GYRO_3AXIS is not set +# CONFIG_ITG3200 is not set + +# +# Humidity sensors +# +# CONFIG_DHT11 is not set +# CONFIG_HDC100X is not set +# CONFIG_HTU21 is not set +# CONFIG_SI7005 is not set +# CONFIG_SI7020 is not set + +# +# Inertial measurement units +# +# CONFIG_ADIS16400 is not set +# CONFIG_ADIS16480 is not set +# CONFIG_KMX61 is not set +# CONFIG_INV_MPU6050_IIO is not set + +# +# Light sensors +# +# CONFIG_ADJD_S311 is not set +# CONFIG_AL3320A is not set +# CONFIG_APDS9300 is not set +# CONFIG_APDS9960 is not set +# CONFIG_BH1750 is not set +# CONFIG_CM32181 is not set +# CONFIG_CM3232 is not set +# CONFIG_CM3323 is not set +# CONFIG_CM36651 is not set +# CONFIG_GP2AP020A00F is not set +# CONFIG_ISL29125 is not set +# CONFIG_HID_SENSOR_ALS is not set +# CONFIG_HID_SENSOR_PROX is not set +# CONFIG_JSA1212 is not set +# CONFIG_RPR0521 is not set +# CONFIG_LTR501 is not set +# CONFIG_OPT3001 is not set +# CONFIG_PA12203001 is not set +# CONFIG_STK3310 is not set +# CONFIG_TCS3414 is not set +# CONFIG_TCS3472 is not set +CONFIG_SENSORS_TSL2563=y +# CONFIG_TSL4531 is not set +# CONFIG_US5182D is not set +# CONFIG_VCNL4000 is not set +CONFIG_VL6180=m + +# +# Magnetometer sensors +# +# CONFIG_AK8975 is not set +# CONFIG_AK09911 is not set +# CONFIG_BMC150_MAGN is not set +# CONFIG_MAG3110 is not set +# CONFIG_HID_SENSOR_MAGNETOMETER_3D is not set +# CONFIG_MMC35240 is not set +# CONFIG_IIO_ST_MAGN_3AXIS is not set + +# +# Inclinometer sensors +# +# CONFIG_HID_SENSOR_INCLINOMETER_3D is not set +# CONFIG_HID_SENSOR_DEVICE_ROTATION is not set + +# +# Triggers - standalone +# +# CONFIG_IIO_INTERRUPT_TRIGGER is not set +CONFIG_IIO_SYSFS_TRIGGER=y + +# +# Digital potentiometers +# +# CONFIG_MCP4531 is not set + +# +# Pressure sensors +# +# CONFIG_BMP280 is not set +# CONFIG_HID_SENSOR_PRESS is not set +# CONFIG_MPL115 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 + +# +# Lightning sensors +# +# CONFIG_AS3935 is not set + +# +# Proximity sensors +# +# CONFIG_LIDAR_LITE_V2 is not set +# CONFIG_SRF04 is not set +# CONFIG_SX9500 is not set + +# +# Temperature sensors +# +# CONFIG_MLX90614 is not set +# CONFIG_TMP006 is not set +# CONFIG_TSYS01 is not set +# CONFIG_TSYS02D is not set +CONFIG_PWM=y +CONFIG_PWM_SYSFS=y +# CONFIG_PWM_CROS_EC is not set +# CONFIG_PWM_FSL_FTM is not set +CONFIG_PWM_GPIO=m +# CONFIG_PWM_PCA9685 is not set +CONFIG_PWM_ROCKCHIP=y +CONFIG_PWM_ROCKCHIP_I2S=m +CONFIG_IRQCHIP=y +CONFIG_ARM_GIC=y +# CONFIG_IPACK_BUS is not set +CONFIG_ARCH_HAS_RESET_CONTROLLER=y +CONFIG_RESET_CONTROLLER=y +# CONFIG_FMC is not set + +# +# PHY Subsystem +# +CONFIG_GENERIC_PHY=y +# CONFIG_PHY_PXA_28NM_HSIC is not set +# CONFIG_PHY_PXA_28NM_USB2 is not set +# CONFIG_BCM_KONA_USB2_PHY is not set +# CONFIG_PHY_SAMSUNG_USB2 is not set +CONFIG_PHY_ROCKCHIP_USB=y +# CONFIG_PHY_ROCKCHIP_INNO_COMBPHY is not set +CONFIG_PHY_ROCKCHIP_INNO_USB2=y +# CONFIG_PHY_ROCKCHIP_INNO_USB3 is not set +CONFIG_PHY_ROCKCHIP_EMMC=y +CONFIG_PHY_ROCKCHIP_DP=y +CONFIG_PHY_ROCKCHIP_MIPI_RX=y +# CONFIG_PHY_ROCKCHIP_INNO_MIPI_DPHY is not set +CONFIG_PHY_ROCKCHIP_INNO_HDMI_PHY=y +# CONFIG_PHY_ROCKCHIP_INNO_VIDEO_PHY is not set +# CONFIG_PHY_ROCKCHIP_INNO_VIDEO_COMBO_PHY is not set +# CONFIG_PHY_ROCKCHIP_TYPEC is not set +# CONFIG_PHY_ROCKCHIP_PCIE is not set +# CONFIG_POWERCAP is not set +# CONFIG_MCB is not set + +# +# Performance monitor support +# +CONFIG_ARM_PMU=y +# CONFIG_RAS is not set + +# +# Android +# +CONFIG_ANDROID=y +# CONFIG_ANDROID_BINDER_IPC is not set +CONFIG_NVMEM=y +CONFIG_ROCKCHIP_EFUSE=y +CONFIG_ROCKCHIP_OTP=m +# CONFIG_STM is not set +# CONFIG_INTEL_TH is not set + +# +# FPGA Configuration Support +# +# CONFIG_FPGA is not set +CONFIG_TEE=m + +# +# TEE drivers +# +CONFIG_OPTEE=m +CONFIG_RK_FLASH=y + +# +# Rockchip Flash Devices +# +# CONFIG_RK_SFC_NOR is not set +CONFIG_RK_NAND=y + +# +# Headset device support +# +# CONFIG_RK_HEADSET is not set + +# +# Firmware Drivers +# +CONFIG_ARM_PSCI_FW=y +# CONFIG_FIRMWARE_MEMMAP is not set +CONFIG_HAVE_ARM_SMCCC=y +CONFIG_ROCKCHIP_SIP=y + +# +# File systems +# +CONFIG_DCACHE_WORD_ACCESS=y +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +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_ENCRYPTION is not set +# CONFIG_EXT4_DEBUG is not set +CONFIG_JBD2=y +# CONFIG_JBD2_DEBUG is not set +CONFIG_FS_MBCACHE=y +CONFIG_REISERFS_FS=y +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +# CONFIG_REISERFS_FS_XATTR is not set +CONFIG_JFS_FS=y +# CONFIG_JFS_POSIX_ACL is not set +# CONFIG_JFS_SECURITY is not set +# CONFIG_JFS_DEBUG is not set +# CONFIG_JFS_STATISTICS is not set +CONFIG_XFS_FS=y +# CONFIG_XFS_QUOTA is not set +# CONFIG_XFS_POSIX_ACL is not set +# CONFIG_XFS_RT is not set +# CONFIG_XFS_WARN is not set +# CONFIG_XFS_DEBUG is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_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_NILFS2_FS is not set +# CONFIG_F2FS_FS is not set +CONFIG_FS_POSIX_ACL=y +CONFIG_EXPORTFS=y +CONFIG_FILE_LOCKING=y +# CONFIG_FS_ENCRYPTION is not set +CONFIG_FSNOTIFY=y +CONFIG_DNOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_FANOTIFY is not set +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_FUSE_FS=m +CONFIG_CUSE=m +CONFIG_OVERLAY_FS=m + +# +# Caches +# +CONFIG_FSCACHE=m +# CONFIG_FSCACHE_STATS is not set +# CONFIG_FSCACHE_HISTOGRAM is not set +# CONFIG_FSCACHE_DEBUG is not set +# CONFIG_FSCACHE_OBJECT_LIST is not set +# CONFIG_CACHEFILES is not set + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=y +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +CONFIG_UDF_FS=y +CONFIG_UDF_NLS=y + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +CONFIG_NTFS_FS=y +# CONFIG_NTFS_DEBUG is not set +CONFIG_NTFS_RW=y + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y +# CONFIG_PROC_CHILDREN is not set +CONFIG_PROC_UID=y +CONFIG_KERNFS=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_TMPFS_XATTR=y +# CONFIG_HUGETLB_PAGE is not set +CONFIG_CONFIGFS_FS=y +CONFIG_MISC_FILESYSTEMS=y +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +CONFIG_ECRYPT_FS=y +# CONFIG_ECRYPT_FS_MESSAGING is not set +# CONFIG_SDCARD_FS is not set +# CONFIG_HFS_FS is not set +CONFIG_HFSPLUS_FS=y +# CONFIG_HFSPLUS_FS_POSIX_ACL is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_LOGFS is not set +# CONFIG_CRAMFS is not set +CONFIG_SQUASHFS=y +CONFIG_SQUASHFS_DECOMP_SINGLE=y +# CONFIG_SQUASHFS_DECOMP_MULTI is not set +# CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU is not set +# CONFIG_SQUASHFS_XATTR is not set +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 is not set +# CONFIG_SQUASHFS_EMBEDDED is not set +CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 +# CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_OMFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX6FS_FS is not set +# CONFIG_ROMFS_FS is not set +CONFIG_PSTORE=y +CONFIG_PSTORE_CONSOLE=y +# CONFIG_PSTORE_PMSG is not set +# CONFIG_PSTORE_FTRACE is not set +CONFIG_PSTORE_RAM=y +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V2=m +CONFIG_NFS_V3=y +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=y +CONFIG_NFS_SWAP=y +CONFIG_NFS_V4_1=y +CONFIG_NFS_V4_2=y +CONFIG_PNFS_FILE_LAYOUT=y +CONFIG_PNFS_BLOCK=y +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_ROOT_NFS=y +CONFIG_NFS_USE_LEGACY_DNS=y +CONFIG_NFS_DEBUG=y +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_V4_SECURITY_LABEL=y +CONFIG_NFSD_FAULT_INJECTION=y +CONFIG_GRACE_PERIOD=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_ACL_SUPPORT=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +CONFIG_SUNRPC_GSS=y +CONFIG_SUNRPC_BACKCHANNEL=y +CONFIG_SUNRPC_SWAP=y +CONFIG_SUNRPC_DEBUG=y +CONFIG_CEPH_FS=m +CONFIG_CEPH_FSCACHE=y +CONFIG_CEPH_FS_POSIX_ACL=y +CONFIG_CIFS=m +CONFIG_CIFS_STATS=y +# CONFIG_CIFS_STATS2 is not set +# CONFIG_CIFS_WEAK_PW_HASH is not set +CONFIG_CIFS_UPCALL=y +CONFIG_CIFS_XATTR=y +CONFIG_CIFS_POSIX=y +CONFIG_CIFS_ACL=y +# CONFIG_CIFS_DEBUG is not set +# CONFIG_CIFS_DFS_UPCALL is not set +CONFIG_CIFS_SMB2=y +CONFIG_CIFS_SMB311=y +CONFIG_CIFS_FSCACHE=y +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set +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=y +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=y +# CONFIG_DLM is not set + +# +# Kernel hacking +# + +# +# printk and dmesg options +# +CONFIG_PRINTK_TIME=y +# CONFIG_PRINTK_PROCESS is not set +CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4 +# CONFIG_BOOT_PRINTK_DELAY is not set +# CONFIG_DYNAMIC_DEBUG is not set + +# +# Compile-time checks and compiler options +# +# CONFIG_DEBUG_INFO is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 +# CONFIG_STRIP_ASM_SYMS is not set +# CONFIG_READABLE_ASM is not set +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_PAGE_OWNER is not set +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_SECTION_MISMATCH is not set +CONFIG_SECTION_MISMATCH_WARN_ONLY=y +CONFIG_FRAME_POINTER=y +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set +CONFIG_MAGIC_SYSRQ=y +CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0 +CONFIG_DEBUG_KERNEL=y + +# +# Memory Debugging +# +# CONFIG_PAGE_EXTENSION is not set +# CONFIG_DEBUG_PAGEALLOC 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_DEBUG_VM is not set +# CONFIG_DEBUG_MEMORY_INIT is not set +# CONFIG_DEBUG_PER_CPU_MAPS is not set +# CONFIG_DEBUG_HIGHMEM is not set +# CONFIG_DEBUG_SHIRQ is not set + +# +# Debug Lockups and Hangs +# +CONFIG_LOCKUP_DETECTOR=y +CONFIG_HARDLOCKUP_DETECTOR_OTHER_CPU=y +CONFIG_HARDLOCKUP_DETECTOR=y +# CONFIG_BOOTPARAM_HARDLOCKUP_PANIC is not set +CONFIG_BOOTPARAM_HARDLOCKUP_PANIC_VALUE=0 +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC=y +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=1 +CONFIG_DETECT_HUNG_TASK=y +CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=120 +CONFIG_BOOTPARAM_HUNG_TASK_PANIC=y +CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=1 +# CONFIG_PANIC_ON_OOPS is not set +CONFIG_PANIC_ON_OOPS_VALUE=0 +CONFIG_PANIC_TIMEOUT=0 +CONFIG_SCHED_DEBUG=y +CONFIG_SCHED_INFO=y +# CONFIG_PANIC_ON_RT_THROTTLING is not set +CONFIG_SCHEDSTATS=y +# CONFIG_SCHED_STACK_END_CHECK is not set +# CONFIG_DEBUG_TIMEKEEPING is not set +CONFIG_TIMER_STATS=y + +# +# Lock Debugging (spinlocks, mutexes, etc...) +# +# CONFIG_DEBUG_RT_MUTEXES is not set +CONFIG_DEBUG_SPINLOCK=y +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT 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_STACKTRACE=y +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_PI_LIST is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +CONFIG_DEBUG_CREDENTIALS=y + +# +# RCU Debugging +# +# CONFIG_PROVE_RCU is not set +# CONFIG_SPARSE_RCU_POINTER is not set +# CONFIG_TORTURE_TEST is not set +# CONFIG_RCU_TORTURE_TEST is not set +CONFIG_RCU_CPU_STALL_TIMEOUT=60 +# CONFIG_RCU_TRACE is not set +# CONFIG_RCU_EQS_DEBUG is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_NOTIFIER_ERROR_INJECTION is not set +# CONFIG_FAULT_INJECTION 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_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_GENERIC_TRACER=y +CONFIG_TRACING_SUPPORT=y +CONFIG_FTRACE=y +CONFIG_FUNCTION_TRACER=y +CONFIG_FUNCTION_GRAPH_TRACER=y +# CONFIG_PREEMPTIRQ_EVENTS is not set +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_SCHED_TRACER 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_PROFILE_ALL_BRANCHES is not set +# CONFIG_STACK_TRACER is not set +CONFIG_BLK_DEV_IO_TRACE=y +# CONFIG_UPROBE_EVENT is not set +# CONFIG_PROBE_EVENTS is not set +CONFIG_DYNAMIC_FTRACE=y +# CONFIG_FUNCTION_PROFILER is not set +CONFIG_FTRACE_MCOUNT_RECORD=y +# CONFIG_FTRACE_STARTUP_TEST is not set +# CONFIG_TRACEPOINT_BENCHMARK is not set +# CONFIG_RING_BUFFER_BENCHMARK is not set +# CONFIG_RING_BUFFER_STARTUP_TEST is not set +# CONFIG_TRACE_ENUM_MAP_FILE is not set +CONFIG_TRACING_EVENTS_GPIO=y + +# +# Runtime Testing +# +CONFIG_LKDTM=y +# CONFIG_TEST_LIST_SORT is not set +# CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_RBTREE_TEST is not set +# CONFIG_INTERVAL_TREE_TEST is not set +# CONFIG_PERCPU_TEST is not set +# CONFIG_ATOMIC64_SELFTEST is not set +# CONFIG_TEST_HEXDUMP is not set +# CONFIG_TEST_STRING_HELPERS is not set +# CONFIG_TEST_KSTRTOX is not set +# CONFIG_TEST_PRINTF is not set +# CONFIG_TEST_RHASHTABLE is not set +# CONFIG_TEST_HASH is not set +# CONFIG_DMA_API_DEBUG is not set +# CONFIG_TEST_LKM is not set +# CONFIG_TEST_USER_COPY is not set +# CONFIG_TEST_BPF is not set +# CONFIG_TEST_FIRMWARE is not set +CONFIG_TEST_UDELAY=y +# CONFIG_MEMTEST is not set +# CONFIG_TEST_STATIC_KEYS is not set +# CONFIG_BUG_ON_DATA_CORRUPTION is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_KGDB is not set +# CONFIG_ARM_PTDUMP is not set +CONFIG_STRICT_DEVMEM=y +CONFIG_ARM_UNWIND=y +CONFIG_OLD_MCOUNT=y +# CONFIG_DEBUG_USER is not set +# CONFIG_DEBUG_LL is not set +CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S" +# CONFIG_DEBUG_UART_8250 is not set +CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h" +# CONFIG_PID_IN_CONTEXTIDR is not set +CONFIG_DEBUG_SET_MODULE_RONX=y +# CONFIG_CORESIGHT is not set + +# +# Security options +# +CONFIG_KEYS=y +# CONFIG_PERSISTENT_KEYRINGS is not set +# CONFIG_BIG_KEYS is not set +# CONFIG_TRUSTED_KEYS is not set +# CONFIG_ENCRYPTED_KEYS is not set +# CONFIG_SECURITY_DMESG_RESTRICT is not set +# CONFIG_SECURITY_PERF_EVENTS_RESTRICT is not set +CONFIG_SECURITY=y +CONFIG_SECURITYFS=y +CONFIG_SECURITY_NETWORK=y +# CONFIG_SECURITY_NETWORK_XFRM is not set +CONFIG_SECURITY_PATH=y +CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR=y +CONFIG_HAVE_ARCH_HARDENED_USERCOPY=y +# CONFIG_HARDENED_USERCOPY is not set +# CONFIG_SECURITY_SMACK is not set +# CONFIG_SECURITY_TOMOYO is not set +# CONFIG_SECURITY_APPARMOR is not set +CONFIG_SECURITY_YAMA=y +# CONFIG_TEE_SUPPORT is not set +CONFIG_INTEGRITY=y +# CONFIG_INTEGRITY_SIGNATURE is not set +# CONFIG_IMA is not set +# CONFIG_EVM is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" +CONFIG_XOR_BLOCKS=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_BLKCIPHER=y +CONFIG_CRYPTO_BLKCIPHER2=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG=y +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_RNG_DEFAULT=y +CONFIG_CRYPTO_PCOMP2=y +CONFIG_CRYPTO_AKCIPHER2=y +CONFIG_CRYPTO_AKCIPHER=y +# CONFIG_CRYPTO_RSA is not set +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y +# CONFIG_CRYPTO_USER is not set +CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y +CONFIG_CRYPTO_GF128MUL=y +CONFIG_CRYPTO_NULL=y +CONFIG_CRYPTO_NULL2=y +# CONFIG_CRYPTO_PCRYPT is not set +CONFIG_CRYPTO_WORKQUEUE=y +CONFIG_CRYPTO_CRYPTD=m +# CONFIG_CRYPTO_MCRYPTD is not set +CONFIG_CRYPTO_AUTHENC=y +# CONFIG_CRYPTO_TEST is not set +CONFIG_CRYPTO_ABLK_HELPER=m + +# +# Authenticated Encryption with Associated Data +# +CONFIG_CRYPTO_CCM=y +CONFIG_CRYPTO_GCM=y +# CONFIG_CRYPTO_CHACHA20POLY1305 is not set +CONFIG_CRYPTO_SEQIV=y +CONFIG_CRYPTO_ECHAINIV=y + +# +# Block modes +# +CONFIG_CRYPTO_CBC=y +# CONFIG_CRYPTO_HEH is not set +CONFIG_CRYPTO_CTR=y +# CONFIG_CRYPTO_CTS is not set +CONFIG_CRYPTO_ECB=y +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_XTS is not set +# CONFIG_CRYPTO_KEYWRAP is not set + +# +# Hash modes +# +CONFIG_CRYPTO_CMAC=y +CONFIG_CRYPTO_HMAC=y +# CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_VMAC is not set + +# +# Digest +# +CONFIG_CRYPTO_CRC32C=y +# CONFIG_CRYPTO_CRC32 is not set +CONFIG_CRYPTO_CRCT10DIF=y +CONFIG_CRYPTO_GHASH=y +# CONFIG_CRYPTO_POLY1305 is not set +CONFIG_CRYPTO_MD4=y +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_MICHAEL_MIC=y +# CONFIG_CRYPTO_RMD128 is not set +# CONFIG_CRYPTO_RMD160 is not set +# CONFIG_CRYPTO_RMD256 is not set +# CONFIG_CRYPTO_RMD320 is not set +CONFIG_CRYPTO_SHA1=y +CONFIG_CRYPTO_SHA256=y +CONFIG_CRYPTO_SHA512=y +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_WP512 is not set + +# +# Ciphers +# +CONFIG_CRYPTO_AES=y +# CONFIG_CRYPTO_ANUBIS is not set +CONFIG_CRYPTO_ARC4=y +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_CHACHA20 is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_TWOFISH is not set + +# +# Compression +# +CONFIG_CRYPTO_DEFLATE=y +# CONFIG_CRYPTO_ZLIB is not set +CONFIG_CRYPTO_LZO=m +# CONFIG_CRYPTO_842 is not set +CONFIG_CRYPTO_LZ4=m +# CONFIG_CRYPTO_LZ4HC is not set +# CONFIG_CRYPTO_ZSTD is not set + +# +# Random Number Generation +# +# CONFIG_CRYPTO_ANSI_CPRNG is not set +CONFIG_CRYPTO_DRBG_MENU=y +CONFIG_CRYPTO_DRBG_HMAC=y +# CONFIG_CRYPTO_DRBG_HASH is not set +# CONFIG_CRYPTO_DRBG_CTR is not set +CONFIG_CRYPTO_DRBG=y +CONFIG_CRYPTO_JITTERENTROPY=y +CONFIG_CRYPTO_USER_API=y +CONFIG_CRYPTO_USER_API_HASH=y +CONFIG_CRYPTO_USER_API_SKCIPHER=y +# CONFIG_CRYPTO_USER_API_RNG is not set +# CONFIG_CRYPTO_USER_API_AEAD is not set +CONFIG_CRYPTO_HASH_INFO=y +CONFIG_CRYPTO_HW=y +# CONFIG_CRYPTO_DEV_ROCKCHIP_V1 is not set +# CONFIG_CRYPTO_DEV_ROCKCHIP_V2 is not set +CONFIG_ASYMMETRIC_KEY_TYPE=y +CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=y +CONFIG_PUBLIC_KEY_ALGO_RSA=y +CONFIG_X509_CERTIFICATE_PARSER=y +CONFIG_PKCS7_MESSAGE_PARSER=y +# CONFIG_PKCS7_TEST_KEY is not set +# CONFIG_SIGNED_PE_FILE_VERIFICATION is not set + +# +# Certificates for signature checking +# +CONFIG_SYSTEM_TRUSTED_KEYRING=y +CONFIG_SYSTEM_TRUSTED_KEYS="" +CONFIG_ARM_CRYPTO=y +CONFIG_CRYPTO_SHA1_ARM=m +CONFIG_CRYPTO_SHA1_ARM_NEON=m +# CONFIG_CRYPTO_SHA1_ARM_CE is not set +# CONFIG_CRYPTO_SHA2_ARM_CE is not set +CONFIG_CRYPTO_SHA256_ARM=m +CONFIG_CRYPTO_SHA512_ARM=m +CONFIG_CRYPTO_AES_ARM=m +CONFIG_CRYPTO_AES_ARM_BS=m +# CONFIG_CRYPTO_AES_ARM_CE is not set +# CONFIG_CRYPTO_GHASH_ARM_CE is not set +CONFIG_BINARY_PRINTF=y + +# +# Library routines +# +CONFIG_RAID6_PQ=y +CONFIG_BITREVERSE=y +CONFIG_HAVE_ARCH_BITREVERSE=y +CONFIG_RATIONAL=y +CONFIG_GENERIC_STRNCPY_FROM_USER=y +CONFIG_GENERIC_STRNLEN_USER=y +CONFIG_GENERIC_NET_UTILS=y +CONFIG_GENERIC_PCI_IOMAP=y +CONFIG_GENERIC_IO=y +CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y +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_CRC7=y +CONFIG_LIBCRC32C=y +# CONFIG_CRC8 is not set +CONFIG_XXHASH=y +# CONFIG_AUDIT_ARCH_COMPAT_GENERIC is not set +# CONFIG_RANDOM32_SELFTEST is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_LZO_COMPRESS=y +CONFIG_LZO_DECOMPRESS=y +CONFIG_LZ4_COMPRESS=m +CONFIG_LZ4_DECOMPRESS=y +CONFIG_ZSTD_DECOMPRESS=y +CONFIG_XZ_DEC=y +# CONFIG_XZ_DEC_X86 is not set +# CONFIG_XZ_DEC_POWERPC is not set +# CONFIG_XZ_DEC_IA64 is not set +CONFIG_XZ_DEC_ARM=y +CONFIG_XZ_DEC_ARMTHUMB=y +# CONFIG_XZ_DEC_SPARC is not set +CONFIG_XZ_DEC_BCJ=y +# CONFIG_XZ_DEC_TEST is not set +CONFIG_DECOMPRESS_GZIP=y +CONFIG_DECOMPRESS_XZ=y +CONFIG_DECOMPRESS_LZ4=y +CONFIG_GENERIC_ALLOCATOR=y +CONFIG_REED_SOLOMON=y +CONFIG_REED_SOLOMON_ENC8=y +CONFIG_REED_SOLOMON_DEC8=y +CONFIG_TEXTSEARCH=y +CONFIG_TEXTSEARCH_KMP=m +CONFIG_TEXTSEARCH_BM=m +CONFIG_TEXTSEARCH_FSM=m +CONFIG_ASSOCIATIVE_ARRAY=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT_MAP=y +CONFIG_HAS_DMA=y +CONFIG_CPU_RMAP=y +CONFIG_DQL=y +CONFIG_NLATTR=y +CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y +CONFIG_CLZ_TAB=y +# CONFIG_CORDIC is not set +# CONFIG_DDR is not set +CONFIG_MPILIB=y +CONFIG_LIBFDT=y +CONFIG_OID_REGISTRY=y +CONFIG_FONT_SUPPORT=y +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +# CONFIG_SG_SPLIT is not set +CONFIG_ARCH_HAS_SG_CHAIN=y +# CONFIG_VIRTUALIZATION is not set diff --git a/config/sources/families/rk322x.conf b/config/sources/families/rk322x.conf new file mode 100644 index 0000000000..fe77b16ecb --- /dev/null +++ b/config/sources/families/rk322x.conf @@ -0,0 +1,120 @@ +BOOTSCRIPT="boot-rk322x.cmd:boot.cmd" +BOOTENV_FILE='rk322x-default.txt' +OVERLAY_PREFIX='rk322x' +UBOOT_TARGET_MAP="all u-boot.itb;;u-boot-rk322x-with-spl.bin" +UBOOT_USE_GCC='< 9.0' +BOOTDELAY=0 +BOOTBRANCH='tag:v2020.04' + +SERIALCON=ttyS2 + +case $BRANCH in + + legacy) + + KERNELSOURCE='https://github.com/rockchip-linux/kernel.git' + KERNELBRANCH='branch:stable-4.4-rk3288-linux-v2.x' + KERNELDIR='linux-rockchip' + KERNEL_USE_GCC='> 8.0' + + ;; + + current) + + KERNELBRANCH='branch:linux-5.6.y' + AUFS=no + + ;; + + dev) + + KERNELBRANCH='branch:master' + + ;; + +esac + +CPUMIN="600000" +CPUMAX="1500000" +GOVERNOR="ondemand" + +write_uboot_platform() +{ + dd if=/dev/zero of=$2 bs=1k count=1023 seek=1 status=noxfer > /dev/null 2>&1 + dd if=$1/u-boot-rk322x-with-spl.bin of=$2 seek=64 conv=notrunc > /dev/null 2>&1 +} + +uboot_custom_postprocess() +{ + + # We use the rockchip proprietary blob to initialize memory chips + # instead of letting u-boot doing the job. Such devices, like xt-mx4vr-v01, have DDR2 + # or LPDDR2 memories and the blob is better suited for the job. + # Also it may come handy when there are different memory flavours among boards, with + # different timings, specs and frequencies. + # The rockchip proprietary blob is a drop-in substitute for the u-boot tpl. + # In case you want to use the u-boot TPL remember to set the proper timing + # registers in device tree and this command line instead of the other one: + # + # tools/mkimage -n rk322x -T rksd -d tpl/u-boot-tpl.bin u-boot-rk322x-with-spl.bin + # + + tools/mkimage -n rk322x -T rksd -d $SRC/packages/blobs/rockchip/rk322x_ddr2_300_ddr3_600_v1.09.bin u-boot-rk322x-with-spl.bin + cat spl/u-boot-spl.bin >> u-boot-rk322x-with-spl.bin + dd if=u-boot.itb of=u-boot-rk322x-with-spl.bin seek=$((0x200 - 0x40)) conv=notrunc + +} + +family_tweaks() +{ + + true + +} + +family_tweaks_bsp() +{ + #Graphics and media + mkdir -p $destination/etc/udev/rules.d + mkdir -p $destination/usr/local/bin + cp $SRC/packages/bsp/rockchip/hdmi.rules $destination/etc/udev/rules.d + cp $SRC/packages/bsp/rockchip/50-hevc.rules $destination/etc/udev/rules.d + cp $SRC/packages/bsp/rockchip/50-mali.rules $destination/etc/udev/rules.d + cp $SRC/packages/bsp/rockchip/50-vpu.rules $destination/etc/udev/rules.d + cp $SRC/packages/bsp/rk322x/50-rkvdec.rules $destination/etc/udev/rules.d + cp $SRC/packages/bsp/rockchip/60-media.rules $destination/etc/udev/rules.d + install -m 755 $SRC/packages/bsp/rockchip/hdmi-hotplug $destination/usr/local/bin + + # Peripheral access for specific groups + addgroup --system --quiet --gid 997 gpio + addgroup --system --quiet --gid 998 i2c + cp $SRC/packages/bsp/rockchip/70-gpio.rules $destination/etc/udev/rules.d + cp $SRC/packages/bsp/rockchip/71-i2c.rules $destination/etc/udev/rules.d + + # Bluetooth + install -m 755 $SRC/packages/bsp/rockchip/rtk_hciattach $destination/usr/bin + install -m 755 $SRC/packages/bsp/rockchip/start_bt.sh $destination/usr/local/bin + cp $SRC/packages/bsp/rockchip/tinker-bluetooth.service $destination/lib/systemd/system/ + + # Sound + cp $SRC/packages/bsp/rockchip/asound.conf $destination/etc/ + cp $SRC/packages/bsp/rockchip/89-pulseaudio-usb.rules $destination/etc/udev/rules.d + + # For rk322x boards copy ssv6051 wifi firmware files to /etc/firmware + # We don't want to copy it into /lib/firmware to not interfere with armbian + # firmware deb package, so for now put them in a separate position + mkdir -p $destination/etc/firmware + cp $SRC/packages/blobs/ssv6051/ssv6051-wifi.cfg $destination/etc/firmware + cp $SRC/packages/blobs/ssv6051/ssv6051-sw.bin $destination/etc/firmware + echo "options ssv6051 stacfgpath=/etc/firmware/ssv6051-wifi.cfg cfgfirmwarepath=/etc/firmware/" > $destination/etc/modprobe.d/ssv6051.conf + + # Board selection script + install -m 755 $SRC/packages/bsp/rk322x/rk322x-config $destination/usr/local/bin + + # Fix for bad device detection for x.org when lima driver is in use + if [[ "$BRANCH" != "legacy" ]]; then + mkdir -p $destination/etc/X11/xorg.conf.d + cp $SRC/packages/bsp/rk322x/40-serverflags.conf $destination/etc/X11/xorg.conf.d + fi + +} diff --git a/config/targets.conf b/config/targets.conf index 3c1c50dac9..1112d1e92f 100644 --- a/config/targets.conf +++ b/config/targets.conf @@ -738,6 +738,13 @@ renegade current focal desktop stable yes renegade legacy bionic desktop stable yes renegade current bionic desktop stable yes +# rk322x-box + +rk322x-box legacy buster cli stable yes +rk322x-box legacy focal desktop stable yes +rk322x-box current buster minimal stable yes +rk322x-box current focal desktop stable yes + # Rock64 rock64 legacy buster cli stable yes @@ -845,3 +852,5 @@ xt-q8l-v10 current focal cli stable yes z28pro legacy buster cli stable yes z28pro legacy bionic desktop stable yes z28pro legacy focal desktop stable yes + + diff --git a/lib/compilation-prepare.sh b/lib/compilation-prepare.sh index e005ad93c5..bdb4522040 100644 --- a/lib/compilation-prepare.sh +++ b/lib/compilation-prepare.sh @@ -57,7 +57,7 @@ compilation_prepare() process_patch_file "${SRC}/patch/misc/general-packaging-4.4.y-rockchip64.patch" "applying" fi - if [[ $version == "4.4."* ]] && [[ "$LINUXFAMILY" == rockchip ]]; then + if [[ $version == "4.4."* ]] && [[ "$LINUXFAMILY" == rockchip || "$LINUXFAMILY" == rk322x ]]; then display_alert "Adjustin" "packaging" "info" cd ${SRC}/cache/sources/${LINUXSOURCEDIR} process_patch_file "${SRC}/patch/misc/general-packaging-4.4.y.patch" "applying" diff --git a/packages/blobs/rockchip/rk322x_ddr2_300_ddr3_600_v1.09.bin b/packages/blobs/rockchip/rk322x_ddr2_300_ddr3_600_v1.09.bin new file mode 100644 index 0000000000..4820365929 Binary files /dev/null and b/packages/blobs/rockchip/rk322x_ddr2_300_ddr3_600_v1.09.bin differ diff --git a/packages/blobs/ssv6051/ssv6051-sw.bin b/packages/blobs/ssv6051/ssv6051-sw.bin new file mode 100644 index 0000000000..8ca0a3726c Binary files /dev/null and b/packages/blobs/ssv6051/ssv6051-sw.bin differ diff --git a/packages/blobs/ssv6051/ssv6051-wifi.cfg b/packages/blobs/ssv6051/ssv6051-wifi.cfg new file mode 100644 index 0000000000..c072960f6d --- /dev/null +++ b/packages/blobs/ssv6051/ssv6051-wifi.cfg @@ -0,0 +1,91 @@ +############################################################ +# ROCKCHIP RK3X28 & RK322X +# WIFI-CONFIGURATION +################################################## + +################################################## +# Firmware setting +# Priority.1 insmod parameter "cfgfirmwarepath" +# Priority.2 firmware_path +# Priority.3 default firmware +################################################## +firmware_path = /vendor/etc/firmware/ + +############################################################ +# MAC address +# +# Priority 1. From wifi.cfg [ hw_mac & hw_mac_2 ] +# +# Priority 2. From e-fuse[ON/OFF switch by wifi.cfg] +# +# Priority 3. From insert module parameter +# +# Priority 4. From external file path +# path only support some special charater "_" ":" "/" "." "-" +# +# Priority 5. Default[Software mode] +# +# 0. => 00:33:33:33:33:33 +# 1. => Always random +# 2. => First random and write to file[Default path mac_output_path] +# +############################################################ +ignore_efuse_mac = 0 +#mac_address_path = /xxxx/xxxx +mac_address_mode = 2 +mac_output_path = /data/wifimac + +################################################## +# Hardware setting +# +#volt regulator(DCDC-0 LDO-1) +# +################################################## +xtal_clock = 24 +volt_regulator = 1 + +################################################## +# Default channel after wifi on +# value range: [1 ~ 14] +################################################## +def_chan = 6 +################################################## +# Hardware Capability Settings: +################################################## +hw_cap_ht = on +hw_cap_gf = off +hw_cap_2ghz = on +hw_cap_5ghz = off +hw_cap_security = on +hw_cap_sgi_20 = on +hw_cap_sgi_40 = off +hw_cap_ap = on +hw_cap_p2p = on +hw_cap_ampdu_rx = on +hw_cap_ampdu_tx = on +use_wpa2_only = 1 +################################################## +# TX power level setting [0-14] +# The larger the number the smaller the TX power +# 0 - The maximum power +# 1 level = -0.5db +# +# 6051Z .. 4 or 4 +# 6051Q .. 2 or 5 +# 6051P .. 0 or 0 +# +################################################## +#wifi_tx_gain_level_b = 2 +#wifi_tx_gain_level_gn = 5 +################################################ +# Signal strength control +# rssi control +#rssi_ctl = 10 + + +################################################## +# Import extenal configuration(UP to 64 groups) +# example: +# register = CE010010:91919191 +# register = 00CC0010:00091919 +################################################## diff --git a/packages/bsp/common/usr/lib/armbian/armbian-hardware-optimization b/packages/bsp/common/usr/lib/armbian/armbian-hardware-optimization index f38c4c5f39..ddf512436b 100755 --- a/packages/bsp/common/usr/lib/armbian/armbian-hardware-optimization +++ b/packages/bsp/common/usr/lib/armbian/armbian-hardware-optimization @@ -139,6 +139,27 @@ prepare_board() { echo 8 >/proc/irq/$i/smp_affinity done ;; + rk322x) # RK322x: usb otg on cpu1, usb2,3,4 (EHCI), usb5,6,7 (OHCI) on cpu2, eth and GPU on cpu3 + echo 2 >/proc/irq/$(awk -F":" "/:usb1/ {print \$1}" /proc/irq/$(awk -F":" "/:usb2/ {print \$1}" /proc/irq/$(awk -F":" "/:usb3/ {print \$1}" /proc/irq/$(awk -F":" "/:usb4/ {print \$1}" /proc/irq/$(awk -F":" "/:usb5/ {print \$1}" /proc/irq/$(awk -F":" "/:usb6/ {print \$1}" /proc/irq/$(awk -F":" "/:usb7/ {print \$1}" /proc/irq/$(awk -F":" "/eth0/ {print \$1}" /sys/class/net/eth0/queues/rx-0/rps_cpus + + # Mali in 4.4 kernel + for i in $(awk -F':' '/Mali_/{print $1}' /proc/interrupts | sed 's/\ //g'); do + echo 8 >/proc/irq/$i/smp_affinity + done + + # Lima in mainline kernel + echo 8 >/proc/irq/$(awk -F':' '/gp$/{print $1}' /proc/interrupts | sed 's/\ //g')/smp_affinity + echo 8 >/proc/irq/$(awk -F':' '/gpmmu/{print $1}' /proc/interrupts | sed 's/\ //g')/smp_affinity + echo 8 >/proc/irq/$(awk -F':' '/pp0/{print $1}' /proc/interrupts | sed 's/\ //g')/smp_affinity + ;; rockchip64) # Rock64 and Renegade: GPU on cpu1, USB3 on cpu2, Ethernet on cpu3 for i in $(awk -F':' '/Mali/{print $1}' /proc/irq/$i/smp_affinity diff --git a/packages/bsp/rk322x/40-serverflags.conf b/packages/bsp/rk322x/40-serverflags.conf new file mode 100644 index 0000000000..e40e146a02 --- /dev/null +++ b/packages/bsp/rk322x/40-serverflags.conf @@ -0,0 +1,10 @@ +Section "ServerFlags" + Option "AutoAddGPU" "off" +EndSection + +Section "Device" + Identifier "meson" + Driver "modesetting" + Option "kmsdev" "/dev/dri/card0" +EndSection + diff --git a/packages/bsp/rk322x/50-rkvdec.rules b/packages/bsp/rk322x/50-rkvdec.rules new file mode 100644 index 0000000000..fad19e9d58 --- /dev/null +++ b/packages/bsp/rk322x/50-rkvdec.rules @@ -0,0 +1 @@ +KERNEL=="rkvdec", MODE="0660", GROUP="video" diff --git a/packages/bsp/rk322x/rk322x-config b/packages/bsp/rk322x/rk322x-config new file mode 100755 index 0000000000..c44a6a66f9 --- /dev/null +++ b/packages/bsp/rk322x/rk322x-config @@ -0,0 +1,405 @@ +#!/bin/bash + +DEVICE_TREE_PATH="/boot/dtb" +DEVICE_TREE_GLOB="rk322*-box*.dtb" +ARMBIAN_ENV_TXT="/boot/armbianEnv.txt" +BLACKLIST_MODPROBE_CONF="/etc/modprobe.d/blacklist-rk322x-box.conf" + +BACKTITLE="Armbian RK322x device tree board selection | Paolo Sabatino" +TITLE="Board configuration" +MENU_TITLE="Please choose your board" + +CONFIRM_FLASH_MISMATCH="\nYour board has a type of internal memory but you \ +selected a board without support for that.\n\nYou will not be able to detect \ +the internal memory and your system may not boot anymore\n\nAre you sure?" + +COLOR_RED="\Z1" +COLOR_BLACK="\Z0" + +EFUSE_PATH="/sys/bus/nvmem/devices/rockchip-efuse0/nvmem" +SDIO_WIFI_PATH="/sys/bus/sdio/devices/mmc1:0001:1" + +EMMC_DEVICE_PATH="/sys/bus/mmc/devices/mmc2:0001" +NAND_DEVICE_PATH="/sys/block/rknand0/device" + +declare -A CHIP_IDS +declare -A WIFI_NAMES +declare -A WIFI_CHIPS + +declare -A DT_FLASH_OVERLAYS +declare -A DT_LED_OVERLAYS +declare -A DT_CPU_OVERLAYS + +# Declarations for the various SoCs IDs +CHIP_IDS+=(["524b2382"]="RK3228A/B") +CHIP_IDS+=(["524b2392"]="RK3229") + +# Declarations for the various Wifi IDs +WIFI_NAMES+=(["3030:3030"]="South Silicon Valley 6051p/6256p") +WIFI_NAMES+=(["024c:b703"]="Realtek RTL8703bs") +WIFI_NAMES+=(["024c:8179"]="Realtek RTL8189ES/ETV") + +# Declarations for the various wifi IDs -> kernel modules +WIFI_CHIPS+=(["3030:3030"]=ssv6051) +WIFI_CHIPS+=(["024c:b703"]=8723cs) +WIFI_CHIPS+=(["024c:8179"]=8189es) + +# Declarations for device tree overlays +DT_FLASH_OVERLAYS+=(["emmc"]="eMMC only flash memory") +DT_FLASH_OVERLAYS+=(["nand"]="NAND only flash memory") +DT_FLASH_OVERLAYS+=(["emmc-nand"]="eMMC or NAND flash memory") + +DT_LED_OVERLAYS+=(["led-conf1"]="LED configuration #1 (Chiptrip)") +DT_LED_OVERLAYS+=(["led-conf2"]="LED configuration #2 (R329q)") + +DT_CPU_OVERLAYS+=(["cpu-hs"]="RK3228B or RK3229") + +KERNEL_VERSION=$(uname -r | cut -d "-" -f 1) +if [[ "$KERNEL_VERSION" < "4.5.0" ]]; then + LEGACY_KERNEL=1 +else + LEGACY_KERNEL=0 +fi + +DT_OVERLAY_PREFIX="$(grep overlay_prefix /boot/armbianEnv.txt | cut -d "=" -f 2)-" + +# Query the efuse to get the chip type. +# Not always reliable, but often. +function get_chip_type() { + + CHIP_ID=$(od -A none -N 4 -tx1 $EFUSE_PATH | tr -d " ") + + CHIP_TYPE=${CHIP_IDS[$CHIP_ID]} + CHIP_TYPE=${CHIP_TYPE:-"unknown"} + + echo $CHIP_TYPE + + return 0 + +} + +# Get the chip serial, from bytes 7 to 22 of the efuse +function get_chip_serial() { + + ASCII_PART=$(od -A none -j 7 -N 9 -tc $EFUSE_PATH | tr -d " ") + BIN_PART=$(od -A none -j 16 -N 7 -tx1 $EFUSE_PATH | tr -d " ") + + echo "$ASCII_PART $BIN_PART" + + return 0 + +} + +# Get the cpu leakage, byte 23 of the efuse +function get_cpu_leakage() { + + LEAKAGE=$(od -A none -j 23 -N 1 -tx1 $EFUSE_PATH | tr -d " ") + + echo $LEAKAGE + + return 0 + +} + +# Get the logic leakage, byte 25 of the efuse +function get_logic_leakage() { + + LEAKAGE=$(od -A none -j 25 -N 1 -tx1 $EFUSE_PATH | tr -d " ") + + echo $LEAKAGE + + return 0 + +} + +# Get the vendor and device ids of the wifi chip +function get_wifi_chip_id() { + + if [ -d "$SDIO_WIFI_PATH" ]; then + + VENDOR=$(cut -c 3- "$SDIO_WIFI_PATH/vendor") + DEVICE=$(cut -c 3- "$SDIO_WIFI_PATH/device") + + echo "$VENDOR:$DEVICE" + + return 0 + + fi + + return 1 + +} + +function get_internal_flash_type() { + + if [ -d "$EMMC_DEVICE_PATH" ]; then + echo "eMMC" + elif [ -d "$NAND_DEVICE_PATH" ]; then + echo "NAND" + fi + + return 0 + +} + +# Blacklists all the modules buth whitelist only that one +# that has been detected +function apply_wifi_blacklist() { + + WIFI_ID=$1 + + # Detect wifi chip on legacy kernel and unblacklist it + WIFI_MODULE="" + + if [ -n "$WIFI_ID" ]; then + + # blacklist all the modules and unblacklist only the one which is matching + WIFI_MODULE="${WIFI_CHIPS[$WIFI_ID]}" + + if [ ! -f $BLACKLIST_MODPROBE_CONF ]; then + touch $BLACKLIST_MODPROBE_CONF + fi + + if [ -n "$WIFI_MODULE" ]; then + + for MODULE in "${WIFI_CHIPS[@]}"; do + sed -i "/blacklist $MODULE/d" $BLACKLIST_MODPROBE_CONF + done + + declare -A BLACKLIST_MODULES + + for VALUE in "${WIFI_CHIPS[@]}"; do + if [ "$VALUE" != "$WIFI_MODULE" ]; then + BLACKLIST_MODULES+=([$VALUE]=1) + fi + done + + for MODULE in "${!BLACKLIST_MODULES[@]}"; do + echo "blacklist $MODULE" >> $BLACKLIST_MODPROBE_CONF + done + + echo "#blacklist $WIFI_MODULE" >> $BLACKLIST_MODPROBE_CONF + + fi + + fi + + # unsupported wifi_chip_type: blacklist all known wifi + # modules if the blacklist file exists. If the blacklist file does not exist just skip over + if [ -z $WIFI_MODULE ]; then + + if [ -f $BLACKLIST_MODPROBE_CONF ]; then + + for MODULE in "${WIFI_CHIPS[@]}"; do + sed -i "s/#blacklist $MODULE/blacklist $MODULE/g" $BLACKLIST_MODPROBE_CONF + done + + fi + + fi + + echo $WIFI_MODULE + + return 0 + +} + +function select_soc() { + + declare -a DIALOG_ENTRIES + + # SoC section + + SELECTION="0" + [[ "$CHIP_TYPE" = "RK3229" ]] && SELECTION="2" + + DIALOG_ENTRIES=("0" "RK3228A (max 1.2Ghz)") + DIALOG_ENTRIES+=("1" "RK3228B (max 1.4Ghz)") + DIALOG_ENTRIES+=("2" "RK3229 (max 1.4Ghz)") + + MENU_TITLE="${BOARD_INFO}Select the SoC type\n" + + MENU_CMD=(dialog --colors --backtitle "$BACKTITLE" --title "$TITLE" --default-item "$SELECTION" --menu "$MENU_TITLE" 24 0 20) + + SELECTION=$("${MENU_CMD[@]}" "${DIALOG_ENTRIES[@]}" 2>&1 >/dev/tty) + + RET=$? + + if [ "$RET" -eq 1 ]; then + echo "Cancelled" + return 1 + fi + + if [ "$RET" -ne 0 ]; then + echo "dialog utility returned an unexpected error code: $RET" + return 1 + fi + + [[ "$SELECTION" -eq 0 ]] && SELECTION="" + [[ "$SELECTION" -eq 1 ]] && SELECTION="cpu-hs" + [[ "$SELECTION" -eq 2 ]] && SELECTION="cpu-hs" + + echo $SELECTION + + return 0 + + +} + +function select_flash() { + + declare -a DIALOG_ENTRIES + + SELECTION="emmc-nand" + [[ "$FLASH_TYPE" = "eMMC" ]] && SELECTION="emmc" + [[ "$FLASH_TYPE" = "NAND" ]] && SELECTION="nand" + + for KEY in "${!DT_FLASH_OVERLAYS[@]}"; do + DIALOG_ENTRIES+=($KEY "${DT_FLASH_OVERLAYS[$KEY]}") + done + + MENU_TITLE="${BOARD_INFO}Select the internal flash type\n" + + MENU_CMD=(dialog --colors --backtitle "$BACKTITLE" --title "$TITLE" --default-item "$SELECTION" --menu "$MENU_TITLE" 24 0 20) + + SELECTION=$("${MENU_CMD[@]}" "${DIALOG_ENTRIES[@]}" 2>&1 >/dev/tty) + + RET=$? + + if [ "$RET" -eq 1 ]; then + echo "Cancelled" + return 1 + fi + + if [ "$RET" -ne 0 ]; then + echo "dialog utility returned an unexpected error code: $RET" + return 1 + fi + + echo $SELECTION + + return 0 + +} + +function select_led_configuration() { + + declare -a DIALOG_ENTRIES + + for KEY in "${!DT_LED_OVERLAYS[@]}"; do + DIALOG_ENTRIES+=($KEY "${DT_LED_OVERLAYS[$KEY]}") + done + + MENU_TITLE="${BOARD_INFO}Select the led wiring configuation\n" + + MENU_CMD=(dialog --colors --backtitle "$BACKTITLE" --title "$TITLE" --default-item "$SELECTION" --menu "$MENU_TITLE" 24 0 20) + + SELECTION=$("${MENU_CMD[@]}" "${DIALOG_ENTRIES[@]}" 2>&1 >/dev/tty) + + RET=$? + + if [ "$RET" -eq 1 ]; then + echo "Cancelled" + return 1 + fi + + if [ "$RET" -ne 0 ]; then + echo "dialog utility returned an unexpected error code: $RET" + return 1 + fi + + echo $SELECTION + + return 0 + + +} + + +# ----- Entry point ----- + +USER_ID=$(id -u) +if [ $USER_ID -ne 0 ]; then + echo "Please run this script with administrative privileges" + exit 2 +fi + +declare -a DT_OVERLAYS_TO_APPLY + +CHIP_TYPE=$(get_chip_type) +CHIP_SERIAL=$(get_chip_serial) +CPU_LEAKAGE=$(get_cpu_leakage) +LOGIC_LEAKAGE=$(get_logic_leakage) +WIFI_ID=$(get_wifi_chip_id) +FLASH_TYPE=$(get_internal_flash_type) + +if [ -z "$WIFI_ID" ]; then + WIFI_NAME="not available" +else + WIFI_NAME="${WIFI_NAMES[$WIFI_ID]:-"unknown"} - Device ID: ${WIFI_ID}" +fi + +if [ -z "$FLASH_TYPE" ]; then + FLASH_NAME="not detected" +else + FLASH_NAME="$FLASH_TYPE" +fi + +BOARD_INFO="\nDetected board features:\n\ +Chip type: ${COLOR_RED}\Zb${CHIP_TYPE}\Zn${COLOR_BLACK} - \ +Serial: $CHIP_SERIAL\n\ +CPU Leakage: 0x$CPU_LEAKAGE - Logic Leakage: 0x$LOGIC_LEAKAGE\n\ +Internal flash: ${COLOR_RED}\Zb${FLASH_NAME}\Zn${COLOR_BLACK}\n\ +Wifi device: $WIFI_NAME\n\n" + +### --- SOC selection --- + +SELECTION=$(select_soc) || exit 1 +DT_OVERLAYS_TO_APPLY+=($SELECTION) + +SELECTION=$(select_flash) || exit 1 +DT_OVERLAYS_TO_APPLY+=($SELECTION) + +SELECTION=$(select_led_configuration) || exit 1 +DT_OVERLAYS_TO_APPLY+=($SELECTION) + +sed -i '/^overlays=/d' $ARMBIAN_ENV_TXT + +if [ $? -ne 0 ]; then + echo "An error occurred while removing existing fdtfile entry from $ARMBIAN_ENV_TXT" + exit 1 +fi + +echo "overlays=${DT_OVERLAYS_TO_APPLY[@]}" >> $ARMBIAN_ENV_TXT + +if [ $? -ne 0 ]; then + echo "An error occurred while adding overlays entry in $ARMBIAN_ENV_TXT" + exit 1 +fi + +# Apply the wifi blacklist only with legacy kernel +if [[ $LEGACY_KERNEL -eq 1 ]]; then + WIFI_MODULE=$(apply_wifi_blacklist "$WIFI_ID") +fi + +echo "" +echo "" +echo "Device tree overlays enabled: ${DT_OVERLAYS_TO_APPLY[@]}" + +# Print the outcome of wifi chip selection only with legacy kernel +# Mainline kernel is supposed to work ok by itself with hardware recognition +if [[ $LEGACY_KERNEL -eq 1 ]]; then + + if [ -n "$WIFI_MODULE" ]; then + echo "Enabled wifi module $WIFI_MODULE" + fi + + if [ -n "$WIFI_ID" ] && [ -z "$WIFI_MODULE" ]; then + echo "Wifi chip $WIFI_ID has been detected, but currently it is unsupported" + echo "Please report to: https://forum.armbian.com/topic/12656-wip-armbian-for-rk322x-devices/" + fi + +fi + +echo "Reboot the device to make changes effective!" +echo "" diff --git a/packages/bsp/rockchip/50-mali.rules b/packages/bsp/rockchip/50-mali.rules index 039a7f09c2..9d12c63742 100644 --- a/packages/bsp/rockchip/50-mali.rules +++ b/packages/bsp/rockchip/50-mali.rules @@ -1 +1,2 @@ -KERNEL=="mali0", MODE="0660", GROUP="video" \ No newline at end of file +KERNEL=="mali0", MODE="0660", GROUP="video" +KERNEL=="mali", MODE="0660", GROUP="video" diff --git a/patch/kernel/rk322x-current/01-linux-0003-rockchip-from-list.patch b/patch/kernel/rk322x-current/01-linux-0003-rockchip-from-list.patch new file mode 100644 index 0000000000..179cc50180 --- /dev/null +++ b/patch/kernel/rk322x-current/01-linux-0003-rockchip-from-list.patch @@ -0,0 +1,2372 @@ +diff --git a/drivers/media/rc/keymaps/Makefile b/drivers/media/rc/keymaps/Makefile +index aaa1bf81d00d..c903112fc0c1 100644 +--- a/drivers/media/rc/keymaps/Makefile ++++ b/drivers/media/rc/keymaps/Makefile +@@ -79,6 +79,7 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \ + rc-npgtech.o \ + rc-odroid.o \ + rc-pctv-sedna.o \ ++ rc-pine64.o \ + rc-pinnacle-color.o \ + rc-pinnacle-grey.o \ + rc-pinnacle-pctv-hd.o \ +diff --git a/drivers/media/rc/keymaps/rc-pine64.c b/drivers/media/rc/keymaps/rc-pine64.c +new file mode 100644 +index 000000000000..94e5624f63f4 +--- /dev/null ++++ b/drivers/media/rc/keymaps/rc-pine64.c +@@ -0,0 +1,59 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++// Keytable for Pine64 IR Remote Controller ++// Copyright (c) 2017 Jonas Karlman ++ ++#include ++#include ++ ++static struct rc_map_table pine64[] = { ++ { 0x404000, KEY_NUMERIC_0 }, ++ { 0x404001, KEY_NUMERIC_1 }, ++ { 0x404002, KEY_NUMERIC_2 }, ++ { 0x404003, KEY_NUMERIC_3 }, ++ { 0x404004, KEY_NUMERIC_4 }, ++ { 0x404005, KEY_NUMERIC_5 }, ++ { 0x404006, KEY_NUMERIC_6 }, ++ { 0x404007, KEY_NUMERIC_7 }, ++ { 0x404008, KEY_NUMERIC_8 }, ++ { 0x404009, KEY_NUMERIC_9 }, ++ { 0x40400a, KEY_MUTE }, ++ { 0x40400b, KEY_UP }, ++ { 0x40400c, KEY_BACKSPACE }, ++ { 0x40400d, KEY_OK }, ++ { 0x40400e, KEY_DOWN }, ++ { 0x404010, KEY_LEFT }, ++ { 0x404011, KEY_RIGHT }, ++ { 0x404017, KEY_VOLUMEDOWN }, ++ { 0x404018, KEY_VOLUMEUP }, ++ { 0x40401a, KEY_HOME }, ++ { 0x40401d, KEY_MENU }, ++ { 0x40401f, KEY_WWW }, ++ { 0x404045, KEY_BACK }, ++ { 0x404047, KEY_CONTEXT_MENU }, ++ { 0x40404d, KEY_POWER }, ++}; ++ ++static struct rc_map_list pine64_map = { ++ .map = { ++ .scan = pine64, ++ .size = ARRAY_SIZE(pine64), ++ .rc_proto = RC_PROTO_NECX, ++ .name = RC_MAP_PINE64, ++ } ++}; ++ ++static int __init init_rc_map_pine64(void) ++{ ++ return rc_map_register(&pine64_map); ++} ++ ++static void __exit exit_rc_map_pine64(void) ++{ ++ rc_map_unregister(&pine64_map); ++} ++ ++module_init(init_rc_map_pine64) ++module_exit(exit_rc_map_pine64) ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Jonas Karlman"); +diff --git a/include/media/rc-map.h b/include/media/rc-map.h +index d22810dcd85c..bd1f4f4347d5 100644 +--- a/include/media/rc-map.h ++++ b/include/media/rc-map.h +@@ -233,6 +233,7 @@ struct rc_map *rc_map_get(const char *name); + #define RC_MAP_NPGTECH "rc-npgtech" + #define RC_MAP_ODROID "rc-odroid" + #define RC_MAP_PCTV_SEDNA "rc-pctv-sedna" ++#define RC_MAP_PINE64 "rc-pine64" + #define RC_MAP_PINNACLE_COLOR "rc-pinnacle-color" + #define RC_MAP_PINNACLE_GREY "rc-pinnacle-grey" + #define RC_MAP_PINNACLE_PCTV_HD "rc-pinnacle-pctv-hd" +-- +2.17.1 + + +From 64be34f37bf89d457bc4352f8f8c663a30464a40 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Wed, 7 Aug 2019 15:11:23 +0000 +Subject: [PATCH] ASoC: hdmi-codec: reorder channel allocation list + +Wrong channel allocation is selected by hdmi_codec_get_ch_alloc_table_idx(). + +E.g when ELD reports FL|FR|LFE|FC|RL|RR or FL|FR|LFE|FC|RL|RR|RC|RLC|RRC + +ca_id 0x01 with speaker mask FL|FR|LFE gets selected instead of +ca_id 0x03 with speaker mask FL|FR|LFE|FC for 4 channels + +and + +ca_id 0x04 with speaker mask FL|FR|RC gets selected instead of +ca_id 0x0b with speaker mask FL|FR|LFE|FC|RL|RR for 6 channels + +Fix this by reorder the channel allocation list with +most specific speaker mask at the top. + +Signed-off-by: Jonas Karlman +--- + sound/soc/codecs/hdmi-codec.c | 115 ++++++++++++++++------------------ + 1 file changed, 53 insertions(+), 62 deletions(-) + +diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c +index f005751da2cc..437759e5f459 100644 +--- a/sound/soc/codecs/hdmi-codec.c ++++ b/sound/soc/codecs/hdmi-codec.c +@@ -189,84 +189,75 @@ static const struct snd_pcm_chmap_elem hdmi_codec_8ch_chmaps[] = { + /* + * hdmi_codec_channel_alloc: speaker configuration available for CEA + * +- * This is an ordered list that must match with hdmi_codec_8ch_chmaps struct ++ * This is an ordered list where ca_id must exist in hdmi_codec_8ch_chmaps + * The preceding ones have better chances to be selected by + * hdmi_codec_get_ch_alloc_table_idx(). + */ + static const struct hdmi_codec_cea_spk_alloc hdmi_codec_channel_alloc[] = { + { .ca_id = 0x00, .n_ch = 2, +- .mask = FL | FR}, +- /* 2.1 */ +- { .ca_id = 0x01, .n_ch = 4, +- .mask = FL | FR | LFE}, +- /* Dolby Surround */ ++ .mask = FL | FR }, ++ { .ca_id = 0x03, .n_ch = 4, ++ .mask = FL | FR | LFE | FC }, + { .ca_id = 0x02, .n_ch = 4, + .mask = FL | FR | FC }, +- /* surround51 */ ++ { .ca_id = 0x01, .n_ch = 4, ++ .mask = FL | FR | LFE }, + { .ca_id = 0x0b, .n_ch = 6, +- .mask = FL | FR | LFE | FC | RL | RR}, +- /* surround40 */ +- { .ca_id = 0x08, .n_ch = 6, +- .mask = FL | FR | RL | RR }, +- /* surround41 */ +- { .ca_id = 0x09, .n_ch = 6, +- .mask = FL | FR | LFE | RL | RR }, +- /* surround50 */ ++ .mask = FL | FR | LFE | FC | RL | RR }, + { .ca_id = 0x0a, .n_ch = 6, + .mask = FL | FR | FC | RL | RR }, +- /* 6.1 */ +- { .ca_id = 0x0f, .n_ch = 8, +- .mask = FL | FR | LFE | FC | RL | RR | RC }, +- /* surround71 */ ++ { .ca_id = 0x09, .n_ch = 6, ++ .mask = FL | FR | LFE | RL | RR }, ++ { .ca_id = 0x08, .n_ch = 6, ++ .mask = FL | FR | RL | RR }, ++ { .ca_id = 0x07, .n_ch = 6, ++ .mask = FL | FR | LFE | FC | RC }, ++ { .ca_id = 0x06, .n_ch = 6, ++ .mask = FL | FR | FC | RC }, ++ { .ca_id = 0x05, .n_ch = 6, ++ .mask = FL | FR | LFE | RC }, ++ { .ca_id = 0x04, .n_ch = 6, ++ .mask = FL | FR | RC }, + { .ca_id = 0x13, .n_ch = 8, + .mask = FL | FR | LFE | FC | RL | RR | RLC | RRC }, +- /* others */ +- { .ca_id = 0x03, .n_ch = 8, +- .mask = FL | FR | LFE | FC }, +- { .ca_id = 0x04, .n_ch = 8, +- .mask = FL | FR | RC}, +- { .ca_id = 0x05, .n_ch = 8, +- .mask = FL | FR | LFE | RC }, +- { .ca_id = 0x06, .n_ch = 8, +- .mask = FL | FR | FC | RC }, +- { .ca_id = 0x07, .n_ch = 8, +- .mask = FL | FR | LFE | FC | RC }, +- { .ca_id = 0x0c, .n_ch = 8, +- .mask = FL | FR | RC | RL | RR }, +- { .ca_id = 0x0d, .n_ch = 8, +- .mask = FL | FR | LFE | RL | RR | RC }, +- { .ca_id = 0x0e, .n_ch = 8, +- .mask = FL | FR | FC | RL | RR | RC }, +- { .ca_id = 0x10, .n_ch = 8, +- .mask = FL | FR | RL | RR | RLC | RRC }, +- { .ca_id = 0x11, .n_ch = 8, +- .mask = FL | FR | LFE | RL | RR | RLC | RRC }, ++ { .ca_id = 0x1f, .n_ch = 8, ++ .mask = FL | FR | LFE | FC | RL | RR | FLC | FRC }, + { .ca_id = 0x12, .n_ch = 8, + .mask = FL | FR | FC | RL | RR | RLC | RRC }, +- { .ca_id = 0x14, .n_ch = 8, +- .mask = FL | FR | FLC | FRC }, +- { .ca_id = 0x15, .n_ch = 8, +- .mask = FL | FR | LFE | FLC | FRC }, +- { .ca_id = 0x16, .n_ch = 8, +- .mask = FL | FR | FC | FLC | FRC }, +- { .ca_id = 0x17, .n_ch = 8, +- .mask = FL | FR | LFE | FC | FLC | FRC }, +- { .ca_id = 0x18, .n_ch = 8, +- .mask = FL | FR | RC | FLC | FRC }, +- { .ca_id = 0x19, .n_ch = 8, +- .mask = FL | FR | LFE | RC | FLC | FRC }, +- { .ca_id = 0x1a, .n_ch = 8, +- .mask = FL | FR | RC | FC | FLC | FRC }, +- { .ca_id = 0x1b, .n_ch = 8, +- .mask = FL | FR | LFE | RC | FC | FLC | FRC }, +- { .ca_id = 0x1c, .n_ch = 8, +- .mask = FL | FR | RL | RR | FLC | FRC }, +- { .ca_id = 0x1d, .n_ch = 8, +- .mask = FL | FR | LFE | RL | RR | FLC | FRC }, + { .ca_id = 0x1e, .n_ch = 8, + .mask = FL | FR | FC | RL | RR | FLC | FRC }, +- { .ca_id = 0x1f, .n_ch = 8, +- .mask = FL | FR | LFE | FC | RL | RR | FLC | FRC }, ++ { .ca_id = 0x11, .n_ch = 8, ++ .mask = FL | FR | LFE | RL | RR | RLC | RRC }, ++ { .ca_id = 0x1d, .n_ch = 8, ++ .mask = FL | FR | LFE | RL | RR | FLC | FRC }, ++ { .ca_id = 0x10, .n_ch = 8, ++ .mask = FL | FR | RL | RR | RLC | RRC }, ++ { .ca_id = 0x1c, .n_ch = 8, ++ .mask = FL | FR | RL | RR | FLC | FRC }, ++ { .ca_id = 0x0f, .n_ch = 8, ++ .mask = FL | FR | LFE | FC | RL | RR | RC }, ++ { .ca_id = 0x1b, .n_ch = 8, ++ .mask = FL | FR | LFE | RC | FC | FLC | FRC }, ++ { .ca_id = 0x0e, .n_ch = 8, ++ .mask = FL | FR | FC | RL | RR | RC }, ++ { .ca_id = 0x1a, .n_ch = 8, ++ .mask = FL | FR | RC | FC | FLC | FRC }, ++ { .ca_id = 0x0d, .n_ch = 8, ++ .mask = FL | FR | LFE | RL | RR | RC }, ++ { .ca_id = 0x19, .n_ch = 8, ++ .mask = FL | FR | LFE | RC | FLC | FRC }, ++ { .ca_id = 0x0c, .n_ch = 8, ++ .mask = FL | FR | RC | RL | RR }, ++ { .ca_id = 0x18, .n_ch = 8, ++ .mask = FL | FR | RC | FLC | FRC }, ++ { .ca_id = 0x17, .n_ch = 8, ++ .mask = FL | FR | LFE | FC | FLC | FRC }, ++ { .ca_id = 0x16, .n_ch = 8, ++ .mask = FL | FR | FC | FLC | FRC }, ++ { .ca_id = 0x15, .n_ch = 8, ++ .mask = FL | FR | LFE | FLC | FRC }, ++ { .ca_id = 0x14, .n_ch = 8, ++ .mask = FL | FR | FLC | FRC }, + }; + + struct hdmi_codec_priv { +-- +2.17.1 + + +From 5e626ea314cb0b25dc7a58e72908b1f91e762dfc Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Tue, 1 Oct 2019 20:52:42 +0000 +Subject: [PATCH] media: cec-adap: add debounce support when setting an invalid + phys addr + +When EDID is refreshed, HDMI cable is unplugged/replugged or +an AVR is power cycled the CEC phys addr gets invalidated. + +This can cause some disruption of CEC communication when +adapter is being reconfigured. + +Add a debounce module option that can be used to debounce setting +an invalid phys addr. Default is not to use debouncing. + +Using a configured debounce of e.g. 5000 ms, cec reconfiguring +could be avoided when AVR was power cycled on my setup. + +Power off AVR (default cec.debounce=0): +[ 101.536866] cec-dw_hdmi: new physical address f.f.f.f +[ 102.495686] cec-dw_hdmi: new physical address 2.1.0.0 +[ 102.495913] cec-dw_hdmi: physical address: 2.1.0.0, claim 1 logical addresses +[ 102.628574] cec-dw_hdmi: config: la 1 pa 2.1.0.0 +[ 105.130115] cec-dw_hdmi: new physical address f.f.f.f +[ 106.979705] cec-dw_hdmi: new physical address 2.1.0.0 +[ 106.979872] cec-dw_hdmi: physical address: 2.1.0.0, claim 1 logical addresses +[ 107.112399] cec-dw_hdmi: config: la 1 pa 2.1.0.0 +[ 108.979408] cec-dw_hdmi: reported physical address 2.0.0.0 for logical address 5 +[ 109.205386] cec-dw_hdmi: reported physical address 2.0.0.0 for logical address 11 + +Power on AVR (default cec.debounce=0): +[ 158.398447] cec-dw_hdmi: new physical address f.f.f.f +[ 161.977714] cec-dw_hdmi: new physical address 2.1.0.0 +[ 161.978766] cec-dw_hdmi: physical address: 2.1.0.0, claim 1 logical addresses +[ 162.115624] cec-dw_hdmi: config: la 1 pa 2.1.0.0 +[ 162.402750] cec-dw_hdmi: new physical address f.f.f.f +[ 162.403389] cec-dw_hdmi: cec_transmit_msg_fh: adapter is unconfigured +[ 162.886757] cec-dw_hdmi: new physical address 2.1.0.0 +[ 162.886964] cec-dw_hdmi: physical address: 2.1.0.0, claim 1 logical addresses +[ 163.510725] cec-dw_hdmi: config: la 1 pa 2.1.0.0 +[ 173.034200] cec-dw_hdmi: message 10 89 02 05 timed out + +Power off AVR (cec.debounce=5000): +[ 251.720471] cec-dw_hdmi: reported physical address 2.0.0.0 for logical address 5 +[ 251.922432] cec-dw_hdmi: reported physical address 2.0.0.0 for logical address 11 + +Power on AVR (cec.debounce=5000): +[ 291.154262] cec-dw_hdmi: reported physical address 2.0.0.0 for logical address 5 +[ 291.296199] cec-dw_hdmi: reported physical address 2.0.0.0 for logical address 11 + +Signed-off-by: Jonas Karlman +--- + Documentation/media/uapi/cec/cec-intro.rst | 8 ++++++++ + drivers/media/cec/cec-adap.c | 9 ++++++++- + drivers/media/cec/cec-core.c | 18 ++++++++++++++++++ + drivers/media/cec/cec-priv.h | 1 + + include/media/cec.h | 2 ++ + 5 files changed, 37 insertions(+), 1 deletion(-) + +diff --git a/Documentation/media/uapi/cec/cec-intro.rst b/Documentation/media/uapi/cec/cec-intro.rst +index 05088fcefe81..9bfd11ef987b 100644 +--- a/Documentation/media/uapi/cec/cec-intro.rst ++++ b/Documentation/media/uapi/cec/cec-intro.rst +@@ -47,3 +47,11 @@ provides three tools to handle CEC: + determine how compliant the CEC implementation is. + + - cec-follower: emulates a CEC follower. ++ ++Debouncing ++---------- ++ ++The ``debounce_ms`` option is a module parameter that can be used to enabled ++debouncing of setting invalid physical address. ++ ++FIXME: Make a section "1.1 Debouncing" that explains this module option. +diff --git a/drivers/media/cec/cec-adap.c b/drivers/media/cec/cec-adap.c +index 6c95dc471d4c..c483e847db95 100644 +--- a/drivers/media/cec/cec-adap.c ++++ b/drivers/media/cec/cec-adap.c +@@ -1609,8 +1609,15 @@ void cec_s_phys_addr(struct cec_adapter *adap, u16 phys_addr, bool block) + if (IS_ERR_OR_NULL(adap)) + return; + ++ cancel_delayed_work_sync(&adap->debounce_work); ++ + mutex_lock(&adap->lock); +- __cec_s_phys_addr(adap, phys_addr, block); ++ if (cec_debounce_ms > 0 && !block && ++ phys_addr == CEC_PHYS_ADDR_INVALID && adap->phys_addr != phys_addr) ++ schedule_delayed_work(&adap->debounce_work, ++ msecs_to_jiffies(cec_debounce_ms)); ++ else ++ __cec_s_phys_addr(adap, phys_addr, block); + mutex_unlock(&adap->lock); + } + EXPORT_SYMBOL_GPL(cec_s_phys_addr); +diff --git a/drivers/media/cec/cec-core.c b/drivers/media/cec/cec-core.c +index 0c52e1bb3910..cd71d77c057c 100644 +--- a/drivers/media/cec/cec-core.c ++++ b/drivers/media/cec/cec-core.c +@@ -28,6 +28,10 @@ static bool debug_phys_addr; + module_param(debug_phys_addr, bool, 0644); + MODULE_PARM_DESC(debug_phys_addr, "add CEC_CAP_PHYS_ADDR if set"); + ++int cec_debounce_ms; ++module_param_named(debounce_ms, cec_debounce_ms, int, 0644); ++MODULE_PARM_DESC(debounce_ms, "invalid physical address debounce time in ms"); ++ + static dev_t cec_dev_t; + + /* Active devices */ +@@ -174,6 +178,8 @@ static void cec_devnode_unregister(struct cec_adapter *adap) + devnode->unregistered = true; + mutex_unlock(&devnode->lock); + ++ cancel_delayed_work_sync(&adap->debounce_work); ++ + mutex_lock(&adap->lock); + __cec_s_phys_addr(adap, CEC_PHYS_ADDR_INVALID, false); + __cec_s_log_addrs(adap, NULL, false); +@@ -232,6 +238,17 @@ static const struct file_operations cec_error_inj_fops = { + }; + #endif + ++static void cec_s_phys_addr_debounce(struct work_struct *work) ++{ ++ struct delayed_work *delayed_work = to_delayed_work(work); ++ struct cec_adapter *adap = ++ container_of(delayed_work, struct cec_adapter, debounce_work); ++ ++ mutex_lock(&adap->lock); ++ __cec_s_phys_addr(adap, CEC_PHYS_ADDR_INVALID, false); ++ mutex_unlock(&adap->lock); ++} ++ + struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops, + void *priv, const char *name, u32 caps, + u8 available_las) +@@ -270,6 +287,7 @@ struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops, + INIT_LIST_HEAD(&adap->transmit_queue); + INIT_LIST_HEAD(&adap->wait_queue); + init_waitqueue_head(&adap->kthread_waitq); ++ INIT_DELAYED_WORK(&adap->debounce_work, cec_s_phys_addr_debounce); + + /* adap->devnode initialization */ + INIT_LIST_HEAD(&adap->devnode.fhs); +diff --git a/drivers/media/cec/cec-priv.h b/drivers/media/cec/cec-priv.h +index 9bbd05053d42..d479dbd50528 100644 +--- a/drivers/media/cec/cec-priv.h ++++ b/drivers/media/cec/cec-priv.h +@@ -27,6 +27,7 @@ static inline bool msg_is_raw(const struct cec_msg *msg) + + /* cec-core.c */ + extern int cec_debug; ++extern int cec_debounce_ms; + int cec_get_device(struct cec_devnode *devnode); + void cec_put_device(struct cec_devnode *devnode); + +diff --git a/include/media/cec.h b/include/media/cec.h +index 972bc8cd4384..5befad3a6a0f 100644 +--- a/include/media/cec.h ++++ b/include/media/cec.h +@@ -164,6 +164,8 @@ struct cec_adapter { + wait_queue_head_t kthread_waitq; + wait_queue_head_t waitq; + ++ struct delayed_work debounce_work; ++ + const struct cec_adap_ops *ops; + void *priv; + u32 capabilities; +-- +2.17.1 + + +From e7067ef6d71c5686c082f37f8e54454d499124a8 Mon Sep 17 00:00:00 2001 +From: Boris Brezillon +Date: Thu, 19 Dec 2019 11:11:48 +0100 +Subject: [PATCH] drm/bridge: Add a drm_bridge_state object + +One of the last remaining objects to not have its atomic state. + +This is being motivated by our attempt to support runtime bus-format +negotiation between elements of the bridge chain. +This patch just paves the road for such a feature by adding a new +drm_bridge_state object inheriting from drm_private_obj so we can +re-use some of the existing state initialization/tracking logic. + +Signed-off-by: Boris Brezillon +Reviewed-by: Neil Armstrong +Reviewed-by: Laurent Pinchart +Signed-off-by: Neil Armstrong +--- + drivers/gpu/drm/drm_atomic.c | 39 +++++++ + drivers/gpu/drm/drm_atomic_helper.c | 20 ++++ + drivers/gpu/drm/drm_bridge.c | 169 +++++++++++++++++++++++++++- + include/drm/drm_atomic.h | 3 + + include/drm/drm_bridge.h | 120 ++++++++++++++++++++ + 5 files changed, 345 insertions(+), 6 deletions(-) + +diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c +index d33691512a8e..bf1b9c37d515 100644 +--- a/drivers/gpu/drm/drm_atomic.c ++++ b/drivers/gpu/drm/drm_atomic.c +@@ -30,6 +30,7 @@ + + #include + #include ++#include + #include + #include + #include +@@ -1017,6 +1018,44 @@ static void drm_atomic_connector_print_state(struct drm_printer *p, + connector->funcs->atomic_print_state(p, state); + } + ++/** ++ * drm_atomic_add_encoder_bridges - add bridges attached to an encoder ++ * @state: atomic state ++ * @encoder: DRM encoder ++ * ++ * This function adds all bridges attached to @encoder. This is needed to add ++ * bridge states to @state and make them available when ++ * &bridge_funcs.atomic_{check,pre_enable,enable,disable_post_disable}() are ++ * called ++ * ++ * Returns: ++ * 0 on success or can fail with -EDEADLK or -ENOMEM. When the error is EDEADLK ++ * then the w/w mutex code has detected a deadlock and the entire atomic ++ * sequence must be restarted. All other errors are fatal. ++ */ ++int ++drm_atomic_add_encoder_bridges(struct drm_atomic_state *state, ++ struct drm_encoder *encoder) ++{ ++ struct drm_bridge_state *bridge_state; ++ struct drm_bridge *bridge; ++ ++ if (!encoder) ++ return 0; ++ ++ DRM_DEBUG_ATOMIC("Adding all bridges for [encoder:%d:%s] to %p\n", ++ encoder->base.id, encoder->name, state); ++ ++ drm_for_each_bridge_in_chain(encoder, bridge) { ++ bridge_state = drm_atomic_get_bridge_state(state, bridge); ++ if (IS_ERR(bridge_state)) ++ return PTR_ERR(bridge_state); ++ } ++ ++ return 0; ++} ++EXPORT_SYMBOL(drm_atomic_add_encoder_bridges); ++ + /** + * drm_atomic_add_affected_connectors - add connectors for CRTC + * @state: atomic state +diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c +index 4511c2e07bb9..ad8eae98d9e8 100644 +--- a/drivers/gpu/drm/drm_atomic_helper.c ++++ b/drivers/gpu/drm/drm_atomic_helper.c +@@ -730,6 +730,26 @@ drm_atomic_helper_check_modeset(struct drm_device *dev, + return ret; + } + ++ /* ++ * Iterate over all connectors again, and add all affected bridges to ++ * the state. ++ */ ++ for_each_oldnew_connector_in_state(state, connector, ++ old_connector_state, ++ new_connector_state, i) { ++ struct drm_encoder *encoder; ++ ++ encoder = old_connector_state->best_encoder; ++ ret = drm_atomic_add_encoder_bridges(state, encoder); ++ if (ret) ++ return ret; ++ ++ encoder = new_connector_state->best_encoder; ++ ret = drm_atomic_add_encoder_bridges(state, encoder); ++ if (ret) ++ return ret; ++ } ++ + ret = mode_valid(state); + if (ret) + return ret; +diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c +index c2cf0c90fa26..a3921b45f044 100644 +--- a/drivers/gpu/drm/drm_bridge.c ++++ b/drivers/gpu/drm/drm_bridge.c +@@ -25,6 +25,7 @@ + #include + #include + ++#include + #include + #include + +@@ -89,6 +90,38 @@ void drm_bridge_remove(struct drm_bridge *bridge) + } + EXPORT_SYMBOL(drm_bridge_remove); + ++static struct drm_private_state * ++drm_bridge_atomic_duplicate_priv_state(struct drm_private_obj *obj) ++{ ++ struct drm_bridge *bridge = drm_priv_to_bridge(obj); ++ struct drm_bridge_state *state; ++ ++ if (bridge->funcs->atomic_duplicate_state) ++ state = bridge->funcs->atomic_duplicate_state(bridge); ++ else ++ state = drm_atomic_helper_bridge_duplicate_state(bridge); ++ ++ return state ? &state->base : NULL; ++} ++ ++static void ++drm_bridge_atomic_destroy_priv_state(struct drm_private_obj *obj, ++ struct drm_private_state *s) ++{ ++ struct drm_bridge_state *state = drm_priv_to_bridge_state(s); ++ struct drm_bridge *bridge = drm_priv_to_bridge(obj); ++ ++ if (bridge->funcs->atomic_destroy_state) ++ bridge->funcs->atomic_destroy_state(bridge, state); ++ else ++ drm_atomic_helper_bridge_destroy_state(bridge, state); ++} ++ ++static const struct drm_private_state_funcs drm_bridge_priv_state_funcs = { ++ .atomic_duplicate_state = drm_bridge_atomic_duplicate_priv_state, ++ .atomic_destroy_state = drm_bridge_atomic_destroy_priv_state, ++}; ++ + /** + * drm_bridge_attach - attach the bridge to an encoder's chain + * +@@ -114,6 +147,7 @@ EXPORT_SYMBOL(drm_bridge_remove); + int drm_bridge_attach(struct drm_encoder *encoder, struct drm_bridge *bridge, + struct drm_bridge *previous) + { ++ struct drm_bridge_state *state; + int ret; + + if (!encoder || !bridge) +@@ -135,15 +169,35 @@ int drm_bridge_attach(struct drm_encoder *encoder, struct drm_bridge *bridge, + + if (bridge->funcs->attach) { + ret = bridge->funcs->attach(bridge); +- if (ret < 0) { +- list_del(&bridge->chain_node); +- bridge->dev = NULL; +- bridge->encoder = NULL; +- return ret; +- } ++ if (ret < 0) ++ goto err_reset_bridge; ++ } ++ ++ if (bridge->funcs->atomic_reset) ++ state = bridge->funcs->atomic_reset(bridge); ++ else ++ state = drm_atomic_helper_bridge_reset(bridge); ++ ++ if (IS_ERR(state)) { ++ ret = PTR_ERR(state); ++ goto err_detach_bridge; + } + ++ drm_atomic_private_obj_init(bridge->dev, &bridge->base, ++ &state->base, ++ &drm_bridge_priv_state_funcs); ++ + return 0; ++ ++err_detach_bridge: ++ if (bridge->funcs->detach) ++ bridge->funcs->detach(bridge); ++ ++err_reset_bridge: ++ bridge->dev = NULL; ++ bridge->encoder = NULL; ++ list_del(&bridge->chain_node); ++ return ret; + } + EXPORT_SYMBOL(drm_bridge_attach); + +@@ -155,6 +209,8 @@ void drm_bridge_detach(struct drm_bridge *bridge) + if (WARN_ON(!bridge->dev)) + return; + ++ drm_atomic_private_obj_fini(&bridge->base); ++ + if (bridge->funcs->detach) + bridge->funcs->detach(bridge); + +@@ -516,6 +572,107 @@ void drm_atomic_bridge_chain_enable(struct drm_bridge *bridge, + } + EXPORT_SYMBOL(drm_atomic_bridge_chain_enable); + ++/** ++ * drm_atomic_helper_bridge_destroy_state() - Default destroy state helper ++ * @bridge: the bridge this state refers to ++ * @state: state object to destroy ++ * ++ * Just a simple kfree() for now. ++ */ ++void drm_atomic_helper_bridge_destroy_state(struct drm_bridge *bridge, ++ struct drm_bridge_state *state) ++{ ++ kfree(state); ++} ++EXPORT_SYMBOL(drm_atomic_helper_bridge_destroy_state); ++ ++/** ++ * __drm_atomic_helper_bridge_reset() - Initialize a bridge state to its ++ * default ++ * @bridge: the bridge this state is refers to ++ * @state: bridge state to initialize ++ * ++ * Initialize the bridge state to default values. This is meant to be* called ++ * by the bridge &drm_plane_funcs.reset hook for bridges that subclass the ++ * bridge state. ++ */ ++void __drm_atomic_helper_bridge_reset(struct drm_bridge *bridge, ++ struct drm_bridge_state *state) ++{ ++ memset(state, 0, sizeof(*state)); ++ state->bridge = bridge; ++} ++EXPORT_SYMBOL(__drm_atomic_helper_bridge_reset); ++ ++/** ++ * drm_atomic_helper_bridge_reset() - default &drm_plane_funcs.reset hook for ++ * bridges ++ * @bridge: the bridge to reset state on ++ * ++ * Resets the atomic state for @bridge by freeing the state pointer (which ++ * might be NULL, e.g. at driver load time) and allocating a new empty state ++ * object. ++ * ++ * RETURNS: ++ * A valid drm_bridge_state object in case of success, an ERR_PTR() ++ * giving the reaon of the failure otherwise. ++ */ ++struct drm_bridge_state * ++drm_atomic_helper_bridge_reset(struct drm_bridge *bridge) ++{ ++ struct drm_bridge_state *bridge_state; ++ ++ bridge_state = kzalloc(sizeof(*bridge_state), GFP_KERNEL); ++ if (!bridge_state) ++ return ERR_PTR(-ENOMEM); ++ ++ __drm_atomic_helper_bridge_reset(bridge, bridge_state); ++ return bridge_state; ++} ++EXPORT_SYMBOL(drm_atomic_helper_bridge_reset); ++ ++/** ++ * __drm_atomic_helper_bridge_duplicate_state() - Copy atomic bridge state ++ * @bridge: bridge object ++ * @state: atomic bridge state ++ * ++ * Copies atomic state from a bridge's current state and resets inferred values. ++ * This is useful for drivers that subclass the bridge state. ++ */ ++void __drm_atomic_helper_bridge_duplicate_state(struct drm_bridge *bridge, ++ struct drm_bridge_state *state) ++{ ++ __drm_atomic_helper_private_obj_duplicate_state(&bridge->base, ++ &state->base); ++ state->bridge = bridge; ++} ++EXPORT_SYMBOL(__drm_atomic_helper_bridge_duplicate_state); ++ ++/** ++ * drm_atomic_helper_duplicate_bridge_state() - Default duplicate state helper ++ * @bridge: bridge containing the state to duplicate ++ * ++ * Default implementation of &drm_bridge_funcs.atomic_duplicate(). ++ * ++ * RETURNS: ++ * a valid state object or NULL if the allocation fails. ++ */ ++struct drm_bridge_state * ++drm_atomic_helper_bridge_duplicate_state(struct drm_bridge *bridge) ++{ ++ struct drm_bridge_state *new; ++ ++ if (WARN_ON(!bridge->base.state)) ++ return NULL; ++ ++ new = kzalloc(sizeof(*new), GFP_KERNEL); ++ if (new) ++ __drm_atomic_helper_bridge_duplicate_state(bridge, new); ++ ++ return new; ++} ++EXPORT_SYMBOL(drm_atomic_helper_bridge_duplicate_state); ++ + #ifdef CONFIG_OF + /** + * of_drm_find_bridge - find the bridge corresponding to the device node in +diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h +index 951dfb15c27b..ccce65e14917 100644 +--- a/include/drm/drm_atomic.h ++++ b/include/drm/drm_atomic.h +@@ -669,6 +669,9 @@ __drm_atomic_get_current_plane_state(struct drm_atomic_state *state, + return plane->state; + } + ++int __must_check ++drm_atomic_add_encoder_bridges(struct drm_atomic_state *state, ++ struct drm_encoder *encoder); + int __must_check + drm_atomic_add_affected_connectors(struct drm_atomic_state *state, + struct drm_crtc *crtc); +diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h +index 694e153a7531..8a926c1a08db 100644 +--- a/include/drm/drm_bridge.h ++++ b/include/drm/drm_bridge.h +@@ -25,6 +25,8 @@ + + #include + #include ++ ++#include + #include + #include + #include +@@ -33,6 +35,23 @@ struct drm_bridge; + struct drm_bridge_timings; + struct drm_panel; + ++/** ++ * struct drm_bridge_state - Atomic bridge state object ++ * @base: inherit from &drm_private_state ++ * @bridge: the bridge this state refers to ++ */ ++struct drm_bridge_state { ++ struct drm_private_state base; ++ ++ struct drm_bridge *bridge; ++}; ++ ++static inline struct drm_bridge_state * ++drm_priv_to_bridge_state(struct drm_private_state *priv) ++{ ++ return container_of(priv, struct drm_bridge_state, base); ++} ++ + /** + * struct drm_bridge_funcs - drm_bridge control functions + */ +@@ -338,6 +357,49 @@ struct drm_bridge_funcs { + */ + void (*atomic_post_disable)(struct drm_bridge *bridge, + struct drm_atomic_state *old_state); ++ ++ /** ++ * @atomic_duplicate_state: ++ * ++ * Duplicate the current bridge state object (which is guaranteed to be ++ * non-NULL). ++ * ++ * The atomic_duplicate_state() is optional. When not implemented the ++ * core allocates a drm_bridge_state object and calls ++ * &__drm_atomic_helper_bridge_duplicate_state() to initialize it. ++ * ++ * RETURNS: ++ * A valid drm_bridge_state object or NULL if the allocation fails. ++ */ ++ struct drm_bridge_state *(*atomic_duplicate_state)(struct drm_bridge *bridge); ++ ++ /** ++ * @atomic_destroy_state: ++ * ++ * Destroy a bridge state object previously allocated by ++ * &drm_bridge_funcs.atomic_duplicate_state(). ++ * ++ * The atomic_destroy_state hook is optional. When not implemented the ++ * core calls kfree() on the state. ++ */ ++ void (*atomic_destroy_state)(struct drm_bridge *bridge, ++ struct drm_bridge_state *state); ++ ++ /** ++ * @atomic_reset: ++ * ++ * Reset the bridge to a predefined state (or retrieve its current ++ * state) and return a &drm_bridge_state object matching this state. ++ * This function is called at attach time. ++ * ++ * The atomic_reset hook is optional. When not implemented the core ++ * allocates a new state and calls &__drm_atomic_helper_bridge_reset(). ++ * ++ * RETURNS: ++ * A valid drm_bridge_state object in case of success, an ERR_PTR() ++ * giving the reason of the failure otherwise. ++ */ ++ struct drm_bridge_state *(*atomic_reset)(struct drm_bridge *bridge); + }; + + /** +@@ -380,6 +442,8 @@ struct drm_bridge_timings { + * struct drm_bridge - central DRM bridge control structure + */ + struct drm_bridge { ++ /** @base: inherit from &drm_private_object */ ++ struct drm_private_obj base; + /** @dev: DRM device this bridge belongs to */ + struct drm_device *dev; + /** @encoder: encoder to which this bridge is connected */ +@@ -404,6 +468,12 @@ struct drm_bridge { + void *driver_private; + }; + ++static inline struct drm_bridge * ++drm_priv_to_bridge(struct drm_private_obj *priv) ++{ ++ return container_of(priv, struct drm_bridge, base); ++} ++ + void drm_bridge_add(struct drm_bridge *bridge); + void drm_bridge_remove(struct drm_bridge *bridge); + struct drm_bridge *of_drm_find_bridge(struct device_node *np); +@@ -491,6 +561,56 @@ void drm_atomic_bridge_chain_pre_enable(struct drm_bridge *bridge, + void drm_atomic_bridge_chain_enable(struct drm_bridge *bridge, + struct drm_atomic_state *state); + ++void __drm_atomic_helper_bridge_reset(struct drm_bridge *bridge, ++ struct drm_bridge_state *state); ++void drm_atomic_helper_bridge_destroy_state(struct drm_bridge *bridge, ++ struct drm_bridge_state *state); ++struct drm_bridge_state * ++drm_atomic_helper_bridge_reset(struct drm_bridge *bridge); ++void __drm_atomic_helper_bridge_duplicate_state(struct drm_bridge *bridge, ++ struct drm_bridge_state *new); ++struct drm_bridge_state * ++drm_atomic_helper_bridge_duplicate_state(struct drm_bridge *bridge); ++ ++static inline struct drm_bridge_state * ++drm_atomic_get_bridge_state(struct drm_atomic_state *state, ++ struct drm_bridge *bridge) ++{ ++ struct drm_private_state *obj_state; ++ ++ obj_state = drm_atomic_get_private_obj_state(state, &bridge->base); ++ if (IS_ERR(obj_state)) ++ return ERR_CAST(obj_state); ++ ++ return drm_priv_to_bridge_state(obj_state); ++} ++ ++static inline struct drm_bridge_state * ++drm_atomic_get_old_bridge_state(struct drm_atomic_state *state, ++ struct drm_bridge *bridge) ++{ ++ struct drm_private_state *obj_state; ++ ++ obj_state = drm_atomic_get_old_private_obj_state(state, &bridge->base); ++ if (!obj_state) ++ return NULL; ++ ++ return drm_priv_to_bridge_state(obj_state); ++} ++ ++static inline struct drm_bridge_state * ++drm_atomic_get_new_bridge_state(struct drm_atomic_state *state, ++ struct drm_bridge *bridge) ++{ ++ struct drm_private_state *obj_state; ++ ++ obj_state = drm_atomic_get_new_private_obj_state(state, &bridge->base); ++ if (!obj_state) ++ return NULL; ++ ++ return drm_priv_to_bridge_state(obj_state); ++} ++ + #ifdef CONFIG_DRM_PANEL_BRIDGE + struct drm_bridge *drm_panel_bridge_add(struct drm_panel *panel); + struct drm_bridge *drm_panel_bridge_add_typed(struct drm_panel *panel, +-- +2.17.1 + + +From 7b00bdecec40941c08461791cdc3ebfe766ffb15 Mon Sep 17 00:00:00 2001 +From: Boris Brezillon +Date: Thu, 19 Dec 2019 11:11:49 +0100 +Subject: [PATCH] drm/bridge: Patch atomic hooks to take a drm_bridge_state + +This way the drm_bridge_funcs interface is consistent with the rest of +the subsystem. + +The only driver implementing those hooks (analogix DP) is patched too. + +Signed-off-by: Boris Brezillon +Reviewed-by: Laurent Pinchart +Signed-off-by: Neil Armstrong +--- + .../drm/bridge/analogix/analogix_dp_core.c | 41 +++++++------ + drivers/gpu/drm/drm_bridge.c | 61 +++++++++++++++---- + include/drm/drm_bridge.h | 8 +-- + 3 files changed, 77 insertions(+), 33 deletions(-) + +diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c +index 6effe532f820..6fab71985cd4 100644 +--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c ++++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c +@@ -1289,19 +1289,21 @@ struct drm_crtc *analogix_dp_get_new_crtc(struct analogix_dp_device *dp, + return conn_state->crtc; + } + +-static void analogix_dp_bridge_atomic_pre_enable(struct drm_bridge *bridge, +- struct drm_atomic_state *state) ++static void ++analogix_dp_bridge_atomic_pre_enable(struct drm_bridge *bridge, ++ struct drm_bridge_state *old_bridge_state) + { ++ struct drm_atomic_state *old_state = old_bridge_state->base.state; + struct analogix_dp_device *dp = bridge->driver_private; + struct drm_crtc *crtc; + struct drm_crtc_state *old_crtc_state; + int ret; + +- crtc = analogix_dp_get_new_crtc(dp, state); ++ crtc = analogix_dp_get_new_crtc(dp, old_state); + if (!crtc) + return; + +- old_crtc_state = drm_atomic_get_old_crtc_state(state, crtc); ++ old_crtc_state = drm_atomic_get_old_crtc_state(old_state, crtc); + /* Don't touch the panel if we're coming back from PSR */ + if (old_crtc_state && old_crtc_state->self_refresh_active) + return; +@@ -1366,20 +1368,22 @@ static int analogix_dp_set_bridge(struct analogix_dp_device *dp) + return ret; + } + +-static void analogix_dp_bridge_atomic_enable(struct drm_bridge *bridge, +- struct drm_atomic_state *state) ++static void ++analogix_dp_bridge_atomic_enable(struct drm_bridge *bridge, ++ struct drm_bridge_state *old_bridge_state) + { ++ struct drm_atomic_state *old_state = old_bridge_state->base.state; + struct analogix_dp_device *dp = bridge->driver_private; + struct drm_crtc *crtc; + struct drm_crtc_state *old_crtc_state; + int timeout_loop = 0; + int ret; + +- crtc = analogix_dp_get_new_crtc(dp, state); ++ crtc = analogix_dp_get_new_crtc(dp, old_state); + if (!crtc) + return; + +- old_crtc_state = drm_atomic_get_old_crtc_state(state, crtc); ++ old_crtc_state = drm_atomic_get_old_crtc_state(old_state, crtc); + /* Not a full enable, just disable PSR and continue */ + if (old_crtc_state && old_crtc_state->self_refresh_active) { + ret = analogix_dp_disable_psr(dp); +@@ -1440,18 +1444,20 @@ static void analogix_dp_bridge_disable(struct drm_bridge *bridge) + dp->dpms_mode = DRM_MODE_DPMS_OFF; + } + +-static void analogix_dp_bridge_atomic_disable(struct drm_bridge *bridge, +- struct drm_atomic_state *state) ++static void ++analogix_dp_bridge_atomic_disable(struct drm_bridge *bridge, ++ struct drm_bridge_state *old_bridge_state) + { ++ struct drm_atomic_state *old_state = old_bridge_state->base.state; + struct analogix_dp_device *dp = bridge->driver_private; + struct drm_crtc *crtc; + struct drm_crtc_state *new_crtc_state = NULL; + +- crtc = analogix_dp_get_new_crtc(dp, state); ++ crtc = analogix_dp_get_new_crtc(dp, old_state); + if (!crtc) + goto out; + +- new_crtc_state = drm_atomic_get_new_crtc_state(state, crtc); ++ new_crtc_state = drm_atomic_get_new_crtc_state(old_state, crtc); + if (!new_crtc_state) + goto out; + +@@ -1463,20 +1469,21 @@ static void analogix_dp_bridge_atomic_disable(struct drm_bridge *bridge, + analogix_dp_bridge_disable(bridge); + } + +-static +-void analogix_dp_bridge_atomic_post_disable(struct drm_bridge *bridge, +- struct drm_atomic_state *state) ++static void ++analogix_dp_bridge_atomic_post_disable(struct drm_bridge *bridge, ++ struct drm_bridge_state *old_bridge_state) + { ++ struct drm_atomic_state *old_state = old_bridge_state->base.state; + struct analogix_dp_device *dp = bridge->driver_private; + struct drm_crtc *crtc; + struct drm_crtc_state *new_crtc_state; + int ret; + +- crtc = analogix_dp_get_new_crtc(dp, state); ++ crtc = analogix_dp_get_new_crtc(dp, old_state); + if (!crtc) + return; + +- new_crtc_state = drm_atomic_get_new_crtc_state(state, crtc); ++ new_crtc_state = drm_atomic_get_new_crtc_state(old_state, crtc); + if (!new_crtc_state || !new_crtc_state->self_refresh_active) + return; + +diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c +index a3921b45f044..6bdc4ab789c9 100644 +--- a/drivers/gpu/drm/drm_bridge.c ++++ b/drivers/gpu/drm/drm_bridge.c +@@ -465,10 +465,19 @@ void drm_atomic_bridge_chain_disable(struct drm_bridge *bridge, + + encoder = bridge->encoder; + list_for_each_entry_reverse(iter, &encoder->bridge_chain, chain_node) { +- if (iter->funcs->atomic_disable) +- iter->funcs->atomic_disable(iter, old_state); +- else if (iter->funcs->disable) ++ if (iter->funcs->atomic_disable) { ++ struct drm_bridge_state *old_bridge_state; ++ ++ old_bridge_state = ++ drm_atomic_get_old_bridge_state(old_state, ++ iter); ++ if (WARN_ON(!old_bridge_state)) ++ return; ++ ++ iter->funcs->atomic_disable(iter, old_bridge_state); ++ } else if (iter->funcs->disable) { + iter->funcs->disable(iter); ++ } + + if (iter == bridge) + break; +@@ -499,10 +508,20 @@ void drm_atomic_bridge_chain_post_disable(struct drm_bridge *bridge, + + encoder = bridge->encoder; + list_for_each_entry_from(bridge, &encoder->bridge_chain, chain_node) { +- if (bridge->funcs->atomic_post_disable) +- bridge->funcs->atomic_post_disable(bridge, old_state); +- else if (bridge->funcs->post_disable) ++ if (bridge->funcs->atomic_post_disable) { ++ struct drm_bridge_state *old_bridge_state; ++ ++ old_bridge_state = ++ drm_atomic_get_old_bridge_state(old_state, ++ bridge); ++ if (WARN_ON(!old_bridge_state)) ++ return; ++ ++ bridge->funcs->atomic_post_disable(bridge, ++ old_bridge_state); ++ } else if (bridge->funcs->post_disable) { + bridge->funcs->post_disable(bridge); ++ } + } + } + EXPORT_SYMBOL(drm_atomic_bridge_chain_post_disable); +@@ -531,10 +550,19 @@ void drm_atomic_bridge_chain_pre_enable(struct drm_bridge *bridge, + + encoder = bridge->encoder; + list_for_each_entry_reverse(iter, &encoder->bridge_chain, chain_node) { +- if (iter->funcs->atomic_pre_enable) +- iter->funcs->atomic_pre_enable(iter, old_state); +- else if (iter->funcs->pre_enable) ++ if (iter->funcs->atomic_pre_enable) { ++ struct drm_bridge_state *old_bridge_state; ++ ++ old_bridge_state = ++ drm_atomic_get_old_bridge_state(old_state, ++ iter); ++ if (WARN_ON(!old_bridge_state)) ++ return; ++ ++ iter->funcs->atomic_pre_enable(iter, old_bridge_state); ++ } else if (iter->funcs->pre_enable) { + iter->funcs->pre_enable(iter); ++ } + + if (iter == bridge) + break; +@@ -564,10 +592,19 @@ void drm_atomic_bridge_chain_enable(struct drm_bridge *bridge, + + encoder = bridge->encoder; + list_for_each_entry_from(bridge, &encoder->bridge_chain, chain_node) { +- if (bridge->funcs->atomic_enable) +- bridge->funcs->atomic_enable(bridge, old_state); +- else if (bridge->funcs->enable) ++ if (bridge->funcs->atomic_enable) { ++ struct drm_bridge_state *old_bridge_state; ++ ++ old_bridge_state = ++ drm_atomic_get_old_bridge_state(old_state, ++ bridge); ++ if (WARN_ON(!old_bridge_state)) ++ return; ++ ++ bridge->funcs->atomic_enable(bridge, old_bridge_state); ++ } else if (bridge->funcs->enable) { + bridge->funcs->enable(bridge); ++ } + } + } + EXPORT_SYMBOL(drm_atomic_bridge_chain_enable); +diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h +index 8a926c1a08db..0331e330635b 100644 +--- a/include/drm/drm_bridge.h ++++ b/include/drm/drm_bridge.h +@@ -282,7 +282,7 @@ struct drm_bridge_funcs { + * The @atomic_pre_enable callback is optional. + */ + void (*atomic_pre_enable)(struct drm_bridge *bridge, +- struct drm_atomic_state *old_state); ++ struct drm_bridge_state *old_bridge_state); + + /** + * @atomic_enable: +@@ -307,7 +307,7 @@ struct drm_bridge_funcs { + * The @atomic_enable callback is optional. + */ + void (*atomic_enable)(struct drm_bridge *bridge, +- struct drm_atomic_state *old_state); ++ struct drm_bridge_state *old_bridge_state); + /** + * @atomic_disable: + * +@@ -330,7 +330,7 @@ struct drm_bridge_funcs { + * The @atomic_disable callback is optional. + */ + void (*atomic_disable)(struct drm_bridge *bridge, +- struct drm_atomic_state *old_state); ++ struct drm_bridge_state *old_bridge_state); + + /** + * @atomic_post_disable: +@@ -356,7 +356,7 @@ struct drm_bridge_funcs { + * The @atomic_post_disable callback is optional. + */ + void (*atomic_post_disable)(struct drm_bridge *bridge, +- struct drm_atomic_state *old_state); ++ struct drm_bridge_state *old_bridge_state); + + /** + * @atomic_duplicate_state: +-- +2.17.1 + + +From 7891bb247f22d65b57b84efb5cadaae13114236b Mon Sep 17 00:00:00 2001 +From: Boris Brezillon +Date: Thu, 19 Dec 2019 11:11:50 +0100 +Subject: [PATCH] drm/bridge: Add an ->atomic_check() hook + +So that bridge drivers have a way to check/reject an atomic operation. +The drm_atomic_bridge_chain_check() (which is just a wrapper around +the ->atomic_check() hook) is called in place of +drm_bridge_chain_mode_fixup() (when ->atomic_check() is not implemented, +the core falls back on ->mode_fixup(), so the behavior should stay +the same for existing bridge drivers). + +Signed-off-by: Boris Brezillon +Reviewed-by: Neil Armstrong +Reviewed-by: Laurent Pinchart +Signed-off-by: Neil Armstrong +--- + drivers/gpu/drm/drm_atomic_helper.c | 12 +++--- + drivers/gpu/drm/drm_bridge.c | 62 +++++++++++++++++++++++++++++ + include/drm/drm_bridge.h | 29 +++++++++++++- + 3 files changed, 96 insertions(+), 7 deletions(-) + +diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c +index ad8eae98d9e8..afe14f72a824 100644 +--- a/drivers/gpu/drm/drm_atomic_helper.c ++++ b/drivers/gpu/drm/drm_atomic_helper.c +@@ -437,12 +437,12 @@ mode_fixup(struct drm_atomic_state *state) + funcs = encoder->helper_private; + + bridge = drm_bridge_chain_get_first_bridge(encoder); +- ret = drm_bridge_chain_mode_fixup(bridge, +- &new_crtc_state->mode, +- &new_crtc_state->adjusted_mode); +- if (!ret) { +- DRM_DEBUG_ATOMIC("Bridge fixup failed\n"); +- return -EINVAL; ++ ret = drm_atomic_bridge_chain_check(bridge, ++ new_crtc_state, ++ new_conn_state); ++ if (ret) { ++ DRM_DEBUG_ATOMIC("Bridge atomic check failed\n"); ++ return ret; + } + + if (funcs && funcs->atomic_check) { +diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c +index 6bdc4ab789c9..442804598f60 100644 +--- a/drivers/gpu/drm/drm_bridge.c ++++ b/drivers/gpu/drm/drm_bridge.c +@@ -609,6 +609,68 @@ void drm_atomic_bridge_chain_enable(struct drm_bridge *bridge, + } + EXPORT_SYMBOL(drm_atomic_bridge_chain_enable); + ++static int drm_atomic_bridge_check(struct drm_bridge *bridge, ++ struct drm_crtc_state *crtc_state, ++ struct drm_connector_state *conn_state) ++{ ++ if (bridge->funcs->atomic_check) { ++ struct drm_bridge_state *bridge_state; ++ int ret; ++ ++ bridge_state = drm_atomic_get_new_bridge_state(crtc_state->state, ++ bridge); ++ if (WARN_ON(!bridge_state)) ++ return -EINVAL; ++ ++ ret = bridge->funcs->atomic_check(bridge, bridge_state, ++ crtc_state, conn_state); ++ if (ret) ++ return ret; ++ } else if (bridge->funcs->mode_fixup) { ++ if (!bridge->funcs->mode_fixup(bridge, &crtc_state->mode, ++ &crtc_state->adjusted_mode)) ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++/** ++ * drm_atomic_bridge_chain_check() - Do an atomic check on the bridge chain ++ * @bridge: bridge control structure ++ * @crtc_state: new CRTC state ++ * @conn_state: new connector state ++ * ++ * Calls &drm_bridge_funcs.atomic_check() (falls back on ++ * &drm_bridge_funcs.mode_fixup()) op for all the bridges in the encoder chain, ++ * starting from the last bridge to the first. These are called before calling ++ * &drm_encoder_helper_funcs.atomic_check() ++ * ++ * RETURNS: ++ * 0 on success, a negative error code on failure ++ */ ++int drm_atomic_bridge_chain_check(struct drm_bridge *bridge, ++ struct drm_crtc_state *crtc_state, ++ struct drm_connector_state *conn_state) ++{ ++ struct drm_encoder *encoder = bridge->encoder; ++ struct drm_bridge *iter; ++ ++ list_for_each_entry_reverse(iter, &encoder->bridge_chain, chain_node) { ++ int ret; ++ ++ ret = drm_atomic_bridge_check(iter, crtc_state, conn_state); ++ if (ret) ++ return ret; ++ ++ if (iter == bridge) ++ break; ++ } ++ ++ return 0; ++} ++EXPORT_SYMBOL(drm_atomic_bridge_chain_check); ++ + /** + * drm_atomic_helper_bridge_destroy_state() - Default destroy state helper + * @bridge: the bridge this state refers to +diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h +index 0331e330635b..269f0d1da339 100644 +--- a/include/drm/drm_bridge.h ++++ b/include/drm/drm_bridge.h +@@ -128,7 +128,9 @@ struct drm_bridge_funcs { + * this function passes all other callbacks must succeed for this + * configuration. + * +- * The @mode_fixup callback is optional. ++ * The mode_fixup callback is optional. &drm_bridge_funcs.mode_fixup() ++ * is not called when &drm_bridge_funcs.atomic_check() is implemented, ++ * so only one of them should be provided. + * + * NOTE: + * +@@ -385,6 +387,28 @@ struct drm_bridge_funcs { + void (*atomic_destroy_state)(struct drm_bridge *bridge, + struct drm_bridge_state *state); + ++ /** ++ * @atomic_check: ++ * ++ * This method is responsible for checking bridge state correctness. ++ * It can also check the state of the surrounding components in chain ++ * to make sure the whole pipeline can work properly. ++ * ++ * &drm_bridge_funcs.atomic_check() hooks are called in reverse ++ * order (from the last to the first bridge). ++ * ++ * This method is optional. &drm_bridge_funcs.mode_fixup() is not ++ * called when &drm_bridge_funcs.atomic_check() is implemented, so only ++ * one of them should be provided. ++ * ++ * RETURNS: ++ * zero if the check passed, a negative error code otherwise. ++ */ ++ int (*atomic_check)(struct drm_bridge *bridge, ++ struct drm_bridge_state *bridge_state, ++ struct drm_crtc_state *crtc_state, ++ struct drm_connector_state *conn_state); ++ + /** + * @atomic_reset: + * +@@ -552,6 +576,9 @@ void drm_bridge_chain_mode_set(struct drm_bridge *bridge, + void drm_bridge_chain_pre_enable(struct drm_bridge *bridge); + void drm_bridge_chain_enable(struct drm_bridge *bridge); + ++int drm_atomic_bridge_chain_check(struct drm_bridge *bridge, ++ struct drm_crtc_state *crtc_state, ++ struct drm_connector_state *conn_state); + void drm_atomic_bridge_chain_disable(struct drm_bridge *bridge, + struct drm_atomic_state *state); + void drm_atomic_bridge_chain_post_disable(struct drm_bridge *bridge, +-- +2.17.1 + + +From 08c9023ffcdae0022fe84dac4e12efc6f989c6c8 Mon Sep 17 00:00:00 2001 +From: Boris Brezillon +Date: Thu, 19 Dec 2019 11:11:51 +0100 +Subject: [PATCH] drm/bridge: Add the necessary bits to support bus format + negotiation + +drm_bridge_state is extended to describe the input and output bus +configurations. These bus configurations are exposed through the +drm_bus_cfg struct which encodes the configuration of a physical +bus between two components in an output pipeline, usually between +two bridges, an encoder and a bridge, or a bridge and a connector. + +The bus configuration is stored in drm_bridge_state separately for +the input and output buses, as seen from the point of view of each +bridge. The bus configuration of a bridge output is usually identical +to the configuration of the next bridge's input, but may differ if +the signals are modified between the two bridges, for instance by an +inverter on the board. The input and output configurations of a +bridge may differ if the bridge modifies the signals internally, +for instance by performing format conversion, or*modifying signals +polarities. + +Bus format negotiation is automated by the core, drivers just have +to implement the ->atomic_get_{output,input}_bus_fmts() hooks if they +want to take part to this negotiation. Negotiation happens in reverse +order, starting from the last element of the chain (the one directly +connected to the display) up to the first element of the chain (the one +connected to the encoder). +During this negotiation all supported formats are tested until we find +one that works, meaning that the formats array should be in decreasing +preference order (assuming the driver has a preference order). + +Note that the bus format negotiation works even if some elements in the +chain don't implement the ->atomic_get_{output,input}_bus_fmts() hooks. +In that case, the core advertises only MEDIA_BUS_FMT_FIXED and lets +the previous bridge element decide what to do (most of the time, bridge +drivers will pick a default bus format or extract this piece of +information from somewhere else, like a FW property). + +Signed-off-by: Boris Brezillon +Signed-off-by: Neil Armstrong +--- + drivers/gpu/drm/drm_bridge.c | 267 ++++++++++++++++++++++++++++++++++- + include/drm/drm_bridge.h | 124 ++++++++++++++++ + 2 files changed, 390 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c +index 442804598f60..9cc4b0181f85 100644 +--- a/drivers/gpu/drm/drm_bridge.c ++++ b/drivers/gpu/drm/drm_bridge.c +@@ -635,13 +635,261 @@ static int drm_atomic_bridge_check(struct drm_bridge *bridge, + return 0; + } + ++/** ++ * drm_atomic_helper_bridge_propagate_bus_fmt() - Propagate output format to ++ * the input end of a bridge ++ * @bridge: bridge control structure ++ * @bridge_state: new bridge state ++ * @crtc_state: new CRTC state ++ * @conn_state: new connector state ++ * @output_fmt: tested output bus format ++ * @num_input_fmts: will contain the size of the returned array ++ * ++ * This helper is a pluggable implementation of the ++ * &drm_bridge_funcs.atomic_get_input_bus_fmts operation for bridges that don't ++ * modify the bus configuration between their input and their output. It ++ * returns an array of input formats with a single element set to @output_fmt. ++ * ++ * RETURNS: ++ * a valid format array of size @num_input_fmts, or NULL if the allocation ++ * failed ++ */ ++u32 * ++drm_atomic_helper_bridge_propagate_bus_fmt(struct drm_bridge *bridge, ++ struct drm_bridge_state *bridge_state, ++ struct drm_crtc_state *crtc_state, ++ struct drm_connector_state *conn_state, ++ u32 output_fmt, ++ unsigned int *num_input_fmts) ++{ ++ u32 *input_fmts; ++ ++ input_fmts = kzalloc(sizeof(*input_fmts), GFP_KERNEL); ++ if (!input_fmts) { ++ *num_input_fmts = 0; ++ return NULL; ++ } ++ ++ *num_input_fmts = 1; ++ input_fmts[0] = output_fmt; ++ return input_fmts; ++} ++EXPORT_SYMBOL(drm_atomic_helper_bridge_propagate_bus_fmt); ++ ++static int select_bus_fmt_recursive(struct drm_bridge *first_bridge, ++ struct drm_bridge *cur_bridge, ++ struct drm_crtc_state *crtc_state, ++ struct drm_connector_state *conn_state, ++ u32 out_bus_fmt) ++{ ++ struct drm_bridge_state *cur_state; ++ unsigned int num_in_bus_fmts, i; ++ struct drm_bridge *prev_bridge; ++ u32 *in_bus_fmts; ++ int ret; ++ ++ prev_bridge = drm_bridge_get_prev_bridge(cur_bridge); ++ cur_state = drm_atomic_get_new_bridge_state(crtc_state->state, ++ cur_bridge); ++ if (WARN_ON(!cur_state)) ++ return -EINVAL; ++ ++ /* ++ * If bus format negotiation is not supported by this bridge, let's ++ * pass MEDIA_BUS_FMT_FIXED to the previous bridge in the chain and ++ * hope that it can handle this situation gracefully (by providing ++ * appropriate default values). ++ */ ++ if (!cur_bridge->funcs->atomic_get_input_bus_fmts) { ++ if (cur_bridge != first_bridge) { ++ ret = select_bus_fmt_recursive(first_bridge, ++ prev_bridge, crtc_state, ++ conn_state, ++ MEDIA_BUS_FMT_FIXED); ++ if (ret) ++ return ret; ++ } ++ ++ cur_state->input_bus_cfg.format = MEDIA_BUS_FMT_FIXED; ++ cur_state->output_bus_cfg.format = out_bus_fmt; ++ return 0; ++ } ++ ++ in_bus_fmts = cur_bridge->funcs->atomic_get_input_bus_fmts(cur_bridge, ++ cur_state, ++ crtc_state, ++ conn_state, ++ out_bus_fmt, ++ &num_in_bus_fmts); ++ if (!num_in_bus_fmts) ++ return -ENOTSUPP; ++ else if (!in_bus_fmts) ++ return -ENOMEM; ++ ++ if (first_bridge == cur_bridge) { ++ cur_state->input_bus_cfg.format = in_bus_fmts[0]; ++ cur_state->output_bus_cfg.format = out_bus_fmt; ++ kfree(in_bus_fmts); ++ return 0; ++ } ++ ++ for (i = 0; i < num_in_bus_fmts; i++) { ++ ret = select_bus_fmt_recursive(first_bridge, prev_bridge, ++ crtc_state, conn_state, ++ in_bus_fmts[i]); ++ if (ret != -ENOTSUPP) ++ break; ++ } ++ ++ if (!ret) { ++ cur_state->input_bus_cfg.format = in_bus_fmts[i]; ++ cur_state->output_bus_cfg.format = out_bus_fmt; ++ } ++ ++ kfree(in_bus_fmts); ++ return ret; ++} ++ ++/* ++ * This function is called by &drm_atomic_bridge_chain_check() just before ++ * calling &drm_bridge_funcs.atomic_check() on all elements of the chain. ++ * It performs bus format negotiation between bridge elements. The negotiation ++ * happens in reverse order, starting from the last element in the chain up to ++ * @bridge. ++ * ++ * Negotiation starts by retrieving supported output bus formats on the last ++ * bridge element and testing them one by one. The test is recursive, meaning ++ * that for each tested output format, the whole chain will be walked backward, ++ * and each element will have to choose an input bus format that can be ++ * transcoded to the requested output format. When a bridge element does not ++ * support transcoding into a specific output format -ENOTSUPP is returned and ++ * the next bridge element will have to try a different format. If none of the ++ * combinations worked, -ENOTSUPP is returned and the atomic modeset will fail. ++ * ++ * This implementation is relying on ++ * &drm_bridge_funcs.atomic_get_output_bus_fmts() and ++ * &drm_bridge_funcs.atomic_get_input_bus_fmts() to gather supported ++ * input/output formats. ++ * ++ * When &drm_bridge_funcs.atomic_get_output_bus_fmts() is not implemented by ++ * the last element of the chain, &drm_atomic_bridge_chain_select_bus_fmts() ++ * tries a single format: &drm_connector.display_info.bus_formats[0] if ++ * available, MEDIA_BUS_FMT_FIXED otherwise. ++ * ++ * When &drm_bridge_funcs.atomic_get_input_bus_fmts() is not implemented, ++ * &drm_atomic_bridge_chain_select_bus_fmts() skips the negotiation on the ++ * bridge element that lacks this hook and asks the previous element in the ++ * chain to try MEDIA_BUS_FMT_FIXED. It's up to bridge drivers to decide what ++ * to do in that case (fail if they want to enforce bus format negotiation, or ++ * provide a reasonable default if they need to support pipelines where not ++ * all elements support bus format negotiation). ++ */ ++static int ++drm_atomic_bridge_chain_select_bus_fmts(struct drm_bridge *bridge, ++ struct drm_crtc_state *crtc_state, ++ struct drm_connector_state *conn_state) ++{ ++ struct drm_connector *conn = conn_state->connector; ++ struct drm_encoder *encoder = bridge->encoder; ++ struct drm_bridge_state *last_bridge_state; ++ unsigned int i, num_out_bus_fmts; ++ struct drm_bridge *last_bridge; ++ u32 *out_bus_fmts; ++ int ret = 0; ++ ++ last_bridge = list_last_entry(&encoder->bridge_chain, ++ struct drm_bridge, chain_node); ++ last_bridge_state = drm_atomic_get_new_bridge_state(crtc_state->state, ++ last_bridge); ++ if (WARN_ON(!last_bridge_state)) ++ return -EINVAL; ++ ++ if (last_bridge->funcs->atomic_get_output_bus_fmts) { ++ const struct drm_bridge_funcs *funcs = last_bridge->funcs; ++ ++ out_bus_fmts = funcs->atomic_get_output_bus_fmts(last_bridge, ++ last_bridge_state, ++ crtc_state, ++ conn_state, ++ &num_out_bus_fmts); ++ if (!num_out_bus_fmts) ++ return -ENOTSUPP; ++ else if (!out_bus_fmts) ++ return -ENOMEM; ++ } else { ++ num_out_bus_fmts = 1; ++ out_bus_fmts = kmalloc(sizeof(*out_bus_fmts), GFP_KERNEL); ++ if (!out_bus_fmts) ++ return -ENOMEM; ++ ++ if (conn->display_info.num_bus_formats && ++ conn->display_info.bus_formats) ++ out_bus_fmts[0] = conn->display_info.bus_formats[0]; ++ else ++ out_bus_fmts[0] = MEDIA_BUS_FMT_FIXED; ++ } ++ ++ for (i = 0; i < num_out_bus_fmts; i++) { ++ ret = select_bus_fmt_recursive(bridge, last_bridge, crtc_state, ++ conn_state, out_bus_fmts[i]); ++ if (ret != -ENOTSUPP) ++ break; ++ } ++ ++ kfree(out_bus_fmts); ++ ++ return ret; ++} ++ ++static void ++drm_atomic_bridge_propagate_bus_flags(struct drm_bridge *bridge, ++ struct drm_connector *conn, ++ struct drm_atomic_state *state) ++{ ++ struct drm_bridge_state *bridge_state, *next_bridge_state; ++ struct drm_bridge *next_bridge; ++ u32 output_flags; ++ ++ bridge_state = drm_atomic_get_new_bridge_state(state, bridge); ++ next_bridge = drm_bridge_get_next_bridge(bridge); ++ ++ /* ++ * Let's try to apply the most common case here, that is, propagate ++ * display_info flags for the last bridge, and propagate the input ++ * flags of the next bridge element to the output end of the current ++ * bridge when the bridge is not the last one. ++ * There are exceptions to this rule, like when signal inversion is ++ * happening at the board level, but that's something drivers can deal ++ * with from their &drm_bridge_funcs.atomic_check() implementation by ++ * simply overriding the flags value we've set here. ++ */ ++ if (!next_bridge) { ++ output_flags = conn->display_info.bus_flags; ++ } else { ++ next_bridge_state = drm_atomic_get_new_bridge_state(state, ++ next_bridge); ++ output_flags = next_bridge_state->input_bus_cfg.flags; ++ } ++ ++ bridge_state->output_bus_cfg.flags = output_flags; ++ ++ /* ++ * Propage the output flags to the input end of the bridge. Again, it's ++ * not necessarily what all bridges want, but that's what most of them ++ * do, and by doing that by default we avoid forcing drivers to ++ * duplicate the "dummy propagation" logic. ++ */ ++ bridge_state->input_bus_cfg.flags = output_flags; ++} ++ + /** + * drm_atomic_bridge_chain_check() - Do an atomic check on the bridge chain + * @bridge: bridge control structure + * @crtc_state: new CRTC state + * @conn_state: new connector state + * +- * Calls &drm_bridge_funcs.atomic_check() (falls back on ++ * First trigger a bus format negotiation before calling ++ * &drm_bridge_funcs.atomic_check() (falls back on + * &drm_bridge_funcs.mode_fixup()) op for all the bridges in the encoder chain, + * starting from the last bridge to the first. These are called before calling + * &drm_encoder_helper_funcs.atomic_check() +@@ -653,12 +901,29 @@ int drm_atomic_bridge_chain_check(struct drm_bridge *bridge, + struct drm_crtc_state *crtc_state, + struct drm_connector_state *conn_state) + { ++ struct drm_connector *conn = conn_state->connector; + struct drm_encoder *encoder = bridge->encoder; + struct drm_bridge *iter; ++ int ret; ++ ++ ret = drm_atomic_bridge_chain_select_bus_fmts(bridge, crtc_state, ++ conn_state); ++ if (ret) ++ return ret; + + list_for_each_entry_reverse(iter, &encoder->bridge_chain, chain_node) { + int ret; + ++ /* ++ * Bus flags are propagated by default. If a bridge needs to ++ * tweak the input bus flags for any reason, it should happen ++ * in its &drm_bridge_funcs.atomic_check() implementation such ++ * that preceding bridges in the chain can propagate the new ++ * bus flags. ++ */ ++ drm_atomic_bridge_propagate_bus_flags(iter, conn, ++ crtc_state->state); ++ + ret = drm_atomic_bridge_check(iter, crtc_state, conn_state); + if (ret) + return ret; +diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h +index 269f0d1da339..192227f03d4b 100644 +--- a/include/drm/drm_bridge.h ++++ b/include/drm/drm_bridge.h +@@ -35,6 +35,38 @@ struct drm_bridge; + struct drm_bridge_timings; + struct drm_panel; + ++/** ++ * struct drm_bus_cfg - bus configuration ++ * ++ * This structure stores the configuration of a physical bus between two ++ * components in an output pipeline, usually between two bridges, an encoder ++ * and a bridge, or a bridge and a connector. ++ * ++ * The bus configuration is stored in &drm_bridge_state separately for the ++ * input and output buses, as seen from the point of view of each bridge. The ++ * bus configuration of a bridge output is usually identical to the ++ * configuration of the next bridge's input, but may differ if the signals are ++ * modified between the two bridges, for instance by an inverter on the board. ++ * The input and output configurations of a bridge may differ if the bridge ++ * modifies the signals internally, for instance by performing format ++ * conversion, or modifying signals polarities. ++ */ ++struct drm_bus_cfg { ++ /** ++ * @fmt: format used on this bus (one of the MEDIA_BUS_FMT_* format) ++ * ++ * This field should not be directly modified by drivers ++ * (&drm_atomic_bridge_chain_select_bus_fmts() takes care of the bus ++ * format negotiation). ++ */ ++ u32 format; ++ ++ /** ++ * @flags: DRM_BUS_* flags used on this bus ++ */ ++ u32 flags; ++}; ++ + /** + * struct drm_bridge_state - Atomic bridge state object + * @base: inherit from &drm_private_state +@@ -44,6 +76,16 @@ struct drm_bridge_state { + struct drm_private_state base; + + struct drm_bridge *bridge; ++ ++ /** ++ * @input_bus_cfg: input bus configuration ++ */ ++ struct drm_bus_cfg input_bus_cfg; ++ ++ /** ++ * @output_bus_cfg: input bus configuration ++ */ ++ struct drm_bus_cfg output_bus_cfg; + }; + + static inline struct drm_bridge_state * +@@ -387,6 +429,72 @@ struct drm_bridge_funcs { + void (*atomic_destroy_state)(struct drm_bridge *bridge, + struct drm_bridge_state *state); + ++ /** ++ * @atomic_get_output_bus_fmts: ++ * ++ * Return the supported bus formats on the output end of a bridge. ++ * The returned array must be allocated with kmalloc() and will be ++ * freed by the caller. If the allocation fails, NULL should be ++ * returned. num_output_fmts must be set to the returned array size. ++ * Formats listed in the returned array should be listed in decreasing ++ * preference order (the core will try all formats until it finds one ++ * that works). ++ * ++ * This method is only called on the last element of the bridge chain ++ * as part of the bus format negotiation process that happens in ++ * &drm_atomic_bridge_chain_select_bus_fmts(). ++ * This method is optional. When not implemented, the core will ++ * fall back to &drm_connector.display_info.bus_formats[0] if ++ * &drm_connector.display_info.num_bus_formats > 0, ++ * or to MEDIA_BUS_FMT_FIXED otherwise. ++ */ ++ u32 *(*atomic_get_output_bus_fmts)(struct drm_bridge *bridge, ++ struct drm_bridge_state *bridge_state, ++ struct drm_crtc_state *crtc_state, ++ struct drm_connector_state *conn_state, ++ unsigned int *num_output_fmts); ++ ++ /** ++ * @atomic_get_input_bus_fmts: ++ * ++ * Return the supported bus formats on the input end of a bridge for ++ * a specific output bus format. ++ * ++ * The returned array must be allocated with kmalloc() and will be ++ * freed by the caller. If the allocation fails, NULL should be ++ * returned. num_output_fmts must be set to the returned array size. ++ * Formats listed in the returned array should be listed in decreasing ++ * preference order (the core will try all formats until it finds one ++ * that works). When the format is not supported NULL should be ++ * returned and *num_output_fmts should be set to 0. ++ * ++ * This method is called on all elements of the bridge chain as part of ++ * the bus format negotiation process that happens in ++ * &drm_atomic_bridge_chain_select_bus_fmts(). ++ * This method is optional. When not implemented, the core will bypass ++ * bus format negotiation on this element of the bridge without ++ * failing, and the previous element in the chain will be passed ++ * MEDIA_BUS_FMT_FIXED as its output bus format. ++ * ++ * Bridge drivers that need to support being linked to bridges that are ++ * not supporting bus format negotiation should handle the ++ * output_fmt == MEDIA_BUS_FMT_FIXED case appropriately, by selecting a ++ * sensible default value or extracting this information from somewhere ++ * else (FW property, &drm_display_mode, &drm_display_info, ...) ++ * ++ * Note: Even if input format selection on the first bridge has no ++ * impact on the negotiation process (bus format negotiation stops once ++ * we reach the first element of the chain), drivers are expected to ++ * return accurate input formats as the input format may be used to ++ * configure the CRTC output appropriately. ++ */ ++ u32 *(*atomic_get_input_bus_fmts)(struct drm_bridge *bridge, ++ struct drm_bridge_state *bridge_state, ++ struct drm_crtc_state *crtc_state, ++ struct drm_connector_state *conn_state, ++ u32 output_fmt, ++ unsigned int *num_input_fmts); ++ + /** + * @atomic_check: + * +@@ -401,6 +509,14 @@ struct drm_bridge_funcs { + * called when &drm_bridge_funcs.atomic_check() is implemented, so only + * one of them should be provided. + * ++ * If drivers need to tweak &drm_bridge_state.input_bus_cfg.flags or ++ * &drm_bridge_state.output_bus_cfg.flags it should should happen in ++ * this function. By default the &drm_bridge_state.output_bus_cfg.flags ++ * field is set to the next bridge ++ * &drm_bridge_state.input_bus_cfg.flags value or ++ * &drm_connector.display_info.bus_flags if the bridge is the last ++ * element in the chain. ++ * + * RETURNS: + * zero if the check passed, a negative error code otherwise. + */ +@@ -588,6 +704,14 @@ void drm_atomic_bridge_chain_pre_enable(struct drm_bridge *bridge, + void drm_atomic_bridge_chain_enable(struct drm_bridge *bridge, + struct drm_atomic_state *state); + ++u32 * ++drm_atomic_helper_bridge_propagate_bus_fmt(struct drm_bridge *bridge, ++ struct drm_bridge_state *bridge_state, ++ struct drm_crtc_state *crtc_state, ++ struct drm_connector_state *conn_state, ++ u32 output_fmt, ++ unsigned int *num_input_fmts); ++ + void __drm_atomic_helper_bridge_reset(struct drm_bridge *bridge, + struct drm_bridge_state *state); + void drm_atomic_helper_bridge_destroy_state(struct drm_bridge *bridge, +-- +2.17.1 + + +From 152ee505b889cb0f5bc3ad4af82b43a8f4f6562b Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Wed, 18 Dec 2019 16:46:28 +0100 +Subject: [PATCH] drm/bridge: dw-hdmi: set mtmdsclock for deep color + +Configure the correct mtmdsclock for deep colors to prepare support +for 10, 12 & 16bit output. + +Signed-off-by: Jonas Karlman +Signed-off-by: Neil Armstrong +--- + drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + +diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +index 24965e53d351..b8b91d28f398 100644 +--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c ++++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +@@ -1824,9 +1824,26 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi, + + dev_dbg(hdmi->dev, "final pixclk = %d\n", vmode->mpixelclock); + ++ if (!hdmi_bus_fmt_is_yuv422(hdmi->hdmi_data.enc_out_bus_format)) { ++ switch (hdmi_bus_fmt_color_depth( ++ hdmi->hdmi_data.enc_out_bus_format)) { ++ case 16: ++ vmode->mtmdsclock = (u64)vmode->mpixelclock * 2; ++ break; ++ case 12: ++ vmode->mtmdsclock = (u64)vmode->mpixelclock * 3 / 2; ++ break; ++ case 10: ++ vmode->mtmdsclock = (u64)vmode->mpixelclock * 5 / 4; ++ break; ++ } ++ } ++ + if (hdmi_bus_fmt_is_yuv420(hdmi->hdmi_data.enc_out_bus_format)) + vmode->mtmdsclock /= 2; + ++ dev_dbg(hdmi->dev, "final tmdsclk = %d\n", vmode->mtmdsclock); ++ + /* Set up HDMI_FC_INVIDCONF */ + inv_val = (hdmi->hdmi_data.hdcp_enable || + (dw_hdmi_support_scdc(hdmi) && +-- +2.17.1 + + +From 7cc0932dda90b853ff45cbe43688d5888a81d0b7 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Wed, 18 Dec 2019 16:46:29 +0100 +Subject: [PATCH] drm/bridge: dw-hdmi: add max bpc connector property + +Add the max_bpc property to the dw-hdmi connector to prepare support +for 10, 12 & 16bit output support. + +Signed-off-by: Jonas Karlman +Signed-off-by: Neil Armstrong +--- + drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +index b8b91d28f398..8da173798ed4 100644 +--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c ++++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +@@ -2412,6 +2412,10 @@ static int dw_hdmi_bridge_attach(struct drm_bridge *bridge) + DRM_MODE_CONNECTOR_HDMIA, + hdmi->ddc); + ++ drm_atomic_helper_connector_reset(connector); ++ ++ drm_connector_attach_max_bpc_property(connector, 8, 16); ++ + if (hdmi->version >= 0x200a && hdmi->plat_data->use_drm_infoframe) + drm_object_attach_property(&connector->base, + connector->dev->mode_config.hdr_output_metadata_property, 0); +-- +2.17.1 + + +From d38c69cb5bb12563a7a533ae5eb75453e736f85b Mon Sep 17 00:00:00 2001 +From: Neil Armstrong +Date: Wed, 18 Dec 2019 16:46:30 +0100 +Subject: [PATCH] drm/bridge: synopsys: dw-hdmi: add bus format negociation + +Add the atomic_get_output_bus_fmts, atomic_get_input_bus_fmts to negociate +the possible output and input formats for the current mode and monitor, +and use the negotiated formats in a basic atomic_check callback. + +Signed-off-by: Neil Armstrong +--- + drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 272 +++++++++++++++++++++- + 1 file changed, 268 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +index 8da173798ed4..88da301dc086 100644 +--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c ++++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +@@ -2101,11 +2101,10 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode *mode) + hdmi->hdmi_data.video_mode.mpixelrepetitionoutput = 0; + hdmi->hdmi_data.video_mode.mpixelrepetitioninput = 0; + +- /* TOFIX: Get input format from plat data or fallback to RGB888 */ + if (hdmi->plat_data->input_bus_format) + hdmi->hdmi_data.enc_in_bus_format = + hdmi->plat_data->input_bus_format; +- else ++ else if (hdmi->hdmi_data.enc_in_bus_format == MEDIA_BUS_FMT_FIXED) + hdmi->hdmi_data.enc_in_bus_format = MEDIA_BUS_FMT_RGB888_1X24; + + /* TOFIX: Get input encoding from plat data or fallback to none */ +@@ -2115,8 +2114,8 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode *mode) + else + hdmi->hdmi_data.enc_in_encoding = V4L2_YCBCR_ENC_DEFAULT; + +- /* TOFIX: Default to RGB888 output format */ +- hdmi->hdmi_data.enc_out_bus_format = MEDIA_BUS_FMT_RGB888_1X24; ++ if (hdmi->hdmi_data.enc_out_bus_format == MEDIA_BUS_FMT_FIXED) ++ hdmi->hdmi_data.enc_out_bus_format = MEDIA_BUS_FMT_RGB888_1X24; + + hdmi->hdmi_data.pix_repet_factor = 0; + hdmi->hdmi_data.hdcp_enable = 0; +@@ -2394,6 +2393,267 @@ static const struct drm_connector_helper_funcs dw_hdmi_connector_helper_funcs = + .atomic_check = dw_hdmi_connector_atomic_check, + }; + ++/* ++ * Possible output formats : ++ * - MEDIA_BUS_FMT_UYYVYY16_0_5X48, ++ * - MEDIA_BUS_FMT_UYYVYY12_0_5X36, ++ * - MEDIA_BUS_FMT_UYYVYY10_0_5X30, ++ * - MEDIA_BUS_FMT_UYYVYY8_0_5X24, ++ * - MEDIA_BUS_FMT_YUV16_1X48, ++ * - MEDIA_BUS_FMT_RGB161616_1X48, ++ * - MEDIA_BUS_FMT_UYVY12_1X24, ++ * - MEDIA_BUS_FMT_YUV12_1X36, ++ * - MEDIA_BUS_FMT_RGB121212_1X36, ++ * - MEDIA_BUS_FMT_UYVY10_1X20, ++ * - MEDIA_BUS_FMT_YUV10_1X30, ++ * - MEDIA_BUS_FMT_RGB101010_1X30, ++ * - MEDIA_BUS_FMT_UYVY8_1X16, ++ * - MEDIA_BUS_FMT_YUV8_1X24, ++ * - MEDIA_BUS_FMT_RGB888_1X24, ++ */ ++ ++/* Can return a maximum of 12 possible output formats for a mode/connector */ ++#define MAX_OUTPUT_SEL_FORMATS 12 ++ ++static u32 *dw_hdmi_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge, ++ struct drm_bridge_state *bridge_state, ++ struct drm_crtc_state *crtc_state, ++ struct drm_connector_state *conn_state, ++ unsigned int *num_output_fmts) ++{ ++ struct drm_connector *conn = conn_state->connector; ++ struct drm_display_info *info = &conn->display_info; ++ struct drm_display_mode *mode = &crtc_state->mode; ++ u8 max_bpc = conn_state->max_requested_bpc; ++ bool is_hdmi2_sink = info->hdmi.scdc.supported || ++ (info->color_formats & DRM_COLOR_FORMAT_YCRCB420); ++ u32 *output_fmts; ++ int i = 0; ++ ++ *num_output_fmts = 0; ++ ++ output_fmts = kcalloc(MAX_OUTPUT_SEL_FORMATS, sizeof(*output_fmts), ++ GFP_KERNEL); ++ if (!output_fmts) ++ return NULL; ++ ++ /* ++ * If the current mode enforces 4:2:0, force the output but format ++ * to 4:2:0 and do not add the YUV422/444/RGB formats ++ */ ++ if (conn->ycbcr_420_allowed && ++ (drm_mode_is_420_only(info, mode) || ++ (is_hdmi2_sink && drm_mode_is_420_also(info, mode)))) { ++ ++ /* Order bus formats from 16bit to 8bit if supported */ ++ if (max_bpc >= 16 && info->bpc == 16 && ++ (info->hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_48)) ++ output_fmts[i++] = MEDIA_BUS_FMT_UYYVYY16_0_5X48; ++ ++ if (max_bpc >= 12 && info->bpc >= 12 && ++ (info->hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_36)) ++ output_fmts[i++] = MEDIA_BUS_FMT_UYYVYY12_0_5X36; ++ ++ if (max_bpc >= 10 && info->bpc >= 10 && ++ (info->hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_30)) ++ output_fmts[i++] = MEDIA_BUS_FMT_UYYVYY10_0_5X30; ++ ++ /* Default 8bit fallback */ ++ output_fmts[i++] = MEDIA_BUS_FMT_UYYVYY8_0_5X24; ++ ++ *num_output_fmts = i; ++ ++ return output_fmts; ++ } ++ ++ /* ++ * Order bus formats from 16bit to 8bit and from YUV422 to RGB ++ * if supported. In any case the default RGB888 format is added ++ */ ++ ++ if (max_bpc >= 16 && info->bpc == 16) { ++ if (info->color_formats & DRM_COLOR_FORMAT_YCRCB444) ++ output_fmts[i++] = MEDIA_BUS_FMT_YUV16_1X48; ++ ++ output_fmts[i++] = MEDIA_BUS_FMT_RGB161616_1X48; ++ } ++ ++ if (max_bpc >= 12 && info->bpc >= 12) { ++ if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422) ++ output_fmts[i++] = MEDIA_BUS_FMT_UYVY12_1X24; ++ ++ if (info->color_formats & DRM_COLOR_FORMAT_YCRCB444) ++ output_fmts[i++] = MEDIA_BUS_FMT_YUV12_1X36; ++ ++ output_fmts[i++] = MEDIA_BUS_FMT_RGB121212_1X36; ++ } ++ ++ if (max_bpc >= 10 && info->bpc >= 10) { ++ if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422) ++ output_fmts[i++] = MEDIA_BUS_FMT_UYVY10_1X20; ++ ++ if (info->color_formats & DRM_COLOR_FORMAT_YCRCB444) ++ output_fmts[i++] = MEDIA_BUS_FMT_YUV10_1X30; ++ ++ output_fmts[i++] = MEDIA_BUS_FMT_RGB101010_1X30; ++ } ++ ++ if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422) ++ output_fmts[i++] = MEDIA_BUS_FMT_UYVY8_1X16; ++ ++ if (info->color_formats & DRM_COLOR_FORMAT_YCRCB444) ++ output_fmts[i++] = MEDIA_BUS_FMT_YUV8_1X24; ++ ++ /* Default 8bit RGB fallback */ ++ output_fmts[i++] = MEDIA_BUS_FMT_RGB888_1X24; ++ ++ *num_output_fmts = i; ++ ++ return output_fmts; ++} ++ ++/* ++ * Possible input formats : ++ * - MEDIA_BUS_FMT_RGB888_1X24 ++ * - MEDIA_BUS_FMT_YUV8_1X24 ++ * - MEDIA_BUS_FMT_UYVY8_1X16 ++ * - MEDIA_BUS_FMT_UYYVYY8_0_5X24 ++ * - MEDIA_BUS_FMT_RGB101010_1X30 ++ * - MEDIA_BUS_FMT_YUV10_1X30 ++ * - MEDIA_BUS_FMT_UYVY10_1X20 ++ * - MEDIA_BUS_FMT_UYYVYY10_0_5X30 ++ * - MEDIA_BUS_FMT_RGB121212_1X36 ++ * - MEDIA_BUS_FMT_YUV12_1X36 ++ * - MEDIA_BUS_FMT_UYVY12_1X24 ++ * - MEDIA_BUS_FMT_UYYVYY12_0_5X36 ++ * - MEDIA_BUS_FMT_RGB161616_1X48 ++ * - MEDIA_BUS_FMT_YUV16_1X48 ++ * - MEDIA_BUS_FMT_UYYVYY16_0_5X48 ++ */ ++ ++/* Can return a maximum of 4 possible input formats for an output format */ ++#define MAX_INPUT_SEL_FORMATS 4 ++ ++static u32 *dw_hdmi_bridge_atomic_get_input_bus_fmts(struct drm_bridge *bridge, ++ struct drm_bridge_state *bridge_state, ++ struct drm_crtc_state *crtc_state, ++ struct drm_connector_state *conn_state, ++ u32 output_fmt, ++ unsigned int *num_input_fmts) ++{ ++ u32 *input_fmts; ++ int i = 0; ++ ++ *num_input_fmts = 0; ++ ++ input_fmts = kcalloc(MAX_INPUT_SEL_FORMATS, sizeof(*input_fmts), ++ GFP_KERNEL); ++ if (!input_fmts) ++ return NULL; ++ ++ switch (output_fmt) { ++ /* 8bit */ ++ case MEDIA_BUS_FMT_RGB888_1X24: ++ input_fmts[i++] = MEDIA_BUS_FMT_RGB888_1X24; ++ input_fmts[i++] = MEDIA_BUS_FMT_YUV8_1X24; ++ input_fmts[i++] = MEDIA_BUS_FMT_UYVY8_1X16; ++ break; ++ case MEDIA_BUS_FMT_YUV8_1X24: ++ input_fmts[i++] = MEDIA_BUS_FMT_YUV8_1X24; ++ input_fmts[i++] = MEDIA_BUS_FMT_UYVY8_1X16; ++ input_fmts[i++] = MEDIA_BUS_FMT_RGB888_1X24; ++ break; ++ case MEDIA_BUS_FMT_UYVY8_1X16: ++ input_fmts[i++] = MEDIA_BUS_FMT_UYVY8_1X16; ++ input_fmts[i++] = MEDIA_BUS_FMT_YUV8_1X24; ++ input_fmts[i++] = MEDIA_BUS_FMT_RGB888_1X24; ++ break; ++ ++ /* 10bit */ ++ case MEDIA_BUS_FMT_RGB101010_1X30: ++ input_fmts[i++] = MEDIA_BUS_FMT_RGB101010_1X30; ++ input_fmts[i++] = MEDIA_BUS_FMT_YUV10_1X30; ++ input_fmts[i++] = MEDIA_BUS_FMT_UYVY10_1X20; ++ break; ++ case MEDIA_BUS_FMT_YUV10_1X30: ++ input_fmts[i++] = MEDIA_BUS_FMT_YUV10_1X30; ++ input_fmts[i++] = MEDIA_BUS_FMT_UYVY10_1X20; ++ input_fmts[i++] = MEDIA_BUS_FMT_RGB101010_1X30; ++ break; ++ case MEDIA_BUS_FMT_UYVY10_1X20: ++ input_fmts[i++] = MEDIA_BUS_FMT_UYVY10_1X20; ++ input_fmts[i++] = MEDIA_BUS_FMT_YUV10_1X30; ++ input_fmts[i++] = MEDIA_BUS_FMT_RGB101010_1X30; ++ break; ++ ++ /* 12bit */ ++ case MEDIA_BUS_FMT_RGB121212_1X36: ++ input_fmts[i++] = MEDIA_BUS_FMT_RGB121212_1X36; ++ input_fmts[i++] = MEDIA_BUS_FMT_YUV12_1X36; ++ input_fmts[i++] = MEDIA_BUS_FMT_UYVY12_1X24; ++ break; ++ case MEDIA_BUS_FMT_YUV12_1X36: ++ input_fmts[i++] = MEDIA_BUS_FMT_YUV12_1X36; ++ input_fmts[i++] = MEDIA_BUS_FMT_UYVY12_1X24; ++ input_fmts[i++] = MEDIA_BUS_FMT_RGB121212_1X36; ++ break; ++ case MEDIA_BUS_FMT_UYVY12_1X24: ++ input_fmts[i++] = MEDIA_BUS_FMT_UYVY12_1X24; ++ input_fmts[i++] = MEDIA_BUS_FMT_YUV12_1X36; ++ input_fmts[i++] = MEDIA_BUS_FMT_RGB121212_1X36; ++ break; ++ ++ /* 16bit */ ++ case MEDIA_BUS_FMT_RGB161616_1X48: ++ input_fmts[i++] = MEDIA_BUS_FMT_RGB161616_1X48; ++ input_fmts[i++] = MEDIA_BUS_FMT_YUV16_1X48; ++ break; ++ case MEDIA_BUS_FMT_YUV16_1X48: ++ input_fmts[i++] = MEDIA_BUS_FMT_YUV16_1X48; ++ input_fmts[i++] = MEDIA_BUS_FMT_RGB161616_1X48; ++ break; ++ ++ /* 420 */ ++ case MEDIA_BUS_FMT_UYYVYY8_0_5X24: ++ case MEDIA_BUS_FMT_UYYVYY10_0_5X30: ++ case MEDIA_BUS_FMT_UYYVYY12_0_5X36: ++ case MEDIA_BUS_FMT_UYYVYY16_0_5X48: ++ input_fmts[i++] = output_fmt; ++ break; ++ } ++ ++ *num_input_fmts = i; ++ ++ if (*num_input_fmts == 0) { ++ kfree(input_fmts); ++ input_fmts = NULL; ++ } ++ ++ return input_fmts; ++} ++ ++static int dw_hdmi_bridge_atomic_check(struct drm_bridge *bridge, ++ struct drm_bridge_state *bridge_state, ++ struct drm_crtc_state *crtc_state, ++ struct drm_connector_state *conn_state) ++{ ++ struct dw_hdmi *hdmi = bridge->driver_private; ++ ++ dev_dbg(hdmi->dev, "selected output format %x\n", ++ bridge_state->output_bus_cfg.format); ++ ++ hdmi->hdmi_data.enc_out_bus_format = ++ bridge_state->output_bus_cfg.format; ++ ++ dev_dbg(hdmi->dev, "selected input format %x\n", ++ bridge_state->input_bus_cfg.format); ++ ++ hdmi->hdmi_data.enc_in_bus_format = ++ bridge_state->input_bus_cfg.format; ++ ++ return 0; ++} ++ + static int dw_hdmi_bridge_attach(struct drm_bridge *bridge) + { + struct dw_hdmi *hdmi = bridge->driver_private; +@@ -2502,6 +2762,9 @@ static void dw_hdmi_bridge_enable(struct drm_bridge *bridge) + static const struct drm_bridge_funcs dw_hdmi_bridge_funcs = { + .attach = dw_hdmi_bridge_attach, + .detach = dw_hdmi_bridge_detach, ++ .atomic_check = dw_hdmi_bridge_atomic_check, ++ .atomic_get_output_bus_fmts = dw_hdmi_bridge_atomic_get_output_bus_fmts, ++ .atomic_get_input_bus_fmts = dw_hdmi_bridge_atomic_get_input_bus_fmts, + .enable = dw_hdmi_bridge_enable, + .disable = dw_hdmi_bridge_disable, + .mode_set = dw_hdmi_bridge_mode_set, +@@ -2966,6 +3229,7 @@ __dw_hdmi_probe(struct platform_device *pdev, + + hdmi->bridge.driver_private = hdmi; + hdmi->bridge.funcs = &dw_hdmi_bridge_funcs; ++ + #ifdef CONFIG_OF + hdmi->bridge.of_node = pdev->dev.of_node; + #endif +-- +2.17.1 + + +From 9c8d9cb1a3fa8b7cfe1052c1e6e549c294f65f69 Mon Sep 17 00:00:00 2001 +From: Neil Armstrong +Date: Wed, 18 Dec 2019 16:46:31 +0100 +Subject: [PATCH] drm/bridge: synopsys: dw-hdmi: allow ycbcr420 modes for >= + 0x200a + +Now the DW-HDMI Controller supports the HDMI2.0 modes, enable support +for these modes in the connector if the platform supports them. +We limit these modes to DW-HDMI IP version >= 0x200a which +are designed to support HDMI2.0 display modes. + +Signed-off-by: Neil Armstrong +--- + drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 6 ++++++ + include/drm/bridge/dw_hdmi.h | 1 + + 2 files changed, 7 insertions(+) + +diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +index 88da301dc086..5749bdaba95b 100644 +--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c ++++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +@@ -3234,6 +3234,12 @@ __dw_hdmi_probe(struct platform_device *pdev, + hdmi->bridge.of_node = pdev->dev.of_node; + #endif + ++ if (hdmi->version >= 0x200a) ++ hdmi->connector.ycbcr_420_allowed = ++ hdmi->plat_data->ycbcr_420_allowed; ++ else ++ hdmi->connector.ycbcr_420_allowed = false; ++ + memset(&pdevinfo, 0, sizeof(pdevinfo)); + pdevinfo.parent = dev; + pdevinfo.id = PLATFORM_DEVID_AUTO; +diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h +index 9d4d5cc47969..0b34a12c4a1c 100644 +--- a/include/drm/bridge/dw_hdmi.h ++++ b/include/drm/bridge/dw_hdmi.h +@@ -129,6 +129,7 @@ struct dw_hdmi_plat_data { + unsigned long input_bus_format; + unsigned long input_bus_encoding; + bool use_drm_infoframe; ++ bool ycbcr_420_allowed; + + /* Vendor PHY support */ + const struct dw_hdmi_phy_ops *phy_ops; +-- +2.17.1 + diff --git a/patch/kernel/rk322x-current/01-linux-0004-work-in-progress.patch b/patch/kernel/rk322x-current/01-linux-0004-work-in-progress.patch new file mode 100644 index 0000000000..c09268ef69 --- /dev/null +++ b/patch/kernel/rk322x-current/01-linux-0004-work-in-progress.patch @@ -0,0 +1,2864 @@ +diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +index 5749bdaba95b..3b383f73fcb0 100644 +--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c ++++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +@@ -197,7 +197,7 @@ struct dw_hdmi { + + hdmi_codec_plugged_cb plugged_cb; + struct device *codec_dev; +- enum drm_connector_status last_connector_result; ++ enum drm_connector_status last_connector_status; + }; + + #define HDMI_IH_PHY_STAT0_RX_SENSE \ +@@ -236,7 +236,7 @@ int dw_hdmi_set_plugged_cb(struct dw_hdmi *hdmi, hdmi_codec_plugged_cb fn, + mutex_lock(&hdmi->mutex); + hdmi->plugged_cb = fn; + hdmi->codec_dev = codec_dev; +- plugged = hdmi->last_connector_result == connector_status_connected; ++ plugged = hdmi->last_connector_status == connector_status_connected; + handle_plugged_change(hdmi, plugged); + mutex_unlock(&hdmi->mutex); + +@@ -2277,7 +2277,7 @@ dw_hdmi_connector_detect(struct drm_connector *connector, bool force) + { + struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi, + connector); +- enum drm_connector_status result; ++ enum drm_connector_status status; + + mutex_lock(&hdmi->mutex); + hdmi->force = DRM_FORCE_UNSPECIFIED; +@@ -2285,18 +2285,18 @@ dw_hdmi_connector_detect(struct drm_connector *connector, bool force) + dw_hdmi_update_phy_mask(hdmi); + mutex_unlock(&hdmi->mutex); + +- result = hdmi->phy.ops->read_hpd(hdmi, hdmi->phy.data); ++ status = hdmi->phy.ops->read_hpd(hdmi, hdmi->phy.data); + + mutex_lock(&hdmi->mutex); +- if (result != hdmi->last_connector_result) { +- dev_dbg(hdmi->dev, "read_hpd result: %d", result); ++ if (status != hdmi->last_connector_status) { ++ dev_dbg(hdmi->dev, "connector status: %d", status); + handle_plugged_change(hdmi, +- result == connector_status_connected); +- hdmi->last_connector_result = result; ++ status == connector_status_connected); ++ hdmi->last_connector_status = status; + } + mutex_unlock(&hdmi->mutex); + +- return result; ++ return status; + } + + static int dw_hdmi_connector_get_modes(struct drm_connector *connector) +@@ -3059,7 +3059,7 @@ __dw_hdmi_probe(struct platform_device *pdev, + hdmi->rxsense = true; + hdmi->phy_mask = (u8)~(HDMI_PHY_HPD | HDMI_PHY_RX_SENSE); + hdmi->mc_clkdis = 0x7f; +- hdmi->last_connector_result = connector_status_disconnected; ++ hdmi->last_connector_status = connector_status_disconnected; + + mutex_init(&hdmi->mutex); + mutex_init(&hdmi->audio_mutex); +-- +2.17.1 + + +From 2cdd6cd8eae12254226b6f3e30c5bcc52ac93ca7 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 1 Dec 2019 20:51:22 +0000 +Subject: [PATCH] drm: dw-hdmi: extract handle_plugged_change call + +Signed-off-by: Jonas Karlman +--- + drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 22 ++++++++++++++-------- + 1 file changed, 14 insertions(+), 8 deletions(-) + +diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +index 3b383f73fcb0..bb430c48488f 100644 +--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c ++++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +@@ -228,6 +228,19 @@ static void handle_plugged_change(struct dw_hdmi *hdmi, bool plugged) + hdmi->plugged_cb(hdmi->codec_dev, plugged); + } + ++static void dw_hdmi_update_connector_status(struct dw_hdmi *hdmi, ++ enum drm_connector_status status) ++{ ++ mutex_lock(&hdmi->mutex); ++ if (status != hdmi->last_connector_status) { ++ dev_dbg(hdmi->dev, "connector status: %d", status); ++ handle_plugged_change(hdmi, ++ status == connector_status_connected); ++ hdmi->last_connector_status = status; ++ } ++ mutex_unlock(&hdmi->mutex); ++} ++ + int dw_hdmi_set_plugged_cb(struct dw_hdmi *hdmi, hdmi_codec_plugged_cb fn, + struct device *codec_dev) + { +@@ -2287,14 +2300,7 @@ dw_hdmi_connector_detect(struct drm_connector *connector, bool force) + + status = hdmi->phy.ops->read_hpd(hdmi, hdmi->phy.data); + +- mutex_lock(&hdmi->mutex); +- if (status != hdmi->last_connector_status) { +- dev_dbg(hdmi->dev, "connector status: %d", status); +- handle_plugged_change(hdmi, +- status == connector_status_connected); +- hdmi->last_connector_status = status; +- } +- mutex_unlock(&hdmi->mutex); ++ dw_hdmi_update_connector_status(hdmi, status); + + return status; + } +-- +2.17.1 + + +From 979981e11fa3ba5e94d25d22f7d0cdc55e8f9348 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sat, 28 Sep 2019 13:34:46 +0000 +Subject: [PATCH] drm: dw-hdmi: remove unused struct member + +Signed-off-by: Jonas Karlman +--- + drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +index bb430c48488f..06620adfed95 100644 +--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c ++++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +@@ -41,8 +41,6 @@ + #define DDC_CI_ADDR 0x37 + #define DDC_SEGMENT_ADDR 0x30 + +-#define HDMI_EDID_LEN 512 +- + /* DW-HDMI Controller >= 0x200a are at least compliant with SCDC version 1 */ + #define SCDC_MIN_SOURCE_VERSION 0x1 + +@@ -152,8 +150,6 @@ struct dw_hdmi { + + int vic; + +- u8 edid[HDMI_EDID_LEN]; +- + struct { + const struct dw_hdmi_phy_ops *ops; + const char *name; +-- +2.17.1 + + +From 74adf054fd1d83d31f03085ec4574318cb135c95 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sat, 28 Sep 2019 13:34:46 +0000 +Subject: [PATCH] drm: dw-hdmi: read edid in detect callback + +Signed-off-by: Jonas Karlman +--- + drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 79 +++++++++++++++++------ + 1 file changed, 58 insertions(+), 21 deletions(-) + +diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +index 06620adfed95..a304dff5f1be 100644 +--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c ++++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +@@ -150,6 +150,8 @@ struct dw_hdmi { + + int vic; + ++ struct edid *cached_edid; ++ + struct { + const struct dw_hdmi_phy_ops *ops; + const char *name; +@@ -2223,9 +2225,55 @@ static void initialize_hdmi_ih_mutes(struct dw_hdmi *hdmi) + hdmi_writeb(hdmi, ih_mute, HDMI_IH_MUTE); + } + ++static void dw_hdmi_clear_edid(struct drm_connector *connector) ++{ ++ struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi, ++ connector); ++ ++ if (!hdmi->cached_edid) ++ return; ++ ++ hdmi->sink_is_hdmi = false; ++ hdmi->sink_has_audio = false; ++ ++ kfree(hdmi->cached_edid); ++ hdmi->cached_edid = NULL; ++} ++ ++static void dw_hdmi_get_edid(struct drm_connector *connector) ++{ ++ struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi, ++ connector); ++ struct edid *edid; ++ ++ if (!hdmi->ddc || hdmi->cached_edid) ++ return; ++ ++ edid = drm_get_edid(connector, hdmi->ddc); ++ ++ if (edid && edid->input & DRM_EDID_INPUT_DIGITAL) { ++ dev_dbg(hdmi->dev, "got edid: width[%d] x height[%d]\n", ++ edid->width_cm, edid->height_cm); ++ ++ hdmi->sink_is_hdmi = drm_detect_hdmi_monitor(edid); ++ hdmi->sink_has_audio = drm_detect_monitor_audio(edid); ++ ++ hdmi->cached_edid = edid; ++ } else { ++ dev_dbg(hdmi->dev, "failed to get edid\n"); ++ ++ kfree(edid); ++ edid = NULL; ++ } ++ ++ drm_connector_update_edid_property(connector, edid); ++ cec_notifier_set_phys_addr_from_edid(hdmi->cec_notifier, edid); ++} ++ + static void dw_hdmi_poweron(struct dw_hdmi *hdmi) + { + hdmi->bridge_is_on = true; ++ dw_hdmi_get_edid(&hdmi->connector); + dw_hdmi_setup(hdmi, &hdmi->previous_mode); + } + +@@ -2296,6 +2344,11 @@ dw_hdmi_connector_detect(struct drm_connector *connector, bool force) + + status = hdmi->phy.ops->read_hpd(hdmi, hdmi->phy.data); + ++ if (status == connector_status_disconnected) ++ dw_hdmi_clear_edid(connector); ++ else ++ dw_hdmi_get_edid(connector); ++ + dw_hdmi_update_connector_status(hdmi, status); + + return status; +@@ -2305,28 +2358,8 @@ static int dw_hdmi_connector_get_modes(struct drm_connector *connector) + { + struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi, + connector); +- struct edid *edid; +- int ret = 0; +- +- if (!hdmi->ddc) +- return 0; + +- edid = drm_get_edid(connector, hdmi->ddc); +- if (edid) { +- dev_dbg(hdmi->dev, "got edid: width[%d] x height[%d]\n", +- edid->width_cm, edid->height_cm); +- +- hdmi->sink_is_hdmi = drm_detect_hdmi_monitor(edid); +- hdmi->sink_has_audio = drm_detect_monitor_audio(edid); +- drm_connector_update_edid_property(connector, edid); +- cec_notifier_set_phys_addr_from_edid(hdmi->cec_notifier, edid); +- ret = drm_add_edid_modes(connector, edid); +- kfree(edid); +- } else { +- dev_dbg(hdmi->dev, "failed to get edid\n"); +- } +- +- return ret; ++ return drm_add_edid_modes(connector, hdmi->cached_edid); + } + + static bool hdr_metadata_equal(const struct drm_connector_state *old_state, +@@ -2705,6 +2738,9 @@ static void dw_hdmi_bridge_detach(struct drm_bridge *bridge) + cec_notifier_conn_unregister(hdmi->cec_notifier); + hdmi->cec_notifier = NULL; + mutex_unlock(&hdmi->cec_notifier_mutex); ++ ++ kfree(hdmi->cached_edid); ++ hdmi->cached_edid = NULL; + } + + static enum drm_mode_status +@@ -3394,6 +3430,7 @@ EXPORT_SYMBOL_GPL(dw_hdmi_unbind); + + void dw_hdmi_resume(struct dw_hdmi *hdmi) + { ++ dw_hdmi_clear_edid(&hdmi->connector); + dw_hdmi_init_hw(hdmi); + } + EXPORT_SYMBOL_GPL(dw_hdmi_resume); +-- +2.17.1 + + +From f44056d77b1e928d0eec26eef9d35ce3c7b04d30 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sat, 28 Sep 2019 13:34:47 +0000 +Subject: [PATCH] drm: dw-hdmi: read edid in force callback + +Signed-off-by: Jonas Karlman +--- + drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +index a304dff5f1be..49a9611249d2 100644 +--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c ++++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +@@ -2411,6 +2411,13 @@ static void dw_hdmi_connector_force(struct drm_connector *connector) + dw_hdmi_update_power(hdmi); + dw_hdmi_update_phy_mask(hdmi); + mutex_unlock(&hdmi->mutex); ++ ++ dw_hdmi_clear_edid(connector); ++ ++ if (connector->status != connector_status_connected) ++ return; ++ ++ dw_hdmi_get_edid(connector); + } + + static const struct drm_connector_funcs dw_hdmi_connector_funcs = { +-- +2.17.1 + + +From 27119e85c5368957ac0182418a26d473dd94ab49 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sat, 28 Sep 2019 13:34:47 +0000 +Subject: [PATCH] drm: dw-hdmi: invalidate cec phys addr in detect callback + +Signed-off-by: Jonas Karlman +--- + drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 17 +++-------------- + 1 file changed, 3 insertions(+), 14 deletions(-) + +diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +index 49a9611249d2..b9fa6c3b07c0 100644 +--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c ++++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +@@ -190,7 +190,6 @@ struct dw_hdmi { + void (*enable_audio)(struct dw_hdmi *hdmi); + void (*disable_audio)(struct dw_hdmi *hdmi); + +- struct mutex cec_notifier_mutex; + struct cec_notifier *cec_notifier; + + hdmi_codec_plugged_cb plugged_cb; +@@ -2238,6 +2237,8 @@ static void dw_hdmi_clear_edid(struct drm_connector *connector) + + kfree(hdmi->cached_edid); + hdmi->cached_edid = NULL; ++ ++ cec_notifier_phys_addr_invalidate(hdmi->cec_notifier); + } + + static void dw_hdmi_get_edid(struct drm_connector *connector) +@@ -2730,9 +2731,7 @@ static int dw_hdmi_bridge_attach(struct drm_bridge *bridge) + if (!notifier) + return -ENOMEM; + +- mutex_lock(&hdmi->cec_notifier_mutex); + hdmi->cec_notifier = notifier; +- mutex_unlock(&hdmi->cec_notifier_mutex); + + return 0; + } +@@ -2741,10 +2740,8 @@ static void dw_hdmi_bridge_detach(struct drm_bridge *bridge) + { + struct dw_hdmi *hdmi = bridge->driver_private; + +- mutex_lock(&hdmi->cec_notifier_mutex); + cec_notifier_conn_unregister(hdmi->cec_notifier); + hdmi->cec_notifier = NULL; +- mutex_unlock(&hdmi->cec_notifier_mutex); + + kfree(hdmi->cached_edid); + hdmi->cached_edid = NULL; +@@ -2912,18 +2909,11 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id) + * ask the source to re-read the EDID. + */ + if (intr_stat & +- (HDMI_IH_PHY_STAT0_RX_SENSE | HDMI_IH_PHY_STAT0_HPD)) { ++ (HDMI_IH_PHY_STAT0_RX_SENSE | HDMI_IH_PHY_STAT0_HPD)) + dw_hdmi_setup_rx_sense(hdmi, + phy_stat & HDMI_PHY_HPD, + phy_stat & HDMI_PHY_RX_SENSE); + +- if ((phy_stat & (HDMI_PHY_RX_SENSE | HDMI_PHY_HPD)) == 0) { +- mutex_lock(&hdmi->cec_notifier_mutex); +- cec_notifier_phys_addr_invalidate(hdmi->cec_notifier); +- mutex_unlock(&hdmi->cec_notifier_mutex); +- } +- } +- + if (intr_stat & HDMI_IH_PHY_STAT0_HPD) { + dev_dbg(hdmi->dev, "EVENT=%s\n", + phy_int_pol & HDMI_PHY_HPD ? "plugin" : "plugout"); +@@ -3108,7 +3098,6 @@ __dw_hdmi_probe(struct platform_device *pdev, + + mutex_init(&hdmi->mutex); + mutex_init(&hdmi->audio_mutex); +- mutex_init(&hdmi->cec_notifier_mutex); + spin_lock_init(&hdmi->audio_lock); + + ddc_node = of_parse_phandle(np, "ddc-i2c-bus", 0); +-- +2.17.1 + + +From d6fca8d650a43ed3ef7d8efb3b51b2e7c3a0a8ba Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 8 Dec 2019 23:41:44 +0000 +Subject: [PATCH] WIP: drm: dw-hdmi: do not force none scan mode + +Signed-off-by: Jonas Karlman +--- + drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +index b9fa6c3b07c0..4d253e5a1c79 100644 +--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c ++++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +@@ -1664,8 +1664,6 @@ static void hdmi_config_AVI(struct dw_hdmi *hdmi, struct drm_display_mode *mode) + HDMI_EXTENDED_COLORIMETRY_XV_YCC_601; + } + +- frame.scan_mode = HDMI_SCAN_MODE_NONE; +- + /* + * The Designware IP uses a different byte format from standard + * AVI info frames, though generally the bits are in the correct +-- +2.17.1 + + +From b16f499ce83d7b9084073e813943ae98d4f5c716 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 8 Dec 2019 23:42:44 +0000 +Subject: [PATCH] WIP: drm: dw-hdmi: add content type connector property + +Signed-off-by: Jonas Karlman +--- + drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +index 4d253e5a1c79..cd10554cde76 100644 +--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c ++++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +@@ -1617,6 +1617,7 @@ static void hdmi_tx_hdcp_config(struct dw_hdmi *hdmi) + + static void hdmi_config_AVI(struct dw_hdmi *hdmi, struct drm_display_mode *mode) + { ++ const struct drm_connector_state *conn_state = hdmi->connector.state; + struct hdmi_avi_infoframe frame; + u8 val; + +@@ -1664,6 +1665,8 @@ static void hdmi_config_AVI(struct dw_hdmi *hdmi, struct drm_display_mode *mode) + HDMI_EXTENDED_COLORIMETRY_XV_YCC_601; + } + ++ drm_hdmi_avi_infoframe_content_type(&frame, conn_state); ++ + /* + * The Designware IP uses a different byte format from standard + * AVI info frames, though generally the bits are in the correct +@@ -2389,7 +2392,8 @@ static int dw_hdmi_connector_atomic_check(struct drm_connector *connector, + if (!crtc) + return 0; + +- if (!hdr_metadata_equal(old_state, new_state)) { ++ if (!hdr_metadata_equal(old_state, new_state) || ++ old_state->content_type != new_state->content_type) { + crtc_state = drm_atomic_get_crtc_state(state, crtc); + if (IS_ERR(crtc_state)) + return PTR_ERR(crtc_state); +@@ -2717,6 +2721,8 @@ static int dw_hdmi_bridge_attach(struct drm_bridge *bridge) + + drm_connector_attach_max_bpc_property(connector, 8, 16); + ++ drm_connector_attach_content_type_property(connector); ++ + if (hdmi->version >= 0x200a && hdmi->plat_data->use_drm_infoframe) + drm_object_attach_property(&connector->base, + connector->dev->mode_config.hdr_output_metadata_property, 0); +-- +2.17.1 + + +From 2203d10f59f25af58fe1f5aaaceb3980ccea2f39 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 8 Dec 2019 23:43:55 +0000 +Subject: [PATCH] WIP: drm: dw-hdmi: add SPD infoframe + +Signed-off-by: Jonas Karlman +--- + drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 42 +++++++++++++++++++---- + drivers/gpu/drm/bridge/synopsys/dw-hdmi.h | 32 +++++++++-------- + 2 files changed, 53 insertions(+), 21 deletions(-) + +diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +index cd10554cde76..5377c55e9927 100644 +--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c ++++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +@@ -1733,6 +1733,35 @@ static void hdmi_config_AVI(struct dw_hdmi *hdmi, struct drm_display_mode *mode) + hdmi_writeb(hdmi, (frame.right_bar >> 8) & 0xff, HDMI_FC_AVISRB1); + } + ++static void hdmi_config_spd_infoframe(struct dw_hdmi *hdmi) ++{ ++ struct hdmi_spd_infoframe frame; ++ u8 buffer[29]; ++ ssize_t err; ++ int i; ++ ++ hdmi_mask_writeb(hdmi, 0, HDMI_FC_DATAUTO0, HDMI_FC_DATAUTO0_SPD_OFFSET, ++ HDMI_FC_DATAUTO0_SPD_MASK); ++ ++ err = hdmi_spd_infoframe_init(&frame, "DW", "HDMI"); ++ if (err < 0) ++ return; ++ ++ frame.sdi = HDMI_SPD_SDI_PC; ++ ++ err = hdmi_spd_infoframe_pack(&frame, buffer, sizeof(buffer)); ++ if (err < 0) { ++ dev_err(hdmi->dev, "Failed to pack spd infoframe: %zd\n", err); ++ return; ++ } ++ ++ for (i = 0; i < frame.length; i++) ++ hdmi_writeb(hdmi, buffer[4 + i], HDMI_FC_SPDVENDORNAME0 + i); ++ ++ hdmi_mask_writeb(hdmi, 1, HDMI_FC_DATAUTO0, HDMI_FC_DATAUTO0_SPD_OFFSET, ++ HDMI_FC_DATAUTO0_SPD_MASK); ++} ++ + static void hdmi_config_vendor_specific_infoframe(struct dw_hdmi *hdmi, + struct drm_display_mode *mode) + { +@@ -1776,12 +1805,6 @@ static void hdmi_config_vendor_specific_infoframe(struct dw_hdmi *hdmi, + if (frame.s3d_struct >= HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF) + hdmi_writeb(hdmi, buffer[9], HDMI_FC_VSDPAYLOAD2); + +- /* Packet frame interpolation */ +- hdmi_writeb(hdmi, 1, HDMI_FC_DATAUTO1); +- +- /* Auto packets per frame and line spacing */ +- hdmi_writeb(hdmi, 0x11, HDMI_FC_DATAUTO2); +- + /* Configures the Frame Composer On RDRB mode */ + hdmi_mask_writeb(hdmi, 1, HDMI_FC_DATAUTO0, HDMI_FC_DATAUTO0_VSD_OFFSET, + HDMI_FC_DATAUTO0_VSD_MASK); +@@ -2158,8 +2181,15 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode *mode) + + /* HDMI Initialization Step F - Configure AVI InfoFrame */ + hdmi_config_AVI(hdmi, mode); ++ hdmi_config_spd_infoframe(hdmi); + hdmi_config_vendor_specific_infoframe(hdmi, mode); + hdmi_config_drm_infoframe(hdmi); ++ ++ /* Packet frame interpolation */ ++ hdmi_writeb(hdmi, 1, HDMI_FC_DATAUTO1); ++ ++ /* Auto packets per frame and line spacing */ ++ hdmi_writeb(hdmi, 0x11, HDMI_FC_DATAUTO2); + } else { + dev_dbg(hdmi->dev, "%s DVI mode\n", __func__); + } +diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h +index 1999db05bc3b..27a91128d0cc 100644 +--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h ++++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h +@@ -139,21 +139,21 @@ + #define HDMI_FC_SPDVENDORNAME5 0x104F + #define HDMI_FC_SPDVENDORNAME6 0x1050 + #define HDMI_FC_SPDVENDORNAME7 0x1051 +-#define HDMI_FC_SDPPRODUCTNAME0 0x1052 +-#define HDMI_FC_SDPPRODUCTNAME1 0x1053 +-#define HDMI_FC_SDPPRODUCTNAME2 0x1054 +-#define HDMI_FC_SDPPRODUCTNAME3 0x1055 +-#define HDMI_FC_SDPPRODUCTNAME4 0x1056 +-#define HDMI_FC_SDPPRODUCTNAME5 0x1057 +-#define HDMI_FC_SDPPRODUCTNAME6 0x1058 +-#define HDMI_FC_SDPPRODUCTNAME7 0x1059 +-#define HDMI_FC_SDPPRODUCTNAME8 0x105A +-#define HDMI_FC_SDPPRODUCTNAME9 0x105B +-#define HDMI_FC_SDPPRODUCTNAME10 0x105C +-#define HDMI_FC_SDPPRODUCTNAME11 0x105D +-#define HDMI_FC_SDPPRODUCTNAME12 0x105E +-#define HDMI_FC_SDPPRODUCTNAME13 0x105F +-#define HDMI_FC_SDPPRODUCTNAME14 0x1060 ++#define HDMI_FC_SPDPRODUCTNAME0 0x1052 ++#define HDMI_FC_SPDPRODUCTNAME1 0x1053 ++#define HDMI_FC_SPDPRODUCTNAME2 0x1054 ++#define HDMI_FC_SPDPRODUCTNAME3 0x1055 ++#define HDMI_FC_SPDPRODUCTNAME4 0x1056 ++#define HDMI_FC_SPDPRODUCTNAME5 0x1057 ++#define HDMI_FC_SPDPRODUCTNAME6 0x1058 ++#define HDMI_FC_SPDPRODUCTNAME7 0x1059 ++#define HDMI_FC_SPDPRODUCTNAME8 0x105A ++#define HDMI_FC_SPDPRODUCTNAME9 0x105B ++#define HDMI_FC_SPDPRODUCTNAME10 0x105C ++#define HDMI_FC_SPDPRODUCTNAME11 0x105D ++#define HDMI_FC_SPDPRODUCTNAME12 0x105E ++#define HDMI_FC_SPDPRODUCTNAME13 0x105F ++#define HDMI_FC_SPDPRODUCTNAME14 0x1060 + #define HDMI_FC_SPDPRODUCTNAME15 0x1061 + #define HDMI_FC_SPDDEVICEINF 0x1062 + #define HDMI_FC_AUDSCONF 0x1063 +@@ -849,6 +849,8 @@ enum { + /* FC_DATAUTO0 field values */ + HDMI_FC_DATAUTO0_VSD_MASK = 0x08, + HDMI_FC_DATAUTO0_VSD_OFFSET = 3, ++ HDMI_FC_DATAUTO0_SPD_MASK = 0x10, ++ HDMI_FC_DATAUTO0_SPD_OFFSET = 4, + + /* PHY_CONF0 field values */ + HDMI_PHY_CONF0_PDZ_MASK = 0x80, +-- +2.17.1 + + +From 02f9cee9acb20262ed704ac658c1f61fbcbb8294 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 29 Sep 2019 13:47:38 +0000 +Subject: [PATCH] WIP: drm: dw-hdmi: debugging logging + +--- + drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 28 +++++++++++++-- + drivers/video/hdmi.c | 44 +++++++++++++++++------ + 2 files changed, 59 insertions(+), 13 deletions(-) + +diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +index 5377c55e9927..cc39b544ae6e 100644 +--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c ++++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +@@ -1667,6 +1667,8 @@ static void hdmi_config_AVI(struct dw_hdmi *hdmi, struct drm_display_mode *mode) + + drm_hdmi_avi_infoframe_content_type(&frame, conn_state); + ++ hdmi_infoframe_log(KERN_INFO, hdmi->dev, (union hdmi_infoframe *)&frame); ++ + /* + * The Designware IP uses a different byte format from standard + * AVI info frames, though generally the bits are in the correct +@@ -1755,6 +1757,8 @@ static void hdmi_config_spd_infoframe(struct dw_hdmi *hdmi) + return; + } + ++ hdmi_infoframe_log(KERN_INFO, hdmi->dev, (union hdmi_infoframe *)&frame); ++ + for (i = 0; i < frame.length; i++) + hdmi_writeb(hdmi, buffer[4 + i], HDMI_FC_SPDVENDORNAME0 + i); + +@@ -1769,6 +1773,9 @@ static void hdmi_config_vendor_specific_infoframe(struct dw_hdmi *hdmi, + u8 buffer[10]; + ssize_t err; + ++ hdmi_mask_writeb(hdmi, 0, HDMI_FC_DATAUTO0, HDMI_FC_DATAUTO0_VSD_OFFSET, ++ HDMI_FC_DATAUTO0_VSD_MASK); ++ + err = drm_hdmi_vendor_infoframe_from_display_mode(&frame, + &hdmi->connector, + mode); +@@ -1787,8 +1794,8 @@ static void hdmi_config_vendor_specific_infoframe(struct dw_hdmi *hdmi, + err); + return; + } +- hdmi_mask_writeb(hdmi, 0, HDMI_FC_DATAUTO0, HDMI_FC_DATAUTO0_VSD_OFFSET, +- HDMI_FC_DATAUTO0_VSD_MASK); ++ ++ hdmi_infoframe_log(KERN_INFO, hdmi->dev, (union hdmi_infoframe *)&frame); + + /* Set the length of HDMI vendor specific InfoFrame payload */ + hdmi_writeb(hdmi, buffer[2], HDMI_FC_VSDSIZE); +@@ -1834,6 +1841,8 @@ static void hdmi_config_drm_infoframe(struct dw_hdmi *hdmi) + return; + } + ++ hdmi_infoframe_log(KERN_INFO, hdmi->dev, (union hdmi_infoframe *)&frame); ++ + hdmi_writeb(hdmi, frame.version, HDMI_FC_DRM_HB0); + hdmi_writeb(hdmi, frame.length, HDMI_FC_DRM_HB1); + +@@ -2368,6 +2377,9 @@ dw_hdmi_connector_detect(struct drm_connector *connector, bool force) + connector); + enum drm_connector_status status; + ++ DRM_DEBUG_KMS("[CONNECTOR:%d:%s] force=%d\n", ++ connector->base.id, connector->name, force); ++ + mutex_lock(&hdmi->mutex); + hdmi->force = DRM_FORCE_UNSPECIFIED; + dw_hdmi_update_power(hdmi); +@@ -2391,6 +2403,9 @@ static int dw_hdmi_connector_get_modes(struct drm_connector *connector) + struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi, + connector); + ++ DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", ++ connector->base.id, connector->name); ++ + return drm_add_edid_modes(connector, hdmi->cached_edid); + } + +@@ -2429,6 +2444,12 @@ static int dw_hdmi_connector_atomic_check(struct drm_connector *connector, + return PTR_ERR(crtc_state); + + crtc_state->mode_changed = true; ++ ++ DRM_DEBUG_KMS("[CONNECTOR:%d:%s] hdr_metadata_equal=false\n", ++ connector->base.id, connector->name); ++ } else { ++ DRM_DEBUG_KMS("[CONNECTOR:%d:%s] hdr_metadata_equal=true\n", ++ connector->base.id, connector->name); + } + + return 0; +@@ -2439,6 +2460,9 @@ static void dw_hdmi_connector_force(struct drm_connector *connector) + struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi, + connector); + ++ DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", ++ connector->base.id, connector->name); ++ + mutex_lock(&hdmi->mutex); + hdmi->force = connector->force; + dw_hdmi_update_power(hdmi); +diff --git a/drivers/video/hdmi.c b/drivers/video/hdmi.c +index 9c82e2a0a411..c3b96d3c59e1 100644 +--- a/drivers/video/hdmi.c ++++ b/drivers/video/hdmi.c +@@ -1419,6 +1419,27 @@ static void hdmi_audio_infoframe_log(const char *level, + frame->downmix_inhibit ? "Yes" : "No"); + } + ++static const char * ++hdmi_eotf_get_name(enum hdmi_eotf eotf) ++{ ++ if (eotf < 0 || eotf > 7) ++ return "Invalid"; ++ ++ switch (eotf) { ++ case HDMI_EOTF_TRADITIONAL_GAMMA_SDR: ++ return "Traditional Gamma - SDR"; ++ case HDMI_EOTF_TRADITIONAL_GAMMA_HDR: ++ return "Traditional Gamma - HDR"; ++ case HDMI_EOTF_SMPTE_ST2084: ++ return "SMPTE ST 2084"; ++ case HDMI_EOTF_BT_2100_HLG: ++ return "Hybrid Log-Gamma (HLG)"; ++ default: ++ break; ++ } ++ return "Reserved"; ++} ++ + static void hdmi_drm_infoframe_log(const char *level, + struct device *dev, + const struct hdmi_drm_infoframe *frame) +@@ -1427,24 +1448,25 @@ static void hdmi_drm_infoframe_log(const char *level, + + hdmi_infoframe_log_header(level, dev, + (struct hdmi_any_infoframe *)frame); +- hdmi_log("length: %d\n", frame->length); +- hdmi_log("metadata type: %d\n", frame->metadata_type); +- hdmi_log("eotf: %d\n", frame->eotf); ++ hdmi_log(" metadata type: %d\n", frame->metadata_type); ++ hdmi_log(" eotf: %s\n", hdmi_eotf_get_name(frame->eotf)); ++ ++ hdmi_log(" display primaries:\n"); + for (i = 0; i < 3; i++) { +- hdmi_log("x[%d]: %d\n", i, frame->display_primaries[i].x); +- hdmi_log("y[%d]: %d\n", i, frame->display_primaries[i].y); ++ hdmi_log(" x[%d]: %d\n", i, frame->display_primaries[i].x); ++ hdmi_log(" y[%d]: %d\n", i, frame->display_primaries[i].y); + } + +- hdmi_log("white point x: %d\n", frame->white_point.x); +- hdmi_log("white point y: %d\n", frame->white_point.y); ++ hdmi_log(" white point x: %d\n", frame->white_point.x); ++ hdmi_log(" white point y: %d\n", frame->white_point.y); + +- hdmi_log("max_display_mastering_luminance: %d\n", ++ hdmi_log(" max display mastering luminance: %d\n", + frame->max_display_mastering_luminance); +- hdmi_log("min_display_mastering_luminance: %d\n", ++ hdmi_log(" min display mastering luminance: %d\n", + frame->min_display_mastering_luminance); + +- hdmi_log("max_cll: %d\n", frame->max_cll); +- hdmi_log("max_fall: %d\n", frame->max_fall); ++ hdmi_log(" max cll: %d\n", frame->max_cll); ++ hdmi_log(" max fall: %d\n", frame->max_fall); + } + + static const char * +-- +2.17.1 + + +From 3c3374a1fbf631037b9fa87a6ddbfdc921cdf16c Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Tue, 26 Feb 2019 20:45:14 +0000 +Subject: [PATCH] WIP: dw-hdmi-cec: sleep 100ms on error + +Signed-off-by: Jonas Karlman +--- + drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c | 19 +++++++++++++++++-- + 1 file changed, 17 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c +index 70ab4fbdc23e..f6a85f73b90d 100644 +--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c ++++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c +@@ -4,6 +4,7 @@ + * + * Copyright (C) 2015-2017 Russell King. + */ ++#include + #include + #include + #include +@@ -129,8 +130,16 @@ static irqreturn_t dw_hdmi_cec_hardirq(int irq, void *data) + + dw_hdmi_write(cec, stat, HDMI_IH_CEC_STAT0); + +- if (stat & CEC_STAT_ERROR_INIT) { +- cec->tx_status = CEC_TX_STATUS_ERROR; ++ /* ++ * Status with both done and error_initiator bits have been seen ++ * on Rockchip RK3328 devices, transmit attempt seems to have failed ++ * when this happens, report as low drive and block cec-framework ++ * 100ms before core retransmits the failed message, this seems to ++ * mitigate the issue with failed transmit attempts. ++ */ ++ if ((stat & (CEC_STAT_DONE|CEC_STAT_ERROR_INIT)) == (CEC_STAT_DONE|CEC_STAT_ERROR_INIT)) { ++ pr_info("dw_hdmi_cec_hardirq: stat=%02x LOW_DRIVE\n", stat); ++ cec->tx_status = CEC_TX_STATUS_LOW_DRIVE; + cec->tx_done = true; + ret = IRQ_WAKE_THREAD; + } else if (stat & CEC_STAT_DONE) { +@@ -141,6 +150,10 @@ static irqreturn_t dw_hdmi_cec_hardirq(int irq, void *data) + cec->tx_status = CEC_TX_STATUS_NACK; + cec->tx_done = true; + ret = IRQ_WAKE_THREAD; ++ } else if (stat & CEC_STAT_ERROR_INIT) { ++ cec->tx_status = CEC_TX_STATUS_ERROR; ++ cec->tx_done = true; ++ ret = IRQ_WAKE_THREAD; + } + + if (stat & CEC_STAT_EOM) { +@@ -173,6 +186,8 @@ static irqreturn_t dw_hdmi_cec_thread(int irq, void *data) + + if (cec->tx_done) { + cec->tx_done = false; ++ if (cec->tx_status == CEC_TX_STATUS_LOW_DRIVE) ++ msleep(100); + cec_transmit_attempt_done(adap, cec->tx_status); + } + if (cec->rx_done) { +-- +2.17.1 + + +From 8a6b932299c4cf68942cbe1809c4f6a846ef54a1 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Fri, 11 Oct 2019 08:01:37 +0000 +Subject: [PATCH] mmc: dw_mmc: add power_off callback + +Signed-off-by: Jonas Karlman +--- + drivers/mmc/host/dw_mmc.c | 3 +++ + drivers/mmc/host/dw_mmc.h | 1 + + 2 files changed, 4 insertions(+) + +diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c +index bc5278ab5707..f192963c2c68 100644 +--- a/drivers/mmc/host/dw_mmc.c ++++ b/drivers/mmc/host/dw_mmc.c +@@ -1495,6 +1495,9 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) + regulator_disable(mmc->supply.vqmmc); + slot->host->vqmmc_enabled = false; + ++ if (drv_data && drv_data->power_off) ++ drv_data->power_off(slot->host); ++ + regs = mci_readl(slot->host, PWREN); + regs &= ~(1 << slot->id); + mci_writel(slot->host, PWREN, regs); +diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h +index da5923a92e60..0b5c880364c5 100644 +--- a/drivers/mmc/host/dw_mmc.h ++++ b/drivers/mmc/host/dw_mmc.h +@@ -563,5 +563,6 @@ struct dw_mci_drv_data { + struct mmc_ios *ios); + int (*switch_voltage)(struct mmc_host *mmc, + struct mmc_ios *ios); ++ void (*power_off)(struct dw_mci *host); + }; + #endif /* _DW_MMC_H_ */ +-- +2.17.1 + + +From bcde49e61ee5dc752e4af4b0195a1c91c550e299 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Fri, 11 Oct 2019 08:01:37 +0000 +Subject: [PATCH] mmc: dw_mmc-rockchip: try set vqmmc regulator to 3.3V on + power_off + +Signed-off-by: Jonas Karlman +--- + drivers/mmc/host/dw_mmc-rockchip.c | 27 +++++++++++++++++++++++++++ + 1 file changed, 27 insertions(+) + +diff --git a/drivers/mmc/host/dw_mmc-rockchip.c b/drivers/mmc/host/dw_mmc-rockchip.c +index d4d02134848c..05410f90ddd3 100644 +--- a/drivers/mmc/host/dw_mmc-rockchip.c ++++ b/drivers/mmc/host/dw_mmc-rockchip.c +@@ -24,6 +24,32 @@ struct dw_mci_rockchip_priv_data { + int num_phases; + }; + ++static void dw_mci_rk3288_power_off(struct dw_mci *host) ++{ ++ struct mmc_host *mmc = host->slot->mmc; ++ struct mmc_ios *ios = &mmc->ios; ++ int old_signal_voltage; ++ ++ if (IS_ERR(mmc->supply.vqmmc)) ++ return; ++ ++ if (mmc_host_is_spi(mmc)) ++ return; ++ ++ if (ios->vdd != 0 || ios->signal_voltage == MMC_SIGNAL_VOLTAGE_330) ++ return; ++ ++ old_signal_voltage = ios->signal_voltage; ++ ++ ios->signal_voltage = MMC_SIGNAL_VOLTAGE_330; ++ ios->vdd = fls(mmc->ocr_avail) - 1; ++ ++ if (mmc_regulator_set_vqmmc(mmc, ios)) ++ ios->signal_voltage = old_signal_voltage; ++ ++ ios->vdd = 0; ++} ++ + static void dw_mci_rk3288_set_ios(struct dw_mci *host, struct mmc_ios *ios) + { + struct dw_mci_rockchip_priv_data *priv = host->priv; +@@ -319,6 +345,7 @@ static const struct dw_mci_drv_data rk3288_drv_data = { + .execute_tuning = dw_mci_rk3288_execute_tuning, + .parse_dt = dw_mci_rk3288_parse_dt, + .init = dw_mci_rockchip_init, ++ .power_off = dw_mci_rk3288_power_off, + }; + + static const struct of_device_id dw_mci_rockchip_match[] = { +-- +2.17.1 + + +From 0cf5aae67b723a0e2e0d1d7041214920b5bf1e59 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Fri, 11 Oct 2019 08:01:37 +0000 +Subject: [PATCH] ARM: dts: rockchip: enable sd ultra-high speeds on + rk3288-tinker + +Signed-off-by: Jonas Karlman +--- + arch/arm/boot/dts/rk3288-tinker.dtsi | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm/boot/dts/rk3288-tinker.dtsi b/arch/arm/boot/dts/rk3288-tinker.dtsi +index 312582c1bd37..67b32dc42220 100644 +--- a/arch/arm/boot/dts/rk3288-tinker.dtsi ++++ b/arch/arm/boot/dts/rk3288-tinker.dtsi +@@ -461,6 +461,7 @@ + disable-wp; /* wp not hooked up */ + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd &sdmmc_bus4>; ++ sd-uhs-sdr104; + status = "okay"; + vmmc-supply = <&vcc33_sd>; + vqmmc-supply = <&vccio_sd>; +-- +2.17.1 + + +From f74e8d61abd366cee71da7779109e5589b4c6c6e Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 8 Dec 2019 13:49:45 +0000 +Subject: [PATCH] ARM: dts: rockchip: enable sd ultra-high speeds on + rk3288-miqi + +Signed-off-by: Jonas Karlman +--- + arch/arm/boot/dts/rk3288-miqi.dts | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/arch/arm/boot/dts/rk3288-miqi.dts b/arch/arm/boot/dts/rk3288-miqi.dts +index c41d012c8850..820926e2feb1 100644 +--- a/arch/arm/boot/dts/rk3288-miqi.dts ++++ b/arch/arm/boot/dts/rk3288-miqi.dts +@@ -60,7 +60,7 @@ + + vcc_sd: sdmmc-regulator { + compatible = "regulator-fixed"; +- gpio = <&gpio7 RK_PB3 GPIO_ACTIVE_LOW>; ++ gpio = <&gpio7 RK_PB3 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc_pwr>; + regulator-name = "vcc_sd"; +@@ -197,7 +197,7 @@ + + vccio_sd: REG5 { + regulator-name = "vccio_sd"; +- regulator-min-microvolt = <3300000>; ++ regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; +@@ -367,6 +367,7 @@ + disable-wp; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc_clk>, <&sdmmc_cmd>, <&sdmmc_cd>, <&sdmmc_bus4>; ++ sd-uhs-sdr104; + vmmc-supply = <&vcc_sd>; + vqmmc-supply = <&vccio_sd>; + status = "okay"; +-- +2.17.1 + + +From f9ec6529193530bff8905ca5ffe36b884c93b12b Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Fri, 11 Oct 2019 08:01:37 +0000 +Subject: [PATCH] arm64: dts: rockchip: enable sd ultra-high speeds on + rk3399-sapphire + +Signed-off-by: Jonas Karlman +--- + arch/arm64/boot/dts/rockchip/rk3399-sapphire.dtsi | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3399-sapphire.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-sapphire.dtsi +index 1bc1579674e5..0885d48011ab 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3399-sapphire.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3399-sapphire.dtsi +@@ -77,7 +77,7 @@ + gpio = <&gpio0 RK_PA1 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc0_pwr_h>; +- regulator-always-on; ++ regulator-boot-on; + regulator-max-microvolt = <3000000>; + regulator-min-microvolt = <3000000>; + regulator-name = "vcc3v0_sd"; +@@ -540,6 +540,7 @@ + max-frequency = <150000000>; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd &sdmmc_bus4>; ++ sd-uhs-sdr104; + vmmc-supply = <&vcc3v0_sd>; + vqmmc-supply = <&vcc_sdio>; + status = "okay"; +-- +2.17.1 + + +From c73762d9ab7c852d7dc691b4d83a42b32ad09771 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Fri, 11 Oct 2019 08:01:37 +0000 +Subject: [PATCH] arm64: dts: rockchip: enable sd ultra-high speeds on + rk3399-rock-pi-4 + +Signed-off-by: Jonas Karlman +--- + arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dts | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dts b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dts +index 3923ec01ef66..e4c71c77c3ef 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dts +@@ -307,7 +307,7 @@ + regulator-name = "vcc_sdio"; + regulator-always-on; + regulator-boot-on; +- regulator-min-microvolt = <3000000>; ++ regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3000000>; + regulator-state-mem { + regulator-on-in-suspend; +@@ -609,6 +609,9 @@ + max-frequency = <150000000>; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc_clk &sdmmc_cd &sdmmc_cmd &sdmmc_bus4>; ++ sd-uhs-sdr104; ++ vmmc-supply = <&vcc3v3_sys>; ++ vqmmc-supply = <&vcc_sdio>; + status = "okay"; + }; + +-- +2.17.1 + + +From c52ee775bd43bcecb26f464c28cdc9eb5bcc08b2 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Fri, 11 Oct 2019 08:01:38 +0000 +Subject: [PATCH] arm64: dts: rockchip: enable sd ultra-high speeds on + rk3399-rockpro64 + +Signed-off-by: Jonas Karlman +--- + .../boot/dts/rockchip/rk3399-rockpro64.dtsi | 22 +++++++++++++++++++ + 1 file changed, 22 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi +index 9bca25801260..72c9bb2cfceb 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi +@@ -108,6 +108,19 @@ + vin-supply = <&vcc12v_dcin>; + }; + ++ vcc3v0_sd: vcc3v0-sd { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpio = <&gpio0 RK_PA1 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdmmc0_pwr_h>; ++ regulator-boot-on; ++ regulator-max-microvolt = <3000000>; ++ regulator-min-microvolt = <3000000>; ++ regulator-name = "vcc3v0_sd"; ++ vin-supply = <&vcc3v3_sys>; ++ }; ++ + vcc3v3_sys: vcc3v3-sys { + compatible = "regulator-fixed"; + regulator-name = "vcc3v3_sys"; +@@ -603,6 +616,12 @@ + }; + }; + ++ sd { ++ sdmmc0_pwr_h: sdmmc0-pwr-h { ++ rockchip,pins = <0 RK_PA1 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ + sdio-pwrseq { + wifi_enable_h: wifi-enable-h { + rockchip,pins = <0 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>; +@@ -661,6 +680,9 @@ + max-frequency = <150000000>; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_bus4>; ++ sd-uhs-sdr104; ++ vmmc-supply = <&vcc3v0_sd>; ++ vqmmc-supply = <&vcc_sdio>; + status = "okay"; + }; + +-- +2.17.1 + + +From 5d729739be59fe9a3435f80f6b13945b0a50e3a1 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 8 Dec 2019 13:27:12 +0000 +Subject: [PATCH] ARM: dts: rockchip: fix sdmmc-regulator gpio warning on + rk3288-tinker + +Fixes sdmmc-regulator GPIO handle specifies active low - ignored + +Signed-off-by: Jonas Karlman +--- + arch/arm/boot/dts/rk3288-tinker.dtsi | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm/boot/dts/rk3288-tinker.dtsi b/arch/arm/boot/dts/rk3288-tinker.dtsi +index 67b32dc42220..dc5b4d81a46c 100644 +--- a/arch/arm/boot/dts/rk3288-tinker.dtsi ++++ b/arch/arm/boot/dts/rk3288-tinker.dtsi +@@ -98,7 +98,7 @@ + + vcc_sd: sdmmc-regulator { + compatible = "regulator-fixed"; +- gpio = <&gpio7 11 GPIO_ACTIVE_LOW>; ++ gpio = <&gpio7 RK_PB3 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc_pwr>; + regulator-name = "vcc_sd"; +-- +2.17.1 + + +From 896ce763b751403f9dcae8732335d53e5a6dcce9 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Thu, 7 Feb 2019 22:03:38 +0000 +Subject: [PATCH] ARM: dts: rockchip: rename hdmi sound card on rk3288-tinker + +--- + arch/arm/boot/dts/rk3288-tinker.dtsi | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/arch/arm/boot/dts/rk3288-tinker.dtsi b/arch/arm/boot/dts/rk3288-tinker.dtsi +index dc5b4d81a46c..49b64f4908cd 100644 +--- a/arch/arm/boot/dts/rk3288-tinker.dtsi ++++ b/arch/arm/boot/dts/rk3288-tinker.dtsi +@@ -75,7 +75,7 @@ + sound { + compatible = "simple-audio-card"; + simple-audio-card,format = "i2s"; +- simple-audio-card,name = "rockchip,tinker-codec"; ++ simple-audio-card,name = "HDMI"; + simple-audio-card,mclk-fs = <512>; + + simple-audio-card,codec { +@@ -352,7 +352,6 @@ + }; + + &i2s { +- #sound-dai-cells = <0>; + status = "okay"; + }; + +-- +2.17.1 + + +From de9b4be54fd5ad12a33aa35aa46421b74411ee75 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 8 Dec 2019 13:49:19 +0000 +Subject: [PATCH] ARM: dts: rockchip: add hdmi sound node on rk3288-miqi + +Signed-off-by: Jonas Karlman +--- + arch/arm/boot/dts/rk3288-miqi.dts | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +diff --git a/arch/arm/boot/dts/rk3288-miqi.dts b/arch/arm/boot/dts/rk3288-miqi.dts +index 820926e2feb1..0e17f66f142f 100644 +--- a/arch/arm/boot/dts/rk3288-miqi.dts ++++ b/arch/arm/boot/dts/rk3288-miqi.dts +@@ -37,6 +37,21 @@ + }; + }; + ++ sound { ++ compatible = "simple-audio-card"; ++ simple-audio-card,format = "i2s"; ++ simple-audio-card,name = "HDMI"; ++ simple-audio-card,mclk-fs = <512>; ++ ++ simple-audio-card,codec { ++ sound-dai = <&hdmi>; ++ }; ++ ++ simple-audio-card,cpu { ++ sound-dai = <&i2s>; ++ }; ++ }; ++ + vcc_flash: flash-regulator { + compatible = "regulator-fixed"; + regulator-name = "vcc_flash"; +@@ -267,6 +282,10 @@ + status = "okay"; + }; + ++&i2s { ++ status = "okay"; ++}; ++ + &io_domains { + status = "okay"; + +-- +2.17.1 + + +From 882e6f0dcf1af01c4bfcf18b07c54894cc6b441e Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Mon, 2 Dec 2019 22:35:51 +0000 +Subject: [PATCH] ARM: dts: rockchip: enable ARM Mali GPU on rk3288-miqi + +Signed-off-by: Jonas Karlman +--- + arch/arm/boot/dts/rk3288-miqi.dts | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/arch/arm/boot/dts/rk3288-miqi.dts b/arch/arm/boot/dts/rk3288-miqi.dts +index 0e17f66f142f..2bee891466f5 100644 +--- a/arch/arm/boot/dts/rk3288-miqi.dts ++++ b/arch/arm/boot/dts/rk3288-miqi.dts +@@ -126,6 +126,11 @@ + status = "ok"; + }; + ++&gpu { ++ mali-supply = <&vdd_gpu>; ++ status = "okay"; ++}; ++ + &hdmi { + ddc-i2c-bus = <&i2c5>; + status = "okay"; +-- +2.17.1 + + +From 72c61d5558abf21a5bb3e9ac4603a99a2594a647 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sat, 14 Dec 2019 01:43:17 +0000 +Subject: [PATCH] ARM: dts: rockchip: enable cec on rk3288-miqi + +Signed-off-by: Jonas Karlman +--- + arch/arm/boot/dts/rk3288-miqi.dts | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/arch/arm/boot/dts/rk3288-miqi.dts b/arch/arm/boot/dts/rk3288-miqi.dts +index 2bee891466f5..8428095934f5 100644 +--- a/arch/arm/boot/dts/rk3288-miqi.dts ++++ b/arch/arm/boot/dts/rk3288-miqi.dts +@@ -133,6 +133,8 @@ + + &hdmi { + ddc-i2c-bus = <&i2c5>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&hdmi_cec_c0>; + status = "okay"; + }; + +-- +2.17.1 + + +From d189fcfc6950f6a2f67662e3b024eff83b929322 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 10 Mar 2019 19:18:36 +0000 +Subject: [PATCH] arm64: dts: rockchip: remove dc_12v regulator on + rk3328-roc-cc + +Remove unnecessary dc_12v regulator node on ROC-RK3328-CC, +the device uses 5v micro-usb as power input. + +Signed-off-by: Jonas Karlman +--- + arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts | 10 ---------- + 1 file changed, 10 deletions(-) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts b/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts +index 8d553c92182a..c4d908bcc82c 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts +@@ -21,15 +21,6 @@ + #clock-cells = <0>; + }; + +- 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>; +- }; +- + vcc_sd: sdmmc-regulator { + compatible = "regulator-fixed"; + gpio = <&gpio0 RK_PD6 GPIO_ACTIVE_LOW>; +@@ -73,7 +64,6 @@ + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; +- vin-supply = <&dc_12v>; + }; + + vcc_phy: vcc-phy-regulator { +-- +2.17.1 + + +From f6da47eada3ffa241c3c37917827ffa278391991 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 10 Mar 2019 19:23:58 +0000 +Subject: [PATCH] arm64: dts: rockchip: add ir-receiver node on rk3328-roc-cc + +Add ir-receiver node to enable on-board IR on ROC-RK3328-CC. + +Signed-off-by: Jonas Karlman +--- + arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts b/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts +index c4d908bcc82c..5a4aadffe9de 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts +@@ -73,6 +73,13 @@ + regulator-boot-on; + }; + ++ ir-receiver { ++ compatible = "gpio-ir-receiver"; ++ gpios = <&gpio2 RK_PA2 GPIO_ACTIVE_LOW>; ++ pinctrl-0 = <&ir_int>; ++ pinctrl-names = "default"; ++ }; ++ + leds { + compatible = "gpio-leds"; + +@@ -273,6 +280,12 @@ + }; + + &pinctrl { ++ ir { ++ ir_int: ir-int { ++ rockchip,pins = <2 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ + pmic { + pmic_int_l: pmic-int-l { + rockchip,pins = <1 RK_PD0 RK_FUNC_GPIO &pcfg_pull_up>; +-- +2.17.1 + + +From 5b7cc260ec063a6cd695ab0119d355b5a72c1a19 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 24 Mar 2019 11:20:51 +0000 +Subject: [PATCH] arm64: dts: rockchip: set tshut mode and priority on + rk3328-roc-cc + +Signed-off-by: Jonas Karlman +--- + arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts b/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts +index 5a4aadffe9de..71f3cd206e13 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts +@@ -317,6 +317,8 @@ + }; + + &tsadc { ++ rockchip,hw-tshut-mode = <0>; ++ rockchip,hw-tshut-polarity = <0>; + status = "okay"; + }; + +-- +2.17.1 + + +From 456c5f7d3accc12acfc84cf6baddb5dcf05836aa Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 24 Mar 2019 11:22:06 +0000 +Subject: [PATCH] arm64: dts: rockchip: rename vcc_sdio regulator on + rk3328-roc-cc + +Signed-off-by: Jonas Karlman +--- + arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts b/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts +index 71f3cd206e13..95ff8f60e21f 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts +@@ -33,12 +33,12 @@ + vin-supply = <&vcc_io>; + }; + +- vcc_sdio: sdmmcio-regulator { ++ vccio_sd: sdmmcio-regulator { + compatible = "regulator-gpio"; + gpios = <&grf_gpio 0 GPIO_ACTIVE_HIGH>; + states = <1800000 0x1 + 3300000 0x0>; +- regulator-name = "vcc_sdio"; ++ regulator-name = "vccio_sd"; + regulator-type = "voltage"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; +@@ -272,7 +272,7 @@ + + vccio1-supply = <&vcc_io>; + vccio2-supply = <&vcc18_emmc>; +- vccio3-supply = <&vcc_sdio>; ++ vccio3-supply = <&vccio_sd>; + vccio4-supply = <&vcc_18>; + vccio5-supply = <&vcc_io>; + vccio6-supply = <&vcc_io>; +@@ -312,7 +312,7 @@ + sd-uhs-sdr50; + sd-uhs-sdr104; + vmmc-supply = <&vcc_sd>; +- vqmmc-supply = <&vcc_sdio>; ++ vqmmc-supply = <&vccio_sd>; + status = "okay"; + }; + +-- +2.17.1 + + +From e077bfec3ae60d827dd8c4a6c1f777e88f2c2a53 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 24 Mar 2019 17:18:39 +0000 +Subject: [PATCH] arm64: dts: rockchip: use recommended regulator limits on + rk3328-roc-cc + +Signed-off-by: Jonas Karlman +--- + arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts b/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts +index 95ff8f60e21f..35d1f89f844c 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts +@@ -185,8 +185,9 @@ + regulators { + vdd_logic: DCDC_REG1 { + regulator-name = "vdd_logic"; +- regulator-min-microvolt = <712500>; +- regulator-max-microvolt = <1450000>; ++ regulator-min-microvolt = <900000>; ++ regulator-max-microvolt = <1150000>; ++ regulator-ramp-delay = <12500>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { +@@ -197,8 +198,9 @@ + + vdd_arm: DCDC_REG2 { + regulator-name = "vdd_arm"; +- regulator-min-microvolt = <712500>; +- regulator-max-microvolt = <1450000>; ++ regulator-min-microvolt = <950000>; ++ regulator-max-microvolt = <1350000>; ++ regulator-ramp-delay = <12500>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { +-- +2.17.1 + + +From b66dcf8f337f9308ba232880f48a93d6594bbf5b Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 21 Apr 2019 10:28:27 +0000 +Subject: [PATCH] arm64: dts: rockchip: use recommended regulator limits on + rk3328-rock64 + +Signed-off-by: Jonas Karlman +--- + arch/arm64/boot/dts/rockchip/rk3328-rock64.dts | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts +index 62936b432f9a..3725fcc7bb38 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts +@@ -193,8 +193,8 @@ + regulators { + vdd_logic: DCDC_REG1 { + regulator-name = "vdd_logic"; +- regulator-min-microvolt = <712500>; +- regulator-max-microvolt = <1450000>; ++ regulator-min-microvolt = <900000>; ++ regulator-max-microvolt = <1150000>; + regulator-ramp-delay = <12500>; + regulator-always-on; + regulator-boot-on; +@@ -206,8 +206,8 @@ + + vdd_arm: DCDC_REG2 { + regulator-name = "vdd_arm"; +- regulator-min-microvolt = <712500>; +- regulator-max-microvolt = <1450000>; ++ regulator-min-microvolt = <950000>; ++ regulator-max-microvolt = <1350000>; + regulator-ramp-delay = <12500>; + regulator-always-on; + regulator-boot-on; +-- +2.17.1 + + +From 52aeabe772f86828a7fd7b2d5f5ca4706214d09f Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 24 Mar 2019 11:23:55 +0000 +Subject: [PATCH] arm64: dts: rockchip: fix vccio4-supply on rk3328-roc-cc + +Signed-off-by: Jonas Karlman +--- + arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts b/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts +index 35d1f89f844c..dd18510fa473 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts +@@ -275,7 +275,7 @@ + vccio1-supply = <&vcc_io>; + vccio2-supply = <&vcc18_emmc>; + vccio3-supply = <&vccio_sd>; +- vccio4-supply = <&vcc_18>; ++ vccio4-supply = <&vcc_io>; + vccio5-supply = <&vcc_io>; + vccio6-supply = <&vcc_io>; + pmuio-supply = <&vcc_io>; +-- +2.17.1 + + +From 589b2803582c476ae058e4fe2157eaa332c15bbf Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 21 Apr 2019 18:13:30 +0000 +Subject: [PATCH] arm64: dts: rockchip: fix vccio4-supply on rk3328-rock64 + +--- + arch/arm64/boot/dts/rockchip/rk3328-rock64.dts | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts +index 3725fcc7bb38..1af6c56a4451 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts +@@ -295,7 +295,7 @@ + vccio1-supply = <&vcc_io>; + vccio2-supply = <&vcc18_emmc>; + vccio3-supply = <&vcc_io>; +- vccio4-supply = <&vcc_18>; ++ vccio4-supply = <&vcc_io>; + vccio5-supply = <&vcc_io>; + vccio6-supply = <&vcc_io>; + pmuio-supply = <&vcc_io>; +-- +2.17.1 + + +From 23aa1a305bffe72c7fb26afac16c475569bef79a Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 21 Apr 2019 18:07:33 +0000 +Subject: [PATCH] arm64: dts: rockchip: fix fixed-regulator gpio warning on + rk3328 + +--- + arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts | 2 +- + arch/arm64/boot/dts/rockchip/rk3328-rock64.dts | 6 +++--- + 2 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts b/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts +index dd18510fa473..48695a2dce7d 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts +@@ -23,7 +23,7 @@ + + vcc_sd: sdmmc-regulator { + compatible = "regulator-fixed"; +- gpio = <&gpio0 RK_PD6 GPIO_ACTIVE_LOW>; ++ gpio = <&gpio0 RK_PD6 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc0m1_gpio>; + regulator-boot-on; +diff --git a/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts +index 1af6c56a4451..7cca8808257e 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts +@@ -23,7 +23,7 @@ + + vcc_sd: sdmmc-regulator { + compatible = "regulator-fixed"; +- gpio = <&gpio0 RK_PD6 GPIO_ACTIVE_LOW>; ++ gpio = <&gpio0 RK_PD6 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc0m1_gpio>; + regulator-name = "vcc_sd"; +@@ -34,7 +34,7 @@ + + vcc_host_5v: vcc-host-5v-regulator { + compatible = "regulator-fixed"; +- gpio = <&gpio0 RK_PA2 GPIO_ACTIVE_LOW>; ++ gpio = <&gpio0 RK_PA2 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&usb20_host_drv>; + regulator-name = "vcc_host_5v"; +@@ -45,7 +45,7 @@ + + vcc_host1_5v: vcc_otg_5v: vcc-host1-5v-regulator { + compatible = "regulator-fixed"; +- gpio = <&gpio0 RK_PA2 GPIO_ACTIVE_LOW>; ++ gpio = <&gpio0 RK_PA2 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&usb20_host_drv>; + regulator-name = "vcc_host1_5v"; +-- +2.17.1 + + +From b05c9d16191a716ba106abf6226410270ffa89a0 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 17 Mar 2019 22:38:09 +0000 +Subject: [PATCH] arm64: dts: rockchip: update gpu node on rk3328 + +--- + arch/arm64/boot/dts/rockchip/rk3328.dtsi | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi +index 1f53ead52c7f..1b45131e8e48 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi +@@ -319,6 +319,10 @@ + #address-cells = <1>; + #size-cells = <0>; + ++ pd_gpu@RK3328_PD_GPU { ++ reg = ; ++ clocks = <&cru ACLK_GPU>; ++ }; + pd_hevc@RK3328_PD_HEVC { + reg = ; + }; +@@ -621,6 +625,7 @@ + "ppmmu1"; + clocks = <&cru ACLK_GPU>, <&cru ACLK_GPU>; + clock-names = "bus", "core"; ++ power-domains = <&power RK3328_PD_GPU>; + resets = <&cru SRST_GPU_A>; + }; + +@@ -793,6 +798,7 @@ + <&cru ACLK_BUS_PRE>, <&cru HCLK_BUS_PRE>, + <&cru PCLK_BUS_PRE>, <&cru ACLK_PERI_PRE>, + <&cru HCLK_PERI>, <&cru PCLK_PERI>, ++ <&cru ACLK_GPU>, + <&cru SCLK_RTC32K>; + assigned-clock-parents = + <&cru HDMIPHY>, <&cru PLL_APLL>, +@@ -814,6 +820,7 @@ + <150000000>, <75000000>, + <75000000>, <150000000>, + <75000000>, <75000000>, ++ <500000000>, + <32768>; + }; + +-- +2.17.1 + + +From c047d9759f3b5376259657dc0608a51252371219 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 8 Dec 2019 23:12:19 +0000 +Subject: [PATCH] arm64: dts: rockchip: add spdif audio pipeline on rk3328 + +Signed-off-by: Jonas Karlman +--- + arch/arm64/boot/dts/rockchip/rk3328.dtsi | 20 ++++++++++++++++++++ + 1 file changed, 20 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi +index 1b45131e8e48..c6f7cec13d15 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi +@@ -210,6 +210,26 @@ + method = "smc"; + }; + ++ spdif_out: spdif-out { ++ compatible = "linux,spdif-dit"; ++ #sound-dai-cells = <0>; ++ status = "disabled"; ++ }; ++ ++ spdif_sound: spdif-sound { ++ compatible = "simple-audio-card"; ++ simple-audio-card,name = "SPDIF"; ++ status = "disabled"; ++ ++ simple-audio-card,cpu { ++ sound-dai = <&spdif>; ++ }; ++ ++ simple-audio-card,codec { ++ sound-dai = <&spdif_out>; ++ }; ++ }; ++ + timer { + compatible = "arm,armv8-timer"; + interrupts = , +-- +2.17.1 + + +From 8d8e7349b476ae980239abfdb8c460ccd5e3df0a Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Tue, 19 Mar 2019 22:18:47 +0000 +Subject: [PATCH] arm64: dts: rockchip: enable sound nodes on rk3328-roc-cc + +--- + .../arm64/boot/dts/rockchip/rk3328-roc-cc.dts | 33 +++++++++++++++++++ + 1 file changed, 33 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts b/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts +index 48695a2dce7d..a340a23cf073 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts +@@ -101,6 +101,14 @@ + }; + }; + ++&analog_sound { ++ status = "okay"; ++}; ++ ++&codec { ++ status = "okay"; ++}; ++ + &cpu0 { + cpu-supply = <&vdd_arm>; + }; +@@ -158,6 +166,10 @@ + status = "okay"; + }; + ++&hdmi_sound { ++ status = "okay"; ++}; ++ + &i2c1 { + status = "okay"; + +@@ -269,6 +281,14 @@ + }; + }; + ++&i2s0 { ++ status = "okay"; ++}; ++ ++&i2s1 { ++ status = "okay"; ++}; ++ + &io_domains { + status = "okay"; + +@@ -318,6 +338,19 @@ + status = "okay"; + }; + ++&spdif { ++ pinctrl-0 = <&spdifm0_tx>; ++ status = "okay"; ++}; ++ ++&spdif_out { ++ status = "okay"; ++}; ++ ++&spdif_sound { ++ status = "okay"; ++}; ++ + &tsadc { + rockchip,hw-tshut-mode = <0>; + rockchip,hw-tshut-polarity = <0>; +-- +2.17.1 + + +From b906dcd1489dd042dc67d9328952e18011fd6960 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 29 Dec 2019 22:13:22 +0000 +Subject: [PATCH] arm64: dts: rockchip: add mmc reset on rk3328 + +--- + arch/arm64/boot/dts/rockchip/rk3328.dtsi | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi +index c6f7cec13d15..b92645187b19 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi +@@ -890,6 +890,8 @@ + clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; + fifo-depth = <0x100>; + max-frequency = <150000000>; ++ resets = <&cru SRST_MMC0>; ++ reset-names = "reset"; + status = "disabled"; + }; + +@@ -902,6 +904,8 @@ + clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; + fifo-depth = <0x100>; + max-frequency = <150000000>; ++ resets = <&cru SRST_SDIO>; ++ reset-names = "reset"; + status = "disabled"; + }; + +@@ -914,6 +918,8 @@ + clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; + fifo-depth = <0x100>; + max-frequency = <150000000>; ++ resets = <&cru SRST_EMMC>; ++ reset-names = "reset"; + status = "disabled"; + }; + +-- +2.17.1 + + +From 584300ab010fa3ab29f5f402d94274740d231e1c Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 29 Dec 2019 22:14:02 +0000 +Subject: [PATCH] arm64: dts: rockchip: add sdmmc_ext node on rk3328 + +--- + arch/arm64/boot/dts/rockchip/rk3328.dtsi | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi +index b92645187b19..cc44e17c8c43 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi +@@ -1018,6 +1018,20 @@ + status = "disabled"; + }; + ++ sdmmc_ext: dwmmc@ff5f0000 { ++ compatible = "rockchip,rk3328-dw-mshc", "rockchip,rk3288-dw-mshc"; ++ reg = <0x0 0xff5f0000 0x0 0x4000>; ++ interrupts = ; ++ clocks = <&cru HCLK_SDMMC_EXT>, <&cru SCLK_SDMMC_EXT>, ++ <&cru SCLK_SDMMC_EXT_DRV>, <&cru SCLK_SDMMC_EXT_SAMPLE>; ++ clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; ++ fifo-depth = <0x100>; ++ max-frequency = <150000000>; ++ resets = <&cru SRST_SDMMCEXT>; ++ reset-names = "reset"; ++ status = "disabled"; ++ }; ++ + gic: interrupt-controller@ff811000 { + compatible = "arm,gic-400"; + #interrupt-cells = <3>; +-- +2.17.1 + + +From af46e567772628417233844bb0994437f842d2a3 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 29 Dec 2019 22:14:36 +0000 +Subject: [PATCH] WIP: arm64: dts: rockchip: add rkvdec power domain on rk3328 + +--- + arch/arm64/boot/dts/rockchip/rk3328.dtsi | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi +index cc44e17c8c43..a4b0947f82a7 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi +@@ -348,6 +348,10 @@ + }; + pd_video@RK3328_PD_VIDEO { + reg = ; ++ clocks = <&cru ACLK_RKVDEC>, ++ <&cru HCLK_RKVDEC>, ++ <&cru SCLK_VDEC_CABAC>, ++ <&cru SCLK_VDEC_CORE>; + }; + pd_vpu@RK3328_PD_VPU { + reg = ; +@@ -701,6 +705,7 @@ + clocks = <&cru ACLK_RKVDEC>, <&cru HCLK_RKVDEC>; + clock-names = "aclk", "iface"; + #iommu-cells = <0>; ++ power-domains = <&power RK3328_PD_VIDEO>; + status = "disabled"; + }; + +-- +2.17.1 + + +From fe5ff9c9fcb07b629f57282a25eba796616fbb50 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 8 Dec 2019 23:23:41 +0000 +Subject: [PATCH] WIP: arm64: dts: rockchip: split sound cards on rk3328-rock64 + +Signed-off-by: Jonas Karlman +--- + .../arm64/boot/dts/rockchip/rk3328-rock64.dts | 54 +++++++------------ + 1 file changed, 18 insertions(+), 36 deletions(-) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts +index 7cca8808257e..e926616b4a0c 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts +@@ -83,34 +83,14 @@ + linux,default-trigger = "heartbeat"; + }; + }; ++}; + +- sound { +- compatible = "audio-graph-card"; +- label = "rockchip,rk3328"; +- dais = <&i2s1_p0 +- &spdif_p0>; +- }; +- +- spdif-dit { +- compatible = "linux,spdif-dit"; +- #sound-dai-cells = <0>; +- +- port { +- dit_p0_0: endpoint { +- remote-endpoint = <&spdif_p0_0>; +- }; +- }; +- }; ++&analog_sound { ++ status = "okay"; + }; + + &codec { + status = "okay"; +- +- port@0 { +- codec_p0_0: endpoint { +- remote-endpoint = <&i2s1_p0_0>; +- }; +- }; + }; + + &cpu0 { +@@ -166,6 +146,10 @@ + status = "okay"; + }; + ++&hdmi_sound { ++ status = "okay"; ++}; ++ + &i2c1 { + status = "okay"; + +@@ -277,16 +261,12 @@ + }; + }; + +-&i2s1 { ++&i2s0 { + status = "okay"; ++}; + +- i2s1_p0: port { +- i2s1_p0_0: endpoint { +- dai-format = "i2s"; +- mclk-fs = <256>; +- remote-endpoint = <&codec_p0_0>; +- }; +- }; ++&i2s1 { ++ status = "okay"; + }; + + &io_domains { +@@ -336,12 +316,14 @@ + &spdif { + pinctrl-0 = <&spdifm0_tx>; + status = "okay"; ++}; + +- spdif_p0: port { +- spdif_p0_0: endpoint { +- remote-endpoint = <&dit_p0_0>; +- }; +- }; ++&spdif_out { ++ status = "okay"; ++}; ++ ++&spdif_sound { ++ status = "okay"; + }; + + &spi0 { +-- +2.17.1 + + +From 1c472df59bdd77b5f9dc651e4c25959cd53a2778 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 8 Dec 2019 23:26:37 +0000 +Subject: [PATCH] WIP: arm64: dts: rockchip: add mali-supply on rk3328-rock64 + and rk3328-roc-cc + +Signed-off-by: Jonas Karlman +--- + arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts | 4 ++++ + arch/arm64/boot/dts/rockchip/rk3328-rock64.dts | 4 ++++ + 2 files changed, 8 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts b/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts +index a340a23cf073..3e564ba682b6 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts +@@ -158,6 +158,10 @@ + status = "okay"; + }; + ++&gpu { ++ mali-supply = <&vdd_logic>; ++}; ++ + &hdmi { + status = "okay"; + }; +diff --git a/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts +index e926616b4a0c..9023f311f89b 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts +@@ -138,6 +138,10 @@ + status = "okay"; + }; + ++&gpu { ++ mali-supply = <&vdd_logic>; ++}; ++ + &hdmi { + status = "okay"; + }; +-- +2.17.1 + + +From 2fae05a90a56a71c1ad749a96fac8eeb8beefaf0 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Mon, 30 Dec 2019 00:30:38 +0000 +Subject: [PATCH] WIP: arm64: dts: rockchip: misc updates on rk3328-rock64 and + rk3328-roc-cc + +--- + .../arm64/boot/dts/rockchip/rk3328-roc-cc.dts | 34 +++++----------- + .../arm64/boot/dts/rockchip/rk3328-rock64.dts | 39 +++++++------------ + 2 files changed, 22 insertions(+), 51 deletions(-) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts b/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts +index 3e564ba682b6..b58948f478a1 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts +@@ -26,7 +26,6 @@ + gpio = <&gpio0 RK_PD6 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc0m1_gpio>; +- regulator-boot-on; + regulator-name = "vcc_sd"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; +@@ -54,25 +53,17 @@ + pinctrl-0 = <&usb20_host_drv>; + regulator-name = "vcc_host1_5v"; + regulator-always-on; ++ regulator-boot-on; + vin-supply = <&vcc_sys>; + }; + + vcc_sys: vcc-sys { + compatible = "regulator-fixed"; + regulator-name = "vcc_sys"; +- regulator-always-on; +- regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + }; + +- vcc_phy: vcc-phy-regulator { +- compatible = "regulator-fixed"; +- regulator-name = "vcc_phy"; +- regulator-always-on; +- regulator-boot-on; +- }; +- + ir-receiver { + compatible = "gpio-ir-receiver"; + gpios = <&gpio2 RK_PA2 GPIO_ACTIVE_LOW>; +@@ -128,7 +119,6 @@ + &emmc { + bus-width = <8>; + cap-mmc-highspeed; +- max-frequency = <150000000>; + mmc-ddr-1_8v; + mmc-hs200-1_8v; + non-removable; +@@ -143,16 +133,15 @@ + assigned-clocks = <&cru SCLK_MAC2IO>, <&cru SCLK_MAC2IO_EXT>; + assigned-clock-parents = <&gmac_clkin>, <&gmac_clkin>; + clock_in_out = "input"; +- phy-supply = <&vcc_phy>; + phy-mode = "rgmii"; ++ phy-supply = <&vcc_io>; + pinctrl-names = "default"; + pinctrl-0 = <&rgmiim1_pins>; + snps,aal; ++ snps,pbl = <0x4>; + snps,reset-gpio = <&gpio1 RK_PC2 GPIO_ACTIVE_LOW>; + snps,reset-active-low; + snps,reset-delays-us = <0 10000 50000>; +- snps,rxpbl = <0x4>; +- snps,txpbl = <0x4>; + tx_delay = <0x24>; + rx_delay = <0x18>; + status = "okay"; +@@ -294,8 +283,6 @@ + }; + + &io_domains { +- status = "okay"; +- + vccio1-supply = <&vcc_io>; + vccio2-supply = <&vcc18_emmc>; + vccio3-supply = <&vccio_sd>; +@@ -303,6 +290,7 @@ + vccio5-supply = <&vcc_io>; + vccio6-supply = <&vcc_io>; + pmuio-supply = <&vcc_io>; ++ status = "okay"; + }; + + &pinctrl { +@@ -330,13 +318,8 @@ + cap-mmc-highspeed; + cap-sd-highspeed; + disable-wp; +- max-frequency = <150000000>; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc0_clk &sdmmc0_cmd &sdmmc0_dectn &sdmmc0_bus4>; +- sd-uhs-sdr12; +- sd-uhs-sdr25; +- sd-uhs-sdr50; +- sd-uhs-sdr104; + vmmc-supply = <&vcc_sd>; + vqmmc-supply = <&vccio_sd>; + status = "okay"; +@@ -361,23 +344,24 @@ + status = "okay"; + }; + +-&u2phy { ++&uart2 { + status = "okay"; + }; + +-&u2phy_host { ++&u2phy { + status = "okay"; + }; + +-&u2phy_otg { ++&u2phy_host { + status = "okay"; + }; + +-&uart2 { ++&u2phy_otg { + status = "okay"; + }; + + &usb20_otg { ++ dr_mode = "host"; + status = "okay"; + }; + +diff --git a/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts +index 9023f311f89b..345c045c58e6 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts +@@ -32,7 +32,7 @@ + vin-supply = <&vcc_io>; + }; + +- vcc_host_5v: vcc-host-5v-regulator { ++ vcc_host_5v: vcc_host1_5v: vcc_otg_5v: vcc-host-5v-regulator { + compatible = "regulator-fixed"; + gpio = <&gpio0 RK_PA2 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; +@@ -43,22 +43,9 @@ + vin-supply = <&vcc_sys>; + }; + +- vcc_host1_5v: vcc_otg_5v: vcc-host1-5v-regulator { +- compatible = "regulator-fixed"; +- gpio = <&gpio0 RK_PA2 GPIO_ACTIVE_HIGH>; +- pinctrl-names = "default"; +- pinctrl-0 = <&usb20_host_drv>; +- regulator-name = "vcc_host1_5v"; +- regulator-always-on; +- regulator-boot-on; +- vin-supply = <&vcc_sys>; +- }; +- + vcc_sys: vcc-sys { + compatible = "regulator-fixed"; + regulator-name = "vcc_sys"; +- regulator-always-on; +- regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + }; +@@ -112,6 +99,7 @@ + &emmc { + bus-width = <8>; + cap-mmc-highspeed; ++ mmc-ddr-1_8v; + mmc-hs200-1_8v; + non-removable; + pinctrl-names = "default"; +@@ -125,11 +113,12 @@ + assigned-clocks = <&cru SCLK_MAC2IO>, <&cru SCLK_MAC2IO_EXT>; + assigned-clock-parents = <&gmac_clkin>, <&gmac_clkin>; + clock_in_out = "input"; +- phy-supply = <&vcc_io>; + phy-mode = "rgmii"; ++ phy-supply = <&vcc_io>; + pinctrl-names = "default"; + pinctrl-0 = <&rgmiim1_pins>; +- snps,force_thresh_dma_mode; ++ snps,aal; ++ snps,pbl = <0x4>; + snps,reset-gpio = <&gpio1 RK_PC2 GPIO_ACTIVE_LOW>; + snps,reset-active-low; + snps,reset-delays-us = <0 10000 50000>; +@@ -176,7 +165,7 @@ + vcc3-supply = <&vcc_sys>; + vcc4-supply = <&vcc_sys>; + vcc5-supply = <&vcc_io>; +- vcc6-supply = <&vcc_sys>; ++ vcc6-supply = <&vcc_io>; + + regulators { + vdd_logic: DCDC_REG1 { +@@ -274,8 +263,6 @@ + }; + + &io_domains { +- status = "okay"; +- + vccio1-supply = <&vcc_io>; + vccio2-supply = <&vcc18_emmc>; + vccio3-supply = <&vcc_io>; +@@ -283,6 +270,7 @@ + vccio5-supply = <&vcc_io>; + vccio6-supply = <&vcc_io>; + pmuio-supply = <&vcc_io>; ++ status = "okay"; + }; + + &pinctrl { +@@ -310,7 +298,6 @@ + cap-mmc-highspeed; + cap-sd-highspeed; + disable-wp; +- max-frequency = <150000000>; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc0_clk &sdmmc0_cmd &sdmmc0_dectn &sdmmc0_bus4>; + vmmc-supply = <&vcc_sd>; +@@ -354,14 +341,14 @@ + + &u2phy { + status = "okay"; ++}; + +- u2phy_host: host-port { +- status = "okay"; +- }; ++&u2phy_host { ++ status = "okay"; ++}; + +- u2phy_otg: otg-port { +- status = "okay"; +- }; ++&u2phy_otg { ++ status = "okay"; + }; + + &usb20_otg { +-- +2.17.1 + + +From 902ee56bf269bf4337eec25f0dc7d343bb9172b9 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 12 May 2019 12:40:00 +0000 +Subject: [PATCH] arm64: dts: rockchip: add rk3328-rockbox + +--- + arch/arm64/boot/dts/rockchip/Makefile | 1 + + .../boot/dts/rockchip/rk3328-rockbox.dts | 349 ++++++++++++++++++ + 2 files changed, 350 insertions(+) + create mode 100644 arch/arm64/boot/dts/rockchip/rk3328-rockbox.dts + +diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile +index 60d9437096c7..1df8933cb084 100644 +--- a/arch/arm64/boot/dts/rockchip/Makefile ++++ b/arch/arm64/boot/dts/rockchip/Makefile +@@ -5,6 +5,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3308-roc-cc.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-a1.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-evb.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-rock64.dtb ++dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-rockbox.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-roc-cc.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3368-evb-act8846.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3368-geekbox.dtb +diff --git a/arch/arm64/boot/dts/rockchip/rk3328-rockbox.dts b/arch/arm64/boot/dts/rockchip/rk3328-rockbox.dts +new file mode 100644 +index 000000000000..b82708cfe742 +--- /dev/null ++++ b/arch/arm64/boot/dts/rockchip/rk3328-rockbox.dts +@@ -0,0 +1,349 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++/* ++ * Copyright (c) 2017 PINE64 ++ */ ++ ++/dts-v1/; ++#include "rk3328.dtsi" ++ ++/ { ++ model = "Popcorn Hour RockBox Basic"; ++ compatible = "popcornhour,rockbox", "rockchip,rk3328"; ++ ++ chosen { ++ stdout-path = "serial2:1500000n8"; ++ }; ++ ++ vcc_sd: sdmmc-regulator { ++ compatible = "regulator-fixed"; ++ gpio = <&gpio0 RK_PD6 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdmmc0m1_gpio>; ++ regulator-name = "vcc_sd"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ vin-supply = <&vcc_io>; ++ }; ++ ++ vcc_host_5v: vcc_host1_5v: vcc_otg_5v: vcc-host-5v-regulator { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc_host_5v"; ++ regulator-always-on; ++ regulator-boot-on; ++ vin-supply = <&vcc_sys>; ++ }; ++ ++ vcc_sys: vcc-sys { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc_sys"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ }; ++ ++ ir-receiver { ++ compatible = "gpio-ir-receiver"; ++ gpios = <&gpio2 RK_PA2 GPIO_ACTIVE_LOW>; ++ linux,rc-map-name = "rc-pine64"; ++ pinctrl-0 = <&ir_int>; ++ pinctrl-names = "default"; ++ }; ++ ++ leds { ++ compatible = "gpio-leds"; ++ ++ power { ++ gpios = <&rk805 0 GPIO_ACTIVE_HIGH>; ++ linux,default-trigger = "default-on"; ++ default-state = "on"; ++ }; ++ }; ++ ++ sdio_pwrseq: sdio-pwrseq { ++ compatible = "mmc-pwrseq-simple"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&wifi_enable_h>; ++ reset-gpios = <&gpio1 RK_PC2 GPIO_ACTIVE_LOW>; ++ }; ++}; ++ ++&cpu0 { ++ cpu-supply = <&vdd_arm>; ++}; ++ ++&cpu1 { ++ cpu-supply = <&vdd_arm>; ++}; ++ ++&cpu2 { ++ cpu-supply = <&vdd_arm>; ++}; ++ ++&cpu3 { ++ cpu-supply = <&vdd_arm>; ++}; ++ ++&emmc { ++ bus-width = <8>; ++ cap-mmc-highspeed; ++ mmc-ddr-1_8v; ++ mmc-hs200-1_8v; ++ non-removable; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>; ++ vmmc-supply = <&vcc_io>; ++ vqmmc-supply = <&vcc18_emmc>; ++ status = "okay"; ++}; ++ ++&gmac2phy { ++ assigned-clocks = <&cru SCLK_MAC2PHY_SRC>; ++ assigned-clock-rate = <50000000>; ++ assigned-clocks = <&cru SCLK_MAC2PHY>; ++ assigned-clock-parents = <&cru SCLK_MAC2PHY_SRC>; ++ clock_in_out = "output"; ++ phy-supply = <&vcc_io>; ++ status = "okay"; ++}; ++ ++&gpu { ++ mali-supply = <&vdd_logic>; ++}; ++ ++&hdmi { ++ status = "okay"; ++}; ++ ++&hdmiphy { ++ status = "okay"; ++}; ++ ++&hdmi_sound { ++ status = "okay"; ++}; ++ ++&i2c1 { ++ status = "okay"; ++ ++ rk805: rk805@18 { ++ compatible = "rockchip,rk805"; ++ reg = <0x18>; ++ interrupt-parent = <&gpio2>; ++ interrupts = <6 IRQ_TYPE_LEVEL_LOW>; ++ #clock-cells = <1>; ++ clock-output-names = "xin32k", "rk805-clkout2"; ++ gpio-controller; ++ #gpio-cells = <2>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pmic_int_l>; ++ rockchip,system-power-controller; ++ wakeup-source; ++ ++ vcc1-supply = <&vcc_sys>; ++ vcc2-supply = <&vcc_sys>; ++ vcc3-supply = <&vcc_sys>; ++ vcc4-supply = <&vcc_sys>; ++ vcc5-supply = <&vcc_io>; ++ vcc6-supply = <&vcc_io>; ++ ++ regulators { ++ vdd_logic: DCDC_REG1 { ++ regulator-name = "vdd_logic"; ++ regulator-min-microvolt = <900000>; ++ regulator-max-microvolt = <1150000>; ++ regulator-ramp-delay = <12500>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1000000>; ++ }; ++ }; ++ ++ vdd_arm: DCDC_REG2 { ++ regulator-name = "vdd_arm"; ++ regulator-min-microvolt = <950000>; ++ regulator-max-microvolt = <1350000>; ++ regulator-ramp-delay = <12500>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <950000>; ++ }; ++ }; ++ ++ vcc_ddr: DCDC_REG3 { ++ regulator-name = "vcc_ddr"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ }; ++ }; ++ ++ vcc_io: DCDC_REG4 { ++ regulator-name = "vcc_io"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <3300000>; ++ }; ++ }; ++ ++ vcc_18: LDO_REG1 { ++ regulator-name = "vcc_18"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ vcc18_emmc: LDO_REG2 { ++ regulator-name = "vcc18_emmc"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ vdd_10: LDO_REG3 { ++ regulator-name = "vdd_10"; ++ regulator-min-microvolt = <1000000>; ++ regulator-max-microvolt = <1000000>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1000000>; ++ }; ++ }; ++ }; ++ }; ++}; ++ ++&i2s0 { ++ status = "okay"; ++}; ++ ++&io_domains { ++ vccio1-supply = <&vcc_io>; ++ vccio2-supply = <&vcc18_emmc>; ++ vccio3-supply = <&vcc_io>; ++ vccio4-supply = <&vcc_io>; ++ vccio5-supply = <&vcc_io>; ++ vccio6-supply = <&vcc_io>; ++ pmuio-supply = <&vcc_io>; ++ status = "okay"; ++}; ++ ++&pinctrl { ++ ir { ++ ir_int: ir-int { ++ rockchip,pins = <2 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ pmic { ++ pmic_int_l: pmic-int-l { ++ rockchip,pins = <2 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ }; ++ ++ sdio-pwrseq { ++ wifi_enable_h: wifi-enable-h { ++ rockchip,pins = <1 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none_4ma>, ++ <1 RK_PC3 RK_FUNC_GPIO &pcfg_pull_none_4ma>; ++ }; ++ }; ++}; ++ ++&sdio { ++ bus-width = <4>; ++ cap-sd-highspeed; ++ cap-sdio-irq; ++ keep-power-in-suspend; ++ mmc-pwrseq = <&sdio_pwrseq>; ++ non-removable; ++ num-slots = <1>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdmmc1_bus4 &sdmmc1_cmd &sdmmc1_clk>; ++ status = "disabled"; ++}; ++ ++&sdmmc { ++ bus-width = <4>; ++ cap-mmc-highspeed; ++ cap-sd-highspeed; ++ disable-wp; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdmmc0_clk &sdmmc0_cmd &sdmmc0_dectn &sdmmc0_bus4>; ++ vmmc-supply = <&vcc_sd>; ++ status = "okay"; ++}; ++ ++&spdif { ++ pinctrl-0 = <&spdifm0_tx>; ++ status = "okay"; ++}; ++ ++&spdif_out { ++ status = "okay"; ++}; ++ ++&spdif_sound { ++ status = "okay"; ++}; ++ ++&tsadc { ++ rockchip,hw-tshut-mode = <0>; ++ rockchip,hw-tshut-polarity = <0>; ++ status = "okay"; ++}; ++ ++&uart2 { ++ status = "okay"; ++}; ++ ++&u2phy { ++ status = "okay"; ++}; ++ ++&u2phy_host { ++ status = "okay"; ++}; ++ ++&u2phy_otg { ++ status = "okay"; ++}; ++ ++&usb20_otg { ++ dr_mode = "host"; ++ status = "okay"; ++}; ++ ++&usb_host0_ehci { ++ status = "okay"; ++}; ++ ++&usb_host0_ohci { ++ status = "okay"; ++}; ++ ++&vop { ++ status = "okay"; ++}; ++ ++&vop_mmu { ++ status = "okay"; ++}; +-- +2.17.1 + + +From 175d289ac91694f01eaf5914a7e124ec1de1f9ac Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 8 Dec 2019 21:29:55 +0000 +Subject: [PATCH] arm64: dts: rockchip: enable hdmi sound on rk3399-firefly + +--- + arch/arm64/boot/dts/rockchip/rk3399-firefly.dts | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3399-firefly.dts b/arch/arm64/boot/dts/rockchip/rk3399-firefly.dts +index d63faf38cc81..e9e2a6fb623b 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3399-firefly.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3399-firefly.dts +@@ -263,6 +263,10 @@ + status = "okay"; + }; + ++&hdmi_sound { ++ status = "okay"; ++}; ++ + &i2c0 { + clock-frequency = <400000>; + i2c-scl-rising-time-ns = <168>; +-- +2.17.1 + + +From f8982a639da0310faf15639a8a068e7534b97b57 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 14 Apr 2019 21:25:34 +0000 +Subject: [PATCH] arm64: dts: rockchip: enable hdmi sound on rk3399-orangepi + +--- + arch/arm64/boot/dts/rockchip/rk3399-orangepi.dts | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3399-orangepi.dts b/arch/arm64/boot/dts/rockchip/rk3399-orangepi.dts +index 9c659f3115c8..bfb9fa11adcc 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3399-orangepi.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3399-orangepi.dts +@@ -517,6 +517,10 @@ + }; + }; + ++&i2s2 { ++ status = "okay"; ++}; ++ + &io_domains { + status = "okay"; + bt656-supply = <&vcc_3v0>; +-- +2.17.1 + diff --git a/patch/kernel/rk322x-current/01-linux-0005-for-libreelec.patch b/patch/kernel/rk322x-current/01-linux-0005-for-libreelec.patch new file mode 100644 index 0000000000..22589ab70b --- /dev/null +++ b/patch/kernel/rk322x-current/01-linux-0005-for-libreelec.patch @@ -0,0 +1,1651 @@ +diff --git a/Documentation/devicetree/bindings/usb/rockchip,dwc3.txt b/Documentation/devicetree/bindings/usb/rockchip,dwc3.txt +index c8c4b00ecb94..4ca357835a48 100644 +--- a/Documentation/devicetree/bindings/usb/rockchip,dwc3.txt ++++ b/Documentation/devicetree/bindings/usb/rockchip,dwc3.txt +@@ -1,7 +1,9 @@ + Rockchip SuperSpeed DWC3 USB SoC controller + + Required properties: +-- compatible: should contain "rockchip,rk3399-dwc3" for rk3399 SoC ++- compatible: should be one of the following: ++ - "rockchip,rk3399-dwc3": for rk3399 SoC ++ - "rockchip,rk3328-dwc3", "rockchip,rk3399-dwc3": for rk3328 SoC + - clocks: A list of phandle + clock-specifier pairs for the + clocks listed in clock-names + - clock-names: Should contain the following: +-- +2.17.1 + + +From 041ddb731b5e025e1bea4d3d68c30f09521ca8dd Mon Sep 17 00:00:00 2001 +From: William Wu +Date: Mon, 4 Dec 2017 10:40:39 +0100 +Subject: [PATCH] arm64: dts: rockchip: add usb3 controller node for RK3328 + SoCs + +RK3328 has one USB 3.0 OTG controller which uses DWC_USB3 +core's general architecture. It can act as static xHCI host +controller, static device controller, USB 3.0/2.0 OTG basing +on ID of USB3.0 PHY. + +Signed-off-by: William Wu +Signed-off-by: Heiko Stuebner +--- + arch/arm64/boot/dts/rockchip/rk3328.dtsi | 32 ++++++++++++++++++++++++ + 1 file changed, 32 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi +index a4b0947f82a7..bc9186f66d9c 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi +@@ -1037,6 +1037,38 @@ + status = "disabled"; + }; + ++ usbdrd3: usb@ff600000 { ++ compatible = "rockchip,rk3328-dwc3", "rockchip,rk3399-dwc3"; ++ clocks = <&cru SCLK_USB3OTG_REF>, <&cru SCLK_USB3OTG_SUSPEND>, ++ <&cru ACLK_USB3OTG>; ++ clock-names = "ref_clk", "suspend_clk", ++ "bus_clk"; ++ resets = <&cru SRST_USB3OTG>; ++ reset-names = "usb3-otg"; ++ #address-cells = <2>; ++ #size-cells = <2>; ++ ranges; ++ status = "disabled"; ++ ++ usbdrd_dwc3: dwc3@ff600000 { ++ compatible = "snps,dwc3"; ++ reg = <0x0 0xff600000 0x0 0x100000>; ++ interrupts = ; ++ clocks = <&cru SCLK_USB3OTG_REF>, <&cru ACLK_USB3OTG>, ++ <&cru SCLK_USB3OTG_SUSPEND>; ++ clock-names = "ref", "bus_early", "suspend"; ++ dr_mode = "otg"; ++ phy_type = "utmi_wide"; ++ snps,dis_enblslpm_quirk; ++ snps,dis-u2-freeclk-exists-quirk; ++ snps,dis_u2_susphy_quirk; ++ snps,dis_u3_susphy_quirk; ++ snps,dis-del-phy-power-chg-quirk; ++ snps,dis-tx-ipgap-linecheck-quirk; ++ status = "disabled"; ++ }; ++ }; ++ + gic: interrupt-controller@ff811000 { + compatible = "arm,gic-400"; + #interrupt-cells = <3>; +-- +2.17.1 + + +From 6b2ec0b7974089cd179241595d76f204151a0329 Mon Sep 17 00:00:00 2001 +From: Heiko Stuebner +Date: Mon, 4 Dec 2017 10:40:41 +0100 +Subject: [PATCH] arm64: dts: rockchip: enable usb3 nodes on rk3328-rock64 + +Enable the nodes to make the usb3 port usable on that board. + +Signed-off-by: Heiko Stuebner +--- + arch/arm64/boot/dts/rockchip/rk3328-rock64.dts | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts +index 345c045c58e6..1cc3a8f5c3d7 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts +@@ -364,6 +364,15 @@ + status = "okay"; + }; + ++&usbdrd3 { ++ status = "okay"; ++}; ++ ++&usbdrd_dwc3 { ++ dr_mode = "host"; ++ status = "okay"; ++}; ++ + &vop { + status = "okay"; + }; +-- +2.17.1 + + +From 39e4f61930b2b6108ae6423698f233d6d2b57958 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Tue, 12 Mar 2019 19:42:03 +0000 +Subject: [PATCH] arm64: dts: rockchip: enable usb3 nodes on rk3328-roc-cc + +Enable the nodes to make the usb3 port usable on that board. + +Signed-off-by: Jonas Karlman +--- + arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts b/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts +index b58948f478a1..78e0e23d1efb 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts +@@ -373,6 +373,15 @@ + status = "okay"; + }; + ++&usbdrd3 { ++ status = "okay"; ++}; ++ ++&usbdrd_dwc3 { ++ dr_mode = "host"; ++ status = "okay"; ++}; ++ + &vop { + status = "okay"; + }; +-- +2.17.1 + + +From aec6055775b63eaeb6b4a509b37aa6718fa2f84f Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 12 May 2019 12:40:00 +0000 +Subject: [PATCH] arm64: dts: rockchip: enable usb3 nodes on rk3328-rockbox + +--- + arch/arm64/boot/dts/rockchip/rk3328-rockbox.dts | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3328-rockbox.dts b/arch/arm64/boot/dts/rockchip/rk3328-rockbox.dts +index b82708cfe742..6f5eab7c0050 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3328-rockbox.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3328-rockbox.dts +@@ -340,6 +340,15 @@ + status = "okay"; + }; + ++&usbdrd3 { ++ status = "okay"; ++}; ++ ++&usbdrd_dwc3 { ++ dr_mode = "host"; ++ status = "okay"; ++}; ++ + &vop { + status = "okay"; + }; +-- +2.17.1 + + +From b1c19ab3e134c7ba1c0352b484fa5b3591f5af4d Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Thu, 7 Feb 2019 22:03:15 +0000 +Subject: [PATCH] HACK: ARM: dts: rockchip: disable vopl node on rk3288 + +--- + arch/arm/boot/dts/rk3288-miqi.dts | 8 -------- + arch/arm/boot/dts/rk3288-tinker.dtsi | 8 -------- + 2 files changed, 16 deletions(-) + +diff --git a/arch/arm/boot/dts/rk3288-miqi.dts b/arch/arm/boot/dts/rk3288-miqi.dts +index 8428095934f5..8d8a4f49e4af 100644 +--- a/arch/arm/boot/dts/rk3288-miqi.dts ++++ b/arch/arm/boot/dts/rk3288-miqi.dts +@@ -438,14 +438,6 @@ + status = "okay"; + }; + +-&vopl { +- status = "okay"; +-}; +- +-&vopl_mmu { +- status = "okay"; +-}; +- + &wdt { + status = "okay"; + }; +diff --git a/arch/arm/boot/dts/rk3288-tinker.dtsi b/arch/arm/boot/dts/rk3288-tinker.dtsi +index 49b64f4908cd..5976c9a8eb0c 100644 +--- a/arch/arm/boot/dts/rk3288-tinker.dtsi ++++ b/arch/arm/boot/dts/rk3288-tinker.dtsi +@@ -534,14 +534,6 @@ + status = "okay"; + }; + +-&vopl { +- status = "okay"; +-}; +- +-&vopl_mmu { +- status = "okay"; +-}; +- + &wdt { + status = "okay"; + }; +-- +2.17.1 + + +From b255ef1b90ebee3cfb44b545f75aa00e653411e8 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Mon, 15 Apr 2019 05:06:50 +0000 +Subject: [PATCH] HACK: arm64: dts: rockchip: disable vopl node on rk3399 + +--- + arch/arm64/boot/dts/rockchip/rk3399-firefly.dts | 8 -------- + arch/arm64/boot/dts/rockchip/rk3399-khadas-edge.dtsi | 8 -------- + arch/arm64/boot/dts/rockchip/rk3399-nanopi4.dtsi | 8 -------- + arch/arm64/boot/dts/rockchip/rk3399-orangepi.dts | 8 -------- + arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi | 8 -------- + arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dts | 8 -------- + arch/arm64/boot/dts/rockchip/rk3399-rock960.dtsi | 8 -------- + arch/arm64/boot/dts/rockchip/rk3399-sapphire.dtsi | 8 -------- + 8 files changed, 64 deletions(-) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3399-firefly.dts b/arch/arm64/boot/dts/rockchip/rk3399-firefly.dts +index e9e2a6fb623b..ee38f6da9368 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3399-firefly.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3399-firefly.dts +@@ -801,11 +801,3 @@ + &vopb_mmu { + status = "okay"; + }; +- +-&vopl { +- status = "okay"; +-}; +- +-&vopl_mmu { +- status = "okay"; +-}; +diff --git a/arch/arm64/boot/dts/rockchip/rk3399-khadas-edge.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-khadas-edge.dtsi +index e87a04477440..f22f54dd0b73 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3399-khadas-edge.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3399-khadas-edge.dtsi +@@ -797,11 +797,3 @@ + &vopb_mmu { + status = "okay"; + }; +- +-&vopl { +- status = "okay"; +-}; +- +-&vopl_mmu { +- status = "okay"; +-}; +diff --git a/arch/arm64/boot/dts/rockchip/rk3399-nanopi4.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-nanopi4.dtsi +index c88018a0ef35..002ed18477e6 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3399-nanopi4.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3399-nanopi4.dtsi +@@ -747,11 +747,3 @@ + &vopb_mmu { + status = "okay"; + }; +- +-&vopl { +- status = "okay"; +-}; +- +-&vopl_mmu { +- status = "okay"; +-}; +diff --git a/arch/arm64/boot/dts/rockchip/rk3399-orangepi.dts b/arch/arm64/boot/dts/rockchip/rk3399-orangepi.dts +index bfb9fa11adcc..aa7f5e89ad72 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3399-orangepi.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3399-orangepi.dts +@@ -787,11 +787,3 @@ + &vopb_mmu { + status = "okay"; + }; +- +-&vopl { +- status = "okay"; +-}; +- +-&vopl_mmu { +- status = "okay"; +-}; +diff --git a/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi +index 9f225e9c3d54..e917060f34c7 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi +@@ -804,11 +804,3 @@ + &vopb_mmu { + status = "okay"; + }; +- +-&vopl { +- status = "okay"; +-}; +- +-&vopl_mmu { +- status = "okay"; +-}; +diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dts b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dts +index e4c71c77c3ef..4fdbc692b138 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dts +@@ -728,11 +728,3 @@ + &vopb_mmu { + status = "okay"; + }; +- +-&vopl { +- status = "okay"; +-}; +- +-&vopl_mmu { +- status = "okay"; +-}; +diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rock960.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-rock960.dtsi +index b69f0f2cbd67..aab612855670 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3399-rock960.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3399-rock960.dtsi +@@ -654,11 +654,3 @@ + &vopb_mmu { + status = "okay"; + }; +- +-&vopl { +- status = "okay"; +-}; +- +-&vopl_mmu { +- status = "okay"; +-}; +diff --git a/arch/arm64/boot/dts/rockchip/rk3399-sapphire.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-sapphire.dtsi +index 0885d48011ab..471161b1accf 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3399-sapphire.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3399-sapphire.dtsi +@@ -639,11 +639,3 @@ + &vopb_mmu { + status = "okay"; + }; +- +-&vopl { +- status = "okay"; +-}; +- +-&vopl_mmu { +- status = "okay"; +-}; +-- +2.17.1 + + +From 915a6f4cd5cb34c183e26f1c0889f93e55fa9de9 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 14 Apr 2019 21:16:31 +0000 +Subject: [PATCH] HACK: arm64: dts: rockchip: rename hdmi sound card on rk3399 + +--- + 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 33cc21fcf4c1..adc8c1058196 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi +@@ -1735,7 +1735,7 @@ + compatible = "simple-audio-card"; + simple-audio-card,format = "i2s"; + simple-audio-card,mclk-fs = <256>; +- simple-audio-card,name = "hdmi-sound"; ++ simple-audio-card,name = "HDMI"; + status = "disabled"; + + simple-audio-card,cpu { +-- +2.17.1 + + +From 259475f3ec472d65fe037e5c6c4d217062e4a55c Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 12 May 2019 12:40:00 +0000 +Subject: [PATCH] WIP: arm64: dts: rockchip: add rk3328-box devices + +--- + arch/arm64/boot/dts/rockchip/Makefile | 3 + + .../boot/dts/rockchip/rk3328-box-trn9.dts | 420 ++++++++++++++++++ + .../boot/dts/rockchip/rk3328-box-z28.dts | 367 +++++++++++++++ + arch/arm64/boot/dts/rockchip/rk3328-box.dts | 400 +++++++++++++++++ + 4 files changed, 1190 insertions(+) + create mode 100644 arch/arm64/boot/dts/rockchip/rk3328-box-trn9.dts + create mode 100644 arch/arm64/boot/dts/rockchip/rk3328-box-z28.dts + create mode 100644 arch/arm64/boot/dts/rockchip/rk3328-box.dts + +diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile +index 1df8933cb084..9ff568832af7 100644 +--- a/arch/arm64/boot/dts/rockchip/Makefile ++++ b/arch/arm64/boot/dts/rockchip/Makefile +@@ -3,6 +3,9 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += px30-evb.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3308-evb.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3308-roc-cc.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-a1.dtb ++dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-box.dtb ++dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-box-trn9.dtb ++dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-box-z28.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-evb.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-rock64.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-rockbox.dtb +diff --git a/arch/arm64/boot/dts/rockchip/rk3328-box-trn9.dts b/arch/arm64/boot/dts/rockchip/rk3328-box-trn9.dts +new file mode 100644 +index 000000000000..e611d12ea375 +--- /dev/null ++++ b/arch/arm64/boot/dts/rockchip/rk3328-box-trn9.dts +@@ -0,0 +1,420 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++/* ++ * Copyright (c) 2017 PINE64 ++ */ ++ ++/dts-v1/; ++#include "rk3328.dtsi" ++ ++/ { ++ model = "Rockchip RK3328 TRN9"; ++ compatible = "rockchip,rk3328-box-trn9", "rockchip,rk3328"; ++ ++ gmac_clkin: external-gmac-clock { ++ compatible = "fixed-clock"; ++ clock-frequency = <125000000>; ++ clock-output-names = "gmac_clkin"; ++ #clock-cells = <0>; ++ }; ++ ++ vcc_sd: sdmmc-regulator { ++ compatible = "regulator-fixed"; ++ gpio = <&gpio0 RK_PD6 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdmmc0m1_gpio>; ++ regulator-name = "vcc_sd"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ vin-supply = <&vcc_io>; ++ }; ++ ++ vcc_host_5v: vcc-host-5v-regulator { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpio = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&usb30_host_drv>; ++ regulator-name = "vcc_host_5v"; ++ regulator-always-on; ++ regulator-boot-on; ++ vin-supply = <&vcc_sys>; ++ }; ++ ++ vcc_host1_5v: vcc_otg_5v: vcc-host1-5v-regulator { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpio = <&gpio0 RK_PA2 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&usb20_host_drv>; ++ regulator-name = "vcc_host1_5v"; ++ regulator-always-on; ++ regulator-boot-on; ++ vin-supply = <&vcc_sys>; ++ }; ++ ++ vcc_sys: vcc-sys { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc_sys"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ }; ++ ++ ir-receiver { ++ compatible = "gpio-ir-receiver"; ++ gpios = <&gpio2 RK_PA2 GPIO_ACTIVE_LOW>; ++ pinctrl-0 = <&ir_int>; ++ pinctrl-names = "default"; ++ }; ++ ++ leds { ++ compatible = "gpio-leds"; ++ ++ power { ++ gpios = <&rk805 0 GPIO_ACTIVE_LOW>; ++ linux,default-trigger = "default-on"; ++ default-state = "on"; ++ }; ++ }; ++ ++ sdio_pwrseq: sdio-pwrseq { ++ compatible = "mmc-pwrseq-simple"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&wifi_enable_h>; ++ reset-gpios = <&gpio3 RK_PB0 GPIO_ACTIVE_LOW>; ++ }; ++}; ++ ++&analog_sound { ++ status = "okay"; ++}; ++ ++&codec { ++ status = "okay"; ++}; ++ ++&cpu0 { ++ cpu-supply = <&vdd_arm>; ++}; ++ ++&cpu1 { ++ cpu-supply = <&vdd_arm>; ++}; ++ ++&cpu2 { ++ cpu-supply = <&vdd_arm>; ++}; ++ ++&cpu3 { ++ cpu-supply = <&vdd_arm>; ++}; ++ ++&emmc { ++ bus-width = <8>; ++ cap-mmc-highspeed; ++ mmc-ddr-1_8v; ++ mmc-hs200-1_8v; ++ non-removable; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>; ++ vmmc-supply = <&vcc_io>; ++ vqmmc-supply = <&vcc18_emmc>; ++ status = "okay"; ++}; ++ ++&gmac2io { ++ assigned-clocks = <&cru SCLK_MAC2IO>, <&cru SCLK_MAC2IO_EXT>; ++ assigned-clock-parents = <&gmac_clkin>, <&gmac_clkin>; ++ clock_in_out = "input"; ++ phy-mode = "rgmii"; ++ phy-supply = <&vcc_io>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&rgmiim1_pins>; ++ snps,aal; ++ snps,pbl = <0x4>; ++ snps,reset-gpio = <&gpio2 RK_PC1 GPIO_ACTIVE_LOW>; ++ snps,reset-active-low; ++ snps,reset-delays-us = <0 10000 50000>; ++ tx_delay = <0x26>; ++ rx_delay = <0x11>; ++ status = "okay"; ++}; ++ ++&gpu { ++ mali-supply = <&vdd_logic>; ++}; ++ ++&hdmi { ++ status = "okay"; ++}; ++ ++&hdmiphy { ++ status = "okay"; ++}; ++ ++&hdmi_sound { ++ status = "okay"; ++}; ++ ++&i2c1 { ++ status = "okay"; ++ ++ rk805: rk805@18 { ++ compatible = "rockchip,rk805"; ++ reg = <0x18>; ++ interrupt-parent = <&gpio2>; ++ interrupts = <6 IRQ_TYPE_LEVEL_LOW>; ++ #clock-cells = <1>; ++ clock-output-names = "xin32k", "rk805-clkout2"; ++ gpio-controller; ++ #gpio-cells = <2>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pmic_int_l>; ++ rockchip,system-power-controller; ++ wakeup-source; ++ ++ vcc1-supply = <&vcc_sys>; ++ vcc2-supply = <&vcc_sys>; ++ vcc3-supply = <&vcc_sys>; ++ vcc4-supply = <&vcc_sys>; ++ vcc5-supply = <&vcc_io>; ++ vcc6-supply = <&vcc_io>; ++ ++ regulators { ++ vdd_logic: DCDC_REG1 { ++ regulator-name = "vdd_logic"; ++ regulator-min-microvolt = <900000>; ++ regulator-max-microvolt = <1150000>; ++ regulator-ramp-delay = <12500>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1000000>; ++ }; ++ }; ++ ++ vdd_arm: DCDC_REG2 { ++ regulator-name = "vdd_arm"; ++ regulator-min-microvolt = <950000>; ++ regulator-max-microvolt = <1350000>; ++ regulator-ramp-delay = <12500>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <950000>; ++ }; ++ }; ++ ++ vcc_ddr: DCDC_REG3 { ++ regulator-name = "vcc_ddr"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ }; ++ }; ++ ++ vcc_io: DCDC_REG4 { ++ regulator-name = "vcc_io"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <3300000>; ++ }; ++ }; ++ ++ vcc_18: LDO_REG1 { ++ regulator-name = "vcc_18"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ vcc18_emmc: LDO_REG2 { ++ regulator-name = "vcc18_emmc"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ vdd_10: LDO_REG3 { ++ regulator-name = "vdd_10"; ++ regulator-min-microvolt = <1000000>; ++ regulator-max-microvolt = <1000000>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1000000>; ++ }; ++ }; ++ }; ++ }; ++}; ++ ++&i2s0 { ++ status = "okay"; ++}; ++ ++&i2s1 { ++ status = "okay"; ++}; ++ ++&io_domains { ++ vccio1-supply = <&vcc_io>; ++ vccio2-supply = <&vcc18_emmc>; ++ vccio3-supply = <&vcc_io>; ++ vccio4-supply = <&vcc_18>; ++ vccio5-supply = <&vcc_io>; ++ vccio6-supply = <&vcc_18>; ++ pmuio-supply = <&vcc_io>; ++ status = "okay"; ++}; ++ ++&pinctrl { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&clk_32k_out>; ++ ++ clk_32k { ++ clk_32k_out: clk-32k-out { ++ rockchip,pins = <1 RK_PD4 RK_FUNC_1 &pcfg_pull_none>; ++ }; ++ }; ++ ++ ir { ++ ir_int: ir-int { ++ rockchip,pins = <2 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ pmic { ++ pmic_int_l: pmic-int-l { ++ rockchip,pins = <2 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ }; ++ ++ sdio-pwrseq { ++ wifi_enable_h: wifi-enable-h { ++ rockchip,pins = <3 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>, ++ <3 RK_PA1 RK_FUNC_GPIO &pcfg_pull_none_4ma>, ++ <1 RK_PD0 RK_FUNC_GPIO &pcfg_pull_none>, ++ <1 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ usb2 { ++ usb20_host_drv: usb20-host-drv { ++ rockchip,pins = <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ usb3 { ++ usb30_host_drv: usb30-host-drv { ++ rockchip,pins = <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++}; ++ ++&sdmmc_ext { ++ bus-width = <4>; ++ cap-sd-highspeed; ++ cap-sdio-irq; ++ keep-power-in-suspend; ++ mmc-pwrseq = <&sdio_pwrseq>; ++ non-removable; ++ num-slots = <1>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdmmc0ext_bus4 &sdmmc0ext_cmd &sdmmc0ext_clk>; ++ sd-uhs-sdr104; ++ status = "okay"; ++}; ++ ++&sdmmc { ++ bus-width = <4>; ++ cap-mmc-highspeed; ++ cap-sd-highspeed; ++ disable-wp; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdmmc0_clk &sdmmc0_cmd &sdmmc0_dectn &sdmmc0_bus4>; ++ vmmc-supply = <&vcc_sd>; ++ status = "okay"; ++}; ++ ++&spdif { ++ pinctrl-0 = <&spdifm0_tx>; ++ status = "okay"; ++}; ++ ++&spdif_out { ++ status = "okay"; ++}; ++ ++&spdif_sound { ++ status = "okay"; ++}; ++ ++&tsadc { ++ rockchip,hw-tshut-mode = <0>; ++ rockchip,hw-tshut-polarity = <0>; ++ status = "okay"; ++}; ++ ++&uart2 { ++ status = "okay"; ++}; ++ ++&u2phy { ++ status = "okay"; ++}; ++ ++&u2phy_host { ++ status = "okay"; ++}; ++ ++&u2phy_otg { ++ status = "okay"; ++}; ++ ++&usb20_otg { ++ dr_mode = "host"; ++ status = "okay"; ++}; ++ ++&usb_host0_ehci { ++ status = "okay"; ++}; ++ ++&usb_host0_ohci { ++ status = "okay"; ++}; ++ ++&usbdrd3 { ++ status = "okay"; ++}; ++ ++&usbdrd_dwc3 { ++ dr_mode = "host"; ++ status = "okay"; ++}; ++ ++&vop { ++ status = "okay"; ++}; ++ ++&vop_mmu { ++ status = "okay"; ++}; +diff --git a/arch/arm64/boot/dts/rockchip/rk3328-box-z28.dts b/arch/arm64/boot/dts/rockchip/rk3328-box-z28.dts +new file mode 100644 +index 000000000000..797b92924f21 +--- /dev/null ++++ b/arch/arm64/boot/dts/rockchip/rk3328-box-z28.dts +@@ -0,0 +1,367 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++/* ++ * Copyright (c) 2017 PINE64 ++ */ ++ ++/dts-v1/; ++#include "rk3328.dtsi" ++ ++/ { ++ model = "Rockchip RK3328 Z28"; ++ compatible = "rockchip,rk3328-box-z28", "rockchip,rk3328"; ++ ++ chosen { ++ stdout-path = "serial2:1500000n8"; ++ }; ++ ++ vcc_sd: sdmmc-regulator { ++ compatible = "regulator-fixed"; ++ gpio = <&gpio0 RK_PD6 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdmmc0m1_gpio>; ++ regulator-name = "vcc_sd"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ vin-supply = <&vcc_io>; ++ }; ++ ++ vcc_host_5v: vcc-host-5v-regulator { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpio = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&usb30_host_drv>; ++ regulator-name = "vcc_host_5v"; ++ regulator-always-on; ++ regulator-boot-on; ++ vin-supply = <&vcc_sys>; ++ }; ++ ++ vcc_host1_5v: vcc_otg_5v: vcc-host1-5v-regulator { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpio = <&gpio0 RK_PA2 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&usb20_host_drv>; ++ regulator-name = "vcc_host1_5v"; ++ regulator-always-on; ++ regulator-boot-on; ++ vin-supply = <&vcc_sys>; ++ }; ++ ++ vcc_sys: vcc-sys { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc_sys"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ }; ++ ++ ir-receiver { ++ compatible = "gpio-ir-receiver"; ++ gpios = <&gpio2 RK_PA2 GPIO_ACTIVE_LOW>; ++ pinctrl-0 = <&ir_int>; ++ pinctrl-names = "default"; ++ }; ++ ++ leds { ++ compatible = "gpio-leds"; ++ ++ power { ++ gpios = <&rk805 0 GPIO_ACTIVE_HIGH>; ++ linux,default-trigger = "default-on"; ++ default-state = "on"; ++ }; ++ }; ++}; ++ ++&cpu0 { ++ cpu-supply = <&vdd_arm>; ++}; ++ ++&cpu1 { ++ cpu-supply = <&vdd_arm>; ++}; ++ ++&cpu2 { ++ cpu-supply = <&vdd_arm>; ++}; ++ ++&cpu3 { ++ cpu-supply = <&vdd_arm>; ++}; ++ ++&emmc { ++ bus-width = <8>; ++ cap-mmc-highspeed; ++ mmc-ddr-1_8v; ++ mmc-hs200-1_8v; ++ non-removable; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>; ++ vmmc-supply = <&vcc_io>; ++ vqmmc-supply = <&vcc18_emmc>; ++ status = "okay"; ++}; ++ ++&gmac2phy { ++ assigned-clocks = <&cru SCLK_MAC2PHY_SRC>; ++ assigned-clock-rate = <50000000>; ++ assigned-clocks = <&cru SCLK_MAC2PHY>; ++ assigned-clock-parents = <&cru SCLK_MAC2PHY_SRC>; ++ clock_in_out = "output"; ++ phy-supply = <&vcc_io>; ++ status = "okay"; ++}; ++ ++&gpu { ++ mali-supply = <&vdd_logic>; ++}; ++ ++&hdmi { ++ status = "okay"; ++}; ++ ++&hdmiphy { ++ status = "okay"; ++}; ++ ++&hdmi_sound { ++ status = "okay"; ++}; ++ ++&i2c1 { ++ status = "okay"; ++ ++ rk805: rk805@18 { ++ compatible = "rockchip,rk805"; ++ reg = <0x18>; ++ interrupt-parent = <&gpio2>; ++ interrupts = <6 IRQ_TYPE_LEVEL_LOW>; ++ #clock-cells = <1>; ++ clock-output-names = "xin32k", "rk805-clkout2"; ++ gpio-controller; ++ #gpio-cells = <2>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pmic_int_l>; ++ rockchip,system-power-controller; ++ wakeup-source; ++ ++ vcc1-supply = <&vcc_sys>; ++ vcc2-supply = <&vcc_sys>; ++ vcc3-supply = <&vcc_sys>; ++ vcc4-supply = <&vcc_sys>; ++ vcc5-supply = <&vcc_io>; ++ vcc6-supply = <&vcc_io>; ++ ++ regulators { ++ vdd_logic: DCDC_REG1 { ++ regulator-name = "vdd_logic"; ++ regulator-min-microvolt = <900000>; ++ regulator-max-microvolt = <1150000>; ++ regulator-ramp-delay = <12500>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1000000>; ++ }; ++ }; ++ ++ vdd_arm: DCDC_REG2 { ++ regulator-name = "vdd_arm"; ++ regulator-min-microvolt = <950000>; ++ regulator-max-microvolt = <1350000>; ++ regulator-ramp-delay = <12500>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <950000>; ++ }; ++ }; ++ ++ vcc_ddr: DCDC_REG3 { ++ regulator-name = "vcc_ddr"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ }; ++ }; ++ ++ vcc_io: DCDC_REG4 { ++ regulator-name = "vcc_io"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <3300000>; ++ }; ++ }; ++ ++ vcc_18: LDO_REG1 { ++ regulator-name = "vcc_18"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ vcc18_emmc: LDO_REG2 { ++ regulator-name = "vcc18_emmc"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ vdd_10: LDO_REG3 { ++ regulator-name = "vdd_10"; ++ regulator-min-microvolt = <1000000>; ++ regulator-max-microvolt = <1000000>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1000000>; ++ }; ++ }; ++ }; ++ }; ++}; ++ ++&i2s0 { ++ status = "okay"; ++}; ++ ++&io_domains { ++ vccio1-supply = <&vcc_io>; ++ vccio2-supply = <&vcc18_emmc>; ++ vccio3-supply = <&vcc_io>; ++ vccio4-supply = <&vcc_18>; ++ vccio5-supply = <&vcc_io>; ++ vccio6-supply = <&vcc_io>; ++ pmuio-supply = <&vcc_io>; ++ status = "okay"; ++}; ++ ++&pinctrl { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&clk_32k_out>; ++ ++ clk_32k { ++ clk_32k_out: clk-32k-out { ++ rockchip,pins = <1 RK_PD4 RK_FUNC_1 &pcfg_pull_none>; ++ }; ++ }; ++ ++ ir { ++ ir_int: ir-int { ++ rockchip,pins = <2 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ pmic { ++ pmic_int_l: pmic-int-l { ++ rockchip,pins = <2 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ }; ++ ++ usb2 { ++ usb20_host_drv: usb20-host-drv { ++ rockchip,pins = <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ usb3 { ++ usb30_host_drv: usb30-host-drv { ++ rockchip,pins = <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++}; ++ ++&sdmmc { ++ bus-width = <4>; ++ cap-mmc-highspeed; ++ cap-sd-highspeed; ++ disable-wp; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdmmc0_clk &sdmmc0_cmd &sdmmc0_dectn &sdmmc0_bus4>; ++ vmmc-supply = <&vcc_sd>; ++ status = "okay"; ++}; ++ ++&spdif { ++ pinctrl-0 = <&spdifm0_tx>; ++ status = "okay"; ++}; ++ ++&spdif_out { ++ status = "okay"; ++}; ++ ++&spdif_sound { ++ status = "okay"; ++}; ++ ++&tsadc { ++ rockchip,hw-tshut-mode = <0>; ++ rockchip,hw-tshut-polarity = <0>; ++ status = "okay"; ++}; ++ ++&uart2 { ++ status = "okay"; ++}; ++ ++&u2phy { ++ status = "okay"; ++}; ++ ++&u2phy_host { ++ status = "okay"; ++}; ++ ++&u2phy_otg { ++ status = "okay"; ++}; ++ ++&usb20_otg { ++ dr_mode = "host"; ++ status = "okay"; ++}; ++ ++&usb_host0_ehci { ++ status = "okay"; ++}; ++ ++&usb_host0_ohci { ++ status = "okay"; ++}; ++ ++&usbdrd3 { ++ status = "okay"; ++}; ++ ++&usbdrd_dwc3 { ++ dr_mode = "host"; ++ status = "okay"; ++}; ++ ++&vop { ++ status = "okay"; ++}; ++ ++&vop_mmu { ++ status = "okay"; ++}; +diff --git a/arch/arm64/boot/dts/rockchip/rk3328-box.dts b/arch/arm64/boot/dts/rockchip/rk3328-box.dts +new file mode 100644 +index 000000000000..2526147fd48b +--- /dev/null ++++ b/arch/arm64/boot/dts/rockchip/rk3328-box.dts +@@ -0,0 +1,400 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++/* ++ * Copyright (c) 2017 PINE64 ++ */ ++ ++/dts-v1/; ++#include "rk3328.dtsi" ++ ++/ { ++ model = "Rockchip RK3328 BOX"; ++ compatible = "rockchip,rk3328-box", "rockchip,rk3328"; ++ ++ chosen { ++ stdout-path = "serial2:1500000n8"; ++ }; ++ ++ vcc_sd: sdmmc-regulator { ++ compatible = "regulator-fixed"; ++ gpio = <&gpio0 RK_PD6 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdmmc0m1_gpio>; ++ regulator-name = "vcc_sd"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ vin-supply = <&vcc_io>; ++ }; ++ ++ vcc_host_5v: vcc-host-5v-regulator { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpio = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&usb30_host_drv>; ++ regulator-name = "vcc_host_5v"; ++ regulator-always-on; ++ regulator-boot-on; ++ vin-supply = <&vcc_sys>; ++ }; ++ ++ vcc_host1_5v: vcc_otg_5v: vcc-host1-5v-regulator { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpio = <&gpio0 RK_PA2 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&usb20_host_drv>; ++ regulator-name = "vcc_host1_5v"; ++ regulator-always-on; ++ regulator-boot-on; ++ vin-supply = <&vcc_sys>; ++ }; ++ ++ vcc_sys: vcc-sys { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc_sys"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ }; ++ ++ ir-receiver { ++ compatible = "gpio-ir-receiver"; ++ gpios = <&gpio2 RK_PA2 GPIO_ACTIVE_LOW>; ++ pinctrl-0 = <&ir_int>; ++ pinctrl-names = "default"; ++ }; ++ ++ leds { ++ compatible = "gpio-leds"; ++ ++ led1 { ++ gpios = <&rk805 0 GPIO_ACTIVE_LOW>; ++ linux,default-trigger = "default-on"; ++ default-state = "on"; ++ }; ++ ++ led2 { ++ gpios = <&rk805 1 GPIO_ACTIVE_LOW>; ++ linux,default-trigger = "mmc0"; ++ }; ++ }; ++ ++ sdio_pwrseq: sdio-pwrseq { ++ compatible = "mmc-pwrseq-simple"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&wifi_enable_h>; ++ reset-gpios = <&gpio1 RK_PC2 GPIO_ACTIVE_LOW>; ++ }; ++}; ++ ++&cpu0 { ++ cpu-supply = <&vdd_arm>; ++}; ++ ++&cpu1 { ++ cpu-supply = <&vdd_arm>; ++}; ++ ++&cpu2 { ++ cpu-supply = <&vdd_arm>; ++}; ++ ++&cpu3 { ++ cpu-supply = <&vdd_arm>; ++}; ++ ++&emmc { ++ bus-width = <8>; ++ cap-mmc-highspeed; ++ mmc-ddr-1_8v; ++ mmc-hs200-1_8v; ++ non-removable; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>; ++ vmmc-supply = <&vcc_io>; ++ vqmmc-supply = <&vcc18_emmc>; ++ status = "okay"; ++}; ++ ++&gmac2phy { ++ assigned-clocks = <&cru SCLK_MAC2PHY_SRC>; ++ assigned-clock-rate = <50000000>; ++ assigned-clocks = <&cru SCLK_MAC2PHY>; ++ assigned-clock-parents = <&cru SCLK_MAC2PHY_SRC>; ++ clock_in_out = "output"; ++ phy-supply = <&vcc_io>; ++ status = "okay"; ++}; ++ ++&gpu { ++ mali-supply = <&vdd_logic>; ++}; ++ ++&hdmi { ++ status = "okay"; ++}; ++ ++&hdmiphy { ++ status = "okay"; ++}; ++ ++&hdmi_sound { ++ status = "okay"; ++}; ++ ++&i2c1 { ++ status = "okay"; ++ ++ rk805: rk805@18 { ++ compatible = "rockchip,rk805"; ++ reg = <0x18>; ++ interrupt-parent = <&gpio2>; ++ interrupts = <6 IRQ_TYPE_LEVEL_LOW>; ++ #clock-cells = <1>; ++ clock-output-names = "xin32k", "rk805-clkout2"; ++ gpio-controller; ++ #gpio-cells = <2>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pmic_int_l>; ++ rockchip,system-power-controller; ++ wakeup-source; ++ ++ vcc1-supply = <&vcc_sys>; ++ vcc2-supply = <&vcc_sys>; ++ vcc3-supply = <&vcc_sys>; ++ vcc4-supply = <&vcc_sys>; ++ vcc5-supply = <&vcc_io>; ++ vcc6-supply = <&vcc_io>; ++ ++ regulators { ++ vdd_logic: DCDC_REG1 { ++ regulator-name = "vdd_logic"; ++ regulator-min-microvolt = <900000>; ++ regulator-max-microvolt = <1150000>; ++ regulator-ramp-delay = <12500>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1000000>; ++ }; ++ }; ++ ++ vdd_arm: DCDC_REG2 { ++ regulator-name = "vdd_arm"; ++ regulator-min-microvolt = <950000>; ++ regulator-max-microvolt = <1350000>; ++ regulator-ramp-delay = <12500>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <950000>; ++ }; ++ }; ++ ++ vcc_ddr: DCDC_REG3 { ++ regulator-name = "vcc_ddr"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ }; ++ }; ++ ++ vcc_io: DCDC_REG4 { ++ regulator-name = "vcc_io"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <3300000>; ++ }; ++ }; ++ ++ vcc_18: LDO_REG1 { ++ regulator-name = "vcc_18"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ vcc18_emmc: LDO_REG2 { ++ regulator-name = "vcc18_emmc"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ vdd_10: LDO_REG3 { ++ regulator-name = "vdd_10"; ++ regulator-min-microvolt = <1000000>; ++ regulator-max-microvolt = <1000000>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1000000>; ++ }; ++ }; ++ }; ++ }; ++}; ++ ++&i2s0 { ++ status = "okay"; ++}; ++ ++&io_domains { ++ vccio1-supply = <&vcc_io>; ++ vccio2-supply = <&vcc18_emmc>; ++ vccio3-supply = <&vcc_io>; ++ vccio4-supply = <&vcc_18>; ++ vccio5-supply = <&vcc_io>; ++ vccio6-supply = <&vcc_io>; ++ pmuio-supply = <&vcc_io>; ++ status = "okay"; ++}; ++ ++&pinctrl { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&clk_32k_out>; ++ ++ clk_32k { ++ clk_32k_out: clk-32k-out { ++ rockchip,pins = <1 RK_PD4 RK_FUNC_1 &pcfg_pull_none>; ++ }; ++ }; ++ ++ ir { ++ ir_int: ir-int { ++ rockchip,pins = <2 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ pmic { ++ pmic_int_l: pmic-int-l { ++ rockchip,pins = <2 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ }; ++ ++ sdio-pwrseq { ++ wifi_enable_h: wifi-enable-h { ++ rockchip,pins = <1 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none_4ma>, ++ <1 RK_PC3 RK_FUNC_GPIO &pcfg_pull_none_4ma>; ++ }; ++ }; ++ ++ usb2 { ++ usb20_host_drv: usb20-host-drv { ++ rockchip,pins = <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ usb3 { ++ usb30_host_drv: usb30-host-drv { ++ rockchip,pins = <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++}; ++ ++&sdio { ++ bus-width = <4>; ++ cap-sd-highspeed; ++ cap-sdio-irq; ++ keep-power-in-suspend; ++ mmc-pwrseq = <&sdio_pwrseq>; ++ non-removable; ++ num-slots = <1>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdmmc1_bus4 &sdmmc1_cmd &sdmmc1_clk>; ++ sd-uhs-sdr104; ++ status = "disabled"; ++}; ++ ++&sdmmc { ++ bus-width = <4>; ++ cap-mmc-highspeed; ++ cap-sd-highspeed; ++ disable-wp; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdmmc0_clk &sdmmc0_cmd &sdmmc0_dectn &sdmmc0_bus4>; ++ vmmc-supply = <&vcc_sd>; ++ status = "okay"; ++}; ++ ++&spdif { ++ pinctrl-0 = <&spdifm0_tx>; ++ status = "okay"; ++}; ++ ++&spdif_out { ++ status = "okay"; ++}; ++ ++&spdif_sound { ++ status = "okay"; ++}; ++ ++&tsadc { ++ rockchip,hw-tshut-mode = <0>; ++ rockchip,hw-tshut-polarity = <0>; ++ status = "okay"; ++}; ++ ++&uart2 { ++ status = "okay"; ++}; ++ ++&u2phy { ++ status = "okay"; ++}; ++ ++&u2phy_host { ++ status = "okay"; ++}; ++ ++&u2phy_otg { ++ status = "okay"; ++}; ++ ++&usb20_otg { ++ dr_mode = "host"; ++ status = "okay"; ++}; ++ ++&usb_host0_ehci { ++ status = "okay"; ++}; ++ ++&usb_host0_ohci { ++ status = "okay"; ++}; ++ ++&usbdrd3 { ++ status = "okay"; ++}; ++ ++&usbdrd_dwc3 { ++ dr_mode = "host"; ++ status = "okay"; ++}; ++ ++&vop { ++ status = "okay"; ++}; ++ ++&vop_mmu { ++ status = "okay"; ++}; +-- +2.17.1 + diff --git a/patch/kernel/rk322x-current/01-linux-0006-experimental.patch b/patch/kernel/rk322x-current/01-linux-0006-experimental.patch new file mode 100644 index 0000000000..892c5b859a --- /dev/null +++ b/patch/kernel/rk322x-current/01-linux-0006-experimental.patch @@ -0,0 +1,1825 @@ +diff --git a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c +index 9ca20c947283..b0ac1d3ee390 100644 +--- a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c ++++ b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c +@@ -790,8 +790,8 @@ static int inno_hdmi_phy_rk3328_clk_set_rate(struct clk_hw *hw, + RK3328_PRE_PLL_POWER_DOWN); + + /* Configure pre-pll */ +- inno_update_bits(inno, 0xa0, RK3228_PCLK_VCO_DIV_5_MASK, +- RK3228_PCLK_VCO_DIV_5(cfg->vco_div_5_en)); ++ inno_update_bits(inno, 0xa0, RK3328_PCLK_VCO_DIV_5_MASK, ++ RK3328_PCLK_VCO_DIV_5(cfg->vco_div_5_en)); + inno_write(inno, 0xa1, RK3328_PRE_PLL_PRE_DIV(cfg->prediv)); + + val = RK3328_SPREAD_SPECTRUM_MOD_DISABLE; +-- +2.17.1 + + +From 0ae81f8167f59ad2c781dc51f2b2fa3e0c9f976b Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Fri, 20 Dec 2019 08:12:42 +0000 +Subject: [PATCH] phy/rockchip: inno-hdmi: round fractal pixclock in rk3328 + recalc_rate + +inno_hdmi_phy_rk3328_clk_recalc_rate() is returning a rate not found +in the pre pll config table when the fractal divider is used. +This can prevent proper power_on because a tmdsclock for the new rate +is not found in the pre pll config table. + +Fix this by saving and returning a rounded pixel rate that exist +in the pre pll config table. + +Fixes: 53706a116863 ("phy: add Rockchip Innosilicon hdmi phy") +Signed-off-by: Zheng Yang +Signed-off-by: Jonas Karlman +--- + drivers/phy/rockchip/phy-rockchip-inno-hdmi.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c +index b0ac1d3ee390..093d2334e8cd 100644 +--- a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c ++++ b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c +@@ -745,10 +745,12 @@ unsigned long inno_hdmi_phy_rk3328_clk_recalc_rate(struct clk_hw *hw, + do_div(vco, (nd * (no_a == 1 ? no_b : no_a) * no_d * 2)); + } + +- inno->pixclock = vco; +- dev_dbg(inno->dev, "%s rate %lu\n", __func__, inno->pixclock); ++ inno->pixclock = DIV_ROUND_CLOSEST((unsigned long)vco, 1000) * 1000; + +- return vco; ++ dev_dbg(inno->dev, "%s rate %lu vco %llu\n", ++ __func__, inno->pixclock, vco); ++ ++ return inno->pixclock; + } + + static long inno_hdmi_phy_rk3328_clk_round_rate(struct clk_hw *hw, +-- +2.17.1 + + +From fcb6a75bac484bec5443241965757b2d7cf99182 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Fri, 20 Dec 2019 08:12:42 +0000 +Subject: [PATCH] phy/rockchip: inno-hdmi: remove unused no_c from rk3328 + recalc_rate + +no_c is not used in any calculation, lets remove it. + +Signed-off-by: Jonas Karlman +--- + drivers/phy/rockchip/phy-rockchip-inno-hdmi.c | 5 +---- + 1 file changed, 1 insertion(+), 4 deletions(-) + +diff --git a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c +index 093d2334e8cd..06db69c8373e 100644 +--- a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c ++++ b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c +@@ -714,7 +714,7 @@ unsigned long inno_hdmi_phy_rk3328_clk_recalc_rate(struct clk_hw *hw, + { + struct inno_hdmi_phy *inno = to_inno_hdmi_phy(hw); + unsigned long frac; +- u8 nd, no_a, no_b, no_c, no_d; ++ u8 nd, no_a, no_b, no_d; + u64 vco; + u16 nf; + +@@ -737,9 +737,6 @@ unsigned long inno_hdmi_phy_rk3328_clk_recalc_rate(struct clk_hw *hw, + no_b = inno_read(inno, 0xa5) & RK3328_PRE_PLL_PCLK_DIV_B_MASK; + no_b >>= RK3328_PRE_PLL_PCLK_DIV_B_SHIFT; + no_b += 2; +- no_c = inno_read(inno, 0xa6) & RK3328_PRE_PLL_PCLK_DIV_C_MASK; +- no_c >>= RK3328_PRE_PLL_PCLK_DIV_C_SHIFT; +- no_c = 1 << no_c; + no_d = inno_read(inno, 0xa6) & RK3328_PRE_PLL_PCLK_DIV_D_MASK; + + do_div(vco, (nd * (no_a == 1 ? no_b : no_a) * no_d * 2)); +-- +2.17.1 + + +From 8da78b0cf0c522be59656ed24a0018bd2fbea5a8 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Fri, 20 Dec 2019 08:12:42 +0000 +Subject: [PATCH] phy/rockchip: inno-hdmi: do not power on rk3328 post pll on + reg write + +inno_write is used to configure 0xaa reg, that also hold the +POST_PLL_POWER_DOWN bit. +When POST_PLL_REFCLK_SEL_TMDS is configured the power down bit is not +taken into consideration. + +Fix this by keeping the power down bit until configuration is complete. +Also reorder the reg write order for consistency. + +Fixes: 53706a116863 ("phy: add Rockchip Innosilicon hdmi phy") +Signed-off-by: Jonas Karlman +--- + drivers/phy/rockchip/phy-rockchip-inno-hdmi.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c +index 06db69c8373e..3a59a6da0440 100644 +--- a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c ++++ b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c +@@ -1020,9 +1020,10 @@ inno_hdmi_phy_rk3328_power_on(struct inno_hdmi_phy *inno, + + inno_write(inno, 0xac, RK3328_POST_PLL_FB_DIV_7_0(cfg->fbdiv)); + if (cfg->postdiv == 1) { +- inno_write(inno, 0xaa, RK3328_POST_PLL_REFCLK_SEL_TMDS); + inno_write(inno, 0xab, RK3328_POST_PLL_FB_DIV_8(cfg->fbdiv) | + RK3328_POST_PLL_PRE_DIV(cfg->prediv)); ++ inno_write(inno, 0xaa, RK3328_POST_PLL_REFCLK_SEL_TMDS | ++ RK3328_POST_PLL_POWER_DOWN); + } else { + v = (cfg->postdiv / 2) - 1; + v &= RK3328_POST_PLL_POST_DIV_MASK; +@@ -1030,7 +1031,8 @@ inno_hdmi_phy_rk3328_power_on(struct inno_hdmi_phy *inno, + inno_write(inno, 0xab, RK3328_POST_PLL_FB_DIV_8(cfg->fbdiv) | + RK3328_POST_PLL_PRE_DIV(cfg->prediv)); + inno_write(inno, 0xaa, RK3328_POST_PLL_POST_DIV_ENABLE | +- RK3328_POST_PLL_REFCLK_SEL_TMDS); ++ RK3328_POST_PLL_REFCLK_SEL_TMDS | ++ RK3328_POST_PLL_POWER_DOWN); + } + + for (v = 0; v < 14; v++) +-- +2.17.1 + + +From 790af1279068ad1cc4ef471d90050570a850f426 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Fri, 20 Dec 2019 08:12:42 +0000 +Subject: [PATCH] phy/rockchip: inno-hdmi: force set_rate on power_on + +Regular 8-bit and Deep Color video formats mainly differ in TMDS rate and +not in pixel clock rate. +When the hdmiphy clock is configured with the same pixel clock rate using +clk_set_rate() the clock framework do not signal the hdmi phy driver +to set_rate when switching between 8-bit and Deep Color. +This result in pre/post pll not being re-configured when switching between +regular 8-bit and Deep Color video formats. + +Fix this by calling set_rate in power_on to force pre pll re-configuration. + +Signed-off-by: Jonas Karlman +--- + drivers/phy/rockchip/phy-rockchip-inno-hdmi.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c +index 3a59a6da0440..3719309ad0d0 100644 +--- a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c ++++ b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c +@@ -245,6 +245,7 @@ struct inno_hdmi_phy { + struct clk_hw hw; + struct clk *phyclk; + unsigned long pixclock; ++ unsigned long tmdsclock; + }; + + struct pre_pll_config { +@@ -485,6 +486,8 @@ static int inno_hdmi_phy_power_on(struct phy *phy) + + dev_dbg(inno->dev, "Inno HDMI PHY Power On\n"); + ++ inno->plat_data->clk_ops->set_rate(&inno->hw, inno->pixclock, 24000000); ++ + ret = clk_prepare_enable(inno->phyclk); + if (ret) + return ret; +@@ -509,6 +512,8 @@ static int inno_hdmi_phy_power_off(struct phy *phy) + + clk_disable_unprepare(inno->phyclk); + ++ inno->tmdsclock = 0; ++ + dev_dbg(inno->dev, "Inno HDMI PHY Power Off\n"); + + return 0; +@@ -628,6 +633,9 @@ static int inno_hdmi_phy_rk3228_clk_set_rate(struct clk_hw *hw, + dev_dbg(inno->dev, "%s rate %lu tmdsclk %lu\n", + __func__, rate, tmdsclock); + ++ if (inno->pixclock == rate && inno->tmdsclock == tmdsclock) ++ return 0; ++ + cfg = inno_hdmi_phy_get_pre_pll_cfg(inno, rate); + if (IS_ERR(cfg)) + return PTR_ERR(cfg); +@@ -670,6 +678,7 @@ static int inno_hdmi_phy_rk3228_clk_set_rate(struct clk_hw *hw, + } + + inno->pixclock = rate; ++ inno->tmdsclock = tmdsclock; + + return 0; + } +@@ -781,6 +790,9 @@ static int inno_hdmi_phy_rk3328_clk_set_rate(struct clk_hw *hw, + dev_dbg(inno->dev, "%s rate %lu tmdsclk %lu\n", + __func__, rate, tmdsclock); + ++ if (inno->pixclock == rate && inno->tmdsclock == tmdsclock) ++ return 0; ++ + cfg = inno_hdmi_phy_get_pre_pll_cfg(inno, rate); + if (IS_ERR(cfg)) + return PTR_ERR(cfg); +@@ -820,6 +832,7 @@ static int inno_hdmi_phy_rk3328_clk_set_rate(struct clk_hw *hw, + } + + inno->pixclock = rate; ++ inno->tmdsclock = tmdsclock; + + return 0; + } +-- +2.17.1 + + +From 852eb17bca3ae36762eb2975bb9a5642cf0865d8 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sat, 21 Dec 2019 23:52:16 +0000 +Subject: [PATCH] drm/rockchip: vop: limit resolution width to 3840 + +Using a destination width that is more then 3840 pixels +is not supported in scl_vop_cal_scl_fac(). + +Work around this limitation by filtering all modes with +a width above 3840. + +Signed-off-by: Jonas Karlman +--- + drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +index d04b3492bdac..f181897cbfad 100644 +--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +@@ -1036,6 +1036,15 @@ static void vop_crtc_disable_vblank(struct drm_crtc *crtc) + spin_unlock_irqrestore(&vop->irq_lock, flags); + } + ++enum drm_mode_status vop_crtc_mode_valid(struct drm_crtc *crtc, ++ const struct drm_display_mode *mode) ++{ ++ if (mode->hdisplay > 3840) ++ return MODE_BAD_HVALUE; ++ ++ return MODE_OK; ++} ++ + static bool vop_crtc_mode_fixup(struct drm_crtc *crtc, + const struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) +@@ -1377,6 +1386,7 @@ static void vop_crtc_atomic_flush(struct drm_crtc *crtc, + } + + static const struct drm_crtc_helper_funcs vop_crtc_helper_funcs = { ++ .mode_valid = vop_crtc_mode_valid, + .mode_fixup = vop_crtc_mode_fixup, + .atomic_check = vop_crtc_atomic_check, + .atomic_begin = vop_crtc_atomic_begin, +-- +2.17.1 + + +From 1f18ed83f51df960be0688db39b086b9a58ef7d1 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 22 Dec 2019 12:43:36 +0000 +Subject: [PATCH] drm/rockchip: dw-hdmi: allow high tmds bit rates + +Prepare support for High TMDS Bit Rates used by HDMI2.0 display modes. + +Signed-off-by: Jonas Karlman +--- + drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +index 7f56d8c3491d..fae38b323a0c 100644 +--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c ++++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +@@ -318,6 +318,8 @@ static int dw_hdmi_rockchip_genphy_init(struct dw_hdmi *dw_hdmi, void *data, + { + struct rockchip_hdmi *hdmi = (struct rockchip_hdmi *)data; + ++ dw_hdmi_set_high_tmds_clock_ratio(dw_hdmi); ++ + return phy_power_on(hdmi->phy); + } + +-- +2.17.1 + + +From d8ee714e54380f7b09dd088944f5c030aa1ee320 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 22 Dec 2019 12:35:16 +0000 +Subject: [PATCH] drm/rockchip: dw-hdmi: require valid vpll clock rate on + rk3228/rk3328 + +RK3228/RK3328 can only support clock rates defined in the pre pll table. +Lets validate the mode clock rate against the pre pll config and filter +out any mode with a clock rate returning error from clk_round_rate(). + +Signed-off-by: Jonas Karlman +--- + drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + +diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +index fae38b323a0c..45fcdce3f27f 100644 +--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c ++++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +@@ -245,6 +245,22 @@ static void dw_hdmi_rockchip_encoder_disable(struct drm_encoder *encoder) + { + } + ++static enum drm_mode_status ++dw_hdmi_rockchip_encoder_mode_valid(struct drm_encoder *encoder, ++ const struct drm_display_mode *mode) ++{ ++ struct rockchip_hdmi *hdmi = to_rockchip_hdmi(encoder); ++ long rate; ++ ++ if (hdmi->vpll_clk) { ++ rate = clk_round_rate(hdmi->vpll_clk, mode->clock * 1000); ++ if (rate < 0) ++ return MODE_CLOCK_RANGE; ++ } ++ ++ return MODE_OK; ++} ++ + static bool + dw_hdmi_rockchip_encoder_mode_fixup(struct drm_encoder *encoder, + const struct drm_display_mode *mode, +@@ -306,6 +322,7 @@ dw_hdmi_rockchip_encoder_atomic_check(struct drm_encoder *encoder, + } + + static const struct drm_encoder_helper_funcs dw_hdmi_rockchip_encoder_helper_funcs = { ++ .mode_valid = dw_hdmi_rockchip_encoder_mode_valid, + .mode_fixup = dw_hdmi_rockchip_encoder_mode_fixup, + .mode_set = dw_hdmi_rockchip_encoder_mode_set, + .enable = dw_hdmi_rockchip_encoder_enable, +-- +2.17.1 + + +From f305ae2094370127c797a4af3772bd9ff4e8dfc2 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 22 Dec 2019 23:42:45 +0000 +Subject: [PATCH] clk: rockchip: set parent rate for DCLK_VOP clock on rk3228 + +Signed-off-by: Jonas Karlman +--- + drivers/clk/rockchip/clk-rk3228.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/clk/rockchip/clk-rk3228.c b/drivers/clk/rockchip/clk-rk3228.c +index d17cfb7a3ff4..25f79af22cb8 100644 +--- a/drivers/clk/rockchip/clk-rk3228.c ++++ b/drivers/clk/rockchip/clk-rk3228.c +@@ -410,7 +410,7 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { + RK2928_CLKSEL_CON(29), 0, 3, DFLAGS), + DIV(0, "sclk_vop_pre", "sclk_vop_src", 0, + RK2928_CLKSEL_CON(27), 8, 8, DFLAGS), +- MUX(DCLK_VOP, "dclk_vop", mux_dclk_vop_p, 0, ++ MUX(DCLK_VOP, "dclk_vop", mux_dclk_vop_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT, + RK2928_CLKSEL_CON(27), 1, 1, MFLAGS), + + FACTOR(0, "xin12m", "xin24m", 0, 1, 2), +-- +2.17.1 + + +From 69f1bbcbc9c02c34f4fda49191ccae1f9dac410e Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 15 Dec 2019 10:05:46 +0000 +Subject: [PATCH] arm64: dts: rockchip: increase vop clock rate on rk3328 + +The VOP on RK3328 needs to run faster in order to procude a proper +3840x2160 signal. + +Signed-off-by: Jonas Karlman +--- + arch/arm64/boot/dts/rockchip/rk3328.dtsi | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi +index bc9186f66d9c..d4cfb1066c5a 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi +@@ -834,8 +834,8 @@ + <0>, <24000000>, + <24000000>, <24000000>, + <15000000>, <15000000>, +- <100000000>, <100000000>, +- <100000000>, <100000000>, ++ <300000000>, <100000000>, ++ <400000000>, <100000000>, + <50000000>, <100000000>, + <100000000>, <100000000>, + <50000000>, <50000000>, +-- +2.17.1 + + +From 2aeb955b7a259182df7c2244531abd4bf233f60b Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 22 Dec 2019 23:43:40 +0000 +Subject: [PATCH] arm64: dts: rockchip: add vpll clock to hdmi node on rk3328 + +Add the hdmiphy clock as the vpll in hdmi node. + +Signed-off-by: Jonas Karlman +--- + arch/arm64/boot/dts/rockchip/rk3328.dtsi | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi +index d4cfb1066c5a..991d2a830887 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi +@@ -750,9 +750,11 @@ + ; + clocks = <&cru PCLK_HDMI>, + <&cru SCLK_HDMI_SFC>, ++ <&hdmiphy>, + <&cru SCLK_RTC32K>; + clock-names = "iahb", + "isfr", ++ "vpll", + "cec"; + phys = <&hdmiphy>; + phy-names = "hdmi"; +-- +2.17.1 + + +From a972a8f4fbc0db4c71fcf2d7eb1c1dcc31a8d089 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 22 Dec 2019 23:43:58 +0000 +Subject: [PATCH] ARM: dts: rockchip: add vpll clock to hdmi node on rk3228 + +Add the hdmiphy clock as the vpll in hdmi node. + +Signed-off-by: Jonas Karlman +--- + arch/arm/boot/dts/rk322x.dtsi | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/arch/arm/boot/dts/rk322x.dtsi b/arch/arm/boot/dts/rk322x.dtsi +index 4e90efdc9630..1e31f6898797 100644 +--- a/arch/arm/boot/dts/rk322x.dtsi ++++ b/arch/arm/boot/dts/rk322x.dtsi +@@ -639,8 +639,8 @@ + interrupts = ; + assigned-clocks = <&cru SCLK_HDMI_PHY>; + assigned-clock-parents = <&hdmi_phy>; +- clocks = <&cru SCLK_HDMI_HDCP>, <&cru PCLK_HDMI_CTRL>, <&cru SCLK_HDMI_CEC>; +- clock-names = "isfr", "iahb", "cec"; ++ clocks = <&cru SCLK_HDMI_HDCP>, <&cru PCLK_HDMI_CTRL>, <&hdmi_phy>, <&cru SCLK_HDMI_CEC>; ++ clock-names = "isfr", "iahb", "vpll", "cec"; + pinctrl-names = "default"; + pinctrl-0 = <&hdmii2c_xfer &hdmi_hpd &hdmi_cec>; + resets = <&cru SRST_HDMI_P>; +-- +2.17.1 + + +From ad13781b15e2a4657e52147461565b99e16dca65 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 22 Dec 2019 10:42:02 +0000 +Subject: [PATCH] drm/rockchip: dw-hdmi: limit tmds to 340mhz on rk3228/rk3328 + +RK3228/RK3328 does not provide a stable hdmi signal at TMDS rates +above 371.25MHz (340MHz pixel clock). + +Limit the pixel clock rate to 340MHz to provide a stable signal. +Also limit the pixel clock to the display reported max tmds clock. + +Signed-off-by: Jonas Karlman +--- + drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 22 +++++++++++++++++++-- + 1 file changed, 20 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +index 45fcdce3f27f..66c14df4a680 100644 +--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c ++++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +@@ -237,6 +237,24 @@ dw_hdmi_rockchip_mode_valid(struct drm_connector *connector, + return (valid) ? MODE_OK : MODE_BAD; + } + ++static enum drm_mode_status ++dw_hdmi_rk3228_mode_valid(struct drm_connector *connector, ++ const struct drm_display_mode *mode) ++{ ++ struct drm_display_info *info = &connector->display_info; ++ int max_tmds_clock = max(info->max_tmds_clock, 165000); ++ int clock = mode->clock; ++ ++ if (connector->ycbcr_420_allowed && drm_mode_is_420(info, mode) && ++ (info->color_formats & DRM_COLOR_FORMAT_YCRCB420)) ++ clock /= 2; ++ ++ if (clock > max_tmds_clock || clock > 340000) ++ return MODE_CLOCK_HIGH; ++ ++ return MODE_OK; ++} ++ + static const struct drm_encoder_funcs dw_hdmi_rockchip_encoder_funcs = { + .destroy = drm_encoder_cleanup, + }; +@@ -424,7 +442,7 @@ static struct rockchip_hdmi_chip_data rk3228_chip_data = { + }; + + static const struct dw_hdmi_plat_data rk3228_hdmi_drv_data = { +- .mode_valid = dw_hdmi_rockchip_mode_valid, ++ .mode_valid = dw_hdmi_rk3228_mode_valid, + .mpll_cfg = rockchip_mpll_cfg, + .cur_ctr = rockchip_cur_ctr, + .phy_config = rockchip_phy_config, +@@ -461,7 +479,7 @@ static struct rockchip_hdmi_chip_data rk3328_chip_data = { + }; + + static const struct dw_hdmi_plat_data rk3328_hdmi_drv_data = { +- .mode_valid = dw_hdmi_rockchip_mode_valid, ++ .mode_valid = dw_hdmi_rk3228_mode_valid, + .mpll_cfg = rockchip_mpll_cfg, + .cur_ctr = rockchip_cur_ctr, + .phy_config = rockchip_phy_config, +-- +2.17.1 + + +From 8e950f0d07a1cea3ad58bd654c91a747d2902c6c Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 22 Dec 2019 10:42:27 +0000 +Subject: [PATCH] drm/rockchip: dw-hdmi: remove unused plat_data on + rk3228/rk3328 + +mpll_cfg/cur_ctr/phy_config is not used when phy_force_vendor is true, +lets remove them. + +Signed-off-by: Jonas Karlman +--- + drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 6 ------ + 1 file changed, 6 deletions(-) + +diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +index 66c14df4a680..a813299e97a2 100644 +--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c ++++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +@@ -443,9 +443,6 @@ static struct rockchip_hdmi_chip_data rk3228_chip_data = { + + static const struct dw_hdmi_plat_data rk3228_hdmi_drv_data = { + .mode_valid = dw_hdmi_rk3228_mode_valid, +- .mpll_cfg = rockchip_mpll_cfg, +- .cur_ctr = rockchip_cur_ctr, +- .phy_config = rockchip_phy_config, + .phy_data = &rk3228_chip_data, + .phy_ops = &rk3228_hdmi_phy_ops, + .phy_name = "inno_dw_hdmi_phy2", +@@ -480,9 +477,6 @@ static struct rockchip_hdmi_chip_data rk3328_chip_data = { + + static const struct dw_hdmi_plat_data rk3328_hdmi_drv_data = { + .mode_valid = dw_hdmi_rk3228_mode_valid, +- .mpll_cfg = rockchip_mpll_cfg, +- .cur_ctr = rockchip_cur_ctr, +- .phy_config = rockchip_phy_config, + .phy_data = &rk3328_chip_data, + .phy_ops = &rk3328_hdmi_phy_ops, + .phy_name = "inno_dw_hdmi_phy2", +-- +2.17.1 + + +From 34326d29065869cc262b2f1644310ec9417dac29 Mon Sep 17 00:00:00 2001 +From: Algea Cao +Date: Fri, 18 May 2018 14:32:08 +0800 +Subject: [PATCH] phy/rockchip: inno-hdmi: Support more pre-pll configuration + +Adding the following freq cfg in 8-bit and 10-bit color depth: + +{ + 40000000, 65000000, 71000000, 83500000, 85750000, + 88750000, 108000000, 119000000, 162000000 +} + +New freq has been validated by quantumdata 980. + +For some freq which can't be got by only using integer freq div, +frac freq div is needed, Such as 88.75Mhz 10-bit. But The actual +freq is different from the target freq, We must try to narrow +the gap between them. RK322X only support integer freq div. + +The VCO of pre-PLL must be more than 2Ghz, otherwise PLL may be +unlocked. + +Signed-off-by: Algea Cao +Signed-off-by: Jonas Karlman +--- + drivers/phy/rockchip/phy-rockchip-inno-hdmi.c | 74 ++++++++++++------- + 1 file changed, 49 insertions(+), 25 deletions(-) + +diff --git a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c +index 3719309ad0d0..bb8bdf5e3301 100644 +--- a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c ++++ b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c +@@ -291,32 +291,56 @@ struct inno_hdmi_phy_drv_data { + const struct phy_config *phy_cfg_table; + }; + ++/* ++ * If only using integer freq div can't get frequency we want, frac ++ * freq div is needed. For example, pclk 88.75 Mhz and tmdsclk ++ * 110.9375 Mhz must use frac div 0xF00000. The actual frequency is different ++ * from the target frequency. Such as the tmds clock 110.9375 Mhz, ++ * the actual tmds clock we get is 110.93719 Mhz. It is important ++ * to note that RK322X platforms do not support frac div. ++ */ + static const struct pre_pll_config pre_pll_cfg_table[] = { +- { 27000000, 27000000, 1, 90, 3, 2, 2, 10, 3, 3, 4, 0, 0}, +- { 27000000, 33750000, 1, 90, 1, 3, 3, 10, 3, 3, 4, 0, 0}, +- { 40000000, 40000000, 1, 80, 2, 2, 2, 12, 2, 2, 2, 0, 0}, +- { 59341000, 59341000, 1, 98, 3, 1, 2, 1, 3, 3, 4, 0, 0xE6AE6B}, +- { 59400000, 59400000, 1, 99, 3, 1, 1, 1, 3, 3, 4, 0, 0}, +- { 59341000, 74176250, 1, 98, 0, 3, 3, 1, 3, 3, 4, 0, 0xE6AE6B}, +- { 59400000, 74250000, 1, 99, 1, 2, 2, 1, 3, 3, 4, 0, 0}, +- { 74176000, 74176000, 1, 98, 1, 2, 2, 1, 2, 3, 4, 0, 0xE6AE6B}, +- { 74250000, 74250000, 1, 99, 1, 2, 2, 1, 2, 3, 4, 0, 0}, +- { 74176000, 92720000, 4, 494, 1, 2, 2, 1, 3, 3, 4, 0, 0x816817}, +- { 74250000, 92812500, 4, 495, 1, 2, 2, 1, 3, 3, 4, 0, 0}, +- {148352000, 148352000, 1, 98, 1, 1, 1, 1, 2, 2, 2, 0, 0xE6AE6B}, +- {148500000, 148500000, 1, 99, 1, 1, 1, 1, 2, 2, 2, 0, 0}, +- {148352000, 185440000, 4, 494, 0, 2, 2, 1, 3, 2, 2, 0, 0x816817}, +- {148500000, 185625000, 4, 495, 0, 2, 2, 1, 3, 2, 2, 0, 0}, +- {296703000, 296703000, 1, 98, 0, 1, 1, 1, 0, 2, 2, 0, 0xE6AE6B}, +- {297000000, 297000000, 1, 99, 0, 1, 1, 1, 0, 2, 2, 0, 0}, +- {296703000, 370878750, 4, 494, 1, 2, 0, 1, 3, 1, 1, 0, 0x816817}, +- {297000000, 371250000, 4, 495, 1, 2, 0, 1, 3, 1, 1, 0, 0}, +- {593407000, 296703500, 1, 98, 0, 1, 1, 1, 0, 2, 1, 0, 0xE6AE6B}, +- {594000000, 297000000, 1, 99, 0, 1, 1, 1, 0, 2, 1, 0, 0}, +- {593407000, 370879375, 4, 494, 1, 2, 0, 1, 3, 1, 1, 1, 0x816817}, +- {594000000, 371250000, 4, 495, 1, 2, 0, 1, 3, 1, 1, 1, 0}, +- {593407000, 593407000, 1, 98, 0, 2, 0, 1, 0, 1, 1, 0, 0xE6AE6B}, +- {594000000, 594000000, 1, 99, 0, 2, 0, 1, 0, 1, 1, 0, 0}, ++ { 27000000, 27000000, 1, 90, 3, 2, 2, 10, 3, 3, 4, 0, 0}, ++ { 27000000, 33750000, 1, 90, 1, 3, 3, 10, 3, 3, 4, 0, 0}, ++ { 40000000, 40000000, 1, 80, 2, 2, 2, 12, 2, 2, 2, 0, 0}, ++ { 40000000, 50000000, 1, 100, 2, 2, 2, 1, 0, 0, 15, 0, 0}, ++ { 59341000, 59341000, 1, 98, 3, 1, 2, 1, 3, 3, 4, 0, 0xE6AE6B}, ++ { 59400000, 59400000, 1, 99, 3, 1, 1, 1, 3, 3, 4, 0, 0}, ++ { 59341000, 74176250, 1, 98, 0, 3, 3, 1, 3, 3, 4, 0, 0xE6AE6B}, ++ { 59400000, 74250000, 1, 99, 1, 2, 2, 1, 3, 3, 4, 0, 0}, ++ { 65000000, 65000000, 1, 130, 2, 2, 2, 1, 0, 0, 12, 0, 0}, ++ { 65000000, 81250000, 3, 325, 0, 3, 3, 1, 0, 0, 10, 0, 0}, ++ { 71000000, 71000000, 3, 284, 0, 3, 3, 1, 0, 0, 8, 0, 0}, ++ { 71000000, 88750000, 3, 355, 0, 3, 3, 1, 0, 0, 10, 0, 0}, ++ { 74176000, 74176000, 1, 98, 1, 2, 2, 1, 2, 3, 4, 0, 0xE6AE6B}, ++ { 74250000, 74250000, 1, 99, 1, 2, 2, 1, 2, 3, 4, 0, 0}, ++ { 74176000, 92720000, 4, 494, 1, 2, 2, 1, 3, 3, 4, 0, 0x816817}, ++ { 74250000, 92812500, 4, 495, 1, 2, 2, 1, 3, 3, 4, 0, 0}, ++ { 83500000, 83500000, 2, 167, 2, 1, 1, 1, 0, 0, 6, 0, 0}, ++ { 83500000, 104375000, 1, 104, 2, 1, 1, 1, 1, 0, 5, 0, 0x600000}, ++ { 85750000, 85750000, 3, 343, 0, 3, 3, 1, 0, 0, 8, 0, 0}, ++ { 88750000, 88750000, 3, 355, 0, 3, 3, 1, 0, 0, 8, 0, 0}, ++ { 88750000, 110937500, 1, 110, 2, 1, 1, 1, 1, 0, 5, 0, 0xF00000}, ++ {108000000, 108000000, 1, 90, 3, 0, 0, 1, 0, 0, 5, 0, 0}, ++ {108000000, 135000000, 1, 90, 0, 2, 2, 1, 0, 0, 5, 0, 0}, ++ {119000000, 119000000, 1, 119, 2, 1, 1, 1, 0, 0, 6, 0, 0}, ++ {119000000, 148750000, 1, 99, 0, 2, 2, 1, 0, 0, 5, 0, 0x2AAAAA}, ++ {148352000, 148352000, 1, 98, 1, 1, 1, 1, 2, 2, 2, 0, 0xE6AE6B}, ++ {148500000, 148500000, 1, 99, 1, 1, 1, 1, 2, 2, 2, 0, 0}, ++ {148352000, 185440000, 4, 494, 0, 2, 2, 1, 3, 2, 2, 0, 0x816817}, ++ {148500000, 185625000, 4, 495, 0, 2, 2, 1, 3, 2, 2, 0, 0}, ++ {162000000, 162000000, 1, 108, 0, 2, 2, 1, 0, 0, 4, 0, 0}, ++ {162000000, 202500000, 1, 135, 0, 2, 2, 1, 0, 0, 5, 0, 0}, ++ {296703000, 296703000, 1, 98, 0, 1, 1, 1, 0, 2, 2, 0, 0xE6AE6B}, ++ {297000000, 297000000, 1, 99, 0, 1, 1, 1, 0, 2, 2, 0, 0}, ++ {296703000, 370878750, 4, 494, 1, 2, 0, 1, 3, 1, 1, 0, 0x816817}, ++ {297000000, 371250000, 4, 495, 1, 2, 0, 1, 3, 1, 1, 0, 0}, ++ {593407000, 296703500, 1, 98, 0, 1, 1, 1, 0, 2, 1, 0, 0xE6AE6B}, ++ {594000000, 297000000, 1, 99, 0, 1, 1, 1, 0, 2, 1, 0, 0}, ++ {593407000, 370879375, 4, 494, 1, 2, 0, 1, 3, 1, 1, 1, 0x816817}, ++ {594000000, 371250000, 4, 495, 1, 2, 0, 1, 3, 1, 1, 1, 0}, ++ {593407000, 593407000, 1, 98, 0, 2, 0, 1, 0, 1, 1, 0, 0xE6AE6B}, ++ {594000000, 594000000, 1, 99, 0, 2, 0, 1, 0, 1, 1, 0, 0}, + { /* sentinel */ } + }; + +-- +2.17.1 + + +From e63e0475c82b77a9e255b1dd354df20e02a73390 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Fri, 20 Dec 2019 08:12:43 +0000 +Subject: [PATCH] WIP: drm/bridge: dw-hdmi: limit mode and bus format to + max_tmds_clock + +--- + drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 121 ++++++++++++++-------- + 1 file changed, 78 insertions(+), 43 deletions(-) + +diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +index cc39b544ae6e..66e3fed23f4b 100644 +--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c ++++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +@@ -1854,6 +1854,21 @@ static void hdmi_config_drm_infoframe(struct dw_hdmi *hdmi) + HDMI_FC_PACKET_TX_EN_DRM_MASK, HDMI_FC_PACKET_TX_EN); + } + ++static unsigned int ++hdmi_get_tmdsclock(unsigned int bus_format, unsigned int pixelclock) ++{ ++ int color_depth = hdmi_bus_fmt_color_depth(bus_format); ++ unsigned int tmdsclock = pixelclock; ++ ++ if (!hdmi_bus_fmt_is_yuv422(bus_format) && color_depth > 8) ++ tmdsclock = (u64)pixelclock * color_depth / 8; ++ ++ if (hdmi_bus_fmt_is_yuv420(bus_format)) ++ tmdsclock /= 2; ++ ++ return tmdsclock; ++} ++ + static void hdmi_av_composer(struct dw_hdmi *hdmi, + const struct drm_display_mode *mode) + { +@@ -1863,28 +1878,12 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi, + int hblank, vblank, h_de_hs, v_de_vs, hsync_len, vsync_len; + unsigned int vdisplay, hdisplay; + +- vmode->mtmdsclock = vmode->mpixelclock = mode->clock * 1000; ++ vmode->mpixelclock = mode->clock * 1000; ++ vmode->mtmdsclock = ++ hdmi_get_tmdsclock(hdmi->hdmi_data.enc_out_bus_format, ++ vmode->mpixelclock); + + dev_dbg(hdmi->dev, "final pixclk = %d\n", vmode->mpixelclock); +- +- if (!hdmi_bus_fmt_is_yuv422(hdmi->hdmi_data.enc_out_bus_format)) { +- switch (hdmi_bus_fmt_color_depth( +- hdmi->hdmi_data.enc_out_bus_format)) { +- case 16: +- vmode->mtmdsclock = (u64)vmode->mpixelclock * 2; +- break; +- case 12: +- vmode->mtmdsclock = (u64)vmode->mpixelclock * 3 / 2; +- break; +- case 10: +- vmode->mtmdsclock = (u64)vmode->mpixelclock * 5 / 4; +- break; +- } +- } +- +- if (hdmi_bus_fmt_is_yuv420(hdmi->hdmi_data.enc_out_bus_format)) +- vmode->mtmdsclock /= 2; +- + dev_dbg(hdmi->dev, "final tmdsclk = %d\n", vmode->mtmdsclock); + + /* Set up HDMI_FC_INVIDCONF */ +@@ -2511,8 +2510,21 @@ static const struct drm_connector_helper_funcs dw_hdmi_connector_helper_funcs = + * - MEDIA_BUS_FMT_RGB888_1X24, + */ + +-/* Can return a maximum of 12 possible output formats for a mode/connector */ +-#define MAX_OUTPUT_SEL_FORMATS 12 ++static bool is_tmds_allowed(struct drm_display_info *info, ++ struct drm_display_mode *mode, ++ u32 bus_format) ++{ ++ unsigned long tmdsclock = hdmi_get_tmdsclock(bus_format, mode->clock); ++ int max_tmds_clock = max(info->max_tmds_clock, 165000); ++ ++ if (max_tmds_clock >= tmdsclock) ++ return true; ++ ++ return false; ++} ++ ++/* Can return a maximum of 16 possible output formats for a mode/connector */ ++#define MAX_OUTPUT_SEL_FORMATS 16 + + static u32 *dw_hdmi_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge, + struct drm_bridge_state *bridge_state, +@@ -2524,8 +2536,6 @@ static u32 *dw_hdmi_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge, + struct drm_display_info *info = &conn->display_info; + struct drm_display_mode *mode = &crtc_state->mode; + u8 max_bpc = conn_state->max_requested_bpc; +- bool is_hdmi2_sink = info->hdmi.scdc.supported || +- (info->color_formats & DRM_COLOR_FORMAT_YCRCB420); + u32 *output_fmts; + int i = 0; + +@@ -2540,29 +2550,33 @@ static u32 *dw_hdmi_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge, + * If the current mode enforces 4:2:0, force the output but format + * to 4:2:0 and do not add the YUV422/444/RGB formats + */ +- if (conn->ycbcr_420_allowed && +- (drm_mode_is_420_only(info, mode) || +- (is_hdmi2_sink && drm_mode_is_420_also(info, mode)))) { ++ if (conn->ycbcr_420_allowed && drm_mode_is_420(info, mode) && ++ (info->color_formats & DRM_COLOR_FORMAT_YCRCB420)) { + + /* Order bus formats from 16bit to 8bit if supported */ + if (max_bpc >= 16 && info->bpc == 16 && +- (info->hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_48)) ++ (info->hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_48) && ++ is_tmds_allowed(info, mode, MEDIA_BUS_FMT_UYYVYY16_0_5X48)) + output_fmts[i++] = MEDIA_BUS_FMT_UYYVYY16_0_5X48; + + if (max_bpc >= 12 && info->bpc >= 12 && +- (info->hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_36)) ++ (info->hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_36) && ++ is_tmds_allowed(info, mode, MEDIA_BUS_FMT_UYYVYY12_0_5X36)) + output_fmts[i++] = MEDIA_BUS_FMT_UYYVYY12_0_5X36; + + if (max_bpc >= 10 && info->bpc >= 10 && +- (info->hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_30)) ++ (info->hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_30) && ++ is_tmds_allowed(info, mode, MEDIA_BUS_FMT_UYYVYY10_0_5X30)) + output_fmts[i++] = MEDIA_BUS_FMT_UYYVYY10_0_5X30; + + /* Default 8bit fallback */ +- output_fmts[i++] = MEDIA_BUS_FMT_UYYVYY8_0_5X24; ++ if (is_tmds_allowed(info, mode, MEDIA_BUS_FMT_UYYVYY8_0_5X24)) ++ output_fmts[i++] = MEDIA_BUS_FMT_UYYVYY8_0_5X24; + + *num_output_fmts = i; + +- return output_fmts; ++ if (drm_mode_is_420_only(info, mode)) ++ return output_fmts; + } + + /* +@@ -2571,40 +2585,51 @@ static u32 *dw_hdmi_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge, + */ + + if (max_bpc >= 16 && info->bpc == 16) { +- if (info->color_formats & DRM_COLOR_FORMAT_YCRCB444) ++ if ((info->color_formats & DRM_COLOR_FORMAT_YCRCB444) && ++ is_tmds_allowed(info, mode, MEDIA_BUS_FMT_YUV16_1X48)) + output_fmts[i++] = MEDIA_BUS_FMT_YUV16_1X48; + +- output_fmts[i++] = MEDIA_BUS_FMT_RGB161616_1X48; ++ if (is_tmds_allowed(info, mode, MEDIA_BUS_FMT_RGB161616_1X48)) ++ output_fmts[i++] = MEDIA_BUS_FMT_RGB161616_1X48; + } + + if (max_bpc >= 12 && info->bpc >= 12) { +- if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422) ++ if ((info->color_formats & DRM_COLOR_FORMAT_YCRCB422) && ++ is_tmds_allowed(info, mode, MEDIA_BUS_FMT_UYVY12_1X24)) + output_fmts[i++] = MEDIA_BUS_FMT_UYVY12_1X24; + +- if (info->color_formats & DRM_COLOR_FORMAT_YCRCB444) ++ if ((info->color_formats & DRM_COLOR_FORMAT_YCRCB444) && ++ is_tmds_allowed(info, mode, MEDIA_BUS_FMT_YUV12_1X36)) + output_fmts[i++] = MEDIA_BUS_FMT_YUV12_1X36; + +- output_fmts[i++] = MEDIA_BUS_FMT_RGB121212_1X36; ++ if (is_tmds_allowed(info, mode, MEDIA_BUS_FMT_RGB121212_1X36)) ++ output_fmts[i++] = MEDIA_BUS_FMT_RGB121212_1X36; + } + + if (max_bpc >= 10 && info->bpc >= 10) { +- if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422) ++ if ((info->color_formats & DRM_COLOR_FORMAT_YCRCB422) && ++ is_tmds_allowed(info, mode, MEDIA_BUS_FMT_UYVY10_1X20)) + output_fmts[i++] = MEDIA_BUS_FMT_UYVY10_1X20; + +- if (info->color_formats & DRM_COLOR_FORMAT_YCRCB444) ++ if ((info->color_formats & DRM_COLOR_FORMAT_YCRCB444) && ++ is_tmds_allowed(info, mode, MEDIA_BUS_FMT_YUV10_1X30)) + output_fmts[i++] = MEDIA_BUS_FMT_YUV10_1X30; + +- output_fmts[i++] = MEDIA_BUS_FMT_RGB101010_1X30; ++ if (is_tmds_allowed(info, mode, MEDIA_BUS_FMT_RGB101010_1X30)) ++ output_fmts[i++] = MEDIA_BUS_FMT_RGB101010_1X30; + } + +- if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422) ++ if ((info->color_formats & DRM_COLOR_FORMAT_YCRCB422) && ++ is_tmds_allowed(info, mode, MEDIA_BUS_FMT_UYVY8_1X16)) + output_fmts[i++] = MEDIA_BUS_FMT_UYVY8_1X16; + +- if (info->color_formats & DRM_COLOR_FORMAT_YCRCB444) ++ if ((info->color_formats & DRM_COLOR_FORMAT_YCRCB444) && ++ is_tmds_allowed(info, mode, MEDIA_BUS_FMT_YUV8_1X24)) + output_fmts[i++] = MEDIA_BUS_FMT_YUV8_1X24; + + /* Default 8bit RGB fallback */ +- output_fmts[i++] = MEDIA_BUS_FMT_RGB888_1X24; ++ if (is_tmds_allowed(info, mode, MEDIA_BUS_FMT_RGB888_1X24)) ++ output_fmts[i++] = MEDIA_BUS_FMT_RGB888_1X24; + + *num_output_fmts = i; + +@@ -2811,12 +2836,22 @@ dw_hdmi_bridge_mode_valid(struct drm_bridge *bridge, + { + struct dw_hdmi *hdmi = bridge->driver_private; + struct drm_connector *connector = &hdmi->connector; ++ struct drm_display_info *info = &connector->display_info; + enum drm_mode_status mode_status = MODE_OK; ++ int max_tmds_clock = max(info->max_tmds_clock, 165000); ++ int clock = mode->clock; + + /* We don't support double-clocked modes */ + if (mode->flags & DRM_MODE_FLAG_DBLCLK) + return MODE_BAD; + ++ if (connector->ycbcr_420_allowed && drm_mode_is_420(info, mode) && ++ (info->color_formats & DRM_COLOR_FORMAT_YCRCB420)) ++ clock /= 2; ++ ++ if (clock > max_tmds_clock) ++ return MODE_CLOCK_HIGH; ++ + if (hdmi->plat_data->mode_valid) + mode_status = hdmi->plat_data->mode_valid(connector, mode); + +-- +2.17.1 + + +From 5c3bbae0afe43b4856b9c9e344bb7eea3702e4f0 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sat, 21 Dec 2019 06:23:52 +0000 +Subject: [PATCH] WIP: drm/bridge: dw-hdmi: do not enable csc for yuv2yuv + +--- + drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +index 66e3fed23f4b..df1789cd8712 100644 +--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c ++++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +@@ -966,6 +966,14 @@ static void hdmi_video_sample(struct dw_hdmi *hdmi) + + static int is_color_space_conversion(struct dw_hdmi *hdmi) + { ++ if (hdmi_bus_fmt_is_yuv444(hdmi->hdmi_data.enc_in_bus_format) && ++ hdmi_bus_fmt_is_yuv422(hdmi->hdmi_data.enc_out_bus_format)) ++ return 0; ++ ++ if (hdmi_bus_fmt_is_yuv422(hdmi->hdmi_data.enc_in_bus_format) && ++ hdmi_bus_fmt_is_yuv444(hdmi->hdmi_data.enc_out_bus_format)) ++ return 0; ++ + return hdmi->hdmi_data.enc_in_bus_format != hdmi->hdmi_data.enc_out_bus_format; + } + +@@ -2050,7 +2058,9 @@ static void dw_hdmi_enable_video_path(struct dw_hdmi *hdmi) + hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS); + + /* Enable csc path */ +- if (is_color_space_conversion(hdmi)) { ++ if (is_color_space_conversion(hdmi) || ++ is_color_space_decimation(hdmi) || ++ is_color_space_interpolation(hdmi)) { + hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_CSCCLK_DISABLE; + hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS); + } +-- +2.17.1 + + +From fd86f78d28a4b6c5fc7440e42916f3f86a7797a4 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Fri, 20 Dec 2019 08:12:42 +0000 +Subject: [PATCH] drm/rockchip: dw-hdmi: add bridge and switch to + drm_bridge_funcs + +Switch the dw-hdmi driver to drm_bridge_funcs by implementing +a new local bridge, connecting it to the dw-hdmi bridge. + +Signed-off-by: Jonas Karlman +--- + drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 65 ++++++++++----------- + 1 file changed, 31 insertions(+), 34 deletions(-) + +diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +index a813299e97a2..8bc42090d0a3 100644 +--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c ++++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +@@ -67,6 +67,7 @@ struct rockchip_hdmi { + struct device *dev; + struct regmap *regmap; + struct drm_encoder encoder; ++ struct drm_bridge bridge; + const struct rockchip_hdmi_chip_data *chip_data; + struct clk *vpll_clk; + struct clk *grf_clk; +@@ -259,15 +260,11 @@ static const struct drm_encoder_funcs dw_hdmi_rockchip_encoder_funcs = { + .destroy = drm_encoder_cleanup, + }; + +-static void dw_hdmi_rockchip_encoder_disable(struct drm_encoder *encoder) +-{ +-} +- + static enum drm_mode_status +-dw_hdmi_rockchip_encoder_mode_valid(struct drm_encoder *encoder, +- const struct drm_display_mode *mode) ++dw_hdmi_rockchip_bridge_mode_valid(struct drm_bridge *bridge, ++ const struct drm_display_mode *mode) + { +- struct rockchip_hdmi *hdmi = to_rockchip_hdmi(encoder); ++ struct rockchip_hdmi *hdmi = to_rockchip_hdmi(bridge); + long rate; + + if (hdmi->vpll_clk) { +@@ -279,26 +276,20 @@ dw_hdmi_rockchip_encoder_mode_valid(struct drm_encoder *encoder, + return MODE_OK; + } + +-static bool +-dw_hdmi_rockchip_encoder_mode_fixup(struct drm_encoder *encoder, +- const struct drm_display_mode *mode, +- struct drm_display_mode *adj_mode) +-{ +- return true; +-} +- +-static void dw_hdmi_rockchip_encoder_mode_set(struct drm_encoder *encoder, +- struct drm_display_mode *mode, +- struct drm_display_mode *adj_mode) ++static void ++dw_hdmi_rockchip_bridge_mode_set(struct drm_bridge *bridge, ++ const struct drm_display_mode *mode, ++ const struct drm_display_mode *adjusted_mode) + { +- struct rockchip_hdmi *hdmi = to_rockchip_hdmi(encoder); ++ struct rockchip_hdmi *hdmi = to_rockchip_hdmi(bridge); + +- clk_set_rate(hdmi->vpll_clk, adj_mode->clock * 1000); ++ clk_set_rate(hdmi->vpll_clk, adjusted_mode->clock * 1000); + } + +-static void dw_hdmi_rockchip_encoder_enable(struct drm_encoder *encoder) ++static void dw_hdmi_rockchip_bridge_enable(struct drm_bridge *bridge) + { +- struct rockchip_hdmi *hdmi = to_rockchip_hdmi(encoder); ++ struct rockchip_hdmi *hdmi = to_rockchip_hdmi(bridge); ++ struct drm_encoder *encoder = bridge->encoder; + u32 val; + int ret; + +@@ -327,9 +318,10 @@ static void dw_hdmi_rockchip_encoder_enable(struct drm_encoder *encoder) + } + + static int +-dw_hdmi_rockchip_encoder_atomic_check(struct drm_encoder *encoder, +- struct drm_crtc_state *crtc_state, +- struct drm_connector_state *conn_state) ++dw_hdmi_rockchip_bridge_atomic_check(struct drm_bridge *bridge, ++ struct drm_bridge_state *bridge_state, ++ struct drm_crtc_state *crtc_state, ++ struct drm_connector_state *conn_state) + { + struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state); + +@@ -339,13 +331,11 @@ dw_hdmi_rockchip_encoder_atomic_check(struct drm_encoder *encoder, + return 0; + } + +-static const struct drm_encoder_helper_funcs dw_hdmi_rockchip_encoder_helper_funcs = { +- .mode_valid = dw_hdmi_rockchip_encoder_mode_valid, +- .mode_fixup = dw_hdmi_rockchip_encoder_mode_fixup, +- .mode_set = dw_hdmi_rockchip_encoder_mode_set, +- .enable = dw_hdmi_rockchip_encoder_enable, +- .disable = dw_hdmi_rockchip_encoder_disable, +- .atomic_check = dw_hdmi_rockchip_encoder_atomic_check, ++static const struct drm_bridge_funcs dw_hdmi_rockchip_bridge_funcs = { ++ .mode_valid = dw_hdmi_rockchip_bridge_mode_valid, ++ .mode_set = dw_hdmi_rockchip_bridge_mode_set, ++ .enable = dw_hdmi_rockchip_bridge_enable, ++ .atomic_check = dw_hdmi_rockchip_bridge_atomic_check, + }; + + static int dw_hdmi_rockchip_genphy_init(struct dw_hdmi *dw_hdmi, void *data, +@@ -523,6 +513,7 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master, + struct dw_hdmi_plat_data *plat_data; + const struct of_device_id *match; + struct drm_device *drm = data; ++ struct drm_bridge *next_bridge; + struct drm_encoder *encoder; + struct rockchip_hdmi *hdmi; + int ret; +@@ -576,13 +567,15 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master, + return ret; + } + +- drm_encoder_helper_add(encoder, &dw_hdmi_rockchip_encoder_helper_funcs); + drm_encoder_init(drm, encoder, &dw_hdmi_rockchip_encoder_funcs, + DRM_MODE_ENCODER_TMDS, NULL); + ++ hdmi->bridge.funcs = &dw_hdmi_rockchip_bridge_funcs; ++ drm_bridge_attach(encoder, &hdmi->bridge, NULL); ++ + platform_set_drvdata(pdev, hdmi); + +- hdmi->hdmi = dw_hdmi_bind(pdev, encoder, plat_data); ++ hdmi->hdmi = dw_hdmi_probe(pdev, plat_data); + + /* + * If dw_hdmi_bind() fails we'll never call dw_hdmi_unbind(), +@@ -594,6 +587,10 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master, + clk_disable_unprepare(hdmi->vpll_clk); + } + ++ next_bridge = of_drm_find_bridge(pdev->dev.of_node); ++ if (next_bridge) ++ drm_bridge_attach(encoder, next_bridge, &hdmi->bridge); ++ + return ret; + } + +-- +2.17.1 + + +From 1e915225fe362b6ab98bec9bc71c62315347eccb Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Fri, 20 Dec 2019 08:12:42 +0000 +Subject: [PATCH] drm/rockchip: dw-hdmi: enable bridge bus format negotiation + +Enable bridge format negotiation by implementing +atomic_get_input_bus_fmts and support for 8-bit RGB 4:4:4. + +Signed-off-by: Jonas Karlman +--- + drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 35 +++++++++++++++++++++ + 1 file changed, 35 insertions(+) + +diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +index 8bc42090d0a3..83a22a061e52 100644 +--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c ++++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +@@ -317,6 +317,16 @@ static void dw_hdmi_rockchip_bridge_enable(struct drm_bridge *bridge) + ret ? "LIT" : "BIG"); + } + ++static bool is_rgb(u32 format) ++{ ++ switch (format) { ++ case MEDIA_BUS_FMT_RGB888_1X24: ++ return true; ++ default: ++ return false; ++ } ++} ++ + static int + dw_hdmi_rockchip_bridge_atomic_check(struct drm_bridge *bridge, + struct drm_bridge_state *bridge_state, +@@ -331,11 +341,36 @@ dw_hdmi_rockchip_bridge_atomic_check(struct drm_bridge *bridge, + return 0; + } + ++static u32 *dw_hdmi_rockchip_get_input_bus_fmts(struct drm_bridge *bridge, ++ struct drm_bridge_state *bridge_state, ++ struct drm_crtc_state *crtc_state, ++ struct drm_connector_state *conn_state, ++ u32 output_fmt, ++ unsigned int *num_input_fmts) ++{ ++ u32 *input_fmt; ++ ++ *num_input_fmts = 0; ++ ++ if (!is_rgb(output_fmt)) ++ return NULL; ++ ++ input_fmt = kzalloc(sizeof(*input_fmt), GFP_KERNEL); ++ if (!input_fmt) ++ return NULL; ++ ++ *num_input_fmts = 1; ++ *input_fmt = output_fmt; ++ ++ return input_fmt; ++} ++ + static const struct drm_bridge_funcs dw_hdmi_rockchip_bridge_funcs = { + .mode_valid = dw_hdmi_rockchip_bridge_mode_valid, + .mode_set = dw_hdmi_rockchip_bridge_mode_set, + .enable = dw_hdmi_rockchip_bridge_enable, + .atomic_check = dw_hdmi_rockchip_bridge_atomic_check, ++ .atomic_get_input_bus_fmts = dw_hdmi_rockchip_get_input_bus_fmts, + }; + + static int dw_hdmi_rockchip_genphy_init(struct dw_hdmi *dw_hdmi, void *data, +-- +2.17.1 + + +From b4cbb8eae8f3a5dbdbb844d59dfd7c979a88f66a Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Fri, 20 Dec 2019 08:12:42 +0000 +Subject: [PATCH] WIP: drm/rockchip: dw_hdmi: add 10-bit rgb bus format + +--- + drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 41 +++++++++++++++++++++ + drivers/gpu/drm/rockchip/rockchip_drm_drv.h | 2 + + drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 10 ++++- + 3 files changed, 52 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +index 83a22a061e52..3c8a95cd38dc 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 { + }; + + #define to_rockchip_hdmi(x) container_of(x, struct rockchip_hdmi, x) ++#define to_crtc_state(x) container_of(x, struct drm_crtc_state, x) + + static const struct dw_hdmi_mpll_config rockchip_mpll_cfg[] = { + { +@@ -282,6 +283,11 @@ dw_hdmi_rockchip_bridge_mode_set(struct drm_bridge *bridge, + const struct drm_display_mode *adjusted_mode) + { + struct rockchip_hdmi *hdmi = to_rockchip_hdmi(bridge); ++ struct drm_crtc_state *crtc_state = to_crtc_state(adjusted_mode); ++ struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state); ++ ++ if (hdmi->phy) ++ phy_set_bus_width(hdmi->phy, s->bus_width); + + clk_set_rate(hdmi->vpll_clk, adjusted_mode->clock * 1000); + } +@@ -320,6 +326,7 @@ static void dw_hdmi_rockchip_bridge_enable(struct drm_bridge *bridge) + static bool is_rgb(u32 format) + { + switch (format) { ++ case MEDIA_BUS_FMT_RGB101010_1X30: + case MEDIA_BUS_FMT_RGB888_1X24: + return true; + default: +@@ -327,6 +334,16 @@ static bool is_rgb(u32 format) + } + } + ++static bool is_10bit(u32 format) ++{ ++ switch (format) { ++ case MEDIA_BUS_FMT_RGB101010_1X30: ++ return true; ++ default: ++ return false; ++ } ++} ++ + static int + dw_hdmi_rockchip_bridge_atomic_check(struct drm_bridge *bridge, + struct drm_bridge_state *bridge_state, +@@ -334,9 +351,24 @@ dw_hdmi_rockchip_bridge_atomic_check(struct drm_bridge *bridge, + struct drm_connector_state *conn_state) + { + struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state); ++ struct drm_atomic_state *state = bridge_state->base.state; ++ struct drm_crtc_state *old_crtc_state; ++ struct rockchip_crtc_state *old_state; ++ u32 format = bridge_state->output_bus_cfg.format; + + s->output_mode = ROCKCHIP_OUT_MODE_AAAA; + s->output_type = DRM_MODE_CONNECTOR_HDMIA; ++ s->output_bpc = 10; ++ s->bus_format = format; ++ s->bus_width = is_10bit(format) ? 10 : 8; ++ ++ old_crtc_state = drm_atomic_get_old_crtc_state(state, conn_state->crtc); ++ if (old_crtc_state && !crtc_state->mode_changed) { ++ old_state = to_rockchip_crtc_state(old_crtc_state); ++ if (s->bus_format != old_state->bus_format || ++ s->bus_width != old_state->bus_width) ++ crtc_state->mode_changed = true; ++ } + + return 0; + } +@@ -348,10 +380,19 @@ static u32 *dw_hdmi_rockchip_get_input_bus_fmts(struct drm_bridge *bridge, + u32 output_fmt, + unsigned int *num_input_fmts) + { ++ struct rockchip_hdmi *hdmi = to_rockchip_hdmi(bridge); ++ struct drm_encoder *encoder = bridge->encoder; + u32 *input_fmt; ++ bool has_10bit = true; + + *num_input_fmts = 0; + ++ if (drm_of_encoder_active_endpoint_id(hdmi->dev->of_node, encoder)) ++ has_10bit = false; ++ ++ if (!has_10bit && is_10bit(output_fmt)) ++ return NULL; ++ + if (!is_rgb(output_fmt)) + return NULL; + +diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h +index c5b06048124e..af1b85d8f7ee 100644 +--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h +@@ -30,6 +30,8 @@ struct rockchip_crtc_state { + int output_mode; + int output_bpc; + int output_flags; ++ u32 bus_format; ++ int bus_width; + }; + #define to_rockchip_crtc_state(s) \ + container_of(s, struct rockchip_crtc_state, base) +diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +index f181897cbfad..e59213d3ea62 100644 +--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +@@ -1402,13 +1402,21 @@ static void vop_crtc_destroy(struct drm_crtc *crtc) + + static struct drm_crtc_state *vop_crtc_duplicate_state(struct drm_crtc *crtc) + { +- struct rockchip_crtc_state *rockchip_state; ++ struct rockchip_crtc_state *rockchip_state, *s; ++ ++ if (WARN_ON(!crtc->state)) ++ return NULL; + + rockchip_state = kzalloc(sizeof(*rockchip_state), GFP_KERNEL); + if (!rockchip_state) + return NULL; + + __drm_atomic_helper_crtc_duplicate_state(crtc, &rockchip_state->base); ++ ++ s = to_rockchip_crtc_state(crtc->state); ++ rockchip_state->bus_format = s->bus_format; ++ rockchip_state->bus_width = s->bus_width; ++ + return &rockchip_state->base; + } + +-- +2.17.1 + + +From 9fedc6efc787bddfad71c6145cf3cbee49ea257d Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Fri, 20 Dec 2019 08:12:43 +0000 +Subject: [PATCH] WIP: drm/rockchip: add yuv444 support + +--- + drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 29 ++++++++++++++++++++- + drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 29 +++++++++++++++++++++ + drivers/gpu/drm/rockchip/rockchip_drm_vop.h | 5 ++++ + drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 10 +++++++ + 4 files changed, 72 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +index 3c8a95cd38dc..9b3c2318ce0e 100644 +--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c ++++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +@@ -61,6 +61,7 @@ struct rockchip_hdmi_chip_data { + int lcdsel_grf_reg; + u32 lcdsel_big; + u32 lcdsel_lit; ++ bool ycbcr_444_allowed; + }; + + struct rockchip_hdmi { +@@ -334,10 +335,22 @@ static bool is_rgb(u32 format) + } + } + ++static bool is_yuv444(u32 format) ++{ ++ switch (format) { ++ case MEDIA_BUS_FMT_YUV10_1X30: ++ case MEDIA_BUS_FMT_YUV8_1X24: ++ return true; ++ default: ++ return false; ++ } ++} ++ + static bool is_10bit(u32 format) + { + switch (format) { + case MEDIA_BUS_FMT_RGB101010_1X30: ++ case MEDIA_BUS_FMT_YUV10_1X30: + return true; + default: + return false; +@@ -354,12 +367,22 @@ dw_hdmi_rockchip_bridge_atomic_check(struct drm_bridge *bridge, + struct drm_atomic_state *state = bridge_state->base.state; + struct drm_crtc_state *old_crtc_state; + struct rockchip_crtc_state *old_state; ++ struct drm_bridge *next_bridge; ++ struct drm_bridge_state *next_bridge_state; + u32 format = bridge_state->output_bus_cfg.format; + + s->output_mode = ROCKCHIP_OUT_MODE_AAAA; + s->output_type = DRM_MODE_CONNECTOR_HDMIA; + s->output_bpc = 10; + s->bus_format = format; ++ ++ next_bridge = drm_bridge_get_next_bridge(bridge); ++ if (next_bridge) { ++ next_bridge_state = drm_atomic_get_new_bridge_state(state, ++ next_bridge); ++ format = next_bridge_state->output_bus_cfg.format; ++ } ++ + s->bus_width = is_10bit(format) ? 10 : 8; + + old_crtc_state = drm_atomic_get_old_crtc_state(state, conn_state->crtc); +@@ -393,7 +416,10 @@ static u32 *dw_hdmi_rockchip_get_input_bus_fmts(struct drm_bridge *bridge, + if (!has_10bit && is_10bit(output_fmt)) + return NULL; + +- if (!is_rgb(output_fmt)) ++ if (is_yuv444(output_fmt)) { ++ if (!hdmi->chip_data->ycbcr_444_allowed) ++ return NULL; ++ } else if (!is_rgb(output_fmt)) + return NULL; + + input_fmt = kzalloc(sizeof(*input_fmt), GFP_KERNEL); +@@ -539,6 +565,7 @@ static const struct dw_hdmi_phy_ops rk3328_hdmi_phy_ops = { + + static struct rockchip_hdmi_chip_data rk3328_chip_data = { + .lcdsel_grf_reg = -1, ++ .ycbcr_444_allowed = true, + }; + + static const struct dw_hdmi_plat_data rk3328_hdmi_drv_data = { +diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +index e59213d3ea62..5bf833ea8ce2 100644 +--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +@@ -274,6 +274,17 @@ static enum vop_data_format vop_convert_format(uint32_t format) + } + } + ++static bool is_yuv_output(uint32_t bus_format) ++{ ++ switch (bus_format) { ++ case MEDIA_BUS_FMT_YUV8_1X24: ++ case MEDIA_BUS_FMT_YUV10_1X30: ++ return true; ++ default: ++ return false; ++ } ++} ++ + static uint16_t scl_vop_cal_scale(enum scale_mode mode, uint32_t src, + uint32_t dst, bool is_horizontal, + int vsu_mode, int *vskiplines) +@@ -1181,6 +1192,7 @@ static void vop_crtc_atomic_enable(struct drm_crtc *crtc, + u16 vact_end = vact_st + vdisplay; + uint32_t pin_pol, val; + int dither_bpc = s->output_bpc ? s->output_bpc : 10; ++ bool yuv_output = is_yuv_output(s->bus_format); + int ret; + + if (old_state && old_state->self_refresh_active) { +@@ -1254,6 +1266,8 @@ static void vop_crtc_atomic_enable(struct drm_crtc *crtc, + !(vop_data->feature & VOP_FEATURE_OUTPUT_RGB10)) + s->output_mode = ROCKCHIP_OUT_MODE_P888; + ++ VOP_REG_SET(vop, common, dsp_data_swap, yuv_output ? 2 : 0); ++ + if (s->output_mode == ROCKCHIP_OUT_MODE_AAAA && dither_bpc <= 8) + VOP_REG_SET(vop, common, pre_dither_down, 1); + else +@@ -1269,6 +1283,21 @@ static void vop_crtc_atomic_enable(struct drm_crtc *crtc, + + VOP_REG_SET(vop, common, out_mode, s->output_mode); + ++ VOP_REG_SET(vop, common, overlay_mode, yuv_output); ++ VOP_REG_SET(vop, common, dsp_out_yuv, yuv_output); ++ ++ /* ++ * Background color is 10bit depth if vop version >= 3.5 ++ */ ++ if (!yuv_output) ++ val = 0; ++ else if (VOP_MAJOR(vop_data->version) == 3 && ++ VOP_MINOR(vop_data->version) >= 5) ++ val = 0x20010200; ++ else ++ val = 0x801080; ++ VOP_REG_SET(vop, common, dsp_background, val); ++ + VOP_REG_SET(vop, modeset, htotal_pw, (htotal << 16) | hsync_len); + val = hact_st << 16; + val |= hact_end; +diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h +index 0b3d18c457b2..9393cf12b1db 100644 +--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h +@@ -77,6 +77,11 @@ struct vop_common { + struct vop_reg mmu_en; + struct vop_reg out_mode; + struct vop_reg standby; ++ ++ struct vop_reg overlay_mode; ++ struct vop_reg dsp_data_swap; ++ struct vop_reg dsp_out_yuv; ++ struct vop_reg dsp_background; + }; + + struct vop_misc { +diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c +index 7a9d979c8d5d..b99e902d949e 100644 +--- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c ++++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c +@@ -606,6 +606,11 @@ static const struct vop_common rk3288_common = { + .dsp_blank = VOP_REG(RK3288_DSP_CTRL0, 0x3, 18), + .out_mode = VOP_REG(RK3288_DSP_CTRL0, 0xf, 0), + .cfg_done = VOP_REG_SYNC(RK3288_REG_CFG_DONE, 0x1, 0), ++ ++ .overlay_mode = VOP_REG(RK3288_SYS_CTRL, 0x1, 16), ++ .dsp_data_swap = VOP_REG(RK3288_DSP_CTRL0, 0x1f, 12), ++ .dsp_out_yuv = VOP_REG(RK3288_POST_SCL_CTRL, 0x1, 2), ++ .dsp_background = VOP_REG(RK3288_DSP_BG, 0xffffffff, 0), + }; + + /* +@@ -914,6 +919,11 @@ static const struct vop_common rk3328_common = { + .dsp_blank = VOP_REG(RK3328_DSP_CTRL0, 0x3, 18), + .out_mode = VOP_REG(RK3328_DSP_CTRL0, 0xf, 0), + .cfg_done = VOP_REG_SYNC(RK3328_REG_CFG_DONE, 0x1, 0), ++ ++ .overlay_mode = VOP_REG(RK3328_SYS_CTRL, 0x1, 16), ++ .dsp_data_swap = VOP_REG(RK3328_DSP_CTRL0, 0x1f, 12), ++ .dsp_out_yuv = VOP_REG(RK3328_POST_SCL_CTRL, 0x1, 2), ++ .dsp_background = VOP_REG(RK3328_DSP_BG, 0xffffffff, 0), + }; + + static const struct vop_intr rk3328_vop_intr = { +-- +2.17.1 + + +From 111c35c19a742d7b76b6f548103f8b561c45a186 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Fri, 20 Dec 2019 08:12:43 +0000 +Subject: [PATCH] WIP: drm/rockchip: add yuv420 support + +--- + drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 22 +++++++++++++++++++++ + drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 18 ++++++++++++++++- + drivers/gpu/drm/rockchip/rockchip_drm_vop.h | 10 ++++++---- + drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 2 ++ + 4 files changed, 47 insertions(+), 5 deletions(-) + +diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +index 9b3c2318ce0e..eb405cb3d1f6 100644 +--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c ++++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +@@ -346,9 +346,21 @@ static bool is_yuv444(u32 format) + } + } + ++static bool is_yuv420(u32 format) ++{ ++ switch (format) { ++ case MEDIA_BUS_FMT_UYYVYY10_0_5X30: ++ case MEDIA_BUS_FMT_UYYVYY8_0_5X24: ++ return true; ++ default: ++ return false; ++ } ++} ++ + static bool is_10bit(u32 format) + { + switch (format) { ++ case MEDIA_BUS_FMT_UYYVYY10_0_5X30: + case MEDIA_BUS_FMT_RGB101010_1X30: + case MEDIA_BUS_FMT_YUV10_1X30: + return true; +@@ -385,6 +397,11 @@ dw_hdmi_rockchip_bridge_atomic_check(struct drm_bridge *bridge, + + s->bus_width = is_10bit(format) ? 10 : 8; + ++ if (is_yuv420(format)) { ++ s->output_mode = ROCKCHIP_OUT_MODE_YUV420; ++ s->bus_width /= 2; ++ } ++ + old_crtc_state = drm_atomic_get_old_crtc_state(state, conn_state->crtc); + if (old_crtc_state && !crtc_state->mode_changed) { + old_state = to_rockchip_crtc_state(old_crtc_state); +@@ -405,6 +422,7 @@ static u32 *dw_hdmi_rockchip_get_input_bus_fmts(struct drm_bridge *bridge, + { + struct rockchip_hdmi *hdmi = to_rockchip_hdmi(bridge); + struct drm_encoder *encoder = bridge->encoder; ++ struct drm_connector *connector = conn_state->connector; + u32 *input_fmt; + bool has_10bit = true; + +@@ -419,6 +437,9 @@ static u32 *dw_hdmi_rockchip_get_input_bus_fmts(struct drm_bridge *bridge, + if (is_yuv444(output_fmt)) { + if (!hdmi->chip_data->ycbcr_444_allowed) + return NULL; ++ } else if (is_yuv420(output_fmt)) { ++ if (!connector->ycbcr_420_allowed) ++ return NULL; + } else if (!is_rgb(output_fmt)) + return NULL; + +@@ -575,6 +596,7 @@ static const struct dw_hdmi_plat_data rk3328_hdmi_drv_data = { + .phy_name = "inno_dw_hdmi_phy2", + .phy_force_vendor = true, + .use_drm_infoframe = true, ++ .ycbcr_420_allowed = true, + }; + + static struct rockchip_hdmi_chip_data rk3399_chip_data = { +diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +index 5bf833ea8ce2..b8c0d2fcc52a 100644 +--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +@@ -275,6 +275,19 @@ static enum vop_data_format vop_convert_format(uint32_t format) + } + + 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: ++ return true; ++ default: ++ return false; ++ } ++} ++ ++static bool has_uv_swapped(uint32_t bus_format) + { + switch (bus_format) { + case MEDIA_BUS_FMT_YUV8_1X24: +@@ -1266,7 +1279,7 @@ static void vop_crtc_atomic_enable(struct drm_crtc *crtc, + !(vop_data->feature & VOP_FEATURE_OUTPUT_RGB10)) + s->output_mode = ROCKCHIP_OUT_MODE_P888; + +- VOP_REG_SET(vop, common, dsp_data_swap, yuv_output ? 2 : 0); ++ VOP_REG_SET(vop, common, dsp_data_swap, has_uv_swapped(s->bus_format) ? 2 : 0); + + if (s->output_mode == ROCKCHIP_OUT_MODE_AAAA && dither_bpc <= 8) + VOP_REG_SET(vop, common, pre_dither_down, 1); +@@ -1283,6 +1296,9 @@ static void vop_crtc_atomic_enable(struct drm_crtc *crtc, + + VOP_REG_SET(vop, common, out_mode, s->output_mode); + ++ VOP_REG_SET(vop, common, dclk_ddr, ++ s->output_mode == ROCKCHIP_OUT_MODE_YUV420 ? 1 : 0); ++ + VOP_REG_SET(vop, common, overlay_mode, yuv_output); + VOP_REG_SET(vop, common, dsp_out_yuv, yuv_output); + +diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h +index 9393cf12b1db..89fe8d5c7721 100644 +--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h +@@ -79,6 +79,7 @@ struct vop_common { + struct vop_reg standby; + + struct vop_reg overlay_mode; ++ struct vop_reg dclk_ddr; + struct vop_reg dsp_data_swap; + struct vop_reg dsp_out_yuv; + struct vop_reg dsp_background; +@@ -230,11 +231,12 @@ struct vop_data { + /* + * display output interface supported by rockchip lcdc + */ +-#define ROCKCHIP_OUT_MODE_P888 0 +-#define ROCKCHIP_OUT_MODE_P666 1 +-#define ROCKCHIP_OUT_MODE_P565 2 ++#define ROCKCHIP_OUT_MODE_P888 0 ++#define ROCKCHIP_OUT_MODE_P666 1 ++#define ROCKCHIP_OUT_MODE_P565 2 ++#define ROCKCHIP_OUT_MODE_YUV420 14 + /* for use special outface */ +-#define ROCKCHIP_OUT_MODE_AAAA 15 ++#define ROCKCHIP_OUT_MODE_AAAA 15 + + /* output flags */ + #define ROCKCHIP_OUTPUT_DSI_DUAL BIT(0) +diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c +index b99e902d949e..73d24c6bbf05 100644 +--- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c ++++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c +@@ -608,6 +608,7 @@ static const struct vop_common rk3288_common = { + .cfg_done = VOP_REG_SYNC(RK3288_REG_CFG_DONE, 0x1, 0), + + .overlay_mode = VOP_REG(RK3288_SYS_CTRL, 0x1, 16), ++ .dclk_ddr = VOP_REG(RK3288_DSP_CTRL0, 0x1, 8), + .dsp_data_swap = VOP_REG(RK3288_DSP_CTRL0, 0x1f, 12), + .dsp_out_yuv = VOP_REG(RK3288_POST_SCL_CTRL, 0x1, 2), + .dsp_background = VOP_REG(RK3288_DSP_BG, 0xffffffff, 0), +@@ -921,6 +922,7 @@ static const struct vop_common rk3328_common = { + .cfg_done = VOP_REG_SYNC(RK3328_REG_CFG_DONE, 0x1, 0), + + .overlay_mode = VOP_REG(RK3328_SYS_CTRL, 0x1, 16), ++ .dclk_ddr = VOP_REG(RK3328_DSP_CTRL0, 0x1, 8), + .dsp_data_swap = VOP_REG(RK3328_DSP_CTRL0, 0x1f, 12), + .dsp_out_yuv = VOP_REG(RK3328_POST_SCL_CTRL, 0x1, 2), + .dsp_background = VOP_REG(RK3328_DSP_BG, 0xffffffff, 0), +-- +2.17.1 + + +From a8f40af332f87e74015d578a14e4491d1e0c9291 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 8 Dec 2019 23:49:00 +0000 +Subject: [PATCH] WIP: drm/bridge: dw-hdmi: signal default quant range + +--- + drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +index df1789cd8712..14a1131cfc21 100644 +--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c ++++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +@@ -1673,6 +1673,9 @@ static void hdmi_config_AVI(struct dw_hdmi *hdmi, struct drm_display_mode *mode) + HDMI_EXTENDED_COLORIMETRY_XV_YCC_601; + } + ++ drm_hdmi_avi_infoframe_quant_range(&frame, &hdmi->connector, mode, ++ drm_default_rgb_quant_range(mode)); ++ + drm_hdmi_avi_infoframe_content_type(&frame, conn_state); + + hdmi_infoframe_log(KERN_INFO, hdmi->dev, (union hdmi_infoframe *)&frame); +-- +2.17.1 + + +From aa34fb23453ea76f533d0af601ec0ce5ee9d8312 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Fri, 20 Dec 2019 08:12:43 +0000 +Subject: [PATCH] WIP: drm/bridge: dw-hdmi: use avmute during modeset + +--- + drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 4 ++++ + drivers/gpu/drm/bridge/synopsys/dw-hdmi.h | 4 ++++ + 2 files changed, 8 insertions(+) + +diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +index 14a1131cfc21..6344c8aac13e 100644 +--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c ++++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +@@ -2328,10 +2328,14 @@ static void dw_hdmi_poweron(struct dw_hdmi *hdmi) + hdmi->bridge_is_on = true; + dw_hdmi_get_edid(&hdmi->connector); + dw_hdmi_setup(hdmi, &hdmi->previous_mode); ++ ++ hdmi_writeb(hdmi, HDMI_FC_GCP_CLEAR_AVMUTE, HDMI_FC_GCP); + } + + static void dw_hdmi_poweroff(struct dw_hdmi *hdmi) + { ++ hdmi_writeb(hdmi, HDMI_FC_GCP_SET_AVMUTE, HDMI_FC_GCP); ++ + if (hdmi->phy.enabled) { + hdmi->phy.ops->disable(hdmi, hdmi->phy.data); + hdmi->phy.enabled = false; +diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h +index 27a91128d0cc..3810326794cc 100644 +--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h ++++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h +@@ -842,6 +842,10 @@ enum { + HDMI_FC_AVICONF3_QUANT_RANGE_LIMITED = 0x00, + HDMI_FC_AVICONF3_QUANT_RANGE_FULL = 0x04, + ++/* HDMI_FC_GCP */ ++ HDMI_FC_GCP_SET_AVMUTE = 0x2, ++ HDMI_FC_GCP_CLEAR_AVMUTE = 0x1, ++ + /* FC_DBGFORCE field values */ + HDMI_FC_DBGFORCE_FORCEAUDIO = 0x10, + HDMI_FC_DBGFORCE_FORCEVIDEO = 0x1, +-- +2.17.1 + diff --git a/patch/kernel/rk322x-current/01-linux-0007-fromlist-drm-lima-and-panfrost-for-5.8-plus.patch b/patch/kernel/rk322x-current/01-linux-0007-fromlist-drm-lima-and-panfrost-for-5.8-plus.patch new file mode 100644 index 0000000000..9d3dbcbe01 --- /dev/null +++ b/patch/kernel/rk322x-current/01-linux-0007-fromlist-drm-lima-and-panfrost-for-5.8-plus.patch @@ -0,0 +1,4172 @@ +diff --git a/drivers/gpu/drm/panfrost/panfrost_gpu.c b/drivers/gpu/drm/panfrost/panfrost_gpu.c +index 8822ec13a0d6..cdebe9a9ade7 100644 +--- a/drivers/gpu/drm/panfrost/panfrost_gpu.c ++++ b/drivers/gpu/drm/panfrost/panfrost_gpu.c +@@ -351,7 +351,7 @@ int panfrost_gpu_init(struct panfrost_device *pfdev) + return -ENODEV; + + err = devm_request_irq(pfdev->dev, irq, panfrost_gpu_irq_handler, +- IRQF_SHARED, "gpu", pfdev); ++ IRQF_SHARED, KBUILD_MODNAME "-gpu", pfdev); + if (err) { + dev_err(pfdev->dev, "failed to request gpu irq"); + return err; +diff --git a/drivers/gpu/drm/panfrost/panfrost_job.c b/drivers/gpu/drm/panfrost/panfrost_job.c +index 9a1a72a748e7..7914b1570841 100644 +--- a/drivers/gpu/drm/panfrost/panfrost_job.c ++++ b/drivers/gpu/drm/panfrost/panfrost_job.c +@@ -508,7 +508,7 @@ int panfrost_job_init(struct panfrost_device *pfdev) + return -ENODEV; + + ret = devm_request_irq(pfdev->dev, irq, panfrost_job_irq_handler, +- IRQF_SHARED, "job", pfdev); ++ IRQF_SHARED, KBUILD_MODNAME "-job", pfdev); + if (ret) { + dev_err(pfdev->dev, "failed to request job irq"); + return ret; +diff --git a/drivers/gpu/drm/panfrost/panfrost_mmu.c b/drivers/gpu/drm/panfrost/panfrost_mmu.c +index 5d75f8cf6477..ed28aeba6d59 100644 +--- a/drivers/gpu/drm/panfrost/panfrost_mmu.c ++++ b/drivers/gpu/drm/panfrost/panfrost_mmu.c +@@ -640,9 +640,11 @@ int panfrost_mmu_init(struct panfrost_device *pfdev) + if (irq <= 0) + return -ENODEV; + +- err = devm_request_threaded_irq(pfdev->dev, irq, panfrost_mmu_irq_handler, ++ err = devm_request_threaded_irq(pfdev->dev, irq, ++ panfrost_mmu_irq_handler, + panfrost_mmu_irq_handler_thread, +- IRQF_SHARED, "mmu", pfdev); ++ IRQF_SHARED, KBUILD_MODNAME "-mmu", ++ pfdev); + + if (err) { + dev_err(pfdev->dev, "failed to request mmu irq"); +-- +2.17.1 + + +From feabec154cc4e8e3e9f1005fc0fc2ad2d0d828ed Mon Sep 17 00:00:00 2001 +From: Qiang Yu +Date: Thu, 16 Jan 2020 21:11:53 +0800 +Subject: [PATCH] drm/lima: update register info + +From Mali r10p0 kernel driver source code. + +Reviewed-by: Vasily Khoruzhick +Tested-by: Andreas Baierl +Signed-off-by: Qiang Yu +--- + drivers/gpu/drm/lima/lima_regs.h | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/gpu/drm/lima/lima_regs.h b/drivers/gpu/drm/lima/lima_regs.h +index ace8ecefbe90..0124c90e0153 100644 +--- a/drivers/gpu/drm/lima/lima_regs.h ++++ b/drivers/gpu/drm/lima/lima_regs.h +@@ -239,6 +239,7 @@ + #define LIMA_MMU_STATUS_REPLAY_BUFFER_EMPTY BIT(4) + #define LIMA_MMU_STATUS_PAGE_FAULT_IS_WRITE BIT(5) + #define LIMA_MMU_STATUS_BUS_ID(x) ((x >> 6) & 0x1F) ++#define LIMA_MMU_STATUS_STALL_NOT_ACTIVE BIT(31) + #define LIMA_MMU_COMMAND 0x0008 + #define LIMA_MMU_COMMAND_ENABLE_PAGING 0x00 + #define LIMA_MMU_COMMAND_DISABLE_PAGING 0x01 +-- +2.17.1 + + +From a39f09230ca6ddf9e147e86c1bad9850913f6d52 Mon Sep 17 00:00:00 2001 +From: Qiang Yu +Date: Thu, 16 Jan 2020 21:11:54 +0800 +Subject: [PATCH] drm/lima: add lima_vm_map_bo + +For dynamically mapping added backup memory of lima_bo to vm. +This is a preparation for adding heap buffer support. + +Reviewed-by: Vasily Khoruzhick +Tested-by: Andreas Baierl +Signed-off-by: Qiang Yu +--- + drivers/gpu/drm/lima/lima_vm.c | 42 ++++++++++++++++++++++++++++++++++ + drivers/gpu/drm/lima/lima_vm.h | 1 + + 2 files changed, 43 insertions(+) + +diff --git a/drivers/gpu/drm/lima/lima_vm.c b/drivers/gpu/drm/lima/lima_vm.c +index 840e2350d872..2e513841de6c 100644 +--- a/drivers/gpu/drm/lima/lima_vm.c ++++ b/drivers/gpu/drm/lima/lima_vm.c +@@ -277,3 +277,45 @@ void lima_vm_print(struct lima_vm *vm) + } + } + } ++ ++int lima_vm_map_bo(struct lima_vm *vm, struct lima_bo *bo, int pageoff) ++{ ++ struct lima_bo_va *bo_va; ++ struct sg_dma_page_iter sg_iter; ++ int offset = 0, err; ++ u32 base; ++ ++ mutex_lock(&bo->lock); ++ ++ bo_va = lima_vm_bo_find(vm, bo); ++ if (!bo_va) { ++ err = -ENOENT; ++ goto err_out0; ++ } ++ ++ mutex_lock(&vm->lock); ++ ++ base = bo_va->node.start + (pageoff << PAGE_SHIFT); ++ for_each_sg_dma_page(bo->base.sgt->sgl, &sg_iter, ++ bo->base.sgt->nents, pageoff) { ++ err = lima_vm_map_page(vm, sg_page_iter_dma_address(&sg_iter), ++ base + offset); ++ if (err) ++ goto err_out1; ++ ++ offset += PAGE_SIZE; ++ } ++ ++ mutex_unlock(&vm->lock); ++ ++ mutex_unlock(&bo->lock); ++ return 0; ++ ++err_out1: ++ if (offset) ++ lima_vm_unmap_range(vm, base, base + offset - 1); ++ mutex_unlock(&vm->lock); ++err_out0: ++ mutex_unlock(&bo->lock); ++ return err; ++} +diff --git a/drivers/gpu/drm/lima/lima_vm.h b/drivers/gpu/drm/lima/lima_vm.h +index e0bdedcf14dd..22aeec77d84d 100644 +--- a/drivers/gpu/drm/lima/lima_vm.h ++++ b/drivers/gpu/drm/lima/lima_vm.h +@@ -58,5 +58,6 @@ static inline void lima_vm_put(struct lima_vm *vm) + } + + void lima_vm_print(struct lima_vm *vm); ++int lima_vm_map_bo(struct lima_vm *vm, struct lima_bo *bo, int pageoff); + + #endif +-- +2.17.1 + + +From 7855619e0208555bf2568e143747d86b882aa6f7 Mon Sep 17 00:00:00 2001 +From: Qiang Yu +Date: Thu, 16 Jan 2020 21:11:55 +0800 +Subject: [PATCH] drm/lima: support heap buffer creation + +heap buffer is used as output of GP and input of PP for +Mali Utgard GPU. Size of heap buffer depends on the task +so is a runtime variable. + +Previously we just create a large enough buffer as heap +buffer. Now we add a heap buffer type to be able to +increase the backup memory dynamically when GP fail due +to lack of heap memory. + +Reviewed-by: Vasily Khoruzhick +Tested-by: Andreas Baierl +Signed-off-by: Qiang Yu +--- + drivers/gpu/drm/lima/lima_drv.c | 6 +- + drivers/gpu/drm/lima/lima_drv.h | 1 + + drivers/gpu/drm/lima/lima_gem.c | 134 ++++++++++++++++++++++++++++++-- + drivers/gpu/drm/lima/lima_gem.h | 4 + + drivers/gpu/drm/lima/lima_vm.c | 4 +- + include/uapi/drm/lima_drm.h | 9 ++- + 6 files changed, 147 insertions(+), 11 deletions(-) + +diff --git a/drivers/gpu/drm/lima/lima_drv.c b/drivers/gpu/drm/lima/lima_drv.c +index 124efe4fa97b..18f88aaef1a2 100644 +--- a/drivers/gpu/drm/lima/lima_drv.c ++++ b/drivers/gpu/drm/lima/lima_drv.c +@@ -15,10 +15,14 @@ + #include "lima_vm.h" + + int lima_sched_timeout_ms; ++uint lima_heap_init_nr_pages = 8; + + MODULE_PARM_DESC(sched_timeout_ms, "task run timeout in ms"); + module_param_named(sched_timeout_ms, lima_sched_timeout_ms, int, 0444); + ++MODULE_PARM_DESC(heap_init_nr_pages, "heap buffer init number of pages"); ++module_param_named(heap_init_nr_pages, lima_heap_init_nr_pages, uint, 0444); ++ + static int lima_ioctl_get_param(struct drm_device *dev, void *data, struct drm_file *file) + { + struct drm_lima_get_param *args = data; +@@ -68,7 +72,7 @@ static int lima_ioctl_gem_create(struct drm_device *dev, void *data, struct drm_ + if (args->pad) + return -EINVAL; + +- if (args->flags) ++ if (args->flags & ~(LIMA_BO_FLAG_HEAP)) + return -EINVAL; + + if (args->size == 0) +diff --git a/drivers/gpu/drm/lima/lima_drv.h b/drivers/gpu/drm/lima/lima_drv.h +index 69c7344715c9..f492ecc6a5d9 100644 +--- a/drivers/gpu/drm/lima/lima_drv.h ++++ b/drivers/gpu/drm/lima/lima_drv.h +@@ -9,6 +9,7 @@ + #include "lima_ctx.h" + + extern int lima_sched_timeout_ms; ++extern uint lima_heap_init_nr_pages; + + struct lima_vm; + struct lima_bo; +diff --git a/drivers/gpu/drm/lima/lima_gem.c b/drivers/gpu/drm/lima/lima_gem.c +index d0059d8c97d8..5404e0d668db 100644 +--- a/drivers/gpu/drm/lima/lima_gem.c ++++ b/drivers/gpu/drm/lima/lima_gem.c +@@ -4,6 +4,8 @@ + #include + #include + #include ++#include ++#include + + #include + #include +@@ -15,6 +17,83 @@ + #include "lima_gem.h" + #include "lima_vm.h" + ++int lima_heap_alloc(struct lima_bo *bo, struct lima_vm *vm) ++{ ++ struct page **pages; ++ struct address_space *mapping = bo->base.base.filp->f_mapping; ++ struct device *dev = bo->base.base.dev->dev; ++ size_t old_size = bo->heap_size; ++ size_t new_size = bo->heap_size ? bo->heap_size * 2 : ++ (lima_heap_init_nr_pages << PAGE_SHIFT); ++ struct sg_table sgt; ++ int i, ret; ++ ++ if (bo->heap_size >= bo->base.base.size) ++ return -ENOSPC; ++ ++ new_size = min(new_size, bo->base.base.size); ++ ++ mutex_lock(&bo->base.pages_lock); ++ ++ if (bo->base.pages) { ++ pages = bo->base.pages; ++ } else { ++ pages = kvmalloc_array(bo->base.base.size >> PAGE_SHIFT, ++ sizeof(*pages), GFP_KERNEL | __GFP_ZERO); ++ if (!pages) { ++ mutex_unlock(&bo->base.pages_lock); ++ return -ENOMEM; ++ } ++ ++ bo->base.pages = pages; ++ bo->base.pages_use_count = 1; ++ ++ mapping_set_unevictable(mapping); ++ } ++ ++ for (i = old_size >> PAGE_SHIFT; i < new_size >> PAGE_SHIFT; i++) { ++ struct page *page = shmem_read_mapping_page(mapping, i); ++ ++ if (IS_ERR(page)) { ++ mutex_unlock(&bo->base.pages_lock); ++ return PTR_ERR(page); ++ } ++ pages[i] = page; ++ } ++ ++ mutex_unlock(&bo->base.pages_lock); ++ ++ ret = sg_alloc_table_from_pages(&sgt, pages, i, 0, ++ new_size, GFP_KERNEL); ++ if (ret) ++ return ret; ++ ++ if (bo->base.sgt) { ++ dma_unmap_sg(dev, bo->base.sgt->sgl, ++ bo->base.sgt->nents, DMA_BIDIRECTIONAL); ++ sg_free_table(bo->base.sgt); ++ } else { ++ bo->base.sgt = kmalloc(sizeof(*bo->base.sgt), GFP_KERNEL); ++ if (!bo->base.sgt) { ++ sg_free_table(&sgt); ++ return -ENOMEM; ++ } ++ } ++ ++ dma_map_sg(dev, sgt.sgl, sgt.nents, DMA_BIDIRECTIONAL); ++ ++ *bo->base.sgt = sgt; ++ ++ if (vm) { ++ ret = lima_vm_map_bo(vm, bo, old_size >> PAGE_SHIFT); ++ if (ret) ++ return ret; ++ } ++ ++ bo->heap_size = new_size; ++ return 0; ++} ++ + int lima_gem_create_handle(struct drm_device *dev, struct drm_file *file, + u32 size, u32 flags, u32 *handle) + { +@@ -22,7 +101,8 @@ int lima_gem_create_handle(struct drm_device *dev, struct drm_file *file, + gfp_t mask; + struct drm_gem_shmem_object *shmem; + struct drm_gem_object *obj; +- struct sg_table *sgt; ++ struct lima_bo *bo; ++ bool is_heap = flags & LIMA_BO_FLAG_HEAP; + + shmem = drm_gem_shmem_create(dev, size); + if (IS_ERR(shmem)) +@@ -36,10 +116,18 @@ int lima_gem_create_handle(struct drm_device *dev, struct drm_file *file, + mask |= __GFP_DMA32; + mapping_set_gfp_mask(obj->filp->f_mapping, mask); + +- sgt = drm_gem_shmem_get_pages_sgt(obj); +- if (IS_ERR(sgt)) { +- err = PTR_ERR(sgt); +- goto out; ++ if (is_heap) { ++ bo = to_lima_bo(obj); ++ err = lima_heap_alloc(bo, NULL); ++ if (err) ++ goto out; ++ } else { ++ struct sg_table *sgt = drm_gem_shmem_get_pages_sgt(obj); ++ ++ if (IS_ERR(sgt)) { ++ err = PTR_ERR(sgt); ++ goto out; ++ } + } + + err = drm_gem_handle_create(file, obj, handle); +@@ -79,17 +167,47 @@ static void lima_gem_object_close(struct drm_gem_object *obj, struct drm_file *f + lima_vm_bo_del(vm, bo); + } + ++static int lima_gem_pin(struct drm_gem_object *obj) ++{ ++ struct lima_bo *bo = to_lima_bo(obj); ++ ++ if (bo->heap_size) ++ return -EINVAL; ++ ++ return drm_gem_shmem_pin(obj); ++} ++ ++static void *lima_gem_vmap(struct drm_gem_object *obj) ++{ ++ struct lima_bo *bo = to_lima_bo(obj); ++ ++ if (bo->heap_size) ++ return ERR_PTR(-EINVAL); ++ ++ return drm_gem_shmem_vmap(obj); ++} ++ ++static int lima_gem_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma) ++{ ++ struct lima_bo *bo = to_lima_bo(obj); ++ ++ if (bo->heap_size) ++ return -EINVAL; ++ ++ return drm_gem_shmem_mmap(obj, vma); ++} ++ + static const struct drm_gem_object_funcs lima_gem_funcs = { + .free = lima_gem_free_object, + .open = lima_gem_object_open, + .close = lima_gem_object_close, + .print_info = drm_gem_shmem_print_info, +- .pin = drm_gem_shmem_pin, ++ .pin = lima_gem_pin, + .unpin = drm_gem_shmem_unpin, + .get_sg_table = drm_gem_shmem_get_sg_table, +- .vmap = drm_gem_shmem_vmap, ++ .vmap = lima_gem_vmap, + .vunmap = drm_gem_shmem_vunmap, +- .mmap = drm_gem_shmem_mmap, ++ .mmap = lima_gem_mmap, + }; + + struct drm_gem_object *lima_gem_create_object(struct drm_device *dev, size_t size) +diff --git a/drivers/gpu/drm/lima/lima_gem.h b/drivers/gpu/drm/lima/lima_gem.h +index 1800feb3e47f..ccea06142f4b 100644 +--- a/drivers/gpu/drm/lima/lima_gem.h ++++ b/drivers/gpu/drm/lima/lima_gem.h +@@ -7,12 +7,15 @@ + #include + + struct lima_submit; ++struct lima_vm; + + struct lima_bo { + struct drm_gem_shmem_object base; + + struct mutex lock; + struct list_head va; ++ ++ size_t heap_size; + }; + + static inline struct lima_bo * +@@ -31,6 +34,7 @@ static inline struct dma_resv *lima_bo_resv(struct lima_bo *bo) + return bo->base.base.resv; + } + ++int lima_heap_alloc(struct lima_bo *bo, struct lima_vm *vm); + struct drm_gem_object *lima_gem_create_object(struct drm_device *dev, size_t size); + int lima_gem_create_handle(struct drm_device *dev, struct drm_file *file, + u32 size, u32 flags, u32 *handle); +diff --git a/drivers/gpu/drm/lima/lima_vm.c b/drivers/gpu/drm/lima/lima_vm.c +index 2e513841de6c..5b92fb82674a 100644 +--- a/drivers/gpu/drm/lima/lima_vm.c ++++ b/drivers/gpu/drm/lima/lima_vm.c +@@ -155,6 +155,7 @@ int lima_vm_bo_add(struct lima_vm *vm, struct lima_bo *bo, bool create) + void lima_vm_bo_del(struct lima_vm *vm, struct lima_bo *bo) + { + struct lima_bo_va *bo_va; ++ u32 size; + + mutex_lock(&bo->lock); + +@@ -166,8 +167,9 @@ void lima_vm_bo_del(struct lima_vm *vm, struct lima_bo *bo) + + mutex_lock(&vm->lock); + ++ size = bo->heap_size ? bo->heap_size : bo_va->node.size; + lima_vm_unmap_range(vm, bo_va->node.start, +- bo_va->node.start + bo_va->node.size - 1); ++ bo_va->node.start + size - 1); + + drm_mm_remove_node(&bo_va->node); + +diff --git a/include/uapi/drm/lima_drm.h b/include/uapi/drm/lima_drm.h +index 95a00fb867e6..1ec58d652a5a 100644 +--- a/include/uapi/drm/lima_drm.h ++++ b/include/uapi/drm/lima_drm.h +@@ -32,12 +32,19 @@ struct drm_lima_get_param { + __u64 value; /* out, parameter value */ + }; + ++/* ++ * heap buffer dynamically increase backup memory size when GP task fail ++ * due to lack of heap memory. size field of heap buffer is an up bound of ++ * the backup memory which can be set to a fairly large value. ++ */ ++#define LIMA_BO_FLAG_HEAP (1 << 0) ++ + /** + * create a buffer for used by GPU + */ + struct drm_lima_gem_create { + __u32 size; /* in, buffer size */ +- __u32 flags; /* in, currently no flags, must be zero */ ++ __u32 flags; /* in, buffer flags */ + __u32 handle; /* out, GEM buffer handle */ + __u32 pad; /* pad, must be zero */ + }; +-- +2.17.1 + + +From a9e57ad7709f2f0794da7ec3ef69fa0075c715d5 Mon Sep 17 00:00:00 2001 +From: Qiang Yu +Date: Thu, 16 Jan 2020 21:11:56 +0800 +Subject: [PATCH] drm/lima: recover task by enlarging heap buffer + +Increase heap buffer backup memory when GP receive PLBU +out of memory interrupt, then resume the task. + +Reviewed-by: Vasily Khoruzhick +Tested-by: Andreas Baierl +Signed-off-by: Qiang Yu +--- + drivers/gpu/drm/lima/lima_gp.c | 58 +++++++++++++++++++++++++++++-- + drivers/gpu/drm/lima/lima_mmu.c | 5 +++ + drivers/gpu/drm/lima/lima_mmu.h | 1 + + drivers/gpu/drm/lima/lima_sched.c | 35 ++++++++++++++++--- + drivers/gpu/drm/lima/lima_sched.h | 6 ++++ + 5 files changed, 98 insertions(+), 7 deletions(-) + +diff --git a/drivers/gpu/drm/lima/lima_gp.c b/drivers/gpu/drm/lima/lima_gp.c +index ccf49faedebf..52b210f9a605 100644 +--- a/drivers/gpu/drm/lima/lima_gp.c ++++ b/drivers/gpu/drm/lima/lima_gp.c +@@ -11,6 +11,8 @@ + #include "lima_device.h" + #include "lima_gp.h" + #include "lima_regs.h" ++#include "lima_gem.h" ++#include "lima_vm.h" + + #define gp_write(reg, data) writel(data, ip->iomem + reg) + #define gp_read(reg) readl(ip->iomem + reg) +@@ -20,6 +22,7 @@ static irqreturn_t lima_gp_irq_handler(int irq, void *data) + struct lima_ip *ip = data; + struct lima_device *dev = ip->dev; + struct lima_sched_pipe *pipe = dev->pipe + lima_pipe_gp; ++ struct lima_sched_task *task = pipe->current_task; + u32 state = gp_read(LIMA_GP_INT_STAT); + u32 status = gp_read(LIMA_GP_STATUS); + bool done = false; +@@ -29,8 +32,16 @@ static irqreturn_t lima_gp_irq_handler(int irq, void *data) + return IRQ_NONE; + + if (state & LIMA_GP_IRQ_MASK_ERROR) { +- dev_err(dev->dev, "gp error irq state=%x status=%x\n", +- state, status); ++ if ((state & LIMA_GP_IRQ_MASK_ERROR) == ++ LIMA_GP_IRQ_PLBU_OUT_OF_MEM) { ++ dev_dbg(dev->dev, "gp out of heap irq status=%x\n", ++ status); ++ } else { ++ dev_err(dev->dev, "gp error irq state=%x status=%x\n", ++ state, status); ++ if (task) ++ task->recoverable = false; ++ } + + /* mask all interrupts before hard reset */ + gp_write(LIMA_GP_INT_MASK, 0); +@@ -43,6 +54,7 @@ static irqreturn_t lima_gp_irq_handler(int irq, void *data) + bool active = status & (LIMA_GP_STATUS_VS_ACTIVE | + LIMA_GP_STATUS_PLBU_ACTIVE); + done = valid && !active; ++ pipe->error = false; + } + + gp_write(LIMA_GP_INT_CLEAR, state); +@@ -121,6 +133,22 @@ static void lima_gp_task_run(struct lima_sched_pipe *pipe, + u32 cmd = 0; + int i; + ++ /* update real heap buffer size for GP */ ++ for (i = 0; i < task->num_bos; i++) { ++ struct lima_bo *bo = task->bos[i]; ++ ++ if (bo->heap_size && ++ lima_vm_get_va(task->vm, bo) == ++ f[LIMA_GP_PLBU_ALLOC_START_ADDR >> 2]) { ++ f[LIMA_GP_PLBU_ALLOC_END_ADDR >> 2] = ++ f[LIMA_GP_PLBU_ALLOC_START_ADDR >> 2] + ++ bo->heap_size; ++ task->recoverable = true; ++ task->heap = bo; ++ break; ++ } ++ } ++ + if (f[LIMA_GP_VSCL_START_ADDR >> 2] != + f[LIMA_GP_VSCL_END_ADDR >> 2]) + cmd |= LIMA_GP_CMD_START_VS; +@@ -184,6 +212,31 @@ static void lima_gp_task_mmu_error(struct lima_sched_pipe *pipe) + lima_sched_pipe_task_done(pipe); + } + ++static int lima_gp_task_recover(struct lima_sched_pipe *pipe) ++{ ++ struct lima_ip *ip = pipe->processor[0]; ++ struct lima_sched_task *task = pipe->current_task; ++ struct drm_lima_gp_frame *frame = task->frame; ++ u32 *f = frame->frame; ++ size_t fail_size = ++ f[LIMA_GP_PLBU_ALLOC_END_ADDR >> 2] - ++ f[LIMA_GP_PLBU_ALLOC_START_ADDR >> 2]; ++ ++ if (fail_size == task->heap->heap_size) { ++ int ret; ++ ++ ret = lima_heap_alloc(task->heap, task->vm); ++ if (ret < 0) ++ return ret; ++ } ++ ++ gp_write(LIMA_GP_INT_MASK, LIMA_GP_IRQ_MASK_USED); ++ gp_write(LIMA_GP_PLBU_ALLOC_END_ADDR, ++ f[LIMA_GP_PLBU_ALLOC_START_ADDR >> 2] + task->heap->heap_size); ++ gp_write(LIMA_GP_CMD, LIMA_GP_CMD_UPDATE_PLBU_ALLOC); ++ return 0; ++} ++ + static void lima_gp_print_version(struct lima_ip *ip) + { + u32 version, major, minor; +@@ -270,6 +323,7 @@ int lima_gp_pipe_init(struct lima_device *dev) + pipe->task_fini = lima_gp_task_fini; + pipe->task_error = lima_gp_task_error; + pipe->task_mmu_error = lima_gp_task_mmu_error; ++ pipe->task_recover = lima_gp_task_recover; + + return 0; + } +diff --git a/drivers/gpu/drm/lima/lima_mmu.c b/drivers/gpu/drm/lima/lima_mmu.c +index 97ec09dee572..f79d2af427e7 100644 +--- a/drivers/gpu/drm/lima/lima_mmu.c ++++ b/drivers/gpu/drm/lima/lima_mmu.c +@@ -99,6 +99,11 @@ void lima_mmu_fini(struct lima_ip *ip) + + } + ++void lima_mmu_flush_tlb(struct lima_ip *ip) ++{ ++ mmu_write(LIMA_MMU_COMMAND, LIMA_MMU_COMMAND_ZAP_CACHE); ++} ++ + void lima_mmu_switch_vm(struct lima_ip *ip, struct lima_vm *vm) + { + struct lima_device *dev = ip->dev; +diff --git a/drivers/gpu/drm/lima/lima_mmu.h b/drivers/gpu/drm/lima/lima_mmu.h +index 8c78319bcc8e..4f8ccbebcba1 100644 +--- a/drivers/gpu/drm/lima/lima_mmu.h ++++ b/drivers/gpu/drm/lima/lima_mmu.h +@@ -10,6 +10,7 @@ struct lima_vm; + int lima_mmu_init(struct lima_ip *ip); + void lima_mmu_fini(struct lima_ip *ip); + ++void lima_mmu_flush_tlb(struct lima_ip *ip); + void lima_mmu_switch_vm(struct lima_ip *ip, struct lima_vm *vm); + void lima_mmu_page_fault_resume(struct lima_ip *ip); + +diff --git a/drivers/gpu/drm/lima/lima_sched.c b/drivers/gpu/drm/lima/lima_sched.c +index b561dd05bd62..3886999b4533 100644 +--- a/drivers/gpu/drm/lima/lima_sched.c ++++ b/drivers/gpu/drm/lima/lima_sched.c +@@ -313,6 +313,26 @@ static const struct drm_sched_backend_ops lima_sched_ops = { + .free_job = lima_sched_free_job, + }; + ++static void lima_sched_recover_work(struct work_struct *work) ++{ ++ struct lima_sched_pipe *pipe = ++ container_of(work, struct lima_sched_pipe, recover_work); ++ int i; ++ ++ for (i = 0; i < pipe->num_l2_cache; i++) ++ lima_l2_cache_flush(pipe->l2_cache[i]); ++ ++ if (pipe->bcast_mmu) { ++ lima_mmu_flush_tlb(pipe->bcast_mmu); ++ } else { ++ for (i = 0; i < pipe->num_mmu; i++) ++ lima_mmu_flush_tlb(pipe->mmu[i]); ++ } ++ ++ if (pipe->task_recover(pipe)) ++ drm_sched_fault(&pipe->base); ++} ++ + int lima_sched_pipe_init(struct lima_sched_pipe *pipe, const char *name) + { + unsigned int timeout = lima_sched_timeout_ms > 0 ? +@@ -321,6 +341,8 @@ int lima_sched_pipe_init(struct lima_sched_pipe *pipe, const char *name) + pipe->fence_context = dma_fence_context_alloc(1); + spin_lock_init(&pipe->fence_lock); + ++ INIT_WORK(&pipe->recover_work, lima_sched_recover_work); ++ + return drm_sched_init(&pipe->base, &lima_sched_ops, 1, 0, + msecs_to_jiffies(timeout), name); + } +@@ -332,11 +354,14 @@ void lima_sched_pipe_fini(struct lima_sched_pipe *pipe) + + void lima_sched_pipe_task_done(struct lima_sched_pipe *pipe) + { +- if (pipe->error) +- drm_sched_fault(&pipe->base); +- else { +- struct lima_sched_task *task = pipe->current_task; +- ++ struct lima_sched_task *task = pipe->current_task; ++ ++ if (pipe->error) { ++ if (task && task->recoverable) ++ schedule_work(&pipe->recover_work); ++ else ++ drm_sched_fault(&pipe->base); ++ } else { + pipe->task_fini(pipe); + dma_fence_signal(task->fence); + } +diff --git a/drivers/gpu/drm/lima/lima_sched.h b/drivers/gpu/drm/lima/lima_sched.h +index 1d814fecbcc0..d64393fb50a9 100644 +--- a/drivers/gpu/drm/lima/lima_sched.h ++++ b/drivers/gpu/drm/lima/lima_sched.h +@@ -20,6 +20,9 @@ struct lima_sched_task { + struct lima_bo **bos; + int num_bos; + ++ bool recoverable; ++ struct lima_bo *heap; ++ + /* pipe fence */ + struct dma_fence *fence; + }; +@@ -68,6 +71,9 @@ struct lima_sched_pipe { + void (*task_fini)(struct lima_sched_pipe *pipe); + void (*task_error)(struct lima_sched_pipe *pipe); + void (*task_mmu_error)(struct lima_sched_pipe *pipe); ++ int (*task_recover)(struct lima_sched_pipe *pipe); ++ ++ struct work_struct recover_work; + }; + + int lima_sched_task_init(struct lima_sched_task *task, +-- +2.17.1 + + +From 6e3dc43aea43e83182588b79dd85e9c5f4d1d033 Mon Sep 17 00:00:00 2001 +From: Qiang Yu +Date: Thu, 16 Jan 2020 21:11:57 +0800 +Subject: [PATCH] drm/lima: increase driver version to 1.1 + +Increase driver version for mesa driver to identify +the support of new heap buffer interface. + +Reviewed-by: Vasily Khoruzhick +Tested-by: Andreas Baierl +Signed-off-by: Qiang Yu +--- + drivers/gpu/drm/lima/lima_drv.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/lima/lima_drv.c b/drivers/gpu/drm/lima/lima_drv.c +index 18f88aaef1a2..2daac64d8955 100644 +--- a/drivers/gpu/drm/lima/lima_drv.c ++++ b/drivers/gpu/drm/lima/lima_drv.c +@@ -245,6 +245,12 @@ static const struct drm_ioctl_desc lima_drm_driver_ioctls[] = { + + DEFINE_DRM_GEM_FOPS(lima_drm_driver_fops); + ++/** ++ * Changelog: ++ * ++ * - 1.1.0 - add heap buffer support ++ */ ++ + static struct drm_driver lima_drm_driver = { + .driver_features = DRIVER_RENDER | DRIVER_GEM | DRIVER_SYNCOBJ, + .open = lima_drm_driver_open, +@@ -254,9 +260,9 @@ static struct drm_driver lima_drm_driver = { + .fops = &lima_drm_driver_fops, + .name = "lima", + .desc = "lima DRM", +- .date = "20190217", ++ .date = "20191231", + .major = 1, +- .minor = 0, ++ .minor = 1, + .patchlevel = 0, + + .gem_create_object = lima_gem_create_object, +-- +2.17.1 + + +From 1a3901778598bc71d64bdbb71ea2278113aeb611 Mon Sep 17 00:00:00 2001 +From: Vasily Khoruzhick +Date: Fri, 14 Feb 2020 19:50:26 -0800 +Subject: [PATCH] drm/lima: fix recovering from PLBU out of memory + +It looks like on PLBU_OUT_OF_MEM interrupt we need to resume from where we +stopped, i.e. new PLBU heap start is old end. Also update end address +in GP frame to grow heap on 2nd and subsequent out of memory interrupts. + +Fixes: 2081e8dcf1ee ("drm/lima: recover task by enlarging heap buffer") +Signed-off-by: Vasily Khoruzhick +Signed-off-by: Qiang Yu +--- + drivers/gpu/drm/lima/lima_gp.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/lima/lima_gp.c b/drivers/gpu/drm/lima/lima_gp.c +index 52b210f9a605..d8841c870d90 100644 +--- a/drivers/gpu/drm/lima/lima_gp.c ++++ b/drivers/gpu/drm/lima/lima_gp.c +@@ -231,8 +231,13 @@ static int lima_gp_task_recover(struct lima_sched_pipe *pipe) + } + + gp_write(LIMA_GP_INT_MASK, LIMA_GP_IRQ_MASK_USED); ++ /* Resume from where we stopped, i.e. new start is old end */ ++ gp_write(LIMA_GP_PLBU_ALLOC_START_ADDR, ++ f[LIMA_GP_PLBU_ALLOC_END_ADDR >> 2]); ++ f[LIMA_GP_PLBU_ALLOC_END_ADDR >> 2] = ++ f[LIMA_GP_PLBU_ALLOC_START_ADDR >> 2] + task->heap->heap_size; + gp_write(LIMA_GP_PLBU_ALLOC_END_ADDR, +- f[LIMA_GP_PLBU_ALLOC_START_ADDR >> 2] + task->heap->heap_size); ++ f[LIMA_GP_PLBU_ALLOC_END_ADDR >> 2]); + gp_write(LIMA_GP_CMD, LIMA_GP_CMD_UPDATE_PLBU_ALLOC); + return 0; + } +-- +2.17.1 + + +From 619bbf1237ff25c39fbef0809bdfb28aa691e925 Mon Sep 17 00:00:00 2001 +From: Nicolas Boichat +Date: Fri, 7 Feb 2020 13:26:23 +0800 +Subject: [PATCH] drm/panfrost: Improve error reporting in + panfrost_gpu_power_on + +It is useful to know which component cannot be powered on. + +Signed-off-by: Nicolas Boichat +Reviewed-by: Alyssa Rosenzweig +Reviewed-by: Steven Price +Signed-off-by: Rob Herring +--- + drivers/gpu/drm/panfrost/panfrost_gpu.c | 14 ++++++++++---- + 1 file changed, 10 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/panfrost/panfrost_gpu.c b/drivers/gpu/drm/panfrost/panfrost_gpu.c +index cdebe9a9ade7..2881f439ff85 100644 +--- a/drivers/gpu/drm/panfrost/panfrost_gpu.c ++++ b/drivers/gpu/drm/panfrost/panfrost_gpu.c +@@ -308,21 +308,27 @@ void panfrost_gpu_power_on(struct panfrost_device *pfdev) + gpu_write(pfdev, L2_PWRON_LO, pfdev->features.l2_present); + ret = readl_relaxed_poll_timeout(pfdev->iomem + L2_READY_LO, + val, val == pfdev->features.l2_present, 100, 1000); ++ if (ret) ++ dev_err(pfdev->dev, "error powering up gpu L2"); + + gpu_write(pfdev, STACK_PWRON_LO, pfdev->features.stack_present); +- ret |= readl_relaxed_poll_timeout(pfdev->iomem + STACK_READY_LO, ++ ret = readl_relaxed_poll_timeout(pfdev->iomem + STACK_READY_LO, + val, val == pfdev->features.stack_present, 100, 1000); ++ if (ret) ++ dev_err(pfdev->dev, "error powering up gpu stack"); + + gpu_write(pfdev, SHADER_PWRON_LO, pfdev->features.shader_present); +- ret |= readl_relaxed_poll_timeout(pfdev->iomem + SHADER_READY_LO, ++ ret = readl_relaxed_poll_timeout(pfdev->iomem + SHADER_READY_LO, + val, val == pfdev->features.shader_present, 100, 1000); ++ if (ret) ++ dev_err(pfdev->dev, "error powering up gpu shader"); + + gpu_write(pfdev, TILER_PWRON_LO, pfdev->features.tiler_present); +- ret |= readl_relaxed_poll_timeout(pfdev->iomem + TILER_READY_LO, ++ ret = readl_relaxed_poll_timeout(pfdev->iomem + TILER_READY_LO, + val, val == pfdev->features.tiler_present, 100, 1000); + + if (ret) +- dev_err(pfdev->dev, "error powering up gpu"); ++ dev_err(pfdev->dev, "error powering up gpu tiler"); + } + + void panfrost_gpu_power_off(struct panfrost_device *pfdev) +-- +2.17.1 + + +From 96780fcbe44b27fda4c273d5b9b726dc4ba1ab5b Mon Sep 17 00:00:00 2001 +From: Nicolas Boichat +Date: Fri, 7 Feb 2020 13:26:24 +0800 +Subject: [PATCH] drm/panfrost: Add support for multiple regulators + +Some GPUs, namely, the bifrost/g72 part on MT8183, have a second +regulator for their SRAM, let's add support for that. + +We extend the framework in a generic manner so that we could +support more than 2 regulators, if required. + +Signed-off-by: Nicolas Boichat +Reviewed-by: Steven Price +Reviwed-by: Mark Brown +Signed-off-by: Rob Herring +--- + drivers/gpu/drm/panfrost/panfrost_device.c | 26 +++++++++++++------- + drivers/gpu/drm/panfrost/panfrost_device.h | 15 +++++++++++- + drivers/gpu/drm/panfrost/panfrost_drv.c | 28 +++++++++++++++------- + 3 files changed, 51 insertions(+), 18 deletions(-) + +diff --git a/drivers/gpu/drm/panfrost/panfrost_device.c b/drivers/gpu/drm/panfrost/panfrost_device.c +index 238fb6d54df4..3720d50f6d9f 100644 +--- a/drivers/gpu/drm/panfrost/panfrost_device.c ++++ b/drivers/gpu/drm/panfrost/panfrost_device.c +@@ -87,18 +87,27 @@ static void panfrost_clk_fini(struct panfrost_device *pfdev) + + static int panfrost_regulator_init(struct panfrost_device *pfdev) + { +- int ret; ++ int ret, i; + +- pfdev->regulator = devm_regulator_get(pfdev->dev, "mali"); +- if (IS_ERR(pfdev->regulator)) { +- ret = PTR_ERR(pfdev->regulator); +- dev_err(pfdev->dev, "failed to get regulator: %d\n", ret); ++ if (WARN(pfdev->comp->num_supplies > ARRAY_SIZE(pfdev->regulators), ++ "Too many supplies in compatible structure.\n")) ++ return -EINVAL; ++ ++ for (i = 0; i < pfdev->comp->num_supplies; i++) ++ pfdev->regulators[i].supply = pfdev->comp->supply_names[i]; ++ ++ ret = devm_regulator_bulk_get(pfdev->dev, ++ pfdev->comp->num_supplies, ++ pfdev->regulators); ++ if (ret < 0) { ++ dev_err(pfdev->dev, "failed to get regulators: %d\n", ret); + return ret; + } + +- ret = regulator_enable(pfdev->regulator); ++ ret = regulator_bulk_enable(pfdev->comp->num_supplies, ++ pfdev->regulators); + if (ret < 0) { +- dev_err(pfdev->dev, "failed to enable regulator: %d\n", ret); ++ dev_err(pfdev->dev, "failed to enable regulators: %d\n", ret); + return ret; + } + +@@ -107,7 +116,8 @@ static int panfrost_regulator_init(struct panfrost_device *pfdev) + + static void panfrost_regulator_fini(struct panfrost_device *pfdev) + { +- regulator_disable(pfdev->regulator); ++ regulator_bulk_disable(pfdev->comp->num_supplies, ++ pfdev->regulators); + } + + int panfrost_device_init(struct panfrost_device *pfdev) +diff --git a/drivers/gpu/drm/panfrost/panfrost_device.h b/drivers/gpu/drm/panfrost/panfrost_device.h +index 06713811b92c..c9468bc5573a 100644 +--- a/drivers/gpu/drm/panfrost/panfrost_device.h ++++ b/drivers/gpu/drm/panfrost/panfrost_device.h +@@ -7,6 +7,7 @@ + + #include + #include ++#include + #include + #include + #include +@@ -19,6 +20,7 @@ struct panfrost_job; + struct panfrost_perfcnt; + + #define NUM_JOB_SLOTS 3 ++#define MAX_REGULATORS 2 + + struct panfrost_features { + u16 id; +@@ -51,6 +53,16 @@ struct panfrost_features { + unsigned long hw_issues[64 / BITS_PER_LONG]; + }; + ++/* ++ * Features that cannot be automatically detected and need matching using the ++ * compatible string, typically SoC-specific. ++ */ ++struct panfrost_compatible { ++ /* Supplies count and names. */ ++ int num_supplies; ++ const char * const *supply_names; ++}; ++ + struct panfrost_device { + struct device *dev; + struct drm_device *ddev; +@@ -59,10 +71,11 @@ struct panfrost_device { + void __iomem *iomem; + struct clk *clock; + struct clk *bus_clock; +- struct regulator *regulator; ++ struct regulator_bulk_data regulators[MAX_REGULATORS]; + struct reset_control *rstc; + + struct panfrost_features features; ++ const struct panfrost_compatible *comp; + + spinlock_t as_lock; + unsigned long as_in_use_mask; +diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c b/drivers/gpu/drm/panfrost/panfrost_drv.c +index b7a618db3ee2..4d0850752623 100644 +--- a/drivers/gpu/drm/panfrost/panfrost_drv.c ++++ b/drivers/gpu/drm/panfrost/panfrost_drv.c +@@ -584,6 +584,10 @@ static int panfrost_probe(struct platform_device *pdev) + + platform_set_drvdata(pdev, pfdev); + ++ pfdev->comp = of_device_get_match_data(&pdev->dev); ++ if (!pfdev->comp) ++ return -ENODEV; ++ + /* Allocate and initialze the DRM device. */ + ddev = drm_dev_alloc(&panfrost_drm_driver, &pdev->dev); + if (IS_ERR(ddev)) +@@ -655,16 +659,22 @@ static int panfrost_remove(struct platform_device *pdev) + return 0; + } + ++const char * const default_supplies[] = { "mali" }; ++static const struct panfrost_compatible default_data = { ++ .num_supplies = ARRAY_SIZE(default_supplies), ++ .supply_names = default_supplies, ++}; ++ + static const struct of_device_id dt_match[] = { +- { .compatible = "arm,mali-t604" }, +- { .compatible = "arm,mali-t624" }, +- { .compatible = "arm,mali-t628" }, +- { .compatible = "arm,mali-t720" }, +- { .compatible = "arm,mali-t760" }, +- { .compatible = "arm,mali-t820" }, +- { .compatible = "arm,mali-t830" }, +- { .compatible = "arm,mali-t860" }, +- { .compatible = "arm,mali-t880" }, ++ { .compatible = "arm,mali-t604", .data = &default_data, }, ++ { .compatible = "arm,mali-t624", .data = &default_data, }, ++ { .compatible = "arm,mali-t628", .data = &default_data, }, ++ { .compatible = "arm,mali-t720", .data = &default_data, }, ++ { .compatible = "arm,mali-t760", .data = &default_data, }, ++ { .compatible = "arm,mali-t820", .data = &default_data, }, ++ { .compatible = "arm,mali-t830", .data = &default_data, }, ++ { .compatible = "arm,mali-t860", .data = &default_data, }, ++ { .compatible = "arm,mali-t880", .data = &default_data, }, + {} + }; + MODULE_DEVICE_TABLE(of, dt_match); +-- +2.17.1 + + +From 7de0cdd88c14fec1927a563e843fae6e6c79f6be Mon Sep 17 00:00:00 2001 +From: Nicolas Boichat +Date: Fri, 7 Feb 2020 13:26:25 +0800 +Subject: [PATCH] drm/panfrost: Add support for multiple power domains + +When there is a single power domain per device, the core will +ensure the power domain is switched on (so it is technically +equivalent to having not power domain specified at all). + +However, when there are multiple domains, as in MT8183 Bifrost +GPU, we need to handle them in driver code. + +Signed-off-by: Nicolas Boichat +Reviewed-by: Ulf Hansson +Reviewed-by: Steven Price +Signed-off-by: Rob Herring +--- + drivers/gpu/drm/panfrost/panfrost_device.c | 97 ++++++++++++++++++++-- + drivers/gpu/drm/panfrost/panfrost_device.h | 11 +++ + drivers/gpu/drm/panfrost/panfrost_drv.c | 2 + + 3 files changed, 102 insertions(+), 8 deletions(-) + +diff --git a/drivers/gpu/drm/panfrost/panfrost_device.c b/drivers/gpu/drm/panfrost/panfrost_device.c +index 3720d50f6d9f..8136babd3ba9 100644 +--- a/drivers/gpu/drm/panfrost/panfrost_device.c ++++ b/drivers/gpu/drm/panfrost/panfrost_device.c +@@ -5,6 +5,7 @@ + #include + #include + #include ++#include + #include + + #include "panfrost_device.h" +@@ -120,6 +121,79 @@ static void panfrost_regulator_fini(struct panfrost_device *pfdev) + pfdev->regulators); + } + ++static void panfrost_pm_domain_fini(struct panfrost_device *pfdev) ++{ ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(pfdev->pm_domain_devs); i++) { ++ if (!pfdev->pm_domain_devs[i]) ++ break; ++ ++ if (pfdev->pm_domain_links[i]) ++ device_link_del(pfdev->pm_domain_links[i]); ++ ++ dev_pm_domain_detach(pfdev->pm_domain_devs[i], true); ++ } ++} ++ ++static int panfrost_pm_domain_init(struct panfrost_device *pfdev) ++{ ++ int err; ++ int i, num_domains; ++ ++ num_domains = of_count_phandle_with_args(pfdev->dev->of_node, ++ "power-domains", ++ "#power-domain-cells"); ++ ++ /* ++ * Single domain is handled by the core, and, if only a single power ++ * the power domain is requested, the property is optional. ++ */ ++ if (num_domains < 2 && pfdev->comp->num_pm_domains < 2) ++ return 0; ++ ++ if (num_domains != pfdev->comp->num_pm_domains) { ++ dev_err(pfdev->dev, ++ "Incorrect number of power domains: %d provided, %d needed\n", ++ num_domains, pfdev->comp->num_pm_domains); ++ return -EINVAL; ++ } ++ ++ if (WARN(num_domains > ARRAY_SIZE(pfdev->pm_domain_devs), ++ "Too many supplies in compatible structure.\n")) ++ return -EINVAL; ++ ++ for (i = 0; i < num_domains; i++) { ++ pfdev->pm_domain_devs[i] = ++ dev_pm_domain_attach_by_name(pfdev->dev, ++ pfdev->comp->pm_domain_names[i]); ++ if (IS_ERR_OR_NULL(pfdev->pm_domain_devs[i])) { ++ err = PTR_ERR(pfdev->pm_domain_devs[i]) ? : -ENODATA; ++ pfdev->pm_domain_devs[i] = NULL; ++ dev_err(pfdev->dev, ++ "failed to get pm-domain %s(%d): %d\n", ++ pfdev->comp->pm_domain_names[i], i, err); ++ goto err; ++ } ++ ++ pfdev->pm_domain_links[i] = device_link_add(pfdev->dev, ++ pfdev->pm_domain_devs[i], DL_FLAG_PM_RUNTIME | ++ DL_FLAG_STATELESS | DL_FLAG_RPM_ACTIVE); ++ if (!pfdev->pm_domain_links[i]) { ++ dev_err(pfdev->pm_domain_devs[i], ++ "adding device link failed!\n"); ++ err = -ENODEV; ++ goto err; ++ } ++ } ++ ++ return 0; ++ ++err: ++ panfrost_pm_domain_fini(pfdev); ++ return err; ++} ++ + int panfrost_device_init(struct panfrost_device *pfdev) + { + int err; +@@ -150,37 +224,43 @@ int panfrost_device_init(struct panfrost_device *pfdev) + goto err_out1; + } + ++ err = panfrost_pm_domain_init(pfdev); ++ if (err) ++ goto err_out2; ++ + res = platform_get_resource(pfdev->pdev, IORESOURCE_MEM, 0); + pfdev->iomem = devm_ioremap_resource(pfdev->dev, res); + if (IS_ERR(pfdev->iomem)) { + dev_err(pfdev->dev, "failed to ioremap iomem\n"); + err = PTR_ERR(pfdev->iomem); +- goto err_out2; ++ goto err_out3; + } + + err = panfrost_gpu_init(pfdev); + if (err) +- goto err_out2; ++ goto err_out3; + + err = panfrost_mmu_init(pfdev); + if (err) +- goto err_out3; ++ goto err_out4; + + err = panfrost_job_init(pfdev); + if (err) +- goto err_out4; ++ goto err_out5; + + err = panfrost_perfcnt_init(pfdev); + if (err) +- goto err_out5; ++ goto err_out6; + + return 0; +-err_out5: ++err_out6: + panfrost_job_fini(pfdev); +-err_out4: ++err_out5: + panfrost_mmu_fini(pfdev); +-err_out3: ++err_out4: + panfrost_gpu_fini(pfdev); ++err_out3: ++ panfrost_pm_domain_fini(pfdev); + err_out2: + panfrost_reset_fini(pfdev); + err_out1: +@@ -196,6 +276,7 @@ void panfrost_device_fini(struct panfrost_device *pfdev) + panfrost_job_fini(pfdev); + panfrost_mmu_fini(pfdev); + panfrost_gpu_fini(pfdev); ++ panfrost_pm_domain_fini(pfdev); + panfrost_reset_fini(pfdev); + panfrost_regulator_fini(pfdev); + panfrost_clk_fini(pfdev); +diff --git a/drivers/gpu/drm/panfrost/panfrost_device.h b/drivers/gpu/drm/panfrost/panfrost_device.h +index c9468bc5573a..c30c719a8059 100644 +--- a/drivers/gpu/drm/panfrost/panfrost_device.h ++++ b/drivers/gpu/drm/panfrost/panfrost_device.h +@@ -21,6 +21,7 @@ struct panfrost_perfcnt; + + #define NUM_JOB_SLOTS 3 + #define MAX_REGULATORS 2 ++#define MAX_PM_DOMAINS 3 + + struct panfrost_features { + u16 id; +@@ -61,6 +62,13 @@ struct panfrost_compatible { + /* Supplies count and names. */ + int num_supplies; + const char * const *supply_names; ++ /* ++ * Number of power domains required, note that values 0 and 1 are ++ * handled identically, as only values > 1 need special handling. ++ */ ++ int num_pm_domains; ++ /* Only required if num_pm_domains > 1. */ ++ const char * const *pm_domain_names; + }; + + struct panfrost_device { +@@ -73,6 +81,9 @@ struct panfrost_device { + struct clk *bus_clock; + struct regulator_bulk_data regulators[MAX_REGULATORS]; + struct reset_control *rstc; ++ /* pm_domains for devices with more than one. */ ++ struct device *pm_domain_devs[MAX_PM_DOMAINS]; ++ struct device_link *pm_domain_links[MAX_PM_DOMAINS]; + + struct panfrost_features features; + const struct panfrost_compatible *comp; +diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c b/drivers/gpu/drm/panfrost/panfrost_drv.c +index 4d0850752623..a6e162236d67 100644 +--- a/drivers/gpu/drm/panfrost/panfrost_drv.c ++++ b/drivers/gpu/drm/panfrost/panfrost_drv.c +@@ -663,6 +663,8 @@ const char * const default_supplies[] = { "mali" }; + static const struct panfrost_compatible default_data = { + .num_supplies = ARRAY_SIZE(default_supplies), + .supply_names = default_supplies, ++ .num_pm_domains = 1, /* optional */ ++ .pm_domain_names = NULL, + }; + + static const struct of_device_id dt_match[] = { +-- +2.17.1 + + +From 4a210ebba6b01cb060a1de524d5d000981025b5b Mon Sep 17 00:00:00 2001 +From: kbuild test robot +Date: Thu, 27 Feb 2020 09:41:46 +0800 +Subject: [PATCH] drm/panfrost: default_supplies[] can be static + +Fixes: 3e1399bccf51 ("drm/panfrost: Add support for multiple regulators") +Signed-off-by: kbuild test robot +Reviewed-by: Nicolas Boichat +Signed-off-by: Rob Herring +--- + drivers/gpu/drm/panfrost/panfrost_drv.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c b/drivers/gpu/drm/panfrost/panfrost_drv.c +index a6e162236d67..882fecc33fdb 100644 +--- a/drivers/gpu/drm/panfrost/panfrost_drv.c ++++ b/drivers/gpu/drm/panfrost/panfrost_drv.c +@@ -659,7 +659,7 @@ static int panfrost_remove(struct platform_device *pdev) + return 0; + } + +-const char * const default_supplies[] = { "mali" }; ++static const char * const default_supplies[] = { "mali" }; + static const struct panfrost_compatible default_data = { + .num_supplies = ARRAY_SIZE(default_supplies), + .supply_names = default_supplies, +-- +2.17.1 + + +From 95695d5e36c49319b2cc6eabae04d32a13ca962e Mon Sep 17 00:00:00 2001 +From: Qiang Yu +Date: Sat, 22 Feb 2020 10:42:06 +0800 +Subject: [PATCH] drm/lima: save process info for debug usage + +When task fail, we can find its process with this information. + +Tested-by: Andreas Baierl +Reviewed-by: Vasily Khoruzhick +Signed-off-by: Qiang Yu +--- + drivers/gpu/drm/lima/lima_ctx.c | 3 +++ + drivers/gpu/drm/lima/lima_ctx.h | 5 +++++ + 2 files changed, 8 insertions(+) + +diff --git a/drivers/gpu/drm/lima/lima_ctx.c b/drivers/gpu/drm/lima/lima_ctx.c +index 22fff6caa961..891d5cd5019a 100644 +--- a/drivers/gpu/drm/lima/lima_ctx.c ++++ b/drivers/gpu/drm/lima/lima_ctx.c +@@ -27,6 +27,9 @@ int lima_ctx_create(struct lima_device *dev, struct lima_ctx_mgr *mgr, u32 *id) + if (err < 0) + goto err_out0; + ++ ctx->pid = task_pid_nr(current); ++ get_task_comm(ctx->pname, current); ++ + return 0; + + err_out0: +diff --git a/drivers/gpu/drm/lima/lima_ctx.h b/drivers/gpu/drm/lima/lima_ctx.h +index 6154e5c9bfe4..74e2be09090f 100644 +--- a/drivers/gpu/drm/lima/lima_ctx.h ++++ b/drivers/gpu/drm/lima/lima_ctx.h +@@ -5,6 +5,7 @@ + #define __LIMA_CTX_H__ + + #include ++#include + + #include "lima_device.h" + +@@ -13,6 +14,10 @@ struct lima_ctx { + struct lima_device *dev; + struct lima_sched_context context[lima_pipe_num]; + atomic_t guilty; ++ ++ /* debug info */ ++ char pname[TASK_COMM_LEN]; ++ pid_t pid; + }; + + struct lima_ctx_mgr { +-- +2.17.1 + + +From c70385c2415949d2a8eecdb3242b0e27fcc56c25 Mon Sep 17 00:00:00 2001 +From: Qiang Yu +Date: Sat, 22 Feb 2020 10:42:07 +0800 +Subject: [PATCH] drm/lima: add max_error_tasks module parameter + +Limit error tasks to save. + +Tested-by: Andreas Baierl +Reviewed-by: Vasily Khoruzhick +Signed-off-by: Qiang Yu +--- + drivers/gpu/drm/lima/lima_drv.c | 4 ++++ + drivers/gpu/drm/lima/lima_drv.h | 1 + + 2 files changed, 5 insertions(+) + +diff --git a/drivers/gpu/drm/lima/lima_drv.c b/drivers/gpu/drm/lima/lima_drv.c +index 2daac64d8955..e235d4545b6c 100644 +--- a/drivers/gpu/drm/lima/lima_drv.c ++++ b/drivers/gpu/drm/lima/lima_drv.c +@@ -16,6 +16,7 @@ + + int lima_sched_timeout_ms; + uint lima_heap_init_nr_pages = 8; ++uint lima_max_error_tasks; + + MODULE_PARM_DESC(sched_timeout_ms, "task run timeout in ms"); + module_param_named(sched_timeout_ms, lima_sched_timeout_ms, int, 0444); +@@ -23,6 +24,9 @@ module_param_named(sched_timeout_ms, lima_sched_timeout_ms, int, 0444); + MODULE_PARM_DESC(heap_init_nr_pages, "heap buffer init number of pages"); + module_param_named(heap_init_nr_pages, lima_heap_init_nr_pages, uint, 0444); + ++MODULE_PARM_DESC(max_error_tasks, "max number of error tasks to save"); ++module_param_named(max_error_tasks, lima_max_error_tasks, uint, 0644); ++ + static int lima_ioctl_get_param(struct drm_device *dev, void *data, struct drm_file *file) + { + struct drm_lima_get_param *args = data; +diff --git a/drivers/gpu/drm/lima/lima_drv.h b/drivers/gpu/drm/lima/lima_drv.h +index f492ecc6a5d9..fdbd4077c768 100644 +--- a/drivers/gpu/drm/lima/lima_drv.h ++++ b/drivers/gpu/drm/lima/lima_drv.h +@@ -10,6 +10,7 @@ + + extern int lima_sched_timeout_ms; + extern uint lima_heap_init_nr_pages; ++extern uint lima_max_error_tasks; + + struct lima_vm; + struct lima_bo; +-- +2.17.1 + + +From 3090b38955b4cb7c17b724fbdda56f5cab02e327 Mon Sep 17 00:00:00 2001 +From: Qiang Yu +Date: Sat, 7 Mar 2020 21:44:23 +0800 +Subject: [PATCH] drm/lima: save task info dump when task fail + +Save all information to start a task which can be exported to user +for debug usage. Dump file data format is specified in lima_dump.h + +v2: +Add include header to address build robot complain. + +Tested-by: Andreas Baierl +Reviewed-by: Vasily Khoruzhick +Signed-off-by: Qiang Yu +--- + drivers/gpu/drm/lima/lima_device.c | 13 +++ + drivers/gpu/drm/lima/lima_device.h | 8 ++ + drivers/gpu/drm/lima/lima_dump.h | 77 +++++++++++++++++ + drivers/gpu/drm/lima/lima_sched.c | 130 +++++++++++++++++++++++++++++ + drivers/gpu/drm/lima/lima_sched.h | 7 ++ + 5 files changed, 235 insertions(+) + create mode 100644 drivers/gpu/drm/lima/lima_dump.h + +diff --git a/drivers/gpu/drm/lima/lima_device.c b/drivers/gpu/drm/lima/lima_device.c +index 19829b543024..42a00171fea5 100644 +--- a/drivers/gpu/drm/lima/lima_device.c ++++ b/drivers/gpu/drm/lima/lima_device.c +@@ -344,6 +344,12 @@ int lima_device_init(struct lima_device *ldev) + if (err) + goto err_out5; + ++ ldev->dump.magic = LIMA_DUMP_MAGIC; ++ ldev->dump.version_major = LIMA_DUMP_MAJOR; ++ ldev->dump.version_minor = LIMA_DUMP_MINOR; ++ INIT_LIST_HEAD(&ldev->error_task_list); ++ mutex_init(&ldev->error_task_list_lock); ++ + dev_info(ldev->dev, "bus rate = %lu\n", clk_get_rate(ldev->clk_bus)); + dev_info(ldev->dev, "mod rate = %lu", clk_get_rate(ldev->clk_gpu)); + +@@ -370,6 +376,13 @@ int lima_device_init(struct lima_device *ldev) + void lima_device_fini(struct lima_device *ldev) + { + int i; ++ struct lima_sched_error_task *et, *tmp; ++ ++ list_for_each_entry_safe(et, tmp, &ldev->error_task_list, list) { ++ list_del(&et->list); ++ kvfree(et); ++ } ++ mutex_destroy(&ldev->error_task_list_lock); + + lima_fini_pp_pipe(ldev); + lima_fini_gp_pipe(ldev); +diff --git a/drivers/gpu/drm/lima/lima_device.h b/drivers/gpu/drm/lima/lima_device.h +index 31158d86271c..f17173f47f26 100644 +--- a/drivers/gpu/drm/lima/lima_device.h ++++ b/drivers/gpu/drm/lima/lima_device.h +@@ -6,8 +6,11 @@ + + #include + #include ++#include ++#include + + #include "lima_sched.h" ++#include "lima_dump.h" + + enum lima_gpu_id { + lima_gpu_mali400 = 0, +@@ -94,6 +97,11 @@ struct lima_device { + + u32 *dlbu_cpu; + dma_addr_t dlbu_dma; ++ ++ /* debug info */ ++ struct lima_dump_head dump; ++ struct list_head error_task_list; ++ struct mutex error_task_list_lock; + }; + + static inline struct lima_device * +diff --git a/drivers/gpu/drm/lima/lima_dump.h b/drivers/gpu/drm/lima/lima_dump.h +new file mode 100644 +index 000000000000..ca243d99c51b +--- /dev/null ++++ b/drivers/gpu/drm/lima/lima_dump.h +@@ -0,0 +1,77 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR MIT */ ++/* Copyright 2020 Qiang Yu */ ++ ++#ifndef __LIMA_DUMP_H__ ++#define __LIMA_DUMP_H__ ++ ++#include ++ ++/** ++ * dump file format for all the information to start a lima task ++ * ++ * top level format ++ * | magic code "LIMA" | format version | num tasks | data size | ++ * | reserved | reserved | reserved | reserved | ++ * | task 1 ID | task 1 size | num chunks | reserved | task 1 data | ++ * | task 2 ID | task 2 size | num chunks | reserved | task 2 data | ++ * ... ++ * ++ * task data format ++ * | chunk 1 ID | chunk 1 size | reserved | reserved | chunk 1 data | ++ * | chunk 2 ID | chunk 2 size | reserved | reserved | chunk 2 data | ++ * ... ++ * ++ */ ++ ++#define LIMA_DUMP_MAJOR 1 ++#define LIMA_DUMP_MINOR 0 ++ ++#define LIMA_DUMP_MAGIC 0x414d494c ++ ++struct lima_dump_head { ++ __u32 magic; ++ __u16 version_major; ++ __u16 version_minor; ++ __u32 num_tasks; ++ __u32 size; ++ __u32 reserved[4]; ++}; ++ ++#define LIMA_DUMP_TASK_GP 0 ++#define LIMA_DUMP_TASK_PP 1 ++#define LIMA_DUMP_TASK_NUM 2 ++ ++struct lima_dump_task { ++ __u32 id; ++ __u32 size; ++ __u32 num_chunks; ++ __u32 reserved; ++}; ++ ++#define LIMA_DUMP_CHUNK_FRAME 0 ++#define LIMA_DUMP_CHUNK_BUFFER 1 ++#define LIMA_DUMP_CHUNK_PROCESS_NAME 2 ++#define LIMA_DUMP_CHUNK_PROCESS_ID 3 ++#define LIMA_DUMP_CHUNK_NUM 4 ++ ++struct lima_dump_chunk { ++ __u32 id; ++ __u32 size; ++ __u32 reserved[2]; ++}; ++ ++struct lima_dump_chunk_buffer { ++ __u32 id; ++ __u32 size; ++ __u32 va; ++ __u32 reserved; ++}; ++ ++struct lima_dump_chunk_pid { ++ __u32 id; ++ __u32 size; ++ __u32 pid; ++ __u32 reserved; ++}; ++ ++#endif +diff --git a/drivers/gpu/drm/lima/lima_sched.c b/drivers/gpu/drm/lima/lima_sched.c +index 3886999b4533..86192422a689 100644 +--- a/drivers/gpu/drm/lima/lima_sched.c ++++ b/drivers/gpu/drm/lima/lima_sched.c +@@ -4,6 +4,7 @@ + #include + #include + #include ++#include + + #include "lima_drv.h" + #include "lima_sched.h" +@@ -256,6 +257,133 @@ static struct dma_fence *lima_sched_run_job(struct drm_sched_job *job) + return task->fence; + } + ++static void lima_sched_build_error_task_list(struct lima_sched_task *task) ++{ ++ struct lima_sched_error_task *et; ++ struct lima_sched_pipe *pipe = to_lima_pipe(task->base.sched); ++ struct lima_ip *ip = pipe->processor[0]; ++ int pipe_id = ip->id == lima_ip_gp ? lima_pipe_gp : lima_pipe_pp; ++ struct lima_device *dev = ip->dev; ++ struct lima_sched_context *sched_ctx = ++ container_of(task->base.entity, ++ struct lima_sched_context, base); ++ struct lima_ctx *ctx = ++ container_of(sched_ctx, struct lima_ctx, context[pipe_id]); ++ struct lima_dump_task *dt; ++ struct lima_dump_chunk *chunk; ++ struct lima_dump_chunk_pid *pid_chunk; ++ struct lima_dump_chunk_buffer *buffer_chunk; ++ u32 size, task_size, mem_size; ++ int i; ++ ++ mutex_lock(&dev->error_task_list_lock); ++ ++ if (dev->dump.num_tasks >= lima_max_error_tasks) { ++ dev_info(dev->dev, "fail to save task state: error task list is full\n"); ++ goto out; ++ } ++ ++ /* frame chunk */ ++ size = sizeof(struct lima_dump_chunk) + pipe->frame_size; ++ /* process name chunk */ ++ size += sizeof(struct lima_dump_chunk) + sizeof(ctx->pname); ++ /* pid chunk */ ++ size += sizeof(struct lima_dump_chunk); ++ /* buffer chunks */ ++ for (i = 0; i < task->num_bos; i++) { ++ struct lima_bo *bo = task->bos[i]; ++ ++ size += sizeof(struct lima_dump_chunk); ++ size += bo->heap_size ? bo->heap_size : lima_bo_size(bo); ++ } ++ ++ task_size = size + sizeof(struct lima_dump_task); ++ mem_size = task_size + sizeof(*et); ++ et = kvmalloc(mem_size, GFP_KERNEL); ++ if (!et) { ++ dev_err(dev->dev, "fail to alloc task dump buffer of size %x\n", ++ mem_size); ++ goto out; ++ } ++ ++ et->data = et + 1; ++ et->size = task_size; ++ ++ dt = et->data; ++ memset(dt, 0, sizeof(*dt)); ++ dt->id = pipe_id; ++ dt->size = size; ++ ++ chunk = (struct lima_dump_chunk *)(dt + 1); ++ memset(chunk, 0, sizeof(*chunk)); ++ chunk->id = LIMA_DUMP_CHUNK_FRAME; ++ chunk->size = pipe->frame_size; ++ memcpy(chunk + 1, task->frame, pipe->frame_size); ++ dt->num_chunks++; ++ ++ chunk = (void *)(chunk + 1) + chunk->size; ++ memset(chunk, 0, sizeof(*chunk)); ++ chunk->id = LIMA_DUMP_CHUNK_PROCESS_NAME; ++ chunk->size = sizeof(ctx->pname); ++ memcpy(chunk + 1, ctx->pname, sizeof(ctx->pname)); ++ dt->num_chunks++; ++ ++ pid_chunk = (void *)(chunk + 1) + chunk->size; ++ memset(pid_chunk, 0, sizeof(*pid_chunk)); ++ pid_chunk->id = LIMA_DUMP_CHUNK_PROCESS_ID; ++ pid_chunk->pid = ctx->pid; ++ dt->num_chunks++; ++ ++ buffer_chunk = (void *)(pid_chunk + 1) + pid_chunk->size; ++ for (i = 0; i < task->num_bos; i++) { ++ struct lima_bo *bo = task->bos[i]; ++ void *data; ++ ++ memset(buffer_chunk, 0, sizeof(*buffer_chunk)); ++ buffer_chunk->id = LIMA_DUMP_CHUNK_BUFFER; ++ buffer_chunk->va = lima_vm_get_va(task->vm, bo); ++ ++ if (bo->heap_size) { ++ buffer_chunk->size = bo->heap_size; ++ ++ data = vmap(bo->base.pages, bo->heap_size >> PAGE_SHIFT, ++ VM_MAP, pgprot_writecombine(PAGE_KERNEL)); ++ if (!data) { ++ kvfree(et); ++ goto out; ++ } ++ ++ memcpy(buffer_chunk + 1, data, buffer_chunk->size); ++ ++ vunmap(data); ++ } else { ++ buffer_chunk->size = lima_bo_size(bo); ++ ++ data = drm_gem_shmem_vmap(&bo->base.base); ++ if (IS_ERR_OR_NULL(data)) { ++ kvfree(et); ++ goto out; ++ } ++ ++ memcpy(buffer_chunk + 1, data, buffer_chunk->size); ++ ++ drm_gem_shmem_vunmap(&bo->base.base, data); ++ } ++ ++ buffer_chunk = (void *)(buffer_chunk + 1) + buffer_chunk->size; ++ dt->num_chunks++; ++ } ++ ++ list_add(&et->list, &dev->error_task_list); ++ dev->dump.size += et->size; ++ dev->dump.num_tasks++; ++ ++ dev_info(dev->dev, "save error task state success\n"); ++ ++out: ++ mutex_unlock(&dev->error_task_list_lock); ++} ++ + static void lima_sched_timedout_job(struct drm_sched_job *job) + { + struct lima_sched_pipe *pipe = to_lima_pipe(job->sched); +@@ -268,6 +396,8 @@ static void lima_sched_timedout_job(struct drm_sched_job *job) + + drm_sched_increase_karma(&task->base); + ++ lima_sched_build_error_task_list(task); ++ + pipe->task_error(pipe); + + if (pipe->bcast_mmu) +diff --git a/drivers/gpu/drm/lima/lima_sched.h b/drivers/gpu/drm/lima/lima_sched.h +index d64393fb50a9..a1496cb7bc41 100644 +--- a/drivers/gpu/drm/lima/lima_sched.h ++++ b/drivers/gpu/drm/lima/lima_sched.h +@@ -5,9 +5,16 @@ + #define __LIMA_SCHED_H__ + + #include ++#include + + struct lima_vm; + ++struct lima_sched_error_task { ++ struct list_head list; ++ void *data; ++ u32 size; ++}; ++ + struct lima_sched_task { + struct drm_sched_job base; + +-- +2.17.1 + + +From 3b95414439abca4e9129238481a36ee9025a8889 Mon Sep 17 00:00:00 2001 +From: Qiang Yu +Date: Sat, 22 Feb 2020 10:42:09 +0800 +Subject: [PATCH] drm/lima: add error sysfs to export error task dump + +Export /sys/class/drm/cardX/device/error sysfs for user read out +error task dump file. + +Tested-by: Andreas Baierl +Reviewed-by: Vasily Khoruzhick +Signed-off-by: Qiang Yu +--- + drivers/gpu/drm/lima/lima_drv.c | 94 +++++++++++++++++++++++++++++++++ + 1 file changed, 94 insertions(+) + +diff --git a/drivers/gpu/drm/lima/lima_drv.c b/drivers/gpu/drm/lima/lima_drv.c +index e235d4545b6c..97ed70c36340 100644 +--- a/drivers/gpu/drm/lima/lima_drv.c ++++ b/drivers/gpu/drm/lima/lima_drv.c +@@ -276,6 +276,93 @@ static struct drm_driver lima_drm_driver = { + .gem_prime_mmap = drm_gem_prime_mmap, + }; + ++struct lima_block_reader { ++ void *dst; ++ size_t base; ++ size_t count; ++ size_t off; ++ ssize_t read; ++}; ++ ++static bool lima_read_block(struct lima_block_reader *reader, ++ void *src, size_t src_size) ++{ ++ size_t max_off = reader->base + src_size; ++ ++ if (reader->off < max_off) { ++ size_t size = min_t(size_t, max_off - reader->off, ++ reader->count); ++ ++ memcpy(reader->dst, src + (reader->off - reader->base), size); ++ ++ reader->dst += size; ++ reader->off += size; ++ reader->read += size; ++ reader->count -= size; ++ } ++ ++ reader->base = max_off; ++ ++ return !!reader->count; ++} ++ ++static ssize_t lima_error_state_read(struct file *filp, struct kobject *kobj, ++ struct bin_attribute *attr, char *buf, ++ loff_t off, size_t count) ++{ ++ struct device *dev = kobj_to_dev(kobj); ++ struct lima_device *ldev = dev_get_drvdata(dev); ++ struct lima_sched_error_task *et; ++ struct lima_block_reader reader = { ++ .dst = buf, ++ .count = count, ++ .off = off, ++ }; ++ ++ mutex_lock(&ldev->error_task_list_lock); ++ ++ if (lima_read_block(&reader, &ldev->dump, sizeof(ldev->dump))) { ++ list_for_each_entry(et, &ldev->error_task_list, list) { ++ if (!lima_read_block(&reader, et->data, et->size)) ++ break; ++ } ++ } ++ ++ mutex_unlock(&ldev->error_task_list_lock); ++ return reader.read; ++} ++ ++static ssize_t lima_error_state_write(struct file *file, struct kobject *kobj, ++ struct bin_attribute *attr, char *buf, ++ loff_t off, size_t count) ++{ ++ struct device *dev = kobj_to_dev(kobj); ++ struct lima_device *ldev = dev_get_drvdata(dev); ++ struct lima_sched_error_task *et, *tmp; ++ ++ mutex_lock(&ldev->error_task_list_lock); ++ ++ list_for_each_entry_safe(et, tmp, &ldev->error_task_list, list) { ++ list_del(&et->list); ++ kvfree(et); ++ } ++ ++ ldev->dump.size = 0; ++ ldev->dump.num_tasks = 0; ++ ++ mutex_unlock(&ldev->error_task_list_lock); ++ ++ return count; ++} ++ ++static const struct bin_attribute lima_error_state_attr = { ++ .attr.name = "error", ++ .attr.mode = 0600, ++ .size = 0, ++ .read = lima_error_state_read, ++ .write = lima_error_state_write, ++}; ++ + static int lima_pdev_probe(struct platform_device *pdev) + { + struct lima_device *ldev; +@@ -318,6 +405,11 @@ static int lima_pdev_probe(struct platform_device *pdev) + if (err < 0) + goto err_out2; + ++ platform_set_drvdata(pdev, ldev); ++ ++ if (sysfs_create_bin_file(&ldev->dev->kobj, &lima_error_state_attr)) ++ dev_warn(ldev->dev, "fail to create error state sysfs\n"); ++ + return 0; + + err_out2: +@@ -334,6 +426,8 @@ static int lima_pdev_remove(struct platform_device *pdev) + struct lima_device *ldev = platform_get_drvdata(pdev); + struct drm_device *ddev = ldev->ddev; + ++ sysfs_remove_bin_file(&ldev->dev->kobj, &lima_error_state_attr); ++ platform_set_drvdata(pdev, NULL); + drm_dev_unregister(ddev); + lima_device_fini(ldev); + drm_dev_put(ddev); +-- +2.17.1 + + +From e58efe898da54ddc1148539961ef3aeefe19fc80 Mon Sep 17 00:00:00 2001 +From: Qiang Yu +Date: Sat, 7 Mar 2020 21:54:38 +0800 +Subject: [PATCH] drm/lima: add trace point for tasks + +track lima task start which can be combined with +dma_fence_signal to identify task execution time. + +example command to record: + +trace-cmd record -i \ + -e "lima:lima_task_submit" -e "lima:lima_task_run" \ + -e "*fence:*fence_signaled" -e "drm:drm_vblank_event" \ + -e "drm:drm_vblank_event_queued" sleep 4 + +Reviewed-by: Vasily Khoruzhick +Signed-off-by: Qiang Yu +--- + drivers/gpu/drm/lima/Makefile | 3 +- + drivers/gpu/drm/lima/lima_sched.c | 5 +++- + drivers/gpu/drm/lima/lima_sched.h | 1 + + drivers/gpu/drm/lima/lima_trace.c | 7 +++++ + drivers/gpu/drm/lima/lima_trace.h | 50 +++++++++++++++++++++++++++++++ + 5 files changed, 64 insertions(+), 2 deletions(-) + create mode 100644 drivers/gpu/drm/lima/lima_trace.c + create mode 100644 drivers/gpu/drm/lima/lima_trace.h + +diff --git a/drivers/gpu/drm/lima/Makefile b/drivers/gpu/drm/lima/Makefile +index a85444b0a1d4..6e7b788408e8 100644 +--- a/drivers/gpu/drm/lima/Makefile ++++ b/drivers/gpu/drm/lima/Makefile +@@ -14,6 +14,7 @@ lima-y := \ + lima_sched.o \ + lima_ctx.o \ + lima_dlbu.o \ +- lima_bcast.o ++ lima_bcast.o \ ++ lima_trace.o + + obj-$(CONFIG_DRM_LIMA) += lima.o +diff --git a/drivers/gpu/drm/lima/lima_sched.c b/drivers/gpu/drm/lima/lima_sched.c +index 86192422a689..4fbf2c489507 100644 +--- a/drivers/gpu/drm/lima/lima_sched.c ++++ b/drivers/gpu/drm/lima/lima_sched.c +@@ -3,7 +3,6 @@ + + #include + #include +-#include + #include + + #include "lima_drv.h" +@@ -12,6 +11,7 @@ + #include "lima_mmu.h" + #include "lima_l2_cache.h" + #include "lima_gem.h" ++#include "lima_trace.h" + + struct lima_fence { + struct dma_fence base; +@@ -177,6 +177,7 @@ struct dma_fence *lima_sched_context_queue_task(struct lima_sched_context *conte + { + struct dma_fence *fence = dma_fence_get(&task->base.s_fence->finished); + ++ trace_lima_task_submit(task); + drm_sched_entity_push_job(&task->base, &context->base); + return fence; + } +@@ -251,6 +252,8 @@ static struct dma_fence *lima_sched_run_job(struct drm_sched_job *job) + if (last_vm) + lima_vm_put(last_vm); + ++ trace_lima_task_run(task); ++ + pipe->error = false; + pipe->task_run(pipe, task); + +diff --git a/drivers/gpu/drm/lima/lima_sched.h b/drivers/gpu/drm/lima/lima_sched.h +index a1496cb7bc41..02dfa14d7083 100644 +--- a/drivers/gpu/drm/lima/lima_sched.h ++++ b/drivers/gpu/drm/lima/lima_sched.h +@@ -6,6 +6,7 @@ + + #include + #include ++#include + + struct lima_vm; + +diff --git a/drivers/gpu/drm/lima/lima_trace.c b/drivers/gpu/drm/lima/lima_trace.c +new file mode 100644 +index 000000000000..ea1c7289bebc +--- /dev/null ++++ b/drivers/gpu/drm/lima/lima_trace.c +@@ -0,0 +1,7 @@ ++// SPDX-License-Identifier: GPL-2.0 OR MIT ++/* Copyright 2020 Qiang Yu */ ++ ++#include "lima_sched.h" ++ ++#define CREATE_TRACE_POINTS ++#include "lima_trace.h" +diff --git a/drivers/gpu/drm/lima/lima_trace.h b/drivers/gpu/drm/lima/lima_trace.h +new file mode 100644 +index 000000000000..3a430e93d384 +--- /dev/null ++++ b/drivers/gpu/drm/lima/lima_trace.h +@@ -0,0 +1,50 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR MIT */ ++/* Copyright 2020 Qiang Yu */ ++ ++#if !defined(_LIMA_TRACE_H) || defined(TRACE_HEADER_MULTI_READ) ++#define _LIMA_TRACE_H_ ++ ++#include ++ ++#undef TRACE_SYSTEM ++#define TRACE_SYSTEM lima ++#define TRACE_INCLUDE_FILE lima_trace ++ ++DECLARE_EVENT_CLASS(lima_task, ++ TP_PROTO(struct lima_sched_task *task), ++ TP_ARGS(task), ++ TP_STRUCT__entry( ++ __field(uint64_t, task_id) ++ __field(unsigned int, context) ++ __field(unsigned int, seqno) ++ __string(pipe, task->base.sched->name) ++ ), ++ ++ TP_fast_assign( ++ __entry->task_id = task->base.id; ++ __entry->context = task->base.s_fence->finished.context; ++ __entry->seqno = task->base.s_fence->finished.seqno; ++ __assign_str(pipe, task->base.sched->name) ++ ), ++ ++ TP_printk("task=%llu, context=%u seqno=%u pipe=%s", ++ __entry->task_id, __entry->context, __entry->seqno, ++ __get_str(pipe)) ++); ++ ++DEFINE_EVENT(lima_task, lima_task_submit, ++ TP_PROTO(struct lima_sched_task *task), ++ TP_ARGS(task) ++); ++ ++DEFINE_EVENT(lima_task, lima_task_run, ++ TP_PROTO(struct lima_sched_task *task), ++ TP_ARGS(task) ++); ++ ++#endif ++ ++/* This part must be outside protection */ ++#undef TRACE_INCLUDE_PATH ++#define TRACE_INCLUDE_PATH ../../drivers/gpu/drm/lima ++#include +-- +2.17.1 + + +From f567d140f87225a04ba6c6035b4a0b79e816f9a9 Mon Sep 17 00:00:00 2001 +From: Martin Blumenstingl +Date: Thu, 19 Mar 2020 21:34:27 +0100 +Subject: [PATCH] drm/lima: Add optional devfreq and cooling device support + +Most platforms with a Mali-400 or Mali-450 GPU also have support for +changing the GPU clock frequency. Add devfreq support so the GPU clock +rate is updated based on the actual GPU usage when the +"operating-points-v2" property is present in the board.dts. + +The actual devfreq code is taken from panfrost_devfreq.c and modified so +it matches what the lima hardware needs: +- a call to dev_pm_opp_set_clkname() during initialization because there + are two clocks on Mali-4x0 IPs. "core" is the one that actually clocks + the GPU so we need to control it using devfreq. +- locking when reading or writing the devfreq statistics because (unlike + than panfrost) we have multiple PP and GP IRQs which may finish jobs + concurrently. + +Signed-off-by: Martin Blumenstingl +Signed-off-by: Qiang Yu +--- + drivers/gpu/drm/lima/Kconfig | 2 + + drivers/gpu/drm/lima/Makefile | 3 +- + drivers/gpu/drm/lima/lima_devfreq.c | 234 ++++++++++++++++++++++++++++ + drivers/gpu/drm/lima/lima_devfreq.h | 41 +++++ + drivers/gpu/drm/lima/lima_device.c | 4 + + drivers/gpu/drm/lima/lima_device.h | 3 + + drivers/gpu/drm/lima/lima_drv.c | 14 +- + drivers/gpu/drm/lima/lima_sched.c | 7 + + drivers/gpu/drm/lima/lima_sched.h | 3 + + 9 files changed, 308 insertions(+), 3 deletions(-) + create mode 100644 drivers/gpu/drm/lima/lima_devfreq.c + create mode 100644 drivers/gpu/drm/lima/lima_devfreq.h + +diff --git a/drivers/gpu/drm/lima/Kconfig b/drivers/gpu/drm/lima/Kconfig +index d589f09d04d9..fa1d4f5df31e 100644 +--- a/drivers/gpu/drm/lima/Kconfig ++++ b/drivers/gpu/drm/lima/Kconfig +@@ -10,5 +10,7 @@ config DRM_LIMA + depends on OF + select DRM_SCHED + select DRM_GEM_SHMEM_HELPER ++ select PM_DEVFREQ ++ select DEVFREQ_GOV_SIMPLE_ONDEMAND + help + DRM driver for ARM Mali 400/450 GPUs. +diff --git a/drivers/gpu/drm/lima/Makefile b/drivers/gpu/drm/lima/Makefile +index 6e7b788408e8..ca2097b8e1ad 100644 +--- a/drivers/gpu/drm/lima/Makefile ++++ b/drivers/gpu/drm/lima/Makefile +@@ -15,6 +15,7 @@ lima-y := \ + lima_ctx.o \ + lima_dlbu.o \ + lima_bcast.o \ +- lima_trace.o ++ lima_trace.o \ ++ lima_devfreq.o + + obj-$(CONFIG_DRM_LIMA) += lima.o +diff --git a/drivers/gpu/drm/lima/lima_devfreq.c b/drivers/gpu/drm/lima/lima_devfreq.c +new file mode 100644 +index 000000000000..8c4d21d07529 +--- /dev/null ++++ b/drivers/gpu/drm/lima/lima_devfreq.c +@@ -0,0 +1,234 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright 2020 Martin Blumenstingl ++ * ++ * Based on panfrost_devfreq.c: ++ * Copyright 2019 Collabora ltd. ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "lima_device.h" ++#include "lima_devfreq.h" ++ ++static void lima_devfreq_update_utilization(struct lima_devfreq *devfreq) ++{ ++ ktime_t now, last; ++ ++ now = ktime_get(); ++ last = devfreq->time_last_update; ++ ++ if (devfreq->busy_count > 0) ++ devfreq->busy_time += ktime_sub(now, last); ++ else ++ devfreq->idle_time += ktime_sub(now, last); ++ ++ devfreq->time_last_update = now; ++} ++ ++static int lima_devfreq_target(struct device *dev, unsigned long *freq, ++ u32 flags) ++{ ++ struct dev_pm_opp *opp; ++ int err; ++ ++ opp = devfreq_recommended_opp(dev, freq, flags); ++ if (IS_ERR(opp)) ++ return PTR_ERR(opp); ++ dev_pm_opp_put(opp); ++ ++ err = dev_pm_opp_set_rate(dev, *freq); ++ if (err) ++ return err; ++ ++ return 0; ++} ++ ++static void lima_devfreq_reset(struct lima_devfreq *devfreq) ++{ ++ devfreq->busy_time = 0; ++ devfreq->idle_time = 0; ++ devfreq->time_last_update = ktime_get(); ++} ++ ++static int lima_devfreq_get_dev_status(struct device *dev, ++ struct devfreq_dev_status *status) ++{ ++ struct lima_device *ldev = dev_get_drvdata(dev); ++ struct lima_devfreq *devfreq = &ldev->devfreq; ++ unsigned long irqflags; ++ ++ status->current_frequency = clk_get_rate(ldev->clk_gpu); ++ ++ spin_lock_irqsave(&devfreq->lock, irqflags); ++ ++ lima_devfreq_update_utilization(devfreq); ++ ++ status->total_time = ktime_to_ns(ktime_add(devfreq->busy_time, ++ devfreq->idle_time)); ++ status->busy_time = ktime_to_ns(devfreq->busy_time); ++ ++ lima_devfreq_reset(devfreq); ++ ++ spin_unlock_irqrestore(&devfreq->lock, irqflags); ++ ++ dev_dbg(ldev->dev, "busy %lu total %lu %lu %% freq %lu MHz\n", ++ status->busy_time, status->total_time, ++ status->busy_time / (status->total_time / 100), ++ status->current_frequency / 1000 / 1000); ++ ++ return 0; ++} ++ ++static struct devfreq_dev_profile lima_devfreq_profile = { ++ .polling_ms = 50, /* ~3 frames */ ++ .target = lima_devfreq_target, ++ .get_dev_status = lima_devfreq_get_dev_status, ++}; ++ ++void lima_devfreq_fini(struct lima_device *ldev) ++{ ++ struct lima_devfreq *devfreq = &ldev->devfreq; ++ ++ if (devfreq->cooling) { ++ devfreq_cooling_unregister(devfreq->cooling); ++ devfreq->cooling = NULL; ++ } ++ ++ if (devfreq->devfreq) { ++ devm_devfreq_remove_device(&ldev->pdev->dev, ++ devfreq->devfreq); ++ devfreq->devfreq = NULL; ++ } ++ ++ if (devfreq->opp_of_table_added) { ++ dev_pm_opp_of_remove_table(&ldev->pdev->dev); ++ devfreq->opp_of_table_added = false; ++ } ++ ++ if (devfreq->regulators_opp_table) { ++ dev_pm_opp_put_regulators(devfreq->regulators_opp_table); ++ devfreq->regulators_opp_table = NULL; ++ } ++ ++ if (devfreq->clkname_opp_table) { ++ dev_pm_opp_put_clkname(devfreq->clkname_opp_table); ++ devfreq->clkname_opp_table = NULL; ++ } ++} ++ ++int lima_devfreq_init(struct lima_device *ldev) ++{ ++ struct thermal_cooling_device *cooling; ++ struct device *dev = &ldev->pdev->dev; ++ struct opp_table *opp_table; ++ struct devfreq *devfreq; ++ struct lima_devfreq *ldevfreq = &ldev->devfreq; ++ struct dev_pm_opp *opp; ++ unsigned long cur_freq; ++ int ret; ++ ++ if (!device_property_present(dev, "operating-points-v2")) ++ /* Optional, continue without devfreq */ ++ return 0; ++ ++ spin_lock_init(&ldevfreq->lock); ++ ++ opp_table = dev_pm_opp_set_clkname(dev, "core"); ++ if (IS_ERR(opp_table)) { ++ ret = PTR_ERR(opp_table); ++ goto err_fini; ++ } ++ ++ ldevfreq->clkname_opp_table = opp_table; ++ ++ opp_table = dev_pm_opp_set_regulators(dev, ++ (const char *[]){ "mali" }, ++ 1); ++ if (IS_ERR(opp_table)) { ++ ret = PTR_ERR(opp_table); ++ ++ /* Continue if the optional regulator is missing */ ++ if (ret != -ENODEV) ++ goto err_fini; ++ } else { ++ ldevfreq->regulators_opp_table = opp_table; ++ } ++ ++ ret = dev_pm_opp_of_add_table(dev); ++ if (ret) ++ goto err_fini; ++ ldevfreq->opp_of_table_added = true; ++ ++ lima_devfreq_reset(ldevfreq); ++ ++ cur_freq = clk_get_rate(ldev->clk_gpu); ++ ++ opp = devfreq_recommended_opp(dev, &cur_freq, 0); ++ if (IS_ERR(opp)) { ++ ret = PTR_ERR(opp); ++ goto err_fini; ++ } ++ ++ lima_devfreq_profile.initial_freq = cur_freq; ++ dev_pm_opp_put(opp); ++ ++ devfreq = devm_devfreq_add_device(dev, &lima_devfreq_profile, ++ DEVFREQ_GOV_SIMPLE_ONDEMAND, NULL); ++ if (IS_ERR(devfreq)) { ++ dev_err(dev, "Couldn't initialize GPU devfreq\n"); ++ ret = PTR_ERR(devfreq); ++ goto err_fini; ++ } ++ ++ ldevfreq->devfreq = devfreq; ++ ++ cooling = of_devfreq_cooling_register(dev->of_node, devfreq); ++ if (IS_ERR(cooling)) ++ dev_info(dev, "Failed to register cooling device\n"); ++ else ++ ldevfreq->cooling = cooling; ++ ++ return 0; ++ ++err_fini: ++ lima_devfreq_fini(ldev); ++ return ret; ++} ++ ++void lima_devfreq_record_busy(struct lima_devfreq *devfreq) ++{ ++ unsigned long irqflags; ++ ++ if (!devfreq->devfreq) ++ return; ++ ++ spin_lock_irqsave(&devfreq->lock, irqflags); ++ ++ lima_devfreq_update_utilization(devfreq); ++ ++ devfreq->busy_count++; ++ ++ spin_unlock_irqrestore(&devfreq->lock, irqflags); ++} ++ ++void lima_devfreq_record_idle(struct lima_devfreq *devfreq) ++{ ++ unsigned long irqflags; ++ ++ if (!devfreq->devfreq) ++ return; ++ ++ spin_lock_irqsave(&devfreq->lock, irqflags); ++ ++ lima_devfreq_update_utilization(devfreq); ++ ++ WARN_ON(--devfreq->busy_count < 0); ++ ++ spin_unlock_irqrestore(&devfreq->lock, irqflags); ++} +diff --git a/drivers/gpu/drm/lima/lima_devfreq.h b/drivers/gpu/drm/lima/lima_devfreq.h +new file mode 100644 +index 000000000000..8d71ba9fb22a +--- /dev/null ++++ b/drivers/gpu/drm/lima/lima_devfreq.h +@@ -0,0 +1,41 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++/* Copyright 2020 Martin Blumenstingl */ ++ ++#ifndef __LIMA_DEVFREQ_H__ ++#define __LIMA_DEVFREQ_H__ ++ ++#include ++#include ++ ++struct devfreq; ++struct opp_table; ++struct thermal_cooling_device; ++ ++struct lima_device; ++ ++struct lima_devfreq { ++ struct devfreq *devfreq; ++ struct opp_table *clkname_opp_table; ++ struct opp_table *regulators_opp_table; ++ struct thermal_cooling_device *cooling; ++ bool opp_of_table_added; ++ ++ ktime_t busy_time; ++ ktime_t idle_time; ++ ktime_t time_last_update; ++ int busy_count; ++ /* ++ * Protect busy_time, idle_time, time_last_update and busy_count ++ * because these can be updated concurrently, for example by the GP ++ * and PP interrupts. ++ */ ++ spinlock_t lock; ++}; ++ ++int lima_devfreq_init(struct lima_device *ldev); ++void lima_devfreq_fini(struct lima_device *ldev); ++ ++void lima_devfreq_record_busy(struct lima_devfreq *devfreq); ++void lima_devfreq_record_idle(struct lima_devfreq *devfreq); ++ ++#endif +diff --git a/drivers/gpu/drm/lima/lima_device.c b/drivers/gpu/drm/lima/lima_device.c +index 42a00171fea5..247f51fd40a2 100644 +--- a/drivers/gpu/drm/lima/lima_device.c ++++ b/drivers/gpu/drm/lima/lima_device.c +@@ -214,6 +214,8 @@ static int lima_init_gp_pipe(struct lima_device *dev) + struct lima_sched_pipe *pipe = dev->pipe + lima_pipe_gp; + int err; + ++ pipe->ldev = dev; ++ + err = lima_sched_pipe_init(pipe, "gp"); + if (err) + return err; +@@ -244,6 +246,8 @@ static int lima_init_pp_pipe(struct lima_device *dev) + struct lima_sched_pipe *pipe = dev->pipe + lima_pipe_pp; + int err, i; + ++ pipe->ldev = dev; ++ + err = lima_sched_pipe_init(pipe, "pp"); + if (err) + return err; +diff --git a/drivers/gpu/drm/lima/lima_device.h b/drivers/gpu/drm/lima/lima_device.h +index f17173f47f26..06fd9636dd72 100644 +--- a/drivers/gpu/drm/lima/lima_device.h ++++ b/drivers/gpu/drm/lima/lima_device.h +@@ -11,6 +11,7 @@ + + #include "lima_sched.h" + #include "lima_dump.h" ++#include "lima_devfreq.h" + + enum lima_gpu_id { + lima_gpu_mali400 = 0, +@@ -98,6 +99,8 @@ struct lima_device { + u32 *dlbu_cpu; + dma_addr_t dlbu_dma; + ++ struct lima_devfreq devfreq; ++ + /* debug info */ + struct lima_dump_head dump; + struct list_head error_task_list; +diff --git a/drivers/gpu/drm/lima/lima_drv.c b/drivers/gpu/drm/lima/lima_drv.c +index 97ed70c36340..bbbdc8455e2f 100644 +--- a/drivers/gpu/drm/lima/lima_drv.c ++++ b/drivers/gpu/drm/lima/lima_drv.c +@@ -10,6 +10,7 @@ + #include + #include + ++#include "lima_device.h" + #include "lima_drv.h" + #include "lima_gem.h" + #include "lima_vm.h" +@@ -397,13 +398,19 @@ static int lima_pdev_probe(struct platform_device *pdev) + if (err) + goto err_out1; + ++ err = lima_devfreq_init(ldev); ++ if (err) { ++ dev_err(&pdev->dev, "Fatal error during devfreq init\n"); ++ goto err_out2; ++ } ++ + /* + * Register the DRM device with the core and the connectors with + * sysfs. + */ + err = drm_dev_register(ddev, 0); + if (err < 0) +- goto err_out2; ++ goto err_out3; + + platform_set_drvdata(pdev, ldev); + +@@ -412,8 +419,10 @@ static int lima_pdev_probe(struct platform_device *pdev) + + return 0; + +-err_out2: ++err_out3: + lima_device_fini(ldev); ++err_out2: ++ lima_devfreq_fini(ldev); + err_out1: + drm_dev_put(ddev); + err_out0: +@@ -429,6 +438,7 @@ static int lima_pdev_remove(struct platform_device *pdev) + sysfs_remove_bin_file(&ldev->dev->kobj, &lima_error_state_attr); + platform_set_drvdata(pdev, NULL); + drm_dev_unregister(ddev); ++ lima_devfreq_fini(ldev); + lima_device_fini(ldev); + drm_dev_put(ddev); + lima_sched_slab_fini(); +diff --git a/drivers/gpu/drm/lima/lima_sched.c b/drivers/gpu/drm/lima/lima_sched.c +index 4fbf2c489507..a2db1c937424 100644 +--- a/drivers/gpu/drm/lima/lima_sched.c ++++ b/drivers/gpu/drm/lima/lima_sched.c +@@ -5,6 +5,7 @@ + #include + #include + ++#include "lima_devfreq.h" + #include "lima_drv.h" + #include "lima_sched.h" + #include "lima_vm.h" +@@ -216,6 +217,8 @@ static struct dma_fence *lima_sched_run_job(struct drm_sched_job *job) + */ + ret = dma_fence_get(task->fence); + ++ lima_devfreq_record_busy(&pipe->ldev->devfreq); ++ + pipe->current_task = task; + + /* this is needed for MMU to work correctly, otherwise GP/PP +@@ -418,6 +421,8 @@ static void lima_sched_timedout_job(struct drm_sched_job *job) + pipe->current_vm = NULL; + pipe->current_task = NULL; + ++ lima_devfreq_record_idle(&pipe->ldev->devfreq); ++ + drm_sched_resubmit_jobs(&pipe->base); + drm_sched_start(&pipe->base, true); + } +@@ -497,5 +502,7 @@ void lima_sched_pipe_task_done(struct lima_sched_pipe *pipe) + } else { + pipe->task_fini(pipe); + dma_fence_signal(task->fence); ++ ++ lima_devfreq_record_idle(&pipe->ldev->devfreq); + } + } +diff --git a/drivers/gpu/drm/lima/lima_sched.h b/drivers/gpu/drm/lima/lima_sched.h +index 02dfa14d7083..90f03c48ef4a 100644 +--- a/drivers/gpu/drm/lima/lima_sched.h ++++ b/drivers/gpu/drm/lima/lima_sched.h +@@ -8,6 +8,7 @@ + #include + #include + ++struct lima_device; + struct lima_vm; + + struct lima_sched_error_task { +@@ -52,6 +53,8 @@ struct lima_sched_pipe { + u32 fence_seqno; + spinlock_t fence_lock; + ++ struct lima_device *ldev; ++ + struct lima_sched_task *current_task; + struct lima_vm *current_vm; + +-- +2.17.1 + + +From 60e8ac9f8b772f5f3cbab5e361531d625444a320 Mon Sep 17 00:00:00 2001 +From: Robin Murphy +Date: Tue, 21 Apr 2020 23:51:36 +0100 +Subject: [PATCH] drm/lima: Clean up IRQ warnings + +Use the optional form of platform_get_irq() for blocks that legitimately +may not be present, to avoid getting an annoying barrage of spurious +warnings for non-existent PPs on configurations like Mali-450 MP2. + +Signed-off-by: Robin Murphy +Signed-off-by: Qiang Yu +--- + drivers/gpu/drm/lima/lima_device.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/lima/lima_device.c b/drivers/gpu/drm/lima/lima_device.c +index 247f51fd40a2..c334d297796a 100644 +--- a/drivers/gpu/drm/lima/lima_device.c ++++ b/drivers/gpu/drm/lima/lima_device.c +@@ -171,8 +171,10 @@ static void lima_regulator_fini(struct lima_device *dev) + + static int lima_init_ip(struct lima_device *dev, int index) + { ++ struct platform_device *pdev = to_platform_device(dev->dev); + struct lima_ip_desc *desc = lima_ip_desc + index; + struct lima_ip *ip = dev->ip + index; ++ const char *irq_name = desc->irq_name; + int offset = desc->offset[dev->id]; + bool must = desc->must_have[dev->id]; + int err; +@@ -183,8 +185,9 @@ static int lima_init_ip(struct lima_device *dev, int index) + ip->dev = dev; + ip->id = index; + ip->iomem = dev->iomem + offset; +- if (desc->irq_name) { +- err = platform_get_irq_byname(dev->pdev, desc->irq_name); ++ if (irq_name) { ++ err = must ? platform_get_irq_byname(pdev, irq_name) : ++ platform_get_irq_byname_optional(pdev, irq_name); + if (err < 0) + goto out; + ip->irq = err; +-- +2.17.1 + + +From 8bb48350b7a927e98b59299ba82c4231fef9816c Mon Sep 17 00:00:00 2001 +From: Robin Murphy +Date: Tue, 21 Apr 2020 23:51:37 +0100 +Subject: [PATCH] drm/lima: Clean up redundant pdev pointer + +There's no point explicitly tracking the platform device when it can be +trivially derived from the regular device pointer in the couple of +places it's ever used. + +Signed-off-by: Robin Murphy +Signed-off-by: Qiang Yu +--- + drivers/gpu/drm/lima/lima_devfreq.c | 7 +++---- + drivers/gpu/drm/lima/lima_device.c | 5 ++--- + drivers/gpu/drm/lima/lima_device.h | 1 - + drivers/gpu/drm/lima/lima_drv.c | 1 - + 4 files changed, 5 insertions(+), 9 deletions(-) + +diff --git a/drivers/gpu/drm/lima/lima_devfreq.c b/drivers/gpu/drm/lima/lima_devfreq.c +index 8c4d21d07529..1d479b5924fe 100644 +--- a/drivers/gpu/drm/lima/lima_devfreq.c ++++ b/drivers/gpu/drm/lima/lima_devfreq.c +@@ -101,13 +101,12 @@ void lima_devfreq_fini(struct lima_device *ldev) + } + + if (devfreq->devfreq) { +- devm_devfreq_remove_device(&ldev->pdev->dev, +- devfreq->devfreq); ++ devm_devfreq_remove_device(ldev->dev, devfreq->devfreq); + devfreq->devfreq = NULL; + } + + if (devfreq->opp_of_table_added) { +- dev_pm_opp_of_remove_table(&ldev->pdev->dev); ++ dev_pm_opp_of_remove_table(ldev->dev); + devfreq->opp_of_table_added = false; + } + +@@ -125,7 +124,7 @@ void lima_devfreq_fini(struct lima_device *ldev) + int lima_devfreq_init(struct lima_device *ldev) + { + struct thermal_cooling_device *cooling; +- struct device *dev = &ldev->pdev->dev; ++ struct device *dev = ldev->dev; + struct opp_table *opp_table; + struct devfreq *devfreq; + struct lima_devfreq *ldevfreq = &ldev->devfreq; +diff --git a/drivers/gpu/drm/lima/lima_device.c b/drivers/gpu/drm/lima/lima_device.c +index c334d297796a..29285dedd124 100644 +--- a/drivers/gpu/drm/lima/lima_device.c ++++ b/drivers/gpu/drm/lima/lima_device.c +@@ -297,8 +297,8 @@ static void lima_fini_pp_pipe(struct lima_device *dev) + + int lima_device_init(struct lima_device *ldev) + { ++ struct platform_device *pdev = to_platform_device(ldev->dev); + int err, i; +- struct resource *res; + + dma_set_coherent_mask(ldev->dev, DMA_BIT_MASK(32)); + +@@ -329,8 +329,7 @@ int lima_device_init(struct lima_device *ldev) + } else + ldev->va_end = LIMA_VA_RESERVE_END; + +- res = platform_get_resource(ldev->pdev, IORESOURCE_MEM, 0); +- ldev->iomem = devm_ioremap_resource(ldev->dev, res); ++ ldev->iomem = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(ldev->iomem)) { + dev_err(ldev->dev, "fail to ioremap iomem\n"); + err = PTR_ERR(ldev->iomem); +diff --git a/drivers/gpu/drm/lima/lima_device.h b/drivers/gpu/drm/lima/lima_device.h +index 06fd9636dd72..99b1fb147dad 100644 +--- a/drivers/gpu/drm/lima/lima_device.h ++++ b/drivers/gpu/drm/lima/lima_device.h +@@ -76,7 +76,6 @@ enum lima_pipe_id { + struct lima_device { + struct device *dev; + struct drm_device *ddev; +- struct platform_device *pdev; + + enum lima_gpu_id id; + u32 gp_version; +diff --git a/drivers/gpu/drm/lima/lima_drv.c b/drivers/gpu/drm/lima/lima_drv.c +index bbbdc8455e2f..4e5dd75822c0 100644 +--- a/drivers/gpu/drm/lima/lima_drv.c ++++ b/drivers/gpu/drm/lima/lima_drv.c +@@ -380,7 +380,6 @@ static int lima_pdev_probe(struct platform_device *pdev) + goto err_out0; + } + +- ldev->pdev = pdev; + ldev->dev = &pdev->dev; + ldev->id = (enum lima_gpu_id)of_device_get_match_data(&pdev->dev); + +-- +2.17.1 + + +From 82f5f9c4e3bca70b8c6c745be7a0c794d0fded53 Mon Sep 17 00:00:00 2001 +From: Qiang Yu +Date: Tue, 21 Apr 2020 21:35:42 +0800 +Subject: [PATCH] drm/lima: use module_platform_driver helper + +Simplify module init/exit with module_platform_driver. + +Tested-by: Bhushan Shah +Reviewed-by: Vasily Khoruzhick +Signed-off-by: Qiang Yu +--- + drivers/gpu/drm/lima/lima_drv.c | 12 +----------- + 1 file changed, 1 insertion(+), 11 deletions(-) + +diff --git a/drivers/gpu/drm/lima/lima_drv.c b/drivers/gpu/drm/lima/lima_drv.c +index 4e5dd75822c0..3d63d496cfc2 100644 +--- a/drivers/gpu/drm/lima/lima_drv.c ++++ b/drivers/gpu/drm/lima/lima_drv.c +@@ -460,17 +460,7 @@ static struct platform_driver lima_platform_driver = { + }, + }; + +-static int __init lima_init(void) +-{ +- return platform_driver_register(&lima_platform_driver); +-} +-module_init(lima_init); +- +-static void __exit lima_exit(void) +-{ +- platform_driver_unregister(&lima_platform_driver); +-} +-module_exit(lima_exit); ++module_platform_driver(lima_platform_driver); + + MODULE_AUTHOR("Lima Project Developers"); + MODULE_DESCRIPTION("Lima DRM Driver"); +-- +2.17.1 + + +From 2cb93a9b51b7c7105fc6baa0799c9474693c15a6 Mon Sep 17 00:00:00 2001 +From: Qiang Yu +Date: Tue, 21 Apr 2020 21:35:43 +0800 +Subject: [PATCH] drm/lima: print process name and pid when task error + +When error task list is full, print the process info where +the error task come from for debug usage. + +Tested-by: Bhushan Shah +Reviewed-by: Vasily Khoruzhick +Signed-off-by: Qiang Yu +--- + drivers/gpu/drm/lima/lima_sched.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/lima/lima_sched.c b/drivers/gpu/drm/lima/lima_sched.c +index a2db1c937424..387f9439450a 100644 +--- a/drivers/gpu/drm/lima/lima_sched.c ++++ b/drivers/gpu/drm/lima/lima_sched.c +@@ -285,7 +285,8 @@ static void lima_sched_build_error_task_list(struct lima_sched_task *task) + mutex_lock(&dev->error_task_list_lock); + + if (dev->dump.num_tasks >= lima_max_error_tasks) { +- dev_info(dev->dev, "fail to save task state: error task list is full\n"); ++ dev_info(dev->dev, "fail to save task state from %s pid %d: " ++ "error task list is full\n", ctx->pname, ctx->pid); + goto out; + } + +-- +2.17.1 + + +From 392cc15d77ef4f3dacff6b991690882051b683ad Mon Sep 17 00:00:00 2001 +From: Qiang Yu +Date: Tue, 21 Apr 2020 21:35:44 +0800 +Subject: [PATCH] drm/lima: check vm != NULL in lima_vm_put + +No need to handle this check before calling lima_vm_put. + +Tested-by: Bhushan Shah +Reviewed-by: Vasily Khoruzhick +Signed-off-by: Qiang Yu +--- + drivers/gpu/drm/lima/lima_sched.c | 7 ++----- + drivers/gpu/drm/lima/lima_vm.h | 3 ++- + 2 files changed, 4 insertions(+), 6 deletions(-) + +diff --git a/drivers/gpu/drm/lima/lima_sched.c b/drivers/gpu/drm/lima/lima_sched.c +index 387f9439450a..3ac5797e31fc 100644 +--- a/drivers/gpu/drm/lima/lima_sched.c ++++ b/drivers/gpu/drm/lima/lima_sched.c +@@ -252,8 +252,7 @@ static struct dma_fence *lima_sched_run_job(struct drm_sched_job *job) + lima_mmu_switch_vm(pipe->mmu[i], vm); + } + +- if (last_vm) +- lima_vm_put(last_vm); ++ lima_vm_put(last_vm); + + trace_lima_task_run(task); + +@@ -416,9 +415,7 @@ static void lima_sched_timedout_job(struct drm_sched_job *job) + lima_mmu_page_fault_resume(pipe->mmu[i]); + } + +- if (pipe->current_vm) +- lima_vm_put(pipe->current_vm); +- ++ lima_vm_put(pipe->current_vm); + pipe->current_vm = NULL; + pipe->current_task = NULL; + +diff --git a/drivers/gpu/drm/lima/lima_vm.h b/drivers/gpu/drm/lima/lima_vm.h +index 22aeec77d84d..3a7c74822d8b 100644 +--- a/drivers/gpu/drm/lima/lima_vm.h ++++ b/drivers/gpu/drm/lima/lima_vm.h +@@ -54,7 +54,8 @@ static inline struct lima_vm *lima_vm_get(struct lima_vm *vm) + + static inline void lima_vm_put(struct lima_vm *vm) + { +- kref_put(&vm->refcount, lima_vm_release); ++ if (vm) ++ kref_put(&vm->refcount, lima_vm_release); + } + + void lima_vm_print(struct lima_vm *vm); +-- +2.17.1 + + +From 60fd3f2cb896fe4727ad7da32aaa85b4baedb097 Mon Sep 17 00:00:00 2001 +From: Qiang Yu +Date: Tue, 21 Apr 2020 21:35:45 +0800 +Subject: [PATCH] drm/lima: always set page directory when switch vm + +We need to flush TLB anyway before every task start, and the +page directory will be set to empty vm after suspend/resume, +so always set it to the task vm even no ctx switch happens. + +Tested-by: Bhushan Shah +Reviewed-by: Vasily Khoruzhick +Signed-off-by: Qiang Yu +--- + drivers/gpu/drm/lima/lima_mmu.c | 3 +-- + drivers/gpu/drm/lima/lima_sched.c | 14 ++++---------- + 2 files changed, 5 insertions(+), 12 deletions(-) + +diff --git a/drivers/gpu/drm/lima/lima_mmu.c b/drivers/gpu/drm/lima/lima_mmu.c +index f79d2af427e7..c26b751b0f9d 100644 +--- a/drivers/gpu/drm/lima/lima_mmu.c ++++ b/drivers/gpu/drm/lima/lima_mmu.c +@@ -113,8 +113,7 @@ void lima_mmu_switch_vm(struct lima_ip *ip, struct lima_vm *vm) + LIMA_MMU_STATUS, v, + v & LIMA_MMU_STATUS_STALL_ACTIVE); + +- if (vm) +- mmu_write(LIMA_MMU_DTE_ADDR, vm->pd.dma); ++ mmu_write(LIMA_MMU_DTE_ADDR, vm->pd.dma); + + /* flush the TLB */ + mmu_write(LIMA_MMU_COMMAND, LIMA_MMU_COMMAND_ZAP_CACHE); +diff --git a/drivers/gpu/drm/lima/lima_sched.c b/drivers/gpu/drm/lima/lima_sched.c +index 3ac5797e31fc..eb46db0717cd 100644 +--- a/drivers/gpu/drm/lima/lima_sched.c ++++ b/drivers/gpu/drm/lima/lima_sched.c +@@ -200,7 +200,6 @@ static struct dma_fence *lima_sched_run_job(struct drm_sched_job *job) + struct lima_sched_pipe *pipe = to_lima_pipe(job->sched); + struct lima_fence *fence; + struct dma_fence *ret; +- struct lima_vm *vm = NULL, *last_vm = NULL; + int i; + + /* after GPU reset */ +@@ -239,21 +238,16 @@ static struct dma_fence *lima_sched_run_job(struct drm_sched_job *job) + for (i = 0; i < pipe->num_l2_cache; i++) + lima_l2_cache_flush(pipe->l2_cache[i]); + +- if (task->vm != pipe->current_vm) { +- vm = lima_vm_get(task->vm); +- last_vm = pipe->current_vm; +- pipe->current_vm = task->vm; +- } ++ lima_vm_put(pipe->current_vm); ++ pipe->current_vm = lima_vm_get(task->vm); + + if (pipe->bcast_mmu) +- lima_mmu_switch_vm(pipe->bcast_mmu, vm); ++ lima_mmu_switch_vm(pipe->bcast_mmu, pipe->current_vm); + else { + for (i = 0; i < pipe->num_mmu; i++) +- lima_mmu_switch_vm(pipe->mmu[i], vm); ++ lima_mmu_switch_vm(pipe->mmu[i], pipe->current_vm); + } + +- lima_vm_put(last_vm); +- + trace_lima_task_run(task); + + pipe->error = false; +-- +2.17.1 + + +From e88c2e9bf4d246ef449323208fc731aad659fc43 Mon Sep 17 00:00:00 2001 +From: Qiang Yu +Date: Tue, 21 Apr 2020 21:35:46 +0800 +Subject: [PATCH] drm/lima: add lima_devfreq_resume/suspend + +Used for device resume/suspend in the following commits. + +Tested-by: Bhushan Shah +Reviewed-by: Vasily Khoruzhick +Signed-off-by: Qiang Yu +--- + drivers/gpu/drm/lima/lima_devfreq.c | 24 ++++++++++++++++++++++++ + drivers/gpu/drm/lima/lima_devfreq.h | 3 +++ + 2 files changed, 27 insertions(+) + +diff --git a/drivers/gpu/drm/lima/lima_devfreq.c b/drivers/gpu/drm/lima/lima_devfreq.c +index 1d479b5924fe..bbe02817721b 100644 +--- a/drivers/gpu/drm/lima/lima_devfreq.c ++++ b/drivers/gpu/drm/lima/lima_devfreq.c +@@ -231,3 +231,27 @@ void lima_devfreq_record_idle(struct lima_devfreq *devfreq) + + spin_unlock_irqrestore(&devfreq->lock, irqflags); + } ++ ++int lima_devfreq_resume(struct lima_devfreq *devfreq) ++{ ++ unsigned long irqflags; ++ ++ if (!devfreq->devfreq) ++ return 0; ++ ++ spin_lock_irqsave(&devfreq->lock, irqflags); ++ ++ lima_devfreq_reset(devfreq); ++ ++ spin_unlock_irqrestore(&devfreq->lock, irqflags); ++ ++ return devfreq_resume_device(devfreq->devfreq); ++} ++ ++int lima_devfreq_suspend(struct lima_devfreq *devfreq) ++{ ++ if (!devfreq->devfreq) ++ return 0; ++ ++ return devfreq_suspend_device(devfreq->devfreq); ++} +diff --git a/drivers/gpu/drm/lima/lima_devfreq.h b/drivers/gpu/drm/lima/lima_devfreq.h +index 8d71ba9fb22a..5eed2975a375 100644 +--- a/drivers/gpu/drm/lima/lima_devfreq.h ++++ b/drivers/gpu/drm/lima/lima_devfreq.h +@@ -38,4 +38,7 @@ void lima_devfreq_fini(struct lima_device *ldev); + void lima_devfreq_record_busy(struct lima_devfreq *devfreq); + void lima_devfreq_record_idle(struct lima_devfreq *devfreq); + ++int lima_devfreq_resume(struct lima_devfreq *devfreq); ++int lima_devfreq_suspend(struct lima_devfreq *devfreq); ++ + #endif +-- +2.17.1 + + +From 1f828aa538ce8def9479aec4669b655ff7e9cbf0 Mon Sep 17 00:00:00 2001 +From: Qiang Yu +Date: Tue, 21 Apr 2020 21:35:47 +0800 +Subject: [PATCH] drm/lima: power down ip blocks when pmu exit + +Prepare resume/suspend PM. + +v2: +Fix lima_pmu_wait_cmd timeout when mali400 case. + +Tested-by: Bhushan Shah +Reviewed-by: Vasily Khoruzhick +Signed-off-by: Qiang Yu +--- + drivers/gpu/drm/lima/lima_device.h | 2 ++ + drivers/gpu/drm/lima/lima_pmu.c | 53 +++++++++++++++++++++++++++++- + 2 files changed, 54 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/lima/lima_device.h b/drivers/gpu/drm/lima/lima_device.h +index 99b1fb147dad..9cd2718079bd 100644 +--- a/drivers/gpu/drm/lima/lima_device.h ++++ b/drivers/gpu/drm/lima/lima_device.h +@@ -64,6 +64,8 @@ struct lima_ip { + bool async_reset; + /* l2 cache */ + spinlock_t lock; ++ /* pmu */ ++ u32 mask; + } data; + }; + +diff --git a/drivers/gpu/drm/lima/lima_pmu.c b/drivers/gpu/drm/lima/lima_pmu.c +index 571f6d661581..d476569f2043 100644 +--- a/drivers/gpu/drm/lima/lima_pmu.c ++++ b/drivers/gpu/drm/lima/lima_pmu.c +@@ -21,7 +21,7 @@ static int lima_pmu_wait_cmd(struct lima_ip *ip) + v, v & LIMA_PMU_INT_CMD_MASK, + 100, 100000); + if (err) { +- dev_err(dev->dev, "timeout wait pmd cmd\n"); ++ dev_err(dev->dev, "timeout wait pmu cmd\n"); + return err; + } + +@@ -29,6 +29,40 @@ static int lima_pmu_wait_cmd(struct lima_ip *ip) + return 0; + } + ++static u32 lima_pmu_get_ip_mask(struct lima_ip *ip) ++{ ++ struct lima_device *dev = ip->dev; ++ u32 ret = 0; ++ int i; ++ ++ ret |= LIMA_PMU_POWER_GP0_MASK; ++ ++ if (dev->id == lima_gpu_mali400) { ++ ret |= LIMA_PMU_POWER_L2_MASK; ++ for (i = 0; i < 4; i++) { ++ if (dev->ip[lima_ip_pp0 + i].present) ++ ret |= LIMA_PMU_POWER_PP_MASK(i); ++ } ++ } else { ++ if (dev->ip[lima_ip_pp0].present) ++ ret |= LIMA450_PMU_POWER_PP0_MASK; ++ for (i = lima_ip_pp1; i <= lima_ip_pp3; i++) { ++ if (dev->ip[i].present) { ++ ret |= LIMA450_PMU_POWER_PP13_MASK; ++ break; ++ } ++ } ++ for (i = lima_ip_pp4; i <= lima_ip_pp7; i++) { ++ if (dev->ip[i].present) { ++ ret |= LIMA450_PMU_POWER_PP47_MASK; ++ break; ++ } ++ } ++ } ++ ++ return ret; ++} ++ + int lima_pmu_init(struct lima_ip *ip) + { + int err; +@@ -56,5 +90,22 @@ int lima_pmu_init(struct lima_ip *ip) + + void lima_pmu_fini(struct lima_ip *ip) + { ++ u32 stat; ++ ++ if (!ip->data.mask) ++ ip->data.mask = lima_pmu_get_ip_mask(ip); + ++ stat = ~pmu_read(LIMA_PMU_STATUS) & ip->data.mask; ++ if (stat) { ++ pmu_write(LIMA_PMU_POWER_DOWN, stat); ++ ++ /* Don't wait for interrupt on Mali400 if all domains are ++ * powered off because the HW won't generate an interrupt ++ * in this case. ++ */ ++ if (ip->dev->id == lima_gpu_mali400) ++ pmu_write(LIMA_PMU_INT_CLEAR, LIMA_PMU_INT_CMD_MASK); ++ else ++ lima_pmu_wait_cmd(ip); ++ } + } +-- +2.17.1 + + +From e7a53d7606fd2e3d6f513f4d8440e2243a9968ae Mon Sep 17 00:00:00 2001 +From: Qiang Yu +Date: Tue, 21 Apr 2020 21:35:48 +0800 +Subject: [PATCH] drm/lima: add resume/suspend callback for each ip + +For called when PM do resume/suspend. + +Tested-by: Bhushan Shah +Reviewed-by: Vasily Khoruzhick +Signed-off-by: Qiang Yu +--- + drivers/gpu/drm/lima/lima_bcast.c | 25 ++++++++++++--- + drivers/gpu/drm/lima/lima_bcast.h | 2 ++ + drivers/gpu/drm/lima/lima_device.c | 4 +++ + drivers/gpu/drm/lima/lima_device.h | 2 +- + drivers/gpu/drm/lima/lima_dlbu.c | 17 +++++++++- + drivers/gpu/drm/lima/lima_dlbu.h | 2 ++ + drivers/gpu/drm/lima/lima_gp.c | 21 +++++++++++-- + drivers/gpu/drm/lima/lima_gp.h | 2 ++ + drivers/gpu/drm/lima/lima_l2_cache.c | 38 +++++++++++++++++------ + drivers/gpu/drm/lima/lima_l2_cache.h | 2 ++ + drivers/gpu/drm/lima/lima_mmu.c | 46 ++++++++++++++++++++-------- + drivers/gpu/drm/lima/lima_mmu.h | 2 ++ + drivers/gpu/drm/lima/lima_pmu.c | 24 +++++++++++++-- + drivers/gpu/drm/lima/lima_pmu.h | 2 ++ + drivers/gpu/drm/lima/lima_pp.c | 31 +++++++++++++++++-- + drivers/gpu/drm/lima/lima_pp.h | 4 +++ + 16 files changed, 187 insertions(+), 37 deletions(-) + +diff --git a/drivers/gpu/drm/lima/lima_bcast.c b/drivers/gpu/drm/lima/lima_bcast.c +index 288398027bfa..fbc43f243c54 100644 +--- a/drivers/gpu/drm/lima/lima_bcast.c ++++ b/drivers/gpu/drm/lima/lima_bcast.c +@@ -26,18 +26,33 @@ void lima_bcast_enable(struct lima_device *dev, int num_pp) + bcast_write(LIMA_BCAST_BROADCAST_MASK, mask); + } + ++static int lima_bcast_hw_init(struct lima_ip *ip) ++{ ++ bcast_write(LIMA_BCAST_BROADCAST_MASK, ip->data.mask << 16); ++ bcast_write(LIMA_BCAST_INTERRUPT_MASK, ip->data.mask); ++ return 0; ++} ++ ++int lima_bcast_resume(struct lima_ip *ip) ++{ ++ return lima_bcast_hw_init(ip); ++} ++ ++void lima_bcast_suspend(struct lima_ip *ip) ++{ ++ ++} ++ + int lima_bcast_init(struct lima_ip *ip) + { +- int i, mask = 0; ++ int i; + + for (i = lima_ip_pp0; i <= lima_ip_pp7; i++) { + if (ip->dev->ip[i].present) +- mask |= 1 << (i - lima_ip_pp0); ++ ip->data.mask |= 1 << (i - lima_ip_pp0); + } + +- bcast_write(LIMA_BCAST_BROADCAST_MASK, mask << 16); +- bcast_write(LIMA_BCAST_INTERRUPT_MASK, mask); +- return 0; ++ return lima_bcast_hw_init(ip); + } + + void lima_bcast_fini(struct lima_ip *ip) +diff --git a/drivers/gpu/drm/lima/lima_bcast.h b/drivers/gpu/drm/lima/lima_bcast.h +index c47e58563d0a..465ee587bceb 100644 +--- a/drivers/gpu/drm/lima/lima_bcast.h ++++ b/drivers/gpu/drm/lima/lima_bcast.h +@@ -6,6 +6,8 @@ + + struct lima_ip; + ++int lima_bcast_resume(struct lima_ip *ip); ++void lima_bcast_suspend(struct lima_ip *ip); + int lima_bcast_init(struct lima_ip *ip); + void lima_bcast_fini(struct lima_ip *ip); + +diff --git a/drivers/gpu/drm/lima/lima_device.c b/drivers/gpu/drm/lima/lima_device.c +index 29285dedd124..a2d4ec75b3b3 100644 +--- a/drivers/gpu/drm/lima/lima_device.c ++++ b/drivers/gpu/drm/lima/lima_device.c +@@ -25,6 +25,8 @@ struct lima_ip_desc { + + int (*init)(struct lima_ip *ip); + void (*fini)(struct lima_ip *ip); ++ int (*resume)(struct lima_ip *ip); ++ void (*suspend)(struct lima_ip *ip); + }; + + #define LIMA_IP_DESC(ipname, mst0, mst1, off0, off1, func, irq) \ +@@ -41,6 +43,8 @@ struct lima_ip_desc { + }, \ + .init = lima_##func##_init, \ + .fini = lima_##func##_fini, \ ++ .resume = lima_##func##_resume, \ ++ .suspend = lima_##func##_suspend, \ + } + + static struct lima_ip_desc lima_ip_desc[lima_ip_num] = { +diff --git a/drivers/gpu/drm/lima/lima_device.h b/drivers/gpu/drm/lima/lima_device.h +index 9cd2718079bd..d9df1b45dfa9 100644 +--- a/drivers/gpu/drm/lima/lima_device.h ++++ b/drivers/gpu/drm/lima/lima_device.h +@@ -64,7 +64,7 @@ struct lima_ip { + bool async_reset; + /* l2 cache */ + spinlock_t lock; +- /* pmu */ ++ /* pmu/bcast */ + u32 mask; + } data; + }; +diff --git a/drivers/gpu/drm/lima/lima_dlbu.c b/drivers/gpu/drm/lima/lima_dlbu.c +index 8399ceffb94b..c1d5ea35daa7 100644 +--- a/drivers/gpu/drm/lima/lima_dlbu.c ++++ b/drivers/gpu/drm/lima/lima_dlbu.c +@@ -42,7 +42,7 @@ void lima_dlbu_set_reg(struct lima_ip *ip, u32 *reg) + dlbu_write(LIMA_DLBU_START_TILE_POS, reg[3]); + } + +-int lima_dlbu_init(struct lima_ip *ip) ++static int lima_dlbu_hw_init(struct lima_ip *ip) + { + struct lima_device *dev = ip->dev; + +@@ -52,6 +52,21 @@ int lima_dlbu_init(struct lima_ip *ip) + return 0; + } + ++int lima_dlbu_resume(struct lima_ip *ip) ++{ ++ return lima_dlbu_hw_init(ip); ++} ++ ++void lima_dlbu_suspend(struct lima_ip *ip) ++{ ++ ++} ++ ++int lima_dlbu_init(struct lima_ip *ip) ++{ ++ return lima_dlbu_hw_init(ip); ++} ++ + void lima_dlbu_fini(struct lima_ip *ip) + { + +diff --git a/drivers/gpu/drm/lima/lima_dlbu.h b/drivers/gpu/drm/lima/lima_dlbu.h +index 16f877984466..be71daaaee89 100644 +--- a/drivers/gpu/drm/lima/lima_dlbu.h ++++ b/drivers/gpu/drm/lima/lima_dlbu.h +@@ -12,6 +12,8 @@ void lima_dlbu_disable(struct lima_device *dev); + + void lima_dlbu_set_reg(struct lima_ip *ip, u32 *reg); + ++int lima_dlbu_resume(struct lima_ip *ip); ++void lima_dlbu_suspend(struct lima_ip *ip); + int lima_dlbu_init(struct lima_ip *ip); + void lima_dlbu_fini(struct lima_ip *ip); + +diff --git a/drivers/gpu/drm/lima/lima_gp.c b/drivers/gpu/drm/lima/lima_gp.c +index d8841c870d90..8dd501b7a3d0 100644 +--- a/drivers/gpu/drm/lima/lima_gp.c ++++ b/drivers/gpu/drm/lima/lima_gp.c +@@ -274,6 +274,23 @@ static void lima_gp_print_version(struct lima_ip *ip) + static struct kmem_cache *lima_gp_task_slab; + static int lima_gp_task_slab_refcnt; + ++static int lima_gp_hw_init(struct lima_ip *ip) ++{ ++ ip->data.async_reset = false; ++ lima_gp_soft_reset_async(ip); ++ return lima_gp_soft_reset_async_wait(ip); ++} ++ ++int lima_gp_resume(struct lima_ip *ip) ++{ ++ return lima_gp_hw_init(ip); ++} ++ ++void lima_gp_suspend(struct lima_ip *ip) ++{ ++ ++} ++ + int lima_gp_init(struct lima_ip *ip) + { + struct lima_device *dev = ip->dev; +@@ -281,9 +298,7 @@ int lima_gp_init(struct lima_ip *ip) + + lima_gp_print_version(ip); + +- ip->data.async_reset = false; +- lima_gp_soft_reset_async(ip); +- err = lima_gp_soft_reset_async_wait(ip); ++ err = lima_gp_hw_init(ip); + if (err) + return err; + +diff --git a/drivers/gpu/drm/lima/lima_gp.h b/drivers/gpu/drm/lima/lima_gp.h +index 516e5c1babbb..02ec9af78a51 100644 +--- a/drivers/gpu/drm/lima/lima_gp.h ++++ b/drivers/gpu/drm/lima/lima_gp.h +@@ -7,6 +7,8 @@ + struct lima_ip; + struct lima_device; + ++int lima_gp_resume(struct lima_ip *ip); ++void lima_gp_suspend(struct lima_ip *ip); + int lima_gp_init(struct lima_ip *ip); + void lima_gp_fini(struct lima_ip *ip); + +diff --git a/drivers/gpu/drm/lima/lima_l2_cache.c b/drivers/gpu/drm/lima/lima_l2_cache.c +index 6873a7af5a5c..c4080a02957b 100644 +--- a/drivers/gpu/drm/lima/lima_l2_cache.c ++++ b/drivers/gpu/drm/lima/lima_l2_cache.c +@@ -38,9 +38,35 @@ int lima_l2_cache_flush(struct lima_ip *ip) + return ret; + } + ++static int lima_l2_cache_hw_init(struct lima_ip *ip) ++{ ++ int err; ++ ++ err = lima_l2_cache_flush(ip); ++ if (err) ++ return err; ++ ++ l2_cache_write(LIMA_L2_CACHE_ENABLE, ++ LIMA_L2_CACHE_ENABLE_ACCESS | ++ LIMA_L2_CACHE_ENABLE_READ_ALLOCATE); ++ l2_cache_write(LIMA_L2_CACHE_MAX_READS, 0x1c); ++ ++ return 0; ++} ++ ++int lima_l2_cache_resume(struct lima_ip *ip) ++{ ++ return lima_l2_cache_hw_init(ip); ++} ++ ++void lima_l2_cache_suspend(struct lima_ip *ip) ++{ ++ ++} ++ + int lima_l2_cache_init(struct lima_ip *ip) + { +- int i, err; ++ int i; + u32 size; + struct lima_device *dev = ip->dev; + +@@ -63,15 +89,7 @@ int lima_l2_cache_init(struct lima_ip *ip) + 1 << (size & 0xff), + 1 << ((size >> 24) & 0xff)); + +- err = lima_l2_cache_flush(ip); +- if (err) +- return err; +- +- l2_cache_write(LIMA_L2_CACHE_ENABLE, +- LIMA_L2_CACHE_ENABLE_ACCESS|LIMA_L2_CACHE_ENABLE_READ_ALLOCATE); +- l2_cache_write(LIMA_L2_CACHE_MAX_READS, 0x1c); +- +- return 0; ++ return lima_l2_cache_hw_init(ip); + } + + void lima_l2_cache_fini(struct lima_ip *ip) +diff --git a/drivers/gpu/drm/lima/lima_l2_cache.h b/drivers/gpu/drm/lima/lima_l2_cache.h +index c63fb676ff14..1aeeefd53fb9 100644 +--- a/drivers/gpu/drm/lima/lima_l2_cache.h ++++ b/drivers/gpu/drm/lima/lima_l2_cache.h +@@ -6,6 +6,8 @@ + + struct lima_ip; + ++int lima_l2_cache_resume(struct lima_ip *ip); ++void lima_l2_cache_suspend(struct lima_ip *ip); + int lima_l2_cache_init(struct lima_ip *ip); + void lima_l2_cache_fini(struct lima_ip *ip); + +diff --git a/drivers/gpu/drm/lima/lima_mmu.c b/drivers/gpu/drm/lima/lima_mmu.c +index c26b751b0f9d..a1ae6c252dc2 100644 +--- a/drivers/gpu/drm/lima/lima_mmu.c ++++ b/drivers/gpu/drm/lima/lima_mmu.c +@@ -59,12 +59,44 @@ static irqreturn_t lima_mmu_irq_handler(int irq, void *data) + return IRQ_HANDLED; + } + +-int lima_mmu_init(struct lima_ip *ip) ++static int lima_mmu_hw_init(struct lima_ip *ip) + { + struct lima_device *dev = ip->dev; + int err; + u32 v; + ++ mmu_write(LIMA_MMU_COMMAND, LIMA_MMU_COMMAND_HARD_RESET); ++ err = lima_mmu_send_command(LIMA_MMU_COMMAND_HARD_RESET, ++ LIMA_MMU_DTE_ADDR, v, v == 0); ++ if (err) ++ return err; ++ ++ mmu_write(LIMA_MMU_INT_MASK, ++ LIMA_MMU_INT_PAGE_FAULT | LIMA_MMU_INT_READ_BUS_ERROR); ++ mmu_write(LIMA_MMU_DTE_ADDR, dev->empty_vm->pd.dma); ++ return lima_mmu_send_command(LIMA_MMU_COMMAND_ENABLE_PAGING, ++ LIMA_MMU_STATUS, v, ++ v & LIMA_MMU_STATUS_PAGING_ENABLED); ++} ++ ++int lima_mmu_resume(struct lima_ip *ip) ++{ ++ if (ip->id == lima_ip_ppmmu_bcast) ++ return 0; ++ ++ return lima_mmu_hw_init(ip); ++} ++ ++void lima_mmu_suspend(struct lima_ip *ip) ++{ ++ ++} ++ ++int lima_mmu_init(struct lima_ip *ip) ++{ ++ struct lima_device *dev = ip->dev; ++ int err; ++ + if (ip->id == lima_ip_ppmmu_bcast) + return 0; + +@@ -74,12 +106,6 @@ int lima_mmu_init(struct lima_ip *ip) + return -EIO; + } + +- mmu_write(LIMA_MMU_COMMAND, LIMA_MMU_COMMAND_HARD_RESET); +- err = lima_mmu_send_command(LIMA_MMU_COMMAND_HARD_RESET, +- LIMA_MMU_DTE_ADDR, v, v == 0); +- if (err) +- return err; +- + err = devm_request_irq(dev->dev, ip->irq, lima_mmu_irq_handler, + IRQF_SHARED, lima_ip_name(ip), ip); + if (err) { +@@ -87,11 +113,7 @@ int lima_mmu_init(struct lima_ip *ip) + return err; + } + +- mmu_write(LIMA_MMU_INT_MASK, LIMA_MMU_INT_PAGE_FAULT | LIMA_MMU_INT_READ_BUS_ERROR); +- mmu_write(LIMA_MMU_DTE_ADDR, dev->empty_vm->pd.dma); +- return lima_mmu_send_command(LIMA_MMU_COMMAND_ENABLE_PAGING, +- LIMA_MMU_STATUS, v, +- v & LIMA_MMU_STATUS_PAGING_ENABLED); ++ return lima_mmu_hw_init(ip); + } + + void lima_mmu_fini(struct lima_ip *ip) +diff --git a/drivers/gpu/drm/lima/lima_mmu.h b/drivers/gpu/drm/lima/lima_mmu.h +index 4f8ccbebcba1..f0c97ac75ea0 100644 +--- a/drivers/gpu/drm/lima/lima_mmu.h ++++ b/drivers/gpu/drm/lima/lima_mmu.h +@@ -7,6 +7,8 @@ + struct lima_ip; + struct lima_vm; + ++int lima_mmu_resume(struct lima_ip *ip); ++void lima_mmu_suspend(struct lima_ip *ip); + int lima_mmu_init(struct lima_ip *ip); + void lima_mmu_fini(struct lima_ip *ip); + +diff --git a/drivers/gpu/drm/lima/lima_pmu.c b/drivers/gpu/drm/lima/lima_pmu.c +index d476569f2043..e397e1146e96 100644 +--- a/drivers/gpu/drm/lima/lima_pmu.c ++++ b/drivers/gpu/drm/lima/lima_pmu.c +@@ -63,7 +63,7 @@ static u32 lima_pmu_get_ip_mask(struct lima_ip *ip) + return ret; + } + +-int lima_pmu_init(struct lima_ip *ip) ++static int lima_pmu_hw_init(struct lima_ip *ip) + { + int err; + u32 stat; +@@ -88,7 +88,7 @@ int lima_pmu_init(struct lima_ip *ip) + return 0; + } + +-void lima_pmu_fini(struct lima_ip *ip) ++static void lima_pmu_hw_fini(struct lima_ip *ip) + { + u32 stat; + +@@ -109,3 +109,23 @@ void lima_pmu_fini(struct lima_ip *ip) + lima_pmu_wait_cmd(ip); + } + } ++ ++int lima_pmu_resume(struct lima_ip *ip) ++{ ++ return lima_pmu_hw_init(ip); ++} ++ ++void lima_pmu_suspend(struct lima_ip *ip) ++{ ++ lima_pmu_hw_fini(ip); ++} ++ ++int lima_pmu_init(struct lima_ip *ip) ++{ ++ return lima_pmu_hw_init(ip); ++} ++ ++void lima_pmu_fini(struct lima_ip *ip) ++{ ++ lima_pmu_hw_fini(ip); ++} +diff --git a/drivers/gpu/drm/lima/lima_pmu.h b/drivers/gpu/drm/lima/lima_pmu.h +index a2a18775eb07..652dc7af3047 100644 +--- a/drivers/gpu/drm/lima/lima_pmu.h ++++ b/drivers/gpu/drm/lima/lima_pmu.h +@@ -6,6 +6,8 @@ + + struct lima_ip; + ++int lima_pmu_resume(struct lima_ip *ip); ++void lima_pmu_suspend(struct lima_ip *ip); + int lima_pmu_init(struct lima_ip *ip); + void lima_pmu_fini(struct lima_ip *ip); + +diff --git a/drivers/gpu/drm/lima/lima_pp.c b/drivers/gpu/drm/lima/lima_pp.c +index 8fef224b93c8..33f01383409c 100644 +--- a/drivers/gpu/drm/lima/lima_pp.c ++++ b/drivers/gpu/drm/lima/lima_pp.c +@@ -223,6 +223,23 @@ static void lima_pp_print_version(struct lima_ip *ip) + lima_ip_name(ip), name, major, minor); + } + ++static int lima_pp_hw_init(struct lima_ip *ip) ++{ ++ ip->data.async_reset = false; ++ lima_pp_soft_reset_async(ip); ++ return lima_pp_soft_reset_async_wait(ip); ++} ++ ++int lima_pp_resume(struct lima_ip *ip) ++{ ++ return lima_pp_hw_init(ip); ++} ++ ++void lima_pp_suspend(struct lima_ip *ip) ++{ ++ ++} ++ + int lima_pp_init(struct lima_ip *ip) + { + struct lima_device *dev = ip->dev; +@@ -230,9 +247,7 @@ int lima_pp_init(struct lima_ip *ip) + + lima_pp_print_version(ip); + +- ip->data.async_reset = false; +- lima_pp_soft_reset_async(ip); +- err = lima_pp_soft_reset_async_wait(ip); ++ err = lima_pp_hw_init(ip); + if (err) + return err; + +@@ -254,6 +269,16 @@ void lima_pp_fini(struct lima_ip *ip) + + } + ++int lima_pp_bcast_resume(struct lima_ip *ip) ++{ ++ return 0; ++} ++ ++void lima_pp_bcast_suspend(struct lima_ip *ip) ++{ ++ ++} ++ + int lima_pp_bcast_init(struct lima_ip *ip) + { + struct lima_device *dev = ip->dev; +diff --git a/drivers/gpu/drm/lima/lima_pp.h b/drivers/gpu/drm/lima/lima_pp.h +index bf60c77b2633..16ec96de15a9 100644 +--- a/drivers/gpu/drm/lima/lima_pp.h ++++ b/drivers/gpu/drm/lima/lima_pp.h +@@ -7,9 +7,13 @@ + struct lima_ip; + struct lima_device; + ++int lima_pp_resume(struct lima_ip *ip); ++void lima_pp_suspend(struct lima_ip *ip); + int lima_pp_init(struct lima_ip *ip); + void lima_pp_fini(struct lima_ip *ip); + ++int lima_pp_bcast_resume(struct lima_ip *ip); ++void lima_pp_bcast_suspend(struct lima_ip *ip); + int lima_pp_bcast_init(struct lima_ip *ip); + void lima_pp_bcast_fini(struct lima_ip *ip); + +-- +2.17.1 + + +From 26ee4346a85cd75c531cb31dc1fe66e43226f275 Mon Sep 17 00:00:00 2001 +From: Qiang Yu +Date: Tue, 21 Apr 2020 21:35:49 +0800 +Subject: [PATCH] drm/lima: separate clk/regulator enable/disable function + +For being used by both device init/fini and suspend/resume. + +Tested-by: Bhushan Shah +Reviewed-by: Vasily Khoruzhick +Signed-off-by: Qiang Yu +--- + drivers/gpu/drm/lima/lima_device.c | 105 +++++++++++++++++++---------- + 1 file changed, 68 insertions(+), 37 deletions(-) + +diff --git a/drivers/gpu/drm/lima/lima_device.c b/drivers/gpu/drm/lima/lima_device.c +index a2d4ec75b3b3..1d9b7f415da1 100644 +--- a/drivers/gpu/drm/lima/lima_device.c ++++ b/drivers/gpu/drm/lima/lima_device.c +@@ -81,26 +81,10 @@ const char *lima_ip_name(struct lima_ip *ip) + return lima_ip_desc[ip->id].name; + } + +-static int lima_clk_init(struct lima_device *dev) ++static int lima_clk_enable(struct lima_device *dev) + { + int err; + +- dev->clk_bus = devm_clk_get(dev->dev, "bus"); +- if (IS_ERR(dev->clk_bus)) { +- err = PTR_ERR(dev->clk_bus); +- if (err != -EPROBE_DEFER) +- dev_err(dev->dev, "get bus clk failed %d\n", err); +- return err; +- } +- +- dev->clk_gpu = devm_clk_get(dev->dev, "core"); +- if (IS_ERR(dev->clk_gpu)) { +- err = PTR_ERR(dev->clk_gpu); +- if (err != -EPROBE_DEFER) +- dev_err(dev->dev, "get core clk failed %d\n", err); +- return err; +- } +- + err = clk_prepare_enable(dev->clk_bus); + if (err) + return err; +@@ -109,15 +93,7 @@ static int lima_clk_init(struct lima_device *dev) + if (err) + goto error_out0; + +- dev->reset = devm_reset_control_array_get_optional_shared(dev->dev); +- +- if (IS_ERR(dev->reset)) { +- err = PTR_ERR(dev->reset); +- if (err != -EPROBE_DEFER) +- dev_err(dev->dev, "get reset controller failed %d\n", +- err); +- goto error_out1; +- } else if (dev->reset != NULL) { ++ if (dev->reset) { + err = reset_control_deassert(dev->reset); + if (err) { + dev_err(dev->dev, +@@ -135,14 +111,76 @@ static int lima_clk_init(struct lima_device *dev) + return err; + } + +-static void lima_clk_fini(struct lima_device *dev) ++static void lima_clk_disable(struct lima_device *dev) + { +- if (dev->reset != NULL) ++ if (dev->reset) + reset_control_assert(dev->reset); + clk_disable_unprepare(dev->clk_gpu); + clk_disable_unprepare(dev->clk_bus); + } + ++static int lima_clk_init(struct lima_device *dev) ++{ ++ int err; ++ ++ dev->clk_bus = devm_clk_get(dev->dev, "bus"); ++ if (IS_ERR(dev->clk_bus)) { ++ err = PTR_ERR(dev->clk_bus); ++ if (err != -EPROBE_DEFER) ++ dev_err(dev->dev, "get bus clk failed %d\n", err); ++ dev->clk_bus = NULL; ++ return err; ++ } ++ ++ dev->clk_gpu = devm_clk_get(dev->dev, "core"); ++ if (IS_ERR(dev->clk_gpu)) { ++ err = PTR_ERR(dev->clk_gpu); ++ if (err != -EPROBE_DEFER) ++ dev_err(dev->dev, "get core clk failed %d\n", err); ++ dev->clk_gpu = NULL; ++ return err; ++ } ++ ++ dev->reset = devm_reset_control_array_get_optional_shared(dev->dev); ++ if (IS_ERR(dev->reset)) { ++ err = PTR_ERR(dev->reset); ++ if (err != -EPROBE_DEFER) ++ dev_err(dev->dev, "get reset controller failed %d\n", ++ err); ++ dev->reset = NULL; ++ return err; ++ } ++ ++ return lima_clk_enable(dev); ++} ++ ++static void lima_clk_fini(struct lima_device *dev) ++{ ++ lima_clk_disable(dev); ++} ++ ++static int lima_regulator_enable(struct lima_device *dev) ++{ ++ int ret; ++ ++ if (!dev->regulator) ++ return 0; ++ ++ ret = regulator_enable(dev->regulator); ++ if (ret < 0) { ++ dev_err(dev->dev, "failed to enable regulator: %d\n", ret); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static void lima_regulator_disable(struct lima_device *dev) ++{ ++ if (dev->regulator) ++ regulator_disable(dev->regulator); ++} ++ + static int lima_regulator_init(struct lima_device *dev) + { + int ret; +@@ -158,19 +196,12 @@ static int lima_regulator_init(struct lima_device *dev) + return ret; + } + +- ret = regulator_enable(dev->regulator); +- if (ret < 0) { +- dev_err(dev->dev, "failed to enable regulator: %d\n", ret); +- return ret; +- } +- +- return 0; ++ return lima_regulator_enable(dev); + } + + static void lima_regulator_fini(struct lima_device *dev) + { +- if (dev->regulator) +- regulator_disable(dev->regulator); ++ lima_regulator_disable(dev); + } + + static int lima_init_ip(struct lima_device *dev, int index) +-- +2.17.1 + + +From 90f27ceb82a87cabf926e65748bdd60cf0e191b6 Mon Sep 17 00:00:00 2001 +From: Qiang Yu +Date: Tue, 21 Apr 2020 21:35:50 +0800 +Subject: [PATCH] drm/lima: add pm resume/suspend ops + +Add driver pm system and runtime hardware resume/suspend ops. +Note this won't enable runtime pm of the device yet. + +v2: +Do clock and power gating when suspend/resume. + +Tested-by: Bhushan Shah +Reviewed-by: Vasily Khoruzhick +Signed-off-by: Qiang Yu +--- + drivers/gpu/drm/lima/lima_device.c | 90 ++++++++++++++++++++++++++++++ + drivers/gpu/drm/lima/lima_device.h | 3 + + drivers/gpu/drm/lima/lima_drv.c | 7 +++ + 3 files changed, 100 insertions(+) + +diff --git a/drivers/gpu/drm/lima/lima_device.c b/drivers/gpu/drm/lima/lima_device.c +index 1d9b7f415da1..65fdca366e41 100644 +--- a/drivers/gpu/drm/lima/lima_device.c ++++ b/drivers/gpu/drm/lima/lima_device.c +@@ -247,6 +247,27 @@ static void lima_fini_ip(struct lima_device *ldev, int index) + desc->fini(ip); + } + ++static int lima_resume_ip(struct lima_device *ldev, int index) ++{ ++ struct lima_ip_desc *desc = lima_ip_desc + index; ++ struct lima_ip *ip = ldev->ip + index; ++ int ret = 0; ++ ++ if (ip->present) ++ ret = desc->resume(ip); ++ ++ return ret; ++} ++ ++static void lima_suspend_ip(struct lima_device *ldev, int index) ++{ ++ struct lima_ip_desc *desc = lima_ip_desc + index; ++ struct lima_ip *ip = ldev->ip + index; ++ ++ if (ip->present) ++ desc->suspend(ip); ++} ++ + static int lima_init_gp_pipe(struct lima_device *dev) + { + struct lima_sched_pipe *pipe = dev->pipe + lima_pipe_gp; +@@ -441,3 +462,72 @@ void lima_device_fini(struct lima_device *ldev) + + lima_clk_fini(ldev); + } ++ ++int lima_device_resume(struct device *dev) ++{ ++ struct lima_device *ldev = dev_get_drvdata(dev); ++ int i, err; ++ ++ err = lima_clk_enable(ldev); ++ if (err) { ++ dev_err(dev, "resume clk fail %d\n", err); ++ return err; ++ } ++ ++ err = lima_regulator_enable(ldev); ++ if (err) { ++ dev_err(dev, "resume regulator fail %d\n", err); ++ goto err_out0; ++ } ++ ++ for (i = 0; i < lima_ip_num; i++) { ++ err = lima_resume_ip(ldev, i); ++ if (err) { ++ dev_err(dev, "resume ip %d fail\n", i); ++ goto err_out1; ++ } ++ } ++ ++ err = lima_devfreq_resume(&ldev->devfreq); ++ if (err) { ++ dev_err(dev, "devfreq resume fail\n"); ++ goto err_out1; ++ } ++ ++ return 0; ++ ++err_out1: ++ while (--i >= 0) ++ lima_suspend_ip(ldev, i); ++ lima_regulator_disable(ldev); ++err_out0: ++ lima_clk_disable(ldev); ++ return err; ++} ++ ++int lima_device_suspend(struct device *dev) ++{ ++ struct lima_device *ldev = dev_get_drvdata(dev); ++ int i, err; ++ ++ /* check any task running */ ++ for (i = 0; i < lima_pipe_num; i++) { ++ if (atomic_read(&ldev->pipe[i].base.hw_rq_count)) ++ return -EBUSY; ++ } ++ ++ err = lima_devfreq_suspend(&ldev->devfreq); ++ if (err) { ++ dev_err(dev, "devfreq suspend fail\n"); ++ return err; ++ } ++ ++ for (i = lima_ip_num - 1; i >= 0; i--) ++ lima_suspend_ip(ldev, i); ++ ++ lima_regulator_disable(ldev); ++ ++ lima_clk_disable(ldev); ++ ++ return 0; ++} +diff --git a/drivers/gpu/drm/lima/lima_device.h b/drivers/gpu/drm/lima/lima_device.h +index d9df1b45dfa9..41b9d7b4bcc7 100644 +--- a/drivers/gpu/drm/lima/lima_device.h ++++ b/drivers/gpu/drm/lima/lima_device.h +@@ -140,4 +140,7 @@ static inline int lima_poll_timeout(struct lima_ip *ip, lima_poll_func_t func, + return 0; + } + ++int lima_device_suspend(struct device *dev); ++int lima_device_resume(struct device *dev); ++ + #endif +diff --git a/drivers/gpu/drm/lima/lima_drv.c b/drivers/gpu/drm/lima/lima_drv.c +index 3d63d496cfc2..f3fe0a2f764b 100644 +--- a/drivers/gpu/drm/lima/lima_drv.c ++++ b/drivers/gpu/drm/lima/lima_drv.c +@@ -5,6 +5,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -451,11 +452,17 @@ static const struct of_device_id dt_match[] = { + }; + MODULE_DEVICE_TABLE(of, dt_match); + ++static const struct dev_pm_ops lima_pm_ops = { ++ SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume) ++ SET_RUNTIME_PM_OPS(lima_device_suspend, lima_device_resume, NULL) ++}; ++ + static struct platform_driver lima_platform_driver = { + .probe = lima_pdev_probe, + .remove = lima_pdev_remove, + .driver = { + .name = "lima", ++ .pm = &lima_pm_ops, + .of_match_table = dt_match, + }, + }; +-- +2.17.1 + + +From 77f3ae2361292cef89c0a06e745991cefb52fcdc Mon Sep 17 00:00:00 2001 +From: Qiang Yu +Date: Tue, 21 Apr 2020 21:35:51 +0800 +Subject: [PATCH] drm/lima: enable runtime pm + +Enable runtime pm by default so GPU suspend when idle +for 200ms. This value can be changed by +autosuspend_delay_ms in device's power sysfs dir. + +On Allwinner H3 lima_device_resume takes ~40us and +lima_device_suspend takes ~20us. + +Tested-by: Bhushan Shah +Reviewed-by: Vasily Khoruzhick +Signed-off-by: Qiang Yu +--- + drivers/gpu/drm/lima/lima_drv.c | 21 ++++++++++++---- + drivers/gpu/drm/lima/lima_sched.c | 41 +++++++++++++++++++++++++++---- + 2 files changed, 52 insertions(+), 10 deletions(-) + +diff --git a/drivers/gpu/drm/lima/lima_drv.c b/drivers/gpu/drm/lima/lima_drv.c +index f3fe0a2f764b..a831565af813 100644 +--- a/drivers/gpu/drm/lima/lima_drv.c ++++ b/drivers/gpu/drm/lima/lima_drv.c +@@ -404,6 +404,12 @@ static int lima_pdev_probe(struct platform_device *pdev) + goto err_out2; + } + ++ pm_runtime_set_active(ldev->dev); ++ pm_runtime_mark_last_busy(ldev->dev); ++ pm_runtime_set_autosuspend_delay(ldev->dev, 200); ++ pm_runtime_use_autosuspend(ldev->dev); ++ pm_runtime_enable(ldev->dev); ++ + /* + * Register the DRM device with the core and the connectors with + * sysfs. +@@ -412,17 +418,16 @@ static int lima_pdev_probe(struct platform_device *pdev) + if (err < 0) + goto err_out3; + +- platform_set_drvdata(pdev, ldev); +- + if (sysfs_create_bin_file(&ldev->dev->kobj, &lima_error_state_attr)) + dev_warn(ldev->dev, "fail to create error state sysfs\n"); + + return 0; + + err_out3: +- lima_device_fini(ldev); +-err_out2: ++ pm_runtime_disable(ldev->dev); + lima_devfreq_fini(ldev); ++err_out2: ++ lima_device_fini(ldev); + err_out1: + drm_dev_put(ddev); + err_out0: +@@ -436,10 +441,16 @@ static int lima_pdev_remove(struct platform_device *pdev) + struct drm_device *ddev = ldev->ddev; + + sysfs_remove_bin_file(&ldev->dev->kobj, &lima_error_state_attr); +- platform_set_drvdata(pdev, NULL); ++ + drm_dev_unregister(ddev); ++ ++ /* stop autosuspend to make sure device is in active state */ ++ pm_runtime_set_autosuspend_delay(ldev->dev, -1); ++ pm_runtime_disable(ldev->dev); ++ + lima_devfreq_fini(ldev); + lima_device_fini(ldev); ++ + drm_dev_put(ddev); + lima_sched_slab_fini(); + return 0; +diff --git a/drivers/gpu/drm/lima/lima_sched.c b/drivers/gpu/drm/lima/lima_sched.c +index eb46db0717cd..e6cefda00279 100644 +--- a/drivers/gpu/drm/lima/lima_sched.c ++++ b/drivers/gpu/drm/lima/lima_sched.c +@@ -4,6 +4,7 @@ + #include + #include + #include ++#include + + #include "lima_devfreq.h" + #include "lima_drv.h" +@@ -194,13 +195,36 @@ static struct dma_fence *lima_sched_dependency(struct drm_sched_job *job, + return NULL; + } + ++static int lima_pm_busy(struct lima_device *ldev) ++{ ++ int ret; ++ ++ /* resume GPU if it has been suspended by runtime PM */ ++ ret = pm_runtime_get_sync(ldev->dev); ++ if (ret < 0) ++ return ret; ++ ++ lima_devfreq_record_busy(&ldev->devfreq); ++ return 0; ++} ++ ++static void lima_pm_idle(struct lima_device *ldev) ++{ ++ lima_devfreq_record_idle(&ldev->devfreq); ++ ++ /* GPU can do auto runtime suspend */ ++ pm_runtime_mark_last_busy(ldev->dev); ++ pm_runtime_put_autosuspend(ldev->dev); ++} ++ + static struct dma_fence *lima_sched_run_job(struct drm_sched_job *job) + { + struct lima_sched_task *task = to_lima_task(job); + struct lima_sched_pipe *pipe = to_lima_pipe(job->sched); ++ struct lima_device *ldev = pipe->ldev; + struct lima_fence *fence; + struct dma_fence *ret; +- int i; ++ int i, err; + + /* after GPU reset */ + if (job->s_fence->finished.error < 0) +@@ -209,6 +233,13 @@ static struct dma_fence *lima_sched_run_job(struct drm_sched_job *job) + fence = lima_fence_create(pipe); + if (!fence) + return NULL; ++ ++ err = lima_pm_busy(ldev); ++ if (err < 0) { ++ dma_fence_put(&fence->base); ++ return NULL; ++ } ++ + task->fence = &fence->base; + + /* for caller usage of the fence, otherwise irq handler +@@ -216,8 +247,6 @@ static struct dma_fence *lima_sched_run_job(struct drm_sched_job *job) + */ + ret = dma_fence_get(task->fence); + +- lima_devfreq_record_busy(&pipe->ldev->devfreq); +- + pipe->current_task = task; + + /* this is needed for MMU to work correctly, otherwise GP/PP +@@ -388,6 +417,7 @@ static void lima_sched_timedout_job(struct drm_sched_job *job) + { + struct lima_sched_pipe *pipe = to_lima_pipe(job->sched); + struct lima_sched_task *task = to_lima_task(job); ++ struct lima_device *ldev = pipe->ldev; + + if (!pipe->error) + DRM_ERROR("lima job timeout\n"); +@@ -413,7 +443,7 @@ static void lima_sched_timedout_job(struct drm_sched_job *job) + pipe->current_vm = NULL; + pipe->current_task = NULL; + +- lima_devfreq_record_idle(&pipe->ldev->devfreq); ++ lima_pm_idle(ldev); + + drm_sched_resubmit_jobs(&pipe->base); + drm_sched_start(&pipe->base, true); +@@ -485,6 +515,7 @@ void lima_sched_pipe_fini(struct lima_sched_pipe *pipe) + void lima_sched_pipe_task_done(struct lima_sched_pipe *pipe) + { + struct lima_sched_task *task = pipe->current_task; ++ struct lima_device *ldev = pipe->ldev; + + if (pipe->error) { + if (task && task->recoverable) +@@ -495,6 +526,6 @@ void lima_sched_pipe_task_done(struct lima_sched_pipe *pipe) + pipe->task_fini(pipe); + dma_fence_signal(task->fence); + +- lima_devfreq_record_idle(&pipe->ldev->devfreq); ++ lima_pm_idle(ldev); + } + } +-- +2.17.1 + + +From 5f88c11fbc001f7cd701af13a4a40c94572848c7 Mon Sep 17 00:00:00 2001 +From: Martin Blumenstingl +Date: Thu, 19 Mar 2020 21:34:26 +0100 +Subject: [PATCH] dt-bindings: gpu: mali-utgard: Add the #cooling-cells + property + +The GPU can be one of the big heat sources on a SoC. Allow the +"#cooling-cells" property to be specified for ARM Mali Utgard GPUs so +the GPU clock speeds (and voltages) can be reduced to prevent a SoC from +overheating. + +Signed-off-by: Martin Blumenstingl +Reviewed-by: Qiang Yu +--- + Documentation/devicetree/bindings/gpu/arm,mali-utgard.yaml | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/Documentation/devicetree/bindings/gpu/arm,mali-utgard.yaml b/Documentation/devicetree/bindings/gpu/arm,mali-utgard.yaml +index afde81be3c29..33548ca2a759 100644 +--- a/Documentation/devicetree/bindings/gpu/arm,mali-utgard.yaml ++++ b/Documentation/devicetree/bindings/gpu/arm,mali-utgard.yaml +@@ -107,6 +107,9 @@ properties: + + operating-points-v2: true + ++ "#cooling-cells": ++ const: 2 ++ + required: + - compatible + - reg +@@ -162,6 +165,7 @@ examples: + clocks = <&ccu 1>, <&ccu 2>; + clock-names = "bus", "core"; + resets = <&ccu 1>; ++ #cooling-cells = <2>; + }; + + ... +-- +2.17.1 + diff --git a/patch/kernel/rk322x-current/01-linux-0008-fromlist-add-rockchip-nfc-driver.patch b/patch/kernel/rk322x-current/01-linux-0008-fromlist-add-rockchip-nfc-driver.patch new file mode 100644 index 0000000000..0afa2f2d61 --- /dev/null +++ b/patch/kernel/rk322x-current/01-linux-0008-fromlist-add-rockchip-nfc-driver.patch @@ -0,0 +1,1514 @@ +diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig +index a80a46bb5b8b..8313b12a9d85 100644 +--- a/drivers/mtd/nand/raw/Kconfig ++++ b/drivers/mtd/nand/raw/Kconfig +@@ -433,6 +433,13 @@ config MTD_NAND_MESON + Enables support for NAND controller on Amlogic's Meson SoCs. + This controller is found on Meson SoCs. + ++config MTD_NAND_ROCKCHIP ++ tristate "Rockchip NAND controller" ++ depends on ARCH_ROCKCHIP || COMPILE_TEST ++ depends on HAS_IOMEM ++ help ++ Enables support for NAND controller on Rockchip SoCs. ++ + config MTD_NAND_GPIO + tristate "GPIO assisted NAND controller" + depends on GPIOLIB || COMPILE_TEST +diff --git a/drivers/mtd/nand/raw/Makefile b/drivers/mtd/nand/raw/Makefile +index 2d136b158fb7..8bafa59b8940 100644 +--- a/drivers/mtd/nand/raw/Makefile ++++ b/drivers/mtd/nand/raw/Makefile +@@ -58,6 +58,7 @@ obj-$(CONFIG_MTD_NAND_TEGRA) += tegra_nand.o + obj-$(CONFIG_MTD_NAND_STM32_FMC2) += stm32_fmc2_nand.o + obj-$(CONFIG_MTD_NAND_MESON) += meson_nand.o + obj-$(CONFIG_MTD_NAND_CADENCE) += cadence-nand-controller.o ++obj-$(CONFIG_MTD_NAND_ROCKCHIP) += rockchip_nand.o + + nand-objs := nand_base.o nand_legacy.o nand_bbt.o nand_timings.o nand_ids.o + nand-objs += nand_onfi.o +diff --git a/drivers/mtd/nand/raw/rockchip_nand.c b/drivers/mtd/nand/raw/rockchip_nand.c +new file mode 100644 +index 000000000000..1e37a1b6c702 +--- /dev/null ++++ b/drivers/mtd/nand/raw/rockchip_nand.c +@@ -0,0 +1,1315 @@ ++// SPDX-License-Identifier: GPL-2.0 OR MIT ++/* ++ * Rockchip NAND Flash controller driver. ++ * Copyright (C) 2020 Rockchip Inc. ++ * Authors: Yifeng Zhao ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* ++ * NFC Page Data Layout: ++ * 1024 Bytes Data + 4Bytes sys data + 28Bytes~124Bytes ecc + ++ * 1024 Bytes Data + 4Bytes sys data + 28Bytes~124Bytes ecc + ++ * ...... ++ * NAND Page Data Layout: ++ * 1024 * n Data + m Bytes oob ++ * Original Bad Block Mask Location: ++ * first byte of oob(spare) ++ * nand_chip->oob_poi data layout: ++ * 4Bytes sys data + .... + 4Bytes sys data + ecc data ++ */ ++ ++/* NAND controller register definition */ ++#define NFC_READ (0) ++#define NFC_WRITE (1) ++#define NFC_FMCTL (0x00) ++#define FMCTL_CE_SEL_M 0xFF ++#define FMCTL_CE_SEL(x) (1 << (x)) ++#define FMCTL_WP BIT(8) ++#define FMCTL_RDY BIT(9) ++#define NFC_FMWAIT (0x04) ++#define FLCTL_RST BIT(0) ++#define FLCTL_WR (1) /* 0: read, 1: write */ ++#define FLCTL_XFER_ST BIT(2) ++#define FLCTL_XFER_EN BIT(3) ++#define FLCTL_ACORRECT BIT(10) /* auto correct error bits */ ++#define FLCTL_XFER_READY BIT(20) ++#define FLCTL_XFER_SECTOR (22) ++#define FLCTL_TOG_FIX BIT(29) ++#define BCHCTL_BANK_M (7 << 5) ++#define BCHCTL_BANK (5) ++#define DMA_ST BIT(0) ++#define DMA_WR (1) /* 0: write, 1: read */ ++#define DMA_EN BIT(2) ++#define DMA_AHB_SIZE (3) /* 0: 1, 1: 2, 2: 4 */ ++#define DMA_BURST_SIZE (6) /* 0: 1, 3: 4, 5: 8, 7: 16 */ ++#define DMA_INC_NUM (9) /* 1 - 16 */ ++#define ECC_ERR_CNT(x, e) ((((x) >> (e).low) & (e).low_mask) \ ++ | (((x) >> (e).high) & (e).high_mask) << (e).low_bn) ++#define INT_DMA BIT(0) ++#define NFC_BANK (0x800) ++#define NFC_BANK_STEP (0x100) ++#define BANK_DATA (0x00) ++#define BANK_ADDR (0x04) ++#define BANK_CMD (0x08) ++#define NFC_SRAM0 (0x1000) ++#define NFC_SRAM1 (0x1400) ++#define NFC_SRAM_SIZE (0x400) ++#define THIS_NAME "rk-nand" ++#define NFC_TIMEOUT (500000) ++#define NFC_MAX_OOB_PER_STEP 128 ++#define NFC_MIN_OOB_PER_STEP 64 ++#define MAX_DATA_SIZE 0xFFFC ++#define MAX_ADDRESS_CYC 6 ++#define NFC_ECC_MAX_MODES 4 ++#define NFC_MAX_NSELS (4) /* Some Soc only has 1 or 2 CSs */ ++#define NFC_SYS_DATA_SIZE (4) /* 4 bytes sys data in oob pre 1024 data */ ++#define RK_DEFAULT_CLOCK_RATE (150 * 1000 * 1000) /* 150 Mhz*/ ++#define ACCTIMING(csrw, rwpw, rwcs) ((csrw) << 12 | (rwpw) << 5 | (rwcs)) ++ ++enum nfc_type { ++ NFC_V6, ++ NFC_V8, ++ NFC_V9, ++}; ++ ++/** ++ * struct rk_ecc_cnt_status: represent a ecc status data. ++ * @err_flag_bit: error flag bit index at register. ++ * @low: ecc count low bit index at register. ++ * @low_mask: mask bit. ++ * @low_bn: ecc count low bit number. ++ * @high: ecc count high bit index at register. ++ * @high_mask: mask bit ++ */ ++struct ecc_cnt_status { ++ u8 err_flag_bit; ++ u8 low; ++ u8 low_mask; ++ u8 low_bn; ++ u8 high; ++ u8 high_mask; ++}; ++ ++/** ++ * @type: nfc version ++ * @ecc_strengths: ecc strengths ++ * @ecc_cfgs: ecc config values ++ * @flctl_off: FLCTL register offset ++ * @bchctl_off: BCHCTL register offset ++ * @dma_data_buf_off: DMA_DATA_BUF register offset ++ * @dma_oob_buf_off: DMA_OOB_BUF register offset ++ * @dma_cfg_off: DMA_CFG register offset ++ * @dma_st_off: DMA_ST register offset ++ * @bch_st_off: BCG_ST register offset ++ * @randmz_off: RANDMZ register offset ++ * @int_en_off: interrupt enable register offset ++ * @int_clr_off: interrupt clean register offset ++ * @int_st_off: interrupt status register offset ++ * @oob0_off: oob0 register offset ++ * @oob1_off: oob1 register offset ++ * @ecc0: represent ECC0 status data ++ * @ecc1: represent ECC1 status data ++ */ ++struct nfc_cfg { ++ enum nfc_type type; ++ u8 ecc_strengths[NFC_ECC_MAX_MODES]; ++ u32 ecc_cfgs[NFC_ECC_MAX_MODES]; ++ u32 flctl_off; ++ u32 bchctl_off; ++ u32 dma_cfg_off; ++ u32 dma_data_buf_off; ++ u32 dma_oob_buf_off; ++ u32 dma_st_off; ++ u32 bch_st_off; ++ u32 randmz_off; ++ u32 int_en_off; ++ u32 int_clr_off; ++ u32 int_st_off; ++ u32 oob0_off; ++ u32 oob1_off; ++ struct ecc_cnt_status ecc0; ++ struct ecc_cnt_status ecc1; ++}; ++ ++struct rk_nfc_nand_chip { ++ struct list_head node; ++ struct nand_chip nand; ++ ++ u32 spare_per_sector; ++ u32 oob_buf_per_sector; ++ ++ int nsels; ++ u8 sels[0]; ++ /* nothing after this field */ ++}; ++ ++struct rk_nfc_clk { ++ int nfc_rate; ++ struct clk *nfc_clk; ++ struct clk *ahb_clk; ++}; ++ ++struct rk_nfc { ++ struct nand_controller controller; ++ struct rk_nfc_clk clk; ++ ++ struct device *dev; ++ const struct nfc_cfg *cfg; ++ void __iomem *regs; ++ ++ int selected_bank; ++ int band_offset; ++ ++ struct completion done; ++ struct list_head chips; ++ ++ u8 *buffer; ++ u8 *page_buf; ++ u32 *oob_buf; ++ ++ unsigned long assigned_cs; ++}; ++ ++static inline struct rk_nfc_nand_chip *to_rk_nand(struct nand_chip *nand) ++{ ++ return container_of(nand, struct rk_nfc_nand_chip, nand); ++} ++ ++static inline u8 *data_ptr(struct nand_chip *chip, const u8 *p, int i) ++{ ++ return (u8 *)p + i * chip->ecc.size; ++} ++ ++static inline u8 *oob_ptr(struct nand_chip *chip, int i) ++{ ++ u8 *poi; ++ ++ poi = chip->oob_poi + i * NFC_SYS_DATA_SIZE; ++ ++ return poi; ++} ++ ++static inline int rk_data_len(struct nand_chip *chip) ++{ ++ struct rk_nfc_nand_chip *rk_nand = to_rk_nand(chip); ++ ++ return chip->ecc.size + rk_nand->spare_per_sector; ++} ++ ++static inline u8 *rk_data_ptr(struct nand_chip *chip, int i) ++{ ++ struct rk_nfc *nfc = nand_get_controller_data(chip); ++ ++ return nfc->buffer + i * rk_data_len(chip); ++} ++ ++static inline u8 *rk_oob_ptr(struct nand_chip *chip, int i) ++{ ++ struct rk_nfc *nfc = nand_get_controller_data(chip); ++ ++ return nfc->buffer + i * rk_data_len(chip) + chip->ecc.size; ++} ++ ++static void rk_nfc_select_chip(struct nand_chip *nand, int chip) ++{ ++ struct rk_nfc *nfc = nand_get_controller_data(nand); ++ struct rk_nfc_nand_chip *rk_nand = to_rk_nand(nand); ++ u32 val; ++ ++ if (chip < 0) { ++ nfc->selected_bank = -1; ++ /* Deselect the currently selected target */ ++ val = readl_relaxed(nfc->regs + NFC_FMCTL); ++ val &= ~FMCTL_CE_SEL_M; ++ writel(val, nfc->regs + NFC_FMCTL); ++ return; ++ } ++ ++ nfc->selected_bank = rk_nand->sels[chip]; ++ nfc->band_offset = NFC_BANK + nfc->selected_bank * NFC_BANK_STEP; ++ ++ val = readl_relaxed(nfc->regs + NFC_FMCTL); ++ val &= ~FMCTL_CE_SEL_M; ++ val |= FMCTL_CE_SEL(nfc->selected_bank); ++ ++ writel(val, nfc->regs + NFC_FMCTL); ++} ++ ++static inline void rk_nfc_wait_ioready(struct rk_nfc *nfc) ++{ ++ int rc; ++ u32 val; ++ ++ rc = readl_poll_timeout_atomic(nfc->regs + NFC_FMCTL, val, ++ val & FMCTL_RDY, 10, NFC_TIMEOUT); ++ if (rc < 0) ++ dev_err(nfc->dev, "data not ready\n"); ++} ++ ++static inline u8 rk_nfc_read_byte(struct nand_chip *chip) ++{ ++ struct rk_nfc *nfc = nand_get_controller_data(chip); ++ ++ return readb_relaxed(nfc->regs + nfc->band_offset + BANK_DATA); ++} ++ ++static void rk_nfc_read_buf(struct nand_chip *chip, u8 *buf, int len) ++{ ++ int i; ++ ++ for (i = 0; i < len; i++) ++ buf[i] = rk_nfc_read_byte(chip); ++} ++ ++static void rk_nfc_write_byte(struct nand_chip *chip, u8 byte) ++{ ++ struct rk_nfc *nfc = nand_get_controller_data(chip); ++ ++ writeb(byte, nfc->regs + nfc->band_offset + BANK_DATA); ++} ++ ++static void rk_nfc_write_buf(struct nand_chip *chip, const u8 *buf, int len) ++{ ++ int i; ++ ++ for (i = 0; i < len; i++) ++ rk_nfc_write_byte(chip, buf[i]); ++} ++ ++static int rk_nfc_cmd(struct nand_chip *chip, ++ const struct nand_subop *subop) ++{ ++ struct rk_nfc *nfc = nand_get_controller_data(chip); ++ u32 cnt = 0; ++ unsigned int i, j, remaining, start; ++ int reg_offset = nfc->band_offset; ++ u8 *inbuf = NULL; ++ const u8 *outbuf; ++ void __iomem *data_reg; ++ ++ for (i = 0; i < subop->ninstrs; i++) { ++ const struct nand_op_instr *instr = &subop->instrs[i]; ++ ++ switch (instr->type) { ++ case NAND_OP_CMD_INSTR: ++ writeb(instr->ctx.cmd.opcode, ++ nfc->regs + reg_offset + BANK_CMD); ++ break; ++ ++ case NAND_OP_ADDR_INSTR: ++ remaining = nand_subop_get_num_addr_cyc(subop, i); ++ start = nand_subop_get_addr_start_off(subop, i); ++ ++ for (j = 0; j < 8 && j + start < remaining; j++) ++ writeb(instr->ctx.addr.addrs[j + start], ++ nfc->regs + reg_offset + BANK_ADDR); ++ break; ++ ++ case NAND_OP_DATA_IN_INSTR: ++ case NAND_OP_DATA_OUT_INSTR: ++ start = nand_subop_get_data_start_off(subop, i); ++ cnt = nand_subop_get_data_len(subop, i); ++ data_reg = nfc->regs + nfc->band_offset + BANK_DATA; ++ ++ if (instr->type == NAND_OP_DATA_OUT_INSTR) { ++ outbuf = instr->ctx.data.buf.out + start; ++ for (j = 0; j < cnt; j++) ++ writeb(outbuf[j], data_reg); ++ } else { ++ inbuf = instr->ctx.data.buf.in + start; ++ for (j = 0; j < cnt; j++) ++ inbuf[j] = readb_relaxed(data_reg); ++ } ++ break; ++ ++ case NAND_OP_WAITRDY_INSTR: ++ rk_nfc_wait_ioready(nfc); ++ break; ++ } ++ } ++ ++ return 0; ++} ++ ++static const struct nand_op_parser rk_nfc_op_parser = NAND_OP_PARSER( ++ NAND_OP_PARSER_PATTERN( ++ rk_nfc_cmd, ++ NAND_OP_PARSER_PAT_CMD_ELEM(true), ++ NAND_OP_PARSER_PAT_ADDR_ELEM(true, MAX_ADDRESS_CYC), ++ NAND_OP_PARSER_PAT_CMD_ELEM(true), ++ NAND_OP_PARSER_PAT_WAITRDY_ELEM(true), ++ NAND_OP_PARSER_PAT_DATA_IN_ELEM(true, MAX_DATA_SIZE)), ++ NAND_OP_PARSER_PATTERN( ++ rk_nfc_cmd, ++ NAND_OP_PARSER_PAT_CMD_ELEM(true), ++ NAND_OP_PARSER_PAT_ADDR_ELEM(true, MAX_ADDRESS_CYC), ++ NAND_OP_PARSER_PAT_DATA_OUT_ELEM(true, MAX_DATA_SIZE), ++ NAND_OP_PARSER_PAT_CMD_ELEM(true), ++ NAND_OP_PARSER_PAT_WAITRDY_ELEM(true)), ++); ++ ++static int rk_nfc_exec_op(struct nand_chip *chip, ++ const struct nand_operation *op, ++ bool check_only) ++{ ++ rk_nfc_select_chip(chip, op->cs); ++ return nand_op_parser_exec_op(chip, &rk_nfc_op_parser, op, ++ check_only); ++} ++ ++static int rk_nfc_setup_data_interface(struct nand_chip *chip, int csline, ++ const struct nand_data_interface *conf) ++{ ++ struct rk_nfc *nfc = nand_get_controller_data(chip); ++ const struct nand_sdr_timings *timings; ++ u32 rate, tc2rw, trwpw, trw2c; ++ u32 temp; ++ ++ if (csline == NAND_DATA_IFACE_CHECK_ONLY) ++ return 0; ++ ++ /* not onfi nand flash */ ++ if (!chip->parameters.onfi) ++ return 0; ++ ++ timings = nand_get_sdr_timings(conf); ++ if (IS_ERR(timings)) ++ return -ENOTSUPP; ++ ++ rate = clk_get_rate(nfc->clk.nfc_clk); ++ ++ /* turn clock rate into KHZ */ ++ rate /= 1000; ++ ++ tc2rw = 1; ++ trw2c = 1; ++ ++ trwpw = max(timings->tWC_min, timings->tRC_min) / 1000; ++ trwpw = DIV_ROUND_UP(trwpw * rate, 1000000); ++ ++ temp = timings->tREA_max / 1000; ++ temp = DIV_ROUND_UP(temp * rate, 1000000); ++ ++ if (trwpw < temp) ++ trwpw = temp; ++ ++ /* ++ * ACCON: access timing control register ++ * ------------------------------------- ++ * 31:18: reserved ++ * 17:12: csrw, clock cycles from the falling edge of CSn to the ++ falling edge of RDn or WRn ++ * 11:11: reserved ++ * 10:05: rwpw, the width of RDn or WRn in processor clock cycles ++ * 04:00: rwcs, clock cycles from the rising edge of RDn or WRn to the ++ rising edge of CSn ++ */ ++ temp = ACCTIMING(tc2rw, trwpw, trw2c); ++ writel(temp, nfc->regs + NFC_FMWAIT); ++ ++ return 0; ++} ++ ++static void rk_nfc_xfer_start(struct rk_nfc *nfc, u8 rw, u8 n_KB, ++ dma_addr_t dma_data, dma_addr_t dma_oob) ++{ ++ u32 dma_reg, fl_reg, bch_reg; ++ ++ dma_reg = DMA_ST | ((!rw) << DMA_WR) | DMA_EN | (2 << DMA_AHB_SIZE) | ++ (7 << DMA_BURST_SIZE) | (16 << DMA_INC_NUM); ++ ++ fl_reg = (rw << FLCTL_WR) | FLCTL_XFER_EN | FLCTL_ACORRECT | ++ (n_KB << FLCTL_XFER_SECTOR) | FLCTL_TOG_FIX; ++ ++ if (nfc->cfg->type == NFC_V6 || nfc->cfg->type == NFC_V8) { ++ bch_reg = readl_relaxed(nfc->regs + nfc->cfg->bchctl_off); ++ bch_reg = (bch_reg & (~BCHCTL_BANK_M)) | ++ (nfc->selected_bank << BCHCTL_BANK); ++ writel(bch_reg, nfc->regs + nfc->cfg->bchctl_off); ++ } ++ ++ writel(dma_reg, nfc->regs + nfc->cfg->dma_cfg_off); ++ writel((u32)dma_data, nfc->regs + nfc->cfg->dma_data_buf_off); ++ writel((u32)dma_oob, nfc->regs + nfc->cfg->dma_oob_buf_off); ++ writel(fl_reg, nfc->regs + nfc->cfg->flctl_off); ++ fl_reg |= FLCTL_XFER_ST; ++ writel(fl_reg, nfc->regs + nfc->cfg->flctl_off); ++} ++ ++static int rk_nfc_wait_for_xfer_done(struct rk_nfc *nfc) ++{ ++ u32 reg; ++ int ret = 0; ++ void __iomem *ptr; ++ ++ ptr = nfc->regs + nfc->cfg->flctl_off; ++ ++ ret = readl_poll_timeout_atomic(ptr, reg, ++ reg & FLCTL_XFER_READY, ++ 10, NFC_TIMEOUT); ++ if (ret) ++ dev_err(nfc->dev, "timeout reg=%x\n", reg); ++ ++ return ret; ++} ++ ++static int rk_nfc_write_page(struct mtd_info *mtd, struct nand_chip *chip, ++ const u8 *buf, int page, int raw) ++{ ++ struct rk_nfc *nfc = nand_get_controller_data(chip); ++ struct nand_ecc_ctrl *ecc = &chip->ecc; ++ u8 *oob; ++ dma_addr_t dma_data, dma_oob; ++ int oob_step = (ecc->bytes > 60) ? NFC_MAX_OOB_PER_STEP : ++ NFC_MIN_OOB_PER_STEP; ++ int pages_per_blk = mtd->erasesize / mtd->writesize; ++ u32 reg; ++ int ret = 0, i; ++ ++ nand_prog_page_begin_op(chip, page, 0, NULL, 0); ++ ++ if (!raw) { ++ memcpy(nfc->page_buf, buf, mtd->writesize); ++ memset(nfc->oob_buf, 0xff, oob_step * ecc->steps); ++ /* ++ * The first 8 blocks is stored loader, the first ++ * 32 bits of oob need link to next page address ++ * in the same block for Bootrom. ++ * Swap the first oob with the seventh oob, ++ * and bad block mask save at seventh oob. ++ */ ++ swap(chip->oob_poi[0], chip->oob_poi[7]); ++ for (i = 0; i < ecc->steps; i++) { ++ oob = chip->oob_poi + i * NFC_SYS_DATA_SIZE; ++ reg = (oob[2] << 16) | (oob[3] << 24); ++ if (!i && page < pages_per_blk * 8) ++ reg |= (page & (pages_per_blk - 1)) * 4; ++ else ++ reg |= oob[0] | (oob[1] << 8); ++ ++ if (nfc->cfg->type == NFC_V6 || ++ nfc->cfg->type == NFC_V8) ++ nfc->oob_buf[i * oob_step / 4] = reg; ++ else ++ nfc->oob_buf[i] = reg; ++ } ++ ++ dma_data = dma_map_single(nfc->dev, (void *)nfc->page_buf, ++ mtd->writesize, DMA_TO_DEVICE); ++ dma_oob = dma_map_single(nfc->dev, nfc->oob_buf, ++ ecc->steps * oob_step, ++ DMA_TO_DEVICE); ++ ++ init_completion(&nfc->done); ++ writel(INT_DMA, nfc->regs + nfc->cfg->int_en_off); ++ ++ rk_nfc_xfer_start(nfc, NFC_WRITE, ecc->steps, dma_data, ++ dma_oob); ++ ret = wait_for_completion_timeout(&nfc->done, ++ msecs_to_jiffies(100)); ++ if (!ret) ++ ret = -ETIMEDOUT; ++ ret = rk_nfc_wait_for_xfer_done(nfc); ++ ++ dma_unmap_single(nfc->dev, dma_data, mtd->writesize, ++ DMA_TO_DEVICE); ++ dma_unmap_single(nfc->dev, dma_oob, ecc->steps * oob_step, ++ DMA_TO_DEVICE); ++ } else { ++ rk_nfc_write_buf(chip, buf, mtd->writesize + + mtd->oobsize); ++ } ++ ++ if (ret) ++ return ret; ++ ++ ret = nand_prog_page_end_op(chip); ++ ++ /* Deselect the currently selected target */ ++ rk_nfc_select_chip(chip, -1); ++ ++ return ret; ++} ++ ++static int rk_nfc_write_page_raw(struct nand_chip *chip, const u8 *buf, ++ int oob_on, int page) ++{ ++ struct mtd_info *mtd = nand_to_mtd(chip); ++ struct rk_nfc *nfc = nand_get_controller_data(chip); ++ u32 i; ++ ++ memset(nfc->buffer, 0xff, mtd->writesize + mtd->oobsize); ++ swap(chip->oob_poi[0], chip->oob_poi[7]); ++ for (i = 0; i < chip->ecc.steps; i++) { ++ if (buf) ++ memcpy(rk_data_ptr(chip, i), data_ptr(chip, buf, i), ++ chip->ecc.size); ++ ++ memcpy(rk_oob_ptr(chip, i), oob_ptr(chip, i), ++ NFC_SYS_DATA_SIZE); ++ } ++ ++ return rk_nfc_write_page(mtd, chip, nfc->buffer, page, 1); ++} ++ ++static int rk_nfc_write_oob_std(struct nand_chip *chip, int page) ++{ ++ return rk_nfc_write_page_raw(chip, NULL, 1, page); ++} ++ ++static int rk_nfc_read_page(struct mtd_info *mtd, struct nand_chip *chip, ++ u32 data_offs, u32 readlen, ++ u8 *buf, int page, int raw) ++{ ++ struct rk_nfc *nfc = nand_get_controller_data(chip); ++ struct nand_ecc_ctrl *ecc = &chip->ecc; ++ dma_addr_t dma_data, dma_oob; ++ int oob_step = (ecc->bytes > 60) ? NFC_MAX_OOB_PER_STEP : ++ NFC_MIN_OOB_PER_STEP; ++ int bitflips = 0; ++ int ret, i, bch_st; ++ u8 *oob; ++ u32 tmp; ++ ++ nand_read_page_op(chip, page, 0, NULL, 0); ++ if (!raw) { ++ dma_data = dma_map_single(nfc->dev, nfc->page_buf, ++ mtd->writesize, ++ DMA_FROM_DEVICE); ++ dma_oob = dma_map_single(nfc->dev, nfc->oob_buf, ++ ecc->steps * oob_step, ++ DMA_FROM_DEVICE); ++ init_completion(&nfc->done); ++ writel(INT_DMA, nfc->regs + nfc->cfg->int_en_off); ++ rk_nfc_xfer_start(nfc, NFC_READ, ecc->steps, dma_data, ++ dma_oob); ++ ret = wait_for_completion_timeout(&nfc->done, ++ msecs_to_jiffies(100)); ++ if (!ret) ++ dev_warn(nfc->dev, "read ahb/dma done timeout\n"); ++ rk_nfc_wait_for_xfer_done(nfc); ++ dma_unmap_single(nfc->dev, dma_data, mtd->writesize, ++ DMA_FROM_DEVICE); ++ dma_unmap_single(nfc->dev, dma_oob, ecc->steps * oob_step, ++ DMA_FROM_DEVICE); ++ ++ for (i = 0; i < ecc->steps; i++) { ++ oob = chip->oob_poi + i * NFC_SYS_DATA_SIZE; ++ if (nfc->cfg->type == NFC_V6 || ++ nfc->cfg->type == NFC_V8) ++ tmp = nfc->oob_buf[i * oob_step / 4]; ++ else ++ tmp = nfc->oob_buf[i]; ++ *oob++ = (u8)tmp; ++ *oob++ = (u8)(tmp >> 8); ++ *oob++ = (u8)(tmp >> 16); ++ *oob++ = (u8)(tmp >> 24); ++ } ++ swap(chip->oob_poi[0], chip->oob_poi[7]); ++ for (i = 0; i < ecc->steps / 2; i++) { ++ bch_st = readl_relaxed(nfc->regs + ++ nfc->cfg->bch_st_off + i * 4); ++ if (bch_st & BIT(nfc->cfg->ecc0.err_flag_bit) || ++ bch_st & BIT(nfc->cfg->ecc1.err_flag_bit)) { ++ mtd->ecc_stats.failed++; ++ bitflips = -1; ++ } else { ++ ret = ECC_ERR_CNT(bch_st, nfc->cfg->ecc0); ++ mtd->ecc_stats.corrected += ret; ++ bitflips = max_t(u32, bitflips, ret); ++ ++ ret = ECC_ERR_CNT(bch_st, nfc->cfg->ecc1); ++ mtd->ecc_stats.corrected += ret; ++ bitflips = max_t(u32, bitflips, ret); ++ } ++ } ++ memcpy(buf, nfc->page_buf, mtd->writesize); ++ ++ if (bitflips == -1) ++ dev_err(nfc->dev, "read_page %x %x %x %x %x %x\n", ++ page, bitflips, bch_st, ((u32 *)buf)[0], ++ ((u32 *)buf)[1], (u32)dma_data); ++ } else { ++ rk_nfc_read_buf(chip, buf, mtd->writesize + mtd->oobsize); ++ } ++ ++ /* Deselect the currently selected target */ ++ rk_nfc_select_chip(chip, -1); ++ ++ return bitflips; ++} ++ ++static int rk_nfc_write_page_hwecc(struct nand_chip *chip, const u8 *buf, ++ int oob_on, int page) ++{ ++ return rk_nfc_write_page(nand_to_mtd(chip), chip, buf, page, 0); ++} ++ ++static int rk_nfc_read_page_hwecc(struct nand_chip *chip, u8 *p, int oob_on, ++ int pg) ++{ ++ struct mtd_info *mtd = nand_to_mtd(chip); ++ ++ return rk_nfc_read_page(mtd, chip, 0, mtd->writesize, p, pg, 0); ++} ++ ++static int rk_nfc_read_page_raw(struct nand_chip *chip, u8 *buf, int oob_on, ++ int page) ++{ ++ struct mtd_info *mtd = nand_to_mtd(chip); ++ struct rk_nfc *nfc = nand_get_controller_data(chip); ++ int i, ret; ++ ++ ret = rk_nfc_read_page(mtd, chip, 0, mtd->writesize, nfc->buffer, ++ page, 1); ++ if (ret < 0) ++ return ret; ++ ++ for (i = 0; i < chip->ecc.steps; i++) { ++ memcpy(oob_ptr(chip, i), rk_oob_ptr(chip, i), ++ NFC_SYS_DATA_SIZE); ++ ++ if (buf) ++ memcpy(data_ptr(chip, buf, i), rk_data_ptr(chip, i), ++ chip->ecc.size); ++ } ++ swap(chip->oob_poi[0], chip->oob_poi[7]); ++ ++ return ret; ++} ++ ++static int rk_nfc_read_oob_std(struct nand_chip *chip, int page) ++{ ++ return rk_nfc_read_page_raw(chip, NULL, 1, page); ++} ++ ++static inline void rk_nfc_hw_init(struct rk_nfc *nfc) ++{ ++ /* disable flash wp */ ++ writel(FMCTL_WP, nfc->regs + NFC_FMCTL); ++ /* config default timing */ ++ writel(0x1081, nfc->regs + NFC_FMWAIT); ++ /* disable randomizer and dma */ ++ writel(0, nfc->regs + nfc->cfg->randmz_off); ++ writel(0, nfc->regs + nfc->cfg->dma_cfg_off); ++ writel(FLCTL_RST, nfc->regs + nfc->cfg->flctl_off); ++} ++ ++static irqreturn_t rk_nfc_irq(int irq, void *id) ++{ ++ struct rk_nfc *nfc = id; ++ u32 sta, ien; ++ ++ sta = readl_relaxed(nfc->regs + nfc->cfg->int_st_off); ++ ien = readl_relaxed(nfc->regs + nfc->cfg->int_en_off); ++ ++ if (!(sta & ien)) ++ return IRQ_NONE; ++ ++ writel(sta, nfc->regs + nfc->cfg->int_clr_off); ++ writel(~sta & ien, nfc->regs + nfc->cfg->int_en_off); ++ ++ complete(&nfc->done); ++ ++ return IRQ_HANDLED; ++} ++ ++static int rk_nfc_enable_clk(struct device *dev, struct rk_nfc_clk *clk) ++{ ++ int ret; ++ ++ ret = clk_prepare_enable(clk->nfc_clk); ++ if (ret) { ++ dev_err(dev, "failed to enable nfc clk\n"); ++ return ret; ++ } ++ ++ ret = clk_prepare_enable(clk->ahb_clk); ++ if (ret) { ++ dev_err(dev, "failed to enable ahb clk\n"); ++ clk_disable_unprepare(clk->nfc_clk); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static void rk_nfc_disable_clk(struct rk_nfc_clk *clk) ++{ ++ clk_disable_unprepare(clk->nfc_clk); ++ clk_disable_unprepare(clk->ahb_clk); ++} ++ ++static int rk_nfc_ooblayout_free(struct mtd_info *mtd, int section, ++ struct mtd_oob_region *oob_region) ++{ ++ struct nand_chip *chip = mtd_to_nand(mtd); ++ ++ if (section >= chip->ecc.steps) ++ return -ERANGE; ++ ++ if (!section) { ++ /* The first byte is bad block mask flag */ ++ oob_region->length = NFC_SYS_DATA_SIZE - 1; ++ oob_region->offset = 1; ++ } else { ++ oob_region->length = NFC_SYS_DATA_SIZE; ++ oob_region->offset = section * NFC_SYS_DATA_SIZE; ++ } ++ ++ return 0; ++} ++ ++static int rk_nfc_ooblayout_ecc(struct mtd_info *mtd, int section, ++ struct mtd_oob_region *oob_region) ++{ ++ struct nand_chip *chip = mtd_to_nand(mtd); ++ ++ if (section) ++ return -ERANGE; ++ ++ oob_region->offset = NFC_SYS_DATA_SIZE * chip->ecc.steps; ++ oob_region->length = mtd->oobsize - oob_region->offset; ++ ++ return 0; ++} ++ ++static const struct mtd_ooblayout_ops rk_nfc_ooblayout_ops = { ++ .free = rk_nfc_ooblayout_free, ++ .ecc = rk_nfc_ooblayout_ecc, ++}; ++ ++static int rk_nfc_hw_ecc_setup(struct mtd_info *mtd, ++ struct nand_ecc_ctrl *ecc, ++ uint32_t strength) ++{ ++ struct nand_chip *nand = mtd_to_nand(mtd); ++ struct rk_nfc *nfc = nand_get_controller_data(nand); ++ u32 reg, i; ++ ++ ecc->strength = strength; ++ ecc->steps = mtd->writesize / ecc->size; ++ ecc->bytes = DIV_ROUND_UP(ecc->strength * 14, 8); ++ /* HW ECC always work with even numbers of ECC bytes */ ++ ecc->bytes = ALIGN(ecc->bytes, 2); ++ ++ for (i = 0; i < NFC_ECC_MAX_MODES; i++) { ++ if (ecc->strength == nfc->cfg->ecc_strengths[i]) { ++ reg = nfc->cfg->ecc_cfgs[i]; ++ break; ++ } ++ } ++ ++ if (i >= NFC_ECC_MAX_MODES) ++ return -EINVAL; ++ ++ writel(reg, nfc->regs + nfc->cfg->bchctl_off); ++ ++ return 0; ++} ++ ++static int rk_nfc_ecc_init(struct device *dev, struct mtd_info *mtd) ++{ ++ struct nand_chip *nand = mtd_to_nand(mtd); ++ struct rk_nfc *nfc = nand_get_controller_data(nand); ++ struct nand_ecc_ctrl *ecc = &nand->ecc; ++ const u8 *strengths = nfc->cfg->ecc_strengths; ++ u8 max_strength, nfc_max_strength; ++ int i; ++ ++ nfc_max_strength = nfc->cfg->ecc_strengths[0]; ++ /* if optional dt settings not present */ ++ if (!ecc->size || !ecc->strength || ++ ecc->strength > nfc_max_strength) { ++ /* use datasheet requirements */ ++ ecc->strength = nand->base.eccreq.strength; ++ ecc->size = nand->base.eccreq.step_size; ++ ++ /* ++ * align eccstrength and eccsize ++ * this controller only supports 512 and 1024 sizes ++ */ ++ if (nand->ecc.size < 1024) { ++ if (mtd->writesize > 512) { ++ nand->ecc.size = 1024; ++ nand->ecc.strength <<= 1; ++ } else { ++ dev_err(dev, "ecc.size not supported\n"); ++ return -EINVAL; ++ } ++ } else { ++ nand->ecc.size = 1024; ++ } ++ ++ ecc->steps = mtd->writesize / ecc->size; ++ max_strength = ((mtd->oobsize / ecc->steps) - 4) * 8 / 14; ++ if (max_strength > nfc_max_strength) ++ max_strength = nfc_max_strength; ++ ++ for (i = 0; i < 4; i++) { ++ if (max_strength >= strengths[i]) ++ break; ++ } ++ ++ if (i >= 4) { ++ dev_err(nfc->dev, "unsupported strength\n"); ++ return -ENOTSUPP; ++ } ++ ++ ecc->strength = strengths[i]; ++ } ++ rk_nfc_hw_ecc_setup(mtd, ecc, ecc->strength); ++ dev_info(dev, "eccsize %d eccstrength %d\n", ++ nand->ecc.size, nand->ecc.strength); ++ ++ return 0; ++} ++ ++static int rk_nfc_attach_chip(struct nand_chip *chip) ++{ ++ struct mtd_info *mtd = nand_to_mtd(chip); ++ struct device *dev = mtd->dev.parent; ++ struct rk_nfc *nfc = nand_get_controller_data(chip); ++ struct rk_nfc_nand_chip *rk_nand = to_rk_nand(chip); ++ struct nand_ecc_ctrl *ecc = &chip->ecc; ++ int len; ++ int ret; ++ ++ if (chip->options & NAND_BUSWIDTH_16) { ++ dev_err(dev, "16bits buswidth not supported"); ++ return -EINVAL; ++ } ++ ++ if (ecc->mode != NAND_ECC_HW) ++ return 0; ++ ++ ret = rk_nfc_ecc_init(dev, mtd); ++ if (ret) ++ return ret; ++ rk_nand->spare_per_sector = ecc->bytes + NFC_SYS_DATA_SIZE; ++ ++ /* Check buffer first, avoid duplicate alloc buffer */ ++ if (nfc->buffer) ++ return 0; ++ ++ len = mtd->writesize + mtd->oobsize; ++ nfc->buffer = devm_kzalloc(dev, len, GFP_KERNEL | GFP_DMA); ++ if (!nfc->buffer) ++ return -ENOMEM; ++ ++ nfc->page_buf = nfc->buffer; ++ len = ecc->steps * NFC_MAX_OOB_PER_STEP; ++ nfc->oob_buf = devm_kzalloc(dev, len, GFP_KERNEL | GFP_DMA); ++ if (!nfc->oob_buf) { ++ devm_kfree(dev, nfc->buffer); ++ nfc->buffer = NULL; ++ nfc->oob_buf = NULL; ++ return -ENOMEM; ++ } ++ ++ chip->ecc.write_page_raw = rk_nfc_write_page_raw; ++ chip->ecc.write_page = rk_nfc_write_page_hwecc; ++ chip->ecc.write_oob_raw = rk_nfc_write_oob_std; ++ chip->ecc.write_oob = rk_nfc_write_oob_std; ++ ++ chip->ecc.read_page_raw = rk_nfc_read_page_raw; ++ chip->ecc.read_page = rk_nfc_read_page_hwecc; ++ chip->ecc.read_oob_raw = rk_nfc_read_oob_std; ++ chip->ecc.read_oob = rk_nfc_read_oob_std; ++ ++ return 0; ++} ++ ++static const struct nand_controller_ops rk_nfc_controller_ops = { ++ .attach_chip = rk_nfc_attach_chip, ++ .exec_op = rk_nfc_exec_op, ++ .setup_data_interface = rk_nfc_setup_data_interface, ++}; ++ ++static int rk_nfc_nand_chip_init(struct device *dev, struct rk_nfc *nfc, ++ struct device_node *np) ++{ ++ struct rk_nfc_nand_chip *chip; ++ struct nand_chip *nand; ++ struct mtd_info *mtd; ++ int nsels; ++ u32 tmp; ++ int ret; ++ int i; ++ ++ if (!of_get_property(np, "reg", &nsels)) ++ return -ENODEV; ++ nsels /= sizeof(u32); ++ if (!nsels || nsels > NFC_MAX_NSELS) { ++ dev_err(dev, "invalid reg property size %d\n", nsels); ++ return -EINVAL; ++ } ++ ++ chip = devm_kzalloc(dev, sizeof(*chip) + nsels * sizeof(u8), ++ GFP_KERNEL); ++ if (!chip) ++ return -ENOMEM; ++ ++ chip->nsels = nsels; ++ for (i = 0; i < nsels; i++) { ++ ret = of_property_read_u32_index(np, "reg", i, &tmp); ++ if (ret) { ++ dev_err(dev, "reg property failure : %d\n", ret); ++ return ret; ++ } ++ ++ if (tmp >= NFC_MAX_NSELS) { ++ dev_err(dev, "invalid CS: %u\n", tmp); ++ return -EINVAL; ++ } ++ ++ if (test_and_set_bit(tmp, &nfc->assigned_cs)) { ++ dev_err(dev, "CS %u already assigned\n", tmp); ++ return -EINVAL; ++ } ++ ++ chip->sels[i] = tmp; ++ } ++ ++ nand = &chip->nand; ++ nand->controller = &nfc->controller; ++ ++ nand_set_flash_node(nand, np); ++ nand_set_controller_data(nand, nfc); ++ ++ nand->options |= NAND_USE_BOUNCE_BUFFER | NAND_NO_SUBPAGE_WRITE; ++ nand->bbt_options = NAND_BBT_USE_FLASH | NAND_BBT_NO_OOB; ++ ++ /* set default mode in case dt entry is missing */ ++ nand->ecc.mode = NAND_ECC_HW; ++ ++ mtd = nand_to_mtd(nand); ++ mtd->owner = THIS_MODULE; ++ mtd->dev.parent = dev; ++ mtd->name = THIS_NAME; ++ mtd_set_ooblayout(mtd, &rk_nfc_ooblayout_ops); ++ rk_nfc_hw_init(nfc); ++ ret = nand_scan(nand, nsels); ++ if (ret) ++ return ret; ++ ret = mtd_device_register(mtd, NULL, 0); ++ if (ret) { ++ dev_err(dev, "mtd parse partition error\n"); ++ nand_release(nand); ++ return ret; ++ } ++ ++ list_add_tail(&chip->node, &nfc->chips); ++ ++ return 0; ++} ++ ++static int rk_nfc_nand_chips_init(struct device *dev, struct rk_nfc *nfc) ++{ ++ struct device_node *np = dev->of_node; ++ struct device_node *nand_np; ++ int ret = -EINVAL; ++ int tmp; ++ ++ for_each_child_of_node(np, nand_np) { ++ tmp = rk_nfc_nand_chip_init(dev, nfc, nand_np); ++ if (tmp) { ++ of_node_put(nand_np); ++ return ret; ++ } ++ /* At least one nand chip is initialized */ ++ ret = 0; ++ } ++ ++ return ret; ++} ++ ++static struct nfc_cfg nfc_v6_cfg = { ++ .type = NFC_V6, ++ .ecc_strengths = {60, 40, 24, 16}, ++ .ecc_cfgs = { ++ 0x00040011, 0x00040001, 0x00000011, 0x00000001, ++ }, ++ .flctl_off = 0x08, ++ .bchctl_off = 0x0C, ++ .dma_cfg_off = 0x10, ++ .dma_data_buf_off = 0x14, ++ .dma_oob_buf_off = 0x18, ++ .dma_st_off = 0x1C, ++ .bch_st_off = 0x20, ++ .randmz_off = 0x150, ++ .int_en_off = 0x16C, ++ .int_clr_off = 0x170, ++ .int_st_off = 0x174, ++ .oob0_off = 0x200, ++ .oob1_off = 0x230, ++ .ecc0 = { ++ .err_flag_bit = 2, ++ .low = 3, ++ .low_mask = 0x1F, ++ .low_bn = 5, ++ .high = 27, ++ .high_mask = 0x1, ++ }, ++ .ecc1 = { ++ .err_flag_bit = 15, ++ .low = 16, ++ .low_mask = 0x1F, ++ .low_bn = 5, ++ .high = 29, ++ .high_mask = 0x1, ++ }, ++}; ++ ++static struct nfc_cfg nfc_v8_cfg = { ++ .type = NFC_V8, ++ .ecc_strengths = {16, 16, 16, 16}, ++ .ecc_cfgs = { ++ 0x00000001, 0x00000001, 0x00000001, 0x00000001, ++ }, ++ .flctl_off = 0x08, ++ .bchctl_off = 0x0C, ++ .dma_cfg_off = 0x10, ++ .dma_data_buf_off = 0x14, ++ .dma_oob_buf_off = 0x18, ++ .dma_st_off = 0x1C, ++ .bch_st_off = 0x20, ++ .bch_st_off = 0x20, ++ .randmz_off = 0x150, ++ .int_en_off = 0x16C, ++ .int_clr_off = 0x170, ++ .int_st_off = 0x174, ++ .oob0_off = 0x200, ++ .oob1_off = 0x230, ++ .ecc0 = { ++ .err_flag_bit = 2, ++ .low = 3, ++ .low_mask = 0x1F, ++ .low_bn = 5, ++ .high = 27, ++ .high_mask = 0x1, ++ }, ++ .ecc1 = { ++ .err_flag_bit = 15, ++ .low = 16, ++ .low_mask = 0x1F, ++ .low_bn = 5, ++ .high = 29, ++ .high_mask = 0x1, ++ }, ++}; ++ ++static struct nfc_cfg nfc_v9_cfg = { ++ .type = NFC_V9, ++ .ecc_strengths = {70, 60, 40, 16}, ++ .ecc_cfgs = { ++ 0x00000001, 0x06000001, 0x04000001, 0x02000001, ++ }, ++ .flctl_off = 0x10, ++ .bchctl_off = 0x20, ++ .dma_cfg_off = 0x30, ++ .dma_data_buf_off = 0x34, ++ .dma_oob_buf_off = 0x38, ++ .dma_st_off = 0x3C, ++ .bch_st_off = 0x150, ++ .randmz_off = 0x208, ++ .int_en_off = 0x120, ++ .int_clr_off = 0x124, ++ .int_st_off = 0x128, ++ .oob0_off = 0x200, ++ .oob1_off = 0x204, ++ .ecc0 = { ++ .err_flag_bit = 2, ++ .low = 3, ++ .low_mask = 0x7F, ++ .low_bn = 7, ++ .high = 0, ++ .high_mask = 0x0, ++ }, ++ .ecc1 = { ++ .err_flag_bit = 18, ++ .low = 19, ++ .low_mask = 0x7F, ++ .low_bn = 7, ++ .high = 0, ++ .high_mask = 0x0, ++ }, ++}; ++ ++static const struct of_device_id rk_nfc_id_table[] = { ++ {.compatible = "rockchip,px30_nfc", ++ .data = &nfc_v9_cfg }, ++ {.compatible = "rockchip,rk3308_nfc", ++ .data = &nfc_v8_cfg }, ++ {.compatible = "rockchip,rv1108_nfc", ++ .data = &nfc_v8_cfg }, ++ {.compatible = "rockchip,rk3066_nfc", ++ .data = &nfc_v6_cfg }, ++ {.compatible = "rockchip,rk3188_nfc", ++ .data = &nfc_v6_cfg }, ++ {.compatible = "rockchip,rk3288_nfc", ++ .data = &nfc_v6_cfg }, ++ {.compatible = "rockchip,rk3368_nfc", ++ .data = &nfc_v6_cfg }, ++ {.compatible = "rockchip,rk2928_nfc", ++ .data = &nfc_v6_cfg }, ++ {.compatible = "rockchip,rk3036_nfc", ++ .data = &nfc_v6_cfg }, ++ {.compatible = "rockchip,rk3128_nfc", ++ .data = &nfc_v6_cfg }, ++ {.compatible = "rockchip,rk3228_nfc", ++ .data = &nfc_v6_cfg }, ++ {} ++}; ++MODULE_DEVICE_TABLE(of, rk_nfc_id_table); ++ ++static int rk_nfc_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct rk_nfc *nfc; ++ struct resource *res; ++ int ret, irq; ++ ++ nfc = devm_kzalloc(dev, sizeof(*nfc), GFP_KERNEL); ++ if (!nfc) ++ return -ENOMEM; ++ ++ nand_controller_init(&nfc->controller); ++ INIT_LIST_HEAD(&nfc->chips); ++ nfc->controller.ops = &rk_nfc_controller_ops; ++ ++ nfc->cfg = of_device_get_match_data(dev); ++ nfc->dev = dev; ++ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ nfc->regs = devm_ioremap_resource(dev, res); ++ if (IS_ERR(nfc->regs)) { ++ ret = PTR_ERR(nfc->regs); ++ goto release_nfc; ++ } ++ nfc->clk.nfc_clk = devm_clk_get(dev, "nfc"); ++ if (IS_ERR(nfc->clk.nfc_clk)) { ++ dev_err(dev, "no nfc clk\n"); ++ ret = PTR_ERR(nfc->clk.nfc_clk); ++ goto release_nfc; ++ } ++ nfc->clk.ahb_clk = devm_clk_get(dev, "ahb"); ++ if (IS_ERR(nfc->clk.ahb_clk)) { ++ dev_err(dev, "no ahb clk\n"); ++ ret = PTR_ERR(nfc->clk.ahb_clk); ++ goto release_nfc; ++ } ++ ++ ret = rk_nfc_enable_clk(dev, &nfc->clk); ++ if (ret) ++ goto release_nfc; ++ ++ irq = platform_get_irq(pdev, 0); ++ if (irq < 0) { ++ dev_err(dev, "no nfc irq resource\n"); ++ ret = -EINVAL; ++ goto clk_disable; ++ } ++ ++ writel(0, nfc->regs + nfc->cfg->int_en_off); ++ ret = devm_request_irq(dev, irq, rk_nfc_irq, 0x0, "rk-nand", nfc); ++ if (ret) { ++ dev_err(dev, "failed to request nfc irq\n"); ++ goto clk_disable; ++ } ++ ++ platform_set_drvdata(pdev, nfc); ++ ++ ret = rk_nfc_nand_chips_init(dev, nfc); ++ if (ret) { ++ dev_err(dev, "failed to init nand chips\n"); ++ goto clk_disable; ++ } ++ return 0; ++ ++clk_disable: ++ rk_nfc_disable_clk(&nfc->clk); ++release_nfc: ++ return ret; ++} ++ ++static int rk_nfc_remove(struct platform_device *pdev) ++{ ++ struct rk_nfc *nfc = platform_get_drvdata(pdev); ++ struct rk_nfc_nand_chip *chip; ++ ++ while (!list_empty(&nfc->chips)) { ++ chip = list_first_entry(&nfc->chips, struct rk_nfc_nand_chip, ++ node); ++ nand_release(&chip->nand); ++ list_del(&chip->node); ++ } ++ ++ rk_nfc_disable_clk(&nfc->clk); ++ ++ return 0; ++} ++ ++static int __maybe_unused rk_nfc_suspend(struct device *dev) ++{ ++ struct rk_nfc *nfc = dev_get_drvdata(dev); ++ ++ rk_nfc_disable_clk(&nfc->clk); ++ ++ return 0; ++} ++ ++static int __maybe_unused rk_nfc_resume(struct device *dev) ++{ ++ struct rk_nfc *nfc = dev_get_drvdata(dev); ++ struct rk_nfc_nand_chip *chip; ++ struct nand_chip *nand; ++ int ret; ++ u32 i; ++ ++ ret = rk_nfc_enable_clk(dev, &nfc->clk); ++ if (ret) ++ return ret; ++ ++ /* reset NAND chip if VCC was powered off */ ++ list_for_each_entry(chip, &nfc->chips, node) { ++ nand = &chip->nand; ++ for (i = 0; i < chip->nsels; i++) ++ nand_reset(nand, i); ++ } ++ ++ return 0; ++} ++ ++static const struct dev_pm_ops rk_nfc_pm_ops = { ++ SET_SYSTEM_SLEEP_PM_OPS(rk_nfc_suspend, rk_nfc_resume) ++}; ++ ++static struct platform_driver rk_nfc_driver = { ++ .probe = rk_nfc_probe, ++ .remove = rk_nfc_remove, ++ .driver = { ++ .name = THIS_NAME, ++ .of_match_table = rk_nfc_id_table, ++ .pm = &rk_nfc_pm_ops, ++ }, ++}; ++ ++module_platform_driver(rk_nfc_driver); ++ ++MODULE_LICENSE("Dual MIT/GPL"); ++MODULE_AUTHOR("Yifeng Zhao "); ++MODULE_DESCRIPTION("Rockchip Nand Flash Controller Driver"); ++MODULE_ALIAS("platform:rockchip_nand"); +-- +2.17.1 + + +From d8b77253afb7292f637d62877f7c2e87f440a1ff Mon Sep 17 00:00:00 2001 +From: Yifeng Zhao +Date: Fri, 20 Mar 2020 17:33:41 +0800 +Subject: [PATCH] dt-bindings: mtd: Describe Rockchip RK3xxx NAND flash + controller + +Documentation support for Rockchip RK3xxx NAND flash controllers + +Signed-off-by: Yifeng Zhao +Reviewed-by: Rob Herring +--- + .../bindings/mtd/rockchip,nand.yaml | 101 ++++++++++++++++++ + 1 file changed, 101 insertions(+) + create mode 100644 Documentation/devicetree/bindings/mtd/rockchip,nand.yaml + +diff --git a/Documentation/devicetree/bindings/mtd/rockchip,nand.yaml b/Documentation/devicetree/bindings/mtd/rockchip,nand.yaml +new file mode 100644 +index 000000000000..907af0d52b6b +--- /dev/null ++++ b/Documentation/devicetree/bindings/mtd/rockchip,nand.yaml +@@ -0,0 +1,101 @@ ++# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) ++%YAML 1.2 ++--- ++$id: http://devicetree.org/schemas/mtd/rockchip,nand.yaml# ++$schema: http://devicetree.org/meta-schemas/core.yaml# ++ ++title: Rockchip SoCs NAND FLASH Controller (NFC) Device Tree Bindings ++ ++allOf: ++ - $ref: "nand-controller.yaml" ++ ++maintainers: ++ - Yifeng Zhao ++ ++properties: ++ "#address-cells": true ++ "#size-cells": true ++ ++ compatible: ++ enum: ++ - rockchip,px30_nfc ++ - rockchip,rk3308_nfc ++ - rockchip,rv1108_nfc ++ - rockchip,rk3066_nfc ++ - rockchip,rk3188_nfc ++ - rockchip,rk3288_nfc ++ - rockchip,rk3368_nfc ++ - rockchip,rk2928_nfc ++ - rockchip,rk3036_nfc ++ - rockchip,rk3128_nfc ++ - rockchip,rk3228_nfc ++ ++ reg: ++ maxItems: 1 ++ ++ interrupts: ++ maxItems: 1 ++ ++ clocks: ++ items: ++ - description: Module Clock ++ - description: Bus Clock ++ ++ clock-names: ++ items: ++ - const: nfc ++ - const: ahb ++ ++patternProperties: ++ "^nand@[0-3]$": ++ type: object ++ properties: ++ reg: ++ minimum: 0 ++ maximum: 3 ++ ++ nand-ecc-step-size: ++ const: 1024 ++ ++ nand-ecc-strength: ++ enum: [16, 24 , 40, 60, 70] ++ ++ nand-bus-width: ++ const: 8 ++ ++required: ++ - compatible ++ - reg ++ - interrupts ++ - clocks ++ - clock-names ++ ++examples: ++ - | ++ #include ++ #include ++ nfc: nand-controller@ff4b0000 { ++ compatible = "rockchip,nfc"; ++ reg = <0x0 0xff4b0000 0x0 0x4000>; ++ interrupts = ; ++ clocks = <&cru SCLK_NANDC>, <&cru HCLK_NANDC>; ++ clock-names = "nfc", "ahb"; ++ assigned-clocks = <&clks SCLK_NANDC>; ++ assigned-clock-rates = <150000000>; ++ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&flash_csn0 &flash_rdy &flash_ale &flash_cle ++ &flash_wrn &flash_rdn &flash_bus8>; ++ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ nand@0 { ++ reg = <0>; ++ nand-ecc-mode = "hw"; ++ nand-ecc-strength = <16>; ++ nand-ecc-step-size = <1024>; ++ nand-bus-width = <8>; ++ }; ++ }; ++ ++... +-- +2.17.1 + + +From 7c0fa2538944c2b988b3575020e4e8b81e8f01ed Mon Sep 17 00:00:00 2001 +From: Yifeng Zhao +Date: Fri, 20 Mar 2020 17:33:42 +0800 +Subject: [PATCH] MAINTAINERS: add maintainers to rockchip nfc + +Signed-off-by: Yifeng Zhao +--- + MAINTAINERS | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/MAINTAINERS b/MAINTAINERS +index 5a5332b3591d..0bff05c4c96d 100644 +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -2276,6 +2276,7 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip.git + S: Maintained + F: Documentation/devicetree/bindings/i2c/i2c-rk3x.txt + F: Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.yaml ++F: Documentation/devicetree/bindings/*/*rockchip*.yaml + F: arch/arm/boot/dts/rk3* + F: arch/arm/boot/dts/rv1108* + F: arch/arm/mach-rockchip/ +@@ -2283,6 +2284,7 @@ F: drivers/clk/rockchip/ + F: drivers/i2c/busses/i2c-rk3x.c + F: drivers/*/*rockchip* + F: drivers/*/*/*rockchip* ++F: drivers/*/*/*/*rockchip* + F: sound/soc/rockchip/ + N: rockchip + +-- +2.17.1 + diff --git a/patch/kernel/rk322x-current/01-linux-0013-v4l2-from-list.patch b/patch/kernel/rk322x-current/01-linux-0013-v4l2-from-list.patch new file mode 100644 index 0000000000..44e7d191f6 --- /dev/null +++ b/patch/kernel/rk322x-current/01-linux-0013-v4l2-from-list.patch @@ -0,0 +1,319 @@ +diff --git a/Documentation/media/uapi/v4l/ext-ctrls-codec.rst b/Documentation/media/uapi/v4l/ext-ctrls-codec.rst +index 28313c0f4e7c..d472a54d1c4d 100644 +--- a/Documentation/media/uapi/v4l/ext-ctrls-codec.rst ++++ b/Documentation/media/uapi/v4l/ext-ctrls-codec.rst +@@ -2028,6 +2028,18 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type - + * - ``V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM`` + - 0x00000004 + - The DPB entry is a long term reference frame ++ * - ``V4L2_H264_DPB_ENTRY_FLAG_FIELD_PICTURE`` ++ - 0x00000008 ++ - The DPB entry is a field picture ++ * - ``V4L2_H264_DPB_ENTRY_FLAG_REF_TOP`` ++ - 0x00000010 ++ - The DPB entry is a top field reference ++ * - ``V4L2_H264_DPB_ENTRY_FLAG_REF_BOTTOM`` ++ - 0x00000020 ++ - The DPB entry is a bottom field reference ++ * - ``V4L2_H264_DPB_ENTRY_FLAG_REF_FRAME`` ++ - 0x00000030 ++ - The DPB entry is a reference frame + + ``V4L2_CID_MPEG_VIDEO_H264_DECODE_MODE (enum)`` + Specifies the decoding mode to use. Currently exposes slice-based and +diff --git a/include/media/h264-ctrls.h b/include/media/h264-ctrls.h +index e877bf1d537c..76020ebd1e6c 100644 +--- a/include/media/h264-ctrls.h ++++ b/include/media/h264-ctrls.h +@@ -185,6 +185,10 @@ struct v4l2_ctrl_h264_slice_params { + #define V4L2_H264_DPB_ENTRY_FLAG_VALID 0x01 + #define V4L2_H264_DPB_ENTRY_FLAG_ACTIVE 0x02 + #define V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM 0x04 ++#define V4L2_H264_DPB_ENTRY_FLAG_FIELD_PICTURE 0x08 ++#define V4L2_H264_DPB_ENTRY_FLAG_REF_TOP 0x10 ++#define V4L2_H264_DPB_ENTRY_FLAG_REF_BOTTOM 0x20 ++#define V4L2_H264_DPB_ENTRY_FLAG_REF_FRAME 0x30 + + struct v4l2_h264_dpb_entry { + __u64 reference_ts; +-- +2.17.1 + + +From ef240de60cedea0264ca954a8e8e2fa25db097ae Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Tue, 29 Oct 2019 01:26:02 +0000 +Subject: [PATCH] RFC: media: hantro: Fix H264 decoding of field encoded + content + +This still need code cleanup and formatting + +Signed-off-by: Jonas Karlman +--- + .../staging/media/hantro/hantro_g1_h264_dec.c | 17 +-- + drivers/staging/media/hantro/hantro_h264.c | 122 ++++++++++++------ + drivers/staging/media/hantro/hantro_hw.h | 2 + + 3 files changed, 85 insertions(+), 56 deletions(-) + +diff --git a/drivers/staging/media/hantro/hantro_g1_h264_dec.c b/drivers/staging/media/hantro/hantro_g1_h264_dec.c +index 424c648ce9fc..89cf5741280e 100644 +--- a/drivers/staging/media/hantro/hantro_g1_h264_dec.c ++++ b/drivers/staging/media/hantro/hantro_g1_h264_dec.c +@@ -132,25 +132,12 @@ static void set_ref(struct hantro_ctx *ctx) + struct v4l2_h264_dpb_entry *dpb = ctx->h264_dec.dpb; + const u8 *b0_reflist, *b1_reflist, *p_reflist; + struct hantro_dev *vpu = ctx->dev; +- u32 dpb_longterm = 0; +- u32 dpb_valid = 0; + int reg_num; + u32 reg; + int i; + +- /* +- * Set up bit maps of valid and long term DPBs. +- * NOTE: The bits are reversed, i.e. MSb is DPB 0. +- */ +- for (i = 0; i < HANTRO_H264_DPB_SIZE; ++i) { +- if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE) +- dpb_valid |= BIT(HANTRO_H264_DPB_SIZE - 1 - i); +- +- if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM) +- dpb_longterm |= BIT(HANTRO_H264_DPB_SIZE - 1 - i); +- } +- vdpu_write_relaxed(vpu, dpb_valid << 16, G1_REG_VALID_REF); +- vdpu_write_relaxed(vpu, dpb_longterm << 16, G1_REG_LT_REF); ++ vdpu_write_relaxed(vpu, ctx->h264_dec.dpb_valid, G1_REG_VALID_REF); ++ vdpu_write_relaxed(vpu, ctx->h264_dec.dpb_longterm, G1_REG_LT_REF); + + /* + * Set up reference frame picture numbers. +diff --git a/drivers/staging/media/hantro/hantro_h264.c b/drivers/staging/media/hantro/hantro_h264.c +index f2d3e81fb6ce..4db779354e89 100644 +--- a/drivers/staging/media/hantro/hantro_h264.c ++++ b/drivers/staging/media/hantro/hantro_h264.c +@@ -225,17 +225,65 @@ static void prepare_table(struct hantro_ctx *ctx) + { + const struct hantro_h264_dec_ctrls *ctrls = &ctx->h264_dec.ctrls; + const struct v4l2_ctrl_h264_decode_params *dec_param = ctrls->decode; ++ const struct v4l2_ctrl_h264_slice_params *slices = ctrls->slices; + struct hantro_h264_dec_priv_tbl *tbl = ctx->h264_dec.priv.cpu; + const struct v4l2_h264_dpb_entry *dpb = ctx->h264_dec.dpb; ++ u32 dpb_longterm = 0; ++ u32 dpb_valid = 0; + int i; + ++ /* ++ * Set up bit maps of valid and long term DPBs. ++ * NOTE: The bits are reversed, i.e. MSb is DPB 0. ++ */ ++ if ((slices[0].flags & V4L2_H264_SLICE_FLAG_FIELD_PIC) || (slices[0].flags & V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD)) { ++ for (i = 0; i < HANTRO_H264_DPB_SIZE * 2; ++i) { ++ // check for correct reference use ++ u32 flag = (i & 0x1) ? V4L2_H264_DPB_ENTRY_FLAG_REF_BOTTOM : V4L2_H264_DPB_ENTRY_FLAG_REF_TOP; ++ if (dpb[i / 2].flags & flag) ++ dpb_valid |= BIT(HANTRO_H264_DPB_SIZE * 2 - 1 - i); ++ ++ if (dpb[i / 2].flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM) ++ dpb_longterm |= BIT(HANTRO_H264_DPB_SIZE * 2 - 1 - i); ++ } ++ ++ ctx->h264_dec.dpb_valid = dpb_valid; ++ ctx->h264_dec.dpb_longterm = dpb_longterm; ++ } else { ++ for (i = 0; i < HANTRO_H264_DPB_SIZE; ++i) { ++ if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE) ++ dpb_valid |= BIT(HANTRO_H264_DPB_SIZE - 1 - i); ++ ++ if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM) ++ dpb_longterm |= BIT(HANTRO_H264_DPB_SIZE - 1 - i); ++ } ++ ++ ctx->h264_dec.dpb_valid = dpb_valid << 16; ++ ctx->h264_dec.dpb_longterm = dpb_longterm << 16; ++ } ++ + for (i = 0; i < HANTRO_H264_DPB_SIZE; ++i) { +- tbl->poc[i * 2] = dpb[i].top_field_order_cnt; +- tbl->poc[i * 2 + 1] = dpb[i].bottom_field_order_cnt; ++ if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE) { ++ tbl->poc[i * 2] = dpb[i].top_field_order_cnt; ++ tbl->poc[i * 2 + 1] = dpb[i].bottom_field_order_cnt; ++ } else { ++ tbl->poc[i * 2] = 0; ++ tbl->poc[i * 2 + 1] = 0; ++ } + } + +- tbl->poc[32] = dec_param->top_field_order_cnt; +- tbl->poc[33] = dec_param->bottom_field_order_cnt; ++ if ((slices[0].flags & V4L2_H264_SLICE_FLAG_FIELD_PIC) || !(slices[0].flags & V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD)) { ++ if ((slices[0].flags & V4L2_H264_SLICE_FLAG_FIELD_PIC)) ++ tbl->poc[32] = (slices[0].flags & V4L2_H264_SLICE_FLAG_BOTTOM_FIELD) ? ++ dec_param->bottom_field_order_cnt : ++ dec_param->top_field_order_cnt; ++ else ++ tbl->poc[32] = min(dec_param->top_field_order_cnt, dec_param->bottom_field_order_cnt); ++ tbl->poc[33] = 0; ++ } else { ++ tbl->poc[32] = dec_param->top_field_order_cnt; ++ tbl->poc[33] = dec_param->bottom_field_order_cnt; ++ } + + reorder_scaling_list(ctx); + } +@@ -249,21 +297,6 @@ struct hantro_h264_reflist_builder { + u8 num_valid; + }; + +-static s32 get_poc(enum v4l2_field field, s32 top_field_order_cnt, +- s32 bottom_field_order_cnt) +-{ +- switch (field) { +- case V4L2_FIELD_TOP: +- return top_field_order_cnt; +- case V4L2_FIELD_BOTTOM: +- return bottom_field_order_cnt; +- default: +- break; +- } +- +- return min(top_field_order_cnt, bottom_field_order_cnt); +-} +- + static void + init_reflist_builder(struct hantro_ctx *ctx, + struct hantro_h264_reflist_builder *b) +@@ -271,9 +304,7 @@ init_reflist_builder(struct hantro_ctx *ctx, + const struct v4l2_ctrl_h264_slice_params *slice_params; + const struct v4l2_ctrl_h264_decode_params *dec_param; + const struct v4l2_ctrl_h264_sps *sps; +- struct vb2_v4l2_buffer *buf = hantro_get_dst_buf(ctx); + const struct v4l2_h264_dpb_entry *dpb = ctx->h264_dec.dpb; +- struct vb2_queue *cap_q = &ctx->fh.m2m_ctx->cap_q_ctx.q; + int cur_frame_num, max_frame_num; + unsigned int i; + +@@ -285,21 +316,15 @@ init_reflist_builder(struct hantro_ctx *ctx, + + memset(b, 0, sizeof(*b)); + b->dpb = dpb; +- b->curpoc = get_poc(buf->field, dec_param->top_field_order_cnt, +- dec_param->bottom_field_order_cnt); ++ b->curpoc = (slice_params->flags & V4L2_H264_SLICE_FLAG_BOTTOM_FIELD) ? ++ dec_param->bottom_field_order_cnt : ++ dec_param->top_field_order_cnt; + + for (i = 0; i < ARRAY_SIZE(ctx->h264_dec.dpb); i++) { +- int buf_idx; +- +- if (!(dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE)) ++ u32 ref_flag = dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_REF_FRAME; ++ if (!ref_flag) + continue; + +- buf_idx = vb2_find_timestamp(cap_q, dpb[i].reference_ts, 0); +- if (buf_idx < 0) +- continue; +- +- buf = to_vb2_v4l2_buffer(vb2_get_buffer(cap_q, buf_idx)); +- + /* + * Handle frame_num wraparound as described in section + * '8.2.4.1 Decoding process for picture numbers' of the spec. +@@ -311,8 +336,13 @@ init_reflist_builder(struct hantro_ctx *ctx, + else + b->frame_nums[i] = dpb[i].frame_num; + +- b->pocs[i] = get_poc(buf->field, dpb[i].top_field_order_cnt, +- dpb[i].bottom_field_order_cnt); ++ if (ref_flag == V4L2_H264_DPB_ENTRY_FLAG_REF_FRAME) ++ b->pocs[i] = min(dpb[i].bottom_field_order_cnt, dpb[i].top_field_order_cnt); ++ else if (ref_flag == V4L2_H264_DPB_ENTRY_FLAG_REF_BOTTOM) ++ b->pocs[i] = dpb[i].bottom_field_order_cnt; ++ else if (ref_flag == V4L2_H264_DPB_ENTRY_FLAG_REF_TOP) ++ b->pocs[i] = dpb[i].top_field_order_cnt; ++ + b->unordered_reflist[b->num_valid] = i; + b->num_valid++; + } +@@ -466,8 +496,7 @@ build_b_ref_lists(const struct hantro_h264_reflist_builder *builder, + static bool dpb_entry_match(const struct v4l2_h264_dpb_entry *a, + const struct v4l2_h264_dpb_entry *b) + { +- return a->top_field_order_cnt == b->top_field_order_cnt && +- a->bottom_field_order_cnt == b->bottom_field_order_cnt; ++ return a->reference_ts == b->reference_ts; + } + + static void update_dpb(struct hantro_ctx *ctx) +@@ -481,13 +510,13 @@ static void update_dpb(struct hantro_ctx *ctx) + + /* Disable all entries by default. */ + for (i = 0; i < ARRAY_SIZE(ctx->h264_dec.dpb); i++) +- ctx->h264_dec.dpb[i].flags &= ~V4L2_H264_DPB_ENTRY_FLAG_ACTIVE; ++ ctx->h264_dec.dpb[i].flags = 0; + + /* Try to match new DPB entries with existing ones by their POCs. */ + for (i = 0; i < ARRAY_SIZE(dec_param->dpb); i++) { + const struct v4l2_h264_dpb_entry *ndpb = &dec_param->dpb[i]; + +- if (!(ndpb->flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE)) ++ if (!(ndpb->flags & V4L2_H264_DPB_ENTRY_FLAG_VALID)) + continue; + + /* +@@ -498,8 +527,7 @@ static void update_dpb(struct hantro_ctx *ctx) + struct v4l2_h264_dpb_entry *cdpb; + + cdpb = &ctx->h264_dec.dpb[j]; +- if (cdpb->flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE || +- !dpb_entry_match(cdpb, ndpb)) ++ if (!dpb_entry_match(cdpb, ndpb)) + continue; + + *cdpb = *ndpb; +@@ -535,7 +563,11 @@ dma_addr_t hantro_h264_get_ref_buf(struct hantro_ctx *ctx, + unsigned int dpb_idx) + { + struct v4l2_h264_dpb_entry *dpb = ctx->h264_dec.dpb; ++ const struct v4l2_ctrl_h264_decode_params *dec_param = ctx->h264_dec.ctrls.decode; ++ const struct v4l2_ctrl_h264_slice_params *slices = ctx->h264_dec.ctrls.slices; + dma_addr_t dma_addr = 0; ++ s32 cur_poc; ++ u32 flags; + + if (dpb[dpb_idx].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE) + dma_addr = hantro_get_ref(ctx, dpb[dpb_idx].reference_ts); +@@ -553,7 +585,15 @@ dma_addr_t hantro_h264_get_ref_buf(struct hantro_ctx *ctx, + dma_addr = vb2_dma_contig_plane_dma_addr(buf, 0); + } + +- return dma_addr; ++ cur_poc = slices[0].flags & V4L2_H264_SLICE_FLAG_BOTTOM_FIELD ? ++ dec_param->bottom_field_order_cnt : ++ dec_param->top_field_order_cnt; ++ flags = dpb[dpb_idx].flags & V4L2_H264_DPB_ENTRY_FLAG_FIELD_PICTURE ? 0x2 : 0; ++ flags |= abs(dpb[dpb_idx].top_field_order_cnt - cur_poc) < ++ abs(dpb[dpb_idx].bottom_field_order_cnt - cur_poc) ? ++ 0x1 : 0; ++ ++ return dma_addr | flags; + } + + int hantro_h264_dec_prepare_run(struct hantro_ctx *ctx) +diff --git a/drivers/staging/media/hantro/hantro_hw.h b/drivers/staging/media/hantro/hantro_hw.h +index 2398d4c1f207..3dc7b8f27c32 100644 +--- a/drivers/staging/media/hantro/hantro_hw.h ++++ b/drivers/staging/media/hantro/hantro_hw.h +@@ -88,6 +88,8 @@ struct hantro_h264_dec_hw_ctx { + struct v4l2_h264_dpb_entry dpb[HANTRO_H264_DPB_SIZE]; + struct hantro_h264_dec_reflists reflists; + struct hantro_h264_dec_ctrls ctrls; ++ u32 dpb_longterm; ++ u32 dpb_valid; + }; + + /** +-- +2.17.1 + diff --git a/patch/kernel/rk322x-current/01-linux-0014-v4l2-work-in-progress.patch b/patch/kernel/rk322x-current/01-linux-0014-v4l2-work-in-progress.patch new file mode 100644 index 0000000000..c032a84141 --- /dev/null +++ b/patch/kernel/rk322x-current/01-linux-0014-v4l2-work-in-progress.patch @@ -0,0 +1,1525 @@ +diff --git a/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c b/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c +index 7e9aad671489..b9b8194b42f2 100644 +--- a/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c ++++ b/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c +@@ -127,7 +127,7 @@ rk3399_vpu_mpeg2_dec_set_buffers(struct hantro_dev *vpu, + current_addr = addr; + + if (picture->picture_structure == PICT_BOTTOM_FIELD) +- addr += ALIGN(ctx->dst_fmt.width, 16); ++ addr += ALIGN(ctx->src_fmt.width, MB_DIM); + vdpu_write_relaxed(vpu, addr, VDPU_REG_DEC_OUT_BASE); + + if (!forward_addr) +@@ -220,8 +220,8 @@ void rk3399_vpu_mpeg2_dec_run(struct hantro_ctx *ctx) + VDPU_REG_DEC_CLK_GATE_E(1); + vdpu_write_relaxed(vpu, reg, VDPU_SWREG(57)); + +- reg = VDPU_REG_PIC_MB_WIDTH(MB_WIDTH(ctx->dst_fmt.width)) | +- VDPU_REG_PIC_MB_HEIGHT_P(MB_HEIGHT(ctx->dst_fmt.height)) | ++ reg = VDPU_REG_PIC_MB_WIDTH(MB_WIDTH(ctx->src_fmt.width)) | ++ VDPU_REG_PIC_MB_HEIGHT_P(MB_HEIGHT(ctx->src_fmt.height)) | + VDPU_REG_ALT_SCAN_E(picture->alternate_scan) | + VDPU_REG_TOPFIELDFIRST_E(picture->top_field_first); + vdpu_write_relaxed(vpu, reg, VDPU_SWREG(120)); +-- +2.17.1 + + +From 3b87f8547b97f13afb8db289cc9974760e668b79 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Tue, 5 Nov 2019 23:06:34 +0000 +Subject: [PATCH] WIP: media: hantro: g1 mpeg2 src_fmt + +Fixes: ceaac6dc5b7a +Signed-off-by: Jonas Karlman +--- + drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c b/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c +index 24041849384a..44f7326aba32 100644 +--- a/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c ++++ b/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c +@@ -125,7 +125,7 @@ hantro_g1_mpeg2_dec_set_buffers(struct hantro_dev *vpu, struct hantro_ctx *ctx, + current_addr = addr; + + if (picture->picture_structure == PICT_BOTTOM_FIELD) +- addr += ALIGN(ctx->dst_fmt.width, 16); ++ addr += ALIGN(ctx->src_fmt.width, MB_DIM); + vdpu_write_relaxed(vpu, addr, G1_REG_DEC_OUT_BASE); + + if (!forward_addr) +@@ -204,8 +204,8 @@ void hantro_g1_mpeg2_dec_run(struct hantro_ctx *ctx) + G1_REG_DEC_AXI_WR_ID(0); + vdpu_write_relaxed(vpu, reg, G1_SWREG(3)); + +- reg = G1_REG_PIC_MB_WIDTH(MB_WIDTH(ctx->dst_fmt.width)) | +- G1_REG_PIC_MB_HEIGHT_P(MB_HEIGHT(ctx->dst_fmt.height)) | ++ reg = G1_REG_PIC_MB_WIDTH(MB_WIDTH(ctx->src_fmt.width)) | ++ G1_REG_PIC_MB_HEIGHT_P(MB_HEIGHT(ctx->src_fmt.height)) | + G1_REG_ALT_SCAN_E(picture->alternate_scan) | + G1_REG_TOPFIELDFIRST_E(picture->top_field_first); + vdpu_write_relaxed(vpu, reg, G1_SWREG(4)); +-- +2.17.1 + + +From 10bf68403975d4fe3b383c7882d6a7d8a8bca64b Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Tue, 5 Nov 2019 23:09:18 +0000 +Subject: [PATCH] WIP: media: hantro: vp8 src_fmt + +Signed-off-by: Jonas Karlman +--- + drivers/staging/media/hantro/hantro_g1_vp8_dec.c | 4 ++-- + drivers/staging/media/hantro/hantro_vp8.c | 4 ++-- + drivers/staging/media/hantro/rk3399_vpu_hw_vp8_dec.c | 4 ++-- + 3 files changed, 6 insertions(+), 6 deletions(-) + +diff --git a/drivers/staging/media/hantro/hantro_g1_vp8_dec.c b/drivers/staging/media/hantro/hantro_g1_vp8_dec.c +index a5cdf150cd16..e36538117fbf 100644 +--- a/drivers/staging/media/hantro/hantro_g1_vp8_dec.c ++++ b/drivers/staging/media/hantro/hantro_g1_vp8_dec.c +@@ -430,8 +430,8 @@ void hantro_g1_vp8_dec_run(struct hantro_ctx *ctx) + { + const struct v4l2_ctrl_vp8_frame_header *hdr; + struct hantro_dev *vpu = ctx->dev; +- size_t height = ctx->dst_fmt.height; +- size_t width = ctx->dst_fmt.width; ++ size_t height = ctx->src_fmt.height; ++ size_t width = ctx->src_fmt.width; + u32 mb_width, mb_height; + u32 reg; + +diff --git a/drivers/staging/media/hantro/hantro_vp8.c b/drivers/staging/media/hantro/hantro_vp8.c +index 0e02d147b189..e010c9088fde 100644 +--- a/drivers/staging/media/hantro/hantro_vp8.c ++++ b/drivers/staging/media/hantro/hantro_vp8.c +@@ -151,8 +151,8 @@ int hantro_vp8_dec_init(struct hantro_ctx *ctx) + int ret; + + /* segment map table size calculation */ +- mb_width = DIV_ROUND_UP(ctx->dst_fmt.width, 16); +- mb_height = DIV_ROUND_UP(ctx->dst_fmt.height, 16); ++ mb_width = MB_WIDTH(ctx->src_fmt.width); ++ mb_height = MB_HEIGHT(ctx->src_fmt.height); + segment_map_size = round_up(DIV_ROUND_UP(mb_width * mb_height, 4), 64); + + /* +diff --git a/drivers/staging/media/hantro/rk3399_vpu_hw_vp8_dec.c b/drivers/staging/media/hantro/rk3399_vpu_hw_vp8_dec.c +index a4a792f00b11..2f553e740294 100644 +--- a/drivers/staging/media/hantro/rk3399_vpu_hw_vp8_dec.c ++++ b/drivers/staging/media/hantro/rk3399_vpu_hw_vp8_dec.c +@@ -508,8 +508,8 @@ void rk3399_vpu_vp8_dec_run(struct hantro_ctx *ctx) + { + const struct v4l2_ctrl_vp8_frame_header *hdr; + struct hantro_dev *vpu = ctx->dev; +- size_t height = ctx->dst_fmt.height; +- size_t width = ctx->dst_fmt.width; ++ size_t height = ctx->src_fmt.height; ++ size_t width = ctx->src_fmt.width; + u32 mb_width, mb_height; + u32 reg; + +-- +2.17.1 + + +From 4f7561c70db7347ade627ee0aacfb45c35022195 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 18 Aug 2019 10:40:31 +0000 +Subject: [PATCH] media: hantro: Refactor G1 H264 code + +Use generated code from my rockchip-vpu-regtool + +Code could possible need some cleanup + +Signed-off-by: Jonas Karlman +--- + .../staging/media/hantro/hantro_g1_h264_dec.c | 653 +++++++++++------- + drivers/staging/media/hantro/hantro_h264.c | 14 + + drivers/staging/media/hantro/hantro_hw.h | 2 + + 3 files changed, 435 insertions(+), 234 deletions(-) + +diff --git a/drivers/staging/media/hantro/hantro_g1_h264_dec.c b/drivers/staging/media/hantro/hantro_g1_h264_dec.c +index 89cf5741280e..20999b005307 100644 +--- a/drivers/staging/media/hantro/hantro_g1_h264_dec.c ++++ b/drivers/staging/media/hantro/hantro_g1_h264_dec.c +@@ -1,6 +1,6 @@ + // SPDX-License-Identifier: GPL-2.0 + /* +- * Rockchip RK3288 VPU codec driver ++ * Hantro VPU codec driver + * + * Copyright (c) 2014 Rockchip Electronics Co., Ltd. + * Hertz Wong +@@ -15,235 +15,430 @@ + + #include + +-#include "hantro_g1_regs.h" + #include "hantro_hw.h" + #include "hantro_v4l2.h" + +-static void set_params(struct hantro_ctx *ctx) ++#define G1_SWREG(nr) ((nr) * 4) ++ ++#define G1_REG_RLC_VLC_BASE G1_SWREG(12) ++#define G1_REG_DEC_OUT_BASE G1_SWREG(13) ++#define G1_REG_REFER0_BASE G1_SWREG(14) ++#define G1_REG_REFER1_BASE G1_SWREG(15) ++#define G1_REG_REFER2_BASE G1_SWREG(16) ++#define G1_REG_REFER3_BASE G1_SWREG(17) ++#define G1_REG_REFER4_BASE G1_SWREG(18) ++#define G1_REG_REFER5_BASE G1_SWREG(19) ++#define G1_REG_REFER6_BASE G1_SWREG(20) ++#define G1_REG_REFER7_BASE G1_SWREG(21) ++#define G1_REG_REFER8_BASE G1_SWREG(22) ++#define G1_REG_REFER9_BASE G1_SWREG(23) ++#define G1_REG_REFER10_BASE G1_SWREG(24) ++#define G1_REG_REFER11_BASE G1_SWREG(25) ++#define G1_REG_REFER12_BASE G1_SWREG(26) ++#define G1_REG_REFER13_BASE G1_SWREG(27) ++#define G1_REG_REFER14_BASE G1_SWREG(28) ++#define G1_REG_REFER15_BASE G1_SWREG(29) ++#define G1_REG_QTABLE_BASE G1_SWREG(40) ++#define G1_REG_DIR_MV_BASE G1_SWREG(41) ++#define G1_REG_DEC_E(v) ((v) ? BIT(0) : 0) ++ ++#define G1_REG_DEC_AXI_RD_ID(v) (((v) << 24) & GENMASK(31, 24)) ++#define G1_REG_DEC_TIMEOUT_E(v) ((v) ? BIT(23) : 0) ++#define G1_REG_DEC_STRSWAP32_E(v) ((v) ? BIT(22) : 0) ++#define G1_REG_DEC_STRENDIAN_E(v) ((v) ? BIT(21) : 0) ++#define G1_REG_DEC_INSWAP32_E(v) ((v) ? BIT(20) : 0) ++#define G1_REG_DEC_OUTSWAP32_E(v) ((v) ? BIT(19) : 0) ++#define G1_REG_DEC_DATA_DISC_E(v) ((v) ? BIT(18) : 0) ++#define G1_REG_DEC_LATENCY(v) (((v) << 11) & GENMASK(16, 11)) ++#define G1_REG_DEC_CLK_GATE_E(v) ((v) ? BIT(10) : 0) ++#define G1_REG_DEC_IN_ENDIAN(v) ((v) ? BIT(9) : 0) ++#define G1_REG_DEC_OUT_ENDIAN(v) ((v) ? BIT(8) : 0) ++#define G1_REG_DEC_ADV_PRE_DIS(v) ((v) ? BIT(6) : 0) ++#define G1_REG_DEC_SCMD_DIS(v) ((v) ? BIT(5) : 0) ++#define G1_REG_DEC_MAX_BURST(v) (((v) << 0) & GENMASK(4, 0)) ++ ++#define G1_REG_DEC_MODE(v) (((v) << 28) & GENMASK(31, 28)) ++#define G1_REG_RLC_MODE_E(v) ((v) ? BIT(27) : 0) ++#define G1_REG_PIC_INTERLACE_E(v) ((v) ? BIT(23) : 0) ++#define G1_REG_PIC_FIELDMODE_E(v) ((v) ? BIT(22) : 0) ++#define G1_REG_PIC_TOPFIELD_E(v) ((v) ? BIT(19) : 0) ++#define G1_REG_FILTERING_DIS(v) ((v) ? BIT(14) : 0) ++#define G1_REG_PIC_FIXED_QUANT(v) ((v) ? BIT(13) : 0) ++#define G1_REG_WRITE_MVS_E(v) ((v) ? BIT(12) : 0) ++#define G1_REG_SEQ_MBAFF_E(v) ((v) ? BIT(10) : 0) ++#define G1_REG_PICORD_COUNT_E(v) ((v) ? BIT(9) : 0) ++#define G1_REG_DEC_AXI_WR_ID(v) (((v) << 0) & GENMASK(7, 0)) ++ ++#define G1_REG_PIC_MB_WIDTH(v) (((v) << 23) & GENMASK(31, 23)) ++#define G1_REG_PIC_MB_HEIGHT_P(v) (((v) << 11) & GENMASK(18, 11)) ++#define G1_REG_REF_FRAMES(v) (((v) << 0) & GENMASK(4, 0)) ++ ++#define G1_REG_STRM_START_BIT(v) (((v) << 26) & GENMASK(31, 26)) ++#define G1_REG_TYPE1_QUANT_E(v) ((v) ? BIT(24) : 0) ++#define G1_REG_CH_QP_OFFSET(v) (((v) << 19) & GENMASK(23, 19)) ++#define G1_REG_CH_QP_OFFSET2(v) (((v) << 14) & GENMASK(18, 14)) ++#define G1_REG_FIELDPIC_FLAG_E(v) ((v) ? BIT(0) : 0) ++ ++#define G1_REG_START_CODE_E(v) ((v) ? BIT(31) : 0) ++#define G1_REG_INIT_QP(v) (((v) << 25) & GENMASK(30, 25)) ++#define G1_REG_CH_8PIX_ILEAV_E(v) ((v) ? BIT(24) : 0) ++#define G1_REG_STREAM_LEN(v) (((v) << 0) & GENMASK(23, 0)) ++ ++#define G1_REG_CABAC_E(v) ((v) ? BIT(31) : 0) ++#define G1_REG_BLACKWHITE_E(v) ((v) ? BIT(30) : 0) ++#define G1_REG_DIR_8X8_INFER_E(v) ((v) ? BIT(29) : 0) ++#define G1_REG_WEIGHT_PRED_E(v) ((v) ? BIT(28) : 0) ++#define G1_REG_WEIGHT_BIPR_IDC(v) (((v) << 26) & GENMASK(27, 26)) ++#define G1_REG_FRAMENUM_LEN(v) (((v) << 16) & GENMASK(20, 16)) ++#define G1_REG_FRAMENUM(v) (((v) << 0) & GENMASK(15, 0)) ++ ++#define G1_REG_CONST_INTRA_E(v) ((v) ? BIT(31) : 0) ++#define G1_REG_FILT_CTRL_PRES(v) ((v) ? BIT(30) : 0) ++#define G1_REG_RDPIC_CNT_PRES(v) ((v) ? BIT(29) : 0) ++#define G1_REG_8X8TRANS_FLAG_E(v) ((v) ? BIT(28) : 0) ++#define G1_REG_REFPIC_MK_LEN(v) (((v) << 17) & GENMASK(27, 17)) ++#define G1_REG_IDR_PIC_E(v) ((v) ? BIT(16) : 0) ++#define G1_REG_IDR_PIC_ID(v) (((v) << 0) & GENMASK(15, 0)) ++ ++#define G1_REG_PPS_ID(v) (((v) << 24) & GENMASK(31, 24)) ++#define G1_REG_REFIDX1_ACTIVE(v) (((v) << 19) & GENMASK(23, 19)) ++#define G1_REG_REFIDX0_ACTIVE(v) (((v) << 14) & GENMASK(18, 14)) ++#define G1_REG_POC_LENGTH(v) (((v) << 0) & GENMASK(7, 0)) ++ ++#define G1_REG_PINIT_RLIST_F9(v) (((v) << 25) & GENMASK(29, 25)) ++#define G1_REG_PINIT_RLIST_F8(v) (((v) << 20) & GENMASK(24, 20)) ++#define G1_REG_PINIT_RLIST_F7(v) (((v) << 15) & GENMASK(19, 15)) ++#define G1_REG_PINIT_RLIST_F6(v) (((v) << 10) & GENMASK(14, 10)) ++#define G1_REG_PINIT_RLIST_F5(v) (((v) << 5) & GENMASK(9, 5)) ++#define G1_REG_PINIT_RLIST_F4(v) (((v) << 0) & GENMASK(4, 0)) ++ ++#define G1_REG_PINIT_RLIST_F15(v) (((v) << 25) & GENMASK(29, 25)) ++#define G1_REG_PINIT_RLIST_F14(v) (((v) << 20) & GENMASK(24, 20)) ++#define G1_REG_PINIT_RLIST_F13(v) (((v) << 15) & GENMASK(19, 15)) ++#define G1_REG_PINIT_RLIST_F12(v) (((v) << 10) & GENMASK(14, 10)) ++#define G1_REG_PINIT_RLIST_F11(v) (((v) << 5) & GENMASK(9, 5)) ++#define G1_REG_PINIT_RLIST_F10(v) (((v) << 0) & GENMASK(4, 0)) ++ ++#define G1_REG_REFER1_NBR(v) (((v) << 16) & GENMASK(31, 16)) ++#define G1_REG_REFER0_NBR(v) (((v) << 0) & GENMASK(15, 0)) ++ ++#define G1_REG_REFER3_NBR(v) (((v) << 16) & GENMASK(31, 16)) ++#define G1_REG_REFER2_NBR(v) (((v) << 0) & GENMASK(15, 0)) ++ ++#define G1_REG_REFER5_NBR(v) (((v) << 16) & GENMASK(31, 16)) ++#define G1_REG_REFER4_NBR(v) (((v) << 0) & GENMASK(15, 0)) ++ ++#define G1_REG_REFER7_NBR(v) (((v) << 16) & GENMASK(31, 16)) ++#define G1_REG_REFER6_NBR(v) (((v) << 0) & GENMASK(15, 0)) ++ ++#define G1_REG_REFER9_NBR(v) (((v) << 16) & GENMASK(31, 16)) ++#define G1_REG_REFER8_NBR(v) (((v) << 0) & GENMASK(15, 0)) ++ ++#define G1_REG_REFER11_NBR(v) (((v) << 16) & GENMASK(31, 16)) ++#define G1_REG_REFER10_NBR(v) (((v) << 0) & GENMASK(15, 0)) ++ ++#define G1_REG_REFER13_NBR(v) (((v) << 16) & GENMASK(31, 16)) ++#define G1_REG_REFER12_NBR(v) (((v) << 0) & GENMASK(15, 0)) ++ ++#define G1_REG_REFER15_NBR(v) (((v) << 16) & GENMASK(31, 16)) ++#define G1_REG_REFER14_NBR(v) (((v) << 0) & GENMASK(15, 0)) ++ ++#define G1_REG_REFER_LTERM_E(v) (((v) << 0) & GENMASK(31, 0)) ++ ++#define G1_REG_REFER_VALID_E(v) (((v) << 0) & GENMASK(31, 0)) ++ ++#define G1_REG_BINIT_RLIST_B2(v) (((v) << 25) & GENMASK(29, 25)) ++#define G1_REG_BINIT_RLIST_F2(v) (((v) << 20) & GENMASK(24, 20)) ++#define G1_REG_BINIT_RLIST_B1(v) (((v) << 15) & GENMASK(19, 15)) ++#define G1_REG_BINIT_RLIST_F1(v) (((v) << 10) & GENMASK(14, 10)) ++#define G1_REG_BINIT_RLIST_B0(v) (((v) << 5) & GENMASK(9, 5)) ++#define G1_REG_BINIT_RLIST_F0(v) (((v) << 0) & GENMASK(4, 0)) ++ ++#define G1_REG_BINIT_RLIST_B5(v) (((v) << 25) & GENMASK(29, 25)) ++#define G1_REG_BINIT_RLIST_F5(v) (((v) << 20) & GENMASK(24, 20)) ++#define G1_REG_BINIT_RLIST_B4(v) (((v) << 15) & GENMASK(19, 15)) ++#define G1_REG_BINIT_RLIST_F4(v) (((v) << 10) & GENMASK(14, 10)) ++#define G1_REG_BINIT_RLIST_B3(v) (((v) << 5) & GENMASK(9, 5)) ++#define G1_REG_BINIT_RLIST_F3(v) (((v) << 0) & GENMASK(4, 0)) ++ ++#define G1_REG_BINIT_RLIST_B8(v) (((v) << 25) & GENMASK(29, 25)) ++#define G1_REG_BINIT_RLIST_F8(v) (((v) << 20) & GENMASK(24, 20)) ++#define G1_REG_BINIT_RLIST_B7(v) (((v) << 15) & GENMASK(19, 15)) ++#define G1_REG_BINIT_RLIST_F7(v) (((v) << 10) & GENMASK(14, 10)) ++#define G1_REG_BINIT_RLIST_B6(v) (((v) << 5) & GENMASK(9, 5)) ++#define G1_REG_BINIT_RLIST_F6(v) (((v) << 0) & GENMASK(4, 0)) ++ ++#define G1_REG_BINIT_RLIST_B11(v) (((v) << 25) & GENMASK(29, 25)) ++#define G1_REG_BINIT_RLIST_F11(v) (((v) << 20) & GENMASK(24, 20)) ++#define G1_REG_BINIT_RLIST_B10(v) (((v) << 15) & GENMASK(19, 15)) ++#define G1_REG_BINIT_RLIST_F10(v) (((v) << 10) & GENMASK(14, 10)) ++#define G1_REG_BINIT_RLIST_B9(v) (((v) << 5) & GENMASK(9, 5)) ++#define G1_REG_BINIT_RLIST_F9(v) (((v) << 0) & GENMASK(4, 0)) ++ ++#define G1_REG_BINIT_RLIST_B14(v) (((v) << 25) & GENMASK(29, 25)) ++#define G1_REG_BINIT_RLIST_F14(v) (((v) << 20) & GENMASK(24, 20)) ++#define G1_REG_BINIT_RLIST_B13(v) (((v) << 15) & GENMASK(19, 15)) ++#define G1_REG_BINIT_RLIST_F13(v) (((v) << 10) & GENMASK(14, 10)) ++#define G1_REG_BINIT_RLIST_B12(v) (((v) << 5) & GENMASK(9, 5)) ++#define G1_REG_BINIT_RLIST_F12(v) (((v) << 0) & GENMASK(4, 0)) ++ ++#define G1_REG_PINIT_RLIST_F3(v) (((v) << 25) & GENMASK(29, 25)) ++#define G1_REG_PINIT_RLIST_F2(v) (((v) << 20) & GENMASK(24, 20)) ++#define G1_REG_PINIT_RLIST_F1(v) (((v) << 15) & GENMASK(19, 15)) ++#define G1_REG_PINIT_RLIST_F0(v) (((v) << 10) & GENMASK(14, 10)) ++#define G1_REG_BINIT_RLIST_B15(v) (((v) << 5) & GENMASK(9, 5)) ++#define G1_REG_BINIT_RLIST_F15(v) (((v) << 0) & GENMASK(4, 0)) ++ ++#define G1_REG_STARTMB_X(v) (((v) << 23) & GENMASK(31, 23)) ++#define G1_REG_STARTMB_Y(v) (((v) << 15) & GENMASK(22, 15)) ++ ++#define G1_REG_PRED_BC_TAP_0_0(v) (((v) << 22) & GENMASK(31, 22)) ++#define G1_REG_PRED_BC_TAP_0_1(v) (((v) << 12) & GENMASK(21, 12)) ++#define G1_REG_PRED_BC_TAP_0_2(v) (((v) << 2) & GENMASK(11, 2)) ++ ++#define G1_REG_REFBU_E(v) ((v) ? BIT(31) : 0) ++ ++#define G1_REG_APF_THRESHOLD(v) (((v) << 0) & GENMASK(13, 0)) ++ ++void hantro_g1_h264_dec_run(struct hantro_ctx *ctx) + { +- const struct hantro_h264_dec_ctrls *ctrls = &ctx->h264_dec.ctrls; +- const struct v4l2_ctrl_h264_decode_params *dec_param = ctrls->decode; +- const struct v4l2_ctrl_h264_slice_params *slices = ctrls->slices; +- const struct v4l2_ctrl_h264_sps *sps = ctrls->sps; +- const struct v4l2_ctrl_h264_pps *pps = ctrls->pps; +- struct vb2_v4l2_buffer *src_buf = hantro_get_src_buf(ctx); + struct hantro_dev *vpu = ctx->dev; ++ struct vb2_v4l2_buffer *src_buf, *dst_buf; ++ const struct hantro_h264_dec_ctrls *ctrls; ++ const struct v4l2_ctrl_h264_decode_params *decode; ++ const struct v4l2_ctrl_h264_slice_params *slices; ++ const struct v4l2_ctrl_h264_sps *sps; ++ const struct v4l2_ctrl_h264_pps *pps; ++ const u8 *b0_reflist, *b1_reflist, *p_reflist; ++ dma_addr_t addr; ++ size_t offset = 0; + u32 reg; + +- /* Decoder control register 0. */ +- reg = G1_REG_DEC_CTRL0_DEC_AXI_WR_ID(0x0); +- if (sps->flags & V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD) +- reg |= G1_REG_DEC_CTRL0_SEQ_MBAFF_E; +- if (sps->profile_idc > 66) { +- reg |= G1_REG_DEC_CTRL0_PICORD_COUNT_E; +- if (dec_param->nal_ref_idc) +- reg |= G1_REG_DEC_CTRL0_WRITE_MVS_E; +- } ++ /* Prepare the H264 decoder context. */ ++ if (hantro_h264_dec_prepare_run(ctx)) ++ return; + +- if (!(sps->flags & V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY) && +- (sps->flags & V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD || +- slices[0].flags & V4L2_H264_SLICE_FLAG_FIELD_PIC)) +- reg |= G1_REG_DEC_CTRL0_PIC_INTERLACE_E; +- if (slices[0].flags & V4L2_H264_SLICE_FLAG_FIELD_PIC) +- reg |= G1_REG_DEC_CTRL0_PIC_FIELDMODE_E; +- if (!(slices[0].flags & V4L2_H264_SLICE_FLAG_BOTTOM_FIELD)) +- reg |= G1_REG_DEC_CTRL0_PIC_TOPFIELD_E; +- vdpu_write_relaxed(vpu, reg, G1_REG_DEC_CTRL0); +- +- /* Decoder control register 1. */ +- reg = G1_REG_DEC_CTRL1_PIC_MB_WIDTH(MB_WIDTH(ctx->src_fmt.width)) | +- G1_REG_DEC_CTRL1_PIC_MB_HEIGHT_P(MB_HEIGHT(ctx->src_fmt.height)) | +- G1_REG_DEC_CTRL1_REF_FRAMES(sps->max_num_ref_frames); +- vdpu_write_relaxed(vpu, reg, G1_REG_DEC_CTRL1); +- +- /* Decoder control register 2. */ +- reg = G1_REG_DEC_CTRL2_CH_QP_OFFSET(pps->chroma_qp_index_offset) | +- G1_REG_DEC_CTRL2_CH_QP_OFFSET2(pps->second_chroma_qp_index_offset); +- +- /* always use the matrix sent from userspace */ +- reg |= G1_REG_DEC_CTRL2_TYPE1_QUANT_E; +- +- if (!(sps->flags & V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY)) +- reg |= G1_REG_DEC_CTRL2_FIELDPIC_FLAG_E; +- vdpu_write_relaxed(vpu, reg, G1_REG_DEC_CTRL2); +- +- /* Decoder control register 3. */ +- reg = G1_REG_DEC_CTRL3_START_CODE_E | +- G1_REG_DEC_CTRL3_INIT_QP(pps->pic_init_qp_minus26 + 26) | +- G1_REG_DEC_CTRL3_STREAM_LEN(vb2_get_plane_payload(&src_buf->vb2_buf, 0)); +- vdpu_write_relaxed(vpu, reg, G1_REG_DEC_CTRL3); +- +- /* Decoder control register 4. */ +- reg = G1_REG_DEC_CTRL4_FRAMENUM_LEN(sps->log2_max_frame_num_minus4 + 4) | +- G1_REG_DEC_CTRL4_FRAMENUM(slices[0].frame_num) | +- G1_REG_DEC_CTRL4_WEIGHT_BIPR_IDC(pps->weighted_bipred_idc); +- if (pps->flags & V4L2_H264_PPS_FLAG_ENTROPY_CODING_MODE) +- reg |= G1_REG_DEC_CTRL4_CABAC_E; +- if (sps->flags & V4L2_H264_SPS_FLAG_DIRECT_8X8_INFERENCE) +- reg |= G1_REG_DEC_CTRL4_DIR_8X8_INFER_E; +- if (sps->profile_idc >= 100 && sps->chroma_format_idc == 0) +- reg |= G1_REG_DEC_CTRL4_BLACKWHITE_E; +- if (pps->flags & V4L2_H264_PPS_FLAG_WEIGHTED_PRED) +- reg |= G1_REG_DEC_CTRL4_WEIGHT_PRED_E; +- vdpu_write_relaxed(vpu, reg, G1_REG_DEC_CTRL4); +- +- /* Decoder control register 5. */ +- reg = G1_REG_DEC_CTRL5_REFPIC_MK_LEN(slices[0].dec_ref_pic_marking_bit_size) | +- G1_REG_DEC_CTRL5_IDR_PIC_ID(slices[0].idr_pic_id); +- if (pps->flags & V4L2_H264_PPS_FLAG_CONSTRAINED_INTRA_PRED) +- reg |= G1_REG_DEC_CTRL5_CONST_INTRA_E; +- if (pps->flags & V4L2_H264_PPS_FLAG_DEBLOCKING_FILTER_CONTROL_PRESENT) +- reg |= G1_REG_DEC_CTRL5_FILT_CTRL_PRES; +- if (pps->flags & V4L2_H264_PPS_FLAG_REDUNDANT_PIC_CNT_PRESENT) +- reg |= G1_REG_DEC_CTRL5_RDPIC_CNT_PRES; +- if (pps->flags & V4L2_H264_PPS_FLAG_TRANSFORM_8X8_MODE) +- reg |= G1_REG_DEC_CTRL5_8X8TRANS_FLAG_E; +- if (dec_param->flags & V4L2_H264_DECODE_PARAM_FLAG_IDR_PIC) +- reg |= G1_REG_DEC_CTRL5_IDR_PIC_E; +- vdpu_write_relaxed(vpu, reg, G1_REG_DEC_CTRL5); +- +- /* Decoder control register 6. */ +- reg = G1_REG_DEC_CTRL6_PPS_ID(slices[0].pic_parameter_set_id) | +- G1_REG_DEC_CTRL6_REFIDX0_ACTIVE(pps->num_ref_idx_l0_default_active_minus1 + 1) | +- G1_REG_DEC_CTRL6_REFIDX1_ACTIVE(pps->num_ref_idx_l1_default_active_minus1 + 1) | +- G1_REG_DEC_CTRL6_POC_LENGTH(slices[0].pic_order_cnt_bit_size); +- vdpu_write_relaxed(vpu, reg, G1_REG_DEC_CTRL6); +- +- /* Error concealment register. */ +- vdpu_write_relaxed(vpu, 0, G1_REG_ERR_CONC); +- +- /* Prediction filter tap register. */ +- vdpu_write_relaxed(vpu, +- G1_REG_PRED_FLT_PRED_BC_TAP_0_0(1) | +- G1_REG_PRED_FLT_PRED_BC_TAP_0_1(-5 & 0x3ff) | +- G1_REG_PRED_FLT_PRED_BC_TAP_0_2(20), +- G1_REG_PRED_FLT); +- +- /* Reference picture buffer control register. */ +- vdpu_write_relaxed(vpu, 0, G1_REG_REF_BUF_CTRL); +- +- /* Reference picture buffer control register 2. */ +- vdpu_write_relaxed(vpu, G1_REG_REF_BUF_CTRL2_APF_THRESHOLD(8), +- G1_REG_REF_BUF_CTRL2); +-} ++ src_buf = hantro_get_src_buf(ctx); ++ dst_buf = hantro_get_dst_buf(ctx); + +-static void set_ref(struct hantro_ctx *ctx) +-{ +- struct v4l2_h264_dpb_entry *dpb = ctx->h264_dec.dpb; +- const u8 *b0_reflist, *b1_reflist, *p_reflist; +- struct hantro_dev *vpu = ctx->dev; +- int reg_num; +- u32 reg; +- int i; +- +- vdpu_write_relaxed(vpu, ctx->h264_dec.dpb_valid, G1_REG_VALID_REF); +- vdpu_write_relaxed(vpu, ctx->h264_dec.dpb_longterm, G1_REG_LT_REF); +- +- /* +- * Set up reference frame picture numbers. +- * +- * Each G1_REG_REF_PIC(x) register contains numbers of two +- * subsequential reference pictures. +- */ +- for (i = 0; i < HANTRO_H264_DPB_SIZE; i += 2) { +- reg = 0; +- if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM) +- reg |= G1_REG_REF_PIC_REFER0_NBR(dpb[i].pic_num); +- else +- reg |= G1_REG_REF_PIC_REFER0_NBR(dpb[i].frame_num); +- +- if (dpb[i + 1].flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM) +- reg |= G1_REG_REF_PIC_REFER1_NBR(dpb[i + 1].pic_num); +- else +- reg |= G1_REG_REF_PIC_REFER1_NBR(dpb[i + 1].frame_num); +- +- vdpu_write_relaxed(vpu, reg, G1_REG_REF_PIC(i / 2)); +- } ++ ctrls = &ctx->h264_dec.ctrls; ++ decode = ctrls->decode; ++ slices = ctrls->slices; ++ sps = ctrls->sps; ++ pps = ctrls->pps; + + b0_reflist = ctx->h264_dec.reflists.b0; + b1_reflist = ctx->h264_dec.reflists.b1; + p_reflist = ctx->h264_dec.reflists.p; + +- /* +- * Each G1_REG_BD_REF_PIC(x) register contains three entries +- * of each forward and backward picture list. +- */ +- reg_num = 0; +- for (i = 0; i < 15; i += 3) { +- reg = G1_REG_BD_REF_PIC_BINIT_RLIST_F0(b0_reflist[i]) | +- G1_REG_BD_REF_PIC_BINIT_RLIST_F1(b0_reflist[i + 1]) | +- G1_REG_BD_REF_PIC_BINIT_RLIST_F2(b0_reflist[i + 2]) | +- G1_REG_BD_REF_PIC_BINIT_RLIST_B0(b1_reflist[i]) | +- G1_REG_BD_REF_PIC_BINIT_RLIST_B1(b1_reflist[i + 1]) | +- G1_REG_BD_REF_PIC_BINIT_RLIST_B2(b1_reflist[i + 2]); +- vdpu_write_relaxed(vpu, reg, G1_REG_BD_REF_PIC(reg_num++)); +- } +- +- /* +- * G1_REG_BD_P_REF_PIC register contains last entries (index 15) +- * of forward and backward reference picture lists and first 4 entries +- * of P forward picture list. +- */ +- reg = G1_REG_BD_P_REF_PIC_BINIT_RLIST_F15(b0_reflist[15]) | +- G1_REG_BD_P_REF_PIC_BINIT_RLIST_B15(b1_reflist[15]) | +- G1_REG_BD_P_REF_PIC_PINIT_RLIST_F0(p_reflist[0]) | +- G1_REG_BD_P_REF_PIC_PINIT_RLIST_F1(p_reflist[1]) | +- G1_REG_BD_P_REF_PIC_PINIT_RLIST_F2(p_reflist[2]) | +- G1_REG_BD_P_REF_PIC_PINIT_RLIST_F3(p_reflist[3]); +- vdpu_write_relaxed(vpu, reg, G1_REG_BD_P_REF_PIC); +- +- /* +- * Each G1_REG_FWD_PIC(x) register contains six consecutive +- * entries of P forward picture list, starting from index 4. +- */ +- reg_num = 0; +- for (i = 4; i < HANTRO_H264_DPB_SIZE; i += 6) { +- reg = G1_REG_FWD_PIC_PINIT_RLIST_F0(p_reflist[i]) | +- G1_REG_FWD_PIC_PINIT_RLIST_F1(p_reflist[i + 1]) | +- G1_REG_FWD_PIC_PINIT_RLIST_F2(p_reflist[i + 2]) | +- G1_REG_FWD_PIC_PINIT_RLIST_F3(p_reflist[i + 3]) | +- G1_REG_FWD_PIC_PINIT_RLIST_F4(p_reflist[i + 4]) | +- G1_REG_FWD_PIC_PINIT_RLIST_F5(p_reflist[i + 5]); +- vdpu_write_relaxed(vpu, reg, G1_REG_FWD_PIC(reg_num++)); +- } ++ reg = G1_REG_DEC_AXI_RD_ID(0xff) | ++ G1_REG_DEC_TIMEOUT_E(1) | ++ G1_REG_DEC_STRSWAP32_E(1) | ++ G1_REG_DEC_STRENDIAN_E(1) | ++ G1_REG_DEC_INSWAP32_E(1) | ++ G1_REG_DEC_OUTSWAP32_E(1) | ++ G1_REG_DEC_DATA_DISC_E(0) | ++ G1_REG_DEC_LATENCY(0) | ++ G1_REG_DEC_CLK_GATE_E(1) | ++ G1_REG_DEC_IN_ENDIAN(0) | ++ G1_REG_DEC_OUT_ENDIAN(1) | ++ G1_REG_DEC_ADV_PRE_DIS(0) | ++ G1_REG_DEC_SCMD_DIS(0) | ++ G1_REG_DEC_MAX_BURST(16); ++ vdpu_write_relaxed(vpu, reg, G1_SWREG(2)); ++ ++ reg = G1_REG_DEC_MODE(0) | ++ G1_REG_RLC_MODE_E(0) | ++ G1_REG_PIC_INTERLACE_E(!(sps->flags & V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY) && (sps->flags & V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD || slices[0].flags & V4L2_H264_SLICE_FLAG_FIELD_PIC)) | ++ G1_REG_PIC_FIELDMODE_E(slices[0].flags & V4L2_H264_SLICE_FLAG_FIELD_PIC) | ++ G1_REG_PIC_TOPFIELD_E(!(slices[0].flags & V4L2_H264_SLICE_FLAG_BOTTOM_FIELD)) | ++ G1_REG_FILTERING_DIS(0) | ++ G1_REG_PIC_FIXED_QUANT(0) | ++ G1_REG_WRITE_MVS_E(sps->profile_idc > 66 && decode->nal_ref_idc) | ++ G1_REG_SEQ_MBAFF_E(sps->flags & V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD) | ++ G1_REG_PICORD_COUNT_E(sps->profile_idc > 66) | ++ G1_REG_DEC_AXI_WR_ID(0); ++ vdpu_write_relaxed(vpu, reg, G1_SWREG(3)); ++ ++ reg = G1_REG_PIC_MB_WIDTH(MB_WIDTH(ctx->src_fmt.width)) | ++ G1_REG_PIC_MB_HEIGHT_P(MB_HEIGHT(ctx->src_fmt.height)) | ++ G1_REG_REF_FRAMES(sps->max_num_ref_frames); ++ vdpu_write_relaxed(vpu, reg, G1_SWREG(4)); ++ ++ reg = G1_REG_STRM_START_BIT(0) | ++ G1_REG_TYPE1_QUANT_E(1) | ++ G1_REG_CH_QP_OFFSET(pps->chroma_qp_index_offset) | ++ G1_REG_CH_QP_OFFSET2(pps->second_chroma_qp_index_offset) | ++ G1_REG_FIELDPIC_FLAG_E(!(sps->flags & V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY)); ++ vdpu_write_relaxed(vpu, reg, G1_SWREG(5)); ++ ++ reg = G1_REG_START_CODE_E(1) | ++ G1_REG_INIT_QP(pps->pic_init_qp_minus26 + 26) | ++ G1_REG_CH_8PIX_ILEAV_E(0) | ++ G1_REG_STREAM_LEN(vb2_get_plane_payload(&src_buf->vb2_buf, 0)); ++ vdpu_write_relaxed(vpu, reg, G1_SWREG(6)); ++ ++ reg = G1_REG_CABAC_E(pps->flags & V4L2_H264_PPS_FLAG_ENTROPY_CODING_MODE) | ++ G1_REG_BLACKWHITE_E(sps->profile_idc >= 100 && sps->chroma_format_idc == 0) | ++ G1_REG_DIR_8X8_INFER_E(sps->flags & V4L2_H264_SPS_FLAG_DIRECT_8X8_INFERENCE) | ++ G1_REG_WEIGHT_PRED_E(pps->flags & V4L2_H264_PPS_FLAG_WEIGHTED_PRED) | ++ G1_REG_WEIGHT_BIPR_IDC(pps->weighted_bipred_idc) | ++ G1_REG_FRAMENUM_LEN(sps->log2_max_frame_num_minus4 + 4) | ++ G1_REG_FRAMENUM(slices[0].frame_num); ++ vdpu_write_relaxed(vpu, reg, G1_SWREG(7)); ++ ++ reg = G1_REG_CONST_INTRA_E(pps->flags & V4L2_H264_PPS_FLAG_CONSTRAINED_INTRA_PRED) | ++ G1_REG_FILT_CTRL_PRES(pps->flags & V4L2_H264_PPS_FLAG_DEBLOCKING_FILTER_CONTROL_PRESENT) | ++ G1_REG_RDPIC_CNT_PRES(pps->flags & V4L2_H264_PPS_FLAG_REDUNDANT_PIC_CNT_PRESENT) | ++ G1_REG_8X8TRANS_FLAG_E(pps->flags & V4L2_H264_PPS_FLAG_TRANSFORM_8X8_MODE) | ++ G1_REG_REFPIC_MK_LEN(slices[0].dec_ref_pic_marking_bit_size) | ++ G1_REG_IDR_PIC_E(decode->flags & V4L2_H264_DECODE_PARAM_FLAG_IDR_PIC) | ++ G1_REG_IDR_PIC_ID(slices[0].idr_pic_id); ++ vdpu_write_relaxed(vpu, reg, G1_SWREG(8)); ++ ++ reg = G1_REG_PPS_ID(slices[0].pic_parameter_set_id) | ++ G1_REG_REFIDX1_ACTIVE(pps->num_ref_idx_l1_default_active_minus1 + 1) | ++ G1_REG_REFIDX0_ACTIVE(pps->num_ref_idx_l0_default_active_minus1 + 1) | ++ G1_REG_POC_LENGTH(slices[0].pic_order_cnt_bit_size); ++ vdpu_write_relaxed(vpu, reg, G1_SWREG(9)); ++ ++ reg = G1_REG_PINIT_RLIST_F9(p_reflist[9]) | ++ G1_REG_PINIT_RLIST_F8(p_reflist[8]) | ++ G1_REG_PINIT_RLIST_F7(p_reflist[7]) | ++ G1_REG_PINIT_RLIST_F6(p_reflist[6]) | ++ G1_REG_PINIT_RLIST_F5(p_reflist[5]) | ++ G1_REG_PINIT_RLIST_F4(p_reflist[4]); ++ vdpu_write_relaxed(vpu, reg, G1_SWREG(10)); ++ ++ reg = G1_REG_PINIT_RLIST_F15(p_reflist[15]) | ++ G1_REG_PINIT_RLIST_F14(p_reflist[14]) | ++ G1_REG_PINIT_RLIST_F13(p_reflist[13]) | ++ G1_REG_PINIT_RLIST_F12(p_reflist[12]) | ++ G1_REG_PINIT_RLIST_F11(p_reflist[11]) | ++ G1_REG_PINIT_RLIST_F10(p_reflist[10]); ++ vdpu_write_relaxed(vpu, reg, G1_SWREG(11)); ++ ++ reg = G1_REG_REFER1_NBR(hantro_h264_get_ref_nbr(ctx, 1)) | ++ G1_REG_REFER0_NBR(hantro_h264_get_ref_nbr(ctx, 0)); ++ vdpu_write_relaxed(vpu, reg, G1_SWREG(30)); ++ ++ reg = G1_REG_REFER3_NBR(hantro_h264_get_ref_nbr(ctx, 3)) | ++ G1_REG_REFER2_NBR(hantro_h264_get_ref_nbr(ctx, 2)); ++ vdpu_write_relaxed(vpu, reg, G1_SWREG(31)); ++ ++ reg = G1_REG_REFER5_NBR(hantro_h264_get_ref_nbr(ctx, 5)) | ++ G1_REG_REFER4_NBR(hantro_h264_get_ref_nbr(ctx, 4)); ++ vdpu_write_relaxed(vpu, reg, G1_SWREG(32)); ++ ++ reg = G1_REG_REFER7_NBR(hantro_h264_get_ref_nbr(ctx, 7)) | ++ G1_REG_REFER6_NBR(hantro_h264_get_ref_nbr(ctx, 6)); ++ vdpu_write_relaxed(vpu, reg, G1_SWREG(33)); ++ ++ reg = G1_REG_REFER9_NBR(hantro_h264_get_ref_nbr(ctx, 9)) | ++ G1_REG_REFER8_NBR(hantro_h264_get_ref_nbr(ctx, 8)); ++ vdpu_write_relaxed(vpu, reg, G1_SWREG(34)); ++ ++ reg = G1_REG_REFER11_NBR(hantro_h264_get_ref_nbr(ctx, 11)) | ++ G1_REG_REFER10_NBR(hantro_h264_get_ref_nbr(ctx, 10)); ++ vdpu_write_relaxed(vpu, reg, G1_SWREG(35)); ++ ++ reg = G1_REG_REFER13_NBR(hantro_h264_get_ref_nbr(ctx, 13)) | ++ G1_REG_REFER12_NBR(hantro_h264_get_ref_nbr(ctx, 12)); ++ vdpu_write_relaxed(vpu, reg, G1_SWREG(36)); ++ ++ reg = G1_REG_REFER15_NBR(hantro_h264_get_ref_nbr(ctx, 15)) | ++ G1_REG_REFER14_NBR(hantro_h264_get_ref_nbr(ctx, 14)); ++ vdpu_write_relaxed(vpu, reg, G1_SWREG(37)); ++ ++ reg = G1_REG_REFER_LTERM_E(ctx->h264_dec.dpb_longterm); ++ vdpu_write_relaxed(vpu, reg, G1_SWREG(38)); ++ ++ reg = G1_REG_REFER_VALID_E(ctx->h264_dec.dpb_valid); ++ vdpu_write_relaxed(vpu, reg, G1_SWREG(39)); ++ ++ reg = G1_REG_BINIT_RLIST_B2(b1_reflist[2]) | ++ G1_REG_BINIT_RLIST_F2(b0_reflist[2]) | ++ G1_REG_BINIT_RLIST_B1(b1_reflist[1]) | ++ G1_REG_BINIT_RLIST_F1(b0_reflist[1]) | ++ G1_REG_BINIT_RLIST_B0(b1_reflist[0]) | ++ G1_REG_BINIT_RLIST_F0(b0_reflist[0]); ++ vdpu_write_relaxed(vpu, reg, G1_SWREG(42)); ++ ++ reg = G1_REG_BINIT_RLIST_B5(b1_reflist[5]) | ++ G1_REG_BINIT_RLIST_F5(b0_reflist[5]) | ++ G1_REG_BINIT_RLIST_B4(b1_reflist[4]) | ++ G1_REG_BINIT_RLIST_F4(b0_reflist[4]) | ++ G1_REG_BINIT_RLIST_B3(b1_reflist[3]) | ++ G1_REG_BINIT_RLIST_F3(b0_reflist[3]); ++ vdpu_write_relaxed(vpu, reg, G1_SWREG(43)); ++ ++ reg = G1_REG_BINIT_RLIST_B8(b1_reflist[8]) | ++ G1_REG_BINIT_RLIST_F8(b0_reflist[8]) | ++ G1_REG_BINIT_RLIST_B7(b1_reflist[7]) | ++ G1_REG_BINIT_RLIST_F7(b0_reflist[7]) | ++ G1_REG_BINIT_RLIST_B6(b1_reflist[6]) | ++ G1_REG_BINIT_RLIST_F6(b0_reflist[6]); ++ vdpu_write_relaxed(vpu, reg, G1_SWREG(44)); ++ ++ reg = G1_REG_BINIT_RLIST_B11(b1_reflist[11]) | ++ G1_REG_BINIT_RLIST_F11(b0_reflist[11]) | ++ G1_REG_BINIT_RLIST_B10(b1_reflist[10]) | ++ G1_REG_BINIT_RLIST_F10(b0_reflist[10]) | ++ G1_REG_BINIT_RLIST_B9(b1_reflist[9]) | ++ G1_REG_BINIT_RLIST_F9(b0_reflist[9]); ++ vdpu_write_relaxed(vpu, reg, G1_SWREG(45)); ++ ++ reg = G1_REG_BINIT_RLIST_B14(b1_reflist[14]) | ++ G1_REG_BINIT_RLIST_F14(b0_reflist[14]) | ++ G1_REG_BINIT_RLIST_B13(b1_reflist[13]) | ++ G1_REG_BINIT_RLIST_F13(b0_reflist[13]) | ++ G1_REG_BINIT_RLIST_B12(b1_reflist[12]) | ++ G1_REG_BINIT_RLIST_F12(b0_reflist[12]); ++ vdpu_write_relaxed(vpu, reg, G1_SWREG(46)); ++ ++ reg = G1_REG_PINIT_RLIST_F3(p_reflist[3]) | ++ G1_REG_PINIT_RLIST_F2(p_reflist[2]) | ++ G1_REG_PINIT_RLIST_F1(p_reflist[1]) | ++ G1_REG_PINIT_RLIST_F0(p_reflist[0]) | ++ G1_REG_BINIT_RLIST_B15(b1_reflist[15]) | ++ G1_REG_BINIT_RLIST_F15(b0_reflist[15]); ++ vdpu_write_relaxed(vpu, reg, G1_SWREG(47)); ++ ++ reg = G1_REG_STARTMB_X(0) | ++ G1_REG_STARTMB_Y(0); ++ vdpu_write_relaxed(vpu, reg, G1_SWREG(48)); ++ ++ reg = G1_REG_PRED_BC_TAP_0_0(1) | ++ G1_REG_PRED_BC_TAP_0_1((u32)-5) | ++ G1_REG_PRED_BC_TAP_0_2(20); ++ vdpu_write_relaxed(vpu, reg, G1_SWREG(49)); ++ ++ reg = G1_REG_REFBU_E(0); ++ vdpu_write_relaxed(vpu, reg, G1_SWREG(51)); ++ ++ reg = G1_REG_APF_THRESHOLD(8); ++ vdpu_write_relaxed(vpu, reg, G1_SWREG(55)); + +- /* Set up addresses of DPB buffers. */ +- for (i = 0; i < HANTRO_H264_DPB_SIZE; i++) { +- dma_addr_t dma_addr = hantro_h264_get_ref_buf(ctx, i); +- +- vdpu_write_relaxed(vpu, dma_addr, G1_REG_ADDR_REF(i)); +- } +-} +- +-static void set_buffers(struct hantro_ctx *ctx) +-{ +- const struct hantro_h264_dec_ctrls *ctrls = &ctx->h264_dec.ctrls; +- struct vb2_v4l2_buffer *src_buf, *dst_buf; +- struct hantro_dev *vpu = ctx->dev; +- dma_addr_t src_dma, dst_dma; +- size_t offset = 0; +- +- src_buf = hantro_get_src_buf(ctx); +- dst_buf = hantro_get_dst_buf(ctx); ++ /* Auxiliary buffer prepared in hantro_g1_h264_dec_prepare_table(). */ ++ vdpu_write_relaxed(vpu, ctx->h264_dec.priv.dma, G1_REG_QTABLE_BASE); + + /* Source (stream) buffer. */ +- src_dma = vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0); +- vdpu_write_relaxed(vpu, src_dma, G1_REG_ADDR_STR); ++ addr = vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0); ++ vdpu_write_relaxed(vpu, addr, G1_REG_RLC_VLC_BASE); + + /* Destination (decoded frame) buffer. */ +- dst_dma = hantro_get_dec_buf_addr(ctx, &dst_buf->vb2_buf); ++ addr = hantro_get_dec_buf_addr(ctx, &dst_buf->vb2_buf); + /* Adjust dma addr to start at second line for bottom field */ +- if (ctrls->slices[0].flags & V4L2_H264_SLICE_FLAG_BOTTOM_FIELD) ++ if (slices[0].flags & V4L2_H264_SLICE_FLAG_BOTTOM_FIELD) + offset = ALIGN(ctx->src_fmt.width, MB_DIM); +- vdpu_write_relaxed(vpu, dst_dma + offset, G1_REG_ADDR_DST); ++ vdpu_write_relaxed(vpu, addr + offset, G1_REG_DEC_OUT_BASE); + + /* Higher profiles require DMV buffer appended to reference frames. */ +- if (ctrls->sps->profile_idc > 66 && ctrls->decode->nal_ref_idc) { ++ if (sps->profile_idc > 66 && decode->nal_ref_idc) { + unsigned int bytes_per_mb = 384; + + /* DMV buffer for monochrome start directly after Y-plane */ +- if (ctrls->sps->profile_idc >= 100 && +- ctrls->sps->chroma_format_idc == 0) ++ if (sps->profile_idc >= 100 && sps->chroma_format_idc == 0) + bytes_per_mb = 256; + offset = bytes_per_mb * MB_WIDTH(ctx->src_fmt.width) * + MB_HEIGHT(ctx->src_fmt.height); +@@ -252,42 +447,32 @@ static void set_buffers(struct hantro_ctx *ctx) + * DMV buffer is split in two for field encoded frames, + * adjust offset for bottom field + */ +- if (ctrls->slices[0].flags & V4L2_H264_SLICE_FLAG_BOTTOM_FIELD) ++ if (slices[0].flags & V4L2_H264_SLICE_FLAG_BOTTOM_FIELD) + offset += 32 * MB_WIDTH(ctx->src_fmt.width) * + MB_HEIGHT(ctx->src_fmt.height); +- vdpu_write_relaxed(vpu, dst_dma + offset, G1_REG_ADDR_DIR_MV); ++ vdpu_write_relaxed(vpu, addr + offset, G1_REG_DIR_MV_BASE); + } + +- /* Auxiliary buffer prepared in hantro_g1_h264_dec_prepare_table(). */ +- vdpu_write_relaxed(vpu, ctx->h264_dec.priv.dma, G1_REG_ADDR_QTABLE); +-} +- +-void hantro_g1_h264_dec_run(struct hantro_ctx *ctx) +-{ +- struct hantro_dev *vpu = ctx->dev; +- +- /* Prepare the H264 decoder context. */ +- if (hantro_h264_dec_prepare_run(ctx)) +- return; +- +- /* Configure hardware registers. */ +- set_params(ctx); +- set_ref(ctx); +- set_buffers(ctx); ++ vdpu_write_relaxed(vpu, hantro_h264_get_ref_buf(ctx, 0), G1_REG_REFER0_BASE); ++ vdpu_write_relaxed(vpu, hantro_h264_get_ref_buf(ctx, 1), G1_REG_REFER1_BASE); ++ vdpu_write_relaxed(vpu, hantro_h264_get_ref_buf(ctx, 2), G1_REG_REFER2_BASE); ++ vdpu_write_relaxed(vpu, hantro_h264_get_ref_buf(ctx, 3), G1_REG_REFER3_BASE); ++ vdpu_write_relaxed(vpu, hantro_h264_get_ref_buf(ctx, 4), G1_REG_REFER4_BASE); ++ vdpu_write_relaxed(vpu, hantro_h264_get_ref_buf(ctx, 5), G1_REG_REFER5_BASE); ++ vdpu_write_relaxed(vpu, hantro_h264_get_ref_buf(ctx, 6), G1_REG_REFER6_BASE); ++ vdpu_write_relaxed(vpu, hantro_h264_get_ref_buf(ctx, 7), G1_REG_REFER7_BASE); ++ vdpu_write_relaxed(vpu, hantro_h264_get_ref_buf(ctx, 8), G1_REG_REFER8_BASE); ++ vdpu_write_relaxed(vpu, hantro_h264_get_ref_buf(ctx, 9), G1_REG_REFER9_BASE); ++ vdpu_write_relaxed(vpu, hantro_h264_get_ref_buf(ctx, 10), G1_REG_REFER10_BASE); ++ vdpu_write_relaxed(vpu, hantro_h264_get_ref_buf(ctx, 11), G1_REG_REFER11_BASE); ++ vdpu_write_relaxed(vpu, hantro_h264_get_ref_buf(ctx, 12), G1_REG_REFER12_BASE); ++ vdpu_write_relaxed(vpu, hantro_h264_get_ref_buf(ctx, 13), G1_REG_REFER13_BASE); ++ vdpu_write_relaxed(vpu, hantro_h264_get_ref_buf(ctx, 14), G1_REG_REFER14_BASE); ++ vdpu_write_relaxed(vpu, hantro_h264_get_ref_buf(ctx, 15), G1_REG_REFER15_BASE); + + hantro_end_prepare_run(ctx); + + /* Start decoding! */ +- vdpu_write_relaxed(vpu, +- G1_REG_CONFIG_DEC_AXI_RD_ID(0xffu) | +- G1_REG_CONFIG_DEC_TIMEOUT_E | +- G1_REG_CONFIG_DEC_OUT_ENDIAN | +- G1_REG_CONFIG_DEC_STRENDIAN_E | +- G1_REG_CONFIG_DEC_MAX_BURST(16) | +- G1_REG_CONFIG_DEC_OUTSWAP32_E | +- G1_REG_CONFIG_DEC_INSWAP32_E | +- G1_REG_CONFIG_DEC_STRSWAP32_E | +- G1_REG_CONFIG_DEC_CLK_GATE_E, +- G1_REG_CONFIG); +- vdpu_write(vpu, G1_REG_INTERRUPT_DEC_E, G1_REG_INTERRUPT); ++ reg = G1_REG_DEC_E(1); ++ vdpu_write(vpu, reg, G1_SWREG(1)); + } +diff --git a/drivers/staging/media/hantro/hantro_h264.c b/drivers/staging/media/hantro/hantro_h264.c +index 4db779354e89..2edcdda2ad63 100644 +--- a/drivers/staging/media/hantro/hantro_h264.c ++++ b/drivers/staging/media/hantro/hantro_h264.c +@@ -596,6 +596,20 @@ dma_addr_t hantro_h264_get_ref_buf(struct hantro_ctx *ctx, + return dma_addr | flags; + } + ++u16 hantro_h264_get_ref_nbr(struct hantro_ctx *ctx, ++ unsigned int dpb_idx) ++{ ++ const struct v4l2_h264_dpb_entry *dpb = &ctx->h264_dec.dpb[dpb_idx]; ++ ++ if (!(dpb->flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE)) ++ return 0; ++ ++ if (dpb->flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM) ++ return dpb->pic_num; ++ ++ return dpb->frame_num; ++} ++ + int hantro_h264_dec_prepare_run(struct hantro_ctx *ctx) + { + struct hantro_h264_dec_hw_ctx *h264_ctx = &ctx->h264_dec; +diff --git a/drivers/staging/media/hantro/hantro_hw.h b/drivers/staging/media/hantro/hantro_hw.h +index 3dc7b8f27c32..fadd3e1bf0d9 100644 +--- a/drivers/staging/media/hantro/hantro_hw.h ++++ b/drivers/staging/media/hantro/hantro_hw.h +@@ -172,6 +172,8 @@ void hantro_jpeg_enc_exit(struct hantro_ctx *ctx); + + dma_addr_t hantro_h264_get_ref_buf(struct hantro_ctx *ctx, + unsigned int dpb_idx); ++u16 hantro_h264_get_ref_nbr(struct hantro_ctx *ctx, ++ unsigned int dpb_idx); + int hantro_h264_dec_prepare_run(struct hantro_ctx *ctx); + void hantro_g1_h264_dec_run(struct hantro_ctx *ctx); + int hantro_h264_dec_init(struct hantro_ctx *ctx); +-- +2.17.1 + + +From 93fc47fb35fdbcc94bf1f1008fccffe16d7465c4 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 18 Aug 2019 10:40:31 +0000 +Subject: [PATCH] media: hantro: Add support for H264 decoding on RK3399 + +Signed-off-by: Jonas Karlman +--- + drivers/staging/media/hantro/Makefile | 1 + + drivers/staging/media/hantro/hantro_hw.h | 1 + + .../media/hantro/rk3399_vpu_hw_h264_dec.c | 493 ++++++++++++++++++ + 3 files changed, 495 insertions(+) + create mode 100644 drivers/staging/media/hantro/rk3399_vpu_hw_h264_dec.c + +diff --git a/drivers/staging/media/hantro/Makefile b/drivers/staging/media/hantro/Makefile +index 496b30c3c396..9bb8a560cb0a 100644 +--- a/drivers/staging/media/hantro/Makefile ++++ b/drivers/staging/media/hantro/Makefile +@@ -9,6 +9,7 @@ hantro-vpu-y += \ + hantro_g1_mpeg2_dec.o \ + hantro_g1_vp8_dec.o \ + rk3399_vpu_hw_jpeg_enc.o \ ++ rk3399_vpu_hw_h264_dec.o \ + rk3399_vpu_hw_mpeg2_dec.o \ + rk3399_vpu_hw_vp8_dec.o \ + hantro_jpeg.o \ +diff --git a/drivers/staging/media/hantro/hantro_hw.h b/drivers/staging/media/hantro/hantro_hw.h +index fadd3e1bf0d9..4a64873bf332 100644 +--- a/drivers/staging/media/hantro/hantro_hw.h ++++ b/drivers/staging/media/hantro/hantro_hw.h +@@ -176,6 +176,7 @@ u16 hantro_h264_get_ref_nbr(struct hantro_ctx *ctx, + unsigned int dpb_idx); + int hantro_h264_dec_prepare_run(struct hantro_ctx *ctx); + void hantro_g1_h264_dec_run(struct hantro_ctx *ctx); ++void rk3399_vpu_h264_dec_run(struct hantro_ctx *ctx); + int hantro_h264_dec_init(struct hantro_ctx *ctx); + void hantro_h264_dec_exit(struct hantro_ctx *ctx); + +diff --git a/drivers/staging/media/hantro/rk3399_vpu_hw_h264_dec.c b/drivers/staging/media/hantro/rk3399_vpu_hw_h264_dec.c +new file mode 100644 +index 000000000000..1f9de7d5a923 +--- /dev/null ++++ b/drivers/staging/media/hantro/rk3399_vpu_hw_h264_dec.c +@@ -0,0 +1,493 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Hantro VPU codec driver ++ * ++ * Copyright (c) 2014 Rockchip Electronics Co., Ltd. ++ * Hertz Wong ++ * Herman Chen ++ * ++ * Copyright (C) 2014 Google, Inc. ++ * Tomasz Figa ++ */ ++ ++#include ++#include ++ ++#include ++ ++#include "hantro_hw.h" ++#include "hantro_v4l2.h" ++ ++#define VDPU_SWREG(nr) ((nr) * 4) ++ ++#define VDPU_REG_DEC_OUT_BASE VDPU_SWREG(63) ++#define VDPU_REG_RLC_VLC_BASE VDPU_SWREG(64) ++#define VDPU_REG_QTABLE_BASE VDPU_SWREG(61) ++#define VDPU_REG_DIR_MV_BASE VDPU_SWREG(62) ++#define VDPU_REG_REFER0_BASE VDPU_SWREG(84) ++#define VDPU_REG_REFER1_BASE VDPU_SWREG(85) ++#define VDPU_REG_REFER2_BASE VDPU_SWREG(86) ++#define VDPU_REG_REFER3_BASE VDPU_SWREG(87) ++#define VDPU_REG_REFER4_BASE VDPU_SWREG(88) ++#define VDPU_REG_REFER5_BASE VDPU_SWREG(89) ++#define VDPU_REG_REFER6_BASE VDPU_SWREG(90) ++#define VDPU_REG_REFER7_BASE VDPU_SWREG(91) ++#define VDPU_REG_REFER8_BASE VDPU_SWREG(92) ++#define VDPU_REG_REFER9_BASE VDPU_SWREG(93) ++#define VDPU_REG_REFER10_BASE VDPU_SWREG(94) ++#define VDPU_REG_REFER11_BASE VDPU_SWREG(95) ++#define VDPU_REG_REFER12_BASE VDPU_SWREG(96) ++#define VDPU_REG_REFER13_BASE VDPU_SWREG(97) ++#define VDPU_REG_REFER14_BASE VDPU_SWREG(98) ++#define VDPU_REG_REFER15_BASE VDPU_SWREG(99) ++#define VDPU_REG_DEC_E(v) ((v) ? BIT(0) : 0) ++ ++#define VDPU_REG_DEC_ADV_PRE_DIS(v) ((v) ? BIT(11) : 0) ++#define VDPU_REG_DEC_SCMD_DIS(v) ((v) ? BIT(10) : 0) ++#define VDPU_REG_FILTERING_DIS(v) ((v) ? BIT(8) : 0) ++#define VDPU_REG_PIC_FIXED_QUANT(v) ((v) ? BIT(7) : 0) ++#define VDPU_REG_DEC_LATENCY(v) (((v) << 1) & GENMASK(6, 1)) ++ ++#define VDPU_REG_INIT_QP(v) (((v) << 25) & GENMASK(30, 25)) ++#define VDPU_REG_STREAM_LEN(v) (((v) << 0) & GENMASK(23, 0)) ++ ++#define VDPU_REG_APF_THRESHOLD(v) (((v) << 17) & GENMASK(30, 17)) ++#define VDPU_REG_STARTMB_X(v) (((v) << 8) & GENMASK(16, 8)) ++#define VDPU_REG_STARTMB_Y(v) (((v) << 0) & GENMASK(7, 0)) ++ ++#define VDPU_REG_DEC_MODE(v) (((v) << 0) & GENMASK(3, 0)) ++ ++#define VDPU_REG_DEC_STRENDIAN_E(v) ((v) ? BIT(5) : 0) ++#define VDPU_REG_DEC_STRSWAP32_E(v) ((v) ? BIT(4) : 0) ++#define VDPU_REG_DEC_OUTSWAP32_E(v) ((v) ? BIT(3) : 0) ++#define VDPU_REG_DEC_INSWAP32_E(v) ((v) ? BIT(2) : 0) ++#define VDPU_REG_DEC_OUT_ENDIAN(v) ((v) ? BIT(1) : 0) ++#define VDPU_REG_DEC_IN_ENDIAN(v) ((v) ? BIT(0) : 0) ++ ++#define VDPU_REG_DEC_DATA_DISC_E(v) ((v) ? BIT(22) : 0) ++#define VDPU_REG_DEC_MAX_BURST(v) (((v) << 16) & GENMASK(20, 16)) ++#define VDPU_REG_DEC_AXI_WR_ID(v) (((v) << 8) & GENMASK(15, 8)) ++#define VDPU_REG_DEC_AXI_RD_ID(v) (((v) << 0) & GENMASK(7, 0)) ++ ++#define VDPU_REG_START_CODE_E(v) ((v) ? BIT(22) : 0) ++#define VDPU_REG_CH_8PIX_ILEAV_E(v) ((v) ? BIT(21) : 0) ++#define VDPU_REG_RLC_MODE_E(v) ((v) ? BIT(20) : 0) ++#define VDPU_REG_PIC_INTERLACE_E(v) ((v) ? BIT(17) : 0) ++#define VDPU_REG_PIC_FIELDMODE_E(v) ((v) ? BIT(16) : 0) ++#define VDPU_REG_PIC_TOPFIELD_E(v) ((v) ? BIT(13) : 0) ++#define VDPU_REG_WRITE_MVS_E(v) ((v) ? BIT(10) : 0) ++#define VDPU_REG_SEQ_MBAFF_E(v) ((v) ? BIT(7) : 0) ++#define VDPU_REG_PICORD_COUNT_E(v) ((v) ? BIT(6) : 0) ++#define VDPU_REG_DEC_TIMEOUT_E(v) ((v) ? BIT(5) : 0) ++#define VDPU_REG_DEC_CLK_GATE_E(v) ((v) ? BIT(4) : 0) ++ ++#define VDPU_REG_PRED_BC_TAP_0_0(v) (((v) << 22) & GENMASK(31, 22)) ++#define VDPU_REG_PRED_BC_TAP_0_1(v) (((v) << 12) & GENMASK(21, 12)) ++#define VDPU_REG_PRED_BC_TAP_0_2(v) (((v) << 2) & GENMASK(11, 2)) ++ ++#define VDPU_REG_REFBU_E(v) ((v) ? BIT(31) : 0) ++ ++#define VDPU_REG_PINIT_RLIST_F9(v) (((v) << 25) & GENMASK(29, 25)) ++#define VDPU_REG_PINIT_RLIST_F8(v) (((v) << 20) & GENMASK(24, 20)) ++#define VDPU_REG_PINIT_RLIST_F7(v) (((v) << 15) & GENMASK(19, 15)) ++#define VDPU_REG_PINIT_RLIST_F6(v) (((v) << 10) & GENMASK(14, 10)) ++#define VDPU_REG_PINIT_RLIST_F5(v) (((v) << 5) & GENMASK(9, 5)) ++#define VDPU_REG_PINIT_RLIST_F4(v) (((v) << 0) & GENMASK(4, 0)) ++ ++#define VDPU_REG_PINIT_RLIST_F15(v) (((v) << 25) & GENMASK(29, 25)) ++#define VDPU_REG_PINIT_RLIST_F14(v) (((v) << 20) & GENMASK(24, 20)) ++#define VDPU_REG_PINIT_RLIST_F13(v) (((v) << 15) & GENMASK(19, 15)) ++#define VDPU_REG_PINIT_RLIST_F12(v) (((v) << 10) & GENMASK(14, 10)) ++#define VDPU_REG_PINIT_RLIST_F11(v) (((v) << 5) & GENMASK(9, 5)) ++#define VDPU_REG_PINIT_RLIST_F10(v) (((v) << 0) & GENMASK(4, 0)) ++ ++#define VDPU_REG_REFER1_NBR(v) (((v) << 16) & GENMASK(31, 16)) ++#define VDPU_REG_REFER0_NBR(v) (((v) << 0) & GENMASK(15, 0)) ++ ++#define VDPU_REG_REFER3_NBR(v) (((v) << 16) & GENMASK(31, 16)) ++#define VDPU_REG_REFER2_NBR(v) (((v) << 0) & GENMASK(15, 0)) ++ ++#define VDPU_REG_REFER5_NBR(v) (((v) << 16) & GENMASK(31, 16)) ++#define VDPU_REG_REFER4_NBR(v) (((v) << 0) & GENMASK(15, 0)) ++ ++#define VDPU_REG_REFER7_NBR(v) (((v) << 16) & GENMASK(31, 16)) ++#define VDPU_REG_REFER6_NBR(v) (((v) << 0) & GENMASK(15, 0)) ++ ++#define VDPU_REG_REFER9_NBR(v) (((v) << 16) & GENMASK(31, 16)) ++#define VDPU_REG_REFER8_NBR(v) (((v) << 0) & GENMASK(15, 0)) ++ ++#define VDPU_REG_REFER11_NBR(v) (((v) << 16) & GENMASK(31, 16)) ++#define VDPU_REG_REFER10_NBR(v) (((v) << 0) & GENMASK(15, 0)) ++ ++#define VDPU_REG_REFER13_NBR(v) (((v) << 16) & GENMASK(31, 16)) ++#define VDPU_REG_REFER12_NBR(v) (((v) << 0) & GENMASK(15, 0)) ++ ++#define VDPU_REG_REFER15_NBR(v) (((v) << 16) & GENMASK(31, 16)) ++#define VDPU_REG_REFER14_NBR(v) (((v) << 0) & GENMASK(15, 0)) ++ ++#define VDPU_REG_BINIT_RLIST_F5(v) (((v) << 25) & GENMASK(29, 25)) ++#define VDPU_REG_BINIT_RLIST_F4(v) (((v) << 20) & GENMASK(24, 20)) ++#define VDPU_REG_BINIT_RLIST_F3(v) (((v) << 15) & GENMASK(19, 15)) ++#define VDPU_REG_BINIT_RLIST_F2(v) (((v) << 10) & GENMASK(14, 10)) ++#define VDPU_REG_BINIT_RLIST_F1(v) (((v) << 5) & GENMASK(9, 5)) ++#define VDPU_REG_BINIT_RLIST_F0(v) (((v) << 0) & GENMASK(4, 0)) ++ ++#define VDPU_REG_BINIT_RLIST_F11(v) (((v) << 25) & GENMASK(29, 25)) ++#define VDPU_REG_BINIT_RLIST_F10(v) (((v) << 20) & GENMASK(24, 20)) ++#define VDPU_REG_BINIT_RLIST_F9(v) (((v) << 15) & GENMASK(19, 15)) ++#define VDPU_REG_BINIT_RLIST_F8(v) (((v) << 10) & GENMASK(14, 10)) ++#define VDPU_REG_BINIT_RLIST_F7(v) (((v) << 5) & GENMASK(9, 5)) ++#define VDPU_REG_BINIT_RLIST_F6(v) (((v) << 0) & GENMASK(4, 0)) ++ ++#define VDPU_REG_BINIT_RLIST_F15(v) (((v) << 15) & GENMASK(19, 15)) ++#define VDPU_REG_BINIT_RLIST_F14(v) (((v) << 10) & GENMASK(14, 10)) ++#define VDPU_REG_BINIT_RLIST_F13(v) (((v) << 5) & GENMASK(9, 5)) ++#define VDPU_REG_BINIT_RLIST_F12(v) (((v) << 0) & GENMASK(4, 0)) ++ ++#define VDPU_REG_BINIT_RLIST_B5(v) (((v) << 25) & GENMASK(29, 25)) ++#define VDPU_REG_BINIT_RLIST_B4(v) (((v) << 20) & GENMASK(24, 20)) ++#define VDPU_REG_BINIT_RLIST_B3(v) (((v) << 15) & GENMASK(19, 15)) ++#define VDPU_REG_BINIT_RLIST_B2(v) (((v) << 10) & GENMASK(14, 10)) ++#define VDPU_REG_BINIT_RLIST_B1(v) (((v) << 5) & GENMASK(9, 5)) ++#define VDPU_REG_BINIT_RLIST_B0(v) (((v) << 0) & GENMASK(4, 0)) ++ ++#define VDPU_REG_BINIT_RLIST_B11(v) (((v) << 25) & GENMASK(29, 25)) ++#define VDPU_REG_BINIT_RLIST_B10(v) (((v) << 20) & GENMASK(24, 20)) ++#define VDPU_REG_BINIT_RLIST_B9(v) (((v) << 15) & GENMASK(19, 15)) ++#define VDPU_REG_BINIT_RLIST_B8(v) (((v) << 10) & GENMASK(14, 10)) ++#define VDPU_REG_BINIT_RLIST_B7(v) (((v) << 5) & GENMASK(9, 5)) ++#define VDPU_REG_BINIT_RLIST_B6(v) (((v) << 0) & GENMASK(4, 0)) ++ ++#define VDPU_REG_BINIT_RLIST_B15(v) (((v) << 15) & GENMASK(19, 15)) ++#define VDPU_REG_BINIT_RLIST_B14(v) (((v) << 10) & GENMASK(14, 10)) ++#define VDPU_REG_BINIT_RLIST_B13(v) (((v) << 5) & GENMASK(9, 5)) ++#define VDPU_REG_BINIT_RLIST_B12(v) (((v) << 0) & GENMASK(4, 0)) ++ ++#define VDPU_REG_PINIT_RLIST_F3(v) (((v) << 15) & GENMASK(19, 15)) ++#define VDPU_REG_PINIT_RLIST_F2(v) (((v) << 10) & GENMASK(14, 10)) ++#define VDPU_REG_PINIT_RLIST_F1(v) (((v) << 5) & GENMASK(9, 5)) ++#define VDPU_REG_PINIT_RLIST_F0(v) (((v) << 0) & GENMASK(4, 0)) ++ ++#define VDPU_REG_REFER_LTERM_E(v) (((v) << 0) & GENMASK(31, 0)) ++ ++#define VDPU_REG_REFER_VALID_E(v) (((v) << 0) & GENMASK(31, 0)) ++ ++#define VDPU_REG_STRM_START_BIT(v) (((v) << 0) & GENMASK(5, 0)) ++ ++#define VDPU_REG_CH_QP_OFFSET2(v) (((v) << 22) & GENMASK(26, 22)) ++#define VDPU_REG_CH_QP_OFFSET(v) (((v) << 17) & GENMASK(21, 17)) ++#define VDPU_REG_PIC_MB_HEIGHT_P(v) (((v) << 9) & GENMASK(16, 9)) ++#define VDPU_REG_PIC_MB_WIDTH(v) (((v) << 0) & GENMASK(8, 0)) ++ ++#define VDPU_REG_WEIGHT_BIPR_IDC(v) (((v) << 16) & GENMASK(17, 16)) ++#define VDPU_REG_REF_FRAMES(v) (((v) << 0) & GENMASK(4, 0)) ++ ++#define VDPU_REG_FILT_CTRL_PRES(v) ((v) ? BIT(31) : 0) ++#define VDPU_REG_RDPIC_CNT_PRES(v) ((v) ? BIT(30) : 0) ++#define VDPU_REG_FRAMENUM_LEN(v) (((v) << 16) & GENMASK(20, 16)) ++#define VDPU_REG_FRAMENUM(v) (((v) << 0) & GENMASK(15, 0)) ++ ++#define VDPU_REG_REFPIC_MK_LEN(v) (((v) << 16) & GENMASK(26, 16)) ++#define VDPU_REG_IDR_PIC_ID(v) (((v) << 0) & GENMASK(15, 0)) ++ ++#define VDPU_REG_PPS_ID(v) (((v) << 24) & GENMASK(31, 24)) ++#define VDPU_REG_REFIDX1_ACTIVE(v) (((v) << 19) & GENMASK(23, 19)) ++#define VDPU_REG_REFIDX0_ACTIVE(v) (((v) << 14) & GENMASK(18, 14)) ++#define VDPU_REG_POC_LENGTH(v) (((v) << 0) & GENMASK(7, 0)) ++ ++#define VDPU_REG_IDR_PIC_E(v) ((v) ? BIT(8) : 0) ++#define VDPU_REG_DIR_8X8_INFER_E(v) ((v) ? BIT(7) : 0) ++#define VDPU_REG_BLACKWHITE_E(v) ((v) ? BIT(6) : 0) ++#define VDPU_REG_CABAC_E(v) ((v) ? BIT(5) : 0) ++#define VDPU_REG_WEIGHT_PRED_E(v) ((v) ? BIT(4) : 0) ++#define VDPU_REG_CONST_INTRA_E(v) ((v) ? BIT(3) : 0) ++#define VDPU_REG_8X8TRANS_FLAG_E(v) ((v) ? BIT(2) : 0) ++#define VDPU_REG_TYPE1_QUANT_E(v) ((v) ? BIT(1) : 0) ++#define VDPU_REG_FIELDPIC_FLAG_E(v) ((v) ? BIT(0) : 0) ++ ++void rk3399_vpu_h264_dec_run(struct hantro_ctx *ctx) ++{ ++ struct hantro_dev *vpu = ctx->dev; ++ struct vb2_v4l2_buffer *src_buf, *dst_buf; ++ const struct hantro_h264_dec_ctrls *ctrls; ++ const struct v4l2_ctrl_h264_decode_params *decode; ++ const struct v4l2_ctrl_h264_slice_params *slices; ++ const struct v4l2_ctrl_h264_sps *sps; ++ const struct v4l2_ctrl_h264_pps *pps; ++ const u8 *b0_reflist, *b1_reflist, *p_reflist; ++ dma_addr_t addr; ++ size_t offset = 0; ++ u32 reg; ++ ++ /* Prepare the H264 decoder context. */ ++ if (hantro_h264_dec_prepare_run(ctx)) ++ return; ++ ++ src_buf = hantro_get_src_buf(ctx); ++ dst_buf = hantro_get_dst_buf(ctx); ++ ++ ctrls = &ctx->h264_dec.ctrls; ++ decode = ctrls->decode; ++ slices = ctrls->slices; ++ sps = ctrls->sps; ++ pps = ctrls->pps; ++ ++ b0_reflist = ctx->h264_dec.reflists.b0; ++ b1_reflist = ctx->h264_dec.reflists.b1; ++ p_reflist = ctx->h264_dec.reflists.p; ++ ++ reg = VDPU_REG_DEC_ADV_PRE_DIS(0) | ++ VDPU_REG_DEC_SCMD_DIS(0) | ++ VDPU_REG_FILTERING_DIS(0) | ++ VDPU_REG_PIC_FIXED_QUANT(0) | ++ VDPU_REG_DEC_LATENCY(0); ++ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(50)); ++ ++ reg = VDPU_REG_INIT_QP(pps->pic_init_qp_minus26 + 26) | ++ VDPU_REG_STREAM_LEN(vb2_get_plane_payload(&src_buf->vb2_buf, 0)); ++ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(51)); ++ ++ reg = VDPU_REG_APF_THRESHOLD(8) | ++ VDPU_REG_STARTMB_X(0) | ++ VDPU_REG_STARTMB_Y(0); ++ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(52)); ++ ++ reg = VDPU_REG_DEC_MODE(0); ++ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(53)); ++ ++ reg = VDPU_REG_DEC_STRENDIAN_E(1) | ++ VDPU_REG_DEC_STRSWAP32_E(1) | ++ VDPU_REG_DEC_OUTSWAP32_E(1) | ++ VDPU_REG_DEC_INSWAP32_E(1) | ++ VDPU_REG_DEC_OUT_ENDIAN(1) | ++ VDPU_REG_DEC_IN_ENDIAN(0); ++ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(54)); ++ ++ reg = VDPU_REG_DEC_DATA_DISC_E(0) | ++ VDPU_REG_DEC_MAX_BURST(16) | ++ VDPU_REG_DEC_AXI_WR_ID(0) | ++ VDPU_REG_DEC_AXI_RD_ID(0xff); ++ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(56)); ++ ++ reg = VDPU_REG_START_CODE_E(1) | ++ VDPU_REG_CH_8PIX_ILEAV_E(0) | ++ VDPU_REG_RLC_MODE_E(0) | ++ VDPU_REG_PIC_INTERLACE_E(!(sps->flags & V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY) && (sps->flags & V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD || slices[0].flags & V4L2_H264_SLICE_FLAG_FIELD_PIC)) | ++ VDPU_REG_PIC_FIELDMODE_E(slices[0].flags & V4L2_H264_SLICE_FLAG_FIELD_PIC) | ++ VDPU_REG_PIC_TOPFIELD_E(!(slices[0].flags & V4L2_H264_SLICE_FLAG_BOTTOM_FIELD)) | ++ VDPU_REG_WRITE_MVS_E(sps->profile_idc > 66 && decode->nal_ref_idc) | ++ VDPU_REG_SEQ_MBAFF_E(sps->flags & V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD) | ++ VDPU_REG_PICORD_COUNT_E(sps->profile_idc > 66) | ++ VDPU_REG_DEC_TIMEOUT_E(1) | ++ VDPU_REG_DEC_CLK_GATE_E(1); ++ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(57)); ++ ++ reg = VDPU_REG_PRED_BC_TAP_0_0(1) | ++ VDPU_REG_PRED_BC_TAP_0_1((u32)-5) | ++ VDPU_REG_PRED_BC_TAP_0_2(20); ++ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(59)); ++ ++ reg = VDPU_REG_REFBU_E(0); ++ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(65)); ++ ++ reg = VDPU_REG_PINIT_RLIST_F9(p_reflist[9]) | ++ VDPU_REG_PINIT_RLIST_F8(p_reflist[8]) | ++ VDPU_REG_PINIT_RLIST_F7(p_reflist[7]) | ++ VDPU_REG_PINIT_RLIST_F6(p_reflist[6]) | ++ VDPU_REG_PINIT_RLIST_F5(p_reflist[5]) | ++ VDPU_REG_PINIT_RLIST_F4(p_reflist[4]); ++ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(74)); ++ ++ reg = VDPU_REG_PINIT_RLIST_F15(p_reflist[15]) | ++ VDPU_REG_PINIT_RLIST_F14(p_reflist[14]) | ++ VDPU_REG_PINIT_RLIST_F13(p_reflist[13]) | ++ VDPU_REG_PINIT_RLIST_F12(p_reflist[12]) | ++ VDPU_REG_PINIT_RLIST_F11(p_reflist[11]) | ++ VDPU_REG_PINIT_RLIST_F10(p_reflist[10]); ++ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(75)); ++ ++ reg = VDPU_REG_REFER1_NBR(hantro_h264_get_ref_nbr(ctx, 1)) | ++ VDPU_REG_REFER0_NBR(hantro_h264_get_ref_nbr(ctx, 0)); ++ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(76)); ++ ++ reg = VDPU_REG_REFER3_NBR(hantro_h264_get_ref_nbr(ctx, 3)) | ++ VDPU_REG_REFER2_NBR(hantro_h264_get_ref_nbr(ctx, 2)); ++ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(77)); ++ ++ reg = VDPU_REG_REFER5_NBR(hantro_h264_get_ref_nbr(ctx, 5)) | ++ VDPU_REG_REFER4_NBR(hantro_h264_get_ref_nbr(ctx, 4)); ++ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(78)); ++ ++ reg = VDPU_REG_REFER7_NBR(hantro_h264_get_ref_nbr(ctx, 7)) | ++ VDPU_REG_REFER6_NBR(hantro_h264_get_ref_nbr(ctx, 6)); ++ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(79)); ++ ++ reg = VDPU_REG_REFER9_NBR(hantro_h264_get_ref_nbr(ctx, 9)) | ++ VDPU_REG_REFER8_NBR(hantro_h264_get_ref_nbr(ctx, 8)); ++ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(80)); ++ ++ reg = VDPU_REG_REFER11_NBR(hantro_h264_get_ref_nbr(ctx, 11)) | ++ VDPU_REG_REFER10_NBR(hantro_h264_get_ref_nbr(ctx, 10)); ++ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(81)); ++ ++ reg = VDPU_REG_REFER13_NBR(hantro_h264_get_ref_nbr(ctx, 13)) | ++ VDPU_REG_REFER12_NBR(hantro_h264_get_ref_nbr(ctx, 12)); ++ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(82)); ++ ++ reg = VDPU_REG_REFER15_NBR(hantro_h264_get_ref_nbr(ctx, 15)) | ++ VDPU_REG_REFER14_NBR(hantro_h264_get_ref_nbr(ctx, 14)); ++ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(83)); ++ ++ reg = VDPU_REG_BINIT_RLIST_F5(b0_reflist[5]) | ++ VDPU_REG_BINIT_RLIST_F4(b0_reflist[4]) | ++ VDPU_REG_BINIT_RLIST_F3(b0_reflist[3]) | ++ VDPU_REG_BINIT_RLIST_F2(b0_reflist[2]) | ++ VDPU_REG_BINIT_RLIST_F1(b0_reflist[1]) | ++ VDPU_REG_BINIT_RLIST_F0(b0_reflist[0]); ++ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(100)); ++ ++ reg = VDPU_REG_BINIT_RLIST_F11(b0_reflist[11]) | ++ VDPU_REG_BINIT_RLIST_F10(b0_reflist[10]) | ++ VDPU_REG_BINIT_RLIST_F9(b0_reflist[9]) | ++ VDPU_REG_BINIT_RLIST_F8(b0_reflist[8]) | ++ VDPU_REG_BINIT_RLIST_F7(b0_reflist[7]) | ++ VDPU_REG_BINIT_RLIST_F6(b0_reflist[6]); ++ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(101)); ++ ++ reg = VDPU_REG_BINIT_RLIST_F15(b0_reflist[15]) | ++ VDPU_REG_BINIT_RLIST_F14(b0_reflist[14]) | ++ VDPU_REG_BINIT_RLIST_F13(b0_reflist[13]) | ++ VDPU_REG_BINIT_RLIST_F12(b0_reflist[12]); ++ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(102)); ++ ++ reg = VDPU_REG_BINIT_RLIST_B5(b1_reflist[5]) | ++ VDPU_REG_BINIT_RLIST_B4(b1_reflist[4]) | ++ VDPU_REG_BINIT_RLIST_B3(b1_reflist[3]) | ++ VDPU_REG_BINIT_RLIST_B2(b1_reflist[2]) | ++ VDPU_REG_BINIT_RLIST_B1(b1_reflist[1]) | ++ VDPU_REG_BINIT_RLIST_B0(b1_reflist[0]); ++ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(103)); ++ ++ reg = VDPU_REG_BINIT_RLIST_B11(b1_reflist[11]) | ++ VDPU_REG_BINIT_RLIST_B10(b1_reflist[10]) | ++ VDPU_REG_BINIT_RLIST_B9(b1_reflist[9]) | ++ VDPU_REG_BINIT_RLIST_B8(b1_reflist[8]) | ++ VDPU_REG_BINIT_RLIST_B7(b1_reflist[7]) | ++ VDPU_REG_BINIT_RLIST_B6(b1_reflist[6]); ++ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(104)); ++ ++ reg = VDPU_REG_BINIT_RLIST_B15(b1_reflist[15]) | ++ VDPU_REG_BINIT_RLIST_B14(b1_reflist[14]) | ++ VDPU_REG_BINIT_RLIST_B13(b1_reflist[13]) | ++ VDPU_REG_BINIT_RLIST_B12(b1_reflist[12]); ++ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(105)); ++ ++ reg = VDPU_REG_PINIT_RLIST_F3(p_reflist[3]) | ++ VDPU_REG_PINIT_RLIST_F2(p_reflist[2]) | ++ VDPU_REG_PINIT_RLIST_F1(p_reflist[1]) | ++ VDPU_REG_PINIT_RLIST_F0(p_reflist[0]); ++ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(106)); ++ ++ reg = VDPU_REG_REFER_LTERM_E(ctx->h264_dec.dpb_longterm); ++ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(107)); ++ ++ reg = VDPU_REG_REFER_VALID_E(ctx->h264_dec.dpb_valid); ++ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(108)); ++ ++ reg = VDPU_REG_STRM_START_BIT(0); ++ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(109)); ++ ++ reg = VDPU_REG_CH_QP_OFFSET2(pps->second_chroma_qp_index_offset) | ++ VDPU_REG_CH_QP_OFFSET(pps->chroma_qp_index_offset) | ++ VDPU_REG_PIC_MB_HEIGHT_P(MB_HEIGHT(ctx->src_fmt.height)) | ++ VDPU_REG_PIC_MB_WIDTH(MB_WIDTH(ctx->src_fmt.width)); ++ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(110)); ++ ++ reg = VDPU_REG_WEIGHT_BIPR_IDC(pps->weighted_bipred_idc) | ++ VDPU_REG_REF_FRAMES(sps->max_num_ref_frames); ++ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(111)); ++ ++ reg = VDPU_REG_FILT_CTRL_PRES(pps->flags & V4L2_H264_PPS_FLAG_DEBLOCKING_FILTER_CONTROL_PRESENT) | ++ VDPU_REG_RDPIC_CNT_PRES(pps->flags & V4L2_H264_PPS_FLAG_REDUNDANT_PIC_CNT_PRESENT) | ++ VDPU_REG_FRAMENUM_LEN(sps->log2_max_frame_num_minus4 + 4) | ++ VDPU_REG_FRAMENUM(slices[0].frame_num); ++ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(112)); ++ ++ reg = VDPU_REG_REFPIC_MK_LEN(slices[0].dec_ref_pic_marking_bit_size) | ++ VDPU_REG_IDR_PIC_ID(slices[0].idr_pic_id); ++ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(113)); ++ ++ reg = VDPU_REG_PPS_ID(slices[0].pic_parameter_set_id) | ++ VDPU_REG_REFIDX1_ACTIVE(pps->num_ref_idx_l1_default_active_minus1 + 1) | ++ VDPU_REG_REFIDX0_ACTIVE(pps->num_ref_idx_l0_default_active_minus1 + 1) | ++ VDPU_REG_POC_LENGTH(slices[0].pic_order_cnt_bit_size); ++ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(114)); ++ ++ reg = VDPU_REG_IDR_PIC_E(decode->flags & V4L2_H264_DECODE_PARAM_FLAG_IDR_PIC) | ++ VDPU_REG_DIR_8X8_INFER_E(sps->flags & V4L2_H264_SPS_FLAG_DIRECT_8X8_INFERENCE) | ++ VDPU_REG_BLACKWHITE_E(sps->profile_idc >= 100 && sps->chroma_format_idc == 0) | ++ VDPU_REG_CABAC_E(pps->flags & V4L2_H264_PPS_FLAG_ENTROPY_CODING_MODE) | ++ VDPU_REG_WEIGHT_PRED_E(pps->flags & V4L2_H264_PPS_FLAG_WEIGHTED_PRED) | ++ VDPU_REG_CONST_INTRA_E(pps->flags & V4L2_H264_PPS_FLAG_CONSTRAINED_INTRA_PRED) | ++ VDPU_REG_8X8TRANS_FLAG_E(pps->flags & V4L2_H264_PPS_FLAG_TRANSFORM_8X8_MODE) | ++ VDPU_REG_TYPE1_QUANT_E(1) | ++ VDPU_REG_FIELDPIC_FLAG_E(!(sps->flags & V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY)); ++ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(115)); ++ ++ /* Auxiliary buffer prepared in hantro_g1_h264_dec_prepare_table(). */ ++ vdpu_write_relaxed(vpu, ctx->h264_dec.priv.dma, VDPU_REG_QTABLE_BASE); ++ ++ /* Source (stream) buffer. */ ++ addr = vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0); ++ vdpu_write_relaxed(vpu, addr, VDPU_REG_RLC_VLC_BASE); ++ ++ /* Destination (decoded frame) buffer. */ ++ addr = hantro_get_dec_buf_addr(ctx, &dst_buf->vb2_buf); ++ /* Adjust dma addr to start at second line for bottom field */ ++ if (slices[0].flags & V4L2_H264_SLICE_FLAG_BOTTOM_FIELD) ++ offset = ALIGN(ctx->src_fmt.width, MB_DIM); ++ vdpu_write_relaxed(vpu, addr + offset, VDPU_REG_DEC_OUT_BASE); ++ ++ /* Higher profiles require DMV buffer appended to reference frames. */ ++ if (sps->profile_idc > 66 && decode->nal_ref_idc) { ++ unsigned int bytes_per_mb = 384; ++ ++ /* DMV buffer for monochrome start directly after Y-plane */ ++ if (sps->profile_idc >= 100 && sps->chroma_format_idc == 0) ++ bytes_per_mb = 256; ++ offset = bytes_per_mb * MB_WIDTH(ctx->src_fmt.width) * ++ MB_HEIGHT(ctx->src_fmt.height); ++ ++ /* ++ * DMV buffer is split in two for field encoded frames, ++ * adjust offset for bottom field ++ */ ++ if (slices[0].flags & V4L2_H264_SLICE_FLAG_BOTTOM_FIELD) ++ offset += 32 * MB_WIDTH(ctx->src_fmt.width) * ++ MB_HEIGHT(ctx->src_fmt.height); ++ vdpu_write_relaxed(vpu, addr + offset, VDPU_REG_DIR_MV_BASE); ++ } ++ ++ vdpu_write_relaxed(vpu, hantro_h264_get_ref_buf(ctx, 0), VDPU_REG_REFER0_BASE); ++ vdpu_write_relaxed(vpu, hantro_h264_get_ref_buf(ctx, 1), VDPU_REG_REFER1_BASE); ++ vdpu_write_relaxed(vpu, hantro_h264_get_ref_buf(ctx, 2), VDPU_REG_REFER2_BASE); ++ vdpu_write_relaxed(vpu, hantro_h264_get_ref_buf(ctx, 3), VDPU_REG_REFER3_BASE); ++ vdpu_write_relaxed(vpu, hantro_h264_get_ref_buf(ctx, 4), VDPU_REG_REFER4_BASE); ++ vdpu_write_relaxed(vpu, hantro_h264_get_ref_buf(ctx, 5), VDPU_REG_REFER5_BASE); ++ vdpu_write_relaxed(vpu, hantro_h264_get_ref_buf(ctx, 6), VDPU_REG_REFER6_BASE); ++ vdpu_write_relaxed(vpu, hantro_h264_get_ref_buf(ctx, 7), VDPU_REG_REFER7_BASE); ++ vdpu_write_relaxed(vpu, hantro_h264_get_ref_buf(ctx, 8), VDPU_REG_REFER8_BASE); ++ vdpu_write_relaxed(vpu, hantro_h264_get_ref_buf(ctx, 9), VDPU_REG_REFER9_BASE); ++ vdpu_write_relaxed(vpu, hantro_h264_get_ref_buf(ctx, 10), VDPU_REG_REFER10_BASE); ++ vdpu_write_relaxed(vpu, hantro_h264_get_ref_buf(ctx, 11), VDPU_REG_REFER11_BASE); ++ vdpu_write_relaxed(vpu, hantro_h264_get_ref_buf(ctx, 12), VDPU_REG_REFER12_BASE); ++ vdpu_write_relaxed(vpu, hantro_h264_get_ref_buf(ctx, 13), VDPU_REG_REFER13_BASE); ++ vdpu_write_relaxed(vpu, hantro_h264_get_ref_buf(ctx, 14), VDPU_REG_REFER14_BASE); ++ vdpu_write_relaxed(vpu, hantro_h264_get_ref_buf(ctx, 15), VDPU_REG_REFER15_BASE); ++ ++ hantro_end_prepare_run(ctx); ++ ++ /* Start decoding! */ ++ reg = vdpu_read(vpu, VDPU_SWREG(57)) | VDPU_REG_DEC_E(1); ++ vdpu_write(vpu, reg, VDPU_SWREG(57)); ++} +-- +2.17.1 + + +From c6ad44bc8c4de5b6e468ee4449bfa181ff564f5a Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 18 Aug 2019 10:40:31 +0000 +Subject: [PATCH] media: hantro: Enable H264 decoding on RK3399 + +Signed-off-by: Jonas Karlman +--- + drivers/staging/media/hantro/rk3399_vpu_hw.c | 21 +++++++++++++++++++- + 1 file changed, 20 insertions(+), 1 deletion(-) + +diff --git a/drivers/staging/media/hantro/rk3399_vpu_hw.c b/drivers/staging/media/hantro/rk3399_vpu_hw.c +index 9ac1f2cb6a16..3e05cd2c870e 100644 +--- a/drivers/staging/media/hantro/rk3399_vpu_hw.c ++++ b/drivers/staging/media/hantro/rk3399_vpu_hw.c +@@ -60,6 +60,19 @@ static const struct hantro_fmt rk3399_vpu_dec_fmts[] = { + .fourcc = V4L2_PIX_FMT_NV12, + .codec_mode = HANTRO_MODE_NONE, + }, ++ { ++ .fourcc = V4L2_PIX_FMT_H264_SLICE, ++ .codec_mode = HANTRO_MODE_H264_DEC, ++ .max_depth = 2, ++ .frmsize = { ++ .min_width = 48, ++ .max_width = 1920, ++ .step_width = MB_DIM, ++ .min_height = 48, ++ .max_height = 1088, ++ .step_height = MB_DIM, ++ }, ++ }, + { + .fourcc = V4L2_PIX_FMT_MPEG2_SLICE, + .codec_mode = HANTRO_MODE_MPEG2_DEC, +@@ -161,6 +174,12 @@ static const struct hantro_codec_ops rk3399_vpu_codec_ops[] = { + .init = hantro_jpeg_enc_init, + .exit = hantro_jpeg_enc_exit, + }, ++ [HANTRO_MODE_H264_DEC] = { ++ .run = rk3399_vpu_h264_dec_run, ++ .reset = rk3399_vpu_dec_reset, ++ .init = hantro_h264_dec_init, ++ .exit = hantro_h264_dec_exit, ++ }, + [HANTRO_MODE_MPEG2_DEC] = { + .run = rk3399_vpu_mpeg2_dec_run, + .reset = rk3399_vpu_dec_reset, +@@ -196,7 +215,7 @@ const struct hantro_variant rk3399_vpu_variant = { + .dec_fmts = rk3399_vpu_dec_fmts, + .num_dec_fmts = ARRAY_SIZE(rk3399_vpu_dec_fmts), + .codec = HANTRO_JPEG_ENCODER | HANTRO_MPEG2_DECODER | +- HANTRO_VP8_DECODER, ++ HANTRO_VP8_DECODER | HANTRO_H264_DECODER, + .codec_ops = rk3399_vpu_codec_ops, + .irqs = rk3399_irqs, + .num_irqs = ARRAY_SIZE(rk3399_irqs), +-- +2.17.1 + + +From 51ec7c26733bd0c96fc9ec7d80b18ee8110d0a7d Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 18 Aug 2019 10:40:31 +0000 +Subject: [PATCH] media: hantro: Enable H264 decoding on RK3328 + +RK3328 SoC has the same decoder IP block as RK3399, +lets enable H264 decoding on RK3328. + +Signed-off-by: Jonas Karlman +--- + drivers/staging/media/hantro/rk3399_vpu_hw.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/staging/media/hantro/rk3399_vpu_hw.c b/drivers/staging/media/hantro/rk3399_vpu_hw.c +index 3e05cd2c870e..78f878ca01ff 100644 +--- a/drivers/staging/media/hantro/rk3399_vpu_hw.c ++++ b/drivers/staging/media/hantro/rk3399_vpu_hw.c +@@ -232,7 +232,8 @@ const struct hantro_variant rk3328_vpu_variant = { + .dec_offset = 0x400, + .dec_fmts = rk3399_vpu_dec_fmts, + .num_dec_fmts = ARRAY_SIZE(rk3399_vpu_dec_fmts), +- .codec = HANTRO_MPEG2_DECODER | HANTRO_VP8_DECODER, ++ .codec = HANTRO_MPEG2_DECODER | HANTRO_VP8_DECODER | ++ HANTRO_H264_DECODER, + .codec_ops = rk3399_vpu_codec_ops, + .irqs = rk3328_irqs, + .num_irqs = ARRAY_SIZE(rk3328_irqs), +-- +2.17.1 + diff --git a/patch/kernel/rk322x-current/01-linux-0015-fromlist-rga-for-rk322x.patch b/patch/kernel/rk322x-current/01-linux-0015-fromlist-rga-for-rk322x.patch new file mode 100644 index 0000000000..178a0d1b16 --- /dev/null +++ b/patch/kernel/rk322x-current/01-linux-0015-fromlist-rga-for-rk322x.patch @@ -0,0 +1,334 @@ +diff --git a/Documentation/devicetree/bindings/media/rockchip-rga.txt b/Documentation/devicetree/bindings/media/rockchip-rga.txt +index fd5276abf..c53a8e513 100644 +--- a/Documentation/devicetree/bindings/media/rockchip-rga.txt ++++ b/Documentation/devicetree/bindings/media/rockchip-rga.txt +@@ -6,8 +6,9 @@ BitBLT, alpha blending and image blur/sharpness. + + Required properties: + - compatible: value should be one of the following +- "rockchip,rk3288-rga"; +- "rockchip,rk3399-rga"; ++ "rockchip,rk3228-rga", "rockchip,rk3288-rga": for Rockchip RK3228 ++ "rockchip,rk3288-rga": for Rockchip RK3288 ++ "rockchip,rk3399-rga": for Rockchip RK3399 + + - interrupts: RGA interrupt specifier. + + +From patchwork Mon Feb 3 22:40:16 2020 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +X-Patchwork-Submitter: Justin Swartz +X-Patchwork-Id: 11363539 +Return-Path: + +Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org + [172.30.200.123]) + by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 8F24B13B4 + for ; + Mon, 3 Feb 2020 22:44:23 +0000 (UTC) +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 mail.kernel.org (Postfix) with ESMTPS id 6D7A520720 + for ; + Mon, 3 Feb 2020 22:44:23 +0000 (UTC) +Authentication-Results: mail.kernel.org; + dkim=pass (2048-bit key) header.d=lists.infradead.org + header.i=@lists.infradead.org header.b="Rk95K6Mw" +DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 6D7A520720 +Authentication-Results: mail.kernel.org; + dmarc=none (p=none dis=none) header.from=risingedge.co.za +Authentication-Results: mail.kernel.org; + spf=none + smtp.mailfrom=linux-rockchip-bounces+patchwork-linux-rockchip=patchwork.kernel.org@lists.infradead.org +DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; + d=lists.infradead.org; s=bombadil.20170209; h=Sender: + Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: + List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:References: + In-Reply-To:Message-Id:Date:Subject:To:From:Reply-To:Content-ID: + Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc + :Resent-Message-ID:List-Owner; + bh=Mr3ZsKOLBMyntVt7QVaqLPXjoGli9v17XimegPwfo5E=; b=Rk95K6MwDe/k1jTL1oE89GZ7jD + Df0s6yzzlU4KnuA/LMujDMQkOy/cXepljEOjNqeiUV4jLTxBtwkKSD3wf80l4yckFm3hFfNIwWMsR + t6JORVjyFPZXkx43QyVBSJJAPsLnWNuM2CqvwSTgNNB5atctQjqbqefws8u/0StFVEobFvVExznkF + 98U9Mkrvy8Pnvami6Tm5n9h2DE2Am3Uv8MkSmfTz2LAahHbfLf6uRwOYO0M3zVNXhkHILAA0bT5Lk + vpPMUywtyX0roHZzhDpsTHMHHuG/6eqM7dHkZi1KXOnbguOs0eS+oKki6qYnxAYX7JZk9cRwTyz+L + Qb1Zyt3g==; +Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) + by bombadil.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) + id 1iykS3-0002t8-1Z; Mon, 03 Feb 2020 22:44:19 +0000 +Received: from outgoing19.flk.host-h.net ([197.242.87.53]) + by bombadil.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) + id 1iykRc-0002Qb-2W; Mon, 03 Feb 2020 22:43:53 +0000 +Received: from www31.flk1.host-h.net ([188.40.1.173]) + by antispam5-flk1.host-h.net with esmtpsa + (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.92) + (envelope-from ) + id 1iykRT-00043D-NX; Tue, 04 Feb 2020 00:43:47 +0200 +Received: from [130.255.73.16] (helo=v01.28459.vpscontrol.net) + by www31.flk1.host-h.net with esmtpsa + (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.89) + (envelope-from ) + id 1iykRN-0001Vj-Ig; Tue, 04 Feb 2020 00:43:37 +0200 +From: Justin Swartz +To: Heiko Stuebner , Rob Herring , + Mark Rutland +Subject: [PATCH v4 2/3] ARM: dts: rockchip: add rga node for rk322x +Date: Mon, 3 Feb 2020 22:40:16 +0000 +Message-Id: + +X-Mailer: git-send-email 2.11.0 +In-Reply-To: +References: +X-Authenticated-Sender: justin.swartz@risingedge.co.za +X-Virus-Scanned: Clear +X-Originating-IP: 188.40.1.173 +X-SpamExperts-Domain: risingedge.co.za +X-SpamExperts-Username: +Authentication-Results: host-h.net; + auth=pass (login) smtp.auth=@risingedge.co.za +X-SpamExperts-Outgoing-Class: ham +X-SpamExperts-Outgoing-Evidence: Combined (0.02) +X-Recommended-Action: accept +X-Filter-ID: + Mvzo4OR0dZXEDF/gcnlw0S9sfM/nP8gxoqs1zeWkeM2pSDasLI4SayDByyq9LIhVs+Mi0mrjo7ud + QWat9IMBR0TNWdUk1Ol2OGx3IfrIJKyP9eGNFz9TW9u+Jt8z2T3K7uDjV/sFUXQr+CDrNQuIHgQg + mAX8Bxy/iUu0ThNZg0jxJtcVJProrT987X1VDPOqN+OoDzRTdku7DidYUZdNf38Sp7Of4wP429AA + f49baR+f3He7jw4SoVhmTJ/3eP9ORQWVx8ds1M4qmk3/bYr2p8zbg4Paoa3pNVQ0zl7t/+UfQLYB + qEPnp1U88kqVD8AM2G81dFO0E3gi+MOI1foZYzDggRXhpvoPtF3cVkniFXU3qJSqpdJudO6+rkiw + E5i8Wl78Q18OeOfsy4h7jF1Uv9lnibl3vcBqVmvQB4A18acp2SHDVKJPvzF61PUldigVAVXirbLu + Jjy3NtnGWLbnBGfrUBEXB2fYGLNieGQuoHtJvp0r29Rf3ZjFwL+MhHEWw/0qBlNDp8uABz3dkWV+ + tgmYFaNu+2UDArzT1gq7P+ZTycYLFeAN4+MGwnsp7SkU6CLbyF0Zq4b1/7rjUzETJrWks4pbbQJq + 6gWopI3ep45X19ZysgQ+31LcAX8eoFXAhohfegXGH2GIVQVglJFbK771YV8YbC29CtmpcTqTfSIf + CWq9oj7OiT8GwpAriB+3/81I3rvR8KJ2fK9jiDYgijyqqY0rATpzHKGfmtNsYTr4SmDZ/bGW8xZC + RRs6ZD24UhFcZZEpLhnBCwImTQNvxaLyCc35VA7RvW/HGiGqxL09Cymermt8NAa/gGopT3kKfO4C + gvcKmV0o9jYzsFpuc43pp/LzIs3ornuRuAAdgrkq+6l7ZLNYJcf7Z6PCydDzoYZgInuDxgFOs7AZ + TwbwMWQbSR6Wmuan/Ls9Qsz9RDDNbvm/+LalXn8ssqxyW1yX38NrFoXSENXH6UXfnav35JPA4YfM + 6tBkXsqvKY6zoLLTPpuFqUUQz+mM8JAD4ECWNo09vb0YLIRnK477e9Xake5PIWKjIXX7qe2zOXoS + foyabLOzJfoDhdDs/9NevXg27n3YPTZnj10duuFw8+p3/2bjO41FyBEqIaDudcVplPE6wCr6GXU1 + lCw88ijyus1sGnWknJqS8gGhNQxpB5P3qu7c1xMljx2PG/R+pKBSKy8hXOgvE1zSS7XUhkYEQYeb + 3jR5NeVaJQBh0uawl0Cg8j+knAzOA9mmoJvkuhKHiekUuskYaI6ERCKp8gXWqnT9kLHhStr5fiGK + 7KncpWELuTEvuGslKTrRIXcXpFg5ivY= +X-Report-Abuse-To: spam@antispammaster.host-h.net +X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 +X-CRM114-CacheID: sfid-20200203_144352_167656_2A074D4B +X-CRM114-Status: UNSURE ( 9.81 ) +X-CRM114-Notice: Please train this message. +X-Spam-Score: -0.7 (/) +X-Spam-Report: SpamAssassin version 3.4.3 on bombadil.infradead.org summary: + Content analysis details: (-0.7 points) + pts rule name description + ---- ---------------------- + -------------------------------------------------- + -0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at https://www.dnswl.org/, + low trust [197.242.87.53 listed in list.dnswl.org] + 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record + -0.0 SPF_PASS SPF: sender matches SPF record +X-BeenThere: linux-rockchip@lists.infradead.org +X-Mailman-Version: 2.1.29 +Precedence: list +List-Id: Upstream kernel work for Rockchip platforms + +List-Unsubscribe: , + +List-Archive: +List-Post: +List-Help: +List-Subscribe: , + +Cc: linux-rockchip@lists.infradead.org, + Justin Swartz , linux-kernel@vger.kernel.org, + linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org +MIME-Version: 1.0 +Sender: "Linux-rockchip" +Errors-To: + linux-rockchip-bounces+patchwork-linux-rockchip=patchwork.kernel.org@lists.infradead.org + +Add a node to define the presence of RGA, a 2D raster +graphic acceleration unit. + +Signed-off-by: Justin Swartz +--- + arch/arm/boot/dts/rk322x.dtsi | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/arch/arm/boot/dts/rk322x.dtsi b/arch/arm/boot/dts/rk322x.dtsi +index 340ed6ccb..29d50bebc 100644 +--- a/arch/arm/boot/dts/rk322x.dtsi ++++ b/arch/arm/boot/dts/rk322x.dtsi +@@ -621,6 +621,17 @@ + status = "disabled"; + }; + ++ rga: rga@20060000 { ++ compatible = "rockchip,rk3228-rga", "rockchip,rk3288-rga"; ++ reg = <0x20060000 0x1000>; ++ interrupts = ; ++ clocks = <&cru ACLK_RGA>, <&cru HCLK_RGA>, <&cru SCLK_RGA>; ++ clock-names = "aclk", "hclk", "sclk"; ++ resets = <&cru SRST_RGA>, <&cru SRST_RGA_A>, <&cru SRST_RGA_H>; ++ reset-names = "core", "axi", "ahb"; ++ status = "disabled"; ++ }; ++ + iep_mmu: iommu@20070800 { + compatible = "rockchip,iommu"; + reg = <0x20070800 0x100>; + +From patchwork Mon Feb 3 22:40:17 2020 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +X-Patchwork-Submitter: Justin Swartz +X-Patchwork-Id: 11363533 +Return-Path: + +Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org + [172.30.200.123]) + by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 38C9C138D + for ; + Mon, 3 Feb 2020 22:43:53 +0000 (UTC) +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 mail.kernel.org (Postfix) with ESMTPS id DFCE520732 + for ; + Mon, 3 Feb 2020 22:43:52 +0000 (UTC) +Authentication-Results: mail.kernel.org; + dkim=pass (2048-bit key) header.d=lists.infradead.org + header.i=@lists.infradead.org header.b="ZPPD3mYU" +DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org DFCE520732 +Authentication-Results: mail.kernel.org; + dmarc=none (p=none dis=none) header.from=risingedge.co.za +Authentication-Results: mail.kernel.org; + spf=none + smtp.mailfrom=linux-rockchip-bounces+patchwork-linux-rockchip=patchwork.kernel.org@lists.infradead.org +DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; + d=lists.infradead.org; s=bombadil.20170209; h=Sender: + Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: + List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:References: + In-Reply-To:Message-Id:Date:Subject:To:From:Reply-To:Content-ID: + Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc + :Resent-Message-ID:List-Owner; + bh=EuLRCmJksZCffcAB30Jmojhx9ACJFycNIoXd8Mvzba4=; b=ZPPD3mYUt8BEU6UlINqRsHKA3e + MKCDg7cZNfkBV15/m6E8M7HwqFvW7qi2Jbve6P0qpXE5fTvjzSrxMsN8xhunCyWs2mxmYQo+VS/No + ngEOaUjaIEbFpF2e2OPoFcV978WHndFC1+kaSKPOQFMWycEcZSi1fErrQrgbqJ38StVipC/M/CutW + vJVXTHtB4fkya1fIcLPNzEvCA+q9qR2seQSiIUBaqsyjUYLKiHE3WAQT4rL2euUmAomDB8z67eaSO + jLnmIedFz4Dzcsoi1QuokQWT5PUP0yWLyL3N9EdFFSwVZWJDH1G3vo1VHgoZte641qn4xMoXTeEsR + kutRoIrQ==; +Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) + by bombadil.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) + id 1iykRV-0002Lb-CZ; Mon, 03 Feb 2020 22:43:45 +0000 +Received: from outgoing3.flk.host-h.net ([188.40.0.89]) + by bombadil.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) + id 1iykRS-0002L3-V7; Mon, 03 Feb 2020 22:43:44 +0000 +Received: from www31.flk1.host-h.net ([188.40.1.173]) + by antispam1-flk1.host-h.net with esmtpsa + (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.92) + (envelope-from ) + id 1iykRR-00057b-1o; Tue, 04 Feb 2020 00:43:41 +0200 +Received: from [130.255.73.16] (helo=v01.28459.vpscontrol.net) + by www31.flk1.host-h.net with esmtpsa + (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.89) + (envelope-from ) + id 1iykRQ-0001Vj-9F; Tue, 04 Feb 2020 00:43:40 +0200 +From: Justin Swartz +To: Heiko Stuebner , Rob Herring , + Mark Rutland +Subject: [PATCH v4 3/3] ARM: dts: rockchip: enable rga for rk3229-xms6 +Date: Mon, 3 Feb 2020 22:40:17 +0000 +Message-Id: + +X-Mailer: git-send-email 2.11.0 +In-Reply-To: +References: +X-Authenticated-Sender: justin.swartz@risingedge.co.za +X-Virus-Scanned: Clear +X-Originating-IP: 188.40.1.173 +X-SpamExperts-Domain: risingedge.co.za +X-SpamExperts-Username: +Authentication-Results: host-h.net; + auth=pass (login) smtp.auth=@risingedge.co.za +X-SpamExperts-Outgoing-Class: ham +X-SpamExperts-Outgoing-Evidence: Combined (0.02) +X-Recommended-Action: accept +X-Filter-ID: + Mvzo4OR0dZXEDF/gcnlw0S9sfM/nP8gxoqs1zeWkeM2pSDasLI4SayDByyq9LIhVfgT6iyTGIFx4 + t4v1bPiGd0TNWdUk1Ol2OGx3IfrIJKyP9eGNFz9TW9u+Jt8z2T3K7uDjV/sFUXQr+CDrNQuIHgQg + mAX8Bxy/iUu0ThNZg0jxJtcVJProrT987X1VDPOqN+OoDzRTdku7DidYUZdNf38Sp7Of4wP429AA + f49baR+f3He7jw4SoVhmTJ/3eP9ORQWVx8ds1M4qmk3/bYr2p8zbg4Paoa3pNVQ0zl7t/+UfQLYB + qEPnp1U88kqVD8AM2G81dFO0E3gi+MOI1foZYzDggRXhpvoPtF3cVkniFXU3qJSqpdJudO6+rkiw + E5i8Wl78Q18OeOfsy4h7jF1Uv9lnibl3vcBqVmvQB4A18acDbZipvP/Qnob2BGYE/rMFAVXirbLu + Jjy3NtnGWLbnBGfrUBEXB2fYGLNieGQuoHtJvp0r29Rf3ZjFwL+MhHEWw/0qBlNDp8uABz3dkWV+ + tqvfVptXu2ZPaDzh52R7cx1TycYLFeAN4+MGwnsp7SkU6CLbyF0Zq4b1/7rjUzETJrWks4pbbQJq + 6gWopI3ep45X19ZysgQ+31LcAX8eoFXAhohfegXGH2GIVQVglJFbK771YV8YbC29CtmpcTqTfSIf + CWq9oj7OiT8GwpAriB+3/81I3rvR8KJ2fK9jiDYgijyqqY0rATpzHKGfmtNsYTr4SmDZ/bGW8xZC + RRs6ZD24UhFcZZEpLhnBCwImTQNvxaLyCc35VA7RvW/HGiGqxL09Cymermt8NAa/gGopT3kKfO4C + gvcKmV0o9jYzsFpuc43pp/LzIs3ornuRuAAdgrkq+6l7ZLNYJcf7Z6PCydDzoYZgInuDxgFOs7AZ + TwbwMQ+abPksLFqImdiM/AYysXvbKb2VdvW5w3MvmFzSUS/S38NrFoXSENXH6UXfnav35JPA4YfM + 6tBkXsqvKY6zoLLTPpuFqUUQz+mM8JAD4ECWNo09vb0YLIRnK477e9Xake5PIWKjIXX7qe2zOXoS + foz0bgFikLHoXc2uAxQnRRu7n7r+eM6iYfrDoYc1hgAawGbjO41FyBEqIaDudcVplPE6wCr6GXU1 + lCw88ijyus1sGnWknJqS8gGhNQxpB5P3qu7c1xMljx2PG/R+pKBSKy8hXOgvE1zSS7XUhkYEQYeb + 3jR5NeVaJQBh0uawl0Cg8j+knAzOA9mmoJvkuhKHiekUuskYaI6ERCKp8gXWqnT9kLHhStr5fiGK + 7KncpWELuTEvuGslKTrRIXcXpFg5ivY= +X-Report-Abuse-To: spam@antispammaster.host-h.net +X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 +X-CRM114-CacheID: sfid-20200203_144343_004138_EA933486 +X-CRM114-Status: UNSURE ( 8.20 ) +X-CRM114-Notice: Please train this message. +X-Spam-Score: 0.0 (/) +X-Spam-Report: SpamAssassin version 3.4.3 on bombadil.infradead.org summary: + Content analysis details: (0.0 points) + pts rule name description + ---- ---------------------- + -------------------------------------------------- + -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, + no trust [188.40.0.89 listed in list.dnswl.org] + 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record + -0.0 SPF_PASS SPF: sender matches SPF record +X-BeenThere: linux-rockchip@lists.infradead.org +X-Mailman-Version: 2.1.29 +Precedence: list +List-Id: Upstream kernel work for Rockchip platforms + +List-Unsubscribe: , + +List-Archive: +List-Post: +List-Help: +List-Subscribe: , + +Cc: linux-rockchip@lists.infradead.org, + Justin Swartz , linux-kernel@vger.kernel.org, + linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org +MIME-Version: 1.0 +Sender: "Linux-rockchip" +Errors-To: + linux-rockchip-bounces+patchwork-linux-rockchip=patchwork.kernel.org@lists.infradead.org + +Enable RGA for Mecer Xtreme Mini S6. + +Signed-off-by: Justin Swartz +--- + arch/arm/boot/dts/rk3229-xms6.dts | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/arch/arm/boot/dts/rk3229-xms6.dts b/arch/arm/boot/dts/rk3229-xms6.dts +index 679fc2b00..894f64a4a 100644 +--- a/arch/arm/boot/dts/rk3229-xms6.dts ++++ b/arch/arm/boot/dts/rk3229-xms6.dts +@@ -202,6 +202,10 @@ + status = "okay"; + }; + ++&rga { ++ status = "okay"; ++}; ++ + &sdmmc { + cap-mmc-highspeed; + disable-wp; diff --git a/patch/kernel/rk322x-current/01-linux-0015-hantro-set-of-small-cleanups-and-fixes.patch b/patch/kernel/rk322x-current/01-linux-0015-hantro-set-of-small-cleanups-and-fixes.patch new file mode 100644 index 0000000000..57759df24f --- /dev/null +++ b/patch/kernel/rk322x-current/01-linux-0015-hantro-set-of-small-cleanups-and-fixes.patch @@ -0,0 +1,732 @@ +diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c +index cc34c5ab7009..3070672e6b4f 100644 +--- a/drivers/media/v4l2-core/v4l2-mem2mem.c ++++ b/drivers/media/v4l2-core/v4l2-mem2mem.c +@@ -499,12 +499,21 @@ void v4l2_m2m_buf_done_and_job_finish(struct v4l2_m2m_dev *m2m_dev, + + if (WARN_ON(!src_buf || !dst_buf)) + goto unlock; +- v4l2_m2m_buf_done(src_buf, state); + dst_buf->is_held = src_buf->flags & V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF; + if (!dst_buf->is_held) { + v4l2_m2m_dst_buf_remove(m2m_ctx); + v4l2_m2m_buf_done(dst_buf, state); + } ++ /* ++ * If the request API is being used, returning the OUTPUT ++ * (src) buffer will wake-up any process waiting on the ++ * request file descriptor. ++ * ++ * Therefore, return the CAPTURE (dst) buffer first, ++ * to avoid signalling the request file descriptor ++ * before the CAPTURE buffer is done. ++ */ ++ v4l2_m2m_buf_done(src_buf, state); + schedule_next = _v4l2_m2m_job_finish(m2m_dev, m2m_ctx); + unlock: + spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags); +-- +2.17.1 + + +From 46fef6ecbc765dedaeef46339474529645f09404 Mon Sep 17 00:00:00 2001 +From: Ezequiel Garcia +Date: Wed, 18 Mar 2020 10:21:02 -0300 +Subject: [PATCH] hantro: Set buffers' zeroth plane payload in .buf_prepare + +Buffers' zeroth plane payload size is calculated at format +negotiation time, and so it can be set in .buf_prepare. + +Keep in mind that, to make this change easier, hantro_buf_prepare +is refactored, using the cedrus driver as reference. This results +in cleaner code as byproduct. + +Signed-off-by: Ezequiel Garcia +--- + drivers/staging/media/hantro/hantro_v4l2.c | 16 +++++++++++----- + 1 file changed, 11 insertions(+), 5 deletions(-) + +diff --git a/drivers/staging/media/hantro/hantro_v4l2.c b/drivers/staging/media/hantro/hantro_v4l2.c +index f4ae2cee0f18..3142ab6697d5 100644 +--- a/drivers/staging/media/hantro/hantro_v4l2.c ++++ b/drivers/staging/media/hantro/hantro_v4l2.c +@@ -608,7 +608,7 @@ hantro_queue_setup(struct vb2_queue *vq, unsigned int *num_buffers, + } + + static int +-hantro_buf_plane_check(struct vb2_buffer *vb, const struct hantro_fmt *vpu_fmt, ++hantro_buf_plane_check(struct vb2_buffer *vb, + struct v4l2_pix_format_mplane *pixfmt) + { + unsigned int sz; +@@ -630,12 +630,18 @@ static int hantro_buf_prepare(struct vb2_buffer *vb) + { + struct vb2_queue *vq = vb->vb2_queue; + struct hantro_ctx *ctx = vb2_get_drv_priv(vq); ++ struct v4l2_pix_format_mplane *pix_fmt; ++ int ret; + + if (V4L2_TYPE_IS_OUTPUT(vq->type)) +- return hantro_buf_plane_check(vb, ctx->vpu_src_fmt, +- &ctx->src_fmt); +- +- return hantro_buf_plane_check(vb, ctx->vpu_dst_fmt, &ctx->dst_fmt); ++ pix_fmt = &ctx->src_fmt; ++ else ++ pix_fmt = &ctx->dst_fmt; ++ ret = hantro_buf_plane_check(vb, pix_fmt); ++ if (ret) ++ return ret; ++ vb2_set_plane_payload(vb, 0, pix_fmt->plane_fmt[0].sizeimage); ++ return 0; + } + + static void hantro_buf_queue(struct vb2_buffer *vb) +-- +2.17.1 + + +From 49b98070ac9cbd4e731a84f0a3c10e6dd803d37c Mon Sep 17 00:00:00 2001 +From: Ezequiel Garcia +Date: Wed, 18 Mar 2020 10:21:03 -0300 +Subject: [PATCH] hantro: Use v4l2_m2m_buf_done_and_job_finish + +Let the core sort out the nuances of returning buffers +to userspace, by using the v4l2_m2m_buf_done_and_job_finish +helper. + +This change also removes usage of buffer sequence fields, +which shouldn't have any meaning for stateless decoders. + +Signed-off-by: Ezequiel Garcia +Nacked-by: Hans Verkuil +--- + drivers/staging/media/hantro/hantro_drv.c | 27 ++++++++--------------- + 1 file changed, 9 insertions(+), 18 deletions(-) + +diff --git a/drivers/staging/media/hantro/hantro_drv.c b/drivers/staging/media/hantro/hantro_drv.c +index c98835326135..dd503918a017 100644 +--- a/drivers/staging/media/hantro/hantro_drv.c ++++ b/drivers/staging/media/hantro/hantro_drv.c +@@ -94,32 +94,23 @@ static void hantro_job_finish(struct hantro_dev *vpu, + unsigned int bytesused, + enum vb2_buffer_state result) + { +- struct vb2_v4l2_buffer *src, *dst; + int ret; + + pm_runtime_mark_last_busy(vpu->dev); + pm_runtime_put_autosuspend(vpu->dev); + clk_bulk_disable(vpu->variant->num_clocks, vpu->clocks); + +- src = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); +- dst = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); +- +- if (WARN_ON(!src)) +- return; +- if (WARN_ON(!dst)) +- return; +- +- src->sequence = ctx->sequence_out++; +- dst->sequence = ctx->sequence_cap++; +- +- ret = ctx->buf_finish(ctx, &dst->vb2_buf, bytesused); +- if (ret) +- result = VB2_BUF_STATE_ERROR; ++ if (ctx->buf_finish) { ++ struct vb2_v4l2_buffer *dst; + +- v4l2_m2m_buf_done(src, result); +- v4l2_m2m_buf_done(dst, result); ++ dst = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); ++ ret = ctx->buf_finish(ctx, &dst->vb2_buf, bytesused); ++ if (ret) ++ result = VB2_BUF_STATE_ERROR; ++ } + +- v4l2_m2m_job_finish(vpu->m2m_dev, ctx->fh.m2m_ctx); ++ v4l2_m2m_buf_done_and_job_finish(ctx->dev->m2m_dev, ctx->fh.m2m_ctx, ++ result); + } + + void hantro_irq_done(struct hantro_dev *vpu, unsigned int bytesused, +-- +2.17.1 + + +From ee3c913094e5776a0b1270b78ecce8a5e9803a42 Mon Sep 17 00:00:00 2001 +From: Ezequiel Garcia +Date: Wed, 18 Mar 2020 10:21:04 -0300 +Subject: [PATCH] hantro: Remove unneeded hantro_dec_buf_finish + +Since now .buf_prepare takes care of setting the +buffer payload size, we can get rid of this, +at least for decoders. + +Signed-off-by: Ezequiel Garcia +--- + drivers/staging/media/hantro/hantro_drv.c | 10 ---------- + 1 file changed, 10 deletions(-) + +diff --git a/drivers/staging/media/hantro/hantro_drv.c b/drivers/staging/media/hantro/hantro_drv.c +index dd503918a017..a732beeb3bb6 100644 +--- a/drivers/staging/media/hantro/hantro_drv.c ++++ b/drivers/staging/media/hantro/hantro_drv.c +@@ -80,15 +80,6 @@ hantro_enc_buf_finish(struct hantro_ctx *ctx, struct vb2_buffer *buf, + return 0; + } + +-static int +-hantro_dec_buf_finish(struct hantro_ctx *ctx, struct vb2_buffer *buf, +- unsigned int bytesused) +-{ +- /* For decoders set bytesused as per the output picture. */ +- buf->planes[0].bytesused = ctx->dst_fmt.plane_fmt[0].sizeimage; +- return 0; +-} +- + static void hantro_job_finish(struct hantro_dev *vpu, + struct hantro_ctx *ctx, + unsigned int bytesused, +@@ -412,7 +403,6 @@ static int hantro_open(struct file *filp) + ctx->buf_finish = hantro_enc_buf_finish; + } else if (func->id == MEDIA_ENT_F_PROC_VIDEO_DECODER) { + allowed_codecs = vpu->variant->codec & HANTRO_DECODERS; +- ctx->buf_finish = hantro_dec_buf_finish; + } else { + ret = -ENODEV; + goto err_ctx_free; +-- +2.17.1 + + +From 403b36c2db7e39b46f8e0f6a363af6763373933d Mon Sep 17 00:00:00 2001 +From: Ezequiel Garcia +Date: Wed, 18 Mar 2020 10:21:05 -0300 +Subject: [PATCH] hantro: Move H264 motion vector calculation to a helper + +Move the extra bytes calculation that are needed for H264 +motion vector to a helper. This is just a cosmetic cleanup. + +Signed-off-by: Ezequiel Garcia +--- + drivers/staging/media/hantro/hantro.h | 4 --- + drivers/staging/media/hantro/hantro_hw.h | 31 ++++++++++++++++++++++ + drivers/staging/media/hantro/hantro_v4l2.c | 25 ++--------------- + 3 files changed, 33 insertions(+), 27 deletions(-) + +diff --git a/drivers/staging/media/hantro/hantro.h b/drivers/staging/media/hantro/hantro.h +index b0faa43b3f79..1a010d438ac2 100644 +--- a/drivers/staging/media/hantro/hantro.h ++++ b/drivers/staging/media/hantro/hantro.h +@@ -26,10 +26,6 @@ + + #include "hantro_hw.h" + +-#define MB_DIM 16 +-#define MB_WIDTH(w) DIV_ROUND_UP(w, MB_DIM) +-#define MB_HEIGHT(h) DIV_ROUND_UP(h, MB_DIM) +- + struct hantro_ctx; + struct hantro_codec_ops; + +diff --git a/drivers/staging/media/hantro/hantro_hw.h b/drivers/staging/media/hantro/hantro_hw.h +index 4a64873bf332..33c1ce169203 100644 +--- a/drivers/staging/media/hantro/hantro_hw.h ++++ b/drivers/staging/media/hantro/hantro_hw.h +@@ -18,6 +18,10 @@ + + #define DEC_8190_ALIGN_MASK 0x07U + ++#define MB_DIM 16 ++#define MB_WIDTH(w) DIV_ROUND_UP(w, MB_DIM) ++#define MB_HEIGHT(h) DIV_ROUND_UP(h, MB_DIM) ++ + struct hantro_dev; + struct hantro_ctx; + struct hantro_buf; +@@ -180,6 +184,33 @@ void rk3399_vpu_h264_dec_run(struct hantro_ctx *ctx); + int hantro_h264_dec_init(struct hantro_ctx *ctx); + void hantro_h264_dec_exit(struct hantro_ctx *ctx); + ++static inline size_t ++hantro_h264_mv_size(unsigned int width, unsigned int height) ++{ ++ /* ++ * A decoded 8-bit 4:2:0 NV12 frame may need memory for up to ++ * 448 bytes per macroblock with additional 32 bytes on ++ * multi-core variants. ++ * ++ * The H264 decoder needs extra space on the output buffers ++ * to store motion vectors. This is needed for reference ++ * frames and only if the format is non-post-processed NV12. ++ * ++ * Memory layout is as follow: ++ * ++ * +---------------------------+ ++ * | Y-plane 256 bytes x MBs | ++ * +---------------------------+ ++ * | UV-plane 128 bytes x MBs | ++ * +---------------------------+ ++ * | MV buffer 64 bytes x MBs | ++ * +---------------------------+ ++ * | MC sync 32 bytes | ++ * +---------------------------+ ++ */ ++ return 64 * MB_WIDTH(width) * MB_WIDTH(height) + 32; ++} ++ + void hantro_g1_mpeg2_dec_run(struct hantro_ctx *ctx); + void rk3399_vpu_mpeg2_dec_run(struct hantro_ctx *ctx); + void hantro_mpeg2_dec_copy_qtable(u8 *qtable, +diff --git a/drivers/staging/media/hantro/hantro_v4l2.c b/drivers/staging/media/hantro/hantro_v4l2.c +index 3142ab6697d5..458b502ff01b 100644 +--- a/drivers/staging/media/hantro/hantro_v4l2.c ++++ b/drivers/staging/media/hantro/hantro_v4l2.c +@@ -273,32 +273,11 @@ static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f, + /* Fill remaining fields */ + v4l2_fill_pixfmt_mp(pix_mp, fmt->fourcc, pix_mp->width, + pix_mp->height); +- /* +- * A decoded 8-bit 4:2:0 NV12 frame may need memory for up to +- * 448 bytes per macroblock with additional 32 bytes on +- * multi-core variants. +- * +- * The H264 decoder needs extra space on the output buffers +- * to store motion vectors. This is needed for reference +- * frames and only if the format is non-post-processed NV12. +- * +- * Memory layout is as follow: +- * +- * +---------------------------+ +- * | Y-plane 256 bytes x MBs | +- * +---------------------------+ +- * | UV-plane 128 bytes x MBs | +- * +---------------------------+ +- * | MV buffer 64 bytes x MBs | +- * +---------------------------+ +- * | MC sync 32 bytes | +- * +---------------------------+ +- */ + if (ctx->vpu_src_fmt->fourcc == V4L2_PIX_FMT_H264_SLICE && + !hantro_needs_postproc(ctx, fmt)) + pix_mp->plane_fmt[0].sizeimage += +- 64 * MB_WIDTH(pix_mp->width) * +- MB_WIDTH(pix_mp->height) + 32; ++ hantro_h264_mv_size(pix_mp->width, ++ pix_mp->height); + } else if (!pix_mp->plane_fmt[0].sizeimage) { + /* + * For coded formats the application can specify +-- +2.17.1 + + +From 220559bea572812494ac528eb4bb3af770748641 Mon Sep 17 00:00:00 2001 +From: Ezequiel Garcia +Date: Wed, 18 Mar 2020 10:21:06 -0300 +Subject: [PATCH] hantro: Refactor for V4L2 API spec compliancy + +Refactor how S_FMT and TRY_FMT are handled, and also make sure +internal initial format and format reset are done properly. + +The latter is achieved by making sure the same hantro_{set,try}_fmt +helpers are called on all paths that set the format (which is +part of the driver state). + +This commit removes the following v4l2-compliance warnings: + +test VIDIOC_G_FMT: OK + fail: v4l2-test-formats.cpp(711): Video Capture Multiplanar: TRY_FMT(G_FMT) != G_FMT +test VIDIOC_TRY_FMT: FAIL + fail: v4l2-test-formats.cpp(1116): Video Capture Multiplanar: S_FMT(G_FMT) != G_FMT +test VIDIOC_S_FMT: FAIL + +Reported-by: Nicolas Dufresne +Signed-off-by: Ezequiel Garcia +--- + drivers/staging/media/hantro/hantro.h | 3 +- + drivers/staging/media/hantro/hantro_v4l2.c | 70 ++++++++++++++-------- + 2 files changed, 47 insertions(+), 26 deletions(-) + +diff --git a/drivers/staging/media/hantro/hantro.h b/drivers/staging/media/hantro/hantro.h +index 1a010d438ac2..f0aca46969f9 100644 +--- a/drivers/staging/media/hantro/hantro.h ++++ b/drivers/staging/media/hantro/hantro.h +@@ -417,7 +417,8 @@ hantro_get_dst_buf(struct hantro_ctx *ctx) + } + + static inline bool +-hantro_needs_postproc(struct hantro_ctx *ctx, const struct hantro_fmt *fmt) ++hantro_needs_postproc(const struct hantro_ctx *ctx, ++ const struct hantro_fmt *fmt) + { + return fmt->fourcc != V4L2_PIX_FMT_NV12; + } +diff --git a/drivers/staging/media/hantro/hantro_v4l2.c b/drivers/staging/media/hantro/hantro_v4l2.c +index 458b502ff01b..f28a94e2fa93 100644 +--- a/drivers/staging/media/hantro/hantro_v4l2.c ++++ b/drivers/staging/media/hantro/hantro_v4l2.c +@@ -30,6 +30,11 @@ + #include "hantro_hw.h" + #include "hantro_v4l2.h" + ++static int hantro_set_fmt_out(struct hantro_ctx *ctx, ++ struct v4l2_pix_format_mplane *pix_mp); ++static int hantro_set_fmt_cap(struct hantro_ctx *ctx, ++ struct v4l2_pix_format_mplane *pix_mp); ++ + static const struct hantro_fmt * + hantro_get_formats(const struct hantro_ctx *ctx, unsigned int *num_fmts) + { +@@ -227,12 +232,12 @@ static int vidioc_g_fmt_cap_mplane(struct file *file, void *priv, + return 0; + } + +-static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f, +- bool capture) ++static int hantro_try_fmt(const struct hantro_ctx *ctx, ++ struct v4l2_pix_format_mplane *pix_mp, ++ enum v4l2_buf_type type) + { +- struct hantro_ctx *ctx = fh_to_ctx(priv); +- struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; + const struct hantro_fmt *fmt, *vpu_fmt; ++ bool capture = !V4L2_TYPE_IS_OUTPUT(type); + bool coded; + + coded = capture == hantro_is_encoder_ctx(ctx); +@@ -246,7 +251,7 @@ static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f, + fmt = hantro_find_format(ctx, pix_mp->pixelformat); + if (!fmt) { + fmt = hantro_get_default_fmt(ctx, coded); +- f->fmt.pix_mp.pixelformat = fmt->fourcc; ++ pix_mp->pixelformat = fmt->fourcc; + } + + if (coded) { +@@ -294,13 +299,13 @@ static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f, + static int vidioc_try_fmt_cap_mplane(struct file *file, void *priv, + struct v4l2_format *f) + { +- return vidioc_try_fmt(file, priv, f, true); ++ return hantro_try_fmt(fh_to_ctx(priv), &f->fmt.pix_mp, f->type); + } + + static int vidioc_try_fmt_out_mplane(struct file *file, void *priv, + struct v4l2_format *f) + { +- return vidioc_try_fmt(file, priv, f, false); ++ return hantro_try_fmt(fh_to_ctx(priv), &f->fmt.pix_mp, f->type); + } + + static void +@@ -334,11 +339,12 @@ hantro_reset_encoded_fmt(struct hantro_ctx *ctx) + } + + hantro_reset_fmt(fmt, vpu_fmt); +- fmt->num_planes = 1; + fmt->width = vpu_fmt->frmsize.min_width; + fmt->height = vpu_fmt->frmsize.min_height; +- fmt->plane_fmt[0].sizeimage = vpu_fmt->header_size + +- fmt->width * fmt->height * vpu_fmt->max_depth; ++ if (hantro_is_encoder_ctx(ctx)) ++ hantro_set_fmt_cap(ctx, fmt); ++ else ++ hantro_set_fmt_out(ctx, fmt); + } + + static void +@@ -360,9 +366,12 @@ hantro_reset_raw_fmt(struct hantro_ctx *ctx) + } + + hantro_reset_fmt(raw_fmt, raw_vpu_fmt); +- v4l2_fill_pixfmt_mp(raw_fmt, raw_vpu_fmt->fourcc, +- encoded_fmt->width, +- encoded_fmt->height); ++ raw_fmt->width = encoded_fmt->width; ++ raw_fmt->width = encoded_fmt->width; ++ if (hantro_is_encoder_ctx(ctx)) ++ hantro_set_fmt_out(ctx, raw_fmt); ++ else ++ hantro_set_fmt_cap(ctx, raw_fmt); + } + + void hantro_reset_fmts(struct hantro_ctx *ctx) +@@ -388,15 +397,15 @@ hantro_update_requires_request(struct hantro_ctx *ctx, u32 fourcc) + } + } + +-static int +-vidioc_s_fmt_out_mplane(struct file *file, void *priv, struct v4l2_format *f) ++static int hantro_set_fmt_out(struct hantro_ctx *ctx, ++ struct v4l2_pix_format_mplane *pix_mp) + { +- struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; +- struct hantro_ctx *ctx = fh_to_ctx(priv); +- struct vb2_queue *vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type); ++ struct vb2_queue *vq; + int ret; + +- ret = vidioc_try_fmt_out_mplane(file, priv, f); ++ vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, ++ V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); ++ ret = hantro_try_fmt(ctx, pix_mp, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); + if (ret) + return ret; + +@@ -458,16 +467,15 @@ vidioc_s_fmt_out_mplane(struct file *file, void *priv, struct v4l2_format *f) + return 0; + } + +-static int vidioc_s_fmt_cap_mplane(struct file *file, void *priv, +- struct v4l2_format *f) ++static int hantro_set_fmt_cap(struct hantro_ctx *ctx, ++ struct v4l2_pix_format_mplane *pix_mp) + { +- struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; +- struct hantro_ctx *ctx = fh_to_ctx(priv); + struct vb2_queue *vq; + int ret; + + /* Change not allowed if queue is busy. */ +- vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type); ++ vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, ++ V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); + if (vb2_is_busy(vq)) + return -EBUSY; + +@@ -488,7 +496,7 @@ static int vidioc_s_fmt_cap_mplane(struct file *file, void *priv, + return -EBUSY; + } + +- ret = vidioc_try_fmt_cap_mplane(file, priv, f); ++ ret = hantro_try_fmt(ctx, pix_mp, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); + if (ret) + return ret; + +@@ -522,6 +530,18 @@ static int vidioc_s_fmt_cap_mplane(struct file *file, void *priv, + return 0; + } + ++static int ++vidioc_s_fmt_out_mplane(struct file *file, void *priv, struct v4l2_format *f) ++{ ++ return hantro_set_fmt_out(fh_to_ctx(priv), &f->fmt.pix_mp); ++} ++ ++static int ++vidioc_s_fmt_cap_mplane(struct file *file, void *priv, struct v4l2_format *f) ++{ ++ return hantro_set_fmt_cap(fh_to_ctx(priv), &f->fmt.pix_mp); ++} ++ + const struct v4l2_ioctl_ops hantro_ioctl_ops = { + .vidioc_querycap = vidioc_querycap, + .vidioc_enum_framesizes = vidioc_enum_framesizes, +-- +2.17.1 + + +From 03a4222379d16c8a5f4a9c74f78c977b6a0e16a0 Mon Sep 17 00:00:00 2001 +From: Ezequiel Garcia +Date: Wed, 18 Mar 2020 10:21:07 -0300 +Subject: [PATCH] dt-bindings: rockchip-vpu: Convert bindings to json-schema + +Convert Rockchip VPU (Hantro IP block) codec driver documentation to +json-schema. + +Cc: Rob Herring +Signed-off-by: Ezequiel Garcia +--- + .../bindings/media/rockchip-vpu.txt | 43 ---------- + .../bindings/media/rockchip-vpu.yaml | 82 +++++++++++++++++++ + MAINTAINERS | 2 +- + 3 files changed, 83 insertions(+), 44 deletions(-) + delete mode 100644 Documentation/devicetree/bindings/media/rockchip-vpu.txt + create mode 100644 Documentation/devicetree/bindings/media/rockchip-vpu.yaml + +diff --git a/Documentation/devicetree/bindings/media/rockchip-vpu.txt b/Documentation/devicetree/bindings/media/rockchip-vpu.txt +deleted file mode 100644 +index 339252d9c515..000000000000 +--- a/Documentation/devicetree/bindings/media/rockchip-vpu.txt ++++ /dev/null +@@ -1,43 +0,0 @@ +-device-tree bindings for rockchip VPU codec +- +-Rockchip (Video Processing Unit) present in various Rockchip platforms, +-such as RK3288, RK3328 and RK3399. +- +-Required properties: +-- compatible: value should be one of the following +- "rockchip,rk3288-vpu"; +- "rockchip,rk3328-vpu"; +- "rockchip,rk3399-vpu"; +-- interrupts: encoding and decoding interrupt specifiers +-- interrupt-names: should be +- "vepu", "vdpu" on RK3288 and RK3399, +- "vdpu" on RK3328. +-- clocks: phandle to VPU aclk, hclk clocks +-- clock-names: should be "aclk" and "hclk" +-- power-domains: phandle to power domain node +-- iommus: phandle to a iommu node +- +-Example: +-SoC-specific DT entry: +- vpu: video-codec@ff9a0000 { +- compatible = "rockchip,rk3288-vpu"; +- reg = <0x0 0xff9a0000 0x0 0x800>; +- interrupts = , +- ; +- interrupt-names = "vepu", "vdpu"; +- clocks = <&cru ACLK_VCODEC>, <&cru HCLK_VCODEC>; +- clock-names = "aclk", "hclk"; +- power-domains = <&power RK3288_PD_VIDEO>; +- iommus = <&vpu_mmu>; +- }; +- +- vpu: video-codec@ff350000 { +- compatible = "rockchip,rk3328-vpu"; +- reg = <0x0 0xff350000 0x0 0x800>; +- interrupts = ; +- interrupt-names = "vdpu"; +- clocks = <&cru ACLK_VPU>, <&cru HCLK_VPU>; +- clock-names = "aclk", "hclk"; +- power-domains = <&power RK3328_PD_VPU>; +- iommus = <&vpu_mmu>; +- }; +diff --git a/Documentation/devicetree/bindings/media/rockchip-vpu.yaml b/Documentation/devicetree/bindings/media/rockchip-vpu.yaml +new file mode 100644 +index 000000000000..a0c45e05cf03 +--- /dev/null ++++ b/Documentation/devicetree/bindings/media/rockchip-vpu.yaml +@@ -0,0 +1,82 @@ ++# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) ++ ++%YAML 1.2 ++--- ++$id: "http://devicetree.org/schemas/media/rockchip-vpu.yaml#" ++$schema: "http://devicetree.org/meta-schemas/core.yaml#" ++ ++title: Hantro G1 VPU codecs implemented on Rockchip SoCs ++ ++maintainers: ++ - Ezequiel Garcia ++ ++description: ++ Hantro G1 video encode and decode accelerators present on Rockchip SoCs. ++ ++properties: ++ compatible: ++ enum: ++ - rockchip,rk3288-vpu ++ - rockchip,rk3328-vpu ++ - rockchip,rk3399-vpu ++ ++ reg: ++ maxItems: 1 ++ ++ interrupts: ++ maxItems: 2 ++ ++ interrupt-names: ++ items: ++ - const: vepu ++ - const: vdpu ++ ++ clocks: ++ maxItems: 2 ++ ++ clock-names: ++ items: ++ - const: aclk ++ - const: hclk ++ ++ power-domains: ++ maxItems: 1 ++ ++ iommus: ++ maxItems: 1 ++ ++required: ++ - compatible ++ - reg ++ - interrupts ++ - interrupt-names ++ - clocks ++ - clock-names ++ ++examples: ++ - | ++ #include ++ #include ++ ++ vpu: video-codec@ff9a0000 { ++ compatible = "rockchip,rk3288-vpu"; ++ reg = <0x0 0xff9a0000 0x0 0x800>; ++ interrupts = , ++ ; ++ interrupt-names = "vepu", "vdpu"; ++ clocks = <&cru ACLK_VCODEC>, <&cru HCLK_VCODEC>; ++ clock-names = "aclk", "hclk"; ++ power-domains = <&power RK3288_PD_VIDEO>; ++ iommus = <&vpu_mmu>; ++ }; ++ ++ vpu: video-codec@ff350000 { ++ compatible = "rockchip,rk3328-vpu"; ++ reg = <0x0 0xff350000 0x0 0x800>; ++ interrupts = ; ++ interrupt-names = "vdpu"; ++ clocks = <&cru ACLK_VPU>, <&cru HCLK_VPU>; ++ clock-names = "aclk", "hclk"; ++ power-domains = <&power RK3328_PD_VPU>; ++ iommus = <&vpu_mmu>; ++ }; +diff --git a/MAINTAINERS b/MAINTAINERS +index 0bff05c4c96d..ca95e804aae0 100644 +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -14319,7 +14319,7 @@ M: Ezequiel Garcia + L: linux-media@vger.kernel.org + S: Maintained + F: drivers/staging/media/hantro/ +-F: Documentation/devicetree/bindings/media/rockchip-vpu.txt ++F: Documentation/devicetree/bindings/media/rockchip-vpu.yaml + + ROCKER DRIVER + M: Jiri Pirko +-- +2.17.1 + + +From 1eba04297572f566a06ab9fe50f901640c77b091 Mon Sep 17 00:00:00 2001 +From: Ezequiel Garcia +Date: Wed, 18 Mar 2020 10:21:08 -0300 +Subject: [PATCH] hantro: Add linux-rockchip mailing list to MAINTAINERS + +The linux-rockchip mailing list is relevant for the +Hantro driver, given this support the VPU present +in Rockchip SoCs. + +Signed-off-by: Ezequiel Garcia +Reviewed-by: Heiko Stuebner +--- + MAINTAINERS | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/MAINTAINERS b/MAINTAINERS +index ca95e804aae0..47876afb9e26 100644 +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -14317,6 +14317,7 @@ F: Documentation/devicetree/bindings/media/rockchip-rga.txt + HANTRO VPU CODEC DRIVER + M: Ezequiel Garcia + L: linux-media@vger.kernel.org ++L: linux-rockchip@lists.infradead.org + S: Maintained + F: drivers/staging/media/hantro/ + F: Documentation/devicetree/bindings/media/rockchip-vpu.yaml +-- +2.17.1 + diff --git a/patch/kernel/rk322x-current/01-linux-1000-clk-rockchip-rk3228-fixup.patch b/patch/kernel/rk322x-current/01-linux-1000-clk-rockchip-rk3228-fixup.patch new file mode 100644 index 0000000000..21826f8565 --- /dev/null +++ b/patch/kernel/rk322x-current/01-linux-1000-clk-rockchip-rk3228-fixup.patch @@ -0,0 +1,98 @@ +diff --git a/drivers/clk/rockchip/clk-rk3228.c b/drivers/clk/rockchip/clk-rk3228.c +index 0127d702720c..6ef71ec239ae 100644 +--- a/drivers/clk/rockchip/clk-rk3228.c ++++ b/drivers/clk/rockchip/clk-rk3228.c +@@ -353,7 +353,7 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { + RK2928_CLKGATE_CON(10), 12, GFLAGS), + + COMPOSITE(SCLK_WIFI, "sclk_wifi", mux_pll_src_cpll_gpll_usb480m_p, 0, +- RK2928_CLKSEL_CON(23), 5, 2, MFLAGS, 0, 6, DFLAGS, ++ RK2928_CLKSEL_CON(23), 5, 2, MFLAGS, 0, 5, DFLAGS, + RK2928_CLKGATE_CON(2), 15, GFLAGS), + + COMPOSITE(SCLK_SDMMC, "sclk_sdmmc", mux_mmc_src_p, 0, +-- +2.17.1 + + +From 3acbbe5eb438e8b1061a803881579030d3c2b424 Mon Sep 17 00:00:00 2001 +From: Chen Lei +Date: Tue, 25 Dec 2018 18:29:04 +0800 +Subject: [PATCH] clk: rockchip: rk322x: fix wrong mmc phase shift for rk3228 + +mmc sample shift should be 1 for rk3228, or it will fail +if we enable mmc tuning for rk3228. + +Change-Id: I301c2a7d33de8d519d7c288aef03a82531016373 +Signed-off-by: Chen Lei +--- + drivers/clk/rockchip/clk-rk3228.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/clk/rockchip/clk-rk3228.c b/drivers/clk/rockchip/clk-rk3228.c +index 6ef71ec239ae..27adfca1a095 100644 +--- a/drivers/clk/rockchip/clk-rk3228.c ++++ b/drivers/clk/rockchip/clk-rk3228.c +@@ -610,13 +610,13 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { + + /* PD_MMC */ + MMC(SCLK_SDMMC_DRV, "sdmmc_drv", "sclk_sdmmc", RK3228_SDMMC_CON0, 1), +- MMC(SCLK_SDMMC_SAMPLE, "sdmmc_sample", "sclk_sdmmc", RK3228_SDMMC_CON1, 0), ++ MMC(SCLK_SDMMC_SAMPLE, "sdmmc_sample", "sclk_sdmmc", RK3228_SDMMC_CON1, 1), + + MMC(SCLK_SDIO_DRV, "sdio_drv", "sclk_sdio", RK3228_SDIO_CON0, 1), +- MMC(SCLK_SDIO_SAMPLE, "sdio_sample", "sclk_sdio", RK3228_SDIO_CON1, 0), ++ MMC(SCLK_SDIO_SAMPLE, "sdio_sample", "sclk_sdio", RK3228_SDIO_CON1, 1), + + MMC(SCLK_EMMC_DRV, "emmc_drv", "sclk_emmc", RK3228_EMMC_CON0, 1), +- MMC(SCLK_EMMC_SAMPLE, "emmc_sample", "sclk_emmc", RK3228_EMMC_CON1, 0), ++ MMC(SCLK_EMMC_SAMPLE, "emmc_sample", "sclk_emmc", RK3228_EMMC_CON1, 1), + }; + + static const char *const rk3228_critical_clocks[] __initconst = { +-- +2.17.1 + + +From a692001c1249473bdfe975ef53d2bdb8a4df736d Mon Sep 17 00:00:00 2001 +From: Finley Xiao +Date: Mon, 5 Feb 2018 10:04:15 +0800 +Subject: [PATCH] clk: rockchip: rk3228: Fix armclk parent + +Change-Id: I09830d96b37cca600f1782b9013b25e043467f97 +Signed-off-by: Finley Xiao +--- + drivers/clk/rockchip/clk-rk3228.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/drivers/clk/rockchip/clk-rk3228.c b/drivers/clk/rockchip/clk-rk3228.c +index 58292f80ad66..fba513de94eb 100644 +--- a/drivers/clk/rockchip/clk-rk3228.c ++++ b/drivers/clk/rockchip/clk-rk3228.c +@@ -170,7 +170,7 @@ static struct rockchip_pll_clock rk3228_pll_clks[] __initdata = { + [cpll] = PLL(pll_rk3036, PLL_CPLL, "cpll", mux_pll_p, 0, RK2928_PLL_CON(6), + RK2928_MODE_CON, 8, 8, 0, NULL), + [gpll] = PLL(pll_rk3036, PLL_GPLL, "gpll", mux_pll_p, 0, RK2928_PLL_CON(9), +- RK2928_MODE_CON, 12, 9, ROCKCHIP_PLL_SYNC_RATE, rk3228_pll_rates), ++ RK2928_MODE_CON, 12, 9, 0, rk3228_pll_rates), + }; + + #define MFLAGS CLK_MUX_HIWORD_MASK +-- +2.17.1 + + +From f57d5061e7357a8f7a181517530658a223ba415b Mon Sep 17 00:00:00 2001 +From: Finley Xiao +Date: Thu, 22 Jun 2017 19:53:46 +0800 +Subject: [PATCH] clk: rockchip: rk3228: fix gpu gate-register + +Fix a typo making the aclk_gpu and aclk_gpu_noc access a wrong register to +handle its gate. + +Change-Id: Ie0bac8014363af7c0409b8a56eacf2e858818843 +Signed-off-by: Finley Xiao +--- + drivers/clk/rockchip/clk-rk3228.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + diff --git a/patch/kernel/rk322x-current/01-linux-1001-clk-rockchip-rk3228-more-fixes.patch b/patch/kernel/rk322x-current/01-linux-1001-clk-rockchip-rk3228-more-fixes.patch new file mode 100644 index 0000000000..024940cd36 --- /dev/null +++ b/patch/kernel/rk322x-current/01-linux-1001-clk-rockchip-rk3228-more-fixes.patch @@ -0,0 +1,219 @@ +diff --git a/drivers/clk/rockchip/clk-rk3228.c b/drivers/clk/rockchip/clk-rk3228.c +index 448b202bf4f3..828d0003a18e 100644 +--- a/drivers/clk/rockchip/clk-rk3228.c ++++ b/drivers/clk/rockchip/clk-rk3228.c +@@ -510,12 +510,12 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { + + /* PD_VOP */ + GATE(ACLK_RGA, "aclk_rga", "aclk_rga_pre", 0, RK2928_CLKGATE_CON(13), 0, GFLAGS), +- GATE(0, "aclk_rga_noc", "aclk_rga_pre", 0, RK2928_CLKGATE_CON(13), 11, GFLAGS), ++ GATE(0, "aclk_rga_noc", "aclk_rga_pre", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(13), 11, GFLAGS), + GATE(ACLK_IEP, "aclk_iep", "aclk_iep_pre", 0, RK2928_CLKGATE_CON(13), 2, GFLAGS), +- GATE(0, "aclk_iep_noc", "aclk_iep_pre", 0, RK2928_CLKGATE_CON(13), 9, GFLAGS), ++ GATE(0, "aclk_iep_noc", "aclk_iep_pre", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(13), 9, GFLAGS), + + GATE(ACLK_VOP, "aclk_vop", "aclk_vop_pre", 0, RK2928_CLKGATE_CON(13), 5, GFLAGS), +- GATE(0, "aclk_vop_noc", "aclk_vop_pre", 0, RK2928_CLKGATE_CON(13), 12, GFLAGS), ++ GATE(0, "aclk_vop_noc", "aclk_vop_pre", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(13), 12, GFLAGS), + + GATE(ACLK_HDCP, "aclk_hdcp", "aclk_hdcp_pre", 0, RK2928_CLKGATE_CON(14), 10, GFLAGS), + GATE(0, "aclk_hdcp_noc", "aclk_hdcp_pre", 0, RK2928_CLKGATE_CON(13), 10, GFLAGS), +@@ -523,13 +523,13 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { + GATE(HCLK_RGA, "hclk_rga", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(13), 1, GFLAGS), + GATE(HCLK_IEP, "hclk_iep", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(13), 3, GFLAGS), + GATE(HCLK_VOP, "hclk_vop", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(13), 6, GFLAGS), +- GATE(0, "hclk_vio_ahb_arbi", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(13), 7, GFLAGS), +- GATE(0, "hclk_vio_noc", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(13), 8, GFLAGS), +- GATE(0, "hclk_vop_noc", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(13), 13, GFLAGS), +- GATE(HCLK_VIO_H2P, "hclk_vio_h2p", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(14), 7, GFLAGS), ++ GATE(0, "hclk_vio_ahb_arbi", "hclk_vio_pre", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(13), 7, GFLAGS), ++ GATE(0, "hclk_vio_noc", "hclk_vio_pre", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(13), 8, GFLAGS), ++ GATE(0, "hclk_vop_noc", "hclk_vio_pre", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(13), 13, GFLAGS), ++ GATE(HCLK_VIO_H2P, "hclk_vio_h2p", "hclk_vio_pre", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(14), 7, GFLAGS), + GATE(HCLK_HDCP_MMU, "hclk_hdcp_mmu", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(14), 12, GFLAGS), + GATE(PCLK_HDMI_CTRL, "pclk_hdmi_ctrl", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(14), 6, GFLAGS), +- GATE(PCLK_VIO_H2P, "pclk_vio_h2p", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(14), 8, GFLAGS), ++ GATE(PCLK_VIO_H2P, "pclk_vio_h2p", "hclk_vio_pre", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(14), 8, GFLAGS), + GATE(PCLK_HDCP, "pclk_hdcp", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(14), 11, GFLAGS), + + /* PD_PERI */ +@@ -541,13 +541,13 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { + GATE(HCLK_EMMC, "hclk_emmc", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 2, GFLAGS), + GATE(HCLK_NANDC, "hclk_nandc", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 3, GFLAGS), + GATE(HCLK_HOST0, "hclk_host0", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 6, GFLAGS), +- GATE(0, "hclk_host0_arb", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 7, GFLAGS), ++ GATE(0, "hclk_host0_arb", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(11), 7, GFLAGS), + GATE(HCLK_HOST1, "hclk_host1", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 8, GFLAGS), +- GATE(0, "hclk_host1_arb", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 9, GFLAGS), ++ GATE(0, "hclk_host1_arb", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(11), 9, GFLAGS), + GATE(HCLK_HOST2, "hclk_host2", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 10, GFLAGS), + GATE(HCLK_OTG, "hclk_otg", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 12, GFLAGS), +- GATE(0, "hclk_otg_pmu", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 13, GFLAGS), +- GATE(0, "hclk_host2_arb", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 14, GFLAGS), ++ GATE(0, "hclk_otg_pmu", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(11), 13, GFLAGS), ++ GATE(0, "hclk_host2_arb", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(11), 14, GFLAGS), + GATE(0, "hclk_peri_noc", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(12), 1, GFLAGS), + + GATE(PCLK_GMAC, "pclk_gmac", "pclk_peri", 0, RK2928_CLKGATE_CON(11), 5, GFLAGS), +@@ -555,15 +555,15 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { + + /* PD_GPU */ + GATE(ACLK_GPU, "aclk_gpu", "aclk_gpu_pre", 0, RK2928_CLKGATE_CON(7), 14, GFLAGS), +- GATE(0, "aclk_gpu_noc", "aclk_gpu_pre", 0, RK2928_CLKGATE_CON(7), 15, GFLAGS), ++ GATE(0, "aclk_gpu_noc", "aclk_gpu_pre", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(7), 15, GFLAGS), + + /* PD_BUS */ +- GATE(0, "sclk_initmem_mbist", "aclk_cpu", 0, RK2928_CLKGATE_CON(8), 1, GFLAGS), +- GATE(0, "aclk_initmem", "aclk_cpu", 0, RK2928_CLKGATE_CON(8), 0, GFLAGS), ++ GATE(0, "sclk_initmem_mbist", "aclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(8), 1, GFLAGS), ++ GATE(0, "aclk_initmem", "aclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(8), 0, GFLAGS), + GATE(ACLK_DMAC, "aclk_dmac_bus", "aclk_cpu", 0, RK2928_CLKGATE_CON(8), 2, GFLAGS), + GATE(0, "aclk_bus_noc", "aclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(10), 1, GFLAGS), + +- GATE(0, "hclk_rom", "hclk_cpu", 0, RK2928_CLKGATE_CON(8), 3, GFLAGS), ++ GATE(0, "hclk_rom", "hclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(8), 3, GFLAGS), + GATE(HCLK_I2S0_8CH, "hclk_i2s0_8ch", "hclk_cpu", 0, RK2928_CLKGATE_CON(8), 7, GFLAGS), + GATE(HCLK_I2S1_8CH, "hclk_i2s1_8ch", "hclk_cpu", 0, RK2928_CLKGATE_CON(8), 8, GFLAGS), + GATE(HCLK_I2S2_2CH, "hclk_i2s2_2ch", "hclk_cpu", 0, RK2928_CLKGATE_CON(8), 9, GFLAGS), +@@ -572,9 +572,9 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { + GATE(HCLK_M_CRYPTO, "hclk_crypto_mst", "hclk_cpu", 0, RK2928_CLKGATE_CON(8), 11, GFLAGS), + GATE(HCLK_S_CRYPTO, "hclk_crypto_slv", "hclk_cpu", 0, RK2928_CLKGATE_CON(8), 12, GFLAGS), + +- GATE(0, "pclk_ddrupctl", "pclk_ddr_pre", 0, RK2928_CLKGATE_CON(8), 4, GFLAGS), +- GATE(0, "pclk_ddrmon", "pclk_ddr_pre", 0, RK2928_CLKGATE_CON(8), 6, GFLAGS), +- GATE(0, "pclk_msch_noc", "pclk_ddr_pre", 0, RK2928_CLKGATE_CON(10), 2, GFLAGS), ++ GATE(0, "pclk_ddrupctl", "pclk_ddr_pre", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(8), 4, GFLAGS), ++ GATE(0, "pclk_ddrmon", "pclk_ddr_pre", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(8), 6, GFLAGS), ++ GATE(0, "pclk_msch_noc", "pclk_ddr_pre", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(10), 2, GFLAGS), + + GATE(PCLK_EFUSE_1024, "pclk_efuse_1024", "pclk_cpu", 0, RK2928_CLKGATE_CON(8), 13, GFLAGS), + GATE(PCLK_EFUSE_256, "pclk_efuse_256", "pclk_cpu", 0, RK2928_CLKGATE_CON(8), 14, GFLAGS), +@@ -583,7 +583,7 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { + GATE(PCLK_I2C2, "pclk_i2c2", "pclk_cpu", 0, RK2928_CLKGATE_CON(9), 1, GFLAGS), + GATE(PCLK_I2C3, "pclk_i2c3", "pclk_cpu", 0, RK2928_CLKGATE_CON(9), 2, GFLAGS), + GATE(PCLK_TIMER, "pclk_timer0", "pclk_cpu", 0, RK2928_CLKGATE_CON(9), 4, GFLAGS), +- GATE(0, "pclk_stimer", "pclk_cpu", 0, RK2928_CLKGATE_CON(9), 5, GFLAGS), ++ GATE(0, "pclk_stimer", "pclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(9), 5, GFLAGS), + GATE(PCLK_SPI0, "pclk_spi0", "pclk_cpu", 0, RK2928_CLKGATE_CON(9), 6, GFLAGS), + GATE(PCLK_PWM, "pclk_rk_pwm", "pclk_cpu", 0, RK2928_CLKGATE_CON(9), 7, GFLAGS), + GATE(PCLK_GPIO0, "pclk_gpio0", "pclk_cpu", 0, RK2928_CLKGATE_CON(9), 8, GFLAGS), +@@ -597,22 +597,22 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { + GATE(PCLK_GRF, "pclk_grf", "pclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(10), 0, GFLAGS), + GATE(0, "pclk_cru", "pclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(10), 1, GFLAGS), + GATE(0, "pclk_sgrf", "pclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(10), 2, GFLAGS), +- GATE(0, "pclk_sim", "pclk_cpu", 0, RK2928_CLKGATE_CON(10), 3, GFLAGS), ++ GATE(0, "pclk_sim", "pclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(10), 3, GFLAGS), + +- GATE(0, "pclk_ddrphy", "pclk_phy_pre", 0, RK2928_CLKGATE_CON(10), 3, GFLAGS), +- GATE(0, "pclk_acodecphy", "pclk_phy_pre", 0, RK2928_CLKGATE_CON(10), 5, GFLAGS), ++ GATE(0, "pclk_ddrphy", "pclk_phy_pre", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(10), 3, GFLAGS), ++ GATE(PCLK_ACODECPHY, "pclk_acodecphy", "pclk_phy_pre", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(10), 5, GFLAGS), + GATE(PCLK_HDMI_PHY, "pclk_hdmiphy", "pclk_phy_pre", 0, RK2928_CLKGATE_CON(10), 7, GFLAGS), +- GATE(0, "pclk_vdacphy", "pclk_phy_pre", 0, RK2928_CLKGATE_CON(10), 8, GFLAGS), +- GATE(0, "pclk_phy_noc", "pclk_phy_pre", 0, RK2928_CLKGATE_CON(10), 9, GFLAGS), ++ GATE(0, "pclk_vdacphy", "pclk_phy_pre", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(10), 8, GFLAGS), ++ GATE(0, "pclk_phy_noc", "pclk_phy_pre", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(10), 9, GFLAGS), + + GATE(ACLK_VPU, "aclk_vpu", "aclk_vpu_pre", 0, RK2928_CLKGATE_CON(15), 0, GFLAGS), +- GATE(0, "aclk_vpu_noc", "aclk_vpu_pre", 0, RK2928_CLKGATE_CON(15), 4, GFLAGS), ++ GATE(0, "aclk_vpu_noc", "aclk_vpu_pre", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(15), 4, GFLAGS), + GATE(ACLK_RKVDEC, "aclk_rkvdec", "aclk_rkvdec_pre", 0, RK2928_CLKGATE_CON(15), 2, GFLAGS), +- GATE(0, "aclk_rkvdec_noc", "aclk_rkvdec_pre", 0, RK2928_CLKGATE_CON(15), 6, GFLAGS), ++ GATE(0, "aclk_rkvdec_noc", "aclk_rkvdec_pre", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(15), 6, GFLAGS), + GATE(HCLK_VPU, "hclk_vpu", "hclk_vpu_pre", 0, RK2928_CLKGATE_CON(15), 1, GFLAGS), +- GATE(0, "hclk_vpu_noc", "hclk_vpu_pre", 0, RK2928_CLKGATE_CON(15), 5, GFLAGS), ++ GATE(0, "hclk_vpu_noc", "hclk_vpu_pre", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(15), 5, GFLAGS), + GATE(HCLK_RKVDEC, "hclk_rkvdec", "hclk_rkvdec_pre", 0, RK2928_CLKGATE_CON(15), 3, GFLAGS), +- GATE(0, "hclk_rkvdec_noc", "hclk_rkvdec_pre", 0, RK2928_CLKGATE_CON(15), 7, GFLAGS), ++ GATE(0, "hclk_rkvdec_noc", "hclk_rkvdec_pre", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(15), 7, GFLAGS), + + /* PD_MMC */ + MMC(SCLK_SDMMC_DRV, "sdmmc_drv", "sclk_sdmmc", RK3228_SDMMC_CON0, 1), +@@ -656,25 +656,34 @@ static const char *const rk3228_critical_clocks[] __initconst = { + "pclk_phy_noc", + "aclk_vpu_noc", + "aclk_rkvdec_noc", ++ "aclk_rkvdec", + "hclk_vpu_noc", + "hclk_rkvdec_noc", ++ "hclk_rkvdec", + }; + ++static void __iomem *rk3228_cru_base; ++ ++static void rk3228_clk_shutdown(void) ++{ ++ writel_relaxed(0x11010000, rk3228_cru_base + RK3228_MODE_CON); ++} ++ + static void __init rk3228_clk_init(struct device_node *np) + { + struct rockchip_clk_provider *ctx; +- void __iomem *reg_base; + +- reg_base = of_iomap(np, 0); +- if (!reg_base) { ++ rk3228_cru_base = of_iomap(np, 0); ++ ++ if (!rk3228_cru_base) { + pr_err("%s: could not map cru region\n", __func__); + return; + } + +- ctx = rockchip_clk_init(np, reg_base, CLK_NR_CLKS); ++ ctx = rockchip_clk_init(np, rk3228_cru_base, CLK_NR_CLKS); + if (IS_ERR(ctx)) { + pr_err("%s: rockchip clk init failed\n", __func__); +- iounmap(reg_base); ++ iounmap(rk3228_cru_base); + return; + } + +@@ -691,10 +700,10 @@ static void __init rk3228_clk_init(struct device_node *np) + &rk3228_cpuclk_data, rk3228_cpuclk_rates, + ARRAY_SIZE(rk3228_cpuclk_rates)); + +- rockchip_register_softrst(np, 9, reg_base + RK2928_SOFTRST_CON(0), ++ rockchip_register_softrst(np, 9, rk3228_cru_base + RK2928_SOFTRST_CON(0), + ROCKCHIP_SOFTRST_HIWORD_MASK); + +- rockchip_register_restart_notifier(ctx, RK3228_GLB_SRST_FST, NULL); ++ rockchip_register_restart_notifier(ctx, RK3228_GLB_SRST_FST, rk3228_clk_shutdown); + + rockchip_clk_of_add_provider(np, ctx); + } +diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h +index 2271a84124b0..f2f80f224f30 100644 +--- a/drivers/clk/rockchip/clk.h ++++ b/drivers/clk/rockchip/clk.h +@@ -134,6 +134,7 @@ struct clk; + #define RK3308_EMMC_CON0 0x490 + #define RK3308_EMMC_CON1 0x494 + ++#define RK3228_MODE_CON 0x40 + #define RK3328_PLL_CON(x) RK2928_PLL_CON(x) + #define RK3328_CLKSEL_CON(x) ((x) * 0x4 + 0x100) + #define RK3328_CLKGATE_CON(x) ((x) * 0x4 + 0x200) +diff --git a/include/dt-bindings/clock/rk3228-cru.h b/include/dt-bindings/clock/rk3228-cru.h +index de550ea56eeb..16e1feae5ce4 100644 +--- a/include/dt-bindings/clock/rk3228-cru.h ++++ b/include/dt-bindings/clock/rk3228-cru.h +@@ -65,6 +65,7 @@ + #define SCLK_OTGPHY0 142 + #define SCLK_OTGPHY1 143 + #define SCLK_HDMI_PHY 144 ++#define SCLK_DDRC 145 + + /* dclk gates */ + #define DCLK_VOP 190 +@@ -115,6 +116,7 @@ + #define PCLK_HDMI_CTRL 364 + #define PCLK_HDMI_PHY 365 + #define PCLK_GMAC 367 ++#define PCLK_ACODECPHY 368 + + /* hclk gates */ + #define HCLK_I2S0_8CH 442 +-- +2.17.1 + diff --git a/patch/kernel/rk322x-current/01-linux-1002-arm-dts-rk322x-dts.patch b/patch/kernel/rk322x-current/01-linux-1002-arm-dts-rk322x-dts.patch new file mode 100644 index 0000000000..f45654f096 --- /dev/null +++ b/patch/kernel/rk322x-current/01-linux-1002-arm-dts-rk322x-dts.patch @@ -0,0 +1,1532 @@ +diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile +index d6546d2676b9..26fbba6273ed 100644 +--- a/arch/arm/boot/dts/Makefile ++++ b/arch/arm/boot/dts/Makefile +@@ -938,6 +938,12 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += \ + rk3188-px3-evb.dtb \ + rk3188-radxarock.dtb \ + rk3228-evb.dtb \ ++ rk3228a-box.dtb \ ++ rk3228a-box-h96mini.dtb \ ++ rk3228a-box-nand.dtb \ ++ rk3229-box.dtb \ ++ rk3229-box-a95xr1.dtb \ ++ rk3229-box-nand.dtb \ + rk3229-evb.dtb \ + rk3229-xms6.dtb \ + rk3288-evb-act8846.dtb \ +diff --git a/arch/arm/boot/dts/rk3228a-box-h96mini.dts b/arch/arm/boot/dts/rk3228a-box-h96mini.dts +new file mode 100644 +index 000000000000..c624500d1470 +--- /dev/null ++++ b/arch/arm/boot/dts/rk3228a-box-h96mini.dts +@@ -0,0 +1,106 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++ ++/dts-v1/; ++#include ++#include ++#include "rk3228a-box.dtsi" ++ ++/ { ++ compatible = "eledvb,h96mini", "rockchip,rk3228a-box", "rockchip,rk3229"; ++ model = "Rockchip RK3228A Box H96 mini"; ++ ++ leds { ++ compatible = "gpio-leds"; ++ ++ led_green { ++ gpios = <&gpio3 RK_PC5 GPIO_ACTIVE_HIGH>; ++ default-state = "on"; ++ }; ++ ++ led_red { ++ gpios = <&gpio0 RK_PB0 GPIO_ACTIVE_HIGH>; ++ default-state = "off"; ++ }; ++ }; ++ ++}; ++ ++&emmc { ++ mmc-hs200-1_8v; ++ status = "okay"; ++}; ++ ++&gmac { ++ tx_delay = <0x26>; ++ rx_delay = <0x11>; ++}; ++ ++&ir_receiver { ++ status = "okay"; ++}; ++ ++&pinctrl { ++ wifi { ++ wifi_host_wake_l: wifi-host-wake-l { ++ rockchip,pins = <0 RK_PD4 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ bt { ++ bt_host_wake_l: bt-host-wake-l { ++ rockchip,pins = <3 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ ++ bt_reg_on_h: bt-reg-on-h { ++ rockchip,pins = <2 RK_PD5 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ ++ bt_wake_l: bt-wake-l { ++ rockchip,pins = <3 RK_PD3 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++}; ++ ++&power_key { ++ status = "okay"; ++}; ++ ++&sdio { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ brcmf: wifi@1 { ++ compatible = "brcm,bcm4329-fmac"; ++ reg = <1>; ++ interrupt-parent = <&gpio0>; ++ interrupts = ; ++ interrupt-names = "host-wake"; ++ brcm,drive-strength = <5>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&wifi_host_wake_l>; ++ }; ++}; ++ ++&sdmmc { ++ disable-wp; ++ status = "okay"; ++}; ++ ++&uart1 { ++ status = "okay"; ++ ++ bluetooth { ++ compatible = "brcm,bcm4330-bt"; ++ host-wakeup-gpios = <&gpio3 RK_PD2 GPIO_ACTIVE_HIGH>; ++ device-wakeup-gpios = <&gpio3 RK_PD3 GPIO_ACTIVE_HIGH>; ++ shutdown-gpios = <&gpio2 RK_PD5 GPIO_ACTIVE_HIGH>; ++ max-speed = <4000000>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&bt_reg_on_h &bt_host_wake_l &bt_wake_l>; ++ }; ++}; ++ ++&usb_otg { ++ dr_mode = "host"; ++}; +diff --git a/arch/arm/boot/dts/rk3228a-box-nand.dts b/arch/arm/boot/dts/rk3228a-box-nand.dts +new file mode 100644 +index 000000000000..f3e5ab89462b +--- /dev/null ++++ b/arch/arm/boot/dts/rk3228a-box-nand.dts +@@ -0,0 +1,57 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++ ++/dts-v1/; ++#include "rk3228a-box.dtsi" ++ ++/ { ++ model = "Rockchip RK3228A Box"; ++ ++ leds { ++ compatible = "gpio-leds"; ++ ++ led_blue { ++ gpios = <&gpio3 RK_PC5 GPIO_ACTIVE_HIGH>; ++ default-state = "on"; ++ }; ++ ++ led_red { ++ gpios = <&gpio1 RK_PA7 GPIO_ACTIVE_HIGH>; ++ default-state = "off"; ++ }; ++ }; ++ ++}; ++ ++&ir_receiver { ++ status = "okay"; ++}; ++ ++&nfc { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ nand@0 { ++ reg = <0>; ++ nand-ecc-mode = "hw"; ++ nand-ecc-strength = <60>; ++ nand-ecc-step-size = <1024>; ++ nand-bus-width = <8>; ++ }; ++}; ++ ++&sdio { ++ status = "okay"; ++}; ++ ++&sdmmc { ++ status = "okay"; ++}; ++ ++&uart1 { ++ status = "okay"; ++}; ++ ++&usb_otg { ++ dr_mode = "host"; ++}; +diff --git a/arch/arm/boot/dts/rk3228a-box.dts b/arch/arm/boot/dts/rk3228a-box.dts +new file mode 100644 +index 000000000000..e68ef44b95c9 +--- /dev/null ++++ b/arch/arm/boot/dts/rk3228a-box.dts +@@ -0,0 +1,47 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++ ++/dts-v1/; ++#include "rk3228a-box.dtsi" ++ ++/ { ++ model = "Rockchip RK3228A Box"; ++ ++ leds { ++ compatible = "gpio-leds"; ++ ++ led_blue { ++ gpios = <&gpio3 RK_PC5 GPIO_ACTIVE_HIGH>; ++ default-state = "on"; ++ }; ++ ++ led_red { ++ gpios = <&gpio1 RK_PA7 GPIO_ACTIVE_HIGH>; ++ default-state = "off"; ++ }; ++ }; ++ ++}; ++ ++&emmc { ++ status = "okay"; ++}; ++ ++&ir_receiver { ++ status = "okay"; ++}; ++ ++&sdio { ++ status = "okay"; ++}; ++ ++&sdmmc { ++ status = "okay"; ++}; ++ ++&uart1 { ++ status = "okay"; ++}; ++ ++&usb_otg { ++ dr_mode = "host"; ++}; +diff --git a/arch/arm/boot/dts/rk3228a-box.dtsi b/arch/arm/boot/dts/rk3228a-box.dtsi +new file mode 100644 +index 000000000000..dbd5c5dc4491 +--- /dev/null ++++ b/arch/arm/boot/dts/rk3228a-box.dtsi +@@ -0,0 +1,12 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++ ++/dts-v1/; ++ ++#include "rk322x-box.dtsi" ++ ++/ { ++ ++ model = "Rockchip RK3228A Box"; ++ compatible = "rockchip,rk3228a-box", "rockchip,rk3229"; ++ ++}; +diff --git a/arch/arm/boot/dts/rk3229-box-a95xr1.dts b/arch/arm/boot/dts/rk3229-box-a95xr1.dts +new file mode 100644 +index 000000000000..b3695fb0b255 +--- /dev/null ++++ b/arch/arm/boot/dts/rk3229-box-a95xr1.dts +@@ -0,0 +1,57 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++ ++/dts-v1/; ++#include ++#include ++#include "rk3229-box.dtsi" ++ ++/ { ++ model = "Rockchip RK3229 Box A95X-R1"; ++ ++ leds { ++ compatible = "gpio-leds"; ++ ++ led_blue { ++ gpios = <&gpio3 RK_PC5 GPIO_ACTIVE_HIGH>; ++ default-state = "on"; ++ }; ++ ++ led_red { ++ gpios = <&gpio1 RK_PA7 GPIO_ACTIVE_HIGH>; ++ default-state = "off"; ++ linux,default-trigger = "rc-feedback"; ++ }; ++ }; ++ ++}; ++ ++&emmc { ++ mmc-hs200-1_8v; ++ status = "okay"; ++}; ++ ++&gmac { ++ tx_delay = <0x26>; ++ rx_delay = <0x11>; ++}; ++ ++&ir_receiver { ++ status = "okay"; ++}; ++ ++&power_key { ++ status = "okay"; ++}; ++ ++&sdio { ++ status = "okay"; ++}; ++ ++&sdmmc { ++ disable-wp; ++ status = "okay"; ++}; ++ ++&usb_otg { ++ dr_mode = "host"; ++}; +diff --git a/arch/arm/boot/dts/rk3229-box-nand.dts b/arch/arm/boot/dts/rk3229-box-nand.dts +new file mode 100644 +index 000000000000..5eca0f335c55 +--- /dev/null ++++ b/arch/arm/boot/dts/rk3229-box-nand.dts +@@ -0,0 +1,60 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++ ++/dts-v1/; ++#include "rk3229-box.dtsi" ++ ++/ { ++ model = "Rockchip RK3229 Box"; ++ ++ leds { ++ compatible = "gpio-leds"; ++ ++ led_green { ++ gpios = <&gpio3 RK_PC5 GPIO_ACTIVE_HIGH>; ++ default-state = "on"; ++ }; ++ ++ led_red { ++ gpios = <&gpio0 RK_PB0 GPIO_ACTIVE_HIGH>; ++ default-state = "off"; ++ }; ++ }; ++}; ++ ++&ir_receiver { ++ status = "okay"; ++}; ++ ++&nfc { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ nand@0 { ++ reg = <0>; ++ nand-ecc-mode = "hw"; ++ nand-ecc-strength = <60>; ++ nand-ecc-step-size = <1024>; ++ nand-bus-width = <8>; ++ }; ++}; ++ ++&power_key { ++ status = "okay"; ++}; ++ ++&sdio { ++ status = "okay"; ++}; ++ ++&sdmmc { ++ status = "okay"; ++}; ++ ++&uart1 { ++ status = "okay"; ++}; ++ ++&usb_otg { ++ dr_mode = "host"; ++}; +diff --git a/arch/arm/boot/dts/rk3229-box.dts b/arch/arm/boot/dts/rk3229-box.dts +new file mode 100644 +index 000000000000..b63e61cda257 +--- /dev/null ++++ b/arch/arm/boot/dts/rk3229-box.dts +@@ -0,0 +1,50 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++ ++/dts-v1/; ++#include "rk3229-box.dtsi" ++ ++/ { ++ model = "Rockchip RK3229 Box"; ++ ++ leds { ++ compatible = "gpio-leds"; ++ ++ led_green { ++ gpios = <&gpio3 RK_PC5 GPIO_ACTIVE_HIGH>; ++ default-state = "on"; ++ }; ++ ++ led_red { ++ gpios = <&gpio0 RK_PB0 GPIO_ACTIVE_HIGH>; ++ default-state = "off"; ++ }; ++ }; ++}; ++ ++&emmc { ++ status = "okay"; ++}; ++ ++&ir_receiver { ++ status = "okay"; ++}; ++ ++&power_key { ++ status = "okay"; ++}; ++ ++&sdio { ++ status = "okay"; ++}; ++ ++&sdmmc { ++ status = "okay"; ++}; ++ ++&uart1 { ++ status = "okay"; ++}; ++ ++&usb_otg { ++ dr_mode = "host"; ++}; +diff --git a/arch/arm/boot/dts/rk3229-box.dtsi b/arch/arm/boot/dts/rk3229-box.dtsi +new file mode 100644 +index 000000000000..79e2524e07f2 +--- /dev/null ++++ b/arch/arm/boot/dts/rk3229-box.dtsi +@@ -0,0 +1,21 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++ ++/dts-v1/; ++ ++#include "rk322x-box.dtsi" ++#include "rk3229-cpu-opp.dtsi" ++ ++/ { ++ ++ model = "Rockchip RK3229 Box"; ++ compatible = "rockchip,rk3229-box", "rockchip,rk3229"; ++ ++}; ++ ++&cpu0_opp_table { ++ ++ opp-1464000000 { ++ status = "disabled"; ++ }; ++ ++}; +diff --git a/arch/arm/boot/dts/rk3229-cpu-opp.dtsi b/arch/arm/boot/dts/rk3229-cpu-opp.dtsi +new file mode 100644 +index 000000000000..c1c7613bab11 +--- /dev/null ++++ b/arch/arm/boot/dts/rk3229-cpu-opp.dtsi +@@ -0,0 +1,50 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++/* ++ * Copyright (c) 2017 Fuzhou Rockchip Electronics Co., Ltd ++ */ ++ ++/ { ++ compatible = "rockchip,rk3229"; ++ ++ /delete-node/ opp-table0; ++ ++ cpu0_opp_table: opp_table0 { ++ compatible = "operating-points-v2"; ++ opp-shared; ++ ++ opp-408000000 { ++ opp-hz = /bits/ 64 <408000000>; ++ opp-microvolt = <950000 950000 1400000>; ++ clock-latency-ns = <40000>; ++ opp-suspend; ++ }; ++ opp-600000000 { ++ opp-hz = /bits/ 64 <600000000>; ++ opp-microvolt = <975000 975000 1400000>; ++ }; ++ opp-816000000 { ++ opp-hz = /bits/ 64 <816000000>; ++ opp-microvolt = <1000000 1000000 1400000>; ++ }; ++ opp-1008000000 { ++ opp-hz = /bits/ 64 <1008000000>; ++ opp-microvolt = <1175000 1175000 1400000>; ++ }; ++ opp-1200000000 { ++ opp-hz = /bits/ 64 <1200000000>; ++ opp-microvolt = <1275000 1275000 1400000>; ++ }; ++ opp-1296000000 { ++ opp-hz = /bits/ 64 <1296000000>; ++ opp-microvolt = <1325000 1325000 1400000>; ++ }; ++ opp-1392000000 { ++ opp-hz = /bits/ 64 <1392000000>; ++ opp-microvolt = <1350000 1350000 1400000>; ++ }; ++ opp-1464000000 { ++ opp-hz = /bits/ 64 <1464000000>; ++ opp-microvolt = <1400000 1400000 1400000>; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/rk322x-box.dtsi b/arch/arm/boot/dts/rk322x-box.dtsi +new file mode 100644 +index 000000000000..29df40f4fa63 +--- /dev/null ++++ b/arch/arm/boot/dts/rk322x-box.dtsi +@@ -0,0 +1,250 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++ ++/dts-v1/; ++ ++#include ++#include ++#include ++#include ++#include "rk322x-dcdc.dtsi" ++ ++/ { ++ model = "Rockchip RK322x Box"; ++ compatible = "rockchip,rk3229"; ++ ++ chosen { ++ bootargs = "earlyprintk=uart8250,mmio32,0x11030000"; ++ }; ++ ++ gpio_keys { ++ compatible = "gpio-keys"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ autorepeat; ++ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pwr_key>; ++ ++ power_key: power-key { ++ label = "GPIO Key Power"; ++ gpios = <&gpio3 RK_PD1 GPIO_ACTIVE_LOW>; ++ linux,code = ; ++ debounce-interval = <100>; ++ wakeup-source; ++ status = "disabled"; ++ }; ++ }; ++ ++ ir_receiver: ir-receiver { ++ compatible = "gpio-ir-receiver"; ++ gpios = <&gpio1 RK_PB3 GPIO_ACTIVE_LOW>; ++ pinctrl-0 = <&ir_int>; ++ pinctrl-names = "default"; ++ status = "disabled"; ++ }; ++ ++ memory@60000000 { ++ device_type = "memory"; ++ reg = <0x60000000 0x40000000>; ++ }; ++ ++ reserved-memory { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges; ++ ++ trust_reserved: trust@68400000 { ++ reg = <0x68400000 0xe00000>; ++ no-map; ++ }; ++ }; ++ ++ sdio_pwrseq: sdio-pwrseq { ++ compatible = "mmc-pwrseq-simple"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&wifi_enable_h>; ++ reset-gpios = <&gpio2 RK_PD2 GPIO_ACTIVE_LOW>; ++ }; ++ ++ timer { ++ arm,cpu-registers-not-fw-configured; ++ }; ++}; ++ ++&cpu_alert1 { ++ temperature = <105000>; ++}; ++ ++&cpu_crit { ++ temperature = <115000>; ++}; ++ ++&cpu_thermal { ++ cooling-maps { ++ /delete-node/ map0; ++ }; ++}; ++ ++&emmc { ++ cap-mmc-highspeed; ++ keep-power-in-suspend; ++ non-removable; ++}; ++ ++&gmac { ++ assigned-clocks = <&cru SCLK_MAC_SRC>; ++ assigned-clock-rates = <50000000>; ++ clock_in_out = "output"; ++ phy-handle = <&phy>; ++ phy-mode = "rmii"; ++ status = "okay"; ++ ++ mdio { ++ compatible = "snps,dwmac-mdio"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ phy: phy@0 { ++ compatible = "ethernet-phy-id1234.d400", ++ "ethernet-phy-ieee802.3-c22"; ++ reg = <0>; ++ clocks = <&cru SCLK_MAC_PHY>; ++ phy-is-integrated; ++ resets = <&cru SRST_MACPHY>; ++ }; ++ }; ++}; ++ ++&hdmi { ++ status = "okay"; ++}; ++ ++&hdmi_sound { ++ status = "okay"; ++}; ++ ++&hdmi_phy { ++ status = "okay"; ++}; ++ ++&i2s0 { ++ status = "okay"; ++}; ++ ++&pinctrl { ++ ++ ir { ++ ir_int: ir-int { ++ rockchip,pins = <1 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ keys { ++ pwr_key: pwr-key { ++ rockchip,pins = <3 RK_PC7 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ }; ++ ++ sdio-pwrseq { ++ wifi_enable_h: wifi-enable-h { ++ rockchip,pins = <2 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++}; ++ ++&rga { ++ status = "okay"; ++}; ++ ++&sdio { ++ mmc-pwrseq = <&sdio_pwrseq>; ++ cap-sd-highspeed; ++ cap-sdio-irq; ++ keep-power-in-suspend; ++ non-removable; ++ no-sd; ++}; ++ ++&sdmmc { ++ cap-sd-highspeed; ++ keep-power-in-suspend; ++ no-sdio; ++}; ++ ++&spdif { ++ status = "okay"; ++}; ++ ++&spdif_out { ++ status = "okay"; ++}; ++ ++&spdif_sound { ++ status = "okay"; ++}; ++ ++&tsadc { ++ rockchip,hw-tshut-mode = <0>; ++ rockchip,hw-tshut-polarity = <1>; ++ status = "okay"; ++}; ++ ++&u2phy0 { ++ status = "okay"; ++}; ++ ++&u2phy1 { ++ status = "okay"; ++}; ++ ++&uart1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart11_xfer &uart11_rts &uart11_cts>; ++}; ++ ++&uart2 { ++ status = "okay"; ++}; ++ ++&usb_host0_ehci { ++ status = "okay"; ++}; ++ ++&usb_host0_ohci { ++ status = "okay"; ++}; ++ ++&usb_host1_ehci { ++ status = "okay"; ++}; ++ ++&usb_host1_ohci { ++ status = "okay"; ++}; ++ ++&usb_host2_ehci { ++ status = "okay"; ++}; ++ ++&usb_host2_ohci { ++ status = "okay"; ++}; ++ ++&usb_otg { ++ status = "okay"; ++}; ++ ++&vop { ++ assigned-clocks = <&cru DCLK_VOP>; ++ assigned-clock-parents = <&cru SCLK_HDMI_PHY>; ++ status = "okay"; ++}; ++ ++&vop_mmu { ++ status = "okay"; ++}; ++ ++&wdt { ++ status = "okay"; ++}; +diff --git a/arch/arm/boot/dts/rk322x-dcdc.dtsi b/arch/arm/boot/dts/rk322x-dcdc.dtsi +new file mode 100644 +index 000000000000..6076cb1d0d0b +--- /dev/null ++++ b/arch/arm/boot/dts/rk322x-dcdc.dtsi +@@ -0,0 +1,164 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++ ++/dts-v1/; ++ ++#include ++#include ++#include "rk322x.dtsi" ++ ++/ { ++ ++ vcc_host: vcc-host-regulator { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpio = <&gpio3 RK_PC4 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&host_vbus_drv>; ++ regulator-name = "vcc_host"; ++ regulator-always-on; ++ regulator-boot-on; ++ vin-supply = <&vcc_sys>; ++ }; ++ ++ vccio_1v8: vccio-1v8-regulator { ++ compatible = "regulator-fixed"; ++ regulator-name = "vccio_1v8"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-always-on; ++ vin-supply = <&vcc_sys>; ++ }; ++ ++ vccio_3v3: vccio-3v3-regulator { ++ compatible = "regulator-fixed"; ++ regulator-name = "vccio_3v3"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-always-on; ++ vin-supply = <&vcc_sys>; ++ }; ++ ++ ++ vcc_otg: vcc-otg-regulator { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpio = <&gpio3 RK_PC6 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&otg_vbus_drv>; ++ regulator-name = "vcc_otg_vbus"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ regulator-always-on; ++ regulator-boot-on; ++ vin-supply = <&vcc_sys>; ++ }; ++ ++ vcc_phy: vcc-phy-regulator { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ regulator-name = "vcc_phy"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-always-on; ++ regulator-boot-on; ++ vin-supply = <&vccio_1v8>; ++ }; ++ ++ vcc_sys: vcc-sys-regulator { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc_sys"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ }; ++ ++ vdd_arm: vdd-arm-regulator { ++ compatible = "pwm-regulator"; ++ pwms = <&pwm1 0 5000 1>; ++ pwm-supply = <&vcc_sys>; ++ regulator-name = "vdd_arm"; ++ regulator-min-microvolt = <950000>; ++ regulator-max-microvolt = <1400000>; ++ regulator-ramp-delay = <12500>; ++ regulator-settling-time-up-us = <250>; ++ regulator-always-on; ++ regulator-boot-on; ++ }; ++ ++ vdd_log: vdd-log-regulator { ++ compatible = "pwm-regulator"; ++ pwms = <&pwm2 0 5000 1>; ++ pwm-supply = <&vcc_sys>; ++ regulator-name = "vdd_log"; ++ regulator-min-microvolt = <1000000>; ++ regulator-max-microvolt = <1300000>; ++ regulator-ramp-delay = <12500>; ++ regulator-settling-time-up-us = <250>; ++ regulator-always-on; ++ regulator-boot-on; ++ }; ++ ++}; ++ ++ ++&cpu0 { ++ cpu-supply = <&vdd_arm>; ++}; ++ ++&cpu1 { ++ cpu-supply = <&vdd_arm>; ++}; ++ ++&cpu2 { ++ cpu-supply = <&vdd_arm>; ++}; ++ ++&cpu3 { ++ cpu-supply = <&vdd_arm>; ++}; ++ ++&io_domains { ++ vccio1-supply = <&vccio_3v3>; ++ vccio2-supply = <&vccio_1v8>; ++ vccio4-supply = <&vccio_3v3>; ++ status = "okay"; ++}; ++ ++&gmac { ++ phy-supply = <&vcc_phy>; ++}; ++ ++&gpu { ++ mali-supply = <&vdd_log>; ++}; ++ ++&pwm1 { ++ pinctrl-0 = <&pwm1_pin_pull_down>; ++ status = "okay"; ++}; ++ ++&pwm2 { ++ pinctrl-0 = <&pwm2_pin_pull_up>; ++ status = "okay"; ++}; ++ ++&u2phy0 { ++ u2phy0_host: host-port { ++ phy-supply = <&vcc_host>; ++ }; ++ ++ u2phy0_otg: otg-port { ++ phy-supply = <&vcc_otg>; ++ }; ++}; ++ ++&u2phy1 { ++ u2phy1_host: host-port { ++ phy-supply = <&vcc_host>; ++ }; ++ ++ u2phy1_otg: otg-port { ++ phy-supply = <&vcc_otg>; ++ }; ++}; +diff --git a/arch/arm/boot/dts/rk322x.dtsi b/arch/arm/boot/dts/rk322x.dtsi +index eef2c44bdf69..f7a50b903a7d 100644 +--- a/arch/arm/boot/dts/rk322x.dtsi ++++ b/arch/arm/boot/dts/rk322x.dtsi +@@ -5,6 +5,8 @@ + #include + #include + #include ++#include ++#include + #include + + / { +@@ -14,6 +16,7 @@ + interrupt-parent = <&gic>; + + aliases { ++ ethernet0 = &gmac; + serial0 = &uart0; + serial1 = &uart1; + serial2 = &uart2; +@@ -73,25 +76,25 @@ + + opp-408000000 { + opp-hz = /bits/ 64 <408000000>; +- opp-microvolt = <950000>; ++ opp-microvolt = <950000 950000 1275000>; + clock-latency-ns = <40000>; + opp-suspend; + }; + opp-600000000 { + opp-hz = /bits/ 64 <600000000>; +- opp-microvolt = <975000>; ++ opp-microvolt = <975000 975000 1275000>; + }; + opp-816000000 { + opp-hz = /bits/ 64 <816000000>; +- opp-microvolt = <1000000>; ++ opp-microvolt = <1000000 1000000 1275000>; + }; + opp-1008000000 { + opp-hz = /bits/ 64 <1008000000>; +- opp-microvolt = <1175000>; ++ opp-microvolt = <1175000 1175000 1275000>; + }; + opp-1200000000 { + opp-hz = /bits/ 64 <1200000000>; +- opp-microvolt = <1275000>; ++ opp-microvolt = <1275000 1275000 1275000>; + }; + }; + +@@ -121,11 +124,52 @@ + interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>; + }; + ++ display_subsystem: display-subsystem { ++ compatible = "rockchip,display-subsystem"; ++ ports = <&vop_out>; ++ }; ++ ++ hdmi_sound: hdmi-sound { ++ compatible = "simple-audio-card"; ++ simple-audio-card,name = "HDMI"; ++ simple-audio-card,format = "i2s"; ++ simple-audio-card,mclk-fs = <128>; ++ status = "disabled"; ++ ++ simple-audio-card,cpu { ++ sound-dai = <&i2s0>; ++ }; ++ ++ simple-audio-card,codec { ++ sound-dai = <&hdmi>; ++ }; ++ }; ++ + psci { + compatible = "arm,psci-1.0", "arm,psci-0.2"; + method = "smc"; + }; + ++ spdif_out: spdif-out { ++ compatible = "linux,spdif-dit"; ++ #sound-dai-cells = <0>; ++ status = "disabled"; ++ }; ++ ++ spdif_sound: spdif-sound { ++ compatible = "simple-audio-card"; ++ simple-audio-card,name = "SPDIF"; ++ status = "disabled"; ++ ++ simple-audio-card,cpu { ++ sound-dai = <&spdif>; ++ }; ++ ++ simple-audio-card,codec { ++ sound-dai = <&spdif_out>; ++ }; ++ }; ++ + timer { + compatible = "arm,armv7-timer"; + arm,cpu-registers-not-fw-configured; +@@ -143,17 +187,13 @@ + #clock-cells = <0>; + }; + +- display_subsystem: display-subsystem { +- compatible = "rockchip,display-subsystem"; +- ports = <&vop_out>; +- }; +- + i2s1: i2s1@100b0000 { + compatible = "rockchip,rk3228-i2s", "rockchip,rk3066-i2s"; + reg = <0x100b0000 0x4000>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; ++ #sound-dai-cells = <0>; + clock-names = "i2s_clk", "i2s_hclk"; + clocks = <&cru SCLK_I2S1>, <&cru HCLK_I2S1_8CH>; + dmas = <&pdma 14>, <&pdma 15>; +@@ -169,6 +209,7 @@ + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; ++ #sound-dai-cells = <0>; + clock-names = "i2s_clk", "i2s_hclk"; + clocks = <&cru SCLK_I2S0>, <&cru HCLK_I2S0_8CH>; + dmas = <&pdma 11>, <&pdma 12>; +@@ -186,6 +227,7 @@ + dma-names = "tx"; + pinctrl-names = "default"; + pinctrl-0 = <&spdif_tx>; ++ #sound-dai-cells = <0>; + status = "disabled"; + }; + +@@ -213,6 +255,43 @@ + status = "disabled"; + }; + ++ power: power-controller { ++ compatible = "rockchip,rk3228-power-controller"; ++ #power-domain-cells = <1>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ pd_gpu@RK3228_PD_GPU { ++ reg = ; ++ clocks = <&cru ACLK_GPU>; ++ pm_qos = <&qos_gpu>; ++ }; ++ ++ pd_vpu@RK3228_PD_VPU { ++ reg = ; ++ clocks = <&cru ACLK_VPU>, <&cru HCLK_VPU>; ++ pm_qos = <&qos_vpu>; ++ }; ++ ++ pd_rkvdec@RK3228_PD_RKVDEC { ++ reg = ; ++ clocks = <&cru ACLK_RKVDEC>, ++ <&cru HCLK_RKVDEC>, ++ <&cru SCLK_VDEC_CABAC>, ++ <&cru SCLK_VDEC_CORE>; ++ pm_qos = <&qos_rkvdec_r>, <&qos_rkvdec_w>; ++ }; ++ }; ++ ++ reboot_mode: reboot-mode { ++ compatible = "syscon-reboot-mode"; ++ offset = <0x5c8>; ++ mode-normal = ; ++ mode-recovery = ; ++ mode-bootloader = ; ++ mode-loader = ; ++ }; ++ + u2phy0: usb2-phy@760 { + compatible = "rockchip,rk3228-usb2phy"; + reg = <0x0760 0x0c>; +@@ -263,6 +342,7 @@ + status = "disabled"; + }; + }; ++ + }; + + uart0: serial@11010000 { +@@ -301,7 +381,7 @@ + clocks = <&cru SCLK_UART2>, <&cru PCLK_UART2>; + clock-names = "baudclk", "apb_pclk"; + pinctrl-names = "default"; +- pinctrl-0 = <&uart2_xfer>; ++ pinctrl-0 = <&uart21_xfer>; + reg-shift = <2>; + reg-io-width = <4>; + status = "disabled"; +@@ -460,13 +540,13 @@ + <&cru PLL_CPLL>, <&cru ACLK_PERI>, + <&cru HCLK_PERI>, <&cru PCLK_PERI>, + <&cru ACLK_CPU>, <&cru HCLK_CPU>, +- <&cru PCLK_CPU>; ++ <&cru PCLK_CPU>, <&cru ACLK_VOP>; + assigned-clock-rates = +- <594000000>, <816000000>, ++ <1200000000>, <816000000>, + <500000000>, <150000000>, + <150000000>, <75000000>, + <150000000>, <150000000>, +- <75000000>; ++ <75000000>, <400000000>; + }; + + thermal-zones { +@@ -511,6 +591,12 @@ + <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; ++ ++ map2 { ++ trip = <&cpu_alert1>; ++ cooling-device = ++ <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; ++ }; + }; + }; + }; +@@ -529,8 +615,9 @@ + pinctrl-0 = <&otp_gpio>; + pinctrl-1 = <&otp_out>; + pinctrl-2 = <&otp_gpio>; ++ rockchip,grf = <&grf>; ++ rockchip,hw-tshut-temp = <120000>; + #thermal-sensor-cells = <0>; +- rockchip,hw-tshut-temp = <95000>; + status = "disabled"; + }; + +@@ -560,10 +647,33 @@ + "ppmmu0", + "pp1", + "ppmmu1"; ++ assigned-clocks = <&cru ACLK_GPU>; ++ assigned-clock-rates = <300000000>; + clocks = <&cru ACLK_GPU>, <&cru ACLK_GPU>; + clock-names = "bus", "core"; ++ operating-points-v2 = <&gpu_opp_table>; ++ #cooling-cells = <2>; /* min followed by max */ ++ power-domains = <&power RK3228_PD_GPU>; + resets = <&cru SRST_GPU_A>; +- status = "disabled"; ++ }; ++ ++ gpu_opp_table: opp-table2 { ++ compatible = "operating-points-v2"; ++ ++ opp-200000000 { ++ opp-hz = /bits/ 64 <200000000>; ++ opp-microvolt = <1050000>; ++ }; ++ ++ opp-300000000 { ++ opp-hz = /bits/ 64 <300000000>; ++ opp-microvolt = <1050000>; ++ }; ++ ++ opp-500000000 { ++ opp-hz = /bits/ 64 <500000000>; ++ opp-microvolt = <1150000>; ++ }; + }; + + vpu_mmu: iommu@20020800 { +@@ -573,8 +683,8 @@ + interrupt-names = "vpu_mmu"; + clocks = <&cru ACLK_VPU>, <&cru HCLK_VPU>; + clock-names = "aclk", "iface"; +- iommu-cells = <0>; +- status = "disabled"; ++ power-domains = <&power RK3228_PD_VPU>; ++ #iommu-cells = <0>; + }; + + vdec_mmu: iommu@20030480 { +@@ -584,8 +694,8 @@ + interrupt-names = "vdec_mmu"; + clocks = <&cru ACLK_RKVDEC>, <&cru HCLK_RKVDEC>; + clock-names = "aclk", "iface"; +- iommu-cells = <0>; +- status = "disabled"; ++ power-domains = <&power RK3228_PD_RKVDEC>; ++ #iommu-cells = <0>; + }; + + vop: vop@20050000 { +@@ -639,7 +749,7 @@ + interrupt-names = "iep_mmu"; + clocks = <&cru ACLK_IEP>, <&cru HCLK_IEP>; + clock-names = "aclk", "iface"; +- iommu-cells = <0>; ++ #iommu-cells = <0>; + status = "disabled"; + }; + +@@ -659,6 +769,7 @@ + phys = <&hdmi_phy>; + phy-names = "hdmi"; + rockchip,grf = <&grf>; ++ #sound-dai-cells = <0>; + status = "disabled"; + + ports { +@@ -680,9 +791,13 @@ + clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>, + <&cru SCLK_SDMMC_DRV>, <&cru SCLK_SDMMC_SAMPLE>; + clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; ++ bus-width = <4>; + fifo-depth = <0x100>; ++ max-frequency = <150000000>; + pinctrl-names = "default"; +- pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_bus4>; ++ pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_bus4 &sdmmc_pwr>; ++ resets = <&cru SRST_SDMMC>; ++ reset-names = "reset"; + status = "disabled"; + }; + +@@ -692,10 +807,14 @@ + interrupts = ; + clocks = <&cru HCLK_SDIO>, <&cru SCLK_SDIO>, + <&cru SCLK_SDIO_DRV>, <&cru SCLK_SDIO_SAMPLE>; ++ bus-width = <4>; + clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; + fifo-depth = <0x100>; ++ max-frequency = <150000000>; + pinctrl-names = "default"; + pinctrl-0 = <&sdio_clk &sdio_cmd &sdio_bus4>; ++ resets = <&cru SRST_SDIO>; ++ reset-names = "reset"; + status = "disabled"; + }; + +@@ -703,14 +822,13 @@ + compatible = "rockchip,rk3228-dw-mshc", "rockchip,rk3288-dw-mshc"; + reg = <0x30020000 0x4000>; + interrupts = ; +- clock-frequency = <37500000>; +- max-frequency = <37500000>; + clocks = <&cru HCLK_EMMC>, <&cru SCLK_EMMC>, + <&cru SCLK_EMMC_DRV>, <&cru SCLK_EMMC_SAMPLE>; + clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; + bus-width = <8>; + default-sample-phase = <158>; + fifo-depth = <0x100>; ++ max-frequency = <150000000>; + pinctrl-names = "default"; + pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>; + resets = <&cru SRST_EMMC>; +@@ -718,6 +836,22 @@ + status = "disabled"; + }; + ++ nfc: nand-controller@ff4b0000 { ++ compatible = "rockchip,rk3228_nfc"; ++ reg = <0x30030000 0x4000>; ++ interrupts = ; ++ clocks = <&cru SCLK_NANDC>, <&cru HCLK_NANDC>; ++ clock-names = "nfc", "ahb"; ++ assigned-clocks = <&cru SCLK_NANDC>; ++ assigned-clock-rates = <150000000>; ++ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&flash_cs0 &flash_rdy &flash_ale &flash_cle ++ &flash_wrn &flash_rdn &flash_bus8>; ++ status = "disabled"; ++ ++ }; ++ + usb_otg: usb@30040000 { + compatible = "rockchip,rk3228-usb", "rockchip,rk3066-usb", + "snps,dwc2"; +@@ -820,6 +954,26 @@ + status = "disabled"; + }; + ++ qos_vpu: qos@31040000 { ++ compatible = "syscon"; ++ reg = <0x31040000 0x20>; ++ }; ++ ++ qos_gpu: qos@31050000 { ++ compatible = "syscon"; ++ reg = <0x31050000 0x20>; ++ }; ++ ++ qos_rkvdec_r: qos@31070000 { ++ compatible = "syscon"; ++ reg = <0x31070000 0x20>; ++ }; ++ ++ qos_rkvdec_w: qos@31070080 { ++ compatible = "syscon"; ++ reg = <0x31070080 0x20>; ++ }; ++ + gic: interrupt-controller@32010000 { + compatible = "arm,gic-400"; + interrupt-controller; +@@ -908,6 +1062,11 @@ + drive-strength = <12>; + }; + ++ pcfg_pull_up_12ma: pcfg-pull-up-12ma { ++ bias-pull-up; ++ drive-strength = <12>; ++ }; ++ + sdmmc { + sdmmc_clk: sdmmc-clk { + rockchip,pins = <1 RK_PC0 1 &pcfg_pull_none_drv_12ma>; +@@ -923,6 +1082,10 @@ + <1 RK_PC4 1 &pcfg_pull_none_drv_12ma>, + <1 RK_PC5 1 &pcfg_pull_none_drv_12ma>; + }; ++ ++ sdmmc_pwr: sdmmc-pwr { ++ rockchip,pins = <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; + }; + + sdio { +@@ -963,6 +1126,55 @@ + }; + }; + ++ flash { ++ ++ flash_cs0: flash-cs0 { ++ rockchip,pins = ++ <2 RK_PA6 1 &pcfg_pull_none>; ++ }; ++ ++ flash_cs1: flash-cs1 { ++ rockchip,pins = ++ <0 RK_PC7 1 &pcfg_pull_none>; ++ }; ++ ++ flash_rdy: flash-rdy { ++ rockchip,pins = ++ <2 RK_PA4 1 &pcfg_pull_none>; ++ }; ++ ++ flash_ale: flash-ale { ++ rockchip,pins = ++ <2 RK_PA0 1 &pcfg_pull_none>; ++ }; ++ ++ flash_cle: flash-cle { ++ rockchip,pins = ++ <2 RK_PA1 1 &pcfg_pull_none>; ++ }; ++ ++ flash_wrn: flash-wrn { ++ rockchip,pins = ++ <2 RK_PA2 1 &pcfg_pull_none>; ++ }; ++ ++ flash_rdn: flash-rdn { ++ rockchip,pins = ++ <2 RK_PA3 1 &pcfg_pull_none>; ++ }; ++ ++ flash_bus8: flash-bus8 { ++ rockchip,pins = <1 RK_PD0 1 &pcfg_pull_none>, ++ <1 RK_PD1 1 &pcfg_pull_none>, ++ <1 RK_PD2 1 &pcfg_pull_none>, ++ <1 RK_PD3 1 &pcfg_pull_none>, ++ <1 RK_PD4 1 &pcfg_pull_none>, ++ <1 RK_PD5 1 &pcfg_pull_none>, ++ <1 RK_PD6 1 &pcfg_pull_none>, ++ <1 RK_PD7 1 &pcfg_pull_none>; ++ }; ++ }; ++ + gmac { + rgmii_pins: rgmii-pins { + rockchip,pins = <2 RK_PB6 1 &pcfg_pull_none>, +@@ -1104,12 +1316,20 @@ + pwm1_pin: pwm1-pin { + rockchip,pins = <0 RK_PD6 2 &pcfg_pull_none>; + }; ++ ++ pwm1_pin_pull_down: pwm1-pin-pull-down { ++ rockchip,pins = <0 RK_PD6 RK_FUNC_2 &pcfg_pull_down>; ++ }; + }; + + pwm2 { + pwm2_pin: pwm2-pin { + rockchip,pins = <1 RK_PB4 2 &pcfg_pull_none>; + }; ++ ++ pwm2_pin_pull_up: pwm2-pin-pull-up { ++ rockchip,pins = <1 RK_PB4 RK_FUNC_2 &pcfg_pull_up>; ++ }; + }; + + pwm3 { +@@ -1164,16 +1384,31 @@ + }; + }; + ++ uart1-1 { ++ uart11_xfer: uart11-xfer { ++ rockchip,pins = <3 RK_PB6 RK_FUNC_1 &pcfg_pull_up>, ++ <3 RK_PB5 RK_FUNC_1 &pcfg_pull_none>; ++ }; ++ ++ uart11_cts: uart11-cts { ++ rockchip,pins = <3 RK_PA7 RK_FUNC_1 &pcfg_pull_none>; ++ }; ++ ++ uart11_rts: uart11-rts { ++ rockchip,pins = <3 RK_PA6 RK_FUNC_1 &pcfg_pull_none>; ++ }; ++ ++ uart11_rts_gpio: uart11-rts-gpio { ++ rockchip,pins = <3 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ + uart2 { + uart2_xfer: uart2-xfer { + rockchip,pins = <1 RK_PC2 2 &pcfg_pull_up>, + <1 RK_PC3 2 &pcfg_pull_none>; + }; + +- uart21_xfer: uart21-xfer { +- rockchip,pins = <1 RK_PB2 2 &pcfg_pull_up>, +- <1 RK_PB1 2 &pcfg_pull_none>; +- }; + + uart2_cts: uart2-cts { + rockchip,pins = <0 RK_PD1 1 &pcfg_pull_none>; +@@ -1183,5 +1418,23 @@ + rockchip,pins = <0 RK_PD0 1 &pcfg_pull_none>; + }; + }; ++ ++ uart2-1 { ++ uart21_xfer: uart21-xfer { ++ rockchip,pins = <1 RK_PB2 RK_FUNC_2 &pcfg_pull_up>, ++ <1 RK_PB1 RK_FUNC_2 &pcfg_pull_none>; ++ }; ++ }; ++ ++ usb { ++ host_vbus_drv: host-vbus-drv { ++ rockchip,pins = <3 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ ++ otg_vbus_drv: otg-vbus-drv { ++ rockchip,pins = <3 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ + }; + }; +-- +2.17.1 + diff --git a/patch/kernel/rk322x-current/01-linux-1003-rk322x-hantro.patch b/patch/kernel/rk322x-current/01-linux-1003-rk322x-hantro.patch new file mode 100644 index 0000000000..7625e64762 --- /dev/null +++ b/patch/kernel/rk322x-current/01-linux-1003-rk322x-hantro.patch @@ -0,0 +1,97 @@ +diff --git a/Documentation/devicetree/bindings/media/rockchip-vpu.yaml b/Documentation/devicetree/bindings/media/rockchip-vpu.yaml +index a0c45e05cf03..a20cfaa8973e 100644 +--- a/Documentation/devicetree/bindings/media/rockchip-vpu.yaml ++++ b/Documentation/devicetree/bindings/media/rockchip-vpu.yaml +@@ -16,6 +16,7 @@ description: + properties: + compatible: + enum: ++ - rockchip,rk322x-vpu + - rockchip,rk3288-vpu + - rockchip,rk3328-vpu + - rockchip,rk3399-vpu +diff --git a/arch/arm/boot/dts/rk322x.dtsi b/arch/arm/boot/dts/rk322x.dtsi +index f7a50b903a7d..2ed8aa7ae520 100644 +--- a/arch/arm/boot/dts/rk322x.dtsi ++++ b/arch/arm/boot/dts/rk322x.dtsi +@@ -676,6 +676,18 @@ + }; + }; + ++ vpu: video-codec@20020000 { ++ compatible = "rockchip,rk322x-vpu"; ++ reg = <0x20020000 0x800>; ++ interrupts = , ++ ; ++ interrupt-names = "vepu", "vdpu"; ++ clocks = <&cru ACLK_VPU>, <&cru HCLK_VPU>; ++ clock-names = "aclk", "hclk"; ++ iommus = <&vpu_mmu>; ++ power-domains = <&power RK3228_PD_VPU>; ++ }; ++ + vpu_mmu: iommu@20020800 { + compatible = "rockchip,iommu"; + reg = <0x20020800 0x100>; +diff --git a/drivers/staging/media/hantro/Kconfig b/drivers/staging/media/hantro/Kconfig +index de77fe6554e7..9f99d1c9f453 100644 +--- a/drivers/staging/media/hantro/Kconfig ++++ b/drivers/staging/media/hantro/Kconfig +@@ -20,4 +20,4 @@ config VIDEO_HANTRO_ROCKCHIP + depends on ARCH_ROCKCHIP || COMPILE_TEST + default y + help +- Enable support for RK3288, RK3328, and RK3399 SoCs. ++ Enable support for RK322x, RK3288, RK3328, and RK3399 SoCs. +diff --git a/drivers/staging/media/hantro/hantro_drv.c b/drivers/staging/media/hantro/hantro_drv.c +index a732beeb3bb6..fae9555a349b 100644 +--- a/drivers/staging/media/hantro/hantro_drv.c ++++ b/drivers/staging/media/hantro/hantro_drv.c +@@ -469,6 +469,7 @@ static const struct of_device_id of_hantro_match[] = { + { .compatible = "rockchip,rk3399-vpu", .data = &rk3399_vpu_variant, }, + { .compatible = "rockchip,rk3328-vpu", .data = &rk3328_vpu_variant, }, + { .compatible = "rockchip,rk3288-vpu", .data = &rk3288_vpu_variant, }, ++ { .compatible = "rockchip,rk322x-vpu", .data = &rk322x_vpu_variant, }, + #endif + { /* sentinel */ } + }; +diff --git a/drivers/staging/media/hantro/hantro_hw.h b/drivers/staging/media/hantro/hantro_hw.h +index 33c1ce169203..e64369e01a21 100644 +--- a/drivers/staging/media/hantro/hantro_hw.h ++++ b/drivers/staging/media/hantro/hantro_hw.h +@@ -157,6 +157,7 @@ enum hantro_enc_fmt { + extern const struct hantro_variant rk3399_vpu_variant; + extern const struct hantro_variant rk3328_vpu_variant; + extern const struct hantro_variant rk3288_vpu_variant; ++extern const struct hantro_variant rk322x_vpu_variant; + + extern const struct hantro_postproc_regs hantro_g1_postproc_regs; + +diff --git a/drivers/staging/media/hantro/rk3399_vpu_hw.c b/drivers/staging/media/hantro/rk3399_vpu_hw.c +index 78f878ca01ff..0a6c021c2332 100644 +--- a/drivers/staging/media/hantro/rk3399_vpu_hw.c ++++ b/drivers/staging/media/hantro/rk3399_vpu_hw.c +@@ -241,3 +241,20 @@ const struct hantro_variant rk3328_vpu_variant = { + .clk_names = rk3399_clk_names, + .num_clocks = ARRAY_SIZE(rk3399_clk_names), + }; ++ ++const struct hantro_variant rk322x_vpu_variant = { ++ .enc_offset = 0x0, ++ .enc_fmts = rk3399_vpu_enc_fmts, ++ .num_enc_fmts = ARRAY_SIZE(rk3399_vpu_enc_fmts), ++ .dec_offset = 0x400, ++ .dec_fmts = rk3399_vpu_dec_fmts, ++ .num_dec_fmts = ARRAY_SIZE(rk3399_vpu_dec_fmts), ++ .codec = HANTRO_MPEG2_DECODER | HANTRO_VP8_DECODER | ++ HANTRO_H264_DECODER, ++ .codec_ops = rk3399_vpu_codec_ops, ++ .irqs = rk3399_irqs, ++ .num_irqs = ARRAY_SIZE(rk3399_irqs), ++ .init = rk3399_vpu_hw_init, ++ .clk_names = rk3399_clk_names, ++ .num_clocks = ARRAY_SIZE(rk3399_clk_names) ++}; +-- +2.17.1 + diff --git a/patch/kernel/rk322x-current/01-linux-1004-rockchip-rk322x-enhancements-and-fixes.patch b/patch/kernel/rk322x-current/01-linux-1004-rockchip-rk322x-enhancements-and-fixes.patch new file mode 100644 index 0000000000..9eeecfde83 --- /dev/null +++ b/patch/kernel/rk322x-current/01-linux-1004-rockchip-rk322x-enhancements-and-fixes.patch @@ -0,0 +1,439 @@ +diff --git a/drivers/soc/rockchip/pm_domains.c b/drivers/soc/rockchip/pm_domains.c +index 54eb6cfc5d5b..c6b33f7c43df 100644 +--- a/drivers/soc/rockchip/pm_domains.c ++++ b/drivers/soc/rockchip/pm_domains.c +@@ -71,6 +71,7 @@ struct rockchip_pm_domain { + struct regmap **qos_regmap; + u32 *qos_save_regs[MAX_QOS_REGS_NUM]; + int num_clks; ++ bool is_ignore_pwr; + struct clk_bulk_data *clks; + }; + +@@ -330,6 +331,9 @@ static int rockchip_pd_power_on(struct generic_pm_domain *domain) + { + struct rockchip_pm_domain *pd = to_rockchip_pd(domain); + ++ if (pd->is_ignore_pwr) ++ return 0; ++ + return rockchip_pd_power(pd, true); + } + +@@ -337,6 +341,9 @@ static int rockchip_pd_power_off(struct generic_pm_domain *domain) + { + struct rockchip_pm_domain *pd = to_rockchip_pd(domain); + ++ if (pd->is_ignore_pwr) ++ return 0; ++ + return rockchip_pd_power(pd, false); + } + +@@ -416,6 +423,9 @@ static int rockchip_pm_add_one_domain(struct rockchip_pmu *pmu, + pd->info = pd_info; + pd->pmu = pmu; + ++ if (!pd_info->pwr_mask) ++ pd->is_ignore_pwr = true; ++ + pd->num_clks = of_clk_get_parent_count(node); + if (pd->num_clks > 0) { + pd->clks = devm_kcalloc(pmu->dev, pd->num_clks, +@@ -566,6 +576,7 @@ static int rockchip_pm_add_subdomain(struct rockchip_pmu *pmu, + { + struct device_node *np; + struct generic_pm_domain *child_domain, *parent_domain; ++ struct rockchip_pm_domain *child_pd, *parent_pd; + int error; + + for_each_child_of_node(parent, np) { +@@ -606,6 +617,18 @@ static int rockchip_pm_add_subdomain(struct rockchip_pmu *pmu, + parent_domain->name, child_domain->name); + } + ++ /* ++ * If child_pd doesn't do idle request or power on/off, ++ * parent_pd may fail to do power on/off, so if parent_pd ++ * need to power on/off, child_pd can't ignore to do idle ++ * request and power on/off. ++ */ ++ child_pd = to_rockchip_pd(child_domain); ++ parent_pd = to_rockchip_pd(parent_domain); ++ if (!parent_pd->is_ignore_pwr) ++ child_pd->is_ignore_pwr = false; ++ ++ + rockchip_pm_add_subdomain(pmu, np); + } + +-- +2.17.1 + +From c94b1272290bafced10d79b7da1525466e8c843b Mon Sep 17 00:00:00 2001 +From: "Huang, Tao" +Date: Thu, 28 Jul 2016 10:59:22 +0800 +Subject: [PATCH] power: reset: reboot-mode: fix normal mode setup + +If cmd is empty in get_reboot_mode_magic, we should return normal magic. + +Change-Id: I10931adc49e33f72ae73d9471159f82cc02ff0c0 +Signed-off-by: Huang, Tao +--- + drivers/power/reset/reboot-mode.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/power/reset/reboot-mode.c b/drivers/power/reset/reboot-mode.c +index b4076b10b893..47f9a162807d 100644 +--- a/drivers/power/reset/reboot-mode.c ++++ b/drivers/power/reset/reboot-mode.c +@@ -26,7 +26,7 @@ static unsigned int get_reboot_mode_magic(struct reboot_mode_driver *reboot, + int magic = 0; + struct mode_info *info; + +- if (!cmd) ++ if (!cmd || !cmd[0]) + cmd = normal; + + list_for_each_entry(info, &reboot->head, list) { +-- +2.17.1 + + +From be9674f270c97399f9f6b1facb11e93eced6ec34 Mon Sep 17 00:00:00 2001 +From: Andy Yan +Date: Thu, 8 Dec 2016 16:58:07 +0800 +Subject: [PATCH] power: reset: reboot-mode: treat unrecognized reboot mode as + normal mode + +Some bootloader will check the reboot mode to take different action, so +we treat unrecognized reboot mode as normal mode to prevent the system +run into abnormal case. + +Change-Id: I88063a5b41e4e645443229fa490b2b55db5ccf27 +Signed-off-by: Andy Yan +--- + drivers/power/reset/reboot-mode.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/power/reset/reboot-mode.c b/drivers/power/reset/reboot-mode.c +index 47f9a162807d..99bf938404e3 100644 +--- a/drivers/power/reset/reboot-mode.c ++++ b/drivers/power/reset/reboot-mode.c +@@ -47,6 +47,8 @@ static int reboot_mode_notify(struct notifier_block *this, + + reboot = container_of(this, struct reboot_mode_driver, reboot_notifier); + magic = get_reboot_mode_magic(reboot, cmd); ++ if (!magic) ++ magic = get_reboot_mode_magic(reboot, NULL); + if (magic) + reboot->write(reboot, magic); + +-- +2.17.1 + +From 7c097120eb21a9bd15ab63c0ac60ffd5cba902b2 Mon Sep 17 00:00:00 2001 +From: Alex Bee +Date: Fri, 24 Apr 2020 13:01:07 +0200 +Subject: [PATCH] sound: soc: rockchip: use rouned rate for i2s + +--- + sound/soc/rockchip/rockchip_i2s.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/sound/soc/rockchip/rockchip_i2s.c b/sound/soc/rockchip/rockchip_i2s.c +index 61c984f10d8e..efca853eba6b 100644 +--- a/sound/soc/rockchip/rockchip_i2s.c ++++ b/sound/soc/rockchip/rockchip_i2s.c +@@ -279,10 +279,13 @@ static int rockchip_i2s_hw_params(struct snd_pcm_substream *substream, + if (i2s->is_master_mode) { + mclk_rate = clk_get_rate(i2s->mclk); + bclk_rate = 2 * 32 * params_rate(params); +- if (bclk_rate && mclk_rate % bclk_rate) ++ if (!bclk_rate) { ++ dev_err(i2s->dev, "invalid bclk_rate: %d\n", ++ bclk_rate); + return -EINVAL; ++ } + +- div_bclk = mclk_rate / bclk_rate; ++ div_bclk = DIV_ROUND_CLOSEST(mclk_rate, bclk_rate); + div_lrck = bclk_rate / params_rate(params); + regmap_update_bits(i2s->regmap, I2S_CKR, + I2S_CKR_MDIV_MASK, +@@ -312,6 +315,8 @@ static int rockchip_i2s_hw_params(struct snd_pcm_substream *substream, + val |= I2S_TXCR_VDW(32); + break; + default: ++ dev_err(i2s->dev, "invalid format: %d\n", ++ params_format(params)); + return -EINVAL; + } + +-- +2.17.1 + +From ed1bc72e4842eddebd2ee06e984d32990ea54e55 Mon Sep 17 00:00:00 2001 +From: Alex Bee +Date: Fri, 24 Apr 2020 08:05:27 +0200 +Subject: [PATCH] drm: rockchip: vop: interlaced modes are not supported by + current driver - reject them + +--- + drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +index b8c0d2fcc52a..d50345bdcadc 100644 +--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +@@ -1063,6 +1063,8 @@ static void vop_crtc_disable_vblank(struct drm_crtc *crtc) + enum drm_mode_status vop_crtc_mode_valid(struct drm_crtc *crtc, + const struct drm_display_mode *mode) + { ++ if (mode->flags & DRM_MODE_FLAG_INTERLACE) ++ return MODE_NO_INTERLACE; + if (mode->hdisplay > 3840) + return MODE_BAD_HVALUE; + +-- +2.17.1 + +From 4102c5b07d8610c729d577612c1df52737fb9a0f Mon Sep 17 00:00:00 2001 +From: Alex Bee +Date: Fri, 24 Apr 2020 09:08:44 +0200 +Subject: [PATCH] phy: rockchip: hdmi: readout hdmi phy flag for RK3228 HDMI + phys + +Some RK3228 HDMI phys only get a stable pll on frequencies higher 337,5 MHz. +This is defined in a flag in efuse of those devices. +--- + arch/arm/boot/dts/rk322x.dtsi | 7 ++++ + drivers/phy/rockchip/phy-rockchip-inno-hdmi.c | 38 ++++++++++++++++++- + 2 files changed, 43 insertions(+), 2 deletions(-) + +diff --git a/arch/arm/boot/dts/rk322x.dtsi b/arch/arm/boot/dts/rk322x.dtsi +index 2ed8aa7ae520..8c50dcb0e9f1 100644 +--- a/arch/arm/boot/dts/rk322x.dtsi ++++ b/arch/arm/boot/dts/rk322x.dtsi +@@ -402,6 +402,11 @@ + cpu_leakage: cpu_leakage@17 { + reg = <0x17 0x1>; + }; ++ ++ hdmi_phy_flag: hdmi-phy-flag@1d { ++ reg = <0x1d 0x1>; ++ bits = <1 1>; ++ }; + }; + + i2c0: i2c@11050000 { +@@ -628,6 +633,8 @@ + clock-names = "sysclk", "refoclk", "refpclk"; + #clock-cells = <0>; + clock-output-names = "hdmiphy_phy"; ++ nvmem-cells = <&hdmi_phy_flag>; ++ nvmem-cell-names = "hdmi-phy-flag"; + #phy-cells = <0>; + status = "disabled"; + }; +diff --git a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c +index bb8bdf5e3301..0c7a97352714 100644 +--- a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c ++++ b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c +@@ -237,6 +237,9 @@ struct inno_hdmi_phy { + struct clk *refoclk; + struct clk *refpclk; + ++ /* phy_flag flag */ ++ bool phy_flag; ++ + /* platform data */ + const struct inno_hdmi_phy_drv_data *plat_data; + int chip_version; +@@ -347,6 +350,7 @@ static const struct pre_pll_config pre_pll_cfg_table[] = { + static const struct post_pll_config post_pll_cfg_table[] = { + {33750000, 1, 40, 8, 1}, + {33750000, 1, 80, 8, 2}, ++ {33750000, 1, 10, 2, 4}, + {74250000, 1, 40, 8, 1}, + {74250000, 18, 80, 8, 2}, + {148500000, 2, 40, 4, 3}, +@@ -497,8 +501,11 @@ static int inno_hdmi_phy_power_on(struct phy *phy) + return -EINVAL; + + for (; cfg->tmdsclock != 0; cfg++) +- if (tmdsclock <= cfg->tmdsclock && +- cfg->version & inno->chip_version) ++ if (((!inno->phy_flag || tmdsclock > 33750000) ++ && tmdsclock <= cfg->tmdsclock ++ && cfg->version & inno->chip_version) || ++ (inno->phy_flag && tmdsclock <= 33750000 ++ && cfg->version & 4)) + break; + + for (; phy_cfg->tmdsclock != 0; phy_cfg++) +@@ -909,6 +916,10 @@ static int inno_hdmi_phy_clk_register(struct inno_hdmi_phy *inno) + + static int inno_hdmi_phy_rk3228_init(struct inno_hdmi_phy *inno) + { ++ struct nvmem_cell *cell; ++ unsigned char *efuse_buf; ++ size_t len; ++ + /* + * Use phy internal register control + * rxsense/poweron/pllpd/pdataen signal. +@@ -923,7 +934,28 @@ static int inno_hdmi_phy_rk3228_init(struct inno_hdmi_phy *inno) + inno_update_bits(inno, 0xaa, RK3228_POST_PLL_CTRL_MANUAL, + RK3228_POST_PLL_CTRL_MANUAL); + ++ + inno->chip_version = 1; ++ inno->phy_flag = false; ++ ++ cell = nvmem_cell_get(inno->dev, "hdmi-phy-flag"); ++ if (IS_ERR(cell)) { ++ if (PTR_ERR(cell) == -EPROBE_DEFER) ++ return -EPROBE_DEFER; ++ ++ return 0; ++ } ++ ++ efuse_buf = nvmem_cell_read(cell, &len); ++ nvmem_cell_put(cell); ++ ++ if (IS_ERR(efuse_buf)) ++ return 0; ++ if (len == 1) ++ inno->phy_flag = (efuse_buf[0] & BIT(1)) ? true : false; ++ kfree(efuse_buf); ++ ++ dev_info(inno->dev, "phy_flag is: %d\n", inno->phy_flag); + + return 0; + } +@@ -1023,6 +1055,8 @@ static int inno_hdmi_phy_rk3328_init(struct inno_hdmi_phy *inno) + + /* try to read the chip-version */ + inno->chip_version = 1; ++ inno->phy_flag = false; ++ + cell = nvmem_cell_get(inno->dev, "cpu-version"); + if (IS_ERR(cell)) { + if (PTR_ERR(cell) == -EPROBE_DEFER) +-- +2.17.1 + +From 80891e83d78781a8dddf8a5e50d89ad944d9c55b Mon Sep 17 00:00:00 2001 +From: Alex Bee +Date: Fri, 24 Apr 2020 14:15:08 +0200 +Subject: [PATCH] drm: rockchip: allow ycbcr420 and yuv444 for RK3228 HDMI + +--- + drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +index eb405cb3d1f6..cb2d3d6bab95 100644 +--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c ++++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +@@ -552,6 +552,7 @@ static const struct dw_hdmi_phy_ops rk3228_hdmi_phy_ops = { + + static struct rockchip_hdmi_chip_data rk3228_chip_data = { + .lcdsel_grf_reg = -1, ++ .ycbcr_444_allowed = false, + }; + + static const struct dw_hdmi_plat_data rk3228_hdmi_drv_data = { +@@ -560,6 +561,7 @@ static const struct dw_hdmi_plat_data rk3228_hdmi_drv_data = { + .phy_ops = &rk3228_hdmi_phy_ops, + .phy_name = "inno_dw_hdmi_phy2", + .phy_force_vendor = true, ++ .ycbcr_420_allowed = false, + }; + + static struct rockchip_hdmi_chip_data rk3288_chip_data = { +-- +2.17.1 + +From fe30b024a7a7d6261dff0b87c2aec270ad530c39 Mon Sep 17 00:00:00 2001 +From: Alex Bee +Date: Fri, 24 Apr 2020 14:23:38 +0200 +Subject: [PATCH] drm: rockchip: Use 2nd RK3228 plane as an overlay + +As per datasheet the second plane of RK3228 vop is an overlay window. For +the missing implementation of hardware cursor it is missued as such (as +already pointed in comment for RK3288). Furthermore the overlay window +does not support YUV modes with the current implementation - so it +supports only RGB modes for now. +--- + drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 44 +++++++++++++++++++-- + 1 file changed, 41 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c +index 73d24c6bbf05..d4ac6e161ef2 100644 +--- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c ++++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c +@@ -614,6 +614,44 @@ static const struct vop_common rk3288_common = { + .dsp_background = VOP_REG(RK3288_DSP_BG, 0xffffffff, 0), + }; + ++static const struct vop_win_phy rk3228_win0_data = { ++ .scl = &rk3288_win_full_scl, ++ .data_formats = formats_win_full, ++ .nformats = ARRAY_SIZE(formats_win_full), ++ .enable = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 0), ++ .format = VOP_REG(RK3288_WIN0_CTRL0, 0x7, 1), ++ .rb_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 12), ++ .act_info = VOP_REG(RK3288_WIN0_ACT_INFO, 0x1fff1fff, 0), ++ .dsp_info = VOP_REG(RK3288_WIN0_DSP_INFO, 0x0fff0fff, 0), ++ .dsp_st = VOP_REG(RK3288_WIN0_DSP_ST, 0x1fff1fff, 0), ++ .yrgb_mst = VOP_REG(RK3288_WIN0_YRGB_MST, 0xffffffff, 0), ++ .uv_mst = VOP_REG(RK3288_WIN0_CBR_MST, 0xffffffff, 0), ++ .yrgb_vir = VOP_REG(RK3288_WIN0_VIR, 0x3fff, 0), ++ .uv_vir = VOP_REG(RK3288_WIN0_VIR, 0x3fff, 16), ++ .src_alpha_ctl = VOP_REG(RK3288_WIN0_SRC_ALPHA_CTRL, 0xff, 0), ++ .dst_alpha_ctl = VOP_REG(RK3288_WIN0_DST_ALPHA_CTRL, 0xff, 0), ++ .channel = VOP_REG(RK3288_WIN0_CTRL2, 0xff, 0), ++}; ++ ++static const struct vop_win_phy rk3228_win1_data = { ++ .scl = &rk3288_win_full_scl, ++ .data_formats = formats_win_lite, ++ .nformats = ARRAY_SIZE(formats_win_lite), ++ .enable = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 0), ++ .format = VOP_REG(RK3288_WIN0_CTRL0, 0x7, 1), ++ .rb_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 12), ++ .act_info = VOP_REG(RK3288_WIN0_ACT_INFO, 0x1fff1fff, 0), ++ .dsp_info = VOP_REG(RK3288_WIN0_DSP_INFO, 0x0fff0fff, 0), ++ .dsp_st = VOP_REG(RK3288_WIN0_DSP_ST, 0x1fff1fff, 0), ++ .yrgb_mst = VOP_REG(RK3288_WIN0_YRGB_MST, 0xffffffff, 0), ++ .uv_mst = VOP_REG(RK3288_WIN0_CBR_MST, 0xffffffff, 0), ++ .yrgb_vir = VOP_REG(RK3288_WIN0_VIR, 0x3fff, 0), ++ .uv_vir = VOP_REG(RK3288_WIN0_VIR, 0x3fff, 16), ++ .src_alpha_ctl = VOP_REG(RK3288_WIN0_SRC_ALPHA_CTRL, 0xff, 0), ++ .dst_alpha_ctl = VOP_REG(RK3288_WIN0_DST_ALPHA_CTRL, 0xff, 0), ++ .channel = VOP_REG(RK3288_WIN0_CTRL2, 0xff, 0), ++}; ++ + /* + * Note: rk3288 has a dedicated 'cursor' window, however, that window requires + * special support to get alpha blending working. For now, just use overlay +@@ -864,10 +902,10 @@ static const struct vop_data rk3399_vop_lit = { + }; + + static const struct vop_win_data rk3228_vop_win_data[] = { +- { .base = 0x00, .phy = &rk3288_win01_data, ++ { .base = 0x00, .phy = &rk3228_win0_data, + .type = DRM_PLANE_TYPE_PRIMARY }, +- { .base = 0x40, .phy = &rk3288_win01_data, +- .type = DRM_PLANE_TYPE_CURSOR }, ++ { .base = 0x40, .phy = &rk3228_win1_data, ++ .type = DRM_PLANE_TYPE_OVERLAY }, + }; + + static const struct vop_data rk3228_vop = { +-- +2.17.1 + diff --git a/patch/kernel/rk322x-current/02-linux-0001-add-board-makefile.patch b/patch/kernel/rk322x-current/02-linux-0001-add-board-makefile.patch new file mode 100644 index 0000000000..3d921d3349 --- /dev/null +++ b/patch/kernel/rk322x-current/02-linux-0001-add-board-makefile.patch @@ -0,0 +1,12 @@ +diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile +index 08011dc8c..4bee5c4cd 100644 +--- a/arch/arm/boot/dts/Makefile ++++ b/arch/arm/boot/dts/Makefile +@@ -923,6 +923,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += \ + rk3228-evb.dtb \ + rk3229-evb.dtb \ + rk3229-xms6.dtb \ ++ rk322x-box.dtb \ + rk3288-evb-act8846.dtb \ + rk3288-evb-rk808.dtb \ + rk3288-firefly-beta.dtb \ diff --git a/patch/kernel/rk322x-current/02-linux-0003-dtsi-integrate-rk322x-box.patch b/patch/kernel/rk322x-current/02-linux-0003-dtsi-integrate-rk322x-box.patch new file mode 100644 index 0000000000..d299d98a75 --- /dev/null +++ b/patch/kernel/rk322x-current/02-linux-0003-dtsi-integrate-rk322x-box.patch @@ -0,0 +1,15 @@ +diff --git a/arch/arm/boot/dts/rk322x-box.dtsi b/arch/arm/boot/dts/rk322x-box.dtsi +index 44fb2f4ea..15d07a736 100644 +--- a/arch/arm/boot/dts/rk322x-box.dtsi ++++ b/arch/arm/boot/dts/rk322x-box.dtsi +@@ -89,6 +89,10 @@ + cap-mmc-highspeed; + keep-power-in-suspend; + non-removable; ++ /delete-property/ pinctrl-names; ++ /delete-property/ pinctrl-0; ++ /delete-property/ default-sample-phase; ++ rockchip,default-sample-phase = <180>; + }; + + &gmac { diff --git a/patch/kernel/rk322x-current/02-linux-0004-dtsi-adjust-nand-pinctrls.patch b/patch/kernel/rk322x-current/02-linux-0004-dtsi-adjust-nand-pinctrls.patch new file mode 100644 index 0000000000..f342f63b7c --- /dev/null +++ b/patch/kernel/rk322x-current/02-linux-0004-dtsi-adjust-nand-pinctrls.patch @@ -0,0 +1,92 @@ +diff --git a/arch/arm/boot/dts/rk322x.dtsi b/arch/arm/boot/dts/rk322x.dtsi +index b2fcf0e75..25051c03f 100644 +--- a/arch/arm/boot/dts/rk322x.dtsi ++++ b/arch/arm/boot/dts/rk322x.dtsi +@@ -1149,51 +1149,71 @@ + + flash_cs0: flash-cs0 { + rockchip,pins = +- <2 RK_PA6 1 &pcfg_pull_none>; ++ <2 RK_PA6 RK_FUNC_1 &pcfg_pull_up>; + }; + + flash_cs1: flash-cs1 { + rockchip,pins = +- <0 RK_PC7 1 &pcfg_pull_none>; ++ <0 RK_PC7 RK_FUNC_1 &pcfg_pull_up>; ++ }; ++ ++ flash_cs2: flash-cs2 { ++ rockchip,pins = ++ <1 RK_PC6 RK_FUNC_1 &pcfg_pull_up>; ++ }; ++ ++ flash_cs3: flash-cs3 { ++ rockchip,pins = ++ <1 RK_PC7 RK_FUNC_1 &pcfg_pull_up>; + }; + + flash_rdy: flash-rdy { + rockchip,pins = +- <2 RK_PA4 1 &pcfg_pull_none>; ++ <2 RK_PA4 RK_FUNC_1 &pcfg_pull_up>; + }; + + flash_ale: flash-ale { + rockchip,pins = +- <2 RK_PA0 1 &pcfg_pull_none>; ++ <2 RK_PA0 RK_FUNC_1 &pcfg_pull_down>; + }; + + flash_cle: flash-cle { + rockchip,pins = +- <2 RK_PA1 1 &pcfg_pull_none>; ++ <2 RK_PA1 RK_FUNC_1 &pcfg_pull_down>; + }; + + flash_wrn: flash-wrn { +- rockchip,pins = +- <2 RK_PA2 1 &pcfg_pull_none>; ++ rockchip,pins = ++ <2 RK_PA2 RK_FUNC_1 &pcfg_pull_up>; + }; + + flash_rdn: flash-rdn { + rockchip,pins = +- <2 RK_PA3 1 &pcfg_pull_none>; ++ <2 RK_PA3 RK_FUNC_1 &pcfg_pull_up>; + }; + + flash_bus8: flash-bus8 { +- rockchip,pins = <1 RK_PD0 1 &pcfg_pull_none>, +- <1 RK_PD1 1 &pcfg_pull_none>, +- <1 RK_PD2 1 &pcfg_pull_none>, +- <1 RK_PD3 1 &pcfg_pull_none>, +- <1 RK_PD4 1 &pcfg_pull_none>, +- <1 RK_PD5 1 &pcfg_pull_none>, +- <1 RK_PD6 1 &pcfg_pull_none>, +- <1 RK_PD7 1 &pcfg_pull_none>; ++ rockchip,pins = <1 RK_PD0 RK_FUNC_1 &pcfg_pull_up>, ++ <1 RK_PD1 RK_FUNC_1 &pcfg_pull_up>, ++ <1 RK_PD2 RK_FUNC_1 &pcfg_pull_up>, ++ <1 RK_PD3 RK_FUNC_1 &pcfg_pull_up>, ++ <1 RK_PD4 RK_FUNC_1 &pcfg_pull_up>, ++ <1 RK_PD5 RK_FUNC_1 &pcfg_pull_up>, ++ <1 RK_PD6 RK_FUNC_1 &pcfg_pull_up>, ++ <1 RK_PD7 RK_FUNC_1 &pcfg_pull_up>; + }; ++ ++ flash_dqs: flash-dqs { ++ rockchip,pins = <2 RK_PA7 RK_FUNC_1 &pcfg_pull_up>; ++ }; ++ ++ flash_wp: flash-wp { ++ rockchip,pins = <2 RK_PA5 RK_FUNC_1 &pcfg_pull_down>; ++ }; ++ + }; + ++ + gmac { + rgmii_pins: rgmii-pins { + rockchip,pins = <2 RK_PB6 1 &pcfg_pull_none>, diff --git a/patch/kernel/rk322x-current/board-rk322x-box.patch b/patch/kernel/rk322x-current/board-rk322x-box.patch new file mode 100644 index 0000000000..778fb60756 --- /dev/null +++ b/patch/kernel/rk322x-current/board-rk322x-box.patch @@ -0,0 +1,219 @@ +diff --git a/arch/arm/boot/dts/rk322x-box.dts b/arch/arm/boot/dts/rk322x-box.dts +new file mode 100644 +index 000000000..6f2833a50 +--- /dev/null ++++ b/arch/arm/boot/dts/rk322x-box.dts +@@ -0,0 +1,213 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++ ++/dts-v1/; ++ ++#include "rk3228a-box.dtsi" ++ ++/ { ++ ++ model = "Generic RK322x Tv Box board"; ++ ++ /delete-node/ leds; ++ ++ gpio_leds: gpio-leds { ++ ++ compatible = "gpio-leds"; ++ ++ /* ++ * Working led, available on all boards ++ */ ++ working { ++ gpios = <&gpio3 RK_PC5 GPIO_ACTIVE_HIGH>; ++ label = "working"; ++ default-state = "on"; ++ linux,default-trigger = "timer"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&gpio_led_working>; ++ }; ++ ++ }; ++ ++}; ++ ++&emmc { ++ status = "okay"; ++ /delete-property/ mmc-ddr-1_8v; ++ /delete-property/ pinctrl-names; ++ /delete-property/ pinctrl-0; ++ rockchip,default-sample-phase = <180>; ++}; ++ ++&nfc { ++ status = "okay"; ++}; ++ ++&gmac { ++ tx_delay = <0x26>; ++ rx_delay = <0x11>; ++}; ++ ++&ir_receiver { ++ status = "okay"; ++}; ++ ++&power_key { ++ status = "okay"; ++}; ++ ++&usb_otg { ++ dr_mode = "host"; ++}; ++ ++&sdio { ++ mmc-pwrseq = <&sdio_pwrseq>; ++ status = "okay"; ++}; ++ ++&sdmmc { ++ status = "okay"; ++}; ++ ++/** Integration to pin controller */ ++&pinctrl { ++ ++ pcfg_pull_up_12ma: pcfg-pull-up-12ma { ++ drive-strength = <12>; ++ bias-pull-up; ++ }; ++ ++ pcfg_pull_down_12ma: pcfg-pull-down-12ma { ++ drive-strength = <12>; ++ bias-pull-down; ++ }; ++ ++ pcfg_pull_none_12ma: pcfg-pull-none-12ma { ++ drive-strength = <12>; ++ bias-disable; ++ }; ++ ++ pcfg_pull_up_2ma: pcfg-pull-up-2ma { ++ drive-strength = <2>; ++ bias-pull-up; ++ }; ++ ++ pcfg_pull_down_2ma: pcfg-pull-down-2ma { ++ drive-strength = <2>; ++ bias-pull-down; ++ }; ++ ++ pcfg_pull_none_2ma: pcfg-pull-none-2ma { ++ drive-strength = <2>; ++ bias-disable; ++ }; ++ ++ /* ++ * Some rk322x electrical schemes report this kind of pull-up/down ++ * pin configurations. We set them here, but we don't use it in this ++ * device tree. These instead are useful for overlays, because they seem ++ * to increase stability on at least one board I got here ++ */ ++ sdmmc { ++ sdmmc_clk: sdmmc-clk { ++ rockchip,pins = <1 16 RK_FUNC_1 &pcfg_pull_down>; ++ }; ++ ++ sdmmc_cmd: sdmmc-cmd { ++ rockchip,pins = <1 15 RK_FUNC_1 &pcfg_pull_up>; ++ }; ++ ++ sdmmc_bus4: sdmmc-bus4 { ++ rockchip,pins = <1 18 RK_FUNC_1 &pcfg_pull_up>, ++ <1 19 RK_FUNC_1 &pcfg_pull_up>, ++ <1 20 RK_FUNC_1 &pcfg_pull_up>, ++ <1 21 RK_FUNC_1 &pcfg_pull_up>; ++ }; ++ }; ++ ++ /* ++ * Same as above, decreasing strength of SDIO pins seems to be benefical ++ * to stability ++ */ ++ sdio { ++ sdio_clk: sdio-clk { ++ rockchip,pins = <3 0 RK_FUNC_1 &pcfg_pull_down_2ma>; ++ }; ++ ++ sdio_cmd: sdio-cmd { ++ rockchip,pins = <3 1 RK_FUNC_1 &pcfg_pull_up_2ma>; ++ }; ++ ++ sdio_bus4: sdio-bus4 { ++ rockchip,pins = <3 2 RK_FUNC_1 &pcfg_pull_up_2ma>, ++ <3 3 RK_FUNC_1 &pcfg_pull_up_2ma>, ++ <3 4 RK_FUNC_1 &pcfg_pull_up_2ma>, ++ <3 5 RK_FUNC_1 &pcfg_pull_up_2ma>; ++ }; ++ }; ++ ++ /* ++ * Same drill as above, electrical schemes also report this pull-up/down ++ * configurations. ++ */ ++ emmc { ++ emmc_clk: emmc-clk { ++ rockchip,pins = <2 7 RK_FUNC_2 &pcfg_pull_up>; ++ }; ++ ++ emmc_cmd: emmc-cmd { ++ rockchip,pins = <1 22 RK_FUNC_2 &pcfg_pull_up>; ++ }; ++ ++ emmc_bus8: emmc-bus8 { ++ rockchip,pins = <1 24 RK_FUNC_2 &pcfg_pull_up>, ++ <1 25 RK_FUNC_2 &pcfg_pull_up>, ++ <1 26 RK_FUNC_2 &pcfg_pull_up>, ++ <1 27 RK_FUNC_2 &pcfg_pull_up>, ++ <1 28 RK_FUNC_2 &pcfg_pull_up>, ++ <1 29 RK_FUNC_2 &pcfg_pull_up>, ++ <1 30 RK_FUNC_2 &pcfg_pull_up>, ++ <1 31 RK_FUNC_2 &pcfg_pull_up>; ++ }; ++ ++ emmc_pwr: emmc-pwr { ++ rockchip,pins = <2 RK_PA5 RK_FUNC_2 &pcfg_pull_down>; ++ }; ++ ++ emmc_rst: emmc-rst { ++ rockchip,pins = <1 RK_PC7 RK_FUNC_2 &pcfg_pull_up>; ++ }; ++ ++ }; ++ ++ ++ gpio { ++ gpio_led_working: gpio-led-working { ++ rockchip,pins = <3 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ ir { ++ ir_int: ir-int { ++ rockchip,pins = <1 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ keys { ++ pwr_key: pwr-key { ++ rockchip,pins = <3 RK_PC7 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ }; ++ ++ sdio-pwrseq { ++ wifi_enable_h: wifi-enable-h { ++ rockchip,pins = <2 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ gpio { ++ gpio_led_working: gpio-led-working { ++ rockchip,pins = <3 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++}; diff --git a/patch/kernel/rk322x-current/general-add-overlay-compilation-support.patch b/patch/kernel/rk322x-current/general-add-overlay-compilation-support.patch new file mode 100644 index 0000000000..c4a515f785 --- /dev/null +++ b/patch/kernel/rk322x-current/general-add-overlay-compilation-support.patch @@ -0,0 +1,96 @@ +diff --git a/arch/arm/boot/.gitignore b/arch/arm/boot/.gitignore +index 3c79f859..4e5c1d59 100644 +--- a/arch/arm/boot/.gitignore ++++ b/arch/arm/boot/.gitignore +@@ -3,3 +3,5 @@ zImage + xipImage + bootpImage + uImage ++*.dtb* ++*.scr +diff --git a/scripts/Makefile.dtbinst b/scripts/Makefile.dtbinst +index 34614a48..8a8313d6 100644 +--- a/scripts/Makefile.dtbinst ++++ b/scripts/Makefile.dtbinst +@@ -20,6 +20,9 @@ include scripts/Kbuild.include + include $(src)/Makefile + + dtbinst-files := $(sort $(dtb-y) $(if $(CONFIG_OF_ALL_DTBS), $(dtb-))) ++dtboinst-files := $(dtbo-y) ++script-files := $(scr-y) ++readme-files := $(dtbotxt-y) + dtbinst-dirs := $(subdir-y) $(subdir-m) + + # Helper targets for Installing DTBs into the boot directory +@@ -32,10 +35,19 @@ install-dir = $(patsubst $(dtbinst-root)%,$(INSTALL_DTBS_PATH)%,$(obj)) + $(dtbinst-files): %.dtb: $(obj)/%.dtb + $(call cmd,dtb_install,$(install-dir)) + ++$(dtboinst-files): %.dtbo: $(obj)/%.dtbo ++ $(call cmd,dtb_install,$(install-dir)) ++ ++$(script-files): %.scr: $(obj)/%.scr ++ $(call cmd,dtb_install,$(install-dir)) ++ ++$(readme-files): %: $(src)/% ++ $(call cmd,dtb_install,$(install-dir)) ++ + $(dtbinst-dirs): + $(Q)$(MAKE) $(dtbinst)=$(obj)/$@ + +-PHONY += $(dtbinst-files) $(dtbinst-dirs) +-__dtbs_install: $(dtbinst-files) $(dtbinst-dirs) ++PHONY += $(dtbinst-files) $(dtboinst-files) $(script-files) $(readme-files) $(dtbinst-dirs) ++__dtbs_install: $(dtbinst-files) $(dtboinst-files) $(script-files) $(readme-files) $(dtbinst-dirs) + + .PHONY: $(PHONY) +diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib +index 58c05e5d..2b95dda9 100644 +--- a/scripts/Makefile.lib ++++ b/scripts/Makefile.lib +@@ -278,6 +278,9 @@ cmd_gzip = (cat $(filter-out FORCE,$^) | gzip -n -f -9 > $@) || \ + # --------------------------------------------------------------------------- + DTC ?= $(objtree)/scripts/dtc/dtc + ++# Overlay support ++DTC_FLAGS += -@ -Wno-unit_address_format -Wno-simple_bus_reg ++ + # Disable noisy checks by default + ifeq ($(KBUILD_ENABLE_EXTRA_GCC_CHECKS),) + DTC_FLAGS += -Wno-unit_address_vs_reg \ +@@ -324,6 +327,23 @@ cmd_dtc = mkdir -p $(dir ${dtc-tmp}) ; \ + $(obj)/%.dtb: $(src)/%.dts FORCE + $(call if_changed_dep,dtc) + ++quiet_cmd_dtco = DTCO $@ ++cmd_dtco = mkdir -p $(dir ${dtc-tmp}) ; \ ++ $(CPP) $(dtc_cpp_flags) -x assembler-with-cpp -o $(dtc-tmp) $< ; \ ++ $(DTC) -O dtb -o $@ -b 0 \ ++ -i $(dir $<) $(DTC_FLAGS) \ ++ -d $(depfile).dtc.tmp $(dtc-tmp) ; \ ++ cat $(depfile).pre.tmp $(depfile).dtc.tmp > $(depfile) ++ ++$(obj)/%.dtbo: $(src)/%.dts FORCE ++ $(call if_changed_dep,dtco) ++ ++quiet_cmd_scr = MKIMAGE $@ ++cmd_scr = mkimage -C none -A $(ARCH) -T script -d $< $@ ++ ++$(obj)/%.scr: $(src)/%.scr-cmd FORCE ++ $(call if_changed,scr) ++ + dtc-tmp = $(subst $(comma),_,$(dot-target).dts.tmp) + + # Bzip2 +diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile +index 1bd2c74f5..560cf1c7f 100644 +--- a/arch/arm/boot/dts/Makefile ++++ b/arch/arm/boot/dts/Makefile +@@ -977,6 +977,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += \ + rk3288-veyron-speedy.dtb \ + rk3288-veyron-tiger.dtb \ + rk3288-vyasa.dtb ++subdir-y := overlay + dtb-$(CONFIG_ARCH_S3C24XX) += \ + s3c2416-smdk2416.dtb + dtb-$(CONFIG_ARCH_S3C64XX) += \ diff --git a/patch/kernel/rk322x-current/general-add-overlay-configfs.patch b/patch/kernel/rk322x-current/general-add-overlay-configfs.patch new file mode 100644 index 0000000000..3b015b8d27 --- /dev/null +++ b/patch/kernel/rk322x-current/general-add-overlay-configfs.patch @@ -0,0 +1,358 @@ +--- /dev/null ++++ b/Documentation/devicetree/configfs-overlays.txt +@@ -0,0 +1,31 @@ ++Howto use the configfs overlay interface. ++ ++A device-tree configfs entry is created in /config/device-tree/overlays ++and and it is manipulated using standard file system I/O. ++Note that this is a debug level interface, for use by developers and ++not necessarily something accessed by normal users due to the ++security implications of having direct access to the kernel's device tree. ++ ++* To create an overlay you mkdir the directory: ++ ++ # mkdir /config/device-tree/overlays/foo ++ ++* Either you echo the overlay firmware file to the path property file. ++ ++ # echo foo.dtbo >/config/device-tree/overlays/foo/path ++ ++* Or you cat the contents of the overlay to the dtbo file ++ ++ # cat foo.dtbo >/config/device-tree/overlays/foo/dtbo ++ ++The overlay file will be applied, and devices will be created/destroyed ++as required. ++ ++To remove it simply rmdir the directory. ++ ++ # rmdir /config/device-tree/overlays/foo ++ ++The rationalle of the dual interface (firmware & direct copy) is that each is ++better suited to different use patterns. The firmware interface is what's ++intended to be used by hardware managers in the kernel, while the copy interface ++make sense for developers (since it avoids problems with namespaces). +diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig +index 37c2ccbefecdc..d3fc81a40c0e7 100644 +--- a/drivers/of/Kconfig ++++ b/drivers/of/Kconfig +@@ -103,4 +103,11 @@ config OF_OVERLAY + config OF_NUMA + bool + ++config OF_CONFIGFS ++ bool "Device Tree Overlay ConfigFS interface" ++ select CONFIGFS_FS ++ select OF_OVERLAY ++ help ++ Enable a simple user-space driven DT overlay interface. ++ + endif # OF +diff --git a/drivers/of/Makefile b/drivers/of/Makefile +index 663a4af0cccd5..b00a95adf5199 100644 +--- a/drivers/of/Makefile ++++ b/drivers/of/Makefile +@@ -1,6 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + obj-y = base.o device.o platform.o property.o + obj-$(CONFIG_OF_KOBJ) += kobj.o ++obj-$(CONFIG_OF_CONFIGFS) += configfs.o + obj-$(CONFIG_OF_DYNAMIC) += dynamic.o + obj-$(CONFIG_OF_FLATTREE) += fdt.o + obj-$(CONFIG_OF_EARLY_FLATTREE) += fdt_address.o +diff --git a/drivers/of/configfs.c b/drivers/of/configfs.c +new file mode 100644 +index 000000000..5dd509e8f +--- /dev/null ++++ b/drivers/of/configfs.c +@@ -0,0 +1,290 @@ ++/* ++ * Configfs entries for device-tree ++ * ++ * Copyright (C) 2013 - Pantelis Antoniou ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version ++ * 2 of the License, or (at your option) any later version. ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "of_private.h" ++ ++struct cfs_overlay_item { ++ struct config_item item; ++ ++ char path[PATH_MAX]; ++ ++ const struct firmware *fw; ++ struct device_node *overlay; ++ int ov_id; ++ ++ void *dtbo; ++ int dtbo_size; ++}; ++ ++static int create_overlay(struct cfs_overlay_item *overlay, void *blob, u32 blob_size) ++{ ++ int err; ++ ++ err = of_overlay_fdt_apply(blob, blob_size, &overlay->ov_id); ++ if (err < 0) { ++ pr_err("%s: Failed to create overlay (err=%d)\n", ++ __func__, err); ++ goto out_err; ++ } ++ ++out_err: ++ return err; ++} ++ ++static inline struct cfs_overlay_item *to_cfs_overlay_item( ++ struct config_item *item) ++{ ++ return item ? container_of(item, struct cfs_overlay_item, item) : NULL; ++} ++ ++static ssize_t cfs_overlay_item_path_show(struct config_item *item, ++ char *page) ++{ ++ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); ++ return sprintf(page, "%s\n", overlay->path); ++} ++ ++static ssize_t cfs_overlay_item_path_store(struct config_item *item, ++ const char *page, size_t count) ++{ ++ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); ++ const char *p = page; ++ char *s; ++ int err; ++ ++ /* if it's set do not allow changes */ ++ if (overlay->path[0] != '\0' || overlay->dtbo_size > 0) ++ return -EPERM; ++ ++ /* copy to path buffer (and make sure it's always zero terminated */ ++ count = snprintf(overlay->path, sizeof(overlay->path) - 1, "%s", p); ++ overlay->path[sizeof(overlay->path) - 1] = '\0'; ++ ++ /* strip trailing newlines */ ++ s = overlay->path + strlen(overlay->path); ++ while (s > overlay->path && *--s == '\n') ++ *s = '\0'; ++ ++ pr_debug("%s: path is '%s'\n", __func__, overlay->path); ++ ++ err = request_firmware(&overlay->fw, overlay->path, NULL); ++ if (err != 0) ++ goto out_err; ++ ++ err = create_overlay(overlay, (void *)overlay->fw->data, overlay->fw->size); ++ if (err != 0) ++ goto out_err; ++ ++ return count; ++ ++out_err: ++ ++ release_firmware(overlay->fw); ++ overlay->fw = NULL; ++ ++ overlay->path[0] = '\0'; ++ return err; ++} ++ ++static ssize_t cfs_overlay_item_status_show(struct config_item *item, ++ char *page) ++{ ++ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); ++ ++ return sprintf(page, "%s\n", ++ overlay->ov_id >= 0 ? "applied" : "unapplied"); ++} ++ ++CONFIGFS_ATTR(cfs_overlay_item_, path); ++CONFIGFS_ATTR_RO(cfs_overlay_item_, status); ++ ++static struct configfs_attribute *cfs_overlay_attrs[] = { ++ &cfs_overlay_item_attr_path, ++ &cfs_overlay_item_attr_status, ++ NULL, ++}; ++ ++ssize_t cfs_overlay_item_dtbo_read(struct config_item *item, ++ void *buf, size_t max_count) ++{ ++ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); ++ ++ pr_debug("%s: buf=%p max_count=%zu\n", __func__, ++ buf, max_count); ++ ++ if (overlay->dtbo == NULL) ++ return 0; ++ ++ /* copy if buffer provided */ ++ if (buf != NULL) { ++ /* the buffer must be large enough */ ++ if (overlay->dtbo_size > max_count) ++ return -ENOSPC; ++ ++ memcpy(buf, overlay->dtbo, overlay->dtbo_size); ++ } ++ ++ return overlay->dtbo_size; ++} ++ ++ssize_t cfs_overlay_item_dtbo_write(struct config_item *item, ++ const void *buf, size_t count) ++{ ++ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); ++ int err; ++ ++ /* if it's set do not allow changes */ ++ if (overlay->path[0] != '\0' || overlay->dtbo_size > 0) ++ return -EPERM; ++ ++ /* copy the contents */ ++ overlay->dtbo = kmemdup(buf, count, GFP_KERNEL); ++ if (overlay->dtbo == NULL) ++ return -ENOMEM; ++ ++ overlay->dtbo_size = count; ++ ++ err = create_overlay(overlay, overlay->dtbo, overlay->dtbo_size); ++ if (err != 0) ++ goto out_err; ++ ++ return count; ++ ++out_err: ++ kfree(overlay->dtbo); ++ overlay->dtbo = NULL; ++ overlay->dtbo_size = 0; ++ ++ return err; ++} ++ ++CONFIGFS_BIN_ATTR(cfs_overlay_item_, dtbo, NULL, SZ_1M); ++ ++static struct configfs_bin_attribute *cfs_overlay_bin_attrs[] = { ++ &cfs_overlay_item_attr_dtbo, ++ NULL, ++}; ++ ++static void cfs_overlay_release(struct config_item *item) ++{ ++ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); ++ ++ if (overlay->ov_id >= 0) ++ of_overlay_remove(&overlay->ov_id); ++ if (overlay->fw) ++ release_firmware(overlay->fw); ++ /* kfree with NULL is safe */ ++ kfree(overlay->dtbo); ++ kfree(overlay); ++} ++ ++static struct configfs_item_operations cfs_overlay_item_ops = { ++ .release = cfs_overlay_release, ++}; ++ ++static struct config_item_type cfs_overlay_type = { ++ .ct_item_ops = &cfs_overlay_item_ops, ++ .ct_attrs = cfs_overlay_attrs, ++ .ct_bin_attrs = cfs_overlay_bin_attrs, ++ .ct_owner = THIS_MODULE, ++}; ++ ++static struct config_item *cfs_overlay_group_make_item( ++ struct config_group *group, const char *name) ++{ ++ struct cfs_overlay_item *overlay; ++ ++ overlay = kzalloc(sizeof(*overlay), GFP_KERNEL); ++ if (!overlay) ++ return ERR_PTR(-ENOMEM); ++ overlay->ov_id = -1; ++ ++ config_item_init_type_name(&overlay->item, name, &cfs_overlay_type); ++ return &overlay->item; ++} ++ ++static void cfs_overlay_group_drop_item(struct config_group *group, ++ struct config_item *item) ++{ ++ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); ++ ++ config_item_put(&overlay->item); ++} ++ ++static struct configfs_group_operations overlays_ops = { ++ .make_item = cfs_overlay_group_make_item, ++ .drop_item = cfs_overlay_group_drop_item, ++}; ++ ++static struct config_item_type overlays_type = { ++ .ct_group_ops = &overlays_ops, ++ .ct_owner = THIS_MODULE, ++}; ++ ++static struct configfs_group_operations of_cfs_ops = { ++ /* empty - we don't allow anything to be created */ ++}; ++ ++static struct config_item_type of_cfs_type = { ++ .ct_group_ops = &of_cfs_ops, ++ .ct_owner = THIS_MODULE, ++}; ++ ++struct config_group of_cfs_overlay_group; ++ ++static struct configfs_subsystem of_cfs_subsys = { ++ .su_group = { ++ .cg_item = { ++ .ci_namebuf = "device-tree", ++ .ci_type = &of_cfs_type, ++ }, ++ }, ++ .su_mutex = __MUTEX_INITIALIZER(of_cfs_subsys.su_mutex), ++}; ++ ++static int __init of_cfs_init(void) ++{ ++ int ret; ++ ++ pr_info("%s\n", __func__); ++ ++ config_group_init(&of_cfs_subsys.su_group); ++ config_group_init_type_name(&of_cfs_overlay_group, "overlays", ++ &overlays_type); ++ configfs_add_default_group(&of_cfs_overlay_group, ++ &of_cfs_subsys.su_group); ++ ++ ret = configfs_register_subsystem(&of_cfs_subsys); ++ if (ret != 0) { ++ pr_err("%s: failed to register subsys\n", __func__); ++ goto out; ++ } ++ pr_info("%s: OK\n", __func__); ++out: ++ return ret; ++} ++late_initcall(of_cfs_init); diff --git a/patch/kernel/rk322x-current/general-add-overlays.patch b/patch/kernel/rk322x-current/general-add-overlays.patch new file mode 100644 index 0000000000..eb88eaf0c4 --- /dev/null +++ b/patch/kernel/rk322x-current/general-add-overlays.patch @@ -0,0 +1,308 @@ +diff --git a/arch/arm/boot/dts/overlay/Makefile b/arch/arm/boot/dts/overlay/Makefile +new file mode 100644 +index 000000000..f024e8db0 +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/Makefile +@@ -0,0 +1,20 @@ ++# SPDX-License-Identifier: GPL-2.0 ++dtbo-$(CONFIG_ARCH_ROCKCHIP) += \ ++ rk322x-emmc.dtbo \ ++ rk322x-nand.dtbo \ ++ rk322x-emmc-nand.dtbo \ ++ rk322x-led-conf1.dtbo \ ++ rk322x-led-conf2.dtbo \ ++ rk322x-cpu-hs.dtbo ++ ++scr-$(CONFIG_ARCH_ROCKCHIP) += \ ++ rk322x-fixup.scr ++ ++dtbotxt-$(CONFIG_ARCH_ROCKCHIP) += \ ++ README.rk322x-overlays ++ ++targets += $(dtbo-y) $(scr-y) $(dtbotxt-y) ++ ++always := $(dtbo-y) $(scr-y) $(dtbotxt-y) ++clean-files := *.dtbo *.scr ++ +diff --git a/arch/arm/boot/dts/overlay/README.rk322x-overlays b/arch/arm/boot/dts/overlay/README.rk322x-overlays +new file mode 100644 +index 000000000..d5bc7f3d5 +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/README.rk322x-overlays +@@ -0,0 +1,51 @@ ++This document describes overlays provided in the kernel packages ++For generic Armbian overlays documentation please see ++https://docs.armbian.com/User-Guide_Allwinner_overlays/ ++ ++### Platform: ++ ++rk322x (Rockchip) ++ ++### Provided overlays: ++ ++- rk322x-cpu-hs ++- rk322x-emmc ++- rk322x-nand ++- rk322x-emmc-nand ++- rk322x-led1-low ++- rk322x-led1-high ++- rk322x-led2-low ++- rk322x-led2-high ++ ++### Overlay details: ++ ++### rk322x-cpu-hs ++ ++Activates higher CPU speed (up to 1.4ghz) for rk3228b/rk3229 boxes ++ ++### emmc ++ ++Activates onboard emmc device node and deactivates the nand controller. ++Also sets up the pin controller default pull up/down configuration ++ ++### nand ++ ++Activates onboard nand device node and deactivates the emmc controller. ++Also sets up the pin controller default pull up/down configuration ++ ++### emmc-nand ++ ++Activates onboard nand and emmc devices. Usually they are alternative ++because manufacturers share the same pads so emmc and nand cannot be ++mixed together. Usually this works because the emmc and nand drivers ++can automatically guess what's in the pads, but may bring instabilities ++or misdetections. Also does not set up the pin controller default ++configuration, which in turn can be detrimental of stability and ++performance ++ ++### rk322x-led-conf* ++ ++Each device tree of this kind provides a different known wiring configuration ++(ie: gpio and active low/high) of the onboard leds. Each board manufacturer ++usually choose a different GPIO for the auxiliary led, but the main "working" ++led is always wired to the same gpio (although it may be active high or low) +diff --git a/arch/arm/boot/dts/overlay/rk322x-cpu-hs.dts b/arch/arm/boot/dts/overlay/rk322x-cpu-hs.dts +new file mode 100644 +index 000000000..1c2fc79e1 +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/rk322x-cpu-hs.dts +@@ -0,0 +1,28 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ ++ fragment@0 { ++ target = <&cpu0_opp_table>; ++ __overlay__ { ++ ++ opp-1296000000 { ++ opp-hz = /bits/ 64 <1296000000>; ++ opp-microvolt = <1325000 1325000 1400000>; ++ }; ++ opp-1392000000 { ++ opp-hz = /bits/ 64 <1392000000>; ++ opp-microvolt = <1350000 1350000 1400000>; ++ }; ++ /* ++ opp-1464000000 { ++ opp-hz = /bits/ 64 <1464000000>; ++ opp-microvolt = <1400000 1400000 1400000>; ++ }; ++ */ ++ ++ }; ++ }; ++ ++}; +diff --git a/arch/arm/boot/dts/overlay/rk322x-emmc-nand.dts b/arch/arm/boot/dts/overlay/rk322x-emmc-nand.dts +new file mode 100644 +index 000000000..9b273bf75 +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/rk322x-emmc-nand.dts +@@ -0,0 +1,22 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ ++ fragment@0 { ++ target = <&emmc>; ++ __overlay__ { ++ status = "okay"; ++ mmc-ddr-1_8v; ++ rockchip,default-sample-phase = <180>; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&nfc>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++}; +diff --git a/arch/arm/boot/dts/overlay/rk322x-emmc.dts b/arch/arm/boot/dts/overlay/rk322x-emmc.dts +new file mode 100644 +index 000000000..10b2f0f0d +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/rk322x-emmc.dts +@@ -0,0 +1,24 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ ++ fragment@0 { ++ target = <&emmc>; ++ __overlay__ { ++ status = "okay"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8 &emmc_pwr &emmc_rst>; ++ mmc-ddr-1_8v; ++ rockchip,default-sample-phase = <180>; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&nfc>; ++ __overlay__ { ++ status = "disabled"; ++ }; ++ }; ++ ++}; +diff --git a/arch/arm/boot/dts/overlay/rk322x-fixup.scr-cmd b/arch/arm/boot/dts/overlay/rk322x-fixup.scr-cmd +new file mode 100644 +index 000000000..d4c39e20a +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/rk322x-fixup.scr-cmd +@@ -0,0 +1,4 @@ ++# overlays fixup script ++# implements (or rather substitutes) overlay arguments functionality ++# using u-boot scripting, environment variables and "fdt" command ++ +diff --git a/arch/arm/boot/dts/overlay/rk322x-led-conf1.dts b/arch/arm/boot/dts/overlay/rk322x-led-conf1.dts +new file mode 100644 +index 000000000..faaee4070 +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/rk322x-led-conf1.dts +@@ -0,0 +1,41 @@ ++/dts-v1/; ++/plugin/; ++ ++#include ++#include ++ ++/ { ++ ++ fragment@0 { ++ target-path = "/gpio-leds"; ++ __overlay__ { ++ ++ working { ++ gpios = <&gpio3 RK_PC5 GPIO_ACTIVE_HIGH>; ++ linux,default-trigger = "none"; ++ }; ++ ++ auxiliary { ++ gpios = <&gpio0 RK_PA1 GPIO_ACTIVE_HIGH>; ++ label = "auxiliary"; ++ linux,default-trigger = "mmc2"; ++ default-state = "off"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&gpio_led_aux>; ++ }; ++ ++ }; ++ }; ++ ++ fragment@1 { ++ target-path = "/pinctrl/gpio"; ++ __overlay__ { ++ ++ gpio_led_aux: gpio-led-aux { ++ rockchip,pins = <0 RK_PA1 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ ++ }; ++ }; ++ ++}; +diff --git a/arch/arm/boot/dts/overlay/rk322x-led-conf2.dts b/arch/arm/boot/dts/overlay/rk322x-led-conf2.dts +new file mode 100644 +index 000000000..bbf2b0ee0 +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/rk322x-led-conf2.dts +@@ -0,0 +1,42 @@ ++/dts-v1/; ++/plugin/; ++ ++#include ++#include ++ ++/ { ++ ++ fragment@0 { ++ target-path = "/gpio-leds"; ++ __overlay__ { ++ ++ working { ++ gpios = <&gpio3 RK_PC5 GPIO_ACTIVE_LOW>; ++ linux,default-trigger = "none"; ++ }; ++ ++ auxiliary { ++ gpios = <&gpio1 RK_PA7 GPIO_ACTIVE_LOW>; ++ label = "auxiliary"; ++ linux,default-trigger = "mmc2"; ++ default-state = "off"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&gpio_led_aux>; ++ }; ++ ++ }; ++ }; ++ ++ fragment@1 { ++ target-path = "/pinctrl/gpio"; ++ __overlay__ { ++ ++ gpio_led_aux: gpio-led-aux { ++ rockchip,pins = <1 RK_PA7 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ ++ }; ++ }; ++ ++ ++}; +diff --git a/arch/arm/boot/dts/overlay/rk322x-nand.dts b/arch/arm/boot/dts/overlay/rk322x-nand.dts +new file mode 100644 +index 000000000..2a939ab49 +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/rk322x-nand.dts +@@ -0,0 +1,22 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ ++ fragment@0 { ++ target = <&nfc>; ++ __overlay__ { ++ status = "okay"; ++ pinctrl-0 = <&flash_cs0 &flash_cs1 &flash_cs2 &flash_cs3 &flash_rdy &flash_ale &flash_cle &flash_wrn &flash_bus8 &flash_dqs &flash_wp>; ++ pinctrl-names = "default"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&emmc>; ++ __overlay__ { ++ status = "disabled"; ++ }; ++ }; ++ ++}; diff --git a/patch/kernel/rk322x-current/linux.999.03-arm-vdso-add-vdso_clock_gettime64-phys-timer-syscall.patch b/patch/kernel/rk322x-current/linux.999.03-arm-vdso-add-vdso_clock_gettime64-phys-timer-syscall.patch new file mode 100644 index 0000000000..8bef6a5996 --- /dev/null +++ b/patch/kernel/rk322x-current/linux.999.03-arm-vdso-add-vdso_clock_gettime64-phys-timer-syscall.patch @@ -0,0 +1,12 @@ +diff --git a/arch/arm/kernel/vdso.c b/arch/arm/kernel/vdso.c +index e0330a25e1..28cfe7bad1 100644 +--- a/arch/arm/kernel/vdso.c ++++ b/arch/arm/kernel/vdso.c +@@ -184,6 +184,7 @@ static void __init patch_vdso(void *ehdr) + if (!cntvct_ok) { + vdso_nullpatch_one(&einfo, "__vdso_gettimeofday"); + vdso_nullpatch_one(&einfo, "__vdso_clock_gettime"); ++ vdso_nullpatch_one(&einfo, "__vdso_clock_gettime64"); + } + } + diff --git a/patch/kernel/rk322x-legacy/01-linux-0000-Revert-rk-add-gcc-wrapper.patch b/patch/kernel/rk322x-legacy/01-linux-0000-Revert-rk-add-gcc-wrapper.patch new file mode 100644 index 0000000000..b5d30ff740 --- /dev/null +++ b/patch/kernel/rk322x-legacy/01-linux-0000-Revert-rk-add-gcc-wrapper.patch @@ -0,0 +1,27 @@ +From a968000cae7b5d0c3c10b4e5a94fd187c891ee08 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Wed, 27 Dec 2017 22:01:06 +0100 +Subject: [PATCH] Revert "rk: add gcc-wrapper" + +This reverts part of commit 7a51384d24fe4da183fc15b2d17aa3c153b822e7. +--- + Makefile | 6 ------ + 1 file changed, 6 deletions(-) + +diff --git a/Makefile b/Makefile +index a785aeed4674..d34c20a89fb7 100644 +--- a/Makefile ++++ b/Makefile +@@ -372,12 +372,6 @@ PERL = perl + PYTHON = python + CHECK = sparse + +-# Use the wrapper for the compiler. This wrapper scans for new +-# warnings and causes the build to stop upon encountering them. +-ifneq ($(wildcard $(srctree)/scripts/gcc-wrapper.py),) +-CC = $(srctree)/scripts/gcc-wrapper.py $(CROSS_COMPILE)gcc +-endif +- + CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ -Dunix -D__unix__ \ + -Wbitwise -Wno-return-void $(CF) + CFLAGS_MODULE = diff --git a/patch/kernel/rk322x-legacy/01-linux-0001-rockchip.patch b/patch/kernel/rk322x-legacy/01-linux-0001-rockchip.patch new file mode 100644 index 0000000000..383844dcc3 --- /dev/null +++ b/patch/kernel/rk322x-legacy/01-linux-0001-rockchip.patch @@ -0,0 +1,1206 @@ +From 92b97663794c1ad57aaf7e66ee418bfce635a494 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Mon, 17 Apr 2017 13:09:16 +0200 +Subject: [PATCH] sound/usb/quirks-table: add Realtek ALC4040 + +--- + sound/usb/quirks-table.h | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h +index 69bf5cf1e91e..00672a818145 100644 +--- a/sound/usb/quirks-table.h ++++ b/sound/usb/quirks-table.h +@@ -3324,4 +3324,13 @@ AU0828_DEVICE(0x2040, 0x7270, "Hauppauge", "HVR-950Q"), + } + }, + ++{ ++ USB_DEVICE(0x0bda, 0x481a), ++ .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) { ++ .vendor_name = "Realtek", ++ .product_name = "ALC4040", ++ .ifnum = QUIRK_NO_INTERFACE ++ } ++}, ++ + #undef USB_DEVICE_VENDOR_SPEC + +From 0fcd82216c0161c9dd6b54ee505988c539df91fb Mon Sep 17 00:00:00 2001 +From: LongChair +Date: Fri, 21 Apr 2017 13:39:12 +0200 +Subject: [PATCH] drm/rockchip: remove unsupported 4K freqs + +--- + drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +index a58edabe600c..7273561fe6b1 100644 +--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c ++++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +@@ -510,9 +510,15 @@ dw_hdmi_rockchip_mode_valid(struct drm_connector *connector, + return MODE_BAD; + + hdmi = to_rockchip_hdmi(encoder); +- if (hdmi->dev_type == RK3368_HDMI && mode->clock > 340000 && ++ if ((hdmi->dev_type == RK3368_HDMI || hdmi->dev_type == RK3328_HDMI) && ++ mode->clock > 340000 && + !drm_mode_is_420(&connector->display_info, mode)) + return MODE_BAD; ++ ++ /* Skip bad clocks for RK3288 */ ++ if (hdmi->dev_type == RK3288_HDMI && (mode->clock < 27500 || mode->clock > 340000)) ++ return MODE_CLOCK_RANGE; ++ + /* + * ensure all drm display mode can work, if someone want support more + * resolutions, please limit the possible_crtc, only connect to + +From 28e3e0508d53dd697fc3dd75588bba08adee1bb0 Mon Sep 17 00:00:00 2001 +From: xuhuicong +Date: Fri, 23 Jun 2017 18:56:17 +0800 +Subject: [PATCH] drm/rockchip: hdmi: fix no sound some time + +Change-Id: Ic9f931d9a5b7bca954363293a20ca242eb0bfa6f +Signed-off-by: xuhuicong +--- + drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +index 8cb2cb4e61a6..30b6bd979eb8 100644 +--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c ++++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +@@ -1991,10 +1991,6 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi, + HDMI_FC_INVIDCONF_IN_I_P_INTERLACED : + HDMI_FC_INVIDCONF_IN_I_P_PROGRESSIVE; + +- inv_val |= hdmi->sink_is_hdmi ? +- HDMI_FC_INVIDCONF_DVI_MODEZ_HDMI_MODE : +- HDMI_FC_INVIDCONF_DVI_MODEZ_DVI_MODE; +- + hdmi_writeb(hdmi, inv_val, HDMI_FC_INVIDCONF); + + hdisplay = mode->hdisplay; +@@ -2292,6 +2288,9 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode *mode) + /* not for DVI mode */ + if (hdmi->sink_is_hdmi) { + dev_dbg(hdmi->dev, "%s HDMI mode\n", __func__); ++ hdmi_modb(hdmi, HDMI_FC_INVIDCONF_DVI_MODEZ_HDMI_MODE, ++ HDMI_FC_INVIDCONF_DVI_MODEZ_HDMI_MODE, ++ HDMI_FC_INVIDCONF); + + /* HDMI Initialization Step F - Configure AVI InfoFrame */ + hdmi_config_AVI(hdmi, mode); + +From 16f51adab10ab06bfecbd0ed9e444329debb426d Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sat, 18 Nov 2017 11:09:39 +0100 +Subject: [PATCH] rockchip: vop: force skip lines if image too big + +--- + drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 13 ++++++++++--- + 1 file changed, 10 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +index 76610608c723..1418402c2668 100644 +--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +@@ -1653,6 +1653,7 @@ static void vop_plane_atomic_update(struct drm_plane *plane, + int ymirror, xmirror; + uint32_t val; + bool rb_swap, global_alpha_en; ++ int skip_lines = 0; + + #if defined(CONFIG_ROCKCHIP_DRM_DEBUG) + bool AFBC_flag = false; +@@ -1689,8 +1690,14 @@ static void vop_plane_atomic_update(struct drm_plane *plane, + } + + mode = &crtc->state->adjusted_mode; ++ ++ /* ++ * force skip lines if image too big. ++ */ + actual_w = drm_rect_width(src) >> 16; +- actual_h = drm_rect_height(src) >> 16; ++ if (actual_w == 3840 && is_yuv_support(fb->pixel_format)) ++ skip_lines = 1; ++ actual_h = drm_rect_height(src) >> (16 + skip_lines); + act_info = (actual_h - 1) << 16 | ((actual_w - 1) & 0xffff); + + dsp_info = (drm_rect_height(dest) - 1) << 16; +@@ -1727,12 +1734,12 @@ static void vop_plane_atomic_update(struct drm_plane *plane, + VOP_WIN_SET(vop, win, xmirror, xmirror); + VOP_WIN_SET(vop, win, ymirror, ymirror); + VOP_WIN_SET(vop, win, format, vop_plane_state->format); +- VOP_WIN_SET(vop, win, yrgb_vir, fb->pitches[0] >> 2); ++ VOP_WIN_SET(vop, win, yrgb_vir, fb->pitches[0] >> (2 - skip_lines)); + VOP_WIN_SET(vop, win, yrgb_mst, vop_plane_state->yrgb_mst); + VOP_WIN_SET(vop, win, yrgb_mst1, vop_plane_state->yrgb_mst); + + if (is_yuv_support(fb->pixel_format)) { +- VOP_WIN_SET(vop, win, uv_vir, fb->pitches[1] >> 2); ++ VOP_WIN_SET(vop, win, uv_vir, fb->pitches[1] >> (2 - skip_lines)); + VOP_WIN_SET(vop, win, uv_mst, vop_plane_state->uv_mst); + } + VOP_WIN_SET(vop, win, fmt_10, is_yuv_10bit(fb->pixel_format)); + +From d56d2c8dcd6dc828693bed0cf965d68e90431019 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sat, 18 Nov 2017 23:17:24 +0100 +Subject: [PATCH] gpu/arm/midgard: default to performance gpu governor + +--- + drivers/gpu/arm/midgard/backend/gpu/mali_kbase_devfreq.c | 5 ++--- + drivers/gpu/arm/midgard/mali_kbase_config_defaults.h | 3 +-- + 2 files changed, 3 insertions(+), 5 deletions(-) + +diff --git a/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_devfreq.c b/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_devfreq.c +index 1495f06cd9b9..a6d2e0121015 100644 +--- a/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_devfreq.c ++++ b/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_devfreq.c +@@ -348,8 +348,7 @@ int kbase_devfreq_init(struct kbase_device *kbdev) + dp = &kbdev->devfreq_profile; + + dp->initial_freq = kbdev->current_freq; +- /* .KP : set devfreq_dvfs_interval_in_ms */ +- dp->polling_ms = 20; ++ dp->polling_ms = 100; + dp->target = kbase_devfreq_target; + dp->get_dev_status = kbase_devfreq_status; + dp->get_cur_freq = kbase_devfreq_cur_freq; +diff --git a/drivers/gpu/arm/midgard/mali_kbase_config_defaults.h b/drivers/gpu/arm/midgard/mali_kbase_config_defaults.h +index 1cf44b3500cf..a6a1a52f0463 100644 +--- a/drivers/gpu/arm/midgard/mali_kbase_config_defaults.h ++++ b/drivers/gpu/arm/midgard/mali_kbase_config_defaults.h +@@ -109,8 +109,7 @@ enum { + /* + * Default period for DVFS sampling + */ +-// #define DEFAULT_PM_DVFS_PERIOD 100 /* 100ms */ +-#define DEFAULT_PM_DVFS_PERIOD 20 /* 20 ms */ ++#define DEFAULT_PM_DVFS_PERIOD 100 /* 100ms */ + + /* + * Power Management poweroff tick granuality. This is in nanoseconds to + +From 955a2a87c8fa737d78c022afef1ed32fd6f06760 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 10 Dec 2017 14:16:09 +0100 +Subject: [PATCH] uapi: install rockchip_drm header + +--- + include/uapi/drm/Kbuild | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/include/uapi/drm/Kbuild b/include/uapi/drm/Kbuild +index 38d437096c35..b7ae9969d41e 100644 +--- a/include/uapi/drm/Kbuild ++++ b/include/uapi/drm/Kbuild +@@ -11,6 +11,7 @@ header-y += nouveau_drm.h + header-y += qxl_drm.h + header-y += r128_drm.h + header-y += radeon_drm.h ++header-y += rockchip_drm.h + header-y += savage_drm.h + header-y += sis_drm.h + header-y += tegra_drm.h + +From b4da8f58954748a2d459d5e480156ee2703ea169 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 10 Dec 2017 18:03:53 +0100 +Subject: [PATCH] phy: rockchip-inno-hdmi-phy: add vesa dmt pixel clocks + +--- + drivers/phy/rockchip/phy-rockchip-inno-hdmi-phy.c | 64 +++++++++++++++++++++++ + 1 file changed, 64 insertions(+) + +diff --git a/drivers/phy/rockchip/phy-rockchip-inno-hdmi-phy.c b/drivers/phy/rockchip/phy-rockchip-inno-hdmi-phy.c +index 0161f80ab964..6cf391405ad6 100644 +--- a/drivers/phy/rockchip/phy-rockchip-inno-hdmi-phy.c ++++ b/drivers/phy/rockchip/phy-rockchip-inno-hdmi-phy.c +@@ -278,6 +278,70 @@ static const struct pre_pll_config pre_pll_cfg_table[] = { + {594000000, 371250000, 4, 495, 1, 2, 0, 1, 3, 1, 1, 1, 0}, + {593407000, 593407000, 1, 98, 0, 2, 0, 1, 0, 1, 1, 0, 0xE6AE6B}, + {594000000, 594000000, 1, 99, 0, 2, 0, 1, 0, 1, 1, 0, 0}, ++ { 25175000, 25175000, 30, 1007, 1, 2, 2, 1, 2, 3, 4, 0, 0}, ++ { 31500000, 31500000, 1, 21, 1, 1, 1, 1, 2, 2, 2, 0, 0}, ++ { 33750000, 33750000, 1, 45, 1, 2, 2, 1, 2, 3, 4, 0, 0}, ++ { 35500000, 35500000, 3, 71, 1, 1, 1, 1, 2, 2, 2, 0, 0}, ++ { 36000000, 36000000, 1, 12, 0, 1, 1, 1, 0, 2, 2, 0, 0}, ++ { 49500000, 49500000, 1, 33, 1, 1, 1, 1, 2, 2, 2, 0, 0}, ++ { 50000000, 50000000, 3, 50, 0, 1, 1, 1, 0, 2, 2, 0, 0}, ++ { 56250000, 56250000, 1, 75, 1, 2, 2, 1, 2, 3, 4, 0, 0}, ++ { 68250000, 68250000, 1, 91, 1, 2, 2, 1, 2, 3, 4, 0, 0}, ++ { 72000000, 72000000, 1, 24, 0, 1, 1, 1, 0, 2, 2, 0, 0}, ++ { 73250000, 73250000, 3, 293, 1, 2, 2, 1, 2, 3, 4, 0, 0}, ++ { 75000000, 75000000, 1, 25, 0, 1, 1, 1, 0, 2, 2, 0, 0}, ++ { 78750000, 78750000, 1, 105, 1, 2, 2, 1, 2, 3, 4, 0, 0}, ++ { 79500000, 79500000, 1, 53, 1, 1, 1, 1, 2, 2, 2, 0, 0}, ++ { 85500000, 85500000, 1, 57, 1, 1, 1, 1, 2, 2, 2, 0, 0}, ++ { 94500000, 94500000, 1, 63, 1, 1, 1, 1, 2, 2, 2, 0, 0}, ++ {101000000, 101000000, 3, 101, 0, 1, 1, 1, 0, 2, 2, 0, 0}, ++ {102250000, 102250000, 3, 409, 1, 2, 2, 1, 2, 3, 4, 0, 0}, ++ {106500000, 106500000, 1, 71, 1, 1, 1, 1, 2, 2, 2, 0, 0}, ++ {115500000, 115500000, 1, 77, 1, 1, 1, 1, 2, 2, 2, 0, 0}, ++ {117500000, 117500000, 3, 235, 1, 1, 1, 1, 2, 2, 2, 0, 0}, ++ {121750000, 121750000, 3, 487, 1, 2, 2, 1, 2, 3, 4, 0, 0}, ++ {122500000, 122500000, 3, 245, 1, 1, 1, 1, 2, 2, 2, 0, 0}, ++ {135000000, 135000000, 1, 45, 0, 1, 1, 1, 0, 2, 2, 0, 0}, ++ {136750000, 136750000, 3, 547, 1, 2, 2, 1, 2, 3, 4, 0, 0}, ++ {140250000, 140250000, 1, 187, 1, 2, 2, 1, 2, 3, 4, 0, 0}, ++ {146250000, 146250000, 1, 195, 1, 2, 2, 1, 2, 3, 4, 0, 0}, ++ {148250000, 148250000, 3, 593, 1, 2, 2, 1, 2, 3, 4, 0, 0}, ++ {154000000, 154000000, 3, 154, 0, 1, 1, 1, 0, 2, 2, 0, 0}, ++ {156000000, 156000000, 1, 52, 0, 1, 1, 1, 0, 2, 2, 0, 0}, ++ {156750000, 156750000, 1, 209, 1, 2, 2, 1, 2, 3, 4, 0, 0}, ++ {157000000, 157000000, 3, 157, 0, 1, 1, 1, 0, 2, 2, 0, 0}, ++ {157500000, 157500000, 1, 105, 1, 1, 1, 1, 2, 2, 2, 0, 0}, ++ {175500000, 175500000, 1, 117, 1, 1, 1, 1, 2, 2, 2, 0, 0}, ++ {179500000, 179500000, 3, 359, 1, 1, 1, 1, 2, 2, 2, 0, 0}, ++ {182750000, 182750000, 3, 731, 1, 2, 2, 1, 2, 3, 4, 0, 0}, ++ {187000000, 187000000, 3, 187, 0, 1, 1, 1, 0, 2, 2, 0, 0}, ++ {187250000, 187250000, 3, 749, 1, 2, 2, 1, 2, 3, 4, 0, 0}, ++ {189000000, 189000000, 1, 63, 0, 1, 1, 1, 0, 2, 2, 0, 0}, ++ {193250000, 193250000, 3, 773, 1, 2, 2, 1, 2, 3, 4, 0, 0}, ++ {202500000, 202500000, 1, 135, 1, 1, 1, 1, 2, 2, 2, 0, 0}, ++ {204750000, 204750000, 1, 273, 1, 2, 2, 1, 2, 3, 4, 0, 0}, ++ {208000000, 208000000, 3, 208, 0, 1, 1, 1, 0, 2, 2, 0, 0}, ++ {214750000, 214750000, 3, 859, 1, 2, 2, 1, 2, 3, 4, 0, 0}, ++ {218250000, 218250000, 1, 291, 1, 2, 2, 1, 2, 3, 4, 0, 0}, ++ {229500000, 229500000, 1, 153, 1, 1, 1, 1, 2, 2, 2, 0, 0}, ++ {234000000, 234000000, 1, 78, 0, 1, 1, 1, 0, 2, 2, 0, 0}, ++ {241500000, 241500000, 1, 161, 1, 1, 1, 1, 2, 2, 2, 0, 0}, ++ {245250000, 245250000, 1, 327, 1, 2, 2, 1, 2, 3, 4, 0, 0}, ++ {245500000, 245500000, 3, 491, 1, 1, 1, 1, 2, 2, 2, 0, 0}, ++ {261000000, 261000000, 1, 87, 0, 1, 1, 1, 0, 2, 2, 0, 0}, ++ {268250000, 268250000, 3, 1073, 1, 2, 2, 1, 2, 3, 4, 0, 0}, ++ {268500000, 268500000, 1, 179, 1, 1, 1, 1, 2, 2, 2, 0, 0}, ++ {281250000, 281250000, 1, 375, 1, 2, 2, 1, 2, 3, 4, 0, 0}, ++ {288000000, 288000000, 1, 96, 0, 1, 1, 1, 0, 2, 2, 0, 0}, ++ {312250000, 312250000, 3, 1249, 1, 2, 2, 1, 2, 3, 4, 0, 0}, ++ {317000000, 317000000, 3, 317, 0, 1, 1, 1, 0, 2, 2, 0, 0}, ++ {333250000, 333250000, 3, 1333, 1, 2, 2, 1, 2, 3, 4, 0, 0}, ++ {348500000, 348500000, 3, 697, 1, 1, 1, 1, 2, 2, 2, 0, 0}, ++ {356500000, 356500000, 3, 713, 1, 1, 1, 1, 2, 2, 2, 0, 0}, ++ {380500000, 380500000, 3, 761, 1, 1, 1, 1, 2, 2, 2, 0, 0}, ++ {443250000, 443250000, 1, 591, 1, 2, 2, 1, 2, 3, 4, 0, 0}, ++ {505250000, 505250000, 3, 2021, 1, 2, 2, 1, 2, 3, 4, 0, 0}, ++ {552750000, 552750000, 1, 737, 1, 2, 2, 1, 2, 3, 4, 0, 0}, + { ~0UL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + }; + + +From f3f9dc1c2c697f0c9fefd501731a07ef64a026b1 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Tue, 12 Dec 2017 00:37:27 +0100 +Subject: [PATCH] clk: rockchip: fix round rate + +--- + drivers/clk/rockchip/clk-pll.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/drivers/clk/rockchip/clk-pll.c b/drivers/clk/rockchip/clk-pll.c +index 0a9f31f2dd27..183114d824a7 100644 +--- a/drivers/clk/rockchip/clk-pll.c ++++ b/drivers/clk/rockchip/clk-pll.c +@@ -364,6 +364,17 @@ static const struct rockchip_pll_rate_table *rockchip_get_pll_settings( + static long rockchip_pll_round_rate(struct clk_hw *hw, + unsigned long drate, unsigned long *prate) + { ++ struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw); ++ const struct rockchip_pll_rate_table *rate; ++ ++ /* Get required rate settings from table */ ++ rate = rockchip_get_pll_settings(pll, drate); ++ if (!rate) { ++ pr_debug("%s: Invalid rate : %lu for pll clk %s\n", __func__, ++ drate, __clk_get_name(hw->clk)); ++ return -EINVAL; ++ } ++ + return drate; + } + + +From 5a5f5ea8edcc75ca49961a458ac0380e60f30a4d Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 21 Jan 2018 17:20:00 +0100 +Subject: [PATCH] drm: fix HDR metadata infoframe length + +HDR metadata infoframe length is 26 bytes (not 30) according to [1] +(CTA-861-G: 6.9 Dynamic Range and Mastering InfoFrame) + +Fixes activation of HDR mode on my LG OLED + +[1] https://standards.cta.tech/kwspub/published_docs/CTA-861-G_FINAL_revised_2017.pdf +--- + drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 2 +- + drivers/gpu/drm/drm_edid.c | 4 ++-- + 2 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +index 30b6bd979eb8..ec002a4a7a7d 100644 +--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c ++++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +@@ -1857,7 +1857,7 @@ static void hdmi_config_hdr_infoframe(struct dw_hdmi *hdmi) + return; + } + +- hdmi_writeb(hdmi, 1, HDMI_FC_DRM_HB0); ++ hdmi_writeb(hdmi, frame.version, HDMI_FC_DRM_HB0); + hdmi_writeb(hdmi, frame.length, HDMI_FC_DRM_HB1); + hdmi_writeb(hdmi, frame.eotf, HDMI_FC_DRM_PB0); + hdmi_writeb(hdmi, frame.metadata_type, HDMI_FC_DRM_PB1); +diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c +index bfe671071d9f..e3a0f561e8f0 100644 +--- a/drivers/gpu/drm/drm_edid.c ++++ b/drivers/gpu/drm/drm_edid.c +@@ -4735,10 +4735,10 @@ drm_hdmi_infoframe_set_hdr_metadata(struct hdmi_drm_infoframe *frame, + + hdr_source_metadata = (struct hdr_static_metadata *)hdr_metadata; + +- frame->length = sizeof(struct hdr_static_metadata); ++ frame->length = 26; + + frame->eotf = hdr_source_metadata->eotf; +- frame->type = hdr_source_metadata->type; ++ frame->metadata_type = hdr_source_metadata->type; + + for (i = 0; i < 3; i++) { + frame->display_primaries_x[i] = + +From 19e9d690fe47e5e4b47760d060b11707bb44194b Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 11 Feb 2018 19:21:41 +0100 +Subject: [PATCH] drm: bridge: dw-hdmi: default to underscan mode + +--- + drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +index ec002a4a7a7d..393bd5b28f07 100644 +--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c ++++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +@@ -1691,7 +1691,7 @@ static void hdmi_config_AVI(struct dw_hdmi *hdmi, struct drm_display_mode *mode) + break; + } + +- frame.scan_mode = HDMI_SCAN_MODE_NONE; ++ frame.scan_mode = HDMI_SCAN_MODE_UNDERSCAN; + + /* + * The Designware IP uses a different byte format from standard + +From b492ddc8ae2777350db224d39346966080a140d6 Mon Sep 17 00:00:00 2001 +From: David Carrillo-Cisneros +Date: Tue, 18 Jul 2017 18:18:37 -0700 +Subject: [PATCH] UPSTREAM: perf tools: Add EXCLUDE_EXTLIBS and EXTRA_PERFLIBS + to makefile + +The goal is to allow users to override linking of libraries that +were automatically added to PERFLIBS. + +EXCLUDE_EXTLIBS contains linker flags to be removed from LIBS +while EXTRA_PERFLIBS contains linker flags to be added. + +My use case is to force certain library to be build statically, +e.g. for libelf: + + EXCLUDE_EXTLIBS=-lelf EXTRA_PERFLIBS=path/libelf.a + +Signed-off-by: David Carrillo-Cisneros +Acked-by: Jiri Olsa +Cc: Alexander Shishkin +Cc: Elena Reshetova +Cc: Kees Kook +Cc: Paul Turner +Cc: Stephane Eranian +Cc: Sudeep Holla +Cc: Wang Nan +Link: http://lkml.kernel.org/r/20170719011839.99399-3-davidcc@google.com +Signed-off-by: Arnaldo Carvalho de Melo +(cherry picked from commit cb281fea4b0a326d2a2104f8ffae2b6895c561fd) +--- + tools/perf/Makefile.perf | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf +index fb1c9ddc3478..9b3b9bd50d54 100644 +--- a/tools/perf/Makefile.perf ++++ b/tools/perf/Makefile.perf +@@ -33,6 +33,11 @@ include config/utilities.mak + # + # Define EXTRA_CFLAGS=-m64 or EXTRA_CFLAGS=-m32 as appropriate for cross-builds. + # ++# Define EXCLUDE_EXTLIBS=-lmylib to exclude libmylib from the auto-generated ++# EXTLIBS. ++# ++# Define EXTRA_PERFLIBS to pass extra libraries to PERFLIBS. ++# + # Define NO_DWARF if you do not want debug-info analysis feature at all. + # + # Define WERROR=0 to disable treating any warnings as errors. +@@ -289,7 +294,8 @@ ifdef ASCIIDOC8 + export ASCIIDOC8 + endif + +-LIBS = -Wl,--whole-archive $(PERFLIBS) -Wl,--no-whole-archive -Wl,--start-group $(EXTLIBS) -Wl,--end-group ++EXTLIBS := $(call filter-out,$(EXCLUDE_EXTLIBS),$(EXTLIBS)) ++LIBS = -Wl,--whole-archive $(PERFLIBS) $(EXTRA_PERFLIBS) -Wl,--no-whole-archive -Wl,--start-group $(EXTLIBS) -Wl,--end-group + + export INSTALL SHELL_PATH + + +From 163448e6d6d5d0bbc9486d43a2d06c5d86e28d34 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Tue, 27 Feb 2018 20:49:00 +0100 +Subject: [PATCH] net: wireless: rockchip_wlan: rtl8723bs: do not accept all + sdio wlan id + +--- + drivers/net/wireless/rockchip_wlan/rtl8723bs/Makefile | 2 +- + .../net/wireless/rockchip_wlan/rtl8723bs/os_dep/linux/sdio_intf.c | 8 ++++++++ + 2 files changed, 9 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bs/Makefile b/drivers/net/wireless/rockchip_wlan/rtl8723bs/Makefile +index fe9d5638a128..e8653b070efb 100644 +--- a/drivers/net/wireless/rockchip_wlan/rtl8723bs/Makefile ++++ b/drivers/net/wireless/rockchip_wlan/rtl8723bs/Makefile +@@ -1347,7 +1347,7 @@ EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN -DCONFIG_PLATFORM_ANDROID -DCONFIG_PLATFO + EXTRA_CFLAGS += -DCONFIG_IOCTL_CFG80211 -DRTW_USE_CFG80211_STA_EVENT + EXTRA_CFLAGS += -DCONFIG_CONCURRENT_MODE + # default setting for Power control +-EXTRA_CFLAGS += -DRTW_ENABLE_WIFI_CONTROL_FUNC ++#EXTRA_CFLAGS += -DRTW_ENABLE_WIFI_CONTROL_FUNC + EXTRA_CFLAGS += -DRTW_SUPPORT_PLATFORM_SHUTDOWN + EXTRA_CFLAGS += -DCONFIG_RESUME_IN_WORKQUEUE + # default setting for Special function +diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bs/os_dep/linux/sdio_intf.c b/drivers/net/wireless/rockchip_wlan/rtl8723bs/os_dep/linux/sdio_intf.c +index b4654d229634..e49e5cb8f21a 100644 +--- a/drivers/net/wireless/rockchip_wlan/rtl8723bs/os_dep/linux/sdio_intf.c ++++ b/drivers/net/wireless/rockchip_wlan/rtl8723bs/os_dep/linux/sdio_intf.c +@@ -45,6 +45,14 @@ static struct mmc_host *mmc_host = NULL; + + static const struct sdio_device_id sdio_ids[] = { + #ifdef CONFIG_RTL8723B ++ { SDIO_DEVICE(0x024c, 0x0240), .driver_data = RTL8723B}, ++ { SDIO_DEVICE(0x024c, 0x0241), .driver_data = RTL8723B}, ++ { SDIO_DEVICE(0x024c, 0x0523), .driver_data = RTL8723B}, ++ { SDIO_DEVICE(0x024c, 0x0524), .driver_data = RTL8723B}, ++ { SDIO_DEVICE(0x024c, 0x0623), .driver_data = RTL8723B}, ++ { SDIO_DEVICE(0x024c, 0x0624), .driver_data = RTL8723B}, ++ { SDIO_DEVICE(0x024c, 0x0626), .driver_data = RTL8723B}, ++ { SDIO_DEVICE(0x024c, 0x8753), .driver_data = RTL8723B}, + { SDIO_DEVICE(0x024c, 0xB723), .driver_data = RTL8723B}, + #endif + #ifdef CONFIG_RTL8188E + +From ba7c1fb0efcf29265c0c88d98f52919a21078e5b Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Fri, 2 Mar 2018 20:53:32 +0100 +Subject: [PATCH] net: wireless: rockchip_wlan: bcmdhd: detect broadcom sdio + device id + +--- + drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/bcmsdh_sdmmc_linux.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/bcmsdh_sdmmc_linux.c b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/bcmsdh_sdmmc_linux.c +index 8864582b1706..b5a388cc3cbe 100755 +--- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/bcmsdh_sdmmc_linux.c ++++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/bcmsdh_sdmmc_linux.c +@@ -225,7 +225,7 @@ static const struct sdio_device_id bcmsdh_sdmmc_ids[] = { + { SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4334) }, + { SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4324) }, + { SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_43239) }, +- { SDIO_DEVICE_CLASS(SDIO_CLASS_NONE) }, ++ { SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_ANY_ID) }, + { 0, 0, 0, 0 /* end: all zeroes */ + }, + }; + +From 922cc477bd191cbfddae005b27a2c89cb9c9623a Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 1 Jul 2018 23:17:47 +0200 +Subject: [PATCH] drm/rockchip: clip yuv + +--- + drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 2 ++ + drivers/gpu/drm/rockchip/rockchip_drm_vop.h | 2 ++ + drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 3 +++ + 3 files changed, 7 insertions(+) + +diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +index 1418402c2668..0916b4284f88 100644 +--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +@@ -1731,6 +1731,7 @@ static void vop_plane_atomic_update(struct drm_plane *plane, + s = to_rockchip_crtc_state(crtc->state); + + spin_lock(&vop->reg_lock); ++ VOP_WIN_SET(vop, win, yuv_clip, 0); + VOP_WIN_SET(vop, win, xmirror, xmirror); + VOP_WIN_SET(vop, win, ymirror, ymirror); + VOP_WIN_SET(vop, win, format, vop_plane_state->format); +@@ -2544,6 +2545,7 @@ static void vop_update_csc(struct drm_crtc *crtc) + VOP_CTRL_SET(vop, dsp_data_swap, 0); + + VOP_CTRL_SET(vop, out_mode, s->output_mode); ++ VOP_CTRL_SET(vop, yuv_clip, 0); + + switch (s->bus_format) { + case MEDIA_BUS_FMT_RGB565_1X16: +diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h +index 618de17e608a..391998c7aa50 100644 +--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h +@@ -178,6 +178,7 @@ struct vop_ctrl { + struct vop_reg dsp_lut_en; + + struct vop_reg out_mode; ++ struct vop_reg yuv_clip; + + struct vop_reg xmirror; + struct vop_reg ymirror; +@@ -409,6 +410,7 @@ struct vop_win_phy { + struct vop_reg format; + struct vop_reg fmt_10; + struct vop_reg csc_mode; ++ struct vop_reg yuv_clip; + struct vop_reg xmirror; + struct vop_reg ymirror; + struct vop_reg rb_swap; +diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c +index 9c96d5614e54..aeb1c7644bc9 100644 +--- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c ++++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c +@@ -119,6 +119,7 @@ static const struct vop_win_phy rk3288_win01_data = { + .fmt_10 = VOP_REG(RK3288_WIN0_CTRL0, 0x7, 4), + .csc_mode = VOP_REG_VER(RK3288_WIN0_CTRL0, 0x3, 10, 3, 2, -1), + .rb_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 12), ++ .yuv_clip = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 20), + .xmirror = VOP_REG_VER(RK3368_WIN0_CTRL0, 0x1, 21, 3, 2, -1), + .ymirror = VOP_REG_VER(RK3368_WIN0_CTRL0, 0x1, 22, 3, 2, -1), + .act_info = VOP_REG(RK3288_WIN0_ACT_INFO, 0x1fff1fff, 0), +@@ -286,6 +287,7 @@ static const struct vop_ctrl rk3288_ctrl_data = { + .bcsh_color_bar = VOP_REG(RK3288_BCSH_COLOR_BAR, 0xffffff, 8), + .bcsh_en = VOP_REG(RK3288_BCSH_COLOR_BAR, 0x1, 0), + ++ .yuv_clip = VOP_REG(RK3288_DSP_CTRL0, 0x1, 21), + .xmirror = VOP_REG(RK3288_DSP_CTRL0, 0x1, 22), + .ymirror = VOP_REG(RK3288_DSP_CTRL0, 0x1, 23), + +@@ -964,6 +966,7 @@ static const struct vop_ctrl rk3328_ctrl_data = { + .dsp_lut_en = VOP_REG(RK3328_DSP_CTRL1, 0x1, 0), + .out_mode = VOP_REG(RK3328_DSP_CTRL0, 0xf, 0), + ++ .yuv_clip = VOP_REG(RK3328_DSP_CTRL0, 0x1, 21), + .xmirror = VOP_REG(RK3328_DSP_CTRL0, 0x1, 22), + .ymirror = VOP_REG(RK3328_DSP_CTRL0, 0x1, 23), + + +From 991811443d72d7915afdee23c30843669a347d7c Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 8 Jul 2018 12:38:00 +0200 +Subject: [PATCH] drm/atomic: use active_only flag for connector atomic + begin/flush + +--- + drivers/gpu/drm/drm_atomic_helper.c | 20 ++++++++++---------- + 1 file changed, 10 insertions(+), 10 deletions(-) + +diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c +index f77d4aa1e58b..4da489b54dc5 100644 +--- a/drivers/gpu/drm/drm_atomic_helper.c ++++ b/drivers/gpu/drm/drm_atomic_helper.c +@@ -1563,15 +1563,15 @@ void drm_atomic_helper_commit_planes(struct drm_device *dev, + for_each_connector_in_state(old_state, connector, old_conn_state, i) { + const struct drm_connector_helper_funcs *funcs; + +- if (!connector->state->crtc) +- continue; ++ funcs = connector->helper_private; + +- if (!connector->state->crtc->state->active) ++ if (!funcs || !funcs->atomic_begin) + continue; + +- funcs = connector->helper_private; ++ if (!connector->state->crtc) ++ continue; + +- if (!funcs || !funcs->atomic_begin) ++ if (active_only && !connector->state->crtc->state->active) + continue; + + DRM_DEBUG_ATOMIC("flush beginning [CONNECTOR:%d:%s]\n", +@@ -1645,15 +1645,15 @@ void drm_atomic_helper_commit_planes(struct drm_device *dev, + for_each_connector_in_state(old_state, connector, old_conn_state, i) { + const struct drm_connector_helper_funcs *funcs; + +- if (!connector->state->crtc) +- continue; ++ funcs = connector->helper_private; + +- if (!connector->state->crtc->state->active) ++ if (!funcs || !funcs->atomic_flush) + continue; + +- funcs = connector->helper_private; ++ if (!connector->state->crtc) ++ continue; + +- if (!funcs || !funcs->atomic_flush) ++ if (active_only && !connector->state->crtc->state->active) + continue; + + DRM_DEBUG_ATOMIC("flushing [CONNECTOR:%d:%s]\n", + +From 8d514d5127fbb4d49247f893ac6b803cbdd3304d Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 22 Jul 2018 14:51:58 +0200 +Subject: [PATCH] drm: rockchip: dw-hdmi: only force YCbCr422 when max tmds is + up to 340Mhz + +--- + drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +index 7273561fe6b1..e2aad6e2149b 100644 +--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c ++++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +@@ -728,7 +728,9 @@ dw_hdmi_rockchip_select_output(struct drm_connector_state *conn_state, + /* BT2020 require color depth at lest 10bit */ + *color_depth = 10; + /* We prefer use YCbCr422 to send 10bit */ +- if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422) ++ if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422 && ++ info->max_tmds_clock <= 340000 && ++ hdmi->dev_type != RK3288_HDMI) + *color_format = DRM_HDMI_OUTPUT_YCBCR422; + } + +--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c ++++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +@@ -510,11 +510,18 @@ + return MODE_BAD; + + hdmi = to_rockchip_hdmi(encoder); +- if ((hdmi->dev_type == RK3368_HDMI || hdmi->dev_type == RK3328_HDMI) && ++ if ((hdmi->dev_type == RK3368_HDMI || hdmi->dev_type == RK3328_HDMI || ++ hdmi->dev_type == RK3228_HDMI) && + mode->clock > 340000 && + !drm_mode_is_420(&connector->display_info, mode)) + return MODE_BAD; + ++ /* Skip (detectable) fractional rates for RK3228 */ ++ if (hdmi->dev_type == RK3228_HDMI && ++ (mode->clock == 59341 || mode->clock == 74176 || mode->clock == 148352 || ++ mode->clock == 296703 || mode->clock == 593407)) ++ return MODE_BAD; ++ + /* Skip bad clocks for RK3288 */ + if (hdmi->dev_type == RK3288_HDMI && (mode->clock < 27500 || mode->clock > 340000)) + return MODE_CLOCK_RANGE; +From 9d6de32c2e992b71e6634a284dc99ab1b3bd43e2 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 22 Jul 2018 15:09:16 +0200 +Subject: [PATCH] drm: bridge: dw-hdmi: signal full range for rgb output + +--- + drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +index 393bd5b28f07..91c5b8fc8fa0 100644 +--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c ++++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +@@ -1693,6 +1693,14 @@ static void hdmi_config_AVI(struct dw_hdmi *hdmi, struct drm_display_mode *mode) + + frame.scan_mode = HDMI_SCAN_MODE_UNDERSCAN; + ++ if (hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_out_bus_format)) { ++ frame.quantization_range = HDMI_QUANTIZATION_RANGE_FULL; ++ frame.ycc_quantization_range = HDMI_YCC_QUANTIZATION_RANGE_FULL; ++ } else { ++ frame.quantization_range = HDMI_QUANTIZATION_RANGE_LIMITED; ++ frame.ycc_quantization_range = HDMI_YCC_QUANTIZATION_RANGE_LIMITED; ++ } ++ + /* + * The Designware IP uses a different byte format from standard + * AVI info frames, though generally the bits are in the correct + +From 35c0ac957d5fcec21d807e801efed57a37c41d9d Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sat, 28 Jul 2018 10:41:40 +0200 +Subject: [PATCH] WIP: mm: dma-mapping: increase dma pool size + +--- + arch/arm/mm/dma-mapping.c | 2 +- + arch/arm64/mm/dma-mapping.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c +index d539dee3c78d..689961153d71 100644 +--- a/arch/arm/mm/dma-mapping.c ++++ b/arch/arm/mm/dma-mapping.c +@@ -301,7 +301,7 @@ static void __dma_free_remap(void *cpu_addr, size_t size) + VM_ARM_DMA_CONSISTENT | VM_USERMAP); + } + +-#define DEFAULT_DMA_COHERENT_POOL_SIZE SZ_256K ++#define DEFAULT_DMA_COHERENT_POOL_SIZE SZ_2M + static struct gen_pool *atomic_pool; + + static size_t atomic_pool_size = DEFAULT_DMA_COHERENT_POOL_SIZE; +diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c +index 2b05653e8156..2ad8515cd4da 100644 +--- a/arch/arm64/mm/dma-mapping.c ++++ b/arch/arm64/mm/dma-mapping.c +@@ -32,7 +32,7 @@ + + static struct gen_pool *atomic_pool; + +-#define DEFAULT_DMA_COHERENT_POOL_SIZE SZ_256K ++#define DEFAULT_DMA_COHERENT_POOL_SIZE SZ_2M + static size_t atomic_pool_size __initdata = DEFAULT_DMA_COHERENT_POOL_SIZE; + + static int __init early_coherent_pool(char *p) + +From 24a070f21767a8d381b81ab5fc5f39c2b9729b24 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sat, 4 Aug 2018 15:19:39 +0200 +Subject: [PATCH] drm: add picture_aspect_ratio to hdmi 1.4 4k modes + +--- + drivers/gpu/drm/drm_edid.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c +index f7d41950614e..69a1eb4ee382 100644 +--- a/drivers/gpu/drm/drm_edid.c ++++ b/drivers/gpu/drm/drm_edid.c +@@ -1233,25 +1233,25 @@ static const struct drm_display_mode edid_4k_modes[] = { + 3840, 4016, 4104, 4400, 0, + 2160, 2168, 2178, 2250, 0, + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), +- .vrefresh = 30, }, ++ .vrefresh = 30, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, + /* 2 - 3840x2160@25Hz */ + { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 297000, + 3840, 4896, 4984, 5280, 0, + 2160, 2168, 2178, 2250, 0, + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), +- .vrefresh = 25, }, ++ .vrefresh = 25, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, + /* 3 - 3840x2160@24Hz */ + { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 297000, + 3840, 5116, 5204, 5500, 0, + 2160, 2168, 2178, 2250, 0, + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), +- .vrefresh = 24, }, ++ .vrefresh = 24, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, + /* 4 - 4096x2160@24Hz (SMPTE) */ + { DRM_MODE("4096x2160", DRM_MODE_TYPE_DRIVER, 297000, + 4096, 5116, 5204, 5500, 0, + 2160, 2168, 2178, 2250, 0, + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), +- .vrefresh = 24, }, ++ .vrefresh = 24, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_256_135, }, + }; + + /*** DDC fetch and block validation ***/ + +From daadd2b2e1bf5419694ebae5243e61e462885b03 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sat, 4 Aug 2018 16:26:47 +0200 +Subject: [PATCH] drm: bridge: dw-hdmi: signal none colorimetry for rgb output + +--- + drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +index 91c5b8fc8fa0..8261ba15f98e 100644 +--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c ++++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +@@ -1694,6 +1694,8 @@ static void hdmi_config_AVI(struct dw_hdmi *hdmi, struct drm_display_mode *mode) + frame.scan_mode = HDMI_SCAN_MODE_UNDERSCAN; + + if (hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_out_bus_format)) { ++ frame.colorimetry = HDMI_COLORIMETRY_NONE; ++ frame.extended_colorimetry = 0; + frame.quantization_range = HDMI_QUANTIZATION_RANGE_FULL; + frame.ycc_quantization_range = HDMI_YCC_QUANTIZATION_RANGE_FULL; + } else { + +From 88c6dbd7a37b01d4029102c6fdad2b1fc24098e0 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sat, 4 Aug 2018 16:27:08 +0200 +Subject: [PATCH] drm: bridge: dw-hdmi: signal it content and content type + +--- + drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +index 8261ba15f98e..cdfa295fc323 100644 +--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c ++++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +@@ -1692,6 +1692,8 @@ static void hdmi_config_AVI(struct dw_hdmi *hdmi, struct drm_display_mode *mode) + } + + frame.scan_mode = HDMI_SCAN_MODE_UNDERSCAN; ++ frame.content_type = HDMI_CONTENT_TYPE_GRAPHICS; ++ frame.itc = true; + + if (hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_out_bus_format)) { + frame.colorimetry = HDMI_COLORIMETRY_NONE; + +From 5d069752d8885584beaac3905a21c34a0bfa5f22 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sat, 4 Aug 2018 16:27:40 +0200 +Subject: [PATCH] drm: bridge: dw-hdmi: log infoframes + +--- + drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +index cdfa295fc323..25546a4471fb 100644 +--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c ++++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +@@ -1705,6 +1705,8 @@ static void hdmi_config_AVI(struct dw_hdmi *hdmi, struct drm_display_mode *mode) + frame.ycc_quantization_range = HDMI_YCC_QUANTIZATION_RANGE_LIMITED; + } + ++ hdmi_infoframe_log(KERN_INFO, hdmi->dev, &frame); ++ + /* + * The Designware IP uses a different byte format from standard + * AVI info frames, though generally the bits are in the correct +@@ -1798,6 +1800,8 @@ static void hdmi_config_vendor_specific_infoframe(struct dw_hdmi *hdmi, + return; + } + ++ hdmi_infoframe_log(KERN_INFO, hdmi->dev, &frame); ++ + /* Set the length of HDMI vendor specific InfoFrame payload */ + hdmi_writeb(hdmi, buffer[2], HDMI_FC_VSDSIZE); + +@@ -1869,6 +1873,8 @@ static void hdmi_config_hdr_infoframe(struct dw_hdmi *hdmi) + return; + } + ++ hdmi_infoframe_log(KERN_INFO, hdmi->dev, &frame); ++ + hdmi_writeb(hdmi, frame.version, HDMI_FC_DRM_HB0); + hdmi_writeb(hdmi, frame.length, HDMI_FC_DRM_HB1); + hdmi_writeb(hdmi, frame.eotf, HDMI_FC_DRM_PB0); + +From 3f61791c437d217b760d9f64d38f69e7c2ac6987 Mon Sep 17 00:00:00 2001 +From: Nickey Yang +Date: Mon, 17 Jul 2017 16:35:34 +0800 +Subject: [PATCH] MINIARM: set npll be used for hdmi only + +Change-Id: I8bebfb2cfb68e3dad172e5547d3886526ad5e912 +Signed-off-by: Nickey Yang +--- + arch/arm/boot/dts/rk3288.dtsi | 2 ++ + drivers/clk/rockchip/clk-rk3288.c | 4 ++-- + 2 files changed, 4 insertions(+), 2 deletions(-) + +diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi +index 1b7602f25f34..7e536c939cc0 100644 +--- a/arch/arm/boot/dts/rk3288.dtsi ++++ b/arch/arm/boot/dts/rk3288.dtsi +@@ -1303,6 +1303,8 @@ + resets = <&cru SRST_LCDC0_AXI>, <&cru SRST_LCDC0_AHB>, <&cru SRST_LCDC0_DCLK>; + reset-names = "axi", "ahb", "dclk"; + iommus = <&vopb_mmu>; ++ assigned-clocks = <&cru DCLK_VOP0>; ++ assigned-clock-parents = <&cru PLL_NPLL>; + status = "disabled"; + + vopb_out: port { +diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c +index ca6c2ad3de96..415df387a5d6 100644 +--- a/drivers/clk/rockchip/clk-rk3288.c ++++ b/drivers/clk/rockchip/clk-rk3288.c +@@ -214,7 +214,7 @@ static struct rockchip_pll_clock rk3288_pll_clks[] __initdata = { + [gpll] = PLL(pll_rk3066, PLL_GPLL, "gpll", mux_pll_p, 0, RK3288_PLL_CON(12), + RK3288_MODE_CON, 12, 8, 0, rk3288_pll_rates), + [npll] = PLL(pll_rk3066, PLL_NPLL, "npll", mux_pll_p, 0, RK3288_PLL_CON(16), +- RK3288_MODE_CON, 14, 9, ROCKCHIP_PLL_SYNC_RATE, rk3288_pll_rates), ++ RK3288_MODE_CON, 14, 9, 0, rk3288_pll_rates), + }; + + static struct clk_div_table div_hclk_cpu_t[] = { +@@ -429,7 +429,7 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = { + RK3288_CLKSEL_CON(30), 14, 2, MFLAGS, 8, 5, DFLAGS, + RK3288_CLKGATE_CON(3), 4, GFLAGS), + +- COMPOSITE(DCLK_VOP0, "dclk_vop0", mux_pll_src_cpll_gpll_npll_p, 0, ++ COMPOSITE(DCLK_VOP0, "dclk_vop0", mux_pll_src_cpll_gpll_npll_p, CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT, + RK3288_CLKSEL_CON(27), 0, 2, MFLAGS, 8, 8, DFLAGS, + RK3288_CLKGATE_CON(3), 1, GFLAGS), + COMPOSITE(DCLK_VOP1, "dclk_vop1", mux_pll_src_cpll_gpll_npll_p, 0, + +From 23a9cfafd5b8c641c2e9d2fdd1c299f19947c548 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sat, 4 Aug 2018 14:51:14 +0200 +Subject: [PATCH] clk: rockchip: rk3288: use npll table to to improve HDMI + compatibility + +Based on https://github.com/TinkerBoard/debian_kernel/commit/3d90870530b8a2901681f7b7fa598ee7381e49f3 +--- + drivers/clk/rockchip/clk-rk3288.c | 23 ++++++++++++++++++++++- + 1 file changed, 22 insertions(+), 1 deletion(-) + +diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c +index 415df387a5d6..f748a292b7f4 100644 +--- a/drivers/clk/rockchip/clk-rk3288.c ++++ b/drivers/clk/rockchip/clk-rk3288.c +@@ -105,6 +105,27 @@ static struct rockchip_pll_rate_table rk3288_pll_rates[] = { + { /* sentinel */ }, + }; + ++static struct rockchip_pll_rate_table rk3288_npll_rates[] = { ++ RK3066_PLL_RATE_NB(594000000, 1, 99, 4, 32), ++ RK3066_PLL_RATE_NB(585000000, 6, 585, 4, 32), ++ RK3066_PLL_RATE_NB(432000000, 3, 216, 4, 32), ++ RK3066_PLL_RATE_NB(426000000, 3, 213, 4, 32), ++ RK3066_PLL_RATE_NB(400000000, 1, 100, 6, 32), ++ RK3066_PLL_RATE_NB(342000000, 3, 171, 4, 32), ++ RK3066_PLL_RATE_NB(297000000, 2, 198, 8, 16), ++ RK3066_PLL_RATE_NB(270000000, 1, 135, 12, 32), ++ RK3066_PLL_RATE_NB(260000000, 1, 130, 12, 32), ++ RK3066_PLL_RATE_NB(148500000, 1, 99, 16, 32), ++ RK3066_PLL_RATE(148352000, 13, 1125, 14), ++ RK3066_PLL_RATE_NB(146250000, 6, 585, 16, 32), ++ RK3066_PLL_RATE_NB(108000000, 1, 54, 12, 32), ++ RK3066_PLL_RATE_NB(106500000, 4, 213, 12, 32), ++ RK3066_PLL_RATE_NB(85500000, 4, 171, 12, 32), ++ RK3066_PLL_RATE_NB(74250000, 4, 198, 16, 32), ++ RK3066_PLL_RATE(74176000, 26, 1125, 14), ++ { /* sentinel */ }, ++}; ++ + #define RK3288_DIV_ACLK_CORE_M0_MASK 0xf + #define RK3288_DIV_ACLK_CORE_M0_SHIFT 0 + #define RK3288_DIV_ACLK_CORE_MP_MASK 0xf +@@ -214,7 +235,7 @@ static struct rockchip_pll_clock rk3288_pll_clks[] __initdata = { + [gpll] = PLL(pll_rk3066, PLL_GPLL, "gpll", mux_pll_p, 0, RK3288_PLL_CON(12), + RK3288_MODE_CON, 12, 8, 0, rk3288_pll_rates), + [npll] = PLL(pll_rk3066, PLL_NPLL, "npll", mux_pll_p, 0, RK3288_PLL_CON(16), +- RK3288_MODE_CON, 14, 9, 0, rk3288_pll_rates), ++ RK3288_MODE_CON, 14, 9, 0, rk3288_npll_rates), + }; + + static struct clk_div_table div_hclk_cpu_t[] = { + +From ba1e5834eef028ca22c2089a2bff453c9bee38af Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Kamil=20Trzci=C5=84ski?= +Date: Wed, 30 May 2018 13:06:14 +0200 +Subject: [PATCH] ayufan: fan53555: support syr83x found in rockpro64 + +Change-Id: I7115081286692f4cbfbe5d11a05d40be112c3037 +--- + drivers/regulator/fan53555.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/regulator/fan53555.c b/drivers/regulator/fan53555.c +index 74e5ae2bc0d2..6b0854a3cae3 100644 +--- a/drivers/regulator/fan53555.c ++++ b/drivers/regulator/fan53555.c +@@ -78,6 +78,7 @@ enum { + + enum { + SILERGY_SYR82X = 8, ++ SILERGY_SYR83X = 9, + }; + + struct fan53555_device_info { +@@ -323,6 +324,7 @@ static int fan53555_voltages_setup_silergy(struct fan53555_device_info *di) + /* Init voltage range and step */ + switch (di->chip_id) { + case SILERGY_SYR82X: ++ case SILERGY_SYR83X: + di->vsel_min = 712500; + di->vsel_step = 12500; + break; + +From 99674f3279042bd694019c26309e4f2a44b6fe81 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 9 Sep 2018 12:33:23 +0200 +Subject: [PATCH] WIP: video: rockchip: iep: fix compile issue + +--- + include/linux/rockchip-iovmm.h | 1 + + 2 files changed, 2 insertions(+), 1 deletion(-) + +diff --git a/include/linux/rockchip-iovmm.h b/include/linux/rockchip-iovmm.h +index 73e2ff159e86..d87b8d2c9904 100644 +--- a/include/linux/rockchip-iovmm.h ++++ b/include/linux/rockchip-iovmm.h +@@ -10,6 +10,7 @@ + #include + #include + #include ++#include + + #define IEP_IOMMU_COMPATIBLE_NAME "rockchip,iep_mmu" + #define VIP_IOMMU_COMPATIBLE_NAME "rockchip,vip_mmu" + +From 6de4ce0e92be7b66429efe88c406e30703639661 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 28 Oct 2018 21:43:01 +0100 +Subject: [PATCH] clk: rockchip: rk3288: add more npll clocks + +Fixes 2560x1440@60Hz, 1600x1200@60Hz, 1920x1200@60Hz, 1680x1050@60Hz and 1440x900@60Hz modes on my monitor +--- + drivers/clk/rockchip/clk-rk3288.c | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c +index f748a292b7f4..d72c02afeb76 100644 +--- a/drivers/clk/rockchip/clk-rk3288.c ++++ b/drivers/clk/rockchip/clk-rk3288.c +@@ -111,18 +111,34 @@ static struct rockchip_pll_rate_table rk3288_npll_rates[] = { + RK3066_PLL_RATE_NB(432000000, 3, 216, 4, 32), + RK3066_PLL_RATE_NB(426000000, 3, 213, 4, 32), + RK3066_PLL_RATE_NB(400000000, 1, 100, 6, 32), ++ RK3066_PLL_RATE(348500000, 8, 697, 6), + RK3066_PLL_RATE_NB(342000000, 3, 171, 4, 32), + RK3066_PLL_RATE_NB(297000000, 2, 198, 8, 16), + RK3066_PLL_RATE_NB(270000000, 1, 135, 12, 32), + RK3066_PLL_RATE_NB(260000000, 1, 130, 12, 32), ++ RK3066_PLL_RATE(241500000, 2, 161, 8), ++ RK3066_PLL_RATE(162000000, 1, 81, 12), ++ RK3066_PLL_RATE(154000000, 6, 539, 14), + RK3066_PLL_RATE_NB(148500000, 1, 99, 16, 32), + RK3066_PLL_RATE(148352000, 13, 1125, 14), + RK3066_PLL_RATE_NB(146250000, 6, 585, 16, 32), ++ RK3066_PLL_RATE(121750000, 6, 487, 16), ++ RK3066_PLL_RATE(119000000, 3, 238, 16), + RK3066_PLL_RATE_NB(108000000, 1, 54, 12, 32), + RK3066_PLL_RATE_NB(106500000, 4, 213, 12, 32), ++ RK3066_PLL_RATE(101000000, 3, 202, 16), ++ RK3066_PLL_RATE(88750000, 6, 355, 16), + RK3066_PLL_RATE_NB(85500000, 4, 171, 12, 32), ++ RK3066_PLL_RATE(83500000, 3, 167, 16), ++ RK3066_PLL_RATE(79500000, 1, 53, 16), + RK3066_PLL_RATE_NB(74250000, 4, 198, 16, 32), + RK3066_PLL_RATE(74176000, 26, 1125, 14), ++ RK3066_PLL_RATE(72000000, 1, 48, 16), ++ RK3066_PLL_RATE(71000000, 3, 142, 16), ++ RK3066_PLL_RATE(68250000, 2, 91, 16), ++ RK3066_PLL_RATE(65000000, 3, 130, 16), ++ RK3066_PLL_RATE(40000000, 3, 80, 16), ++ RK3066_PLL_RATE(33750000, 2, 45, 16), + { /* sentinel */ }, + }; + + +From 06d1099d7f4cece7af7793ff68fabc08eb55935d Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Wed, 14 Nov 2018 06:08:01 +0100 +Subject: [PATCH] drm: workaround for crash when trying to open render node + +--- + drivers/gpu/drm/drm_ioctl.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c +index 34757168ffaa..0914c886277f 100644 +--- a/drivers/gpu/drm/drm_ioctl.c ++++ b/drivers/gpu/drm/drm_ioctl.c +@@ -57,6 +57,9 @@ static int drm_getunique(struct drm_device *dev, void *data, + struct drm_unique *u = data; + struct drm_master *master = file_priv->master; + ++ if (!master) ++ return -EINVAL; ++ + if (u->unique_len >= master->unique_len) { + if (copy_to_user(u->unique, master->unique, master->unique_len)) + return -EFAULT; + +From 309a27eaf2f4e429ef102e3eef70a2f908360c44 Mon Sep 17 00:00:00 2001 +From: Nick +Date: Wed, 19 Sep 2018 22:14:58 +0800 +Subject: [PATCH] bump PD voltage & current for board without charge IC + +--- + drivers/mfd/fusb302.c | 28 ++++++++++++++++++++++++++-- + 1 file changed, 26 insertions(+), 2 deletions(-) + +diff --git a/drivers/mfd/fusb302.c b/drivers/mfd/fusb302.c +index 240cecac65b5..8fe4163214e0 100644 +--- a/drivers/mfd/fusb302.c ++++ b/drivers/mfd/fusb302.c +@@ -217,8 +217,32 @@ static int fusb302_set_pos_power_by_charge_ic(struct fusb30x_chip *chip) + max_vol = 0; + max_cur = 0; + psy = power_supply_get_by_phandle(chip->dev->of_node, "charge-dev"); +- if (!psy || IS_ERR(psy)) +- return -1; ++ if (!psy || IS_ERR(psy)) { ++ int ret; ++ u32 value; ++ ++ ret = of_property_read_u32(chip->dev->of_node, "max-input-voltage", &value); ++ if (ret) { ++ dev_err(chip->dev, "'max-input-voltage' not found!\n"); ++ return -1; ++ } ++ ++ max_vol = value / 1000; ++ ++ ret = of_property_read_u32(chip->dev->of_node, "max-input-current", &value); ++ ++ if (ret) { ++ dev_err(chip->dev, "'max-input-current' not found!\n"); ++ return -1; ++ } ++ ++ max_cur = value / 1000; ++ ++ if (max_vol > 0 && max_cur > 0) ++ fusb_set_pos_power(chip, max_vol, max_cur); ++ ++ return 0; ++ } + + psp = POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT_MAX; + if (power_supply_get_property(psy, psp, &val) == 0) +--- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c ++++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c +@@ -646,7 +646,7 @@ + { .base = 0x00, .phy = &rk3288_win01_data, + .type = DRM_PLANE_TYPE_PRIMARY }, + { .base = 0x40, .phy = &rk3288_win01_data, +- .type = DRM_PLANE_TYPE_CURSOR }, ++ .type = DRM_PLANE_TYPE_OVERLAY }, + }; + + static const struct vop_data rk322x_vop = { +diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_linux.c b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_linux.c +index f3ad402..d8112c9 100644 +--- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_linux.c ++++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_linux.c +@@ -6962,7 +6962,7 @@ dhd_ethtool(dhd_info_t *dhd, void *uaddr) + /* Copy out any request driver name */ + if (copy_from_user(&info, uaddr, sizeof(info))) + return -EFAULT; +- strncpy(drvname, info.driver, sizeof(info.driver)); ++ strncpy(drvname, info.driver, sizeof(drvname)); + drvname[sizeof(info.driver)-1] = '\0'; + + /* clear struct for return */ diff --git a/patch/kernel/rk322x-legacy/01-linux-0002-ir.patch b/patch/kernel/rk322x-legacy/01-linux-0002-ir.patch new file mode 100644 index 0000000000..e376075159 --- /dev/null +++ b/patch/kernel/rk322x-legacy/01-linux-0002-ir.patch @@ -0,0 +1,831 @@ +From 2031709371a600b1b803ec928cc1adb2e9b5a4c1 Mon Sep 17 00:00:00 2001 +From: Mauro Carvalho Chehab +Date: Thu, 19 Nov 2015 11:41:36 -0200 +Subject: [PATCH] UPSTREAM: smsir.h: remove a now duplicated definition + (IR_DEFAULT_TIMEOUT) + +This macro is now part of the core. Remove from Siano driver. + +Signed-off-by: Mauro Carvalho Chehab +(cherry picked from commit 850c8a7d68a761b5f11d5b443b5ece185e8068f4) +--- + drivers/media/common/siano/smsir.h | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/drivers/media/common/siano/smsir.h b/drivers/media/common/siano/smsir.h +index fc8b7925c532..d9abd96ef48b 100644 +--- a/drivers/media/common/siano/smsir.h ++++ b/drivers/media/common/siano/smsir.h +@@ -30,8 +30,6 @@ along with this program. If not, see . + #include + #include + +-#define IR_DEFAULT_TIMEOUT 100 +- + struct smscore_device_t; + + struct ir_t { + +From 3b533a5c5f7880759fcad51e9400851a80295764 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Wed, 6 Sep 2017 18:39:09 +0200 +Subject: [PATCH] [media] rc/keymaps: add keytable for Pine64 IR Remote + Controller + +--- + drivers/media/rc/keymaps/Makefile | 1 + + drivers/media/rc/keymaps/rc-pine64.c | 65 ++++++++++++++++++++++++++++++++++++ + include/media/rc-map.h | 1 + + 3 files changed, 67 insertions(+) + create mode 100644 drivers/media/rc/keymaps/rc-pine64.c + +diff --git a/drivers/media/rc/keymaps/Makefile b/drivers/media/rc/keymaps/Makefile +index fbbd3bbcd252..8816520600f7 100644 +--- a/drivers/media/rc/keymaps/Makefile ++++ b/drivers/media/rc/keymaps/Makefile +@@ -66,6 +66,7 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \ + rc-norwood.o \ + rc-npgtech.o \ + rc-pctv-sedna.o \ ++ rc-pine64.o \ + rc-pinnacle-color.o \ + rc-pinnacle-grey.o \ + rc-pinnacle-pctv-hd.o \ +diff --git a/drivers/media/rc/keymaps/rc-pine64.c b/drivers/media/rc/keymaps/rc-pine64.c +new file mode 100644 +index 000000000000..bdf3975e7445 +--- /dev/null ++++ b/drivers/media/rc/keymaps/rc-pine64.c +@@ -0,0 +1,65 @@ ++/* Keytable for Pine64 IR Remote Controller ++ * ++ * Copyright (c) 2017 PINE64 ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ */ ++ ++#include ++#include ++ ++static struct rc_map_table pine64[] = { ++ { 0x404000, KEY_NUMERIC_0 }, ++ { 0x404001, KEY_NUMERIC_1 }, ++ { 0x404002, KEY_NUMERIC_2 }, ++ { 0x404003, KEY_NUMERIC_3 }, ++ { 0x404004, KEY_NUMERIC_4 }, ++ { 0x404005, KEY_NUMERIC_5 }, ++ { 0x404006, KEY_NUMERIC_6 }, ++ { 0x404007, KEY_NUMERIC_7 }, ++ { 0x404008, KEY_NUMERIC_8 }, ++ { 0x404009, KEY_NUMERIC_9 }, ++ { 0x40400a, KEY_MUTE }, ++ { 0x40400b, KEY_UP }, ++ { 0x40400c, KEY_BACKSPACE }, ++ { 0x40400d, KEY_OK }, ++ { 0x40400e, KEY_DOWN }, ++ { 0x404010, KEY_LEFT }, ++ { 0x404011, KEY_RIGHT }, ++ { 0x404017, KEY_VOLUMEDOWN }, ++ { 0x404018, KEY_VOLUMEUP }, ++ { 0x40401a, KEY_HOME }, ++ { 0x40401d, KEY_MENU }, ++ { 0x40401f, KEY_WWW }, ++ { 0x404045, KEY_BACK }, ++ { 0x404047, KEY_INFO }, ++ { 0x40404d, KEY_POWER }, ++}; ++ ++static struct rc_map_list pine64_map = { ++ .map = { ++ .scan = pine64, ++ .size = ARRAY_SIZE(pine64), ++ .rc_type = RC_TYPE_NEC, ++ .name = RC_MAP_PINE64, ++ } ++}; ++ ++static int __init init_rc_map_pine64(void) ++{ ++ return rc_map_register(&pine64_map); ++} ++ ++static void __exit exit_rc_map_pine64(void) ++{ ++ rc_map_unregister(&pine64_map); ++} ++ ++module_init(init_rc_map_pine64) ++module_exit(exit_rc_map_pine64) ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("PINE64"); +diff --git a/include/media/rc-map.h b/include/media/rc-map.h +index 7c4bbc4dfab4..3a34a9631dd1 100644 +--- a/include/media/rc-map.h ++++ b/include/media/rc-map.h +@@ -173,6 +173,7 @@ void rc_map_init(void); + #define RC_MAP_NORWOOD "rc-norwood" + #define RC_MAP_NPGTECH "rc-npgtech" + #define RC_MAP_PCTV_SEDNA "rc-pctv-sedna" ++#define RC_MAP_PINE64 "rc-pine64" + #define RC_MAP_PINNACLE_COLOR "rc-pinnacle-color" + #define RC_MAP_PINNACLE_GREY "rc-pinnacle-grey" + #define RC_MAP_PINNACLE_PCTV_HD "rc-pinnacle-pctv-hd" + +From 21e2e6f847c6e1d0f98ce3770e6d380b20af3064 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Wed, 6 Sep 2017 18:39:09 +0200 +Subject: [PATCH] [media] rc/keymaps: add keytable for ODROID IR Remote + Controller + +--- + drivers/media/rc/keymaps/Makefile | 1 + + drivers/media/rc/keymaps/rc-odroid.c | 52 ++++++++++++++++++++++++++++++++++++ + include/media/rc-map.h | 1 + + 3 files changed, 54 insertions(+) + create mode 100644 drivers/media/rc/keymaps/rc-odroid.c + +diff --git a/drivers/media/rc/keymaps/Makefile b/drivers/media/rc/keymaps/Makefile +index 8816520600f7..f4321cfbbc79 100644 +--- a/drivers/media/rc/keymaps/Makefile ++++ b/drivers/media/rc/keymaps/Makefile +@@ -65,6 +65,7 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \ + rc-nec-terratec-cinergy-xs.o \ + rc-norwood.o \ + rc-npgtech.o \ ++ rc-odroid.o \ + rc-pctv-sedna.o \ + rc-pine64.o \ + rc-pinnacle-color.o \ +diff --git a/drivers/media/rc/keymaps/rc-odroid.c b/drivers/media/rc/keymaps/rc-odroid.c +new file mode 100644 +index 000000000000..52089f0b7c1d +--- /dev/null ++++ b/drivers/media/rc/keymaps/rc-odroid.c +@@ -0,0 +1,52 @@ ++/* Keytable for ODROID IR Remote Controller ++ * ++ * Copyright (c) 2017 Hardkernel co., Ltd. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ */ ++ ++#include ++#include ++ ++static struct rc_map_table odroid[] = { ++ { 0xb2dc, KEY_POWER }, ++ { 0xb288, KEY_MUTE }, ++ { 0xb282, KEY_HOME }, ++ { 0xb2ce, KEY_OK }, ++ { 0xb2ca, KEY_UP }, ++ { 0xb299, KEY_LEFT }, ++ { 0xb2c1, KEY_RIGHT }, ++ { 0xb2d2, KEY_DOWN }, ++ { 0xb2c5, KEY_MENU }, ++ { 0xb29a, KEY_BACK }, ++ { 0xb281, KEY_VOLUMEDOWN }, ++ { 0xb280, KEY_VOLUMEUP }, ++}; ++ ++static struct rc_map_list odroid_map = { ++ .map = { ++ .scan = odroid, ++ .size = ARRAY_SIZE(odroid), ++ .rc_type = RC_TYPE_NEC, ++ .name = RC_MAP_ODROID, ++ } ++}; ++ ++static int __init init_rc_map_odroid(void) ++{ ++ return rc_map_register(&odroid_map); ++} ++ ++static void __exit exit_rc_map_odroid(void) ++{ ++ rc_map_unregister(&odroid_map); ++} ++ ++module_init(init_rc_map_odroid) ++module_exit(exit_rc_map_odroid) ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Hardkernel co., Ltd."); +diff --git a/include/media/rc-map.h b/include/media/rc-map.h +index 3a34a9631dd1..f1badbfbca90 100644 +--- a/include/media/rc-map.h ++++ b/include/media/rc-map.h +@@ -172,6 +172,7 @@ void rc_map_init(void); + #define RC_MAP_NEC_TERRATEC_CINERGY_XS "rc-nec-terratec-cinergy-xs" + #define RC_MAP_NORWOOD "rc-norwood" + #define RC_MAP_NPGTECH "rc-npgtech" ++#define RC_MAP_ODROID "rc-odroid" + #define RC_MAP_PCTV_SEDNA "rc-pctv-sedna" + #define RC_MAP_PINE64 "rc-pine64" + #define RC_MAP_PINNACLE_COLOR "rc-pinnacle-color" + +From 0cb159b68f91fb352861a23241a24611201e0d05 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Wed, 6 Sep 2017 18:39:09 +0200 +Subject: [PATCH] [media] rc/keymaps: add keytable for WeTek Hub Remote + Controller + +--- + drivers/media/rc/keymaps/Makefile | 1 + + drivers/media/rc/keymaps/rc-wetek-hub.c | 52 +++++++++++++++++++++++++++++++++ + include/media/rc-map.h | 1 + + 3 files changed, 54 insertions(+) + create mode 100644 drivers/media/rc/keymaps/rc-wetek-hub.c + +diff --git a/drivers/media/rc/keymaps/Makefile b/drivers/media/rc/keymaps/Makefile +index f4321cfbbc79..e8e6434cbc13 100644 +--- a/drivers/media/rc/keymaps/Makefile ++++ b/drivers/media/rc/keymaps/Makefile +@@ -101,6 +101,7 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \ + rc-tt-1500.o \ + rc-twinhan-dtv-cab-ci.o \ + rc-twinhan1027.o \ ++ rc-wetek-hub.o \ + rc-videomate-m1f.o \ + rc-videomate-s350.o \ + rc-videomate-tv-pvr.o \ +diff --git a/drivers/media/rc/keymaps/rc-wetek-hub.c b/drivers/media/rc/keymaps/rc-wetek-hub.c +new file mode 100644 +index 000000000000..0955ecfcb77c +--- /dev/null ++++ b/drivers/media/rc/keymaps/rc-wetek-hub.c +@@ -0,0 +1,52 @@ ++/* Keytable for WeTek Hub Remote Controller ++ * ++ * Copyright (c) 2017 WeTek ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ */ ++ ++#include ++#include ++ ++static struct rc_map_table wetek_hub[] = { ++ { 0x77f1, KEY_POWER }, ++ { 0x77f2, KEY_HOME }, ++ { 0x77f3, KEY_MUTE }, ++ { 0x77f4, KEY_UP }, ++ { 0x77f5, KEY_DOWN }, ++ { 0x77f6, KEY_LEFT }, ++ { 0x77f7, KEY_RIGHT }, ++ { 0x77f8, KEY_OK }, ++ { 0x77f9, KEY_BACK }, ++ { 0x77fa, KEY_MENU }, ++ { 0x77fb, KEY_VOLUMEUP }, ++ { 0x77fc, KEY_VOLUMEDOWN }, ++}; ++ ++static struct rc_map_list wetek_hub_map = { ++ .map = { ++ .scan = wetek_hub, ++ .size = ARRAY_SIZE(wetek_hub), ++ .rc_type = RC_TYPE_NEC, ++ .name = RC_MAP_WETEK_HUB, ++ } ++}; ++ ++static int __init init_rc_map_wetek_hub(void) ++{ ++ return rc_map_register(&wetek_hub_map); ++} ++ ++static void __exit exit_rc_map_wetek_hub(void) ++{ ++ rc_map_unregister(&wetek_hub_map); ++} ++ ++module_init(init_rc_map_wetek_hub) ++module_exit(exit_rc_map_wetek_hub) ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("WeTek"); +diff --git a/include/media/rc-map.h b/include/media/rc-map.h +index f1badbfbca90..cd8590c99e22 100644 +--- a/include/media/rc-map.h ++++ b/include/media/rc-map.h +@@ -209,6 +209,7 @@ void rc_map_init(void); + #define RC_MAP_TT_1500 "rc-tt-1500" + #define RC_MAP_TWINHAN_DTV_CAB_CI "rc-twinhan-dtv-cab-ci" + #define RC_MAP_TWINHAN_VP1027_DVBS "rc-twinhan1027" ++#define RC_MAP_WETEK_HUB "rc-wetek-hub" + #define RC_MAP_VIDEOMATE_K100 "rc-videomate-k100" + #define RC_MAP_VIDEOMATE_S350 "rc-videomate-s350" + #define RC_MAP_VIDEOMATE_TV_PVR "rc-videomate-tv-pvr" + +From d81bc903c323311f09eb3f8a298c10d99c62f601 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Wed, 6 Sep 2017 18:39:09 +0200 +Subject: [PATCH] [media] rc/keymaps: add keytable for WeTek Play 2 Remote + Controller + +--- + drivers/media/rc/keymaps/Makefile | 1 + + drivers/media/rc/keymaps/rc-wetek-play-2.c | 83 ++++++++++++++++++++++++++++++ + include/media/rc-map.h | 1 + + 3 files changed, 85 insertions(+) + create mode 100644 drivers/media/rc/keymaps/rc-wetek-play-2.c + +diff --git a/drivers/media/rc/keymaps/Makefile b/drivers/media/rc/keymaps/Makefile +index e8e6434cbc13..650481039f00 100644 +--- a/drivers/media/rc/keymaps/Makefile ++++ b/drivers/media/rc/keymaps/Makefile +@@ -102,6 +102,7 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \ + rc-twinhan-dtv-cab-ci.o \ + rc-twinhan1027.o \ + rc-wetek-hub.o \ ++ rc-wetek-play-2.o \ + rc-videomate-m1f.o \ + rc-videomate-s350.o \ + rc-videomate-tv-pvr.o \ +diff --git a/drivers/media/rc/keymaps/rc-wetek-play-2.c b/drivers/media/rc/keymaps/rc-wetek-play-2.c +new file mode 100644 +index 000000000000..37586cedbb8a +--- /dev/null ++++ b/drivers/media/rc/keymaps/rc-wetek-play-2.c +@@ -0,0 +1,83 @@ ++/* Keytable for WeTek Play 2 Remote Controller ++ * ++ * Copyright (c) 2017 WeTek ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ */ ++ ++#include ++#include ++ ++static struct rc_map_table wetek_play_2[] = { ++ { 0x5e5f02, KEY_POWER }, ++ { 0x5e5f46, KEY_POWER2 }, ++ { 0x5e5f10, KEY_MUTE }, ++ { 0x5e5f22, KEY_NUMERIC_1 }, ++ { 0x5e5f23, KEY_NUMERIC_2 }, ++ { 0x5e5f24, KEY_NUMERIC_3 }, ++ { 0x5e5f25, KEY_NUMERIC_4 }, ++ { 0x5e5f26, KEY_NUMERIC_5 }, ++ { 0x5e5f27, KEY_NUMERIC_6 }, ++ { 0x5e5f28, KEY_NUMERIC_7 }, ++ { 0x5e5f29, KEY_NUMERIC_8 }, ++ { 0x5e5f30, KEY_NUMERIC_9 }, ++ { 0x5e5f71, KEY_BACKSPACE }, ++ { 0x5e5f21, KEY_NUMERIC_0 }, ++ { 0x5e5f72, KEY_CAPSLOCK }, ++ { 0x5e5f03, KEY_HOME }, ++ { 0x5e5f48, KEY_MENU }, ++ { 0x5e5f61, KEY_BACK }, ++ { 0x5e5f83, KEY_INFO }, ++ { 0x5e5f84, KEY_COMPOSE }, ++ { 0x5e5f77, KEY_HELP }, ++ { 0x5e5f50, KEY_UP }, ++ { 0x5e5f4b, KEY_DOWN }, ++ { 0x5e5f4c, KEY_LEFT }, ++ { 0x5e5f4d, KEY_RIGHT }, ++ { 0x5e5f47, KEY_OK }, ++ { 0x5e5f44, KEY_VOLUMEUP }, ++ { 0x5e5f43, KEY_VOLUMEDOWN }, ++ { 0x5e5f41, KEY_CHANNELUP }, ++ { 0x5e5f42, KEY_CHANNELDOWN }, ++ { 0x5e5f4f, KEY_ZENKAKUHANKAKU }, ++ { 0x5e5f82, KEY_TEXT }, ++ { 0x5e5f73, KEY_RED }, ++ { 0x5e5f74, KEY_GREEN }, ++ { 0x5e5f75, KEY_YELLOW }, ++ { 0x5e5f76, KEY_BLUE }, ++ { 0x5e5f67, KEY_PREVIOUS }, ++ { 0x5e5f79, KEY_REWIND }, ++ { 0x5e5f80, KEY_FASTFORWARD }, ++ { 0x5e5f81, KEY_NEXT }, ++ { 0x5e5f04, KEY_RECORD }, ++ { 0x5e5f2c, KEY_PLAYPAUSE }, ++ { 0x5e5f2b, KEY_STOP }, ++}; ++ ++static struct rc_map_list wetek_play_2_map = { ++ .map = { ++ .scan = wetek_play_2, ++ .size = ARRAY_SIZE(wetek_play_2), ++ .rc_type = RC_TYPE_NEC, ++ .name = RC_MAP_WETEK_PLAY_2, ++ } ++}; ++ ++static int __init init_rc_map_wetek_play_2(void) ++{ ++ return rc_map_register(&wetek_play_2_map); ++} ++ ++static void __exit exit_rc_map_wetek_play_2(void) ++{ ++ rc_map_unregister(&wetek_play_2_map); ++} ++ ++module_init(init_rc_map_wetek_play_2) ++module_exit(exit_rc_map_wetek_play_2) ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("WeTek"); +diff --git a/include/media/rc-map.h b/include/media/rc-map.h +index cd8590c99e22..93cac05a5170 100644 +--- a/include/media/rc-map.h ++++ b/include/media/rc-map.h +@@ -210,6 +210,7 @@ void rc_map_init(void); + #define RC_MAP_TWINHAN_DTV_CAB_CI "rc-twinhan-dtv-cab-ci" + #define RC_MAP_TWINHAN_VP1027_DVBS "rc-twinhan1027" + #define RC_MAP_WETEK_HUB "rc-wetek-hub" ++#define RC_MAP_WETEK_PLAY_2 "rc-wetek-play-2" + #define RC_MAP_VIDEOMATE_K100 "rc-videomate-k100" + #define RC_MAP_VIDEOMATE_S350 "rc-videomate-s350" + #define RC_MAP_VIDEOMATE_TV_PVR "rc-videomate-tv-pvr" + +From 6518b8acbe53a153740bad1e93c9d361fed136fd Mon Sep 17 00:00:00 2001 +From: hzq +Date: Mon, 19 Mar 2018 16:47:24 +0800 +Subject: [PATCH] [media] rc/keymaps: add keytable for ROC-RK3328-CC Remote + Controller + +--- + drivers/media/rc/keymaps/Makefile | 1 + + drivers/media/rc/keymaps/rc-roc-cc.c | 52 ++++++++++++++++++++++++++++++++++++ + include/media/rc-map.h | 1 + + 3 files changed, 54 insertions(+) + create mode 100644 drivers/media/rc/keymaps/rc-roc-cc.c + +diff --git a/drivers/media/rc/keymaps/Makefile b/drivers/media/rc/keymaps/Makefile +index 650481039f00..b743914487a5 100644 +--- a/drivers/media/rc/keymaps/Makefile ++++ b/drivers/media/rc/keymaps/Makefile +@@ -83,6 +83,7 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \ + rc-rc6-mce.o \ + rc-real-audio-220-32-keys.o \ + rc-reddo.o \ ++ rc-roc-cc.o \ + rc-snapstream-firefly.o \ + rc-streamzap.o \ + rc-tbs-nec.o \ +diff --git a/drivers/media/rc/keymaps/rc-roc-cc.c b/drivers/media/rc/keymaps/rc-roc-cc.c +new file mode 100644 +index 000000000000..3a2a255d5723 +--- /dev/null ++++ b/drivers/media/rc/keymaps/rc-roc-cc.c +@@ -0,0 +1,52 @@ ++/* Keytable for ROC-RK3328-CC IR Remote Controller ++ * ++ * Copyright (c) 2017 ROC-RK3328-CC ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ */ ++ ++#include ++#include ++ ++static struct rc_map_table roc_cc[] = { ++ { 0x28d7, KEY_POWER }, ++ { 0xc837, KEY_MUTE }, ++ { 0xe01f, KEY_ENTER}, ++ { 0xc03f, KEY_UP }, ++ { 0x40bf, KEY_DOWN }, ++ { 0x708f, KEY_LEFT }, ++ { 0x58a7, KEY_RIGHT }, ++ { 0x1ae5, KEY_VOLUMEDOWN }, ++ { 0xd02f, KEY_VOLUMEUP }, ++ { 0x3ac5, KEY_WWW }, ++ { 0x807f, KEY_BACK }, ++ { 0x12ed, KEY_HOME }, ++}; ++ ++static struct rc_map_list roc_cc_map = { ++ .map = { ++ .scan = roc_cc, ++ .size = ARRAY_SIZE(roc_cc), ++ .rc_type = RC_TYPE_NEC, ++ .name = RC_MAP_ROC_CC, ++ } ++}; ++ ++static int __init init_rc_map_roc_cc(void) ++{ ++ return rc_map_register(&roc_cc_map); ++} ++ ++static void __exit exit_rc_map_roc_cc(void) ++{ ++ rc_map_unregister(&roc_cc_map); ++} ++ ++module_init(init_rc_map_roc_cc) ++module_exit(exit_rc_map_roc_cc) ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("ROC-RK3328-CC"); +diff --git a/include/media/rc-map.h b/include/media/rc-map.h +index 93cac05a5170..8bbe335e650c 100644 +--- a/include/media/rc-map.h ++++ b/include/media/rc-map.h +@@ -191,6 +191,7 @@ void rc_map_init(void); + #define RC_MAP_RC6_MCE "rc-rc6-mce" + #define RC_MAP_REAL_AUDIO_220_32_KEYS "rc-real-audio-220-32-keys" + #define RC_MAP_REDDO "rc-reddo" ++#define RC_MAP_ROC_CC "rc-roc-cc" + #define RC_MAP_SNAPSTREAM_FIREFLY "rc-snapstream-firefly" + #define RC_MAP_STREAMZAP "rc-streamzap" + #define RC_MAP_TBS_NEC "rc-tbs-nec" + +From c0220800efec28f6a59eae563f4f083ceedff6cc Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Tue, 3 Jul 2018 21:55:56 +0200 +Subject: [PATCH] [media] rc/keymaps: add keytable for T-Chip TRN9 IR Remote + Controller + +--- + drivers/media/rc/keymaps/Makefile | 1 + + drivers/media/rc/keymaps/rc-trn9.c | 52 ++++++++++++++++++++++++++++++++++++++ + include/media/rc-map.h | 1 + + 3 files changed, 54 insertions(+) + create mode 100644 drivers/media/rc/keymaps/rc-trn9.c + +diff --git a/drivers/media/rc/keymaps/Makefile b/drivers/media/rc/keymaps/Makefile +index b743914487a5..2aaa1b33ddca 100644 +--- a/drivers/media/rc/keymaps/Makefile ++++ b/drivers/media/rc/keymaps/Makefile +@@ -102,6 +102,7 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \ + rc-tt-1500.o \ + rc-twinhan-dtv-cab-ci.o \ + rc-twinhan1027.o \ ++ rc-trn9.o \ + rc-wetek-hub.o \ + rc-wetek-play-2.o \ + rc-videomate-m1f.o \ +diff --git a/drivers/media/rc/keymaps/rc-trn9.c b/drivers/media/rc/keymaps/rc-trn9.c +new file mode 100644 +index 000000000000..f81bc3a419b3 +--- /dev/null ++++ b/drivers/media/rc/keymaps/rc-trn9.c +@@ -0,0 +1,52 @@ ++/* Keytable for T-Chip TRN9 IR Remote Controller ++ * ++ * Copyright (c) 2018 Omegamoon ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ */ ++ ++#include ++#include ++ ++static struct rc_map_table trn9[] = { ++ { 0x0014, KEY_POWER }, ++ { 0x0013, KEY_MENU }, ++ { 0x0003, KEY_UP }, ++ { 0x0002, KEY_DOWN }, ++ { 0x000e, KEY_LEFT }, ++ { 0x001a, KEY_RIGHT }, ++ { 0x0007, KEY_OK }, ++ { 0x0058, KEY_VOLUMEDOWN }, ++ { 0x005c, KEY_MUTE }, ++ { 0x000b, KEY_VOLUMEUP }, ++ { 0x0001, KEY_BACK }, ++ { 0x0048, KEY_HOME }, ++}; ++ ++static struct rc_map_list trn9_map = { ++ .map = { ++ .scan = trn9, ++ .size = ARRAY_SIZE(trn9), ++ .rc_type = RC_TYPE_NEC, ++ .name = RC_MAP_TRN9, ++ } ++}; ++ ++static int __init init_rc_map_trn9(void) ++{ ++ return rc_map_register(&trn9_map); ++} ++ ++static void __exit exit_rc_map_trn9(void) ++{ ++ rc_map_unregister(&trn9_map); ++} ++ ++module_init(init_rc_map_trn9) ++module_exit(exit_rc_map_trn9) ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Omegamoon"); +diff --git a/include/media/rc-map.h b/include/media/rc-map.h +index 8bbe335e650c..66e1c50b38fc 100644 +--- a/include/media/rc-map.h ++++ b/include/media/rc-map.h +@@ -210,6 +210,7 @@ void rc_map_init(void); + #define RC_MAP_TT_1500 "rc-tt-1500" + #define RC_MAP_TWINHAN_DTV_CAB_CI "rc-twinhan-dtv-cab-ci" + #define RC_MAP_TWINHAN_VP1027_DVBS "rc-twinhan1027" ++#define RC_MAP_TRN9 "rc-trn9" + #define RC_MAP_WETEK_HUB "rc-wetek-hub" + #define RC_MAP_WETEK_PLAY_2 "rc-wetek-play-2" + #define RC_MAP_VIDEOMATE_K100 "rc-videomate-k100" + +From 312b78202feca8f3966343b0362466e9c6ff2297 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Mon, 17 Dec 2018 07:41:16 +0100 +Subject: [PATCH] [media] rc/keymaps: add keytable for Khadas IR Remote + Controller + +--- + drivers/media/rc/keymaps/Makefile | 1 + + drivers/media/rc/keymaps/rc-khadas.c | 52 ++++++++++++++++++++++++++++++++++++ + include/media/rc-map.h | 1 + + 3 files changed, 54 insertions(+) + create mode 100644 drivers/media/rc/keymaps/rc-khadas.c + +diff --git a/drivers/media/rc/keymaps/Makefile b/drivers/media/rc/keymaps/Makefile +index 2aaa1b33ddca..fc0207d322a0 100644 +--- a/drivers/media/rc/keymaps/Makefile ++++ b/drivers/media/rc/keymaps/Makefile +@@ -47,6 +47,7 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \ + rc-it913x-v1.o \ + rc-it913x-v2.o \ + rc-kaiomy.o \ ++ rc-khadas.o \ + rc-kworld-315u.o \ + rc-kworld-pc150u.o \ + rc-kworld-plus-tv-analog.o \ +diff --git a/drivers/media/rc/keymaps/rc-khadas.c b/drivers/media/rc/keymaps/rc-khadas.c +new file mode 100644 +index 000000000000..492368db75d9 +--- /dev/null ++++ b/drivers/media/rc/keymaps/rc-khadas.c +@@ -0,0 +1,52 @@ ++/* Keytable for Khadas IR Remote Controller ++ * ++ * Copyright (c) 2018 Shenzhen Wesion Technology Co., Ltd ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ */ ++ ++#include ++#include ++ ++static struct rc_map_table khadas[] = { ++ { 0x14, KEY_POWER }, ++ { 0x07, KEY_OK }, ++ { 0x03, KEY_UP }, ++ { 0x02, KEY_DOWN }, ++ { 0x0e, KEY_LEFT }, ++ { 0x1a, KEY_RIGHT }, ++ { 0x13, KEY_MENU }, ++ { 0x01, KEY_BACK }, ++ { 0x0b, KEY_VOLUMEUP }, ++ { 0x58, KEY_VOLUMEDOWN }, ++ { 0x48, KEY_HOME }, ++ { 0x5b, KEY_CONTEXT_MENU }, ++}; ++ ++static struct rc_map_list khadas_map = { ++ .map = { ++ .scan = khadas, ++ .size = ARRAY_SIZE(khadas), ++ .rc_type = RC_TYPE_NEC, ++ .name = RC_MAP_KHADAS, ++ } ++}; ++ ++static int __init init_rc_map_khadas(void) ++{ ++ return rc_map_register(&khadas_map); ++} ++ ++static void __exit exit_rc_map_khadas(void) ++{ ++ rc_map_unregister(&khadas_map); ++} ++ ++module_init(init_rc_map_khadas) ++module_exit(exit_rc_map_khadas) ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Khadas"); +diff --git a/include/media/rc-map.h b/include/media/rc-map.h +index 66e1c50b38fc..6b2db526fac0 100644 +--- a/include/media/rc-map.h ++++ b/include/media/rc-map.h +@@ -154,6 +154,7 @@ void rc_map_init(void); + #define RC_MAP_IT913X_V1 "rc-it913x-v1" + #define RC_MAP_IT913X_V2 "rc-it913x-v2" + #define RC_MAP_KAIOMY "rc-kaiomy" ++#define RC_MAP_KHADAS "rc-khadas" + #define RC_MAP_KWORLD_315U "rc-kworld-315u" + #define RC_MAP_KWORLD_PC150U "rc-kworld-pc150u" + #define RC_MAP_KWORLD_PLUS_TV_ANALOG "rc-kworld-plus-tv-analog" +--- a/drivers/media/rc/keymaps/rc-rktvbox.c ++++ b/drivers/media/rc/keymaps/rc-rktvbox.c +@@ -0,0 +1,65 @@ ++/* Keytable for Rockchip TV Box IR Remote Controller ++ * ++ * Copyright (c) 2018 knaerzche ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ */ ++ ++#include ++#include ++ ++static struct rc_map_table rktvbox[] = { ++ { 0xcc1d49, KEY_NUMERIC_0 }, ++ { 0xcc1d41, KEY_NUMERIC_1 }, ++ { 0xcc1d45, KEY_NUMERIC_2 }, ++ { 0xcc1d4d, KEY_NUMERIC_3 }, ++ { 0xcc1d42, KEY_NUMERIC_4 }, ++ { 0xcc1d46, KEY_NUMERIC_5 }, ++ { 0xcc1d4e, KEY_NUMERIC_6 }, ++ { 0xcc1d43, KEY_NUMERIC_7 }, ++ { 0xcc1d47, KEY_NUMERIC_8 }, ++ { 0xcc1d4f, KEY_NUMERIC_9 }, ++ { 0xcc1d0c, KEY_MUTE }, ++ { 0xcc1d07, KEY_UP }, ++ { 0xcc1d4a, KEY_BACKSPACE }, ++ { 0xcc1d11, KEY_OK }, ++ { 0xcc1d44, KEY_DOWN }, ++ { 0xcc1d10, KEY_LEFT }, ++ { 0xcc1d12, KEY_RIGHT }, ++ { 0xcc1d02, KEY_VOLUMEDOWN }, ++ { 0xcc1d0e, KEY_VOLUMEUP }, ++ { 0xcc1d03, KEY_HOME }, ++ { 0xcc1d40, KEY_MENU }, ++ { 0xcc1d09, KEY_WWW }, ++ { 0xcc1d0f, KEY_BACK }, ++ { 0xcc1d4c, KEY_INFO }, ++ { 0xcc1d00, KEY_POWER }, ++}; ++ ++static struct rc_map_list rktvbox_map = { ++ .map = { ++ .scan = rktvbox, ++ .size = ARRAY_SIZE(rktvbox), ++ .rc_proto = RC_PROTO_NEC, ++ .name = RC_MAP_RKTVBOX, ++ } ++}; ++ ++static int __init init_rc_map_rktvbox(void) ++{ ++ return rc_map_register(&rktvbox_map); ++} ++ ++static void __exit exit_rc_map_rktvbox(void) ++{ ++ rc_map_unregister(&rktvbox_map); ++} ++ ++module_init(init_rc_map_rktvbox) ++module_exit(exit_rc_map_rktvbox) ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("knaerzche"); +--- a/drivers/media/rc/keymaps/Makefile ++++ b/drivers/media/rc/keymaps/Makefile +@@ -69,6 +69,7 @@ + rc-odroid.o \ + rc-pctv-sedna.o \ + rc-pine64.o \ ++ rc-rktvbox.o \ + rc-pinnacle-color.o \ + rc-pinnacle-grey.o \ + rc-pinnacle-pctv-hd.o \ +--- a/include/media/rc-map.h ++++ b/include/media/rc-map.h +@@ -178,6 +178,7 @@ + #define RC_MAP_ODROID "rc-odroid" + #define RC_MAP_PCTV_SEDNA "rc-pctv-sedna" + #define RC_MAP_PINE64 "rc-pine64" ++#define RC_MAP_RKTVBOX "rc-rktvbox" + #define RC_MAP_PINNACLE_COLOR "rc-pinnacle-color" + #define RC_MAP_PINNACLE_GREY "rc-pinnacle-grey" + #define RC_MAP_PINNACLE_PCTV_HD "rc-pinnacle-pctv-hd" diff --git a/patch/kernel/rk322x-legacy/01-linux-0003-cec.patch b/patch/kernel/rk322x-legacy/01-linux-0003-cec.patch new file mode 100644 index 0000000000..048814bee2 --- /dev/null +++ b/patch/kernel/rk322x-legacy/01-linux-0003-cec.patch @@ -0,0 +1,4422 @@ +From 0dcc2992b7f03fbe5bf9bd9f65edaf5479bf975a Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Mon, 4 Sep 2017 22:34:19 +0200 +Subject: [PATCH] BACKPORT: HDMI CEC support from v4.15 + +Skipped changes: +857313e51006ff51524579bcd8808b70f9a80812 "media: utilize new cdev_device_add helper function" +0f7499fddb153a333dff3c1dc4280c178b9b5a80 "[media] rc-main: assign driver type during allocation" +--- + Documentation/devicetree/bindings/media/cec.txt | 8 + + Documentation/media/kapi/cec-core.rst | 381 +++++++++++++++++++++ + Documentation/media/uapi/cec/cec-api.rst | 46 +++ + Documentation/media/uapi/cec/cec-func-close.rst | 47 +++ + Documentation/media/uapi/cec/cec-func-ioctl.rst | 66 ++++ + Documentation/media/uapi/cec/cec-func-open.rst | 78 +++++ + Documentation/media/uapi/cec/cec-func-poll.rst | 77 +++++ + Documentation/media/uapi/cec/cec-funcs.rst | 20 ++ + Documentation/media/uapi/cec/cec-header.rst | 10 + + Documentation/media/uapi/cec/cec-intro.rst | 40 +++ + .../media/uapi/cec/cec-ioc-adap-g-caps.rst | 139 ++++++++ + .../media/uapi/cec/cec-ioc-adap-g-log-addrs.rst | 371 ++++++++++++++++++++ + .../media/uapi/cec/cec-ioc-adap-g-phys-addr.rst | 93 +++++ + Documentation/media/uapi/cec/cec-ioc-dqevent.rst | 226 ++++++++++++ + Documentation/media/uapi/cec/cec-ioc-g-mode.rst | 293 ++++++++++++++++ + Documentation/media/uapi/cec/cec-ioc-receive.rst | 344 +++++++++++++++++++ + MAINTAINERS | 16 + + drivers/media/cec/cec-adap.c | 61 +++- + drivers/media/cec/cec-core.c | 15 +- + drivers/media/rc/keymaps/Makefile | 1 + + drivers/media/rc/keymaps/rc-cec.c | 182 ++++++++++ + drivers/media/rc/rc-main.c | 1 + + fs/compat_ioctl.c | 12 + + include/media/cec-notifier.h | 22 ++ + include/media/cec.h | 9 +- + include/media/rc-map.h | 5 +- + include/uapi/linux/cec-funcs.h | 1 + + include/uapi/linux/cec.h | 2 +- + include/uapi/linux/input-event-codes.h | 31 ++ + include/uapi/linux/input.h | 1 + + 30 files changed, 2606 insertions(+), 15 deletions(-) + create mode 100644 Documentation/devicetree/bindings/media/cec.txt + create mode 100644 Documentation/media/kapi/cec-core.rst + create mode 100644 Documentation/media/uapi/cec/cec-api.rst + create mode 100644 Documentation/media/uapi/cec/cec-func-close.rst + create mode 100644 Documentation/media/uapi/cec/cec-func-ioctl.rst + create mode 100644 Documentation/media/uapi/cec/cec-func-open.rst + create mode 100644 Documentation/media/uapi/cec/cec-func-poll.rst + create mode 100644 Documentation/media/uapi/cec/cec-funcs.rst + create mode 100644 Documentation/media/uapi/cec/cec-header.rst + create mode 100644 Documentation/media/uapi/cec/cec-intro.rst + create mode 100644 Documentation/media/uapi/cec/cec-ioc-adap-g-caps.rst + create mode 100644 Documentation/media/uapi/cec/cec-ioc-adap-g-log-addrs.rst + create mode 100644 Documentation/media/uapi/cec/cec-ioc-adap-g-phys-addr.rst + create mode 100644 Documentation/media/uapi/cec/cec-ioc-dqevent.rst + create mode 100644 Documentation/media/uapi/cec/cec-ioc-g-mode.rst + create mode 100644 Documentation/media/uapi/cec/cec-ioc-receive.rst + create mode 100644 drivers/media/rc/keymaps/rc-cec.c + +diff --git a/Documentation/devicetree/bindings/media/cec.txt b/Documentation/devicetree/bindings/media/cec.txt +new file mode 100644 +index 000000000000..22d7aae3d3d7 +--- /dev/null ++++ b/Documentation/devicetree/bindings/media/cec.txt +@@ -0,0 +1,8 @@ ++Common bindings for HDMI CEC adapters ++ ++- hdmi-phandle: phandle to the HDMI controller. ++ ++- needs-hpd: if present the CEC support is only available when the HPD ++ is high. Some boards only let the CEC pin through if the HPD is high, ++ for example if there is a level converter that uses the HPD to power ++ up or down. +diff --git a/Documentation/media/kapi/cec-core.rst b/Documentation/media/kapi/cec-core.rst +new file mode 100644 +index 000000000000..d37e107f2fde +--- /dev/null ++++ b/Documentation/media/kapi/cec-core.rst +@@ -0,0 +1,381 @@ ++CEC Kernel Support ++================== ++ ++The CEC framework provides a unified kernel interface for use with HDMI CEC ++hardware. It is designed to handle a multiple types of hardware (receivers, ++transmitters, USB dongles). The framework also gives the option to decide ++what to do in the kernel driver and what should be handled by userspace ++applications. In addition it integrates the remote control passthrough ++feature into the kernel's remote control framework. ++ ++ ++The CEC Protocol ++---------------- ++ ++The CEC protocol enables consumer electronic devices to communicate with each ++other through the HDMI connection. The protocol uses logical addresses in the ++communication. The logical address is strictly connected with the functionality ++provided by the device. The TV acting as the communication hub is always ++assigned address 0. The physical address is determined by the physical ++connection between devices. ++ ++The CEC framework described here is up to date with the CEC 2.0 specification. ++It is documented in the HDMI 1.4 specification with the new 2.0 bits documented ++in the HDMI 2.0 specification. But for most of the features the freely available ++HDMI 1.3a specification is sufficient: ++ ++http://www.microprocessor.org/HDMISpecification13a.pdf ++ ++ ++CEC Adapter Interface ++--------------------- ++ ++The struct cec_adapter represents the CEC adapter hardware. It is created by ++calling cec_allocate_adapter() and deleted by calling cec_delete_adapter(): ++ ++.. c:function:: ++ struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops, void *priv, ++ const char *name, u32 caps, u8 available_las); ++ ++.. c:function:: ++ void cec_delete_adapter(struct cec_adapter *adap); ++ ++To create an adapter you need to pass the following information: ++ ++ops: ++ adapter operations which are called by the CEC framework and that you ++ have to implement. ++ ++priv: ++ will be stored in adap->priv and can be used by the adapter ops. ++ Use cec_get_drvdata(adap) to get the priv pointer. ++ ++name: ++ the name of the CEC adapter. Note: this name will be copied. ++ ++caps: ++ capabilities of the CEC adapter. These capabilities determine the ++ capabilities of the hardware and which parts are to be handled ++ by userspace and which parts are handled by kernelspace. The ++ capabilities are returned by CEC_ADAP_G_CAPS. ++ ++available_las: ++ the number of simultaneous logical addresses that this ++ adapter can handle. Must be 1 <= available_las <= CEC_MAX_LOG_ADDRS. ++ ++To obtain the priv pointer use this helper function: ++ ++.. c:function:: ++ void *cec_get_drvdata(const struct cec_adapter *adap); ++ ++To register the /dev/cecX device node and the remote control device (if ++CEC_CAP_RC is set) you call: ++ ++.. c:function:: ++ int cec_register_adapter(struct cec_adapter *adap, struct device *parent); ++ ++where parent is the parent device. ++ ++To unregister the devices call: ++ ++.. c:function:: ++ void cec_unregister_adapter(struct cec_adapter *adap); ++ ++Note: if cec_register_adapter() fails, then call cec_delete_adapter() to ++clean up. But if cec_register_adapter() succeeded, then only call ++cec_unregister_adapter() to clean up, never cec_delete_adapter(). The ++unregister function will delete the adapter automatically once the last user ++of that /dev/cecX device has closed its file handle. ++ ++ ++Implementing the Low-Level CEC Adapter ++-------------------------------------- ++ ++The following low-level adapter operations have to be implemented in ++your driver: ++ ++.. c:type:: struct cec_adap_ops ++ ++.. code-block:: none ++ ++ struct cec_adap_ops ++ { ++ /* Low-level callbacks */ ++ int (*adap_enable)(struct cec_adapter *adap, bool enable); ++ int (*adap_monitor_all_enable)(struct cec_adapter *adap, bool enable); ++ int (*adap_log_addr)(struct cec_adapter *adap, u8 logical_addr); ++ int (*adap_transmit)(struct cec_adapter *adap, u8 attempts, ++ u32 signal_free_time, struct cec_msg *msg); ++ void (*adap_status)(struct cec_adapter *adap, struct seq_file *file); ++ void (*adap_free)(struct cec_adapter *adap); ++ ++ /* High-level callbacks */ ++ ... ++ }; ++ ++The five low-level ops deal with various aspects of controlling the CEC adapter ++hardware: ++ ++ ++To enable/disable the hardware: ++ ++.. c:function:: ++ int (*adap_enable)(struct cec_adapter *adap, bool enable); ++ ++This callback enables or disables the CEC hardware. Enabling the CEC hardware ++means powering it up in a state where no logical addresses are claimed. This ++op assumes that the physical address (adap->phys_addr) is valid when enable is ++true and will not change while the CEC adapter remains enabled. The initial ++state of the CEC adapter after calling cec_allocate_adapter() is disabled. ++ ++Note that adap_enable must return 0 if enable is false. ++ ++ ++To enable/disable the 'monitor all' mode: ++ ++.. c:function:: ++ int (*adap_monitor_all_enable)(struct cec_adapter *adap, bool enable); ++ ++If enabled, then the adapter should be put in a mode to also monitor messages ++that not for us. Not all hardware supports this and this function is only ++called if the CEC_CAP_MONITOR_ALL capability is set. This callback is optional ++(some hardware may always be in 'monitor all' mode). ++ ++Note that adap_monitor_all_enable must return 0 if enable is false. ++ ++ ++To program a new logical address: ++ ++.. c:function:: ++ int (*adap_log_addr)(struct cec_adapter *adap, u8 logical_addr); ++ ++If logical_addr == CEC_LOG_ADDR_INVALID then all programmed logical addresses ++are to be erased. Otherwise the given logical address should be programmed. ++If the maximum number of available logical addresses is exceeded, then it ++should return -ENXIO. Once a logical address is programmed the CEC hardware ++can receive directed messages to that address. ++ ++Note that adap_log_addr must return 0 if logical_addr is CEC_LOG_ADDR_INVALID. ++ ++ ++To transmit a new message: ++ ++.. c:function:: ++ int (*adap_transmit)(struct cec_adapter *adap, u8 attempts, ++ u32 signal_free_time, struct cec_msg *msg); ++ ++This transmits a new message. The attempts argument is the suggested number of ++attempts for the transmit. ++ ++The signal_free_time is the number of data bit periods that the adapter should ++wait when the line is free before attempting to send a message. This value ++depends on whether this transmit is a retry, a message from a new initiator or ++a new message for the same initiator. Most hardware will handle this ++automatically, but in some cases this information is needed. ++ ++The CEC_FREE_TIME_TO_USEC macro can be used to convert signal_free_time to ++microseconds (one data bit period is 2.4 ms). ++ ++ ++To log the current CEC hardware status: ++ ++.. c:function:: ++ void (*adap_status)(struct cec_adapter *adap, struct seq_file *file); ++ ++This optional callback can be used to show the status of the CEC hardware. ++The status is available through debugfs: cat /sys/kernel/debug/cec/cecX/status ++ ++To free any resources when the adapter is deleted: ++ ++.. c:function:: ++ void (*adap_free)(struct cec_adapter *adap); ++ ++This optional callback can be used to free any resources that might have been ++allocated by the driver. It's called from cec_delete_adapter. ++ ++ ++Your adapter driver will also have to react to events (typically interrupt ++driven) by calling into the framework in the following situations: ++ ++When a transmit finished (successfully or otherwise): ++ ++.. c:function:: ++ void cec_transmit_done(struct cec_adapter *adap, u8 status, u8 arb_lost_cnt, ++ u8 nack_cnt, u8 low_drive_cnt, u8 error_cnt); ++ ++or: ++ ++.. c:function:: ++ void cec_transmit_attempt_done(struct cec_adapter *adap, u8 status); ++ ++The status can be one of: ++ ++CEC_TX_STATUS_OK: ++ the transmit was successful. ++ ++CEC_TX_STATUS_ARB_LOST: ++ arbitration was lost: another CEC initiator ++ took control of the CEC line and you lost the arbitration. ++ ++CEC_TX_STATUS_NACK: ++ the message was nacked (for a directed message) or ++ acked (for a broadcast message). A retransmission is needed. ++ ++CEC_TX_STATUS_LOW_DRIVE: ++ low drive was detected on the CEC bus. This indicates that ++ a follower detected an error on the bus and requested a ++ retransmission. ++ ++CEC_TX_STATUS_ERROR: ++ some unspecified error occurred: this can be one of ARB_LOST ++ or LOW_DRIVE if the hardware cannot differentiate or something ++ else entirely. ++ ++CEC_TX_STATUS_MAX_RETRIES: ++ could not transmit the message after trying multiple times. ++ Should only be set by the driver if it has hardware support for ++ retrying messages. If set, then the framework assumes that it ++ doesn't have to make another attempt to transmit the message ++ since the hardware did that already. ++ ++The hardware must be able to differentiate between OK, NACK and 'something ++else'. ++ ++The \*_cnt arguments are the number of error conditions that were seen. ++This may be 0 if no information is available. Drivers that do not support ++hardware retry can just set the counter corresponding to the transmit error ++to 1, if the hardware does support retry then either set these counters to ++0 if the hardware provides no feedback of which errors occurred and how many ++times, or fill in the correct values as reported by the hardware. ++ ++The cec_transmit_attempt_done() function is a helper for cases where the ++hardware never retries, so the transmit is always for just a single ++attempt. It will call cec_transmit_done() in turn, filling in 1 for the ++count argument corresponding to the status. Or all 0 if the status was OK. ++ ++When a CEC message was received: ++ ++.. c:function:: ++ void cec_received_msg(struct cec_adapter *adap, struct cec_msg *msg); ++ ++Speaks for itself. ++ ++Implementing the interrupt handler ++---------------------------------- ++ ++Typically the CEC hardware provides interrupts that signal when a transmit ++finished and whether it was successful or not, and it provides and interrupt ++when a CEC message was received. ++ ++The CEC driver should always process the transmit interrupts first before ++handling the receive interrupt. The framework expects to see the cec_transmit_done ++call before the cec_received_msg call, otherwise it can get confused if the ++received message was in reply to the transmitted message. ++ ++Implementing the High-Level CEC Adapter ++--------------------------------------- ++ ++The low-level operations drive the hardware, the high-level operations are ++CEC protocol driven. The following high-level callbacks are available: ++ ++.. code-block:: none ++ ++ struct cec_adap_ops { ++ /* Low-level callbacks */ ++ ... ++ ++ /* High-level CEC message callback */ ++ int (*received)(struct cec_adapter *adap, struct cec_msg *msg); ++ }; ++ ++The received() callback allows the driver to optionally handle a newly ++received CEC message ++ ++.. c:function:: ++ int (*received)(struct cec_adapter *adap, struct cec_msg *msg); ++ ++If the driver wants to process a CEC message, then it can implement this ++callback. If it doesn't want to handle this message, then it should return ++-ENOMSG, otherwise the CEC framework assumes it processed this message and ++it will not do anything with it. ++ ++ ++CEC framework functions ++----------------------- ++ ++CEC Adapter drivers can call the following CEC framework functions: ++ ++.. c:function:: ++ int cec_transmit_msg(struct cec_adapter *adap, struct cec_msg *msg, ++ bool block); ++ ++Transmit a CEC message. If block is true, then wait until the message has been ++transmitted, otherwise just queue it and return. ++ ++.. c:function:: ++ void cec_s_phys_addr(struct cec_adapter *adap, u16 phys_addr, ++ bool block); ++ ++Change the physical address. This function will set adap->phys_addr and ++send an event if it has changed. If cec_s_log_addrs() has been called and ++the physical address has become valid, then the CEC framework will start ++claiming the logical addresses. If block is true, then this function won't ++return until this process has finished. ++ ++When the physical address is set to a valid value the CEC adapter will ++be enabled (see the adap_enable op). When it is set to CEC_PHYS_ADDR_INVALID, ++then the CEC adapter will be disabled. If you change a valid physical address ++to another valid physical address, then this function will first set the ++address to CEC_PHYS_ADDR_INVALID before enabling the new physical address. ++ ++.. c:function:: ++ void cec_s_phys_addr_from_edid(struct cec_adapter *adap, ++ const struct edid *edid); ++ ++A helper function that extracts the physical address from the edid struct ++and calls cec_s_phys_addr() with that address, or CEC_PHYS_ADDR_INVALID ++if the EDID did not contain a physical address or edid was a NULL pointer. ++ ++.. c:function:: ++ int cec_s_log_addrs(struct cec_adapter *adap, ++ struct cec_log_addrs *log_addrs, bool block); ++ ++Claim the CEC logical addresses. Should never be called if CEC_CAP_LOG_ADDRS ++is set. If block is true, then wait until the logical addresses have been ++claimed, otherwise just queue it and return. To unconfigure all logical ++addresses call this function with log_addrs set to NULL or with ++log_addrs->num_log_addrs set to 0. The block argument is ignored when ++unconfiguring. This function will just return if the physical address is ++invalid. Once the physical address becomes valid, then the framework will ++attempt to claim these logical addresses. ++ ++CEC Pin framework ++----------------- ++ ++Most CEC hardware operates on full CEC messages where the software provides ++the message and the hardware handles the low-level CEC protocol. But some ++hardware only drives the CEC pin and software has to handle the low-level ++CEC protocol. The CEC pin framework was created to handle such devices. ++ ++Note that due to the close-to-realtime requirements it can never be guaranteed ++to work 100%. This framework uses highres timers internally, but if a ++timer goes off too late by more than 300 microseconds wrong results can ++occur. In reality it appears to be fairly reliable. ++ ++One advantage of this low-level implementation is that it can be used as ++a cheap CEC analyser, especially if interrupts can be used to detect ++CEC pin transitions from low to high or vice versa. ++ ++.. kernel-doc:: include/media/cec-pin.h ++ ++CEC Notifier framework ++---------------------- ++ ++Most drm HDMI implementations have an integrated CEC implementation and no ++notifier support is needed. But some have independent CEC implementations ++that have their own driver. This could be an IP block for an SoC or a ++completely separate chip that deals with the CEC pin. For those cases a ++drm driver can install a notifier and use the notifier to inform the ++CEC driver about changes in the physical address. ++ ++.. kernel-doc:: include/media/cec-notifier.h +diff --git a/Documentation/media/uapi/cec/cec-api.rst b/Documentation/media/uapi/cec/cec-api.rst +new file mode 100644 +index 000000000000..b68ca9c1d2e0 +--- /dev/null ++++ b/Documentation/media/uapi/cec/cec-api.rst +@@ -0,0 +1,46 @@ ++.. -*- coding: utf-8; mode: rst -*- ++ ++.. include:: ++ ++.. _cec: ++ ++######################################### ++Part V - Consumer Electronics Control API ++######################################### ++ ++This part describes the CEC: Consumer Electronics Control ++ ++ ++.. only:: html ++ ++ .. class:: toc-title ++ ++ Table of Contents ++ ++.. toctree:: ++ :maxdepth: 5 ++ :numbered: ++ ++ cec-intro ++ cec-funcs ++ cec-header ++ ++ ++********************** ++Revision and Copyright ++********************** ++Authors: ++ ++- Verkuil, Hans ++ ++ - Initial version. ++ ++**Copyright** |copy| 2016 : Hans Verkuil ++ ++**************** ++Revision History ++**************** ++ ++:revision: 1.0.0 / 2016-03-17 (*hv*) ++ ++Initial revision +diff --git a/Documentation/media/uapi/cec/cec-func-close.rst b/Documentation/media/uapi/cec/cec-func-close.rst +new file mode 100644 +index 000000000000..334358dfa72e +--- /dev/null ++++ b/Documentation/media/uapi/cec/cec-func-close.rst +@@ -0,0 +1,47 @@ ++.. -*- coding: utf-8; mode: rst -*- ++ ++.. _cec-func-close: ++ ++*********** ++cec close() ++*********** ++ ++Name ++==== ++ ++cec-close - Close a cec device ++ ++ ++Synopsis ++======== ++ ++.. code-block:: c ++ ++ #include ++ ++ ++.. c:function:: int close( int fd ) ++ :name: cec-close ++ ++Arguments ++========= ++ ++``fd`` ++ File descriptor returned by :c:func:`open() `. ++ ++ ++Description ++=========== ++ ++Closes the cec device. Resources associated with the file descriptor are ++freed. The device configuration remain unchanged. ++ ++ ++Return Value ++============ ++ ++:c:func:`close() ` returns 0 on success. On error, -1 is returned, and ++``errno`` is set appropriately. Possible error codes are: ++ ++``EBADF`` ++ ``fd`` is not a valid open file descriptor. +diff --git a/Documentation/media/uapi/cec/cec-func-ioctl.rst b/Documentation/media/uapi/cec/cec-func-ioctl.rst +new file mode 100644 +index 000000000000..e2b6260b0086 +--- /dev/null ++++ b/Documentation/media/uapi/cec/cec-func-ioctl.rst +@@ -0,0 +1,66 @@ ++.. -*- coding: utf-8; mode: rst -*- ++ ++.. _cec-func-ioctl: ++ ++*********** ++cec ioctl() ++*********** ++ ++Name ++==== ++ ++cec-ioctl - Control a cec device ++ ++Synopsis ++======== ++ ++.. code-block:: c ++ ++ #include ++ ++ ++.. c:function:: int ioctl( int fd, int request, void *argp ) ++ :name: cec-ioctl ++ ++Arguments ++========= ++ ++``fd`` ++ File descriptor returned by :c:func:`open() `. ++ ++``request`` ++ CEC ioctl request code as defined in the cec.h header file, for ++ example :ref:`CEC_ADAP_G_CAPS `. ++ ++``argp`` ++ Pointer to a request-specific structure. ++ ++ ++Description ++=========== ++ ++The :c:func:`ioctl() ` function manipulates cec device parameters. The ++argument ``fd`` must be an open file descriptor. ++ ++The ioctl ``request`` code specifies the cec function to be called. It ++has encoded in it whether the argument is an input, output or read/write ++parameter, and the size of the argument ``argp`` in bytes. ++ ++Macros and structures definitions specifying cec ioctl requests and ++their parameters are located in the cec.h header file. All cec ioctl ++requests, their respective function and parameters are specified in ++:ref:`cec-user-func`. ++ ++ ++Return Value ++============ ++ ++On success 0 is returned, on error -1 and the ``errno`` variable is set ++appropriately. The generic error codes are described at the ++:ref:`Generic Error Codes ` chapter. ++ ++Request-specific error codes are listed in the individual requests ++descriptions. ++ ++When an ioctl that takes an output or read/write parameter fails, the ++parameter remains unmodified. +diff --git a/Documentation/media/uapi/cec/cec-func-open.rst b/Documentation/media/uapi/cec/cec-func-open.rst +new file mode 100644 +index 000000000000..5d6663a649bd +--- /dev/null ++++ b/Documentation/media/uapi/cec/cec-func-open.rst +@@ -0,0 +1,78 @@ ++.. -*- coding: utf-8; mode: rst -*- ++ ++.. _cec-func-open: ++ ++********** ++cec open() ++********** ++ ++Name ++==== ++ ++cec-open - Open a cec device ++ ++Synopsis ++======== ++ ++.. code-block:: c ++ ++ #include ++ ++ ++.. c:function:: int open( const char *device_name, int flags ) ++ :name: cec-open ++ ++ ++Arguments ++========= ++ ++``device_name`` ++ Device to be opened. ++ ++``flags`` ++ Open flags. Access mode must be ``O_RDWR``. ++ ++ When the ``O_NONBLOCK`` flag is given, the ++ :ref:`CEC_RECEIVE ` and :ref:`CEC_DQEVENT ` ioctls ++ will return the ``EAGAIN`` error code when no message or event is available, and ++ ioctls :ref:`CEC_TRANSMIT `, ++ :ref:`CEC_ADAP_S_PHYS_ADDR ` and ++ :ref:`CEC_ADAP_S_LOG_ADDRS ` ++ all return 0. ++ ++ Other flags have no effect. ++ ++ ++Description ++=========== ++ ++To open a cec device applications call :c:func:`open() ` with the ++desired device name. The function has no side effects; the device ++configuration remain unchanged. ++ ++When the device is opened in read-only mode, attempts to modify its ++configuration will result in an error, and ``errno`` will be set to ++EBADF. ++ ++ ++Return Value ++============ ++ ++:c:func:`open() ` returns the new file descriptor on success. On error, ++-1 is returned, and ``errno`` is set appropriately. Possible error codes ++include: ++ ++``EACCES`` ++ The requested access to the file is not allowed. ++ ++``EMFILE`` ++ The process already has the maximum number of files open. ++ ++``ENFILE`` ++ The system limit on the total number of open files has been reached. ++ ++``ENOMEM`` ++ Insufficient kernel memory was available. ++ ++``ENXIO`` ++ No device corresponding to this device special file exists. +diff --git a/Documentation/media/uapi/cec/cec-func-poll.rst b/Documentation/media/uapi/cec/cec-func-poll.rst +new file mode 100644 +index 000000000000..d49f1ee0742d +--- /dev/null ++++ b/Documentation/media/uapi/cec/cec-func-poll.rst +@@ -0,0 +1,77 @@ ++.. -*- coding: utf-8; mode: rst -*- ++ ++.. _cec-func-poll: ++ ++********** ++cec poll() ++********** ++ ++Name ++==== ++ ++cec-poll - Wait for some event on a file descriptor ++ ++ ++Synopsis ++======== ++ ++.. code-block:: c ++ ++ #include ++ ++ ++.. c:function:: int poll( struct pollfd *ufds, unsigned int nfds, int timeout ) ++ :name: cec-poll ++ ++Arguments ++========= ++ ++``ufds`` ++ List of FD events to be watched ++ ++``nfds`` ++ Number of FD events at the \*ufds array ++ ++``timeout`` ++ Timeout to wait for events ++ ++ ++Description ++=========== ++ ++With the :c:func:`poll() ` function applications can wait for CEC ++events. ++ ++On success :c:func:`poll() ` returns the number of file descriptors ++that have been selected (that is, file descriptors for which the ++``revents`` field of the respective struct :c:type:`pollfd` ++is non-zero). CEC devices set the ``POLLIN`` and ``POLLRDNORM`` flags in ++the ``revents`` field if there are messages in the receive queue. If the ++transmit queue has room for new messages, the ``POLLOUT`` and ++``POLLWRNORM`` flags are set. If there are events in the event queue, ++then the ``POLLPRI`` flag is set. When the function times out it returns ++a value of zero, on failure it returns -1 and the ``errno`` variable is ++set appropriately. ++ ++For more details see the :c:func:`poll() ` manual page. ++ ++ ++Return Value ++============ ++ ++On success, :c:func:`poll() ` returns the number structures which have ++non-zero ``revents`` fields, or zero if the call timed out. On error -1 ++is returned, and the ``errno`` variable is set appropriately: ++ ++``EBADF`` ++ One or more of the ``ufds`` members specify an invalid file ++ descriptor. ++ ++``EFAULT`` ++ ``ufds`` references an inaccessible memory area. ++ ++``EINTR`` ++ The call was interrupted by a signal. ++ ++``EINVAL`` ++ The ``nfds`` argument is greater than ``OPEN_MAX``. +diff --git a/Documentation/media/uapi/cec/cec-funcs.rst b/Documentation/media/uapi/cec/cec-funcs.rst +new file mode 100644 +index 000000000000..6d696cead5cb +--- /dev/null ++++ b/Documentation/media/uapi/cec/cec-funcs.rst +@@ -0,0 +1,20 @@ ++.. _cec-user-func: ++ ++****************** ++Function Reference ++****************** ++ ++ ++.. toctree:: ++ :maxdepth: 1 ++ ++ cec-func-open ++ cec-func-close ++ cec-func-ioctl ++ cec-func-poll ++ cec-ioc-adap-g-caps ++ cec-ioc-adap-g-log-addrs ++ cec-ioc-adap-g-phys-addr ++ cec-ioc-dqevent ++ cec-ioc-g-mode ++ cec-ioc-receive +diff --git a/Documentation/media/uapi/cec/cec-header.rst b/Documentation/media/uapi/cec/cec-header.rst +new file mode 100644 +index 000000000000..d5a9a2828274 +--- /dev/null ++++ b/Documentation/media/uapi/cec/cec-header.rst +@@ -0,0 +1,10 @@ ++.. -*- coding: utf-8; mode: rst -*- ++ ++.. _cec_header: ++ ++*************** ++CEC Header File ++*************** ++ ++.. kernel-include:: $BUILDDIR/cec.h.rst ++ +diff --git a/Documentation/media/uapi/cec/cec-intro.rst b/Documentation/media/uapi/cec/cec-intro.rst +new file mode 100644 +index 000000000000..07ee2b8f89d6 +--- /dev/null ++++ b/Documentation/media/uapi/cec/cec-intro.rst +@@ -0,0 +1,40 @@ ++.. _cec-intro: ++ ++Introduction ++============ ++ ++HDMI connectors provide a single pin for use by the Consumer Electronics ++Control protocol. This protocol allows different devices connected by an ++HDMI cable to communicate. The protocol for CEC version 1.4 is defined ++in supplements 1 (CEC) and 2 (HEAC or HDMI Ethernet and Audio Return ++Channel) of the HDMI 1.4a (:ref:`hdmi`) specification and the ++extensions added to CEC version 2.0 are defined in chapter 11 of the ++HDMI 2.0 (:ref:`hdmi2`) specification. ++ ++The bitrate is very slow (effectively no more than 36 bytes per second) ++and is based on the ancient AV.link protocol used in old SCART ++connectors. The protocol closely resembles a crazy Rube Goldberg ++contraption and is an unholy mix of low and high level messages. Some ++messages, especially those part of the HEAC protocol layered on top of ++CEC, need to be handled by the kernel, others can be handled either by ++the kernel or by userspace. ++ ++In addition, CEC can be implemented in HDMI receivers, transmitters and ++in USB devices that have an HDMI input and an HDMI output and that ++control just the CEC pin. ++ ++Drivers that support CEC will create a CEC device node (/dev/cecX) to ++give userspace access to the CEC adapter. The ++:ref:`CEC_ADAP_G_CAPS` ioctl will tell userspace what it is allowed to do. ++ ++In order to check the support and test it, it is suggested to download ++the `v4l-utils `_ package. It ++provides three tools to handle CEC: ++ ++- cec-ctl: the Swiss army knife of CEC. Allows you to configure, transmit ++ and monitor CEC messages. ++ ++- cec-compliance: does a CEC compliance test of a remote CEC device to ++ determine how compliant the CEC implementation is. ++ ++- cec-follower: emulates a CEC follower. +diff --git a/Documentation/media/uapi/cec/cec-ioc-adap-g-caps.rst b/Documentation/media/uapi/cec/cec-ioc-adap-g-caps.rst +new file mode 100644 +index 000000000000..6c1f6efb822e +--- /dev/null ++++ b/Documentation/media/uapi/cec/cec-ioc-adap-g-caps.rst +@@ -0,0 +1,139 @@ ++.. -*- coding: utf-8; mode: rst -*- ++ ++.. _CEC_ADAP_G_CAPS: ++ ++********************* ++ioctl CEC_ADAP_G_CAPS ++********************* ++ ++Name ++==== ++ ++CEC_ADAP_G_CAPS - Query device capabilities ++ ++Synopsis ++======== ++ ++.. c:function:: int ioctl( int fd, CEC_ADAP_G_CAPS, struct cec_caps *argp ) ++ :name: CEC_ADAP_G_CAPS ++ ++Arguments ++========= ++ ++``fd`` ++ File descriptor returned by :c:func:`open() `. ++ ++``argp`` ++ ++ ++Description ++=========== ++ ++All cec devices must support :ref:`ioctl CEC_ADAP_G_CAPS `. To query ++device information, applications call the ioctl with a pointer to a ++struct :c:type:`cec_caps`. The driver fills the structure and ++returns the information to the application. The ioctl never fails. ++ ++.. tabularcolumns:: |p{1.2cm}|p{2.5cm}|p{13.8cm}| ++ ++.. c:type:: cec_caps ++ ++.. flat-table:: struct cec_caps ++ :header-rows: 0 ++ :stub-columns: 0 ++ :widths: 1 1 16 ++ ++ * - char ++ - ``driver[32]`` ++ - The name of the cec adapter driver. ++ * - char ++ - ``name[32]`` ++ - The name of this CEC adapter. The combination ``driver`` and ++ ``name`` must be unique. ++ * - __u32 ++ - ``capabilities`` ++ - The capabilities of the CEC adapter, see ++ :ref:`cec-capabilities`. ++ * - __u32 ++ - ``version`` ++ - CEC Framework API version, formatted with the ``KERNEL_VERSION()`` ++ macro. ++ ++ ++.. tabularcolumns:: |p{4.4cm}|p{2.5cm}|p{10.6cm}| ++ ++.. _cec-capabilities: ++ ++.. flat-table:: CEC Capabilities Flags ++ :header-rows: 0 ++ :stub-columns: 0 ++ :widths: 3 1 8 ++ ++ * .. _`CEC-CAP-PHYS-ADDR`: ++ ++ - ``CEC_CAP_PHYS_ADDR`` ++ - 0x00000001 ++ - Userspace has to configure the physical address by calling ++ :ref:`ioctl CEC_ADAP_S_PHYS_ADDR `. If ++ this capability isn't set, then setting the physical address is ++ handled by the kernel whenever the EDID is set (for an HDMI ++ receiver) or read (for an HDMI transmitter). ++ * .. _`CEC-CAP-LOG-ADDRS`: ++ ++ - ``CEC_CAP_LOG_ADDRS`` ++ - 0x00000002 ++ - Userspace has to configure the logical addresses by calling ++ :ref:`ioctl CEC_ADAP_S_LOG_ADDRS `. If ++ this capability isn't set, then the kernel will have configured ++ this. ++ * .. _`CEC-CAP-TRANSMIT`: ++ ++ - ``CEC_CAP_TRANSMIT`` ++ - 0x00000004 ++ - Userspace can transmit CEC messages by calling ++ :ref:`ioctl CEC_TRANSMIT `. This implies that ++ userspace can be a follower as well, since being able to transmit ++ messages is a prerequisite of becoming a follower. If this ++ capability isn't set, then the kernel will handle all CEC ++ transmits and process all CEC messages it receives. ++ * .. _`CEC-CAP-PASSTHROUGH`: ++ ++ - ``CEC_CAP_PASSTHROUGH`` ++ - 0x00000008 ++ - Userspace can use the passthrough mode by calling ++ :ref:`ioctl CEC_S_MODE `. ++ * .. _`CEC-CAP-RC`: ++ ++ - ``CEC_CAP_RC`` ++ - 0x00000010 ++ - This adapter supports the remote control protocol. ++ * .. _`CEC-CAP-MONITOR-ALL`: ++ ++ - ``CEC_CAP_MONITOR_ALL`` ++ - 0x00000020 ++ - The CEC hardware can monitor all messages, not just directed and ++ broadcast messages. ++ * .. _`CEC-CAP-NEEDS-HPD`: ++ ++ - ``CEC_CAP_NEEDS_HPD`` ++ - 0x00000040 ++ - The CEC hardware is only active if the HDMI Hotplug Detect pin is ++ high. This makes it impossible to use CEC to wake up displays that ++ set the HPD pin low when in standby mode, but keep the CEC bus ++ alive. ++ * .. _`CEC-CAP-MONITOR-PIN`: ++ ++ - ``CEC_CAP_MONITOR_PIN`` ++ - 0x00000080 ++ - The CEC hardware can monitor CEC pin changes from low to high voltage ++ and vice versa. When in pin monitoring mode the application will ++ receive ``CEC_EVENT_PIN_CEC_LOW`` and ``CEC_EVENT_PIN_CEC_HIGH`` events. ++ ++ ++ ++Return Value ++============ ++ ++On success 0 is returned, on error -1 and the ``errno`` variable is set ++appropriately. The generic error codes are described at the ++:ref:`Generic Error Codes ` chapter. +diff --git a/Documentation/media/uapi/cec/cec-ioc-adap-g-log-addrs.rst b/Documentation/media/uapi/cec/cec-ioc-adap-g-log-addrs.rst +new file mode 100644 +index 000000000000..84f431a022ad +--- /dev/null ++++ b/Documentation/media/uapi/cec/cec-ioc-adap-g-log-addrs.rst +@@ -0,0 +1,371 @@ ++.. -*- coding: utf-8; mode: rst -*- ++ ++.. _CEC_ADAP_LOG_ADDRS: ++.. _CEC_ADAP_G_LOG_ADDRS: ++.. _CEC_ADAP_S_LOG_ADDRS: ++ ++**************************************************** ++ioctls CEC_ADAP_G_LOG_ADDRS and CEC_ADAP_S_LOG_ADDRS ++**************************************************** ++ ++Name ++==== ++ ++CEC_ADAP_G_LOG_ADDRS, CEC_ADAP_S_LOG_ADDRS - Get or set the logical addresses ++ ++ ++Synopsis ++======== ++ ++.. c:function:: int ioctl( int fd, CEC_ADAP_G_LOG_ADDRS, struct cec_log_addrs *argp ) ++ :name: CEC_ADAP_G_LOG_ADDRS ++ ++.. c:function:: int ioctl( int fd, CEC_ADAP_S_LOG_ADDRS, struct cec_log_addrs *argp ) ++ :name: CEC_ADAP_S_LOG_ADDRS ++ ++Arguments ++========= ++ ++``fd`` ++ File descriptor returned by :c:func:`open() `. ++ ++``argp`` ++ Pointer to struct :c:type:`cec_log_addrs`. ++ ++Description ++=========== ++ ++To query the current CEC logical addresses, applications call ++:ref:`ioctl CEC_ADAP_G_LOG_ADDRS ` with a pointer to a ++struct :c:type:`cec_log_addrs` where the driver stores the logical addresses. ++ ++To set new logical addresses, applications fill in ++struct :c:type:`cec_log_addrs` and call :ref:`ioctl CEC_ADAP_S_LOG_ADDRS ` ++with a pointer to this struct. The :ref:`ioctl CEC_ADAP_S_LOG_ADDRS ` ++is only available if ``CEC_CAP_LOG_ADDRS`` is set (the ``ENOTTY`` error code is ++returned otherwise). The :ref:`ioctl CEC_ADAP_S_LOG_ADDRS ` ++can only be called by a file descriptor in initiator mode (see :ref:`CEC_S_MODE`), if not ++the ``EBUSY`` error code will be returned. ++ ++To clear existing logical addresses set ``num_log_addrs`` to 0. All other fields ++will be ignored in that case. The adapter will go to the unconfigured state and the ++``cec_version``, ``vendor_id`` and ``osd_name`` fields are all reset to their default ++values (CEC version 2.0, no vendor ID and an empty OSD name). ++ ++If the physical address is valid (see :ref:`ioctl CEC_ADAP_S_PHYS_ADDR `), ++then this ioctl will block until all requested logical ++addresses have been claimed. If the file descriptor is in non-blocking mode then it will ++not wait for the logical addresses to be claimed, instead it just returns 0. ++ ++A :ref:`CEC_EVENT_STATE_CHANGE ` event is sent when the ++logical addresses are claimed or cleared. ++ ++Attempting to call :ref:`ioctl CEC_ADAP_S_LOG_ADDRS ` when ++logical address types are already defined will return with error ``EBUSY``. ++ ++.. c:type:: cec_log_addrs ++ ++.. tabularcolumns:: |p{1.0cm}|p{8.0cm}|p{7.5cm}| ++ ++.. cssclass:: longtable ++ ++.. flat-table:: struct cec_log_addrs ++ :header-rows: 0 ++ :stub-columns: 0 ++ :widths: 1 1 16 ++ ++ * - __u8 ++ - ``log_addr[CEC_MAX_LOG_ADDRS]`` ++ - The actual logical addresses that were claimed. This is set by the ++ driver. If no logical address could be claimed, then it is set to ++ ``CEC_LOG_ADDR_INVALID``. If this adapter is Unregistered, then ++ ``log_addr[0]`` is set to 0xf and all others to ++ ``CEC_LOG_ADDR_INVALID``. ++ * - __u16 ++ - ``log_addr_mask`` ++ - The bitmask of all logical addresses this adapter has claimed. If ++ this adapter is Unregistered then ``log_addr_mask`` sets bit 15 ++ and clears all other bits. If this adapter is not configured at ++ all, then ``log_addr_mask`` is set to 0. Set by the driver. ++ * - __u8 ++ - ``cec_version`` ++ - The CEC version that this adapter shall use. See ++ :ref:`cec-versions`. Used to implement the ++ ``CEC_MSG_CEC_VERSION`` and ``CEC_MSG_REPORT_FEATURES`` messages. ++ Note that :ref:`CEC_OP_CEC_VERSION_1_3A ` is not allowed by the CEC ++ framework. ++ * - __u8 ++ - ``num_log_addrs`` ++ - Number of logical addresses to set up. Must be ≤ ++ ``available_log_addrs`` as returned by ++ :ref:`CEC_ADAP_G_CAPS`. All arrays in ++ this structure are only filled up to index ++ ``available_log_addrs``-1. The remaining array elements will be ++ ignored. Note that the CEC 2.0 standard allows for a maximum of 2 ++ logical addresses, although some hardware has support for more. ++ ``CEC_MAX_LOG_ADDRS`` is 4. The driver will return the actual ++ number of logical addresses it could claim, which may be less than ++ what was requested. If this field is set to 0, then the CEC ++ adapter shall clear all claimed logical addresses and all other ++ fields will be ignored. ++ * - __u32 ++ - ``vendor_id`` ++ - The vendor ID is a 24-bit number that identifies the specific ++ vendor or entity. Based on this ID vendor specific commands may be ++ defined. If you do not want a vendor ID then set it to ++ ``CEC_VENDOR_ID_NONE``. ++ * - __u32 ++ - ``flags`` ++ - Flags. See :ref:`cec-log-addrs-flags` for a list of available flags. ++ * - char ++ - ``osd_name[15]`` ++ - The On-Screen Display name as is returned by the ++ ``CEC_MSG_SET_OSD_NAME`` message. ++ * - __u8 ++ - ``primary_device_type[CEC_MAX_LOG_ADDRS]`` ++ - Primary device type for each logical address. See ++ :ref:`cec-prim-dev-types` for possible types. ++ * - __u8 ++ - ``log_addr_type[CEC_MAX_LOG_ADDRS]`` ++ - Logical address types. See :ref:`cec-log-addr-types` for ++ possible types. The driver will update this with the actual ++ logical address type that it claimed (e.g. it may have to fallback ++ to :ref:`CEC_LOG_ADDR_TYPE_UNREGISTERED `). ++ * - __u8 ++ - ``all_device_types[CEC_MAX_LOG_ADDRS]`` ++ - CEC 2.0 specific: the bit mask of all device types. See ++ :ref:`cec-all-dev-types-flags`. It is used in the CEC 2.0 ++ ``CEC_MSG_REPORT_FEATURES`` message. For CEC 1.4 you can either leave ++ this field to 0, or fill it in according to the CEC 2.0 guidelines to ++ give the CEC framework more information about the device type, even ++ though the framework won't use it directly in the CEC message. ++ * - __u8 ++ - ``features[CEC_MAX_LOG_ADDRS][12]`` ++ - Features for each logical address. It is used in the CEC 2.0 ++ ``CEC_MSG_REPORT_FEATURES`` message. The 12 bytes include both the ++ RC Profile and the Device Features. For CEC 1.4 you can either leave ++ this field to all 0, or fill it in according to the CEC 2.0 guidelines to ++ give the CEC framework more information about the device type, even ++ though the framework won't use it directly in the CEC message. ++ ++ ++.. tabularcolumns:: |p{7.8cm}|p{1.0cm}|p{8.7cm}| ++ ++.. _cec-log-addrs-flags: ++ ++.. flat-table:: Flags for struct cec_log_addrs ++ :header-rows: 0 ++ :stub-columns: 0 ++ :widths: 3 1 4 ++ ++ * .. _`CEC-LOG-ADDRS-FL-ALLOW-UNREG-FALLBACK`: ++ ++ - ``CEC_LOG_ADDRS_FL_ALLOW_UNREG_FALLBACK`` ++ - 1 ++ - By default if no logical address of the requested type can be claimed, then ++ it will go back to the unconfigured state. If this flag is set, then it will ++ fallback to the Unregistered logical address. Note that if the Unregistered ++ logical address was explicitly requested, then this flag has no effect. ++ * .. _`CEC-LOG-ADDRS-FL-ALLOW-RC-PASSTHRU`: ++ ++ - ``CEC_LOG_ADDRS_FL_ALLOW_RC_PASSTHRU`` ++ - 2 ++ - By default the ``CEC_MSG_USER_CONTROL_PRESSED`` and ``CEC_MSG_USER_CONTROL_RELEASED`` ++ messages are only passed on to the follower(s), if any. If this flag is set, ++ then these messages are also passed on to the remote control input subsystem ++ and will appear as keystrokes. This features needs to be enabled explicitly. ++ If CEC is used to enter e.g. passwords, then you may not want to enable this ++ to avoid trivial snooping of the keystrokes. ++ * .. _`CEC-LOG-ADDRS-FL-CDC-ONLY`: ++ ++ - ``CEC_LOG_ADDRS_FL_CDC_ONLY`` ++ - 4 ++ - If this flag is set, then the device is CDC-Only. CDC-Only CEC devices ++ are CEC devices that can only handle CDC messages. ++ ++ All other messages are ignored. ++ ++ ++.. tabularcolumns:: |p{7.8cm}|p{1.0cm}|p{8.7cm}| ++ ++.. _cec-versions: ++ ++.. flat-table:: CEC Versions ++ :header-rows: 0 ++ :stub-columns: 0 ++ :widths: 3 1 4 ++ ++ * .. _`CEC-OP-CEC-VERSION-1-3A`: ++ ++ - ``CEC_OP_CEC_VERSION_1_3A`` ++ - 4 ++ - CEC version according to the HDMI 1.3a standard. ++ * .. _`CEC-OP-CEC-VERSION-1-4B`: ++ ++ - ``CEC_OP_CEC_VERSION_1_4B`` ++ - 5 ++ - CEC version according to the HDMI 1.4b standard. ++ * .. _`CEC-OP-CEC-VERSION-2-0`: ++ ++ - ``CEC_OP_CEC_VERSION_2_0`` ++ - 6 ++ - CEC version according to the HDMI 2.0 standard. ++ ++ ++.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}| ++ ++.. _cec-prim-dev-types: ++ ++.. flat-table:: CEC Primary Device Types ++ :header-rows: 0 ++ :stub-columns: 0 ++ :widths: 3 1 4 ++ ++ * .. _`CEC-OP-PRIM-DEVTYPE-TV`: ++ ++ - ``CEC_OP_PRIM_DEVTYPE_TV`` ++ - 0 ++ - Use for a TV. ++ * .. _`CEC-OP-PRIM-DEVTYPE-RECORD`: ++ ++ - ``CEC_OP_PRIM_DEVTYPE_RECORD`` ++ - 1 ++ - Use for a recording device. ++ * .. _`CEC-OP-PRIM-DEVTYPE-TUNER`: ++ ++ - ``CEC_OP_PRIM_DEVTYPE_TUNER`` ++ - 3 ++ - Use for a device with a tuner. ++ * .. _`CEC-OP-PRIM-DEVTYPE-PLAYBACK`: ++ ++ - ``CEC_OP_PRIM_DEVTYPE_PLAYBACK`` ++ - 4 ++ - Use for a playback device. ++ * .. _`CEC-OP-PRIM-DEVTYPE-AUDIOSYSTEM`: ++ ++ - ``CEC_OP_PRIM_DEVTYPE_AUDIOSYSTEM`` ++ - 5 ++ - Use for an audio system (e.g. an audio/video receiver). ++ * .. _`CEC-OP-PRIM-DEVTYPE-SWITCH`: ++ ++ - ``CEC_OP_PRIM_DEVTYPE_SWITCH`` ++ - 6 ++ - Use for a CEC switch. ++ * .. _`CEC-OP-PRIM-DEVTYPE-VIDEOPROC`: ++ ++ - ``CEC_OP_PRIM_DEVTYPE_VIDEOPROC`` ++ - 7 ++ - Use for a video processor device. ++ ++ ++.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}| ++ ++.. _cec-log-addr-types: ++ ++.. flat-table:: CEC Logical Address Types ++ :header-rows: 0 ++ :stub-columns: 0 ++ :widths: 3 1 16 ++ ++ * .. _`CEC-LOG-ADDR-TYPE-TV`: ++ ++ - ``CEC_LOG_ADDR_TYPE_TV`` ++ - 0 ++ - Use for a TV. ++ * .. _`CEC-LOG-ADDR-TYPE-RECORD`: ++ ++ - ``CEC_LOG_ADDR_TYPE_RECORD`` ++ - 1 ++ - Use for a recording device. ++ * .. _`CEC-LOG-ADDR-TYPE-TUNER`: ++ ++ - ``CEC_LOG_ADDR_TYPE_TUNER`` ++ - 2 ++ - Use for a tuner device. ++ * .. _`CEC-LOG-ADDR-TYPE-PLAYBACK`: ++ ++ - ``CEC_LOG_ADDR_TYPE_PLAYBACK`` ++ - 3 ++ - Use for a playback device. ++ * .. _`CEC-LOG-ADDR-TYPE-AUDIOSYSTEM`: ++ ++ - ``CEC_LOG_ADDR_TYPE_AUDIOSYSTEM`` ++ - 4 ++ - Use for an audio system device. ++ * .. _`CEC-LOG-ADDR-TYPE-SPECIFIC`: ++ ++ - ``CEC_LOG_ADDR_TYPE_SPECIFIC`` ++ - 5 ++ - Use for a second TV or for a video processor device. ++ * .. _`CEC-LOG-ADDR-TYPE-UNREGISTERED`: ++ ++ - ``CEC_LOG_ADDR_TYPE_UNREGISTERED`` ++ - 6 ++ - Use this if you just want to remain unregistered. Used for pure ++ CEC switches or CDC-only devices (CDC: Capability Discovery and ++ Control). ++ ++ ++ ++.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}| ++ ++.. _cec-all-dev-types-flags: ++ ++.. flat-table:: CEC All Device Types Flags ++ :header-rows: 0 ++ :stub-columns: 0 ++ :widths: 3 1 4 ++ ++ * .. _`CEC-OP-ALL-DEVTYPE-TV`: ++ ++ - ``CEC_OP_ALL_DEVTYPE_TV`` ++ - 0x80 ++ - This supports the TV type. ++ * .. _`CEC-OP-ALL-DEVTYPE-RECORD`: ++ ++ - ``CEC_OP_ALL_DEVTYPE_RECORD`` ++ - 0x40 ++ - This supports the Recording type. ++ * .. _`CEC-OP-ALL-DEVTYPE-TUNER`: ++ ++ - ``CEC_OP_ALL_DEVTYPE_TUNER`` ++ - 0x20 ++ - This supports the Tuner type. ++ * .. _`CEC-OP-ALL-DEVTYPE-PLAYBACK`: ++ ++ - ``CEC_OP_ALL_DEVTYPE_PLAYBACK`` ++ - 0x10 ++ - This supports the Playback type. ++ * .. _`CEC-OP-ALL-DEVTYPE-AUDIOSYSTEM`: ++ ++ - ``CEC_OP_ALL_DEVTYPE_AUDIOSYSTEM`` ++ - 0x08 ++ - This supports the Audio System type. ++ * .. _`CEC-OP-ALL-DEVTYPE-SWITCH`: ++ ++ - ``CEC_OP_ALL_DEVTYPE_SWITCH`` ++ - 0x04 ++ - This supports the CEC Switch or Video Processing type. ++ ++ ++ ++Return Value ++============ ++ ++On success 0 is returned, on error -1 and the ``errno`` variable is set ++appropriately. The generic error codes are described at the ++:ref:`Generic Error Codes ` chapter. ++ ++The :ref:`ioctl CEC_ADAP_S_LOG_ADDRS ` can return the following ++error codes: ++ ++ENOTTY ++ The ``CEC_CAP_LOG_ADDRS`` capability wasn't set, so this ioctl is not supported. ++ ++EBUSY ++ The CEC adapter is currently configuring itself, or it is already configured and ++ ``num_log_addrs`` is non-zero, or another filehandle is in exclusive follower or ++ initiator mode, or the filehandle is in mode ``CEC_MODE_NO_INITIATOR``. ++ ++EINVAL ++ The contents of struct :c:type:`cec_log_addrs` is invalid. +diff --git a/Documentation/media/uapi/cec/cec-ioc-adap-g-phys-addr.rst b/Documentation/media/uapi/cec/cec-ioc-adap-g-phys-addr.rst +new file mode 100644 +index 000000000000..9e49d4be35d5 +--- /dev/null ++++ b/Documentation/media/uapi/cec/cec-ioc-adap-g-phys-addr.rst +@@ -0,0 +1,93 @@ ++.. -*- coding: utf-8; mode: rst -*- ++ ++.. _CEC_ADAP_PHYS_ADDR: ++.. _CEC_ADAP_G_PHYS_ADDR: ++.. _CEC_ADAP_S_PHYS_ADDR: ++ ++**************************************************** ++ioctls CEC_ADAP_G_PHYS_ADDR and CEC_ADAP_S_PHYS_ADDR ++**************************************************** ++ ++Name ++==== ++ ++CEC_ADAP_G_PHYS_ADDR, CEC_ADAP_S_PHYS_ADDR - Get or set the physical address ++ ++ ++Synopsis ++======== ++ ++.. c:function:: int ioctl( int fd, CEC_ADAP_G_PHYS_ADDR, __u16 *argp ) ++ :name: CEC_ADAP_G_PHYS_ADDR ++ ++.. c:function:: int ioctl( int fd, CEC_ADAP_S_PHYS_ADDR, __u16 *argp ) ++ :name: CEC_ADAP_S_PHYS_ADDR ++ ++Arguments ++========= ++ ++``fd`` ++ File descriptor returned by :c:func:`open() `. ++ ++``argp`` ++ Pointer to the CEC address. ++ ++Description ++=========== ++ ++To query the current physical address applications call ++:ref:`ioctl CEC_ADAP_G_PHYS_ADDR ` with a pointer to a __u16 where the ++driver stores the physical address. ++ ++To set a new physical address applications store the physical address in ++a __u16 and call :ref:`ioctl CEC_ADAP_S_PHYS_ADDR ` with a pointer to ++this integer. The :ref:`ioctl CEC_ADAP_S_PHYS_ADDR ` is only available if ++``CEC_CAP_PHYS_ADDR`` is set (the ``ENOTTY`` error code will be returned ++otherwise). The :ref:`ioctl CEC_ADAP_S_PHYS_ADDR ` can only be called ++by a file descriptor in initiator mode (see :ref:`CEC_S_MODE`), if not ++the ``EBUSY`` error code will be returned. ++ ++To clear an existing physical address use ``CEC_PHYS_ADDR_INVALID``. ++The adapter will go to the unconfigured state. ++ ++If logical address types have been defined (see :ref:`ioctl CEC_ADAP_S_LOG_ADDRS `), ++then this ioctl will block until all ++requested logical addresses have been claimed. If the file descriptor is in non-blocking mode ++then it will not wait for the logical addresses to be claimed, instead it just returns 0. ++ ++A :ref:`CEC_EVENT_STATE_CHANGE ` event is sent when the physical address ++changes. ++ ++The physical address is a 16-bit number where each group of 4 bits ++represent a digit of the physical address a.b.c.d where the most ++significant 4 bits represent 'a'. The CEC root device (usually the TV) ++has address 0.0.0.0. Every device that is hooked up to an input of the ++TV has address a.0.0.0 (where 'a' is ≥ 1), devices hooked up to those in ++turn have addresses a.b.0.0, etc. So a topology of up to 5 devices deep ++is supported. The physical address a device shall use is stored in the ++EDID of the sink. ++ ++For example, the EDID for each HDMI input of the TV will have a ++different physical address of the form a.0.0.0 that the sources will ++read out and use as their physical address. ++ ++ ++Return Value ++============ ++ ++On success 0 is returned, on error -1 and the ``errno`` variable is set ++appropriately. The generic error codes are described at the ++:ref:`Generic Error Codes ` chapter. ++ ++The :ref:`ioctl CEC_ADAP_S_PHYS_ADDR ` can return the following ++error codes: ++ ++ENOTTY ++ The ``CEC_CAP_PHYS_ADDR`` capability wasn't set, so this ioctl is not supported. ++ ++EBUSY ++ Another filehandle is in exclusive follower or initiator mode, or the filehandle ++ is in mode ``CEC_MODE_NO_INITIATOR``. ++ ++EINVAL ++ The physical address is malformed. +diff --git a/Documentation/media/uapi/cec/cec-ioc-dqevent.rst b/Documentation/media/uapi/cec/cec-ioc-dqevent.rst +new file mode 100644 +index 000000000000..b6fd86424fbb +--- /dev/null ++++ b/Documentation/media/uapi/cec/cec-ioc-dqevent.rst +@@ -0,0 +1,226 @@ ++.. -*- coding: utf-8; mode: rst -*- ++ ++.. _CEC_DQEVENT: ++ ++***************** ++ioctl CEC_DQEVENT ++***************** ++ ++Name ++==== ++ ++CEC_DQEVENT - Dequeue a CEC event ++ ++ ++Synopsis ++======== ++ ++.. c:function:: int ioctl( int fd, CEC_DQEVENT, struct cec_event *argp ) ++ :name: CEC_DQEVENT ++ ++Arguments ++========= ++ ++``fd`` ++ File descriptor returned by :c:func:`open() `. ++ ++``argp`` ++ ++ ++Description ++=========== ++ ++CEC devices can send asynchronous events. These can be retrieved by ++calling :c:func:`CEC_DQEVENT`. If the file descriptor is in ++non-blocking mode and no event is pending, then it will return -1 and ++set errno to the ``EAGAIN`` error code. ++ ++The internal event queues are per-filehandle and per-event type. If ++there is no more room in a queue then the last event is overwritten with ++the new one. This means that intermediate results can be thrown away but ++that the latest event is always available. This also means that is it ++possible to read two successive events that have the same value (e.g. ++two :ref:`CEC_EVENT_STATE_CHANGE ` events with ++the same state). In that case the intermediate state changes were lost but ++it is guaranteed that the state did change in between the two events. ++ ++.. tabularcolumns:: |p{1.2cm}|p{2.9cm}|p{13.4cm}| ++ ++.. c:type:: cec_event_state_change ++ ++.. flat-table:: struct cec_event_state_change ++ :header-rows: 0 ++ :stub-columns: 0 ++ :widths: 1 1 8 ++ ++ * - __u16 ++ - ``phys_addr`` ++ - The current physical address. This is ``CEC_PHYS_ADDR_INVALID`` if no ++ valid physical address is set. ++ * - __u16 ++ - ``log_addr_mask`` ++ - The current set of claimed logical addresses. This is 0 if no logical ++ addresses are claimed or if ``phys_addr`` is ``CEC_PHYS_ADDR_INVALID``. ++ If bit 15 is set (``1 << CEC_LOG_ADDR_UNREGISTERED``) then this device ++ has the unregistered logical address. In that case all other bits are 0. ++ ++ ++.. c:type:: cec_event_lost_msgs ++ ++.. tabularcolumns:: |p{1.0cm}|p{2.0cm}|p{14.5cm}| ++ ++.. flat-table:: struct cec_event_lost_msgs ++ :header-rows: 0 ++ :stub-columns: 0 ++ :widths: 1 1 16 ++ ++ * - __u32 ++ - ``lost_msgs`` ++ - Set to the number of lost messages since the filehandle was opened ++ or since the last time this event was dequeued for this ++ filehandle. The messages lost are the oldest messages. So when a ++ new message arrives and there is no more room, then the oldest ++ message is discarded to make room for the new one. The internal ++ size of the message queue guarantees that all messages received in ++ the last two seconds will be stored. Since messages should be ++ replied to within a second according to the CEC specification, ++ this is more than enough. ++ ++ ++.. tabularcolumns:: |p{1.0cm}|p{4.4cm}|p{2.5cm}|p{9.6cm}| ++ ++.. c:type:: cec_event ++ ++.. flat-table:: struct cec_event ++ :header-rows: 0 ++ :stub-columns: 0 ++ :widths: 1 1 1 8 ++ ++ * - __u64 ++ - ``ts`` ++ - :cspan:`1`\ Timestamp of the event in ns. ++ ++ The timestamp has been taken from the ``CLOCK_MONOTONIC`` clock. ++ ++ To access the same clock from userspace use :c:func:`clock_gettime`. ++ * - __u32 ++ - ``event`` ++ - :cspan:`1` The CEC event type, see :ref:`cec-events`. ++ * - __u32 ++ - ``flags`` ++ - :cspan:`1` Event flags, see :ref:`cec-event-flags`. ++ * - union ++ - (anonymous) ++ - ++ - ++ * - ++ - struct cec_event_state_change ++ - ``state_change`` ++ - The new adapter state as sent by the :ref:`CEC_EVENT_STATE_CHANGE ` ++ event. ++ * - ++ - struct cec_event_lost_msgs ++ - ``lost_msgs`` ++ - The number of lost messages as sent by the :ref:`CEC_EVENT_LOST_MSGS ` ++ event. ++ ++ ++.. tabularcolumns:: |p{5.6cm}|p{0.9cm}|p{11.0cm}| ++ ++.. _cec-events: ++ ++.. flat-table:: CEC Events Types ++ :header-rows: 0 ++ :stub-columns: 0 ++ :widths: 3 1 16 ++ ++ * .. _`CEC-EVENT-STATE-CHANGE`: ++ ++ - ``CEC_EVENT_STATE_CHANGE`` ++ - 1 ++ - Generated when the CEC Adapter's state changes. When open() is ++ called an initial event will be generated for that filehandle with ++ the CEC Adapter's state at that time. ++ * .. _`CEC-EVENT-LOST-MSGS`: ++ ++ - ``CEC_EVENT_LOST_MSGS`` ++ - 2 ++ - Generated if one or more CEC messages were lost because the ++ application didn't dequeue CEC messages fast enough. ++ * .. _`CEC-EVENT-PIN-CEC-LOW`: ++ ++ - ``CEC_EVENT_PIN_CEC_LOW`` ++ - 3 ++ - Generated if the CEC pin goes from a high voltage to a low voltage. ++ Only applies to adapters that have the ``CEC_CAP_MONITOR_PIN`` ++ capability set. ++ * .. _`CEC-EVENT-PIN-CEC-HIGH`: ++ ++ - ``CEC_EVENT_PIN_CEC_HIGH`` ++ - 4 ++ - Generated if the CEC pin goes from a low voltage to a high voltage. ++ Only applies to adapters that have the ``CEC_CAP_MONITOR_PIN`` ++ capability set. ++ * .. _`CEC-EVENT-PIN-HPD-LOW`: ++ ++ - ``CEC_EVENT_PIN_HPD_LOW`` ++ - 5 ++ - Generated if the HPD pin goes from a high voltage to a low voltage. ++ Only applies to adapters that have the ``CEC_CAP_MONITOR_PIN`` ++ capability set. When open() is called, the HPD pin can be read and ++ if the HPD is low, then an initial event will be generated for that ++ filehandle. ++ * .. _`CEC-EVENT-PIN-HPD-HIGH`: ++ ++ - ``CEC_EVENT_PIN_HPD_HIGH`` ++ - 6 ++ - Generated if the HPD pin goes from a low voltage to a high voltage. ++ Only applies to adapters that have the ``CEC_CAP_MONITOR_PIN`` ++ capability set. When open() is called, the HPD pin can be read and ++ if the HPD is high, then an initial event will be generated for that ++ filehandle. ++ ++ ++.. tabularcolumns:: |p{6.0cm}|p{0.6cm}|p{10.9cm}| ++ ++.. _cec-event-flags: ++ ++.. flat-table:: CEC Event Flags ++ :header-rows: 0 ++ :stub-columns: 0 ++ :widths: 3 1 8 ++ ++ * .. _`CEC-EVENT-FL-INITIAL-STATE`: ++ ++ - ``CEC_EVENT_FL_INITIAL_STATE`` ++ - 1 ++ - Set for the initial events that are generated when the device is ++ opened. See the table above for which events do this. This allows ++ applications to learn the initial state of the CEC adapter at ++ open() time. ++ * .. _`CEC-EVENT-FL-DROPPED-EVENTS`: ++ ++ - ``CEC_EVENT_FL_DROPPED_EVENTS`` ++ - 2 ++ - Set if one or more events of the given event type have been dropped. ++ This is an indication that the application cannot keep up. ++ ++ ++ ++Return Value ++============ ++ ++On success 0 is returned, on error -1 and the ``errno`` variable is set ++appropriately. The generic error codes are described at the ++:ref:`Generic Error Codes ` chapter. ++ ++The :ref:`ioctl CEC_DQEVENT ` can return the following ++error codes: ++ ++EAGAIN ++ This is returned when the filehandle is in non-blocking mode and there ++ are no pending events. ++ ++ERESTARTSYS ++ An interrupt (e.g. Ctrl-C) arrived while in blocking mode waiting for ++ events to arrive. +diff --git a/Documentation/media/uapi/cec/cec-ioc-g-mode.rst b/Documentation/media/uapi/cec/cec-ioc-g-mode.rst +new file mode 100644 +index 000000000000..508e2e325683 +--- /dev/null ++++ b/Documentation/media/uapi/cec/cec-ioc-g-mode.rst +@@ -0,0 +1,293 @@ ++.. -*- coding: utf-8; mode: rst -*- ++ ++.. _CEC_MODE: ++.. _CEC_G_MODE: ++.. _CEC_S_MODE: ++ ++******************************** ++ioctls CEC_G_MODE and CEC_S_MODE ++******************************** ++ ++CEC_G_MODE, CEC_S_MODE - Get or set exclusive use of the CEC adapter ++ ++Synopsis ++======== ++ ++.. c:function:: int ioctl( int fd, CEC_G_MODE, __u32 *argp ) ++ :name: CEC_G_MODE ++ ++.. c:function:: int ioctl( int fd, CEC_S_MODE, __u32 *argp ) ++ :name: CEC_S_MODE ++ ++Arguments ++========= ++ ++``fd`` ++ File descriptor returned by :c:func:`open() `. ++ ++``argp`` ++ Pointer to CEC mode. ++ ++Description ++=========== ++ ++By default any filehandle can use :ref:`CEC_TRANSMIT`, but in order to prevent ++applications from stepping on each others toes it must be possible to ++obtain exclusive access to the CEC adapter. This ioctl sets the ++filehandle to initiator and/or follower mode which can be exclusive ++depending on the chosen mode. The initiator is the filehandle that is ++used to initiate messages, i.e. it commands other CEC devices. The ++follower is the filehandle that receives messages sent to the CEC ++adapter and processes them. The same filehandle can be both initiator ++and follower, or this role can be taken by two different filehandles. ++ ++When a CEC message is received, then the CEC framework will decide how ++it will be processed. If the message is a reply to an earlier ++transmitted message, then the reply is sent back to the filehandle that ++is waiting for it. In addition the CEC framework will process it. ++ ++If the message is not a reply, then the CEC framework will process it ++first. If there is no follower, then the message is just discarded and a ++feature abort is sent back to the initiator if the framework couldn't ++process it. If there is a follower, then the message is passed on to the ++follower who will use :ref:`ioctl CEC_RECEIVE ` to dequeue ++the new message. The framework expects the follower to make the right ++decisions. ++ ++The CEC framework will process core messages unless requested otherwise ++by the follower. The follower can enable the passthrough mode. In that ++case, the CEC framework will pass on most core messages without ++processing them and the follower will have to implement those messages. ++There are some messages that the core will always process, regardless of ++the passthrough mode. See :ref:`cec-core-processing` for details. ++ ++If there is no initiator, then any CEC filehandle can use ++:ref:`ioctl CEC_TRANSMIT `. If there is an exclusive ++initiator then only that initiator can call ++:ref:`CEC_TRANSMIT`. The follower can of course ++always call :ref:`ioctl CEC_TRANSMIT `. ++ ++Available initiator modes are: ++ ++.. tabularcolumns:: |p{5.6cm}|p{0.9cm}|p{11.0cm}| ++ ++.. _cec-mode-initiator_e: ++ ++.. flat-table:: Initiator Modes ++ :header-rows: 0 ++ :stub-columns: 0 ++ :widths: 3 1 16 ++ ++ * .. _`CEC-MODE-NO-INITIATOR`: ++ ++ - ``CEC_MODE_NO_INITIATOR`` ++ - 0x0 ++ - This is not an initiator, i.e. it cannot transmit CEC messages or ++ make any other changes to the CEC adapter. ++ * .. _`CEC-MODE-INITIATOR`: ++ ++ - ``CEC_MODE_INITIATOR`` ++ - 0x1 ++ - This is an initiator (the default when the device is opened) and ++ it can transmit CEC messages and make changes to the CEC adapter, ++ unless there is an exclusive initiator. ++ * .. _`CEC-MODE-EXCL-INITIATOR`: ++ ++ - ``CEC_MODE_EXCL_INITIATOR`` ++ - 0x2 ++ - This is an exclusive initiator and this file descriptor is the ++ only one that can transmit CEC messages and make changes to the ++ CEC adapter. If someone else is already the exclusive initiator ++ then an attempt to become one will return the ``EBUSY`` error code ++ error. ++ ++ ++Available follower modes are: ++ ++.. tabularcolumns:: |p{6.6cm}|p{0.9cm}|p{10.0cm}| ++ ++.. _cec-mode-follower_e: ++ ++.. cssclass:: longtable ++ ++.. flat-table:: Follower Modes ++ :header-rows: 0 ++ :stub-columns: 0 ++ :widths: 3 1 16 ++ ++ * .. _`CEC-MODE-NO-FOLLOWER`: ++ ++ - ``CEC_MODE_NO_FOLLOWER`` ++ - 0x00 ++ - This is not a follower (the default when the device is opened). ++ * .. _`CEC-MODE-FOLLOWER`: ++ ++ - ``CEC_MODE_FOLLOWER`` ++ - 0x10 ++ - This is a follower and it will receive CEC messages unless there ++ is an exclusive follower. You cannot become a follower if ++ :ref:`CEC_CAP_TRANSMIT ` is not set or if :ref:`CEC_MODE_NO_INITIATOR ` ++ was specified, the ``EINVAL`` error code is returned in that case. ++ * .. _`CEC-MODE-EXCL-FOLLOWER`: ++ ++ - ``CEC_MODE_EXCL_FOLLOWER`` ++ - 0x20 ++ - This is an exclusive follower and only this file descriptor will ++ receive CEC messages for processing. If someone else is already ++ the exclusive follower then an attempt to become one will return ++ the ``EBUSY`` error code. You cannot become a follower if ++ :ref:`CEC_CAP_TRANSMIT ` is not set or if :ref:`CEC_MODE_NO_INITIATOR ` ++ was specified, the ``EINVAL`` error code is returned in that case. ++ * .. _`CEC-MODE-EXCL-FOLLOWER-PASSTHRU`: ++ ++ - ``CEC_MODE_EXCL_FOLLOWER_PASSTHRU`` ++ - 0x30 ++ - This is an exclusive follower and only this file descriptor will ++ receive CEC messages for processing. In addition it will put the ++ CEC device into passthrough mode, allowing the exclusive follower ++ to handle most core messages instead of relying on the CEC ++ framework for that. If someone else is already the exclusive ++ follower then an attempt to become one will return the ``EBUSY`` error ++ code. You cannot become a follower if :ref:`CEC_CAP_TRANSMIT ` ++ is not set or if :ref:`CEC_MODE_NO_INITIATOR ` was specified, ++ the ``EINVAL`` error code is returned in that case. ++ * .. _`CEC-MODE-MONITOR-PIN`: ++ ++ - ``CEC_MODE_MONITOR_PIN`` ++ - 0xd0 ++ - Put the file descriptor into pin monitoring mode. Can only be used in ++ combination with :ref:`CEC_MODE_NO_INITIATOR `, ++ otherwise the ``EINVAL`` error code will be returned. ++ This mode requires that the :ref:`CEC_CAP_MONITOR_PIN ` ++ capability is set, otherwise the ``EINVAL`` error code is returned. ++ While in pin monitoring mode this file descriptor can receive the ++ ``CEC_EVENT_PIN_CEC_LOW`` and ``CEC_EVENT_PIN_CEC_HIGH`` events to see the ++ low-level CEC pin transitions. This is very useful for debugging. ++ This mode is only allowed if the process has the ``CAP_NET_ADMIN`` ++ capability. If that is not set, then the ``EPERM`` error code is returned. ++ * .. _`CEC-MODE-MONITOR`: ++ ++ - ``CEC_MODE_MONITOR`` ++ - 0xe0 ++ - Put the file descriptor into monitor mode. Can only be used in ++ combination with :ref:`CEC_MODE_NO_INITIATOR `,i ++ otherwise the ``EINVAL`` error code will be returned. ++ In monitor mode all messages this CEC ++ device transmits and all messages it receives (both broadcast ++ messages and directed messages for one its logical addresses) will ++ be reported. This is very useful for debugging. This is only ++ allowed if the process has the ``CAP_NET_ADMIN`` capability. If ++ that is not set, then the ``EPERM`` error code is returned. ++ * .. _`CEC-MODE-MONITOR-ALL`: ++ ++ - ``CEC_MODE_MONITOR_ALL`` ++ - 0xf0 ++ - Put the file descriptor into 'monitor all' mode. Can only be used ++ in combination with :ref:`CEC_MODE_NO_INITIATOR `, otherwise ++ the ``EINVAL`` error code will be returned. In 'monitor all' mode all messages ++ this CEC device transmits and all messages it receives, including ++ directed messages for other CEC devices will be reported. This is ++ very useful for debugging, but not all devices support this. This ++ mode requires that the :ref:`CEC_CAP_MONITOR_ALL ` capability is set, ++ otherwise the ``EINVAL`` error code is returned. This is only allowed if ++ the process has the ``CAP_NET_ADMIN`` capability. If that is not ++ set, then the ``EPERM`` error code is returned. ++ ++ ++Core message processing details: ++ ++.. tabularcolumns:: |p{6.6cm}|p{10.9cm}| ++ ++.. _cec-core-processing: ++ ++.. flat-table:: Core Message Processing ++ :header-rows: 0 ++ :stub-columns: 0 ++ :widths: 1 8 ++ ++ * .. _`CEC-MSG-GET-CEC-VERSION`: ++ ++ - ``CEC_MSG_GET_CEC_VERSION`` ++ - The core will return the CEC version that was set with ++ :ref:`ioctl CEC_ADAP_S_LOG_ADDRS `, ++ except when in passthrough mode. In passthrough mode the core ++ does nothing and this message has to be handled by a follower ++ instead. ++ * .. _`CEC-MSG-GIVE-DEVICE-VENDOR-ID`: ++ ++ - ``CEC_MSG_GIVE_DEVICE_VENDOR_ID`` ++ - The core will return the vendor ID that was set with ++ :ref:`ioctl CEC_ADAP_S_LOG_ADDRS `, ++ except when in passthrough mode. In passthrough mode the core ++ does nothing and this message has to be handled by a follower ++ instead. ++ * .. _`CEC-MSG-ABORT`: ++ ++ - ``CEC_MSG_ABORT`` ++ - The core will return a Feature Abort message with reason ++ 'Feature Refused' as per the specification, except when in ++ passthrough mode. In passthrough mode the core does nothing ++ and this message has to be handled by a follower instead. ++ * .. _`CEC-MSG-GIVE-PHYSICAL-ADDR`: ++ ++ - ``CEC_MSG_GIVE_PHYSICAL_ADDR`` ++ - The core will report the current physical address, except when ++ in passthrough mode. In passthrough mode the core does nothing ++ and this message has to be handled by a follower instead. ++ * .. _`CEC-MSG-GIVE-OSD-NAME`: ++ ++ - ``CEC_MSG_GIVE_OSD_NAME`` ++ - The core will report the current OSD name that was set with ++ :ref:`ioctl CEC_ADAP_S_LOG_ADDRS `, ++ except when in passthrough mode. In passthrough mode the core ++ does nothing and this message has to be handled by a follower ++ instead. ++ * .. _`CEC-MSG-GIVE-FEATURES`: ++ ++ - ``CEC_MSG_GIVE_FEATURES`` ++ - The core will do nothing if the CEC version is older than 2.0, ++ otherwise it will report the current features that were set with ++ :ref:`ioctl CEC_ADAP_S_LOG_ADDRS `, ++ except when in passthrough mode. In passthrough mode the core ++ does nothing (for any CEC version) and this message has to be handled ++ by a follower instead. ++ * .. _`CEC-MSG-USER-CONTROL-PRESSED`: ++ ++ - ``CEC_MSG_USER_CONTROL_PRESSED`` ++ - If :ref:`CEC_CAP_RC ` is set and if ++ :ref:`CEC_LOG_ADDRS_FL_ALLOW_RC_PASSTHRU ` ++ is set, then generate a remote control key ++ press. This message is always passed on to the follower(s). ++ * .. _`CEC-MSG-USER-CONTROL-RELEASED`: ++ ++ - ``CEC_MSG_USER_CONTROL_RELEASED`` ++ - If :ref:`CEC_CAP_RC ` is set and if ++ :ref:`CEC_LOG_ADDRS_FL_ALLOW_RC_PASSTHRU ` ++ is set, then generate a remote control key ++ release. This message is always passed on to the follower(s). ++ * .. _`CEC-MSG-REPORT-PHYSICAL-ADDR`: ++ ++ - ``CEC_MSG_REPORT_PHYSICAL_ADDR`` ++ - The CEC framework will make note of the reported physical address ++ and then just pass the message on to the follower(s). ++ ++ ++ ++Return Value ++============ ++ ++On success 0 is returned, on error -1 and the ``errno`` variable is set ++appropriately. The generic error codes are described at the ++:ref:`Generic Error Codes ` chapter. ++ ++The :ref:`ioctl CEC_S_MODE ` can return the following ++error codes: ++ ++EINVAL ++ The requested mode is invalid. ++ ++EPERM ++ Monitor mode is requested without having root permissions ++ ++EBUSY ++ Someone else is already an exclusive follower or initiator. +diff --git a/Documentation/media/uapi/cec/cec-ioc-receive.rst b/Documentation/media/uapi/cec/cec-ioc-receive.rst +new file mode 100644 +index 000000000000..bdad4b197bcd +--- /dev/null ++++ b/Documentation/media/uapi/cec/cec-ioc-receive.rst +@@ -0,0 +1,344 @@ ++.. -*- coding: utf-8; mode: rst -*- ++ ++.. _CEC_TRANSMIT: ++.. _CEC_RECEIVE: ++ ++*********************************** ++ioctls CEC_RECEIVE and CEC_TRANSMIT ++*********************************** ++ ++Name ++==== ++ ++CEC_RECEIVE, CEC_TRANSMIT - Receive or transmit a CEC message ++ ++ ++Synopsis ++======== ++ ++.. c:function:: int ioctl( int fd, CEC_RECEIVE, struct cec_msg *argp ) ++ :name: CEC_RECEIVE ++ ++.. c:function:: int ioctl( int fd, CEC_TRANSMIT, struct cec_msg *argp ) ++ :name: CEC_TRANSMIT ++ ++Arguments ++========= ++ ++``fd`` ++ File descriptor returned by :c:func:`open() `. ++ ++``argp`` ++ Pointer to struct cec_msg. ++ ++Description ++=========== ++ ++To receive a CEC message the application has to fill in the ++``timeout`` field of struct :c:type:`cec_msg` and pass it to ++:ref:`ioctl CEC_RECEIVE `. ++If the file descriptor is in non-blocking mode and there are no received ++messages pending, then it will return -1 and set errno to the ``EAGAIN`` ++error code. If the file descriptor is in blocking mode and ``timeout`` ++is non-zero and no message arrived within ``timeout`` milliseconds, then ++it will return -1 and set errno to the ``ETIMEDOUT`` error code. ++ ++A received message can be: ++ ++1. a message received from another CEC device (the ``sequence`` field will ++ be 0). ++2. the result of an earlier non-blocking transmit (the ``sequence`` field will ++ be non-zero). ++ ++To send a CEC message the application has to fill in the struct ++:c:type:`cec_msg` and pass it to :ref:`ioctl CEC_TRANSMIT `. ++The :ref:`ioctl CEC_TRANSMIT ` is only available if ++``CEC_CAP_TRANSMIT`` is set. If there is no more room in the transmit ++queue, then it will return -1 and set errno to the ``EBUSY`` error code. ++The transmit queue has enough room for 18 messages (about 1 second worth ++of 2-byte messages). Note that the CEC kernel framework will also reply ++to core messages (see :ref:`cec-core-processing`), so it is not a good ++idea to fully fill up the transmit queue. ++ ++If the file descriptor is in non-blocking mode then the transmit will ++return 0 and the result of the transmit will be available via ++:ref:`ioctl CEC_RECEIVE ` once the transmit has finished ++(including waiting for a reply, if requested). ++ ++The ``sequence`` field is filled in for every transmit and this can be ++checked against the received messages to find the corresponding transmit ++result. ++ ++Normally calling :ref:`ioctl CEC_TRANSMIT ` when the physical ++address is invalid (due to e.g. a disconnect) will return ``ENONET``. ++ ++However, the CEC specification allows sending messages from 'Unregistered' to ++'TV' when the physical address is invalid since some TVs pull the hotplug detect ++pin of the HDMI connector low when they go into standby, or when switching to ++another input. ++ ++When the hotplug detect pin goes low the EDID disappears, and thus the ++physical address, but the cable is still connected and CEC still works. ++In order to detect/wake up the device it is allowed to send poll and 'Image/Text ++View On' messages from initiator 0xf ('Unregistered') to destination 0 ('TV'). ++ ++.. tabularcolumns:: |p{1.0cm}|p{3.5cm}|p{13.0cm}| ++ ++.. c:type:: cec_msg ++ ++.. cssclass:: longtable ++ ++.. flat-table:: struct cec_msg ++ :header-rows: 0 ++ :stub-columns: 0 ++ :widths: 1 1 16 ++ ++ * - __u64 ++ - ``tx_ts`` ++ - Timestamp in ns of when the last byte of the message was transmitted. ++ The timestamp has been taken from the ``CLOCK_MONOTONIC`` clock. To access ++ the same clock from userspace use :c:func:`clock_gettime`. ++ * - __u64 ++ - ``rx_ts`` ++ - Timestamp in ns of when the last byte of the message was received. ++ The timestamp has been taken from the ``CLOCK_MONOTONIC`` clock. To access ++ the same clock from userspace use :c:func:`clock_gettime`. ++ * - __u32 ++ - ``len`` ++ - The length of the message. For :ref:`ioctl CEC_TRANSMIT ` this is filled in ++ by the application. The driver will fill this in for ++ :ref:`ioctl CEC_RECEIVE `. For :ref:`ioctl CEC_TRANSMIT ` it will be ++ filled in by the driver with the length of the reply message if ``reply`` was set. ++ * - __u32 ++ - ``timeout`` ++ - The timeout in milliseconds. This is the time the device will wait ++ for a message to be received before timing out. If it is set to 0, ++ then it will wait indefinitely when it is called by :ref:`ioctl CEC_RECEIVE `. ++ If it is 0 and it is called by :ref:`ioctl CEC_TRANSMIT `, ++ then it will be replaced by 1000 if the ``reply`` is non-zero or ++ ignored if ``reply`` is 0. ++ * - __u32 ++ - ``sequence`` ++ - A non-zero sequence number is automatically assigned by the CEC framework ++ for all transmitted messages. It is used by the CEC framework when it queues ++ the transmit result (when transmit was called in non-blocking mode). This ++ allows the application to associate the received message with the original ++ transmit. ++ * - __u32 ++ - ``flags`` ++ - Flags. See :ref:`cec-msg-flags` for a list of available flags. ++ * - __u8 ++ - ``tx_status`` ++ - The status bits of the transmitted message. See ++ :ref:`cec-tx-status` for the possible status values. It is 0 if ++ this message was received, not transmitted. ++ * - __u8 ++ - ``msg[16]`` ++ - The message payload. For :ref:`ioctl CEC_TRANSMIT ` this is filled in by the ++ application. The driver will fill this in for :ref:`ioctl CEC_RECEIVE `. ++ For :ref:`ioctl CEC_TRANSMIT ` it will be filled in by the driver with ++ the payload of the reply message if ``timeout`` was set. ++ * - __u8 ++ - ``reply`` ++ - Wait until this message is replied. If ``reply`` is 0 and the ++ ``timeout`` is 0, then don't wait for a reply but return after ++ transmitting the message. Ignored by :ref:`ioctl CEC_RECEIVE `. ++ The case where ``reply`` is 0 (this is the opcode for the Feature Abort ++ message) and ``timeout`` is non-zero is specifically allowed to make it ++ possible to send a message and wait up to ``timeout`` milliseconds for a ++ Feature Abort reply. In this case ``rx_status`` will either be set ++ to :ref:`CEC_RX_STATUS_TIMEOUT ` or ++ :ref:`CEC_RX_STATUS_FEATURE_ABORT `. ++ ++ If the transmitter message is ``CEC_MSG_INITIATE_ARC`` then the ``reply`` ++ values ``CEC_MSG_REPORT_ARC_INITIATED`` and ``CEC_MSG_REPORT_ARC_TERMINATED`` ++ are processed differently: either value will match both possible replies. ++ The reason is that the ``CEC_MSG_INITIATE_ARC`` message is the only CEC ++ message that has two possible replies other than Feature Abort. The ++ ``reply`` field will be updated with the actual reply so that it is ++ synchronized with the contents of the received message. ++ * - __u8 ++ - ``rx_status`` ++ - The status bits of the received message. See ++ :ref:`cec-rx-status` for the possible status values. It is 0 if ++ this message was transmitted, not received, unless this is the ++ reply to a transmitted message. In that case both ``rx_status`` ++ and ``tx_status`` are set. ++ * - __u8 ++ - ``tx_status`` ++ - The status bits of the transmitted message. See ++ :ref:`cec-tx-status` for the possible status values. It is 0 if ++ this message was received, not transmitted. ++ * - __u8 ++ - ``tx_arb_lost_cnt`` ++ - A counter of the number of transmit attempts that resulted in the ++ Arbitration Lost error. This is only set if the hardware supports ++ this, otherwise it is always 0. This counter is only valid if the ++ :ref:`CEC_TX_STATUS_ARB_LOST ` status bit is set. ++ * - __u8 ++ - ``tx_nack_cnt`` ++ - A counter of the number of transmit attempts that resulted in the ++ Not Acknowledged error. This is only set if the hardware supports ++ this, otherwise it is always 0. This counter is only valid if the ++ :ref:`CEC_TX_STATUS_NACK ` status bit is set. ++ * - __u8 ++ - ``tx_low_drive_cnt`` ++ - A counter of the number of transmit attempts that resulted in the ++ Arbitration Lost error. This is only set if the hardware supports ++ this, otherwise it is always 0. This counter is only valid if the ++ :ref:`CEC_TX_STATUS_LOW_DRIVE ` status bit is set. ++ * - __u8 ++ - ``tx_error_cnt`` ++ - A counter of the number of transmit errors other than Arbitration ++ Lost or Not Acknowledged. This is only set if the hardware ++ supports this, otherwise it is always 0. This counter is only ++ valid if the :ref:`CEC_TX_STATUS_ERROR ` status bit is set. ++ ++ ++.. tabularcolumns:: |p{6.2cm}|p{1.0cm}|p{10.3cm}| ++ ++.. _cec-msg-flags: ++ ++.. flat-table:: Flags for struct cec_msg ++ :header-rows: 0 ++ :stub-columns: 0 ++ :widths: 3 1 4 ++ ++ * .. _`CEC-MSG-FL-REPLY-TO-FOLLOWERS`: ++ ++ - ``CEC_MSG_FL_REPLY_TO_FOLLOWERS`` ++ - 1 ++ - If a CEC transmit expects a reply, then by default that reply is only sent to ++ the filehandle that called :ref:`ioctl CEC_TRANSMIT `. If this ++ flag is set, then the reply is also sent to all followers, if any. If the ++ filehandle that called :ref:`ioctl CEC_TRANSMIT ` is also a ++ follower, then that filehandle will receive the reply twice: once as the ++ result of the :ref:`ioctl CEC_TRANSMIT `, and once via ++ :ref:`ioctl CEC_RECEIVE `. ++ ++ ++.. tabularcolumns:: |p{5.6cm}|p{0.9cm}|p{11.0cm}| ++ ++.. _cec-tx-status: ++ ++.. flat-table:: CEC Transmit Status ++ :header-rows: 0 ++ :stub-columns: 0 ++ :widths: 3 1 16 ++ ++ * .. _`CEC-TX-STATUS-OK`: ++ ++ - ``CEC_TX_STATUS_OK`` ++ - 0x01 ++ - The message was transmitted successfully. This is mutually ++ exclusive with :ref:`CEC_TX_STATUS_MAX_RETRIES `. Other bits can still ++ be set if earlier attempts met with failure before the transmit ++ was eventually successful. ++ * .. _`CEC-TX-STATUS-ARB-LOST`: ++ ++ - ``CEC_TX_STATUS_ARB_LOST`` ++ - 0x02 ++ - CEC line arbitration was lost. ++ * .. _`CEC-TX-STATUS-NACK`: ++ ++ - ``CEC_TX_STATUS_NACK`` ++ - 0x04 ++ - Message was not acknowledged. ++ * .. _`CEC-TX-STATUS-LOW-DRIVE`: ++ ++ - ``CEC_TX_STATUS_LOW_DRIVE`` ++ - 0x08 ++ - Low drive was detected on the CEC bus. This indicates that a ++ follower detected an error on the bus and requests a ++ retransmission. ++ * .. _`CEC-TX-STATUS-ERROR`: ++ ++ - ``CEC_TX_STATUS_ERROR`` ++ - 0x10 ++ - Some error occurred. This is used for any errors that do not fit ++ ``CEC_TX_STATUS_ARB_LOST`` or ``CEC_TX_STATUS_LOW_DRIVE``, either because ++ the hardware could not tell which error occurred, or because the hardware ++ tested for other conditions besides those two. ++ * .. _`CEC-TX-STATUS-MAX-RETRIES`: ++ ++ - ``CEC_TX_STATUS_MAX_RETRIES`` ++ - 0x20 ++ - The transmit failed after one or more retries. This status bit is ++ mutually exclusive with :ref:`CEC_TX_STATUS_OK `. Other bits can still ++ be set to explain which failures were seen. ++ ++ ++.. tabularcolumns:: |p{5.6cm}|p{0.9cm}|p{11.0cm}| ++ ++.. _cec-rx-status: ++ ++.. flat-table:: CEC Receive Status ++ :header-rows: 0 ++ :stub-columns: 0 ++ :widths: 3 1 16 ++ ++ * .. _`CEC-RX-STATUS-OK`: ++ ++ - ``CEC_RX_STATUS_OK`` ++ - 0x01 ++ - The message was received successfully. ++ * .. _`CEC-RX-STATUS-TIMEOUT`: ++ ++ - ``CEC_RX_STATUS_TIMEOUT`` ++ - 0x02 ++ - The reply to an earlier transmitted message timed out. ++ * .. _`CEC-RX-STATUS-FEATURE-ABORT`: ++ ++ - ``CEC_RX_STATUS_FEATURE_ABORT`` ++ - 0x04 ++ - The message was received successfully but the reply was ++ ``CEC_MSG_FEATURE_ABORT``. This status is only set if this message ++ was the reply to an earlier transmitted message. ++ ++ ++ ++Return Value ++============ ++ ++On success 0 is returned, on error -1 and the ``errno`` variable is set ++appropriately. The generic error codes are described at the ++:ref:`Generic Error Codes ` chapter. ++ ++The :ref:`ioctl CEC_RECEIVE ` can return the following ++error codes: ++ ++EAGAIN ++ No messages are in the receive queue, and the filehandle is in non-blocking mode. ++ ++ETIMEDOUT ++ The ``timeout`` was reached while waiting for a message. ++ ++ERESTARTSYS ++ The wait for a message was interrupted (e.g. by Ctrl-C). ++ ++The :ref:`ioctl CEC_TRANSMIT ` can return the following ++error codes: ++ ++ENOTTY ++ The ``CEC_CAP_TRANSMIT`` capability wasn't set, so this ioctl is not supported. ++ ++EPERM ++ The CEC adapter is not configured, i.e. :ref:`ioctl CEC_ADAP_S_LOG_ADDRS ` ++ has never been called. ++ ++ENONET ++ The CEC adapter is not configured, i.e. :ref:`ioctl CEC_ADAP_S_LOG_ADDRS ` ++ was called, but the physical address is invalid so no logical address was claimed. ++ An exception is made in this case for transmits from initiator 0xf ('Unregistered') ++ to destination 0 ('TV'). In that case the transmit will proceed as usual. ++ ++EBUSY ++ Another filehandle is in exclusive follower or initiator mode, or the filehandle ++ is in mode ``CEC_MODE_NO_INITIATOR``. This is also returned if the transmit ++ queue is full. ++ ++EINVAL ++ The contents of struct :c:type:`cec_msg` is invalid. ++ ++ERESTARTSYS ++ The wait for a successful transmit was interrupted (e.g. by Ctrl-C). +diff --git a/MAINTAINERS b/MAINTAINERS +index 443bc975b562..225ab2c1d35b 100644 +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -2674,6 +2674,22 @@ F: drivers/net/ieee802154/cc2520.c + F: include/linux/spi/cc2520.h + F: Documentation/devicetree/bindings/net/ieee802154/cc2520.txt + ++CEC FRAMEWORK ++M: Hans Verkuil ++L: linux-media@vger.kernel.org ++T: git git://linuxtv.org/media_tree.git ++W: http://linuxtv.org ++S: Supported ++F: Documentation/media/kapi/cec-core.rst ++F: Documentation/media/uapi/cec ++F: drivers/media/cec/ ++F: drivers/media/rc/keymaps/rc-cec.c ++F: include/media/cec.h ++F: include/media/cec-notifier.h ++F: include/uapi/linux/cec.h ++F: include/uapi/linux/cec-funcs.h ++F: Documentation/devicetree/bindings/media/cec.txt ++ + CELL BROADBAND ENGINE ARCHITECTURE + M: Arnd Bergmann + L: linuxppc-dev@lists.ozlabs.org +diff --git a/drivers/media/cec/cec-adap.c b/drivers/media/cec/cec-adap.c +index 8c75a51333b2..4f5d382268f7 100644 +--- a/drivers/media/cec/cec-adap.c ++++ b/drivers/media/cec/cec-adap.c +@@ -202,7 +202,10 @@ static void cec_queue_msg_fh(struct cec_fh *fh, const struct cec_msg *msg) + { + static const struct cec_event ev_lost_msgs = { + .event = CEC_EVENT_LOST_MSGS, +- .lost_msgs.lost_msgs = 1, ++ .flags = 0, ++ { ++ .lost_msgs = { 1 }, ++ }, + }; + struct cec_msg_entry *entry; + +@@ -1793,6 +1796,9 @@ static int cec_receive_notify(struct cec_adapter *adap, struct cec_msg *msg, + int la_idx = cec_log_addr2idx(adap, dest_laddr); + bool from_unregistered = init_laddr == 0xf; + struct cec_msg tx_cec_msg = { }; ++#ifdef CONFIG_MEDIA_CEC_RC ++ int scancode; ++#endif + + dprintk(2, "%s: %*ph\n", __func__, msg->len, msg->msg); + +@@ -1888,11 +1894,9 @@ static int cec_receive_notify(struct cec_adapter *adap, struct cec_msg *msg, + */ + case 0x60: + if (msg->len == 2) +- rc_keydown(adap->rc, RC_TYPE_CEC, +- msg->msg[2], 0); ++ scancode = msg->msg[2]; + else +- rc_keydown(adap->rc, RC_TYPE_CEC, +- msg->msg[2] << 8 | msg->msg[3], 0); ++ scancode = msg->msg[2] << 8 | msg->msg[3]; + break; + /* + * Other function messages that are not handled. +@@ -1905,11 +1909,54 @@ static int cec_receive_notify(struct cec_adapter *adap, struct cec_msg *msg, + */ + case 0x56: case 0x57: + case 0x67: case 0x68: case 0x69: case 0x6a: ++ scancode = -1; + break; + default: +- rc_keydown(adap->rc, RC_TYPE_CEC, msg->msg[2], 0); ++ scancode = msg->msg[2]; ++ break; ++ } ++ ++ /* Was repeating, but keypress timed out */ ++ if (adap->rc_repeating && !adap->rc->keypressed) { ++ adap->rc_repeating = false; ++ adap->rc_last_scancode = -1; ++ } ++ /* Different keypress from last time, ends repeat mode */ ++ if (adap->rc_last_scancode != scancode) { ++ rc_keyup(adap->rc); ++ adap->rc_repeating = false; ++ } ++ /* We can't handle this scancode */ ++ if (scancode < 0) { ++ adap->rc_last_scancode = scancode; ++ break; ++ } ++ ++ /* Send key press */ ++ rc_keydown(adap->rc, RC_TYPE_CEC, scancode, 0); ++ ++ /* When in repeating mode, we're done */ ++ if (adap->rc_repeating) ++ break; ++ ++ /* ++ * We are not repeating, but the new scancode is ++ * the same as the last one, and this second key press is ++ * within 550 ms (the 'Follower Safety Timeout') from the ++ * previous key press, so we now enable the repeating mode. ++ */ ++ if (adap->rc_last_scancode == scancode && ++ msg->rx_ts - adap->rc_last_keypress < 550 * NSEC_PER_MSEC) { ++ adap->rc_repeating = true; + break; + } ++ /* ++ * Not in repeating mode, so avoid triggering repeat mode ++ * by calling keyup. ++ */ ++ rc_keyup(adap->rc); ++ adap->rc_last_scancode = scancode; ++ adap->rc_last_keypress = msg->rx_ts; + #endif + break; + +@@ -1919,6 +1966,8 @@ static int cec_receive_notify(struct cec_adapter *adap, struct cec_msg *msg, + break; + #ifdef CONFIG_MEDIA_CEC_RC + rc_keyup(adap->rc); ++ adap->rc_repeating = false; ++ adap->rc_last_scancode = -1; + #endif + break; + +diff --git a/drivers/media/cec/cec-core.c b/drivers/media/cec/cec-core.c +index 969f770acf77..65d763be4385 100644 +--- a/drivers/media/cec/cec-core.c ++++ b/drivers/media/cec/cec-core.c +@@ -263,7 +263,7 @@ struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops, + return adap; + + /* Prepare the RC input device */ +- adap->rc = rc_allocate_device(RC_DRIVER_SCANCODE); ++ adap->rc = rc_allocate_device(); + if (!adap->rc) { + pr_err("cec-%s: failed to allocate memory for rc_dev\n", + name); +@@ -283,11 +283,13 @@ struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops, + adap->rc->input_id.vendor = 0; + adap->rc->input_id.product = 0; + adap->rc->input_id.version = 1; ++ adap->rc->driver_type = RC_DRIVER_SCANCODE; + adap->rc->driver_name = CEC_NAME; + adap->rc->allowed_protocols = RC_BIT_CEC; + adap->rc->priv = adap; + adap->rc->map_name = RC_MAP_CEC; + adap->rc->timeout = MS_TO_NS(550); ++ adap->rc_last_scancode = -1; + #endif + return adap; + } +@@ -319,6 +321,17 @@ int cec_register_adapter(struct cec_adapter *adap, + adap->rc = NULL; + return res; + } ++ /* ++ * The REP_DELAY for CEC is really the time between the initial ++ * 'User Control Pressed' message and the second. The first ++ * keypress is always seen as non-repeating, the second ++ * (provided it has the same UI Command) will start the 'Press ++ * and Hold' (aka repeat) behavior. By setting REP_DELAY to the ++ * same value as REP_PERIOD the expected CEC behavior is ++ * reproduced. ++ */ ++ adap->rc->input_dev->rep[REP_DELAY] = ++ adap->rc->input_dev->rep[REP_PERIOD]; + } + #endif + +diff --git a/drivers/media/rc/keymaps/Makefile b/drivers/media/rc/keymaps/Makefile +index fbbd3bbcd252..9cffcc61fdca 100644 +--- a/drivers/media/rc/keymaps/Makefile ++++ b/drivers/media/rc/keymaps/Makefile +@@ -18,6 +18,7 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \ + rc-behold.o \ + rc-behold-columbus.o \ + rc-budget-ci-old.o \ ++ rc-cec.o \ + rc-cinergy-1400.o \ + rc-cinergy.o \ + rc-delock-61959.o \ +diff --git a/drivers/media/rc/keymaps/rc-cec.c b/drivers/media/rc/keymaps/rc-cec.c +new file mode 100644 +index 000000000000..354c8e724b8e +--- /dev/null ++++ b/drivers/media/rc/keymaps/rc-cec.c +@@ -0,0 +1,182 @@ ++/* Keytable for the CEC remote control ++ * ++ * Copyright (c) 2015 by Kamil Debski ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ */ ++ ++#include ++#include ++ ++/* ++ * CEC Spec "High-Definition Multimedia Interface Specification" can be obtained ++ * here: http://xtreamerdev.googlecode.com/files/CEC_Specs.pdf ++ * The list of control codes is listed in Table 27: User Control Codes p. 95 ++ */ ++ ++static struct rc_map_table cec[] = { ++ { 0x00, KEY_OK }, ++ { 0x01, KEY_UP }, ++ { 0x02, KEY_DOWN }, ++ { 0x03, KEY_LEFT }, ++ { 0x04, KEY_RIGHT }, ++ { 0x05, KEY_RIGHT_UP }, ++ { 0x06, KEY_RIGHT_DOWN }, ++ { 0x07, KEY_LEFT_UP }, ++ { 0x08, KEY_LEFT_DOWN }, ++ { 0x09, KEY_ROOT_MENU }, /* CEC Spec: Device Root Menu - see Note 2 */ ++ /* ++ * Note 2: This is the initial display that a device shows. It is ++ * device-dependent and can be, for example, a contents menu, setup ++ * menu, favorite menu or other menu. The actual menu displayed ++ * may also depend on the device's current state. ++ */ ++ { 0x0a, KEY_SETUP }, ++ { 0x0b, KEY_MENU }, /* CEC Spec: Contents Menu */ ++ { 0x0c, KEY_FAVORITES }, /* CEC Spec: Favorite Menu */ ++ { 0x0d, KEY_EXIT }, ++ /* 0x0e-0x0f: Reserved */ ++ { 0x10, KEY_MEDIA_TOP_MENU }, ++ { 0x11, KEY_CONTEXT_MENU }, ++ /* 0x12-0x1c: Reserved */ ++ { 0x1d, KEY_DIGITS }, /* CEC Spec: select/toggle a Number Entry Mode */ ++ { 0x1e, KEY_NUMERIC_11 }, ++ { 0x1f, KEY_NUMERIC_12 }, ++ /* 0x20-0x29: Keys 0 to 9 */ ++ { 0x20, KEY_NUMERIC_0 }, ++ { 0x21, KEY_NUMERIC_1 }, ++ { 0x22, KEY_NUMERIC_2 }, ++ { 0x23, KEY_NUMERIC_3 }, ++ { 0x24, KEY_NUMERIC_4 }, ++ { 0x25, KEY_NUMERIC_5 }, ++ { 0x26, KEY_NUMERIC_6 }, ++ { 0x27, KEY_NUMERIC_7 }, ++ { 0x28, KEY_NUMERIC_8 }, ++ { 0x29, KEY_NUMERIC_9 }, ++ { 0x2a, KEY_DOT }, ++ { 0x2b, KEY_ENTER }, ++ { 0x2c, KEY_CLEAR }, ++ /* 0x2d-0x2e: Reserved */ ++ { 0x2f, KEY_NEXT_FAVORITE }, /* CEC Spec: Next Favorite */ ++ { 0x30, KEY_CHANNELUP }, ++ { 0x31, KEY_CHANNELDOWN }, ++ { 0x32, KEY_PREVIOUS }, /* CEC Spec: Previous Channel */ ++ { 0x33, KEY_SOUND }, /* CEC Spec: Sound Select */ ++ { 0x34, KEY_VIDEO }, /* 0x34: CEC Spec: Input Select */ ++ { 0x35, KEY_INFO }, /* CEC Spec: Display Information */ ++ { 0x36, KEY_HELP }, ++ { 0x37, KEY_PAGEUP }, ++ { 0x38, KEY_PAGEDOWN }, ++ /* 0x39-0x3f: Reserved */ ++ { 0x40, KEY_POWER }, ++ { 0x41, KEY_VOLUMEUP }, ++ { 0x42, KEY_VOLUMEDOWN }, ++ { 0x43, KEY_MUTE }, ++ { 0x44, KEY_PLAYCD }, ++ { 0x45, KEY_STOPCD }, ++ { 0x46, KEY_PAUSECD }, ++ { 0x47, KEY_RECORD }, ++ { 0x48, KEY_REWIND }, ++ { 0x49, KEY_FASTFORWARD }, ++ { 0x4a, KEY_EJECTCD }, /* CEC Spec: Eject */ ++ { 0x4b, KEY_FORWARD }, ++ { 0x4c, KEY_BACK }, ++ { 0x4d, KEY_STOP_RECORD }, /* CEC Spec: Stop-Record */ ++ { 0x4e, KEY_PAUSE_RECORD }, /* CEC Spec: Pause-Record */ ++ /* 0x4f: Reserved */ ++ { 0x50, KEY_ANGLE }, ++ { 0x51, KEY_TV2 }, ++ { 0x52, KEY_VOD }, /* CEC Spec: Video on Demand */ ++ { 0x53, KEY_EPG }, ++ { 0x54, KEY_TIME }, /* CEC Spec: Timer */ ++ { 0x55, KEY_CONFIG }, ++ /* ++ * The following codes are hard to implement at this moment, as they ++ * carry an additional additional argument. Most likely changes to RC ++ * framework are necessary. ++ * For now they are interpreted by the CEC framework as non keycodes ++ * and are passed as messages enabling user application to parse them. ++ */ ++ /* 0x56: CEC Spec: Select Broadcast Type */ ++ /* 0x57: CEC Spec: Select Sound presentation */ ++ { 0x58, KEY_AUDIO_DESC }, /* CEC 2.0 and up */ ++ { 0x59, KEY_WWW }, /* CEC 2.0 and up */ ++ { 0x5a, KEY_3D_MODE }, /* CEC 2.0 and up */ ++ /* 0x5b-0x5f: Reserved */ ++ { 0x60, KEY_PLAYCD }, /* CEC Spec: Play Function */ ++ { 0x6005, KEY_FASTFORWARD }, ++ { 0x6006, KEY_FASTFORWARD }, ++ { 0x6007, KEY_FASTFORWARD }, ++ { 0x6015, KEY_SLOW }, ++ { 0x6016, KEY_SLOW }, ++ { 0x6017, KEY_SLOW }, ++ { 0x6009, KEY_FASTREVERSE }, ++ { 0x600a, KEY_FASTREVERSE }, ++ { 0x600b, KEY_FASTREVERSE }, ++ { 0x6019, KEY_SLOWREVERSE }, ++ { 0x601a, KEY_SLOWREVERSE }, ++ { 0x601b, KEY_SLOWREVERSE }, ++ { 0x6020, KEY_REWIND }, ++ { 0x6024, KEY_PLAYCD }, ++ { 0x6025, KEY_PAUSECD }, ++ { 0x61, KEY_PLAYPAUSE }, /* CEC Spec: Pause-Play Function */ ++ { 0x62, KEY_RECORD }, /* Spec: Record Function */ ++ { 0x63, KEY_PAUSE_RECORD }, /* CEC Spec: Pause-Record Function */ ++ { 0x64, KEY_STOPCD }, /* CEC Spec: Stop Function */ ++ { 0x65, KEY_MUTE }, /* CEC Spec: Mute Function */ ++ { 0x66, KEY_UNMUTE }, /* CEC Spec: Restore the volume */ ++ /* ++ * The following codes are hard to implement at this moment, as they ++ * carry an additional additional argument. Most likely changes to RC ++ * framework are necessary. ++ * For now they are interpreted by the CEC framework as non keycodes ++ * and are passed as messages enabling user application to parse them. ++ */ ++ /* 0x67: CEC Spec: Tune Function */ ++ /* 0x68: CEC Spec: Seleect Media Function */ ++ /* 0x69: CEC Spec: Select A/V Input Function */ ++ /* 0x6a: CEC Spec: Select Audio Input Function */ ++ { 0x6b, KEY_POWER }, /* CEC Spec: Power Toggle Function */ ++ { 0x6c, KEY_SLEEP }, /* CEC Spec: Power Off Function */ ++ { 0x6d, KEY_WAKEUP }, /* CEC Spec: Power On Function */ ++ /* 0x6e-0x70: Reserved */ ++ { 0x71, KEY_BLUE }, /* CEC Spec: F1 (Blue) */ ++ { 0x72, KEY_RED }, /* CEC Spec: F2 (Red) */ ++ { 0x73, KEY_GREEN }, /* CEC Spec: F3 (Green) */ ++ { 0x74, KEY_YELLOW }, /* CEC Spec: F4 (Yellow) */ ++ { 0x75, KEY_F5 }, ++ { 0x76, KEY_DATA }, /* CEC Spec: Data - see Note 3 */ ++ /* ++ * Note 3: This is used, for example, to enter or leave a digital TV ++ * data broadcast application. ++ */ ++ /* 0x77-0xff: Reserved */ ++}; ++ ++static struct rc_map_list cec_map = { ++ .map = { ++ .scan = cec, ++ .size = ARRAY_SIZE(cec), ++ .rc_type = RC_TYPE_CEC, ++ .name = RC_MAP_CEC, ++ } ++}; ++ ++static int __init init_rc_map_cec(void) ++{ ++ return rc_map_register(&cec_map); ++} ++ ++static void __exit exit_rc_map_cec(void) ++{ ++ rc_map_unregister(&cec_map); ++} ++ ++module_init(init_rc_map_cec); ++module_exit(exit_rc_map_cec); ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Kamil Debski"); +diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c +index a52ca5cba015..b0b96fc01da3 100644 +--- a/fs/compat_ioctl.c ++++ b/fs/compat_ioctl.c +@@ -57,6 +57,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -1381,6 +1382,17 @@ COMPATIBLE_IOCTL(VIDEO_GET_NAVI) + COMPATIBLE_IOCTL(VIDEO_SET_ATTRIBUTES) + COMPATIBLE_IOCTL(VIDEO_GET_SIZE) + COMPATIBLE_IOCTL(VIDEO_GET_FRAME_RATE) ++/* cec */ ++COMPATIBLE_IOCTL(CEC_ADAP_G_CAPS) ++COMPATIBLE_IOCTL(CEC_ADAP_G_LOG_ADDRS) ++COMPATIBLE_IOCTL(CEC_ADAP_S_LOG_ADDRS) ++COMPATIBLE_IOCTL(CEC_ADAP_G_PHYS_ADDR) ++COMPATIBLE_IOCTL(CEC_ADAP_S_PHYS_ADDR) ++COMPATIBLE_IOCTL(CEC_G_MODE) ++COMPATIBLE_IOCTL(CEC_S_MODE) ++COMPATIBLE_IOCTL(CEC_TRANSMIT) ++COMPATIBLE_IOCTL(CEC_RECEIVE) ++COMPATIBLE_IOCTL(CEC_DQEVENT) + + /* joystick */ + COMPATIBLE_IOCTL(JSIOCGVERSION) +diff --git a/include/media/cec-notifier.h b/include/media/cec-notifier.h +index ca19a9305782..8bb169ac7afd 100644 +--- a/include/media/cec-notifier.h ++++ b/include/media/cec-notifier.h +@@ -91,6 +91,14 @@ void cec_notifier_register(struct cec_notifier *n, + */ + void cec_notifier_unregister(struct cec_notifier *n); + ++/** ++ * cec_register_cec_notifier - register the notifier with the cec adapter. ++ * @adap: the CEC adapter ++ * @notifier: the CEC notifier ++ */ ++void cec_register_cec_notifier(struct cec_adapter *adap, ++ struct cec_notifier *notifier); ++ + #else + static inline struct cec_notifier *cec_notifier_get(struct device *dev) + { +@@ -111,6 +119,20 @@ static inline void cec_notifier_set_phys_addr_from_edid(struct cec_notifier *n, + { + } + ++static inline void cec_notifier_register(struct cec_notifier *n, ++ struct cec_adapter *adap, ++ void (*callback)(struct cec_adapter *adap, u16 pa)) ++{ ++} ++ ++static inline void cec_notifier_unregister(struct cec_notifier *n) ++{ ++} ++ ++static inline void cec_register_cec_notifier(struct cec_adapter *adap, ++ struct cec_notifier *notifier) ++{ ++} + #endif + + /** +diff --git a/include/media/cec.h b/include/media/cec.h +index df3c94f05aa5..f64807a78064 100644 +--- a/include/media/cec.h ++++ b/include/media/cec.h +@@ -191,6 +191,11 @@ struct cec_adapter { + + u32 tx_timeouts; + ++#ifdef CONFIG_MEDIA_CEC_RC ++ bool rc_repeating; ++ int rc_last_scancode; ++ u64 rc_last_keypress; ++#endif + #ifdef CONFIG_CEC_NOTIFIER + struct cec_notifier *notifier; + #endif +@@ -229,7 +234,7 @@ static inline bool cec_is_sink(const struct cec_adapter *adap) + + struct edid; + +-#if IS_ENABLED(CONFIG_CEC_CORE) ++#if IS_REACHABLE(CONFIG_CEC_CORE) + struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops, + void *priv, const char *name, u32 caps, u8 available_las); + int cec_register_adapter(struct cec_adapter *adap, struct device *parent); +@@ -427,6 +427,10 @@ static inline u16 cec_phys_addr_for_input(u16 phys_addr, u8 input) + + static inline int cec_phys_addr_validate(u16 phys_addr, u16 *parent, u16 *port) + { ++ if (parent) ++ *parent = phys_addr; ++ if (port) ++ *port = 0; + return 0; + } + +diff --git a/include/uapi/linux/cec-funcs.h b/include/uapi/linux/cec-funcs.h +index c451eec42a83..270b251a3d9b 100644 +--- a/include/uapi/linux/cec-funcs.h ++++ b/include/uapi/linux/cec-funcs.h +@@ -895,6 +895,7 @@ static inline void cec_ops_report_features(const struct cec_msg *msg, + *cec_version = msg->msg[2]; + *all_device_types = msg->msg[3]; + *rc_profile = p; ++ *dev_features = NULL; + while (p < &msg->msg[14] && (*p & CEC_OP_FEAT_EXT)) + p++; + if (!(*p & CEC_OP_FEAT_EXT)) { +diff --git a/include/uapi/linux/cec.h b/include/uapi/linux/cec.h +index af6682f5ea85..b9f8df3a0477 100644 +--- a/include/uapi/linux/cec.h ++++ b/include/uapi/linux/cec.h +@@ -223,7 +223,7 @@ static inline int cec_msg_status_is_ok(const struct cec_msg *msg) + #define CEC_LOG_ADDR_BACKUP_2 13 + #define CEC_LOG_ADDR_SPECIFIC 14 + #define CEC_LOG_ADDR_UNREGISTERED 15 /* as initiator address */ +-#define CEC_LOG_ADDR_BROADCAST 15 /* ad destination address */ ++#define CEC_LOG_ADDR_BROADCAST 15 /* as destination address */ + + /* The logical address types that the CEC device wants to claim */ + #define CEC_LOG_ADDR_TYPE_TV 0 +diff --git a/include/uapi/linux/input-event-codes.h b/include/uapi/linux/input-event-codes.h +index 87cf351bab03..b0c5c4888a4b 100644 +--- a/include/uapi/linux/input-event-codes.h ++++ b/include/uapi/linux/input-event-codes.h +@@ -611,6 +611,37 @@ + #define KEY_KBDINPUTASSIST_ACCEPT 0x264 + #define KEY_KBDINPUTASSIST_CANCEL 0x265 + ++/* Diagonal movement keys */ ++#define KEY_RIGHT_UP 0x266 ++#define KEY_RIGHT_DOWN 0x267 ++#define KEY_LEFT_UP 0x268 ++#define KEY_LEFT_DOWN 0x269 ++ ++#define KEY_ROOT_MENU 0x26a /* Show Device's Root Menu */ ++/* Show Top Menu of the Media (e.g. DVD) */ ++#define KEY_MEDIA_TOP_MENU 0x26b ++#define KEY_NUMERIC_11 0x26c ++#define KEY_NUMERIC_12 0x26d ++/* ++ * Toggle Audio Description: refers to an audio service that helps blind and ++ * visually impaired consumers understand the action in a program. Note: in ++ * some countries this is referred to as "Video Description". ++ */ ++#define KEY_AUDIO_DESC 0x26e ++#define KEY_3D_MODE 0x26f ++#define KEY_NEXT_FAVORITE 0x270 ++#define KEY_STOP_RECORD 0x271 ++#define KEY_PAUSE_RECORD 0x272 ++#define KEY_VOD 0x273 /* Video on Demand */ ++#define KEY_UNMUTE 0x274 ++#define KEY_FASTREVERSE 0x275 ++#define KEY_SLOWREVERSE 0x276 ++/* ++ * Control a data application associated with the currently viewed channel, ++ * e.g. teletext or data broadcast application (MHEG, MHP, HbbTV, etc.) ++ */ ++#define KEY_DATA 0x277 ++ + #define BTN_TRIGGER_HAPPY 0x2c0 + #define BTN_TRIGGER_HAPPY1 0x2c0 + #define BTN_TRIGGER_HAPPY2 0x2c1 +diff --git a/include/uapi/linux/input.h b/include/uapi/linux/input.h +index 2758687300b4..41e8dff588e1 100644 +--- a/include/uapi/linux/input.h ++++ b/include/uapi/linux/input.h +@@ -246,6 +246,7 @@ struct input_mask { + #define BUS_GSC 0x1A + #define BUS_ATARI 0x1B + #define BUS_SPI 0x1C ++#define BUS_CEC 0x1E + + /* + * MT_TOOL types + +From 8e3b262321c2121f8ceed952be3619039aebea9d Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Mon, 4 Sep 2017 22:34:22 +0200 +Subject: [PATCH] BACKPORT: Pulse Eight HDMI CEC from v4.15 + +--- + MAINTAINERS | 7 + + drivers/input/serio/serport.c | 17 +- + drivers/media/usb/Kconfig | 5 + + drivers/media/usb/Makefile | 1 + + drivers/media/usb/pulse8-cec/Kconfig | 11 + + drivers/media/usb/pulse8-cec/Makefile | 1 + + drivers/media/usb/pulse8-cec/pulse8-cec.c | 757 ++++++++++++++++++++++++++++++ + include/uapi/linux/serio.h | 1 + + 8 files changed, 797 insertions(+), 3 deletions(-) + create mode 100644 drivers/media/usb/pulse8-cec/Kconfig + create mode 100644 drivers/media/usb/pulse8-cec/Makefile + create mode 100644 drivers/media/usb/pulse8-cec/pulse8-cec.c + +diff --git a/MAINTAINERS b/MAINTAINERS +index 225ab2c1d35b..0c1232c326a5 100644 +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -8673,6 +8673,13 @@ F: include/linux/tracehook.h + F: include/uapi/linux/ptrace.h + F: kernel/ptrace.c + ++PULSE8-CEC DRIVER ++M: Hans Verkuil ++L: linux-media@vger.kernel.org ++T: git git://linuxtv.org/media_tree.git ++S: Maintained ++F: drivers/media/usb/pulse8-cec/* ++ + PVRUSB2 VIDEO4LINUX DRIVER + M: Mike Isely + L: pvrusb2@isely.net (subscribers-only) +diff --git a/drivers/input/serio/serport.c b/drivers/input/serio/serport.c +index 9c927d35c1f5..d189843f3727 100644 +--- a/drivers/input/serio/serport.c ++++ b/drivers/input/serio/serport.c +@@ -71,10 +71,7 @@ static void serport_serio_close(struct serio *serio) + + spin_lock_irqsave(&serport->lock, flags); + clear_bit(SERPORT_ACTIVE, &serport->flags); +- set_bit(SERPORT_DEAD, &serport->flags); + spin_unlock_irqrestore(&serport->lock, flags); +- +- wake_up_interruptible(&serport->wait); + } + + /* +@@ -248,6 +245,19 @@ static long serport_ldisc_compat_ioctl(struct tty_struct *tty, + } + #endif + ++static int serport_ldisc_hangup(struct tty_struct *tty) ++{ ++ struct serport *serport = (struct serport *) tty->disc_data; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&serport->lock, flags); ++ set_bit(SERPORT_DEAD, &serport->flags); ++ spin_unlock_irqrestore(&serport->lock, flags); ++ ++ wake_up_interruptible(&serport->wait); ++ return 0; ++} ++ + static void serport_ldisc_write_wakeup(struct tty_struct * tty) + { + struct serport *serport = (struct serport *) tty->disc_data; +@@ -274,6 +284,7 @@ static struct tty_ldisc_ops serport_ldisc = { + .compat_ioctl = serport_ldisc_compat_ioctl, + #endif + .receive_buf = serport_ldisc_receive, ++ .hangup = serport_ldisc_hangup, + .write_wakeup = serport_ldisc_write_wakeup + }; + +diff --git a/drivers/media/usb/Kconfig b/drivers/media/usb/Kconfig +index 7496f332f3f5..c9644b62f91a 100644 +--- a/drivers/media/usb/Kconfig ++++ b/drivers/media/usb/Kconfig +@@ -60,5 +60,10 @@ source "drivers/media/usb/hackrf/Kconfig" + source "drivers/media/usb/msi2500/Kconfig" + endif + ++if MEDIA_CEC_SUPPORT ++ comment "USB HDMI CEC adapters" ++source "drivers/media/usb/pulse8-cec/Kconfig" ++endif ++ + endif #MEDIA_USB_SUPPORT + endif #USB +diff --git a/drivers/media/usb/Makefile b/drivers/media/usb/Makefile +index 8874ba774a34..0f15e3351ddc 100644 +--- a/drivers/media/usb/Makefile ++++ b/drivers/media/usb/Makefile +@@ -24,3 +24,4 @@ obj-$(CONFIG_VIDEO_EM28XX) += em28xx/ + obj-$(CONFIG_VIDEO_USBTV) += usbtv/ + obj-$(CONFIG_VIDEO_GO7007) += go7007/ + obj-$(CONFIG_DVB_AS102) += as102/ ++obj-$(CONFIG_USB_PULSE8_CEC) += pulse8-cec/ +diff --git a/drivers/media/usb/pulse8-cec/Kconfig b/drivers/media/usb/pulse8-cec/Kconfig +new file mode 100644 +index 000000000000..18ead44824ba +--- /dev/null ++++ b/drivers/media/usb/pulse8-cec/Kconfig +@@ -0,0 +1,11 @@ ++config USB_PULSE8_CEC ++ tristate "Pulse Eight HDMI CEC" ++ depends on USB_ACM ++ select CEC_CORE ++ select SERIO ++ select SERIO_SERPORT ++ ---help--- ++ This is a cec driver for the Pulse Eight HDMI CEC device. ++ ++ To compile this driver as a module, choose M here: the ++ module will be called pulse8-cec. +diff --git a/drivers/media/usb/pulse8-cec/Makefile b/drivers/media/usb/pulse8-cec/Makefile +new file mode 100644 +index 000000000000..9800690bc25a +--- /dev/null ++++ b/drivers/media/usb/pulse8-cec/Makefile +@@ -0,0 +1 @@ ++obj-$(CONFIG_USB_PULSE8_CEC) += pulse8-cec.o +diff --git a/drivers/media/usb/pulse8-cec/pulse8-cec.c b/drivers/media/usb/pulse8-cec/pulse8-cec.c +new file mode 100644 +index 000000000000..50146f263d90 +--- /dev/null ++++ b/drivers/media/usb/pulse8-cec/pulse8-cec.c +@@ -0,0 +1,757 @@ ++/* ++ * Pulse Eight HDMI CEC driver ++ * ++ * Copyright 2016 Hans Verkuil ["Power On"], ["Power] or ["Power Toggle"], or if it ++ * receives with its own physical address. It also does this ++ * if it receives [0x03 0x00] from an LG TV. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++MODULE_AUTHOR("Hans Verkuil "); ++MODULE_DESCRIPTION("Pulse Eight HDMI CEC driver"); ++MODULE_LICENSE("GPL"); ++ ++static int debug; ++static int persistent_config; ++module_param(debug, int, 0644); ++module_param(persistent_config, int, 0644); ++MODULE_PARM_DESC(debug, "debug level (0-1)"); ++MODULE_PARM_DESC(persistent_config, "read config from persistent memory (0-1)"); ++ ++enum pulse8_msgcodes { ++ MSGCODE_NOTHING = 0, ++ MSGCODE_PING, ++ MSGCODE_TIMEOUT_ERROR, ++ MSGCODE_HIGH_ERROR, ++ MSGCODE_LOW_ERROR, ++ MSGCODE_FRAME_START, ++ MSGCODE_FRAME_DATA, ++ MSGCODE_RECEIVE_FAILED, ++ MSGCODE_COMMAND_ACCEPTED, /* 0x08 */ ++ MSGCODE_COMMAND_REJECTED, ++ MSGCODE_SET_ACK_MASK, ++ MSGCODE_TRANSMIT, ++ MSGCODE_TRANSMIT_EOM, ++ MSGCODE_TRANSMIT_IDLETIME, ++ MSGCODE_TRANSMIT_ACK_POLARITY, ++ MSGCODE_TRANSMIT_LINE_TIMEOUT, ++ MSGCODE_TRANSMIT_SUCCEEDED, /* 0x10 */ ++ MSGCODE_TRANSMIT_FAILED_LINE, ++ MSGCODE_TRANSMIT_FAILED_ACK, ++ MSGCODE_TRANSMIT_FAILED_TIMEOUT_DATA, ++ MSGCODE_TRANSMIT_FAILED_TIMEOUT_LINE, ++ MSGCODE_FIRMWARE_VERSION, ++ MSGCODE_START_BOOTLOADER, ++ MSGCODE_GET_BUILDDATE, ++ MSGCODE_SET_CONTROLLED, /* 0x18 */ ++ MSGCODE_GET_AUTO_ENABLED, ++ MSGCODE_SET_AUTO_ENABLED, ++ MSGCODE_GET_DEFAULT_LOGICAL_ADDRESS, ++ MSGCODE_SET_DEFAULT_LOGICAL_ADDRESS, ++ MSGCODE_GET_LOGICAL_ADDRESS_MASK, ++ MSGCODE_SET_LOGICAL_ADDRESS_MASK, ++ MSGCODE_GET_PHYSICAL_ADDRESS, ++ MSGCODE_SET_PHYSICAL_ADDRESS, /* 0x20 */ ++ MSGCODE_GET_DEVICE_TYPE, ++ MSGCODE_SET_DEVICE_TYPE, ++ MSGCODE_GET_HDMI_VERSION, ++ MSGCODE_SET_HDMI_VERSION, ++ MSGCODE_GET_OSD_NAME, ++ MSGCODE_SET_OSD_NAME, ++ MSGCODE_WRITE_EEPROM, ++ MSGCODE_GET_ADAPTER_TYPE, /* 0x28 */ ++ MSGCODE_SET_ACTIVE_SOURCE, ++ ++ MSGCODE_FRAME_EOM = 0x80, ++ MSGCODE_FRAME_ACK = 0x40, ++}; ++ ++#define MSGSTART 0xff ++#define MSGEND 0xfe ++#define MSGESC 0xfd ++#define MSGOFFSET 3 ++ ++#define DATA_SIZE 256 ++ ++#define PING_PERIOD (15 * HZ) ++ ++struct pulse8 { ++ struct device *dev; ++ struct serio *serio; ++ struct cec_adapter *adap; ++ unsigned int vers; ++ struct completion cmd_done; ++ struct work_struct work; ++ struct delayed_work ping_eeprom_work; ++ struct cec_msg rx_msg; ++ u8 data[DATA_SIZE]; ++ unsigned int len; ++ u8 buf[DATA_SIZE]; ++ unsigned int idx; ++ bool escape; ++ bool started; ++ struct mutex config_lock; ++ struct mutex write_lock; ++ bool config_pending; ++ bool restoring_config; ++ bool autonomous; ++}; ++ ++static void pulse8_ping_eeprom_work_handler(struct work_struct *work); ++ ++static void pulse8_irq_work_handler(struct work_struct *work) ++{ ++ struct pulse8 *pulse8 = ++ container_of(work, struct pulse8, work); ++ ++ switch (pulse8->data[0] & 0x3f) { ++ case MSGCODE_FRAME_DATA: ++ cec_received_msg(pulse8->adap, &pulse8->rx_msg); ++ break; ++ case MSGCODE_TRANSMIT_SUCCEEDED: ++ cec_transmit_attempt_done(pulse8->adap, CEC_TX_STATUS_OK); ++ break; ++ case MSGCODE_TRANSMIT_FAILED_ACK: ++ cec_transmit_attempt_done(pulse8->adap, CEC_TX_STATUS_NACK); ++ break; ++ case MSGCODE_TRANSMIT_FAILED_LINE: ++ case MSGCODE_TRANSMIT_FAILED_TIMEOUT_DATA: ++ case MSGCODE_TRANSMIT_FAILED_TIMEOUT_LINE: ++ cec_transmit_attempt_done(pulse8->adap, CEC_TX_STATUS_ERROR); ++ break; ++ } ++} ++ ++static irqreturn_t pulse8_interrupt(struct serio *serio, unsigned char data, ++ unsigned int flags) ++{ ++ struct pulse8 *pulse8 = serio_get_drvdata(serio); ++ ++ if (!pulse8->started && data != MSGSTART) ++ return IRQ_HANDLED; ++ if (data == MSGESC) { ++ pulse8->escape = true; ++ return IRQ_HANDLED; ++ } ++ if (pulse8->escape) { ++ data += MSGOFFSET; ++ pulse8->escape = false; ++ } else if (data == MSGEND) { ++ struct cec_msg *msg = &pulse8->rx_msg; ++ ++ if (debug) ++ dev_info(pulse8->dev, "received: %*ph\n", ++ pulse8->idx, pulse8->buf); ++ pulse8->data[0] = pulse8->buf[0]; ++ switch (pulse8->buf[0] & 0x3f) { ++ case MSGCODE_FRAME_START: ++ msg->len = 1; ++ msg->msg[0] = pulse8->buf[1]; ++ break; ++ case MSGCODE_FRAME_DATA: ++ if (msg->len == CEC_MAX_MSG_SIZE) ++ break; ++ msg->msg[msg->len++] = pulse8->buf[1]; ++ if (pulse8->buf[0] & MSGCODE_FRAME_EOM) ++ schedule_work(&pulse8->work); ++ break; ++ case MSGCODE_TRANSMIT_SUCCEEDED: ++ case MSGCODE_TRANSMIT_FAILED_LINE: ++ case MSGCODE_TRANSMIT_FAILED_ACK: ++ case MSGCODE_TRANSMIT_FAILED_TIMEOUT_DATA: ++ case MSGCODE_TRANSMIT_FAILED_TIMEOUT_LINE: ++ schedule_work(&pulse8->work); ++ break; ++ case MSGCODE_HIGH_ERROR: ++ case MSGCODE_LOW_ERROR: ++ case MSGCODE_RECEIVE_FAILED: ++ case MSGCODE_TIMEOUT_ERROR: ++ break; ++ case MSGCODE_COMMAND_ACCEPTED: ++ case MSGCODE_COMMAND_REJECTED: ++ default: ++ if (pulse8->idx == 0) ++ break; ++ memcpy(pulse8->data, pulse8->buf, pulse8->idx); ++ pulse8->len = pulse8->idx; ++ complete(&pulse8->cmd_done); ++ break; ++ } ++ pulse8->idx = 0; ++ pulse8->started = false; ++ return IRQ_HANDLED; ++ } else if (data == MSGSTART) { ++ pulse8->idx = 0; ++ pulse8->started = true; ++ return IRQ_HANDLED; ++ } ++ ++ if (pulse8->idx >= DATA_SIZE) { ++ dev_dbg(pulse8->dev, ++ "throwing away %d bytes of garbage\n", pulse8->idx); ++ pulse8->idx = 0; ++ } ++ pulse8->buf[pulse8->idx++] = data; ++ return IRQ_HANDLED; ++} ++ ++static void pulse8_disconnect(struct serio *serio) ++{ ++ struct pulse8 *pulse8 = serio_get_drvdata(serio); ++ ++ cec_unregister_adapter(pulse8->adap); ++ cancel_delayed_work_sync(&pulse8->ping_eeprom_work); ++ dev_info(&serio->dev, "disconnected\n"); ++ serio_close(serio); ++ serio_set_drvdata(serio, NULL); ++ kfree(pulse8); ++} ++ ++static int pulse8_send(struct serio *serio, const u8 *command, u8 cmd_len) ++{ ++ int err = 0; ++ ++ err = serio_write(serio, MSGSTART); ++ if (err) ++ return err; ++ for (; !err && cmd_len; command++, cmd_len--) { ++ if (*command >= MSGESC) { ++ err = serio_write(serio, MSGESC); ++ if (!err) ++ err = serio_write(serio, *command - MSGOFFSET); ++ } else { ++ err = serio_write(serio, *command); ++ } ++ } ++ if (!err) ++ err = serio_write(serio, MSGEND); ++ ++ return err; ++} ++ ++static int pulse8_send_and_wait_once(struct pulse8 *pulse8, ++ const u8 *cmd, u8 cmd_len, ++ u8 response, u8 size) ++{ ++ int err; ++ ++ /*dev_info(pulse8->dev, "transmit: %*ph\n", cmd_len, cmd);*/ ++ init_completion(&pulse8->cmd_done); ++ ++ err = pulse8_send(pulse8->serio, cmd, cmd_len); ++ if (err) ++ return err; ++ ++ if (!wait_for_completion_timeout(&pulse8->cmd_done, HZ)) ++ return -ETIMEDOUT; ++ if ((pulse8->data[0] & 0x3f) == MSGCODE_COMMAND_REJECTED && ++ cmd[0] != MSGCODE_SET_CONTROLLED && ++ cmd[0] != MSGCODE_SET_AUTO_ENABLED && ++ cmd[0] != MSGCODE_GET_BUILDDATE) ++ return -ENOTTY; ++ if (response && ++ ((pulse8->data[0] & 0x3f) != response || pulse8->len < size + 1)) { ++ dev_info(pulse8->dev, "transmit: failed %02x\n", ++ pulse8->data[0] & 0x3f); ++ return -EIO; ++ } ++ return 0; ++} ++ ++static int pulse8_send_and_wait(struct pulse8 *pulse8, ++ const u8 *cmd, u8 cmd_len, u8 response, u8 size) ++{ ++ u8 cmd_sc[2]; ++ int err; ++ ++ mutex_lock(&pulse8->write_lock); ++ err = pulse8_send_and_wait_once(pulse8, cmd, cmd_len, response, size); ++ ++ if (err == -ENOTTY) { ++ cmd_sc[0] = MSGCODE_SET_CONTROLLED; ++ cmd_sc[1] = 1; ++ err = pulse8_send_and_wait_once(pulse8, cmd_sc, 2, ++ MSGCODE_COMMAND_ACCEPTED, 1); ++ if (err) ++ goto unlock; ++ err = pulse8_send_and_wait_once(pulse8, cmd, cmd_len, ++ response, size); ++ } ++ ++unlock: ++ mutex_unlock(&pulse8->write_lock); ++ return err == -ENOTTY ? -EIO : err; ++} ++ ++static int pulse8_setup(struct pulse8 *pulse8, struct serio *serio, ++ struct cec_log_addrs *log_addrs, u16 *pa) ++{ ++ u8 *data = pulse8->data + 1; ++ u8 cmd[2]; ++ int err; ++ struct tm tm; ++ time_t date; ++ ++ pulse8->vers = 0; ++ ++ cmd[0] = MSGCODE_FIRMWARE_VERSION; ++ err = pulse8_send_and_wait(pulse8, cmd, 1, cmd[0], 2); ++ if (err) ++ return err; ++ pulse8->vers = (data[0] << 8) | data[1]; ++ dev_info(pulse8->dev, "Firmware version %04x\n", pulse8->vers); ++ if (pulse8->vers < 2) { ++ *pa = CEC_PHYS_ADDR_INVALID; ++ return 0; ++ } ++ ++ cmd[0] = MSGCODE_GET_BUILDDATE; ++ err = pulse8_send_and_wait(pulse8, cmd, 1, cmd[0], 4); ++ if (err) ++ return err; ++ date = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3]; ++ time_to_tm(date, 0, &tm); ++ dev_info(pulse8->dev, "Firmware build date %04ld.%02d.%02d %02d:%02d:%02d\n", ++ tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, ++ tm.tm_hour, tm.tm_min, tm.tm_sec); ++ ++ dev_dbg(pulse8->dev, "Persistent config:\n"); ++ cmd[0] = MSGCODE_GET_AUTO_ENABLED; ++ err = pulse8_send_and_wait(pulse8, cmd, 1, cmd[0], 1); ++ if (err) ++ return err; ++ pulse8->autonomous = data[0]; ++ dev_dbg(pulse8->dev, "Autonomous mode: %s", ++ data[0] ? "on" : "off"); ++ ++ cmd[0] = MSGCODE_GET_DEVICE_TYPE; ++ err = pulse8_send_and_wait(pulse8, cmd, 1, cmd[0], 1); ++ if (err) ++ return err; ++ log_addrs->primary_device_type[0] = data[0]; ++ dev_dbg(pulse8->dev, "Primary device type: %d\n", data[0]); ++ switch (log_addrs->primary_device_type[0]) { ++ case CEC_OP_PRIM_DEVTYPE_TV: ++ log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_TV; ++ log_addrs->all_device_types[0] = CEC_OP_ALL_DEVTYPE_TV; ++ break; ++ case CEC_OP_PRIM_DEVTYPE_RECORD: ++ log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_RECORD; ++ log_addrs->all_device_types[0] = CEC_OP_ALL_DEVTYPE_RECORD; ++ break; ++ case CEC_OP_PRIM_DEVTYPE_TUNER: ++ log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_TUNER; ++ log_addrs->all_device_types[0] = CEC_OP_ALL_DEVTYPE_TUNER; ++ break; ++ case CEC_OP_PRIM_DEVTYPE_PLAYBACK: ++ log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_PLAYBACK; ++ log_addrs->all_device_types[0] = CEC_OP_ALL_DEVTYPE_PLAYBACK; ++ break; ++ case CEC_OP_PRIM_DEVTYPE_AUDIOSYSTEM: ++ log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_PLAYBACK; ++ log_addrs->all_device_types[0] = CEC_OP_ALL_DEVTYPE_AUDIOSYSTEM; ++ break; ++ case CEC_OP_PRIM_DEVTYPE_SWITCH: ++ log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_UNREGISTERED; ++ log_addrs->all_device_types[0] = CEC_OP_ALL_DEVTYPE_SWITCH; ++ break; ++ case CEC_OP_PRIM_DEVTYPE_PROCESSOR: ++ log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_SPECIFIC; ++ log_addrs->all_device_types[0] = CEC_OP_ALL_DEVTYPE_SWITCH; ++ break; ++ default: ++ log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_UNREGISTERED; ++ log_addrs->all_device_types[0] = CEC_OP_ALL_DEVTYPE_SWITCH; ++ dev_info(pulse8->dev, "Unknown Primary Device Type: %d\n", ++ log_addrs->primary_device_type[0]); ++ break; ++ } ++ ++ cmd[0] = MSGCODE_GET_LOGICAL_ADDRESS_MASK; ++ err = pulse8_send_and_wait(pulse8, cmd, 1, cmd[0], 2); ++ if (err) ++ return err; ++ log_addrs->log_addr_mask = (data[0] << 8) | data[1]; ++ dev_dbg(pulse8->dev, "Logical address ACK mask: %x\n", ++ log_addrs->log_addr_mask); ++ if (log_addrs->log_addr_mask) ++ log_addrs->num_log_addrs = 1; ++ ++ cmd[0] = MSGCODE_GET_PHYSICAL_ADDRESS; ++ err = pulse8_send_and_wait(pulse8, cmd, 1, cmd[0], 1); ++ if (err) ++ return err; ++ *pa = (data[0] << 8) | data[1]; ++ dev_dbg(pulse8->dev, "Physical address: %x.%x.%x.%x\n", ++ cec_phys_addr_exp(*pa)); ++ ++ cmd[0] = MSGCODE_GET_HDMI_VERSION; ++ err = pulse8_send_and_wait(pulse8, cmd, 1, cmd[0], 1); ++ if (err) ++ return err; ++ log_addrs->cec_version = data[0]; ++ dev_dbg(pulse8->dev, "CEC version: %d\n", log_addrs->cec_version); ++ ++ cmd[0] = MSGCODE_GET_OSD_NAME; ++ err = pulse8_send_and_wait(pulse8, cmd, 1, cmd[0], 0); ++ if (err) ++ return err; ++ strncpy(log_addrs->osd_name, data, 13); ++ dev_dbg(pulse8->dev, "OSD name: %s\n", log_addrs->osd_name); ++ ++ return 0; ++} ++ ++static int pulse8_apply_persistent_config(struct pulse8 *pulse8, ++ struct cec_log_addrs *log_addrs, ++ u16 pa) ++{ ++ int err; ++ ++ err = cec_s_log_addrs(pulse8->adap, log_addrs, false); ++ if (err) ++ return err; ++ ++ cec_s_phys_addr(pulse8->adap, pa, false); ++ ++ return 0; ++} ++ ++static int pulse8_cec_adap_enable(struct cec_adapter *adap, bool enable) ++{ ++ struct pulse8 *pulse8 = cec_get_drvdata(adap); ++ u8 cmd[16]; ++ int err; ++ ++ cmd[0] = MSGCODE_SET_CONTROLLED; ++ cmd[1] = enable; ++ err = pulse8_send_and_wait(pulse8, cmd, 2, ++ MSGCODE_COMMAND_ACCEPTED, 1); ++ return enable ? err : 0; ++} ++ ++static int pulse8_cec_adap_log_addr(struct cec_adapter *adap, u8 log_addr) ++{ ++ struct pulse8 *pulse8 = cec_get_drvdata(adap); ++ u16 mask = 0; ++ u16 pa = adap->phys_addr; ++ u8 cmd[16]; ++ int err = 0; ++ ++ mutex_lock(&pulse8->config_lock); ++ if (log_addr != CEC_LOG_ADDR_INVALID) ++ mask = 1 << log_addr; ++ cmd[0] = MSGCODE_SET_ACK_MASK; ++ cmd[1] = mask >> 8; ++ cmd[2] = mask & 0xff; ++ err = pulse8_send_and_wait(pulse8, cmd, 3, ++ MSGCODE_COMMAND_ACCEPTED, 0); ++ if ((err && mask != 0) || pulse8->restoring_config) ++ goto unlock; ++ ++ cmd[0] = MSGCODE_SET_AUTO_ENABLED; ++ cmd[1] = log_addr == CEC_LOG_ADDR_INVALID ? 0 : 1; ++ err = pulse8_send_and_wait(pulse8, cmd, 2, ++ MSGCODE_COMMAND_ACCEPTED, 0); ++ if (err) ++ goto unlock; ++ pulse8->autonomous = cmd[1]; ++ if (log_addr == CEC_LOG_ADDR_INVALID) ++ goto unlock; ++ ++ cmd[0] = MSGCODE_SET_DEVICE_TYPE; ++ cmd[1] = adap->log_addrs.primary_device_type[0]; ++ err = pulse8_send_and_wait(pulse8, cmd, 2, ++ MSGCODE_COMMAND_ACCEPTED, 0); ++ if (err) ++ goto unlock; ++ ++ switch (adap->log_addrs.primary_device_type[0]) { ++ case CEC_OP_PRIM_DEVTYPE_TV: ++ mask = CEC_LOG_ADDR_MASK_TV; ++ break; ++ case CEC_OP_PRIM_DEVTYPE_RECORD: ++ mask = CEC_LOG_ADDR_MASK_RECORD; ++ break; ++ case CEC_OP_PRIM_DEVTYPE_TUNER: ++ mask = CEC_LOG_ADDR_MASK_TUNER; ++ break; ++ case CEC_OP_PRIM_DEVTYPE_PLAYBACK: ++ mask = CEC_LOG_ADDR_MASK_PLAYBACK; ++ break; ++ case CEC_OP_PRIM_DEVTYPE_AUDIOSYSTEM: ++ mask = CEC_LOG_ADDR_MASK_AUDIOSYSTEM; ++ break; ++ case CEC_OP_PRIM_DEVTYPE_SWITCH: ++ mask = CEC_LOG_ADDR_MASK_UNREGISTERED; ++ break; ++ case CEC_OP_PRIM_DEVTYPE_PROCESSOR: ++ mask = CEC_LOG_ADDR_MASK_SPECIFIC; ++ break; ++ default: ++ mask = 0; ++ break; ++ } ++ cmd[0] = MSGCODE_SET_LOGICAL_ADDRESS_MASK; ++ cmd[1] = mask >> 8; ++ cmd[2] = mask & 0xff; ++ err = pulse8_send_and_wait(pulse8, cmd, 3, ++ MSGCODE_COMMAND_ACCEPTED, 0); ++ if (err) ++ goto unlock; ++ ++ cmd[0] = MSGCODE_SET_DEFAULT_LOGICAL_ADDRESS; ++ cmd[1] = log_addr; ++ err = pulse8_send_and_wait(pulse8, cmd, 2, ++ MSGCODE_COMMAND_ACCEPTED, 0); ++ if (err) ++ goto unlock; ++ ++ cmd[0] = MSGCODE_SET_PHYSICAL_ADDRESS; ++ cmd[1] = pa >> 8; ++ cmd[2] = pa & 0xff; ++ err = pulse8_send_and_wait(pulse8, cmd, 3, ++ MSGCODE_COMMAND_ACCEPTED, 0); ++ if (err) ++ goto unlock; ++ ++ cmd[0] = MSGCODE_SET_HDMI_VERSION; ++ cmd[1] = adap->log_addrs.cec_version; ++ err = pulse8_send_and_wait(pulse8, cmd, 2, ++ MSGCODE_COMMAND_ACCEPTED, 0); ++ if (err) ++ goto unlock; ++ ++ if (adap->log_addrs.osd_name[0]) { ++ size_t osd_len = strlen(adap->log_addrs.osd_name); ++ char *osd_str = cmd + 1; ++ ++ cmd[0] = MSGCODE_SET_OSD_NAME; ++ strncpy(cmd + 1, adap->log_addrs.osd_name, 13); ++ if (osd_len < 4) { ++ memset(osd_str + osd_len, ' ', 4 - osd_len); ++ osd_len = 4; ++ osd_str[osd_len] = '\0'; ++ strcpy(adap->log_addrs.osd_name, osd_str); ++ } ++ err = pulse8_send_and_wait(pulse8, cmd, 1 + osd_len, ++ MSGCODE_COMMAND_ACCEPTED, 0); ++ if (err) ++ goto unlock; ++ } ++ ++unlock: ++ if (pulse8->restoring_config) ++ pulse8->restoring_config = false; ++ else ++ pulse8->config_pending = true; ++ mutex_unlock(&pulse8->config_lock); ++ return err; ++} ++ ++static int pulse8_cec_adap_transmit(struct cec_adapter *adap, u8 attempts, ++ u32 signal_free_time, struct cec_msg *msg) ++{ ++ struct pulse8 *pulse8 = cec_get_drvdata(adap); ++ u8 cmd[2]; ++ unsigned int i; ++ int err; ++ ++ cmd[0] = MSGCODE_TRANSMIT_IDLETIME; ++ cmd[1] = signal_free_time; ++ err = pulse8_send_and_wait(pulse8, cmd, 2, ++ MSGCODE_COMMAND_ACCEPTED, 1); ++ cmd[0] = MSGCODE_TRANSMIT_ACK_POLARITY; ++ cmd[1] = cec_msg_is_broadcast(msg); ++ if (!err) ++ err = pulse8_send_and_wait(pulse8, cmd, 2, ++ MSGCODE_COMMAND_ACCEPTED, 1); ++ cmd[0] = msg->len == 1 ? MSGCODE_TRANSMIT_EOM : MSGCODE_TRANSMIT; ++ cmd[1] = msg->msg[0]; ++ if (!err) ++ err = pulse8_send_and_wait(pulse8, cmd, 2, ++ MSGCODE_COMMAND_ACCEPTED, 1); ++ if (!err && msg->len > 1) { ++ cmd[0] = msg->len == 2 ? MSGCODE_TRANSMIT_EOM : ++ MSGCODE_TRANSMIT; ++ cmd[1] = msg->msg[1]; ++ err = pulse8_send_and_wait(pulse8, cmd, 2, ++ MSGCODE_COMMAND_ACCEPTED, 1); ++ for (i = 0; !err && i + 2 < msg->len; i++) { ++ cmd[0] = (i + 2 == msg->len - 1) ? ++ MSGCODE_TRANSMIT_EOM : MSGCODE_TRANSMIT; ++ cmd[1] = msg->msg[i + 2]; ++ err = pulse8_send_and_wait(pulse8, cmd, 2, ++ MSGCODE_COMMAND_ACCEPTED, 1); ++ } ++ } ++ ++ return err; ++} ++ ++static int pulse8_received(struct cec_adapter *adap, struct cec_msg *msg) ++{ ++ return -ENOMSG; ++} ++ ++static const struct cec_adap_ops pulse8_cec_adap_ops = { ++ .adap_enable = pulse8_cec_adap_enable, ++ .adap_log_addr = pulse8_cec_adap_log_addr, ++ .adap_transmit = pulse8_cec_adap_transmit, ++ .received = pulse8_received, ++}; ++ ++static int pulse8_connect(struct serio *serio, struct serio_driver *drv) ++{ ++ u32 caps = CEC_CAP_DEFAULTS | CEC_CAP_PHYS_ADDR | CEC_CAP_MONITOR_ALL; ++ struct pulse8 *pulse8; ++ int err = -ENOMEM; ++ struct cec_log_addrs log_addrs = {}; ++ u16 pa = CEC_PHYS_ADDR_INVALID; ++ ++ pulse8 = kzalloc(sizeof(*pulse8), GFP_KERNEL); ++ ++ if (!pulse8) ++ return -ENOMEM; ++ ++ pulse8->serio = serio; ++ pulse8->adap = cec_allocate_adapter(&pulse8_cec_adap_ops, pulse8, ++ dev_name(&serio->dev), caps, 1); ++ err = PTR_ERR_OR_ZERO(pulse8->adap); ++ if (err < 0) ++ goto free_device; ++ ++ pulse8->dev = &serio->dev; ++ serio_set_drvdata(serio, pulse8); ++ INIT_WORK(&pulse8->work, pulse8_irq_work_handler); ++ mutex_init(&pulse8->write_lock); ++ mutex_init(&pulse8->config_lock); ++ pulse8->config_pending = false; ++ ++ err = serio_open(serio, drv); ++ if (err) ++ goto delete_adap; ++ ++ err = pulse8_setup(pulse8, serio, &log_addrs, &pa); ++ if (err) ++ goto close_serio; ++ ++ err = cec_register_adapter(pulse8->adap, &serio->dev); ++ if (err < 0) ++ goto close_serio; ++ ++ pulse8->dev = &pulse8->adap->devnode.dev; ++ ++ if (persistent_config && pulse8->autonomous) { ++ err = pulse8_apply_persistent_config(pulse8, &log_addrs, pa); ++ if (err) ++ goto close_serio; ++ pulse8->restoring_config = true; ++ } ++ ++ INIT_DELAYED_WORK(&pulse8->ping_eeprom_work, ++ pulse8_ping_eeprom_work_handler); ++ schedule_delayed_work(&pulse8->ping_eeprom_work, PING_PERIOD); ++ ++ return 0; ++ ++close_serio: ++ serio_close(serio); ++delete_adap: ++ cec_delete_adapter(pulse8->adap); ++ serio_set_drvdata(serio, NULL); ++free_device: ++ kfree(pulse8); ++ return err; ++} ++ ++static void pulse8_ping_eeprom_work_handler(struct work_struct *work) ++{ ++ struct pulse8 *pulse8 = ++ container_of(work, struct pulse8, ping_eeprom_work.work); ++ u8 cmd; ++ ++ schedule_delayed_work(&pulse8->ping_eeprom_work, PING_PERIOD); ++ cmd = MSGCODE_PING; ++ pulse8_send_and_wait(pulse8, &cmd, 1, ++ MSGCODE_COMMAND_ACCEPTED, 0); ++ ++ if (pulse8->vers < 2) ++ return; ++ ++ mutex_lock(&pulse8->config_lock); ++ if (pulse8->config_pending && persistent_config) { ++ dev_dbg(pulse8->dev, "writing pending config to EEPROM\n"); ++ cmd = MSGCODE_WRITE_EEPROM; ++ if (pulse8_send_and_wait(pulse8, &cmd, 1, ++ MSGCODE_COMMAND_ACCEPTED, 0)) ++ dev_info(pulse8->dev, "failed to write pending config to EEPROM\n"); ++ else ++ pulse8->config_pending = false; ++ } ++ mutex_unlock(&pulse8->config_lock); ++} ++ ++static const struct serio_device_id pulse8_serio_ids[] = { ++ { ++ .type = SERIO_RS232, ++ .proto = SERIO_PULSE8_CEC, ++ .id = SERIO_ANY, ++ .extra = SERIO_ANY, ++ }, ++ { 0 } ++}; ++ ++MODULE_DEVICE_TABLE(serio, pulse8_serio_ids); ++ ++static struct serio_driver pulse8_drv = { ++ .driver = { ++ .name = "pulse8-cec", ++ }, ++ .description = "Pulse Eight HDMI CEC driver", ++ .id_table = pulse8_serio_ids, ++ .interrupt = pulse8_interrupt, ++ .connect = pulse8_connect, ++ .disconnect = pulse8_disconnect, ++}; ++ ++module_serio_driver(pulse8_drv); +diff --git a/include/uapi/linux/serio.h b/include/uapi/linux/serio.h +index becdd78295cc..4588c66a8df0 100644 +--- a/include/uapi/linux/serio.h ++++ b/include/uapi/linux/serio.h +@@ -77,5 +77,6 @@ + #define SERIO_PS2MULT 0x3c + #define SERIO_TSC40 0x3d + #define SERIO_WACOM_IV 0x3e ++#define SERIO_PULSE8_CEC 0x40 + + #endif /* _UAPI_SERIO_H */ + +From 7f6dbf0df7f833b1d9e8da72365eebffd046e7c7 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Mon, 4 Sep 2017 22:34:24 +0200 +Subject: [PATCH] BACKPORT: RainShadow Tech HDMI CEC from v4.15 + +--- + MAINTAINERS | 7 + + drivers/media/usb/Kconfig | 1 + + drivers/media/usb/Makefile | 1 + + drivers/media/usb/rainshadow-cec/Kconfig | 11 + + drivers/media/usb/rainshadow-cec/Makefile | 1 + + drivers/media/usb/rainshadow-cec/rainshadow-cec.c | 384 ++++++++++++++++++++++ + include/uapi/linux/serio.h | 1 + + 7 files changed, 406 insertions(+) + create mode 100644 drivers/media/usb/rainshadow-cec/Kconfig + create mode 100644 drivers/media/usb/rainshadow-cec/Makefile + create mode 100644 drivers/media/usb/rainshadow-cec/rainshadow-cec.c + +diff --git a/MAINTAINERS b/MAINTAINERS +index 0c1232c326a5..551555a162c3 100644 +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -8912,6 +8912,13 @@ L: linux-fbdev@vger.kernel.org + S: Maintained + F: drivers/video/fbdev/aty/aty128fb.c + ++RAINSHADOW-CEC DRIVER ++M: Hans Verkuil ++L: linux-media@vger.kernel.org ++T: git git://linuxtv.org/media_tree.git ++S: Maintained ++F: drivers/media/usb/rainshadow-cec/* ++ + RALINK RT2X00 WIRELESS LAN DRIVER + P: rt2x00 project + M: Stanislaw Gruszka +diff --git a/drivers/media/usb/Kconfig b/drivers/media/usb/Kconfig +index c9644b62f91a..b24e753c4766 100644 +--- a/drivers/media/usb/Kconfig ++++ b/drivers/media/usb/Kconfig +@@ -63,6 +63,7 @@ endif + if MEDIA_CEC_SUPPORT + comment "USB HDMI CEC adapters" + source "drivers/media/usb/pulse8-cec/Kconfig" ++source "drivers/media/usb/rainshadow-cec/Kconfig" + endif + + endif #MEDIA_USB_SUPPORT +diff --git a/drivers/media/usb/Makefile b/drivers/media/usb/Makefile +index 0f15e3351ddc..738b993ec8b0 100644 +--- a/drivers/media/usb/Makefile ++++ b/drivers/media/usb/Makefile +@@ -25,3 +25,4 @@ obj-$(CONFIG_VIDEO_USBTV) += usbtv/ + obj-$(CONFIG_VIDEO_GO7007) += go7007/ + obj-$(CONFIG_DVB_AS102) += as102/ + obj-$(CONFIG_USB_PULSE8_CEC) += pulse8-cec/ ++obj-$(CONFIG_USB_RAINSHADOW_CEC) += rainshadow-cec/ +diff --git a/drivers/media/usb/rainshadow-cec/Kconfig b/drivers/media/usb/rainshadow-cec/Kconfig +new file mode 100644 +index 000000000000..030ef01b1ff0 +--- /dev/null ++++ b/drivers/media/usb/rainshadow-cec/Kconfig +@@ -0,0 +1,11 @@ ++config USB_RAINSHADOW_CEC ++ tristate "RainShadow Tech HDMI CEC" ++ depends on USB_ACM ++ select CEC_CORE ++ select SERIO ++ select SERIO_SERPORT ++ ---help--- ++ This is a cec driver for the RainShadow Tech HDMI CEC device. ++ ++ To compile this driver as a module, choose M here: the ++ module will be called rainshadow-cec. +diff --git a/drivers/media/usb/rainshadow-cec/Makefile b/drivers/media/usb/rainshadow-cec/Makefile +new file mode 100644 +index 000000000000..a79fbc77e1f7 +--- /dev/null ++++ b/drivers/media/usb/rainshadow-cec/Makefile +@@ -0,0 +1 @@ ++obj-$(CONFIG_USB_RAINSHADOW_CEC) += rainshadow-cec.o +diff --git a/drivers/media/usb/rainshadow-cec/rainshadow-cec.c b/drivers/media/usb/rainshadow-cec/rainshadow-cec.c +new file mode 100644 +index 000000000000..cecdcbcd400c +--- /dev/null ++++ b/drivers/media/usb/rainshadow-cec/rainshadow-cec.c +@@ -0,0 +1,384 @@ ++/* ++ * RainShadow Tech HDMI CEC driver ++ * ++ * Copyright 2016 Hans Verkuil ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++MODULE_AUTHOR("Hans Verkuil "); ++MODULE_DESCRIPTION("RainShadow Tech HDMI CEC driver"); ++MODULE_LICENSE("GPL"); ++ ++#define DATA_SIZE 256 ++ ++struct rain { ++ struct device *dev; ++ struct serio *serio; ++ struct cec_adapter *adap; ++ struct completion cmd_done; ++ struct work_struct work; ++ ++ /* Low-level ringbuffer, collecting incoming characters */ ++ char buf[DATA_SIZE]; ++ unsigned int buf_rd_idx; ++ unsigned int buf_wr_idx; ++ unsigned int buf_len; ++ spinlock_t buf_lock; ++ ++ /* command buffer */ ++ char cmd[DATA_SIZE]; ++ unsigned int cmd_idx; ++ bool cmd_started; ++ ++ /* reply to a command, only used to store the firmware version */ ++ char cmd_reply[DATA_SIZE]; ++ ++ struct mutex write_lock; ++}; ++ ++static void rain_process_msg(struct rain *rain) ++{ ++ struct cec_msg msg = {}; ++ const char *cmd = rain->cmd + 3; ++ int stat = -1; ++ ++ for (; *cmd; cmd++) { ++ if (!isxdigit(*cmd)) ++ continue; ++ if (isxdigit(cmd[0]) && isxdigit(cmd[1])) { ++ if (msg.len == CEC_MAX_MSG_SIZE) ++ break; ++ if (hex2bin(msg.msg + msg.len, cmd, 1)) ++ continue; ++ msg.len++; ++ cmd++; ++ continue; ++ } ++ if (!cmd[1]) ++ stat = hex_to_bin(cmd[0]); ++ break; ++ } ++ ++ if (rain->cmd[0] == 'R') { ++ if (stat == 1 || stat == 2) ++ cec_received_msg(rain->adap, &msg); ++ return; ++ } ++ ++ switch (stat) { ++ case 1: ++ cec_transmit_attempt_done(rain->adap, CEC_TX_STATUS_OK); ++ break; ++ case 2: ++ cec_transmit_attempt_done(rain->adap, CEC_TX_STATUS_NACK); ++ break; ++ default: ++ cec_transmit_attempt_done(rain->adap, CEC_TX_STATUS_LOW_DRIVE); ++ break; ++ } ++} ++ ++static void rain_irq_work_handler(struct work_struct *work) ++{ ++ struct rain *rain = ++ container_of(work, struct rain, work); ++ ++ while (true) { ++ unsigned long flags; ++ char data; ++ ++ spin_lock_irqsave(&rain->buf_lock, flags); ++ if (!rain->buf_len) { ++ spin_unlock_irqrestore(&rain->buf_lock, flags); ++ break; ++ } ++ ++ data = rain->buf[rain->buf_rd_idx]; ++ rain->buf_len--; ++ rain->buf_rd_idx = (rain->buf_rd_idx + 1) & 0xff; ++ ++ spin_unlock_irqrestore(&rain->buf_lock, flags); ++ ++ if (!rain->cmd_started && data != '?') ++ continue; ++ ++ switch (data) { ++ case '\r': ++ rain->cmd[rain->cmd_idx] = '\0'; ++ dev_dbg(rain->dev, "received: %s\n", rain->cmd); ++ if (!memcmp(rain->cmd, "REC", 3) || ++ !memcmp(rain->cmd, "STA", 3)) { ++ rain_process_msg(rain); ++ } else { ++ strcpy(rain->cmd_reply, rain->cmd); ++ complete(&rain->cmd_done); ++ } ++ rain->cmd_idx = 0; ++ rain->cmd_started = false; ++ break; ++ ++ case '\n': ++ rain->cmd_idx = 0; ++ rain->cmd_started = false; ++ break; ++ ++ case '?': ++ rain->cmd_idx = 0; ++ rain->cmd_started = true; ++ break; ++ ++ default: ++ if (rain->cmd_idx >= DATA_SIZE - 1) { ++ dev_dbg(rain->dev, ++ "throwing away %d bytes of garbage\n", rain->cmd_idx); ++ rain->cmd_idx = 0; ++ } ++ rain->cmd[rain->cmd_idx++] = data; ++ break; ++ } ++ } ++} ++ ++static irqreturn_t rain_interrupt(struct serio *serio, unsigned char data, ++ unsigned int flags) ++{ ++ struct rain *rain = serio_get_drvdata(serio); ++ ++ if (rain->buf_len == DATA_SIZE) { ++ dev_warn_once(rain->dev, "buffer overflow\n"); ++ return IRQ_HANDLED; ++ } ++ spin_lock(&rain->buf_lock); ++ rain->buf_len++; ++ rain->buf[rain->buf_wr_idx] = data; ++ rain->buf_wr_idx = (rain->buf_wr_idx + 1) & 0xff; ++ spin_unlock(&rain->buf_lock); ++ schedule_work(&rain->work); ++ return IRQ_HANDLED; ++} ++ ++static void rain_disconnect(struct serio *serio) ++{ ++ struct rain *rain = serio_get_drvdata(serio); ++ ++ cancel_work_sync(&rain->work); ++ cec_unregister_adapter(rain->adap); ++ dev_info(&serio->dev, "disconnected\n"); ++ serio_close(serio); ++ serio_set_drvdata(serio, NULL); ++ kfree(rain); ++} ++ ++static int rain_send(struct rain *rain, const char *command) ++{ ++ int err = serio_write(rain->serio, '!'); ++ ++ dev_dbg(rain->dev, "send: %s\n", command); ++ while (!err && *command) ++ err = serio_write(rain->serio, *command++); ++ if (!err) ++ err = serio_write(rain->serio, '~'); ++ ++ return err; ++} ++ ++static int rain_send_and_wait(struct rain *rain, ++ const char *cmd, const char *reply) ++{ ++ int err; ++ ++ init_completion(&rain->cmd_done); ++ ++ mutex_lock(&rain->write_lock); ++ err = rain_send(rain, cmd); ++ if (err) ++ goto err; ++ ++ if (!wait_for_completion_timeout(&rain->cmd_done, HZ)) { ++ err = -ETIMEDOUT; ++ goto err; ++ } ++ if (reply && strncmp(rain->cmd_reply, reply, strlen(reply))) { ++ dev_dbg(rain->dev, ++ "transmit of '%s': received '%s' instead of '%s'\n", ++ cmd, rain->cmd_reply, reply); ++ err = -EIO; ++ } ++err: ++ mutex_unlock(&rain->write_lock); ++ return err; ++} ++ ++static int rain_setup(struct rain *rain, struct serio *serio, ++ struct cec_log_addrs *log_addrs, u16 *pa) ++{ ++ int err; ++ ++ err = rain_send_and_wait(rain, "R", "REV"); ++ if (err) ++ return err; ++ dev_info(rain->dev, "Firmware version %s\n", rain->cmd_reply + 4); ++ ++ err = rain_send_and_wait(rain, "Q 1", "QTY"); ++ if (err) ++ return err; ++ err = rain_send_and_wait(rain, "c0000", "CFG"); ++ if (err) ++ return err; ++ return rain_send_and_wait(rain, "A F 0000", "ADR"); ++} ++ ++static int rain_cec_adap_enable(struct cec_adapter *adap, bool enable) ++{ ++ return 0; ++} ++ ++static int rain_cec_adap_log_addr(struct cec_adapter *adap, u8 log_addr) ++{ ++ struct rain *rain = cec_get_drvdata(adap); ++ u8 cmd[16]; ++ ++ if (log_addr == CEC_LOG_ADDR_INVALID) ++ log_addr = CEC_LOG_ADDR_UNREGISTERED; ++ snprintf(cmd, sizeof(cmd), "A %x", log_addr); ++ return rain_send_and_wait(rain, cmd, "ADR"); ++} ++ ++static int rain_cec_adap_transmit(struct cec_adapter *adap, u8 attempts, ++ u32 signal_free_time, struct cec_msg *msg) ++{ ++ struct rain *rain = cec_get_drvdata(adap); ++ char cmd[2 * CEC_MAX_MSG_SIZE + 16]; ++ unsigned int i; ++ int err; ++ ++ if (msg->len == 1) { ++ snprintf(cmd, sizeof(cmd), "x%x", cec_msg_destination(msg)); ++ } else { ++ char hex[3]; ++ ++ snprintf(cmd, sizeof(cmd), "x%x %02x ", ++ cec_msg_destination(msg), msg->msg[1]); ++ for (i = 2; i < msg->len; i++) { ++ snprintf(hex, sizeof(hex), "%02x", msg->msg[i]); ++ strlcat(cmd, hex, sizeof(cmd)); ++ } ++ } ++ mutex_lock(&rain->write_lock); ++ err = rain_send(rain, cmd); ++ mutex_unlock(&rain->write_lock); ++ return err; ++} ++ ++static const struct cec_adap_ops rain_cec_adap_ops = { ++ .adap_enable = rain_cec_adap_enable, ++ .adap_log_addr = rain_cec_adap_log_addr, ++ .adap_transmit = rain_cec_adap_transmit, ++}; ++ ++static int rain_connect(struct serio *serio, struct serio_driver *drv) ++{ ++ u32 caps = CEC_CAP_DEFAULTS | CEC_CAP_PHYS_ADDR | CEC_CAP_MONITOR_ALL; ++ struct rain *rain; ++ int err = -ENOMEM; ++ struct cec_log_addrs log_addrs = {}; ++ u16 pa = CEC_PHYS_ADDR_INVALID; ++ ++ rain = kzalloc(sizeof(*rain), GFP_KERNEL); ++ ++ if (!rain) ++ return -ENOMEM; ++ ++ rain->serio = serio; ++ rain->adap = cec_allocate_adapter(&rain_cec_adap_ops, rain, ++ dev_name(&serio->dev), caps, 1); ++ err = PTR_ERR_OR_ZERO(rain->adap); ++ if (err < 0) ++ goto free_device; ++ ++ rain->dev = &serio->dev; ++ serio_set_drvdata(serio, rain); ++ INIT_WORK(&rain->work, rain_irq_work_handler); ++ mutex_init(&rain->write_lock); ++ spin_lock_init(&rain->buf_lock); ++ ++ err = serio_open(serio, drv); ++ if (err) ++ goto delete_adap; ++ ++ err = rain_setup(rain, serio, &log_addrs, &pa); ++ if (err) ++ goto close_serio; ++ ++ err = cec_register_adapter(rain->adap, &serio->dev); ++ if (err < 0) ++ goto close_serio; ++ ++ rain->dev = &rain->adap->devnode.dev; ++ return 0; ++ ++close_serio: ++ serio_close(serio); ++delete_adap: ++ cec_delete_adapter(rain->adap); ++ serio_set_drvdata(serio, NULL); ++free_device: ++ kfree(rain); ++ return err; ++} ++ ++static const struct serio_device_id rain_serio_ids[] = { ++ { ++ .type = SERIO_RS232, ++ .proto = SERIO_RAINSHADOW_CEC, ++ .id = SERIO_ANY, ++ .extra = SERIO_ANY, ++ }, ++ { 0 } ++}; ++ ++MODULE_DEVICE_TABLE(serio, rain_serio_ids); ++ ++static struct serio_driver rain_drv = { ++ .driver = { ++ .name = "rainshadow-cec", ++ }, ++ .description = "RainShadow Tech HDMI CEC driver", ++ .id_table = rain_serio_ids, ++ .interrupt = rain_interrupt, ++ .connect = rain_connect, ++ .disconnect = rain_disconnect, ++}; ++ ++module_serio_driver(rain_drv); +diff --git a/include/uapi/linux/serio.h b/include/uapi/linux/serio.h +index 4588c66a8df0..89b72003fb68 100644 +--- a/include/uapi/linux/serio.h ++++ b/include/uapi/linux/serio.h +@@ -78,5 +78,6 @@ + #define SERIO_TSC40 0x3d + #define SERIO_WACOM_IV 0x3e + #define SERIO_PULSE8_CEC 0x40 ++#define SERIO_RAINSHADOW_CEC 0x41 + + #endif /* _UAPI_SERIO_H */ + +From f532f514ca373430332f2733be987335af7ae75c Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sat, 2 Sep 2017 16:23:11 +0200 +Subject: [PATCH] [media] rc/keymaps: initialize rc-cec early + +--- + drivers/media/rc/keymaps/rc-cec.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/media/rc/keymaps/rc-cec.c b/drivers/media/rc/keymaps/rc-cec.c +index 354c8e724b8e..fb0c2b1f3814 100644 +--- a/drivers/media/rc/keymaps/rc-cec.c ++++ b/drivers/media/rc/keymaps/rc-cec.c +@@ -175,7 +175,7 @@ static void __exit exit_rc_map_cec(void) + rc_map_unregister(&cec_map); + } + +-module_init(init_rc_map_cec); ++subsys_initcall(init_rc_map_cec); + module_exit(exit_rc_map_cec); + + MODULE_LICENSE("GPL"); + +From 54c779a399fb852e06f11a03bf03c31090c4b722 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sat, 2 Sep 2017 16:23:11 +0200 +Subject: [PATCH] drm/bridge: dw-hdmi: read edid on hpd event + +--- + drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 23 +++++++++++++++++++---- + 1 file changed, 19 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +index 8cb2cb4e61a6..c045cc0717cd 100644 +--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c ++++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +@@ -2479,6 +2479,7 @@ static void dw_hdmi_bridge_nop(struct drm_bridge *bridge) + static enum drm_connector_status + dw_hdmi_connector_detect(struct drm_connector *connector, bool force) + { ++ enum drm_connector_status status; + struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi, + connector); + +@@ -2488,7 +2489,24 @@ dw_hdmi_connector_detect(struct drm_connector *connector, bool force) + dw_hdmi_update_phy_mask(hdmi); + mutex_unlock(&hdmi->mutex); + +- return hdmi->phy.ops->read_hpd(hdmi, hdmi->phy.data); ++ status = hdmi->phy.ops->read_hpd(hdmi, hdmi->phy.data); ++ ++ if (status == connector_status_connected && hdmi->ddc) { ++ struct edid *edid = drm_get_edid(connector, hdmi->ddc); ++ if (edid) { ++ dev_dbg(hdmi->dev, "got edid: width[%d] x height[%d]\n", ++ edid->width_cm, edid->height_cm); ++ ++ hdmi->sink_is_hdmi = drm_detect_hdmi_monitor(edid); ++ hdmi->sink_has_audio = drm_detect_monitor_audio(edid); ++ drm_mode_connector_update_edid_property(connector, edid); ++ cec_notifier_set_phys_addr_from_edid(hdmi->cec_notifier, edid); ++ drm_edid_to_eld(connector, edid); ++ kfree(edid); ++ } ++ } ++ ++ return status; + } + + static int dw_hdmi_connector_get_modes(struct drm_connector *connector) +@@ -2891,9 +2909,6 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id) + dw_hdmi_update_phy_mask(hdmi); + } + mutex_unlock(&hdmi->mutex); +- if (!(phy_stat & (HDMI_PHY_RX_SENSE | HDMI_PHY_HPD))) +- cec_notifier_set_phys_addr(hdmi->cec_notifier, +- CEC_PHYS_ADDR_INVALID); + } + + check_hdmi_irq(hdmi, intr_stat, phy_int_pol); diff --git a/patch/kernel/rk322x-legacy/01-linux-0004-audio.patch b/patch/kernel/rk322x-legacy/01-linux-0004-audio.patch new file mode 100644 index 0000000000..1e09db54c5 --- /dev/null +++ b/patch/kernel/rk322x-legacy/01-linux-0004-audio.patch @@ -0,0 +1,1383 @@ +From 46e3e82a547b78ca5db11a8444f787fd15f8e8ce Mon Sep 17 00:00:00 2001 +From: Sugar Zhang +Date: Wed, 7 Sep 2016 14:30:21 +0800 +Subject: [PATCH] UPSTREAM: ASoC: rockchip: spdif: restore register during + runtime_suspend/resume cycle + +when step into runtime_suspend, spdif pd will be disabled and loss state. +so need to restore register when runtime_resume. + +Signed-off-by: Sugar Zhang +Signed-off-by: Mark Brown +(cherry picked from commit 3628c6987fb45d719cd963805bbba9f15017290e) +--- + sound/soc/rockchip/rockchip_spdif.c | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +diff --git a/sound/soc/rockchip/rockchip_spdif.c b/sound/soc/rockchip/rockchip_spdif.c +index 784941ca2408..831e4caf29d3 100644 +--- a/sound/soc/rockchip/rockchip_spdif.c ++++ b/sound/soc/rockchip/rockchip_spdif.c +@@ -69,6 +69,7 @@ static int __maybe_unused rk_spdif_runtime_suspend(struct device *dev) + { + struct rk_spdif_dev *spdif = dev_get_drvdata(dev); + ++ regcache_cache_only(spdif->regmap, true); + clk_disable_unprepare(spdif->mclk); + clk_disable_unprepare(spdif->hclk); + +@@ -92,7 +93,16 @@ static int __maybe_unused rk_spdif_runtime_resume(struct device *dev) + return ret; + } + +- return 0; ++ regcache_cache_only(spdif->regmap, false); ++ regcache_mark_dirty(spdif->regmap); ++ ++ ret = regcache_sync(spdif->regmap); ++ if (ret) { ++ clk_disable_unprepare(spdif->mclk); ++ clk_disable_unprepare(spdif->hclk); ++ } ++ ++ return ret; + } + + static int rk_spdif_hw_params(struct snd_pcm_substream *substream, + +From d8a8c9964022565ecf7b5ea7249262c3ac381a1b Mon Sep 17 00:00:00 2001 +From: Arnaud Pouliquen +Date: Tue, 3 Jan 2017 16:52:50 +0100 +Subject: [PATCH] UPSTREAM: DRM: add help to get ELD speaker allocation + +Add helper to allow users to retrieve the speaker allocations without +knowledge of the ELD structure. + +Signed-off-by: Arnaud Pouliquen +Reviewed-by: Jani Nikula +Signed-off-by: Mark Brown +(cherry picked from commit c82dbe5c055e4d246bd07c4d7b24801c9445c241) +--- + include/drm/drm_edid.h | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h +index 85861b63e77a..55201e7e2ede 100644 +--- a/include/drm/drm_edid.h ++++ b/include/drm/drm_edid.h +@@ -254,6 +254,7 @@ struct detailed_timing { + # define DRM_ELD_AUD_SYNCH_DELAY_MAX 0xfa /* 500 ms */ + + #define DRM_ELD_SPEAKER 7 ++# define DRM_ELD_SPEAKER_MASK 0x7f + # define DRM_ELD_SPEAKER_RLRC (1 << 6) + # define DRM_ELD_SPEAKER_FLRC (1 << 5) + # define DRM_ELD_SPEAKER_RC (1 << 4) +@@ -417,6 +418,18 @@ static inline int drm_eld_size(const uint8_t *eld) + return DRM_ELD_HEADER_BLOCK_SIZE + eld[DRM_ELD_BASELINE_ELD_LEN] * 4; + } + ++/** ++ * drm_eld_get_spk_alloc - Get speaker allocation ++ * @eld: pointer to an ELD memory structure ++ * ++ * The returned value is the speakers mask. User has to use %DRM_ELD_SPEAKER ++ * field definitions to identify speakers. ++ */ ++static inline u8 drm_eld_get_spk_alloc(const uint8_t *eld) ++{ ++ return eld[DRM_ELD_SPEAKER] & DRM_ELD_SPEAKER_MASK; ++} ++ + struct edid *drm_do_get_edid(struct drm_connector *connector, + int (*get_edid_block)(void *data, u8 *buf, unsigned int block, + size_t len), + +From e622344ce58345eda1ce7372bf7e91e4e90ece5f Mon Sep 17 00:00:00 2001 +From: Arnaud Pouliquen +Date: Tue, 3 Jan 2017 16:52:51 +0100 +Subject: [PATCH] UPSTREAM: ASoC: core: add optional pcm_new callback for DAI + driver + +During probe, DAIs can need to perform some actions that requests +the knowledge of the pcm runtime handle. +The callback is called during DAIs linking, after PCM device creation. +For instance this can be used to add relationship between a DAI pcm +control and the pcm device. + +Signed-off-by: Arnaud Pouliquen +Signed-off-by: Mark Brown +(cherry picked from commit 25f7b701c20db3e9ae09e28dd652949bd977e5cd) +--- + include/sound/soc-dai.h | 3 +++ + sound/soc/soc-core.c | 28 ++++++++++++++++++++++++++++ + 2 files changed, 31 insertions(+) + +diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h +index 212eaaf172ed..345e4f8ee93f 100644 +--- a/include/sound/soc-dai.h ++++ b/include/sound/soc-dai.h +@@ -230,6 +230,9 @@ struct snd_soc_dai_driver { + int (*resume)(struct snd_soc_dai *dai); + /* compress dai */ + int (*compress_new)(struct snd_soc_pcm_runtime *rtd, int num); ++ /* Optional Callback used at pcm creation*/ ++ int (*pcm_new)(struct snd_soc_pcm_runtime *rtd, ++ struct snd_soc_dai *dai); + /* DAI is also used for the control bus */ + bool bus_control; + +diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c +index 3c6713da3ad9..e46e80c0e07d 100644 +--- a/sound/soc/soc-core.c ++++ b/sound/soc/soc-core.c +@@ -1289,6 +1289,27 @@ static int soc_probe_dai(struct snd_soc_dai *dai, int order) + return 0; + } + ++static int soc_link_dai_pcm_new(struct snd_soc_dai **dais, int num_dais, ++ struct snd_soc_pcm_runtime *rtd) ++{ ++ int i, ret = 0; ++ ++ for (i = 0; i < num_dais; ++i) { ++ struct snd_soc_dai_driver *drv = dais[i]->driver; ++ ++ if (!rtd->dai_link->no_pcm && drv->pcm_new) ++ ret = drv->pcm_new(rtd, dais[i]); ++ if (ret < 0) { ++ dev_err(dais[i]->dev, ++ "ASoC: Failed to bind %s with pcm device\n", ++ dais[i]->name); ++ return ret; ++ } ++ } ++ ++ return 0; ++} ++ + static int soc_link_dai_widgets(struct snd_soc_card *card, + struct snd_soc_dai_link *dai_link, + struct snd_soc_pcm_runtime *rtd) +@@ -1400,6 +1421,13 @@ static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order) + dai_link->stream_name, ret); + return ret; + } ++ ret = soc_link_dai_pcm_new(&cpu_dai, 1, rtd); ++ if (ret < 0) ++ return ret; ++ ret = soc_link_dai_pcm_new(rtd->codec_dais, ++ rtd->num_codecs, rtd); ++ if (ret < 0) ++ return ret; + } else { + INIT_DELAYED_WORK(&rtd->delayed_work, + codec2codec_close_delayed_work); + +From 3877e4beac5a5efc2898185fe75555e21cf6b090 Mon Sep 17 00:00:00 2001 +From: Arnaud Pouliquen +Date: Tue, 3 Jan 2017 16:52:52 +0100 +Subject: [PATCH] UPSTREAM: ASoC: hdmi-codec: add channel mapping control + +Add user interface to provide channel mapping. +In a first step this control is read only. + +As TLV type, the control provides all configuration available for +HDMI sink(ELD), and provides current channel mapping selected by codec +based on ELD and number of channels specified by user on open. +When control is called before the number of the channel is specified +(i.e. hw_params is set), it returns all channels set to UNKNOWN. + +Signed-off-by: Arnaud Pouliquen +Signed-off-by: Mark Brown +(cherry picked from commit cd6111b26280a2f38a9fb8e6630c63a96477e4bf) +--- + sound/soc/codecs/hdmi-codec.c | 377 +++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 376 insertions(+), 1 deletion(-) + +diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c +index 028d60c196ae..cb78d8971b41 100644 +--- a/sound/soc/codecs/hdmi-codec.c ++++ b/sound/soc/codecs/hdmi-codec.c +@@ -21,12 +21,264 @@ + #include + #include + #include ++#include + #include + #include + #include + + #include /* This is only to get MAX_ELD_BYTES */ + ++#define HDMI_CODEC_CHMAP_IDX_UNKNOWN -1 ++ ++struct hdmi_codec_channel_map_table { ++ unsigned char map; /* ALSA API channel map position */ ++ unsigned long spk_mask; /* speaker position bit mask */ ++}; ++ ++/* ++ * CEA speaker placement for HDMI 1.4: ++ * ++ * FL FLC FC FRC FR FRW ++ * ++ * LFE ++ * ++ * RL RLC RC RRC RR ++ * ++ * Speaker placement has to be extended to support HDMI 2.0 ++ */ ++enum hdmi_codec_cea_spk_placement { ++ FL = BIT(0), /* Front Left */ ++ FC = BIT(1), /* Front Center */ ++ FR = BIT(2), /* Front Right */ ++ FLC = BIT(3), /* Front Left Center */ ++ FRC = BIT(4), /* Front Right Center */ ++ RL = BIT(5), /* Rear Left */ ++ RC = BIT(6), /* Rear Center */ ++ RR = BIT(7), /* Rear Right */ ++ RLC = BIT(8), /* Rear Left Center */ ++ RRC = BIT(9), /* Rear Right Center */ ++ LFE = BIT(10), /* Low Frequency Effect */ ++}; ++ ++/* ++ * cea Speaker allocation structure ++ */ ++struct hdmi_codec_cea_spk_alloc { ++ const int ca_id; ++ unsigned int n_ch; ++ unsigned long mask; ++}; ++ ++/* Channel maps stereo HDMI */ ++const struct snd_pcm_chmap_elem hdmi_codec_stereo_chmaps[] = { ++ { .channels = 2, ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR } }, ++ { } ++}; ++ ++/* Channel maps for multi-channel playbacks, up to 8 n_ch */ ++const struct snd_pcm_chmap_elem hdmi_codec_8ch_chmaps[] = { ++ { .channels = 2, /* CA_ID 0x00 */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR } }, ++ { .channels = 4, /* CA_ID 0x01 */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE, ++ SNDRV_CHMAP_NA } }, ++ { .channels = 4, /* CA_ID 0x02 */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_FC } }, ++ { .channels = 4, /* CA_ID 0x03 */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE, ++ SNDRV_CHMAP_FC } }, ++ { .channels = 6, /* CA_ID 0x04 */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_NA, SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } }, ++ { .channels = 6, /* CA_ID 0x05 */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE, ++ SNDRV_CHMAP_NA, SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } }, ++ { .channels = 6, /* CA_ID 0x06 */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_FC, SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } }, ++ { .channels = 6, /* CA_ID 0x07 */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE, ++ SNDRV_CHMAP_FC, SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } }, ++ { .channels = 6, /* CA_ID 0x08 */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_NA, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } }, ++ { .channels = 6, /* CA_ID 0x09 */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE, ++ SNDRV_CHMAP_NA, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } }, ++ { .channels = 6, /* CA_ID 0x0A */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_FC, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } }, ++ { .channels = 6, /* CA_ID 0x0B */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE, ++ SNDRV_CHMAP_FC, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } }, ++ { .channels = 8, /* CA_ID 0x0C */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_NA, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR, ++ SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } }, ++ { .channels = 8, /* CA_ID 0x0D */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE, ++ SNDRV_CHMAP_NA, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR, ++ SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } }, ++ { .channels = 8, /* CA_ID 0x0E */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_FC, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR, ++ SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } }, ++ { .channels = 8, /* CA_ID 0x0F */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE, ++ SNDRV_CHMAP_FC, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR, ++ SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } }, ++ { .channels = 8, /* CA_ID 0x10 */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_NA, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR, ++ SNDRV_CHMAP_RLC, SNDRV_CHMAP_RRC } }, ++ { .channels = 8, /* CA_ID 0x11 */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE, ++ SNDRV_CHMAP_NA, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR, ++ SNDRV_CHMAP_RLC, SNDRV_CHMAP_RRC } }, ++ { .channels = 8, /* CA_ID 0x12 */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_FC, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR, ++ SNDRV_CHMAP_RLC, SNDRV_CHMAP_RRC } }, ++ { .channels = 8, /* CA_ID 0x13 */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE, ++ SNDRV_CHMAP_FC, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR, ++ SNDRV_CHMAP_RLC, SNDRV_CHMAP_RRC } }, ++ { .channels = 8, /* CA_ID 0x14 */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } }, ++ { .channels = 8, /* CA_ID 0x15 */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE, ++ SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } }, ++ { .channels = 8, /* CA_ID 0x16 */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_FC, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } }, ++ { .channels = 8, /* CA_ID 0x17 */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE, ++ SNDRV_CHMAP_FC, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } }, ++ { .channels = 8, /* CA_ID 0x18 */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } }, ++ { .channels = 8, /* CA_ID 0x19 */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE, ++ SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } }, ++ { .channels = 8, /* CA_ID 0x1A */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_FC, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } }, ++ { .channels = 8, /* CA_ID 0x1B */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE, ++ SNDRV_CHMAP_FC, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } }, ++ { .channels = 8, /* CA_ID 0x1C */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } }, ++ { .channels = 8, /* CA_ID 0x1D */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE, ++ SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } }, ++ { .channels = 8, /* CA_ID 0x1E */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_FC, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } }, ++ { .channels = 8, /* CA_ID 0x1F */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE, ++ SNDRV_CHMAP_FC, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } }, ++ { } ++}; ++ ++/* ++ * hdmi_codec_channel_alloc: speaker configuration available for CEA ++ * ++ * This is an ordered list that must match with hdmi_codec_8ch_chmaps struct ++ * The preceding ones have better chances to be selected by ++ * hdmi_codec_get_ch_alloc_table_idx(). ++ */ ++static const struct hdmi_codec_cea_spk_alloc hdmi_codec_channel_alloc[] = { ++ { .ca_id = 0x00, .n_ch = 2, ++ .mask = FL | FR}, ++ /* 2.1 */ ++ { .ca_id = 0x01, .n_ch = 4, ++ .mask = FL | FR | LFE}, ++ /* Dolby Surround */ ++ { .ca_id = 0x02, .n_ch = 4, ++ .mask = FL | FR | FC }, ++ /* surround51 */ ++ { .ca_id = 0x0b, .n_ch = 6, ++ .mask = FL | FR | LFE | FC | RL | RR}, ++ /* surround40 */ ++ { .ca_id = 0x08, .n_ch = 6, ++ .mask = FL | FR | RL | RR }, ++ /* surround41 */ ++ { .ca_id = 0x09, .n_ch = 6, ++ .mask = FL | FR | LFE | RL | RR }, ++ /* surround50 */ ++ { .ca_id = 0x0a, .n_ch = 6, ++ .mask = FL | FR | FC | RL | RR }, ++ /* 6.1 */ ++ { .ca_id = 0x0f, .n_ch = 8, ++ .mask = FL | FR | LFE | FC | RL | RR | RC }, ++ /* surround71 */ ++ { .ca_id = 0x13, .n_ch = 8, ++ .mask = FL | FR | LFE | FC | RL | RR | RLC | RRC }, ++ /* others */ ++ { .ca_id = 0x03, .n_ch = 8, ++ .mask = FL | FR | LFE | FC }, ++ { .ca_id = 0x04, .n_ch = 8, ++ .mask = FL | FR | RC}, ++ { .ca_id = 0x05, .n_ch = 8, ++ .mask = FL | FR | LFE | RC }, ++ { .ca_id = 0x06, .n_ch = 8, ++ .mask = FL | FR | FC | RC }, ++ { .ca_id = 0x07, .n_ch = 8, ++ .mask = FL | FR | LFE | FC | RC }, ++ { .ca_id = 0x0c, .n_ch = 8, ++ .mask = FL | FR | RC | RL | RR }, ++ { .ca_id = 0x0d, .n_ch = 8, ++ .mask = FL | FR | LFE | RL | RR | RC }, ++ { .ca_id = 0x0e, .n_ch = 8, ++ .mask = FL | FR | FC | RL | RR | RC }, ++ { .ca_id = 0x10, .n_ch = 8, ++ .mask = FL | FR | RL | RR | RLC | RRC }, ++ { .ca_id = 0x11, .n_ch = 8, ++ .mask = FL | FR | LFE | RL | RR | RLC | RRC }, ++ { .ca_id = 0x12, .n_ch = 8, ++ .mask = FL | FR | FC | RL | RR | RLC | RRC }, ++ { .ca_id = 0x14, .n_ch = 8, ++ .mask = FL | FR | FLC | FRC }, ++ { .ca_id = 0x15, .n_ch = 8, ++ .mask = FL | FR | LFE | FLC | FRC }, ++ { .ca_id = 0x16, .n_ch = 8, ++ .mask = FL | FR | FC | FLC | FRC }, ++ { .ca_id = 0x17, .n_ch = 8, ++ .mask = FL | FR | LFE | FC | FLC | FRC }, ++ { .ca_id = 0x18, .n_ch = 8, ++ .mask = FL | FR | RC | FLC | FRC }, ++ { .ca_id = 0x19, .n_ch = 8, ++ .mask = FL | FR | LFE | RC | FLC | FRC }, ++ { .ca_id = 0x1a, .n_ch = 8, ++ .mask = FL | FR | RC | FC | FLC | FRC }, ++ { .ca_id = 0x1b, .n_ch = 8, ++ .mask = FL | FR | LFE | RC | FC | FLC | FRC }, ++ { .ca_id = 0x1c, .n_ch = 8, ++ .mask = FL | FR | RL | RR | FLC | FRC }, ++ { .ca_id = 0x1d, .n_ch = 8, ++ .mask = FL | FR | LFE | RL | RR | FLC | FRC }, ++ { .ca_id = 0x1e, .n_ch = 8, ++ .mask = FL | FR | FC | RL | RR | FLC | FRC }, ++ { .ca_id = 0x1f, .n_ch = 8, ++ .mask = FL | FR | LFE | FC | RL | RR | FLC | FRC }, ++}; ++ + struct hdmi_codec_priv { + struct hdmi_codec_pdata hcd; + struct snd_soc_dai_driver *daidrv; +@@ -41,6 +293,8 @@ struct hdmi_codec_priv { + struct notifier_block nb; + unsigned int jack_status; + unsigned int mode; ++ struct snd_pcm_chmap *chmap_info; ++ unsigned int chmap_idx; + }; + + static const struct snd_soc_dapm_widget hdmi_widgets[] = { +@@ -109,6 +363,83 @@ static int hdmi_audio_mode_put(struct snd_kcontrol *kcontrol, + return 0; + } + ++static unsigned long hdmi_codec_spk_mask_from_alloc(int spk_alloc) ++{ ++ int i; ++ const unsigned long hdmi_codec_eld_spk_alloc_bits[] = { ++ [0] = FL | FR, [1] = LFE, [2] = FC, [3] = RL | RR, ++ [4] = RC, [5] = FLC | FRC, [6] = RLC | RRC, ++ }; ++ unsigned long spk_mask = 0; ++ ++ for (i = 0; i < ARRAY_SIZE(hdmi_codec_eld_spk_alloc_bits); i++) { ++ if (spk_alloc & (1 << i)) ++ spk_mask |= hdmi_codec_eld_spk_alloc_bits[i]; ++ } ++ ++ return spk_mask; ++} ++ ++void hdmi_codec_eld_chmap(struct hdmi_codec_priv *hcp) ++{ ++ u8 spk_alloc; ++ unsigned long spk_mask; ++ ++ spk_alloc = drm_eld_get_spk_alloc(hcp->eld); ++ spk_mask = hdmi_codec_spk_mask_from_alloc(spk_alloc); ++ ++ /* Detect if only stereo supported, else return 8 channels mappings */ ++ if ((spk_mask & ~(FL | FR)) && hcp->chmap_info->max_channels > 2) ++ hcp->chmap_info->chmap = hdmi_codec_8ch_chmaps; ++ else ++ hcp->chmap_info->chmap = hdmi_codec_stereo_chmaps; ++} ++ ++static int hdmi_codec_get_ch_alloc_table_idx(struct hdmi_codec_priv *hcp, ++ unsigned char channels) ++{ ++ int i; ++ u8 spk_alloc; ++ unsigned long spk_mask; ++ const struct hdmi_codec_cea_spk_alloc *cap = hdmi_codec_channel_alloc; ++ ++ spk_alloc = drm_eld_get_spk_alloc(hcp->eld); ++ spk_mask = hdmi_codec_spk_mask_from_alloc(spk_alloc); ++ ++ for (i = 0; i < ARRAY_SIZE(hdmi_codec_channel_alloc); i++, cap++) { ++ /* If spk_alloc == 0, HDMI is unplugged return stereo config*/ ++ if (!spk_alloc && cap->ca_id == 0) ++ return i; ++ if (cap->n_ch != channels) ++ continue; ++ if (!(cap->mask == (spk_mask & cap->mask))) ++ continue; ++ return i; ++ } ++ ++ return -EINVAL; ++} ++static int hdmi_codec_chmap_ctl_get(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ unsigned const char *map; ++ unsigned int i; ++ struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol); ++ struct hdmi_codec_priv *hcp = info->private_data; ++ ++ map = info->chmap[hcp->chmap_idx].map; ++ ++ for (i = 0; i < info->max_channels; i++) { ++ if (hcp->chmap_idx == HDMI_CODEC_CHMAP_IDX_UNKNOWN) ++ ucontrol->value.integer.value[i] = 0; ++ else ++ ucontrol->value.integer.value[i] = map[i]; ++ } ++ ++ return 0; ++} ++ ++ + static const struct snd_kcontrol_new hdmi_controls[] = { + { + .access = SNDRV_CTL_ELEM_ACCESS_READ | +@@ -184,6 +515,9 @@ static int hdmi_codec_startup(struct snd_pcm_substream *substream, + ret = snd_pcm_hw_constraint_eld(substream->runtime, + hcp->eld); + mutex_unlock(&hcp->eld_lock); ++ ++ /* Select chmap supported */ ++ hdmi_codec_eld_chmap(hcp); + } + return ret; + } +@@ -201,6 +535,7 @@ static void hdmi_codec_shutdown(struct snd_pcm_substream *substream, + + WARN_ON(hcp->current_stream != substream); + ++ hcp->chmap_idx = HDMI_CODEC_CHMAP_IDX_UNKNOWN; + hcp->hcd.ops->audio_shutdown(dai->dev->parent, hcp->hcd.data); + + mutex_lock(&hcp->current_stream_lock); +@@ -221,7 +556,7 @@ static int hdmi_codec_hw_params(struct snd_pcm_substream *substream, + .dig_subframe = { 0 }, + } + }; +- int ret; ++ int ret, idx; + + dev_dbg(dai->dev, "%s() width %d rate %d channels %d\n", __func__, + params_width(params), params_rate(params), +@@ -248,6 +583,17 @@ static int hdmi_codec_hw_params(struct snd_pcm_substream *substream, + hp.cea.sample_size = HDMI_AUDIO_SAMPLE_SIZE_STREAM; + hp.cea.sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_STREAM; + ++ /* Select a channel allocation that matches with ELD and pcm channels */ ++ idx = hdmi_codec_get_ch_alloc_table_idx(hcp, hp.cea.channels); ++ if (idx < 0) { ++ dev_err(dai->dev, "Not able to map channels to speakers (%d)\n", ++ idx); ++ hcp->chmap_idx = HDMI_CODEC_CHMAP_IDX_UNKNOWN; ++ return idx; ++ } ++ hp.cea.channel_allocation = hdmi_codec_channel_alloc[idx].ca_id; ++ hcp->chmap_idx = hdmi_codec_channel_alloc[idx].ca_id; ++ + hp.sample_width = params_width(params); + hp.sample_rate = params_rate(params); + hp.channels = params_channels(params); +@@ -377,6 +723,32 @@ static const struct snd_soc_dai_ops hdmi_dai_ops = { + SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE |\ + SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE) + ++static int hdmi_codec_pcm_new(struct snd_soc_pcm_runtime *rtd, ++ struct snd_soc_dai *dai) ++{ ++ struct snd_soc_dai_driver *drv = dai->driver; ++ struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai); ++ int ret; ++ ++ dev_dbg(dai->dev, "%s()\n", __func__); ++ ++ ret = snd_pcm_add_chmap_ctls(rtd->pcm, SNDRV_PCM_STREAM_PLAYBACK, ++ NULL, drv->playback.channels_max, 0, ++ &hcp->chmap_info); ++ if (ret < 0) ++ return ret; ++ ++ /* override handlers */ ++ hcp->chmap_info->private_data = hcp; ++ hcp->chmap_info->kctl->get = hdmi_codec_chmap_ctl_get; ++ ++ /* default chmap supported is stereo */ ++ hcp->chmap_info->chmap = hdmi_codec_stereo_chmaps; ++ hcp->chmap_idx = HDMI_CODEC_CHMAP_IDX_UNKNOWN; ++ ++ return 0; ++} ++ + static struct snd_soc_dai_driver hdmi_i2s_dai = { + .name = "i2s-hifi", + .id = DAI_ID_I2S, +@@ -389,6 +761,7 @@ static struct snd_soc_dai_driver hdmi_i2s_dai = { + .sig_bits = 24, + }, + .ops = &hdmi_dai_ops, ++ .pcm_new = hdmi_codec_pcm_new, + }; + + static const struct snd_soc_dai_driver hdmi_spdif_dai = { +@@ -402,6 +775,7 @@ static const struct snd_soc_dai_driver hdmi_spdif_dai = { + .formats = SPDIF_FORMATS, + }, + .ops = &hdmi_dai_ops, ++ .pcm_new = hdmi_codec_pcm_new, + }; + + static struct snd_soc_codec_driver hdmi_codec = { +@@ -534,6 +908,7 @@ static int hdmi_codec_remove(struct platform_device *pdev) + { + struct hdmi_codec_priv *hcp = platform_get_drvdata(pdev); + ++ kfree(hcp->chmap_info); + hdmi_unregister_notifier(&hcp->nb); + snd_soc_unregister_codec(&pdev->dev); + return 0; + +From 52c48ffd0956821dd3f1315b9ec3fd2a677b2b63 Mon Sep 17 00:00:00 2001 +From: Christophe Jaillet +Date: Thu, 15 Jun 2017 07:53:11 +0200 +Subject: [PATCH] UPSTREAM: ASoC: rockchip: Fix an error handling in + 'rockchip_i2s_probe' + +If this memory allocation fail, we must disable what has been enabled. +Do not return immediately but go thrue the error handling path instead. + +Also use 'devm_kmemdup' instead of 'devm_kzalloc+memcpy' to simplify code. + +Signed-off-by: Christophe JAILLET +Signed-off-by: Mark Brown +(cherry picked from commit c3a3d3c41b74b05267bab6173f2a8224a1443ba6) +--- + sound/soc/rockchip/rockchip_i2s.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/sound/soc/rockchip/rockchip_i2s.c b/sound/soc/rockchip/rockchip_i2s.c +index b359639c1038..02ff642499bf 100644 +--- a/sound/soc/rockchip/rockchip_i2s.c ++++ b/sound/soc/rockchip/rockchip_i2s.c +@@ -658,12 +658,13 @@ static int rockchip_i2s_probe(struct platform_device *pdev) + goto err_pm_disable; + } + +- soc_dai = devm_kzalloc(&pdev->dev, ++ soc_dai = devm_kmemdup(&pdev->dev, &rockchip_i2s_dai, + sizeof(*soc_dai), GFP_KERNEL); +- if (!soc_dai) +- return -ENOMEM; ++ if (!soc_dai) { ++ ret = -ENOMEM; ++ goto err_pm_disable; ++ } + +- memcpy(soc_dai, &rockchip_i2s_dai, sizeof(*soc_dai)); + if (!of_property_read_u32(node, "rockchip,playback-channels", &val)) { + if (val >= 2 && val <= 8) + soc_dai->playback.channels_max = val; + +From 7b9368e1f2d50d7ca5b07ea50240fd8f45d884fe Mon Sep 17 00:00:00 2001 +From: Markus Elfring +Date: Thu, 10 Aug 2017 18:38:09 +0200 +Subject: [PATCH] UPSTREAM: ASoC: rockchip: Delete an error message for a + failed memory allocation in rockchip_i2s_probe() + +Omit an extra message for a memory allocation failure in this function. + +This issue was detected by using the Coccinelle software. + +Link: http://events.linuxfoundation.org/sites/events/files/slides/LCJ16-Refactor_Strings-WSang_0.pdf +Signed-off-by: Markus Elfring +Signed-off-by: Mark Brown +(cherry picked from commit b48b2710913d583ff93c365413532e1a7cd60d84) +--- + sound/soc/rockchip/rockchip_i2s.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/sound/soc/rockchip/rockchip_i2s.c b/sound/soc/rockchip/rockchip_i2s.c +index 02ff642499bf..16ff8d5e0033 100644 +--- a/sound/soc/rockchip/rockchip_i2s.c ++++ b/sound/soc/rockchip/rockchip_i2s.c +@@ -594,10 +594,8 @@ static int rockchip_i2s_probe(struct platform_device *pdev) + int val; + + i2s = devm_kzalloc(&pdev->dev, sizeof(*i2s), GFP_KERNEL); +- if (!i2s) { +- dev_err(&pdev->dev, "Can't allocate rk_i2s_dev\n"); ++ if (!i2s) + return -ENOMEM; +- } + + i2s->dev = &pdev->dev; + + +From f217d206adafde4eb886ffbd5ecd7779c37438ef Mon Sep 17 00:00:00 2001 +From: John Keeping +Date: Thu, 14 Sep 2017 16:58:55 +0100 +Subject: [PATCH] UPSTREAM: ASoC: rockchip: i2s: fix unbalanced clk_disable + +mclk is enabled and disabled only in i2s_runtime_{resume,suspend}() and +we ensure that the device is runtime suspended before reaching this +clk_disable_unprepare() call, so it is wrong to call it again here. + +Signed-off-by: John Keeping +Signed-off-by: Mark Brown +(cherry picked from commit 32debfcd3ff0939c93238ddde03ffcc96cca5c60) +--- + sound/soc/rockchip/rockchip_i2s.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/sound/soc/rockchip/rockchip_i2s.c b/sound/soc/rockchip/rockchip_i2s.c +index 16ff8d5e0033..986ad2efc8e9 100644 +--- a/sound/soc/rockchip/rockchip_i2s.c ++++ b/sound/soc/rockchip/rockchip_i2s.c +@@ -727,7 +727,6 @@ static int rockchip_i2s_remove(struct platform_device *pdev) + if (!pm_runtime_status_suspended(&pdev->dev)) + i2s_runtime_suspend(&pdev->dev); + +- clk_disable_unprepare(i2s->mclk); + clk_disable_unprepare(i2s->hclk); + + return 0; + +From 8b1551df18617eba99d59f89724191954a7213a4 Mon Sep 17 00:00:00 2001 +From: Romain Perier +Date: Thu, 20 Apr 2017 14:34:34 +0530 +Subject: [PATCH] UPSTREAM: drm: dw-hdmi: gate audio clock from the I2S + enablement callbacks + +Currently, the audio sampler clock is enabled from dw_hdmi_setup() at +step E. and is kept enabled for later use. This clock should be enabled +and disabled along with the actual audio stream and not always on (that +is bad for PM). Furthermore, as described by the datasheet, the I2S +variant needs to gate/ungate the clock when the stream is +enabled/disabled. + +This commit adds a parameter to hdmi_audio_enable_clk() that controls +when the audio sample clock must be enabled or disabled. Then, it adds +the call to this function from dw_hdmi_i2s_audio_enable() and +dw_hdmi_i2s_audio_disable(). + +Reviewed-by: Neil Armstrong +Signed-off-by: Romain Perier +Link: http://patchwork.freedesktop.org/patch/msgid/20170414083113.4255-3-romain.perier@collabora.com +Signed-off-by: Archit Taneja +(cherry picked from commit 57fbc05585a9c841c910677228f1e3f8a3a62801) +--- + drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 24 +++++++++++++++++------- + 1 file changed, 17 insertions(+), 7 deletions(-) + +diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +index 8726498e9f73..17c182cb07b5 100644 +--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c ++++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +@@ -824,6 +824,15 @@ void dw_hdmi_set_sample_rate(struct dw_hdmi *hdmi, unsigned int rate) + } + EXPORT_SYMBOL_GPL(dw_hdmi_set_sample_rate); + ++static void hdmi_enable_audio_clk(struct dw_hdmi *hdmi, bool enable) ++{ ++ if (enable) ++ hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_AUDCLK_DISABLE; ++ else ++ hdmi->mc_clkdis |= HDMI_MC_CLKDIS_AUDCLK_DISABLE; ++ hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS); ++} ++ + static void dw_hdmi_ahb_audio_enable(struct dw_hdmi *hdmi) + { + hdmi_set_cts_n(hdmi, hdmi->audio_cts, hdmi->audio_n); +@@ -837,6 +846,12 @@ static void dw_hdmi_ahb_audio_disable(struct dw_hdmi *hdmi) + static void dw_hdmi_i2s_audio_enable(struct dw_hdmi *hdmi) + { + hdmi_set_cts_n(hdmi, hdmi->audio_cts, hdmi->audio_n); ++ hdmi_enable_audio_clk(hdmi, true); ++} ++ ++static void dw_hdmi_i2s_audio_disable(struct dw_hdmi *hdmi) ++{ ++ hdmi_enable_audio_clk(hdmi, false); + } + + void dw_hdmi_audio_enable(struct dw_hdmi *hdmi) +@@ -2149,12 +2164,6 @@ static void dw_hdmi_enable_video_path(struct dw_hdmi *hdmi) + HDMI_MC_FLOWCTRL); + } + +-static void hdmi_enable_audio_clk(struct dw_hdmi *hdmi) +-{ +- hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_AUDCLK_DISABLE; +- hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS); +-} +- + /* Workaround to clear the overflow condition */ + static void dw_hdmi_clear_overflow(struct dw_hdmi *hdmi) + { +@@ -2306,7 +2315,7 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode *mode) + + /* HDMI Initialization Step E - Configure audio */ + hdmi_clk_regenerator_update_pixel_clock(hdmi); +- hdmi_enable_audio_clk(hdmi); ++ hdmi_enable_audio_clk(hdmi, true); + } + + /* not for DVI mode */ +@@ -3742,6 +3751,7 @@ int dw_hdmi_bind(struct device *dev, struct device *master, + audio.read = hdmi_readb; + audio.mod = hdmi_modb; + hdmi->enable_audio = dw_hdmi_i2s_audio_enable; ++ hdmi->disable_audio = dw_hdmi_i2s_audio_disable; + + pdevinfo.name = "dw-hdmi-i2s-audio"; + pdevinfo.data = &audio; + +From 442b913082d21de7a8364344feb520946413da5b Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Mon, 7 Aug 2017 22:24:15 +0200 +Subject: [PATCH] drm: dw-hdmi-i2s: sync with upstream + +--- + drivers/gpu/drm/bridge/synopsys/dw-hdmi-audio.h | 1 - + drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c | 20 +++++++++++++------- + 2 files changed, 13 insertions(+), 8 deletions(-) + +diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-audio.h b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-audio.h +index 3930ba04977b..af7f39c85ba4 100644 +--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-audio.h ++++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-audio.h +@@ -14,7 +14,6 @@ struct dw_hdmi_audio_data { + + struct dw_hdmi_i2s_audio_data { + struct dw_hdmi *hdmi; +- struct platform_device *pdev; + + void (*write)(struct dw_hdmi *hdmi, u8 val, int offset); + u8 (*read)(struct dw_hdmi *hdmi, int offset); +diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c +index f1f62d8c1d16..5ff993a35ab6 100644 +--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c ++++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c +@@ -16,7 +16,8 @@ + + #define DRIVER_NAME "dw-hdmi-i2s-audio" + +-static inline void hdmi_write(struct dw_hdmi_i2s_audio_data *audio, u8 val, int offset) ++static inline void hdmi_write(struct dw_hdmi_i2s_audio_data *audio, ++ u8 val, int offset) + { + struct dw_hdmi *hdmi = audio->hdmi; + +@@ -220,6 +221,7 @@ static int snd_dw_hdmi_probe(struct platform_device *pdev) + struct dw_hdmi_i2s_audio_data *audio = pdev->dev.platform_data; + struct platform_device_info pdevinfo; + struct hdmi_codec_pdata pdata; ++ struct platform_device *platform; + + pdata.ops = &dw_hdmi_i2s_ops; + pdata.i2s = 1; +@@ -234,23 +236,27 @@ static int snd_dw_hdmi_probe(struct platform_device *pdev) + pdevinfo.size_data = sizeof(pdata); + pdevinfo.dma_mask = DMA_BIT_MASK(32); + +- audio->pdev = platform_device_register_full(&pdevinfo); +- return IS_ERR_OR_NULL(audio->pdev); ++ platform = platform_device_register_full(&pdevinfo); ++ if (IS_ERR(platform)) ++ return PTR_ERR(platform); ++ ++ dev_set_drvdata(&pdev->dev, platform); ++ ++ return 0; + } + + static int snd_dw_hdmi_remove(struct platform_device *pdev) + { +- struct dw_hdmi_i2s_audio_data *audio = pdev->dev.platform_data; ++ struct platform_device *platform = dev_get_drvdata(&pdev->dev); + +- if (!IS_ERR_OR_NULL(audio->pdev)) +- platform_device_unregister(audio->pdev); ++ platform_device_unregister(platform); + + return 0; + } + + static struct platform_driver snd_dw_hdmi_driver = { + .probe = snd_dw_hdmi_probe, +- .remove = snd_dw_hdmi_remove, ++ .remove = snd_dw_hdmi_remove, + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + +From 1d3de24bd61e0bfba1a9e042e040fa65346ccd9d Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 2 Apr 2017 11:33:39 +0200 +Subject: [PATCH] drm: dw-hdmi-i2s: implement get_eld + +--- + drivers/gpu/drm/bridge/synopsys/dw-hdmi-audio.h | 1 + + drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c | 12 ++++++++++++ + drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 1 + + 3 files changed, 14 insertions(+) + +diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-audio.h b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-audio.h +index af7f39c85ba4..c5ace7808fdf 100644 +--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-audio.h ++++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-audio.h +@@ -14,6 +14,7 @@ struct dw_hdmi_audio_data { + + struct dw_hdmi_i2s_audio_data { + struct dw_hdmi *hdmi; ++ u8 *eld; + + void (*write)(struct dw_hdmi *hdmi, u8 val, int offset); + u8 (*read)(struct dw_hdmi *hdmi, int offset); +diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c +index 5ff993a35ab6..e7312571e2cb 100644 +--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c ++++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c +@@ -11,6 +11,8 @@ + + #include + ++#include /* This is only to get MAX_ELD_BYTES */ ++ + #include "dw-hdmi.h" + #include "dw-hdmi-audio.h" + +@@ -211,9 +213,19 @@ static void dw_hdmi_i2s_audio_shutdown(struct device *dev, void *data) + hdmi_write(audio, HDMI_AUD_CONF0_SW_RESET, HDMI_AUD_CONF0); + } + ++static int dw_hdmi_i2s_get_eld(struct device *dev, void *data, u8 *buf, size_t len) ++{ ++ struct dw_hdmi_i2s_audio_data *audio = data; ++ ++ memcpy(buf, audio->eld, min(len, (size_t)MAX_ELD_BYTES)); ++ ++ return 0; ++} ++ + static struct hdmi_codec_ops dw_hdmi_i2s_ops = { + .hw_params = dw_hdmi_i2s_hw_params, + .audio_shutdown = dw_hdmi_i2s_audio_shutdown, ++ .get_eld = dw_hdmi_i2s_get_eld, + }; + + static int snd_dw_hdmi_probe(struct platform_device *pdev) +diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +index 17c182cb07b5..df1ea752ac3d 100644 +--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c ++++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +@@ -3750,6 +3750,7 @@ int dw_hdmi_bind(struct device *dev, struct device *master, + audio.write = hdmi_writeb; + audio.read = hdmi_readb; + audio.mod = hdmi_modb; ++ audio.eld = hdmi->connector.eld; + hdmi->enable_audio = dw_hdmi_i2s_audio_enable; + hdmi->disable_audio = dw_hdmi_i2s_audio_disable; + + +From 1e16f2f6b861a7273d922c9251665acec542eed9 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Mon, 17 Apr 2017 13:09:16 +0200 +Subject: [PATCH] drm: dw-hdmi-i2s: configure channel allocation + +--- + drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c +index e7312571e2cb..1d4570e3fbed 100644 +--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c ++++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c +@@ -188,7 +188,7 @@ static int dw_hdmi_i2s_hw_params(struct device *dev, void *data, + hdmi_write(audio, 0x00, HDMI_FC_AUDICONF1); + + /* Set Channel Allocation */ +- hdmi_write(audio, 0x00, HDMI_FC_AUDICONF2); ++ hdmi_write(audio, hparms->cea.channel_allocation, HDMI_FC_AUDICONF2); + + /* Set LFEPBLDOWN-MIX INH and LSV */ + hdmi_write(audio, 0x00, HDMI_FC_AUDICONF3); + +From 747742580e282f4374100909906f6957c997c4a3 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Mon, 14 Aug 2017 00:14:05 +0200 +Subject: [PATCH] ASoC: hdmi-codec: reorder channel map + +--- + sound/soc/codecs/hdmi-codec.c | 113 +++++++++++++++++++----------------------- + 1 file changed, 52 insertions(+), 61 deletions(-) + +diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c +index cb78d8971b41..b74659bc3bbc 100644 +--- a/sound/soc/codecs/hdmi-codec.c ++++ b/sound/soc/codecs/hdmi-codec.c +@@ -205,78 +205,69 @@ const struct snd_pcm_chmap_elem hdmi_codec_8ch_chmaps[] = { + */ + static const struct hdmi_codec_cea_spk_alloc hdmi_codec_channel_alloc[] = { + { .ca_id = 0x00, .n_ch = 2, +- .mask = FL | FR}, +- /* 2.1 */ +- { .ca_id = 0x01, .n_ch = 4, +- .mask = FL | FR | LFE}, +- /* Dolby Surround */ ++ .mask = FL | FR }, ++ { .ca_id = 0x03, .n_ch = 4, ++ .mask = FL | FR | LFE | FC }, + { .ca_id = 0x02, .n_ch = 4, + .mask = FL | FR | FC }, +- /* surround51 */ ++ { .ca_id = 0x01, .n_ch = 4, ++ .mask = FL | FR | LFE }, + { .ca_id = 0x0b, .n_ch = 6, +- .mask = FL | FR | LFE | FC | RL | RR}, +- /* surround40 */ +- { .ca_id = 0x08, .n_ch = 6, +- .mask = FL | FR | RL | RR }, +- /* surround41 */ +- { .ca_id = 0x09, .n_ch = 6, +- .mask = FL | FR | LFE | RL | RR }, +- /* surround50 */ ++ .mask = FL | FR | LFE | FC | RL | RR }, + { .ca_id = 0x0a, .n_ch = 6, + .mask = FL | FR | FC | RL | RR }, +- /* 6.1 */ +- { .ca_id = 0x0f, .n_ch = 8, +- .mask = FL | FR | LFE | FC | RL | RR | RC }, +- /* surround71 */ ++ { .ca_id = 0x09, .n_ch = 6, ++ .mask = FL | FR | LFE | RL | RR }, ++ { .ca_id = 0x08, .n_ch = 6, ++ .mask = FL | FR | RL | RR }, ++ { .ca_id = 0x07, .n_ch = 6, ++ .mask = FL | FR | LFE | FC | RC }, ++ { .ca_id = 0x06, .n_ch = 6, ++ .mask = FL | FR | FC | RC }, ++ { .ca_id = 0x05, .n_ch = 6, ++ .mask = FL | FR | LFE | RC }, ++ { .ca_id = 0x04, .n_ch = 6, ++ .mask = FL | FR | RC }, + { .ca_id = 0x13, .n_ch = 8, + .mask = FL | FR | LFE | FC | RL | RR | RLC | RRC }, +- /* others */ +- { .ca_id = 0x03, .n_ch = 8, +- .mask = FL | FR | LFE | FC }, +- { .ca_id = 0x04, .n_ch = 8, +- .mask = FL | FR | RC}, +- { .ca_id = 0x05, .n_ch = 8, +- .mask = FL | FR | LFE | RC }, +- { .ca_id = 0x06, .n_ch = 8, +- .mask = FL | FR | FC | RC }, +- { .ca_id = 0x07, .n_ch = 8, +- .mask = FL | FR | LFE | FC | RC }, +- { .ca_id = 0x0c, .n_ch = 8, +- .mask = FL | FR | RC | RL | RR }, +- { .ca_id = 0x0d, .n_ch = 8, +- .mask = FL | FR | LFE | RL | RR | RC }, +- { .ca_id = 0x0e, .n_ch = 8, +- .mask = FL | FR | FC | RL | RR | RC }, +- { .ca_id = 0x10, .n_ch = 8, +- .mask = FL | FR | RL | RR | RLC | RRC }, +- { .ca_id = 0x11, .n_ch = 8, +- .mask = FL | FR | LFE | RL | RR | RLC | RRC }, ++ { .ca_id = 0x1f, .n_ch = 8, ++ .mask = FL | FR | LFE | FC | RL | RR | FLC | FRC }, + { .ca_id = 0x12, .n_ch = 8, + .mask = FL | FR | FC | RL | RR | RLC | RRC }, +- { .ca_id = 0x14, .n_ch = 8, +- .mask = FL | FR | FLC | FRC }, +- { .ca_id = 0x15, .n_ch = 8, +- .mask = FL | FR | LFE | FLC | FRC }, +- { .ca_id = 0x16, .n_ch = 8, +- .mask = FL | FR | FC | FLC | FRC }, +- { .ca_id = 0x17, .n_ch = 8, +- .mask = FL | FR | LFE | FC | FLC | FRC }, +- { .ca_id = 0x18, .n_ch = 8, +- .mask = FL | FR | RC | FLC | FRC }, +- { .ca_id = 0x19, .n_ch = 8, +- .mask = FL | FR | LFE | RC | FLC | FRC }, +- { .ca_id = 0x1a, .n_ch = 8, +- .mask = FL | FR | RC | FC | FLC | FRC }, +- { .ca_id = 0x1b, .n_ch = 8, +- .mask = FL | FR | LFE | RC | FC | FLC | FRC }, +- { .ca_id = 0x1c, .n_ch = 8, +- .mask = FL | FR | RL | RR | FLC | FRC }, +- { .ca_id = 0x1d, .n_ch = 8, +- .mask = FL | FR | LFE | RL | RR | FLC | FRC }, + { .ca_id = 0x1e, .n_ch = 8, + .mask = FL | FR | FC | RL | RR | FLC | FRC }, +- { .ca_id = 0x1f, .n_ch = 8, +- .mask = FL | FR | LFE | FC | RL | RR | FLC | FRC }, ++ { .ca_id = 0x11, .n_ch = 8, ++ .mask = FL | FR | LFE | RL | RR | RLC | RRC }, ++ { .ca_id = 0x1d, .n_ch = 8, ++ .mask = FL | FR | LFE | RL | RR | FLC | FRC }, ++ { .ca_id = 0x10, .n_ch = 8, ++ .mask = FL | FR | RL | RR | RLC | RRC }, ++ { .ca_id = 0x1c, .n_ch = 8, ++ .mask = FL | FR | RL | RR | FLC | FRC }, ++ { .ca_id = 0x0f, .n_ch = 8, ++ .mask = FL | FR | LFE | FC | RL | RR | RC }, ++ { .ca_id = 0x1b, .n_ch = 8, ++ .mask = FL | FR | LFE | RC | FC | FLC | FRC }, ++ { .ca_id = 0x0e, .n_ch = 8, ++ .mask = FL | FR | FC | RL | RR | RC }, ++ { .ca_id = 0x1a, .n_ch = 8, ++ .mask = FL | FR | RC | FC | FLC | FRC }, ++ { .ca_id = 0x0d, .n_ch = 8, ++ .mask = FL | FR | LFE | RL | RR | RC }, ++ { .ca_id = 0x19, .n_ch = 8, ++ .mask = FL | FR | LFE | RC | FLC | FRC }, ++ { .ca_id = 0x0c, .n_ch = 8, ++ .mask = FL | FR | RC | RL | RR }, ++ { .ca_id = 0x18, .n_ch = 8, ++ .mask = FL | FR | RC | FLC | FRC }, ++ { .ca_id = 0x17, .n_ch = 8, ++ .mask = FL | FR | LFE | FC | FLC | FRC }, ++ { .ca_id = 0x16, .n_ch = 8, ++ .mask = FL | FR | FC | FLC | FRC }, ++ { .ca_id = 0x15, .n_ch = 8, ++ .mask = FL | FR | LFE | FLC | FRC }, ++ { .ca_id = 0x14, .n_ch = 8, ++ .mask = FL | FR | FLC | FRC }, + }; + + struct hdmi_codec_priv { + +From 1cdb1f115b4bc9781c90d01d914dd4bbac6d0977 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 27 Aug 2017 23:32:40 +0200 +Subject: [PATCH] ASoC: codecs: rk3328: limit to working rates + +--- + sound/soc/codecs/rk3328_codec.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/sound/soc/codecs/rk3328_codec.c b/sound/soc/codecs/rk3328_codec.c +index af1b7429b6d4..d0b4578ffa0e 100644 +--- a/sound/soc/codecs/rk3328_codec.c ++++ b/sound/soc/codecs/rk3328_codec.c +@@ -354,7 +354,12 @@ static struct snd_soc_dai_driver rk3328_dai[] = { + .stream_name = "HIFI Playback", + .channels_min = 1, + .channels_max = 2, +- .rates = SNDRV_PCM_RATE_8000_96000, ++ .rates = (SNDRV_PCM_RATE_8000 | ++ SNDRV_PCM_RATE_16000 | ++ SNDRV_PCM_RATE_32000 | ++ SNDRV_PCM_RATE_48000 | ++ SNDRV_PCM_RATE_64000 | ++ SNDRV_PCM_RATE_96000), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S20_3LE | + SNDRV_PCM_FMTBIT_S24_LE | +--- a/sound/soc/codecs/rk3228_codec.c ++++ b/sound/soc/codecs/rk3228_codec.c +@@ -352,7 +352,12 @@ + .stream_name = "HIFI Playback", + .channels_min = 1, + .channels_max = 2, +- .rates = SNDRV_PCM_RATE_8000_96000, ++ .rates = (SNDRV_PCM_RATE_8000 | ++ SNDRV_PCM_RATE_16000 | ++ SNDRV_PCM_RATE_32000 | ++ SNDRV_PCM_RATE_48000 | ++ SNDRV_PCM_RATE_64000 | ++ SNDRV_PCM_RATE_96000), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S20_3LE | + SNDRV_PCM_FMTBIT_S24_LE | +From 878d789ff5faa02f0da5e68126e2276124611eeb Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 8 Jul 2018 12:34:43 +0200 +Subject: [PATCH] drm: dw-hdmi: change audio config + +--- + drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c | 9 ++------- + drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 15 ++++++++++++--- + 2 files changed, 14 insertions(+), 10 deletions(-) + +diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c +index 1d4570e3fbed..d0904f6b7a82 100644 +--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c ++++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c +@@ -110,8 +110,7 @@ static int dw_hdmi_i2s_hw_params(struct device *dev, void *data, + HDMI_AUD_INT_FIFO_FULL_MSK, HDMI_AUD_INT); + hdmi_update_bits(audio, HDMI_AUD_CONF0_SW_RESET, + HDMI_AUD_CONF0_SW_RESET, HDMI_AUD_CONF0); +- hdmi_update_bits(audio, HDMI_MC_SWRSTZ_I2S_RESET_MSK, +- HDMI_MC_SWRSTZ_I2S_RESET_MSK, HDMI_MC_SWRSTZ); ++ hdmi_write(audio, (u8)~HDMI_MC_SWRSTZ_I2S_RESET_MSK, HDMI_MC_SWRSTZ); + + switch (hparms->mode) { + case NLPCM: +@@ -193,11 +192,6 @@ static int dw_hdmi_i2s_hw_params(struct device *dev, void *data, + /* Set LFEPBLDOWN-MIX INH and LSV */ + hdmi_write(audio, 0x00, HDMI_FC_AUDICONF3); + +- hdmi_update_bits(audio, HDMI_AUD_CONF0_SW_RESET, +- HDMI_AUD_CONF0_SW_RESET, HDMI_AUD_CONF0); +- hdmi_update_bits(audio, HDMI_MC_SWRSTZ_I2S_RESET_MSK, +- HDMI_MC_SWRSTZ_I2S_RESET_MSK, HDMI_MC_SWRSTZ); +- + dw_hdmi_audio_enable(hdmi); + + return 0; +diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +index df1ea752ac3d..4bf4ff0fd741 100644 +--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c ++++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +@@ -89,6 +89,7 @@ static const struct dw_hdmi_audio_tmds_n common_tmds_n_table[] = { + { .tmds = 71000000, .n_32k = 4096, .n_44k1 = 7056, .n_48k = 6144, }, + { .tmds = 72000000, .n_32k = 4096, .n_44k1 = 5635, .n_48k = 6144, }, + { .tmds = 73250000, .n_32k = 4096, .n_44k1 = 14112, .n_48k = 6144, }, ++ { .tmds = 74176000, .n_32k = 11648, .n_44k1 = 17836, .n_48k = 11648, }, + { .tmds = 74250000, .n_32k = 4096, .n_44k1 = 6272, .n_48k = 6144, }, + { .tmds = 75000000, .n_32k = 4096, .n_44k1 = 5880, .n_48k = 6144, }, + { .tmds = 78750000, .n_32k = 4096, .n_44k1 = 5600, .n_48k = 6144, }, +@@ -105,13 +106,16 @@ static const struct dw_hdmi_audio_tmds_n common_tmds_n_table[] = { + { .tmds = 119000000, .n_32k = 4096, .n_44k1 = 5544, .n_48k = 6144, }, + { .tmds = 135000000, .n_32k = 4096, .n_44k1 = 5488, .n_48k = 6144, }, + { .tmds = 146250000, .n_32k = 4096, .n_44k1 = 6272, .n_48k = 6144, }, +- { .tmds = 148500000, .n_32k = 4096, .n_44k1 = 5488, .n_48k = 6144, }, ++ { .tmds = 148352000, .n_32k = 11648, .n_44k1 = 8918, .n_48k = 5824, }, ++ { .tmds = 148500000, .n_32k = 4096, .n_44k1 = 6272, .n_48k = 6144, }, + { .tmds = 154000000, .n_32k = 4096, .n_44k1 = 5544, .n_48k = 6144, }, + { .tmds = 162000000, .n_32k = 4096, .n_44k1 = 5684, .n_48k = 6144, }, + + /* For 297 MHz+ HDMI spec have some other rule for setting N */ +- { .tmds = 297000000, .n_32k = 3073, .n_44k1 = 4704, .n_48k = 5120, }, +- { .tmds = 594000000, .n_32k = 3073, .n_44k1 = 9408, .n_48k = 10240, }, ++ { .tmds = 296703000, .n_32k = 5824, .n_44k1 = 4459, .n_48k = 5824, }, ++ { .tmds = 297000000, .n_32k = 3072, .n_44k1 = 4704, .n_48k = 5120, }, ++ { .tmds = 593407000, .n_32k = 5824, .n_44k1 = 8918, .n_48k = 5824, }, ++ { .tmds = 594000000, .n_32k = 3072, .n_44k1 = 9408, .n_48k = 6144, }, + + /* End of table */ + { .tmds = 0, .n_32k = 0, .n_44k1 = 0, .n_48k = 0, }, +@@ -831,6 +835,11 @@ static void hdmi_enable_audio_clk(struct dw_hdmi *hdmi, bool enable) + else + hdmi->mc_clkdis |= HDMI_MC_CLKDIS_AUDCLK_DISABLE; + hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS); ++ ++ if (enable) { ++ hdmi_set_cts_n(hdmi, 0, 0); ++ hdmi_set_cts_n(hdmi, hdmi->audio_cts, hdmi->audio_n); ++ } + } + + static void dw_hdmi_ahb_audio_enable(struct dw_hdmi *hdmi) + +From 6bf23972f26fde1abad52cd1a65d1223d51d47c2 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 8 Jul 2018 12:56:51 +0200 +Subject: [PATCH] WIP: drm: dw-hdmi: use Auto CTS mode + +--- + drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 52 ++++++++++++++++++------------- + 1 file changed, 31 insertions(+), 21 deletions(-) + +diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +index 4bf4ff0fd741..2583320f3289 100644 +--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c ++++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +@@ -643,14 +643,18 @@ static struct i2c_adapter *dw_hdmi_i2c_adapter(struct dw_hdmi *hdmi) + static void hdmi_set_cts_n(struct dw_hdmi *hdmi, unsigned int cts, + unsigned int n) + { +- /* Must be set/cleared first */ +- hdmi_modb(hdmi, 0, HDMI_AUD_CTS3_CTS_MANUAL, HDMI_AUD_CTS3); +- +- /* nshift factor = 0 */ +- hdmi_modb(hdmi, 0, HDMI_AUD_CTS3_N_SHIFT_MASK, HDMI_AUD_CTS3); +- +- hdmi_writeb(hdmi, ((cts >> 16) & HDMI_AUD_CTS3_AUDCTS19_16_MASK) | +- HDMI_AUD_CTS3_CTS_MANUAL, HDMI_AUD_CTS3); ++ /* Use Auto CTS mode with CTS is unknown */ ++ if (cts) { ++ /* Must be set/cleared first */ ++ hdmi_modb(hdmi, 0, HDMI_AUD_CTS3_CTS_MANUAL, HDMI_AUD_CTS3); ++ ++ /* nshift factor = 0 */ ++ hdmi_modb(hdmi, 0, HDMI_AUD_CTS3_N_SHIFT_MASK, HDMI_AUD_CTS3); ++ ++ hdmi_writeb(hdmi, ((cts >> 16) & HDMI_AUD_CTS3_AUDCTS19_16_MASK) | ++ HDMI_AUD_CTS3_CTS_MANUAL, HDMI_AUD_CTS3); ++ } else ++ hdmi_writeb(hdmi, 0, HDMI_AUD_CTS3); + hdmi_writeb(hdmi, (cts >> 8) & 0xff, HDMI_AUD_CTS2); + hdmi_writeb(hdmi, cts & 0xff, HDMI_AUD_CTS1); + +@@ -777,24 +781,30 @@ static void hdmi_set_clk_regenerator(struct dw_hdmi *hdmi, + { + unsigned long ftdms = pixel_clk; + unsigned int n, cts; ++ u8 config3; + u64 tmp; + + n = hdmi_find_n(hdmi, pixel_clk, sample_rate); + +- /* +- * Compute the CTS value from the N value. Note that CTS and N +- * can be up to 20 bits in total, so we need 64-bit math. Also +- * note that our TDMS clock is not fully accurate; it is accurate +- * to kHz. This can introduce an unnecessary remainder in the +- * calculation below, so we don't try to warn about that. +- */ +- tmp = (u64)ftdms * n; +- do_div(tmp, 128 * sample_rate); +- cts = tmp; ++ config3 = hdmi_readb(hdmi, HDMI_CONFIG3_ID); + +- dev_dbg(hdmi->dev, "%s: fs=%uHz ftdms=%lu.%03luMHz N=%d cts=%d\n", +- __func__, sample_rate, ftdms / 1000000, (ftdms / 1000) % 1000, +- n, cts); ++ if (config3 & HDMI_CONFIG3_AHBAUDDMA) { ++ /* ++ * Compute the CTS value from the N value. Note that CTS and N ++ * can be up to 20 bits in total, so we need 64-bit math. Also ++ * note that our TDMS clock is not fully accurate; it is accurate ++ * to kHz. This can introduce an unnecessary remainder in the ++ * calculation below, so we don't try to warn about that. ++ */ ++ tmp = (u64)ftdms * n; ++ do_div(tmp, 128 * sample_rate); ++ cts = tmp; ++ ++ dev_dbg(hdmi->dev, "%s: fs=%uHz ftdms=%lu.%03luMHz N=%d cts=%d\n", ++ __func__, sample_rate, ftdms / 1000000, (ftdms / 1000) % 1000, ++ n, cts); ++ } else ++ cts = 0; + + spin_lock_irq(&hdmi->audio_lock); + hdmi->audio_n = n; + diff --git a/patch/kernel/rk322x-legacy/01-linux-0005-dts.patch b/patch/kernel/rk322x-legacy/01-linux-0005-dts.patch new file mode 100644 index 0000000000..f32ba6a1e8 --- /dev/null +++ b/patch/kernel/rk322x-legacy/01-linux-0005-dts.patch @@ -0,0 +1,9064 @@ +From 65a89294e3434d03640530a5dda6314dd588f01f Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 1 Jul 2018 23:22:32 +0200 +Subject: [PATCH] arm: dts: rockchip: rk3288: update dtsi + +--- + arch/arm/boot/dts/rk3288.dtsi | 20 +++++++++++++++----- + 1 file changed, 15 insertions(+), 5 deletions(-) + +diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi +index 1b7602f25f34..9cca69f9f5ba 100644 +--- a/arch/arm/boot/dts/rk3288.dtsi ++++ b/arch/arm/boot/dts/rk3288.dtsi +@@ -352,49 +352,57 @@ + + sdmmc: dwmmc@ff0c0000 { + compatible = "rockchip,rk3288-dw-mshc"; +- clock-freq-min-max = <400000 150000000>; ++ max-frequency = <150000000>; + clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>, + <&cru SCLK_SDMMC_DRV>, <&cru SCLK_SDMMC_SAMPLE>; + clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; + fifo-depth = <0x100>; + interrupts = ; + reg = <0x0 0xff0c0000 0x0 0x4000>; ++ resets = <&cru SRST_MMC0>; ++ reset-names = "reset"; + status = "disabled"; + }; + + sdio0: dwmmc@ff0d0000 { + compatible = "rockchip,rk3288-dw-mshc"; +- clock-freq-min-max = <400000 150000000>; ++ max-frequency = <150000000>; + clocks = <&cru HCLK_SDIO0>, <&cru SCLK_SDIO0>, + <&cru SCLK_SDIO0_DRV>, <&cru SCLK_SDIO0_SAMPLE>; + clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; + fifo-depth = <0x100>; + interrupts = ; + reg = <0x0 0xff0d0000 0x0 0x4000>; ++ resets = <&cru SRST_SDIO0>; ++ reset-names = "reset"; + status = "disabled"; + }; + + sdio1: dwmmc@ff0e0000 { + compatible = "rockchip,rk3288-dw-mshc"; +- clock-freq-min-max = <400000 150000000>; ++ max-frequency = <150000000>; + clocks = <&cru HCLK_SDIO1>, <&cru SCLK_SDIO1>, + <&cru SCLK_SDIO1_DRV>, <&cru SCLK_SDIO1_SAMPLE>; + clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; + fifo-depth = <0x100>; + interrupts = ; + reg = <0x0 0xff0e0000 0x0 0x4000>; ++ resets = <&cru SRST_SDIO1>; ++ reset-names = "reset"; + status = "disabled"; + }; + + emmc: dwmmc@ff0f0000 { + compatible = "rockchip,rk3288-dw-mshc"; +- clock-freq-min-max = <400000 150000000>; ++ max-frequency = <150000000>; + clocks = <&cru HCLK_EMMC>, <&cru SCLK_EMMC>, + <&cru SCLK_EMMC_DRV>, <&cru SCLK_EMMC_SAMPLE>; + clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; + fifo-depth = <0x100>; + interrupts = ; + reg = <0x0 0xff0f0000 0x0 0x4000>; ++ resets = <&cru SRST_EMMC>; ++ reset-names = "reset"; + status = "disabled"; + supports-emmc; + }; +@@ -638,6 +646,7 @@ + compatible = "rockchip,rk3288-tsadc"; + reg = <0x0 0xff280000 0x0 0x100>; + interrupts = ; ++ rockchip,grf = <&grf>; + clocks = <&cru SCLK_TSADC>, <&cru PCLK_TSADC>; + clock-names = "tsadc", "apb_pclk"; + assigned-clocks = <&cru SCLK_TSADC>; +@@ -646,7 +655,7 @@ + reset-names = "tsadc-apb"; + pinctrl-names = "gpio", "otpout"; + pinctrl-0 = <&otp_gpio>; +- pinctrl-1 = <&otp_gpio>; ++ pinctrl-1 = <&otp_out>; + #thermal-sensor-cells = <1>; + rockchip,hw-tshut-temp = <120000>; + rockchip,hw-tshut-mode = <0>; /* tshut mode 0:CRU 1:GPIO */ +@@ -1699,6 +1708,7 @@ + operating-points-v2 = <&gpu_opp_table>; + #cooling-cells = <2>; /* min followed by max */ + power-domains = <&power RK3288_PD_GPU>; ++ power-off-delay-ms = <200>; + status = "disabled"; + + upthreshold = <75>; + +From 4cea1d3405885efca9c1d7e80b6eeb52e40d990f Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 13 Aug 2017 10:24:19 +0200 +Subject: [PATCH] arm: dts: rk3288-miniarm: update dts + +--- + arch/arm/boot/dts/rk3288-miniarm.dts | 64 +++++++++++++++++++++++++++++------- + 1 file changed, 53 insertions(+), 11 deletions(-) + +diff --git a/arch/arm/boot/dts/rk3288-miniarm.dts b/arch/arm/boot/dts/rk3288-miniarm.dts +index a5c5300797ab..eac9b1501878 100644 +--- a/arch/arm/boot/dts/rk3288-miniarm.dts ++++ b/arch/arm/boot/dts/rk3288-miniarm.dts +@@ -42,11 +42,22 @@ + #include + #include "rk3288.dtsi" + #include "rk3288-rkisp1.dtsi" +-#include "rk3288-linux.dtsi" ++#include "rk3288cg-opp.dtsi" + + / { ++ model = "ASUS Tinker Board"; + compatible = "rockchip,rk3288-miniarm", "rockchip,rk3288"; + ++ chosen { ++ bootargs = "earlyprintk=uart8250-32bit,0xff690000"; ++ }; ++ ++ cpuinfo { ++ compatible = "rockchip,cpuinfo"; ++ nvmem-cells = <&efuse_id>; ++ nvmem-cell-names = "id"; ++ }; ++ + memory { + device_type = "memory"; + reg = <0x0 0x0 0x0 0x80000000>; +@@ -67,7 +78,7 @@ + wireless-wlan { + compatible = "wlan-platdata"; + rockchip,grf = <&grf>; +- wifi_chip_type = "ap6212"; ++ wifi_chip_type = "rtl8723bs"; + sdio_vref = <1800>; + WIFI,host_wake_irq = <&gpio4 30 GPIO_ACTIVE_HIGH>; + status = "okay"; +@@ -129,16 +140,16 @@ + linux,default-trigger="mmc0"; + }; + +- led1-led { ++ heartbeat-led { + gpios=<&gpio1 25 GPIO_ACTIVE_HIGH>; +- linux,default-trigger="default-off"; ++ linux,default-trigger="heartbeat"; + }; + }; + + sound { + compatible = "simple-audio-card"; + simple-audio-card,format = "i2s"; +- simple-audio-card,name = "rockchip,miniarm-codec"; ++ simple-audio-card,name = "HDMI"; + simple-audio-card,mclk-fs = <512>; + simple-audio-card,cpu { + sound-dai = <&i2s>; +@@ -204,20 +215,34 @@ + cpu0-supply = <&vdd_cpu>; + }; + ++&emmc { ++ bus-width = <8>; ++ cap-mmc-highspeed; ++ disable-wp; ++ mmc-ddr-1_8v; ++ mmc-hs200-1_8v; ++ non-removable; ++ num-slots = <1>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_pwr &emmc_bus8>; ++ status = "okay"; ++}; ++ + &gmac { + phy-supply = <&vcc33_lan>; + phy-mode = "rgmii"; + clock_in_out = "input"; ++ snps,force_thresh_dma_mode; + snps,reset-gpio = <&gpio4 7 0>; + snps,reset-active-low; +- snps,reset-delays-us = <0 10000 1000000>; ++ snps,reset-delays-us = <0 10000 50000>; + assigned-clocks = <&cru SCLK_MAC>; + assigned-clock-parents = <&ext_gmac>; + pinctrl-names = "default"; + pinctrl-0 = <&rgmii_pins>; + tx_delay = <0x30>; + rx_delay = <0x10>; +- status = "ok"; ++ status = "okay"; + }; + + &dsi0 { +@@ -238,6 +263,11 @@ + #address-cells = <1>; + #size-cells = <0>; + #sound-dai-cells = <0>; ++ rockchip,phy-table = ++ <74250000 0x8009 0x0004 0x0272>, ++ <165000000 0x802b 0x0004 0x0209>, ++ <371250000 0x802d 0x0001 0x0149>, ++ <0 0x0000 0x0000 0x0000>; + status = "okay"; + /* Don't use vopl for HDMI */ + ports { +@@ -545,6 +575,15 @@ + + &i2s { + #sound-dai-cells = <0>; ++ rockchip,bclk-fs = <128>; ++ status = "okay"; ++}; ++ ++&iep { ++ status = "okay"; ++}; ++ ++&iep_mmu { + status = "okay"; + }; + +@@ -558,7 +597,7 @@ + &sdio0 { + status = "okay"; + clock-frequency = <50000000>; +- clock-freq-min-max = <200000 50000000>; ++ max-frequency = <50000000>; + bus-width = <4>; + cap-sd-highspeed; + cap-sdio-irq; +@@ -579,7 +618,7 @@ + + &saradc { + vref-supply = <&vcc18_ldo1>; +- status ="okay"; ++ status = "okay"; + }; + + &sdmmc { +@@ -604,7 +643,6 @@ + &tsadc { + rockchip,hw-tshut-mode = <1>; /* tshut mode 0:CRU 1:GPIO */ + rockchip,hw-tshut-polarity = <1>; /* tshut polarity 0:LOW 1:HIGH */ +- pinctrl-1 = <&otp_out>; + status = "okay"; + }; + +@@ -615,6 +653,8 @@ + }; + + &uart1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart1_xfer>, <&uart1_cts>, <&uart1_rts>; + status = "okay"; + }; + +@@ -627,6 +667,8 @@ + }; + + &uart4 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart4_xfer>, <&uart4_cts>, <&uart4_rts>; + status = "okay"; + }; + +@@ -644,7 +686,7 @@ + }; + + &usb_otg { +- status= "okay"; ++ status = "okay"; + }; + + &vopb { + +From 3da8fccb1f5b73ef313d320925e81bd1b5cacbfa Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Thu, 2 Nov 2017 23:17:46 +0100 +Subject: [PATCH] arm: dts: rk3288-miqi: update dts + +--- + arch/arm/boot/dts/rk3288-miqi.dts | 75 ++++++++++++++++++++++++++------------- + 1 file changed, 50 insertions(+), 25 deletions(-) + +diff --git a/arch/arm/boot/dts/rk3288-miqi.dts b/arch/arm/boot/dts/rk3288-miqi.dts +index a2862c6a17f1..9655365db416 100644 +--- a/arch/arm/boot/dts/rk3288-miqi.dts ++++ b/arch/arm/boot/dts/rk3288-miqi.dts +@@ -43,11 +43,22 @@ + /dts-v1/; + #include + #include "rk3288.dtsi" +-#include "rk3288-linux.dtsi" ++#include "rk3288cg-opp.dtsi" + + / { ++ model = "mqmaker MiQi"; + compatible = "rockchip,rk3288-miqi", "rockchip,rk3288"; + ++ chosen { ++ bootargs = "earlyprintk=uart8250-32bit,0xff690000"; ++ }; ++ ++ cpuinfo { ++ compatible = "rockchip,cpuinfo"; ++ nvmem-cells = <&efuse_id>; ++ nvmem-cell-names = "id"; ++ }; ++ + memory { + device_type = "memory"; + reg = <0x0 0x0 0x0 0x80000000>; +@@ -56,29 +67,14 @@ + sound { + compatible = "simple-audio-card"; + simple-audio-card,format = "i2s"; +- simple-audio-card,name = "DW-HDMI"; ++ simple-audio-card,name = "HDMI"; + simple-audio-card,mclk-fs = <512>; +- +- simple-audio-card,dai-link@0 { /* I2S - S/PDIF */ +- format = "i2s"; +- cpu { +- sound-dai = <&i2s>; +- }; +- codec { +- sound-dai = <&hdmi>; +- }; ++ simple-audio-card,cpu { ++ sound-dai = <&i2s>; ++ }; ++ simple-audio-card,codec { ++ sound-dai = <&hdmi>; + }; +- +- /* +- * If you want to support more cards, +- * you can add more dai-link node, +- * such as +- * +- * simple-audio-card,dai-link@1 { +- * ...... +- * } +- */ +- + }; + + ext_gmac: external-gmac-clock { +@@ -204,6 +200,12 @@ + #size-cells = <0>; + #sound-dai-cells = <0>; + status = "okay"; ++ /* Don't use vopl for HDMI */ ++ ports { ++ hdmi_in: port { ++ /delete-node/ endpoint@1; ++ }; ++ }; + }; + + &hevc_service { +@@ -235,14 +237,14 @@ + clock_in_out = "input"; + snps,reset-gpio = <&gpio4 7 0>; + snps,reset-active-low; +- snps,reset-delays-us = <0 10000 1000000>; ++ snps,reset-delays-us = <0 10000 50000>; + assigned-clocks = <&cru SCLK_MAC>; + assigned-clock-parents = <&ext_gmac>; + pinctrl-names = "default"; + pinctrl-0 = <&rgmii_pins>; + tx_delay = <0x30>; + rx_delay = <0x10>; +- status = "ok"; ++ status = "okay"; + }; + + /* ---------------------------------------------------------------------------------- +@@ -414,6 +416,15 @@ I2C + + &i2s { + #sound-dai-cells = <0>; ++ rockchip,bclk-fs = <128>; ++ status = "okay"; ++}; ++ ++&iep { ++ status = "okay"; ++}; ++ ++&iep_mmu { + status = "okay"; + }; + +@@ -439,6 +450,17 @@ I2C + status = "okay"; + }; + ++&saradc { ++ vref-supply = <&vcc_18>; ++ status = "okay"; ++}; ++ ++&tsadc { ++ rockchip,hw-tshut-mode = <0>; ++ rockchip,hw-tshut-polarity = <0>; ++ status = "okay"; ++}; ++ + &uart3 { + status = "okay"; + }; +@@ -472,6 +494,10 @@ I2C + + &vopl { + status = "okay"; ++ /* Don't use vopl for HDMI */ ++ vopl_out: port { ++ /delete-node/ endpoint@0; ++ }; + }; + + &vopl_mmu { +@@ -546,4 +572,3 @@ I2C + }; + + }; +- + +From 49c65a7f1c91517d56efdbe72a046b64b687664c Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Wed, 17 Jan 2018 22:17:45 +0100 +Subject: [PATCH] arm64: dts: rockchip: rk3328: update dtsi + +--- + arch/arm64/boot/dts/rockchip/rk3328.dtsi | 68 ++++++++++++++++++++++++++------ + 1 file changed, 56 insertions(+), 12 deletions(-) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi +index 0d2251c903b1..b7b6f9304706 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi +@@ -88,6 +88,8 @@ + device_type = "cpu"; + compatible = "arm,cortex-a53", "arm,armv8"; + reg = <0x0 0x1>; ++ clocks = <&cru ARMCLK>; ++ dynamic-power-coefficient = <120>; + enable-method = "psci"; + operating-points-v2 = <&cpu0_opp_table>; + }; +@@ -95,6 +97,8 @@ + device_type = "cpu"; + compatible = "arm,cortex-a53", "arm,armv8"; + reg = <0x0 0x2>; ++ clocks = <&cru ARMCLK>; ++ dynamic-power-coefficient = <120>; + enable-method = "psci"; + operating-points-v2 = <&cpu0_opp_table>; + }; +@@ -102,6 +106,8 @@ + device_type = "cpu"; + compatible = "arm,cortex-a53", "arm,armv8"; + reg = <0x0 0x3>; ++ clocks = <&cru ARMCLK>; ++ dynamic-power-coefficient = <120>; + enable-method = "psci"; + operating-points-v2 = <&cpu0_opp_table>; + }; +@@ -161,6 +167,22 @@ + opp-microvolt-L1 = <1300000 1300000 1350000>; + clock-latency-ns = <40000>; + }; ++ /* ++ opp-1392000000 { ++ opp-hz = /bits/ 64 <1392000000>; ++ opp-microvolt = <1350000 1350000 1350000>; ++ opp-microvolt-L0 = <1350000 1350000 1350000>; ++ opp-microvolt-L1 = <1325000 1325000 1350000>; ++ clock-latency-ns = <40000>; ++ }; ++ opp-1512000000 { ++ opp-hz = /bits/ 64 <1512000000>; ++ opp-microvolt = <1350000 1350000 1350000>; ++ opp-microvolt-L0 = <1350000 1350000 1350000>; ++ opp-microvolt-L1 = <1325000 1325000 1350000>; ++ clock-latency-ns = <40000>; ++ }; ++ */ + }; + + arm-pmu { +@@ -438,6 +460,7 @@ + reg-shift = <2>; + reg-io-width = <4>; + dmas = <&dmac 2>, <&dmac 3>; ++ dma-names = "tx", "rx"; + pinctrl-names = "default"; + pinctrl-0 = <&uart0_xfer &uart0_cts &uart0_rts>; + status = "disabled"; +@@ -452,6 +475,7 @@ + reg-shift = <2>; + reg-io-width = <4>; + dmas = <&dmac 4>, <&dmac 5>; ++ dma-names = "tx", "rx"; + pinctrl-names = "default"; + pinctrl-0 = <&uart1_xfer &uart1_cts &uart1_rts>; + status = "disabled"; +@@ -466,6 +490,7 @@ + reg-shift = <2>; + reg-io-width = <4>; + dmas = <&dmac 6>, <&dmac 7>; ++ dma-names = "tx", "rx"; + pinctrl-names = "default"; + pinctrl-0 = <&uart2m1_xfer>; + status = "disabled"; +@@ -704,9 +729,9 @@ + }; + opp-300000000 { + opp-hz = /bits/ 64 <300000000>; +- opp-microvolt = <975000>; +- opp-microvolt-L0 = <975000>; +- opp-microvolt-L1 = <950000>; ++ opp-microvolt = <1050000>; ++ opp-microvolt-L0 = <1050000>; ++ opp-microvolt-L1 = <1025000>; + }; + opp-400000000 { + opp-hz = /bits/ 64 <400000000>; +@@ -720,6 +745,14 @@ + opp-microvolt-L0 = <1150000>; + opp-microvolt-L1 = <1100000>; + }; ++ /* ++ opp-600000000 { ++ opp-hz = /bits/ 64 <600000000>; ++ opp-microvolt = <1150000>; ++ opp-microvolt-L0 = <1150000>; ++ opp-microvolt-L1 = <1125000>; ++ }; ++ */ + }; + + vdpu: vpu_service@ff350000 { +@@ -843,7 +876,7 @@ + interrupts = ; + interrupt-names = "rkvdec_mmu"; + clocks = <&cru ACLK_RKVDEC>, <&cru HCLK_RKVDEC>; +- clock-names = "aclk_vcodec", "hclk_vcodec"; ++ clock-names = "aclk", "hclk"; + power-domains = <&power RK3328_PD_VIDEO>; + #iommu-cells = <0>; + }; +@@ -921,6 +954,8 @@ + vop: vop@ff370000 { + compatible = "rockchip,rk3328-vop"; + reg = <0x0 0xff370000 0x0 0x3efc>; ++ reg-names = "regs", "gamma_lut"; ++ rockchip,grf = <&grf>; + interrupts = ; + clocks = <&cru ACLK_VOP>, <&cru DCLK_LCDC>, <&cru HCLK_VOP>; + clock-names = "aclk_vop", "dclk_vop", "hclk_vop"; +@@ -1275,6 +1316,7 @@ + "pclk_mac"; + resets = <&cru SRST_GMAC2IO_A>; + reset-names = "stmmaceth"; ++ snps,force_thresh_dma_mode; + status = "disabled"; + }; + +@@ -1345,12 +1387,14 @@ + sdmmc_ext: dwmmc@ff5f0000 { + compatible = "rockchip,rk3328-dw-mshc", "rockchip,rk3288-dw-mshc"; + reg = <0x0 0xff5f0000 0x0 0x4000>; +- clock-freq-min-max = <400000 150000000>; ++ max-frequency = <150000000>; + clocks = <&cru HCLK_SDMMC_EXT>, <&cru SCLK_SDMMC_EXT>, + <&cru SCLK_SDMMC_EXT_DRV>, <&cru SCLK_SDMMC_EXT_SAMPLE>; +- clock-names = "biu", "ciu", "ciu-drv", "ciu-sample"; ++ clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; + fifo-depth = <0x100>; + interrupts = ; ++ resets = <&cru SRST_SDMMCEXT>; ++ reset-names = "reset"; + status = "disabled"; + }; + + +From bffef35a0fe1b0cd133c32569b448575ae422be5 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Wed, 17 Jan 2018 22:17:45 +0100 +Subject: [PATCH] arm64: dts: rockchip: rk3328-rock64: update dts + +--- + arch/arm64/boot/dts/rockchip/rk3328-rock64.dts | 262 ++++++++++++++++--------- + 1 file changed, 168 insertions(+), 94 deletions(-) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts +index 4b2eef609601..ff90c5379671 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts +@@ -48,20 +48,15 @@ + compatible = "pine64,rock64", "rockchip,rk3328"; + + chosen { +- bootargs = "rockchip_jtag earlycon=uart8250-32bit,0xff130000 swiotlb=1 kpti=0 coherent_pool=1m"; ++ bootargs = "earlycon=uart8250-32bit,0xff130000 swiotlb=1 kpti=0 coherent_pool=1m"; + stdout-path = "serial2:1500000n8"; + }; + +- fiq-debugger { +- compatible = "rockchip,fiq-debugger"; +- rockchip,serial-id = <2>; +- rockchip,signal-irq = <159>; +- rockchip,wake-irq = <0>; +- /* If enable uart uses irq instead of fiq */ +- rockchip,irq-mode-enable = <0>; +- rockchip,baudrate = <1500000>; /* Only 115200 and 1500000 */ +- interrupts = ; +- status = "okay"; ++ xin32k: xin32k { ++ compatible = "fixed-clock"; ++ clock-frequency = <32768>; ++ clock-output-names = "xin32k"; ++ #clock-cells = <0>; + }; + + gmac_clkin: external-gmac-clock { +@@ -71,67 +66,86 @@ + #clock-cells = <0>; + }; + ++ vcc_phy: vcc-phy-regulator { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc_phy"; ++ regulator-always-on; ++ regulator-boot-on; ++ }; ++ ++ vcc_sys: vcc-sys { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc_sys"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ }; ++ + vcc_sd: sdmmc-regulator { + compatible = "regulator-fixed"; +- gpio = <&gpio0 30 GPIO_ACTIVE_LOW>; ++ gpio = <&gpio0 RK_PD6 GPIO_ACTIVE_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc0m1_gpio>; + regulator-name = "vcc_sd"; ++ regulator-always-on; ++ regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vcc_io>; + }; + +- vcc_host_5v: vcc-host-5v-regulator { ++ vcc_host_5v: vcc_otg_5v: vcc-host-5v-regulator { + compatible = "regulator-fixed"; +- enable-active-high; +- gpio = <&gpio0 0 GPIO_ACTIVE_HIGH>; ++ gpio = <&gpio0 RK_PA2 GPIO_ACTIVE_LOW>; + pinctrl-names = "default"; +- pinctrl-0 = <&usb30_host_drv>; ++ pinctrl-0 = <&usb_host_drv>; + regulator-name = "vcc_host_5v"; +- regulator-always-on; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; + vin-supply = <&vcc_sys>; + }; + +- vcc_host1_5v: vcc_otg_5v: vcc-host1-5v-regulator { +- compatible = "regulator-fixed"; +- enable-active-high; +- gpio = <&gpio0 27 GPIO_ACTIVE_HIGH>; +- pinctrl-names = "default"; +- pinctrl-0 = <&usb20_host_drv>; +- regulator-name = "vcc_host1_5v"; +- regulator-always-on; +- vin-supply = <&vcc_sys>; +- }; ++ leds { ++ compatible = "gpio-leds"; + +- vcc_sys: vcc-sys { +- compatible = "regulator-fixed"; +- regulator-name = "vcc_sys"; +- regulator-always-on; +- regulator-boot-on; +- regulator-min-microvolt = <5000000>; +- regulator-max-microvolt = <5000000>; +- }; ++ standby-led { ++ gpios = <&rk805 0 GPIO_ACTIVE_LOW>; ++ linux,default-trigger = "heartbeat"; ++ }; + +- xin32k: xin32k { +- compatible = "fixed-clock"; +- clock-frequency = <32768>; +- clock-output-names = "xin32k"; +- #clock-cells = <0>; ++ power-led { ++ gpios = <&rk805 1 GPIO_ACTIVE_LOW>; ++ linux,default-trigger = "mmc0"; ++ }; + }; + + ir-receiver { + compatible = "gpio-ir-receiver"; ++ gpios = <&gpio2 RK_PA2 GPIO_ACTIVE_LOW>; ++ linux,rc-map-name = "rc-pine64"; + pinctrl-0 = <&ir_int>; + pinctrl-names = "default"; +- status = "okay"; ++ }; ++ ++ hdmi-sound { ++ compatible = "simple-audio-card"; ++ simple-audio-card,format = "i2s"; ++ simple-audio-card,mclk-fs = <128>; ++ simple-audio-card,name = "HDMI"; ++ simple-audio-card,cpu { ++ sound-dai = <&i2s0>; ++ }; ++ simple-audio-card,codec { ++ sound-dai = <&hdmi>; ++ }; + }; + + sound { + compatible = "simple-audio-card"; + simple-audio-card,format = "i2s"; + simple-audio-card,mclk-fs = <256>; +- simple-audio-card,name = "rockchip,rk3328"; ++ simple-audio-card,name = "I2S"; + simple-audio-card,cpu { + sound-dai = <&i2s1>; + }; +@@ -140,18 +154,21 @@ + }; + }; + +- hdmi-sound { ++ spdif-sound { + compatible = "simple-audio-card"; +- simple-audio-card,format = "i2s"; +- simple-audio-card,mclk-fs = <128>; +- simple-audio-card,name = "rockchip,hdmi"; ++ simple-audio-card,name = "SPDIF"; + simple-audio-card,cpu { +- sound-dai = <&i2s0>; ++ sound-dai = <&spdif>; + }; + simple-audio-card,codec { +- sound-dai = <&hdmi>; ++ sound-dai = <&spdif_out>; + }; + }; ++ ++ spdif_out: spdif-out { ++ compatible = "linux,spdif-dit"; ++ #sound-dai-cells = <0>; ++ }; + }; + + &codec { +@@ -175,6 +192,15 @@ + cpu-supply = <&vdd_arm>; + }; + ++&dfi { ++ status = "okay"; ++}; ++ ++&dmc { ++ center-supply = <&vdd_logic>; ++ status = "okay"; ++}; ++ + &display_subsystem { + status = "okay"; + }; +@@ -184,30 +210,40 @@ + cap-mmc-highspeed; + mmc-hs200-1_8v; + non-removable; +- supports-emmc; + pinctrl-names = "default"; + pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>; ++ supports-emmc; + vmmc-supply = <&vcc_io>; + vqmmc-supply = <&vcc18_emmc>; + status = "okay"; + }; + + &gmac2io { +- phy-supply = <&vcc_io>; +- phy-mode = "rgmii"; + assigned-clocks = <&cru SCLK_MAC2IO>, <&cru SCLK_MAC2IO_EXT>; + assigned-clock-parents = <&gmac_clkin>, <&gmac_clkin>; + clock_in_out = "input"; +- snps,reset-gpio = <&gpio1 18 GPIO_ACTIVE_LOW>; +- snps,reset-active-low; +- snps,reset-delays-us = <0 10000 50000>; ++ phy-supply = <&vcc_phy>; ++ phy-mode = "rgmii"; + pinctrl-names = "default"; + pinctrl-0 = <&rgmiim1_pins>; +- tx_delay = <0x26>; +- rx_delay = <0x11>; ++ snps,reset-gpio = <&gpio1 RK_PC2 GPIO_ACTIVE_LOW>; ++ snps,reset-active-low; ++ snps,reset-delays-us = <0 10000 50000>; ++ tx_delay = <0x24>; ++ rx_delay = <0x18>; + status = "okay"; + }; + ++&gmac2phy { ++ phy-supply = <&vcc_phy>; ++ assigned-clocks = <&cru SCLK_MAC2PHY_SRC>; ++ assigned-clock-rate = <50000000>; ++ assigned-clocks = <&cru SCLK_MAC2PHY>; ++ assigned-clock-parents = <&cru SCLK_MAC2PHY_SRC>; ++ clock_in_out = "output"; ++ status = "disabled"; ++}; ++ + &gpu { + status = "okay"; + mali-supply = <&vdd_logic>; +@@ -223,6 +259,8 @@ + + &hdmi { + #sound-dai-cells = <0>; ++ ddc-i2c-scl-high-time-ns = <9625>; ++ ddc-i2c-scl-low-time-ns = <10000>; + status = "okay"; + }; + +@@ -239,14 +277,14 @@ + reg = <0x18>; + interrupt-parent = <&gpio2>; + interrupts = <6 IRQ_TYPE_LEVEL_LOW>; ++ #clock-cells = <1>; ++ clock-output-names = "rk805-clkout1", "rk805-clkout2"; + pinctrl-names = "default"; + pinctrl-0 = <&pmic_int_l>; + rockchip,system-power-controller; + wakeup-source; + gpio-controller; +- clock-output-names = "rk805-clkout1", "rk805-clkout2"; + #gpio-cells = <2>; +- #clock-cells = <1>; + + vcc1-supply = <&vcc_sys>; + vcc2-supply = <&vcc_sys>; +@@ -256,11 +294,11 @@ + vcc6-supply = <&vcc_sys>; + + rtc { +- status = "disabled"; ++ status = "okay"; + }; + + pwrkey { +- status = "disabled"; ++ status = "okay"; + }; + + gpio { +@@ -280,8 +318,8 @@ + regulator-max-microvolt = <1450000>; + regulator-initial-mode = <0x1>; + regulator-ramp-delay = <12500>; +- regulator-boot-on; + regulator-always-on; ++ regulator-boot-on; + regulator-state-mem { + regulator-mode = <0x2>; + regulator-on-in-suspend; +@@ -292,12 +330,13 @@ + vdd_arm: RK805_DCDC2 { + regulator-compatible = "RK805_DCDC2"; + regulator-name = "vdd_arm"; ++ regulator-init-microvolt = <1225000>; + regulator-min-microvolt = <712500>; + regulator-max-microvolt = <1450000>; + regulator-initial-mode = <0x1>; + regulator-ramp-delay = <12500>; +- regulator-boot-on; + regulator-always-on; ++ regulator-boot-on; + regulator-state-mem { + regulator-mode = <0x2>; + regulator-on-in-suspend; +@@ -309,8 +348,8 @@ + regulator-compatible = "RK805_DCDC3"; + regulator-name = "vcc_ddr"; + regulator-initial-mode = <0x1>; +- regulator-boot-on; + regulator-always-on; ++ regulator-boot-on; + regulator-state-mem { + regulator-mode = <0x2>; + regulator-on-in-suspend; +@@ -323,8 +362,8 @@ + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-initial-mode = <0x1>; +- regulator-boot-on; + regulator-always-on; ++ regulator-boot-on; + regulator-state-mem { + regulator-mode = <0x2>; + regulator-on-in-suspend; +@@ -332,13 +371,13 @@ + }; + }; + +- vdd_18: RK805_LDO1 { ++ vcc_18: RK805_LDO1 { + regulator-compatible = "RK805_LDO1"; +- regulator-name = "vdd_18"; ++ regulator-name = "vcc_18"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; +- regulator-boot-on; + regulator-always-on; ++ regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; +@@ -350,8 +389,8 @@ + regulator-name = "vcc18_emmc"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; +- regulator-boot-on; + regulator-always-on; ++ regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; +@@ -363,8 +402,8 @@ + regulator-name = "vdd_10"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; +- regulator-boot-on; + regulator-always-on; ++ regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1000000>; +@@ -381,17 +420,35 @@ + }; + + &i2s1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2s1_mclk ++ &i2s1_sclk ++ &i2s1_lrcktx ++ &i2s1_lrckrx ++ &i2s1_sdo ++ &i2s1_sdi ++ &i2s1_sdio1 ++ &i2s1_sdio2 ++ &i2s1_sdio3>; + #sound-dai-cells = <0>; + status = "okay"; + }; + ++&iep { ++ status = "okay"; ++}; ++ ++&iep_mmu { ++ status = "okay"; ++}; ++ + &io_domains { + status = "okay"; + + vccio1-supply = <&vcc_io>; + vccio2-supply = <&vcc18_emmc>; + vccio3-supply = <&vcc_io>; +- vccio4-supply = <&vdd_18>; ++ vccio4-supply = <&vcc_18>; + vccio5-supply = <&vcc_io>; + vccio6-supply = <&vcc_io>; + pmuio-supply = <&vcc_io>; +@@ -400,37 +457,26 @@ + &pinctrl { + ir { + ir_int: ir-int { +- rockchip,pins = <2 2 RK_FUNC_GPIO &pcfg_pull_none>; ++ rockchip,pins = <2 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + pmic { + pmic_int_l: pmic-int-l { +- rockchip,pins = <2 6 RK_FUNC_GPIO &pcfg_pull_up>; ++ rockchip,pins = <2 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + +- sdio-pwrseq { +- wifi_enable_h: wifi-enable-h { +- rockchip,pins = <1 18 RK_FUNC_GPIO &pcfg_pull_none>; +- }; +- }; +- +- usb2 { +- usb20_host_drv: usb20-host-drv { +- rockchip,pins = <0 27 RK_FUNC_GPIO &pcfg_pull_none>; +- }; +- }; +- +- usb3 { +- usb30_host_drv: usb30-host-drv { +- rockchip,pins = <0 0 RK_FUNC_GPIO &pcfg_pull_none>; ++ usb { ++ usb_host_drv: usb-host-drv { ++ rockchip,pins = <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + }; + + &rkvdec { + status = "okay"; ++ vcodec-supply = <&vdd_logic>; + }; + + &rkvdec_mmu { +@@ -442,11 +488,17 @@ + cap-mmc-highspeed; + cap-sd-highspeed; + disable-wp; +- max-frequency = <150000000>; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc0_clk &sdmmc0_cmd &sdmmc0_dectn &sdmmc0_bus4>; +- vmmc-supply = <&vcc_sd>; + supports-sd; ++ vmmc-supply = <&vcc_sd>; ++ status = "okay"; ++}; ++ ++&spdif { ++ #sound-dai-cells = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spdifm0_tx>; + status = "okay"; + }; + +@@ -454,19 +506,43 @@ + status = "okay"; + + flash@0 { +- compatible = "gigadevice,gd25q128", "jedec,spi-nor"; ++ compatible = "jedec,spi-nor"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0>; + m25p,fast-read; + /* The max SCLK of the flash 104/80 MHZ */ + spi-max-frequency = <50000000>; ++ ++ partitions { ++ compatible = "fixed-partitions"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ loader@8000 { ++ label = "loader"; ++ reg = <0x8000 0x3F0000>; ++ }; ++ }; + }; + }; + ++&threshold { ++ temperature = <80000>; /* millicelsius */ ++}; ++ ++&target { ++ temperature = <95000>; /* millicelsius */ ++}; ++ ++&soc_crit { ++ temperature = <100000>; /* millicelsius */ ++}; ++ + &tsadc { + rockchip,hw-tshut-mode = <0>; + rockchip,hw-tshut-polarity = <0>; ++ rockchip,hw-tshut-temp = <110000>; + status = "okay"; + }; + +@@ -476,21 +552,19 @@ + + &u2phy { + status = "okay"; +- + }; + + &u2phy_host { +- phy-supply = <&vcc_host1_5v>; + status = "okay"; + }; + + &u2phy_otg { +- phy-supply = <&vcc_otg_5v>; ++ vbus-supply = <&vcc_otg_5v>; + status = "okay"; + }; + + &u3phy { +- phy-supply = <&vcc_host_5v>; ++ vbus-supply = <&vcc_host_5v>; + status = "okay"; + }; + + +From ed7848e24407cd2a65e524c46ba8fbb92db2bdc5 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Wed, 17 Jan 2018 22:17:45 +0100 +Subject: [PATCH] arm64: dts: rockchip: add rk3328-box board + +--- + arch/arm64/boot/dts/rockchip/rk3328-box.dts | 648 ++++++++++++++++++++++++++++ + 1 file changed, 648 insertions(+) + create mode 100644 arch/arm64/boot/dts/rockchip/rk3328-box.dts + +diff --git a/arch/arm64/boot/dts/rockchip/rk3328-box.dts b/arch/arm64/boot/dts/rockchip/rk3328-box.dts +new file mode 100644 +index 000000000000..eae652d55208 +--- /dev/null ++++ b/arch/arm64/boot/dts/rockchip/rk3328-box.dts +@@ -0,0 +1,648 @@ ++/* ++ * Copyright (c) 2017 Fuzhou Rockchip Electronics Co., Ltd ++ * ++ * This file is dual-licensed: you can use it either under the terms ++ * of the GPL or the X11 license, at your option. Note that this dual ++ * licensing only applies to this file, and not this project as a ++ * whole. ++ * ++ * a) This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation; either version 2 of the ++ * License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * Or, alternatively, ++ * ++ * b) Permission is hereby granted, free of charge, to any person ++ * obtaining a copy of this software and associated documentation ++ * files (the "Software"), to deal in the Software without ++ * restriction, including without limitation the rights to use, ++ * copy, modify, merge, publish, distribute, sublicense, and/or ++ * sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following ++ * conditions: ++ * ++ * The above copyright notice and this permission notice shall be ++ * included in all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES ++ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ++ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT ++ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, ++ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING ++ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ++ * OTHER DEALINGS IN THE SOFTWARE. ++ */ ++ ++/dts-v1/; ++#include "rk3328.dtsi" ++ ++/ { ++ model = "Rockchip RK3328 BOX"; ++ compatible = "rockchip,rk3328-box", "rockchip,rk3328"; ++ ++ chosen { ++ bootargs = "earlyprintk=uart8250-32bit,0xff130000 swiotlb=1 kpti=0"; ++ stdout-path = "serial2:1500000n8"; ++ }; ++ ++ xin32k: xin32k { ++ compatible = "fixed-clock"; ++ clock-frequency = <32768>; ++ clock-output-names = "xin32k"; ++ #clock-cells = <0>; ++ }; ++ ++ vcc_phy: vcc-phy-regulator { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc_phy"; ++ regulator-always-on; ++ regulator-boot-on; ++ }; ++ ++ vcc_sys: vcc-sys { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc_sys"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ }; ++ ++ vcc_sd: sdmmc-regulator { ++ compatible = "regulator-fixed"; ++ gpio = <&gpio0 RK_PD6 GPIO_ACTIVE_LOW>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdmmc0m1_gpio>; ++ regulator-name = "vcc_sd"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ vin-supply = <&vcc_io>; ++ }; ++ ++ vcc_host_5v: vcc-host-5v-regulator { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpio = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&usb30_host_drv>; ++ regulator-name = "vcc_host_5v"; ++ regulator-always-on; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ vin-supply = <&vcc_sys>; ++ }; ++ ++ vcc_host1_5v: vcc_otg_5v: vcc-host1-5v-regulator { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpio = <&gpio0 RK_PA2 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&usb20_host_drv>; ++ regulator-name = "vcc_host1_5v"; ++ regulator-always-on; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ vin-supply = <&vcc_sys>; ++ }; ++ ++ leds { ++ compatible = "gpio-leds"; ++ ++ led1 { ++ gpios = <&rk805 0 GPIO_ACTIVE_LOW>; ++ linux,default-trigger = "default-on"; ++ default-state = "on"; ++ }; ++ ++ led2 { ++ gpios = <&rk805 1 GPIO_ACTIVE_LOW>; ++ linux,default-trigger = "mmc0"; ++ }; ++ }; ++ ++ ir-receiver { ++ compatible = "gpio-ir-receiver"; ++ gpios = <&gpio2 RK_PA2 GPIO_ACTIVE_LOW>; ++ pinctrl-0 = <&ir_int>; ++ pinctrl-names = "default"; ++ }; ++ ++ hdmi-sound { ++ compatible = "simple-audio-card"; ++ simple-audio-card,format = "i2s"; ++ simple-audio-card,mclk-fs = <128>; ++ simple-audio-card,name = "HDMI"; ++ simple-audio-card,cpu { ++ sound-dai = <&i2s0>; ++ }; ++ simple-audio-card,codec { ++ sound-dai = <&hdmi>; ++ }; ++ }; ++ ++ spdif-sound { ++ compatible = "simple-audio-card"; ++ simple-audio-card,name = "SPDIF"; ++ simple-audio-card,cpu { ++ sound-dai = <&spdif>; ++ }; ++ simple-audio-card,codec { ++ sound-dai = <&spdif_out>; ++ }; ++ }; ++ ++ spdif_out: spdif-out { ++ compatible = "linux,spdif-dit"; ++ #sound-dai-cells = <0>; ++ }; ++ ++ sdio_pwrseq: sdio-pwrseq { ++ compatible = "mmc-pwrseq-simple"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&wifi_enable_h>; ++ ++ /* ++ * On the module itself this is one of these (depending ++ * on the actual card populated): ++ * - SDIO_RESET_L_WL_REG_ON ++ * - PDN (power down when low) ++ */ ++ reset-gpios = <&gpio1 RK_PC2 GPIO_ACTIVE_LOW>; ++ }; ++ ++ wireless-bluetooth { ++ compatible = "bluetooth-platdata"; ++ uart_rts_gpios = <&gpio1 RK_PB2 GPIO_ACTIVE_LOW>; ++ pinctrl-names = "default", "rts_gpio"; ++ pinctrl-0 = <&uart0_rts>; ++ pinctrl-1 = <&uart0_gpios>; ++ BT,power_gpio = <&gpio1 RK_PC5 GPIO_ACTIVE_HIGH>; ++ BT,wake_host_irq = <&gpio1 RK_PD2 GPIO_ACTIVE_HIGH>; ++ }; ++ ++ wireless-wlan { ++ compatible = "wlan-platdata"; ++ rockchip,grf = <&grf>; ++ wifi_chip_type = "rtl8723bs"; ++ WIFI,host_wake_irq = <&gpio1 RK_PC3 GPIO_ACTIVE_HIGH>; ++ }; ++}; ++ ++&codec { ++ #sound-dai-cells = <0>; ++ status = "okay"; ++}; ++ ++&cpu0 { ++ cpu-supply = <&vdd_arm>; ++}; ++ ++&cpu1 { ++ cpu-supply = <&vdd_arm>; ++}; ++ ++&cpu2 { ++ cpu-supply = <&vdd_arm>; ++}; ++ ++&cpu3 { ++ cpu-supply = <&vdd_arm>; ++}; ++ ++&dfi { ++ status = "okay"; ++}; ++ ++&dmc { ++ center-supply = <&vdd_logic>; ++ status = "okay"; ++}; ++ ++&display_subsystem { ++ status = "okay"; ++}; ++ ++&emmc { ++ bus-width = <8>; ++ cap-mmc-highspeed; ++ mmc-hs200-1_8v; ++ non-removable; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>; ++ supports-emmc; ++ vmmc-supply = <&vcc_io>; ++ vqmmc-supply = <&vcc18_emmc>; ++ status = "okay"; ++}; ++ ++&gmac2phy { ++ phy-supply = <&vcc_phy>; ++ assigned-clocks = <&cru SCLK_MAC2PHY_SRC>; ++ assigned-clock-rate = <50000000>; ++ assigned-clocks = <&cru SCLK_MAC2PHY>; ++ assigned-clock-parents = <&cru SCLK_MAC2PHY_SRC>; ++ clock_in_out = "output"; ++ status = "okay"; ++}; ++ ++&gpu { ++ status = "okay"; ++ mali-supply = <&vdd_logic>; ++}; ++ ++&h265e { ++ status = "okay"; ++}; ++ ++&h265e_mmu { ++ status = "okay"; ++}; ++ ++&hdmi { ++ #sound-dai-cells = <0>; ++ ddc-i2c-scl-high-time-ns = <9625>; ++ ddc-i2c-scl-low-time-ns = <10000>; ++ status = "okay"; ++}; ++ ++&hdmiphy { ++ status = "okay"; ++}; ++ ++&i2c1 { ++ status = "okay"; ++ ++ rk805: rk805@18 { ++ compatible = "rockchip,rk805"; ++ status = "okay"; ++ reg = <0x18>; ++ interrupt-parent = <&gpio2>; ++ interrupts = <6 IRQ_TYPE_LEVEL_LOW>; ++ #clock-cells = <1>; ++ clock-output-names = "rk805-clkout1", "rk805-clkout2"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pmic_int_l>; ++ rockchip,system-power-controller; ++ wakeup-source; ++ gpio-controller; ++ #gpio-cells = <2>; ++ ++ vcc1-supply = <&vcc_sys>; ++ vcc2-supply = <&vcc_sys>; ++ vcc3-supply = <&vcc_sys>; ++ vcc4-supply = <&vcc_sys>; ++ vcc5-supply = <&vcc_io>; ++ vcc6-supply = <&vcc_sys>; ++ ++ rtc { ++ status = "okay"; ++ }; ++ ++ pwrkey { ++ status = "okay"; ++ }; ++ ++ gpio { ++ status = "okay"; ++ }; ++ ++ regulators { ++ compatible = "rk805-regulator"; ++ status = "okay"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ vdd_logic: RK805_DCDC1 { ++ regulator-compatible = "RK805_DCDC1"; ++ regulator-name = "vdd_logic"; ++ regulator-min-microvolt = <712500>; ++ regulator-max-microvolt = <1450000>; ++ regulator-initial-mode = <0x1>; ++ regulator-ramp-delay = <12500>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-mode = <0x2>; ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1000000>; ++ }; ++ }; ++ ++ vdd_arm: RK805_DCDC2 { ++ regulator-compatible = "RK805_DCDC2"; ++ regulator-name = "vdd_arm"; ++ regulator-init-microvolt = <1225000>; ++ regulator-min-microvolt = <712500>; ++ regulator-max-microvolt = <1450000>; ++ regulator-initial-mode = <0x1>; ++ regulator-ramp-delay = <12500>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-mode = <0x2>; ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <950000>; ++ }; ++ }; ++ ++ vcc_ddr: RK805_DCDC3 { ++ regulator-compatible = "RK805_DCDC3"; ++ regulator-name = "vcc_ddr"; ++ regulator-initial-mode = <0x1>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-mode = <0x2>; ++ regulator-on-in-suspend; ++ }; ++ }; ++ ++ vcc_io: RK805_DCDC4 { ++ regulator-compatible = "RK805_DCDC4"; ++ regulator-name = "vcc_io"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-initial-mode = <0x1>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-mode = <0x2>; ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <3300000>; ++ }; ++ }; ++ ++ vcc_18: RK805_LDO1 { ++ regulator-compatible = "RK805_LDO1"; ++ regulator-name = "vcc_18"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ vcc18_emmc: RK805_LDO2 { ++ regulator-compatible = "RK805_LDO2"; ++ regulator-name = "vcc18_emmc"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ vdd_10: RK805_LDO3 { ++ regulator-compatible = "RK805_LDO3"; ++ regulator-name = "vdd_10"; ++ regulator-min-microvolt = <1000000>; ++ regulator-max-microvolt = <1000000>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1000000>; ++ }; ++ }; ++ }; ++ }; ++}; ++ ++&i2s0 { ++ #sound-dai-cells = <0>; ++ rockchip,bclk-fs = <128>; ++ status = "okay"; ++}; ++ ++&iep { ++ status = "okay"; ++}; ++ ++&iep_mmu { ++ status = "okay"; ++}; ++ ++&io_domains { ++ status = "okay"; ++ ++ vccio1-supply = <&vcc_io>; ++ vccio2-supply = <&vcc18_emmc>; ++ vccio3-supply = <&vcc_io>; ++ vccio4-supply = <&vcc_18>; ++ vccio5-supply = <&vcc_io>; ++ vccio6-supply = <&vcc_io>; ++ pmuio-supply = <&vcc_io>; ++}; ++ ++&pinctrl { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&clk_32k_out>; ++ ++ clk_32k { ++ clk_32k_out: clk-32k-out { ++ rockchip,pins = <1 RK_PD4 RK_FUNC_1 &pcfg_pull_none>; ++ }; ++ }; ++ ++ ir { ++ ir_int: ir-int { ++ rockchip,pins = <2 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ pmic { ++ pmic_int_l: pmic-int-l { ++ rockchip,pins = <2 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ }; ++ ++ sdio-pwrseq { ++ wifi_enable_h: wifi-enable-h { ++ rockchip,pins = <1 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none_4ma>, ++ <1 RK_PC3 RK_FUNC_GPIO &pcfg_pull_none_4ma>; ++ }; ++ }; ++ ++ usb2 { ++ usb20_host_drv: usb20-host-drv { ++ rockchip,pins = <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ usb3 { ++ usb30_host_drv: usb30-host-drv { ++ rockchip,pins = <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ wireless-bluetooth { ++ uart0_gpios: uart0-gpios { ++ rockchip,pins = <1 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++}; ++ ++&rkvdec { ++ status = "okay"; ++ vcodec-supply = <&vdd_logic>; ++}; ++ ++&rkvdec_mmu { ++ status = "okay"; ++}; ++ ++&sdio { ++ bus-width = <4>; ++ cap-sd-highspeed; ++ cap-sdio-irq; ++ disable-wp; ++ keep-power-in-suspend; ++ mmc-pwrseq = <&sdio_pwrseq>; ++ non-removable; ++ num-slots = <1>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdmmc1_bus4 &sdmmc1_cmd &sdmmc1_clk>; ++ sd-uhs-sdr104; ++ supports-sdio; ++ status = "okay"; ++}; ++ ++&sdmmc { ++ bus-width = <4>; ++ cap-mmc-highspeed; ++ cap-sd-highspeed; ++ disable-wp; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdmmc0_clk &sdmmc0_cmd &sdmmc0_dectn &sdmmc0_bus4>; ++ supports-sd; ++ vmmc-supply = <&vcc_sd>; ++ status = "okay"; ++}; ++ ++&spdif { ++ #sound-dai-cells = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spdifm0_tx>; ++ status = "okay"; ++}; ++ ++&threshold { ++ temperature = <80000>; /* millicelsius */ ++}; ++ ++&target { ++ temperature = <95000>; /* millicelsius */ ++}; ++ ++&soc_crit { ++ temperature = <100000>; /* millicelsius */ ++}; ++ ++&tsadc { ++ rockchip,hw-tshut-mode = <0>; ++ rockchip,hw-tshut-polarity = <0>; ++ rockchip,hw-tshut-temp = <110000>; ++ status = "okay"; ++}; ++ ++&uart0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart0_xfer &uart0_cts>; ++ status = "okay"; ++}; ++ ++&uart2 { ++ status = "okay"; ++}; ++ ++&u2phy { ++ status = "okay"; ++}; ++ ++&u2phy_host { ++ phy-supply = <&vcc_host1_5v>; ++ status = "okay"; ++}; ++ ++&u2phy_otg { ++ phy-supply = <&vcc_otg_5v>; ++ status = "okay"; ++}; ++ ++&u3phy { ++ status = "okay"; ++}; ++ ++&u3phy_utmi { ++ phy-supply = <&vcc_host_5v>; ++ status = "okay"; ++}; ++ ++&u3phy_pipe { ++ phy-supply = <&vcc_host_5v>; ++ status = "okay"; ++}; ++ ++&usb20_otg { ++ dr_mode = "host"; ++ status = "okay"; ++}; ++ ++&usb_host0_ehci { ++ status = "okay"; ++}; ++ ++&usb_host0_ohci { ++ status = "okay"; ++}; ++ ++&usbdrd3 { ++ status = "okay"; ++}; ++ ++&usbdrd_dwc3 { ++ status = "okay"; ++}; ++ ++&vop { ++ status = "okay"; ++}; ++ ++&vop_mmu { ++ status = "okay"; ++}; ++ ++&vpu_service { ++ status = "okay"; ++}; ++ ++&vpu_mmu { ++ status = "okay"; ++}; ++ ++&vepu { ++ status = "okay"; ++}; ++ ++&vepu_mmu { ++ status = "okay"; ++}; ++ ++&venc_srv { ++ status = "okay"; ++}; + +From 8d1e765adaeb6d597b7cda84c9922f2aa5d34239 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Wed, 17 Jan 2018 22:17:45 +0100 +Subject: [PATCH] arm64: dts: rockchip: add rk3328-rockbox board + +--- + arch/arm64/boot/dts/rockchip/rk3328-rockbox.dts | 583 ++++++++++++++++++++++++ + 1 file changed, 583 insertions(+) + create mode 100644 arch/arm64/boot/dts/rockchip/rk3328-rockbox.dts + +diff --git a/arch/arm64/boot/dts/rockchip/rk3328-rockbox.dts b/arch/arm64/boot/dts/rockchip/rk3328-rockbox.dts +new file mode 100644 +index 000000000000..4ba9b1e78846 +--- /dev/null ++++ b/arch/arm64/boot/dts/rockchip/rk3328-rockbox.dts +@@ -0,0 +1,583 @@ ++/* ++ * Copyright (c) 2017 Fuzhou Rockchip Electronics Co., Ltd ++ * ++ * This file is dual-licensed: you can use it either under the terms ++ * of the GPL or the X11 license, at your option. Note that this dual ++ * licensing only applies to this file, and not this project as a ++ * whole. ++ * ++ * a) This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation; either version 2 of the ++ * License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * Or, alternatively, ++ * ++ * b) Permission is hereby granted, free of charge, to any person ++ * obtaining a copy of this software and associated documentation ++ * files (the "Software"), to deal in the Software without ++ * restriction, including without limitation the rights to use, ++ * copy, modify, merge, publish, distribute, sublicense, and/or ++ * sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following ++ * conditions: ++ * ++ * The above copyright notice and this permission notice shall be ++ * included in all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES ++ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ++ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT ++ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, ++ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING ++ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ++ * OTHER DEALINGS IN THE SOFTWARE. ++ */ ++ ++/dts-v1/; ++#include "rk3328.dtsi" ++ ++/ { ++ model = "Pine64 RockBox"; ++ compatible = "pine64,rockbox", "rockchip,rk3328"; ++ ++ chosen { ++ bootargs = "earlyprintk=uart8250-32bit,0xff130000 swiotlb=1 kpti=0"; ++ stdout-path = "serial2:1500000n8"; ++ }; ++ ++ xin32k: xin32k { ++ compatible = "fixed-clock"; ++ clock-frequency = <32768>; ++ clock-output-names = "xin32k"; ++ #clock-cells = <0>; ++ }; ++ ++ vcc_phy: vcc-phy-regulator { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc_phy"; ++ regulator-always-on; ++ regulator-boot-on; ++ }; ++ ++ vcc_sys: vcc-sys { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc_sys"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ }; ++ ++ vcc_sd: sdmmc-regulator { ++ compatible = "regulator-fixed"; ++ gpio = <&gpio0 RK_PD6 GPIO_ACTIVE_LOW>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdmmc0m1_gpio>; ++ regulator-name = "vcc_sd"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ vin-supply = <&vcc_io>; ++ }; ++ ++ vcc_host_5v: vcc_host1_5v: vcc_otg_5v: vcc-host-5v-regulator { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc_host_5v"; ++ regulator-always-on; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ vin-supply = <&vcc_sys>; ++ }; ++ ++ leds { ++ compatible = "gpio-leds"; ++ ++ power { ++ gpios = <&rk805 0 GPIO_ACTIVE_HIGH>; ++ linux,default-trigger = "default-on"; ++ default-state = "on"; ++ }; ++ }; ++ ++ ir-receiver { ++ compatible = "gpio-ir-receiver"; ++ gpios = <&gpio2 RK_PA2 GPIO_ACTIVE_LOW>; ++ linux,rc-map-name = "rc-pine64"; ++ pinctrl-0 = <&ir_int>; ++ pinctrl-names = "default"; ++ }; ++ ++ hdmi-sound { ++ compatible = "simple-audio-card"; ++ simple-audio-card,format = "i2s"; ++ simple-audio-card,mclk-fs = <128>; ++ simple-audio-card,name = "HDMI"; ++ simple-audio-card,cpu { ++ sound-dai = <&i2s0>; ++ }; ++ simple-audio-card,codec { ++ sound-dai = <&hdmi>; ++ }; ++ }; ++ ++ spdif-sound { ++ compatible = "simple-audio-card"; ++ simple-audio-card,name = "SPDIF"; ++ simple-audio-card,cpu { ++ sound-dai = <&spdif>; ++ }; ++ simple-audio-card,codec { ++ sound-dai = <&spdif_out>; ++ }; ++ }; ++ ++ spdif_out: spdif-out { ++ compatible = "linux,spdif-dit"; ++ #sound-dai-cells = <0>; ++ }; ++ ++ sdio_pwrseq: sdio-pwrseq { ++ compatible = "mmc-pwrseq-simple"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&wifi_enable_h>; ++ ++ /* ++ * On the module itself this is one of these (depending ++ * on the actual card populated): ++ * - SDIO_RESET_L_WL_REG_ON ++ * - PDN (power down when low) ++ */ ++ reset-gpios = <&gpio1 RK_PC2 GPIO_ACTIVE_LOW>; ++ }; ++ ++ wireless-wlan { ++ compatible = "wlan-platdata"; ++ rockchip,grf = <&grf>; ++ wifi_chip_type = "rtl8189fs"; ++ WIFI,host_wake_irq = <&gpio1 RK_PC3 GPIO_ACTIVE_HIGH>; ++ }; ++}; ++ ++&codec { ++ #sound-dai-cells = <0>; ++ status = "okay"; ++}; ++ ++&cpu0 { ++ cpu-supply = <&vdd_arm>; ++}; ++ ++&cpu1 { ++ cpu-supply = <&vdd_arm>; ++}; ++ ++&cpu2 { ++ cpu-supply = <&vdd_arm>; ++}; ++ ++&cpu3 { ++ cpu-supply = <&vdd_arm>; ++}; ++ ++&dfi { ++ status = "okay"; ++}; ++ ++&dmc { ++ center-supply = <&vdd_logic>; ++ status = "okay"; ++}; ++ ++&display_subsystem { ++ status = "okay"; ++}; ++ ++&emmc { ++ bus-width = <8>; ++ cap-mmc-highspeed; ++ mmc-hs200-1_8v; ++ non-removable; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>; ++ supports-emmc; ++ vmmc-supply = <&vcc_io>; ++ vqmmc-supply = <&vcc18_emmc>; ++ status = "okay"; ++}; ++ ++&gmac2phy { ++ phy-supply = <&vcc_phy>; ++ assigned-clocks = <&cru SCLK_MAC2PHY_SRC>; ++ assigned-clock-rate = <50000000>; ++ assigned-clocks = <&cru SCLK_MAC2PHY>; ++ assigned-clock-parents = <&cru SCLK_MAC2PHY_SRC>; ++ clock_in_out = "output"; ++ status = "okay"; ++}; ++ ++&gpu { ++ status = "okay"; ++ mali-supply = <&vdd_logic>; ++}; ++ ++&h265e { ++ status = "okay"; ++}; ++ ++&h265e_mmu { ++ status = "okay"; ++}; ++ ++&hdmi { ++ #sound-dai-cells = <0>; ++ ddc-i2c-scl-high-time-ns = <9625>; ++ ddc-i2c-scl-low-time-ns = <10000>; ++ status = "okay"; ++}; ++ ++&hdmiphy { ++ status = "okay"; ++}; ++ ++&i2c1 { ++ status = "okay"; ++ ++ rk805: rk805@18 { ++ compatible = "rockchip,rk805"; ++ status = "okay"; ++ reg = <0x18>; ++ interrupt-parent = <&gpio2>; ++ interrupts = <6 IRQ_TYPE_LEVEL_LOW>; ++ #clock-cells = <1>; ++ clock-output-names = "rk805-clkout1", "rk805-clkout2"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pmic_int_l>; ++ rockchip,system-power-controller; ++ wakeup-source; ++ gpio-controller; ++ #gpio-cells = <2>; ++ ++ vcc1-supply = <&vcc_sys>; ++ vcc2-supply = <&vcc_sys>; ++ vcc3-supply = <&vcc_sys>; ++ vcc4-supply = <&vcc_sys>; ++ vcc5-supply = <&vcc_io>; ++ vcc6-supply = <&vcc_sys>; ++ ++ rtc { ++ status = "okay"; ++ }; ++ ++ pwrkey { ++ status = "okay"; ++ }; ++ ++ gpio { ++ status = "okay"; ++ }; ++ ++ regulators { ++ compatible = "rk805-regulator"; ++ status = "okay"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ vdd_logic: RK805_DCDC1 { ++ regulator-compatible = "RK805_DCDC1"; ++ regulator-name = "vdd_logic"; ++ regulator-min-microvolt = <712500>; ++ regulator-max-microvolt = <1450000>; ++ regulator-initial-mode = <0x1>; ++ regulator-ramp-delay = <12500>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-mode = <0x2>; ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1000000>; ++ }; ++ }; ++ ++ vdd_arm: RK805_DCDC2 { ++ regulator-compatible = "RK805_DCDC2"; ++ regulator-name = "vdd_arm"; ++ regulator-init-microvolt = <1225000>; ++ regulator-min-microvolt = <712500>; ++ regulator-max-microvolt = <1450000>; ++ regulator-initial-mode = <0x1>; ++ regulator-ramp-delay = <12500>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-mode = <0x2>; ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <950000>; ++ }; ++ }; ++ ++ vcc_ddr: RK805_DCDC3 { ++ regulator-compatible = "RK805_DCDC3"; ++ regulator-name = "vcc_ddr"; ++ regulator-initial-mode = <0x1>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-mode = <0x2>; ++ regulator-on-in-suspend; ++ }; ++ }; ++ ++ vcc_io: RK805_DCDC4 { ++ regulator-compatible = "RK805_DCDC4"; ++ regulator-name = "vcc_io"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-initial-mode = <0x1>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-mode = <0x2>; ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <3300000>; ++ }; ++ }; ++ ++ vcc_18: RK805_LDO1 { ++ regulator-compatible = "RK805_LDO1"; ++ regulator-name = "vcc_18"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ vcc18_emmc: RK805_LDO2 { ++ regulator-compatible = "RK805_LDO2"; ++ regulator-name = "vcc18_emmc"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ vdd_10: RK805_LDO3 { ++ regulator-compatible = "RK805_LDO3"; ++ regulator-name = "vdd_10"; ++ regulator-min-microvolt = <1000000>; ++ regulator-max-microvolt = <1000000>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1000000>; ++ }; ++ }; ++ }; ++ }; ++}; ++ ++&i2s0 { ++ #sound-dai-cells = <0>; ++ rockchip,bclk-fs = <128>; ++ status = "okay"; ++}; ++ ++&iep { ++ status = "okay"; ++}; ++ ++&iep_mmu { ++ status = "okay"; ++}; ++ ++&io_domains { ++ status = "okay"; ++ ++ vccio1-supply = <&vcc_io>; ++ vccio2-supply = <&vcc18_emmc>; ++ vccio3-supply = <&vcc_io>; ++ vccio4-supply = <&vcc_io>; ++ vccio5-supply = <&vcc_io>; ++ vccio6-supply = <&vcc_io>; ++ pmuio-supply = <&vcc_io>; ++}; ++ ++&pinctrl { ++ ir { ++ ir_int: ir-int { ++ rockchip,pins = <2 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ pmic { ++ pmic_int_l: pmic-int-l { ++ rockchip,pins = <2 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ }; ++ ++ sdio-pwrseq { ++ wifi_enable_h: wifi-enable-h { ++ rockchip,pins = <1 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none_4ma>, ++ <1 RK_PC3 RK_FUNC_GPIO &pcfg_pull_none_4ma>; ++ }; ++ }; ++}; ++ ++&rkvdec { ++ status = "okay"; ++ vcodec-supply = <&vdd_logic>; ++}; ++ ++&rkvdec_mmu { ++ status = "okay"; ++}; ++ ++&sdio { ++ bus-width = <4>; ++ cap-sd-highspeed; ++ cap-sdio-irq; ++ disable-wp; ++ keep-power-in-suspend; ++ mmc-pwrseq = <&sdio_pwrseq>; ++ non-removable; ++ num-slots = <1>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdmmc1_bus4 &sdmmc1_cmd &sdmmc1_clk>; ++ supports-sdio; ++ status = "okay"; ++}; ++ ++&sdmmc { ++ bus-width = <4>; ++ cap-mmc-highspeed; ++ cap-sd-highspeed; ++ disable-wp; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdmmc0_clk &sdmmc0_cmd &sdmmc0_dectn &sdmmc0_bus4>; ++ supports-sd; ++ vmmc-supply = <&vcc_sd>; ++ status = "okay"; ++}; ++ ++&spdif { ++ #sound-dai-cells = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spdifm0_tx>; ++ status = "okay"; ++}; ++ ++&threshold { ++ temperature = <80000>; /* millicelsius */ ++}; ++ ++&target { ++ temperature = <95000>; /* millicelsius */ ++}; ++ ++&soc_crit { ++ temperature = <100000>; /* millicelsius */ ++}; ++ ++&tsadc { ++ rockchip,hw-tshut-mode = <0>; ++ rockchip,hw-tshut-polarity = <0>; ++ rockchip,hw-tshut-temp = <110000>; ++ status = "okay"; ++}; ++ ++&uart2 { ++ status = "okay"; ++}; ++ ++&u2phy { ++ status = "okay"; ++}; ++ ++&u2phy_host { ++ phy-supply = <&vcc_host1_5v>; ++ status = "okay"; ++}; ++ ++&u2phy_otg { ++ phy-supply = <&vcc_otg_5v>; ++ status = "okay"; ++}; ++ ++&u3phy { ++ status = "okay"; ++}; ++ ++&u3phy_utmi { ++ phy-supply = <&vcc_host_5v>; ++ status = "okay"; ++}; ++ ++&u3phy_pipe { ++ phy-supply = <&vcc_host_5v>; ++ status = "okay"; ++}; ++ ++&usb20_otg { ++ dr_mode = "host"; ++ status = "okay"; ++}; ++ ++&usb_host0_ehci { ++ status = "okay"; ++}; ++ ++&usb_host0_ohci { ++ status = "okay"; ++}; ++ ++&usbdrd3 { ++ status = "okay"; ++}; ++ ++&usbdrd_dwc3 { ++ status = "okay"; ++}; ++ ++&vop { ++ status = "okay"; ++}; ++ ++&vop_mmu { ++ status = "okay"; ++}; ++ ++&vpu_service { ++ status = "okay"; ++}; ++ ++&vpu_mmu { ++ status = "okay"; ++}; ++ ++&vepu { ++ status = "okay"; ++}; ++ ++&vepu_mmu { ++ status = "okay"; ++}; ++ ++&venc_srv { ++ status = "okay"; ++}; + +From aa7c314431dcd5fd3dd6dd8b06859c472e93cf5d Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Wed, 17 Jan 2018 22:17:45 +0100 +Subject: [PATCH] arm64: dts: rockchip: add rk3328-roc-cc board + +--- + arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts | 576 +++++++++++++++++++++++++ + 1 file changed, 576 insertions(+) + create mode 100644 arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts + +diff --git a/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts b/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts +new file mode 100644 +index 000000000000..af2af859d56e +--- /dev/null ++++ b/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts +@@ -0,0 +1,576 @@ ++/* ++ * Copyright (c) 2017 Fuzhou Rockchip Electronics Co., Ltd ++ * ++ * This file is dual-licensed: you can use it either under the terms ++ * of the GPL or the X11 license, at your option. Note that this dual ++ * licensing only applies to this file, and not this project as a ++ * whole. ++ * ++ * a) This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation; either version 2 of the ++ * License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * Or, alternatively, ++ * ++ * b) Permission is hereby granted, free of charge, to any person ++ * obtaining a copy of this software and associated documentation ++ * files (the "Software"), to deal in the Software without ++ * restriction, including without limitation the rights to use, ++ * copy, modify, merge, publish, distribute, sublicense, and/or ++ * sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following ++ * conditions: ++ * ++ * The above copyright notice and this permission notice shall be ++ * included in all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES ++ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ++ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT ++ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, ++ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING ++ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ++ * OTHER DEALINGS IN THE SOFTWARE. ++ */ ++ ++/dts-v1/; ++#include "rk3328.dtsi" ++ ++/ { ++ model = "Firefly ROC-RK3328-CC Board"; ++ compatible = "firefly,roc-rk3328-cc", "rockchip,rk3328"; ++ ++ chosen { ++ bootargs = "earlyprintk=uart8250-32bit,0xff130000 swiotlb=1 kpti=0"; ++ stdout-path = "serial2:1500000n8"; ++ }; ++ ++ xin32k: xin32k { ++ compatible = "fixed-clock"; ++ clock-frequency = <32768>; ++ clock-output-names = "xin32k"; ++ #clock-cells = <0>; ++ }; ++ ++ gmac_clkin: external-gmac-clock { ++ compatible = "fixed-clock"; ++ clock-frequency = <125000000>; ++ clock-output-names = "gmac_clkin"; ++ #clock-cells = <0>; ++ }; ++ ++ vcc_phy: vcc-phy-regulator { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc_phy"; ++ regulator-always-on; ++ regulator-boot-on; ++ }; ++ ++ vcc_sys: vcc-sys { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc_sys"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ }; ++ ++ vcc_sd: sdmmc-regulator { ++ compatible = "regulator-fixed"; ++ gpio = <&gpio0 RK_PD6 GPIO_ACTIVE_LOW>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdmmc0m1_gpio>; ++ regulator-name = "vcc_sd"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ vin-supply = <&vcc_io>; ++ }; ++ ++ vccio_sd: sdmmcio-regulator { ++ compatible = "regulator-gpio"; ++ gpios = <&gpio0 RK_PD1 GPIO_ACTIVE_HIGH>; ++ states = <1800000 0x1 ++ 3300000 0x0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sd_pwr_1800_sel>; ++ regulator-name = "vccio_sd"; ++ regulator-type = "voltage"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <3300000>; ++ }; ++ ++ vcc_host_5v: vcc_host1_5v: vcc_otg_5v: vcc-host-5v-regulator { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpio = <&gpio1 RK_PD2 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&usb_host_drv>; ++ regulator-name = "vcc_host_5v"; ++ regulator-always-on; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ vin-supply = <&vcc_sys>; ++ }; ++ ++ leds { ++ compatible = "gpio-leds"; ++ ++ power { ++ gpios = <&rk805 1 GPIO_ACTIVE_LOW>; ++ linux,default-trigger = "heartbeat"; ++ }; ++ ++ user { ++ gpios = <&rk805 0 GPIO_ACTIVE_LOW>; ++ linux,default-trigger = "mmc0"; ++ }; ++ }; ++ ++ ir-receiver { ++ compatible = "gpio-ir-receiver"; ++ gpios = <&gpio2 RK_PA2 GPIO_ACTIVE_LOW>; ++ linux,rc-map-name = "rc-roc-cc"; ++ pinctrl-0 = <&ir_int>; ++ pinctrl-names = "default"; ++ }; ++ ++ hdmi-sound { ++ compatible = "simple-audio-card"; ++ simple-audio-card,format = "i2s"; ++ simple-audio-card,mclk-fs = <128>; ++ simple-audio-card,name = "HDMI"; ++ simple-audio-card,cpu { ++ sound-dai = <&i2s0>; ++ }; ++ simple-audio-card,codec { ++ sound-dai = <&hdmi>; ++ }; ++ }; ++ ++ sound { ++ compatible = "simple-audio-card"; ++ simple-audio-card,format = "i2s"; ++ simple-audio-card,mclk-fs = <256>; ++ simple-audio-card,name = "I2S"; ++ simple-audio-card,cpu { ++ sound-dai = <&i2s1>; ++ }; ++ simple-audio-card,codec { ++ sound-dai = <&codec>; ++ }; ++ }; ++}; ++ ++&codec { ++ #sound-dai-cells = <0>; ++ status = "okay"; ++}; ++ ++&cpu0 { ++ cpu-supply = <&vdd_arm>; ++}; ++ ++&cpu1 { ++ cpu-supply = <&vdd_arm>; ++}; ++ ++&cpu2 { ++ cpu-supply = <&vdd_arm>; ++}; ++ ++&cpu3 { ++ cpu-supply = <&vdd_arm>; ++}; ++ ++&dfi { ++ status = "okay"; ++}; ++ ++&dmc { ++ center-supply = <&vdd_logic>; ++ status = "okay"; ++}; ++ ++&display_subsystem { ++ status = "okay"; ++}; ++ ++&emmc { ++ bus-width = <8>; ++ cap-mmc-highspeed; ++ mmc-hs200-1_8v; ++ non-removable; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>; ++ supports-emmc; ++ vmmc-supply = <&vcc_io>; ++ vqmmc-supply = <&vcc18_emmc>; ++ status = "okay"; ++}; ++ ++&gmac2io { ++ assigned-clocks = <&cru SCLK_MAC2IO>, <&cru SCLK_MAC2IO_EXT>; ++ assigned-clock-parents = <&gmac_clkin>, <&gmac_clkin>; ++ clock_in_out = "input"; ++ phy-supply = <&vcc_phy>; ++ phy-mode = "rgmii"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&rgmiim1_pins>; ++ snps,reset-gpio = <&gpio1 RK_PC2 GPIO_ACTIVE_LOW>; ++ snps,reset-active-low; ++ snps,reset-delays-us = <0 10000 50000>; ++ tx_delay = <0x25>; ++ rx_delay = <0x11>; ++ status = "okay"; ++}; ++ ++&gpu { ++ status = "okay"; ++ mali-supply = <&vdd_logic>; ++}; ++ ++&h265e { ++ status = "okay"; ++}; ++ ++&h265e_mmu { ++ status = "okay"; ++}; ++ ++&hdmi { ++ #sound-dai-cells = <0>; ++ ddc-i2c-scl-high-time-ns = <9625>; ++ ddc-i2c-scl-low-time-ns = <10000>; ++ status = "okay"; ++}; ++ ++&hdmiphy { ++ status = "okay"; ++}; ++ ++&i2c1 { ++ status = "okay"; ++ ++ rk805: rk805@18 { ++ compatible = "rockchip,rk805"; ++ status = "okay"; ++ reg = <0x18>; ++ interrupt-parent = <&gpio1>; ++ interrupts = <24 IRQ_TYPE_LEVEL_LOW>; ++ #clock-cells = <1>; ++ clock-output-names = "rk805-clkout1", "rk805-clkout2"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pmic_int_l>; ++ rockchip,system-power-controller; ++ wakeup-source; ++ gpio-controller; ++ #gpio-cells = <2>; ++ ++ vcc1-supply = <&vcc_sys>; ++ vcc2-supply = <&vcc_sys>; ++ vcc3-supply = <&vcc_sys>; ++ vcc4-supply = <&vcc_sys>; ++ vcc5-supply = <&vcc_io>; ++ vcc6-supply = <&vcc_sys>; ++ ++ rtc { ++ status = "okay"; ++ }; ++ ++ pwrkey { ++ status = "okay"; ++ }; ++ ++ gpio { ++ status = "okay"; ++ }; ++ ++ regulators { ++ compatible = "rk805-regulator"; ++ status = "okay"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ vdd_logic: RK805_DCDC1 { ++ regulator-compatible = "RK805_DCDC1"; ++ regulator-name = "vdd_logic"; ++ regulator-min-microvolt = <712500>; ++ regulator-max-microvolt = <1450000>; ++ regulator-initial-mode = <0x1>; ++ regulator-ramp-delay = <12500>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-mode = <0x2>; ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1000000>; ++ }; ++ }; ++ ++ vdd_arm: RK805_DCDC2 { ++ regulator-compatible = "RK805_DCDC2"; ++ regulator-name = "vdd_arm"; ++ regulator-init-microvolt = <1225000>; ++ regulator-min-microvolt = <712500>; ++ regulator-max-microvolt = <1450000>; ++ regulator-initial-mode = <0x1>; ++ regulator-ramp-delay = <12500>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-mode = <0x2>; ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <950000>; ++ }; ++ }; ++ ++ vcc_ddr: RK805_DCDC3 { ++ regulator-compatible = "RK805_DCDC3"; ++ regulator-name = "vcc_ddr"; ++ regulator-initial-mode = <0x1>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-mode = <0x2>; ++ regulator-on-in-suspend; ++ }; ++ }; ++ ++ vcc_io: RK805_DCDC4 { ++ regulator-compatible = "RK805_DCDC4"; ++ regulator-name = "vcc_io"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-initial-mode = <0x1>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-mode = <0x2>; ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <3300000>; ++ }; ++ }; ++ ++ vcc_18: RK805_LDO1 { ++ regulator-compatible = "RK805_LDO1"; ++ regulator-name = "vcc_18"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ vcc18_emmc: RK805_LDO2 { ++ regulator-compatible = "RK805_LDO2"; ++ regulator-name = "vcc18_emmc"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ vdd_10: RK805_LDO3 { ++ regulator-compatible = "RK805_LDO3"; ++ regulator-name = "vdd_10"; ++ regulator-min-microvolt = <1000000>; ++ regulator-max-microvolt = <1000000>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1000000>; ++ }; ++ }; ++ }; ++ }; ++}; ++ ++&i2s0 { ++ #sound-dai-cells = <0>; ++ rockchip,bclk-fs = <128>; ++ status = "okay"; ++}; ++ ++&iep { ++ status = "okay"; ++}; ++ ++&iep_mmu { ++ status = "okay"; ++}; ++ ++&io_domains { ++ status = "okay"; ++ ++ vccio1-supply = <&vcc_io>; ++ vccio2-supply = <&vcc18_emmc>; ++ vccio3-supply = <&vccio_sd>; ++ vccio4-supply = <&vcc_io>; ++ vccio5-supply = <&vcc_io>; ++ vccio6-supply = <&vcc_io>; ++ pmuio-supply = <&vcc_io>; ++}; ++ ++&pinctrl { ++ ir { ++ ir_int: ir-int { ++ rockchip,pins = <2 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ sd-pwerset { ++ sd_pwr_1800_sel: sd-pwr-1800-sel { ++ rockchip,pins = <0 RK_PD1 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ pmic { ++ pmic_int_l: pmic-int-l { ++ rockchip,pins = <1 RK_PD0 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ }; ++ ++ usb { ++ usb_host_drv: usb-host-drv { ++ rockchip,pins = <1 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++}; ++ ++&rkvdec { ++ status = "okay"; ++ vcodec-supply = <&vdd_logic>; ++}; ++ ++&rkvdec_mmu { ++ status = "okay"; ++}; ++ ++&sdmmc { ++ bus-width = <4>; ++ cap-mmc-highspeed; ++ cap-sd-highspeed; ++ disable-wp; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdmmc0_clk &sdmmc0_cmd &sdmmc0_dectn &sdmmc0_bus4>; ++ sd-uhs-sdr104; ++ supports-sd; ++ vmmc-supply = <&vcc_sd>; ++ vqmmc-supply = <&vccio_sd>; ++ status = "okay"; ++}; ++ ++&threshold { ++ temperature = <80000>; /* millicelsius */ ++}; ++ ++&target { ++ temperature = <95000>; /* millicelsius */ ++}; ++ ++&soc_crit { ++ temperature = <100000>; /* millicelsius */ ++}; ++ ++&tsadc { ++ rockchip,hw-tshut-mode = <0>; ++ rockchip,hw-tshut-polarity = <0>; ++ rockchip,hw-tshut-temp = <110000>; ++ status = "okay"; ++}; ++ ++&uart2 { ++ status = "okay"; ++}; ++ ++&u2phy { ++ status = "okay"; ++}; ++ ++&u2phy_host { ++ phy-supply = <&vcc_host1_5v>; ++ status = "okay"; ++}; ++ ++&u2phy_otg { ++ phy-supply = <&vcc_otg_5v>; ++ status = "okay"; ++}; ++ ++&u3phy { ++ status = "okay"; ++}; ++ ++&u3phy_utmi { ++ phy-supply = <&vcc_host_5v>; ++ status = "okay"; ++}; ++ ++&u3phy_pipe { ++ phy-supply = <&vcc_host_5v>; ++ status = "okay"; ++}; ++ ++&usb20_otg { ++ dr_mode = "host"; ++ status = "okay"; ++}; ++ ++&usb_host0_ehci { ++ status = "okay"; ++}; ++ ++&usb_host0_ohci { ++ status = "okay"; ++}; ++ ++&usbdrd3 { ++ status = "okay"; ++}; ++ ++&usbdrd_dwc3 { ++ status = "okay"; ++}; ++ ++&vop { ++ status = "okay"; ++}; ++ ++&vop_mmu { ++ status = "okay"; ++}; ++ ++&vpu_service { ++ status = "okay"; ++}; ++ ++&vpu_mmu { ++ status = "okay"; ++}; ++ ++&vepu { ++ status = "okay"; ++}; ++ ++&vepu_mmu { ++ status = "okay"; ++}; ++ ++&venc_srv { ++ status = "okay"; ++}; + +From 1652fa888921eb14a53fd6b12b6860247d5a9d0c Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 3 Sep 2017 11:19:19 +0200 +Subject: [PATCH] arm64: dts: rockchip: rk3328-rock64: use two dai-link for i2s + sound + +--- + arch/arm64/boot/dts/rockchip/rk3328-rock64.dts | 26 +++++++++++++++++++++----- + sound/soc/soc-utils.c | 10 ++++++++++ + 2 files changed, 31 insertions(+), 5 deletions(-) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts +index ff90c5379671..d47d572a6ca6 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts +@@ -128,6 +128,11 @@ + pinctrl-names = "default"; + }; + ++ dummy_codec: dummy-codec { ++ compatible = "linux,snd-soc-dummy"; ++ #sound-dai-cells = <0>; ++ }; ++ + hdmi-sound { + compatible = "simple-audio-card"; + simple-audio-card,format = "i2s"; +@@ -143,14 +148,25 @@ + + sound { + compatible = "simple-audio-card"; +- simple-audio-card,format = "i2s"; + simple-audio-card,mclk-fs = <256>; + simple-audio-card,name = "I2S"; +- simple-audio-card,cpu { +- sound-dai = <&i2s1>; ++ simple-audio-card,dai-link@0 { ++ format = "i2s"; ++ cpu { ++ sound-dai = <&i2s1>; ++ }; ++ codec { ++ sound-dai = <&codec>; ++ }; + }; +- simple-audio-card,codec { +- sound-dai = <&codec>; ++ simple-audio-card,dai-link@1 { ++ format = "i2s"; ++ cpu { ++ sound-dai = <&i2s1>; ++ }; ++ codec { ++ sound-dai = <&dummy_codec>; ++ }; + }; + }; + +diff --git a/sound/soc/soc-utils.c b/sound/soc/soc-utils.c +index 53dd085d3ee2..bf7ce34084a9 100644 +--- a/sound/soc/soc-utils.c ++++ b/sound/soc/soc-utils.c +@@ -19,6 +19,7 @@ + #include + #include + #include ++#include + + int snd_soc_calc_frame_size(int sample_size, int channels, int tdm_slots) + { +@@ -160,9 +161,18 @@ static int snd_soc_dummy_remove(struct platform_device *pdev) + return 0; + } + ++#ifdef CONFIG_OF ++static const struct of_device_id soc_dummy_ids[] = { ++ { .compatible = "linux,snd-soc-dummy", }, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, soc_dummy_ids); ++#endif ++ + static struct platform_driver soc_dummy_driver = { + .driver = { + .name = "snd-soc-dummy", ++ .of_match_table = of_match_ptr(soc_dummy_ids), + }, + .probe = snd_soc_dummy_probe, + .remove = snd_soc_dummy_remove, + +From 3184eaf3788de374e37ba0ee24ce641d6a20f780 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Fri, 26 Jan 2018 00:03:46 +0100 +Subject: [PATCH] arm64: dts: rockchip: rk3328-roc-cc: disable sd-card voltage + select + +Voltage select should set GRF_SOC_CON10 bit 1, +vendor kernel repurpose GPIO0_D1 to signal this, +RK kernel uses GRF_SOC_CON10 bit 1 to mute avcodec. +--- + arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts | 10 ---------- + 1 file changed, 10 deletions(-) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts b/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts +index af2af859d56e..e911cf265a64 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts +@@ -98,8 +98,6 @@ + gpios = <&gpio0 RK_PD1 GPIO_ACTIVE_HIGH>; + states = <1800000 0x1 + 3300000 0x0>; +- pinctrl-names = "default"; +- pinctrl-0 = <&sd_pwr_1800_sel>; + regulator-name = "vccio_sd"; + regulator-type = "voltage"; + regulator-min-microvolt = <1800000>; +@@ -433,12 +431,6 @@ + }; + }; + +- sd-pwerset { +- sd_pwr_1800_sel: sd-pwr-1800-sel { +- rockchip,pins = <0 RK_PD1 RK_FUNC_GPIO &pcfg_pull_none>; +- }; +- }; +- + pmic { + pmic_int_l: pmic-int-l { + rockchip,pins = <1 RK_PD0 RK_FUNC_GPIO &pcfg_pull_up>; +@@ -468,10 +460,8 @@ + disable-wp; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc0_clk &sdmmc0_cmd &sdmmc0_dectn &sdmmc0_bus4>; +- sd-uhs-sdr104; + supports-sd; + vmmc-supply = <&vcc_sd>; +- vqmmc-supply = <&vccio_sd>; + status = "okay"; + }; + + +From 200c456121d8644da9f4ffc3ac8acf2f8f8ecb5c Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 28 Jan 2018 15:17:34 +0100 +Subject: [PATCH] arm64: dts: rockchip: add rk3399-sapphire board + +--- + arch/arm64/boot/dts/rockchip/rk3399-sapphire.dts | 170 +++++++++++++++++++++++ + 1 file changed, 170 insertions(+) + create mode 100644 arch/arm64/boot/dts/rockchip/rk3399-sapphire.dts + +diff --git a/arch/arm64/boot/dts/rockchip/rk3399-sapphire.dts b/arch/arm64/boot/dts/rockchip/rk3399-sapphire.dts +new file mode 100644 +index 000000000000..8706dc7d91af +--- /dev/null ++++ b/arch/arm64/boot/dts/rockchip/rk3399-sapphire.dts +@@ -0,0 +1,170 @@ ++/* ++ * Copyright (c) 2016 Fuzhou Rockchip Electronics Co., Ltd ++ * ++ * This file is dual-licensed: you can use it either under the terms ++ * of the GPL or the X11 license, at your option. Note that this dual ++ * licensing only applies to this file, and not this project as a ++ * whole. ++ * ++ * a) This file is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation; either version 2 of the ++ * License, or (at your option) any later version. ++ * ++ * This file is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * Or, alternatively, ++ * ++ * b) Permission is hereby granted, free of charge, to any person ++ * obtaining a copy of this software and associated documentation ++ * files (the "Software"), to deal in the Software without ++ * restriction, including without limitation the rights to use, ++ * copy, modify, merge, publish, distribute, sublicense, and/or ++ * sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following ++ * conditions: ++ * ++ * The above copyright notice and this permission notice shall be ++ * included in all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES ++ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ++ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT ++ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, ++ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING ++ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ++ * OTHER DEALINGS IN THE SOFTWARE. ++ */ ++ ++/dts-v1/; ++ ++#include "rk3399-sapphire.dtsi" ++#include "rk3399-linux.dtsi" ++#include ++ ++/ { ++ model = "Rockchip RK3399 Sapphire Board"; ++ compatible = "rockchip,rk3399-sapphire", "rockchip,rk3399"; ++ ++ gpio-keys { ++ compatible = "gpio-keys"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ autorepeat; ++ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pwrbtn>; ++ ++ button@0 { ++ gpios = <&gpio0 5 GPIO_ACTIVE_LOW>; ++ linux,code = ; ++ label = "GPIO Key Power"; ++ linux,input-type = <1>; ++ gpio-key,wakeup = <1>; ++ debounce-interval = <100>; ++ }; ++ }; ++ ++ vccadc_ref: vccadc-ref { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc1v8_sys"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ }; ++}; ++ ++&hdmi_sound { ++ simple-audio-card,name = "HDMI"; ++ status = "okay"; ++}; ++ ++&i2s2 { ++ #sound-dai-cells = <0>; ++ rockchip,bclk-fs = <128>; ++ status = "okay"; ++}; ++ ++&iep { ++ status = "okay"; ++}; ++ ++&iep_mmu { ++ status = "okay"; ++}; ++ ++&saradc { ++ vref-supply = <&vccadc_ref>; ++}; ++ ++&vpu { ++ status = "okay"; ++}; ++ ++&rkvdec { ++ status = "okay"; ++}; ++ ++&display_subsystem { ++ ports = <&vopb_out>; ++ status = "okay"; ++}; ++ ++&route_hdmi { ++ status = "okay"; ++}; ++ ++&cdn_dp { ++ status = "disabled"; ++}; ++ ++&dp_in_vopb { ++ status = "disabled"; ++}; ++ ++&hdmi { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ #sound-dai-cells = <0>; ++ status = "okay"; ++}; ++ ++&pcie_phy { ++ status = "disabled"; ++}; ++ ++&pcie0 { ++ status = "disabled"; ++}; ++ ++&sdio0 { ++ status = "disabled"; ++}; ++ ++&vopb { ++ status = "okay"; ++}; ++ ++&vopb_mmu { ++ status = "okay"; ++}; ++ ++&pinctrl { ++ sdio-pwrseq { ++ wifi_enable_h: wifi-enable-h { ++ rockchip,pins = ++ <0 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ buttons { ++ pwrbtn: pwrbtn { ++ rockchip,pins = <0 5 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ }; ++}; + +From 1ac825316b3a44cd22bf7904f230e725a8163f2c Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 28 Jan 2018 15:17:53 +0100 +Subject: [PATCH] arm64: dts: rockchip: add rk3399-rock960 board + +--- + arch/arm64/boot/dts/rockchip/rk3399-rock960.dts | 1003 +++++++++++++++++++++++ + 1 file changed, 1003 insertions(+) + create mode 100644 arch/arm64/boot/dts/rockchip/rk3399-rock960.dts + +diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rock960.dts b/arch/arm64/boot/dts/rockchip/rk3399-rock960.dts +new file mode 100644 +index 000000000000..865a1da96aee +--- /dev/null ++++ b/arch/arm64/boot/dts/rockchip/rk3399-rock960.dts +@@ -0,0 +1,1003 @@ ++/* ++ * Copyright (c) 2016 Fuzhou Rockchip Electronics Co., Ltd ++ * ++ * This file is dual-licensed: you can use it either under the terms ++ * of the GPL or the X11 license, at your option. Note that this dual ++ * licensing only applies to this file, and not this project as a ++ * whole. ++ * ++ * a) This file is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation; either version 2 of the ++ * License, or (at your option) any later version. ++ * ++ * This file is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * Or, alternatively, ++ * ++ * b) Permission is hereby granted, free of charge, to any person ++ * obtaining a copy of this software and associated documentation ++ * files (the "Software"), to deal in the Software without ++ * restriction, including without limitation the rights to use, ++ * copy, modify, merge, publish, distribute, sublicense, and/or ++ * sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following ++ * conditions: ++ * ++ * The above copyright notice and this permission notice shall be ++ * included in all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES ++ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ++ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT ++ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, ++ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING ++ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ++ * OTHER DEALINGS IN THE SOFTWARE. ++ */ ++ ++/dts-v1/; ++ ++#include ++#include ++#include "rk3399.dtsi" ++#include "rk3399-linux.dtsi" ++#include "rk3399-opp.dtsi" ++ ++ ++/ { ++ model = "ROCK960"; ++ compatible = "96rocks,rock960", "rockchip,rk3399"; ++ ++ vcc1v8_s0: vcc1v8-s0 { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc1v8_s0"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-always-on; ++ }; ++ ++ vcc_sys: vcc-sys { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc_sys"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ regulator-always-on; ++ }; ++ ++ vcc_phy: vcc-phy-regulator { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc_phy"; ++ regulator-always-on; ++ regulator-boot-on; ++ }; ++ ++ vcc3v3_sys: vcc3v3-sys { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc3v3_sys"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-always-on; ++ vin-supply = <&vcc_sys>; ++ }; ++ ++ vcc3v3_pcie: vcc3v3-pcie-regulator { ++ compatible = "regulator-fixed"; ++ gpio = <&gpio3 11 GPIO_ACTIVE_LOW>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pcie_drv>; ++ regulator-boot-on; ++ regulator-always-on; ++ regulator-name = "vcc3v3_pcie"; ++ vin-supply = <&vcc3v3_sys>; ++ }; ++ ++ vcc5v0_host: vcc5v0-host-regulator { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpio = <&gpio4 25 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&host_vbus_drv>; ++ regulator-name = "vcc5v0_host"; ++ regulator-always-on; ++ }; ++ ++ vdd_log: vdd-log { ++ compatible = "pwm-regulator"; ++ pwms = <&pwm2 0 25000 1>; ++ regulator-name = "vdd_log"; ++ regulator-min-microvolt = <800000>; ++ regulator-max-microvolt = <1400000>; ++ regulator-always-on; ++ regulator-boot-on; ++ ++ /* for rockchip boot on */ ++ rockchip,pwm_id= <2>; ++ rockchip,pwm_voltage = <900000>; ++ ++ vin-supply = <&vcc_sys>; ++ }; ++ ++ clkin_gmac: external-gmac-clock { ++ compatible = "fixed-clock"; ++ clock-frequency = <125000000>; ++ clock-output-names = "clkin_gmac"; ++ #clock-cells = <0>; ++ }; ++ ++ hdmi-sound { ++ compatible = "simple-audio-card"; ++ simple-audio-card,format = "i2s"; ++ simple-audio-card,mclk-fs = <256>; ++ simple-audio-card,name = "HDMI"; ++ simple-audio-card,cpu { ++ sound-dai = <&i2s2>; ++ }; ++ simple-audio-card,codec { ++ sound-dai = <&hdmi>; ++ }; ++ }; ++ ++ spdif-sound { ++ compatible = "simple-audio-card"; ++ simple-audio-card,name = "SPDIF"; ++ simple-audio-card,cpu { ++ sound-dai = <&spdif>; ++ }; ++ simple-audio-card,codec { ++ sound-dai = <&spdif_out>; ++ }; ++ }; ++ ++ spdif_out: spdif-out { ++ compatible = "linux,spdif-dit"; ++ #sound-dai-cells = <0>; ++ }; ++ ++ sdio_pwrseq: sdio-pwrseq { ++ compatible = "mmc-pwrseq-simple"; ++ clocks = <&rk808 1>; ++ clock-names = "ext_clock"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&wifi_enable_h>; ++ post-power-on-delay-ms = <200>; ++ power-off-delay-us = <10>; ++ ++ /* ++ * On the module itself this is one of these (depending ++ * on the actual card populated): ++ * - SDIO_RESET_L_WL_REG_ON ++ * - PDN (power down when low) ++ */ ++ reset-gpios = <&gpio0 10 GPIO_ACTIVE_LOW>; ++ }; ++ ++ wireless-wlan { ++ compatible = "wlan-platdata"; ++ rockchip,grf = <&grf>; ++ wifi_chip_type = "ap6354"; ++ sdio_vref = <1800>; ++ WIFI,host_wake_irq = <&gpio0 3 GPIO_ACTIVE_HIGH>; ++ status = "okay"; ++ }; ++ ++ wireless-bluetooth { ++ compatible = "bluetooth-platdata"; ++ clocks = <&rk808 1>; ++ clock-names = "ext_clock"; ++ /* wifi-bt-power-toggle; */ ++ uart_rts_gpios = <&gpio2 19 GPIO_ACTIVE_LOW>; ++ pinctrl-names = "default", "rts_gpio"; ++ pinctrl-0 = <&uart0_rts>; ++ pinctrl-1 = <&uart0_gpios>; ++ /* BT,power_gpio = <&gpio3 19 GPIO_ACTIVE_HIGH>; */ ++ BT,reset_gpio = <&gpio0 9 GPIO_ACTIVE_HIGH>; ++ BT,wake_gpio = <&gpio2 27 GPIO_ACTIVE_HIGH>; ++ BT,wake_host_irq = <&gpio0 4 GPIO_ACTIVE_HIGH>; ++ status = "okay"; ++ }; ++ ++ test-power { ++ status = "okay"; ++ }; ++}; ++ ++&hdmi { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ #sound-dai-cells = <0>; ++ status = "okay"; ++}; ++ ++&sdmmc { ++ clock-frequency = <100000000>; ++ max-frequency = <100000000>; ++ supports-sd; ++ bus-width = <4>; ++ cap-mmc-highspeed; ++ cap-sd-highspeed; ++ disable-wp; ++ num-slots = <1>; ++ sd-uhs-sdr12; ++ sd-uhs-sdr25; ++ sd-uhs-sdr50; ++ sd-uhs-sdr104; ++ vqmmc-supply = <&vcc_sd>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd &sdmmc_bus4>; ++ card-detect-delay = <800>; ++ status = "okay"; ++}; ++ ++&sdio0 { ++ clock-frequency = <100000000>; ++ max-frequency = <100000000>; ++ supports-sdio; ++ bus-width = <4>; ++ disable-wp; ++ cap-sd-highspeed; ++ cap-sdio-irq; ++ keep-power-in-suspend; ++ mmc-pwrseq = <&sdio_pwrseq>; ++ non-removable; ++ num-slots = <1>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdio0_bus4 &sdio0_cmd &sdio0_clk>; ++ sd-uhs-sdr104; ++ status = "okay"; ++}; ++ ++&emmc_phy { ++ status = "okay"; ++}; ++ ++&sdhci { ++ bus-width = <8>; ++ mmc-hs400-1_8v; ++ supports-emmc; ++ non-removable; ++ mmc-hs400-enhanced-strobe; ++ status = "okay"; ++}; ++ ++&i2s0 { ++ status = "okay"; ++ rockchip,i2s-broken-burst-len; ++ rockchip,playback-channels = <8>; ++ rockchip,capture-channels = <8>; ++ #sound-dai-cells = <0>; ++}; ++ ++&i2s2 { ++ #sound-dai-cells = <0>; ++ rockchip,bclk-fs = <128>; ++ status = "okay"; ++}; ++ ++&spdif { ++ pinctrl-0 = <&spdif_bus_1>; ++ status = "okay"; ++ #sound-dai-cells = <0>; ++}; ++ ++&i2c0 { ++ status = "okay"; ++ i2c-scl-rising-time-ns = <168>; ++ i2c-scl-falling-time-ns = <4>; ++ clock-frequency = <400000>; ++ ++ vdd_cpu_b: syr827@40 { ++ compatible = "silergy,syr827"; ++ reg = <0x40>; ++ regulator-compatible = "fan53555-reg"; ++ pinctrl-0 = <&vsel1_gpio>; ++ vsel-gpios = <&gpio1 17 GPIO_ACTIVE_HIGH>; ++ regulator-name = "vdd_cpu_b"; ++ regulator-min-microvolt = <712500>; ++ regulator-max-microvolt = <1500000>; ++ regulator-ramp-delay = <1000>; ++ fcs,suspend-voltage-selector = <1>; ++ regulator-always-on; ++ regulator-boot-on; ++ vin-supply = <&vcc_sys>; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vdd_gpu: syr828@41 { ++ compatible = "silergy,syr828"; ++ reg = <0x41>; ++ regulator-compatible = "fan53555-reg"; ++ pinctrl-0 = <&vsel2_gpio>; ++ vsel-gpios = <&gpio1 14 GPIO_ACTIVE_HIGH>; ++ regulator-name = "vdd_gpu"; ++ regulator-min-microvolt = <712500>; ++ regulator-max-microvolt = <1500000>; ++ regulator-ramp-delay = <1000>; ++ fcs,suspend-voltage-selector = <1>; ++ regulator-always-on; ++ regulator-boot-on; ++ vin-supply = <&vcc_sys>; ++ regulator-initial-mode = <1>; /* 1:force PWM 2:auto */ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ rk808: pmic@1b { ++ compatible = "rockchip,rk808"; ++ reg = <0x1b>; ++ interrupt-parent = <&gpio1>; ++ interrupts = <21 IRQ_TYPE_LEVEL_LOW>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pmic_int_l>; ++ rockchip,system-power-controller; ++ wakeup-source; ++ #clock-cells = <1>; ++ clock-output-names = "xin32k", "rk808-clkout2"; ++ ++ vcc1-supply = <&vcc_sys>; ++ vcc2-supply = <&vcc_sys>; ++ vcc3-supply = <&vcc_sys>; ++ vcc4-supply = <&vcc_sys>; ++ vcc6-supply = <&vcc_sys>; ++ vcc7-supply = <&vcc_sys>; ++ vcc8-supply = <&vcc3v3_sys>; ++ vcc9-supply = <&vcc_sys>; ++ vcc10-supply = <&vcc_sys>; ++ vcc11-supply = <&vcc_sys>; ++ vcc12-supply = <&vcc3v3_sys>; ++ vddio-supply = <&vcc_1v8>; ++ ++ regulators { ++ vdd_center: DCDC_REG1 { ++ regulator-name = "vdd_center"; ++ regulator-min-microvolt = <750000>; ++ regulator-max-microvolt = <1350000>; ++ regulator-ramp-delay = <6001>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vdd_cpu_l: DCDC_REG2 { ++ regulator-name = "vdd_cpu_l"; ++ regulator-min-microvolt = <750000>; ++ regulator-max-microvolt = <1350000>; ++ regulator-ramp-delay = <6001>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcc_ddr: DCDC_REG3 { ++ regulator-name = "vcc_ddr"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ }; ++ }; ++ ++ vcc_1v8: DCDC_REG4 { ++ regulator-name = "vcc_1v8"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ vcc1v8_dvp: LDO_REG1 { ++ regulator-name = "vcc1v8_dvp"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ vcca1v8_hdmi: LDO_REG2 { ++ regulator-name = "vcca1v8_hdmi"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ vcca_1v8: LDO_REG3 { ++ regulator-name = "vcca_1v8"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ vcc_sd: LDO_REG4 { ++ regulator-name = "vcc_sd"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <3000000>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <3000000>; ++ }; ++ }; ++ ++ vcc3v0_sd: LDO_REG5 { ++ regulator-name = "vcc3v0_sd"; ++ regulator-min-microvolt = <3000000>; ++ regulator-max-microvolt = <3000000>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <3000000>; ++ }; ++ }; ++ ++ vcc_1v5: LDO_REG6 { ++ regulator-name = "vcc_1v5"; ++ regulator-min-microvolt = <1500000>; ++ regulator-max-microvolt = <1500000>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1500000>; ++ }; ++ }; ++ ++ vcca0v9_hdmi: LDO_REG7 { ++ regulator-name = "vcca0v9_hdmi"; ++ regulator-min-microvolt = <900000>; ++ regulator-max-microvolt = <900000>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <900000>; ++ }; ++ }; ++ ++ vcc_3v0: LDO_REG8 { ++ regulator-name = "vcc_3v0"; ++ regulator-min-microvolt = <3000000>; ++ regulator-max-microvolt = <3000000>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <3000000>; ++ }; ++ }; ++ ++ vcc3v3_s3: SWITCH_REG1 { ++ regulator-name = "vcc3v3_s3"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ }; ++ }; ++ ++ vcc3v3_s0: SWITCH_REG2 { ++ regulator-name = "vcc3v3_s0"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ }; ++ }; ++ }; ++ }; ++}; ++ ++&i2c1 { ++ status = "okay"; ++}; ++ ++&i2c6 { ++ status = "okay"; ++}; ++ ++&i2c4 { ++ status = "okay"; ++ fusb0: fusb30x@22 { ++ compatible = "fairchild,fusb302"; ++ reg = <0x22>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&fusb0_int>; ++ vbus-5v-gpios = <&gpio1 3 GPIO_ACTIVE_LOW>; ++ int-n-gpios = <&gpio1 2 GPIO_ACTIVE_HIGH>; ++ status = "okay"; ++ }; ++}; ++ ++&i2c2 { ++ status = "okay"; ++ camera0: camera-module@10 { ++ status = "disabled"; ++ compatible = "omnivision,ov13850-v4l2-i2c-subdev"; ++ reg = < 0x10 >; ++ device_type = "v4l2-i2c-subdev"; ++ clocks = <&cru SCLK_CIF_OUT>; ++ clock-names = "clk_cif_out"; ++ pinctrl-names = "rockchip,camera_default", ++ "rockchip,camera_sleep"; ++ pinctrl-0 = <&cam0_default_pins>; ++ pinctrl-1 = <&cam0_sleep_pins>; ++ //rockchip,pd-gpio = <&gpio4 4 GPIO_ACTIVE_LOW>; ++ rockchip,pwr-gpio = <&gpio4 4 GPIO_ACTIVE_HIGH>; ++ rockchip,rst-gpio = <&gpio3 29 GPIO_ACTIVE_LOW>; ++ rockchip,camera-module-mclk-name = "clk_cif_out"; ++ rockchip,camera-module-facing = "back"; ++ rockchip,camera-module-name = "cmk-cb0695-fv1"; ++ rockchip,camera-module-len-name = "lg9569a2"; ++ rockchip,camera-module-fov-h = "66.0"; ++ rockchip,camera-module-fov-v = "50.1"; ++ rockchip,camera-module-orientation = <0>; ++ rockchip,camera-module-iq-flip = <0>; ++ rockchip,camera-module-iq-mirror = <0>; ++ rockchip,camera-module-flip = <1>; ++ rockchip,camera-module-mirror = <0>; ++ ++ rockchip,camera-module-defrect0 = <2112 1568 0 0 2112 1568>; ++ rockchip,camera-module-defrect1 = <4224 3136 0 0 4224 3136>; ++ rockchip,camera-module-defrect3 = <3264 2448 0 0 3264 2448>; ++ rockchip,camera-module-flash-support = <1>; ++ rockchip,camera-module-mipi-dphy-index = <0>; ++ }; ++ ++ camera1: camera-module@36 { ++ status = "disabled"; ++ compatible = "omnivision,ov4690-v4l2-i2c-subdev"; ++ reg = <0x36>; ++ device_type = "v4l2-i2c-subdev"; ++ clocks = <&cru SCLK_CIF_OUT>; ++ clock-names = "clk_cif_out"; ++ pinctrl-names = "rockchip,camera_default", ++ "rockchip,camera_sleep"; ++ pinctrl-0 = <&cam0_default_pins>; ++ pinctrl-1 = <&cam0_sleep_pins>; ++ rockchip,pd-gpio = <&gpio3 4 GPIO_ACTIVE_LOW>; ++ //rockchip,pwr-gpio = <&gpio3 13 0>; ++ rockchip,rst-gpio = <&gpio2 10 GPIO_ACTIVE_LOW>; ++ rockchip,camera-module-mclk-name = "clk_cif_out"; ++ rockchip,camera-module-facing = "back"; ++ rockchip,camera-module-name = "LA6111PA"; ++ rockchip,camera-module-len-name = "YM6011P"; ++ rockchip,camera-module-fov-h = "116"; ++ rockchip,camera-module-fov-v = "61"; ++ rockchip,camera-module-orientation = <0>; ++ rockchip,camera-module-iq-flip = <0>; ++ rockchip,camera-module-iq-mirror = <0>; ++ rockchip,camera-module-flip = <0>; ++ rockchip,camera-module-mirror = <1>; ++ ++ rockchip,camera-module-defrect0 = <2688 1520 0 0 2688 1520>; ++ rockchip,camera-module-flash-support = <0>; ++ rockchip,camera-module-mipi-dphy-index = <0>; ++ }; ++ ++}; ++ ++&cpu_l0 { ++ cpu-supply = <&vdd_cpu_l>; ++}; ++ ++&cpu_l1 { ++ cpu-supply = <&vdd_cpu_l>; ++}; ++ ++&cpu_l2 { ++ cpu-supply = <&vdd_cpu_l>; ++}; ++ ++&cpu_l3 { ++ cpu-supply = <&vdd_cpu_l>; ++}; ++ ++&cpu_b0 { ++ cpu-supply = <&vdd_cpu_b>; ++}; ++ ++&cpu_b1 { ++ cpu-supply = <&vdd_cpu_b>; ++}; ++ ++&gpu { ++ status = "okay"; ++ mali-supply = <&vdd_gpu>; ++}; ++ ++&threshold { ++ temperature = <85000>; ++}; ++ ++&target { ++ temperature = <100000>; ++}; ++ ++&soc_crit { ++ temperature = <105000>; ++}; ++ ++&tcphy0 { ++ extcon = <&fusb0>; ++ status = "okay"; ++}; ++ ++&tcphy1 { ++ status = "okay"; ++}; ++ ++&tsadc { ++ /* tshut mode 0:CRU 1:GPIO */ ++ rockchip,hw-tshut-mode = <1>; ++ /* tshut polarity 0:LOW 1:HIGH */ ++ rockchip,hw-tshut-polarity = <1>; ++ rockchip,hw-tshut-temp = <110000>; ++ status = "okay"; ++}; ++ ++&u2phy0 { ++ status = "okay"; ++ extcon = <&fusb0>; ++ ++ u2phy0_otg: otg-port { ++ status = "okay"; ++ }; ++ ++ u2phy0_host: host-port { ++ phy-supply = <&vcc5v0_host>; ++ status = "okay"; ++ }; ++}; ++ ++&u2phy1 { ++ status = "okay"; ++ ++ u2phy1_otg: otg-port { ++ status = "okay"; ++ }; ++ ++ u2phy1_host: host-port { ++ phy-supply = <&vcc5v0_host>; ++ status = "okay"; ++ }; ++}; ++ ++&uart0 { ++ dmas = <&dmac_peri 0>, <&dmac_peri 1>; ++ dma-names = "tx", "rx"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart0_xfer &uart0_cts>; ++ status = "okay"; ++}; ++ ++&uart2 { ++ status = "okay"; ++}; ++ ++&uart3 { ++ dmas = <&dmac_peri 6>, <&dmac_peri 7>; ++ dma-names = "tx", "rx"; ++ status = "okay"; ++}; ++ ++&uart4 { ++ dmas = <&dmac_peri 8>, <&dmac_peri 9>; ++ dma-names = "tx", "rx"; ++ status = "okay"; ++}; ++ ++&usb_host0_ehci { ++ status = "okay"; ++}; ++ ++&usb_host0_ohci { ++ status = "okay"; ++}; ++ ++&usb_host1_ehci { ++ status = "okay"; ++}; ++ ++&usb_host1_ohci { ++ status = "okay"; ++}; ++ ++&usbdrd3_0 { ++ extcon = <&fusb0>; ++ status = "okay"; ++}; ++ ++&usbdrd_dwc3_0 { ++ dr_mode = "otg"; ++ status = "okay"; ++}; ++ ++&usbdrd3_1 { ++ status = "okay"; ++}; ++ ++&usbdrd_dwc3_1 { ++ dr_mode = "host"; ++ status = "okay"; ++}; ++ ++&pwm2 { ++ status = "okay"; ++}; ++ ++&gmac { ++ phy-supply = <&vcc_phy>; ++ phy-mode = "rgmii"; ++ clock_in_out = "input"; ++ snps,reset-gpio = <&gpio3 15 GPIO_ACTIVE_LOW>; ++ snps,reset-active-low; ++ snps,reset-delays-us = <0 10000 50000>; ++ assigned-clocks = <&cru SCLK_RMII_SRC>; ++ assigned-clock-parents = <&clkin_gmac>; ++ pinctrl-names = "default", "sleep"; ++ pinctrl-0 = <&rgmii_pins>; ++ pinctrl-1 = <&rgmii_sleep_pins>; ++ tx_delay = <0x28>; ++ rx_delay = <0x11>; ++ status = "disabled"; ++}; ++ ++&saradc { ++ status = "okay"; ++}; ++ ++&iep { ++ status = "okay"; ++}; ++ ++&iep_mmu { ++ status = "okay"; ++}; ++ ++&io_domains { ++ status = "okay"; ++ ++ bt656-supply = <&vcc1v8_s0>; /* bt656_gpio2ab_ms */ ++ audio-supply = <&vcc1v8_s0>; /* audio_gpio3d4a_ms */ ++ sdmmc-supply = <&vcc_sd>; /* sdmmc_gpio4b_ms */ ++ gpio1830-supply = <&vcc_3v0>; /* gpio1833_gpio4cd_ms */ ++}; ++ ++&pcie_phy { ++ status = "okay"; ++}; ++ ++&pcie0 { ++ ep-gpios = <&gpio3 9 GPIO_ACTIVE_HIGH>; ++ num-lanes = <4>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pcie_clkreqn_cpm>; ++ status = "okay"; ++}; ++ ++&pinctrl { ++ ++ sdio0 { ++ sdio0_bus1: sdio0-bus1 { ++ rockchip,pins = ++ <2 20 RK_FUNC_1 &pcfg_pull_up_20ma>; ++ }; ++ ++ sdio0_bus4: sdio0-bus4 { ++ rockchip,pins = ++ <2 20 RK_FUNC_1 &pcfg_pull_up_20ma>, ++ <2 21 RK_FUNC_1 &pcfg_pull_up_20ma>, ++ <2 22 RK_FUNC_1 &pcfg_pull_up_20ma>, ++ <2 23 RK_FUNC_1 &pcfg_pull_up_20ma>; ++ }; ++ ++ sdio0_cmd: sdio0-cmd { ++ rockchip,pins = ++ <2 24 RK_FUNC_1 &pcfg_pull_up_20ma>; ++ }; ++ ++ sdio0_clk: sdio0-clk { ++ rockchip,pins = ++ <2 25 RK_FUNC_1 &pcfg_pull_none_20ma>; ++ }; ++ }; ++ ++ sdmmc { ++ sdmmc_bus1: sdmmc-bus1 { ++ rockchip,pins = ++ <4 8 RK_FUNC_1 &pcfg_pull_up_8ma>; ++ }; ++ ++ sdmmc_bus4: sdmmc-bus4 { ++ rockchip,pins = ++ <4 8 RK_FUNC_1 &pcfg_pull_up_8ma>, ++ <4 9 RK_FUNC_1 &pcfg_pull_up_8ma>, ++ <4 10 RK_FUNC_1 &pcfg_pull_up_8ma>, ++ <4 11 RK_FUNC_1 &pcfg_pull_up_8ma>; ++ }; ++ ++ sdmmc_clk: sdmmc-clk { ++ rockchip,pins = ++ <4 12 RK_FUNC_1 &pcfg_pull_none_18ma>; ++ }; ++ ++ sdmmc_cmd: sdmmc-cmd { ++ rockchip,pins = ++ <4 13 RK_FUNC_1 &pcfg_pull_up_8ma>; ++ }; ++ }; ++ ++ sdio-pwrseq { ++ wifi_enable_h: wifi-enable-h { ++ rockchip,pins = ++ <0 9 RK_FUNC_GPIO &pcfg_pull_none>, ++ <0 10 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ wireless-bluetooth { ++ uart0_gpios: uart0-gpios { ++ rockchip,pins = ++ <2 19 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ usb2 { ++ host_vbus_drv: host-vbus-drv { ++ rockchip,pins = ++ <4 25 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ pcie { ++ pcie_drv: pcie-drv { ++ rockchip,pins = ++ <3 11 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ pmic { ++ pmic_int_l: pmic-int-l { ++ rockchip,pins = ++ <1 21 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ ++ vsel1_gpio: vsel1-gpio { ++ rockchip,pins = ++ <1 17 RK_FUNC_GPIO &pcfg_pull_down>; ++ }; ++ ++ vsel2_gpio: vsel2-gpio { ++ rockchip,pins = ++ <1 14 RK_FUNC_GPIO &pcfg_pull_down>; ++ }; ++ }; ++ ++ gmac { ++ rgmii_sleep_pins: rgmii-sleep-pins { ++ rockchip,pins = ++ <3 15 RK_FUNC_GPIO &pcfg_output_low>; ++ }; ++ }; ++ ++ fusb30x { ++ fusb0_int: fusb0-int { ++ rockchip,pins = ++ <1 2 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ }; ++}; ++ ++&pvtm { ++ status = "okay"; ++}; ++ ++&pmu_pvtm { ++ status = "okay"; ++}; ++ ++&pmu_io_domains { ++ status = "okay"; ++ pmu1830-supply = <&vcc_1v8>; ++}; ++ ++&rockchip_suspend { ++ status = "okay"; ++ rockchip,sleep-debug-en = <0>; ++ rockchip,sleep-mode-config = < ++ (0 ++ | RKPM_SLP_ARMPD ++ | RKPM_SLP_PERILPPD ++ | RKPM_SLP_DDR_RET ++ | RKPM_SLP_PLLPD ++ | RKPM_SLP_CENTER_PD ++ | RKPM_SLP_AP_PWROFF ++ ) ++ >; ++ rockchip,wakeup-config = < ++ (0 ++ | RKPM_GPIO_WKUP_EN ++ | RKPM_PWM_WKUP_EN ++ ) ++ >; ++ rockchip,pwm-regulator-config = < ++ (0 ++ | PWM2_REGULATOR_EN ++ ) ++ >; ++ rockchip,power-ctrl = ++ <&gpio1 17 GPIO_ACTIVE_HIGH>, ++ <&gpio1 14 GPIO_ACTIVE_HIGH>; ++}; ++ ++&vopb { ++ status = "okay"; ++}; ++ ++&vopb_mmu { ++ status = "okay"; ++}; ++ ++&cif_isp0 { ++ rockchip,camera-modules-attached = <&camera0>; ++ status = "okay"; ++}; ++ ++&isp0_mmu { ++ status = "okay"; ++}; ++ ++&cif_isp1 { ++ rockchip,camera-modules-attached = <&camera1>; ++ status = "disabled"; ++}; ++ ++&isp1_mmu { ++ status = "okay"; ++}; ++ ++&vpu { ++ status = "okay"; ++ /* 0 means ion, 1 means drm */ ++ //allocator = <0>; ++}; ++ ++&rkvdec { ++ status = "okay"; ++ /* 0 means ion, 1 means drm */ ++ //allocator = <0>; ++}; ++ ++&display_subsystem { ++ status = "okay"; ++}; + +From 493cb1d1e8ae9aeafe0a008039fb03fe7f441c8b Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 28 Jan 2018 15:38:32 +0100 +Subject: [PATCH] arm: dts: rk3288: add cec clock and pinctrl + +--- + arch/arm/boot/dts/rk3288.dtsi | 16 +++++++++++++--- + 1 file changed, 13 insertions(+), 3 deletions(-) + +diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi +index 9cca69f9f5ba..2141eb23faa7 100644 +--- a/arch/arm/boot/dts/rk3288.dtsi ++++ b/arch/arm/boot/dts/rk3288.dtsi +@@ -981,7 +981,8 @@ + <&cru PCLK_MIPI_DSI1>, + <&cru SCLK_EDP_24M>, + <&cru SCLK_EDP>, + <&cru SCLK_HDMI_CEC>, ++ <&cru SCLK_HDMI_HDCP>, + <&cru SCLK_ISP_JPE>, + <&cru SCLK_ISP>, + <&cru SCLK_RGA>; +@@ -1966,6 +1968,14 @@ + &pcfg_pull_none>; + }; + ++ hdmi_cec_c0: hdmi-cec-c0 { ++ rockchip,pins = <7 16 RK_FUNC_2 &pcfg_pull_none>; ++ }; ++ ++ hdmi_cec_c7: hdmi-cec-c7 { ++ rockchip,pins = <7 23 RK_FUNC_4 &pcfg_pull_none>; ++ }; ++ + hdmi_ddc: hdmi-ddc { + rockchip,pins = <7 19 RK_FUNC_2 &pcfg_pull_none>, + <7 20 RK_FUNC_2 &pcfg_pull_none>; + +@@ -1660,7 +1660,7 @@ + clocks = <&cru PCLK_HDMI_CTRL>, <&cru SCLK_HDMI_HDCP>, <&cru SCLK_HDMI_CEC>; + clock-names = "iahb", "isfr", "cec"; + pinctrl-names = "default", "sleep"; +- pinctrl-0 = <&hdmi_ddc>; ++ pinctrl-0 = <&hdmi_ddc &hdmi_cec_c0>; + pinctrl-1 = <&hdmi_gpio>; + power-domains = <&power RK3288_PD_VIO>; + status = "disabled"; +@@ -2050,10 +2050,6 @@ + &pcfg_pull_none>; + }; + +- hdmi_cec: hdmi-cec { +- rockchip,pins = <7 16 RK_FUNC_2 &pcfg_pull_none>; +- }; +- + hdmi_cec_c0: hdmi-cec-c0 { + rockchip,pins = <7 16 RK_FUNC_2 &pcfg_pull_none>; + }; + +From d7b647f6bb133b0ee27d759900516c1750c268fe Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 4 Mar 2018 09:08:35 +0100 +Subject: [PATCH] arm64: dts: rockchip: add rk3328-box-trn9 board + +--- + arch/arm64/boot/dts/rockchip/rk3328-box-trn9.dts | 675 +++++++++++++++++++++++ + 1 file changed, 675 insertions(+) + create mode 100644 arch/arm64/boot/dts/rockchip/rk3328-box-trn9.dts + +diff --git a/arch/arm64/boot/dts/rockchip/rk3328-box-trn9.dts b/arch/arm64/boot/dts/rockchip/rk3328-box-trn9.dts +new file mode 100644 +index 000000000000..51d471ba8cef +--- /dev/null ++++ b/arch/arm64/boot/dts/rockchip/rk3328-box-trn9.dts +@@ -0,0 +1,675 @@ ++/* ++ * Copyright (c) 2017 Fuzhou Rockchip Electronics Co., Ltd ++ * ++ * This file is dual-licensed: you can use it either under the terms ++ * of the GPL or the X11 license, at your option. Note that this dual ++ * licensing only applies to this file, and not this project as a ++ * whole. ++ * ++ * a) This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation; either version 2 of the ++ * License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * Or, alternatively, ++ * ++ * b) Permission is hereby granted, free of charge, to any person ++ * obtaining a copy of this software and associated documentation ++ * files (the "Software"), to deal in the Software without ++ * restriction, including without limitation the rights to use, ++ * copy, modify, merge, publish, distribute, sublicense, and/or ++ * sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following ++ * conditions: ++ * ++ * The above copyright notice and this permission notice shall be ++ * included in all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES ++ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ++ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT ++ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, ++ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING ++ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ++ * OTHER DEALINGS IN THE SOFTWARE. ++ */ ++ ++/dts-v1/; ++#include "rk3328.dtsi" ++ ++/ { ++ model = "Rockchip RK3328 TRN9"; ++ compatible = "rockchip,rk3328-box-trn9", "rockchip,rk3328"; ++ ++ chosen { ++ bootargs = "swiotlb=1 kpti=0"; ++ }; ++ ++ aliases { ++ serial0 = &uart2; ++ serial2 = &uart0; ++ }; ++ ++ xin32k: xin32k { ++ compatible = "fixed-clock"; ++ clock-frequency = <32768>; ++ clock-output-names = "xin32k"; ++ #clock-cells = <0>; ++ }; ++ ++ gmac_clkin: external-gmac-clock { ++ compatible = "fixed-clock"; ++ clock-frequency = <125000000>; ++ clock-output-names = "gmac_clkin"; ++ #clock-cells = <0>; ++ }; ++ ++ vcc_phy: vcc-phy-regulator { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc_phy"; ++ regulator-always-on; ++ regulator-boot-on; ++ }; ++ ++ vcc_sys: vcc-sys { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc_sys"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ }; ++ ++ vcc_sd: sdmmc-regulator { ++ compatible = "regulator-fixed"; ++ gpio = <&gpio0 RK_PD6 GPIO_ACTIVE_LOW>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdmmc0m1_gpio>; ++ regulator-name = "vcc_sd"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ vin-supply = <&vcc_io>; ++ }; ++ ++ vcc_host_5v: vcc-host-5v-regulator { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpio = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&usb30_host_drv>; ++ regulator-name = "vcc_host_5v"; ++ regulator-always-on; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ vin-supply = <&vcc_sys>; ++ }; ++ ++ vcc_host1_5v: vcc_otg_5v: vcc-host1-5v-regulator { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpio = <&gpio0 RK_PA2 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&usb20_host_drv>; ++ regulator-name = "vcc_host1_5v"; ++ regulator-always-on; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ vin-supply = <&vcc_sys>; ++ }; ++ ++ leds { ++ compatible = "gpio-leds"; ++ ++ power { ++ gpios = <&rk805 0 GPIO_ACTIVE_LOW>; ++ linux,default-trigger = "default-on"; ++ default-state = "on"; ++ }; ++ }; ++ ++ ir-receiver { ++ compatible = "gpio-ir-receiver"; ++ gpios = <&gpio2 RK_PA2 GPIO_ACTIVE_LOW>; ++ linux,rc-map-name = "rc-trn9"; ++ pinctrl-0 = <&ir_int>; ++ pinctrl-names = "default"; ++ }; ++ ++ hdmi-sound { ++ compatible = "simple-audio-card"; ++ simple-audio-card,format = "i2s"; ++ simple-audio-card,mclk-fs = <128>; ++ simple-audio-card,name = "HDMI"; ++ simple-audio-card,cpu { ++ sound-dai = <&i2s0>; ++ }; ++ simple-audio-card,codec { ++ sound-dai = <&hdmi>; ++ }; ++ }; ++ ++ sound { ++ compatible = "simple-audio-card"; ++ simple-audio-card,format = "i2s"; ++ simple-audio-card,mclk-fs = <256>; ++ simple-audio-card,name = "I2S"; ++ simple-audio-card,cpu { ++ sound-dai = <&i2s1>; ++ }; ++ simple-audio-card,codec { ++ sound-dai = <&codec>; ++ }; ++ }; ++ ++ spdif-sound { ++ compatible = "simple-audio-card"; ++ simple-audio-card,name = "SPDIF"; ++ simple-audio-card,cpu { ++ sound-dai = <&spdif>; ++ }; ++ simple-audio-card,codec { ++ sound-dai = <&spdif_out>; ++ }; ++ }; ++ ++ spdif_out: spdif-out { ++ compatible = "linux,spdif-dit"; ++ #sound-dai-cells = <0>; ++ }; ++ ++ sdio_pwrseq: sdio-pwrseq { ++ compatible = "mmc-pwrseq-simple"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&wifi_enable_h>; ++ ++ /* ++ * On the module itself this is one of these (depending ++ * on the actual card populated): ++ * - SDIO_RESET_L_WL_REG_ON ++ * - PDN (power down when low) ++ */ ++ reset-gpios = <&gpio3 RK_PB0 GPIO_ACTIVE_LOW>; ++ }; ++ ++ wireless-bluetooth { ++ compatible = "bluetooth-platdata"; ++ BT,power_gpio = <&gpio1 RK_PD0 GPIO_ACTIVE_HIGH>; ++ BT,wake_host_irq = <&gpio1 RK_PD2 GPIO_ACTIVE_HIGH>; ++ }; ++ ++ wireless-wlan { ++ compatible = "wlan-platdata"; ++ rockchip,grf = <&grf>; ++ wifi_chip_type = "rtl8723bs"; ++ WIFI,host_wake_irq = <&gpio3 RK_PA1 GPIO_ACTIVE_HIGH>; ++ }; ++}; ++ ++&codec { ++ #sound-dai-cells = <0>; ++ status = "okay"; ++}; ++ ++&cpu0 { ++ cpu-supply = <&vdd_arm>; ++}; ++ ++&cpu1 { ++ cpu-supply = <&vdd_arm>; ++}; ++ ++&cpu2 { ++ cpu-supply = <&vdd_arm>; ++}; ++ ++&cpu3 { ++ cpu-supply = <&vdd_arm>; ++}; ++ ++&dfi { ++ status = "okay"; ++}; ++ ++&dmc { ++ center-supply = <&vdd_logic>; ++ status = "okay"; ++}; ++ ++&display_subsystem { ++ status = "okay"; ++}; ++ ++&emmc { ++ bus-width = <8>; ++ cap-mmc-highspeed; ++ mmc-hs200-1_8v; ++ non-removable; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>; ++ supports-emmc; ++ vmmc-supply = <&vcc_io>; ++ vqmmc-supply = <&vcc18_emmc>; ++ status = "okay"; ++}; ++ ++&gmac2io { ++ assigned-clocks = <&cru SCLK_MAC2IO>, <&cru SCLK_MAC2IO_EXT>; ++ assigned-clock-parents = <&gmac_clkin>, <&gmac_clkin>; ++ clock_in_out = "input"; ++ phy-supply = <&vcc_phy>; ++ phy-mode = "rgmii"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&rgmiim1_pins>; ++ snps,reset-gpio = <&gpio1 RK_PC2 GPIO_ACTIVE_LOW>; ++ snps,reset-active-low; ++ snps,reset-delays-us = <0 10000 50000>; ++ tx_delay = <0x26>; ++ rx_delay = <0x11>; ++ status = "okay"; ++}; ++ ++&gmac2phy { ++ phy-supply = <&vcc_phy>; ++ assigned-clocks = <&cru SCLK_MAC2PHY_SRC>; ++ assigned-clock-rate = <50000000>; ++ assigned-clocks = <&cru SCLK_MAC2PHY>; ++ assigned-clock-parents = <&cru SCLK_MAC2PHY_SRC>; ++ clock_in_out = "output"; ++ status = "disabled"; ++}; ++ ++&gpu { ++ status = "okay"; ++ mali-supply = <&vdd_logic>; ++}; ++ ++&h265e { ++ status = "okay"; ++}; ++ ++&h265e_mmu { ++ status = "okay"; ++}; ++ ++&hdmi { ++ #sound-dai-cells = <0>; ++ ddc-i2c-scl-high-time-ns = <9625>; ++ ddc-i2c-scl-low-time-ns = <10000>; ++ status = "okay"; ++}; ++ ++&hdmiphy { ++ status = "okay"; ++}; ++ ++&i2c1 { ++ status = "okay"; ++ ++ rk805: rk805@18 { ++ compatible = "rockchip,rk805"; ++ status = "okay"; ++ reg = <0x18>; ++ interrupt-parent = <&gpio2>; ++ interrupts = <6 IRQ_TYPE_LEVEL_LOW>; ++ #clock-cells = <1>; ++ clock-output-names = "rk805-clkout1", "rk805-clkout2"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pmic_int_l>; ++ rockchip,system-power-controller; ++ wakeup-source; ++ gpio-controller; ++ #gpio-cells = <2>; ++ ++ vcc1-supply = <&vcc_sys>; ++ vcc2-supply = <&vcc_sys>; ++ vcc3-supply = <&vcc_sys>; ++ vcc4-supply = <&vcc_sys>; ++ vcc5-supply = <&vcc_io>; ++ vcc6-supply = <&vcc_sys>; ++ ++ rtc { ++ status = "okay"; ++ }; ++ ++ pwrkey { ++ status = "okay"; ++ }; ++ ++ gpio { ++ status = "okay"; ++ }; ++ ++ regulators { ++ compatible = "rk805-regulator"; ++ status = "okay"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ vdd_logic: RK805_DCDC1 { ++ regulator-compatible = "RK805_DCDC1"; ++ regulator-name = "vdd_logic"; ++ regulator-min-microvolt = <712500>; ++ regulator-max-microvolt = <1450000>; ++ regulator-initial-mode = <0x1>; ++ regulator-ramp-delay = <12500>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-mode = <0x2>; ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1000000>; ++ }; ++ }; ++ ++ vdd_arm: RK805_DCDC2 { ++ regulator-compatible = "RK805_DCDC2"; ++ regulator-name = "vdd_arm"; ++ regulator-init-microvolt = <1225000>; ++ regulator-min-microvolt = <712500>; ++ regulator-max-microvolt = <1450000>; ++ regulator-initial-mode = <0x1>; ++ regulator-ramp-delay = <12500>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-mode = <0x2>; ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <950000>; ++ }; ++ }; ++ ++ vcc_ddr: RK805_DCDC3 { ++ regulator-compatible = "RK805_DCDC3"; ++ regulator-name = "vcc_ddr"; ++ regulator-initial-mode = <0x1>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-mode = <0x2>; ++ regulator-on-in-suspend; ++ }; ++ }; ++ ++ vcc_io: RK805_DCDC4 { ++ regulator-compatible = "RK805_DCDC4"; ++ regulator-name = "vcc_io"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-initial-mode = <0x1>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-mode = <0x2>; ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <3300000>; ++ }; ++ }; ++ ++ vcc_18: RK805_LDO1 { ++ regulator-compatible = "RK805_LDO1"; ++ regulator-name = "vcc_18"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ vcc18_emmc: RK805_LDO2 { ++ regulator-compatible = "RK805_LDO2"; ++ regulator-name = "vcc18_emmc"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ vdd_10: RK805_LDO3 { ++ regulator-compatible = "RK805_LDO3"; ++ regulator-name = "vdd_10"; ++ regulator-min-microvolt = <1000000>; ++ regulator-max-microvolt = <1000000>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1000000>; ++ }; ++ }; ++ }; ++ }; ++}; ++ ++&i2s0 { ++ #sound-dai-cells = <0>; ++ rockchip,bclk-fs = <128>; ++ status = "okay"; ++}; ++ ++&i2s1 { ++ #sound-dai-cells = <0>; ++ status = "okay"; ++}; ++ ++&iep { ++ status = "okay"; ++}; ++ ++&iep_mmu { ++ status = "okay"; ++}; ++ ++&io_domains { ++ status = "okay"; ++ ++ vccio1-supply = <&vcc_io>; ++ vccio2-supply = <&vcc18_emmc>; ++ vccio3-supply = <&vcc_io>; ++ vccio4-supply = <&vcc_18>; ++ vccio5-supply = <&vcc_io>; ++ vccio6-supply = <&vcc_18>; ++ pmuio-supply = <&vcc_io>; ++}; ++ ++&pinctrl { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&clk_32k_out>; ++ ++ clk_32k { ++ clk_32k_out: clk-32k-out { ++ rockchip,pins = <1 RK_PD4 RK_FUNC_1 &pcfg_pull_none>; ++ }; ++ }; ++ ++ ir { ++ ir_int: ir-int { ++ rockchip,pins = <2 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ pmic { ++ pmic_int_l: pmic-int-l { ++ rockchip,pins = <2 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ }; ++ ++ sdio-pwrseq { ++ wifi_enable_h: wifi-enable-h { ++ rockchip,pins = <3 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>, ++ <3 RK_PA1 RK_FUNC_GPIO &pcfg_pull_none_4ma>, ++ <1 RK_PD0 RK_FUNC_GPIO &pcfg_pull_none>, ++ <1 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ usb2 { ++ usb20_host_drv: usb20-host-drv { ++ rockchip,pins = <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ usb3 { ++ usb30_host_drv: usb30-host-drv { ++ rockchip,pins = <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++}; ++ ++&rkvdec { ++ status = "okay"; ++ vcodec-supply = <&vdd_logic>; ++}; ++ ++&rkvdec_mmu { ++ status = "okay"; ++}; ++ ++&sdmmc_ext { ++ bus-width = <4>; ++ cap-sd-highspeed; ++ cap-sdio-irq; ++ disable-wp; ++ keep-power-in-suspend; ++ mmc-pwrseq = <&sdio_pwrseq>; ++ non-removable; ++ num-slots = <1>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdmmc0ext_bus4 &sdmmc0ext_cmd &sdmmc0ext_clk>; ++ sd-uhs-sdr104; ++ supports-sdio; ++ status = "okay"; ++}; ++ ++&sdmmc { ++ bus-width = <4>; ++ cap-mmc-highspeed; ++ cap-sd-highspeed; ++ disable-wp; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdmmc0_clk &sdmmc0_cmd &sdmmc0_dectn &sdmmc0_bus4>; ++ supports-sd; ++ vmmc-supply = <&vcc_sd>; ++ status = "okay"; ++}; ++ ++&spdif { ++ #sound-dai-cells = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spdifm0_tx>; ++ status = "okay"; ++}; ++ ++&threshold { ++ temperature = <80000>; /* millicelsius */ ++}; ++ ++&target { ++ temperature = <95000>; /* millicelsius */ ++}; ++ ++&soc_crit { ++ temperature = <100000>; /* millicelsius */ ++}; ++ ++&tsadc { ++ rockchip,hw-tshut-mode = <0>; ++ rockchip,hw-tshut-polarity = <0>; ++ rockchip,hw-tshut-temp = <110000>; ++ status = "okay"; ++}; ++ ++&uart2 { ++ status = "okay"; ++}; ++ ++&u2phy { ++ status = "okay"; ++}; ++ ++&u2phy_host { ++ phy-supply = <&vcc_host1_5v>; ++ status = "okay"; ++}; ++ ++&u2phy_otg { ++ phy-supply = <&vcc_otg_5v>; ++ status = "okay"; ++}; ++ ++&u3phy { ++ status = "okay"; ++}; ++ ++&u3phy_utmi { ++ phy-supply = <&vcc_host_5v>; ++ status = "okay"; ++}; ++ ++&u3phy_pipe { ++ phy-supply = <&vcc_host_5v>; ++ status = "okay"; ++}; ++ ++&usb20_otg { ++ dr_mode = "host"; ++ status = "okay"; ++}; ++ ++&usb_host0_ehci { ++ status = "okay"; ++}; ++ ++&usb_host0_ohci { ++ status = "okay"; ++}; ++ ++&usbdrd3 { ++ status = "okay"; ++}; ++ ++&usbdrd_dwc3 { ++ status = "okay"; ++}; ++ ++&vop { ++ status = "okay"; ++}; ++ ++&vop_mmu { ++ status = "okay"; ++}; ++ ++&vpu_service { ++ status = "okay"; ++}; ++ ++&vpu_mmu { ++ status = "okay"; ++}; ++ ++&vepu { ++ status = "okay"; ++}; ++ ++&vepu_mmu { ++ status = "okay"; ++}; ++ ++&venc_srv { ++ status = "okay"; ++}; + +From 9c8d6637e4223718bdefacb33c32ffd1b386a343 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 4 Mar 2018 09:08:35 +0100 +Subject: [PATCH] arm64: dts: rockchip: add rk3328-box-z28 board + +--- + arch/arm64/boot/dts/rockchip/rk3328-box-z28.dts | 598 ++++++++++++++++++++++++ + 1 file changed, 598 insertions(+) + create mode 100644 arch/arm64/boot/dts/rockchip/rk3328-box-z28.dts + +diff --git a/arch/arm64/boot/dts/rockchip/rk3328-box-z28.dts b/arch/arm64/boot/dts/rockchip/rk3328-box-z28.dts +new file mode 100644 +index 000000000000..00a3394cefcb +--- /dev/null ++++ b/arch/arm64/boot/dts/rockchip/rk3328-box-z28.dts +@@ -0,0 +1,598 @@ ++/* ++ * Copyright (c) 2017 Fuzhou Rockchip Electronics Co., Ltd ++ * ++ * This file is dual-licensed: you can use it either under the terms ++ * of the GPL or the X11 license, at your option. Note that this dual ++ * licensing only applies to this file, and not this project as a ++ * whole. ++ * ++ * a) This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation; either version 2 of the ++ * License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * Or, alternatively, ++ * ++ * b) Permission is hereby granted, free of charge, to any person ++ * obtaining a copy of this software and associated documentation ++ * files (the "Software"), to deal in the Software without ++ * restriction, including without limitation the rights to use, ++ * copy, modify, merge, publish, distribute, sublicense, and/or ++ * sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following ++ * conditions: ++ * ++ * The above copyright notice and this permission notice shall be ++ * included in all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES ++ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ++ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT ++ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, ++ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING ++ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ++ * OTHER DEALINGS IN THE SOFTWARE. ++ */ ++ ++/dts-v1/; ++#include "rk3328.dtsi" ++ ++/ { ++ model = "Rockchip RK3328 Z28"; ++ compatible = "rockchip,rk3328-box-z28", "rockchip,rk3328"; ++ ++ chosen { ++ bootargs = "earlyprintk=uart8250-32bit,0xff130000 swiotlb=1 kpti=0"; ++ stdout-path = "serial2:1500000n8"; ++ }; ++ ++ xin32k: xin32k { ++ compatible = "fixed-clock"; ++ clock-frequency = <32768>; ++ clock-output-names = "xin32k"; ++ #clock-cells = <0>; ++ }; ++ ++ vcc_phy: vcc-phy-regulator { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc_phy"; ++ regulator-always-on; ++ regulator-boot-on; ++ }; ++ ++ vcc_sys: vcc-sys { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc_sys"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ }; ++ ++ vcc_sd: sdmmc-regulator { ++ compatible = "regulator-fixed"; ++ gpio = <&gpio0 RK_PD6 GPIO_ACTIVE_LOW>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdmmc0m1_gpio>; ++ regulator-name = "vcc_sd"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ vin-supply = <&vcc_io>; ++ }; ++ ++ vcc_host_5v: vcc-host-5v-regulator { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpio = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&usb30_host_drv>; ++ regulator-name = "vcc_host_5v"; ++ regulator-always-on; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ vin-supply = <&vcc_sys>; ++ }; ++ ++ vcc_host1_5v: vcc_otg_5v: vcc-host1-5v-regulator { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpio = <&gpio0 RK_PA2 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&usb20_host_drv>; ++ regulator-name = "vcc_host1_5v"; ++ regulator-always-on; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ vin-supply = <&vcc_sys>; ++ }; ++ ++ leds { ++ compatible = "gpio-leds"; ++ ++ power { ++ gpios = <&rk805 0 GPIO_ACTIVE_HIGH>; ++ linux,default-trigger = "default-on"; ++ default-state = "on"; ++ }; ++ }; ++ ++ ir-receiver { ++ compatible = "gpio-ir-receiver"; ++ gpios = <&gpio2 RK_PA2 GPIO_ACTIVE_LOW>; ++ pinctrl-0 = <&ir_int>; ++ pinctrl-names = "default"; ++ }; ++ ++ hdmi-sound { ++ compatible = "simple-audio-card"; ++ simple-audio-card,format = "i2s"; ++ simple-audio-card,mclk-fs = <128>; ++ simple-audio-card,name = "HDMI"; ++ simple-audio-card,cpu { ++ sound-dai = <&i2s0>; ++ }; ++ simple-audio-card,codec { ++ sound-dai = <&hdmi>; ++ }; ++ }; ++ ++ spdif-sound { ++ compatible = "simple-audio-card"; ++ simple-audio-card,name = "SPDIF"; ++ simple-audio-card,cpu { ++ sound-dai = <&spdif>; ++ }; ++ simple-audio-card,codec { ++ sound-dai = <&spdif_out>; ++ }; ++ }; ++ ++ spdif_out: spdif-out { ++ compatible = "linux,spdif-dit"; ++ #sound-dai-cells = <0>; ++ }; ++ ++ wireless-bluetooth { ++ compatible = "bluetooth-platdata"; ++ BT,power_gpio = <&gpio2 RK_PC5 GPIO_ACTIVE_HIGH>; ++ BT,wake_host_irq = <&gpio2 RK_PC0 GPIO_ACTIVE_HIGH>; ++ }; ++ ++ wireless-wlan { ++ compatible = "wlan-platdata"; ++ rockchip,grf = <&grf>; ++ wifi_chip_type = "rtl8188eu"; ++ WIFI,poweren_gpio = <&gpio2 RK_PC3 GPIO_ACTIVE_HIGH>; ++ WIFI,reset_gpio = <&gpio2 RK_PC4 GPIO_ACTIVE_HIGH>; ++ WIFI,host_wake_irq = <&gpio2 RK_PC6 GPIO_ACTIVE_HIGH>; ++ }; ++}; ++ ++&codec { ++ #sound-dai-cells = <0>; ++ status = "okay"; ++}; ++ ++&cpu0 { ++ cpu-supply = <&vdd_arm>; ++}; ++ ++&cpu1 { ++ cpu-supply = <&vdd_arm>; ++}; ++ ++&cpu2 { ++ cpu-supply = <&vdd_arm>; ++}; ++ ++&cpu3 { ++ cpu-supply = <&vdd_arm>; ++}; ++ ++&dfi { ++ status = "okay"; ++}; ++ ++&dmc { ++ center-supply = <&vdd_logic>; ++ status = "okay"; ++}; ++ ++&display_subsystem { ++ status = "okay"; ++}; ++ ++&emmc { ++ bus-width = <8>; ++ cap-mmc-highspeed; ++ mmc-hs200-1_8v; ++ non-removable; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>; ++ supports-emmc; ++ vmmc-supply = <&vcc_io>; ++ vqmmc-supply = <&vcc18_emmc>; ++ status = "okay"; ++}; ++ ++&gmac2phy { ++ phy-supply = <&vcc_phy>; ++ assigned-clocks = <&cru SCLK_MAC2PHY_SRC>; ++ assigned-clock-rate = <50000000>; ++ assigned-clocks = <&cru SCLK_MAC2PHY>; ++ assigned-clock-parents = <&cru SCLK_MAC2PHY_SRC>; ++ clock_in_out = "output"; ++ status = "okay"; ++}; ++ ++&gpu { ++ status = "okay"; ++ mali-supply = <&vdd_logic>; ++}; ++ ++&h265e { ++ status = "okay"; ++}; ++ ++&h265e_mmu { ++ status = "okay"; ++}; ++ ++&hdmi { ++ #sound-dai-cells = <0>; ++ ddc-i2c-scl-high-time-ns = <9625>; ++ ddc-i2c-scl-low-time-ns = <10000>; ++ status = "okay"; ++}; ++ ++&hdmiphy { ++ status = "okay"; ++}; ++ ++&i2c1 { ++ status = "okay"; ++ ++ rk805: rk805@18 { ++ compatible = "rockchip,rk805"; ++ status = "okay"; ++ reg = <0x18>; ++ interrupt-parent = <&gpio2>; ++ interrupts = <6 IRQ_TYPE_LEVEL_LOW>; ++ #clock-cells = <1>; ++ clock-output-names = "rk805-clkout1", "rk805-clkout2"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pmic_int_l>; ++ rockchip,system-power-controller; ++ wakeup-source; ++ gpio-controller; ++ #gpio-cells = <2>; ++ ++ vcc1-supply = <&vcc_sys>; ++ vcc2-supply = <&vcc_sys>; ++ vcc3-supply = <&vcc_sys>; ++ vcc4-supply = <&vcc_sys>; ++ vcc5-supply = <&vcc_io>; ++ vcc6-supply = <&vcc_sys>; ++ ++ rtc { ++ status = "okay"; ++ }; ++ ++ pwrkey { ++ status = "okay"; ++ }; ++ ++ gpio { ++ status = "okay"; ++ }; ++ ++ regulators { ++ compatible = "rk805-regulator"; ++ status = "okay"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ vdd_logic: RK805_DCDC1 { ++ regulator-compatible = "RK805_DCDC1"; ++ regulator-name = "vdd_logic"; ++ regulator-min-microvolt = <712500>; ++ regulator-max-microvolt = <1450000>; ++ regulator-initial-mode = <0x1>; ++ regulator-ramp-delay = <12500>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-mode = <0x2>; ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1000000>; ++ }; ++ }; ++ ++ vdd_arm: RK805_DCDC2 { ++ regulator-compatible = "RK805_DCDC2"; ++ regulator-name = "vdd_arm"; ++ regulator-init-microvolt = <1225000>; ++ regulator-min-microvolt = <712500>; ++ regulator-max-microvolt = <1450000>; ++ regulator-initial-mode = <0x1>; ++ regulator-ramp-delay = <12500>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-mode = <0x2>; ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <950000>; ++ }; ++ }; ++ ++ vcc_ddr: RK805_DCDC3 { ++ regulator-compatible = "RK805_DCDC3"; ++ regulator-name = "vcc_ddr"; ++ regulator-initial-mode = <0x1>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-mode = <0x2>; ++ regulator-on-in-suspend; ++ }; ++ }; ++ ++ vcc_io: RK805_DCDC4 { ++ regulator-compatible = "RK805_DCDC4"; ++ regulator-name = "vcc_io"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-initial-mode = <0x1>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-mode = <0x2>; ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <3300000>; ++ }; ++ }; ++ ++ vcc_18: RK805_LDO1 { ++ regulator-compatible = "RK805_LDO1"; ++ regulator-name = "vcc_18"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ vcc18_emmc: RK805_LDO2 { ++ regulator-compatible = "RK805_LDO2"; ++ regulator-name = "vcc18_emmc"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ vdd_10: RK805_LDO3 { ++ regulator-compatible = "RK805_LDO3"; ++ regulator-name = "vdd_10"; ++ regulator-min-microvolt = <1000000>; ++ regulator-max-microvolt = <1000000>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1000000>; ++ }; ++ }; ++ }; ++ }; ++}; ++ ++&i2s0 { ++ #sound-dai-cells = <0>; ++ rockchip,bclk-fs = <128>; ++ status = "okay"; ++}; ++ ++&iep { ++ status = "okay"; ++}; ++ ++&iep_mmu { ++ status = "okay"; ++}; ++ ++&io_domains { ++ status = "okay"; ++ ++ vccio1-supply = <&vcc_io>; ++ vccio2-supply = <&vcc18_emmc>; ++ vccio3-supply = <&vcc_io>; ++ vccio4-supply = <&vcc_18>; ++ vccio5-supply = <&vcc_io>; ++ vccio6-supply = <&vcc_io>; ++ pmuio-supply = <&vcc_io>; ++}; ++ ++&pinctrl { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&clk_32k_out>; ++ ++ clk_32k { ++ clk_32k_out: clk-32k-out { ++ rockchip,pins = <1 RK_PD4 RK_FUNC_1 &pcfg_pull_none>; ++ }; ++ }; ++ ++ ir { ++ ir_int: ir-int { ++ rockchip,pins = <2 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ pmic { ++ pmic_int_l: pmic-int-l { ++ rockchip,pins = <2 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ }; ++ ++ usb2 { ++ usb20_host_drv: usb20-host-drv { ++ rockchip,pins = <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ usb3 { ++ usb30_host_drv: usb30-host-drv { ++ rockchip,pins = <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++}; ++ ++&rkvdec { ++ status = "okay"; ++ vcodec-supply = <&vdd_logic>; ++}; ++ ++&rkvdec_mmu { ++ status = "okay"; ++}; ++ ++&sdmmc { ++ bus-width = <4>; ++ cap-mmc-highspeed; ++ cap-sd-highspeed; ++ disable-wp; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdmmc0_clk &sdmmc0_cmd &sdmmc0_dectn &sdmmc0_bus4>; ++ supports-sd; ++ vmmc-supply = <&vcc_sd>; ++ status = "okay"; ++}; ++ ++&spdif { ++ #sound-dai-cells = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spdifm0_tx>; ++ status = "okay"; ++}; ++ ++&threshold { ++ temperature = <80000>; /* millicelsius */ ++}; ++ ++&target { ++ temperature = <95000>; /* millicelsius */ ++}; ++ ++&soc_crit { ++ temperature = <100000>; /* millicelsius */ ++}; ++ ++&tsadc { ++ rockchip,hw-tshut-mode = <0>; ++ rockchip,hw-tshut-polarity = <0>; ++ rockchip,hw-tshut-temp = <110000>; ++ status = "okay"; ++}; ++ ++&uart0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart0_xfer &uart0_cts>; ++ status = "okay"; ++}; ++ ++&uart2 { ++ status = "okay"; ++}; ++ ++&u2phy { ++ status = "okay"; ++}; ++ ++&u2phy_host { ++ phy-supply = <&vcc_host1_5v>; ++ status = "okay"; ++}; ++ ++&u2phy_otg { ++ phy-supply = <&vcc_otg_5v>; ++ status = "okay"; ++}; ++ ++&u3phy { ++ status = "okay"; ++}; ++ ++&u3phy_utmi { ++ phy-supply = <&vcc_host_5v>; ++ status = "okay"; ++}; ++ ++&u3phy_pipe { ++ phy-supply = <&vcc_host_5v>; ++ status = "okay"; ++}; ++ ++&usb20_otg { ++ dr_mode = "host"; ++ status = "okay"; ++}; ++ ++&usb_host0_ehci { ++ status = "okay"; ++}; ++ ++&usb_host0_ohci { ++ status = "okay"; ++}; ++ ++&usbdrd3 { ++ status = "okay"; ++}; ++ ++&usbdrd_dwc3 { ++ status = "okay"; ++}; ++ ++&vop { ++ status = "okay"; ++}; ++ ++&vop_mmu { ++ status = "okay"; ++}; ++ ++&vpu_service { ++ status = "okay"; ++}; ++ ++&vpu_mmu { ++ status = "okay"; ++}; ++ ++&vepu { ++ status = "okay"; ++}; ++ ++&vepu_mmu { ++ status = "okay"; ++}; ++ ++&venc_srv { ++ status = "okay"; ++}; + +From 63d34d434542f4551cc12578317f7d6337918d1d Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Tue, 10 Apr 2018 22:07:37 +0200 +Subject: [PATCH] arm64: dts: rockchip: rk3328-roc-cc: use 1066MHz ddr + frequency + +--- + .../dts/rockchip/rk3328-dram-box-plus-timing.dtsi | 263 +++++++++++++++++++++ + arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts | 33 ++- + 2 files changed, 295 insertions(+), 1 deletion(-) + create mode 100644 arch/arm64/boot/dts/rockchip/rk3328-dram-box-plus-timing.dtsi + +diff --git a/arch/arm64/boot/dts/rockchip/rk3328-dram-box-plus-timing.dtsi b/arch/arm64/boot/dts/rockchip/rk3328-dram-box-plus-timing.dtsi +new file mode 100644 +index 000000000000..ac34cc7ab1ce +--- /dev/null ++++ b/arch/arm64/boot/dts/rockchip/rk3328-dram-box-plus-timing.dtsi +@@ -0,0 +1,263 @@ ++/* ++ * Copyright (c) 2016 Fuzhou Rockchip Electronics Co., Ltd ++ * ++ * This file is dual-licensed: you can use it either under the terms ++ * of the GPL or the X11 license, at your option. Note that this dual ++ * licensing only applies to this file, and not this project as a ++ * whole. ++ * ++ * a) This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation; either version 2 of the ++ * License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * Or, alternatively, ++ * ++ * b) Permission is hereby granted, free of charge, to any person ++ * obtaining a copy of this software and associated documentation ++ * files (the "Software"), to deal in the Software without ++ * restriction, including without limitation the rights to use, ++ * copy, modify, merge, publish, distribute, sublicense, and/or ++ * sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following ++ * conditions: ++ * ++ * The above copyright notice and this permission notice shall be ++ * included in all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES ++ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ++ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT ++ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, ++ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING ++ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ++ * OTHER DEALINGS IN THE SOFTWARE. ++ */ ++#include ++#include ++ ++&ddr_timing { ++ ddr4_odt = ; ++ phy_ddr4_ca_drv = ; ++ phy_ddr4_ck_drv = ; ++ phy_ddr4_dq_drv = ; ++ phy_ddr4_odt = ; ++ ++ /* CA de-skew, one step is 47.8ps, range 0-15 */ ++ ddr3a1_ddr4a9_de-skew = <1>; ++ ddr3a0_ddr4a10_de-skew = <1>; ++ ddr3a3_ddr4a6_de-skew = <0>; ++ ddr3a2_ddr4a4_de-skew = <1>; ++ ddr3a5_ddr4a8_de-skew = <0>; ++ ddr3a4_ddr4a5_de-skew = <1>; ++ ddr3a7_ddr4a11_de-skew = <1>; ++ ddr3a6_ddr4a7_de-skew = <0>; ++ ddr3a9_ddr4a0_de-skew = <1>; ++ ddr3a8_ddr4a13_de-skew = <0>; ++ ddr3a11_ddr4a3_de-skew = <2>; ++ ddr3a10_ddr4cs0_de-skew = <3>; ++ ddr3a13_ddr4a2_de-skew = <1>; ++ ddr3a12_ddr4ba1_de-skew = <0>; ++ ddr3a15_ddr4odt0_de-skew = <3>; ++ ddr3a14_ddr4a1_de-skew = <2>; ++ ddr3ba1_ddr4a15_de-skew = <1>; ++ ddr3ba0_ddr4bg0_de-skew = <1>; ++ ddr3ras_ddr4cke_de-skew = <3>; ++ ddr3ba2_ddr4ba0_de-skew = <1>; ++ ddr3we_ddr4bg1_de-skew = <3>; ++ ddr3cas_ddr4a12_de-skew = <1>; ++ ddr3ckn_ddr4ckn_de-skew = <4>; ++ ddr3ckp_ddr4ckp_de-skew = <4>; ++ ddr3cke_ddr4a16_de-skew = <1>; ++ ddr3odt0_ddr4a14_de-skew = <1>; ++ ddr3cs0_ddr4act_de-skew = <2>; ++ ddr3reset_ddr4reset_de-skew = <3>; ++ ddr3cs1_ddr4cs1_de-skew = <2>; ++ ddr3odt1_ddr4odt1_de-skew = <2>; ++ ++ /* DATA de-skew ++ * RX one step is 25.1ps, range 0-15 ++ * TX one step is 47.8ps, range 0-15 ++ */ ++ cs0_dm0_rx_de-skew = <8>; ++ cs0_dm0_tx_de-skew = <9>; ++ cs0_dq0_rx_de-skew = <8>; ++ cs0_dq0_tx_de-skew = <9>; ++ cs0_dq1_rx_de-skew = <8>; ++ cs0_dq1_tx_de-skew = <9>; ++ cs0_dq2_rx_de-skew = <8>; ++ cs0_dq2_tx_de-skew = <9>; ++ cs0_dq3_rx_de-skew = <8>; ++ cs0_dq3_tx_de-skew = <9>; ++ cs0_dq4_rx_de-skew = <8>; ++ cs0_dq4_tx_de-skew = <9>; ++ cs0_dq5_rx_de-skew = <8>; ++ cs0_dq5_tx_de-skew = <9>; ++ cs0_dq6_rx_de-skew = <8>; ++ cs0_dq6_tx_de-skew = <9>; ++ cs0_dq7_rx_de-skew = <8>; ++ cs0_dq7_tx_de-skew = <9>; ++ cs0_dqs0_rx_de-skew = <7>; ++ cs0_dqs0p_tx_de-skew = <10>; ++ cs0_dqs0n_tx_de-skew = <10>; ++ ++ cs0_dm1_rx_de-skew = <8>; ++ cs0_dm1_tx_de-skew = <8>; ++ cs0_dq8_rx_de-skew = <8>; ++ cs0_dq8_tx_de-skew = <9>; ++ cs0_dq9_rx_de-skew = <8>; ++ cs0_dq9_tx_de-skew = <8>; ++ cs0_dq10_rx_de-skew = <8>; ++ cs0_dq10_tx_de-skew = <9>; ++ cs0_dq11_rx_de-skew = <8>; ++ cs0_dq11_tx_de-skew = <8>; ++ cs0_dq12_rx_de-skew = <8>; ++ cs0_dq12_tx_de-skew = <9>; ++ cs0_dq13_rx_de-skew = <8>; ++ cs0_dq13_tx_de-skew = <8>; ++ cs0_dq14_rx_de-skew = <8>; ++ cs0_dq14_tx_de-skew = <9>; ++ cs0_dq15_rx_de-skew = <8>; ++ cs0_dq15_tx_de-skew = <8>; ++ cs0_dqs1_rx_de-skew = <8>; ++ cs0_dqs1p_tx_de-skew = <10>; ++ cs0_dqs1n_tx_de-skew = <10>; ++ ++ cs0_dm2_rx_de-skew = <8>; ++ cs0_dm2_tx_de-skew = <9>; ++ cs0_dq16_rx_de-skew = <8>; ++ cs0_dq16_tx_de-skew = <9>; ++ cs0_dq17_rx_de-skew = <8>; ++ cs0_dq17_tx_de-skew = <9>; ++ cs0_dq18_rx_de-skew = <8>; ++ cs0_dq18_tx_de-skew = <9>; ++ cs0_dq19_rx_de-skew = <8>; ++ cs0_dq19_tx_de-skew = <9>; ++ cs0_dq20_rx_de-skew = <8>; ++ cs0_dq20_tx_de-skew = <9>; ++ cs0_dq21_rx_de-skew = <8>; ++ cs0_dq21_tx_de-skew = <9>; ++ cs0_dq22_rx_de-skew = <8>; ++ cs0_dq22_tx_de-skew = <9>; ++ cs0_dq23_rx_de-skew = <8>; ++ cs0_dq23_tx_de-skew = <9>; ++ cs0_dqs2_rx_de-skew = <7>; ++ cs0_dqs2p_tx_de-skew = <10>; ++ cs0_dqs2n_tx_de-skew = <10>; ++ ++ cs0_dm3_rx_de-skew = <8>; ++ cs0_dm3_tx_de-skew = <8>; ++ cs0_dq24_rx_de-skew = <8>; ++ cs0_dq24_tx_de-skew = <9>; ++ cs0_dq25_rx_de-skew = <8>; ++ cs0_dq25_tx_de-skew = <8>; ++ cs0_dq26_rx_de-skew = <8>; ++ cs0_dq26_tx_de-skew = <8>; ++ cs0_dq27_rx_de-skew = <8>; ++ cs0_dq27_tx_de-skew = <8>; ++ cs0_dq28_rx_de-skew = <8>; ++ cs0_dq28_tx_de-skew = <8>; ++ cs0_dq29_rx_de-skew = <8>; ++ cs0_dq29_tx_de-skew = <8>; ++ cs0_dq30_rx_de-skew = <8>; ++ cs0_dq30_tx_de-skew = <8>; ++ cs0_dq31_rx_de-skew = <8>; ++ cs0_dq31_tx_de-skew = <8>; ++ cs0_dqs3_rx_de-skew = <8>; ++ cs0_dqs3p_tx_de-skew = <10>; ++ cs0_dqs3n_tx_de-skew = <10>; ++ ++ cs1_dm0_rx_de-skew = <8>; ++ cs1_dm0_tx_de-skew = <9>; ++ cs1_dq0_rx_de-skew = <8>; ++ cs1_dq0_tx_de-skew = <9>; ++ cs1_dq1_rx_de-skew = <8>; ++ cs1_dq1_tx_de-skew = <9>; ++ cs1_dq2_rx_de-skew = <8>; ++ cs1_dq2_tx_de-skew = <9>; ++ cs1_dq3_rx_de-skew = <8>; ++ cs1_dq3_tx_de-skew = <9>; ++ cs1_dq4_rx_de-skew = <8>; ++ cs1_dq4_tx_de-skew = <9>; ++ cs1_dq5_rx_de-skew = <8>; ++ cs1_dq5_tx_de-skew = <9>; ++ cs1_dq6_rx_de-skew = <8>; ++ cs1_dq6_tx_de-skew = <9>; ++ cs1_dq7_rx_de-skew = <8>; ++ cs1_dq7_tx_de-skew = <9>; ++ cs1_dqs0_rx_de-skew = <7>; ++ cs1_dqs0p_tx_de-skew = <10>; ++ cs1_dqs0n_tx_de-skew = <10>; ++ ++ cs1_dm1_rx_de-skew = <8>; ++ cs1_dm1_tx_de-skew = <8>; ++ cs1_dq8_rx_de-skew = <8>; ++ cs1_dq8_tx_de-skew = <9>; ++ cs1_dq9_rx_de-skew = <8>; ++ cs1_dq9_tx_de-skew = <8>; ++ cs1_dq10_rx_de-skew = <8>; ++ cs1_dq10_tx_de-skew = <9>; ++ cs1_dq11_rx_de-skew = <8>; ++ cs1_dq11_tx_de-skew = <8>; ++ cs1_dq12_rx_de-skew = <8>; ++ cs1_dq12_tx_de-skew = <9>; ++ cs1_dq13_rx_de-skew = <8>; ++ cs1_dq13_tx_de-skew = <8>; ++ cs1_dq14_rx_de-skew = <8>; ++ cs1_dq14_tx_de-skew = <9>; ++ cs1_dq15_rx_de-skew = <8>; ++ cs1_dq15_tx_de-skew = <8>; ++ cs1_dqs1_rx_de-skew = <8>; ++ cs1_dqs1p_tx_de-skew = <10>; ++ cs1_dqs1n_tx_de-skew = <10>; ++ ++ cs1_dm2_rx_de-skew = <8>; ++ cs1_dm2_tx_de-skew = <9>; ++ cs1_dq16_rx_de-skew = <8>; ++ cs1_dq16_tx_de-skew = <9>; ++ cs1_dq17_rx_de-skew = <8>; ++ cs1_dq17_tx_de-skew = <9>; ++ cs1_dq18_rx_de-skew = <8>; ++ cs1_dq18_tx_de-skew = <9>; ++ cs1_dq19_rx_de-skew = <8>; ++ cs1_dq19_tx_de-skew = <9>; ++ cs1_dq20_rx_de-skew = <8>; ++ cs1_dq20_tx_de-skew = <9>; ++ cs1_dq21_rx_de-skew = <8>; ++ cs1_dq21_tx_de-skew = <9>; ++ cs1_dq22_rx_de-skew = <8>; ++ cs1_dq22_tx_de-skew = <9>; ++ cs1_dq23_rx_de-skew = <8>; ++ cs1_dq23_tx_de-skew = <9>; ++ cs1_dqs2_rx_de-skew = <7>; ++ cs1_dqs2p_tx_de-skew = <10>; ++ cs1_dqs2n_tx_de-skew = <10>; ++ ++ cs1_dm3_rx_de-skew = <8>; ++ cs1_dm3_tx_de-skew = <8>; ++ cs1_dq24_rx_de-skew = <8>; ++ cs1_dq24_tx_de-skew = <9>; ++ cs1_dq25_rx_de-skew = <8>; ++ cs1_dq25_tx_de-skew = <8>; ++ cs1_dq26_rx_de-skew = <8>; ++ cs1_dq26_tx_de-skew = <8>; ++ cs1_dq27_rx_de-skew = <8>; ++ cs1_dq27_tx_de-skew = <8>; ++ cs1_dq28_rx_de-skew = <8>; ++ cs1_dq28_tx_de-skew = <8>; ++ cs1_dq29_rx_de-skew = <8>; ++ cs1_dq29_tx_de-skew = <8>; ++ cs1_dq30_rx_de-skew = <8>; ++ cs1_dq30_tx_de-skew = <8>; ++ cs1_dq31_rx_de-skew = <8>; ++ cs1_dq31_tx_de-skew = <8>; ++ cs1_dqs3_rx_de-skew = <8>; ++ cs1_dqs3p_tx_de-skew = <10>; ++ cs1_dqs3n_tx_de-skew = <10>; ++}; +diff --git a/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts b/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts +index e911cf265a64..5df9b4976ba2 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts +@@ -42,6 +42,7 @@ + + /dts-v1/; + #include "rk3328.dtsi" ++#include "rk3328-dram-box-plus-timing.dtsi" + + / { + model = "Firefly ROC-RK3328-CC Board"; +@@ -193,7 +194,37 @@ + + &dmc { + center-supply = <&vdd_logic>; +- status = "okay"; ++ system-status-freq = < ++ /*system status freq(KHz)*/ ++ SYS_STATUS_NORMAL 1066000 ++ SYS_STATUS_REBOOT 1066000 ++ SYS_STATUS_SUSPEND 1066000 ++ SYS_STATUS_VIDEO_1080P 1066000 ++ SYS_STATUS_VIDEO_4K 1066000 ++ SYS_STATUS_VIDEO_4K_10B 1066000 ++ SYS_STATUS_PERFORMANCE 1066000 ++ SYS_STATUS_BOOST 1066000 ++ >; ++ status = "okay"; ++}; ++ ++&dmc_opp_table { ++ rockchip,leakage-voltage-sel = < ++ 1 8 0 ++ 9 254 0 ++ >; ++ opp-933000000 { ++ opp-hz = /bits/ 64 <933000000>; ++ opp-microvolt = <1150000>; ++ opp-microvolt-L0 = <1150000>; ++ opp-microvolt-L1 = <1100000>; ++ }; ++ opp-1066000000 { ++ opp-hz = /bits/ 64 <1066000000>; ++ opp-microvolt = <1200000>; ++ opp-microvolt-L0 = <1200000>; ++ opp-microvolt-L1 = <1175000>; ++ }; + }; + + &display_subsystem { + +From 76d468bccff1b742965b5a8d78beb028488ee6e3 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sat, 21 Apr 2018 13:21:24 +0200 +Subject: [PATCH] arm64: dts: rockchip: rk3328-box-trn9: use 1066MHz ddr + frequency + +--- + arch/arm64/boot/dts/rockchip/rk3328-box-trn9.dts | 29 +++++++++++++++++++++++- + 1 file changed, 28 insertions(+), 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3328-box-trn9.dts b/arch/arm64/boot/dts/rockchip/rk3328-box-trn9.dts +index 51d471ba8cef..81ec7b66e199 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3328-box-trn9.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3328-box-trn9.dts +@@ -42,6 +42,7 @@ + + /dts-v1/; + #include "rk3328.dtsi" ++#include "rk3328-dram-box-plus-timing.dtsi" + + / { + model = "Rockchip RK3328 TRN9"; +@@ -240,7 +241,33 @@ + + &dmc { + center-supply = <&vdd_logic>; +- status = "okay"; ++ system-status-freq = < ++ /*system status freq(KHz)*/ ++ SYS_STATUS_NORMAL 1066000 ++ SYS_STATUS_REBOOT 1066000 ++ SYS_STATUS_SUSPEND 1066000 ++ SYS_STATUS_VIDEO_1080P 1066000 ++ SYS_STATUS_VIDEO_4K 1066000 ++ SYS_STATUS_VIDEO_4K_10B 1066000 ++ SYS_STATUS_PERFORMANCE 1066000 ++ SYS_STATUS_BOOST 1066000 ++ >; ++ status = "okay"; ++}; ++ ++&dmc_opp_table { ++ opp-933000000 { ++ opp-hz = /bits/ 64 <933000000>; ++ opp-microvolt = <1150000>; ++ opp-microvolt-L0 = <1150000>; ++ opp-microvolt-L1 = <1100000>; ++ }; ++ opp-1066000000 { ++ opp-hz = /bits/ 64 <1066000000>; ++ opp-microvolt = <1200000>; ++ opp-microvolt-L0 = <1200000>; ++ opp-microvolt-L1 = <1175000>; ++ }; + }; + + &display_subsystem { + +From 6116b7515612fa5ce0ada65030f3cfc71eb70206 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sat, 18 Aug 2018 20:53:04 +0200 +Subject: [PATCH] arm64: dts: rockchip: rk3399: update dtsi + +--- + arch/arm64/boot/dts/rockchip/rk3399-sapphire.dtsi | 17 ++++++++++++--- + arch/arm64/boot/dts/rockchip/rk3399.dtsi | 26 ++++++++++++++++++++++- + 3 files changed, 40 insertions(+), 17 deletions(-) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3399-sapphire.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-sapphire.dtsi +index 3d76b9733665..62ba4281197e 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3399-sapphire.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3399-sapphire.dtsi +@@ -536,6 +536,14 @@ + status = "okay"; + }; + ++&pvtm { ++ status = "okay"; ++}; ++ ++&pmu_pvtm { ++ status = "okay"; ++}; ++ + &pmu_io_domains { + status = "okay"; + pmu1830-supply = <&vcc_3v0>; +@@ -563,7 +571,7 @@ + + &sdio0 { + clock-frequency = <50000000>; +- clock-freq-min-max = <200000 50000000>; ++ max-frequency = <50000000>; + supports-sdio; + bus-width = <4>; + disable-wp; +@@ -581,14 +589,17 @@ + + &sdmmc { + clock-frequency = <150000000>; +- clock-freq-min-max = <100000 150000000>; ++ max-frequency = <150000000>; + supports-sd; + bus-width = <4>; + cap-mmc-highspeed; + cap-sd-highspeed; + disable-wp; + num-slots = <1>; +- //sd-uhs-sdr104; ++ sd-uhs-sdr12; ++ sd-uhs-sdr25; ++ sd-uhs-sdr50; ++ sd-uhs-sdr104; + vmmc-supply = <&vcc_sd>; + vqmmc-supply = <&vccio_sd>; + pinctrl-names = "default"; +diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi b/arch/arm64/boot/dts/rockchip/rk3399.dtsi +index 815a8c131239..fbe3d0edc961 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi +@@ -646,6 +646,8 @@ + uart0: serial@ff180000 { + compatible = "rockchip,rk3399-uart", "snps,dw-apb-uart"; + reg = <0x0 0xff180000 0x0 0x100>; ++ dmas = <&dmac_peri 0>, <&dmac_peri 1>; ++ dma-names = "tx", "rx"; + clocks = <&cru SCLK_UART0>, <&cru PCLK_UART0>; + clock-names = "baudclk", "apb_pclk"; + interrupts = ; +@@ -659,6 +661,8 @@ + uart1: serial@ff190000 { + compatible = "rockchip,rk3399-uart", "snps,dw-apb-uart"; + reg = <0x0 0xff190000 0x0 0x100>; ++ dmas = <&dmac_peri 2>, <&dmac_peri 3>; ++ dma-names = "tx", "rx"; + clocks = <&cru SCLK_UART1>, <&cru PCLK_UART1>; + clock-names = "baudclk", "apb_pclk"; + interrupts = ; +@@ -672,6 +676,8 @@ + uart2: serial@ff1a0000 { + compatible = "rockchip,rk3399-uart", "snps,dw-apb-uart"; + reg = <0x0 0xff1a0000 0x0 0x100>; ++ dmas = <&dmac_peri 4>, <&dmac_peri 5>; ++ dma-names = "tx", "rx"; + clocks = <&cru SCLK_UART2>, <&cru PCLK_UART2>; + clock-names = "baudclk", "apb_pclk"; + interrupts = ; +@@ -685,6 +691,8 @@ + uart3: serial@ff1b0000 { + compatible = "rockchip,rk3399-uart", "snps,dw-apb-uart"; + reg = <0x0 0xff1b0000 0x0 0x100>; ++ dmas = <&dmac_peri 6>, <&dmac_peri 7>; ++ dma-names = "tx", "rx"; + clocks = <&cru SCLK_UART3>, <&cru PCLK_UART3>; + clock-names = "baudclk", "apb_pclk"; + interrupts = ; +@@ -698,6 +706,8 @@ + spi0: spi@ff1c0000 { + compatible = "rockchip,rk3399-spi", "rockchip,rk3066-spi"; + reg = <0x0 0xff1c0000 0x0 0x1000>; ++ dmas = <&dmac_peri 10>, <&dmac_peri 11>; ++ dma-names = "tx", "rx"; + clocks = <&cru SCLK_SPI0>, <&cru PCLK_SPI0>; + clock-names = "spiclk", "apb_pclk"; + interrupts = ; +@@ -711,6 +721,8 @@ + spi1: spi@ff1d0000 { + compatible = "rockchip,rk3399-spi", "rockchip,rk3066-spi"; + reg = <0x0 0xff1d0000 0x0 0x1000>; ++ dmas = <&dmac_peri 12>, <&dmac_peri 13>; ++ dma-names = "tx", "rx"; + clocks = <&cru SCLK_SPI1>, <&cru PCLK_SPI1>; + clock-names = "spiclk", "apb_pclk"; + interrupts = ; +@@ -724,6 +736,8 @@ + spi2: spi@ff1e0000 { + compatible = "rockchip,rk3399-spi", "rockchip,rk3066-spi"; + reg = <0x0 0xff1e0000 0x0 0x1000>; ++ dmas = <&dmac_peri 14>, <&dmac_peri 15>; ++ dma-names = "tx", "rx"; + clocks = <&cru SCLK_SPI2>, <&cru PCLK_SPI2>; + clock-names = "spiclk", "apb_pclk"; + interrupts = ; +@@ -737,6 +751,8 @@ + spi4: spi@ff1f0000 { + compatible = "rockchip,rk3399-spi", "rockchip,rk3066-spi"; + reg = <0x0 0xff1f0000 0x0 0x1000>; ++ dmas = <&dmac_peri 18>, <&dmac_peri 19>; ++ dma-names = "tx", "rx"; + clocks = <&cru SCLK_SPI4>, <&cru PCLK_SPI4>; + clock-names = "spiclk", "apb_pclk"; + interrupts = ; +@@ -750,6 +766,8 @@ + spi5: spi@ff200000 { + compatible = "rockchip,rk3399-spi", "rockchip,rk3066-spi"; + reg = <0x0 0xff200000 0x0 0x1000>; ++ dmas = <&dmac_bus 8>, <&dmac_bus 9>; ++ dma-names = "tx", "rx"; + clocks = <&cru SCLK_SPI5>, <&cru PCLK_SPI5>; + clock-names = "spiclk", "apb_pclk"; + interrupts = ; +@@ -1152,6 +1170,8 @@ + spi3: spi@ff350000 { + compatible = "rockchip,rk3399-spi", "rockchip,rk3066-spi"; + reg = <0x0 0xff350000 0x0 0x1000>; ++ dmas = <&dmac_peri 16>, <&dmac_peri 17>; ++ dma-names = "tx", "rx"; + clocks = <&pmucru SCLK_SPI3_PMU>, <&pmucru PCLK_SPI3_PMU>; + clock-names = "spiclk", "apb_pclk"; + interrupts = ; +@@ -1165,6 +1185,8 @@ + uart4: serial@ff370000 { + compatible = "rockchip,rk3399-uart", "snps,dw-apb-uart"; + reg = <0x0 0xff370000 0x0 0x100>; ++ dmas = <&dmac_peri 8>, <&dmac_peri 9>; ++ dma-names = "tx", "rx"; + clocks = <&pmucru SCLK_UART4_PMU>, <&pmucru PCLK_UART4_PMU>; + clock-names = "baudclk", "apb_pclk"; + interrupts = ; +@@ -1790,6 +1812,7 @@ + clocks = <&cru ACLK_VOP1>, <&cru DCLK_VOP1>, <&cru HCLK_VOP1>, <&cru DCLK_VOP1_DIV>; + clock-names = "aclk_vop", "dclk_vop", "hclk_vop", "dclk_source"; + iommus = <&vopl_mmu>; ++ rockchip,grf = <&grf>; + power-domains = <&power RK3399_PD_VOPL>; + resets = <&cru SRST_A_VOP1>, <&cru SRST_H_VOP1>, <&cru SRST_D_VOP1>; + reset-names = "axi", "ahb", "dclk"; +@@ -1860,6 +1883,7 @@ + clock-names = "aclk_vop", "dclk_vop", "hclk_vop", "dclk_source"; + resets = <&cru SRST_A_VOP0>, <&cru SRST_H_VOP0>, <&cru SRST_D_VOP0>; + reset-names = "axi", "ahb", "dclk"; ++ rockchip,grf = <&grf>; + power-domains = <&power RK3399_PD_VOPB>; + iommus = <&vopb_mmu>; + status = "disabled"; +@@ -1982,7 +2006,7 @@ + compatible = "rockchip,rk3399-dw-hdmi"; + reg = <0x0 0xff940000 0x0 0x20000>; + pinctrl-names = "default"; +- pinctrl-0 = <&hdmi_i2c_xfer>; ++ pinctrl-0 = <&hdmi_i2c_xfer>, <&hdmi_cec>; + interrupts = ; + clocks = <&cru PCLK_HDMI_CTRL>, + <&cru SCLK_HDMI_SFR>, + +From caa58eaa7cec6e36cdd4e3ec91757f01504b5f2e Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 19 Aug 2018 23:10:05 +0200 +Subject: [PATCH] arm64: dts: rk3399-rockpro64: update dts + +--- + arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dts | 421 +++++++++------------- + 1 file changed, 175 insertions(+), 246 deletions(-) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dts b/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dts +index 02b8ba7dcc94..aa1aee547036 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dts +@@ -8,23 +8,33 @@ + #include + #include + #include "rk3399.dtsi" ++#include "rk3399-linux.dtsi" + #include "rk3399-opp.dtsi" + + / { + model = "Pine64 RockPro64"; + compatible = "pine64,rockpro64", "rockchip,rk3399"; + +- chosen { +- bootargs = "earlycon=uart8250,mmio32,0xff1a0000 swiotlb=1 coherent_pool=1m"; +- stdout-path = "serial2:1500000n8"; +- }; +- + /* first 64k(0xff8c0000~0xff8d0000) for ddr and suspend */ + iram: sram@ff8d0000 { + compatible = "mmio-sram"; + reg = <0x0 0xff8d0000 0x0 0x20000>; /* 128k */ + }; + ++ xin32k: xin32k { ++ compatible = "fixed-clock"; ++ clock-frequency = <32768>; ++ clock-output-names = "xin32k"; ++ #clock-cells = <0>; ++ }; ++ ++ clkin_gmac: external-gmac-clock { ++ compatible = "fixed-clock"; ++ clock-frequency = <125000000>; ++ clock-output-names = "clkin_gmac"; ++ #clock-cells = <0>; ++ }; ++ + dc_12v: dc-12v { + compatible = "regulator-fixed"; + regulator-name = "dc_12v"; +@@ -92,6 +102,7 @@ + vdd_log: vdd-log { + compatible = "pwm-regulator"; + pwms = <&pwm2 0 25000 1>; ++ pwm-supply = <&vcc_sys>; + regulator-name = "vdd_log"; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <1400000>; +@@ -101,56 +112,54 @@ + /* for rockchip boot on */ + rockchip,pwm_id= <2>; + rockchip,pwm_voltage = <900000>; ++ }; + +- vin-supply = <&vcc_sys>; ++ leds { ++ compatible = "gpio-leds"; ++ ++ work-led { ++ gpios = <&gpio0 RK_PB3 GPIO_ACTIVE_HIGH>; ++ linux,default-trigger = "mmc0"; ++ }; ++ ++ diy-led { ++ gpios = <&gpio0 RK_PA2 GPIO_ACTIVE_HIGH>; ++ linux,default-trigger = "heartbeat"; ++ }; + }; + +- clkin_gmac: external-gmac-clock { +- compatible = "fixed-clock"; +- clock-frequency = <125000000>; +- clock-output-names = "clkin_gmac"; +- #clock-cells = <0>; ++ ir-receiver { ++ compatible = "gpio-ir-receiver"; ++ gpios = <&gpio0 RK_PA6 GPIO_ACTIVE_LOW>; ++ linux,rc-map-name = "rc-pine64"; ++ pinctrl-0 = <&ir_int>; ++ pinctrl-names = "default"; + }; + +- spdif-sound { +- status = "disabled"; ++ hdmi-sound { + compatible = "simple-audio-card"; +- simple-audio-card,name = "ROCKCHIP,SPDIF"; ++ simple-audio-card,format = "i2s"; ++ simple-audio-card,mclk-fs = <256>; ++ simple-audio-card,name = "HDMI"; + simple-audio-card,cpu { +- sound-dai = <&spdif>; ++ sound-dai = <&i2s2>; + }; + simple-audio-card,codec { +- sound-dai = <&spdif_out>; ++ sound-dai = <&hdmi>; + }; + }; + +- spdif_out: spdif-out { ++ hdmi-dp-sound { ++ compatible = "rockchip,rk3399-hdmi-dp"; ++ rockchip,cpu = <&i2s2>; ++ rockchip,codec = <&hdmi>, <&cdn_dp>; + status = "disabled"; +- compatible = "linux,spdif-dit"; +- #sound-dai-cells = <0>; +- }; +- +- sdio_pwrseq: sdio-pwrseq { +- compatible = "mmc-pwrseq-simple"; +- clocks = <&rk808 1>; +- clock-names = "ext_clock"; +- pinctrl-names = "default"; +- pinctrl-0 = <&wifi_enable_h>; +- +- /* +- * On the module itself this is one of these (depending +- * on the actual card populated): +- * - SDIO_RESET_L_WL_REG_ON +- * - PDN (power down when low) +- */ +- reset-gpios = <&gpio0 RK_PB2 GPIO_ACTIVE_LOW>; + }; + + es8316-sound { +- status = "okay"; + compatible = "simple-audio-card"; + simple-audio-card,format = "i2s"; +- simple-audio-card,name = "rockchip,es8316-codec"; ++ simple-audio-card,name = "ES8316"; + simple-audio-card,mclk-fs = <256>; + simple-audio-card,widgets = + "Microphone", "Mic Jack", +@@ -168,40 +177,59 @@ + }; + }; + +- leds { +- status = "okay"; +- compatible = "gpio-leds"; +- work-led { +- gpios = <&gpio0 RK_PB3 GPIO_ACTIVE_HIGH>; +- linux,default-trigger = "heartbeat"; +- default-state = "on"; ++ spdif-sound { ++ compatible = "simple-audio-card"; ++ simple-audio-card,name = "SPDIF"; ++ simple-audio-card,cpu { ++ sound-dai = <&spdif>; + }; +- diy-led { +- gpios = <&gpio0 RK_PA2 GPIO_ACTIVE_HIGH>; +- linux,default-trigger = "none"; +- default-state = "off"; ++ simple-audio-card,codec { ++ sound-dai = <&spdif_out>; + }; + }; + +- rk_key: rockchip-key { +- compatible = "rockchip,key"; +- status = "okay"; ++ spdif_out: spdif-out { ++ compatible = "linux,spdif-dit"; ++ #sound-dai-cells = <0>; ++ }; + +- io-channels = <&saradc 1>; ++ sdio_pwrseq: sdio-pwrseq { ++ compatible = "mmc-pwrseq-simple"; ++ clocks = <&rk808 1>; ++ clock-names = "ext_clock"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&wifi_enable_h>; + +- power-key { +- gpios = <&gpio0 RK_PA5 GPIO_ACTIVE_LOW>; +- linux,code = <116>; +- label = "power"; +- gpio-key,wakeup; +- }; ++ /* ++ * On the module itself this is one of these (depending ++ * on the actual card populated): ++ * - SDIO_RESET_L_WL_REG_ON ++ * - PDN (power down when low) ++ */ ++ reset-gpios = <&gpio0 RK_PB2 GPIO_ACTIVE_LOW>; + }; + +- hdmi_dp_sound: hdmi-dp-sound { +- status = "okay"; +- compatible = "rockchip,rk3399-hdmi-dp"; +- rockchip,cpu = <&i2s2>; +- rockchip,codec = <&hdmi>, <&cdn_dp>; ++ wireless-wlan { ++ compatible = "wlan-platdata"; ++ rockchip,grf = <&grf>; ++ wifi_chip_type = "ap6354"; ++ sdio_vref = <1800>; ++ WIFI,host_wake_irq = <&gpio0 RK_PA3 GPIO_ACTIVE_HIGH>; ++ status = "disabled"; ++ }; ++ ++ wireless-bluetooth { ++ compatible = "bluetooth-platdata"; ++ clocks = <&rk808 1>; ++ clock-names = "ext_clock"; ++ uart_rts_gpios = <&gpio2 RK_PC3 GPIO_ACTIVE_LOW>; ++ pinctrl-names = "default", "rts_gpio"; ++ pinctrl-0 = <&uart0_rts>; ++ pinctrl-1 = <&uart0_gpios>; ++ BT,reset_gpio = <&gpio0 RK_PB1 GPIO_ACTIVE_HIGH>; ++ BT,wake_gpio = <&gpio2 RK_PD3 GPIO_ACTIVE_HIGH>; ++ BT,wake_host_irq = <&gpio0 RK_PA4 GPIO_ACTIVE_HIGH>; ++ status = "disabled"; + }; + }; + +@@ -253,30 +281,21 @@ + &dmc { + status = "okay"; + center-supply = <&vdd_center>; +- upthreshold = <40>; +- downdifferential = <20>; + system-status-freq = < + /*system status freq(KHz)*/ + SYS_STATUS_NORMAL 800000 + SYS_STATUS_REBOOT 400000 + SYS_STATUS_SUSPEND 400000 +- SYS_STATUS_VIDEO_1080P 400000 ++ SYS_STATUS_VIDEO_1080P 800000 + SYS_STATUS_VIDEO_4K 800000 + SYS_STATUS_VIDEO_4K_10B 800000 + SYS_STATUS_PERFORMANCE 800000 +- SYS_STATUS_BOOST 400000 ++ SYS_STATUS_BOOST 800000 + SYS_STATUS_DUALVIEW 800000 + SYS_STATUS_ISP 800000 + >; +- vop-bw-dmc-freq = < +- /* min_bw(MB/s) max_bw(MB/s) freq(KHz) */ +- 0 577 200000 +- 578 1701 300000 +- 1702 99999 400000 +- >; +- auto-min-freq = <400000>; ++ auto-min-freq = <800000>; + auto-freq-en = <0>; +- + }; + + &dmc_opp_table { +@@ -325,42 +344,26 @@ + &display_subsystem { + status = "okay"; + +- ports = <&vopb_out>; +- + route { + route_hdmi: route-hdmi { + status = "okay"; + connect = <&vopb_out_hdmi>; + }; + +- route_dsi: route-dsi { +- status = "disabled"; +- connect = <&vopb_out_dsi>; +- }; +- +- route_edp: route-edp { +- status = "disabled"; +- connect = <&vopb_out_edp>; ++ route_dp: route-dp { ++ connect = <&vopl_out_dp>; + }; + }; + }; + +-&dp_in_vopb { +- status = "disabled"; +-}; +- +-&edp { +- /delete-node/ pinctrl-0; +-}; +- + &emmc_phy { + status = "okay"; + }; + + &i2c0 { + status = "okay"; +- i2c-scl-rising-time-ns = <168>; +- i2c-scl-falling-time-ns = <4>; ++ i2c-scl-rising-time-ns = <180>; ++ i2c-scl-falling-time-ns = <30>; + clock-frequency = <400000>; + + vdd_cpu_b: syr827@40 { +@@ -393,6 +396,7 @@ + regulator-max-microvolt = <1500000>; + regulator-ramp-delay = <1000>; + fcs,suspend-voltage-selector = <1>; ++ regulator-always-on; + regulator-boot-on; + vin-supply = <&vcc_sys>; + regulator-initial-mode = <1>; /* 1:force PWM 2:auto */ +@@ -411,7 +415,7 @@ + rockchip,system-power-controller; + wakeup-source; + #clock-cells = <1>; +- clock-output-names = "xin32k", "rk808-clkout2"; ++ clock-output-names = "rk808-clkout1", "rk808-clkout2"; + + vcc1-supply = <&vcc_sys>; + vcc2-supply = <&vcc_sys>; +@@ -429,8 +433,8 @@ + regulators { + vdd_center: DCDC_REG1 { + regulator-name = "vdd_center"; +- regulator-min-microvolt = <750000>; +- regulator-max-microvolt = <1350000>; ++ regulator-min-microvolt = <900000>; ++ regulator-max-microvolt = <900000>; + regulator-ramp-delay = <6001>; + regulator-always-on; + regulator-boot-on; +@@ -476,6 +480,7 @@ + regulator-name = "vcc1v8_dvp"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; ++ regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; +@@ -487,6 +492,7 @@ + regulator-name = "vcc3v0_touch"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; ++ regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; +@@ -510,6 +516,7 @@ + regulator-name = "vcc_sd"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; ++ regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; +@@ -586,14 +593,6 @@ + }; + }; + +-&i2s0 { +- status = "okay"; +- rockchip,i2s-broken-burst-len; +- rockchip,playback-channels = <8>; +- rockchip,capture-channels = <8>; +- #sound-dai-cells = <0>; +-}; +- + &i2c1 { + status = "okay"; + i2c-scl-rising-time-ns = <168>; +@@ -624,6 +623,14 @@ + }; + }; + ++&i2s0 { ++ status = "okay"; ++ rockchip,i2s-broken-burst-len; ++ rockchip,playback-channels = <8>; ++ rockchip,capture-channels = <8>; ++ #sound-dai-cells = <0>; ++}; ++ + &i2s1 { + status = "okay"; + rockchip,i2s-broken-burst-len; +@@ -634,6 +641,7 @@ + + &i2s2 { + #sound-dai-cells = <0>; ++ rockchip,bclk-fs = <128>; + status = "okay"; + }; + +@@ -641,6 +649,7 @@ + phy-supply = <&vcc_phy>; + phy-mode = "rgmii"; + clock_in_out = "input"; ++ snps,force_thresh_dma_mode; + snps,reset-gpio = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>; + snps,reset-active-low; + snps,reset-delays-us = <0 10000 50000>; +@@ -660,6 +669,17 @@ + }; + + &hdmi { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ #sound-dai-cells = <0>; ++ status = "okay"; ++}; ++ ++&iep { ++ status = "okay"; ++}; ++ ++&iep_mmu { + status = "okay"; + }; + +@@ -678,13 +698,17 @@ + + &sdmmc { + clock-frequency = <50000000>; +- clock-freq-min-max = <400000 150000000>; ++ max-frequency = <150000000>; + supports-sd; + bus-width = <4>; + cap-mmc-highspeed; + cap-sd-highspeed; + disable-wp; + num-slots = <1>; ++ sd-uhs-sdr12; ++ sd-uhs-sdr25; ++ sd-uhs-sdr50; ++ sd-uhs-sdr104; + vqmmc-supply = <&vcc_sd>; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd &sdmmc_bus4>; +@@ -694,7 +718,7 @@ + + &sdio0 { + clock-frequency = <50000000>; +- clock-freq-min-max = <200000 50000000>; ++ max-frequency = <50000000>; + supports-sdio; + bus-width = <4>; + disable-wp; +@@ -707,35 +731,50 @@ + pinctrl-names = "default"; + pinctrl-0 = <&sdio0_bus4 &sdio0_cmd &sdio0_clk>; + sd-uhs-sdr104; +- status = "okay"; ++ status = "disabled"; + }; + + &sdhci { + bus-width = <8>; +- mmc-hs200-1_8v; + mmc-hs400-1_8v; ++ mmc-hs400-enhanced-strobe; ++ supports-emmc; ++ non-removable; + keep-power-in-suspend; + status = "okay"; + }; + + &spdif { +- status = "disabled"; ++ status = "okay"; + pinctrl-0 = <&spdif_bus_1>; + #sound-dai-cells = <0>; + }; + + &spi1 { + status = "okay"; ++ max-freq = <10000000>; ++ + flash@0 { +- compatible = "gigadevice,gd25q128", "jedec,spi-nor"; ++ compatible = "jedec,spi-nor"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0>; +- m25p,fast-read; +- spi-max-frequency = <24000000>; ++ spi-max-frequency = <10000000>; + }; + }; + ++&threshold { ++ temperature = <80000>; ++}; ++ ++&target { ++ temperature = <95000>; ++}; ++ ++&soc_crit { ++ temperature = <100000>; ++}; ++ + &tcphy0 { + extcon = <&fusb0>; + status = "okay"; +@@ -826,114 +865,15 @@ + status = "okay"; + }; + +-&pwm2 { ++&pwm1 { + status = "okay"; + pinctrl-names = "active"; +- pinctrl-0 = <&pwm2_pin_pull_down>; + }; + +-&pwm3 { ++&pwm2 { + status = "okay"; +- +- interrupts = ; +- compatible = "rockchip,remotectl-pwm"; +- remote_pwm_id = <3>; +- handle_cpu_id = <1>; +- remote_support_psci = <1>; +- +- ir_key1 { +- rockchip,usercode = <0x4040>; +- rockchip,key_table = +- <0xf2 KEY_REPLY>, +- <0xba KEY_BACK>, +- <0xf4 KEY_UP>, +- <0xf1 KEY_DOWN>, +- <0xef KEY_LEFT>, +- <0xee KEY_RIGHT>, +- <0xbd KEY_HOME>, +- <0xea KEY_VOLUMEUP>, +- <0xe3 KEY_VOLUMEDOWN>, +- <0xe2 KEY_SEARCH>, +- <0xb2 KEY_POWER>, +- <0xbc KEY_MUTE>, +- <0xec KEY_MENU>, +- <0xbf 0x190>, +- <0xe0 0x191>, +- <0xe1 0x192>, +- <0xe9 183>, +- <0xe6 248>, +- <0xe8 185>, +- <0xe7 186>, +- <0xf0 388>, +- <0xbe 0x175>; +- }; +- +- ir_key2 { +- rockchip,usercode = <0xff00>; +- rockchip,key_table = +- <0xf9 KEY_HOME>, +- <0xbf KEY_BACK>, +- <0xfb KEY_MENU>, +- <0xaa KEY_REPLY>, +- <0xb9 KEY_UP>, +- <0xe9 KEY_DOWN>, +- <0xb8 KEY_LEFT>, +- <0xea KEY_RIGHT>, +- <0xeb KEY_VOLUMEDOWN>, +- <0xef KEY_VOLUMEUP>, +- <0xf7 KEY_MUTE>, +- <0xe7 KEY_POWER>, +- <0xfc KEY_POWER>, +- <0xa9 KEY_VOLUMEDOWN>, +- <0xa8 KEY_VOLUMEDOWN>, +- <0xe0 KEY_VOLUMEDOWN>, +- <0xa5 KEY_VOLUMEDOWN>, +- <0xab 183>, +- <0xb7 388>, +- <0xe8 388>, +- <0xf8 184>, +- <0xaf 185>, +- <0xed KEY_VOLUMEDOWN>, +- <0xee 186>, +- <0xb3 KEY_VOLUMEDOWN>, +- <0xf1 KEY_VOLUMEDOWN>, +- <0xf2 KEY_VOLUMEDOWN>, +- <0xf3 KEY_SEARCH>, +- <0xb4 KEY_VOLUMEDOWN>, +- <0xbe KEY_SEARCH>; +- }; +- +- ir_key3 { +- rockchip,usercode = <0x1dcc>; +- rockchip,key_table = +- <0xee KEY_REPLY>, +- <0xf0 KEY_BACK>, +- <0xf8 KEY_UP>, +- <0xbb KEY_DOWN>, +- <0xef KEY_LEFT>, +- <0xed KEY_RIGHT>, +- <0xfc KEY_HOME>, +- <0xf1 KEY_VOLUMEUP>, +- <0xfd KEY_VOLUMEDOWN>, +- <0xb7 KEY_SEARCH>, +- <0xff KEY_POWER>, +- <0xf3 KEY_MUTE>, +- <0xbf KEY_MENU>, +- <0xf9 0x191>, +- <0xf5 0x192>, +- <0xb3 388>, +- <0xbe KEY_1>, +- <0xba KEY_2>, +- <0xb2 KEY_3>, +- <0xbd KEY_4>, +- <0xf9 KEY_5>, +- <0xb1 KEY_6>, +- <0xfc KEY_7>, +- <0xf8 KEY_8>, +- <0xb0 KEY_9>, +- <0xb6 KEY_0>, +- <0xb5 KEY_BACKSPACE>; +- }; ++ pinctrl-names = "active"; ++ pinctrl-0 = <&pwm2_pin_pull_down>; + }; + + &pinctrl { +@@ -951,6 +891,13 @@ + }; + }; + ++ ir { ++ ir_int: ir-int { ++ rockchip,pins = ++ <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ + pcie { + pcie_pwr_en: pcie-pwr-en { + rockchip,pins = +@@ -982,6 +929,7 @@ + sdio-pwrseq { + wifi_enable_h: wifi-enable-h { + rockchip,pins = ++ <0 RK_PB1 RK_FUNC_GPIO &pcfg_pull_none>, + <0 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; +@@ -1085,35 +1033,6 @@ + status = "okay"; + }; + +-&rockchip_suspend { +- status = "okay"; +- rockchip,sleep-debug-en = <0>; +- rockchip,sleep-mode-config = < +- (0 +- | RKPM_SLP_ARMPD +- | RKPM_SLP_PERILPPD +- | RKPM_SLP_DDR_RET +- | RKPM_SLP_PLLPD +- | RKPM_SLP_CENTER_PD +- | RKPM_SLP_AP_PWROFF +- ) +- >; +- rockchip,wakeup-config = < +- (0 +- | RKPM_GPIO_WKUP_EN +- | RKPM_PWM_WKUP_EN +- ) +- >; +- rockchip,pwm-regulator-config = < +- (0 +- | PWM2_REGULATOR_EN +- ) +- >; +- rockchip,power-ctrl = +- <&gpio1 RK_PC1 GPIO_ACTIVE_HIGH>, +- <&gpio1 RK_PB6 GPIO_ACTIVE_HIGH>; +-}; +- + &vdec_mmu { + status = "okay"; + }; +@@ -1135,3 +1054,13 @@ + &vopb_mmu { + status = "okay"; + }; ++ ++&vopl { ++ status = "disabled"; ++ assigned-clocks = <&cru DCLK_VOP1_DIV>; ++ assigned-clock-parents = <&cru PLL_CPLL>; ++}; ++ ++&vopl_mmu { ++ status = "disabled"; ++}; + +From b48757753fd87cd0dc058e439bbd586dfbd4f6fb Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Mon, 17 Dec 2018 07:41:38 +0100 +Subject: [PATCH] arm64: dts: rockchip: add rk3399-khadas-edge board + +--- + .../arm64/boot/dts/rockchip/rk3399-khadas-edge.dts | 66 ++ + .../boot/dts/rockchip/rk3399-khadas-edge.dtsi | 1005 ++++++++++++++++++++ + 2 files changed, 1071 insertions(+) + create mode 100644 arch/arm64/boot/dts/rockchip/rk3399-khadas-edge.dts + create mode 100644 arch/arm64/boot/dts/rockchip/rk3399-khadas-edge.dtsi + +diff --git a/arch/arm64/boot/dts/rockchip/rk3399-khadas-edge.dts b/arch/arm64/boot/dts/rockchip/rk3399-khadas-edge.dts +new file mode 100644 +index 000000000000..1381ba09b72d +--- /dev/null ++++ b/arch/arm64/boot/dts/rockchip/rk3399-khadas-edge.dts +@@ -0,0 +1,66 @@ ++/* ++ * Copyright (c) 2018 Wesion Co., Ltd ++ * ++ * This file is dual-licensed: you can use it either under the terms ++ * of the GPL or the X11 license, at your option. Note that this dual ++ * licensing only applies to this file, and not this project as a ++ * whole. ++ * ++ * a) This file is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation; either version 2 of the ++ * License, or (at your option) any later version. ++ * ++ * This file is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * Or, alternatively, ++ * ++ * b) Permission is hereby granted, free of charge, to any person ++ * obtaining a copy of this software and associated documentation ++ * files (the "Software"), to deal in the Software without ++ * restriction, including without limitation the rights to use, ++ * copy, modify, merge, publish, distribute, sublicense, and/or ++ * sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following ++ * conditions: ++ * ++ * The above copyright notice and this permission notice shall be ++ * included in all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES ++ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ++ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT ++ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, ++ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING ++ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ++ * OTHER DEALINGS IN THE SOFTWARE. ++ */ ++ ++/dts-v1/; ++ ++#include "rk3399-khadas-edge.dtsi" ++ ++/ { ++ model = "Khadas Edge"; ++ compatible = "khadas,edge", "rockchip,rk3399"; ++}; ++ ++&gmac { ++ status = "okay"; ++}; ++ ++&fusb0 { ++ status = "okay"; ++ max-input-voltage = <13000000>; ++ max-input-current = <6000000>; ++}; ++ ++&fusb1 { ++ status = "okay"; ++ max-input-voltage = <13000000>; ++ max-input-current = <6000000>; ++}; +diff --git a/arch/arm64/boot/dts/rockchip/rk3399-khadas-edge.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-khadas-edge.dtsi +new file mode 100644 +index 000000000000..a7c14f6ccd92 +--- /dev/null ++++ b/arch/arm64/boot/dts/rockchip/rk3399-khadas-edge.dtsi +@@ -0,0 +1,1005 @@ ++/* ++ * Copyright (c) 2018 Wesion Co., Ltd ++ * ++ * This file is dual-licensed: you can use it either under the terms ++ * of the GPL or the X11 license, at your option. Note that this dual ++ * licensing only applies to this file, and not this project as a ++ * whole. ++ * ++ * a) This file is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation; either version 2 of the ++ * License, or (at your option) any later version. ++ * ++ * This file is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * Or, alternatively, ++ * ++ * b) Permission is hereby granted, free of charge, to any person ++ * obtaining a copy of this software and associated documentation ++ * files (the "Software"), to deal in the Software without ++ * restriction, including without limitation the rights to use, ++ * copy, modify, merge, publish, distribute, sublicense, and/or ++ * sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following ++ * conditions: ++ * ++ * The above copyright notice and this permission notice shall be ++ * included in all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES ++ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ++ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT ++ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, ++ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING ++ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ++ * OTHER DEALINGS IN THE SOFTWARE. ++ */ ++ ++/dts-v1/; ++#include ++#include ++#include "rk3399.dtsi" ++#include "rk3399-linux.dtsi" ++#include "rk3399-opp.dtsi" ++ ++/ { ++ compatible = "khadas,edge", "rockchip,rk3399"; ++ ++ /* first 64k(0xff8c0000~0xff8d0000) for ddr and suspend */ ++ iram: sram@ff8d0000 { ++ compatible = "mmio-sram"; ++ reg = <0x0 0xff8d0000 0x0 0x20000>; /* 128k */ ++ }; ++ ++ gpio-keys { ++ compatible = "gpio-keys"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ autorepeat; ++ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pwrbtn>; ++ ++ button@0 { ++ gpios = <&gpio0 5 GPIO_ACTIVE_LOW>; ++ linux,code = ; ++ label = "GPIO Key Power"; ++ linux,input-type = <1>; ++ gpio-key,wakeup = <1>; ++ debounce-interval = <100>; ++ }; ++ }; ++ ++ vccadc_ref: vccadc-ref { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc1v8_sys"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ }; ++ ++ adc-keys { ++ compatible = "adc-keys"; ++ io-channels = <&saradc 1>; ++ io-channel-names = "buttons"; ++ poll-interval = <100>; ++ keyup-threshold-microvolt = <1800000>; ++ ++ button-up { ++ label = "Volume Up"; ++ linux,code = ; ++ press-threshold-microvolt = <100000>; ++ }; ++ ++ button-down { ++ label = "Volume Down"; ++ linux,code = ; ++ press-threshold-microvolt = <300000>; ++ }; ++ ++ back { ++ label = "Back"; ++ linux,code = ; ++ press-threshold-microvolt = <985000>; ++ }; ++ ++ menu { ++ label = "Menu"; ++ linux,code = ; ++ press-threshold-microvolt = <1314000>; ++ }; ++ }; ++ ++ clkin_gmac: external-gmac-clock { ++ compatible = "fixed-clock"; ++ clock-frequency = <125000000>; ++ clock-output-names = "clkin_gmac"; ++ #clock-cells = <0>; ++ }; ++ ++ dw_hdmi_audio: dw-hdmi-audio { ++ status = "disabled"; ++ compatible = "rockchip,dw-hdmi-audio"; ++ #sound-dai-cells = <0>; ++ }; ++ ++ hdmi-sound { ++ compatible = "simple-audio-card"; ++ simple-audio-card,format = "i2s"; ++ simple-audio-card,mclk-fs = <256>; ++ simple-audio-card,name = "HDMI"; ++ simple-audio-card,cpu { ++ sound-dai = <&i2s2>; ++ }; ++ simple-audio-card,codec { ++ sound-dai = <&hdmi>; ++ }; ++ }; ++ ++ hdmi-dp-sound { ++ compatible = "rockchip,rk3399-hdmi-dp"; ++ rockchip,cpu = <&i2s2>; ++ rockchip,codec = <&hdmi>, <&cdn_dp>; ++ status = "disabled"; ++ }; ++ ++ sdio_pwrseq: sdio-pwrseq { ++ compatible = "mmc-pwrseq-simple"; ++ clocks = <&rk808 1>; ++ clock-names = "ext_clock"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&wifi_enable_h>; ++ ++ /* ++ * On the module itself this is one of these (depending ++ * on the actual card populated): ++ * - SDIO_RESET_L_WL_REG_ON ++ * - PDN (power down when low) ++ */ ++ reset-gpios = <&gpio2 28 GPIO_ACTIVE_LOW>; /* GPIO2_D4 */ ++ }; ++ ++ wireless-wlan { ++ compatible = "wlan-platdata"; ++ rockchip,grf = <&grf>; ++ wifi_chip_type = "ap6354"; ++ sdio_vref = <1800>; ++ WIFI,host_wake_irq = <&gpio0 3 GPIO_ACTIVE_HIGH>; /* GPIO0_a3 */ ++ status = "okay"; ++ }; ++ ++ wireless-bluetooth { ++ compatible = "bluetooth-platdata"; ++ //wifi-bt-power-toggle; ++ uart_rts_gpios = <&gpio2 19 GPIO_ACTIVE_LOW>; /* GPIO2_C3 */ ++ pinctrl-names = "default", "rts_gpio"; ++ pinctrl-0 = <&uart0_rts>; ++ pinctrl-1 = <&uart0_gpios>; ++ //BT,power_gpio = <&gpio3 19 GPIO_ACTIVE_HIGH>; /* GPIOx_xx */ ++ BT,reset_gpio = <&gpio2 27 GPIO_ACTIVE_HIGH>; /* GPIO2_D3 */ ++ BT,wake_gpio = <&gpio2 26 GPIO_ACTIVE_HIGH>; /* GPIO2_D2 */ ++ BT,wake_host_irq = <&gpio0 4 GPIO_ACTIVE_HIGH>; /* GPIO0_A4 */ ++ status = "okay"; ++ }; ++ ++ leds { ++ compatible = "gpio-leds"; ++ pinctrl-names = "default"; ++ ++ sys_led { ++ gpios = <&gpio0 6 GPIO_ACTIVE_HIGH>; /* GPIO0_A6 */ ++ label = "sys_led"; ++ linux,default-trigger = "heartbeat"; ++ default-state = "on"; ++ }; ++ }; ++ ++ ir-receiver { ++ compatible = "gpio-ir-receiver"; ++ gpios = <&gpio1 RK_PB6 GPIO_ACTIVE_LOW>; ++ linux,rc-map-name = "rc-khadas"; ++ pinctrl-0 = <&ir_int>; ++ pinctrl-names = "default"; ++ }; ++ ++ 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>; ++ }; ++ ++ vcc5v0_host: vcc5v0-host-regulator { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpio = <&gpio4 25 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&host_vbus_drv>; ++ regulator-name = "vcc5v0_host"; ++ regulator-always-on; ++ }; ++ ++ 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>; ++ }; ++ ++ vcc_sd: vcc-sd { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ regulator-boot-on; ++ regulator-always-on; ++ gpio = <&gpio0 1 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&vcc_sd_h>; ++ regulator-name = "vcc_sd"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ }; ++ ++ vcc_phy: vcc-phy-regulator { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc_phy"; ++ regulator-always-on; ++ regulator-boot-on; ++ }; ++ ++ vdd_log: vdd-log { ++ compatible = "pwm-regulator"; ++ pwms = <&pwm2 0 25000 1>; ++ regulator-name = "vdd_log"; ++ regulator-min-microvolt = <800000>; ++ regulator-max-microvolt = <1400000>; ++ regulator-always-on; ++ regulator-boot-on; ++ ++ /* for rockchip boot on */ ++ rockchip,pwm_id= <2>; ++ rockchip,pwm_voltage = <900000>; ++ }; ++ ++ xin32k: xin32k { ++ compatible = "fixed-clock"; ++ clock-frequency = <32768>; ++ clock-output-names = "xin32k"; ++ #clock-cells = <0>; ++ }; ++ ++ fan0: pwm-fan { ++ compatible = "pwm-fan"; ++ status = "okay"; ++ pwms = <&pwm0 0 40000 0>; /* 25kHz */ ++ cooling-min-state = <0>; ++ cooling-max-state = <3>; ++ #cooling-cells = <2>; ++ cooling-levels = <0 150 200 255>; ++ }; ++}; ++ ++&cdn_dp { ++ status = "okay"; ++ extcon = <&fusb0>; ++ phys = <&tcphy0_dp>; ++}; ++ ++&cpu_l0 { ++ cpu-supply = <&vdd_cpu_l>; ++}; ++ ++&cpu_l1 { ++ cpu-supply = <&vdd_cpu_l>; ++}; ++ ++&cpu_l2 { ++ cpu-supply = <&vdd_cpu_l>; ++}; ++ ++&cpu_l3 { ++ cpu-supply = <&vdd_cpu_l>; ++}; ++ ++&cpu_b0 { ++ cpu-supply = <&vdd_cpu_b>; ++}; ++ ++&cpu_b1 { ++ cpu-supply = <&vdd_cpu_b>; ++}; ++ ++&dfi { ++ status = "okay"; ++}; ++ ++&dmac_bus { ++ iram = <&iram>; ++}; ++ ++&dmc { ++ status = "okay"; ++ center-supply = <&vdd_center>; ++ system-status-freq = < ++ /*system status freq(KHz)*/ ++ SYS_STATUS_NORMAL 800000 ++ SYS_STATUS_REBOOT 400000 ++ SYS_STATUS_SUSPEND 400000 ++ SYS_STATUS_VIDEO_1080P 800000 ++ SYS_STATUS_VIDEO_4K 800000 ++ SYS_STATUS_VIDEO_4K_10B 800000 ++ SYS_STATUS_PERFORMANCE 800000 ++ SYS_STATUS_BOOST 800000 ++ SYS_STATUS_DUALVIEW 800000 ++ SYS_STATUS_ISP 800000 ++ >; ++ auto-min-freq = <400000>; ++ auto-freq-en = <0>; ++}; ++ ++&dmc_opp_table { ++ compatible = "operating-points-v2"; ++ ++ opp-200000000 { ++ opp-hz = /bits/ 64 <200000000>; ++ opp-microvolt = <825000>; ++ status = "disabled"; ++ }; ++ opp-300000000 { ++ opp-hz = /bits/ 64 <300000000>; ++ opp-microvolt = <850000>; ++ status = "disabled"; ++ }; ++ opp-400000000 { ++ opp-hz = /bits/ 64 <400000000>; ++ opp-microvolt = <900000>; ++ }; ++ opp-528000000 { ++ opp-hz = /bits/ 64 <528000000>; ++ opp-microvolt = <900000>; ++ status = "disabled"; ++ }; ++ opp-600000000 { ++ opp-hz = /bits/ 64 <600000000>; ++ opp-microvolt = <900000>; ++ status = "disabled"; ++ }; ++ opp-800000000 { ++ opp-hz = /bits/ 64 <800000000>; ++ opp-microvolt = <900000>; ++ }; ++ opp-928000000 { ++ opp-hz = /bits/ 64 <928000000>; ++ opp-microvolt = <900000>; ++ status = "disabled"; ++ }; ++ opp-1056000000 { ++ opp-hz = /bits/ 64 <1056000000>; ++ opp-microvolt = <900000>; ++ status = "disabled"; ++ }; ++}; ++ ++&display_subsystem { ++ status = "okay"; ++ ++ route { ++ route_hdmi: route-hdmi { ++ status = "okay"; ++ connect = <&vopb_out_hdmi>; ++ }; ++ ++ route_dp: route-dp { ++ connect = <&vopl_out_dp>; ++ }; ++ }; ++}; ++ ++&emmc_phy { ++ status = "okay"; ++}; ++ ++&i2c4 { ++ status = "okay"; ++ i2c-scl-rising-time-ns = <168>; ++ i2c-scl-falling-time-ns = <4>; ++ clock-frequency = <400000>; ++ ++ vdd_cpu_b: syr827@40 { ++ compatible = "silergy,syr827"; ++ reg = <0x40>; ++ vin-supply = <&vcc5v0_sys>; ++ regulator-compatible = "fan53555-reg"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&vsel1_gpio>; ++ vsel-gpios = <&gpio1 13 GPIO_ACTIVE_HIGH>; /* GPIO1_B5 */ ++ regulator-name = "vdd_cpu_b"; ++ regulator-min-microvolt = <712500>; ++ regulator-max-microvolt = <1500000>; ++ regulator-ramp-delay = <1000>; ++ fcs,suspend-voltage-selector = <1>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-initial-state = <3>; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vdd_gpu: syr828@41 { ++ compatible = "silergy,syr828"; ++ reg = <0x41>; ++ vin-supply = <&vcc5v0_sys>; ++ regulator-compatible = "fan53555-reg"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&vsel2_gpio>; ++ sel-gpios = <&gpio0 13 GPIO_ACTIVE_HIGH>;/* GPIO0_B5 */ ++ regulator-name = "vdd_gpu"; ++ regulator-min-microvolt = <712500>; ++ regulator-max-microvolt = <1500000>; ++ regulator-ramp-delay = <1000>; ++ fcs,suspend-voltage-selector = <1>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-initial-state = <3>; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ rk808: pmic@1b { ++ compatible = "rockchip,rk808"; ++ reg = <0x1b>; ++ interrupt-parent = <&gpio1>; ++ interrupts = <22 IRQ_TYPE_LEVEL_LOW>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pmic_int_l &pmic_dvs2>; ++ rockchip,system-power-controller; ++ wakeup-source; ++ #clock-cells = <1>; ++ clock-output-names = "rk808-clkout1", "rk808-clkout2"; ++ ++ vcc1-supply = <&vcc3v3_sys>; ++ vcc2-supply = <&vcc3v3_sys>; ++ vcc3-supply = <&vcc3v3_sys>; ++ vcc4-supply = <&vcc3v3_sys>; ++ vcc6-supply = <&vcc3v3_sys>; ++ vcc7-supply = <&vcc3v3_sys>; ++ vcc8-supply = <&vcc3v3_sys>; ++ vcc9-supply = <&vcc3v3_sys>; ++ vcc10-supply = <&vcc3v3_sys>; ++ vcc11-supply = <&vcc3v3_sys>; ++ vcc12-supply = <&vcc3v3_sys>; ++ vddio-supply = <&vcc1v8_pmu>; ++ ++ regulators { ++ vdd_center: DCDC_REG1 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <750000>; ++ regulator-max-microvolt = <1350000>; ++ regulator-ramp-delay = <6001>; ++ regulator-name = "vdd_center"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vdd_cpu_l: DCDC_REG2 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <750000>; ++ regulator-max-microvolt = <1350000>; ++ regulator-ramp-delay = <6001>; ++ regulator-name = "vdd_cpu_l"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcc_ddr: DCDC_REG3 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-name = "vcc_ddr"; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ }; ++ }; ++ ++ vcc_1v8: DCDC_REG4 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-name = "vcc_1v8"; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ vcc1v8_apio2: LDO_REG1 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-name = "vcc1v8_apio2"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcc3v0_tp: LDO_REG2 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <3000000>; ++ regulator-max-microvolt = <3000000>; ++ regulator-name = "vcc3v0_tp"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcc1v8_pmu: LDO_REG3 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-name = "vcc1v8_pmu"; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ vccio_sd: LDO_REG4 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <3000000>; ++ regulator-name = "vccio_sd"; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <3000000>; ++ }; ++ }; ++ ++ vcc_vldo5: LDO_REG5 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <3000000>; ++ regulator-max-microvolt = <3000000>; ++ regulator-name = "vcc_vldo5"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcc_1v5: LDO_REG6 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1500000>; ++ regulator-max-microvolt = <1500000>; ++ regulator-name = "vcc_1v5"; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1500000>; ++ }; ++ }; ++ ++ vcca1v8_codec: LDO_REG7 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-name = "vcca1v8_codec"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcc_3v0: LDO_REG8 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <3000000>; ++ regulator-max-microvolt = <3000000>; ++ regulator-name = "vcc_3v0"; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <3000000>; ++ }; ++ }; ++ ++ vcc3v3_s3: SWITCH_REG1 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-name = "vcc3v3_s3"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcc3v3_s0: SWITCH_REG2 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-name = "vcc3v3_s0"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ }; ++ }; ++ ++ fusb1: fusb30x@22 { ++ compatible = "fairchild,fusb302"; ++ reg = <0x22>; ++ //fusb302,role="ROLE_MODE_UFP"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&fusb1_int>; ++ int-n-gpios = <&gpio4 30 GPIO_ACTIVE_HIGH>; ++ support-uboot-charge = <1>; ++ port-num = <1>; ++ status = "okay"; ++ }; ++}; ++ ++&i2c8 { ++ status = "okay"; ++ i2c-scl-rising-time-ns = <475>; ++ i2c-scl-falling-time-ns = <26>; ++ ++ fusb0: fusb30x@22 { ++ compatible = "fairchild,fusb302"; ++ reg = <0x22>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&fusb0_int>; ++ int-n-gpios = <&gpio1 2 GPIO_ACTIVE_HIGH>; ++ vbus-5v-gpios = <&gpio4 26 GPIO_ACTIVE_HIGH>; ++ status = "okay"; ++ }; ++}; ++ ++&i2s2 { ++ #sound-dai-cells = <0>; ++ rockchip,bclk-fs = <128>; ++ status = "okay"; ++}; ++ ++&gmac { ++ phy-supply = <&vcc_phy>; ++ phy-mode = "rgmii"; ++ clock_in_out = "input"; ++ snps,reset-gpio = <&gpio3 15 GPIO_ACTIVE_LOW>; ++ snps,reset-active-low; ++ snps,reset-delays-us = <0 20000 100000>; ++ assigned-clocks = <&cru SCLK_RMII_SRC>; ++ assigned-clock-parents = <&clkin_gmac>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&rgmii_pins>; ++ tx_delay = <0x28>; ++ rx_delay = <0x11>; ++ status = "disabled"; ++}; ++ ++&gpu { ++ status = "okay"; ++ mali-supply = <&vdd_gpu>; ++}; ++ ++&hdmi { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ #sound-dai-cells = <0>; ++ status = "okay"; ++}; ++ ++&iep { ++ status = "okay"; ++}; ++ ++&iep_mmu { ++ status = "okay"; ++}; ++ ++&io_domains { ++ status = "okay"; ++ ++ bt656-supply = <&vcc1v8_apio2>; /* bt656_gpio2ab_ms */ ++ audio-supply = <&vcca1v8_codec>; /* audio_gpio3d4a_ms */ ++ sdmmc-supply = <&vccio_sd>; /* sdmmc_gpio4b_ms */ ++ gpio1830-supply = <&vcc_3v0>; /* gpio1833_gpio4cd_ms */ ++}; ++ ++&saradc { ++ status = "okay"; ++}; ++ ++&sdmmc { ++ clock-frequency = <150000000>; ++ max-frequency = <150000000>; ++ supports-sd; ++ bus-width = <4>; ++ cap-mmc-highspeed; ++ cap-sd-highspeed; ++ disable-wp; ++ num-slots = <1>; ++ sd-uhs-sdr12; ++ sd-uhs-sdr25; ++ sd-uhs-sdr50; ++ sd-uhs-sdr104; ++ vmmc-supply = <&vcc_sd>; ++ vqmmc-supply = <&vccio_sd>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd &sdmmc_bus4>; ++ status = "okay"; ++}; ++ ++&sdio0 { ++ clock-frequency = <200000000>; ++ max-frequency = <200000000>; ++ supports-sdio; ++ bus-width = <4>; ++ disable-wp; ++ cap-sd-highspeed; ++ cap-sdio-irq; ++ keep-power-in-suspend; ++ mmc-pwrseq = <&sdio_pwrseq>; ++ non-removable; ++ num-slots = <1>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdio0_bus4 &sdio0_cmd &sdio0_clk>; ++ sd-uhs-sdr104; ++ status = "okay"; ++}; ++ ++&sdhci { ++ bus-width = <8>; ++ mmc-hs400-1_8v; ++ mmc-hs400-enhanced-strobe; ++ supports-emmc; ++ non-removable; ++ keep-power-in-suspend; ++ status = "okay"; ++}; ++ ++&tcphy0 { ++ extcon = <&fusb0>; ++ status = "okay"; ++}; ++ ++&tcphy1 { ++ status = "okay"; ++}; ++ ++&tsadc { ++ /* tshut mode 0:CRU 1:GPIO */ ++ rockchip,hw-tshut-mode = <1>; ++ /* tshut polarity 0:LOW 1:HIGH */ ++ rockchip,hw-tshut-polarity = <1>; ++ status = "okay"; ++}; ++ ++&u2phy0 { ++ status = "okay"; ++ extcon = <&fusb0>; ++ ++ u2phy0_otg: otg-port { ++ status = "okay"; ++ }; ++ ++ u2phy0_host: host-port { ++ phy-supply = <&vcc5v0_host>; ++ status = "okay"; ++ }; ++}; ++ ++&u2phy1 { ++ status = "okay"; ++ ++ u2phy1_otg: otg-port { ++ status = "okay"; ++ }; ++ ++ u2phy1_host: host-port { ++ phy-supply = <&vcc5v0_host>; ++ status = "okay"; ++ }; ++}; ++ ++&uart0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart0_xfer &uart0_cts>; ++ status = "okay"; ++}; ++ ++&uart2 { ++ status = "okay"; ++}; ++ ++&usb_host0_ehci { ++ status = "okay"; ++}; ++ ++&usb_host0_ohci { ++ status = "okay"; ++}; ++ ++&usb_host1_ehci { ++ status = "okay"; ++}; ++ ++&usb_host1_ohci { ++ status = "okay"; ++}; ++ ++&usbdrd3_0 { ++ extcon = <&fusb0>; ++ status = "okay"; ++}; ++ ++&usbdrd_dwc3_0 { ++ status = "okay"; ++}; ++ ++&usbdrd3_1 { ++ status = "okay"; ++}; ++ ++&usbdrd_dwc3_1 { ++ dr_mode = "host"; ++ status = "okay"; ++}; ++ ++&pwm0 { ++ status = "okay"; ++}; ++ ++&pwm2 { ++ status = "okay"; ++ pinctrl-names = "active"; ++ pinctrl-0 = <&pwm2_pin_pull_down>; ++}; ++ ++&saradc { ++ vref-supply = <&vccadc_ref>; ++}; ++ ++&route_edp { ++ status = "disabled"; ++}; ++ ++&pinctrl { ++ ir { ++ ir_int: ir-int { ++ rockchip,pins = ++ <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ pmic { ++ pmic_int_l: pmic-int-l { ++ rockchip,pins = ++ <1 22 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ ++ pmic_dvs2: pmic-dvs2 { ++ rockchip,pins = ++ <1 18 RK_FUNC_GPIO &pcfg_pull_down>; ++ }; ++ vsel1_gpio: vsel1-gpio { ++ rockchip,pins = ++ <1 13 RK_FUNC_GPIO &pcfg_pull_down>; ++ }; ++ vsel2_gpio: vsel2-gpio { ++ rockchip,pins = ++ <0 13 RK_FUNC_GPIO &pcfg_pull_down>; ++ }; ++ }; ++ ++ usb2 { ++ host_vbus_drv: host-vbus-drv { ++ rockchip,pins = ++ <4 25 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ vcc_sd { ++ vcc_sd_h: vcc-sd-h { ++ rockchip,pins = ++ <0 1 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ }; ++ ++ fusb30x { ++ fusb0_int: fusb0-int { ++ rockchip,pins = <1 2 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ fusb1_int: fusb1-int { ++ rockchip,pins = <4 30 RK_FUNC_GPIO &pcfg_pull_up>; /* GPIO4_D6 */ ++ }; ++ }; ++ ++ buttons { ++ pwrbtn: pwrbtn { ++ rockchip,pins = <0 5 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ }; ++ ++ lcd-panel { ++ lcd_panel_reset: lcd-panel-reset { ++ rockchip,pins = <4 30 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ }; ++ ++ sdio-pwrseq { ++ wifi_enable_h: wifi-enable-h { ++ rockchip,pins = ++ <2 28 RK_FUNC_GPIO &pcfg_pull_none>; /* GPIO2_D4 */ ++ }; ++ }; ++ ++ wireless-bluetooth { ++ uart0_gpios: uart0-gpios { ++ rockchip,pins = ++ <2 27 RK_FUNC_GPIO &pcfg_pull_none>; /* GPIO2_D3 */ ++ }; ++ }; ++}; ++ ++&pvtm { ++ status = "okay"; ++}; ++ ++&pmu_pvtm { ++ status = "okay"; ++}; ++ ++&pmu_io_domains { ++ status = "okay"; ++ pmu1830-supply = <&vcc_1v8>; ++}; ++ ++&rkvdec { ++ status = "okay"; ++}; ++ ++&vdec_mmu { ++ status = "okay"; ++}; ++ ++&vpu { ++ status = "okay"; ++}; ++ ++&vpu_mmu { ++ status = "okay"; ++}; ++ ++&vopb { ++ status = "okay"; ++ assigned-clocks = <&cru DCLK_VOP0_DIV>; ++ assigned-clock-parents = <&cru PLL_VPLL>; ++}; ++ ++&vopb_mmu { ++ status = "okay"; ++}; ++ ++&vopl { ++ status = "disabled"; ++ assigned-clocks = <&cru DCLK_VOP1_DIV>; ++ assigned-clock-parents = <&cru PLL_CPLL>; ++}; ++ ++&vopl_mmu { ++ status = "disabled"; ++}; + +From 2de45e1b4eb4b763bf396e768e5add15433ba0f0 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sat, 19 Jan 2019 19:31:40 +0100 +Subject: [PATCH] arm64: dts: rockchip: add rk3399-rock-pi-4 board + +--- + arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dts | 926 ++++++++++++++++++++++ + 1 file changed, 926 insertions(+) + create mode 100644 arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dts + +diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dts b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dts +new file mode 100644 +index 000000000000..7b376aee97c4 +--- /dev/null ++++ b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dts +@@ -0,0 +1,926 @@ ++/* ++ * Copyright (c) 2016 Fuzhou Rockchip Electronics Co., Ltd ++ * ++ * This file is dual-licensed: you can use it either under the terms ++ * of the GPL or the X11 license, at your option. Note that this dual ++ * licensing only applies to this file, and not this project as a ++ * whole. ++ * ++ * a) This file is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation; either version 2 of the ++ * License, or (at your option) any later version. ++ * ++ * This file is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * Or, alternatively, ++ * ++ * b) Permission is hereby granted, free of charge, to any person ++ * obtaining a copy of this software and associated documentation ++ * files (the "Software"), to deal in the Software without ++ * restriction, including without limitation the rights to use, ++ * copy, modify, merge, publish, distribute, sublicense, and/or ++ * sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following ++ * conditions: ++ * ++ * The above copyright notice and this permission notice shall be ++ * included in all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES ++ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ++ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT ++ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, ++ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING ++ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ++ * OTHER DEALINGS IN THE SOFTWARE. ++ */ ++ ++/dts-v1/; ++#include ++#include ++#include "rk3399.dtsi" ++#include "rk3399-linux.dtsi" ++#include "rk3399-opp.dtsi" ++ ++/ { ++ model = "Radxa ROCK Pi 4"; ++ compatible = "radxa,rockpi4", "rockchip,rk3399"; ++ ++ xin32k: xin32k { ++ compatible = "fixed-clock"; ++ clock-frequency = <32768>; ++ clock-output-names = "xin32k"; ++ #clock-cells = <0>; ++ }; ++ ++ clkin_gmac: external-gmac-clock { ++ compatible = "fixed-clock"; ++ clock-frequency = <125000000>; ++ clock-output-names = "clkin_gmac"; ++ #clock-cells = <0>; ++ }; ++ ++ vcc1v8_s0: vcc1v8-s0 { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc1v8_s0"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-always-on; ++ }; ++ ++ vcc_sys: vcc-sys { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc_sys"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ regulator-always-on; ++ }; ++ ++ vcc_phy: vcc-phy-regulator { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc_phy"; ++ regulator-always-on; ++ regulator-boot-on; ++ }; ++ ++ vcc3v3_sys: vcc3v3-sys { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc3v3_sys"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-always-on; ++ vin-supply = <&vcc_sys>; ++ }; ++ ++ vcc3v3_pcie: vcc3v3-pcie-regulator { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpio = <&gpio2 RK_PD2 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pcie_drv>; ++ regulator-boot-on; ++ regulator-always-on; ++ regulator-name = "vcc3v3_pcie"; ++ vin-supply = <&vcc3v3_sys>; ++ }; ++ ++ vcc5v0_host: vcc5v0-host-regulator { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpio = <&gpio4 RK_PD1 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&host_vbus_drv>; ++ regulator-name = "vcc5v0_host"; ++ regulator-always-on; ++ }; ++ ++ vcc5v0_otg: vcc5v0-otg-regulator { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpio = <&gpio1 RK_PA3 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&otg_vbus_drv>; ++ regulator-name = "vcc5v0_otg"; ++ regulator-always-on; ++ }; ++ ++ vdd_log: vdd-log { ++ compatible = "pwm-regulator"; ++ pwms = <&pwm2 0 25000 1>; ++ regulator-name = "vdd_log"; ++ regulator-min-microvolt = <800000>; ++ regulator-max-microvolt = <1400000>; ++ regulator-always-on; ++ regulator-boot-on; ++ ++ /* for rockchip boot on */ ++ rockchip,pwm_id= <2>; ++ rockchip,pwm_voltage = <900000>; ++ ++ vin-supply = <&vcc_sys>; ++ }; ++ ++ leds { ++ compatible = "gpio-leds"; ++ ++ user-led1 { ++ gpios=<&gpio3 RK_PD4 GPIO_ACTIVE_HIGH>; ++ linux,default-trigger = "mmc0"; ++ }; ++ ++ user-led2 { ++ gpios=<&gpio3 RK_PD5 GPIO_ACTIVE_HIGH>; ++ linux,default-trigger = "heartbeat"; ++ }; ++ }; ++ ++ hdmi-sound { ++ compatible = "simple-audio-card"; ++ simple-audio-card,format = "i2s"; ++ simple-audio-card,mclk-fs = <256>; ++ simple-audio-card,name = "HDMI"; ++ simple-audio-card,cpu { ++ sound-dai = <&i2s2>; ++ }; ++ simple-audio-card,codec { ++ sound-dai = <&hdmi>; ++ }; ++ }; ++ ++ es8316-sound { ++ compatible = "simple-audio-card"; ++ simple-audio-card,format = "i2s"; ++ simple-audio-card,name = "ES8316"; ++ simple-audio-card,mclk-fs = <256>; ++ simple-audio-card,widgets = ++ "Microphone", "Mic Jack", ++ "Headphone", "Headphone Jack"; ++ simple-audio-card,routing = ++ "Mic Jack", "MICBIAS1", ++ "IN1P", "Mic Jack", ++ "Headphone Jack", "HPOL", ++ "Headphone Jack", "HPOR"; ++ simple-audio-card,cpu { ++ sound-dai = <&i2s0>; ++ }; ++ simple-audio-card,codec { ++ sound-dai = <&es8316>; ++ }; ++ }; ++ ++ sdio_pwrseq: sdio-pwrseq { ++ compatible = "mmc-pwrseq-simple"; ++ clocks = <&rk808 1>; ++ clock-names = "ext_clock"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&wifi_enable_h>; ++ ++ /* ++ * On the module itself this is one of these (depending ++ * on the actual card populated): ++ * - SDIO_RESET_L_WL_REG_ON ++ * - PDN (power down when low) ++ */ ++ reset-gpios = <&gpio0 RK_PB2 GPIO_ACTIVE_LOW>; ++ }; ++ ++ wireless-wlan { ++ compatible = "wlan-platdata"; ++ rockchip,grf = <&grf>; ++ wifi_chip_type = "ap6256"; ++ sdio_vref = <1800>; ++ WIFI,host_wake_irq = <&gpio0 RK_PA3 GPIO_ACTIVE_HIGH>; ++ status = "okay"; ++ }; ++ ++ wireless-bluetooth { ++ compatible = "bluetooth-platdata"; ++ clocks = <&rk808 1>; ++ clock-names = "ext_clock"; ++ uart_rts_gpios = <&gpio2 RK_PC3 GPIO_ACTIVE_LOW>; ++ pinctrl-names = "default", "rts_gpio"; ++ pinctrl-0 = <&uart0_rts>; ++ pinctrl-1 = <&uart0_gpios>; ++ BT,reset_gpio = <&gpio0 RK_PB1 GPIO_ACTIVE_HIGH>; ++ BT,wake_gpio = <&gpio2 RK_PD3 GPIO_ACTIVE_HIGH>; ++ BT,wake_host_irq = <&gpio0 RK_PA4 GPIO_ACTIVE_HIGH>; ++ status = "okay"; ++ }; ++}; ++ ++&cpu_l0 { ++ cpu-supply = <&vdd_cpu_l>; ++}; ++ ++&cpu_l1 { ++ cpu-supply = <&vdd_cpu_l>; ++}; ++ ++&cpu_l2 { ++ cpu-supply = <&vdd_cpu_l>; ++}; ++ ++&cpu_l3 { ++ cpu-supply = <&vdd_cpu_l>; ++}; ++ ++&cpu_b0 { ++ cpu-supply = <&vdd_cpu_b>; ++}; ++ ++&cpu_b1 { ++ cpu-supply = <&vdd_cpu_b>; ++}; ++ ++&display_subsystem { ++ status = "okay"; ++ ++ route { ++ route_hdmi: route-hdmi { ++ status = "okay"; ++ connect = <&vopb_out_hdmi>; ++ }; ++ }; ++}; ++ ++&emmc_phy { ++ status = "okay"; ++}; ++ ++&i2c0 { ++ status = "okay"; ++ i2c-scl-rising-time-ns = <168>; ++ i2c-scl-falling-time-ns = <4>; ++ clock-frequency = <400000>; ++ ++ vdd_cpu_b: syr827@40 { ++ compatible = "silergy,syr827"; ++ reg = <0x40>; ++ regulator-compatible = "fan53555-reg"; ++ pinctrl-0 = <&vsel1_gpio>; ++ vsel-gpios = <&gpio1 RK_PC1 GPIO_ACTIVE_HIGH>; ++ regulator-name = "vdd_cpu_b"; ++ regulator-min-microvolt = <712500>; ++ regulator-max-microvolt = <1500000>; ++ regulator-ramp-delay = <1000>; ++ fcs,suspend-voltage-selector = <1>; ++ regulator-always-on; ++ regulator-boot-on; ++ vin-supply = <&vcc_sys>; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vdd_gpu: syr828@41 { ++ compatible = "silergy,syr828"; ++ reg = <0x41>; ++ regulator-compatible = "fan53555-reg"; ++ pinctrl-0 = <&vsel2_gpio>; ++ vsel-gpios = <&gpio1 RK_PB6 GPIO_ACTIVE_HIGH>; ++ regulator-name = "vdd_gpu"; ++ regulator-min-microvolt = <712500>; ++ regulator-max-microvolt = <1500000>; ++ regulator-ramp-delay = <1000>; ++ fcs,suspend-voltage-selector = <1>; ++ regulator-always-on; ++ regulator-boot-on; ++ vin-supply = <&vcc_sys>; ++ regulator-initial-mode = <1>; /* 1:force PWM 2:auto */ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ rk808: pmic@1b { ++ compatible = "rockchip,rk808"; ++ reg = <0x1b>; ++ interrupt-parent = <&gpio1>; ++ interrupts = <21 IRQ_TYPE_LEVEL_LOW>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pmic_int_l>; ++ rockchip,system-power-controller; ++ wakeup-source; ++ #clock-cells = <1>; ++ clock-output-names = "rk808-clkout1", "rk808-clkout2"; ++ ++ vcc1-supply = <&vcc_sys>; ++ vcc2-supply = <&vcc_sys>; ++ vcc3-supply = <&vcc_sys>; ++ vcc4-supply = <&vcc_sys>; ++ vcc6-supply = <&vcc_sys>; ++ vcc7-supply = <&vcc_sys>; ++ vcc8-supply = <&vcc3v3_sys>; ++ vcc9-supply = <&vcc_sys>; ++ vcc10-supply = <&vcc_sys>; ++ vcc11-supply = <&vcc_sys>; ++ vcc12-supply = <&vcc3v3_sys>; ++ vddio-supply = <&vcc_1v8>; ++ ++ regulators { ++ vdd_center: DCDC_REG1 { ++ regulator-name = "vdd_center"; ++ regulator-min-microvolt = <750000>; ++ regulator-max-microvolt = <1350000>; ++ regulator-ramp-delay = <6001>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vdd_cpu_l: DCDC_REG2 { ++ regulator-name = "vdd_cpu_l"; ++ regulator-min-microvolt = <750000>; ++ regulator-max-microvolt = <1350000>; ++ regulator-ramp-delay = <6001>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcc_ddr: DCDC_REG3 { ++ regulator-name = "vcc_ddr"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ }; ++ }; ++ ++ vcc_1v8: DCDC_REG4 { ++ regulator-name = "vcc_1v8"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ vcc1v8_dvp: LDO_REG1 { ++ regulator-name = "vcc1v8_codec"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ vcca1v8_hdmi: LDO_REG2 { ++ regulator-name = "vcca1v8_hdmi"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ vcca_1v8: LDO_REG3 { ++ regulator-name = "vcca_1v8"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ vcc_sd: LDO_REG4 { ++ regulator-name = "vcc_sd"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <3000000>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <3000000>; ++ }; ++ }; ++ ++ vcc3v0_sd: LDO_REG5 { ++ regulator-name = "vcc3v0_sd"; ++ regulator-min-microvolt = <3000000>; ++ regulator-max-microvolt = <3000000>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <3000000>; ++ }; ++ }; ++ ++ vcc_1v5: LDO_REG6 { ++ regulator-name = "vcc_1v5"; ++ regulator-min-microvolt = <1500000>; ++ regulator-max-microvolt = <1500000>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1500000>; ++ }; ++ }; ++ ++ vcca0v9_hdmi: LDO_REG7 { ++ regulator-name = "vcca0v9_hdmi"; ++ regulator-min-microvolt = <900000>; ++ regulator-max-microvolt = <900000>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <900000>; ++ }; ++ }; ++ ++ vcc_3v0: LDO_REG8 { ++ regulator-name = "vcc_3v0"; ++ regulator-min-microvolt = <3000000>; ++ regulator-max-microvolt = <3000000>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <3000000>; ++ }; ++ }; ++ ++ vcc3v3_s3: SWITCH_REG1 { ++ regulator-name = "vcc3v3_s3"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ }; ++ }; ++ ++ vcc3v3_s0: SWITCH_REG2 { ++ regulator-name = "vcc3v3_s0"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ }; ++ }; ++ }; ++ }; ++}; ++ ++&i2c1 { ++ status = "okay"; ++ i2c-scl-rising-time-ns = <300>; ++ i2c-scl-falling-time-ns = <15>; ++ ++ es8316: es8316@11 { ++ #sound-dai-cells = <0>; ++ compatible = "everest,es8316"; ++ reg = <0x11>; ++ clocks = <&cru SCLK_I2S_8CH_OUT>; ++ clock-names = "mclk"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2s_8ch_mclk>; ++ }; ++}; ++ ++&i2s0 { ++ status = "okay"; ++ rockchip,i2s-broken-burst-len; ++ rockchip,playback-channels = <8>; ++ rockchip,capture-channels = <8>; ++ #sound-dai-cells = <0>; ++}; ++ ++&i2s2 { ++ #sound-dai-cells = <0>; ++ rockchip,bclk-fs = <128>; ++ status = "okay"; ++}; ++ ++&gmac { ++ phy-supply = <&vcc_phy>; ++ phy-mode = "rgmii"; ++ clock_in_out = "input"; ++ snps,reset-gpio = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>; ++ snps,reset-active-low; ++ snps,reset-delays-us = <0 10000 50000>; ++ assigned-clocks = <&cru SCLK_RMII_SRC>; ++ assigned-clock-parents = <&clkin_gmac>; ++ pinctrl-names = "default", "sleep"; ++ pinctrl-0 = <&rgmii_pins>; ++ pinctrl-1 = <&rgmii_sleep_pins>; ++ tx_delay = <0x28>; ++ rx_delay = <0x11>; ++ status = "okay"; ++}; ++ ++&gpu { ++ status = "okay"; ++ mali-supply = <&vdd_gpu>; ++}; ++ ++&hdmi { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ #sound-dai-cells = <0>; ++ status = "okay"; ++}; ++ ++&iep { ++ status = "okay"; ++}; ++ ++&iep_mmu { ++ status = "okay"; ++}; ++ ++&io_domains { ++ status = "okay"; ++ ++ bt656-supply = <&vcc_3v0>; /* bt656_gpio2ab_ms */ ++ audio-supply = <&vcc_3v0>; /* audio_gpio3d4a_ms */ ++ sdmmc-supply = <&vcc_sd>; /* sdmmc_gpio4b_ms */ ++ gpio1830-supply = <&vcc_3v0>; /* gpio1833_gpio4cd_ms */ ++}; ++ ++&saradc { ++ status = "okay"; ++}; ++ ++&sdmmc { ++ clock-frequency = <100000000>; ++ max-frequency = <100000000>; ++ supports-sd; ++ bus-width = <4>; ++ cap-mmc-highspeed; ++ cap-sd-highspeed; ++ disable-wp; ++ num-slots = <1>; ++ sd-uhs-sdr12; ++ sd-uhs-sdr25; ++ sd-uhs-sdr50; ++ sd-uhs-sdr104; ++ vqmmc-supply = <&vcc_sd>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd &sdmmc_bus4>; ++ card-detect-delay = <800>; ++ status = "okay"; ++}; ++ ++&sdio0 { ++ clock-frequency = <100000000>; ++ max-frequency = <100000000>; ++ supports-sdio; ++ bus-width = <4>; ++ disable-wp; ++ cap-sd-highspeed; ++ cap-sdio-irq; ++ keep-power-in-suspend; ++ mmc-pwrseq = <&sdio_pwrseq>; ++ non-removable; ++ num-slots = <1>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdio0_bus4 &sdio0_cmd &sdio0_clk>; ++ sd-uhs-sdr104; ++ status = "okay"; ++}; ++ ++&sdhci { ++ bus-width = <8>; ++ mmc-hs400-1_8v; ++ mmc-hs400-enhanced-strobe; ++ supports-emmc; ++ non-removable; ++ status = "okay"; ++}; ++ ++&threshold { ++ temperature = <85000>; ++}; ++ ++&target { ++ temperature = <100000>; ++}; ++ ++&soc_crit { ++ temperature = <105000>; ++}; ++ ++&tcphy0 { ++ status = "okay"; ++}; ++ ++&tcphy1 { ++ status = "okay"; ++}; ++ ++&tsadc { ++ /* tshut mode 0:CRU 1:GPIO */ ++ rockchip,hw-tshut-mode = <1>; ++ /* tshut polarity 0:LOW 1:HIGH */ ++ rockchip,hw-tshut-polarity = <1>; ++ rockchip,hw-tshut-temp = <110000>; ++ status = "okay"; ++}; ++ ++&u2phy0 { ++ status = "okay"; ++ enable-active-high; ++ /* otg-vbus-gpios = <&gpio1 3 GPIO_ACTIVE_HIGH>;*/ ++ gpio = <&gpio1 3 GPIO_ACTIVE_HIGH>; ++ ++ u2phy0_otg: otg-port { ++ status = "okay"; ++ }; ++ ++ u2phy0_host: host-port { ++ phy-supply = <&vcc5v0_host>; ++ status = "okay"; ++ }; ++}; ++ ++&u2phy1 { ++ status = "okay"; ++ ++ u2phy1_otg: otg-port { ++ status = "okay"; ++ }; ++ ++ u2phy1_host: host-port { ++ phy-supply = <&vcc5v0_host>; ++ status = "okay"; ++ }; ++}; ++ ++&uart0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart0_xfer &uart0_cts>; ++ status = "okay"; ++}; ++ ++&uart2 { ++ status = "okay"; ++}; ++ ++&uart4 { ++ status = "okay"; ++}; ++ ++&usb_host0_ehci { ++ status = "okay"; ++}; ++ ++&usb_host0_ohci { ++ status = "okay"; ++}; ++ ++&usb_host1_ehci { ++ status = "okay"; ++}; ++ ++&usb_host1_ohci { ++ status = "okay"; ++}; ++ ++&usbdrd3_0 { ++ extcon = <&u2phy0>; ++ status = "okay"; ++}; ++ ++&usbdrd_dwc3_0 { ++ dr_mode = "otg"; ++ status = "okay"; ++}; ++ ++&usbdrd3_1 { ++ status = "okay"; ++}; ++ ++&usbdrd_dwc3_1 { ++ dr_mode = "host"; ++ status = "okay"; ++}; ++ ++&pwm2 { ++ status = "okay"; ++}; ++ ++&pinctrl { ++ gmac { ++ rgmii_sleep_pins: rgmii-sleep-pins { ++ rockchip,pins = ++ <3 RK_PB7 RK_FUNC_GPIO &pcfg_output_low>; ++ }; ++ }; ++ ++ i2c4 { ++ i2c4_xfer: i2c4-xfer { ++ rockchip,pins = ++ <1 12 RK_FUNC_1 &pcfg_pull_up>, ++ <1 11 RK_FUNC_1 &pcfg_pull_up>; ++ }; ++ }; ++ ++ i2s0 { ++ i2s0_8ch_bus: i2s0-8ch-bus { ++ rockchip,pins = ++ <3 28 0 &pcfg_pull_none>, ++ <3 29 0 &pcfg_pull_none>; ++ }; ++ }; ++ ++ pcie { ++ pcie_drv: pcie-drv { ++ rockchip,pins = ++ <2 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ pmic { ++ pmic_int_l: pmic-int-l { ++ rockchip,pins = ++ <1 RK_PC5 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ ++ vsel1_gpio: vsel1-gpio { ++ rockchip,pins = ++ <1 RK_PC1 RK_FUNC_GPIO &pcfg_pull_down>; ++ }; ++ ++ vsel2_gpio: vsel2-gpio { ++ rockchip,pins = ++ <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_down>; ++ }; ++ }; ++ ++ sdio-pwrseq { ++ wifi_enable_h: wifi-enable-h { ++ rockchip,pins = ++ <0 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ sdio0 { ++ sdio0_bus1: sdio0-bus1 { ++ rockchip,pins = ++ <2 RK_PC4 RK_FUNC_1 &pcfg_pull_up_20ma>; ++ }; ++ ++ sdio0_bus4: sdio0-bus4 { ++ rockchip,pins = ++ <2 RK_PC4 RK_FUNC_1 &pcfg_pull_up_20ma>, ++ <2 RK_PC5 RK_FUNC_1 &pcfg_pull_up_20ma>, ++ <2 RK_PC6 RK_FUNC_1 &pcfg_pull_up_20ma>, ++ <2 RK_PC7 RK_FUNC_1 &pcfg_pull_up_20ma>; ++ }; ++ ++ sdio0_cmd: sdio0-cmd { ++ rockchip,pins = ++ <2 RK_PD0 RK_FUNC_1 &pcfg_pull_up_20ma>; ++ }; ++ ++ sdio0_clk: sdio0-clk { ++ rockchip,pins = ++ <2 RK_PD1 RK_FUNC_1 &pcfg_pull_none_20ma>; ++ }; ++ }; ++ ++ sdmmc { ++ sdmmc_bus1: sdmmc-bus1 { ++ rockchip,pins = ++ <4 RK_PB0 RK_FUNC_1 &pcfg_pull_up_8ma>; ++ }; ++ ++ sdmmc_bus4: sdmmc-bus4 { ++ rockchip,pins = ++ <4 RK_PB0 RK_FUNC_1 &pcfg_pull_up_8ma>, ++ <4 RK_PB1 RK_FUNC_1 &pcfg_pull_up_8ma>, ++ <4 RK_PB2 RK_FUNC_1 &pcfg_pull_up_8ma>, ++ <4 RK_PB3 RK_FUNC_1 &pcfg_pull_up_8ma>; ++ }; ++ ++ sdmmc_clk: sdmmc-clk { ++ rockchip,pins = ++ <4 RK_PB4 RK_FUNC_1 &pcfg_pull_none_18ma>; ++ }; ++ ++ sdmmc_cmd: sdmmc-cmd { ++ rockchip,pins = ++ <4 RK_PB5 RK_FUNC_1 &pcfg_pull_up_8ma>; ++ }; ++ }; ++ ++ usb2 { ++ host_vbus_drv: host-vbus-drv { ++ rockchip,pins = ++ <4 RK_PD1 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ ++ otg_vbus_drv: otg-vbus-drv { ++ rockchip,pins = ++ <1 3 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ wireless-bluetooth { ++ uart0_gpios: uart0-gpios { ++ rockchip,pins = ++ <2 RK_PC3 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++}; ++ ++&pvtm { ++ status = "okay"; ++}; ++ ++&pmu_pvtm { ++ status = "okay"; ++}; ++ ++&pmu_io_domains { ++ status = "okay"; ++ pmu1830-supply = <&vcc_3v0>; ++}; ++ ++&pcie_phy { ++ status = "okay"; ++}; ++ ++&pcie0 { ++ ep-gpios = <&gpio4 27 GPIO_ACTIVE_HIGH>; ++ num-lanes = <4>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pcie_clkreqnb_cpm>; ++ status = "okay"; ++}; ++ ++&rkvdec { ++ status = "okay"; ++}; ++ ++&vdec_mmu { ++ status = "okay"; ++}; ++ ++&vpu { ++ status = "okay"; ++}; ++ ++&vpu_mmu { ++ status = "okay"; ++}; ++ ++&vopb { ++ status = "okay"; ++}; ++ ++&vopb_mmu { ++ status = "okay"; ++}; ++ ++&vopl { ++ status = "disabled"; ++}; ++ ++&vopl_mmu { ++ status = "disabled"; ++}; + +diff --git a/arch/arm64/boot/dts/rockchip/rk3399-linux.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-linux.dtsi +index a57b372..910fee7 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3399-linux.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3399-linux.dtsi +@@ -47,7 +47,7 @@ + compatible = "rockchip,linux", "rockchip,rk3399"; + + chosen { +- bootargs = "earlycon=uart8250,mmio32,0xff1a0000 swiotlb=1 console=ttyFIQ0 rw root=PARTUUID=614e0000-0000 rootfstype=ext4 rootwait coherent_pool=1m"; ++ bootargs = "earlycon=uart8250,mmio32,0xff1a0000 swiotlb=1 coherent_pool=1m"; + }; + + reserved-memory { +@@ -55,11 +55,6 @@ + #size-cells = <2>; + ranges; + +- drm_logo: drm-logo@00000000 { +- compatible = "rockchip,drm-logo"; +- reg = <0x0 0x0 0x0 0x0>; +- }; +- + ramoops_mem: region@110000 { + reg = <0x0 0x110000 0x0 0xf0000>; + reg-names = "ramoops_mem"; diff --git a/patch/kernel/rk322x-legacy/01-linux-0006-rtl8211f.patch b/patch/kernel/rk322x-legacy/01-linux-0006-rtl8211f.patch new file mode 100644 index 0000000000..6a5e7a4e7f --- /dev/null +++ b/patch/kernel/rk322x-legacy/01-linux-0006-rtl8211f.patch @@ -0,0 +1,870 @@ +From eec386c5e9f5067dc7fdd3c86adae7de835e090a Mon Sep 17 00:00:00 2001 +From: Martin Blumenstingl +Date: Fri, 25 Nov 2016 14:12:01 +0100 +Subject: [PATCH] UPSTREAM: net: phy: realtek: fix enabling of the TX-delay for + RTL8211F + +The old logic always enabled the TX-delay when the phy-mode was set to +PHY_INTERFACE_MODE_RGMII. There are dedicated phy-modes which tell the +PHY driver to enable the RX and/or TX delays: +- PHY_INTERFACE_MODE_RGMII should disable the RX and TX delay in the + PHY (if required, the MAC should add the delays in this case) +- PHY_INTERFACE_MODE_RGMII_ID should enable RX and TX delay in the PHY +- PHY_INTERFACE_MODE_RGMII_TXID should enable the TX delay in the PHY +- PHY_INTERFACE_MODE_RGMII_RXID should enable the RX delay in the PHY + (currently not supported by RTL8211F) + +With this patch we enable the TX delay for PHY_INTERFACE_MODE_RGMII_ID +and PHY_INTERFACE_MODE_RGMII_TXID. +Additionally we now explicity disable the TX-delay, which seems to be +enabled automatically after a hard-reset of the PHY (by triggering it's +reset pin) to get a consistent state (as defined by the phy-mode). + +This fixes a compatibility problem with some SoCs where the TX-delay was +also added by the MAC. With the TX-delay being applied twice the TX +clock was off and TX traffic was broken or very slow (<10Mbit/s) on +1000Mbit/s links. + +Signed-off-by: Martin Blumenstingl +Reviewed-by: Florian Fainelli +Signed-off-by: David S. Miller +(cherry picked from commit e3230494b57ece68750e3e32d3e53d6b00917058) +--- + drivers/net/phy/realtek.c | 20 ++++++++++++-------- + 1 file changed, 12 insertions(+), 8 deletions(-) + +diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c +index 43ab691362d4..686f3b259dc0 100644 +--- a/drivers/net/phy/realtek.c ++++ b/drivers/net/phy/realtek.c +@@ -102,15 +102,19 @@ static int rtl8211f_config_init(struct phy_device *phydev) + if (ret < 0) + return ret; + +- if (phydev->interface == PHY_INTERFACE_MODE_RGMII) { +- /* enable TXDLY */ +- phy_write(phydev, RTL8211F_PAGE_SELECT, 0xd08); +- reg = phy_read(phydev, 0x11); ++ phy_write(phydev, RTL8211F_PAGE_SELECT, 0xd08); ++ reg = phy_read(phydev, 0x11); ++ ++ /* enable TX-delay for rgmii-id and rgmii-txid, otherwise disable it */ ++ if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID || ++ phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) + reg |= RTL8211F_TX_DELAY; +- phy_write(phydev, 0x11, reg); +- /* restore to default page 0 */ +- phy_write(phydev, RTL8211F_PAGE_SELECT, 0x0); +- } ++ else ++ reg &= ~RTL8211F_TX_DELAY; ++ ++ phy_write(phydev, 0x11, reg); ++ /* restore to default page 0 */ ++ phy_write(phydev, RTL8211F_PAGE_SELECT, 0x0); + + return 0; + } + +From e0a1654d1e79bea21f6397b6caa038c2dee25f97 Mon Sep 17 00:00:00 2001 +From: Kunihiko Hayashi +Date: Tue, 12 Sep 2017 18:54:35 +0900 +Subject: [PATCH] UPSTREAM: net: phy: realtek: rename RTL8211F_PAGE_SELECT to + RTL821x_PAGE_SELECT + +This renames the definition of page select register from +RTL8211F_PAGE_SELECT to RTL821x_PAGE_SELECT to use it across models. + +Signed-off-by: Kunihiko Hayashi +Reviewed-by: Andrew Lunn +Signed-off-by: David S. Miller +(cherry picked from commit 013955a6556766a76f9f2cc31e740fc6db6ecff4) +--- + drivers/net/phy/realtek.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c +index 686f3b259dc0..d58cc8f518ac 100644 +--- a/drivers/net/phy/realtek.c ++++ b/drivers/net/phy/realtek.c +@@ -22,11 +22,11 @@ + #define RTL821x_INER 0x12 + #define RTL821x_INER_INIT 0x6400 + #define RTL821x_INSR 0x13 ++#define RTL821x_PAGE_SELECT 0x1f + #define RTL8211E_INER_LINK_STATUS 0x400 + + #define RTL8211F_INER_LINK_STATUS 0x0010 + #define RTL8211F_INSR 0x1d +-#define RTL8211F_PAGE_SELECT 0x1f + #define RTL8211F_TX_DELAY 0x100 + + MODULE_DESCRIPTION("Realtek PHY driver"); +@@ -46,10 +46,10 @@ static int rtl8211f_ack_interrupt(struct phy_device *phydev) + { + int err; + +- phy_write(phydev, RTL8211F_PAGE_SELECT, 0xa43); ++ phy_write(phydev, RTL821x_PAGE_SELECT, 0xa43); + err = phy_read(phydev, RTL8211F_INSR); + /* restore to default page 0 */ +- phy_write(phydev, RTL8211F_PAGE_SELECT, 0x0); ++ phy_write(phydev, RTL821x_PAGE_SELECT, 0x0); + + return (err < 0) ? err : 0; + } +@@ -102,7 +102,7 @@ static int rtl8211f_config_init(struct phy_device *phydev) + if (ret < 0) + return ret; + +- phy_write(phydev, RTL8211F_PAGE_SELECT, 0xd08); ++ phy_write(phydev, RTL821x_PAGE_SELECT, 0xd08); + reg = phy_read(phydev, 0x11); + + /* enable TX-delay for rgmii-id and rgmii-txid, otherwise disable it */ +@@ -114,7 +114,7 @@ static int rtl8211f_config_init(struct phy_device *phydev) + + phy_write(phydev, 0x11, reg); + /* restore to default page 0 */ +- phy_write(phydev, RTL8211F_PAGE_SELECT, 0x0); ++ phy_write(phydev, RTL821x_PAGE_SELECT, 0x0); + + return 0; + } + +From 4ec70bc0ea714cc0129a4631dbda493ba706f40f Mon Sep 17 00:00:00 2001 +From: Jassi Brar +Date: Tue, 12 Sep 2017 18:54:36 +0900 +Subject: [PATCH] UPSTREAM: net: phy: realtek: add RTL8201F phy-id and + functions + +Add RTL8201F phy-id and the related functions to the driver. + +The original patch is as follows: +https://patchwork.kernel.org/patch/2538341/ + +Signed-off-by: Jongsung Kim +Signed-off-by: Jassi Brar +Signed-off-by: Kunihiko Hayashi +Reviewed-by: Andrew Lunn +Reviewed-by: Florian Fainelli +Signed-off-by: David S. Miller +(cherry picked from commit 513588dd44b09bb5fdd5066a4fbc1e7443b86d1c) +--- + drivers/net/phy/realtek.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 44 insertions(+) + +diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c +index d58cc8f518ac..422cf1f6a60c 100644 +--- a/drivers/net/phy/realtek.c ++++ b/drivers/net/phy/realtek.c +@@ -29,10 +29,22 @@ + #define RTL8211F_INSR 0x1d + #define RTL8211F_TX_DELAY 0x100 + ++#define RTL8201F_ISR 0x1e ++#define RTL8201F_IER 0x13 ++ + MODULE_DESCRIPTION("Realtek PHY driver"); + MODULE_AUTHOR("Johnson Leung"); + MODULE_LICENSE("GPL"); + ++static int rtl8201_ack_interrupt(struct phy_device *phydev) ++{ ++ int err; ++ ++ err = phy_read(phydev, RTL8201F_ISR); ++ ++ return (err < 0) ? err : 0; ++} ++ + static int rtl821x_ack_interrupt(struct phy_device *phydev) + { + int err; +@@ -54,6 +66,25 @@ static int rtl8211f_ack_interrupt(struct phy_device *phydev) + return (err < 0) ? err : 0; + } + ++static int rtl8201_config_intr(struct phy_device *phydev) ++{ ++ int err; ++ ++ /* switch to page 7 */ ++ phy_write(phydev, RTL821x_PAGE_SELECT, 0x7); ++ ++ if (phydev->interrupts == PHY_INTERRUPT_ENABLED) ++ err = phy_write(phydev, RTL8201F_IER, ++ BIT(13) | BIT(12) | BIT(11)); ++ else ++ err = phy_write(phydev, RTL8201F_IER, 0); ++ ++ /* restore to default page 0 */ ++ phy_write(phydev, RTL821x_PAGE_SELECT, 0x0); ++ ++ return err; ++} ++ + static int rtl8211b_config_intr(struct phy_device *phydev) + { + int err; +@@ -129,6 +160,18 @@ static struct phy_driver realtek_drvs[] = { + .config_aneg = &genphy_config_aneg, + .read_status = &genphy_read_status, + .driver = { .owner = THIS_MODULE,}, ++ }, { ++ .phy_id = 0x001cc816, ++ .name = "RTL8201F 10/100Mbps Ethernet", ++ .phy_id_mask = 0x001fffff, ++ .features = PHY_BASIC_FEATURES, ++ .flags = PHY_HAS_INTERRUPT, ++ .config_aneg = &genphy_config_aneg, ++ .read_status = &genphy_read_status, ++ .ack_interrupt = &rtl8201_ack_interrupt, ++ .config_intr = &rtl8201_config_intr, ++ .suspend = genphy_suspend, ++ .resume = genphy_resume, + }, { + .phy_id = 0x001cc912, + .name = "RTL8211B Gigabit Ethernet", +@@ -186,6 +229,7 @@ static struct phy_driver realtek_drvs[] = { + module_phy_driver(realtek_drvs); + + static struct mdio_device_id __maybe_unused realtek_tbl[] = { ++ { 0x001cc816, 0x001fffff }, + { 0x001cc912, 0x001fffff }, + { 0x001cc914, 0x001fffff }, + { 0x001cc915, 0x001fffff }, + +From cd0c207d7747ac36c446099ff018682373999764 Mon Sep 17 00:00:00 2001 +From: Heiner Kallweit +Date: Sun, 12 Nov 2017 16:16:04 +0100 +Subject: [PATCH] UPSTREAM: net: phy: realtek: fix RTL8211F interrupt mode + +After commit b94d22d94ad22 "ARM64: dts: meson-gx: add external PHY +interrupt on some platforms" ethernet stopped working on my Odroid-C2 +which has a RTL8211F phy. + +It turned out that no interrupts were triggered. Further analysis +showed the register INER can't be altered on page 0. +Because register INSR needs to be accessed via page 0xa43 I assumed +that register INER needs to be accessed via some page too. +Some brute force check resulted in page 0xa42 being the right one. + +With this patch the phy is working properly in interrupt mode. + +Fixes: 3447cf2e9a11 ("net/phy: Add support for Realtek RTL8211F") +Signed-off-by: Heiner Kallweit +Tested-by: Jerome Brunet +Signed-off-by: David S. Miller +(cherry picked from commit 3697d058b08d5b874f0253de173ef72e5d648f9a) +--- + drivers/net/phy/realtek.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c +index 422cf1f6a60c..a30d0c08c63b 100644 +--- a/drivers/net/phy/realtek.c ++++ b/drivers/net/phy/realtek.c +@@ -115,11 +115,13 @@ static int rtl8211f_config_intr(struct phy_device *phydev) + { + int err; + ++ phy_write(phydev, RTL821x_PAGE_SELECT, 0xa42); + if (phydev->interrupts == PHY_INTERRUPT_ENABLED) + err = phy_write(phydev, RTL821x_INER, + RTL8211F_INER_LINK_STATUS); + else + err = phy_write(phydev, RTL821x_INER, 0); ++ phy_write(phydev, RTL821x_PAGE_SELECT, 0); + + return err; + } + +From df04368281177832f4dff078f0cc735ce651ded1 Mon Sep 17 00:00:00 2001 +From: Martin Blumenstingl +Date: Sat, 2 Dec 2017 22:51:24 +0100 +Subject: [PATCH] UPSTREAM: net: phy: realtek: use the BIT and GENMASK macros + +This makes it easier to compare the #defines with the datasheets. +No functional changes. + +Signed-off-by: Martin Blumenstingl +Reviewed-by: Andrew Lunn +Signed-off-by: David S. Miller +(cherry picked from commit 8cc5baefbc0266b6d6c8e99cb8568f59be36a575) +--- + drivers/net/phy/realtek.c | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c +index a30d0c08c63b..f8dc29a75828 100644 +--- a/drivers/net/phy/realtek.c ++++ b/drivers/net/phy/realtek.c +@@ -13,21 +13,22 @@ + * option) any later version. + * + */ ++#include + #include + #include + + #define RTL821x_PHYSR 0x11 +-#define RTL821x_PHYSR_DUPLEX 0x2000 +-#define RTL821x_PHYSR_SPEED 0xc000 ++#define RTL821x_PHYSR_DUPLEX BIT(13) ++#define RTL821x_PHYSR_SPEED GENMASK(15, 14) + #define RTL821x_INER 0x12 + #define RTL821x_INER_INIT 0x6400 + #define RTL821x_INSR 0x13 + #define RTL821x_PAGE_SELECT 0x1f +-#define RTL8211E_INER_LINK_STATUS 0x400 ++#define RTL8211E_INER_LINK_STATUS BIT(10) + +-#define RTL8211F_INER_LINK_STATUS 0x0010 ++#define RTL8211F_INER_LINK_STATUS BIT(4) + #define RTL8211F_INSR 0x1d +-#define RTL8211F_TX_DELAY 0x100 ++#define RTL8211F_TX_DELAY BIT(8) + + #define RTL8201F_ISR 0x1e + #define RTL8201F_IER 0x13 + +From c6479ba05b0013658491a86171df7e0110a0e85a Mon Sep 17 00:00:00 2001 +From: Martin Blumenstingl +Date: Sat, 2 Dec 2017 22:51:25 +0100 +Subject: [PATCH] UPSTREAM: net: phy: realtek: rename RTL821x_INER_INIT to + RTL8211B_INER_INIT + +This macro is only used by the RTL8211B code. RTL8211E and RTL8211F both +use other bits to initialize the RTL821x_INER register. +No functional changes. + +Signed-off-by: Martin Blumenstingl +Reviewed-by: Andrew Lunn +Signed-off-by: David S. Miller +(cherry picked from commit 69021e32ec3ef02170482f6ed8130febaed27357) +--- + drivers/net/phy/realtek.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c +index f8dc29a75828..89308eac4088 100644 +--- a/drivers/net/phy/realtek.c ++++ b/drivers/net/phy/realtek.c +@@ -21,7 +21,7 @@ + #define RTL821x_PHYSR_DUPLEX BIT(13) + #define RTL821x_PHYSR_SPEED GENMASK(15, 14) + #define RTL821x_INER 0x12 +-#define RTL821x_INER_INIT 0x6400 ++#define RTL8211B_INER_INIT 0x6400 + #define RTL821x_INSR 0x13 + #define RTL821x_PAGE_SELECT 0x1f + #define RTL8211E_INER_LINK_STATUS BIT(10) +@@ -92,7 +92,7 @@ static int rtl8211b_config_intr(struct phy_device *phydev) + + if (phydev->interrupts == PHY_INTERRUPT_ENABLED) + err = phy_write(phydev, RTL821x_INER, +- RTL821x_INER_INIT); ++ RTL8211B_INER_INIT); + else + err = phy_write(phydev, RTL821x_INER, 0); + + +From c49b1806174ac4140a3fe90c626ef694992f7db6 Mon Sep 17 00:00:00 2001 +From: Martin Blumenstingl +Date: Sat, 2 Dec 2017 22:51:26 +0100 +Subject: [PATCH] UPSTREAM: net: phy: realtek: group all register bit #defines + for RTL821x_INER + +This simply moves all register bit #defines which describe the (PHY +specific) bits in the RTL821x_INER right below the RTL821x_INER register +definition. This makes it easier to spot which registers and bits belong +together. +No functional changes. + +Signed-off-by: Martin Blumenstingl +Reviewed-by: Andrew Lunn +Signed-off-by: David S. Miller +(cherry picked from commit a82f266d240d87e6111878bbfe287024fb6857c1) +--- + drivers/net/phy/realtek.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c +index 89308eac4088..df97d903d2bf 100644 +--- a/drivers/net/phy/realtek.c ++++ b/drivers/net/phy/realtek.c +@@ -20,13 +20,16 @@ + #define RTL821x_PHYSR 0x11 + #define RTL821x_PHYSR_DUPLEX BIT(13) + #define RTL821x_PHYSR_SPEED GENMASK(15, 14) ++ + #define RTL821x_INER 0x12 + #define RTL8211B_INER_INIT 0x6400 ++#define RTL8211E_INER_LINK_STATUS BIT(10) ++#define RTL8211F_INER_LINK_STATUS BIT(4) ++ + #define RTL821x_INSR 0x13 ++ + #define RTL821x_PAGE_SELECT 0x1f +-#define RTL8211E_INER_LINK_STATUS BIT(10) + +-#define RTL8211F_INER_LINK_STATUS BIT(4) + #define RTL8211F_INSR 0x1d + #define RTL8211F_TX_DELAY BIT(8) + + +From 3cd6e2f5de15c4c071d9ca9f02efcbd23b8435ad Mon Sep 17 00:00:00 2001 +From: Martin Blumenstingl +Date: Sat, 2 Dec 2017 22:51:27 +0100 +Subject: [PATCH] UPSTREAM: net: phy: realtek: use the same indentation for all + #defines + +This simply makes the code easier to read. No functional changes. + +Signed-off-by: Martin Blumenstingl +Reviewed-by: Andrew Lunn +Signed-off-by: David S. Miller +(cherry picked from commit f609ab0ed8e7bef2cd61d230bf9e83e1ec5b9ddb) +--- + drivers/net/phy/realtek.c | 27 ++++++++++++++------------- + 1 file changed, 14 insertions(+), 13 deletions(-) + +diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c +index df97d903d2bf..701f34ad7d8d 100644 +--- a/drivers/net/phy/realtek.c ++++ b/drivers/net/phy/realtek.c +@@ -17,24 +17,25 @@ + #include + #include + +-#define RTL821x_PHYSR 0x11 +-#define RTL821x_PHYSR_DUPLEX BIT(13) +-#define RTL821x_PHYSR_SPEED GENMASK(15, 14) ++#define RTL821x_PHYSR 0x11 ++#define RTL821x_PHYSR_DUPLEX BIT(13) ++#define RTL821x_PHYSR_SPEED GENMASK(15, 14) + +-#define RTL821x_INER 0x12 +-#define RTL8211B_INER_INIT 0x6400 +-#define RTL8211E_INER_LINK_STATUS BIT(10) +-#define RTL8211F_INER_LINK_STATUS BIT(4) ++#define RTL821x_INER 0x12 ++#define RTL8211B_INER_INIT 0x6400 ++#define RTL8211E_INER_LINK_STATUS BIT(10) ++#define RTL8211F_INER_LINK_STATUS BIT(4) + +-#define RTL821x_INSR 0x13 ++#define RTL821x_INSR 0x13 + +-#define RTL821x_PAGE_SELECT 0x1f ++#define RTL821x_PAGE_SELECT 0x1f + +-#define RTL8211F_INSR 0x1d +-#define RTL8211F_TX_DELAY BIT(8) ++#define RTL8211F_INSR 0x1d + +-#define RTL8201F_ISR 0x1e +-#define RTL8201F_IER 0x13 ++#define RTL8211F_TX_DELAY BIT(8) ++ ++#define RTL8201F_ISR 0x1e ++#define RTL8201F_IER 0x13 + + MODULE_DESCRIPTION("Realtek PHY driver"); + MODULE_AUTHOR("Johnson Leung"); + +From 47e40b66fdafc0ce940090626759fe8418034a0e Mon Sep 17 00:00:00 2001 +From: Martin Blumenstingl +Date: Sat, 2 Dec 2017 22:51:28 +0100 +Subject: [PATCH] UPSTREAM: net: phy: realtek: add utility functions to + read/write page addresses + +Realtek PHYs implement the concept of so-called "extension pages". The +reason for this is probably because these PHYs expose more registers +than available in the standard address range. +After all read/write operations on such a page are done the driver +should switch back to page 0 where the standard MII registers (such as +MII_BMCR) are available. + +When referring to such a register the datasheets of RTL8211E and +RTL8211F always specify: +- the page / "ext. page" which has to be written to RTL821x_PAGE_SELECT +- an address (sometimes also called reg) + +These new utility functions make the existing code easier to read since +it removes some duplication (switching back to page 0 is done within the +new helpers for example). + +No functional changes are intended. + +Signed-off-by: Martin Blumenstingl +Reviewed-by: Andrew Lunn +Signed-off-by: David S. Miller +(cherry picked from commit 136819a6e8df374e6b9b424586ff11c9e241a1cb) +--- + drivers/net/phy/realtek.c | 83 ++++++++++++++++++++++++++++++----------------- + 1 file changed, 53 insertions(+), 30 deletions(-) + +diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c +index 701f34ad7d8d..b1d52e61d91c 100644 +--- a/drivers/net/phy/realtek.c ++++ b/drivers/net/phy/realtek.c +@@ -41,6 +41,39 @@ MODULE_DESCRIPTION("Realtek PHY driver"); + MODULE_AUTHOR("Johnson Leung"); + MODULE_LICENSE("GPL"); + ++static int rtl8211x_page_read(struct phy_device *phydev, u16 page, u16 address) ++{ ++ int ret; ++ ++ ret = phy_write(phydev, RTL821x_PAGE_SELECT, page); ++ if (ret) ++ return ret; ++ ++ ret = phy_read(phydev, address); ++ ++ /* restore to default page 0 */ ++ phy_write(phydev, RTL821x_PAGE_SELECT, 0x0); ++ ++ return ret; ++} ++ ++static int rtl8211x_page_write(struct phy_device *phydev, u16 page, ++ u16 address, u16 val) ++{ ++ int ret; ++ ++ ret = phy_write(phydev, RTL821x_PAGE_SELECT, page); ++ if (ret) ++ return ret; ++ ++ ret = phy_write(phydev, address, val); ++ ++ /* restore to default page 0 */ ++ phy_write(phydev, RTL821x_PAGE_SELECT, 0x0); ++ ++ return ret; ++} ++ + static int rtl8201_ack_interrupt(struct phy_device *phydev) + { + int err; +@@ -63,31 +96,21 @@ static int rtl8211f_ack_interrupt(struct phy_device *phydev) + { + int err; + +- phy_write(phydev, RTL821x_PAGE_SELECT, 0xa43); +- err = phy_read(phydev, RTL8211F_INSR); +- /* restore to default page 0 */ +- phy_write(phydev, RTL821x_PAGE_SELECT, 0x0); ++ err = rtl8211x_page_read(phydev, 0xa43, RTL8211F_INSR); + + return (err < 0) ? err : 0; + } + + static int rtl8201_config_intr(struct phy_device *phydev) + { +- int err; +- +- /* switch to page 7 */ +- phy_write(phydev, RTL821x_PAGE_SELECT, 0x7); ++ u16 val; + + if (phydev->interrupts == PHY_INTERRUPT_ENABLED) +- err = phy_write(phydev, RTL8201F_IER, +- BIT(13) | BIT(12) | BIT(11)); ++ val = BIT(13) | BIT(12) | BIT(11); + else +- err = phy_write(phydev, RTL8201F_IER, 0); ++ val = 0; + +- /* restore to default page 0 */ +- phy_write(phydev, RTL821x_PAGE_SELECT, 0x0); +- +- return err; ++ return rtl8211x_page_write(phydev, 0x7, RTL8201F_IER, val); + } + + static int rtl8211b_config_intr(struct phy_device *phydev) +@@ -118,41 +141,41 @@ static int rtl8211e_config_intr(struct phy_device *phydev) + + static int rtl8211f_config_intr(struct phy_device *phydev) + { +- int err; ++ u16 val; + +- phy_write(phydev, RTL821x_PAGE_SELECT, 0xa42); + if (phydev->interrupts == PHY_INTERRUPT_ENABLED) +- err = phy_write(phydev, RTL821x_INER, +- RTL8211F_INER_LINK_STATUS); ++ val = RTL8211F_INER_LINK_STATUS; + else +- err = phy_write(phydev, RTL821x_INER, 0); +- phy_write(phydev, RTL821x_PAGE_SELECT, 0); ++ val = 0; + +- return err; ++ return rtl8211x_page_write(phydev, 0xa42, RTL821x_INER, val); + } + + static int rtl8211f_config_init(struct phy_device *phydev) + { + int ret; +- u16 reg; ++ u16 val; + + ret = genphy_config_init(phydev); + if (ret < 0) + return ret; + +- phy_write(phydev, RTL821x_PAGE_SELECT, 0xd08); +- reg = phy_read(phydev, 0x11); ++ ret = rtl8211x_page_read(phydev, 0xd08, 0x11); ++ if (ret < 0) ++ return ret; ++ ++ val = ret & 0xffff; + + /* enable TX-delay for rgmii-id and rgmii-txid, otherwise disable it */ + if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID || + phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) +- reg |= RTL8211F_TX_DELAY; ++ val |= RTL8211F_TX_DELAY; + else +- reg &= ~RTL8211F_TX_DELAY; ++ val &= ~RTL8211F_TX_DELAY; + +- phy_write(phydev, 0x11, reg); +- /* restore to default page 0 */ +- phy_write(phydev, RTL821x_PAGE_SELECT, 0x0); ++ ret = rtl8211x_page_write(phydev, 0xd08, 0x11, val); ++ if (ret) ++ return ret; + + return 0; + } + +From b747e5d48f83fd4d3b824578f666ac136bc6de49 Mon Sep 17 00:00:00 2001 +From: Martin Blumenstingl +Date: Sat, 2 Dec 2017 23:06:48 +0100 +Subject: [PATCH] FROMLIST: net: phy: realtek: add support for configuring the + RX delay on RTL8211F + +On RTL8211F the RX delay can also be enabled/disabled. +The overall behavior of the RX delay is similar to the behavior of the +TX delay, which was already supported by the driver. + +The RX delay (similar to the TX delay) may be enabled using hardware pin +strapping. If the MAC already configures the RX delay (if required) then +the RX delay generated by the RTL8211F PHY has to be turned off. + +While here, update the comment regarding the TX delay why it has to be +enabled or disabled within the driver. +Also avoid code-duplication by extracting the code to mask/unmask bits +in a paged register into a new rtl8211x_page_mask_bits helper function. + +Signed-off-by: Martin Blumenstingl +--- + drivers/net/phy/realtek.c | 55 ++++++++++++++++++++++++++++++++++++++--------- + 1 file changed, 45 insertions(+), 10 deletions(-) + +diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c +index b1d52e61d91c..890ea9d18d27 100644 +--- a/drivers/net/phy/realtek.c ++++ b/drivers/net/phy/realtek.c +@@ -32,7 +32,10 @@ + + #define RTL8211F_INSR 0x1d + +-#define RTL8211F_TX_DELAY BIT(8) ++#define RTL8211F_RX_DELAY_REG 0x15 ++#define RTL8211F_RX_DELAY_EN BIT(3) ++#define RTL8211F_TX_DELAY_REG 0x11 ++#define RTL8211F_TX_DELAY_EN BIT(8) + + #define RTL8201F_ISR 0x1e + #define RTL8201F_IER 0x13 +@@ -74,6 +77,23 @@ static int rtl8211x_page_write(struct phy_device *phydev, u16 page, + return ret; + } + ++static int rtl8211x_page_mask_bits(struct phy_device *phydev, u16 page, ++ u16 address, u16 mask, u16 set) ++{ ++ int ret; ++ u16 val; ++ ++ ret = rtl8211x_page_read(phydev, page, address); ++ if (ret < 0) ++ return ret; ++ ++ val = ret & 0xffff; ++ val &= ~mask; ++ val |= (set & mask); ++ ++ return rtl8211x_page_write(phydev, page, address, val); ++} ++ + static int rtl8201_ack_interrupt(struct phy_device *phydev) + { + int err; +@@ -160,20 +180,35 @@ static int rtl8211f_config_init(struct phy_device *phydev) + if (ret < 0) + return ret; + +- ret = rtl8211x_page_read(phydev, 0xd08, 0x11); +- if (ret < 0) +- return ret; ++ /* ++ * enable TX-delay for rgmii-id and rgmii-txid, otherwise disable it. ++ * this is needed because it can be enabled by pin strapping and ++ * conflict with the TX-delay configured by the MAC. ++ */ ++ if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID || ++ phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) ++ val = RTL8211F_TX_DELAY_EN; ++ else ++ val = 0; + +- val = ret & 0xffff; ++ ret = rtl8211x_page_mask_bits(phydev, 0xd08, RTL8211F_TX_DELAY_REG, ++ RTL8211F_TX_DELAY_EN, val); ++ if (ret) ++ return ret; + +- /* enable TX-delay for rgmii-id and rgmii-txid, otherwise disable it */ ++ /* ++ * enable RX-delay for rgmii-id and rgmii-rxid, otherwise disable it. ++ * this is needed because it can be enabled by pin strapping and ++ * conflict with the RX-delay configured by the MAC. ++ */ + if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID || +- phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) +- val |= RTL8211F_TX_DELAY; ++ phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) ++ val = RTL8211F_RX_DELAY_EN; + else +- val &= ~RTL8211F_TX_DELAY; ++ val = 0; + +- ret = rtl8211x_page_write(phydev, 0xd08, 0x11, val); ++ ret = rtl8211x_page_mask_bits(phydev, 0xd08, RTL8211F_RX_DELAY_REG, ++ RTL8211F_RX_DELAY_EN, val); + if (ret) + return ret; + + +From 4264d7cd3670514648b2ef632097c80e210e5690 Mon Sep 17 00:00:00 2001 +From: Martin Blumenstingl +Date: Sat, 2 Dec 2017 23:06:49 +0100 +Subject: [PATCH] FROMLIST: net: phy: realtek: configure the INTB pin on + RTL8211F + +The interrupt pin on the RTL8211F PHY can be used in two different +modes: +INTB +- the default mode of the PHY +- interrupts can be configured through page 0xa42 register RTL821x_INER +- interrupts can be ACK'ed through RTL8211F_INSR +- it acts as a level-interrupt which is active low +- Wake-on-LAN "wakeup" status is available in RTL8211F_INSR bit 7 + +PMEB: +- special mode for Wake-on-LAN +- interrupts configured through page 0xa42 register RTL821x_INER are + disabled +- it supports a "pulse low" waveform for the interrupt + +For now we simply force the pin into INTB mode since the PHY driver does +not support Wake-on-LAN yet. + +Signed-off-by: Martin Blumenstingl +--- + drivers/net/phy/realtek.c | 27 +++++++++++++++++++++++++-- + 1 file changed, 25 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c +index 890ea9d18d27..f307d220b49a 100644 +--- a/drivers/net/phy/realtek.c ++++ b/drivers/net/phy/realtek.c +@@ -40,6 +40,9 @@ + #define RTL8201F_ISR 0x1e + #define RTL8201F_IER 0x13 + ++#define RTL8211F_INTBCR 0x16 ++#define RTL8211F_INTBCR_INTB_PMEB BIT(5) ++ + MODULE_DESCRIPTION("Realtek PHY driver"); + MODULE_AUTHOR("Johnson Leung"); + MODULE_LICENSE("GPL"); +@@ -161,12 +164,32 @@ static int rtl8211e_config_intr(struct phy_device *phydev) + + static int rtl8211f_config_intr(struct phy_device *phydev) + { ++ int err; + u16 val; + +- if (phydev->interrupts == PHY_INTERRUPT_ENABLED) ++ if (phydev->interrupts == PHY_INTERRUPT_ENABLED) { ++ /* ++ * The interrupt pin has two functions: ++ * 0: INTB: it acts as interrupt pin which can be configured ++ * through RTL821x_INER and the status can be read through ++ * RTL8211F_INSR ++ * 1: PMEB: a special "Power Management Event" mode for ++ * Wake-on-LAN operation (with support for a "pulse low" ++ * wave format). Interrupts configured through RTL821x_INER ++ * will not work in this mode ++ * ++ * select INTB mode in the "INTB pin control" register to ++ * ensure that the interrupt pin is in the correct mode. ++ */ ++ err = rtl8211x_page_mask_bits(phydev, 0xd40, RTL8211F_INTBCR, ++ RTL8211F_INTBCR_INTB_PMEB, 0); ++ if (err) ++ return err; ++ + val = RTL8211F_INER_LINK_STATUS; +- else ++ } else { + val = 0; ++ } + + return rtl8211x_page_write(phydev, 0xa42, RTL821x_INER, val); + } + +From 5f21ae02ffa16fafd12f635e7a5965842d7d492a Mon Sep 17 00:00:00 2001 +From: Martin Blumenstingl +Date: Sat, 2 Dec 2017 23:06:50 +0100 +Subject: [PATCH] FROMLIST: net: phy: realtek: add more interrupt bits for + RTL8211E and RTL8211F + +This documents a few more bits in the RTL821x_INER register for RTL8211E +and RTL8211F. These are added only to document them (as no public +datasheets are available for these PHYs), they are currently not used. + +Signed-off-by: Martin Blumenstingl +--- + drivers/net/phy/realtek.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c +index f307d220b49a..15d342eefd6d 100644 +--- a/drivers/net/phy/realtek.c ++++ b/drivers/net/phy/realtek.c +@@ -24,7 +24,14 @@ + #define RTL821x_INER 0x12 + #define RTL8211B_INER_INIT 0x6400 + #define RTL8211E_INER_LINK_STATUS BIT(10) ++#define RTL8211E_INER_ANEG_COMPLETED BIT(11) ++#define RTL8211E_INER_PAGE_RECEIVED BIT(12) ++#define RTL8211E_INER_ANEG_ERROR BIT(15) + #define RTL8211F_INER_LINK_STATUS BIT(4) ++#define RTL8211F_INER_PHY_REGISTER_ACCESSIBLE BIT(5) ++#define RTL8211F_INER_WOL_PME BIT(7) ++#define RTL8211F_INER_ALDPS_STATE_CHANGE BIT(9) ++#define RTL8211F_INER_JABBER BIT(10) + + #define RTL821x_INSR 0x13 + diff --git a/patch/kernel/rk322x-legacy/01-linux-0007-dtoverlay-configfs.patch b/patch/kernel/rk322x-legacy/01-linux-0007-dtoverlay-configfs.patch new file mode 100644 index 0000000000..eb0b391224 --- /dev/null +++ b/patch/kernel/rk322x-legacy/01-linux-0007-dtoverlay-configfs.patch @@ -0,0 +1,1120 @@ +From 062e69c83449e4f5f363bb3caf4ba411907636d5 Mon Sep 17 00:00:00 2001 +From: Pantelis Antoniou +Date: Thu, 22 Oct 2015 23:30:04 +0300 +Subject: [PATCH] UPSTREAM: configfs: implement binary attributes + +ConfigFS lacked binary attributes up until now. This patch +introduces support for binary attributes in a somewhat similar +manner of sysfs binary attributes albeit with changes that +fit the configfs usage model. + +Problems that configfs binary attributes fix are everything that +requires a binary blob as part of the configuration of a resource, +such as bitstream loading for FPGAs, DTBs for dynamically created +devices etc. + +Look at Documentation/filesystems/configfs/configfs.txt for internals +and howto use them. + +This patch is against linux-next as of today that contains +Christoph's configfs rework. + +Signed-off-by: Pantelis Antoniou +[hch: folded a fix from Geert Uytterhoeven ] +[hch: a few tiny updates based on review feedback] +Signed-off-by: Christoph Hellwig +(cherry picked from commit 03607ace807b414eab46323c794b6fb8fcc2d48c) +--- + Documentation/filesystems/configfs/configfs.txt | 57 +++++- + fs/configfs/configfs_internal.h | 14 +- + fs/configfs/dir.c | 18 +- + fs/configfs/file.c | 255 +++++++++++++++++++++++- + fs/configfs/inode.c | 2 +- + include/linux/configfs.h | 50 +++++ + 6 files changed, 374 insertions(+), 22 deletions(-) + +diff --git a/Documentation/filesystems/configfs/configfs.txt b/Documentation/filesystems/configfs/configfs.txt +index af68efdbbfad..e5fe521eea1d 100644 +--- a/Documentation/filesystems/configfs/configfs.txt ++++ b/Documentation/filesystems/configfs/configfs.txt +@@ -51,15 +51,27 @@ configfs tree is always there, whether mounted on /config or not. + An item is created via mkdir(2). The item's attributes will also + appear at this time. readdir(3) can determine what the attributes are, + read(2) can query their default values, and write(2) can store new +-values. Like sysfs, attributes should be ASCII text files, preferably +-with only one value per file. The same efficiency caveats from sysfs +-apply. Don't mix more than one attribute in one attribute file. +- +-Like sysfs, configfs expects write(2) to store the entire buffer at +-once. When writing to configfs attributes, userspace processes should +-first read the entire file, modify the portions they wish to change, and +-then write the entire buffer back. Attribute files have a maximum size +-of one page (PAGE_SIZE, 4096 on i386). ++values. Don't mix more than one attribute in one attribute file. ++ ++There are two types of configfs attributes: ++ ++* Normal attributes, which similar to sysfs attributes, are small ASCII text ++files, with a maximum size of one page (PAGE_SIZE, 4096 on i386). Preferably ++only one value per file should be used, and the same caveats from sysfs apply. ++Configfs expects write(2) to store the entire buffer at once. When writing to ++normal configfs attributes, userspace processes should first read the entire ++file, modify the portions they wish to change, and then write the entire ++buffer back. ++ ++* Binary attributes, which are somewhat similar to sysfs binary attributes, ++but with a few slight changes to semantics. The PAGE_SIZE limitation does not ++apply, but the whole binary item must fit in single kernel vmalloc'ed buffer. ++The write(2) calls from user space are buffered, and the attributes' ++write_bin_attribute method will be invoked on the final close, therefore it is ++imperative for user-space to check the return code of close(2) in order to ++verify that the operation finished successfully. ++To avoid a malicious user OOMing the kernel, there's a per-binary attribute ++maximum buffer value. + + When an item needs to be destroyed, remove it with rmdir(2). An + item cannot be destroyed if any other item has a link to it (via +@@ -171,6 +183,7 @@ among other things. For that, it needs a type. + struct configfs_item_operations *ct_item_ops; + struct configfs_group_operations *ct_group_ops; + struct configfs_attribute **ct_attrs; ++ struct configfs_bin_attribute **ct_bin_attrs; + }; + + The most basic function of a config_item_type is to define what +@@ -201,6 +214,32 @@ be called whenever userspace asks for a read(2) on the attribute. If an + attribute is writable and provides a ->store method, that method will be + be called whenever userspace asks for a write(2) on the attribute. + ++[struct configfs_bin_attribute] ++ ++ struct configfs_attribute { ++ struct configfs_attribute cb_attr; ++ void *cb_private; ++ size_t cb_max_size; ++ }; ++ ++The binary attribute is used when the one needs to use binary blob to ++appear as the contents of a file in the item's configfs directory. ++To do so add the binary attribute to the NULL-terminated array ++config_item_type->ct_bin_attrs, and the item appears in configfs, the ++attribute file will appear with the configfs_bin_attribute->cb_attr.ca_name ++filename. configfs_bin_attribute->cb_attr.ca_mode specifies the file ++permissions. ++The cb_private member is provided for use by the driver, while the ++cb_max_size member specifies the maximum amount of vmalloc buffer ++to be used. ++ ++If binary attribute is readable and the config_item provides a ++ct_item_ops->read_bin_attribute() method, that method will be called ++whenever userspace asks for a read(2) on the attribute. The converse ++will happen for write(2). The reads/writes are bufferred so only a ++single read/write will occur; the attributes' need not concern itself ++with it. ++ + [struct config_group] + + A config_item cannot live in a vacuum. The only way one can be created +diff --git a/fs/configfs/configfs_internal.h b/fs/configfs/configfs_internal.h +index b65d1ef532d5..ccc31fa6f1a7 100644 +--- a/fs/configfs/configfs_internal.h ++++ b/fs/configfs/configfs_internal.h +@@ -53,13 +53,14 @@ struct configfs_dirent { + #define CONFIGFS_ROOT 0x0001 + #define CONFIGFS_DIR 0x0002 + #define CONFIGFS_ITEM_ATTR 0x0004 ++#define CONFIGFS_ITEM_BIN_ATTR 0x0008 + #define CONFIGFS_ITEM_LINK 0x0020 + #define CONFIGFS_USET_DIR 0x0040 + #define CONFIGFS_USET_DEFAULT 0x0080 + #define CONFIGFS_USET_DROPPING 0x0100 + #define CONFIGFS_USET_IN_MKDIR 0x0200 + #define CONFIGFS_USET_CREATING 0x0400 +-#define CONFIGFS_NOT_PINNED (CONFIGFS_ITEM_ATTR) ++#define CONFIGFS_NOT_PINNED (CONFIGFS_ITEM_ATTR | CONFIGFS_ITEM_BIN_ATTR) + + extern struct mutex configfs_symlink_mutex; + extern spinlock_t configfs_dirent_lock; +@@ -72,6 +73,8 @@ extern struct inode * configfs_new_inode(umode_t mode, struct configfs_dirent *, + extern int configfs_create(struct dentry *, umode_t mode, void (*init)(struct inode *)); + + extern int configfs_create_file(struct config_item *, const struct configfs_attribute *); ++extern int configfs_create_bin_file(struct config_item *, ++ const struct configfs_bin_attribute *); + extern int configfs_make_dirent(struct configfs_dirent *, + struct dentry *, void *, umode_t, int); + extern int configfs_dirent_is_ready(struct configfs_dirent *); +@@ -88,7 +91,7 @@ extern void configfs_release_fs(void); + extern struct rw_semaphore configfs_rename_sem; + extern const struct file_operations configfs_dir_operations; + extern const struct file_operations configfs_file_operations; +-extern const struct file_operations bin_fops; ++extern const struct file_operations configfs_bin_file_operations; + extern const struct inode_operations configfs_dir_inode_operations; + extern const struct inode_operations configfs_root_inode_operations; + extern const struct inode_operations configfs_symlink_inode_operations; +@@ -119,6 +122,13 @@ static inline struct configfs_attribute * to_attr(struct dentry * dentry) + return ((struct configfs_attribute *) sd->s_element); + } + ++static inline struct configfs_bin_attribute *to_bin_attr(struct dentry *dentry) ++{ ++ struct configfs_attribute *attr = to_attr(dentry); ++ ++ return container_of(attr, struct configfs_bin_attribute, cb_attr); ++} ++ + static inline struct config_item *configfs_get_config_item(struct dentry *dentry) + { + struct config_item * item = NULL; +diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c +index a7a1b218f308..7ae97e83f121 100644 +--- a/fs/configfs/dir.c ++++ b/fs/configfs/dir.c +@@ -255,6 +255,12 @@ static void configfs_init_file(struct inode * inode) + inode->i_fop = &configfs_file_operations; + } + ++static void configfs_init_bin_file(struct inode *inode) ++{ ++ inode->i_size = 0; ++ inode->i_fop = &configfs_bin_file_operations; ++} ++ + static void init_symlink(struct inode * inode) + { + inode->i_op = &configfs_symlink_inode_operations; +@@ -423,7 +429,9 @@ static int configfs_attach_attr(struct configfs_dirent * sd, struct dentry * den + spin_unlock(&configfs_dirent_lock); + + error = configfs_create(dentry, (attr->ca_mode & S_IALLUGO) | S_IFREG, +- configfs_init_file); ++ (sd->s_type & CONFIGFS_ITEM_BIN_ATTR) ? ++ configfs_init_bin_file : ++ configfs_init_file); + if (error) { + configfs_put(sd); + return error; +@@ -583,6 +591,7 @@ static int populate_attrs(struct config_item *item) + { + struct config_item_type *t = item->ci_type; + struct configfs_attribute *attr; ++ struct configfs_bin_attribute *bin_attr; + int error = 0; + int i; + +@@ -594,6 +603,13 @@ static int populate_attrs(struct config_item *item) + break; + } + } ++ if (t->ct_bin_attrs) { ++ for (i = 0; (bin_attr = t->ct_bin_attrs[i]) != NULL; i++) { ++ error = configfs_create_bin_file(item, bin_attr); ++ if (error) ++ break; ++ } ++ } + + if (error) + detach_attrs(item); +diff --git a/fs/configfs/file.c b/fs/configfs/file.c +index d39099ea7df7..3687187c8ea5 100644 +--- a/fs/configfs/file.c ++++ b/fs/configfs/file.c +@@ -28,6 +28,7 @@ + #include + #include + #include ++#include + #include + + #include +@@ -48,6 +49,10 @@ struct configfs_buffer { + struct configfs_item_operations * ops; + struct mutex mutex; + int needs_read_fill; ++ bool read_in_progress; ++ bool write_in_progress; ++ char *bin_buffer; ++ int bin_buffer_size; + }; + + +@@ -123,6 +128,87 @@ out: + return retval; + } + ++/** ++ * configfs_read_bin_file - read a binary attribute. ++ * @file: file pointer. ++ * @buf: buffer to fill. ++ * @count: number of bytes to read. ++ * @ppos: starting offset in file. ++ * ++ * Userspace wants to read a binary attribute file. The attribute ++ * descriptor is in the file's ->d_fsdata. The target item is in the ++ * directory's ->d_fsdata. ++ * ++ * We check whether we need to refill the buffer. If so we will ++ * call the attributes' attr->read() twice. The first time we ++ * will pass a NULL as a buffer pointer, which the attributes' method ++ * will use to return the size of the buffer required. If no error ++ * occurs we will allocate the buffer using vmalloc and call ++ * attr->read() again passing that buffer as an argument. ++ * Then we just copy to user-space using simple_read_from_buffer. ++ */ ++ ++static ssize_t ++configfs_read_bin_file(struct file *file, char __user *buf, ++ size_t count, loff_t *ppos) ++{ ++ struct configfs_buffer *buffer = file->private_data; ++ struct dentry *dentry = file->f_path.dentry; ++ struct config_item *item = to_item(dentry->d_parent); ++ struct configfs_bin_attribute *bin_attr = to_bin_attr(dentry); ++ ssize_t retval = 0; ++ ssize_t len = min_t(size_t, count, PAGE_SIZE); ++ ++ mutex_lock(&buffer->mutex); ++ ++ /* we don't support switching read/write modes */ ++ if (buffer->write_in_progress) { ++ retval = -ETXTBSY; ++ goto out; ++ } ++ buffer->read_in_progress = 1; ++ ++ if (buffer->needs_read_fill) { ++ /* perform first read with buf == NULL to get extent */ ++ len = bin_attr->read(item, NULL, 0); ++ if (len <= 0) { ++ retval = len; ++ goto out; ++ } ++ ++ /* do not exceed the maximum value */ ++ if (bin_attr->cb_max_size && len > bin_attr->cb_max_size) { ++ retval = -EFBIG; ++ goto out; ++ } ++ ++ buffer->bin_buffer = vmalloc(len); ++ if (buffer->bin_buffer == NULL) { ++ retval = -ENOMEM; ++ goto out; ++ } ++ buffer->bin_buffer_size = len; ++ ++ /* perform second read to fill buffer */ ++ len = bin_attr->read(item, buffer->bin_buffer, len); ++ if (len < 0) { ++ retval = len; ++ vfree(buffer->bin_buffer); ++ buffer->bin_buffer_size = 0; ++ buffer->bin_buffer = NULL; ++ goto out; ++ } ++ ++ buffer->needs_read_fill = 0; ++ } ++ ++ retval = simple_read_from_buffer(buf, count, ppos, buffer->bin_buffer, ++ buffer->bin_buffer_size); ++out: ++ mutex_unlock(&buffer->mutex); ++ return retval; ++} ++ + + /** + * fill_write_buffer - copy buffer from userspace. +@@ -209,10 +295,80 @@ configfs_write_file(struct file *file, const char __user *buf, size_t count, lof + return len; + } + +-static int check_perm(struct inode * inode, struct file * file) ++/** ++ * configfs_write_bin_file - write a binary attribute. ++ * @file: file pointer ++ * @buf: data to write ++ * @count: number of bytes ++ * @ppos: starting offset ++ * ++ * Writing to a binary attribute file is similar to a normal read. ++ * We buffer the consecutive writes (binary attribute files do not ++ * support lseek) in a continuously growing buffer, but we don't ++ * commit until the close of the file. ++ */ ++ ++static ssize_t ++configfs_write_bin_file(struct file *file, const char __user *buf, ++ size_t count, loff_t *ppos) ++{ ++ struct configfs_buffer *buffer = file->private_data; ++ struct dentry *dentry = file->f_path.dentry; ++ struct configfs_bin_attribute *bin_attr = to_bin_attr(dentry); ++ void *tbuf = NULL; ++ ssize_t len; ++ ++ mutex_lock(&buffer->mutex); ++ ++ /* we don't support switching read/write modes */ ++ if (buffer->read_in_progress) { ++ len = -ETXTBSY; ++ goto out; ++ } ++ buffer->write_in_progress = 1; ++ ++ /* buffer grows? */ ++ if (*ppos + count > buffer->bin_buffer_size) { ++ ++ if (bin_attr->cb_max_size && ++ *ppos + count > bin_attr->cb_max_size) { ++ len = -EFBIG; ++ } ++ ++ tbuf = vmalloc(*ppos + count); ++ if (tbuf == NULL) { ++ len = -ENOMEM; ++ goto out; ++ } ++ ++ /* copy old contents */ ++ if (buffer->bin_buffer) { ++ memcpy(tbuf, buffer->bin_buffer, ++ buffer->bin_buffer_size); ++ vfree(buffer->bin_buffer); ++ } ++ ++ /* clear the new area */ ++ memset(tbuf + buffer->bin_buffer_size, 0, ++ *ppos + count - buffer->bin_buffer_size); ++ buffer->bin_buffer = tbuf; ++ buffer->bin_buffer_size = *ppos + count; ++ } ++ ++ len = simple_write_to_buffer(buffer->bin_buffer, ++ buffer->bin_buffer_size, ppos, buf, count); ++ if (len > 0) ++ *ppos += len; ++out: ++ mutex_unlock(&buffer->mutex); ++ return len; ++} ++ ++static int check_perm(struct inode * inode, struct file * file, int type) + { + struct config_item *item = configfs_get_config_item(file->f_path.dentry->d_parent); + struct configfs_attribute * attr = to_attr(file->f_path.dentry); ++ struct configfs_bin_attribute *bin_attr = NULL; + struct configfs_buffer * buffer; + struct configfs_item_operations * ops = NULL; + int error = 0; +@@ -220,6 +376,9 @@ static int check_perm(struct inode * inode, struct file * file) + if (!item || !attr) + goto Einval; + ++ if (type & CONFIGFS_ITEM_BIN_ATTR) ++ bin_attr = to_bin_attr(file->f_path.dentry); ++ + /* Grab the module reference for this attribute if we have one */ + if (!try_module_get(attr->ca_owner)) { + error = -ENODEV; +@@ -236,9 +395,14 @@ static int check_perm(struct inode * inode, struct file * file) + * and we must have a store method. + */ + if (file->f_mode & FMODE_WRITE) { +- if (!(inode->i_mode & S_IWUGO) || !attr->store) ++ if (!(inode->i_mode & S_IWUGO)) ++ goto Eaccess; ++ ++ if ((type & CONFIGFS_ITEM_ATTR) && !attr->store) + goto Eaccess; + ++ if ((type & CONFIGFS_ITEM_BIN_ATTR) && !bin_attr->write) ++ goto Eaccess; + } + + /* File needs read support. +@@ -246,7 +410,13 @@ static int check_perm(struct inode * inode, struct file * file) + * must be a show method for it. + */ + if (file->f_mode & FMODE_READ) { +- if (!(inode->i_mode & S_IRUGO) || !attr->show) ++ if (!(inode->i_mode & S_IRUGO)) ++ goto Eaccess; ++ ++ if ((type & CONFIGFS_ITEM_ATTR) && !attr->show) ++ goto Eaccess; ++ ++ if ((type & CONFIGFS_ITEM_BIN_ATTR) && !bin_attr->read) + goto Eaccess; + } + +@@ -260,6 +430,8 @@ static int check_perm(struct inode * inode, struct file * file) + } + mutex_init(&buffer->mutex); + buffer->needs_read_fill = 1; ++ buffer->read_in_progress = 0; ++ buffer->write_in_progress = 0; + buffer->ops = ops; + file->private_data = buffer; + goto Done; +@@ -277,12 +449,7 @@ static int check_perm(struct inode * inode, struct file * file) + return error; + } + +-static int configfs_open_file(struct inode * inode, struct file * filp) +-{ +- return check_perm(inode,filp); +-} +- +-static int configfs_release(struct inode * inode, struct file * filp) ++static int configfs_release(struct inode *inode, struct file *filp) + { + struct config_item * item = to_item(filp->f_path.dentry->d_parent); + struct configfs_attribute * attr = to_attr(filp->f_path.dentry); +@@ -303,6 +470,47 @@ static int configfs_release(struct inode * inode, struct file * filp) + return 0; + } + ++static int configfs_open_file(struct inode *inode, struct file *filp) ++{ ++ return check_perm(inode, filp, CONFIGFS_ITEM_ATTR); ++} ++ ++static int configfs_open_bin_file(struct inode *inode, struct file *filp) ++{ ++ return check_perm(inode, filp, CONFIGFS_ITEM_BIN_ATTR); ++} ++ ++static int configfs_release_bin_file(struct inode *inode, struct file *filp) ++{ ++ struct configfs_buffer *buffer = filp->private_data; ++ struct dentry *dentry = filp->f_path.dentry; ++ struct config_item *item = to_item(dentry->d_parent); ++ struct configfs_bin_attribute *bin_attr = to_bin_attr(dentry); ++ ssize_t len = 0; ++ int ret; ++ ++ buffer->read_in_progress = 0; ++ ++ if (buffer->write_in_progress) { ++ buffer->write_in_progress = 0; ++ ++ len = bin_attr->write(item, buffer->bin_buffer, ++ buffer->bin_buffer_size); ++ ++ /* vfree on NULL is safe */ ++ vfree(buffer->bin_buffer); ++ buffer->bin_buffer = NULL; ++ buffer->bin_buffer_size = 0; ++ buffer->needs_read_fill = 1; ++ } ++ ++ ret = configfs_release(inode, filp); ++ if (len < 0) ++ return len; ++ return ret; ++} ++ ++ + const struct file_operations configfs_file_operations = { + .read = configfs_read_file, + .write = configfs_write_file, +@@ -311,6 +519,14 @@ const struct file_operations configfs_file_operations = { + .release = configfs_release, + }; + ++const struct file_operations configfs_bin_file_operations = { ++ .read = configfs_read_bin_file, ++ .write = configfs_write_bin_file, ++ .llseek = NULL, /* bin file is not seekable */ ++ .open = configfs_open_bin_file, ++ .release = configfs_release_bin_file, ++}; ++ + /** + * configfs_create_file - create an attribute file for an item. + * @item: item we're creating for. +@@ -332,3 +548,24 @@ int configfs_create_file(struct config_item * item, const struct configfs_attrib + return error; + } + ++/** ++ * configfs_create_bin_file - create a binary attribute file for an item. ++ * @item: item we're creating for. ++ * @attr: atrribute descriptor. ++ */ ++ ++int configfs_create_bin_file(struct config_item *item, ++ const struct configfs_bin_attribute *bin_attr) ++{ ++ struct dentry *dir = item->ci_dentry; ++ struct configfs_dirent *parent_sd = dir->d_fsdata; ++ umode_t mode = (bin_attr->cb_attr.ca_mode & S_IALLUGO) | S_IFREG; ++ int error = 0; ++ ++ mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_NORMAL); ++ error = configfs_make_dirent(parent_sd, NULL, (void *) bin_attr, mode, ++ CONFIGFS_ITEM_BIN_ATTR); ++ mutex_unlock(&dir->d_inode->i_mutex); ++ ++ return error; ++} +diff --git a/fs/configfs/inode.c b/fs/configfs/inode.c +index eae87575e681..0cc810e9dccc 100644 +--- a/fs/configfs/inode.c ++++ b/fs/configfs/inode.c +@@ -218,7 +218,7 @@ const unsigned char * configfs_get_name(struct configfs_dirent *sd) + if (sd->s_type & (CONFIGFS_DIR | CONFIGFS_ITEM_LINK)) + return sd->s_dentry->d_name.name; + +- if (sd->s_type & CONFIGFS_ITEM_ATTR) { ++ if (sd->s_type & (CONFIGFS_ITEM_ATTR | CONFIGFS_ITEM_BIN_ATTR)) { + attr = sd->s_element; + return attr->ca_name; + } +diff --git a/include/linux/configfs.h b/include/linux/configfs.h +index 758a029011b1..f7300d023dbe 100644 +--- a/include/linux/configfs.h ++++ b/include/linux/configfs.h +@@ -51,6 +51,7 @@ struct module; + struct configfs_item_operations; + struct configfs_group_operations; + struct configfs_attribute; ++struct configfs_bin_attribute; + struct configfs_subsystem; + + struct config_item { +@@ -84,6 +85,7 @@ struct config_item_type { + struct configfs_item_operations *ct_item_ops; + struct configfs_group_operations *ct_group_ops; + struct configfs_attribute **ct_attrs; ++ struct configfs_bin_attribute **ct_bin_attrs; + }; + + /** +@@ -154,6 +156,54 @@ static struct configfs_attribute _pfx##attr_##_name = { \ + .store = _pfx##_name##_store, \ + } + ++struct file; ++struct vm_area_struct; ++ ++struct configfs_bin_attribute { ++ struct configfs_attribute cb_attr; /* std. attribute */ ++ void *cb_private; /* for user */ ++ size_t cb_max_size; /* max core size */ ++ ssize_t (*read)(struct config_item *, void *, size_t); ++ ssize_t (*write)(struct config_item *, const void *, size_t); ++}; ++ ++#define CONFIGFS_BIN_ATTR(_pfx, _name, _priv, _maxsz) \ ++static struct configfs_bin_attribute _pfx##attr_##_name = { \ ++ .cb_attr = { \ ++ .ca_name = __stringify(_name), \ ++ .ca_mode = S_IRUGO | S_IWUSR, \ ++ .ca_owner = THIS_MODULE, \ ++ }, \ ++ .cb_private = _priv, \ ++ .cb_max_size = _maxsz, \ ++ .read = _pfx##_name##_read, \ ++ .write = _pfx##_name##_write, \ ++} ++ ++#define CONFIGFS_BIN_ATTR_RO(_pfx, _name, _priv, _maxsz) \ ++static struct configfs_attribute _pfx##attr_##_name = { \ ++ .cb_attr = { \ ++ .ca_name = __stringify(_name), \ ++ .ca_mode = S_IRUGO, \ ++ .ca_owner = THIS_MODULE, \ ++ }, \ ++ .cb_private = _priv, \ ++ .cb_max_size = _maxsz, \ ++ .read = _pfx##_name##_read, \ ++} ++ ++#define CONFIGFS_BIN_ATTR_WO(_pfx, _name, _priv, _maxsz) \ ++static struct configfs_attribute _pfx##attr_##_name = { \ ++ .cb_attr = { \ ++ .ca_name = __stringify(_name), \ ++ .ca_mode = S_IWUSR, \ ++ .ca_owner = THIS_MODULE, \ ++ }, \ ++ .cb_private = _priv, \ ++ .cb_max_size = _maxsz, \ ++ .write = _pfx##_name##_write, \ ++} ++ + /* + * If allow_link() exists, the item can symlink(2) out to other + * items. If the item is a group, it may support mkdir(2). + +From 2dc994339b24321895cff69fda659e47648871be Mon Sep 17 00:00:00 2001 +From: Octavian Purdila +Date: Wed, 23 Mar 2016 14:14:48 +0200 +Subject: [PATCH] UPSTREAM: configfs: fix CONFIGFS_BIN_ATTR_[RW]O definitions + +The type should be struct configfs_bin_attribute and not struct +configfs_attribute. + +Signed-off-by: Octavian Purdila +Signed-off-by: Christoph Hellwig +(cherry picked from commit 96c22a3293512ba684e73a981196430f524689da) +--- + include/linux/configfs.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/include/linux/configfs.h b/include/linux/configfs.h +index f7300d023dbe..658066d63180 100644 +--- a/include/linux/configfs.h ++++ b/include/linux/configfs.h +@@ -181,7 +181,7 @@ static struct configfs_bin_attribute _pfx##attr_##_name = { \ + } + + #define CONFIGFS_BIN_ATTR_RO(_pfx, _name, _priv, _maxsz) \ +-static struct configfs_attribute _pfx##attr_##_name = { \ ++static struct configfs_bin_attribute _pfx##attr_##_name = { \ + .cb_attr = { \ + .ca_name = __stringify(_name), \ + .ca_mode = S_IRUGO, \ +@@ -193,7 +193,7 @@ static struct configfs_attribute _pfx##attr_##_name = { \ + } + + #define CONFIGFS_BIN_ATTR_WO(_pfx, _name, _priv, _maxsz) \ +-static struct configfs_attribute _pfx##attr_##_name = { \ ++static struct configfs_bin_attribute _pfx##attr_##_name = { \ + .cb_attr = { \ + .ca_name = __stringify(_name), \ + .ca_mode = S_IWUSR, \ + +From a2a707f138cf997e098a6d3aceac4b0944f7d76e Mon Sep 17 00:00:00 2001 +From: Pantelis Antoniou +Date: Wed, 4 Dec 2013 19:32:00 +0200 +Subject: [PATCH] FROMLIST: OF: DT-Overlay configfs interface (v7) + +Add a runtime interface to using configfs for generic device tree overlay +usage. With it its possible to use device tree overlays without having +to use a per-platform overlay manager. + +Please see Documentation/devicetree/configfs-overlays.txt for more info. + +Changes since v6: +- Default groups properties API changed. + +Changes since v5: +- New style configfs. + +Changes since v4: +- Loading fix for multiple overlays as found out by + Geert Uytterhoeven + +Changes since v3: +- Fixed compilation on SPARC & Xtensa + +Changes since v2: +- Removed ifdef CONFIG_OF_OVERLAY (since for now it's required) +- Created a documentation entry +- Slight rewording in Kconfig + +Changes since v1: +- of_resolve() -> of_resolve_phandles(). + +Signed-off-by: Pantelis Antoniou +[geert: Use %zu to format size_t] +[geert: Let OF_CONFIGFS select OF_FLATTREE to fix sparc all*config] +Signed-off-by: Geert Uytterhoeven +--- + Documentation/devicetree/configfs-overlays.txt | 31 +++ + drivers/of/Kconfig | 8 + + drivers/of/Makefile | 1 + + drivers/of/configfs.c | 314 +++++++++++++++++++++++++ + 4 files changed, 354 insertions(+) + create mode 100644 Documentation/devicetree/configfs-overlays.txt + create mode 100644 drivers/of/configfs.c + +diff --git a/Documentation/devicetree/configfs-overlays.txt b/Documentation/devicetree/configfs-overlays.txt +new file mode 100644 +index 000000000000..5fa43e064307 +--- /dev/null ++++ b/Documentation/devicetree/configfs-overlays.txt +@@ -0,0 +1,31 @@ ++Howto use the configfs overlay interface. ++ ++A device-tree configfs entry is created in /config/device-tree/overlays ++and and it is manipulated using standard file system I/O. ++Note that this is a debug level interface, for use by developers and ++not necessarily something accessed by normal users due to the ++security implications of having direct access to the kernel's device tree. ++ ++* To create an overlay you mkdir the directory: ++ ++ # mkdir /config/device-tree/overlays/foo ++ ++* Either you echo the overlay firmware file to the path property file. ++ ++ # echo foo.dtbo >/config/device-tree/overlays/foo/path ++ ++* Or you cat the contents of the overlay to the dtbo file ++ ++ # cat foo.dtbo >/config/device-tree/overlays/foo/dtbo ++ ++The overlay file will be applied, and devices will be created/destroyed ++as required. ++ ++To remove it simply rmdir the directory. ++ ++ # rmdir /config/device-tree/overlays/foo ++ ++The rationalle of the dual interface (firmware & direct copy) is that each is ++better suited to different use patterns. The firmware interface is what's ++intended to be used by hardware managers in the kernel, while the copy interface ++make sense for developers (since it avoids problems with namespaces). +diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig +index e2a48415d969..c112c9f2ca6b 100644 +--- a/drivers/of/Kconfig ++++ b/drivers/of/Kconfig +@@ -112,4 +112,12 @@ config OF_OVERLAY + While this option is selected automatically when needed, you can + enable it manually to improve device tree unit test coverage. + ++config OF_CONFIGFS ++ bool "Device Tree Overlay ConfigFS interface" ++ select CONFIGFS_FS ++ select OF_FLATTREE ++ depends on OF_OVERLAY ++ help ++ Enable a simple user-space driven DT overlay interface. ++ + endif # OF +diff --git a/drivers/of/Makefile b/drivers/of/Makefile +index 478d4edcd763..732fa66b5263 100644 +--- a/drivers/of/Makefile ++++ b/drivers/of/Makefile +@@ -1,4 +1,5 @@ + obj-y = base.o device.o platform.o property.o ++obj-$(CONFIG_OF_CONFIGFS) += configfs.o + obj-$(CONFIG_OF_DYNAMIC) += dynamic.o + obj-$(CONFIG_OF_FLATTREE) += fdt.o + obj-$(CONFIG_OF_EARLY_FLATTREE) += fdt_address.o +diff --git a/drivers/of/configfs.c b/drivers/of/configfs.c +new file mode 100644 +index 000000000000..908ce4960c30 +--- /dev/null ++++ b/drivers/of/configfs.c +@@ -0,0 +1,314 @@ ++/* ++ * Configfs entries for device-tree ++ * ++ * Copyright (C) 2013 - Pantelis Antoniou ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version ++ * 2 of the License, or (at your option) any later version. ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "of_private.h" ++ ++struct cfs_overlay_item { ++ struct config_item item; ++ ++ char path[PATH_MAX]; ++ ++ const struct firmware *fw; ++ struct device_node *overlay; ++ int ov_id; ++ ++ void *dtbo; ++ int dtbo_size; ++}; ++ ++static int create_overlay(struct cfs_overlay_item *overlay, void *blob) ++{ ++ int err; ++ ++ /* unflatten the tree */ ++ of_fdt_unflatten_tree(blob, &overlay->overlay); ++ if (overlay->overlay == NULL) { ++ pr_err("%s: failed to unflatten tree\n", __func__); ++ err = -EINVAL; ++ goto out_err; ++ } ++ pr_debug("%s: unflattened OK\n", __func__); ++ ++ /* mark it as detached */ ++ of_node_set_flag(overlay->overlay, OF_DETACHED); ++ ++ /* perform resolution */ ++ err = of_resolve_phandles(overlay->overlay); ++ if (err != 0) { ++ pr_err("%s: Failed to resolve tree\n", __func__); ++ goto out_err; ++ } ++ pr_debug("%s: resolved OK\n", __func__); ++ ++ err = of_overlay_create(overlay->overlay); ++ if (err < 0) { ++ pr_err("%s: Failed to create overlay (err=%d)\n", ++ __func__, err); ++ goto out_err; ++ } ++ overlay->ov_id = err; ++ ++out_err: ++ return err; ++} ++ ++static inline struct cfs_overlay_item *to_cfs_overlay_item( ++ struct config_item *item) ++{ ++ return item ? container_of(item, struct cfs_overlay_item, item) : NULL; ++} ++ ++static ssize_t cfs_overlay_item_path_show(struct config_item *item, ++ char *page) ++{ ++ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); ++ return sprintf(page, "%s\n", overlay->path); ++} ++ ++static ssize_t cfs_overlay_item_path_store(struct config_item *item, ++ const char *page, size_t count) ++{ ++ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); ++ const char *p = page; ++ char *s; ++ int err; ++ ++ /* if it's set do not allow changes */ ++ if (overlay->path[0] != '\0' || overlay->dtbo_size > 0) ++ return -EPERM; ++ ++ /* copy to path buffer (and make sure it's always zero terminated */ ++ count = snprintf(overlay->path, sizeof(overlay->path) - 1, "%s", p); ++ overlay->path[sizeof(overlay->path) - 1] = '\0'; ++ ++ /* strip trailing newlines */ ++ s = overlay->path + strlen(overlay->path); ++ while (s > overlay->path && *--s == '\n') ++ *s = '\0'; ++ ++ pr_debug("%s: path is '%s'\n", __func__, overlay->path); ++ ++ err = request_firmware(&overlay->fw, overlay->path, NULL); ++ if (err != 0) ++ goto out_err; ++ ++ err = create_overlay(overlay, (void *)overlay->fw->data); ++ if (err < 0) ++ goto out_err; ++ ++ return count; ++ ++out_err: ++ ++ release_firmware(overlay->fw); ++ overlay->fw = NULL; ++ ++ overlay->path[0] = '\0'; ++ return err; ++} ++ ++static ssize_t cfs_overlay_item_status_show(struct config_item *item, ++ char *page) ++{ ++ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); ++ ++ return sprintf(page, "%s\n", ++ overlay->ov_id >= 0 ? "applied" : "unapplied"); ++} ++ ++CONFIGFS_ATTR(cfs_overlay_item_, path); ++CONFIGFS_ATTR_RO(cfs_overlay_item_, status); ++ ++static struct configfs_attribute *cfs_overlay_attrs[] = { ++ &cfs_overlay_item_attr_path, ++ &cfs_overlay_item_attr_status, ++ NULL, ++}; ++ ++ssize_t cfs_overlay_item_dtbo_read(struct config_item *item, ++ void *buf, size_t max_count) ++{ ++ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); ++ ++ pr_debug("%s: buf=%p max_count=%zu\n", __func__, ++ buf, max_count); ++ ++ if (overlay->dtbo == NULL) ++ return 0; ++ ++ /* copy if buffer provided */ ++ if (buf != NULL) { ++ /* the buffer must be large enough */ ++ if (overlay->dtbo_size > max_count) ++ return -ENOSPC; ++ ++ memcpy(buf, overlay->dtbo, overlay->dtbo_size); ++ } ++ ++ return overlay->dtbo_size; ++} ++ ++ssize_t cfs_overlay_item_dtbo_write(struct config_item *item, ++ const void *buf, size_t count) ++{ ++ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); ++ int err; ++ ++ /* if it's set do not allow changes */ ++ if (overlay->path[0] != '\0' || overlay->dtbo_size > 0) ++ return -EPERM; ++ ++ /* copy the contents */ ++ overlay->dtbo = kmemdup(buf, count, GFP_KERNEL); ++ if (overlay->dtbo == NULL) ++ return -ENOMEM; ++ ++ overlay->dtbo_size = count; ++ ++ err = create_overlay(overlay, overlay->dtbo); ++ if (err < 0) ++ goto out_err; ++ ++ return count; ++ ++out_err: ++ kfree(overlay->dtbo); ++ overlay->dtbo = NULL; ++ overlay->dtbo_size = 0; ++ ++ return err; ++} ++ ++CONFIGFS_BIN_ATTR(cfs_overlay_item_, dtbo, NULL, SZ_1M); ++ ++static struct configfs_bin_attribute *cfs_overlay_bin_attrs[] = { ++ &cfs_overlay_item_attr_dtbo, ++ NULL, ++}; ++ ++static void cfs_overlay_release(struct config_item *item) ++{ ++ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); ++ ++ if (overlay->ov_id >= 0) ++ of_overlay_destroy(overlay->ov_id); ++ if (overlay->fw) ++ release_firmware(overlay->fw); ++ /* kfree with NULL is safe */ ++ kfree(overlay->dtbo); ++ kfree(overlay); ++} ++ ++static struct configfs_item_operations cfs_overlay_item_ops = { ++ .release = cfs_overlay_release, ++}; ++ ++static struct config_item_type cfs_overlay_type = { ++ .ct_item_ops = &cfs_overlay_item_ops, ++ .ct_attrs = cfs_overlay_attrs, ++ .ct_bin_attrs = cfs_overlay_bin_attrs, ++ .ct_owner = THIS_MODULE, ++}; ++ ++static struct config_item *cfs_overlay_group_make_item( ++ struct config_group *group, const char *name) ++{ ++ struct cfs_overlay_item *overlay; ++ ++ overlay = kzalloc(sizeof(*overlay), GFP_KERNEL); ++ if (!overlay) ++ return ERR_PTR(-ENOMEM); ++ overlay->ov_id = -1; ++ ++ config_item_init_type_name(&overlay->item, name, &cfs_overlay_type); ++ return &overlay->item; ++} ++ ++static void cfs_overlay_group_drop_item(struct config_group *group, ++ struct config_item *item) ++{ ++ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); ++ ++ config_item_put(&overlay->item); ++} ++ ++static struct configfs_group_operations overlays_ops = { ++ .make_item = cfs_overlay_group_make_item, ++ .drop_item = cfs_overlay_group_drop_item, ++}; ++ ++static struct config_item_type overlays_type = { ++ .ct_group_ops = &overlays_ops, ++ .ct_owner = THIS_MODULE, ++}; ++ ++static struct configfs_group_operations of_cfs_ops = { ++ /* empty - we don't allow anything to be created */ ++}; ++ ++static struct config_item_type of_cfs_type = { ++ .ct_group_ops = &of_cfs_ops, ++ .ct_owner = THIS_MODULE, ++}; ++ ++struct config_group of_cfs_overlay_group; ++ ++struct config_group *of_cfs_def_groups[] = { ++ &of_cfs_overlay_group, ++ NULL ++}; ++ ++static struct configfs_subsystem of_cfs_subsys = { ++ .su_group = { ++ .cg_item = { ++ .ci_namebuf = "device-tree", ++ .ci_type = &of_cfs_type, ++ }, ++ .default_groups = of_cfs_def_groups, ++ }, ++ .su_mutex = __MUTEX_INITIALIZER(of_cfs_subsys.su_mutex), ++}; ++ ++static int __init of_cfs_init(void) ++{ ++ int ret; ++ ++ pr_info("%s\n", __func__); ++ ++ config_group_init(&of_cfs_subsys.su_group); ++ config_group_init_type_name(&of_cfs_overlay_group, "overlays", ++ &overlays_type); ++ ++ ret = configfs_register_subsystem(&of_cfs_subsys); ++ if (ret != 0) { ++ pr_err("%s: failed to register subsys\n", __func__); ++ goto out; ++ } ++ pr_info("%s: OK\n", __func__); ++out: ++ return ret; ++} ++late_initcall(of_cfs_init); diff --git a/patch/kernel/rk322x-legacy/01-linux-0008-mmc-pwrseq.patch b/patch/kernel/rk322x-legacy/01-linux-0008-mmc-pwrseq.patch new file mode 100644 index 0000000000..55f4be4ac0 --- /dev/null +++ b/patch/kernel/rk322x-legacy/01-linux-0008-mmc-pwrseq.patch @@ -0,0 +1,877 @@ +From 625c86fa85aa4d18f7711d0314f2ef78a71b79c0 Mon Sep 17 00:00:00 2001 +From: Julia Lawall +Date: Sat, 14 Nov 2015 18:05:20 +0100 +Subject: [PATCH] UPSTREAM: mmc: pwrseq: constify mmc_pwrseq_ops structures + +The mmc_pwrseq_ops structures are never modified, so declare them as const. + +Done with the help of Coccinelle. + +Signed-off-by: Julia Lawall +Signed-off-by: Ulf Hansson +(cherry picked from commit ffedbd2210f2f4cba490a9205adc11fd1b89a852) +--- + drivers/mmc/core/pwrseq.h | 2 +- + drivers/mmc/core/pwrseq_emmc.c | 2 +- + drivers/mmc/core/pwrseq_simple.c | 2 +- + 3 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/mmc/core/pwrseq.h b/drivers/mmc/core/pwrseq.h +index 096da48c6a7e..133de0426687 100644 +--- a/drivers/mmc/core/pwrseq.h ++++ b/drivers/mmc/core/pwrseq.h +@@ -16,7 +16,7 @@ struct mmc_pwrseq_ops { + }; + + struct mmc_pwrseq { +- struct mmc_pwrseq_ops *ops; ++ const struct mmc_pwrseq_ops *ops; + }; + + #ifdef CONFIG_OF +diff --git a/drivers/mmc/core/pwrseq_emmc.c b/drivers/mmc/core/pwrseq_emmc.c +index ad4f94ec7e8d..4a82bc77fe49 100644 +--- a/drivers/mmc/core/pwrseq_emmc.c ++++ b/drivers/mmc/core/pwrseq_emmc.c +@@ -51,7 +51,7 @@ static void mmc_pwrseq_emmc_free(struct mmc_host *host) + kfree(pwrseq); + } + +-static struct mmc_pwrseq_ops mmc_pwrseq_emmc_ops = { ++static const struct mmc_pwrseq_ops mmc_pwrseq_emmc_ops = { + .post_power_on = mmc_pwrseq_emmc_reset, + .free = mmc_pwrseq_emmc_free, + }; +diff --git a/drivers/mmc/core/pwrseq_simple.c b/drivers/mmc/core/pwrseq_simple.c +index d10538bb5e07..2b16263458af 100644 +--- a/drivers/mmc/core/pwrseq_simple.c ++++ b/drivers/mmc/core/pwrseq_simple.c +@@ -87,7 +87,7 @@ static void mmc_pwrseq_simple_free(struct mmc_host *host) + kfree(pwrseq); + } + +-static struct mmc_pwrseq_ops mmc_pwrseq_simple_ops = { ++static const struct mmc_pwrseq_ops mmc_pwrseq_simple_ops = { + .pre_power_on = mmc_pwrseq_simple_pre_power_on, + .post_power_on = mmc_pwrseq_simple_post_power_on, + .power_off = mmc_pwrseq_simple_power_off, + +From 58975b7a58defa92efd5533cc731fb9a0c1cb780 Mon Sep 17 00:00:00 2001 +From: Peter Chen +Date: Wed, 6 Jan 2016 11:34:10 +0800 +Subject: [PATCH] UPSTREAM: mmc: core: pwrseq_simple: remove unused header file + +Signed-off-by: Peter Chen +Signed-off-by: Ulf Hansson +(cherry picked from commit 62c03ca3ffa1ddf55a66411be02f7e4678771fce) +--- + drivers/mmc/core/pwrseq_simple.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/drivers/mmc/core/pwrseq_simple.c b/drivers/mmc/core/pwrseq_simple.c +index aba786daebca..bc173e18b71c 100644 +--- a/drivers/mmc/core/pwrseq_simple.c ++++ b/drivers/mmc/core/pwrseq_simple.c +@@ -12,7 +12,6 @@ + #include + #include + #include +-#include + #include + + #include + +From 01946788b015b9d3f7d18f5b4a43e09e6bf66623 Mon Sep 17 00:00:00 2001 +From: Srinivas Kandagatla +Date: Thu, 14 Apr 2016 14:02:14 +0100 +Subject: [PATCH] UPSTREAM: mmc: pwrseq_simple: add to_pwrseq_simple() macro + +This patch adds to_pwrseq_simple() macro to make the code more readable. + +Signed-off-by: Srinivas Kandagatla +Signed-off-by: Ulf Hansson +(cherry picked from commit 5b96fea730ab79bdf6f8071cadf8208296bf5e8d) +--- + drivers/mmc/core/pwrseq_simple.c | 14 ++++++-------- + 1 file changed, 6 insertions(+), 8 deletions(-) + +diff --git a/drivers/mmc/core/pwrseq_simple.c b/drivers/mmc/core/pwrseq_simple.c +index bc173e18b71c..f94271bb1f6b 100644 +--- a/drivers/mmc/core/pwrseq_simple.c ++++ b/drivers/mmc/core/pwrseq_simple.c +@@ -25,6 +25,8 @@ struct mmc_pwrseq_simple { + struct gpio_descs *reset_gpios; + }; + ++#define to_pwrseq_simple(p) container_of(p, struct mmc_pwrseq_simple, pwrseq) ++ + static void mmc_pwrseq_simple_set_gpios_value(struct mmc_pwrseq_simple *pwrseq, + int value) + { +@@ -44,8 +46,7 @@ static void mmc_pwrseq_simple_set_gpios_value(struct mmc_pwrseq_simple *pwrseq, + + static void mmc_pwrseq_simple_pre_power_on(struct mmc_host *host) + { +- struct mmc_pwrseq_simple *pwrseq = container_of(host->pwrseq, +- struct mmc_pwrseq_simple, pwrseq); ++ struct mmc_pwrseq_simple *pwrseq = to_pwrseq_simple(host->pwrseq); + + if (!IS_ERR(pwrseq->ext_clk) && !pwrseq->clk_enabled) { + clk_prepare_enable(pwrseq->ext_clk); +@@ -57,16 +58,14 @@ static void mmc_pwrseq_simple_pre_power_on(struct mmc_host *host) + + static void mmc_pwrseq_simple_post_power_on(struct mmc_host *host) + { +- struct mmc_pwrseq_simple *pwrseq = container_of(host->pwrseq, +- struct mmc_pwrseq_simple, pwrseq); ++ struct mmc_pwrseq_simple *pwrseq = to_pwrseq_simple(host->pwrseq); + + mmc_pwrseq_simple_set_gpios_value(pwrseq, 0); + } + + static void mmc_pwrseq_simple_power_off(struct mmc_host *host) + { +- struct mmc_pwrseq_simple *pwrseq = container_of(host->pwrseq, +- struct mmc_pwrseq_simple, pwrseq); ++ struct mmc_pwrseq_simple *pwrseq = to_pwrseq_simple(host->pwrseq); + + mmc_pwrseq_simple_set_gpios_value(pwrseq, 1); + +@@ -78,8 +77,7 @@ static void mmc_pwrseq_simple_power_off(struct mmc_host *host) + + static void mmc_pwrseq_simple_free(struct mmc_host *host) + { +- struct mmc_pwrseq_simple *pwrseq = container_of(host->pwrseq, +- struct mmc_pwrseq_simple, pwrseq); ++ struct mmc_pwrseq_simple *pwrseq = to_pwrseq_simple(host->pwrseq); + + if (!IS_ERR(pwrseq->reset_gpios)) + gpiod_put_array(pwrseq->reset_gpios); + +From b76637491013b2298cf46729767ba76544d4023b Mon Sep 17 00:00:00 2001 +From: Srinivas Kandagatla +Date: Thu, 14 Apr 2016 14:02:15 +0100 +Subject: [PATCH] UPSTREAM: mmc: pwrseq_emmc: add to_pwrseq_emmc() macro + +This patch adds to_pwrseq_emmc() macro to make the code more readable. + +Signed-off-by: Srinivas Kandagatla +Signed-off-by: Ulf Hansson +(cherry picked from commit f01b72d0fd53b61cafd25b16d15e18b1ef8ae065) +--- + drivers/mmc/core/pwrseq_emmc.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/mmc/core/pwrseq_emmc.c b/drivers/mmc/core/pwrseq_emmc.c +index 4a82bc77fe49..c2d732aa464c 100644 +--- a/drivers/mmc/core/pwrseq_emmc.c ++++ b/drivers/mmc/core/pwrseq_emmc.c +@@ -25,6 +25,8 @@ struct mmc_pwrseq_emmc { + struct gpio_desc *reset_gpio; + }; + ++#define to_pwrseq_emmc(p) container_of(p, struct mmc_pwrseq_emmc, pwrseq) ++ + static void __mmc_pwrseq_emmc_reset(struct mmc_pwrseq_emmc *pwrseq) + { + gpiod_set_value(pwrseq->reset_gpio, 1); +@@ -35,16 +37,14 @@ static void __mmc_pwrseq_emmc_reset(struct mmc_pwrseq_emmc *pwrseq) + + static void mmc_pwrseq_emmc_reset(struct mmc_host *host) + { +- struct mmc_pwrseq_emmc *pwrseq = container_of(host->pwrseq, +- struct mmc_pwrseq_emmc, pwrseq); ++ struct mmc_pwrseq_emmc *pwrseq = to_pwrseq_emmc(host->pwrseq); + + __mmc_pwrseq_emmc_reset(pwrseq); + } + + static void mmc_pwrseq_emmc_free(struct mmc_host *host) + { +- struct mmc_pwrseq_emmc *pwrseq = container_of(host->pwrseq, +- struct mmc_pwrseq_emmc, pwrseq); ++ struct mmc_pwrseq_emmc *pwrseq = to_pwrseq_emmc(host->pwrseq); + + unregister_restart_handler(&pwrseq->reset_nb); + gpiod_put(pwrseq->reset_gpio); + +From c1631d2cea4e5956e368c4652859a9090a509af2 Mon Sep 17 00:00:00 2001 +From: Srinivas Kandagatla +Date: Thu, 14 Apr 2016 14:02:16 +0100 +Subject: [PATCH] UPSTREAM: mmc: pwrseq: convert to proper platform device + +simple-pwrseq and emmc-pwrseq drivers rely on platform_device +structure from of_find_device_by_node(), this works mostly. But, as there +is no driver associated with this devices, cases like default/init pinctrl +setup would never be performed by pwrseq. This becomes problem when the +gpios used in pwrseq require pinctrl setup. + +Currently most of the common pinctrl setup is done in +drivers/base/pinctrl.c by pinctrl_bind_pins(). + +There are two ways to solve this issue on either convert pwrseq drivers +to a proper platform drivers or copy the exact code from +pcintrl_bind_pins(). I prefer converting pwrseq to proper drivers so that +other cases like setting up clks/parents from dt would also be possible. + +Signed-off-by: Srinivas Kandagatla +Signed-off-by: Ulf Hansson +(cherry picked from commit d97a1e5d7cd2b5b0edc02a40fe6897b710c9e10f) +--- + drivers/mmc/core/Kconfig | 22 ++++++++ + drivers/mmc/core/Makefile | 4 +- + drivers/mmc/core/pwrseq.c | 108 ++++++++++++++++++--------------------- + drivers/mmc/core/pwrseq.h | 19 ++++--- + drivers/mmc/core/pwrseq_emmc.c | 75 +++++++++++++++++---------- + drivers/mmc/core/pwrseq_simple.c | 79 +++++++++++++++------------- + 6 files changed, 178 insertions(+), 129 deletions(-) + +diff --git a/drivers/mmc/core/Kconfig b/drivers/mmc/core/Kconfig +index 87cc07dedd9f..00dfaea06003 100644 +--- a/drivers/mmc/core/Kconfig ++++ b/drivers/mmc/core/Kconfig +@@ -16,3 +16,25 @@ config MMC_PARANOID_SD_INIT + about re-trying SD init requests. This can be a useful + work-around for buggy controllers and hardware. Enable + if you are experiencing issues with SD detection. ++ ++config PWRSEQ_EMMC ++ tristate "HW reset support for eMMC" ++ default y ++ depends on OF ++ help ++ This selects Hardware reset support aka pwrseq-emmc for eMMC ++ devices. By default this option is set to y. ++ ++ This driver can also be built as a module. If so, the module ++ will be called pwrseq_emmc. ++ ++config PWRSEQ_SIMPLE ++ tristate "Simple HW reset support for MMC" ++ default y ++ depends on OF ++ help ++ This selects simple hardware reset support aka pwrseq-simple for MMC ++ devices. By default this option is set to y. ++ ++ This driver can also be built as a module. If so, the module ++ will be called pwrseq_simple. +diff --git a/drivers/mmc/core/Makefile b/drivers/mmc/core/Makefile +index 2c25138f28b7..f007151dfdc6 100644 +--- a/drivers/mmc/core/Makefile ++++ b/drivers/mmc/core/Makefile +@@ -8,5 +8,7 @@ mmc_core-y := core.o bus.o host.o \ + sdio.o sdio_ops.o sdio_bus.o \ + sdio_cis.o sdio_io.o sdio_irq.o \ + quirks.o slot-gpio.o +-mmc_core-$(CONFIG_OF) += pwrseq.o pwrseq_simple.o pwrseq_emmc.o ++mmc_core-$(CONFIG_OF) += pwrseq.o ++obj-$(CONFIG_PWRSEQ_SIMPLE) += pwrseq_simple.o ++obj-$(CONFIG_PWRSEQ_EMMC) += pwrseq_emmc.o + mmc_core-$(CONFIG_DEBUG_FS) += debugfs.o +diff --git a/drivers/mmc/core/pwrseq.c b/drivers/mmc/core/pwrseq.c +index 4c1d1757dbf9..9386c4771814 100644 +--- a/drivers/mmc/core/pwrseq.c ++++ b/drivers/mmc/core/pwrseq.c +@@ -8,88 +8,55 @@ + * MMC power sequence management + */ + #include +-#include + #include ++#include + #include +-#include + + #include + + #include "pwrseq.h" + +-struct mmc_pwrseq_match { +- const char *compatible; +- struct mmc_pwrseq *(*alloc)(struct mmc_host *host, struct device *dev); +-}; +- +-static struct mmc_pwrseq_match pwrseq_match[] = { +- { +- .compatible = "mmc-pwrseq-simple", +- .alloc = mmc_pwrseq_simple_alloc, +- }, { +- .compatible = "mmc-pwrseq-emmc", +- .alloc = mmc_pwrseq_emmc_alloc, +- }, +-}; +- +-static struct mmc_pwrseq_match *mmc_pwrseq_find(struct device_node *np) +-{ +- struct mmc_pwrseq_match *match = ERR_PTR(-ENODEV); +- int i; +- +- for (i = 0; i < ARRAY_SIZE(pwrseq_match); i++) { +- if (of_device_is_compatible(np, pwrseq_match[i].compatible)) { +- match = &pwrseq_match[i]; +- break; +- } +- } +- +- return match; +-} ++static DEFINE_MUTEX(pwrseq_list_mutex); ++static LIST_HEAD(pwrseq_list); + + int mmc_pwrseq_alloc(struct mmc_host *host) + { +- struct platform_device *pdev; + struct device_node *np; +- struct mmc_pwrseq_match *match; +- struct mmc_pwrseq *pwrseq; +- int ret = 0; ++ struct mmc_pwrseq *p; + + np = of_parse_phandle(host->parent->of_node, "mmc-pwrseq", 0); + if (!np) + return 0; + +- pdev = of_find_device_by_node(np); +- if (!pdev) { +- ret = -ENODEV; +- goto err; +- } ++ mutex_lock(&pwrseq_list_mutex); ++ list_for_each_entry(p, &pwrseq_list, pwrseq_node) { ++ if (p->dev->of_node == np) { ++ if (!try_module_get(p->owner)) ++ dev_err(host->parent, ++ "increasing module refcount failed\n"); ++ else ++ host->pwrseq = p; + +- match = mmc_pwrseq_find(np); +- if (IS_ERR(match)) { +- ret = PTR_ERR(match); +- goto err; ++ break; ++ } + } + +- pwrseq = match->alloc(host, &pdev->dev); +- if (IS_ERR(pwrseq)) { +- ret = PTR_ERR(pwrseq); +- goto err; +- } ++ of_node_put(np); ++ mutex_unlock(&pwrseq_list_mutex); ++ ++ if (!host->pwrseq) ++ return -EPROBE_DEFER; + +- host->pwrseq = pwrseq; + dev_info(host->parent, "allocated mmc-pwrseq\n"); + +-err: +- of_node_put(np); +- return ret; ++ return 0; + } + + void mmc_pwrseq_pre_power_on(struct mmc_host *host) + { + struct mmc_pwrseq *pwrseq = host->pwrseq; + +- if (pwrseq && pwrseq->ops && pwrseq->ops->pre_power_on) ++ if (pwrseq && pwrseq->ops->pre_power_on) + pwrseq->ops->pre_power_on(host); + } + +@@ -97,7 +64,7 @@ void mmc_pwrseq_post_power_on(struct mmc_host *host) + { + struct mmc_pwrseq *pwrseq = host->pwrseq; + +- if (pwrseq && pwrseq->ops && pwrseq->ops->post_power_on) ++ if (pwrseq && pwrseq->ops->post_power_on) + pwrseq->ops->post_power_on(host); + } + +@@ -105,7 +72,7 @@ void mmc_pwrseq_power_off(struct mmc_host *host) + { + struct mmc_pwrseq *pwrseq = host->pwrseq; + +- if (pwrseq && pwrseq->ops && pwrseq->ops->power_off) ++ if (pwrseq && pwrseq->ops->power_off) + pwrseq->ops->power_off(host); + } + +@@ -113,8 +80,31 @@ void mmc_pwrseq_free(struct mmc_host *host) + { + struct mmc_pwrseq *pwrseq = host->pwrseq; + +- if (pwrseq && pwrseq->ops && pwrseq->ops->free) +- pwrseq->ops->free(host); ++ if (pwrseq) { ++ module_put(pwrseq->owner); ++ host->pwrseq = NULL; ++ } ++} ++ ++int mmc_pwrseq_register(struct mmc_pwrseq *pwrseq) ++{ ++ if (!pwrseq || !pwrseq->ops || !pwrseq->dev) ++ return -EINVAL; + +- host->pwrseq = NULL; ++ mutex_lock(&pwrseq_list_mutex); ++ list_add(&pwrseq->pwrseq_node, &pwrseq_list); ++ mutex_unlock(&pwrseq_list_mutex); ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(mmc_pwrseq_register); ++ ++void mmc_pwrseq_unregister(struct mmc_pwrseq *pwrseq) ++{ ++ if (pwrseq) { ++ mutex_lock(&pwrseq_list_mutex); ++ list_del(&pwrseq->pwrseq_node); ++ mutex_unlock(&pwrseq_list_mutex); ++ } + } ++EXPORT_SYMBOL_GPL(mmc_pwrseq_unregister); +diff --git a/drivers/mmc/core/pwrseq.h b/drivers/mmc/core/pwrseq.h +index 133de0426687..d69e751f148b 100644 +--- a/drivers/mmc/core/pwrseq.h ++++ b/drivers/mmc/core/pwrseq.h +@@ -8,32 +8,39 @@ + #ifndef _MMC_CORE_PWRSEQ_H + #define _MMC_CORE_PWRSEQ_H + ++#include ++ + struct mmc_pwrseq_ops { + void (*pre_power_on)(struct mmc_host *host); + void (*post_power_on)(struct mmc_host *host); + void (*power_off)(struct mmc_host *host); +- void (*free)(struct mmc_host *host); + }; + + struct mmc_pwrseq { + const struct mmc_pwrseq_ops *ops; ++ struct device *dev; ++ struct list_head pwrseq_node; ++ struct module *owner; + }; + + #ifdef CONFIG_OF + ++int mmc_pwrseq_register(struct mmc_pwrseq *pwrseq); ++void mmc_pwrseq_unregister(struct mmc_pwrseq *pwrseq); ++ + int mmc_pwrseq_alloc(struct mmc_host *host); + void mmc_pwrseq_pre_power_on(struct mmc_host *host); + void mmc_pwrseq_post_power_on(struct mmc_host *host); + void mmc_pwrseq_power_off(struct mmc_host *host); + void mmc_pwrseq_free(struct mmc_host *host); + +-struct mmc_pwrseq *mmc_pwrseq_simple_alloc(struct mmc_host *host, +- struct device *dev); +-struct mmc_pwrseq *mmc_pwrseq_emmc_alloc(struct mmc_host *host, +- struct device *dev); +- + #else + ++static inline int mmc_pwrseq_register(struct mmc_pwrseq *pwrseq) ++{ ++ return -ENOSYS; ++} ++static inline void mmc_pwrseq_unregister(struct mmc_pwrseq *pwrseq) {} + static inline int mmc_pwrseq_alloc(struct mmc_host *host) { return 0; } + static inline void mmc_pwrseq_pre_power_on(struct mmc_host *host) {} + static inline void mmc_pwrseq_post_power_on(struct mmc_host *host) {} +diff --git a/drivers/mmc/core/pwrseq_emmc.c b/drivers/mmc/core/pwrseq_emmc.c +index c2d732aa464c..adc9c0c614fb 100644 +--- a/drivers/mmc/core/pwrseq_emmc.c ++++ b/drivers/mmc/core/pwrseq_emmc.c +@@ -9,6 +9,9 @@ + */ + #include + #include ++#include ++#include ++#include + #include + #include + #include +@@ -42,20 +45,6 @@ static void mmc_pwrseq_emmc_reset(struct mmc_host *host) + __mmc_pwrseq_emmc_reset(pwrseq); + } + +-static void mmc_pwrseq_emmc_free(struct mmc_host *host) +-{ +- struct mmc_pwrseq_emmc *pwrseq = to_pwrseq_emmc(host->pwrseq); +- +- unregister_restart_handler(&pwrseq->reset_nb); +- gpiod_put(pwrseq->reset_gpio); +- kfree(pwrseq); +-} +- +-static const struct mmc_pwrseq_ops mmc_pwrseq_emmc_ops = { +- .post_power_on = mmc_pwrseq_emmc_reset, +- .free = mmc_pwrseq_emmc_free, +-}; +- + static int mmc_pwrseq_emmc_reset_nb(struct notifier_block *this, + unsigned long mode, void *cmd) + { +@@ -66,21 +55,22 @@ static int mmc_pwrseq_emmc_reset_nb(struct notifier_block *this, + return NOTIFY_DONE; + } + +-struct mmc_pwrseq *mmc_pwrseq_emmc_alloc(struct mmc_host *host, +- struct device *dev) ++static const struct mmc_pwrseq_ops mmc_pwrseq_emmc_ops = { ++ .post_power_on = mmc_pwrseq_emmc_reset, ++}; ++ ++static int mmc_pwrseq_emmc_probe(struct platform_device *pdev) + { + struct mmc_pwrseq_emmc *pwrseq; +- int ret = 0; ++ struct device *dev = &pdev->dev; + +- pwrseq = kzalloc(sizeof(struct mmc_pwrseq_emmc), GFP_KERNEL); ++ pwrseq = devm_kzalloc(dev, sizeof(*pwrseq), GFP_KERNEL); + if (!pwrseq) +- return ERR_PTR(-ENOMEM); ++ return -ENOMEM; + +- pwrseq->reset_gpio = gpiod_get(dev, "reset", GPIOD_OUT_LOW); +- if (IS_ERR(pwrseq->reset_gpio)) { +- ret = PTR_ERR(pwrseq->reset_gpio); +- goto free; +- } ++ pwrseq->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW); ++ if (IS_ERR(pwrseq->reset_gpio)) ++ return PTR_ERR(pwrseq->reset_gpio); + + /* + * register reset handler to ensure emmc reset also from +@@ -92,9 +82,38 @@ struct mmc_pwrseq *mmc_pwrseq_emmc_alloc(struct mmc_host *host, + register_restart_handler(&pwrseq->reset_nb); + + pwrseq->pwrseq.ops = &mmc_pwrseq_emmc_ops; ++ pwrseq->pwrseq.dev = dev; ++ pwrseq->pwrseq.owner = THIS_MODULE; ++ platform_set_drvdata(pdev, pwrseq); ++ ++ return mmc_pwrseq_register(&pwrseq->pwrseq); ++} ++ ++static int mmc_pwrseq_emmc_remove(struct platform_device *pdev) ++{ ++ struct mmc_pwrseq_emmc *pwrseq = platform_get_drvdata(pdev); ++ ++ unregister_restart_handler(&pwrseq->reset_nb); ++ mmc_pwrseq_unregister(&pwrseq->pwrseq); + +- return &pwrseq->pwrseq; +-free: +- kfree(pwrseq); +- return ERR_PTR(ret); ++ return 0; + } ++ ++static const struct of_device_id mmc_pwrseq_emmc_of_match[] = { ++ { .compatible = "mmc-pwrseq-emmc",}, ++ {/* sentinel */}, ++}; ++ ++MODULE_DEVICE_TABLE(of, mmc_pwrseq_emmc_of_match); ++ ++static struct platform_driver mmc_pwrseq_emmc_driver = { ++ .probe = mmc_pwrseq_emmc_probe, ++ .remove = mmc_pwrseq_emmc_remove, ++ .driver = { ++ .name = "pwrseq_emmc", ++ .of_match_table = mmc_pwrseq_emmc_of_match, ++ }, ++}; ++ ++module_platform_driver(mmc_pwrseq_emmc_driver); ++MODULE_LICENSE("GPL v2"); +diff --git a/drivers/mmc/core/pwrseq_simple.c b/drivers/mmc/core/pwrseq_simple.c +index f94271bb1f6b..450d907c6e6c 100644 +--- a/drivers/mmc/core/pwrseq_simple.c ++++ b/drivers/mmc/core/pwrseq_simple.c +@@ -8,7 +8,10 @@ + * Simple MMC power sequence management + */ + #include ++#include + #include ++#include ++#include + #include + #include + #include +@@ -75,58 +78,64 @@ static void mmc_pwrseq_simple_power_off(struct mmc_host *host) + } + } + +-static void mmc_pwrseq_simple_free(struct mmc_host *host) +-{ +- struct mmc_pwrseq_simple *pwrseq = to_pwrseq_simple(host->pwrseq); +- +- if (!IS_ERR(pwrseq->reset_gpios)) +- gpiod_put_array(pwrseq->reset_gpios); +- +- if (!IS_ERR(pwrseq->ext_clk)) +- clk_put(pwrseq->ext_clk); +- +- kfree(pwrseq); +-} +- + static const struct mmc_pwrseq_ops mmc_pwrseq_simple_ops = { + .pre_power_on = mmc_pwrseq_simple_pre_power_on, + .post_power_on = mmc_pwrseq_simple_post_power_on, + .power_off = mmc_pwrseq_simple_power_off, +- .free = mmc_pwrseq_simple_free, + }; + +-struct mmc_pwrseq *mmc_pwrseq_simple_alloc(struct mmc_host *host, +- struct device *dev) ++static const struct of_device_id mmc_pwrseq_simple_of_match[] = { ++ { .compatible = "mmc-pwrseq-simple",}, ++ {/* sentinel */}, ++}; ++MODULE_DEVICE_TABLE(of, mmc_pwrseq_simple_of_match); ++ ++static int mmc_pwrseq_simple_probe(struct platform_device *pdev) + { + struct mmc_pwrseq_simple *pwrseq; +- int ret = 0; ++ struct device *dev = &pdev->dev; + +- pwrseq = kzalloc(sizeof(*pwrseq), GFP_KERNEL); ++ pwrseq = devm_kzalloc(dev, sizeof(*pwrseq), GFP_KERNEL); + if (!pwrseq) +- return ERR_PTR(-ENOMEM); ++ return -ENOMEM; + +- pwrseq->ext_clk = clk_get(dev, "ext_clock"); +- if (IS_ERR(pwrseq->ext_clk) && +- PTR_ERR(pwrseq->ext_clk) != -ENOENT) { +- ret = PTR_ERR(pwrseq->ext_clk); +- goto free; +- } ++ pwrseq->ext_clk = devm_clk_get(dev, "ext_clock"); ++ if (IS_ERR(pwrseq->ext_clk) && PTR_ERR(pwrseq->ext_clk) != -ENOENT) ++ return PTR_ERR(pwrseq->ext_clk); + +- pwrseq->reset_gpios = gpiod_get_array(dev, "reset", GPIOD_OUT_HIGH); ++ pwrseq->reset_gpios = devm_gpiod_get_array(dev, "reset", ++ GPIOD_OUT_HIGH); + if (IS_ERR(pwrseq->reset_gpios) && + PTR_ERR(pwrseq->reset_gpios) != -ENOENT && + PTR_ERR(pwrseq->reset_gpios) != -ENOSYS) { +- ret = PTR_ERR(pwrseq->reset_gpios); +- goto clk_put; ++ return PTR_ERR(pwrseq->reset_gpios); + } + ++ pwrseq->pwrseq.dev = dev; + pwrseq->pwrseq.ops = &mmc_pwrseq_simple_ops; ++ pwrseq->pwrseq.owner = THIS_MODULE; ++ platform_set_drvdata(pdev, pwrseq); + +- return &pwrseq->pwrseq; +-clk_put: +- if (!IS_ERR(pwrseq->ext_clk)) +- clk_put(pwrseq->ext_clk); +-free: +- kfree(pwrseq); +- return ERR_PTR(ret); ++ return mmc_pwrseq_register(&pwrseq->pwrseq); + } ++ ++static int mmc_pwrseq_simple_remove(struct platform_device *pdev) ++{ ++ struct mmc_pwrseq_simple *pwrseq = platform_get_drvdata(pdev); ++ ++ mmc_pwrseq_unregister(&pwrseq->pwrseq); ++ ++ return 0; ++} ++ ++static struct platform_driver mmc_pwrseq_simple_driver = { ++ .probe = mmc_pwrseq_simple_probe, ++ .remove = mmc_pwrseq_simple_remove, ++ .driver = { ++ .name = "pwrseq_simple", ++ .of_match_table = mmc_pwrseq_simple_of_match, ++ }, ++}; ++ ++module_platform_driver(mmc_pwrseq_simple_driver); ++MODULE_LICENSE("GPL v2"); + +From 2abada2ff3999a38dc87d5803f98141a0971c06c Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Sun, 7 Aug 2016 21:02:38 +0200 +Subject: [PATCH] UPSTREAM: mmc: pwrseq-simple: Add an optional + post-power-on-delay + +Some devices need a while to boot their firmware after providing clks / +de-asserting resets before they are ready to receive sdio commands. + +This commits adds a post-power-on-delay-ms devicetree property to +mmc-pwrseq-simple for use with such devices. + +Signed-off-by: Hans de Goede +Acked-by: Rob Herring +Signed-off-by: Ulf Hansson +(cherry picked from commit 721e0497172f0fa661eed2d63367cddf479f35e8) +--- + Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt | 2 ++ + drivers/mmc/core/pwrseq_simple.c | 9 +++++++++ + 2 files changed, 11 insertions(+) + +diff --git a/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt b/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt +index ce0e76749671..e25436861867 100644 +--- a/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt ++++ b/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt +@@ -16,6 +16,8 @@ Optional properties: + See ../clocks/clock-bindings.txt for details. + - clock-names : Must include the following entry: + "ext_clock" (External clock provided to the card). ++- post-power-on-delay-ms : Delay in ms after powering the card and ++ de-asserting the reset-gpios (if any) + + Example: + +diff --git a/drivers/mmc/core/pwrseq_simple.c b/drivers/mmc/core/pwrseq_simple.c +index 450d907c6e6c..1304160de168 100644 +--- a/drivers/mmc/core/pwrseq_simple.c ++++ b/drivers/mmc/core/pwrseq_simple.c +@@ -16,6 +16,8 @@ + #include + #include + #include ++#include ++#include + + #include + +@@ -24,6 +26,7 @@ + struct mmc_pwrseq_simple { + struct mmc_pwrseq pwrseq; + bool clk_enabled; ++ u32 post_power_on_delay_ms; + struct clk *ext_clk; + struct gpio_descs *reset_gpios; + }; +@@ -64,6 +67,9 @@ static void mmc_pwrseq_simple_post_power_on(struct mmc_host *host) + struct mmc_pwrseq_simple *pwrseq = to_pwrseq_simple(host->pwrseq); + + mmc_pwrseq_simple_set_gpios_value(pwrseq, 0); ++ ++ if (pwrseq->post_power_on_delay_ms) ++ msleep(pwrseq->post_power_on_delay_ms); + } + + static void mmc_pwrseq_simple_power_off(struct mmc_host *host) +@@ -111,6 +117,9 @@ static int mmc_pwrseq_simple_probe(struct platform_device *pdev) + return PTR_ERR(pwrseq->reset_gpios); + } + ++ device_property_read_u32(dev, "post-power-on-delay-ms", ++ &pwrseq->post_power_on_delay_ms); ++ + pwrseq->pwrseq.dev = dev; + pwrseq->pwrseq.ops = &mmc_pwrseq_simple_ops; + pwrseq->pwrseq.owner = THIS_MODULE; + +From 4d0a703460821fc7541ae96916eca948e326b16c Mon Sep 17 00:00:00 2001 +From: Ulf Hansson +Date: Sat, 6 May 2017 11:41:30 +0200 +Subject: [PATCH] UPSTREAM: mmc: dt: pwrseq-simple: Invent power-off-delay-us + +During power off, after the GPIO pin has been asserted, some devices like +the Wifi chip from TI, Wl18xx, needs a delay before the host continues with +clock gating and turning off regulators as to follow a graceful shutdown +sequence. + +Therefore invent an optional power-off-delay-us DT binding for +mmc-pwrseq-simple, to allow us to support this constraint. + +Cc: devicetree@vger.kernel.org +Cc: Rob Herring +Cc: linux-mmc@vger.kernel.org +Signed-off-by: Ulf Hansson +Acked-by: Arnd Bergmann +--- + Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt b/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt +index e25436861867..9029b45b8a22 100644 +--- a/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt ++++ b/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt +@@ -18,6 +18,8 @@ Optional properties: + "ext_clock" (External clock provided to the card). + - post-power-on-delay-ms : Delay in ms after powering the card and + de-asserting the reset-gpios (if any) ++- power-off-delay-us : Delay in us after asserting the reset-gpios (if any) ++ during power off of the card. + + Example: + + +From e85294cdf12c6a6e6fb3c24cae1ad0994ae6aca2 Mon Sep 17 00:00:00 2001 +From: Ulf Hansson +Date: Sat, 6 May 2017 11:43:05 +0200 +Subject: [PATCH] UPSTREAM: mmc: pwrseq_simple: Parse DTS for the + power-off-delay-us property + +If the optional power-off-delay-us property is found, insert the +corresponding delay after asserting the GPIO during power off. This enables +a graceful shutdown sequence for some devices. + +Cc: linux-mmc@vger.kernel.org +Signed-off-by: Ulf Hansson +Acked-by: Arnd Bergmann +(cherry picked from commit e9256e142f597edf90c68cec22db4c4aebaa27de) +--- + drivers/mmc/core/pwrseq_simple.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/mmc/core/pwrseq_simple.c b/drivers/mmc/core/pwrseq_simple.c +index 1304160de168..13ef162cf066 100644 +--- a/drivers/mmc/core/pwrseq_simple.c ++++ b/drivers/mmc/core/pwrseq_simple.c +@@ -27,6 +27,7 @@ struct mmc_pwrseq_simple { + struct mmc_pwrseq pwrseq; + bool clk_enabled; + u32 post_power_on_delay_ms; ++ u32 power_off_delay_us; + struct clk *ext_clk; + struct gpio_descs *reset_gpios; + }; +@@ -78,6 +79,10 @@ static void mmc_pwrseq_simple_power_off(struct mmc_host *host) + + mmc_pwrseq_simple_set_gpios_value(pwrseq, 1); + ++ if (pwrseq->power_off_delay_us) ++ usleep_range(pwrseq->power_off_delay_us, ++ 2 * pwrseq->power_off_delay_us); ++ + if (!IS_ERR(pwrseq->ext_clk) && pwrseq->clk_enabled) { + clk_disable_unprepare(pwrseq->ext_clk); + pwrseq->clk_enabled = false; +@@ -119,6 +124,8 @@ static int mmc_pwrseq_simple_probe(struct platform_device *pdev) + + device_property_read_u32(dev, "post-power-on-delay-ms", + &pwrseq->post_power_on_delay_ms); ++ device_property_read_u32(dev, "power-off-delay-us", ++ &pwrseq->power_off_delay_us); + + pwrseq->pwrseq.dev = dev; + pwrseq->pwrseq.ops = &mmc_pwrseq_simple_ops; diff --git a/patch/kernel/rk322x-legacy/01-linux-0009-mmc.patch b/patch/kernel/rk322x-legacy/01-linux-0009-mmc.patch new file mode 100644 index 0000000000..78940bbf07 --- /dev/null +++ b/patch/kernel/rk322x-legacy/01-linux-0009-mmc.patch @@ -0,0 +1,267 @@ +diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c +index f82b1eb..d2c59b5 100644 +--- a/drivers/mmc/core/core.c ++++ b/drivers/mmc/core/core.c +@@ -1574,7 +1574,34 @@ u32 mmc_select_voltage(struct mmc_host *host, u32 ocr) + return ocr; + } + +-int mmc_host_set_uhs_voltage(struct mmc_host *host, int signal_voltage) ++int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage) ++{ ++ int err = 0; ++ int old_signal_voltage = host->ios.signal_voltage; ++ ++ host->ios.signal_voltage = signal_voltage; ++ if (host->ops->start_signal_voltage_switch) ++ err = host->ops->start_signal_voltage_switch(host, &host->ios); ++ ++ if (err) ++ host->ios.signal_voltage = old_signal_voltage; ++ ++ return err; ++ ++} ++ ++void mmc_set_initial_signal_voltage(struct mmc_host *host) ++{ ++ /* Try to set signal voltage to 3.3V but fall back to 1.8v or 1.2v */ ++ if (!mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_330)) ++ dev_dbg(mmc_dev(host), "Initial signal voltage of 3.3v\n"); ++ else if (!mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180)) ++ dev_dbg(mmc_dev(host), "Initial signal voltage of 1.8v\n"); ++ else if (!mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_120)) ++ dev_dbg(mmc_dev(host), "Initial signal voltage of 1.2v\n"); ++} ++ ++int mmc_host_set_uhs_voltage(struct mmc_host *host) + { + u32 clock; + +@@ -1586,7 +1613,7 @@ int mmc_host_set_uhs_voltage(struct mmc_host *host, int signal_voltage) + host->ios.clock = 0; + mmc_set_ios(host); + +- if (__mmc_set_signal_voltage(host, signal_voltage)) ++ if (mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180)) + return -EAGAIN; + + /* Keep clock gated for at least 10 ms, though spec only says 5 ms */ +@@ -1597,23 +1624,7 @@ int mmc_host_set_uhs_voltage(struct mmc_host *host, int signal_voltage) + return 0; + } + +-int __mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage) +-{ +- int err = 0; +- int old_signal_voltage = host->ios.signal_voltage; +- +- host->ios.signal_voltage = signal_voltage; +- if (host->ops->start_signal_voltage_switch) +- err = host->ops->start_signal_voltage_switch(host, &host->ios); +- +- if (err) +- host->ios.signal_voltage = old_signal_voltage; +- +- return err; +- +-} +- +-int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage, u32 ocr) ++int mmc_set_uhs_voltage(struct mmc_host *host, u32 ocr) + { + struct mmc_command cmd = {0}; + int err = 0; +@@ -1621,13 +1632,6 @@ int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage, u32 ocr) + BUG_ON(!host); + + /* +- * Send CMD11 only if the request is to switch the card to +- * 1.8V signalling. +- */ +- if (signal_voltage == MMC_SIGNAL_VOLTAGE_330) +- return __mmc_set_signal_voltage(host, signal_voltage); +- +- /* + * If we cannot switch voltages, return failure so the caller + * can continue without UHS mode + */ +@@ -1658,7 +1662,7 @@ int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage, u32 ocr) + goto power_cycle; + } + +- if (mmc_host_set_uhs_voltage(host, signal_voltage)) { ++ if (mmc_host_set_uhs_voltage(host)) { + /* + * Voltages may not have been switched, but we've already + * sent CMD11, so a power cycle is required anyway +@@ -1761,13 +1765,7 @@ void mmc_power_up(struct mmc_host *host, u32 ocr) + /* Set initial state and call mmc_set_ios */ + mmc_set_initial_state(host); + +- /* Try to set signal voltage to 3.3V but fall back to 1.8v or 1.2v */ +- if (__mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_330) == 0) +- dev_dbg(mmc_dev(host), "Initial signal voltage of 3.3v\n"); +- else if (__mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180) == 0) +- dev_dbg(mmc_dev(host), "Initial signal voltage of 1.8v\n"); +- else if (__mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_120) == 0) +- dev_dbg(mmc_dev(host), "Initial signal voltage of 1.2v\n"); ++ mmc_set_initial_signal_voltage(host); + + /* + * This delay should be sufficient to allow the power supply +@@ -1794,6 +1792,14 @@ void mmc_power_off(struct mmc_host *host) + if (host->ios.power_mode == MMC_POWER_OFF) + return; + ++ mmc_set_initial_signal_voltage(host); ++ ++ /* ++ * This delay should be sufficient to allow the power supply ++ * to reach the minimum voltage. ++ */ ++ mmc_delay(10); ++ + mmc_pwrseq_power_off(host); + + host->ios.clock = 0; +diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h +index 2cd32dc..2634722 100644 +--- a/drivers/mmc/core/core.h ++++ b/drivers/mmc/core/core.h +@@ -43,9 +43,10 @@ void mmc_set_clock(struct mmc_host *host, unsigned int hz); + void mmc_set_bus_mode(struct mmc_host *host, unsigned int mode); + void mmc_set_bus_width(struct mmc_host *host, unsigned int width); + u32 mmc_select_voltage(struct mmc_host *host, u32 ocr); +-int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage, u32 ocr); +-int mmc_host_set_uhs_voltage(struct mmc_host *host, int signal_voltage); +-int __mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage); ++int mmc_set_uhs_voltage(struct mmc_host *host, u32 ocr); ++int mmc_host_set_uhs_voltage(struct mmc_host *host); ++int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage); ++void mmc_set_initial_signal_voltage(struct mmc_host *host); + void mmc_set_timing(struct mmc_host *host, unsigned int timing); + void mmc_set_driver_type(struct mmc_host *host, unsigned int drv_type); + int mmc_select_drive_strength(struct mmc_card *card, unsigned int max_dtr, +diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c +index a814eb6..dd0040a 100644 +--- a/drivers/mmc/core/mmc.c ++++ b/drivers/mmc/core/mmc.c +@@ -1088,14 +1088,14 @@ static int mmc_select_hs_ddr(struct mmc_card *card) + */ + err = -EINVAL; + if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_DDR_1_2V) +- err = __mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_120); ++ err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_120); + + if (err && (card->mmc_avail_type & EXT_CSD_CARD_TYPE_DDR_1_8V)) +- err = __mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180); ++ err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180); + + /* make sure vccq is 3.3v after switching disaster */ + if (err) +- err = __mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_330); ++ err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_330); + + if (!err) + mmc_set_timing(host, MMC_TIMING_MMC_DDR52); +@@ -1251,7 +1251,7 @@ out_err: + static int mmc_select_hs400es(struct mmc_card *card) + { + struct mmc_host *host = card->host; +- int err = 0; ++ int err = -EINVAL; + u8 val; + + if (!(host->caps & MMC_CAP_8_BIT_DATA)) { +@@ -1259,11 +1259,11 @@ static int mmc_select_hs400es(struct mmc_card *card) + goto out_err; + } + +- if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS200_1_2V) +- err = __mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_120); ++ if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400_1_2V) ++ err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_120); + +- if (err && card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS200_1_8V) +- err = __mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180); ++ if (err && card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400_1_8V) ++ err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180); + + /* If fails try again during next card power cycle */ + if (err) +@@ -1362,10 +1362,10 @@ static int mmc_select_hs200(struct mmc_card *card) + + old_signal_voltage = host->ios.signal_voltage; + if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS200_1_2V) +- err = __mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_120); ++ err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_120); + + if (err && card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS200_1_8V) +- err = __mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180); ++ err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180); + + /* If fails try again during next card power cycle */ + if (err) +@@ -1393,7 +1393,7 @@ static int mmc_select_hs200(struct mmc_card *card) + err: + if (err) { + /* fall back to the old signal voltage, if fails report error */ +- if (__mmc_set_signal_voltage(host, old_signal_voltage)) ++ if (mmc_set_signal_voltage(host, old_signal_voltage)) + err = -EIO; + + pr_err("%s: %s failed, error %d\n", mmc_hostname(card->host), +diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c +index 78638ee..17919cb 100644 +--- a/drivers/mmc/core/sd.c ++++ b/drivers/mmc/core/sd.c +@@ -742,8 +742,7 @@ try_again: + */ + if (!mmc_host_is_spi(host) && rocr && + ((*rocr & 0x41000000) == 0x41000000)) { +- err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180, +- pocr); ++ err = mmc_set_uhs_voltage(host, pocr); + if (err == -EAGAIN) { + retries--; + goto try_again; +@@ -928,7 +927,6 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr, + + BUG_ON(!host); + WARN_ON(!host->claimed); +- + retry: + err = mmc_sd_get_cid(host, ocr, cid, &rocr); + if (err) +@@ -1013,7 +1011,7 @@ retry: + goto free_card; + } + if (mmc_sd_card_using_v18(card)) { +- if (mmc_host_set_uhs_voltage(host, MMC_SIGNAL_VOLTAGE_180) || ++ if (mmc_host_set_uhs_voltage(host) || + mmc_sd_init_uhs_card(card)) { + v18_fixup_failed = true; + mmc_power_cycle(host, ocr); +@@ -1057,7 +1055,6 @@ retry: + mmc_set_bus_width(host, MMC_BUS_WIDTH_4); + } + } +- + done: + host->card = card; + return 0; +diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c +index c586b11..f221418 100644 +--- a/drivers/mmc/core/sdio.c ++++ b/drivers/mmc/core/sdio.c +@@ -648,8 +648,7 @@ try_again: + * to make sure which speed mode should work. + */ + if (!powered_resume && (rocr & ocr & R4_18V_PRESENT)) { +- err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180, +- ocr_card); ++ err = mmc_set_uhs_voltage(host, ocr_card); + if (err == -EAGAIN) { + mmc_sdio_resend_if_cond(host, card); + retries--; diff --git a/patch/kernel/rk322x-legacy/01-linux-0010-dvb.patch b/patch/kernel/rk322x-legacy/01-linux-0010-dvb.patch new file mode 100644 index 0000000000..b311cb410b --- /dev/null +++ b/patch/kernel/rk322x-legacy/01-linux-0010-dvb.patch @@ -0,0 +1,376 @@ +From 77d2716cf5579c4ad74df978ad58d983419cc44b Mon Sep 17 00:00:00 2001 +From: Jakub Kicinski +Date: Wed, 31 Aug 2016 12:46:44 +0100 +Subject: [PATCH] UPSTREAM: add basic register-field manipulation macros + +Common approach to accessing register fields is to define +structures or sets of macros containing mask and shift pair. +Operations on the register are then performed as follows: + + field = (reg >> shift) & mask; + + reg &= ~(mask << shift); + reg |= (field & mask) << shift; + +Defining shift and mask separately is tedious. Ivo van Doorn +came up with an idea of computing them at compilation time +based on a single shifted mask (later refined by Felix) which +can be used like this: + + #define REG_FIELD 0x000ff000 + + field = FIELD_GET(REG_FIELD, reg); + + reg &= ~REG_FIELD; + reg |= FIELD_PREP(REG_FIELD, field); + +FIELD_{GET,PREP} macros take care of finding out what the +appropriate shift is based on compilation time ffs operation. + +GENMASK can be used to define registers (which is usually +less error-prone and easier to match with datasheets). + +This approach is the most convenient I've seen so to limit code +multiplication let's move the macros to a global header file. +Attempts to use static inlines instead of macros failed due +to false positive triggering of BUILD_BUG_ON()s, especially with +GCC < 6.0. + +Signed-off-by: Jakub Kicinski +Reviewed-by: Dinan Gunawardena +Signed-off-by: Kalle Valo +(cherry picked from commit 3e9b3112ec74f192eaab976c3889e34255cae940) +--- + include/linux/bitfield.h | 93 ++++++++++++++++++++++++++++++++++++++++++++++++ + include/linux/bug.h | 3 ++ + 2 files changed, 96 insertions(+) + create mode 100644 include/linux/bitfield.h + +diff --git a/include/linux/bitfield.h b/include/linux/bitfield.h +new file mode 100644 +index 000000000000..f6505d83069d +--- /dev/null ++++ b/include/linux/bitfield.h +@@ -0,0 +1,93 @@ ++/* ++ * Copyright (C) 2014 Felix Fietkau ++ * Copyright (C) 2004 - 2009 Ivo van Doorn ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 ++ * as published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef _LINUX_BITFIELD_H ++#define _LINUX_BITFIELD_H ++ ++#include ++ ++/* ++ * Bitfield access macros ++ * ++ * FIELD_{GET,PREP} macros take as first parameter shifted mask ++ * from which they extract the base mask and shift amount. ++ * Mask must be a compilation time constant. ++ * ++ * Example: ++ * ++ * #define REG_FIELD_A GENMASK(6, 0) ++ * #define REG_FIELD_B BIT(7) ++ * #define REG_FIELD_C GENMASK(15, 8) ++ * #define REG_FIELD_D GENMASK(31, 16) ++ * ++ * Get: ++ * a = FIELD_GET(REG_FIELD_A, reg); ++ * b = FIELD_GET(REG_FIELD_B, reg); ++ * ++ * Set: ++ * reg = FIELD_PREP(REG_FIELD_A, 1) | ++ * FIELD_PREP(REG_FIELD_B, 0) | ++ * FIELD_PREP(REG_FIELD_C, c) | ++ * FIELD_PREP(REG_FIELD_D, 0x40); ++ * ++ * Modify: ++ * reg &= ~REG_FIELD_C; ++ * reg |= FIELD_PREP(REG_FIELD_C, c); ++ */ ++ ++#define __bf_shf(x) (__builtin_ffsll(x) - 1) ++ ++#define __BF_FIELD_CHECK(_mask, _reg, _val, _pfx) \ ++ ({ \ ++ BUILD_BUG_ON_MSG(!__builtin_constant_p(_mask), \ ++ _pfx "mask is not constant"); \ ++ BUILD_BUG_ON_MSG(!(_mask), _pfx "mask is zero"); \ ++ BUILD_BUG_ON_MSG(__builtin_constant_p(_val) ? \ ++ ~((_mask) >> __bf_shf(_mask)) & (_val) : 0, \ ++ _pfx "value too large for the field"); \ ++ BUILD_BUG_ON_MSG((_mask) > (typeof(_reg))~0ull, \ ++ _pfx "type of reg too small for mask"); \ ++ __BUILD_BUG_ON_NOT_POWER_OF_2((_mask) + \ ++ (1ULL << __bf_shf(_mask))); \ ++ }) ++ ++/** ++ * FIELD_PREP() - prepare a bitfield element ++ * @_mask: shifted mask defining the field's length and position ++ * @_val: value to put in the field ++ * ++ * FIELD_PREP() masks and shifts up the value. The result should ++ * be combined with other fields of the bitfield using logical OR. ++ */ ++#define FIELD_PREP(_mask, _val) \ ++ ({ \ ++ __BF_FIELD_CHECK(_mask, 0ULL, _val, "FIELD_PREP: "); \ ++ ((typeof(_mask))(_val) << __bf_shf(_mask)) & (_mask); \ ++ }) ++ ++/** ++ * FIELD_GET() - extract a bitfield element ++ * @_mask: shifted mask defining the field's length and position ++ * @_reg: 32bit value of entire bitfield ++ * ++ * FIELD_GET() extracts the field specified by @_mask from the ++ * bitfield passed in as @_reg by masking and shifting it down. ++ */ ++#define FIELD_GET(_mask, _reg) \ ++ ({ \ ++ __BF_FIELD_CHECK(_mask, _reg, 0U, "FIELD_GET: "); \ ++ (typeof(_mask))(((_reg) & (_mask)) >> __bf_shf(_mask)); \ ++ }) ++ ++#endif +diff --git a/include/linux/bug.h b/include/linux/bug.h +index 7f4818673c41..edd3d8d3cd90 100644 +--- a/include/linux/bug.h ++++ b/include/linux/bug.h +@@ -13,6 +13,7 @@ enum bug_trap_type { + struct pt_regs; + + #ifdef __CHECKER__ ++#define __BUILD_BUG_ON_NOT_POWER_OF_2(n) (0) + #define BUILD_BUG_ON_NOT_POWER_OF_2(n) (0) + #define BUILD_BUG_ON_ZERO(e) (0) + #define BUILD_BUG_ON_NULL(e) ((void*)0) +@@ -23,6 +24,8 @@ struct pt_regs; + #else /* __CHECKER__ */ + + /* Force a compilation error if a constant expression is not a power of 2 */ ++#define __BUILD_BUG_ON_NOT_POWER_OF_2(n) \ ++ BUILD_BUG_ON(((n) & ((n) - 1)) != 0) + #define BUILD_BUG_ON_NOT_POWER_OF_2(n) \ + BUILD_BUG_ON((n) == 0 || (((n) & ((n) - 1)) != 0)) + + +From 3841d053b087e87d8d3d77738452c3b14d724049 Mon Sep 17 00:00:00 2001 +From: Jakub Kicinski +Date: Thu, 9 Feb 2017 09:17:27 -0800 +Subject: [PATCH] UPSTREAM: bitfield.h: add FIELD_FIT() helper + +Add a helper for checking at runtime that a value will fit inside +a specified field/mask. + +Signed-off-by: Jakub Kicinski +Signed-off-by: David S. Miller +(cherry picked from commit 1697599ee301a52cded6499a09bd609f7f63fd06) +--- + include/linux/bitfield.h | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/include/linux/bitfield.h b/include/linux/bitfield.h +index f6505d83069d..8b9d6fff002d 100644 +--- a/include/linux/bitfield.h ++++ b/include/linux/bitfield.h +@@ -62,6 +62,19 @@ + (1ULL << __bf_shf(_mask))); \ + }) + ++/** ++ * FIELD_FIT() - check if value fits in the field ++ * @_mask: shifted mask defining the field's length and position ++ * @_val: value to test against the field ++ * ++ * Return: true if @_val can fit inside @_mask, false if @_val is too big. ++ */ ++#define FIELD_FIT(_mask, _val) \ ++ ({ \ ++ __BF_FIELD_CHECK(_mask, 0ULL, _val, "FIELD_FIT: "); \ ++ !((((typeof(_mask))_val) << __bf_shf(_mask)) & ~(_mask)); \ ++ }) ++ + /** + * FIELD_PREP() - prepare a bitfield element + * @_mask: shifted mask defining the field's length and position + +From b0dcc7c8cc60ef7877baf3639a46344d8b184fc7 Mon Sep 17 00:00:00 2001 +From: Laurent Defert +Date: Wed, 11 Oct 2017 08:46:52 +0200 +Subject: [PATCH] FROMLIST: compat_ioctl: add compat handler for + FE_SET_PROPERTY and FE_GET_PROPERTY + +https://patchwork.linuxtv.org/patch/8209/ +--- + fs/compat_ioctl.c | 138 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 138 insertions(+) + +diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c +index a52ca5cba015..438ce0c6851e 100644 +--- a/fs/compat_ioctl.c ++++ b/fs/compat_ioctl.c +@@ -223,6 +223,140 @@ static int do_video_set_spu_palette(unsigned int fd, unsigned int cmd, + return err; + } + ++struct compat_dtv_property { ++ __u32 cmd; ++ __u32 reserved[3]; ++ union { ++ __u32 data; ++ struct { ++ __u8 data[32]; ++ __u32 len; ++ __u32 reserved1[3]; ++ compat_uptr_t reserved2; ++ } buffer; ++ } u; ++ int result; ++}; ++ ++struct compat_dtv_properties { ++ __u32 num; ++ compat_uptr_t props; ++}; ++ ++#define FE_SET_PROPERTY32 _IOW('o', 82, struct compat_dtv_properties) ++#define FE_GET_PROPERTY32 _IOR('o', 83, struct compat_dtv_properties) ++ ++static int do_fe_set_property(unsigned int fd, unsigned int cmd, ++ struct compat_dtv_properties __user *dtv32) ++{ ++ struct dtv_properties __user *dtv; ++ struct dtv_property __user *properties; ++ struct compat_dtv_property __user *properties32; ++ compat_uptr_t data; ++ ++ int err; ++ int i; ++ __u32 num; ++ ++ err = get_user(num, &dtv32->num); ++ err |= get_user(data, &dtv32->props); ++ ++ if(err) ++ return -EFAULT; ++ ++ dtv = compat_alloc_user_space(sizeof(struct dtv_properties) + ++ sizeof(struct dtv_property) * num); ++ properties = (struct dtv_property*)((char*)dtv + ++ sizeof(struct dtv_properties)); ++ ++ err = put_user(properties, &dtv->props); ++ err |= put_user(num, &dtv->num); ++ ++ properties32 = compat_ptr(data); ++ ++ if(err) ++ return -EFAULT; ++ ++ for(i = 0; i < num; i++) { ++ compat_uptr_t reserved2; ++ ++ err |= copy_in_user(&properties[i], &properties32[i], ++ (8 * sizeof(__u32)) + (32 * sizeof(__u8))); ++ err |= get_user(reserved2, &properties32[i].u.buffer.reserved2); ++ err |= put_user(compat_ptr(reserved2), ++ &properties[i].u.buffer.reserved2); ++ } ++ ++ if(err) ++ return -EFAULT; ++ ++ err = sys_ioctl(fd, FE_SET_PROPERTY, (unsigned long) dtv); ++ ++ for(i = 0; i < num; i++) { ++ if(copy_in_user(&properties32[i].result, &properties[i].result, ++ sizeof(int))) ++ return -EFAULT; ++ } ++ ++ return err; ++} ++ ++static int do_fe_get_property(unsigned int fd, unsigned int cmd, ++ struct compat_dtv_properties __user *dtv32) ++{ ++ struct dtv_properties __user *dtv; ++ struct dtv_property __user *properties; ++ struct compat_dtv_property __user *properties32; ++ compat_uptr_t data; ++ ++ int err; ++ int i; ++ __u32 num; ++ ++ err = get_user(num, &dtv32->num); ++ err |= get_user(data, &dtv32->props); ++ ++ if(err) ++ return -EFAULT; ++ ++ dtv = compat_alloc_user_space(sizeof(struct dtv_properties) + ++ sizeof(struct dtv_property) * num); ++ properties = (struct dtv_property*)((char*)dtv + ++ sizeof(struct dtv_properties)); ++ ++ err = put_user(properties, &dtv->props); ++ err |= put_user(num, &dtv->num); ++ ++ properties32 = compat_ptr(data); ++ ++ if(err) ++ return -EFAULT; ++ ++ for(i = 0; i < num; i++) { ++ compat_uptr_t reserved2; ++ ++ err |= copy_in_user(&properties[i], &properties32[i], ++ (8 * sizeof(__u32)) + (32 * sizeof(__u8))); ++ err |= get_user(reserved2, &properties32[i].u.buffer.reserved2); ++ err |= put_user(compat_ptr(reserved2), ++ &properties[i].u.buffer.reserved2); ++ } ++ ++ if(err) ++ return -EFAULT; ++ ++ err = sys_ioctl(fd, FE_GET_PROPERTY, (unsigned long) dtv); ++ ++ for(i = 0; i < num; i++) { ++ ++ if(copy_in_user(&properties32[i], &properties[i], ++ sizeof(properties32[i]))) ++ return -EFAULT; ++ } ++ ++ return err; ++} ++ + #ifdef CONFIG_BLOCK + typedef struct sg_io_hdr32 { + compat_int_t interface_id; /* [i] 'S' for SCSI generic (required) */ +@@ -1483,6 +1617,10 @@ static long do_ioctl_trans(int fd, unsigned int cmd, + return do_video_stillpicture(fd, cmd, argp); + case VIDEO_SET_SPU_PALETTE: + return do_video_set_spu_palette(fd, cmd, argp); ++ case FE_SET_PROPERTY32: ++ return do_fe_set_property(fd, cmd, argp); ++ case FE_GET_PROPERTY32: ++ return do_fe_get_property(fd, cmd, argp); + } + + /* diff --git a/patch/kernel/rk322x-legacy/01-linux-0011-ir-rename-macros.patch b/patch/kernel/rk322x-legacy/01-linux-0011-ir-rename-macros.patch new file mode 100644 index 0000000000..12909ad7ac --- /dev/null +++ b/patch/kernel/rk322x-legacy/01-linux-0011-ir-rename-macros.patch @@ -0,0 +1,1738 @@ +diff --git a/drivers/media/cec/cec-adap.c b/drivers/media/cec/cec-adap.c +index 4f5d382..1d2e98a 100644 +--- a/drivers/media/cec/cec-adap.c ++++ b/drivers/media/cec/cec-adap.c +@@ -1933,7 +1933,7 @@ static int cec_receive_notify(struct cec_adapter *adap, struct cec_msg *msg, + } + + /* Send key press */ +- rc_keydown(adap->rc, RC_TYPE_CEC, scancode, 0); ++ rc_keydown(adap->rc, RC_PROTO_CEC, scancode, 0); + + /* When in repeating mode, we're done */ + if (adap->rc_repeating) +diff --git a/drivers/media/cec/cec-core.c b/drivers/media/cec/cec-core.c +index 6a562d9..f4ea68f 100644 +--- a/drivers/media/cec/cec-core.c ++++ b/drivers/media/cec/cec-core.c +@@ -263,7 +263,7 @@ struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops, + return adap; + + /* Prepare the RC input device */ +- adap->rc = rc_allocate_device(); ++ adap->rc = rc_allocate_device(RC_DRIVER_SCANCODE); + if (!adap->rc) { + pr_err("cec-%s: failed to allocate memory for rc_dev\n", + name); +@@ -283,9 +283,8 @@ struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops, + adap->rc->input_id.vendor = 0; + adap->rc->input_id.product = 0; + adap->rc->input_id.version = 1; +- adap->rc->driver_type = RC_DRIVER_SCANCODE; + adap->rc->driver_name = CEC_NAME; +- adap->rc->allowed_protocols = RC_BIT_CEC; ++ adap->rc->allowed_protocols = RC_PROTO_BIT_CEC; + adap->rc->priv = adap; + adap->rc->map_name = RC_MAP_CEC; + adap->rc->timeout = MS_TO_NS(550); +diff --git a/drivers/media/pci/cx23885/cx23885-input.c b/drivers/media/pci/cx23885/cx23885-input.c +index c185903..bed2170 100644 +--- a/drivers/media/pci/cx23885/cx23885-input.c ++++ b/drivers/media/pci/cx23885/cx23885-input.c +@@ -285,37 +285,32 @@ int cx23885_input_init(struct cx23885_dev *dev) + case CX23885_BOARD_HAUPPAUGE_HVR1290: + case CX23885_BOARD_HAUPPAUGE_HVR1250: + /* Integrated CX2388[58] IR controller */ +- driver_type = RC_DRIVER_IR_RAW; +- allowed_protos = RC_BIT_ALL_IR_DECODER; ++ allowed_protos = RC_PROTO_BIT_ALL_IR_DECODER; + /* The grey Hauppauge RC-5 remote */ + rc_map = RC_MAP_HAUPPAUGE; + break; + case CX23885_BOARD_TERRATEC_CINERGY_T_PCIE_DUAL: + /* Integrated CX23885 IR controller */ +- driver_type = RC_DRIVER_IR_RAW; +- allowed_protos = RC_BIT_ALL_IR_DECODER; ++ allowed_protos = RC_PROTO_BIT_ALL_IR_DECODER; + /* The grey Terratec remote with orange buttons */ + rc_map = RC_MAP_NEC_TERRATEC_CINERGY_XS; + break; + case CX23885_BOARD_TEVII_S470: + /* Integrated CX23885 IR controller */ +- driver_type = RC_DRIVER_IR_RAW; +- allowed_protos = RC_BIT_ALL_IR_DECODER; ++ allowed_protos = RC_PROTO_BIT_ALL_IR_DECODER; + /* A guess at the remote */ + rc_map = RC_MAP_TEVII_NEC; + break; + case CX23885_BOARD_MYGICA_X8507: + /* Integrated CX23885 IR controller */ +- driver_type = RC_DRIVER_IR_RAW; +- allowed_protos = RC_BIT_ALL_IR_DECODER; ++ allowed_protos = RC_PROTO_BIT_ALL_IR_DECODER; + /* A guess at the remote */ + rc_map = RC_MAP_TOTAL_MEDIA_IN_HAND_02; + break; + case CX23885_BOARD_TBS_6980: + case CX23885_BOARD_TBS_6981: + /* Integrated CX23885 IR controller */ +- driver_type = RC_DRIVER_IR_RAW; +- allowed_protos = RC_BIT_ALL_IR_DECODER; ++ allowed_protos = RC_PROTO_BIT_ALL_IR_DECODER; + /* A guess at the remote */ + rc_map = RC_MAP_TBS_NEC; + break; +@@ -326,14 +321,12 @@ int cx23885_input_init(struct cx23885_dev *dev) + case CX23885_BOARD_DVBSKY_S952: + case CX23885_BOARD_DVBSKY_T982: + /* Integrated CX23885 IR controller */ +- driver_type = RC_DRIVER_IR_RAW; +- allowed_protos = RC_BIT_ALL_IR_DECODER; ++ allowed_protos = RC_PROTO_BIT_ALL_IR_DECODER; + rc_map = RC_MAP_DVBSKY; + break; + case CX23885_BOARD_TT_CT2_4500_CI: + /* Integrated CX23885 IR controller */ +- driver_type = RC_DRIVER_IR_RAW; +- allowed_protos = RC_BIT_ALL_IR_DECODER; ++ allowed_protos = RC_PROTO_BIT_ALL_IR_DECODER; + rc_map = RC_MAP_TT_1500; + break; + default: +@@ -352,7 +345,7 @@ int cx23885_input_init(struct cx23885_dev *dev) + pci_name(dev->pci)); + + /* input device */ +- rc = rc_allocate_device(); ++ rc = rc_allocate_device(RC_DRIVER_IR_RAW); + if (!rc) { + ret = -ENOMEM; + goto err_out_free; +@@ -371,7 +364,6 @@ int cx23885_input_init(struct cx23885_dev *dev) + rc->input_id.product = dev->pci->device; + } + rc->dev.parent = &dev->pci->dev; +- rc->driver_type = driver_type; + rc->allowed_protocols = allowed_protos; + rc->priv = kernel_ir; + rc->open = cx23885_input_ir_open; +diff --git a/drivers/media/pci/cx88/cx88-input.c b/drivers/media/pci/cx88/cx88-input.c +index 540eaa3..13c6b21 100644 +--- a/drivers/media/pci/cx88/cx88-input.c ++++ b/drivers/media/pci/cx88/cx88-input.c +@@ -130,7 +130,7 @@ static void cx88_ir_handle_key(struct cx88_IR *ir) + + data = (data << 4) | ((gpio_key & 0xf0) >> 4); + +- rc_keydown(ir->dev, RC_TYPE_UNKNOWN, data, 0); ++ rc_keydown(ir->dev, RC_PROTO_UNKNOWN, data, 0); + + } else if (ir->core->boardnr == CX88_BOARD_PROLINK_PLAYTVPVR || + ir->core->boardnr == CX88_BOARD_PIXELVIEW_PLAYTV_ULTRA_PRO) { +@@ -144,7 +144,7 @@ static void cx88_ir_handle_key(struct cx88_IR *ir) + scancode = RC_SCANCODE_NECX(addr, cmd); + + if (0 == (gpio & ir->mask_keyup)) +- rc_keydown_notimeout(ir->dev, RC_TYPE_NECX, scancode, ++ rc_keydown_notimeout(ir->dev, RC_PROTO_NECX, scancode, + 0); + else + rc_keyup(ir->dev); +@@ -152,20 +152,20 @@ static void cx88_ir_handle_key(struct cx88_IR *ir) + } else if (ir->mask_keydown) { + /* bit set on keydown */ + if (gpio & ir->mask_keydown) +- rc_keydown_notimeout(ir->dev, RC_TYPE_UNKNOWN, data, 0); ++ rc_keydown_notimeout(ir->dev, RC_PROTO_UNKNOWN, data, 0); + else + rc_keyup(ir->dev); + + } else if (ir->mask_keyup) { + /* bit cleared on keydown */ + if (0 == (gpio & ir->mask_keyup)) +- rc_keydown_notimeout(ir->dev, RC_TYPE_UNKNOWN, data, 0); ++ rc_keydown_notimeout(ir->dev, RC_PROTO_UNKNOWN, data, 0); + else + rc_keyup(ir->dev); + + } else { + /* can't distinguish keydown/up :-/ */ +- rc_keydown_notimeout(ir->dev, RC_TYPE_UNKNOWN, data, 0); ++ rc_keydown_notimeout(ir->dev, RC_PROTO_UNKNOWN, data, 0); + rc_keyup(ir->dev); + } + } +@@ -265,7 +265,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) + struct cx88_IR *ir; + struct rc_dev *dev; + char *ir_codes = NULL; +- u64 rc_type = RC_BIT_OTHER; ++ u64 rc_proto = RC_PROTO_BIT_OTHER; + int err = -ENOMEM; + u32 hardware_mask = 0; /* For devices with a hardware mask, when + * used with a full-code IR table +@@ -346,7 +346,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) + * 002-T mini RC, provided with newer PV hardware + */ + ir_codes = RC_MAP_PIXELVIEW_MK12; +- rc_type = RC_BIT_NECX; ++ rc_proto = RC_PROTO_BIT_NECX; + ir->gpio_addr = MO_GP1_IO; + ir->mask_keyup = 0x80; + ir->polling = 10; /* ms */ +@@ -485,7 +485,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) + dev->timeout = 10 * 1000 * 1000; /* 10 ms */ + } else { + dev->driver_type = RC_DRIVER_SCANCODE; +- dev->allowed_protocols = rc_type; ++ dev->allowed_protocols = rc_proto; + } + + ir->core = core; +@@ -544,7 +544,6 @@ void cx88_ir_irq(struct cx88_core *core) + if (samples == 0xff && ir->dev->idle) + return; + +- init_ir_raw_event(&ev); + for (todo = 32; todo > 0; todo -= bits) { + ev.pulse = samples & 0x80000000 ? false : true; + bits = min(todo, 32U - fls(ev.pulse ? samples : ~samples)); +@@ -555,7 +554,7 @@ void cx88_ir_irq(struct cx88_core *core) + ir_raw_event_handle(ir->dev); + } + +-static int get_key_pvr2000(struct IR_i2c *ir, enum rc_type *protocol, ++static int get_key_pvr2000(struct IR_i2c *ir, enum rc_proto *protocol, + u32 *scancode, u8 *toggle) + { + int flags, code; +@@ -580,7 +579,7 @@ static int get_key_pvr2000(struct IR_i2c *ir, enum rc_type *protocol, + dprintk("IR Key/Flags: (0x%02x/0x%02x)\n", + code & 0xff, flags & 0xff); + +- *protocol = RC_TYPE_UNKNOWN; ++ *protocol = RC_PROTO_UNKNOWN; + *scancode = code & 0xff; + *toggle = 0; + return 1; +@@ -610,7 +609,7 @@ void cx88_i2c_init_ir(struct cx88_core *core) + case CX88_BOARD_LEADTEK_PVR2000: + addr_list = pvr2000_addr_list; + core->init_data.name = "cx88 Leadtek PVR 2000 remote"; +- core->init_data.type = RC_BIT_UNKNOWN; ++ core->init_data.type = RC_PROTO_BIT_UNKNOWN; + core->init_data.get_key = get_key_pvr2000; + core->init_data.ir_codes = RC_MAP_EMPTY; + break; +@@ -631,8 +630,8 @@ void cx88_i2c_init_ir(struct cx88_core *core) + /* Hauppauge XVR */ + core->init_data.name = "cx88 Hauppauge XVR remote"; + core->init_data.ir_codes = RC_MAP_HAUPPAUGE; +- core->init_data.type = RC_BIT_RC5 | RC_BIT_RC6_MCE | +- RC_BIT_RC6_6A_32; ++ core->init_data.type = RC_PROTO_BIT_RC5 | RC_PROTO_BIT_RC6_MCE | ++ RC_PROTO_BIT_RC6_6A_32; + core->init_data.internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR; + + info.platform_data = &core->init_data; +diff --git a/drivers/media/pci/saa7134/saa7134-input.c b/drivers/media/pci/saa7134/saa7134-input.c +index 3e43d8f..3691d18 100644 +--- a/drivers/media/pci/saa7134/saa7134-input.c ++++ b/drivers/media/pci/saa7134/saa7134-input.c +@@ -87,14 +87,14 @@ static int build_key(struct saa7134_dev *dev) + if (data == ir->mask_keycode) + rc_keyup(ir->dev); + else +- rc_keydown_notimeout(ir->dev, RC_TYPE_UNKNOWN, data, 0); ++ rc_keydown_notimeout(ir->dev, RC_PROTO_UNKNOWN, data, 0); + return 0; + } + + if (ir->polling) { + if ((ir->mask_keydown && (0 != (gpio & ir->mask_keydown))) || + (ir->mask_keyup && (0 == (gpio & ir->mask_keyup)))) { +- rc_keydown_notimeout(ir->dev, RC_TYPE_UNKNOWN, data, 0); ++ rc_keydown_notimeout(ir->dev, RC_PROTO_UNKNOWN, data, 0); + } else { + rc_keyup(ir->dev); + } +@@ -102,7 +102,7 @@ static int build_key(struct saa7134_dev *dev) + else { /* IRQ driven mode - handle key press and release in one go */ + if ((ir->mask_keydown && (0 != (gpio & ir->mask_keydown))) || + (ir->mask_keyup && (0 == (gpio & ir->mask_keyup)))) { +- rc_keydown_notimeout(ir->dev, RC_TYPE_UNKNOWN, data, 0); ++ rc_keydown_notimeout(ir->dev, RC_PROTO_UNKNOWN, data, 0); + rc_keyup(ir->dev); + } + } +@@ -112,7 +112,7 @@ static int build_key(struct saa7134_dev *dev) + + /* --------------------- Chip specific I2C key builders ----------------- */ + +-static int get_key_flydvb_trio(struct IR_i2c *ir, enum rc_type *protocol, ++static int get_key_flydvb_trio(struct IR_i2c *ir, enum rc_proto *protocol, + u32 *scancode, u8 *toggle) + { + int gpio; +@@ -159,13 +159,13 @@ static int get_key_flydvb_trio(struct IR_i2c *ir, enum rc_type *protocol, + return -EIO; + } + +- *protocol = RC_TYPE_UNKNOWN; ++ *protocol = RC_PROTO_UNKNOWN; + *scancode = b; + *toggle = 0; + return 1; + } + +-static int get_key_msi_tvanywhere_plus(struct IR_i2c *ir, enum rc_type *protocol, ++static int get_key_msi_tvanywhere_plus(struct IR_i2c *ir, enum rc_proto *protocol, + u32 *scancode, u8 *toggle) + { + unsigned char b; +@@ -207,14 +207,14 @@ static int get_key_msi_tvanywhere_plus(struct IR_i2c *ir, enum rc_type *protocol + /* Button pressed */ + + input_dbg("get_key_msi_tvanywhere_plus: Key = 0x%02X\n", b); +- *protocol = RC_TYPE_UNKNOWN; ++ *protocol = RC_PROTO_UNKNOWN; + *scancode = b; + *toggle = 0; + return 1; + } + + /* copied and modified from get_key_msi_tvanywhere_plus() */ +-static int get_key_kworld_pc150u(struct IR_i2c *ir, enum rc_type *protocol, ++static int get_key_kworld_pc150u(struct IR_i2c *ir, enum rc_proto *protocol, + u32 *scancode, u8 *toggle) + { + unsigned char b; +@@ -256,13 +256,13 @@ static int get_key_kworld_pc150u(struct IR_i2c *ir, enum rc_type *protocol, + /* Button pressed */ + + input_dbg("get_key_kworld_pc150u: Key = 0x%02X\n", b); +- *protocol = RC_TYPE_UNKNOWN; ++ *protocol = RC_PROTO_UNKNOWN; + *scancode = b; + *toggle = 0; + return 1; + } + +-static int get_key_purpletv(struct IR_i2c *ir, enum rc_type *protocol, ++static int get_key_purpletv(struct IR_i2c *ir, enum rc_proto *protocol, + u32 *scancode, u8 *toggle) + { + unsigned char b; +@@ -281,13 +281,13 @@ static int get_key_purpletv(struct IR_i2c *ir, enum rc_type *protocol, + if (b & 0x80) + return 1; + +- *protocol = RC_TYPE_UNKNOWN; ++ *protocol = RC_PROTO_UNKNOWN; + *scancode = b; + *toggle = 0; + return 1; + } + +-static int get_key_hvr1110(struct IR_i2c *ir, enum rc_type *protocol, ++static int get_key_hvr1110(struct IR_i2c *ir, enum rc_proto *protocol, + u32 *scancode, u8 *toggle) + { + unsigned char buf[5]; +@@ -311,14 +311,14 @@ static int get_key_hvr1110(struct IR_i2c *ir, enum rc_type *protocol, + * + * FIXME: start bits could maybe be used...? + */ +- *protocol = RC_TYPE_RC5; ++ *protocol = RC_PROTO_RC5; + *scancode = RC_SCANCODE_RC5(buf[3] & 0x1f, buf[4] >> 2); + *toggle = !!(buf[3] & 0x40); + return 1; + } + + +-static int get_key_beholdm6xx(struct IR_i2c *ir, enum rc_type *protocol, ++static int get_key_beholdm6xx(struct IR_i2c *ir, enum rc_proto *protocol, + u32 *scancode, u8 *toggle) + { + unsigned char data[12]; +@@ -345,7 +345,7 @@ static int get_key_beholdm6xx(struct IR_i2c *ir, enum rc_type *protocol, + if (data[9] != (unsigned char)(~data[8])) + return 0; + +- *protocol = RC_TYPE_NECX; ++ *protocol = RC_PROTO_NECX; + *scancode = RC_SCANCODE_NECX(data[11] << 8 | data[10], data[9]); + *toggle = 0; + return 1; +@@ -354,7 +354,7 @@ static int get_key_beholdm6xx(struct IR_i2c *ir, enum rc_type *protocol, + /* Common (grey or coloured) pinnacle PCTV remote handling + * + */ +-static int get_key_pinnacle(struct IR_i2c *ir, enum rc_type *protocol, ++static int get_key_pinnacle(struct IR_i2c *ir, enum rc_proto *protocol, + u32 *scancode, u8 *toggle, int parity_offset, + int marker, int code_modulo) + { +@@ -391,7 +391,7 @@ static int get_key_pinnacle(struct IR_i2c *ir, enum rc_type *protocol, + + code %= code_modulo; + +- *protocol = RC_TYPE_UNKNOWN; ++ *protocol = RC_PROTO_UNKNOWN; + *scancode = code; + *toggle = 0; + +@@ -408,7 +408,7 @@ static int get_key_pinnacle(struct IR_i2c *ir, enum rc_type *protocol, + * + * Sylvain Pasche + */ +-static int get_key_pinnacle_grey(struct IR_i2c *ir, enum rc_type *protocol, ++static int get_key_pinnacle_grey(struct IR_i2c *ir, enum rc_proto *protocol, + u32 *scancode, u8 *toggle) + { + +@@ -420,7 +420,7 @@ static int get_key_pinnacle_grey(struct IR_i2c *ir, enum rc_type *protocol, + * + * Ricardo Cerqueira + */ +-static int get_key_pinnacle_color(struct IR_i2c *ir, enum rc_type *protocol, ++static int get_key_pinnacle_color(struct IR_i2c *ir, enum rc_proto *protocol, + u32 *scancode, u8 *toggle) + { + /* code_modulo parameter (0x88) is used to reduce code value to fit inside IR_KEYTAB_SIZE +@@ -1006,7 +1006,7 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev) + dev->init_data.name = "BeholdTV"; + dev->init_data.get_key = get_key_beholdm6xx; + dev->init_data.ir_codes = RC_MAP_BEHOLD; +- dev->init_data.type = RC_BIT_NECX; ++ dev->init_data.type = RC_PROTO_BIT_NECX; + info.addr = 0x2d; + break; + case SAA7134_BOARD_AVERMEDIA_CARDBUS_501: +diff --git a/drivers/media/pci/smipcie/smipcie-ir.c b/drivers/media/pci/smipcie/smipcie-ir.c +index a5d4bc7..363d1bc 100644 +--- a/drivers/media/pci/smipcie/smipcie-ir.c ++++ b/drivers/media/pci/smipcie/smipcie-ir.c +@@ -183,7 +183,7 @@ int smi_ir_init(struct smi_dev *dev) + struct rc_dev *rc_dev; + struct smi_rc *ir = &dev->ir; + +- rc_dev = rc_allocate_device(); ++ rc_dev = rc_allocate_device(RC_DRIVER_SCANCODE); + if (!rc_dev) + return -ENOMEM; + +@@ -202,7 +202,6 @@ int smi_ir_init(struct smi_dev *dev) + rc_dev->input_id.product = dev->pci_dev->subsystem_device; + rc_dev->dev.parent = &dev->pci_dev->dev; + +- rc_dev->driver_type = RC_DRIVER_SCANCODE; + rc_dev->map_name = RC_MAP_DVBSKY; + + ir->rc_dev = rc_dev; +diff --git a/drivers/media/platform/s5p-mfc/regs-mfc-v6.h b/drivers/media/platform/s5p-mfc/regs-mfc-v6.h +index 83e01f3..5b2cbf8 100644 +--- a/drivers/media/platform/s5p-mfc/regs-mfc-v6.h ++++ b/drivers/media/platform/s5p-mfc/regs-mfc-v6.h +@@ -259,7 +259,7 @@ + #define S5P_FIMV_E_FRAME_INSERTION_V6 0xfa1c + + #define S5P_FIMV_E_RC_FRAME_RATE_V6 0xfa20 +-#define S5P_FIMV_E_RC_BIT_RATE_V6 0xfa24 ++#define S5P_FIMV_E_RC_PROTO_BIT_RATE_V6 0xfa24 + #define S5P_FIMV_E_RC_QP_OFFSET_V6 0xfa28 + #define S5P_FIMV_E_RC_ROI_CTRL_V6 0xfa2c + #define S5P_FIMV_E_PICTURE_TAG_V6 0xfa30 +@@ -328,7 +328,7 @@ + + #define S5P_FIMV_E_MVC_FRAME_QP_VIEW1_V6 0xfd40 + #define S5P_FIMV_E_MVC_RC_FRAME_RATE_VIEW1_V6 0xfd44 +-#define S5P_FIMV_E_MVC_RC_BIT_RATE_VIEW1_V6 0xfd48 ++#define S5P_FIMV_E_MVC_RC_PROTO_BIT_RATE_VIEW1_V6 0xfd48 + #define S5P_FIMV_E_MVC_RC_QBOUND_VIEW1_V6 0xfd4c + #define S5P_FIMV_E_MVC_RC_RPARA_VIEW1_V6 0xfd50 + #define S5P_FIMV_E_MVC_INTER_VIEW_PREDICTION_ON_V6 0xfd80 +diff --git a/drivers/media/platform/s5p-mfc/regs-mfc.h b/drivers/media/platform/s5p-mfc/regs-mfc.h +index 6ccc3f8..54eea05 100644 +--- a/drivers/media/platform/s5p-mfc/regs-mfc.h ++++ b/drivers/media/platform/s5p-mfc/regs-mfc.h +@@ -299,7 +299,7 @@ + #define S5P_FIMV_ENC_PADDING_CTRL 0xc520 /* padding control */ + + #define S5P_FIMV_ENC_RC_CONFIG 0xc5a0 /* RC config */ +-#define S5P_FIMV_ENC_RC_BIT_RATE 0xc5a8 /* bit rate */ ++#define S5P_FIMV_ENC_RC_PROTO_BIT_RATE 0xc5a8 /* bit rate */ + #define S5P_FIMV_ENC_RC_QBOUND 0xc5ac /* max/min QP */ + #define S5P_FIMV_ENC_RC_RPARA 0xc5b0 /* rate control reaction coeff */ + #define S5P_FIMV_ENC_RC_MB_CTRL 0xc5b4 /* MB adaptive scaling */ +diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c +index 873c933..7b322a6 100644 +--- a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c ++++ b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c +@@ -740,9 +740,9 @@ static int s5p_mfc_set_enc_params(struct s5p_mfc_ctx *ctx) + /* bit rate */ + if (p->rc_frame) + mfc_write(dev, p->rc_bitrate, +- S5P_FIMV_ENC_RC_BIT_RATE); ++ S5P_FIMV_ENC_RC_PROTO_BIT_RATE); + else +- mfc_write(dev, 0, S5P_FIMV_ENC_RC_BIT_RATE); ++ mfc_write(dev, 0, S5P_FIMV_ENC_RC_PROTO_BIT_RATE); + /* reaction coefficient */ + if (p->rc_frame) + mfc_write(dev, p->rc_reaction_coeff, S5P_FIMV_ENC_RC_RPARA); +diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.h b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.h +index ffee39a..0b8cd93 100644 +--- a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.h ++++ b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.h +@@ -53,8 +53,8 @@ enum MFC_SHM_OFS { + FLUSH_CMD_INBUF1 = 0x84, /* C */ + FLUSH_CMD_INBUF2 = 0x88, /* C */ + FLUSH_CMD_OUTBUF = 0x8C, /* E */ +- NEW_RC_BIT_RATE = 0x90, /* E, format as RC_BIT_RATE(0xC5A8) +- depend on RC_BIT_RATE_CHANGE in ENC_PARAM_CHANGE */ ++ NEW_RC_PROTO_BIT_RATE = 0x90, /* E, format as RC_PROTO_BIT_RATE(0xC5A8) ++ depend on RC_PROTO_BIT_RATE_CHANGE in ENC_PARAM_CHANGE */ + NEW_RC_FRAME_RATE = 0x94, /* E, format as RC_FRAME_RATE(0xD0D0) + depend on RC_FRAME_RATE_CHANGE in ENC_PARAM_CHANGE */ + NEW_I_PERIOD = 0x98, /* E, format as I_FRM_CTRL(0xC504) +diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c +index b958453..a826251 100644 +--- a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c ++++ b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c +@@ -2143,7 +2143,7 @@ const struct s5p_mfc_regs *s5p_mfc_init_regs_v6_plus(struct s5p_mfc_dev *dev) + R(e_mslice_size_bits, S5P_FIMV_E_MSLICE_SIZE_BITS_V6); + R(e_frame_insertion, S5P_FIMV_E_FRAME_INSERTION_V6); + R(e_rc_frame_rate, S5P_FIMV_E_RC_FRAME_RATE_V6); +- R(e_rc_bit_rate, S5P_FIMV_E_RC_BIT_RATE_V6); ++ R(e_rc_bit_rate, S5P_FIMV_E_RC_PROTO_BIT_RATE_V6); + R(e_rc_roi_ctrl, S5P_FIMV_E_RC_ROI_CTRL_V6); + R(e_picture_tag, S5P_FIMV_E_PICTURE_TAG_V6); + R(e_bit_count_enable, S5P_FIMV_E_BIT_COUNT_ENABLE_V6); +diff --git a/drivers/media/rc/igorplugusb.c b/drivers/media/rc/igorplugusb.c +index 8118769..2052b4e 100644 +--- a/drivers/media/rc/igorplugusb.c ++++ b/drivers/media/rc/igorplugusb.c +@@ -190,12 +190,11 @@ static int igorplugusb_probe(struct usb_interface *intf, + + usb_make_path(udev, ir->phys, sizeof(ir->phys)); + +- rc = rc_allocate_device(); +- rc->input_name = DRIVER_DESC; ++ rc = rc_allocate_device(RC_DRIVER_IR_RAW); ++ rc->device_name = DRIVER_DESC; + rc->input_phys = ir->phys; + usb_to_input_id(udev, &rc->input_id); + rc->dev.parent = &intf->dev; +- rc->driver_type = RC_DRIVER_IR_RAW; + /* + * This device can only store 36 pulses + spaces, which is not enough + * for the NEC protocol and many others. +diff --git a/drivers/media/rc/img-ir/img-ir-hw.c b/drivers/media/rc/img-ir/img-ir-hw.c +index 3e5c50b..ab6881b 100644 +--- a/drivers/media/rc/img-ir/img-ir-hw.c ++++ b/drivers/media/rc/img-ir/img-ir-hw.c +@@ -703,7 +703,7 @@ static void img_ir_set_protocol(struct img_ir_priv *priv, u64 proto) + struct rc_dev *rdev = priv->hw.rdev; + + spin_lock_irq(&rdev->rc_map.lock); +- rdev->rc_map.rc_type = __ffs64(proto); ++ rdev->rc_map.rc_proto = __ffs64(proto); + spin_unlock_irq(&rdev->rc_map.lock); + + mutex_lock(&rdev->lock); +diff --git a/drivers/media/rc/imon.c b/drivers/media/rc/imon.c +index b6dff86..126946b 100644 +--- a/drivers/media/rc/imon.c ++++ b/drivers/media/rc/imon.c +@@ -145,7 +145,7 @@ struct imon_context { + u32 last_keycode; /* last reported input keycode */ + u32 rc_scancode; /* the computed remote scancode */ + u8 rc_toggle; /* the computed remote toggle bit */ +- u64 rc_type; /* iMON or MCE (RC6) IR protocol? */ ++ u64 rc_proto; /* iMON or MCE (RC6) IR protocol? */ + bool release_code; /* some keys send a release code */ + + u8 display_type; /* store the display type */ +@@ -1099,7 +1099,7 @@ static void imon_touch_display_timeout(unsigned long data) + * it is not, so we must acquire it prior to calling send_packet, which + * requires that the lock is held. + */ +-static int imon_ir_change_protocol(struct rc_dev *rc, u64 *rc_type) ++static int imon_ir_change_protocol(struct rc_dev *rc, u64 *rc_proto) + { + int retval; + struct imon_context *ictx = rc->priv; +@@ -1108,25 +1108,25 @@ static int imon_ir_change_protocol(struct rc_dev *rc, u64 *rc_type) + unsigned char ir_proto_packet[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86 }; + +- if (*rc_type && !(*rc_type & rc->allowed_protocols)) ++ if (*rc_proto && !(*rc_proto & rc->allowed_protocols)) + dev_warn(dev, "Looks like you're trying to use an IR protocol this device does not support\n"); + +- if (*rc_type & RC_BIT_RC6_MCE) { ++ if (*rc_proto & RC_PROTO_BIT_RC6_MCE) { + dev_dbg(dev, "Configuring IR receiver for MCE protocol\n"); + ir_proto_packet[0] = 0x01; +- *rc_type = RC_BIT_RC6_MCE; +- } else if (*rc_type & RC_BIT_OTHER) { ++ *rc_proto = RC_PROTO_BIT_RC6_MCE; ++ } else if (*rc_proto & RC_PROTO_BIT_OTHER) { + dev_dbg(dev, "Configuring IR receiver for iMON protocol\n"); + if (!pad_stabilize) + dev_dbg(dev, "PAD stabilize functionality disabled\n"); + /* ir_proto_packet[0] = 0x00; // already the default */ +- *rc_type = RC_BIT_OTHER; ++ *rc_proto = RC_PROTO_BIT_OTHER; + } else { + dev_warn(dev, "Unsupported IR protocol specified, overriding to iMON IR protocol\n"); + if (!pad_stabilize) + dev_dbg(dev, "PAD stabilize functionality disabled\n"); + /* ir_proto_packet[0] = 0x00; // already the default */ +- *rc_type = RC_BIT_OTHER; ++ *rc_proto = RC_PROTO_BIT_OTHER; + } + + memcpy(ictx->usb_tx_buf, &ir_proto_packet, sizeof(ir_proto_packet)); +@@ -1140,7 +1140,7 @@ static int imon_ir_change_protocol(struct rc_dev *rc, u64 *rc_type) + if (retval) + goto out; + +- ictx->rc_type = *rc_type; ++ ictx->rc_proto = *rc_proto; + ictx->pad_mouse = false; + + out: +@@ -1416,7 +1416,7 @@ static void imon_pad_to_keys(struct imon_context *ictx, unsigned char *buf) + rel_x = buf[2]; + rel_y = buf[3]; + +- if (ictx->rc_type == RC_BIT_OTHER && pad_stabilize) { ++ if (ictx->rc_proto == RC_PROTO_BIT_OTHER && pad_stabilize) { + if ((buf[1] == 0) && ((rel_x != 0) || (rel_y != 0))) { + dir = stabilize((int)rel_x, (int)rel_y, + timeout, threshold); +@@ -1483,7 +1483,7 @@ static void imon_pad_to_keys(struct imon_context *ictx, unsigned char *buf) + buf[0] = 0x01; + buf[1] = buf[4] = buf[5] = buf[6] = buf[7] = 0; + +- if (ictx->rc_type == RC_BIT_OTHER && pad_stabilize) { ++ if (ictx->rc_proto == RC_PROTO_BIT_OTHER && pad_stabilize) { + dir = stabilize((int)rel_x, (int)rel_y, + timeout, threshold); + if (!dir) { +@@ -1605,7 +1605,7 @@ static void imon_incoming_packet(struct imon_context *ictx, + ictx->release_code = false; + } else { + scancode = be32_to_cpu(*((__be32 *)buf)); +- if (ictx->rc_type == RC_BIT_RC6_MCE) { ++ if (ictx->rc_proto == RC_PROTO_BIT_RC6_MCE) { + ktype = IMON_KEY_IMON; + if (buf[0] == 0x80) + ktype = IMON_KEY_MCE; +@@ -1670,10 +1670,10 @@ static void imon_incoming_packet(struct imon_context *ictx, + if (press_type == 0) + rc_keyup(ictx->rdev); + else { +- if (ictx->rc_type == RC_BIT_RC6_MCE || +- ictx->rc_type == RC_BIT_OTHER) ++ if (ictx->rc_proto == RC_PROTO_BIT_RC6_MCE || ++ ictx->rc_proto == RC_PROTO_BIT_OTHER) + rc_keydown(ictx->rdev, +- ictx->rc_type == RC_BIT_RC6_MCE ? RC_TYPE_RC6_MCE : RC_TYPE_OTHER, ++ ictx->rc_proto == RC_PROTO_BIT_RC6_MCE ? RC_PROTO_RC6_MCE : RC_PROTO_OTHER, + ictx->rc_scancode, ictx->rc_toggle); + spin_lock_irqsave(&ictx->kc_lock, flags); + ictx->last_keycode = ictx->kc; +@@ -1831,7 +1831,7 @@ static void imon_get_ffdc_type(struct imon_context *ictx) + { + u8 ffdc_cfg_byte = ictx->usb_rx_buf[6]; + u8 detected_display_type = IMON_DISPLAY_TYPE_NONE; +- u64 allowed_protos = RC_BIT_OTHER; ++ u64 allowed_protos = RC_PROTO_BIT_OTHER; + + switch (ffdc_cfg_byte) { + /* iMON Knob, no display, iMON IR + vol knob */ +@@ -1862,27 +1862,27 @@ static void imon_get_ffdc_type(struct imon_context *ictx) + case 0x9e: + dev_info(ictx->dev, "0xffdc iMON VFD, MCE IR"); + detected_display_type = IMON_DISPLAY_TYPE_VFD; +- allowed_protos = RC_BIT_RC6_MCE; ++ allowed_protos = RC_PROTO_BIT_RC6_MCE; + break; + /* iMON LCD, MCE IR */ + case 0x9f: + dev_info(ictx->dev, "0xffdc iMON LCD, MCE IR"); + detected_display_type = IMON_DISPLAY_TYPE_LCD; +- allowed_protos = RC_BIT_RC6_MCE; ++ allowed_protos = RC_PROTO_BIT_RC6_MCE; + break; + default: + dev_info(ictx->dev, "Unknown 0xffdc device, defaulting to VFD and iMON IR"); + detected_display_type = IMON_DISPLAY_TYPE_VFD; + /* We don't know which one it is, allow user to set the + * RC6 one from userspace if OTHER wasn't correct. */ +- allowed_protos |= RC_BIT_RC6_MCE; ++ allowed_protos |= RC_PROTO_BIT_RC6_MCE; + break; + } + + printk(KERN_CONT " (id 0x%02x)\n", ffdc_cfg_byte); + + ictx->display_type = detected_display_type; +- ictx->rc_type = allowed_protos; ++ ictx->rc_proto = allowed_protos; + } + + static void imon_set_display_type(struct imon_context *ictx) +@@ -1960,7 +1960,7 @@ static struct rc_dev *imon_init_rdev(struct imon_context *ictx) + rdev->dev.parent = ictx->dev; + + rdev->priv = ictx; +- rdev->allowed_protocols = RC_BIT_OTHER | RC_BIT_RC6_MCE; /* iMON PAD or MCE */ ++ rdev->allowed_protocols = RC_PROTO_BIT_OTHER | RC_PROTO_BIT_RC6_MCE; /* iMON PAD or MCE */ + rdev->change_protocol = imon_ir_change_protocol; + rdev->driver_name = MOD_NAME; + +@@ -1973,12 +1973,12 @@ static struct rc_dev *imon_init_rdev(struct imon_context *ictx) + + if (ictx->product == 0xffdc) { + imon_get_ffdc_type(ictx); +- rdev->allowed_protocols = ictx->rc_type; ++ rdev->allowed_protocols = ictx->rc_proto; + } + + imon_set_display_type(ictx); + +- if (ictx->rc_type == RC_BIT_RC6_MCE) ++ if (ictx->rc_proto == RC_PROTO_BIT_RC6_MCE) + rdev->map_name = RC_MAP_IMON_MCE; + else + rdev->map_name = RC_MAP_IMON_PAD; +diff --git a/drivers/media/rc/keymaps/rc-cec.c b/drivers/media/rc/keymaps/rc-cec.c +index fb0c2b1..6556934 100644 +--- a/drivers/media/rc/keymaps/rc-cec.c ++++ b/drivers/media/rc/keymaps/rc-cec.c +@@ -160,7 +160,7 @@ static struct rc_map_list cec_map = { + .map = { + .scan = cec, + .size = ARRAY_SIZE(cec), +- .rc_type = RC_TYPE_CEC, ++ .rc_proto = RC_PROTO_CEC, + .name = RC_MAP_CEC, + } + }; +diff --git a/drivers/media/rc/keymaps/rc-khadas.c b/drivers/media/rc/keymaps/rc-khadas.c +index 492368d..ad51a8c 100644 +--- a/drivers/media/rc/keymaps/rc-khadas.c ++++ b/drivers/media/rc/keymaps/rc-khadas.c +@@ -30,7 +30,7 @@ static struct rc_map_list khadas_map = { + .map = { + .scan = khadas, + .size = ARRAY_SIZE(khadas), +- .rc_type = RC_TYPE_NEC, ++ .rc_proto = RC_PROTO_NEC, + .name = RC_MAP_KHADAS, + } + }; +diff --git a/drivers/media/rc/keymaps/rc-odroid.c b/drivers/media/rc/keymaps/rc-odroid.c +index 52089f0..70b99e5 100644 +--- a/drivers/media/rc/keymaps/rc-odroid.c ++++ b/drivers/media/rc/keymaps/rc-odroid.c +@@ -30,7 +30,7 @@ static struct rc_map_list odroid_map = { + .map = { + .scan = odroid, + .size = ARRAY_SIZE(odroid), +- .rc_type = RC_TYPE_NEC, ++ .rc_proto = RC_PROTO_NEC, + .name = RC_MAP_ODROID, + } + }; +diff --git a/drivers/media/rc/keymaps/rc-pine64.c b/drivers/media/rc/keymaps/rc-pine64.c +index bdf3975..d47038c 100644 +--- a/drivers/media/rc/keymaps/rc-pine64.c ++++ b/drivers/media/rc/keymaps/rc-pine64.c +@@ -43,7 +43,7 @@ static struct rc_map_list pine64_map = { + .map = { + .scan = pine64, + .size = ARRAY_SIZE(pine64), +- .rc_type = RC_TYPE_NEC, ++ .rc_proto = RC_PROTO_NEC, + .name = RC_MAP_PINE64, + } + }; +diff --git a/drivers/media/rc/keymaps/rc-roc-cc.c b/drivers/media/rc/keymaps/rc-roc-cc.c +index 3a2a255..c8a8205 100644 +--- a/drivers/media/rc/keymaps/rc-roc-cc.c ++++ b/drivers/media/rc/keymaps/rc-roc-cc.c +@@ -30,7 +30,7 @@ static struct rc_map_list roc_cc_map = { + .map = { + .scan = roc_cc, + .size = ARRAY_SIZE(roc_cc), +- .rc_type = RC_TYPE_NEC, ++ .rc_proto = RC_PROTO_NEC, + .name = RC_MAP_ROC_CC, + } + }; +diff --git a/drivers/media/rc/keymaps/rc-trn9.c b/drivers/media/rc/keymaps/rc-trn9.c +index f81bc3a..21f0983 100644 +--- a/drivers/media/rc/keymaps/rc-trn9.c ++++ b/drivers/media/rc/keymaps/rc-trn9.c +@@ -30,7 +30,7 @@ static struct rc_map_list trn9_map = { + .map = { + .scan = trn9, + .size = ARRAY_SIZE(trn9), +- .rc_type = RC_TYPE_NEC, ++ .rc_proto = RC_PROTO_NEC, + .name = RC_MAP_TRN9, + } + }; +diff --git a/drivers/media/rc/keymaps/rc-wetek-hub.c b/drivers/media/rc/keymaps/rc-wetek-hub.c +index 0955ecf..733a6be 100644 +--- a/drivers/media/rc/keymaps/rc-wetek-hub.c ++++ b/drivers/media/rc/keymaps/rc-wetek-hub.c +@@ -30,7 +30,7 @@ static struct rc_map_list wetek_hub_map = { + .map = { + .scan = wetek_hub, + .size = ARRAY_SIZE(wetek_hub), +- .rc_type = RC_TYPE_NEC, ++ .rc_proto = RC_PROTO_NEC, + .name = RC_MAP_WETEK_HUB, + } + }; +diff --git a/drivers/media/rc/keymaps/rc-wetek-play-2.c b/drivers/media/rc/keymaps/rc-wetek-play-2.c +index 37586ce..8f34ae0 100644 +--- a/drivers/media/rc/keymaps/rc-wetek-play-2.c ++++ b/drivers/media/rc/keymaps/rc-wetek-play-2.c +@@ -61,7 +61,7 @@ static struct rc_map_list wetek_play_2_map = { + .map = { + .scan = wetek_play_2, + .size = ARRAY_SIZE(wetek_play_2), +- .rc_type = RC_TYPE_NEC, ++ .rc_proto = RC_PROTO_NEC, + .name = RC_MAP_WETEK_PLAY_2, + } + }; +diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c +index 43811a4..52a532d 100644 +--- a/drivers/media/rc/mceusb.c ++++ b/drivers/media/rc/mceusb.c +@@ -979,7 +979,7 @@ static void mceusb_handle_command(struct mceusb_dev *ir, int index) + + static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len) + { +- DEFINE_IR_RAW_EVENT(rawir); ++ struct ir_raw_event rawir = {}; + bool event = false; + int i = 0; + +@@ -1002,7 +1002,6 @@ static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len) + break; + case PARSE_IRDATA: + ir->rem--; +- init_ir_raw_event(&rawir); + rawir.pulse = ((ir->buf_in[i] & MCE_PULSE_BIT) != 0); + rawir.duration = (ir->buf_in[i] & MCE_PULSE_MASK) + * US_TO_NS(MCE_TIME_UNIT); +diff --git a/drivers/media/rc/meson-ir.c b/drivers/media/rc/meson-ir.c +index bd7b0c4..c0fa0d7 100644 +--- a/drivers/media/rc/meson-ir.c ++++ b/drivers/media/rc/meson-ir.c +@@ -77,7 +77,7 @@ static irqreturn_t meson_ir_irq(int irqno, void *dev_id) + { + struct meson_ir *ir = dev_id; + u32 duration; +- DEFINE_IR_RAW_EVENT(rawir); ++ struct ir_raw_event rawir = {}; + + spin_lock(&ir->lock); + +@@ -134,7 +134,7 @@ static int meson_ir_probe(struct platform_device *pdev) + map_name = of_get_property(node, "linux,rc-map-name", NULL); + ir->rc->map_name = map_name ? map_name : RC_MAP_EMPTY; + ir->rc->dev.parent = dev; +- ir->rc->allowed_protocols = RC_BIT_ALL_IR_DECODER; ++ ir->rc->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER; + ir->rc->rx_resolution = US_TO_NS(MESON_TRATE); + ir->rc->timeout = MS_TO_NS(200); + ir->rc->driver_name = DRIVER_NAME; +diff --git a/drivers/media/rc/nuvoton-cir.c b/drivers/media/rc/nuvoton-cir.c +index 6d47b9c..e23c0ab 100644 +--- a/drivers/media/rc/nuvoton-cir.c ++++ b/drivers/media/rc/nuvoton-cir.c +@@ -626,8 +626,6 @@ static void nvt_process_rx_ir_data(struct nvt_dev *nvt) + + nvt_dbg_verbose("Processing buffer of len %d", nvt->pkts); + +- init_ir_raw_event(&rawir); +- + for (i = 0; i < nvt->pkts; i++) { + sample = nvt->buf[i]; + +@@ -979,7 +977,7 @@ static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id) + return ret; + + /* input device for IR remote (and tx) */ +- rdev = rc_allocate_device(); ++ rdev = rc_allocate_device(RC_DRIVER_IR_RAW); + if (!rdev) + goto exit_free_dev_rdev; + +@@ -1042,13 +1040,12 @@ static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id) + + /* Set up the rc device */ + rdev->priv = nvt; +- rdev->driver_type = RC_DRIVER_IR_RAW; +- rdev->allowed_protocols = RC_BIT_ALL_IR_DECODER; ++ rdev->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER; + rdev->open = nvt_open; + rdev->close = nvt_close; + rdev->tx_ir = nvt_tx_ir; + rdev->s_tx_carrier = nvt_set_tx_carrier; +- rdev->input_name = "Nuvoton w836x7hg Infrared Remote Transceiver"; ++ rdev->device_name = "Nuvoton w836x7hg Infrared Remote Transceiver"; + rdev->input_phys = "nuvoton/cir0"; + rdev->input_id.bustype = BUS_HOST; + rdev->input_id.vendor = PCI_VENDOR_ID_WINBOND2; +diff --git a/drivers/media/rc/redrat3.c b/drivers/media/rc/redrat3.c +index c889530..df6b5c7 100644 +--- a/drivers/media/rc/redrat3.c ++++ b/drivers/media/rc/redrat3.c +@@ -336,7 +336,7 @@ static void redrat3_rx_timeout(unsigned long data) + + static void redrat3_process_ir_data(struct redrat3_dev *rr3) + { +- DEFINE_IR_RAW_EVENT(rawir); ++ struct ir_raw_event rawir = {}; + struct device *dev; + unsigned i, trailer = 0; + unsigned sig_size, single_len, offset, val; +@@ -855,7 +855,7 @@ static struct rc_dev *redrat3_init_rc_dev(struct redrat3_dev *rr3) + int ret = -ENODEV; + u16 prod = le16_to_cpu(rr3->udev->descriptor.idProduct); + +- rc = rc_allocate_device(); ++ rc = rc_allocate_device(RC_DRIVER_IR_RAW); + if (!rc) { + dev_err(dev, "remote input dev allocation failed\n"); + goto out; +@@ -873,7 +873,7 @@ static struct rc_dev *redrat3_init_rc_dev(struct redrat3_dev *rr3) + rc->dev.parent = dev; + rc->priv = rr3; + rc->driver_type = RC_DRIVER_IR_RAW; +- rc->allowed_protocols = RC_BIT_ALL; ++ rc->allowed_protocols = RC_PROTO_BIT_ALL; + rc->timeout = US_TO_NS(2750); + rc->tx_ir = redrat3_transmit_ir; + rc->s_tx_carrier = redrat3_set_tx_carrier; +diff --git a/drivers/media/rc/winbond-cir.c b/drivers/media/rc/winbond-cir.c +index a47637f..b188cdf 100644 +--- a/drivers/media/rc/winbond-cir.c ++++ b/drivers/media/rc/winbond-cir.c +@@ -1078,7 +1078,7 @@ wbcir_probe(struct pnp_dev *device, const struct pnp_device_id *dev_id) + data->dev->dev.parent = &device->dev; + data->dev->timeout = MS_TO_NS(100); + data->dev->rx_resolution = US_TO_NS(2); +- data->dev->allowed_protocols = RC_BIT_ALL; ++ data->dev->allowed_protocols = RC_PROTO_BIT_ALL; + + err = rc_register_device(data->dev); + if (err) +diff --git a/drivers/media/usb/dvb-usb/dib0700_devices.c b/drivers/media/usb/dvb-usb/dib0700_devices.c +index 38c0328..a254374 100644 +--- a/drivers/media/usb/dvb-usb/dib0700_devices.c ++++ b/drivers/media/usb/dvb-usb/dib0700_devices.c +@@ -519,7 +519,7 @@ static u8 rc_request[] = { REQUEST_POLL_RC, 0 }; + static int dib0700_rc_query_old_firmware(struct dvb_usb_device *d) + { + u8 key[4]; +- enum rc_type protocol; ++ enum rc_proto protocol; + u32 scancode; + u8 toggle; + int i; +@@ -548,7 +548,7 @@ static int dib0700_rc_query_old_firmware(struct dvb_usb_device *d) + dib0700_rc_setup(d, NULL); /* reset ir sensor data to prevent false events */ + + switch (d->props.rc.core.protocol) { +- case RC_BIT_NEC: ++ case RC_PROTO_BIT_NEC: + /* NEC protocol sends repeat code as 0 0 0 FF */ + if ((key[3-2] == 0x00) && (key[3-3] == 0x00) && + (key[3] == 0xff)) { +@@ -556,14 +556,14 @@ static int dib0700_rc_query_old_firmware(struct dvb_usb_device *d) + return 0; + } + +- protocol = RC_TYPE_NEC; ++ protocol = RC_PROTO_NEC; + scancode = RC_SCANCODE_NEC(key[3-2], key[3-3]); + toggle = 0; + break; + + default: + /* RC-5 protocol changes toggle bit on new keypress */ +- protocol = RC_TYPE_RC5; ++ protocol = RC_PROTO_RC5; + scancode = RC_SCANCODE_RC5(key[3-2], key[3-3]); + toggle = key[3-1]; + break; +@@ -3887,9 +3887,9 @@ struct dvb_usb_device_properties dib0700_devices[] = { + .rc_interval = DEFAULT_RC_INTERVAL, + .rc_codes = RC_MAP_DIB0700_RC5_TABLE, + .rc_query = dib0700_rc_query_old_firmware, +- .allowed_protos = RC_BIT_RC5 | +- RC_BIT_RC6_MCE | +- RC_BIT_NEC, ++ .allowed_protos = RC_PROTO_BIT_RC5 | ++ RC_PROTO_BIT_RC6_MCE | ++ RC_PROTO_BIT_NEC, + .change_protocol = dib0700_change_protocol, + }, + }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, +@@ -3927,9 +3927,9 @@ struct dvb_usb_device_properties dib0700_devices[] = { + .rc_interval = DEFAULT_RC_INTERVAL, + .rc_codes = RC_MAP_DIB0700_RC5_TABLE, + .rc_query = dib0700_rc_query_old_firmware, +- .allowed_protos = RC_BIT_RC5 | +- RC_BIT_RC6_MCE | +- RC_BIT_NEC, ++ .allowed_protos = RC_PROTO_BIT_RC5 | ++ RC_PROTO_BIT_RC6_MCE | ++ RC_PROTO_BIT_NEC, + .change_protocol = dib0700_change_protocol, + }, + }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, +@@ -3992,9 +3992,9 @@ struct dvb_usb_device_properties dib0700_devices[] = { + .rc_interval = DEFAULT_RC_INTERVAL, + .rc_codes = RC_MAP_DIB0700_RC5_TABLE, + .rc_query = dib0700_rc_query_old_firmware, +- .allowed_protos = RC_BIT_RC5 | +- RC_BIT_RC6_MCE | +- RC_BIT_NEC, ++ .allowed_protos = RC_PROTO_BIT_RC5 | ++ RC_PROTO_BIT_RC6_MCE | ++ RC_PROTO_BIT_NEC, + .change_protocol = dib0700_change_protocol, + }, + }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, +@@ -4037,9 +4037,9 @@ struct dvb_usb_device_properties dib0700_devices[] = { + .rc_codes = RC_MAP_DIB0700_RC5_TABLE, + .module_name = "dib0700", + .rc_query = dib0700_rc_query_old_firmware, +- .allowed_protos = RC_BIT_RC5 | +- RC_BIT_RC6_MCE | +- RC_BIT_NEC, ++ .allowed_protos = RC_PROTO_BIT_RC5 | ++ RC_PROTO_BIT_RC6_MCE | ++ RC_PROTO_BIT_NEC, + .change_protocol = dib0700_change_protocol, + }, + }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, +@@ -4118,9 +4118,9 @@ struct dvb_usb_device_properties dib0700_devices[] = { + .rc_codes = RC_MAP_DIB0700_RC5_TABLE, + .module_name = "dib0700", + .rc_query = dib0700_rc_query_old_firmware, +- .allowed_protos = RC_BIT_RC5 | +- RC_BIT_RC6_MCE | +- RC_BIT_NEC, ++ .allowed_protos = RC_PROTO_BIT_RC5 | ++ RC_PROTO_BIT_RC6_MCE | ++ RC_PROTO_BIT_NEC, + .change_protocol = dib0700_change_protocol, + }, + }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, +@@ -4163,9 +4163,9 @@ struct dvb_usb_device_properties dib0700_devices[] = { + .rc_codes = RC_MAP_DIB0700_RC5_TABLE, + .module_name = "dib0700", + .rc_query = dib0700_rc_query_old_firmware, +- .allowed_protos = RC_BIT_RC5 | +- RC_BIT_RC6_MCE | +- RC_BIT_NEC, ++ .allowed_protos = RC_PROTO_BIT_RC5 | ++ RC_PROTO_BIT_RC6_MCE | ++ RC_PROTO_BIT_NEC, + .change_protocol = dib0700_change_protocol, + }, + }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, +@@ -4220,9 +4220,9 @@ struct dvb_usb_device_properties dib0700_devices[] = { + .rc_codes = RC_MAP_DIB0700_RC5_TABLE, + .module_name = "dib0700", + .rc_query = dib0700_rc_query_old_firmware, +- .allowed_protos = RC_BIT_RC5 | +- RC_BIT_RC6_MCE | +- RC_BIT_NEC, ++ .allowed_protos = RC_PROTO_BIT_RC5 | ++ RC_PROTO_BIT_RC6_MCE | ++ RC_PROTO_BIT_NEC, + .change_protocol = dib0700_change_protocol, + }, + }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, +@@ -4286,9 +4286,9 @@ struct dvb_usb_device_properties dib0700_devices[] = { + .rc_codes = RC_MAP_DIB0700_RC5_TABLE, + .module_name = "dib0700", + .rc_query = dib0700_rc_query_old_firmware, +- .allowed_protos = RC_BIT_RC5 | +- RC_BIT_RC6_MCE | +- RC_BIT_NEC, ++ .allowed_protos = RC_PROTO_BIT_RC5 | ++ RC_PROTO_BIT_RC6_MCE | ++ RC_PROTO_BIT_NEC, + .change_protocol = dib0700_change_protocol, + }, + }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, +@@ -4335,9 +4335,9 @@ struct dvb_usb_device_properties dib0700_devices[] = { + .rc_codes = RC_MAP_DIB0700_NEC_TABLE, + .module_name = "dib0700", + .rc_query = dib0700_rc_query_old_firmware, +- .allowed_protos = RC_BIT_RC5 | +- RC_BIT_RC6_MCE | +- RC_BIT_NEC, ++ .allowed_protos = RC_PROTO_BIT_RC5 | ++ RC_PROTO_BIT_RC6_MCE | ++ RC_PROTO_BIT_NEC, + .change_protocol = dib0700_change_protocol, + }, + }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, +@@ -4404,9 +4404,9 @@ struct dvb_usb_device_properties dib0700_devices[] = { + .rc_codes = RC_MAP_DIB0700_RC5_TABLE, + .module_name = "dib0700", + .rc_query = dib0700_rc_query_old_firmware, +- .allowed_protos = RC_BIT_RC5 | +- RC_BIT_RC6_MCE | +- RC_BIT_NEC, ++ .allowed_protos = RC_PROTO_BIT_RC5 | ++ RC_PROTO_BIT_RC6_MCE | ++ RC_PROTO_BIT_NEC, + .change_protocol = dib0700_change_protocol, + }, + }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, +@@ -4440,9 +4440,9 @@ struct dvb_usb_device_properties dib0700_devices[] = { + .rc_codes = RC_MAP_DIB0700_RC5_TABLE, + .module_name = "dib0700", + .rc_query = dib0700_rc_query_old_firmware, +- .allowed_protos = RC_BIT_RC5 | +- RC_BIT_RC6_MCE | +- RC_BIT_NEC, ++ .allowed_protos = RC_PROTO_BIT_RC5 | ++ RC_PROTO_BIT_RC6_MCE | ++ RC_PROTO_BIT_NEC, + .change_protocol = dib0700_change_protocol, + }, + }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, +@@ -4516,9 +4516,9 @@ struct dvb_usb_device_properties dib0700_devices[] = { + .rc_codes = RC_MAP_DIB0700_RC5_TABLE, + .module_name = "dib0700", + .rc_query = dib0700_rc_query_old_firmware, +- .allowed_protos = RC_BIT_RC5 | +- RC_BIT_RC6_MCE | +- RC_BIT_NEC, ++ .allowed_protos = RC_PROTO_BIT_RC5 | ++ RC_PROTO_BIT_RC6_MCE | ++ RC_PROTO_BIT_NEC, + .change_protocol = dib0700_change_protocol, + }, + }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, +@@ -4560,9 +4560,9 @@ struct dvb_usb_device_properties dib0700_devices[] = { + .rc_codes = RC_MAP_DIB0700_NEC_TABLE, + .module_name = "dib0700", + .rc_query = dib0700_rc_query_old_firmware, +- .allowed_protos = RC_BIT_RC5 | +- RC_BIT_RC6_MCE | +- RC_BIT_NEC, ++ .allowed_protos = RC_PROTO_BIT_RC5 | ++ RC_PROTO_BIT_RC6_MCE | ++ RC_PROTO_BIT_NEC, + .change_protocol = dib0700_change_protocol, + }, + }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, +@@ -4609,9 +4609,9 @@ struct dvb_usb_device_properties dib0700_devices[] = { + .rc_codes = RC_MAP_DIB0700_RC5_TABLE, + .module_name = "dib0700", + .rc_query = dib0700_rc_query_old_firmware, +- .allowed_protos = RC_BIT_RC5 | +- RC_BIT_RC6_MCE | +- RC_BIT_NEC, ++ .allowed_protos = RC_PROTO_BIT_RC5 | ++ RC_PROTO_BIT_RC6_MCE | ++ RC_PROTO_BIT_NEC, + .change_protocol = dib0700_change_protocol, + }, + }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, +@@ -4646,9 +4646,9 @@ struct dvb_usb_device_properties dib0700_devices[] = { + .rc_codes = RC_MAP_DIB0700_RC5_TABLE, + .module_name = "dib0700", + .rc_query = dib0700_rc_query_old_firmware, +- .allowed_protos = RC_BIT_RC5 | +- RC_BIT_RC6_MCE | +- RC_BIT_NEC, ++ .allowed_protos = RC_PROTO_BIT_RC5 | ++ RC_PROTO_BIT_RC6_MCE | ++ RC_PROTO_BIT_NEC, + .change_protocol = dib0700_change_protocol, + }, + }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, +@@ -4683,9 +4683,9 @@ struct dvb_usb_device_properties dib0700_devices[] = { + .rc_codes = RC_MAP_DIB0700_RC5_TABLE, + .module_name = "dib0700", + .rc_query = dib0700_rc_query_old_firmware, +- .allowed_protos = RC_BIT_RC5 | +- RC_BIT_RC6_MCE | +- RC_BIT_NEC, ++ .allowed_protos = RC_PROTO_BIT_RC5 | ++ RC_PROTO_BIT_RC6_MCE | ++ RC_PROTO_BIT_NEC, + .change_protocol = dib0700_change_protocol, + }, + }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, +@@ -4720,9 +4720,9 @@ struct dvb_usb_device_properties dib0700_devices[] = { + .rc_codes = RC_MAP_DIB0700_RC5_TABLE, + .module_name = "dib0700", + .rc_query = dib0700_rc_query_old_firmware, +- .allowed_protos = RC_BIT_RC5 | +- RC_BIT_RC6_MCE | +- RC_BIT_NEC, ++ .allowed_protos = RC_PROTO_BIT_RC5 | ++ RC_PROTO_BIT_RC6_MCE | ++ RC_PROTO_BIT_NEC, + .change_protocol = dib0700_change_protocol, + }, + }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, +@@ -4757,9 +4757,9 @@ struct dvb_usb_device_properties dib0700_devices[] = { + .rc_codes = RC_MAP_DIB0700_RC5_TABLE, + .module_name = "dib0700", + .rc_query = dib0700_rc_query_old_firmware, +- .allowed_protos = RC_BIT_RC5 | +- RC_BIT_RC6_MCE | +- RC_BIT_NEC, ++ .allowed_protos = RC_PROTO_BIT_RC5 | ++ RC_PROTO_BIT_RC6_MCE | ++ RC_PROTO_BIT_NEC, + .change_protocol = dib0700_change_protocol, + }, + }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, +@@ -4794,9 +4794,9 @@ struct dvb_usb_device_properties dib0700_devices[] = { + .rc_codes = RC_MAP_DIB0700_RC5_TABLE, + .module_name = "dib0700", + .rc_query = dib0700_rc_query_old_firmware, +- .allowed_protos = RC_BIT_RC5 | +- RC_BIT_RC6_MCE | +- RC_BIT_NEC, ++ .allowed_protos = RC_PROTO_BIT_RC5 | ++ RC_PROTO_BIT_RC6_MCE | ++ RC_PROTO_BIT_NEC, + .change_protocol = dib0700_change_protocol, + }, + }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, +@@ -4845,9 +4845,9 @@ struct dvb_usb_device_properties dib0700_devices[] = { + .rc_codes = RC_MAP_DIB0700_RC5_TABLE, + .module_name = "dib0700", + .rc_query = dib0700_rc_query_old_firmware, +- .allowed_protos = RC_BIT_RC5 | +- RC_BIT_RC6_MCE | +- RC_BIT_NEC, ++ .allowed_protos = RC_PROTO_BIT_RC5 | ++ RC_PROTO_BIT_RC6_MCE | ++ RC_PROTO_BIT_NEC, + .change_protocol = dib0700_change_protocol, + }, + }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, +@@ -4880,9 +4880,9 @@ struct dvb_usb_device_properties dib0700_devices[] = { + .rc_codes = RC_MAP_DIB0700_RC5_TABLE, + .module_name = "dib0700", + .rc_query = dib0700_rc_query_old_firmware, +- .allowed_protos = RC_BIT_RC5 | +- RC_BIT_RC6_MCE | +- RC_BIT_NEC, ++ .allowed_protos = RC_PROTO_BIT_RC5 | ++ RC_PROTO_BIT_RC6_MCE | ++ RC_PROTO_BIT_NEC, + .change_protocol = dib0700_change_protocol, + }, + }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, +@@ -4917,9 +4917,9 @@ struct dvb_usb_device_properties dib0700_devices[] = { + .rc_codes = RC_MAP_DIB0700_RC5_TABLE, + .module_name = "dib0700", + .rc_query = dib0700_rc_query_old_firmware, +- .allowed_protos = RC_BIT_RC5 | +- RC_BIT_RC6_MCE | +- RC_BIT_NEC, ++ .allowed_protos = RC_PROTO_BIT_RC5 | ++ RC_PROTO_BIT_RC6_MCE | ++ RC_PROTO_BIT_NEC, + .change_protocol = dib0700_change_protocol, + }, + }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, +@@ -4955,9 +4955,9 @@ struct dvb_usb_device_properties dib0700_devices[] = { + .rc_codes = RC_MAP_DIB0700_RC5_TABLE, + .module_name = "dib0700", + .rc_query = dib0700_rc_query_old_firmware, +- .allowed_protos = RC_BIT_RC5 | +- RC_BIT_RC6_MCE | +- RC_BIT_NEC, ++ .allowed_protos = RC_PROTO_BIT_RC5 | ++ RC_PROTO_BIT_RC6_MCE | ++ RC_PROTO_BIT_NEC, + .change_protocol = dib0700_change_protocol, + }, + }, +diff --git a/drivers/media/usb/em28xx/em28xx-input.c b/drivers/media/usb/em28xx/em28xx-input.c +index 1e3d33a..0a886ac 100644 +--- a/drivers/media/usb/em28xx/em28xx-input.c ++++ b/drivers/media/usb/em28xx/em28xx-input.c +@@ -54,7 +54,7 @@ struct em28xx_ir_poll_result { + unsigned int toggle_bit:1; + unsigned int read_count:7; + +- enum rc_type protocol; ++ enum rc_proto protocol; + u32 scancode; + }; + +@@ -69,11 +69,11 @@ struct em28xx_IR { + struct delayed_work work; + unsigned int full_code:1; + unsigned int last_readcount; +- u64 rc_type; ++ u64 rc_proto; + + struct i2c_client *i2c_client; + +- int (*get_key_i2c)(struct i2c_client *ir, enum rc_type *protocol, u32 *scancode); ++ int (*get_key_i2c)(struct i2c_client *ir, enum rc_proto *protocol, u32 *scancode); + int (*get_key)(struct em28xx_IR *, struct em28xx_ir_poll_result *); + }; + +@@ -82,7 +82,7 @@ struct em28xx_IR { + **********************************************************/ + + static int em28xx_get_key_terratec(struct i2c_client *i2c_dev, +- enum rc_type *protocol, u32 *scancode) ++ enum rc_proto *protocol, u32 *scancode) + { + unsigned char b; + +@@ -100,13 +100,13 @@ static int em28xx_get_key_terratec(struct i2c_client *i2c_dev, + /* keep old data */ + return 1; + +- *protocol = RC_TYPE_UNKNOWN; ++ *protocol = RC_PROTO_UNKNOWN; + *scancode = b; + return 1; + } + + static int em28xx_get_key_em_haup(struct i2c_client *i2c_dev, +- enum rc_type *protocol, u32 *scancode) ++ enum rc_proto *protocol, u32 *scancode) + { + unsigned char buf[2]; + int size; +@@ -130,13 +130,13 @@ static int em28xx_get_key_em_haup(struct i2c_client *i2c_dev, + * So, the code translation is not complete. Yet, it is enough to + * work with the provided RC5 IR. + */ +- *protocol = RC_TYPE_RC5; ++ *protocol = RC_PROTO_RC5; + *scancode = (bitrev8(buf[1]) & 0x1f) << 8 | bitrev8(buf[0]) >> 2; + return 1; + } + + static int em28xx_get_key_pinnacle_usb_grey(struct i2c_client *i2c_dev, +- enum rc_type *protocol, u32 *scancode) ++ enum rc_proto *protocol, u32 *scancode) + { + unsigned char buf[3]; + +@@ -148,13 +148,13 @@ static int em28xx_get_key_pinnacle_usb_grey(struct i2c_client *i2c_dev, + if (buf[0] != 0x00) + return 0; + +- *protocol = RC_TYPE_UNKNOWN; ++ *protocol = RC_PROTO_UNKNOWN; + *scancode = buf[2] & 0x3f; + return 1; + } + + static int em28xx_get_key_winfast_usbii_deluxe(struct i2c_client *i2c_dev, +- enum rc_type *protocol, u32 *scancode) ++ enum rc_proto *protocol, u32 *scancode) + { + unsigned char subaddr, keydetect, key; + +@@ -174,7 +174,7 @@ static int em28xx_get_key_winfast_usbii_deluxe(struct i2c_client *i2c_dev, + if (key == 0x00) + return 0; + +- *protocol = RC_TYPE_UNKNOWN; ++ *protocol = RC_PROTO_UNKNOWN; + *scancode = key; + return 1; + } +@@ -206,19 +206,19 @@ static int default_polling_getkey(struct em28xx_IR *ir, + poll_result->read_count = (msg[0] & 0x7f); + + /* Remote Control Address/Data (Regs 0x46/0x47) */ +- switch (ir->rc_type) { +- case RC_BIT_RC5: +- poll_result->protocol = RC_TYPE_RC5; ++ switch (ir->rc_proto) { ++ case RC_PROTO_BIT_RC5: ++ poll_result->protocol = RC_PROTO_RC5; + poll_result->scancode = RC_SCANCODE_RC5(msg[1], msg[2]); + break; + +- case RC_BIT_NEC: +- poll_result->protocol = RC_TYPE_NEC; ++ case RC_PROTO_BIT_NEC: ++ poll_result->protocol = RC_PROTO_NEC; + poll_result->scancode = RC_SCANCODE_NEC(msg[1], msg[2]); + break; + + default: +- poll_result->protocol = RC_TYPE_UNKNOWN; ++ poll_result->protocol = RC_PROTO_UNKNOWN; + poll_result->scancode = msg[1] << 8 | msg[2]; + break; + } +@@ -251,14 +251,14 @@ static int em2874_polling_getkey(struct em28xx_IR *ir, + * Remote Control Address (Reg 0x52) + * Remote Control Data (Reg 0x53-0x55) + */ +- switch (ir->rc_type) { +- case RC_BIT_RC5: +- poll_result->protocol = RC_TYPE_RC5; ++ switch (ir->rc_proto) { ++ case RC_PROTO_BIT_RC5: ++ poll_result->protocol = RC_PROTO_RC5; + poll_result->scancode = RC_SCANCODE_RC5(msg[1], msg[2]); + break; + +- case RC_BIT_NEC: +- poll_result->protocol = RC_TYPE_RC5; ++ case RC_PROTO_BIT_NEC: ++ poll_result->protocol = RC_PROTO_RC5; + poll_result->scancode = msg[1] << 8 | msg[2]; + if ((msg[3] ^ msg[4]) != 0xff) /* 32 bits NEC */ + poll_result->scancode = RC_SCANCODE_NEC32((msg[1] << 24) | +@@ -272,13 +272,13 @@ static int em2874_polling_getkey(struct em28xx_IR *ir, + poll_result->scancode = RC_SCANCODE_NEC(msg[1], msg[3]); + break; + +- case RC_BIT_RC6_0: +- poll_result->protocol = RC_TYPE_RC6_0; ++ case RC_PROTO_BIT_RC6_0: ++ poll_result->protocol = RC_PROTO_RC6_0; + poll_result->scancode = RC_SCANCODE_RC6_0(msg[1], msg[2]); + break; + + default: +- poll_result->protocol = RC_TYPE_UNKNOWN; ++ poll_result->protocol = RC_PROTO_UNKNOWN; + poll_result->scancode = (msg[1] << 24) | (msg[2] << 16) | + (msg[3] << 8) | msg[4]; + break; +@@ -294,7 +294,7 @@ static int em2874_polling_getkey(struct em28xx_IR *ir, + static int em28xx_i2c_ir_handle_key(struct em28xx_IR *ir) + { + static u32 scancode; +- enum rc_type protocol; ++ enum rc_proto protocol; + int rc; + + rc = ir->get_key_i2c(ir->i2c_client, &protocol, &scancode); +@@ -334,7 +334,7 @@ static void em28xx_ir_handle_key(struct em28xx_IR *ir) + poll_result.toggle_bit); + else + rc_keydown(ir->rc, +- RC_TYPE_UNKNOWN, ++ RC_PROTO_UNKNOWN, + poll_result.scancode & 0xff, + poll_result.toggle_bit); + +@@ -379,70 +379,70 @@ static void em28xx_ir_stop(struct rc_dev *rc) + cancel_delayed_work_sync(&ir->work); + } + +-static int em2860_ir_change_protocol(struct rc_dev *rc_dev, u64 *rc_type) ++static int em2860_ir_change_protocol(struct rc_dev *rc_dev, u64 *rc_proto) + { + struct em28xx_IR *ir = rc_dev->priv; + struct em28xx *dev = ir->dev; + + /* Adjust xclk based on IR table for RC5/NEC tables */ +- if (*rc_type & RC_BIT_RC5) { ++ if (*rc_proto & RC_PROTO_BIT_RC5) { + dev->board.xclk |= EM28XX_XCLK_IR_RC5_MODE; + ir->full_code = 1; +- *rc_type = RC_BIT_RC5; +- } else if (*rc_type & RC_BIT_NEC) { ++ *rc_proto = RC_PROTO_BIT_RC5; ++ } else if (*rc_proto & RC_PROTO_BIT_NEC) { + dev->board.xclk &= ~EM28XX_XCLK_IR_RC5_MODE; + ir->full_code = 1; +- *rc_type = RC_BIT_NEC; +- } else if (*rc_type & RC_BIT_UNKNOWN) { +- *rc_type = RC_BIT_UNKNOWN; ++ *rc_proto = RC_PROTO_BIT_NEC; ++ } else if (*rc_proto & RC_PROTO_BIT_UNKNOWN) { ++ *rc_proto = RC_PROTO_BIT_UNKNOWN; + } else { +- *rc_type = ir->rc_type; ++ *rc_proto = ir->rc_proto; + return -EINVAL; + } + em28xx_write_reg_bits(dev, EM28XX_R0F_XCLK, dev->board.xclk, + EM28XX_XCLK_IR_RC5_MODE); + +- ir->rc_type = *rc_type; ++ ir->rc_proto = *rc_proto; + + return 0; + } + +-static int em2874_ir_change_protocol(struct rc_dev *rc_dev, u64 *rc_type) ++static int em2874_ir_change_protocol(struct rc_dev *rc_dev, u64 *rc_proto) + { + struct em28xx_IR *ir = rc_dev->priv; + struct em28xx *dev = ir->dev; + u8 ir_config = EM2874_IR_RC5; + + /* Adjust xclk and set type based on IR table for RC5/NEC/RC6 tables */ +- if (*rc_type & RC_BIT_RC5) { ++ if (*rc_proto & RC_PROTO_BIT_RC5) { + dev->board.xclk |= EM28XX_XCLK_IR_RC5_MODE; + ir->full_code = 1; +- *rc_type = RC_BIT_RC5; +- } else if (*rc_type & RC_BIT_NEC) { ++ *rc_proto = RC_PROTO_BIT_RC5; ++ } else if (*rc_proto & RC_PROTO_BIT_NEC) { + dev->board.xclk &= ~EM28XX_XCLK_IR_RC5_MODE; + ir_config = EM2874_IR_NEC | EM2874_IR_NEC_NO_PARITY; + ir->full_code = 1; +- *rc_type = RC_BIT_NEC; +- } else if (*rc_type & RC_BIT_RC6_0) { ++ *rc_proto = RC_PROTO_BIT_NEC; ++ } else if (*rc_proto & RC_PROTO_BIT_RC6_0) { + dev->board.xclk |= EM28XX_XCLK_IR_RC5_MODE; + ir_config = EM2874_IR_RC6_MODE_0; + ir->full_code = 1; +- *rc_type = RC_BIT_RC6_0; +- } else if (*rc_type & RC_BIT_UNKNOWN) { +- *rc_type = RC_BIT_UNKNOWN; ++ *rc_proto = RC_PROTO_BIT_RC6_0; ++ } else if (*rc_proto & RC_PROTO_BIT_UNKNOWN) { ++ *rc_proto = RC_PROTO_BIT_UNKNOWN; + } else { +- *rc_type = ir->rc_type; ++ *rc_proto = ir->rc_proto; + return -EINVAL; + } + em28xx_write_regs(dev, EM2874_R50_IR_CONFIG, &ir_config, 1); + em28xx_write_reg_bits(dev, EM28XX_R0F_XCLK, dev->board.xclk, + EM28XX_XCLK_IR_RC5_MODE); + +- ir->rc_type = *rc_type; ++ ir->rc_proto = *rc_proto; + + return 0; + } +-static int em28xx_ir_change_protocol(struct rc_dev *rc_dev, u64 *rc_type) ++static int em28xx_ir_change_protocol(struct rc_dev *rc_dev, u64 *rc_proto) + { + struct em28xx_IR *ir = rc_dev->priv; + struct em28xx *dev = ir->dev; +@@ -451,12 +451,12 @@ static int em28xx_ir_change_protocol(struct rc_dev *rc_dev, u64 *rc_type) + switch (dev->chip_id) { + case CHIP_ID_EM2860: + case CHIP_ID_EM2883: +- return em2860_ir_change_protocol(rc_dev, rc_type); ++ return em2860_ir_change_protocol(rc_dev, rc_proto); + case CHIP_ID_EM2884: + case CHIP_ID_EM2874: + case CHIP_ID_EM28174: + case CHIP_ID_EM28178: +- return em2874_ir_change_protocol(rc_dev, rc_type); ++ return em2874_ir_change_protocol(rc_dev, rc_proto); + default: + printk("Unrecognized em28xx chip id 0x%02x: IR not supported\n", + dev->chip_id); +@@ -678,7 +678,7 @@ static int em28xx_ir_init(struct em28xx *dev) + struct em28xx_IR *ir; + struct rc_dev *rc; + int err = -ENOMEM; +- u64 rc_type; ++ u64 rc_proto; + u16 i2c_rc_dev_addr = 0; + + if (dev->is_audio_only) { +@@ -740,7 +740,7 @@ static int em28xx_ir_init(struct em28xx *dev) + case EM2820_BOARD_HAUPPAUGE_WINTV_USB_2: + rc->map_name = RC_MAP_HAUPPAUGE; + ir->get_key_i2c = em28xx_get_key_em_haup; +- rc->allowed_protocols = RC_BIT_RC5; ++ rc->allowed_protocols = RC_PROTO_BIT_RC5; + break; + case EM2820_BOARD_LEADTEK_WINFAST_USBII_DELUXE: + rc->map_name = RC_MAP_WINFAST_USBII_DELUXE; +@@ -762,7 +762,7 @@ static int em28xx_ir_init(struct em28xx *dev) + switch (dev->chip_id) { + case CHIP_ID_EM2860: + case CHIP_ID_EM2883: +- rc->allowed_protocols = RC_BIT_RC5 | RC_BIT_NEC; ++ rc->allowed_protocols = RC_PROTO_BIT_RC5 | RC_PROTO_BIT_NEC; + ir->get_key = default_polling_getkey; + break; + case CHIP_ID_EM2884: +@@ -770,8 +770,8 @@ static int em28xx_ir_init(struct em28xx *dev) + case CHIP_ID_EM28174: + case CHIP_ID_EM28178: + ir->get_key = em2874_polling_getkey; +- rc->allowed_protocols = RC_BIT_RC5 | RC_BIT_NEC | +- RC_BIT_RC6_0; ++ rc->allowed_protocols = RC_PROTO_BIT_RC5 | RC_PROTO_BIT_NEC | ++ RC_PROTO_BIT_RC6_0; + break; + default: + err = -ENODEV; +@@ -782,8 +782,8 @@ static int em28xx_ir_init(struct em28xx *dev) + rc->map_name = dev->board.ir_codes; + + /* By default, keep protocol field untouched */ +- rc_type = RC_BIT_UNKNOWN; +- err = em28xx_ir_change_protocol(rc, &rc_type); ++ rc_proto = RC_PROTO_BIT_UNKNOWN; ++ err = em28xx_ir_change_protocol(rc, &rc_proto); + if (err) + goto error; + } +diff --git a/drivers/media/usb/tm6000/tm6000-input.c b/drivers/media/usb/tm6000/tm6000-input.c +index af18423..99cdbc0 100644 +--- a/drivers/media/usb/tm6000/tm6000-input.c ++++ b/drivers/media/usb/tm6000/tm6000-input.c +@@ -71,7 +71,7 @@ struct tm6000_IR { + struct urb *int_urb; + + /* IR device properties */ +- u64 rc_type; ++ u64 rc_proto; + }; + + void tm6000_ir_wait(struct tm6000_core *dev, u8 state) +@@ -108,13 +108,13 @@ static int tm6000_ir_config(struct tm6000_IR *ir) + * IR, in order to discard such decoding + */ + +- switch (ir->rc_type) { +- case RC_BIT_NEC: ++ switch (ir->rc_proto) { ++ case RC_PROTO_BIT_NEC: + leader = 900; /* ms */ + pulse = 700; /* ms - the actual value would be 562 */ + break; + default: +- case RC_BIT_RC5: ++ case RC_PROTO_BIT_RC5: + leader = 900; /* ms - from the NEC decoding */ + pulse = 1780; /* ms - The actual value would be 1776 */ + break; +@@ -122,12 +122,12 @@ static int tm6000_ir_config(struct tm6000_IR *ir) + + pulse = ir_clock_mhz * pulse; + leader = ir_clock_mhz * leader; +- if (ir->rc_type == RC_BIT_NEC) ++ if (ir->rc_proto == RC_PROTO_BIT_NEC) + leader = leader | 0x8000; + + dprintk(2, "%s: %s, %d MHz, leader = 0x%04x, pulse = 0x%06x \n", + __func__, +- (ir->rc_type == RC_BIT_NEC) ? "NEC" : "RC-5", ++ (ir->rc_proto == RC_PROTO_BIT_NEC) ? "NEC" : "RC-5", + ir_clock_mhz, leader, pulse); + + /* Remote WAKEUP = enable, normal mode, from IR decoder output */ +@@ -167,24 +167,24 @@ static void tm6000_ir_keydown(struct tm6000_IR *ir, + { + u8 device, command; + u32 scancode; +- enum rc_type protocol; ++ enum rc_proto protocol; + + if (len < 1) + return; + + command = buf[0]; + device = (len > 1 ? buf[1] : 0x0); +- switch (ir->rc_type) { +- case RC_BIT_RC5: +- protocol = RC_TYPE_RC5; ++ switch (ir->rc_proto) { ++ case RC_PROTO_BIT_RC5: ++ protocol = RC_PROTO_RC5; + scancode = RC_SCANCODE_RC5(device, command); + break; +- case RC_BIT_NEC: +- protocol = RC_TYPE_NEC; ++ case RC_PROTO_BIT_NEC: ++ protocol = RC_PROTO_NEC; + scancode = RC_SCANCODE_NEC(device, command); + break; + default: +- protocol = RC_TYPE_OTHER; ++ protocol = RC_PROTO_OTHER; + scancode = RC_SCANCODE_OTHER(device << 8 | command); + break; + } +@@ -316,7 +316,7 @@ static void tm6000_ir_stop(struct rc_dev *rc) + cancel_delayed_work_sync(&ir->work); + } + +-static int tm6000_ir_change_protocol(struct rc_dev *rc, u64 *rc_type) ++static int tm6000_ir_change_protocol(struct rc_dev *rc, u64 *rc_proto) + { + struct tm6000_IR *ir = rc->priv; + +@@ -325,10 +325,10 @@ static int tm6000_ir_change_protocol(struct rc_dev *rc, u64 *rc_type) + + dprintk(2, "%s\n",__func__); + +- if ((rc->rc_map.scan) && (*rc_type == RC_BIT_NEC)) ++ if ((rc->rc_map.scan) && (*rc_proto == RC_PROTO_BIT_NEC)) + ir->key_addr = ((rc->rc_map.scan[0].scancode >> 8) & 0xffff); + +- ir->rc_type = *rc_type; ++ ir->rc_proto = *rc_proto; + + tm6000_ir_config(ir); + /* TODO */ +@@ -417,7 +417,7 @@ int tm6000_ir_init(struct tm6000_core *dev) + struct tm6000_IR *ir; + struct rc_dev *rc; + int err = -ENOMEM; +- u64 rc_type; ++ u64 rc_proto; + + if (!enable_ir) + return -ENODEV; +@@ -441,7 +441,7 @@ int tm6000_ir_init(struct tm6000_core *dev) + ir->rc = rc; + + /* input setup */ +- rc->allowed_protocols = RC_BIT_RC5 | RC_BIT_NEC; ++ rc->allowed_protocols = RC_PROTO_BIT_RC5 | RC_PROTO_BIT_NEC; + /* Neded, in order to support NEC remotes with 24 or 32 bits */ + rc->scancode_mask = 0xffff; + rc->priv = ir; +@@ -463,8 +463,8 @@ int tm6000_ir_init(struct tm6000_core *dev) + usb_make_path(dev->udev, ir->phys, sizeof(ir->phys)); + strlcat(ir->phys, "/input0", sizeof(ir->phys)); + +- rc_type = RC_BIT_UNKNOWN; +- tm6000_ir_change_protocol(rc, &rc_type); ++ rc_proto = RC_PROTO_BIT_UNKNOWN; ++ tm6000_ir_change_protocol(rc, &rc_proto); + + rc->device_name = ir->name; + rc->input_phys = ir->phys; diff --git a/patch/kernel/rk322x-legacy/01-linux-1000-pl330.patch b/patch/kernel/rk322x-legacy/01-linux-1000-pl330.patch new file mode 100644 index 0000000000..34027fc155 --- /dev/null +++ b/patch/kernel/rk322x-legacy/01-linux-1000-pl330.patch @@ -0,0 +1,2682 @@ +From de1d7ef4900e4083d3eb61a41ef21970cd572a59 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sat, 8 Sep 2018 11:03:36 +0200 +Subject: [PATCH] Revert "dmaengine: pl330: add support for interlace single + xfer" + +This reverts commit 83623425bceb4005151379cc959e41eddd2a0937. +--- + drivers/dma/pl330.c | 10 +--------- + 1 file changed, 1 insertion(+), 9 deletions(-) + +diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c +index b14f5c225401..8746c24d3cd7 100644 +--- a/drivers/dma/pl330.c ++++ b/drivers/dma/pl330.c +@@ -1477,12 +1477,6 @@ static inline int _setup_loops(struct pl330_dmac *pl330, + off += _emit_FLUSHP(dry_run, &buf[off], + pxs->desc->peri); + #endif +- if (pxs->desc->rqtype == DMA_DEV_TO_MEM) +- bursts = x->bytes / (BRST_SIZE(ccr) * BRST_LEN(ccr) + +- pxs->desc->dst_interlace_size); +- else if (pxs->desc->rqtype == DMA_MEM_TO_DEV) +- bursts = x->bytes / (BRST_SIZE(ccr) * BRST_LEN(ccr) + +- pxs->desc->src_interlace_size); + while (bursts) { + c = bursts; + off += _loop(pl330, dry_run, &buf[off], &c, pxs); +@@ -1507,9 +1501,7 @@ static inline int _setup_xfer(struct pl330_dmac *pl330, + /* Setup Loop(s) */ + off += _setup_loops(pl330, dry_run, &buf[off], pxs); + +- if (pxs->desc->src_interlace_size == 0 && +- pxs->desc->dst_interlace_size == 0 && +- pl330->peripherals_req_type == BURST) { ++ if (pl330->peripherals_req_type == BURST) { + unsigned int ccr = pxs->ccr; + unsigned long c = 0; + + +From 875fb88fb64f5dc61abb8c4a311de82b68792d0e Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sat, 1 Sep 2018 07:43:58 +0200 +Subject: [PATCH] Revert "dmaengine: pl330: _loop_cyclic: fixup loopcnt is too + large" + +This reverts commit 8ea3f97aab1b68b5aa1aece7eb83bef6d08b3c84. +--- + drivers/dma/pl330.c | 67 +++++++++++++++++------------------------------------ + 1 file changed, 21 insertions(+), 46 deletions(-) + +diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c +index 8746c24d3cd7..5893c11dd858 100644 +--- a/drivers/dma/pl330.c ++++ b/drivers/dma/pl330.c +@@ -1341,14 +1341,19 @@ static inline int _loop(struct pl330_dmac *pl330, unsigned dry_run, u8 buf[], + return off; + } + +-static int _period(struct pl330_dmac *pl330, unsigned int dry_run, u8 buf[], +- unsigned long bursts, const struct _xfer_spec *pxs, int ev) ++/* Returns bytes consumed */ ++static inline int _loop_cyclic(struct pl330_dmac *pl330, unsigned dry_run, ++ u8 buf[], unsigned long bursts, const struct _xfer_spec *pxs, int ev) + { +- unsigned int lcnt1, ljmp1; +- int cyc, off = 0; ++ int cyc, off; ++ unsigned lcnt0, lcnt1, ljmp0, ljmp1, ljmpfe; + struct _arg_LPEND lpend; + struct pl330_xfer *x = &pxs->desc->px; + ++ off = 0; ++ ljmpfe = off; ++ lcnt0 = pxs->desc->num_periods; ++ + if (bursts > 256) { + lcnt1 = 256; + cyc = bursts / 256; +@@ -1357,6 +1362,18 @@ static int _period(struct pl330_dmac *pl330, unsigned int dry_run, u8 buf[], + cyc = 1; + } + ++ /* forever loop */ ++ off += _emit_MOV(dry_run, &buf[off], SAR, x->src_addr); ++ off += _emit_MOV(dry_run, &buf[off], DAR, x->dst_addr); ++#ifdef CONFIG_ARCH_ROCKCHIP ++ if (!(pl330->quirks & PL330_QUIRK_BROKEN_NO_FLUSHP)) ++ off += _emit_FLUSHP(dry_run, &buf[off], ++ pxs->desc->peri); ++#endif ++ /* loop0 */ ++ off += _emit_LP(dry_run, &buf[off], 0, lcnt0); ++ ljmp0 = off; ++ + /* loop1 */ + off += _emit_LP(dry_run, &buf[off], 1, lcnt1); + ljmp1 = off; +@@ -1407,54 +1424,12 @@ static int _period(struct pl330_dmac *pl330, unsigned int dry_run, u8 buf[], + + off += _emit_SEV(dry_run, &buf[off], ev); + +- return off; +-} +- +-/* Returns bytes consumed */ +-static inline int _loop_cyclic(struct pl330_dmac *pl330, unsigned int dry_run, +- u8 buf[], unsigned long bursts, const struct _xfer_spec *pxs, int ev) +-{ +- int off, periods, residue, i; +- unsigned int lcnt0, ljmp0, ljmpfe; +- struct _arg_LPEND lpend; +- struct pl330_xfer *x = &pxs->desc->px; +- +- off = 0; +- ljmpfe = off; +- lcnt0 = pxs->desc->num_periods; +- periods = 1; +- +- while (lcnt0 > 256) { +- periods++; +- lcnt0 = pxs->desc->num_periods / periods; +- } +- +- residue = pxs->desc->num_periods % periods; +- +- /* forever loop */ +- off += _emit_MOV(dry_run, &buf[off], SAR, x->src_addr); +- off += _emit_MOV(dry_run, &buf[off], DAR, x->dst_addr); +-#ifdef CONFIG_ARCH_ROCKCHIP +- if (!(pl330->quirks & PL330_QUIRK_BROKEN_NO_FLUSHP)) +- off += _emit_FLUSHP(dry_run, &buf[off], +- pxs->desc->peri); +-#endif +- /* loop0 */ +- off += _emit_LP(dry_run, &buf[off], 0, lcnt0); +- ljmp0 = off; +- +- for (i = 0; i < periods; i++) +- off += _period(pl330, dry_run, &buf[off], bursts, pxs, ev); +- + lpend.cond = ALWAYS; + lpend.forever = false; + lpend.loop = 0; + lpend.bjump = off - ljmp0; + off += _emit_LPEND(dry_run, &buf[off], &lpend); + +- for (i = 0; i < residue; i++) +- off += _period(pl330, dry_run, &buf[off], bursts, pxs, ev); +- + lpend.cond = ALWAYS; + lpend.forever = true; + lpend.loop = 1; + +From b773c238a40773bd6f717701324630a917b67567 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 3 Jun 2018 07:36:35 +0200 +Subject: [PATCH] Revert "dmaengine: pl330: add support for interlace cyclic + xfer" + +This reverts commit 191583d95bae59c82b50f7437f2b738fcc5f8015. +--- + drivers/dma/pl330.c | 21 ++++++++++++--------- + 1 file changed, 12 insertions(+), 9 deletions(-) + +diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c +index 5893c11dd858..b4a0d48bafa4 100644 +--- a/drivers/dma/pl330.c ++++ b/drivers/dma/pl330.c +@@ -1398,9 +1398,7 @@ static inline int _loop_cyclic(struct pl330_dmac *pl330, unsigned dry_run, + off += _emit_LPEND(dry_run, &buf[off], &lpend); + } + +- if (pxs->desc->src_interlace_size == 0 && +- pxs->desc->dst_interlace_size == 0 && +- pl330->peripherals_req_type == BURST) { ++ if (pl330->peripherals_req_type == BURST) { + unsigned int ccr = pxs->ccr; + unsigned long c = 0; + +@@ -1501,12 +1499,6 @@ static inline int _setup_xfer_cyclic(struct pl330_dmac *pl330, unsigned dry_run, + unsigned long bursts = BYTE_TO_BURST(x->bytes, ccr); + int off = 0; + +- if (pxs->desc->rqtype == DMA_DEV_TO_MEM) +- bursts = x->bytes / (BRST_SIZE(ccr) * BRST_LEN(ccr) +- + pxs->desc->dst_interlace_size); +- else if (pxs->desc->rqtype == DMA_MEM_TO_DEV) +- bursts = x->bytes / (BRST_SIZE(ccr) * BRST_LEN(ccr) +- + pxs->desc->src_interlace_size); + /* Setup Loop(s) */ + off += _loop_cyclic(pl330, dry_run, &buf[off], bursts, pxs, ev); + +@@ -2729,6 +2721,7 @@ static struct dma_async_tx_descriptor *pl330_prep_dma_cyclic( + struct dma_pl330_desc *desc = NULL; + struct dma_pl330_chan *pch = to_pchan(chan); + struct pl330_dmac *pl330 = pch->dmac; ++ unsigned int size = 0; + dma_addr_t dst; + dma_addr_t src; + +@@ -2754,12 +2747,14 @@ static struct dma_async_tx_descriptor *pl330_prep_dma_cyclic( + desc->rqcfg.dst_inc = 0; + src = dma_addr; + dst = pch->fifo_addr; ++ size = pch->src_interlace_size; + break; + case DMA_DEV_TO_MEM: + desc->rqcfg.src_inc = 0; + desc->rqcfg.dst_inc = 1; + src = pch->fifo_addr; + dst = dma_addr; ++ size = pch->dst_interlace_size; + break; + default: + break; +@@ -2779,8 +2774,16 @@ static struct dma_async_tx_descriptor *pl330_prep_dma_cyclic( + desc->cyclic = true; + desc->num_periods = len / period_len; + desc->txd.flags = flags; ++ + desc->src_interlace_size = pch->src_interlace_size; + desc->dst_interlace_size = pch->dst_interlace_size; ++ /* refine bytes_requested if interlace_size set */ ++ if (size) { ++ size += (pch->burst_len * (1 << pch->burst_sz)); ++ size *= desc->bytes_requested; ++ size /= (pch->burst_len * (1 << pch->burst_sz)); ++ desc->bytes_requested = size; ++ } + return &desc->txd; + } + + +From b933f0eb613228472124849615f5a5e075b8b787 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 3 Jun 2018 07:36:53 +0200 +Subject: [PATCH] Revert "dmaengine: pl330: add support for interlace size + config" + +This reverts commit ddd2e87ad41e2c9e95322a1fb7d8ca65e578aa65. +--- + drivers/dma/pl330.c | 32 -------------------------------- + include/linux/dmaengine.h | 2 -- + 2 files changed, 34 deletions(-) + +diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c +index b4a0d48bafa4..babaeace0a8a 100644 +--- a/drivers/dma/pl330.c ++++ b/drivers/dma/pl330.c +@@ -447,10 +447,6 @@ struct dma_pl330_chan { + int burst_len; /* the number of burst */ + dma_addr_t fifo_addr; + +- /* interlace size */ +- unsigned int src_interlace_size; +- unsigned int dst_interlace_size; +- + /* for runtime pm tracking */ + bool active; + }; +@@ -540,9 +536,6 @@ struct dma_pl330_desc { + /* For cyclic capability */ + bool cyclic; + size_t num_periods; +- /* interlace size */ +- unsigned int src_interlace_size; +- unsigned int dst_interlace_size; + }; + + struct _xfer_spec { +@@ -1194,10 +1187,6 @@ static inline int _ldst_devtomem(struct pl330_dmac *pl330, unsigned dry_run, + if (!(pl330->quirks & PL330_QUIRK_BROKEN_NO_FLUSHP)) + off += _emit_FLUSHP(dry_run, &buf[off], + pxs->desc->peri); +- if (pxs->desc->dst_interlace_size) { +- off += _emit_ADDH(dry_run, &buf[off], DST, +- pxs->desc->dst_interlace_size); +- } + } + + return off; +@@ -1228,9 +1217,6 @@ static inline int _ldst_memtodev(struct pl330_dmac *pl330, + if (!(pl330->quirks & PL330_QUIRK_BROKEN_NO_FLUSHP)) + off += _emit_FLUSHP(dry_run, &buf[off], + pxs->desc->peri); +- if (pxs->desc->src_interlace_size) +- off += _emit_ADDH(dry_run, &buf[off], SRC, +- pxs->desc->src_interlace_size); + } + + return off; +@@ -2318,8 +2304,6 @@ static int pl330_config(struct dma_chan *chan, + pch->burst_sz = __ffs(slave_config->dst_addr_width); + if (slave_config->dst_maxburst) + pch->burst_len = slave_config->dst_maxburst; +- if (slave_config->src_interlace_size) +- pch->src_interlace_size = slave_config->src_interlace_size; + } else if (slave_config->direction == DMA_DEV_TO_MEM) { + if (slave_config->src_addr) + pch->fifo_addr = slave_config->src_addr; +@@ -2327,8 +2311,6 @@ static int pl330_config(struct dma_chan *chan, + pch->burst_sz = __ffs(slave_config->src_addr_width); + if (slave_config->src_maxburst) + pch->burst_len = slave_config->src_maxburst; +- if (slave_config->dst_interlace_size) +- pch->dst_interlace_size = slave_config->dst_interlace_size; + } + + return 0; +@@ -2721,7 +2703,6 @@ static struct dma_async_tx_descriptor *pl330_prep_dma_cyclic( + struct dma_pl330_desc *desc = NULL; + struct dma_pl330_chan *pch = to_pchan(chan); + struct pl330_dmac *pl330 = pch->dmac; +- unsigned int size = 0; + dma_addr_t dst; + dma_addr_t src; + +@@ -2747,14 +2728,12 @@ static struct dma_async_tx_descriptor *pl330_prep_dma_cyclic( + desc->rqcfg.dst_inc = 0; + src = dma_addr; + dst = pch->fifo_addr; +- size = pch->src_interlace_size; + break; + case DMA_DEV_TO_MEM: + desc->rqcfg.src_inc = 0; + desc->rqcfg.dst_inc = 1; + src = pch->fifo_addr; + dst = dma_addr; +- size = pch->dst_interlace_size; + break; + default: + break; +@@ -2775,15 +2754,6 @@ static struct dma_async_tx_descriptor *pl330_prep_dma_cyclic( + desc->num_periods = len / period_len; + desc->txd.flags = flags; + +- desc->src_interlace_size = pch->src_interlace_size; +- desc->dst_interlace_size = pch->dst_interlace_size; +- /* refine bytes_requested if interlace_size set */ +- if (size) { +- size += (pch->burst_len * (1 << pch->burst_sz)); +- size *= desc->bytes_requested; +- size /= (pch->burst_len * (1 << pch->burst_sz)); +- desc->bytes_requested = size; +- } + return &desc->txd; + } + +@@ -2920,8 +2890,6 @@ pl330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, + + desc->rqtype = direction; + desc->bytes_requested = sg_dma_len(sg); +- desc->src_interlace_size = pch->src_interlace_size; +- desc->dst_interlace_size = pch->dst_interlace_size; + } + + /* Return the last desc in the chain */ +diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h +index 3050f88daf9e..948c17e409e9 100644 +--- a/include/linux/dmaengine.h ++++ b/include/linux/dmaengine.h +@@ -365,8 +365,6 @@ struct dma_slave_config { + u32 dst_maxburst; + bool device_fc; + unsigned int slave_id; +- unsigned int src_interlace_size; +- unsigned int dst_interlace_size; + }; + + /** + +From 90870281a7399dffb49ff4d631ee9df249c3d0c0 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 4 Feb 2018 10:47:28 +0100 +Subject: [PATCH] Revert "dmaengine: pl330: fix bug that chan descdone is null" + +This reverts commit 636c30b38ae6ec499735ce7621ba474944b4e9b7. +--- + drivers/dma/pl330.c | 17 ++++++++--------- + 1 file changed, 8 insertions(+), 9 deletions(-) + +diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c +index babaeace0a8a..6e375d7ec09c 100644 +--- a/drivers/dma/pl330.c ++++ b/drivers/dma/pl330.c +@@ -1789,17 +1789,16 @@ static int pl330_update(struct pl330_dmac *pl330) + + /* Detach the req */ + descdone = thrd->req[active].desc; +- if (descdone) { +- if (!descdone->cyclic) { +- thrd->req[active].desc = NULL; +- thrd->req_running = -1; +- /* Get going again ASAP */ +- _start(thrd); +- } + +- /* For now, just make a list of callbacks to be done */ +- list_add_tail(&descdone->rqd, &pl330->req_done); ++ if (!descdone->cyclic) { ++ thrd->req[active].desc = NULL; ++ thrd->req_running = -1; ++ /* Get going again ASAP */ ++ _start(thrd); + } ++ ++ /* For now, just make a list of callbacks to be done */ ++ list_add_tail(&descdone->rqd, &pl330->req_done); + } + } + + +From ca7c03b12f7c113e9f722a02c7acebabb2cccc27 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 4 Feb 2018 10:47:38 +0100 +Subject: [PATCH] Revert "dmaengine: pl330: flush before first loop" + +This reverts commit 34be2cf4679cadbf910de9651d54b46930166446. +--- + drivers/dma/pl330.c | 12 ++---------- + 1 file changed, 2 insertions(+), 10 deletions(-) + +diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c +index 6e375d7ec09c..9664f71dbab2 100644 +--- a/drivers/dma/pl330.c ++++ b/drivers/dma/pl330.c +@@ -1351,11 +1351,7 @@ static inline int _loop_cyclic(struct pl330_dmac *pl330, unsigned dry_run, + /* forever loop */ + off += _emit_MOV(dry_run, &buf[off], SAR, x->src_addr); + off += _emit_MOV(dry_run, &buf[off], DAR, x->dst_addr); +-#ifdef CONFIG_ARCH_ROCKCHIP +- if (!(pl330->quirks & PL330_QUIRK_BROKEN_NO_FLUSHP)) +- off += _emit_FLUSHP(dry_run, &buf[off], +- pxs->desc->peri); +-#endif ++ + /* loop0 */ + off += _emit_LP(dry_run, &buf[off], 0, lcnt0); + ljmp0 = off; +@@ -1431,11 +1427,7 @@ static inline int _setup_loops(struct pl330_dmac *pl330, + u32 ccr = pxs->ccr; + unsigned long c, bursts = BYTE_TO_BURST(x->bytes, ccr); + int off = 0; +-#ifdef CONFIG_ARCH_ROCKCHIP +- if (!(pl330->quirks & PL330_QUIRK_BROKEN_NO_FLUSHP)) +- off += _emit_FLUSHP(dry_run, &buf[off], +- pxs->desc->peri); +-#endif ++ + while (bursts) { + c = bursts; + off += _loop(pl330, dry_run, &buf[off], &c, pxs); + +From 7e5d6f86b631c40624eb595910c23e7972783347 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 4 Feb 2018 10:47:51 +0100 +Subject: [PATCH] Revert "dmaengine: pl330: fix 2 bursts transfer when dma + flushes" + +This reverts commit 98753e172dc1d06cf4d61c48f5c3487df0247472. +--- + drivers/dma/pl330.c | 20 -------------------- + 1 file changed, 20 deletions(-) + +diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c +index 9664f71dbab2..9c3699ad2245 100644 +--- a/drivers/dma/pl330.c ++++ b/drivers/dma/pl330.c +@@ -1173,16 +1173,6 @@ static inline int _ldst_devtomem(struct pl330_dmac *pl330, unsigned dry_run, + off += _emit_WFP(dry_run, &buf[off], cond, pxs->desc->peri); + off += _emit_LDP(dry_run, &buf[off], cond, pxs->desc->peri); + off += _emit_ST(dry_run, &buf[off], ALWAYS); +-#ifdef CONFIG_ARCH_ROCKCHIP +- /* +- * Make suree dma has finish transmission, or later flush may +- * cause dma second transmission,and fifo is overrun. +- */ +- off += _emit_WMB(dry_run, &buf[off]); +- off += _emit_NOP(dry_run, &buf[off]); +- off += _emit_WMB(dry_run, &buf[off]); +- off += _emit_NOP(dry_run, &buf[off]); +-#endif + + if (!(pl330->quirks & PL330_QUIRK_BROKEN_NO_FLUSHP)) + off += _emit_FLUSHP(dry_run, &buf[off], +@@ -1203,16 +1193,6 @@ static inline int _ldst_memtodev(struct pl330_dmac *pl330, + off += _emit_WFP(dry_run, &buf[off], cond, pxs->desc->peri); + off += _emit_LD(dry_run, &buf[off], ALWAYS); + off += _emit_STP(dry_run, &buf[off], cond, pxs->desc->peri); +-#ifdef CONFIG_ARCH_ROCKCHIP +- /* +- * Make suree dma has finish transmission, or later flush may +- * cause dma second transmission,and fifo is overrun. +- */ +- off += _emit_WMB(dry_run, &buf[off]); +- off += _emit_NOP(dry_run, &buf[off]); +- off += _emit_WMB(dry_run, &buf[off]); +- off += _emit_NOP(dry_run, &buf[off]); +-#endif + + if (!(pl330->quirks & PL330_QUIRK_BROKEN_NO_FLUSHP)) + off += _emit_FLUSHP(dry_run, &buf[off], + +From 846d1829607d8806fd932fa3f8f4f0eb9e71d241 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sat, 21 Oct 2017 19:49:27 +0200 +Subject: [PATCH] Revert "dmaengine: pl330: _loop_cyclic fix cycles of last + loop" + +This reverts commit d7155171cbc65e45b5b0c8db03fd16fa57a181f2. +--- + drivers/dma/pl330.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c +index 9c3699ad2245..be4ea6e089ae 100644 +--- a/drivers/dma/pl330.c ++++ b/drivers/dma/pl330.c +@@ -1370,7 +1370,7 @@ static inline int _loop_cyclic(struct pl330_dmac *pl330, unsigned dry_run, + ccr &= ~(0xf << CC_SRCBRSTLEN_SHFT); + ccr &= ~(0xf << CC_DSTBRSTLEN_SHFT); + off += _emit_MOV(dry_run, &buf[off], CCR, ccr); +- off += _emit_LP(dry_run, &buf[off], 1, c); ++ off += _emit_LP(dry_run, &buf[off], 1, c - 1); + ljmp1 = off; + off += _bursts(pl330, dry_run, &buf[off], pxs, 1); + lpend.cond = ALWAYS; + +From f7fdbad73413294e56e632fa8353765b8e205582 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 4 Feb 2018 11:05:44 +0100 +Subject: [PATCH] Revert "dmaengine: pl330: pl330_tasklet init power_down by + pch->active" + +This reverts commit 796b13f24a158f14d540bcf7316d843f72242c0d. +--- + drivers/dma/pl330.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c +index be4ea6e089ae..2ba795d599fb 100644 +--- a/drivers/dma/pl330.c ++++ b/drivers/dma/pl330.c +@@ -2169,7 +2169,7 @@ static void pl330_tasklet(unsigned long data) + spin_lock(&pch->thread->dmac->lock); + _stop(pch->thread); + spin_unlock(&pch->thread->dmac->lock); +- power_down = pch->active; ++ power_down = true; + pch->active = false; + } else { + /* Make sure the PL330 Channel thread is active */ + +From 07a5172605729425390855a0b6ced66bfde22ee5 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Fri, 16 Jun 2017 23:14:54 +0200 +Subject: [PATCH] Revert "dmaengine: pl330: _loop_cyclic supports unaligned + size" + +This reverts commit 13dbe2cccd5851540af8158b12499c33801b6ef6. +--- + drivers/dma/pl330.c | 38 ++++++++++---------------------------- + 1 file changed, 10 insertions(+), 28 deletions(-) + +diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c +index 2ba795d599fb..e5b3893d441e 100644 +--- a/drivers/dma/pl330.c ++++ b/drivers/dma/pl330.c +@@ -1360,28 +1360,6 @@ static inline int _loop_cyclic(struct pl330_dmac *pl330, unsigned dry_run, + off += _emit_LPEND(dry_run, &buf[off], &lpend); + } + +- if (pl330->peripherals_req_type == BURST) { +- unsigned int ccr = pxs->ccr; +- unsigned long c = 0; +- +- c = BYTE_MOD_BURST_LEN(x->bytes, pxs->ccr); +- +- if (c) { +- ccr &= ~(0xf << CC_SRCBRSTLEN_SHFT); +- ccr &= ~(0xf << CC_DSTBRSTLEN_SHFT); +- off += _emit_MOV(dry_run, &buf[off], CCR, ccr); +- off += _emit_LP(dry_run, &buf[off], 1, c - 1); +- ljmp1 = off; +- off += _bursts(pl330, dry_run, &buf[off], pxs, 1); +- lpend.cond = ALWAYS; +- lpend.forever = false; +- lpend.loop = 1; +- lpend.bjump = off - ljmp1; +- off += _emit_LPEND(dry_run, &buf[off], &lpend); +- off += _emit_MOV(dry_run, &buf[off], CCR, pxs->ccr); +- } +- } +- + off += _emit_SEV(dry_run, &buf[off], ev); + + lpend.cond = ALWAYS; +@@ -1483,13 +1461,13 @@ static int _setup_req(struct pl330_dmac *pl330, unsigned dry_run, + + x = &pxs->desc->px; + +- if (pl330->peripherals_req_type != BURST) { +- /* Error if xfer length is not aligned at burst size */ +- if (x->bytes % (BRST_SIZE(pxs->ccr) * BRST_LEN(pxs->ccr))) +- return -EINVAL; +- } +- + if (!pxs->desc->cyclic) { ++ if (pl330->peripherals_req_type != BURST) { ++ /* Error if xfer length is not aligned at burst size */ ++ if (x->bytes % (BRST_SIZE(pxs->ccr) * BRST_LEN(pxs->ccr))) ++ return -EINVAL; ++ } ++ + off += _setup_xfer(pl330, dry_run, &buf[off], pxs); + + /* DMASEV peripheral/event */ +@@ -1497,6 +1475,10 @@ static int _setup_req(struct pl330_dmac *pl330, unsigned dry_run, + /* DMAEND */ + off += _emit_END(dry_run, &buf[off]); + } else { ++ /* Error if xfer length is not aligned at burst size */ ++ if (x->bytes % (BRST_SIZE(pxs->ccr) * BRST_LEN(pxs->ccr))) ++ return -EINVAL; ++ + off += _setup_xfer_cyclic(pl330, dry_run, &buf[off], + pxs, thrd->ev); + } + +From 5083d82f6622749e07174fe6da32e431068b59cb Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Fri, 16 Jun 2017 23:14:54 +0200 +Subject: [PATCH] Revert "dmaengine: pl330: redefine the cyclic transfer" + +This reverts commit 5f638786e66089344c9cf594b81fbf02cd794f15. +--- + drivers/dma/pl330.c | 137 +++++++++++----------------------------------------- + 1 file changed, 29 insertions(+), 108 deletions(-) + +diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c +index e5b3893d441e..38c46f4e0408 100644 +--- a/drivers/dma/pl330.c ++++ b/drivers/dma/pl330.c +@@ -1307,76 +1307,6 @@ static inline int _loop(struct pl330_dmac *pl330, unsigned dry_run, u8 buf[], + return off; + } + +-/* Returns bytes consumed */ +-static inline int _loop_cyclic(struct pl330_dmac *pl330, unsigned dry_run, +- u8 buf[], unsigned long bursts, const struct _xfer_spec *pxs, int ev) +-{ +- int cyc, off; +- unsigned lcnt0, lcnt1, ljmp0, ljmp1, ljmpfe; +- struct _arg_LPEND lpend; +- struct pl330_xfer *x = &pxs->desc->px; +- +- off = 0; +- ljmpfe = off; +- lcnt0 = pxs->desc->num_periods; +- +- if (bursts > 256) { +- lcnt1 = 256; +- cyc = bursts / 256; +- } else { +- lcnt1 = bursts; +- cyc = 1; +- } +- +- /* forever loop */ +- off += _emit_MOV(dry_run, &buf[off], SAR, x->src_addr); +- off += _emit_MOV(dry_run, &buf[off], DAR, x->dst_addr); +- +- /* loop0 */ +- off += _emit_LP(dry_run, &buf[off], 0, lcnt0); +- ljmp0 = off; +- +- /* loop1 */ +- off += _emit_LP(dry_run, &buf[off], 1, lcnt1); +- ljmp1 = off; +- off += _bursts(pl330, dry_run, &buf[off], pxs, cyc); +- lpend.cond = ALWAYS; +- lpend.forever = false; +- lpend.loop = 1; +- lpend.bjump = off - ljmp1; +- off += _emit_LPEND(dry_run, &buf[off], &lpend); +- +- /* remainder */ +- lcnt1 = bursts - (lcnt1 * cyc); +- +- if (lcnt1) { +- off += _emit_LP(dry_run, &buf[off], 1, lcnt1); +- ljmp1 = off; +- off += _bursts(pl330, dry_run, &buf[off], pxs, 1); +- lpend.cond = ALWAYS; +- lpend.forever = false; +- lpend.loop = 1; +- lpend.bjump = off - ljmp1; +- off += _emit_LPEND(dry_run, &buf[off], &lpend); +- } +- +- off += _emit_SEV(dry_run, &buf[off], ev); +- +- lpend.cond = ALWAYS; +- lpend.forever = false; +- lpend.loop = 0; +- lpend.bjump = off - ljmp0; +- off += _emit_LPEND(dry_run, &buf[off], &lpend); +- +- lpend.cond = ALWAYS; +- lpend.forever = true; +- lpend.loop = 1; +- lpend.bjump = off - ljmpfe; +- off += _emit_LPEND(dry_run, &buf[off], &lpend); +- +- return off; +-} +- + static inline int _setup_loops(struct pl330_dmac *pl330, + unsigned dry_run, u8 buf[], + const struct _xfer_spec *pxs) +@@ -1396,16 +1326,19 @@ static inline int _setup_loops(struct pl330_dmac *pl330, + } + + static inline int _setup_xfer(struct pl330_dmac *pl330, +- unsigned dry_run, u8 buf[], ++ unsigned dry_run, u8 buf[], u32 period, + const struct _xfer_spec *pxs) + { + struct pl330_xfer *x = &pxs->desc->px; ++ struct pl330_reqcfg *rqcfg = &pxs->desc->rqcfg; + int off = 0; + + /* DMAMOV SAR, x->src_addr */ +- off += _emit_MOV(dry_run, &buf[off], SAR, x->src_addr); ++ off += _emit_MOV(dry_run, &buf[off], SAR, ++ x->src_addr + rqcfg->src_inc * period * x->bytes); + /* DMAMOV DAR, x->dst_addr */ +- off += _emit_MOV(dry_run, &buf[off], DAR, x->dst_addr); ++ off += _emit_MOV(dry_run, &buf[off], DAR, ++ x->dst_addr + rqcfg->dst_inc * period * x->bytes); + + /* Setup Loop(s) */ + off += _setup_loops(pl330, dry_run, &buf[off], pxs); +@@ -1427,20 +1360,6 @@ static inline int _setup_xfer(struct pl330_dmac *pl330, + return off; + } + +-static inline int _setup_xfer_cyclic(struct pl330_dmac *pl330, unsigned dry_run, +- u8 buf[], const struct _xfer_spec *pxs, int ev) +-{ +- struct pl330_xfer *x = &pxs->desc->px; +- u32 ccr = pxs->ccr; +- unsigned long bursts = BYTE_TO_BURST(x->bytes, ccr); +- int off = 0; +- +- /* Setup Loop(s) */ +- off += _loop_cyclic(pl330, dry_run, &buf[off], bursts, pxs, ev); +- +- return off; +-} +- + /* + * A req is a sequence of one or more xfer units. + * Returns the number of bytes taken to setup the MC for the req. +@@ -1453,34 +1372,42 @@ static int _setup_req(struct pl330_dmac *pl330, unsigned dry_run, + struct pl330_xfer *x; + u8 *buf = req->mc_cpu; + int off = 0; ++ int period; ++ int again_off; + + PL330_DBGMC_START(req->mc_bus); + + /* DMAMOV CCR, ccr */ + off += _emit_MOV(dry_run, &buf[off], CCR, pxs->ccr); ++ again_off = off; + + x = &pxs->desc->px; ++ if (pl330->peripherals_req_type != BURST) { ++ /* Error if xfer length is not aligned at burst size */ ++ if (x->bytes % (BRST_SIZE(pxs->ccr) * BRST_LEN(pxs->ccr))) ++ return -EINVAL; ++ } + +- if (!pxs->desc->cyclic) { +- if (pl330->peripherals_req_type != BURST) { +- /* Error if xfer length is not aligned at burst size */ +- if (x->bytes % (BRST_SIZE(pxs->ccr) * BRST_LEN(pxs->ccr))) +- return -EINVAL; +- } +- +- off += _setup_xfer(pl330, dry_run, &buf[off], pxs); ++ for (period = 0; period < pxs->desc->num_periods; period++) { ++ off += _setup_xfer(pl330, dry_run, &buf[off], period, pxs); + + /* DMASEV peripheral/event */ + off += _emit_SEV(dry_run, &buf[off], thrd->ev); ++ } ++ ++ if (!pxs->desc->cyclic) { + /* DMAEND */ + off += _emit_END(dry_run, &buf[off]); + } else { +- /* Error if xfer length is not aligned at burst size */ +- if (x->bytes % (BRST_SIZE(pxs->ccr) * BRST_LEN(pxs->ccr))) +- return -EINVAL; +- +- off += _setup_xfer_cyclic(pl330, dry_run, &buf[off], +- pxs, thrd->ev); ++ struct _arg_LPEND lpend; ++ /* LP */ ++ off += _emit_LP(dry_run, &buf[off], 0, 255); ++ /* LPEND */ ++ lpend.cond = ALWAYS; ++ lpend.forever = false; ++ lpend.loop = 0; ++ lpend.bjump = off - again_off; ++ off += _emit_LPEND(dry_run, &buf[off], &lpend); + } + + return off; +@@ -2655,7 +2582,6 @@ static struct dma_async_tx_descriptor *pl330_prep_dma_cyclic( + { + struct dma_pl330_desc *desc = NULL; + struct dma_pl330_chan *pch = to_pchan(chan); +- struct pl330_dmac *pl330 = pch->dmac; + dma_addr_t dst; + dma_addr_t src; + +@@ -2694,12 +2620,7 @@ static struct dma_async_tx_descriptor *pl330_prep_dma_cyclic( + + desc->rqtype = direction; + desc->rqcfg.brst_size = pch->burst_sz; +- +- if (pl330->peripherals_req_type == BURST) +- desc->rqcfg.brst_len = pch->burst_len; +- else +- desc->rqcfg.brst_len = 1; +- ++ desc->rqcfg.brst_len = pch->burst_len; + desc->bytes_requested = len; + fill_px(&desc->px, dst, src, period_len); + + +From e8a5eaffda3179b78b9d1bb619ddf25dd651d134 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Fri, 16 Jun 2017 23:14:54 +0200 +Subject: [PATCH] Revert "dmaengine: pl330: make transfer run infinitely + without CPU intervention" + +This reverts commit e8a6e5086cb82d59cae6ae029b1eb4432cc62288. +--- + drivers/dma/pl330.c | 199 +++++++++++++++++++++++++++------------------------- + 1 file changed, 105 insertions(+), 94 deletions(-) + +diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c +index 38c46f4e0408..ad9d616551f8 100644 +--- a/drivers/dma/pl330.c ++++ b/drivers/dma/pl330.c +@@ -447,6 +447,9 @@ struct dma_pl330_chan { + int burst_len; /* the number of burst */ + dma_addr_t fifo_addr; + ++ /* for cyclic capability */ ++ bool cyclic; ++ + /* for runtime pm tracking */ + bool active; + }; +@@ -532,10 +535,6 @@ struct dma_pl330_desc { + unsigned peri:5; + /* Hook to attach to DMAC's list of reqs with due callback */ + struct list_head rqd; +- +- /* For cyclic capability */ +- bool cyclic; +- size_t num_periods; + }; + + struct _xfer_spec { +@@ -1326,19 +1325,16 @@ static inline int _setup_loops(struct pl330_dmac *pl330, + } + + static inline int _setup_xfer(struct pl330_dmac *pl330, +- unsigned dry_run, u8 buf[], u32 period, ++ unsigned dry_run, u8 buf[], + const struct _xfer_spec *pxs) + { + struct pl330_xfer *x = &pxs->desc->px; +- struct pl330_reqcfg *rqcfg = &pxs->desc->rqcfg; + int off = 0; + + /* DMAMOV SAR, x->src_addr */ +- off += _emit_MOV(dry_run, &buf[off], SAR, +- x->src_addr + rqcfg->src_inc * period * x->bytes); ++ off += _emit_MOV(dry_run, &buf[off], SAR, x->src_addr); + /* DMAMOV DAR, x->dst_addr */ +- off += _emit_MOV(dry_run, &buf[off], DAR, +- x->dst_addr + rqcfg->dst_inc * period * x->bytes); ++ off += _emit_MOV(dry_run, &buf[off], DAR, x->dst_addr); + + /* Setup Loop(s) */ + off += _setup_loops(pl330, dry_run, &buf[off], pxs); +@@ -1372,14 +1368,11 @@ static int _setup_req(struct pl330_dmac *pl330, unsigned dry_run, + struct pl330_xfer *x; + u8 *buf = req->mc_cpu; + int off = 0; +- int period; +- int again_off; + + PL330_DBGMC_START(req->mc_bus); + + /* DMAMOV CCR, ccr */ + off += _emit_MOV(dry_run, &buf[off], CCR, pxs->ccr); +- again_off = off; + + x = &pxs->desc->px; + if (pl330->peripherals_req_type != BURST) { +@@ -1388,27 +1381,12 @@ static int _setup_req(struct pl330_dmac *pl330, unsigned dry_run, + return -EINVAL; + } + +- for (period = 0; period < pxs->desc->num_periods; period++) { +- off += _setup_xfer(pl330, dry_run, &buf[off], period, pxs); +- +- /* DMASEV peripheral/event */ +- off += _emit_SEV(dry_run, &buf[off], thrd->ev); +- } ++ off += _setup_xfer(pl330, dry_run, &buf[off], pxs); + +- if (!pxs->desc->cyclic) { +- /* DMAEND */ +- off += _emit_END(dry_run, &buf[off]); +- } else { +- struct _arg_LPEND lpend; +- /* LP */ +- off += _emit_LP(dry_run, &buf[off], 0, 255); +- /* LPEND */ +- lpend.cond = ALWAYS; +- lpend.forever = false; +- lpend.loop = 0; +- lpend.bjump = off - again_off; +- off += _emit_LPEND(dry_run, &buf[off], &lpend); +- } ++ /* DMASEV peripheral/event */ ++ off += _emit_SEV(dry_run, &buf[off], thrd->ev); ++ /* DMAEND */ ++ off += _emit_END(dry_run, &buf[off]); + + return off; + } +@@ -1670,13 +1648,12 @@ static int pl330_update(struct pl330_dmac *pl330) + + /* Detach the req */ + descdone = thrd->req[active].desc; ++ thrd->req[active].desc = NULL; + +- if (!descdone->cyclic) { +- thrd->req[active].desc = NULL; +- thrd->req_running = -1; +- /* Get going again ASAP */ +- _start(thrd); +- } ++ thrd->req_running = -1; ++ ++ /* Get going again ASAP */ ++ _start(thrd); + + /* For now, just make a list of callbacks to be done */ + list_add_tail(&descdone->rqd, &pl330->req_done); +@@ -2049,27 +2026,12 @@ static void pl330_tasklet(unsigned long data) + spin_lock_irqsave(&pch->lock, flags); + + /* Pick up ripe tomatoes */ +- list_for_each_entry_safe(desc, _dt, &pch->work_list, node) { ++ list_for_each_entry_safe(desc, _dt, &pch->work_list, node) + if (desc->status == DONE) { +- if (!desc->cyclic) { ++ if (!pch->cyclic) + dma_cookie_complete(&desc->txd); +- list_move_tail(&desc->node, &pch->completed_list); +- } else { +- dma_async_tx_callback callback; +- void *callback_param; +- +- desc->status = BUSY; +- callback = desc->txd.callback; +- callback_param = desc->txd.callback_param; +- +- if (callback) { +- spin_unlock_irqrestore(&pch->lock, flags); +- callback(callback_param); +- spin_lock_irqsave(&pch->lock, flags); +- } +- } ++ list_move_tail(&desc->node, &pch->completed_list); + } +- } + + /* Try to submit a req imm. next to the last completed cookie */ + fill_queue(pch); +@@ -2097,8 +2059,20 @@ static void pl330_tasklet(unsigned long data) + callback = desc->txd.callback; + callback_param = desc->txd.callback_param; + +- desc->status = FREE; +- list_move_tail(&desc->node, &pch->dmac->desc_pool); ++ if (pch->cyclic) { ++ desc->status = PREP; ++ list_move_tail(&desc->node, &pch->work_list); ++ if (power_down) { ++ pch->active = true; ++ spin_lock(&pch->thread->dmac->lock); ++ _start(pch->thread); ++ spin_unlock(&pch->thread->dmac->lock); ++ power_down = false; ++ } ++ } else { ++ desc->status = FREE; ++ list_move_tail(&desc->node, &pch->dmac->desc_pool); ++ } + + dma_descriptor_unmap(&desc->txd); + +@@ -2158,6 +2132,7 @@ static int pl330_alloc_chan_resources(struct dma_chan *chan) + spin_lock_irqsave(&pl330->lock, flags); + + dma_cookie_init(chan); ++ pch->cyclic = false; + + pch->thread = pl330_request_channel(pl330); + if (!pch->thread) { +@@ -2281,7 +2256,8 @@ static void pl330_free_chan_resources(struct dma_chan *chan) + pl330_release_channel(pch->thread); + pch->thread = NULL; + +- list_splice_tail_init(&pch->work_list, &pch->dmac->desc_pool); ++ if (pch->cyclic) ++ list_splice_tail_init(&pch->work_list, &pch->dmac->desc_pool); + + spin_unlock_irqrestore(&pl330->lock, flags); + pm_runtime_mark_last_busy(pch->dmac->ddma.dev); +@@ -2335,7 +2311,7 @@ pl330_tx_status(struct dma_chan *chan, dma_cookie_t cookie, + + /* Check in pending list */ + list_for_each_entry(desc, &pch->work_list, node) { +- if (desc->status == DONE && !desc->cyclic) ++ if (desc->status == DONE) + transferred = desc->bytes_requested; + else if (running && desc == running) + transferred = +@@ -2407,8 +2383,12 @@ static dma_cookie_t pl330_tx_submit(struct dma_async_tx_descriptor *tx) + /* Assign cookies to all nodes */ + while (!list_empty(&last->node)) { + desc = list_entry(last->node.next, struct dma_pl330_desc, node); +- ++ if (pch->cyclic) { ++ desc->txd.callback = last->txd.callback; ++ desc->txd.callback_param = last->txd.callback_param; ++ } + desc->last = false; ++ + dma_cookie_assign(&desc->txd); + + list_move_tail(&desc->node, &pch->submitted_list); +@@ -2508,9 +2488,6 @@ static struct dma_pl330_desc *pl330_get_desc(struct dma_pl330_chan *pch) + desc->peri = peri_id ? pch->chan.chan_id : 0; + desc->rqcfg.pcfg = &pch->dmac->pcfg; + +- desc->cyclic = false; +- desc->num_periods = 1; +- + dma_async_tx_descriptor_init(&desc->txd, &pch->chan); + + return desc; +@@ -2580,8 +2557,10 @@ static struct dma_async_tx_descriptor *pl330_prep_dma_cyclic( + size_t period_len, enum dma_transfer_direction direction, + unsigned long flags) + { +- struct dma_pl330_desc *desc = NULL; ++ struct dma_pl330_desc *desc = NULL, *first = NULL; + struct dma_pl330_chan *pch = to_pchan(chan); ++ struct pl330_dmac *pl330 = pch->dmac; ++ unsigned int i; + dma_addr_t dst; + dma_addr_t src; + +@@ -2594,38 +2573,70 @@ static struct dma_async_tx_descriptor *pl330_prep_dma_cyclic( + return NULL; + } + +- desc = pl330_get_desc(pch); +- if (!desc) { +- dev_err(pch->dmac->ddma.dev, "%s:%d Unable to fetch desc\n", +- __func__, __LINE__); +- return NULL; +- } ++ for (i = 0; i < len / period_len; i++) { ++ desc = pl330_get_desc(pch); ++ if (!desc) { ++ dev_err(pch->dmac->ddma.dev, "%s:%d Unable to fetch desc\n", ++ __func__, __LINE__); + +- switch (direction) { +- case DMA_MEM_TO_DEV: +- desc->rqcfg.src_inc = 1; +- desc->rqcfg.dst_inc = 0; +- src = dma_addr; +- dst = pch->fifo_addr; +- break; +- case DMA_DEV_TO_MEM: +- desc->rqcfg.src_inc = 0; +- desc->rqcfg.dst_inc = 1; +- src = pch->fifo_addr; +- dst = dma_addr; +- break; +- default: +- break; ++ if (!first) ++ return NULL; ++ ++ spin_lock_irqsave(&pl330->pool_lock, flags); ++ ++ while (!list_empty(&first->node)) { ++ desc = list_entry(first->node.next, ++ struct dma_pl330_desc, node); ++ list_move_tail(&desc->node, &pl330->desc_pool); ++ } ++ ++ list_move_tail(&first->node, &pl330->desc_pool); ++ ++ spin_unlock_irqrestore(&pl330->pool_lock, flags); ++ ++ return NULL; ++ } ++ ++ switch (direction) { ++ case DMA_MEM_TO_DEV: ++ desc->rqcfg.src_inc = 1; ++ desc->rqcfg.dst_inc = 0; ++ src = dma_addr; ++ dst = pch->fifo_addr; ++ break; ++ case DMA_DEV_TO_MEM: ++ desc->rqcfg.src_inc = 0; ++ desc->rqcfg.dst_inc = 1; ++ src = pch->fifo_addr; ++ dst = dma_addr; ++ break; ++ default: ++ break; ++ } ++ ++ desc->rqtype = direction; ++ desc->rqcfg.brst_size = pch->burst_sz; ++ ++ if (pl330->peripherals_req_type == BURST) ++ desc->rqcfg.brst_len = pch->burst_len; ++ else ++ desc->rqcfg.brst_len = 1; ++ ++ desc->bytes_requested = period_len; ++ fill_px(&desc->px, dst, src, period_len); ++ ++ if (!first) ++ first = desc; ++ else ++ list_add_tail(&desc->node, &first->node); ++ ++ dma_addr += period_len; + } + +- desc->rqtype = direction; +- desc->rqcfg.brst_size = pch->burst_sz; +- desc->rqcfg.brst_len = pch->burst_len; +- desc->bytes_requested = len; +- fill_px(&desc->px, dst, src, period_len); ++ if (!desc) ++ return NULL; + +- desc->cyclic = true; +- desc->num_periods = len / period_len; ++ pch->cyclic = true; + desc->txd.flags = flags; + + return &desc->txd; + +From 0cb8495a963957245b2196e34e404472445a9d3a Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 22 Jul 2018 16:07:46 +0200 +Subject: [PATCH] Revert "dmaengine: pl330: fix error message to + dev_err_ratelimited" + +This reverts commit e25503f147cf665b6fc910983859d9f94eaf0d00. +--- + drivers/dma/pl330.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c +index ad9d616551f8..3d5d91084605 100644 +--- a/drivers/dma/pl330.c ++++ b/drivers/dma/pl330.c +@@ -1620,8 +1620,8 @@ static int pl330_update(struct pl330_dmac *pl330) + if (pl330->pcfg.num_events < 32 + && val & ~((1 << pl330->pcfg.num_events) - 1)) { + pl330->dmac_tbd.reset_dmac = true; +- dev_err_ratelimited(pl330->ddma.dev, "%s:%d Unexpected!\n", +- __func__, __LINE__); ++ dev_err(pl330->ddma.dev, "%s:%d Unexpected!\n", __func__, ++ __LINE__); + ret = 1; + goto updt_exit; + } + +From c32a7b1b9bac8450d9c0ff71b2256714ab32e5c3 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Fri, 16 Jun 2017 23:14:55 +0200 +Subject: [PATCH] Revert "dmaengine: pl330: support transfer that doesn't align + with (burst len * burst size)" + +This reverts commit c66ecf19b98ffac86177c29859e683de39f44e73. +--- + drivers/dma/pl330.c | 23 +++-------------------- + 1 file changed, 3 insertions(+), 20 deletions(-) + +diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c +index 3d5d91084605..2f5f8d40147c 100644 +--- a/drivers/dma/pl330.c ++++ b/drivers/dma/pl330.c +@@ -240,7 +240,6 @@ enum pl330_byteswap { + + #define BYTE_TO_BURST(b, ccr) ((b) / BRST_SIZE(ccr) / BRST_LEN(ccr)) + #define BURST_TO_BYTE(c, ccr) ((c) * BRST_SIZE(ccr) * BRST_LEN(ccr)) +-#define BYTE_MOD_BURST_LEN(b, ccr) (((b) / BRST_SIZE(ccr)) % BRST_LEN(ccr)) + + /* + * With 256 bytes, we can do more than 2.5MB and 5MB xfers per req +@@ -1339,20 +1338,6 @@ static inline int _setup_xfer(struct pl330_dmac *pl330, + /* Setup Loop(s) */ + off += _setup_loops(pl330, dry_run, &buf[off], pxs); + +- if (pl330->peripherals_req_type == BURST) { +- unsigned int ccr = pxs->ccr; +- unsigned long c = 0; +- +- c = BYTE_MOD_BURST_LEN(x->bytes, pxs->ccr); +- +- if (c) { +- ccr &= ~(0xf << CC_SRCBRSTLEN_SHFT); +- ccr &= ~(0xf << CC_DSTBRSTLEN_SHFT); +- off += _emit_MOV(dry_run, &buf[off], CCR, ccr); +- off += _loop(pl330, dry_run, &buf[off], &c, pxs); +- } +- } +- + return off; + } + +@@ -1375,11 +1360,9 @@ static int _setup_req(struct pl330_dmac *pl330, unsigned dry_run, + off += _emit_MOV(dry_run, &buf[off], CCR, pxs->ccr); + + x = &pxs->desc->px; +- if (pl330->peripherals_req_type != BURST) { +- /* Error if xfer length is not aligned at burst size */ +- if (x->bytes % (BRST_SIZE(pxs->ccr) * BRST_LEN(pxs->ccr))) +- return -EINVAL; +- } ++ /* Error if xfer length is not aligned at burst size */ ++ if (x->bytes % (BRST_SIZE(pxs->ccr) * BRST_LEN(pxs->ccr))) ++ return -EINVAL; + + off += _setup_xfer(pl330, dry_run, &buf[off], pxs); + + +From 8a5c2aac1f170e5d8a8cdce3ab147cf641e38981 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Fri, 16 Jun 2017 23:14:55 +0200 +Subject: [PATCH] Revert "dmaengine: pl330: add burst mode according to dts + config" + +This reverts commit 8e770f371cc27f8828cb9ceb0516adc23fe75995. +--- + drivers/dma/pl330.c | 36 ++++++++++++++---------------------- + 1 file changed, 14 insertions(+), 22 deletions(-) + +diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c +index 2f5f8d40147c..f7977979cbf5 100644 +--- a/drivers/dma/pl330.c ++++ b/drivers/dma/pl330.c +@@ -494,8 +494,6 @@ struct pl330_dmac { + /* Peripheral channels connected to this DMAC */ + unsigned int num_peripherals; + struct dma_pl330_chan *peripherals; /* keep at end */ +- /* set peripherals request type according to soc config*/ +- enum pl330_cond peripherals_req_type; + int quirks; + }; + +@@ -1165,7 +1163,12 @@ static inline int _ldst_devtomem(struct pl330_dmac *pl330, unsigned dry_run, + int cyc) + { + int off = 0; +- enum pl330_cond cond = pl330->peripherals_req_type; ++ enum pl330_cond cond; ++ ++ if (pl330->quirks & PL330_QUIRK_BROKEN_NO_FLUSHP) ++ cond = BURST; ++ else ++ cond = SINGLE; + + while (cyc--) { + off += _emit_WFP(dry_run, &buf[off], cond, pxs->desc->peri); +@@ -1185,7 +1188,12 @@ static inline int _ldst_memtodev(struct pl330_dmac *pl330, + const struct _xfer_spec *pxs, int cyc) + { + int off = 0; +- enum pl330_cond cond = pl330->peripherals_req_type; ++ enum pl330_cond cond; ++ ++ if (pl330->quirks & PL330_QUIRK_BROKEN_NO_FLUSHP) ++ cond = BURST; ++ else ++ cond = SINGLE; + + while (cyc--) { + off += _emit_WFP(dry_run, &buf[off], cond, pxs->desc->peri); +@@ -2599,12 +2607,7 @@ static struct dma_async_tx_descriptor *pl330_prep_dma_cyclic( + + desc->rqtype = direction; + desc->rqcfg.brst_size = pch->burst_sz; +- +- if (pl330->peripherals_req_type == BURST) +- desc->rqcfg.brst_len = pch->burst_len; +- else +- desc->rqcfg.brst_len = 1; +- ++ desc->rqcfg.brst_len = 1; + desc->bytes_requested = period_len; + fill_px(&desc->px, dst, src, period_len); + +@@ -2706,7 +2709,6 @@ pl330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, + { + struct dma_pl330_desc *first, *desc = NULL; + struct dma_pl330_chan *pch = to_pchan(chan); +- struct pl330_dmac *pl330 = pch->dmac; + struct scatterlist *sg; + int i; + dma_addr_t addr; +@@ -2750,12 +2752,7 @@ pl330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, + } + + desc->rqcfg.brst_size = pch->burst_sz; +- +- if (pl330->peripherals_req_type == BURST) +- desc->rqcfg.brst_len = pch->burst_len; +- else +- desc->rqcfg.brst_len = 1; +- ++ desc->rqcfg.brst_len = 1; + desc->rqtype = direction; + desc->bytes_requested = sg_dma_len(sg); + } +@@ -2851,11 +2848,6 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id) + + pl330->mcbufsz = pdat ? pdat->mcbuf_sz : 0; + +- if (of_find_property(np, "peripherals-req-type-burst", NULL)) +- pl330->peripherals_req_type = BURST; +- else +- pl330->peripherals_req_type = SINGLE; +- + /* get quirk */ + for (i = 0; i < ARRAY_SIZE(of_quirks); i++) + if (of_property_read_bool(np, of_quirks[i].quirk)) + +From 31567aa7a43385bbc429eff72855b49c90c2ac97 Mon Sep 17 00:00:00 2001 +From: Vinod Koul +Date: Tue, 5 Jul 2016 10:02:16 +0530 +Subject: [PATCH] UPSTREAM: dmaengine: pl330: explicitly freeup irq + +dmaengine device should explicitly call devm_free_irq() when using +devm_request_irq(). + +The irq is still ON when devices remove is executed and irq should be +quiesced before remove is completed. + +Signed-off-by: Vinod Koul +Cc: Jassi Brar +Cc: Linus Walleij +(cherry picked from commit 46cf94d6ab38420690d890d9922bfc61a7b3e2c5) +--- + drivers/dma/pl330.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c +index f7977979cbf5..b6793b0d53c9 100644 +--- a/drivers/dma/pl330.c ++++ b/drivers/dma/pl330.c +@@ -3015,12 +3015,18 @@ static int pl330_remove(struct amba_device *adev) + { + struct pl330_dmac *pl330 = amba_get_drvdata(adev); + struct dma_pl330_chan *pch, *_p; ++ int i, irq; + + pm_runtime_get_noresume(pl330->ddma.dev); + + if (adev->dev.of_node) + of_dma_controller_free(adev->dev.of_node); + ++ for (i = 0; i < AMBA_NR_IRQS; i++) { ++ irq = adev->irq[i]; ++ devm_free_irq(&adev->dev, irq, pl330); ++ } ++ + dma_async_device_unregister(&pl330->ddma); + + /* Idle the DMAC */ + +From ba1d527ad2e0ac6b1f60f79b6e15cd2231876367 Mon Sep 17 00:00:00 2001 +From: Stephen Barber +Date: Thu, 18 Aug 2016 17:59:59 -0700 +Subject: [PATCH] UPSTREAM: dmaengine: pl330: fix residual for non-running BUSY + descriptors + +Only one descriptor in the work list should be running at +any given time, but it's possible to have an enqueued BUSY +descriptor that has not yet transferred any data, or for +a BUSY descriptor to linger briefly before transitioning +to DONE. These cases should be handled to keep residual +calculations consistent even with the non-running BUSY +descriptors in the work list. + +Signed-off-by: Stephen Barber +Signed-off-by: Vinod Koul +(cherry picked from commit d64e9a2c750930272492952c16f3f2c95311a6c9) +--- + drivers/dma/pl330.c | 13 ++++++++++++- + 1 file changed, 12 insertions(+), 1 deletion(-) + +diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c +index b6793b0d53c9..7e05ef5ba37f 100644 +--- a/drivers/dma/pl330.c ++++ b/drivers/dma/pl330.c +@@ -2283,7 +2283,7 @@ pl330_tx_status(struct dma_chan *chan, dma_cookie_t cookie, + { + enum dma_status ret; + unsigned long flags; +- struct dma_pl330_desc *desc, *running = NULL; ++ struct dma_pl330_desc *desc, *running = NULL, *last_enq = NULL; + struct dma_pl330_chan *pch = to_pchan(chan); + unsigned int transferred, residual = 0; + +@@ -2300,6 +2300,8 @@ pl330_tx_status(struct dma_chan *chan, dma_cookie_t cookie, + if (pch->thread->req_running != -1) + running = pch->thread->req[pch->thread->req_running].desc; + ++ last_enq = pch->thread->req[pch->thread->lstenq].desc; ++ + /* Check in pending list */ + list_for_each_entry(desc, &pch->work_list, node) { + if (desc->status == DONE) +@@ -2307,6 +2309,15 @@ pl330_tx_status(struct dma_chan *chan, dma_cookie_t cookie, + else if (running && desc == running) + transferred = + pl330_get_current_xferred_count(pch, desc); ++ else if (desc->status == BUSY) ++ /* ++ * Busy but not running means either just enqueued, ++ * or finished and not yet marked done ++ */ ++ if (desc == last_enq) ++ transferred = 0; ++ else ++ transferred = desc->bytes_requested; + else + transferred = 0; + residual += desc->bytes_requested - transferred; + +From c6ddb1c340be89262163fc1f1ddbeff2b7adac7c Mon Sep 17 00:00:00 2001 +From: Hsin-Yu Chao +Date: Tue, 23 Aug 2016 17:16:55 +0800 +Subject: [PATCH] UPSTREAM: dmaengine: pl330: Acquire dmac's spinlock in + pl330_tx_status + +There is a racing when accessing dmac thread in pl330_tx_status that +the pl330_update is handling active request at the same time and +changing the status of descriptors. This could cause an invalid +transferred count from BUSY descriptor added up to the residual number. +Fix the bug by using the dmac's spinlock in pl330_tx_status to protect +thread resources from changing. +Note that the nested order of holding dmac's and dma_chan's spinlock is +consistent with the rest of the driver: dma_chan first and then dmac, +so it is safe from deadlock scenario. + +Signed-off-by: Hsin-Yu Chao +Reviewed-by: Guenter Roeck +Signed-off-by: Vinod Koul +(cherry picked from commit a40235a2278a315261ee007fc433ec1cfb31666f) +--- + drivers/dma/pl330.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c +index 7e05ef5ba37f..93efdcc54f19 100644 +--- a/drivers/dma/pl330.c ++++ b/drivers/dma/pl330.c +@@ -2296,6 +2296,7 @@ pl330_tx_status(struct dma_chan *chan, dma_cookie_t cookie, + goto out; + + spin_lock_irqsave(&pch->lock, flags); ++ spin_lock(&pch->thread->dmac->lock); + + if (pch->thread->req_running != -1) + running = pch->thread->req[pch->thread->req_running].desc; +@@ -2338,6 +2339,7 @@ pl330_tx_status(struct dma_chan *chan, dma_cookie_t cookie, + if (desc->last) + residual = 0; + } ++ spin_unlock(&pch->thread->dmac->lock); + spin_unlock_irqrestore(&pch->lock, flags); + + out: + +From a2bd9dfc9421a44c86ad35c6b29fc28534917553 Mon Sep 17 00:00:00 2001 +From: Stephen Barber +Date: Tue, 1 Nov 2016 16:44:27 -0700 +Subject: [PATCH] UPSTREAM: dmaengine: pl330: Handle xferred count if DMAMOV + hasn't finished + +After executing DMAGO it's possible that a request can come in for the +current xferred count, but if that happens too soon then DMAMOV SAR/DAR +may not have yet completed. If that happens, we should explicitly return 0 +since nothing has been transferred yet. + +Signed-off-by: Stephen Barber +Signed-off-by: Vinod Koul +(cherry picked from commit c44da03dd517c11c2b3525937b0a241fc1c69399) +--- + drivers/dma/pl330.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c +index 93efdcc54f19..497cc048feaa 100644 +--- a/drivers/dma/pl330.c ++++ b/drivers/dma/pl330.c +@@ -2274,6 +2274,11 @@ static int pl330_get_current_xferred_count(struct dma_pl330_chan *pch, + } + pm_runtime_mark_last_busy(pch->dmac->ddma.dev); + pm_runtime_put_autosuspend(pl330->ddma.dev); ++ ++ /* If DMAMOV hasn't finished yet, SAR/DAR can be zero */ ++ if (!val) ++ return 0; ++ + return val - addr; + } + + +From 166204f617a83115d81ffdf34329757b4b1f9fb0 Mon Sep 17 00:00:00 2001 +From: Vladimir Murzin +Date: Wed, 7 Dec 2016 13:17:40 +0000 +Subject: [PATCH] UPSTREAM: dmaengine: pl330: do not generate unaligned access + +When PL330 is used with !MMU the following fault is seen: + +Unhandled fault: alignment exception (0x801) at 0x8f26a002 +Internal error: : 801 [#1] ARM +Modules linked in: +CPU: 0 PID: 640 Comm: dma0chan0-copy0 Not tainted 4.8.0-6a82063-clean+ #1600 +Hardware name: ARM-Versatile Express +task: 8f1baa80 task.stack: 8e6fe000 +PC is at _setup_req+0x4c/0x350 +LR is at 0x8f2cbc00 +pc : [<801ea538>] lr : [<8f2cbc00>] psr: 60000093 +sp : 8e6ffdc0 ip : 00000000 fp : 00000000 +r10: 00000000 r9 : 8f2cba10 r8 : 8f2cbc00 +r7 : 80000013 r6 : 8f21a050 r5 : 8f21a000 r4 : 8f2ac800 +r3 : 8e6ffe18 r2 : 00944251 r1 : ffffffbc r0 : 8f26a000 +Flags: nZCv IRQs off FIQs on Mode SVC_32 ISA ARM Segment none +Control: 00c5387c +Process dma0chan0-copy0 (pid: 640, stack limit = 0x8e6fe210) +Stack: (0x8e6ffdc0 to 0x8e700000) +fdc0: 00000001 60000093 00000000 8f2cba10 8f26a000 00000004 8f0ae000 8f2cbc00 +fde0: 8f0ae000 8f2ac800 8f21a000 8f21a050 80000013 8f2cbc00 8f2cba10 00000000 +fe00: 60000093 801ebca0 8e6ffe18 000013ff 40000093 00000000 00944251 8f2ac800 +fe20: a0000013 8f2b1320 00001986 00000000 00000001 000013ff 8f1e4f00 8f2cba10 +fe40: 8e6fff6c 801e9044 00000003 00000000 fef98c80 002faf07 8e6ffe7c 00000000 +fe60: 00000002 00000000 00001986 8f1f158d 8f1e4f00 80568de4 00000002 00000000 +fe80: 00001986 8f1f53ff 40000001 80580500 8f1f158d 8001e00c 00000000 cfdfdfdf +fea0: fdae2a25 00000001 00000004 8e6fe000 00000008 00000010 00000000 00000005 +fec0: 8f2b1330 8f2b1334 8e6ffe80 8e6ffe8c 00001986 00000000 8f21a014 00000001 +fee0: 8e6ffe60 8e6ffe78 00000002 00000000 000013ff 00000001 80568de4 8f1e8018 +ff00: 0000158d 8055ec30 00000001 803f6b00 00001986 8f2cba10 fdae2a25 00000001 +ff20: 8f1baca8 8e6fff24 8e6fff24 00000000 8e6fff24 ac6f3037 00000000 00000000 +ff40: 00000000 8e6fe000 8f1e4f40 00000000 8f1e4f40 8f1e4f00 801e84ec 00000000 +ff60: 00000000 00000000 00000000 80031714 dfdfdfcf 00000000 dfdfdfcf 8f1e4f00 +ff80: 00000000 8e6fff84 8e6fff84 00000000 8e6fff90 8e6fff90 8e6fffac 8f1e4f40 +ffa0: 80031640 00000000 00000000 8000f548 00000000 00000000 00000000 00000000 +ffc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 +ffe0: 00000000 00000000 00000000 00000000 00000013 00000000 dfdfdfcf cfdfdfdf +[<801ea538>] (_setup_req) from [<801ebca0>] (pl330_tasklet+0x41c/0x490) +[<801ebca0>] (pl330_tasklet) from [<801e9044>] (dmatest_func+0xb58/0x149c) +[<801e9044>] (dmatest_func) from [<80031714>] (kthread+0xd4/0xec) +[<80031714>] (kthread) from [<8000f548>] (ret_from_fork+0x14/0x2c) +Code: e3a03001 e3e01043 e5c03001 e59d3048 (e5802002) + +This happens because _emit_{ADDH,MOV,GO) accessing to unaligned data +while writing to buffer. Fix it with writing to buffer byte by byte. + +Reviewed-by: Robin Murphy +Tested-by: Robin Murphy +Signed-off-by: Vladimir Murzin +Signed-off-by: Vinod Koul +(cherry picked from commit d07c9e1e212c9687f9198bfeba582e86cae3f6f9) +--- + drivers/dma/pl330.c | 15 ++++++++++----- + 1 file changed, 10 insertions(+), 5 deletions(-) + +diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c +index 497cc048feaa..eb274eeda0aa 100644 +--- a/drivers/dma/pl330.c ++++ b/drivers/dma/pl330.c +@@ -573,7 +573,8 @@ static inline u32 _emit_ADDH(unsigned dry_run, u8 buf[], + + buf[0] = CMD_DMAADDH; + buf[0] |= (da << 1); +- *((__le16 *)&buf[1]) = cpu_to_le16(val); ++ buf[1] = val; ++ buf[2] = val >> 8; + + PL330_DBGCMD_DUMP(SZ_DMAADDH, "\tDMAADDH %s %u\n", + da == 1 ? "DA" : "SA", val); +@@ -727,7 +728,10 @@ static inline u32 _emit_MOV(unsigned dry_run, u8 buf[], + + buf[0] = CMD_DMAMOV; + buf[1] = dst; +- *((__le32 *)&buf[2]) = cpu_to_le32(val); ++ buf[2] = val; ++ buf[3] = val >> 8; ++ buf[4] = val >> 16; ++ buf[5] = val >> 24; + + PL330_DBGCMD_DUMP(SZ_DMAMOV, "\tDMAMOV %s 0x%x\n", + dst == SAR ? "SAR" : (dst == DAR ? "DAR" : "CCR"), val); +@@ -902,10 +906,11 @@ static inline u32 _emit_GO(unsigned dry_run, u8 buf[], + + buf[0] = CMD_DMAGO; + buf[0] |= (ns << 1); +- + buf[1] = chan & 0x7; +- +- *((__le32 *)&buf[2]) = cpu_to_le32(addr); ++ buf[2] = addr; ++ buf[3] = addr >> 8; ++ buf[4] = addr >> 16; ++ buf[5] = addr >> 24; + + return SZ_DMAGO; + } + +From 50165cc7de07efd5986eeb604bbefe6328a142c4 Mon Sep 17 00:00:00 2001 +From: Vinod Koul +Date: Fri, 9 Dec 2016 15:24:12 +0530 +Subject: [PATCH] =?UTF-8?q?UPSTREAM:=20dmaengine:=20pl330:=20remove=20unus?= + =?UTF-8?q?ed=20=E2=80=98regs=E2=80=99?= +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +In pl330_add(), variable ‘regs’ is initialized but never used, which +leads to warning with W=1. + +drivers/dma/pl330.c: In function 'pl330_add': +drivers/dma/pl330.c:1891:16: warning: variable 'regs' set but not used [-Wunused-but-set-variable] + +So remove it. + +Cc: Linus Walleij +Signed-off-by: Vinod Koul +(cherry picked from commit 920e00d62ef9a818a4af7b2f9e1dbca23f846fc1) +--- + drivers/dma/pl330.c | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c +index eb274eeda0aa..14efb0e4a6a8 100644 +--- a/drivers/dma/pl330.c ++++ b/drivers/dma/pl330.c +@@ -1889,11 +1889,8 @@ static int dmac_alloc_resources(struct pl330_dmac *pl330) + + static int pl330_add(struct pl330_dmac *pl330) + { +- void __iomem *regs; + int i, ret; + +- regs = pl330->base; +- + /* Check if we can handle this DMAC */ + if ((pl330->pcfg.periph_id & 0xfffff) != PERIPH_ID_VAL) { + dev_err(pl330->ddma.dev, "PERIPH_ID 0x%x !\n", + +From 9d2bcf1dd31ccb4cf3486deeda428b5e4211aff7 Mon Sep 17 00:00:00 2001 +From: Marek Szyprowski +Date: Mon, 27 Mar 2017 07:31:03 +0200 +Subject: [PATCH] UPSTREAM: dmaengine: pl330: remove pdata based initialization + +This driver is now used only on platforms which support device tree, so +it is safe to remove legacy platform data based initialization code. + +Signed-off-by: Marek Szyprowski +Reviewed-by: Ulf Hansson +Acked-by: Arnd Bergmann +For plat-samsung: +Acked-by: Krzysztof Kozlowski +Signed-off-by: Vinod Koul +(cherry picked from commit e8bb4673596ea28fab287dbc417e8100d798cd40) +--- + arch/arm/plat-samsung/devs.c | 1 - + drivers/dma/pl330.c | 42 ++++++++---------------------------------- + include/linux/amba/pl330.h | 35 ----------------------------------- + 3 files changed, 8 insertions(+), 70 deletions(-) + delete mode 100644 include/linux/amba/pl330.h + +diff --git a/arch/arm/plat-samsung/devs.c b/arch/arm/plat-samsung/devs.c +index e212f9d804bd..2ef19ad5cb62 100644 +--- a/arch/arm/plat-samsung/devs.c ++++ b/arch/arm/plat-samsung/devs.c +@@ -10,7 +10,6 @@ + * published by the Free Software Foundation. + */ + +-#include + #include + #include + #include +diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c +index 14efb0e4a6a8..8d6c483663dc 100644 +--- a/drivers/dma/pl330.c ++++ b/drivers/dma/pl330.c +@@ -22,7 +22,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -2084,18 +2083,6 @@ static void pl330_tasklet(unsigned long data) + } + } + +-bool pl330_filter(struct dma_chan *chan, void *param) +-{ +- u8 *peri_id; +- +- if (chan->device->dev->driver != &pl330_driver.drv) +- return false; +- +- peri_id = chan->private; +- return *peri_id == (unsigned long)param; +-} +-EXPORT_SYMBOL(pl330_filter); +- + static struct dma_chan *of_dma_pl330_xlate(struct of_phandle_args *dma_spec, + struct of_dma *ofdma) + { +@@ -2840,7 +2827,6 @@ static SIMPLE_DEV_PM_OPS(pl330_pm, pl330_suspend, pl330_resume); + static int + pl330_probe(struct amba_device *adev, const struct amba_id *id) + { +- struct dma_pl330_platdata *pdat; + struct pl330_config *pcfg; + struct pl330_dmac *pl330; + struct dma_pl330_chan *pch, *_p; +@@ -2850,8 +2836,6 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id) + int num_chan; + struct device_node *np = adev->dev.of_node; + +- pdat = dev_get_platdata(&adev->dev); +- + ret = dma_set_mask_and_coherent(&adev->dev, DMA_BIT_MASK(32)); + if (ret) + return ret; +@@ -2866,7 +2850,7 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id) + pd = &pl330->ddma; + pd->dev = &adev->dev; + +- pl330->mcbufsz = pdat ? pdat->mcbuf_sz : 0; ++ pl330->mcbufsz = 0; + + /* get quirk */ + for (i = 0; i < ARRAY_SIZE(of_quirks); i++) +@@ -2910,10 +2894,7 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id) + INIT_LIST_HEAD(&pd->channels); + + /* Initialize channel parameters */ +- if (pdat) +- num_chan = max_t(int, pdat->nr_valid_peri, pcfg->num_chan); +- else +- num_chan = max_t(int, pcfg->num_peri, pcfg->num_chan); ++ num_chan = max_t(int, pcfg->num_peri, pcfg->num_chan); + + pl330->num_peripherals = num_chan; + +@@ -2926,11 +2907,8 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id) + + for (i = 0; i < num_chan; i++) { + pch = &pl330->peripherals[i]; +- if (!adev->dev.of_node) +- pch->chan.private = pdat ? &pdat->peri_id[i] : NULL; +- else +- pch->chan.private = adev->dev.of_node; + ++ pch->chan.private = adev->dev.of_node; + INIT_LIST_HEAD(&pch->submitted_list); + INIT_LIST_HEAD(&pch->work_list); + INIT_LIST_HEAD(&pch->completed_list); +@@ -2943,15 +2921,11 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id) + list_add_tail(&pch->chan.device_node, &pd->channels); + } + +- if (pdat) { +- pd->cap_mask = pdat->cap_mask; +- } else { +- dma_cap_set(DMA_MEMCPY, pd->cap_mask); +- if (pcfg->num_peri) { +- dma_cap_set(DMA_SLAVE, pd->cap_mask); +- dma_cap_set(DMA_CYCLIC, pd->cap_mask); +- dma_cap_set(DMA_PRIVATE, pd->cap_mask); +- } ++ dma_cap_set(DMA_MEMCPY, pd->cap_mask); ++ if (pcfg->num_peri) { ++ dma_cap_set(DMA_SLAVE, pd->cap_mask); ++ dma_cap_set(DMA_CYCLIC, pd->cap_mask); ++ dma_cap_set(DMA_PRIVATE, pd->cap_mask); + } + + pd->device_alloc_chan_resources = pl330_alloc_chan_resources; +diff --git a/include/linux/amba/pl330.h b/include/linux/amba/pl330.h +deleted file mode 100644 +index fe93758e8403..000000000000 +--- a/include/linux/amba/pl330.h ++++ /dev/null +@@ -1,35 +0,0 @@ +-/* linux/include/linux/amba/pl330.h +- * +- * Copyright (C) 2010 Samsung Electronics Co. Ltd. +- * Jaswinder Singh +- * +- * This program is free software; you can redistribute it and/or modify +- * it under the terms of the GNU General Public License as published by +- * the Free Software Foundation; either version 2 of the License, or +- * (at your option) any later version. +- */ +- +-#ifndef __AMBA_PL330_H_ +-#define __AMBA_PL330_H_ +- +-#include +- +-struct dma_pl330_platdata { +- /* +- * Number of valid peripherals connected to DMAC. +- * This may be different from the value read from +- * CR0, as the PL330 implementation might have 'holes' +- * in the peri list or the peri could also be reached +- * from another DMAC which the platform prefers. +- */ +- u8 nr_valid_peri; +- /* Array of valid peripherals */ +- u8 *peri_id; +- /* Operational capabilities */ +- dma_cap_mask_t cap_mask; +- /* Bytes to allocate for MC buffer */ +- unsigned mcbuf_sz; +-}; +- +-extern bool pl330_filter(struct dma_chan *chan, void *param); +-#endif /* __AMBA_PL330_H_ */ + +From 4ecadbeac3bbd8cd7e2377681b458a4036c33233 Mon Sep 17 00:00:00 2001 +From: Jean-Philippe Brucker +Date: Thu, 1 Jun 2017 19:22:01 +0100 +Subject: [PATCH] UPSTREAM: dmaengine: pl330: fix warning in pl330_remove + +When removing a device with less than 9 IRQs (AMBA_NR_IRQS), we'll get a +big WARN_ON from devres.c because pl330_remove calls devm_free_irqs for +unallocated irqs. Similarly to pl330_probe, check that IRQ number is +present before calling devm_free_irq. + +Signed-off-by: Jean-Philippe Brucker +Signed-off-by: Vinod Koul +(cherry picked from commit ebcdaee4cebb3a8d0d702ab5e9392373672ec1de) +--- + drivers/dma/pl330.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c +index 8d6c483663dc..f6a4a89ae8aa 100644 +--- a/drivers/dma/pl330.c ++++ b/drivers/dma/pl330.c +@@ -3018,7 +3018,8 @@ static int pl330_remove(struct amba_device *adev) + + for (i = 0; i < AMBA_NR_IRQS; i++) { + irq = adev->irq[i]; +- devm_free_irq(&adev->dev, irq, pl330); ++ if (irq) ++ devm_free_irq(&adev->dev, irq, pl330); + } + + dma_async_device_unregister(&pl330->ddma); + +From 062d0ddfbc9c08f971870e6ce8636a06b5b6d4d7 Mon Sep 17 00:00:00 2001 +From: Matthias Kaehlcke +Date: Thu, 15 Jun 2017 16:55:57 -0700 +Subject: [PATCH] UPSTREAM: dmaengine: pl330: Delete unused functions + +The functions _queue_empty(), _emit_ADDH(), _emit_NOP(), _emit_STZ() +and _emit_WFE() are not used. Delete them. + +Signed-off-by: Matthias Kaehlcke +Signed-off-by: Vinod Koul +(cherry picked from commit d43674ecc002b49926f216cb414cff2d230ca3fb) +--- + drivers/dma/pl330.c | 67 ----------------------------------------------------- + 1 file changed, 67 deletions(-) + +diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c +index f6a4a89ae8aa..bd4a0c3deaf6 100644 +--- a/drivers/dma/pl330.c ++++ b/drivers/dma/pl330.c +@@ -538,11 +538,6 @@ struct _xfer_spec { + struct dma_pl330_desc *desc; + }; + +-static inline bool _queue_empty(struct pl330_thread *thrd) +-{ +- return thrd->req[0].desc == NULL && thrd->req[1].desc == NULL; +-} +- + static inline bool _queue_full(struct pl330_thread *thrd) + { + return thrd->req[0].desc != NULL && thrd->req[1].desc != NULL; +@@ -564,23 +559,6 @@ static inline u32 get_revision(u32 periph_id) + return (periph_id >> PERIPH_REV_SHIFT) & PERIPH_REV_MASK; + } + +-static inline u32 _emit_ADDH(unsigned dry_run, u8 buf[], +- enum pl330_dst da, u16 val) +-{ +- if (dry_run) +- return SZ_DMAADDH; +- +- buf[0] = CMD_DMAADDH; +- buf[0] |= (da << 1); +- buf[1] = val; +- buf[2] = val >> 8; +- +- PL330_DBGCMD_DUMP(SZ_DMAADDH, "\tDMAADDH %s %u\n", +- da == 1 ? "DA" : "SA", val); +- +- return SZ_DMAADDH; +-} +- + static inline u32 _emit_END(unsigned dry_run, u8 buf[]) + { + if (dry_run) +@@ -738,18 +716,6 @@ static inline u32 _emit_MOV(unsigned dry_run, u8 buf[], + return SZ_DMAMOV; + } + +-static inline u32 _emit_NOP(unsigned dry_run, u8 buf[]) +-{ +- if (dry_run) +- return SZ_DMANOP; +- +- buf[0] = CMD_DMANOP; +- +- PL330_DBGCMD_DUMP(SZ_DMANOP, "\tDMANOP\n"); +- +- return SZ_DMANOP; +-} +- + static inline u32 _emit_RMB(unsigned dry_run, u8 buf[]) + { + if (dry_run) +@@ -817,39 +783,6 @@ static inline u32 _emit_STP(unsigned dry_run, u8 buf[], + return SZ_DMASTP; + } + +-static inline u32 _emit_STZ(unsigned dry_run, u8 buf[]) +-{ +- if (dry_run) +- return SZ_DMASTZ; +- +- buf[0] = CMD_DMASTZ; +- +- PL330_DBGCMD_DUMP(SZ_DMASTZ, "\tDMASTZ\n"); +- +- return SZ_DMASTZ; +-} +- +-static inline u32 _emit_WFE(unsigned dry_run, u8 buf[], u8 ev, +- unsigned invalidate) +-{ +- if (dry_run) +- return SZ_DMAWFE; +- +- buf[0] = CMD_DMAWFE; +- +- ev &= 0x1f; +- ev <<= 3; +- buf[1] = ev; +- +- if (invalidate) +- buf[1] |= (1 << 1); +- +- PL330_DBGCMD_DUMP(SZ_DMAWFE, "\tDMAWFE %u%s\n", +- ev >> 3, invalidate ? ", I" : ""); +- +- return SZ_DMAWFE; +-} +- + static inline u32 _emit_WFP(unsigned dry_run, u8 buf[], + enum pl330_cond cond, u8 peri) + { + +From 5d7da5fbd04fb60500162c823056b836c78ba397 Mon Sep 17 00:00:00 2001 +From: Arvind Yadav +Date: Wed, 23 Aug 2017 21:57:31 +0530 +Subject: [PATCH] UPSTREAM: dmaengine: pl330: constify amba_id + +amba_id are not supposed to change at runtime. All functions +working with const amba_id. So mark the non-const structs as const. + +Signed-off-by: Arvind Yadav +Signed-off-by: Vinod Koul +(cherry picked from commit b753351ec8f4c6a25c6d9b5c4eccce62e448a571) +--- + drivers/dma/pl330.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c +index bd4a0c3deaf6..63ffb8d1f885 100644 +--- a/drivers/dma/pl330.c ++++ b/drivers/dma/pl330.c +@@ -2976,7 +2976,7 @@ static int pl330_remove(struct amba_device *adev) + return 0; + } + +-static struct amba_id pl330_ids[] = { ++static const struct amba_id pl330_ids[] = { + { + .id = 0x00041330, + .mask = 0x000fffff, + +From 79dd0f02e59662d1f1ce0b118280356ed9e63d65 Mon Sep 17 00:00:00 2001 +From: Alexander Kochetkov +Date: Wed, 4 Oct 2017 14:37:23 +0300 +Subject: [PATCH] UPSTREAM: dmaengine: pl330: fix descriptor allocation fail + +If two concurrent threads call pl330_get_desc() when DMAC descriptor +pool is empty it is possible that allocation for one of threads will fail +with message: + +kernel: dma-pl330 20078000.dma-controller: pl330_get_desc:2469 ALERT! + +Here how that can happen. Thread A calls pl330_get_desc() to get +descriptor. If DMAC descriptor pool is empty pl330_get_desc() allocates +new descriptor on shared pool using add_desc() and then get newly +allocated descriptor using pluck_desc(). At the same time thread B calls +pluck_desc() and take newly allocated descriptor. In that case descriptor +allocation for thread A will fail. + +Using on-stack pool for new descriptor allow avoid the issue described. +The patch modify pl330_get_desc() to use on-stack pool for allocation +new descriptors. + +Signed-off-by: Alexander Kochetkov +Tested-by: Marek Szyprowski +Signed-off-by: Vinod Koul +(cherry picked from commit e588710311ee5bece284871d613418831d56f2bd) +--- + drivers/dma/pl330.c | 39 ++++++++++++++++++++------------------- + 1 file changed, 20 insertions(+), 19 deletions(-) + +diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c +index 63ffb8d1f885..257492238cea 100644 +--- a/drivers/dma/pl330.c ++++ b/drivers/dma/pl330.c +@@ -2344,7 +2344,8 @@ static inline void _init_desc(struct dma_pl330_desc *desc) + } + + /* Returns the number of descriptors added to the DMAC pool */ +-static int add_desc(struct pl330_dmac *pl330, gfp_t flg, int count) ++static int add_desc(struct list_head *pool, spinlock_t *lock, ++ gfp_t flg, int count) + { + struct dma_pl330_desc *desc; + unsigned long flags; +@@ -2354,27 +2355,28 @@ static int add_desc(struct pl330_dmac *pl330, gfp_t flg, int count) + if (!desc) + return 0; + +- spin_lock_irqsave(&pl330->pool_lock, flags); ++ spin_lock_irqsave(lock, flags); + + for (i = 0; i < count; i++) { + _init_desc(&desc[i]); +- list_add_tail(&desc[i].node, &pl330->desc_pool); ++ list_add_tail(&desc[i].node, pool); + } + +- spin_unlock_irqrestore(&pl330->pool_lock, flags); ++ spin_unlock_irqrestore(lock, flags); + + return count; + } + +-static struct dma_pl330_desc *pluck_desc(struct pl330_dmac *pl330) ++static struct dma_pl330_desc *pluck_desc(struct list_head *pool, ++ spinlock_t *lock) + { + struct dma_pl330_desc *desc = NULL; + unsigned long flags; + +- spin_lock_irqsave(&pl330->pool_lock, flags); ++ spin_lock_irqsave(lock, flags); + +- if (!list_empty(&pl330->desc_pool)) { +- desc = list_entry(pl330->desc_pool.next, ++ if (!list_empty(pool)) { ++ desc = list_entry(pool->next, + struct dma_pl330_desc, node); + + list_del_init(&desc->node); +@@ -2383,7 +2385,7 @@ static struct dma_pl330_desc *pluck_desc(struct pl330_dmac *pl330) + desc->txd.callback = NULL; + } + +- spin_unlock_irqrestore(&pl330->pool_lock, flags); ++ spin_unlock_irqrestore(lock, flags); + + return desc; + } +@@ -2395,20 +2397,18 @@ static struct dma_pl330_desc *pl330_get_desc(struct dma_pl330_chan *pch) + struct dma_pl330_desc *desc; + + /* Pluck one desc from the pool of DMAC */ +- desc = pluck_desc(pl330); ++ desc = pluck_desc(&pl330->desc_pool, &pl330->pool_lock); + + /* If the DMAC pool is empty, alloc new */ + if (!desc) { +- if (!add_desc(pl330, GFP_ATOMIC, 1)) +- return NULL; ++ DEFINE_SPINLOCK(lock); ++ LIST_HEAD(pool); + +- /* Try again */ +- desc = pluck_desc(pl330); +- if (!desc) { +- dev_err(pch->dmac->ddma.dev, +- "%s:%d ALERT!\n", __func__, __LINE__); ++ if (!add_desc(&pool, &lock, GFP_ATOMIC, 1)) + return NULL; +- } ++ ++ desc = pluck_desc(&pool, &lock); ++ WARN_ON(!desc || !list_empty(&pool)); + } + + /* Initialize the descriptor */ +@@ -2821,7 +2821,8 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id) + spin_lock_init(&pl330->pool_lock); + + /* Create a descriptor pool of default size */ +- if (!add_desc(pl330, GFP_KERNEL, NR_DEFAULT_DESC)) ++ if (!add_desc(&pl330->desc_pool, &pl330->pool_lock, ++ GFP_KERNEL, NR_DEFAULT_DESC)) + dev_warn(&adev->dev, "unable to allocate desc\n"); + + INIT_LIST_HEAD(&pd->channels); + +From a285cd8b8945bbe899f23e90c98d54249903e7bf Mon Sep 17 00:00:00 2001 +From: Frank Mori Hess +Date: Wed, 18 Apr 2018 20:31:06 -0400 +Subject: [PATCH] UPSTREAM: dmaengine: pl330: flush before wait, and add dev + burst support. + +Do DMAFLUSHP _before_ the first DMAWFP to ensure controller +and peripheral are in agreement about dma request state before first +transfer. Add support for burst transfers to/from peripherals. In the new +scheme, the controller does as many burst transfers as it can then +transfers the remaining dregs with either single transfers for +peripherals, or with a reduced size burst for memory-to-memory transfers. + +Signed-off-by: Frank Mori Hess +Tested-by: Frank Mori Hess +Signed-off-by: Vinod Koul +(cherry picked from commit 1d48745b192a7a45bbdd3557b4c039609569ca41) +--- + drivers/dma/pl330.c | 209 +++++++++++++++++++++++++++++++++++++++------------- + 1 file changed, 159 insertions(+), 50 deletions(-) + +diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c +index 257492238cea..fd48c031ead8 100644 +--- a/drivers/dma/pl330.c ++++ b/drivers/dma/pl330.c +@@ -27,6 +27,7 @@ + #include + #include + #include ++#include + + #include "dmaengine.h" + #define PL330_MAX_CHAN 8 +@@ -1095,51 +1096,96 @@ static inline int _ldst_memtomem(unsigned dry_run, u8 buf[], + return off; + } + +-static inline int _ldst_devtomem(struct pl330_dmac *pl330, unsigned dry_run, +- u8 buf[], const struct _xfer_spec *pxs, +- int cyc) ++static u32 _emit_load(unsigned int dry_run, u8 buf[], ++ enum pl330_cond cond, enum dma_transfer_direction direction, ++ u8 peri) + { + int off = 0; +- enum pl330_cond cond; + +- if (pl330->quirks & PL330_QUIRK_BROKEN_NO_FLUSHP) +- cond = BURST; +- else +- cond = SINGLE; ++ switch (direction) { ++ case DMA_MEM_TO_MEM: ++ /* fall through */ ++ case DMA_MEM_TO_DEV: ++ off += _emit_LD(dry_run, &buf[off], cond); ++ break; + +- while (cyc--) { +- off += _emit_WFP(dry_run, &buf[off], cond, pxs->desc->peri); +- off += _emit_LDP(dry_run, &buf[off], cond, pxs->desc->peri); +- off += _emit_ST(dry_run, &buf[off], ALWAYS); ++ case DMA_DEV_TO_MEM: ++ if (cond == ALWAYS) { ++ off += _emit_LDP(dry_run, &buf[off], SINGLE, ++ peri); ++ off += _emit_LDP(dry_run, &buf[off], BURST, ++ peri); ++ } else { ++ off += _emit_LDP(dry_run, &buf[off], cond, ++ peri); ++ } ++ break; + +- if (!(pl330->quirks & PL330_QUIRK_BROKEN_NO_FLUSHP)) +- off += _emit_FLUSHP(dry_run, &buf[off], +- pxs->desc->peri); ++ default: ++ /* this code should be unreachable */ ++ WARN_ON(1); ++ break; + } + + return off; + } + +-static inline int _ldst_memtodev(struct pl330_dmac *pl330, ++static inline u32 _emit_store(unsigned int dry_run, u8 buf[], ++ enum pl330_cond cond, enum dma_transfer_direction direction, ++ u8 peri) ++{ ++ int off = 0; ++ ++ switch (direction) { ++ case DMA_MEM_TO_MEM: ++ /* fall through */ ++ case DMA_DEV_TO_MEM: ++ off += _emit_ST(dry_run, &buf[off], cond); ++ break; ++ ++ case DMA_MEM_TO_DEV: ++ if (cond == ALWAYS) { ++ off += _emit_STP(dry_run, &buf[off], SINGLE, ++ peri); ++ off += _emit_STP(dry_run, &buf[off], BURST, ++ peri); ++ } else { ++ off += _emit_STP(dry_run, &buf[off], cond, ++ peri); ++ } ++ break; ++ ++ default: ++ /* this code should be unreachable */ ++ WARN_ON(1); ++ break; ++ } ++ ++ return off; ++} ++ ++static inline int _ldst_peripheral(struct pl330_dmac *pl330, + unsigned dry_run, u8 buf[], +- const struct _xfer_spec *pxs, int cyc) ++ const struct _xfer_spec *pxs, int cyc, ++ enum pl330_cond cond) + { + int off = 0; +- enum pl330_cond cond; + + if (pl330->quirks & PL330_QUIRK_BROKEN_NO_FLUSHP) + cond = BURST; +- else +- cond = SINGLE; + ++ /* ++ * do FLUSHP at beginning to clear any stale dma requests before the ++ * first WFP. ++ */ ++ if (!(pl330->quirks & PL330_QUIRK_BROKEN_NO_FLUSHP)) ++ off += _emit_FLUSHP(dry_run, &buf[off], pxs->desc->peri); + while (cyc--) { + off += _emit_WFP(dry_run, &buf[off], cond, pxs->desc->peri); +- off += _emit_LD(dry_run, &buf[off], ALWAYS); +- off += _emit_STP(dry_run, &buf[off], cond, pxs->desc->peri); +- +- if (!(pl330->quirks & PL330_QUIRK_BROKEN_NO_FLUSHP)) +- off += _emit_FLUSHP(dry_run, &buf[off], +- pxs->desc->peri); ++ off += _emit_load(dry_run, &buf[off], cond, pxs->desc->rqtype, ++ pxs->desc->peri); ++ off += _emit_store(dry_run, &buf[off], cond, pxs->desc->rqtype, ++ pxs->desc->peri); + } + + return off; +@@ -1149,19 +1195,65 @@ static int _bursts(struct pl330_dmac *pl330, unsigned dry_run, u8 buf[], + const struct _xfer_spec *pxs, int cyc) + { + int off = 0; ++ enum pl330_cond cond = BRST_LEN(pxs->ccr) > 1 ? BURST : SINGLE; + + switch (pxs->desc->rqtype) { + case DMA_MEM_TO_DEV: +- off += _ldst_memtodev(pl330, dry_run, &buf[off], pxs, cyc); +- break; ++ /* fall through */ + case DMA_DEV_TO_MEM: +- off += _ldst_devtomem(pl330, dry_run, &buf[off], pxs, cyc); ++ off += _ldst_peripheral(pl330, dry_run, &buf[off], pxs, cyc, ++ cond); + break; ++ + case DMA_MEM_TO_MEM: + off += _ldst_memtomem(dry_run, &buf[off], pxs, cyc); + break; ++ ++ default: ++ /* this code should be unreachable */ ++ WARN_ON(1); ++ break; ++ } ++ ++ return off; ++} ++ ++/* ++ * transfer dregs with single transfers to peripheral, or a reduced size burst ++ * for mem-to-mem. ++ */ ++static int _dregs(struct pl330_dmac *pl330, unsigned int dry_run, u8 buf[], ++ const struct _xfer_spec *pxs, int transfer_length) ++{ ++ int off = 0; ++ int dregs_ccr; ++ ++ if (transfer_length == 0) ++ return off; ++ ++ switch (pxs->desc->rqtype) { ++ case DMA_MEM_TO_DEV: ++ /* fall through */ ++ case DMA_DEV_TO_MEM: ++ off += _ldst_peripheral(pl330, dry_run, &buf[off], pxs, ++ transfer_length, SINGLE); ++ break; ++ ++ case DMA_MEM_TO_MEM: ++ dregs_ccr = pxs->ccr; ++ dregs_ccr &= ~((0xf << CC_SRCBRSTLEN_SHFT) | ++ (0xf << CC_DSTBRSTLEN_SHFT)); ++ dregs_ccr |= (((transfer_length - 1) & 0xf) << ++ CC_SRCBRSTLEN_SHFT); ++ dregs_ccr |= (((transfer_length - 1) & 0xf) << ++ CC_DSTBRSTLEN_SHFT); ++ off += _emit_MOV(dry_run, &buf[off], CCR, dregs_ccr); ++ off += _ldst_memtomem(dry_run, &buf[off], pxs, 1); ++ break; ++ + default: +- off += 0x40000000; /* Scare off the Client */ ++ /* this code should be unreachable */ ++ WARN_ON(1); + break; + } + +@@ -1257,6 +1349,8 @@ static inline int _setup_loops(struct pl330_dmac *pl330, + struct pl330_xfer *x = &pxs->desc->px; + u32 ccr = pxs->ccr; + unsigned long c, bursts = BYTE_TO_BURST(x->bytes, ccr); ++ int num_dregs = (x->bytes - BURST_TO_BYTE(bursts, ccr)) / ++ BRST_SIZE(ccr); + int off = 0; + + while (bursts) { +@@ -1264,6 +1358,7 @@ static inline int _setup_loops(struct pl330_dmac *pl330, + off += _loop(pl330, dry_run, &buf[off], &c, pxs); + bursts -= c; + } ++ off += _dregs(pl330, dry_run, &buf[off], pxs, num_dregs); + + return off; + } +@@ -1295,7 +1390,6 @@ static int _setup_req(struct pl330_dmac *pl330, unsigned dry_run, + struct _xfer_spec *pxs) + { + struct _pl330_req *req = &thrd->req[index]; +- struct pl330_xfer *x; + u8 *buf = req->mc_cpu; + int off = 0; + +@@ -1304,11 +1398,6 @@ static int _setup_req(struct pl330_dmac *pl330, unsigned dry_run, + /* DMAMOV CCR, ccr */ + off += _emit_MOV(dry_run, &buf[off], CCR, pxs->ccr); + +- x = &pxs->desc->px; +- /* Error if xfer length is not aligned at burst size */ +- if (x->bytes % (BRST_SIZE(pxs->ccr) * BRST_LEN(pxs->ccr))) +- return -EINVAL; +- + off += _setup_xfer(pl330, dry_run, &buf[off], pxs); + + /* DMASEV peripheral/event */ +@@ -1366,6 +1455,20 @@ static int pl330_submit_req(struct pl330_thread *thrd, + u32 ccr; + int ret = 0; + ++ switch (desc->rqtype) { ++ case DMA_MEM_TO_DEV: ++ break; ++ ++ case DMA_DEV_TO_MEM: ++ break; ++ ++ case DMA_MEM_TO_MEM: ++ break; ++ ++ default: ++ return -ENOTSUPP; ++ } ++ + if (pl330->state == DYING + || pl330->dmac_tbd.reset_chan & (1 << thrd->id)) { + dev_info(thrd->dmac->ddma.dev, "%s:%d\n", +@@ -2060,6 +2163,18 @@ static int pl330_alloc_chan_resources(struct dma_chan *chan) + return 1; + } + ++static int fixup_burst_len(int max_burst_len, int quirks) ++{ ++ if (quirks & PL330_QUIRK_BROKEN_NO_FLUSHP) ++ return 1; ++ else if (max_burst_len > PL330_MAX_BURST) ++ return PL330_MAX_BURST; ++ else if (max_burst_len < 1) ++ return 1; ++ else ++ return max_burst_len; ++} ++ + static int pl330_config(struct dma_chan *chan, + struct dma_slave_config *slave_config) + { +@@ -2070,15 +2185,15 @@ static int pl330_config(struct dma_chan *chan, + pch->fifo_addr = slave_config->dst_addr; + if (slave_config->dst_addr_width) + pch->burst_sz = __ffs(slave_config->dst_addr_width); +- if (slave_config->dst_maxburst) +- pch->burst_len = slave_config->dst_maxburst; ++ pch->burst_len = fixup_burst_len(slave_config->dst_maxburst, ++ pch->dmac->quirks); + } else if (slave_config->direction == DMA_DEV_TO_MEM) { + if (slave_config->src_addr) + pch->fifo_addr = slave_config->src_addr; + if (slave_config->src_addr_width) + pch->burst_sz = __ffs(slave_config->src_addr_width); +- if (slave_config->src_maxburst) +- pch->burst_len = slave_config->src_maxburst; ++ pch->burst_len = fixup_burst_len(slave_config->src_maxburst, ++ pch->dmac->quirks); + } + + return 0; +@@ -2471,14 +2586,8 @@ static inline int get_burst_len(struct dma_pl330_desc *desc, size_t len) + burst_len >>= desc->rqcfg.brst_size; + + /* src/dst_burst_len can't be more than 16 */ +- if (burst_len > 16) +- burst_len = 16; +- +- while (burst_len > 1) { +- if (!(len % (burst_len << desc->rqcfg.brst_size))) +- break; +- burst_len--; +- } ++ if (burst_len > PL330_MAX_BURST) ++ burst_len = PL330_MAX_BURST; + + return burst_len; + } +@@ -2547,7 +2656,7 @@ static struct dma_async_tx_descriptor *pl330_prep_dma_cyclic( + + desc->rqtype = direction; + desc->rqcfg.brst_size = pch->burst_sz; +- desc->rqcfg.brst_len = 1; ++ desc->rqcfg.brst_len = pch->burst_len; + desc->bytes_requested = period_len; + fill_px(&desc->px, dst, src, period_len); + +@@ -2692,7 +2801,7 @@ pl330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, + } + + desc->rqcfg.brst_size = pch->burst_sz; +- desc->rqcfg.brst_len = 1; ++ desc->rqcfg.brst_len = pch->burst_len; + desc->rqtype = direction; + desc->bytes_requested = sg_dma_len(sg); + } + +From 058373c4d717d3a353bca1345ea90f8ca6531136 Mon Sep 17 00:00:00 2001 +From: Marek Szyprowski +Date: Tue, 19 Jun 2018 15:20:50 +0200 +Subject: [PATCH] UPSTREAM: dmaengine: pl330: report BURST residue granularity + +The reported residue is already calculated in BURST unit granularity, so +advertise this capability properly to other devices in the system. + +Fixes: aee4d1fac887 ("dmaengine: pl330: improve pl330_tx_status() function") +Signed-off-by: Marek Szyprowski +Signed-off-by: Vinod Koul +(cherry picked from commit e3f329c600033f011a978a8bc4ddb1e2e94c4f4d) +--- + drivers/dma/pl330.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c +index fd48c031ead8..029bd0444137 100644 +--- a/drivers/dma/pl330.c ++++ b/drivers/dma/pl330.c +@@ -2984,7 +2984,7 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id) + pd->src_addr_widths = PL330_DMA_BUSWIDTHS; + pd->dst_addr_widths = PL330_DMA_BUSWIDTHS; + pd->directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV); +- pd->residue_granularity = DMA_RESIDUE_GRANULARITY_SEGMENT; ++ pd->residue_granularity = DMA_RESIDUE_GRANULARITY_BURST; + pd->max_burst = ((pl330->quirks & PL330_QUIRK_BROKEN_NO_FLUSHP) ? + 1 : PL330_MAX_BURST); + + +From 05fa0eafd6eda3e61ac5d4a9511eb4d1bb1924f9 Mon Sep 17 00:00:00 2001 +From: Vinod Koul +Date: Mon, 9 Jul 2018 17:09:58 +0530 +Subject: [PATCH] dmaengine: pl330: Mark expected switch fall-through + +In preparation to enabling -Wimplicit-fallthrough, mark switch cases +where we are expecting to fall through. + +Reviewed-by: Krzysztof Kozlowski +Signed-off-by: Vinod Koul +(cherry picked from commit bbcb87555869cb6c249bf00d13d3bc400c476c84) +--- + drivers/dma/pl330.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c +index 029bd0444137..c3bd238b0c22 100644 +--- a/drivers/dma/pl330.c ++++ b/drivers/dma/pl330.c +@@ -1047,13 +1047,16 @@ static bool _start(struct pl330_thread *thrd) + + if (_state(thrd) == PL330_STATE_KILLING) + UNTIL(thrd, PL330_STATE_STOPPED) ++ /* fall through */ + + case PL330_STATE_FAULTING: + _stop(thrd); ++ /* fall through */ + + case PL330_STATE_KILLING: + case PL330_STATE_COMPLETING: + UNTIL(thrd, PL330_STATE_STOPPED) ++ /* fall through */ + + case PL330_STATE_STOPPED: + return _trigger(thrd); + +From b654bf6ca9ee98bab1a3c55ebd359f251b9c1a61 Mon Sep 17 00:00:00 2001 +From: Vinod Koul +Date: Mon, 9 Jul 2018 20:08:48 +0530 +Subject: [PATCH] dmaengine: pl330: remove set but unused variable +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Compiler complains (with W=1): +drivers/dma/pl330.c: In function ‘pl330_release_channel’: +drivers/dma/pl330.c:1782:21: warning: + variable ‘pl330’ set but not used [-Wunused-but-set-variable] + struct pl330_dmac *pl330; + ^~~~~ + +Remove the pl330 variable in pl330_release_channel as it is set but +never used. + +Signed-off-by: Vinod Koul +(cherry picked from commit 2f903bab92dea8dec8c93e4fa3c7c5295ef0a0fe) +--- + drivers/dma/pl330.c | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c +index c3bd238b0c22..a25ab357b87c 100644 +--- a/drivers/dma/pl330.c ++++ b/drivers/dma/pl330.c +@@ -1783,8 +1783,6 @@ static inline void _free_event(struct pl330_thread *thrd, int ev) + + static void pl330_release_channel(struct pl330_thread *thrd) + { +- struct pl330_dmac *pl330; +- + if (!thrd || thrd->free) + return; + +@@ -1793,8 +1791,6 @@ static void pl330_release_channel(struct pl330_thread *thrd) + dma_pl330_rqcb(thrd->req[1 - thrd->lstenq].desc, PL330_ERR_ABORT); + dma_pl330_rqcb(thrd->req[thrd->lstenq].desc, PL330_ERR_ABORT); + +- pl330 = thrd->dmac; +- + _free_event(thrd, thrd->ev); + thrd->free = true; + } + +From 31c885c621005218388ca68648dec38d2ea3f9a2 Mon Sep 17 00:00:00 2001 +From: John Keeping +Date: Tue, 17 Jul 2018 11:48:16 +0100 +Subject: [PATCH] dmaengine: pl330: fix irq race with terminate_all + +In pl330_update() when checking if a channel has been aborted, the +channel's lock is not taken, only the overall pl330_dmac lock. But in +pl330_terminate_all() the aborted flag (req_running==-1) is set under +the channel lock and not the pl330_dmac lock. + +With threaded interrupts, this leads to a potential race: + + pl330_terminate_all pl330_update + ------------------- ------------ + lock channel + entry + lock pl330 + _stop channel + unlock pl330 + lock pl330 + check req_running != -1 + req_running = -1 + _start channel + diff --git a/patch/kernel/rk322x-legacy/01-linux-1000-vcodec.patch b/patch/kernel/rk322x-legacy/01-linux-1000-vcodec.patch new file mode 100644 index 0000000000..55a8e63dd8 --- /dev/null +++ b/patch/kernel/rk322x-legacy/01-linux-1000-vcodec.patch @@ -0,0 +1,945 @@ +From e222e9913d3c70967bae92f1aed46de726974dc7 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Thu, 5 Jul 2018 00:14:14 +0200 +Subject: [PATCH] Revert "drm/drm-prime: cache dma_buf import context" + +This reverts commit 5a90381e5acc2cf32be03099a14d05d4362b3348. +--- + drivers/gpu/drm/drm_prime.c | 46 ++--------------------------- + drivers/gpu/drm/rockchip/rockchip_drm_gem.c | 1 + + 2 files changed, 3 insertions(+), 44 deletions(-) + +diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c +index 6f207d5946dc..6b7417a194a3 100644 +--- a/drivers/gpu/drm/drm_prime.c ++++ b/drivers/gpu/drm/drm_prime.c +@@ -71,11 +71,6 @@ struct drm_prime_attachment { + enum dma_data_direction dir; + }; + +-struct drm_prime_callback_data { +- struct drm_gem_object *obj; +- struct sg_table *sgt; +-}; +- + static int drm_prime_add_buf_handle(struct drm_prime_file_private *prime_fpriv, + struct dma_buf *dma_buf, uint32_t handle) + { +@@ -524,23 +519,6 @@ out_unlock: + } + EXPORT_SYMBOL(drm_gem_prime_handle_to_fd); + +-static void drm_gem_prime_dmabuf_release_callback(void *data) +-{ +- struct drm_prime_callback_data *cb_data = data; +- +- if (cb_data && cb_data->obj && cb_data->obj->import_attach) { +- struct dma_buf_attachment *attach = cb_data->obj->import_attach; +- struct sg_table *sgt = cb_data->sgt; +- +- if (sgt) +- dma_buf_unmap_attachment(attach, sgt, +- DMA_BIDIRECTIONAL); +- dma_buf_detach(attach->dmabuf, attach); +- drm_gem_object_unreference_unlocked(cb_data->obj); +- kfree(cb_data); +- } +-} +- + /** + * drm_gem_prime_import - helper library implementation of the import callback + * @dev: drm_device to import into +@@ -555,7 +533,6 @@ struct drm_gem_object *drm_gem_prime_import(struct drm_device *dev, + struct dma_buf_attachment *attach; + struct sg_table *sgt; + struct drm_gem_object *obj; +- struct drm_prime_callback_data *cb_data; + int ret; + + if (dma_buf->ops == &drm_gem_prime_dmabuf_ops) { +@@ -570,13 +547,6 @@ struct drm_gem_object *drm_gem_prime_import(struct drm_device *dev, + } + } + +- cb_data = dma_buf_get_release_callback_data(dma_buf, +- drm_gem_prime_dmabuf_release_callback); +- if (cb_data && cb_data->obj && cb_data->obj->dev == dev) { +- drm_gem_object_reference(cb_data->obj); +- return cb_data->obj; +- } +- + if (!dev->driver->gem_prime_import_sg_table) + return ERR_PTR(-EINVAL); + +@@ -585,16 +555,11 @@ struct drm_gem_object *drm_gem_prime_import(struct drm_device *dev, + return ERR_CAST(attach); + + get_dma_buf(dma_buf); +- cb_data = kmalloc(sizeof(*cb_data), GFP_KERNEL); +- if (!cb_data) { +- ret = -ENOMEM; +- goto fail_detach; +- } + + sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL); + if (IS_ERR(sgt)) { + ret = PTR_ERR(sgt); +- goto fail_free; ++ goto fail_detach; + } + + obj = dev->driver->gem_prime_import_sg_table(dev, attach, sgt); +@@ -602,20 +567,13 @@ struct drm_gem_object *drm_gem_prime_import(struct drm_device *dev, + ret = PTR_ERR(obj); + goto fail_unmap; + } ++ + obj->import_attach = attach; +- cb_data->obj = obj; +- cb_data->sgt = sgt; +- dma_buf_set_release_callback(dma_buf, +- drm_gem_prime_dmabuf_release_callback, cb_data); +- dma_buf_put(dma_buf); +- drm_gem_object_reference(obj); + + return obj; + + fail_unmap: + dma_buf_unmap_attachment(attach, sgt, DMA_BIDIRECTIONAL); +-fail_free: +- kfree(cb_data); + fail_detach: + dma_buf_detach(dma_buf, attach); + dma_buf_put(dma_buf); +diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c +index 273a52b5eb66..85bbd19c87b0 100644 +--- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c +@@ -649,6 +649,7 @@ void rockchip_gem_free_object(struct drm_gem_object *obj) + dma_unmap_sg(drm->dev, rk_obj->sgt->sgl, + rk_obj->sgt->nents, DMA_BIDIRECTIONAL); + } ++ drm_prime_gem_destroy(obj, rk_obj->sgt); + } else { + rockchip_gem_free_buf(rk_obj); + } + +From 0868438e92b0e9a44d6c6e711ef3be0a429ab4af Mon Sep 17 00:00:00 2001 +From: Rob Clark +Date: Thu, 9 Jun 2016 15:29:19 -0400 +Subject: [PATCH] UPSTREAM: drm/prime: fix error path deadlock fail + +There were a couple messed up things about this fail path. +(1) it would drop object_name_lock twice +(2) drm_gem_handle_delete() (in drm_gem_remove_prime_handles()) + needs to grab prime_lock + +Reported-by: Alex Deucher +Signed-off-by: Rob Clark +Reviewed-by: Alex Deucher +Signed-off-by: Daniel Vetter +Link: http://patchwork.freedesktop.org/patch/msgid/1465500559-17873-1-git-send-email-robdclark@gmail.com +(cherry picked from commit bd6e2732f0e2894ce792f344c41fc32591436fe3) +--- + drivers/gpu/drm/drm_prime.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c +index 6b7417a194a3..d8d85286764d 100644 +--- a/drivers/gpu/drm/drm_prime.c ++++ b/drivers/gpu/drm/drm_prime.c +@@ -628,7 +628,7 @@ int drm_gem_prime_fd_to_handle(struct drm_device *dev, + get_dma_buf(dma_buf); + } + +- /* drm_gem_handle_create_tail unlocks dev->object_name_lock. */ ++ /* _handle_create_tail unconditionally unlocks dev->object_name_lock. */ + ret = drm_gem_handle_create_tail(file_priv, obj, handle); + drm_gem_object_unreference_unlocked(obj); + if (ret) +@@ -636,11 +636,10 @@ int drm_gem_prime_fd_to_handle(struct drm_device *dev, + + ret = drm_prime_add_buf_handle(&file_priv->prime, + dma_buf, *handle); ++ mutex_unlock(&file_priv->prime.lock); + if (ret) + goto fail; + +- mutex_unlock(&file_priv->prime.lock); +- + dma_buf_put(dma_buf); + + return 0; +@@ -650,11 +649,14 @@ fail: + * to detach.. which seems ok.. + */ + drm_gem_handle_delete(file_priv, *handle); ++ dma_buf_put(dma_buf); ++ return ret; ++ + out_unlock: + mutex_unlock(&dev->object_name_lock); + out_put: +- dma_buf_put(dma_buf); + mutex_unlock(&file_priv->prime.lock); ++ dma_buf_put(dma_buf); + return ret; + } + EXPORT_SYMBOL(drm_gem_prime_fd_to_handle); + +From 8e4ac090d0a814f73d719887f96f7dc44112e03e Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Mon, 26 Sep 2016 21:44:14 +0100 +Subject: [PATCH] UPSTREAM: drm: Convert prime dma-buf <-> handle to rbtree + +Currently we use a linear walk to lookup a handle and return a dma-buf, +and vice versa. A long overdue TODO task is to convert that to a +hashtable. Since the initial implementation of dma-buf/prime, we now +have resizeable hashtables we can use (and now a future task is to RCU +enable the lookup!). However, this patch opts to use an rbtree instead +to provide O(lgN) lookups (and insertion, deletion). rbtrees were chosen +over using the RCU backed resizable hashtable to firstly avoid the +reallocations (rbtrees can be embedded entirely within the parent +struct) and to favour simpler code with predictable worst case +behaviour. In simple testing, the difference between using the constant +lookup and insertion of the rhashtable and the rbtree was less than 10% +of the wall time (igt/benchmarks/prime_lookup) - both are dramatic +improvements over the existing linear lists. + +v2: Favour rbtree over rhashtable + +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=94631 +Signed-off-by: Chris Wilson +Cc: Sean Paul +Cc: David Herrmann +Reviewed-by: David Herrmann +Reviewed-by: Sean Paul +Signed-off-by: Daniel Vetter +Link: http://patchwork.freedesktop.org/patch/msgid/20160926204414.23222-1-chris@chris-wilson.co.uk +(cherry picked from commit 077675c1e8a193a6355d4a7c8c7bf63be310b472) +--- + drivers/gpu/drm/drm_prime.c | 85 +++++++++++++++++++++++++++++++++++++++------ + include/drm/drmP.h | 5 +-- + 2 files changed, 77 insertions(+), 13 deletions(-) + +diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c +index d8d85286764d..4c49e736bc9c 100644 +--- a/drivers/gpu/drm/drm_prime.c ++++ b/drivers/gpu/drm/drm_prime.c +@@ -28,6 +28,7 @@ + + #include + #include ++#include + #include + #include + +@@ -61,9 +62,11 @@ + */ + + struct drm_prime_member { +- struct list_head entry; + struct dma_buf *dma_buf; + uint32_t handle; ++ ++ struct rb_node dmabuf_rb; ++ struct rb_node handle_rb; + }; + + struct drm_prime_attachment { +@@ -75,6 +78,7 @@ static int drm_prime_add_buf_handle(struct drm_prime_file_private *prime_fpriv, + struct dma_buf *dma_buf, uint32_t handle) + { + struct drm_prime_member *member; ++ struct rb_node **p, *rb; + + member = kmalloc(sizeof(*member), GFP_KERNEL); + if (!member) +@@ -83,18 +87,56 @@ static int drm_prime_add_buf_handle(struct drm_prime_file_private *prime_fpriv, + get_dma_buf(dma_buf); + member->dma_buf = dma_buf; + member->handle = handle; +- list_add(&member->entry, &prime_fpriv->head); ++ ++ rb = NULL; ++ p = &prime_fpriv->dmabufs.rb_node; ++ while (*p) { ++ struct drm_prime_member *pos; ++ ++ rb = *p; ++ pos = rb_entry(rb, struct drm_prime_member, dmabuf_rb); ++ if (dma_buf > pos->dma_buf) ++ p = &rb->rb_right; ++ else ++ p = &rb->rb_left; ++ } ++ rb_link_node(&member->dmabuf_rb, rb, p); ++ rb_insert_color(&member->dmabuf_rb, &prime_fpriv->dmabufs); ++ ++ rb = NULL; ++ p = &prime_fpriv->handles.rb_node; ++ while (*p) { ++ struct drm_prime_member *pos; ++ ++ rb = *p; ++ pos = rb_entry(rb, struct drm_prime_member, handle_rb); ++ if (handle > pos->handle) ++ p = &rb->rb_right; ++ else ++ p = &rb->rb_left; ++ } ++ rb_link_node(&member->handle_rb, rb, p); ++ rb_insert_color(&member->handle_rb, &prime_fpriv->handles); ++ + return 0; + } + + static struct dma_buf *drm_prime_lookup_buf_by_handle(struct drm_prime_file_private *prime_fpriv, + uint32_t handle) + { +- struct drm_prime_member *member; ++ struct rb_node *rb; ++ ++ rb = prime_fpriv->handles.rb_node; ++ while (rb) { ++ struct drm_prime_member *member; + +- list_for_each_entry(member, &prime_fpriv->head, entry) { ++ member = rb_entry(rb, struct drm_prime_member, handle_rb); + if (member->handle == handle) + return member->dma_buf; ++ else if (member->handle < handle) ++ rb = rb->rb_right; ++ else ++ rb = rb->rb_left; + } + + return NULL; +@@ -104,14 +146,23 @@ static int drm_prime_lookup_buf_handle(struct drm_prime_file_private *prime_fpri + struct dma_buf *dma_buf, + uint32_t *handle) + { +- struct drm_prime_member *member; ++ struct rb_node *rb; ++ ++ rb = prime_fpriv->dmabufs.rb_node; ++ while (rb) { ++ struct drm_prime_member *member; + +- list_for_each_entry(member, &prime_fpriv->head, entry) { ++ member = rb_entry(rb, struct drm_prime_member, dmabuf_rb); + if (member->dma_buf == dma_buf) { + *handle = member->handle; + return 0; ++ } else if (member->dma_buf < dma_buf) { ++ rb = rb->rb_right; ++ } else { ++ rb = rb->rb_left; + } + } ++ + return -ENOENT; + } + +@@ -166,13 +217,24 @@ static void drm_gem_map_detach(struct dma_buf *dma_buf, + void drm_prime_remove_buf_handle_locked(struct drm_prime_file_private *prime_fpriv, + struct dma_buf *dma_buf) + { +- struct drm_prime_member *member, *safe; ++ struct rb_node *rb; + +- list_for_each_entry_safe(member, safe, &prime_fpriv->head, entry) { ++ rb = prime_fpriv->dmabufs.rb_node; ++ while (rb) { ++ struct drm_prime_member *member; ++ ++ member = rb_entry(rb, struct drm_prime_member, dmabuf_rb); + if (member->dma_buf == dma_buf) { ++ rb_erase(&member->handle_rb, &prime_fpriv->handles); ++ rb_erase(&member->dmabuf_rb, &prime_fpriv->dmabufs); ++ + dma_buf_put(dma_buf); +- list_del(&member->entry); + kfree(member); ++ return; ++ } else if (member->dma_buf < dma_buf) { ++ rb = rb->rb_right; ++ } else { ++ rb = rb->rb_left; + } + } + } +@@ -794,12 +856,13 @@ EXPORT_SYMBOL(drm_prime_gem_destroy); + + void drm_prime_init_file_private(struct drm_prime_file_private *prime_fpriv) + { +- INIT_LIST_HEAD(&prime_fpriv->head); + mutex_init(&prime_fpriv->lock); ++ prime_fpriv->dmabufs = RB_ROOT; ++ prime_fpriv->handles = RB_ROOT; + } + + void drm_prime_destroy_file_private(struct drm_prime_file_private *prime_fpriv) + { + /* by now drm_gem_release should've made sure the list is empty */ +- WARN_ON(!list_empty(&prime_fpriv->head)); ++ WARN_ON(!RB_EMPTY_ROOT(&prime_fpriv->dmabufs)); + } +diff --git a/include/drm/drmP.h b/include/drm/drmP.h +index 04edcd32b409..93da65df2e7e 100644 +--- a/include/drm/drmP.h ++++ b/include/drm/drmP.h +@@ -51,6 +51,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -365,10 +366,10 @@ struct drm_pending_event { + void (*destroy)(struct drm_pending_event *event); + }; + +-/* initial implementaton using a linked list - todo hashtab */ + struct drm_prime_file_private { +- struct list_head head; + struct mutex lock; ++ struct rb_root dmabufs; ++ struct rb_root handles; + }; + + /** File private data */ + +From fcb8af30f524cd437434ec6ddea0231cc37529bc Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Wed, 5 Oct 2016 13:21:44 +0100 +Subject: [PATCH] UPSTREAM: drm/prime: Take a ref on the drm_dev when exporting + a dma_buf +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +dma_buf may live a long time, longer than the last direct user of the +driver. We already hold a reference to the owner module (that prevents +the object code from disappearing), but there is no reference to the +drm_dev - so the pointers to the driver backend themselves may vanish. + +v2: Resist temptation to fix the bug in armada_gem.c not setting the +correct flags on the exported dma-buf (it should pass the flags through +and not be arbitrarily setting O_RDWR). + +Use a common wrapper for exporting the dmabuf and acquiring the +reference to the drm_device. + +Testcase: igt/vgem_basic/unload +Suggested-by: Daniel Vetter +Signed-off-by: Chris Wilson +Cc: Petri Latvala +Cc: Daniel Vetter +Cc: stable@vger.kernel.org +Tested-by: Petri Latvala +Reviewed-by: Christian König +Signed-off-by: Daniel Vetter +Link: http://patchwork.freedesktop.org/patch/msgid/20161005122145.1507-2-chris@chris-wilson.co.uk +(cherry picked from commit a4fce9cb782ad340ee5576a38e934e5e75832dc6) +--- + drivers/gpu/drm/armada/armada_gem.c | 2 +- + drivers/gpu/drm/drm_prime.c | 30 +++++++++++++++++++++++++++++- + drivers/gpu/drm/i915/i915_gem_dmabuf.c | 2 +- + drivers/gpu/drm/tegra/gem.c | 2 +- + drivers/gpu/drm/udl/udl_dmabuf.c | 2 +- + include/drm/drmP.h | 4 ++++ + 6 files changed, 37 insertions(+), 5 deletions(-) + +diff --git a/drivers/gpu/drm/armada/armada_gem.c b/drivers/gpu/drm/armada/armada_gem.c +index 60a688ef81c7..cd5bb991f49a 100644 +--- a/drivers/gpu/drm/armada/armada_gem.c ++++ b/drivers/gpu/drm/armada/armada_gem.c +@@ -546,7 +546,7 @@ armada_gem_prime_export(struct drm_device *dev, struct drm_gem_object *obj, + exp_info.flags = O_RDWR; + exp_info.priv = obj; + +- return dma_buf_export(&exp_info); ++ return drm_gem_dmabuf_export(dev, &exp_info); + } + + struct drm_gem_object * +diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c +index 4c49e736bc9c..94b4872255c8 100644 +--- a/drivers/gpu/drm/drm_prime.c ++++ b/drivers/gpu/drm/drm_prime.c +@@ -283,19 +283,47 @@ static void drm_gem_unmap_dma_buf(struct dma_buf_attachment *attach, + /* nothing to be done here */ + } + ++/** ++ * drm_gem_dmabuf_export - dma_buf export implementation for GEM ++ * @dma_buf: buffer to be exported ++ * ++ * This wraps dma_buf_export() for use by generic GEM drivers that are using ++ * drm_gem_dmabuf_release(). In addition to calling dma_buf_export(), we take ++ * a reference to the drm_device which is released by drm_gem_dmabuf_release(). ++ * ++ * Returns the new dmabuf. ++ */ ++struct dma_buf *drm_gem_dmabuf_export(struct drm_device *dev, ++ struct dma_buf_export_info *exp_info) ++{ ++ struct dma_buf *dma_buf; ++ ++ dma_buf = dma_buf_export(exp_info); ++ if (!IS_ERR(dma_buf)) ++ drm_dev_ref(dev); ++ ++ return dma_buf; ++} ++EXPORT_SYMBOL(drm_gem_dmabuf_export); ++ + /** + * drm_gem_dmabuf_release - dma_buf release implementation for GEM + * @dma_buf: buffer to be released + * + * Generic release function for dma_bufs exported as PRIME buffers. GEM drivers + * must use this in their dma_buf ops structure as the release callback. ++ * drm_gem_dmabuf_release() should be used in conjunction with ++ * drm_gem_dmabuf_export(). + */ + void drm_gem_dmabuf_release(struct dma_buf *dma_buf) + { + struct drm_gem_object *obj = dma_buf->priv; ++ struct drm_device *dev = obj->dev; + + /* drop the reference on the export fd holds */ + drm_gem_object_unreference_unlocked(obj); ++ ++ drm_dev_unref(dev); + } + EXPORT_SYMBOL(drm_gem_dmabuf_release); + +@@ -444,7 +472,7 @@ struct dma_buf *drm_gem_prime_export(struct drm_device *dev, + if (dev->driver->gem_prime_res_obj) + exp_info.resv = dev->driver->gem_prime_res_obj(obj); + +- return dma_buf_export(&exp_info); ++ return drm_gem_dmabuf_export(dev, &exp_info); + } + EXPORT_SYMBOL(drm_gem_prime_export); + +diff --git a/drivers/gpu/drm/i915/i915_gem_dmabuf.c b/drivers/gpu/drm/i915/i915_gem_dmabuf.c +index e9c2bfd85b52..d4a021629bd6 100644 +--- a/drivers/gpu/drm/i915/i915_gem_dmabuf.c ++++ b/drivers/gpu/drm/i915/i915_gem_dmabuf.c +@@ -244,7 +244,7 @@ struct dma_buf *i915_gem_prime_export(struct drm_device *dev, + return ERR_PTR(ret); + } + +- return dma_buf_export(&exp_info); ++ return drm_gem_dmabuf_export(dev, &exp_info); + } + + static int i915_gem_object_get_pages_dmabuf(struct drm_i915_gem_object *obj) +diff --git a/drivers/gpu/drm/tegra/gem.c b/drivers/gpu/drm/tegra/gem.c +index 01e16e146bfe..da06f1c1ee0f 100644 +--- a/drivers/gpu/drm/tegra/gem.c ++++ b/drivers/gpu/drm/tegra/gem.c +@@ -625,7 +625,7 @@ struct dma_buf *tegra_gem_prime_export(struct drm_device *drm, + exp_info.flags = flags; + exp_info.priv = gem; + +- return dma_buf_export(&exp_info); ++ return drm_gem_dmabuf_export(drm, &exp_info); + } + + struct drm_gem_object *tegra_gem_prime_import(struct drm_device *drm, +diff --git a/drivers/gpu/drm/udl/udl_dmabuf.c b/drivers/gpu/drm/udl/udl_dmabuf.c +index e2243edd1ce3..ac90ffdb5912 100644 +--- a/drivers/gpu/drm/udl/udl_dmabuf.c ++++ b/drivers/gpu/drm/udl/udl_dmabuf.c +@@ -209,7 +209,7 @@ struct dma_buf *udl_gem_prime_export(struct drm_device *dev, + exp_info.flags = flags; + exp_info.priv = obj; + +- return dma_buf_export(&exp_info); ++ return drm_gem_dmabuf_export(dev, &exp_info); + } + + static int udl_prime_create(struct drm_device *dev, +diff --git a/include/drm/drmP.h b/include/drm/drmP.h +index 93da65df2e7e..4aba6478d718 100644 +--- a/include/drm/drmP.h ++++ b/include/drm/drmP.h +@@ -1124,6 +1124,8 @@ static inline int drm_debugfs_remove_files(const struct drm_info_list *files, + } + #endif + ++struct dma_buf_export_info; ++ + extern struct dma_buf *drm_gem_prime_export(struct drm_device *dev, + struct drm_gem_object *obj, + int flags); +@@ -1134,6 +1136,8 @@ extern struct drm_gem_object *drm_gem_prime_import(struct drm_device *dev, + struct dma_buf *dma_buf); + extern int drm_gem_prime_fd_to_handle(struct drm_device *dev, + struct drm_file *file_priv, int prime_fd, uint32_t *handle); ++struct dma_buf *drm_gem_dmabuf_export(struct drm_device *dev, ++ struct dma_buf_export_info *exp_info); + extern void drm_gem_dmabuf_release(struct dma_buf *dma_buf); + + extern int drm_prime_sg_to_page_addr_arrays(struct sg_table *sgt, struct page **pages, + +From 2c0a8737dd35ba259d3bbbf1b956fb43da32f117 Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Wed, 7 Dec 2016 21:45:27 +0000 +Subject: [PATCH] UPSTREAM: drm: Take ownership of the dmabuf->obj when + exporting + +Currently the reference for the dmabuf->obj is incremented for the +dmabuf in drm_gem_prime_handle_to_fd() (at the high level userspace +interface), but is released in drm_gem_dmabuf_release() (the lowlevel +handler). Improve the symmetry of the dmabuf->obj ownership by acquiring +the reference in drm_gem_dmabuf_export(). This makes it easier to use +the prime functions directly. + +Signed-off-by: Chris Wilson +[danvet: Update kerneldoc.] +Signed-off-by: Daniel Vetter +Link: http://patchwork.freedesktop.org/patch/msgid/20161207214527.22533-1-chris@chris-wilson.co.uk +(cherry picked from commit 72a93e8dd52c9feea42f1258d555e6070680a347) +--- + drivers/gpu/drm/drm_prime.c | 12 +++++++----- + 1 file changed, 7 insertions(+), 5 deletions(-) + +diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c +index 94b4872255c8..dbd34fa7f71c 100644 +--- a/drivers/gpu/drm/drm_prime.c ++++ b/drivers/gpu/drm/drm_prime.c +@@ -289,7 +289,8 @@ static void drm_gem_unmap_dma_buf(struct dma_buf_attachment *attach, + * + * This wraps dma_buf_export() for use by generic GEM drivers that are using + * drm_gem_dmabuf_release(). In addition to calling dma_buf_export(), we take +- * a reference to the drm_device which is released by drm_gem_dmabuf_release(). ++ * a reference to the &drm_device and the exported &drm_gem_object (stored in ++ * exp_info->priv) which is released by drm_gem_dmabuf_release(). + * + * Returns the new dmabuf. + */ +@@ -299,8 +300,11 @@ struct dma_buf *drm_gem_dmabuf_export(struct drm_device *dev, + struct dma_buf *dma_buf; + + dma_buf = dma_buf_export(exp_info); +- if (!IS_ERR(dma_buf)) +- drm_dev_ref(dev); ++ if (IS_ERR(dma_buf)) ++ return dma_buf; ++ ++ drm_dev_ref(dev); ++ drm_gem_object_reference(exp_info->priv); + + return dma_buf; + } +@@ -503,8 +507,6 @@ static struct dma_buf *export_and_register_object(struct drm_device *dev, + */ + obj->dma_buf = dmabuf; + get_dma_buf(obj->dma_buf); +- /* Grab a new ref since the callers is now used by the dma-buf */ +- drm_gem_object_reference(obj); + + return dmabuf; + } + +From 595e921b1e908458bd1ee022c9a7ee08cf203ad9 Mon Sep 17 00:00:00 2001 +From: Lucas Stach +Date: Thu, 30 Nov 2017 18:34:28 +0100 +Subject: [PATCH] UPSTREAM: drm/prime: skip CPU sync in map/unmap dma_buf + +Dma-bufs should already be device coherent, as they are only pulled in the +CPU domain via the begin/end cpu_access calls. As we cache the mapping set +up by dma_map_sg a CPU sync at this point will not actually guarantee proper +coherency on non-coherent architectures, so we can as well stop pretending. + +This is an important performance fix for architectures which need explicit +cache synchronization and userspace doing lots of dma-buf imports. +Improves Weston on Etnaviv performance 5x, where before this patch > 90% +of Weston CPU time was spent synchronizing caches for buffers which are +already device coherent. + +Signed-off-by: Lucas Stach +Reviewed-by: Chris Wilson +Signed-off-by: Daniel Vetter +Link: https://patchwork.freedesktop.org/patch/msgid/20171130173428.8666-1-l.stach@pengutronix.de +(cherry picked from commit ca0e68e21aae10220eff71a297e7d794425add77) +--- + drivers/gpu/drm/drm_prime.c | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c +index dbd34fa7f71c..133362279591 100644 +--- a/drivers/gpu/drm/drm_prime.c ++++ b/drivers/gpu/drm/drm_prime.c +@@ -203,9 +203,12 @@ static void drm_gem_map_detach(struct dma_buf *dma_buf, + + sgt = prime_attach->sgt; + if (sgt) { ++ DEFINE_DMA_ATTRS(attrs); ++ dma_set_attr(DMA_ATTR_SKIP_CPU_SYNC, &attrs); + if (prime_attach->dir != DMA_NONE) +- dma_unmap_sg(attach->dev, sgt->sgl, sgt->nents, +- prime_attach->dir); ++ dma_unmap_sg_attrs(attach->dev, sgt->sgl, sgt->nents, ++ prime_attach->dir, ++ &attrs); + sg_free_table(sgt); + } + +@@ -263,7 +266,9 @@ static struct sg_table *drm_gem_map_dma_buf(struct dma_buf_attachment *attach, + sgt = obj->dev->driver->gem_prime_get_sg_table(obj); + + if (!IS_ERR(sgt)) { +- if (!dma_map_sg(attach->dev, sgt->sgl, sgt->nents, dir)) { ++ DEFINE_DMA_ATTRS(attrs); ++ dma_set_attr(DMA_ATTR_SKIP_CPU_SYNC, &attrs); ++ if (!dma_map_sg_attrs(attach->dev, sgt->sgl, sgt->nents, dir, &attrs)) { + sg_free_table(sgt); + kfree(sgt); + sgt = ERR_PTR(-ENOMEM); + +From d314fd1a48e930d034eccd49342a23340c3f1c27 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20K=C3=B6nig?= +Date: Tue, 27 Feb 2018 12:49:56 +0100 +Subject: [PATCH] UPSTREAM: drm/prime: fix potential race in drm_gem_map_detach +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Unpin the GEM object only after freeing the sg table. + +Signed-off-by: Christian König +Reviewed-by: Daniel Vetter +Acked-by: Roger He +Signed-off-by: Alex Deucher +Link: https://patchwork.freedesktop.org/patch/msgid/20180227115000.4105-1-christian.koenig@amd.com +(cherry picked from commit 681066ec1d41e4b299146bada52cef846b323c04) +--- + drivers/gpu/drm/drm_prime.c | 36 ++++++++++++++++++------------------ + 1 file changed, 18 insertions(+), 18 deletions(-) + +diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c +index 133362279591..95ecc69d03a0 100644 +--- a/drivers/gpu/drm/drm_prime.c ++++ b/drivers/gpu/drm/drm_prime.c +@@ -193,28 +193,28 @@ static void drm_gem_map_detach(struct dma_buf *dma_buf, + struct drm_prime_attachment *prime_attach = attach->priv; + struct drm_gem_object *obj = dma_buf->priv; + struct drm_device *dev = obj->dev; +- struct sg_table *sgt; +- +- if (dev->driver->gem_prime_unpin) +- dev->driver->gem_prime_unpin(obj); + +- if (!prime_attach) +- return; ++ if (prime_attach) { ++ struct sg_table *sgt = prime_attach->sgt; ++ ++ if (sgt) { ++ DEFINE_DMA_ATTRS(attrs); ++ dma_set_attr(DMA_ATTR_SKIP_CPU_SYNC, &attrs); ++ if (prime_attach->dir != DMA_NONE) ++ dma_unmap_sg_attrs(attach->dev, sgt->sgl, ++ sgt->nents, ++ prime_attach->dir, ++ &attrs); ++ sg_free_table(sgt); ++ } + +- sgt = prime_attach->sgt; +- if (sgt) { +- DEFINE_DMA_ATTRS(attrs); +- dma_set_attr(DMA_ATTR_SKIP_CPU_SYNC, &attrs); +- if (prime_attach->dir != DMA_NONE) +- dma_unmap_sg_attrs(attach->dev, sgt->sgl, sgt->nents, +- prime_attach->dir, +- &attrs); +- sg_free_table(sgt); ++ kfree(sgt); ++ kfree(prime_attach); ++ attach->priv = NULL; + } + +- kfree(sgt); +- kfree(prime_attach); +- attach->priv = NULL; ++ if (dev->driver->gem_prime_unpin) ++ dev->driver->gem_prime_unpin(obj); + } + + void drm_prime_remove_buf_handle_locked(struct drm_prime_file_private *prime_fpriv, + +From c74449bbd7e3ee3f3195ac9da48271c83c56f101 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20K=C3=B6nig?= +Date: Tue, 27 Feb 2018 12:49:57 +0100 +Subject: [PATCH] UPSTREAM: drm/prime: make the pages array optional for + drm_prime_sg_to_page_addr_arrays +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Most of the time we only need the dma addresses. + +Signed-off-by: Christian König +Reviewed-by: Roger He +Signed-off-by: Alex Deucher +Link: https://patchwork.freedesktop.org/patch/msgid/20180227115000.4105-2-christian.koenig@amd.com +Link: https://patchwork.freedesktop.org/patch/msgid/20180227115000.4105-3-christian.koenig@amd.com +Link: https://patchwork.freedesktop.org/patch/msgid/20180227115000.4105-4-christian.koenig@amd.com +Link: https://patchwork.freedesktop.org/patch/msgid/20180227115000.4105-5-christian.koenig@amd.com +Link: https://patchwork.freedesktop.org/patch/msgid/BN6PR12MB18262C0DE9B5F07B9A42EAE7F2C60@BN6PR12MB1826.namprd12.prod.outlook.com +(cherry picked from commit 186ca446aea19e49d2e1433dd170c6e1c211a52a) +--- + drivers/gpu/drm/drm_prime.c | 20 ++++++++++---------- + 1 file changed, 10 insertions(+), 10 deletions(-) + +diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c +index 95ecc69d03a0..7ea65c4105c1 100644 +--- a/drivers/gpu/drm/drm_prime.c ++++ b/drivers/gpu/drm/drm_prime.c +@@ -827,40 +827,40 @@ EXPORT_SYMBOL(drm_prime_pages_to_sg); + /** + * drm_prime_sg_to_page_addr_arrays - convert an sg table into a page array + * @sgt: scatter-gather table to convert +- * @pages: array of page pointers to store the page array in ++ * @pages: optional array of page pointers to store the page array in + * @addrs: optional array to store the dma bus address of each page +- * @max_pages: size of both the passed-in arrays ++ * @max_entries: size of both the passed-in arrays + * + * Exports an sg table into an array of pages and addresses. This is currently + * required by the TTM driver in order to do correct fault handling. + */ + int drm_prime_sg_to_page_addr_arrays(struct sg_table *sgt, struct page **pages, +- dma_addr_t *addrs, int max_pages) ++ dma_addr_t *addrs, int max_entries) + { + unsigned count; + struct scatterlist *sg; + struct page *page; +- u32 len; +- int pg_index; ++ u32 len, index; + dma_addr_t addr; + +- pg_index = 0; ++ index = 0; + for_each_sg(sgt->sgl, sg, sgt->nents, count) { + len = sg->length; + page = sg_page(sg); + addr = sg_dma_address(sg); + + while (len > 0) { +- if (WARN_ON(pg_index >= max_pages)) ++ if (WARN_ON(index >= max_entries)) + return -1; +- pages[pg_index] = page; ++ if (pages) ++ pages[index] = page; + if (addrs) +- addrs[pg_index] = addr; ++ addrs[index] = addr; + + page++; + addr += PAGE_SIZE; + len -= PAGE_SIZE; +- pg_index++; ++ index++; + } + } + return 0; + +From 2fc969d64eb928db78c9fd99fb68d9d2442a8919 Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Sat, 19 Aug 2017 13:05:58 +0100 +Subject: [PATCH] UPSTREAM: drm: Release driver tracking before making the + object available again +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This is the same bug as we fixed in commit f6cd7daecff5 ("drm: Release +driver references to handle before making it available again"), but now +the exposure is via the PRIME lookup tables. If we remove the +object/handle from the PRIME lut, then a new request for the same +object/fd will generate a new handle, thus for a short window that +object is known to userspace by two different handles. Fix this by +releasing the driver tracking before PRIME. + +Fixes: 0ff926c7d4f0 ("drm/prime: add exported buffers to current fprivs +imported buffer list (v2)") +Signed-off-by: Chris Wilson +Cc: David Airlie +Cc: Daniel Vetter +Cc: Rob Clark +Cc: Ville Syrjälä +Cc: Thierry Reding +Cc: stable@vger.kernel.org +Reviewed-by: Daniel Vetter +Signed-off-by: Joonas Lahtinen +Link: https://patchwork.freedesktop.org/patch/msgid/20170819120558.6465-1-chris@chris-wilson.co.uk +(cherry picked from commit d0a133f7f5bc3583e460ba6bb54474a50ada5201) +--- + drivers/gpu/drm/drm_gem.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c +index d7f39a03c2c9..966ea63581b1 100644 +--- a/drivers/gpu/drm/drm_gem.c ++++ b/drivers/gpu/drm/drm_gem.c +@@ -255,13 +255,13 @@ drm_gem_object_release_handle(int id, void *ptr, void *data) + struct drm_gem_object *obj = ptr; + struct drm_device *dev = obj->dev; + ++ if (dev->driver->gem_close_object) ++ dev->driver->gem_close_object(obj, file_priv); ++ + if (drm_core_check_feature(dev, DRIVER_PRIME)) + drm_gem_remove_prime_handles(obj, file_priv); + drm_vma_node_revoke(&obj->vma_node, file_priv->filp); + +- if (dev->driver->gem_close_object) +- dev->driver->gem_close_object(obj, file_priv); +- + drm_gem_object_handle_unreference_unlocked(obj); + + return 0; + +From 1d9b65acb4e776f43408afed2b0fd7b86fdb95ce Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sat, 17 Feb 2018 05:30:36 +0100 +Subject: [PATCH] vcodec: skip reduce freq + +--- + drivers/video/rockchip/vcodec/vcodec_service.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/drivers/video/rockchip/vcodec/vcodec_service.c b/drivers/video/rockchip/vcodec/vcodec_service.c +index c4ee73be92d3..9d5ee5c8b1f9 100644 +--- a/drivers/video/rockchip/vcodec/vcodec_service.c ++++ b/drivers/video/rockchip/vcodec/vcodec_service.c +@@ -1630,9 +1630,6 @@ static void try_set_reg(struct vpu_subdev_data *data) + reg_from_wait_to_run(pservice, reg); + reg_copy_to_hw(reg->data, reg); + } +- } else { +- if (pservice->hw_ops->reduce_freq) +- pservice->hw_ops->reduce_freq(pservice); + } + + mutex_unlock(&pservice->shutdown_lock); +@@ -2385,6 +2382,7 @@ static void vcodec_set_freq_rk3328(struct vpu_service_info *pservice, + if (curr == reg->freq) + return; + ++ atomic_set(&pservice->freq_status, reg->freq); + if (pservice->dev_id == VCODEC_DEVICE_ID_RKVDEC) { + if (reg->reg[1] & 0x00800000) { + if (rkv_dec_get_fmt(reg->reg) == FMT_H264D) diff --git a/patch/kernel/rk322x-legacy/01-linux-1001-ssv6051.patch b/patch/kernel/rk322x-legacy/01-linux-1001-ssv6051.patch new file mode 100644 index 0000000000..8f7c4816bf --- /dev/null +++ b/patch/kernel/rk322x-legacy/01-linux-1001-ssv6051.patch @@ -0,0 +1,174 @@ +--- a/drivers/net/wireless/rockchip_wlan/ssv6xxx/ssvdevice/ssvdevice.c ++++ b/drivers/net/wireless/rockchip_wlan/ssv6xxx/ssvdevice/ssvdevice.c +@@ -58,7 +58,7 @@ + char *ssv6xxx_result_buf; + extern struct ssv6xxx_cfg_cmd_table cfg_cmds[]; + extern struct ssv6xxx_cfg ssv_cfg; +-char DEFAULT_CFG_PATH[] = "/vendor/etc/firmware/ssv6051-wifi.cfg"; ++char DEFAULT_CFG_PATH[] = "/etc/firmware/ssv6051/ssv6051-wifi.cfg"; + static int ssv6xxx_dbg_open(struct inode *inode, struct file *filp) + { + filp->private_data = inode->i_private; + +--- a/drivers/net/wireless/rockchip_wlan/ssv6xxx/ssvdevice/ssv_cmd.c ++++ b/drivers/net/wireless/rockchip_wlan/ssv6xxx/ssvdevice/ssv_cmd.c +@@ -1541,7 +1541,7 @@ + size_per_frame = simple_strtoul(argv[2], &endp, 10); + loop_times = simple_strtoul(argv[3], &endp, 10); + sprintf(tmpbf, "type&size&frames:%d&%d&%d\n", pkt_type, size_per_frame, loop_times); +- strncat(ssv6xxx_result_buf, tmpbf, sizeof(tmpbf)); ++ strcat(ssv6xxx_result_buf, tmpbf); + if (ssv6xxx_txtput->txtput_tsk) { + sprintf(tmpbf, "txtput already in progress\n"); + strcat(ssv6xxx_result_buf, tmpbf); +--- a/drivers/net/wireless/rockchip_wlan/ssv6xxx/smac/dev.c ++++ b/drivers/net/wireless/rockchip_wlan/ssv6xxx/smac/dev.c +@@ -92,8 +92,6 @@ + unsigned int timeout; + SKB_info *mpdu_skb_info = (SKB_info *)mpdu_skb->head; + timeout = (unsigned int)ktime_to_ms(ktime_sub(ktime_get(), mpdu_skb_info->timestamp)); +- if (timeout > SKB_DURATION_TIMEOUT_MS) +- printk("*mpdu_duration: %ums\n", timeout); + return timeout; + } + #endif +@@ -179,7 +177,7 @@ + size, type); + else + { +- dev_info(sc->dev, "Allocated %d type packet buffer of size %d (%d) at address %x.\n", ++ dev_dbg(sc->dev, "Allocated %d type packet buffer of size %d (%d) at address %x.\n", + type, size, page_cnt, regval); + } + return regval; +@@ -197,7 +195,6 @@ + } + mutex_lock(&sc->mem_mutex); + regval = ((M_ENG_TRASH_CAN << HW_ID_OFFSET) |(pbuf_addr >> ADDRESS_OFFSET)); +- printk("[A] ssv6xxx_pbuf_free addr[%08x][%x]\n", pbuf_addr, regval); + SMAC_REG_WRITE(sc->sh, ADR_CH0_TRIG_1, regval); + if (*p_tx_page_cnt) + { +@@ -1136,7 +1133,7 @@ + address = sec_key_tbl + + ((index-1) * sizeof(struct ssv6xxx_hw_key)); + if (vif_info->vif_priv != NULL) +- dev_info(sc->dev, "Write group key %d to VIF %d to %08X\n", ++ dev_dbg(sc->dev, "Write group key %d to VIF %d to %08X\n", + index, vif_info->vif_priv->vif_idx, address); + else + dev_err(sc->dev, "NULL VIF.\n"); +@@ -1189,7 +1186,7 @@ + #if 0 + sta_info->s_flags |= STA_FLAG_ENCRYPT; + #endif +- dev_info(sc->dev, "Set STA %d's pair-wise key of %d bytes.\n", wsid, key_len); ++ dev_dbg(sc->dev, "Set STA %d's pair-wise key of %d bytes.\n", wsid, key_len); + sramKey = &(sc->vif_info[vif_priv->vif_idx].sramKey); + sramKey->sta_key[wsid].pair_key_idx = 0; + sramKey->sta_key[wsid].group_key_idx = vif_priv->group_key_idx; +@@ -1234,7 +1231,7 @@ + dev_err(sc->dev, "Setting group key to NULL VIF\n"); + return -EOPNOTSUPP; + } +- dev_info(sc->dev, "Setting VIF %d group key %d of length %d to WSID %d.\n", ++ dev_dbg(sc->dev, "Setting VIF %d group key %d of length %d to WSID %d.\n", + vif_priv->vif_idx, index, key_len, wsid); + sramKey = &(sc->vif_info[vif_priv->vif_idx].sramKey); + vif_priv->group_key_idx = index; +@@ -1384,7 +1381,7 @@ + else + { + dev_err(sc->dev, "[Local Crypto]: Failed to initialize driver's crypto!\n"); +- dev_info(sc->dev, "[Local Crypto]: Use MAC80211's encrypter.\n"); ++ dev_dbg(sc->dev, "[Local Crypto]: Use MAC80211's encrypter.\n"); + vif_priv->need_sw_decrypt = false; + vif_priv->need_sw_encrypt = false; + vif_priv->use_mac80211_decrypt = true; +@@ -1457,7 +1454,7 @@ + if (((val >>4) & 0xF) != M_ENG_CPU){ + SMAC_REG_WRITE(sc->sh, ADR_RX_FLOW_DATA, ((val & 0xf) | (M_ENG_CPU<<4) + | (val & 0xfffffff0) <<4)); +- dev_info(sc->dev, "orginal Rx_Flow %x , modified flow %x \n", val, ++ dev_dbg(sc->dev, "orginal Rx_Flow %x , modified flow %x \n", val, + ((val & 0xf) | (M_ENG_CPU<<4) | (val & 0xfffffff0) <<4)); + } + } +@@ -1476,7 +1473,7 @@ + (sta_priv->sta_info->sta->ht_cap.ht_supported == false)) + && (vif_priv->force_sw_encrypt == false))) + { +- dev_info(sc->dev, "STA %d uses HW encrypter for pairwise.\n", sta_priv->sta_idx); ++ dev_dbg(sc->dev, "STA %d uses HW encrypter for pairwise.\n", sta_priv->sta_idx); + sta_priv->has_hw_encrypt = true; + sta_priv->need_sw_encrypt = false; + sta_priv->use_mac80211_decrypt = false; +@@ -1601,7 +1598,7 @@ + if (((vif_priv->vif_idx == 0) && (tkip_use_sw_cipher == false)) + || ((cipher == SSV_CIPHER_CCMP) && (sc->sh->cfg.use_wpa2_only == 1))) + { +- dev_info(sc->dev, "VIF %d uses HW %s cipher for group.\n", vif_priv->vif_idx, cipher_name); ++ dev_dbg(sc->dev, "VIF %d uses HW %s cipher for group.\n", vif_priv->vif_idx, cipher_name); + #ifdef USE_MAC80211_DECRYPT_BROADCAST + vif_priv->has_hw_decrypt = false; + ret = -EOPNOTSUPP; +@@ -1700,7 +1697,7 @@ + if (((val >>4) & 0xF) != M_ENG_CPU){ + SMAC_REG_WRITE(sc->sh, ADR_RX_FLOW_DATA, ((val & 0xf) | (M_ENG_CPU<<4) + | (val & 0xfffffff0) <<4)); +- dev_info(sc->dev, "orginal Rx_Flow %x , modified flow %x \n", val, ++ dev_dbg(sc->dev, "orginal Rx_Flow %x , modified flow %x \n", val, + ((val & 0xf) | (M_ENG_CPU<<4) | (val & 0xfffffff0) <<4)); + } else { + printk(" doesn't need to change rx flow\n"); +@@ -1913,7 +1910,7 @@ + SMAC_REG_WRITE(sc->sh, ADR_RX_FLOW_DATA, + ((val & 0xf) | (M_ENG_CPU<<4) + | (val & 0xfffffff0) <<4)); +- dev_info(sc->dev, "orginal Rx_Flow %x , modified flow %x \n", ++ dev_dbg(sc->dev, "orginal Rx_Flow %x , modified flow %x \n", + val, ((val & 0xf) | (M_ENG_CPU<<4) | (val & 0xfffffff0) <<4)); + } else { + printk(" doesn't need to change rx flow\n"); +@@ -2997,15 +2994,15 @@ + u32 sta_addr0_3 = *(u32 *)&sta->addr[0]; + u32 sta_addr4_5 = (u32)*(u16 *)&sta->addr[4]; + u32 removed_skb_num; +- dev_info(sc->dev, "Clean up skb for STA %pM.\n", sta->addr); ++ dev_dbg(sc->dev, "Clean up skb for STA %pM.\n", sta->addr); + _stop_crypto_task(sc); + spin_lock_irqsave(&sc->crypt_st_lock, flags); + removed_skb_num = _remove_sta_skb_from_q(sc, &sc->preprocess_q, + sta_addr0_3, sta_addr4_5); +- dev_info(sc->dev, "Removed %u MPDU from precess queue.\n", removed_skb_num); ++ dev_dbg(sc->dev, "Removed %u MPDU from precess queue.\n", removed_skb_num); + removed_skb_num = _remove_sta_skb_from_q(sc, &sc->crypted_q, + sta_addr0_3, sta_addr4_5); +- dev_info(sc->dev, "Removed %u MPDU from encrypted queue.\n", removed_skb_num); ++ dev_dbg(sc->dev, "Removed %u MPDU from encrypted queue.\n", removed_skb_num); + spin_unlock_irqrestore(&sc->crypt_st_lock, flags); + _resume_crypto_task(sc); + } +@@ -4007,7 +4004,7 @@ + && crypto_data->priv) + { + crypto_data->ops->deinit(crypto_data->priv); +- dev_info(sc->dev, "STA releases crypto OK!\n"); ++ dev_dbg(sc->dev, "STA releases crypto OK!\n"); + } + crypto_data->priv = NULL; + crypto_data->ops = NULL; + +diff --git a/drivers/net/wireless/rockchip_wlan/ssv6xxx/Makefile b/drivers/net/wireless/rockchip_wlan/ssv6xxx/Makefile +index f86faef..e1df615 100644 +--- a/drivers/net/wireless/rockchip_wlan/ssv6xxx/Makefile ++++ b/drivers/net/wireless/rockchip_wlan/ssv6xxx/Makefile +@@ -19,7 +19,7 @@ include $(KBUILD_TOP)/ssv6051.cfg + include $(KBUILD_TOP)/platform-config.mak + + +-EXTRA_CFLAGS := -I$(KBUILD_TOP) -I$(KBUILD_TOP)/include ++EXTRA_CFLAGS := -I$(KBUILD_TOP) -I$(KBUILD_TOP)/include -Wno-error=missing-attributes + DEF_PARSER_H = $(KBUILD_TOP)/include/ssv_conf_parser.h + $(shell env ccflags="$(ccflags-y)" $(KBUILD_TOP)/parser-conf.sh $(DEF_PARSER_H)) + diff --git a/patch/kernel/rk322x-legacy/01-linux-1002-rk322x-dts.patch b/patch/kernel/rk322x-legacy/01-linux-1002-rk322x-dts.patch new file mode 100644 index 0000000000..e546eadb88 --- /dev/null +++ b/patch/kernel/rk322x-legacy/01-linux-1002-rk322x-dts.patch @@ -0,0 +1,1664 @@ +diff --git a/arch/arm/boot/dts/rk322x-box.dtsi b/arch/arm/boot/dts/rk322x-box.dtsi +new file mode 100644 +index 0000000..04330d3 +--- /dev/null ++++ b/arch/arm/boot/dts/rk322x-box.dtsi +@@ -0,0 +1,503 @@ ++/* ++ * Copyright (C) 2020 knaerzche ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++ ++#include ++#include ++#include "rk322x.dtsi" ++ ++/ { ++ ++ compatible = "rockchip,rk3229"; ++ model = "Rockchip RK3229 SoC"; ++ ++ memory@60000000 { ++ device_type = "memory"; ++ reg = <0x60000000 0x40000000>; ++ }; ++ ++ ++ chosen { ++ bootargs = "earlycon=uart8250,mmio32,0x11030000"; ++ }; ++ ++ reserved-memory { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges; ++ ++ ramoops_mem: ramoops@62e00000 { ++ reg = <0x62e00000 0xf0000>; ++ }; ++ ++ trust_reserved: trust@68400000 { ++ reg = <0x68400000 0xe00000>; ++ no-map; ++ }; ++ }; ++ ++ ramoops { ++ compatible = "ramoops"; ++ record-size = <0x0 0x20000>; ++ console-size = <0x0 0x80000>; ++ ftrace-size = <0x0 0x00000>; ++ pmsg-size = <0x0 0x50000>; ++ memory-region = <&ramoops_mem>; ++ }; ++ ++ psci { ++ compatible = "arm,psci-1.0"; ++ method = "smc"; ++ }; ++ ++ sound { ++ status = "okay"; ++ compatible = "simple-audio-card"; ++ simple-audio-card,format = "i2s"; ++ simple-audio-card,mclk-fs = <256>; ++ simple-audio-card,name = "ROCKCHIP,RK3229"; ++ simple-audio-card,cpu { ++ sound-dai = <&i2s1>; ++ }; ++ simple-audio-card,codec { ++ sound-dai = <&codec>; ++ }; ++ }; ++ ++ hdmi_sound: hdmi-sound { ++ status = "okay"; ++ compatible = "simple-audio-card"; ++ simple-audio-card,format = "i2s"; ++ simple-audio-card,mclk-fs = <128>; ++ simple-audio-card,name = "HDMI"; ++ simple-audio-card,cpu { ++ sound-dai = <&i2s0>; ++ }; ++ simple-audio-card,codec { ++ sound-dai = <&hdmi>; ++ }; ++ }; ++ ++ regulators { ++ compatible = "simple-bus"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ vccio_1v8_reg: regulator@0 { ++ compatible = "regulator-fixed"; ++ regulator-name = "vccio_1v8"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-always-on; ++ }; ++ ++ vccio_3v3_reg: regulator@1 { ++ compatible = "regulator-fixed"; ++ regulator-name = "vccio_3v3"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-always-on; ++ }; ++ }; ++ ++ spdif_out: spdif-out { ++ status = "okay"; ++ compatible = "linux,spdif-dit"; ++ #sound-dai-cells = <0>; ++ }; ++ ++ spdif-sound { ++ status = "okay"; ++ compatible = "simple-audio-card"; ++ simple-audio-card,name = "ROCKCHIP,SPDIF"; ++ simple-audio-card,cpu { ++ sound-dai = <&spdif>; ++ }; ++ simple-audio-card,codec { ++ sound-dai = <&spdif_out>; ++ }; ++ }; ++ ++ vcc_host: vcc-host-regulator { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpio = <&gpio3 20 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&host_vbus_drv>; ++ regulator-name = "vcc_host"; ++ regulator-always-on; ++ regulator-boot-on; ++ }; ++ ++ vcc_otg_vbus: otg-vbus-regulator { ++ compatible = "regulator-fixed"; ++ gpio = <&gpio3 RK_PC6 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&otg_vbus_drv>; ++ regulator-name = "vcc_otg_vbus"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ enable-active-high; ++ }; ++ ++ vcc_phy: vcc-phy-regulator { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ regulator-name = "vcc_phy"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-always-on; ++ regulator-boot-on; ++ }; ++ ++ vdd_arm: vdd-arm-regulator { ++ compatible = "pwm-regulator"; ++ rockchip,pwm_id = <1>; ++ rockchip,pwm_voltage = <1100000>; ++ pwms = <&pwm1 0 5000 1>; ++ regulator-name = "vdd_arm"; ++ regulator-min-microvolt = <950000>; ++ regulator-max-microvolt = <1400000>; ++ regulator-ramp-delay = <12500>; ++ regulator-settling-time-up-us = <250>; ++ regulator-always-on; ++ regulator-boot-on; ++ }; ++ ++ vdd_log: vdd-log-regulator { ++ compatible = "pwm-regulator"; ++ rockchip,pwm_id = <2>; ++ rockchip,pwm_voltage = <1200000>; ++ pwms = <&pwm2 0 5000 1>; ++ regulator-name = "vdd_log"; ++ regulator-min-microvolt = <1000000>; ++ regulator-max-microvolt = <1300000>; ++ regulator-ramp-delay = <12500>; ++ regulator-settling-time-up-us = <250>; ++ regulator-always-on; ++ regulator-boot-on; ++ }; ++ ++ ir_receiver: ir-receiver { ++ compatible = "gpio-ir-receiver"; ++ gpios = <&gpio1 RK_PB3 GPIO_ACTIVE_LOW>; ++ linux,rc-map-name = "rc-rktvbox"; ++ pinctrl-0 = <&ir_int>; ++ pinctrl-names = "default"; ++ }; ++ ++}; ++ ++&display_subsystem { ++ ++ status = "okay"; ++ ++ route_hdmi: route-hdmi { ++ status = "okay"; ++ connect = <&vop_out_hdmi>; ++ }; ++ ++ route_tve: route-tve { ++ status = "disabled"; ++ connect = <&vop_out_tve>; ++ }; ++}; ++ ++&codec { ++ #sound-dai-cells = <0>; ++ status = "okay"; ++}; ++ ++&cpu0 { ++ enable-method = "psci"; ++ cpu-supply = <&vdd_arm>; ++}; ++ ++&cpu1 { ++ enable-method = "psci"; ++}; ++ ++&cpu2 { ++ enable-method = "psci"; ++}; ++ ++&cpu3 { ++ enable-method = "psci"; ++}; ++ ++ ++&dmc { ++ center-supply = <&vdd_log>; ++}; ++ ++&gmac { ++ assigned-clocks = <&cru SCLK_MAC_SRC>; ++ assigned-clock-rates = <50000000>; ++ clock_in_out = "output"; ++ phy-supply = <&vcc_phy>; ++ phy-mode = "rmii"; ++ phy-is-integrated; ++ status = "okay"; ++}; ++ ++&gpu { ++ status = "okay"; ++ mali-supply = <&vdd_log>; ++}; ++ ++ ++ ++&hdmi { ++ status = "okay"; ++ #sound-dai-cells = <0>; ++ ddc-i2c-scl-high-time-ns = <9625>; ++ ddc-i2c-scl-low-time-ns = <10000>; ++}; ++ ++&hdmi_phy { ++ status = "okay"; ++}; ++ ++&io_domains { ++ status = "okay"; ++ vccio1-supply = <&vccio_3v3_reg>; ++ vccio2-supply = <&vccio_1v8_reg>; ++ vccio4-supply = <&vccio_3v3_reg>; ++}; ++ ++&emmc { ++ broken-cd; ++ bus-width = <8>; ++ cap-mmc-highspeed; ++ mmc-hs200-1_8v; ++ supports-emmc; ++ disable-wp; ++ non-removable; ++ num-slots = <1>; ++ /delete-property/ default-sample-phase; ++ /delete-property/ pinctrl-names; ++ /delete-property/ pinctrl-0; ++}; ++ ++&sdmmc { ++ bus-width = <4>; ++ cap-sd-highspeed; ++ card-detect-delay = <200>; ++ disable-wp; ++ max-frequency = <50000000>; ++ num-slots = <1>; ++ supports-sd; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdmmc_pwr &sdmmc_clk &sdmmc_cmd &sdmmc_bus4>; ++}; ++ ++&sdio { ++ bus-width = <4>; ++ cap-mmc-highspeed; ++ cap-sd-highspeed; ++ cap-sdio-irq; ++ non-removable; ++ ignore-pm-notify; ++ keep-power-in-suspend; ++ max-frequency = <150000000>; ++ supports-sdio; ++}; ++ ++&i2s0 { ++ status = "okay"; ++ rockchip,bclk-fs = <128>; ++ #sound-dai-cells = <0>; ++}; ++ ++&i2s1 { ++ #sound-dai-cells = <0>; ++ status = "okay"; ++}; ++ ++&iep { ++ status = "okay"; ++}; ++ ++&iep_mmu { ++ status = "okay"; ++}; ++ ++&pinctrl { ++ keys { ++ pwr_key: pwr-key { ++ rockchip,pins = <3 23 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ }; ++ ++ sdmmc { ++ sdmmc_pwr: sdmmc-pwr { ++ rockchip,pins = <1 14 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ sdio-pwrseq { ++ wifi_enable_h: wifi-enable-h { ++ rockchip,pins = <2 26 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ usb { ++ host_vbus_drv: host-vbus-drv { ++ rockchip,pins = <3 20 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ ++ otg_vbus_drv: otg-vbus-drv { ++ rockchip,pins = <3 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ ir { ++ ir_int: ir-int { ++ rockchip,pins = <1 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++}; ++ ++&pwm1 { ++ status = "okay"; ++ pinctrl-names = "active"; ++ pinctrl-0 = <&pwm1_pin_pull_down>; ++}; ++ ++&pwm2 { ++ status = "okay"; ++ pinctrl-names = "active"; ++ pinctrl-0 = <&pwm2_pin_pull_up>; ++}; ++ ++&rockchip_suspend { ++ status = "okay"; ++ rockchip,virtual-poweroff = <1>; ++ rockchip,sleep-mode-config = < ++ (0 ++ |RKPM_CTR_GTCLKS ++ |RKPM_CTR_IDLESRAM_MD ++ |RKPM_CTR_PMIC ++ ) ++ >; ++}; ++ ++ ++&tsadc { ++ rockchip,hw-tshut-mode = <0>; /* tshut mode 0:CRU 1:GPIO */ ++ rockchip,hw-tshut-polarity = <1>; /* tshut polarity 0:LOW 1:HIGH */ ++ rockchip,grf = <&grf>; ++ status = "okay"; ++}; ++ ++&spdif { ++ status = "okay"; ++ #sound-dai-cells = <0>; ++}; ++ ++&threshold { ++ temperature = <90000>; /* millicelsius */ ++}; ++ ++&target { ++ temperature = <105000>; /* millicelsius */ ++}; ++ ++&soc_crit { ++ temperature = <115000>; /* millicelsius */ ++}; ++ ++&uart2 { ++ status = "okay"; ++}; ++ ++&u2phy0 { ++ status = "okay"; ++ ++ u2phy0_otg: otg-port { ++ vbus-supply = <&vcc_otg_vbus>; ++ status = "okay"; ++ }; ++ ++ u2phy0_host: host-port { ++ phy-supply = <&vcc_host>; ++ status = "okay"; ++ }; ++}; ++ ++&u2phy1 { ++ status = "okay"; ++ ++ u2phy1_otg: otg-port { ++ status = "okay"; ++ }; ++ ++ u2phy1_host: host-port { ++ phy-supply = <&vcc_host>; ++ status = "okay"; ++ }; ++}; ++ ++&usb_otg { ++ status = "okay"; ++}; ++ ++&rkvdec { ++ vcodec-supply = <&vdd_log>; ++ status = "okay"; ++}; ++ ++&rkvdec_mmu { ++ status = "okay"; ++}; ++ ++&rk_rga { ++ status = "okay"; ++}; ++ ++&usb_host0_ehci { ++ status = "okay"; ++}; ++ ++&usb_host0_ohci { ++ status = "okay"; ++}; ++ ++&usb_host1_ehci { ++ status = "okay"; ++}; ++ ++&usb_host1_ohci { ++ status = "okay"; ++}; ++ ++&usb_host2_ehci { ++ status = "okay"; ++}; ++ ++&usb_host2_ohci { ++ status = "okay"; ++}; ++ ++&vop { ++ assigned-clocks = <&cru DCLK_VOP>; ++ assigned-clock-parents = <&cru HDMIPHY>; ++ rockchip,grf = <&grf>; ++ status = "okay"; ++}; ++ ++&vop_mmu { ++ status = "okay"; ++}; ++ ++&vpu_service { ++ status = "okay"; ++}; ++ ++&vpu_mmu { ++ status = "okay"; ++}; +diff --git a/arch/arm/boot/dts/rk3228a-box.dtsi b/arch/arm/boot/dts/rk3228a-box.dtsi +new file mode 100644 +index 0000000..103c324 +--- /dev/null ++++ b/arch/arm/boot/dts/rk3228a-box.dtsi +@@ -0,0 +1,47 @@ ++/* ++ * Copyright (C) 2020 knaerzche ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++ ++/dts-v1/; ++ ++#include "rk322x-box.dtsi" ++#include "rk3228a-cpu-opp.dtsi" ++ ++/ { ++ compatible = "rockchip,rk3228a-box", "rockchip,rk3229"; ++ ++ /delete-node/ opp-table2; ++ ++ gpu_opp_table: opp-table2 { ++ compatible = "operating-points-v2"; ++ rockchip,leakage-voltage-sel = < ++ 1 5 0 ++ 6 254 1 ++ >; ++ nvmem-cells = <&logic_leakage>; ++ nvmem-cell-names = "gpu_leakage"; ++ ++ opp-200000000 { ++ opp-hz = /bits/ 64 <200000000>; ++ opp-microvolt = <1050000>; ++ opp-microvolt-L0 = <1050000>; ++ opp-microvolt-L1 = <1000000>; ++ }; ++ opp-300000000 { ++ opp-hz = /bits/ 64 <300000000>; ++ opp-microvolt = <1050000>; ++ opp-microvolt-L0 = <1050000>; ++ opp-microvolt-L1 = <1000000>; ++ }; ++ opp-400000000 { ++ opp-hz = /bits/ 64 <400000000>; ++ opp-microvolt = <1150000>; ++ opp-microvolt-L0 = <1150000>; ++ opp-microvolt-L1 = <1100000>; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/rk3228b-box.dtsi b/arch/arm/boot/dts/rk3228b-box.dtsi +new file mode 100644 +index 0000000..1aa448e +--- /dev/null ++++ b/arch/arm/boot/dts/rk3228b-box.dtsi +@@ -0,0 +1,16 @@ ++/* ++ * Copyright (C) 2020 knaerzche ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++ ++/dts-v1/; ++ ++#include "rk322x-box.dtsi" ++#include "rk3229-cpu-opp.dtsi" ++ ++/ { ++ compatible = "rockchip,rk3228b-box", "rockchip,rk3229"; ++}; +diff --git a/arch/arm/boot/dts/rk3229-box.dtsi b/arch/arm/boot/dts/rk3229-box.dtsi +new file mode 100644 +index 0000000..8a4b25e +--- /dev/null ++++ b/arch/arm/boot/dts/rk3229-box.dtsi +@@ -0,0 +1,16 @@ ++/* ++ * Copyright (C) 2020 knaerzche ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++ ++/dts-v1/; ++ ++#include "rk322x-box.dtsi" ++#include "rk3229-cpu-opp.dtsi" ++ ++/ { ++ compatible = "rockchip,rk3229-box", "rockchip,rk3229"; ++}; +diff --git a/arch/arm/boot/dts/rk3228a-box-h96mini.dts b/arch/arm/boot/dts/rk3228a-box-h96mini.dts +new file mode 100644 +index 0000000..d191686 +--- /dev/null ++++ b/arch/arm/boot/dts/rk3228a-box-h96mini.dts +@@ -0,0 +1,151 @@ ++/* ++ * Copyright (C) 2020 knaerzche ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++ ++ ++/dts-v1/; ++ ++#include "rk3228a-box.dtsi" ++ ++/ { ++ model = "RK3228a H96 mini"; ++ ++ leds { ++ compatible = "gpio-leds"; ++ ++ led_green { ++ gpios = <&gpio3 RK_PC5 GPIO_ACTIVE_HIGH>; ++ default-state = "on"; ++ }; ++ ++ led_red { ++ gpios = <&gpio0 RK_PB0 GPIO_ACTIVE_HIGH>; ++ default-state = "off"; ++ linux,default-trigger = "rc-feedback"; ++ }; ++ }; ++ ++ wireless-wlan { ++ compatible = "wlan-platdata"; ++ rockchip,grf = <&grf>; ++ wifi_chip_type = "ap6330"; ++ sdio_vref = <3300>; ++ WIFI,host_wake_irq = <&gpio0 RK_PD4 GPIO_ACTIVE_HIGH>; ++ status = "okay"; ++ }; ++ ++ wireless-bluetooth { ++ compatible = "bluetooth-platdata"; ++ uart_rts_gpios = <&gpio3 6 GPIO_ACTIVE_LOW>; ++ pinctrl-names = "default", "rts_gpio"; ++ pinctrl-0 = <&uart11_rts>; ++ pinctrl-1 = <&uart11_rts_gpio>; ++ BT,power_gpio = <&gpio2 29 GPIO_ACTIVE_HIGH>; ++ BT,wake_gpio = <&gpio3 27 GPIO_ACTIVE_HIGH>; ++ BT,wake_host_irq = <&gpio3 26 GPIO_ACTIVE_HIGH>; ++ status = "okay"; ++ }; ++ ++ gpio_keys { ++ compatible = "gpio-keys"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ autorepeat; ++ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pwr_key>; ++ ++ power_key: power-key { ++ label = "GPIO Key Power"; ++ gpios = <&gpio3 RK_PC7 GPIO_ACTIVE_LOW>; ++ linux,code = ; ++ debounce-interval = <100>; ++ wakeup-source; ++ status = "okay"; ++ }; ++ }; ++ ++ sdio_pwrseq: sdio-pwrseq { ++ compatible = "mmc-pwrseq-simple"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&wifi_enable_h>; ++ reset-gpios = <&gpio2 26 GPIO_ACTIVE_LOW>; /* GPIO2_D2 */ ++ }; ++}; ++ ++&dram_timing { ++ sr_idle = <0x18>; ++ pd_idle = <0x20>; ++ ddr3_drv = ; ++ ddr3_odt = ; ++ phy_ddr3_clk_drv = ; ++ phy_ddr3_cmd_drv = ; ++ phy_ddr3_dqs_drv = ; ++ phy_ddr3_odt = ; ++}; ++ ++&dmc { ++ system-status-freq = < ++ /*system status freq(KHz)*/ ++ SYS_STATUS_NORMAL 600000 ++ SYS_STATUS_VIDEO_4K 700000 ++ SYS_STATUS_VIDEO_4K_10B 800000 ++ >; ++ ++ dram_freq = <300000000>; ++ status = "okay"; ++}; ++ ++&dmc_opp_table { ++ ++ /delete-node/ opp-400000000; ++ ++ /delete-node/ opp-666000000; ++ ++ opp-700000000 { ++ opp-microvolt = <1100000>; ++ opp-microvolt-L0 = <1100000>; ++ opp-microvolt-L1 = <1050000>; ++ }; ++ ++ /delete-node/ opp-786000000; ++ ++}; ++ ++&emmc { ++ clock-frequency = <37500000>; ++ max-frequency = <37500000>; ++ status = "okay"; ++}; ++ ++&sdio { ++ clock-frequency = <37500000>; ++ max-frequency = <37500000>; ++ mmc-pwrseq = <&sdio_pwrseq>; ++ status = "okay"; ++}; ++ ++&gmac { ++ tx_delay = <0x26>; ++ rx_delay = <0x11>; ++}; ++ ++&usb_otg { ++ dr_mode = "host"; ++}; ++ ++&ir_receiver { ++ linux,rc-map-name = "rc-trn9"; ++ status = "okay"; ++}; ++ ++&uart1 { ++ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart1_xfer &uart11_cts>; ++ status = "okay"; ++}; +diff --git a/arch/arm/boot/dts/rk3229-box-a95xr1.dts b/arch/arm/boot/dts/rk3229-box-a95xr1.dts +new file mode 100644 +index 0000000..4c9daf3 +--- /dev/null ++++ b/arch/arm/boot/dts/rk3229-box-a95xr1.dts +@@ -0,0 +1,120 @@ ++/* ++ * Copyright (C) 2020 knaerzche ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++ ++/dts-v1/; ++ ++#include "rk3229-box.dtsi" ++ ++/ { ++ model = "RK3229 Box A95X-R1"; ++ ++ leds { ++ compatible = "gpio-leds"; ++ ++ led_blue { ++ gpios = <&gpio3 RK_PC5 GPIO_ACTIVE_HIGH>; ++ default-state = "on"; ++ }; ++ ++ led_red { ++ gpios = <&gpio1 RK_PA7 GPIO_ACTIVE_HIGH>; ++ default-state = "off"; ++ linux,default-trigger = "rc-feedback"; ++ }; ++ }; ++ ++ wireless-wlan { ++ compatible = "wlan-platdata"; ++ rockchip,grf = <&grf>; ++ wifi_chip_type = "ssv6051"; ++ sdio_vref = <3300>; ++ WIFI,host_wake_irq = <&gpio0 28 GPIO_ACTIVE_HIGH>; ++ status = "okay"; ++ }; ++ ++ gpio_keys { ++ compatible = "gpio-keys"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ autorepeat; ++ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pwr_key>; ++ ++ power_key: power-key { ++ label = "GPIO Key Power"; ++ gpios = <&gpio0 35 GPIO_ACTIVE_HIGH>; ++ linux,code = ; ++ debounce-interval = <100>; ++ wakeup-source; ++ status = "okay"; ++ }; ++ }; ++ ++ sdio_pwrseq: sdio-pwrseq { ++ compatible = "mmc-pwrseq-simple"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&wifi_enable_h>; ++ reset-gpios = <&gpio2 26 GPIO_ACTIVE_LOW>; /* GPIO2_D2 */ ++ }; ++}; ++ ++&dram_timing { ++ sr_idle = <0x0>; ++ pd_idle = <0x0>; ++ ddr3_drv = ; ++ ddr3_odt = ; ++ phy_ddr3_clk_drv = ; ++ phy_ddr3_cmd_drv = ; ++ phy_ddr3_dqs_drv = ; ++ phy_ddr3_odt = ; ++}; ++ ++&dmc { ++ system-status-freq = < ++ /*system status freq(KHz)*/ ++ SYS_STATUS_NORMAL 786000 ++ SYS_STATUS_VIDEO_4K 786000 ++ SYS_STATUS_VIDEO_4K_10B 800000 ++ >; ++ ++ dram_freq = <786000000>; ++ status = "okay"; ++}; ++ ++&emmc { ++ clock-frequency = <100000000>; ++ max-frequency = <100000000>; ++ status = "okay"; ++}; ++ ++&sdmmc { ++ clock-frequency = <37500000>; ++ max-frequency = <37500000>; ++ status = "okay"; ++}; ++ ++&sdio { ++ clock-frequency = <37500000>; ++ max-frequency = <37500000>; ++ mmc-pwrseq = <&sdio_pwrseq>; ++ status = "okay"; ++}; ++ ++&gmac { ++ tx_delay = <0x26>; ++ rx_delay = <0x11>; ++}; ++ ++&usb_otg { ++ dr_mode = "host"; ++}; ++ ++&ir_receiver { ++ status = "okay"; ++}; +diff --git a/arch/arm/boot/dts/rk3229-box-ntn8.dts b/arch/arm/boot/dts/rk3229-box-ntn8.dts +new file mode 100644 +index 0000000..5ca6a9d +--- /dev/null ++++ b/arch/arm/boot/dts/rk3229-box-ntn8.dts +@@ -0,0 +1,132 @@ ++/* ++ * Copyright (C) 2020 knaerzche ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++ ++/dts-v1/; ++ ++#include "rk3229-box.dtsi" ++ ++/ { ++ model = "RK3229 HPH NT-N8"; ++ ++ leds { ++ compatible = "gpio-leds"; ++ ++ led_green { ++ gpios = <&gpio3 RK_PC5 GPIO_ACTIVE_HIGH>; ++ default-state = "on"; ++ }; ++ ++ led_red { ++ gpios = <&gpio0 RK_PB0 GPIO_ACTIVE_HIGH>; ++ default-state = "off"; ++ linux,default-trigger = "rc-feedback"; ++ }; ++ }; ++ ++ wireless-wlan { ++ compatible = "wlan-platdata"; ++ rockchip,grf = <&grf>; ++ wifi_chip_type = "ap6212"; ++ sdio_vref = <3300>; ++ WIFI,host_wake_irq = <&gpio0 RK_PD4 GPIO_ACTIVE_HIGH>; ++ status = "okay"; ++ }; ++ ++ wireless-bluetooth { ++ compatible = "bluetooth-platdata"; ++ uart_rts_gpios = <&gpio3 6 GPIO_ACTIVE_LOW>; ++ pinctrl-names = "default", "rts_gpio"; ++ pinctrl-0 = <&uart11_rts>; ++ pinctrl-1 = <&uart11_rts_gpio>; ++ BT,power_gpio = <&gpio2 29 GPIO_ACTIVE_HIGH>; ++ BT,wake_host_irq = <&gpio3 26 GPIO_ACTIVE_HIGH>; ++ status = "okay"; ++ }; ++ ++ gpio_keys { ++ compatible = "gpio-keys"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ autorepeat; ++ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pwr_key>; ++ ++ power_key: power-key { ++ label = "GPIO Key Power"; ++ gpios = <&gpio3 RK_PC7 GPIO_ACTIVE_LOW>; ++ linux,code = ; ++ debounce-interval = <100>; ++ wakeup-source; ++ status = "okay"; ++ }; ++ }; ++ ++ sdio_pwrseq: sdio-pwrseq { ++ compatible = "mmc-pwrseq-simple"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&wifi_enable_h>; ++ reset-gpios = <&gpio2 26 GPIO_ACTIVE_LOW>; /* GPIO2_D2 */ ++ }; ++}; ++ ++&dram_timing { ++ sr_idle = <0xc>; ++ pd_idle = <0x20>; ++ ddr3_drv = ; ++ ddr3_odt = ; ++ phy_ddr3_clk_drv = ; ++ phy_ddr3_cmd_drv = ; ++ phy_ddr3_dqs_drv = ; ++ phy_ddr3_odt = ; ++}; ++ ++&dmc { ++ system-status-freq = < ++ /*system status freq(KHz)*/ ++ SYS_STATUS_NORMAL 786000 ++ SYS_STATUS_VIDEO_4K 786000 ++ SYS_STATUS_VIDEO_4K_10B 800000 ++ >; ++ ++ dram_freq = <786000000>; ++ status = "okay"; ++}; ++ ++&emmc { ++ clock-frequency = <125000000>; ++ max-frequency = <125000000>; ++ status = "okay"; ++}; ++ ++&sdmmc { ++ clock-frequency = <37500000>; ++ max-frequency = <37500000>; ++ status = "okay"; ++}; ++ ++&sdio { ++ clock-frequency = <37500000>; ++ max-frequency = <37500000>; ++ mmc-pwrseq = <&sdio_pwrseq>; ++ status = "okay"; ++}; ++ ++&gmac { ++ tx_delay = <0x26>; ++ rx_delay = <0x11>; ++}; ++ ++&usb_otg { ++ dr_mode = "host"; ++}; ++ ++&ir_receiver { ++ linux,rc-map-name = "rc-trn9"; ++ status = "okay"; ++}; +diff --git a/arch/arm/boot/dts/rk3229-box-v884k.dts b/arch/arm/boot/dts/rk3229-box-v884k.dts +new file mode 100644 +index 0000000..d306c7a +--- /dev/null ++++ b/arch/arm/boot/dts/rk3229-box-v884k.dts +@@ -0,0 +1,109 @@ ++/* ++ * Copyright (C) 2020 knaerzche ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++ ++/dts-v1/; ++ ++#include "rk3229-box.dtsi" ++ ++/ { ++ model = "RK3229 V88 4K"; ++ ++ leds { ++ compatible = "gpio-leds"; ++ ++ led_blue { ++ gpios = <&gpio3 RK_PC5 GPIO_ACTIVE_HIGH>; ++ default-state = "on"; ++ }; ++ }; ++ ++ ++ wireless-wlan { ++ compatible = "wlan-platdata"; ++ rockchip,grf = <&grf>; ++ sdio_vref = <3300>; ++ WIFI,host_wake_irq = <&gpio0 RK_PD4 GPIO_ACTIVE_HIGH>; ++ status = "okay"; ++ }; ++ ++ gpio_keys { ++ compatible = "gpio-keys"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ autorepeat; ++ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pwr_key>; ++ ++ power_key: power-key { ++ label = "GPIO Key Power"; ++ gpios = <&gpio3 RK_PC7 GPIO_ACTIVE_LOW>; ++ linux,code = ; ++ debounce-interval = <100>; ++ wakeup-source; ++ status = "okay"; ++ }; ++ }; ++ ++ sdio_pwrseq: sdio-pwrseq { ++ compatible = "mmc-pwrseq-simple"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&wifi_enable_h>; ++ reset-gpios = <&gpio2 26 GPIO_ACTIVE_LOW>; /* GPIO2_D2 */ ++ }; ++}; ++ ++&dram_timing { ++ dram_spd_bin = <0x15>; ++ sr_idle = <0xc>; ++ pd_idle = <0x20>; ++ ddr3_drv = ; ++ ddr3_odt = ; ++ phy_ddr3_clk_drv = ; ++ phy_ddr3_cmd_drv = ; ++ phy_ddr3_dqs_drv = ; ++ phy_ddr3_odt = ; ++}; ++ ++&dmc { ++ system-status-freq = < ++ /*system status freq(KHz)*/ ++ SYS_STATUS_NORMAL 786000 ++ SYS_STATUS_VIDEO_4K 786000 ++ SYS_STATUS_VIDEO_4K_10B 800000 ++ >; ++ ++ dram_freq = <786000000>; ++ status = "okay"; ++}; ++ ++&nandc { ++ status = "okay"; ++}; ++ ++&sdmmc { ++ clock-frequency = <37500000>; ++ max-frequency = <37500000>; ++ status = "okay"; ++}; ++ ++&sdio { ++ clock-frequency = <37500000>; ++ max-frequency = <37500000>; ++ mmc-pwrseq = <&sdio_pwrseq>; ++ status = "okay"; ++}; ++ ++ ++&usb_otg { ++ dr_mode = "host"; ++}; ++ ++&ir_receiver { ++ status = "okay"; ++}; +diff --git a/arch/arm/boot/dts/rk3229-box-v88mars.dts b/arch/arm/boot/dts/rk3229-box-v88mars.dts +new file mode 100644 +index 0000000..4964f21 +--- /dev/null ++++ b/arch/arm/boot/dts/rk3229-box-v88mars.dts +@@ -0,0 +1,92 @@ ++/* ++ * Copyright (C) 2020 knaerzche ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++ ++/dts-v1/; ++ ++#include "rk3229-box.dtsi" ++ ++/ { ++ model = "RK3229 V88 Mars"; ++ ++ leds { ++ compatible = "gpio-leds"; ++ ++ led_blue { ++ gpios = <&gpio3 RK_PC5 GPIO_ACTIVE_HIGH>; ++ default-state = "on"; ++ }; ++ ++ led_red { ++ gpios = <&gpio0 RK_PA1 GPIO_ACTIVE_HIGH>; ++ default-state = "off"; ++ linux,default-trigger = "rc-feedback"; ++ }; ++ }; ++ ++ ++ wireless-wlan { ++ compatible = "wlan-platdata"; ++ rockchip,grf = <&grf>; ++ sdio_vref = <3300>; ++ WIFI,host_wake_irq = <&gpio0 RK_PD4 GPIO_ACTIVE_HIGH>; ++ status = "okay"; ++ }; ++ ++ gpio_keys { ++ compatible = "gpio-keys"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ autorepeat; ++ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pwr_key>; ++ ++ power_key: power-key { ++ label = "GPIO Key Power"; ++ gpios = <&gpio3 RK_PC7 GPIO_ACTIVE_LOW>; ++ linux,code = ; ++ debounce-interval = <100>; ++ wakeup-source; ++ status = "okay"; ++ }; ++ }; ++ ++ sdio_pwrseq: sdio-pwrseq { ++ compatible = "mmc-pwrseq-simple"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&wifi_enable_h>; ++ reset-gpios = <&gpio2 26 GPIO_ACTIVE_LOW>; /* GPIO2_D2 */ ++ }; ++}; ++ ++ ++&nandc { ++ status = "okay"; ++}; ++ ++&sdmmc { ++ clock-frequency = <50000000>; ++ max-frequency = <50000000>; ++ status = "okay"; ++}; ++ ++&sdio { ++ clock-frequency = <37500000>; ++ max-frequency = <37500000>; ++ mmc-pwrseq = <&sdio_pwrseq>; ++ status = "okay"; ++}; ++ ++ ++&usb_otg { ++ dr_mode = "host"; ++}; ++ ++&ir_receiver { ++ status = "okay"; ++}; +diff --git a/arch/arm/boot/dts/rk3229-box-hk1mini.dts b/arch/arm/boot/dts/rk3229-box-hk1mini.dts +new file mode 100644 +index 0000000..9616f11 +--- /dev/null ++++ b/arch/arm/boot/dts/rk3229-box-hk1mini.dts +@@ -0,0 +1,115 @@ ++/* ++ * Copyright (C) 2020 knaerzche ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++ ++/dts-v1/; ++ ++#include "rk3229-box.dtsi" ++ ++/ { ++ model = "RK3229 HK1mini"; ++ ++ leds { ++ compatible = "gpio-leds"; ++ ++ led_red { ++ gpios = <&gpio3 RK_PC5 GPIO_ACTIVE_HIGH>; ++ default-state = "off"; ++ linux,default-trigger = "rc-feedback"; ++ }; ++ ++ led_blue { ++ gpios = <&gpio1 RK_PA7 GPIO_ACTIVE_HIGH>; ++ default-state = "on"; ++ }; ++ }; ++ ++ wireless-wlan { ++ compatible = "wlan-platdata"; ++ rockchip,grf = <&grf>; ++ wifi_chip_type = "ssv6051"; ++ sdio_vref = <3300>; ++ WIFI,host_wake_irq = <&gpio0 28 GPIO_ACTIVE_HIGH>; ++ status = "okay"; ++ }; ++ ++ gpio_keys { ++ compatible = "gpio-keys"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ autorepeat; ++ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pwr_key>; ++ ++ power_key: power-key { ++ label = "GPIO Key Power"; ++ gpios = <&gpio0 35 GPIO_ACTIVE_HIGH>; ++ linux,code = ; ++ debounce-interval = <100>; ++ wakeup-source; ++ status = "okay"; ++ }; ++ }; ++ ++ sdio_pwrseq: sdio-pwrseq { ++ compatible = "mmc-pwrseq-simple"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&wifi_enable_h>; ++ reset-gpios = <&gpio2 26 GPIO_ACTIVE_LOW>; /* GPIO2_D2 */ ++ }; ++}; ++ ++&dram_timing { ++ sr_idle = <0x18>; ++ pd_idle = <0x20>; ++ ddr3_drv = ; ++ ddr3_odt = ; ++ phy_ddr3_clk_drv = ; ++ phy_ddr3_cmd_drv = ; ++ phy_ddr3_dqs_drv = ; ++ phy_ddr3_odt = ; ++}; ++ ++&dmc { ++ ++ system-status-freq = < ++ /*system status freq(KHz)*/ ++ SYS_STATUS_NORMAL 786000 ++ SYS_STATUS_VIDEO_4K 700000 ++ SYS_STATUS_VIDEO_4K_10B 786000 ++ >; ++ ++ dram_freq = <786000000>; ++ status = "okay"; ++}; ++ ++&nandc { ++ status = "okay"; ++}; ++ ++&sdmmc { ++ clock-frequency = <50000000>; ++ max-frequency = <50000000>; ++ status = "okay"; ++}; ++ ++&sdio { ++ clock-frequency = <37500000>; ++ max-frequency = <37500000>; ++ mmc-pwrseq = <&sdio_pwrseq>; ++ status = "okay"; ++}; ++ ++ ++&usb_otg { ++ dr_mode = "host"; ++}; ++ ++&ir_receiver { ++ status = "okay"; ++}; +diff --git a/arch/arm/boot/dts/rk3229-box-d88.dts b/arch/arm/boot/dts/rk3229-box-d88.dts +new file mode 100644 +index 0000000..b5845c5 +--- /dev/null ++++ b/arch/arm/boot/dts/rk3229-box-d88.dts +@@ -0,0 +1,119 @@ ++/* ++ * Copyright (C) 2020 knaerzche ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++ ++/dts-v1/; ++ ++#include "rk3229-box.dtsi" ++ ++/ { ++ model = "RK3229 D88 HDMI Stick"; ++ ++ leds { ++ compatible = "gpio-leds"; ++ ++ led_red { ++ gpios = <&gpio3 RK_PC5 GPIO_ACTIVE_HIGH>; ++ default-state = "off"; ++ }; ++ ++ }; ++ ++ wireless-wlan { ++ compatible = "wlan-platdata"; ++ rockchip,grf = <&grf>; ++ sdio_vref = <3300>; ++ WIFI,host_wake_irq = <&gpio0 RK_PD4 GPIO_ACTIVE_HIGH>; ++ status = "okay"; ++ }; ++ ++ wireless-bluetooth { ++ compatible = "bluetooth-platdata"; ++ uart_rts_gpios = <&gpio3 6 GPIO_ACTIVE_LOW>; ++ pinctrl-names = "default", "rts_gpio"; ++ pinctrl-0 = <&uart11_rts>; ++ pinctrl-1 = <&uart11_rts_gpio>; ++ BT,power_gpio = <&gpio2 29 GPIO_ACTIVE_HIGH>; ++ BT,wake_host_irq = <&gpio3 26 GPIO_ACTIVE_HIGH>; ++ status = "okay"; ++ }; ++ ++ gpio_keys { ++ compatible = "gpio-keys"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ autorepeat; ++ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pwr_key>; ++ ++ power_key: power-key { ++ label = "GPIO Key Power"; ++ gpios = <&gpio3 RK_PC7 GPIO_ACTIVE_LOW>; ++ linux,code = ; ++ debounce-interval = <100>; ++ wakeup-source; ++ status = "okay"; ++ }; ++ }; ++ ++ sdio_pwrseq: sdio-pwrseq { ++ compatible = "mmc-pwrseq-simple"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&wifi_enable_h>; ++ reset-gpios = <&gpio2 26 GPIO_ACTIVE_LOW>; /* GPIO2_D2 */ ++ }; ++}; ++ ++&gmac { ++ status = "disabled"; ++}; ++ ++&dram_timing { ++ sr_idle = <0x18>; ++ pd_idle = <0x20>; ++ ddr3_drv = ; ++ ddr3_odt = ; ++ phy_ddr3_clk_drv = ; ++ phy_ddr3_cmd_drv = ; ++ phy_ddr3_dqs_drv = ; ++ phy_ddr3_odt = ; ++}; ++ ++&dmc { ++ system-status-freq = < ++ /*system status freq(KHz)*/ ++ SYS_STATUS_NORMAL 600000 ++ SYS_STATUS_VIDEO_4K 786000 ++ SYS_STATUS_VIDEO_4K_10B 800000 ++ >; ++ ++ dram_freq = <786000000>; ++ status = "okay"; ++}; ++ ++&nandc { ++ status = "okay"; ++}; ++ ++&sdmmc { ++ clock-frequency = <37500000>; ++ max-frequency = <37500000>; ++ status = "okay"; ++}; ++ ++&sdio { ++ clock-frequency = <37500000>; ++ max-frequency = <37500000>; ++ mmc-pwrseq = <&sdio_pwrseq>; ++ status = "okay"; ++}; ++ ++ ++&usb_otg { ++ dr_mode = "host"; ++}; +diff --git a/arch/arm/boot/dts/rk3228a-cpu-opp.dtsi b/arch/arm/boot/dts/rk3228a-cpu-opp.dtsi +new file mode 100644 +index 0000000..98b01e5 +--- /dev/null ++++ b/arch/arm/boot/dts/rk3228a-cpu-opp.dtsi +@@ -0,0 +1,92 @@ ++/* ++ * Copyright (c) 2017 Fuzhou Rockchip Electronics Co., Ltd ++ * ++ * This file is dual-licensed: you can use it either under the terms ++ * of the GPL or the X11 license, at your option. Note that this dual ++ * licensing only applies to this file, and not this project as a ++ * whole. ++ * ++ * a) This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation; either version 2 of the ++ * License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * Or, alternatively, ++ * ++ * b) Permission is hereby granted, free of charge, to any person ++ * obtaining a copy of this software and associated documentation ++ * files (the "Software"), to deal in the Software without ++ * restriction, including without limitation the rights to use, ++ * copy, modify, merge, publish, distribute, sublicense, and/or ++ * sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following ++ * conditions: ++ * ++ * The above copyright notice and this permission notice shall be ++ * included in all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES ++ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ++ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT ++ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, ++ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING ++ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ++ * OTHER DEALINGS IN THE SOFTWARE. ++ */ ++ ++/ { ++ /delete-node/ opp-table0; ++ ++ cpu0_opp_table: opp_table0 { ++ compatible = "operating-points-v2"; ++ opp-shared; ++ ++ clocks = <&cru PLL_APLL>; ++ rockchip,max-volt = <1350000>; ++ rockchip,leakage-voltage-sel = < ++ 1 8 0 ++ 9 254 1 ++ >; ++ nvmem-cells = <&cpu_leakage>; ++ nvmem-cell-names = "cpu_leakage"; ++ ++ opp-408000000 { ++ opp-hz = /bits/ 64 <408000000>; ++ opp-microvolt = <950000 950000 1400000>; ++ opp-microvolt-L0 = <950000 950000 1400000>; ++ opp-microvolt-L1 = <950000 950000 1400000>; ++ clock-latency-ns = <40000>; ++ opp-suspend; ++ }; ++ opp-600000000 { ++ opp-hz = /bits/ 64 <600000000>; ++ opp-microvolt = <975000 975000 1400000>; ++ opp-microvolt-L0 = <975000 975000 1400000>; ++ opp-microvolt-L1 = <975000 975000 1400000>; ++ }; ++ opp-816000000 { ++ opp-hz = /bits/ 64 <816000000>; ++ opp-microvolt = <1000000 1000000 1400000>; ++ opp-microvolt-L0 = <1000000 1000000 1400000>; ++ opp-microvolt-L1 = <1000000 1000000 1400000>; ++ }; ++ opp-1008000000 { ++ opp-hz = /bits/ 64 <1008000000>; ++ opp-microvolt = <1175000 1175000 1400000>; ++ opp-microvolt-L0 = <1175000 1175000 1400000>; ++ opp-microvolt-L1 = <1125000 1125000 1400000>; ++ }; ++ opp-1200000000 { ++ opp-hz = /bits/ 64 <1200000000>; ++ opp-microvolt = <1275000 1275000 1400000>; ++ opp-microvolt-L0 = <1275000 1275000 1400000>; ++ opp-microvolt-L1 = <1225000 1225000 1400000>; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/rk3228b-box-v88mars-II.dts b/arch/arm/boot/dts/rk3228b-box-v88mars-II.dts +new file mode 100644 +index 0000000..a0d29bd +--- /dev/null ++++ b/arch/arm/boot/dts/rk3228b-box-v88mars-II.dts +@@ -0,0 +1,74 @@ ++/* ++ * Copyright (C) 2020 knaerzche ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++ ++/dts-v1/; ++ ++#include "rk3228b-box.dtsi" ++ ++/ { ++ model = "RK3228b V88 Mars II"; ++ ++ leds { ++ compatible = "gpio-leds"; ++ ++ led_blue { ++ gpios = <&gpio3 RK_PC5 GPIO_ACTIVE_HIGH>; ++ default-state = "on"; ++ }; ++ ++ led_red { ++ gpios = <&gpio0 RK_PA1 GPIO_ACTIVE_HIGH>; ++ default-state = "off"; ++ linux,default-trigger = "rc-feedback"; ++ }; ++ }; ++ ++ ++ wireless-wlan { ++ compatible = "wlan-platdata"; ++ rockchip,grf = <&grf>; ++ sdio_vref = <3300>; ++ WIFI,host_wake_irq = <&gpio0 RK_PD4 GPIO_ACTIVE_HIGH>; ++ status = "okay"; ++ }; ++ ++ ++ sdio_pwrseq: sdio-pwrseq { ++ compatible = "mmc-pwrseq-simple"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&wifi_enable_h>; ++ reset-gpios = <&gpio2 26 GPIO_ACTIVE_LOW>; /* GPIO2_D2 */ ++ }; ++}; ++ ++ ++&nandc { ++ status = "okay"; ++}; ++ ++&sdmmc { ++ clock-frequency = <37500000>; ++ max-frequency = <37500000>; ++ status = "okay"; ++}; ++ ++&sdio { ++ clock-frequency = <37500000>; ++ max-frequency = <37500000>; ++ mmc-pwrseq = <&sdio_pwrseq>; ++ status = "okay"; ++}; ++ ++ ++&usb_otg { ++ dr_mode = "host"; ++}; ++ ++&ir_receiver { ++ status = "okay"; ++}; diff --git a/patch/kernel/rk322x-legacy/02-000-remove-broken-dts.patch b/patch/kernel/rk322x-legacy/02-000-remove-broken-dts.patch new file mode 100644 index 0000000000..76b9aac384 --- /dev/null +++ b/patch/kernel/rk322x-legacy/02-000-remove-broken-dts.patch @@ -0,0 +1,12 @@ +diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile +index 4d9f7b32..1133f2ad 100644 +--- a/arch/arm/boot/dts/Makefile ++++ b/arch/arm/boot/dts/Makefile +@@ -536,7 +536,6 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += \ + rk3229-echo-v10.dtb \ + rk3229-evb.dtb \ + rk3229-evb-android.dtb \ +- rk3229-evb-android-avb.dts \ + rk3229-gva-sdk.dtb \ + rk3288-evb-act8846.dtb \ + rk3288-evb-android-act8846-edp.dtb \ diff --git a/patch/kernel/rk322x-legacy/02-001-rk322x-box-dtsi-integrate.patch b/patch/kernel/rk322x-legacy/02-001-rk322x-box-dtsi-integrate.patch new file mode 100644 index 0000000000..1bd389ee42 --- /dev/null +++ b/patch/kernel/rk322x-legacy/02-001-rk322x-box-dtsi-integrate.patch @@ -0,0 +1,153 @@ +diff --git a/arch/arm/boot/dts/rk322x-box.dtsi b/arch/arm/boot/dts/rk322x-box.dtsi +index 04330d393..608d3f386 100644 +--- a/arch/arm/boot/dts/rk322x-box.dtsi ++++ b/arch/arm/boot/dts/rk322x-box.dtsi +@@ -22,9 +22,39 @@ + + + chosen { ++ stdout-path = &uart2; + bootargs = "earlycon=uart8250,mmio32,0x11030000"; + }; + ++ bus_intmem@10080000 { ++ compatible = "mmio-sram"; ++ reg = <0x10080000 0x9000>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges = <0 0x10080000 0x9000>; ++ smp-sram@0 { ++ compatible = "rockchip,rk3066-smp-sram"; ++ reg = <0x00 0x10>; ++ }; ++ ddr_sram: ddr-sram@1000 { ++ compatible = "rockchip,rk322x-ddr-sram"; ++ reg = <0x1000 0x8000>; ++ }; ++ }; ++ ++ fiq-debugger { ++ compatible = "rockchip,fiq-debugger"; ++ interrupts = ; ++ rockchip,serial-id = <2>; ++ rockchip,signal-irq = <159>; ++ rockchip,wake-irq = <0>; ++ rockchip,irq-mode-enable = <0>; /* If enable uart uses irq instead of fiq */ ++ rockchip,baudrate = <115200>; /* Only 115200 and 1500000 */ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart21_xfer>; ++ status = "disabled"; ++ }; ++ + reserved-memory { + #address-cells = <1>; + #size-cells = <1>; +@@ -59,7 +89,7 @@ + compatible = "simple-audio-card"; + simple-audio-card,format = "i2s"; + simple-audio-card,mclk-fs = <256>; +- simple-audio-card,name = "ROCKCHIP,RK3229"; ++ simple-audio-card,name = "ANALOG"; + simple-audio-card,cpu { + sound-dai = <&i2s1>; + }; +@@ -73,7 +103,7 @@ + compatible = "simple-audio-card"; + simple-audio-card,format = "i2s"; + simple-audio-card,mclk-fs = <128>; +- simple-audio-card,name = "HDMI"; ++ simple-audio-card,name = "DW-I2S-HDMI"; + simple-audio-card,cpu { + sound-dai = <&i2s0>; + }; +@@ -113,7 +143,7 @@ + spdif-sound { + status = "okay"; + compatible = "simple-audio-card"; +- simple-audio-card,name = "ROCKCHIP,SPDIF"; ++ simple-audio-card,name = "SPDIF"; + simple-audio-card,cpu { + sound-dai = <&spdif>; + }; +@@ -219,14 +249,17 @@ + + &cpu1 { + enable-method = "psci"; ++ cpu-supply = <&vdd_arm>; + }; + + &cpu2 { + enable-method = "psci"; ++ cpu-supply = <&vdd_arm>; + }; + + &cpu3 { + enable-method = "psci"; ++ cpu-supply = <&vdd_arm>; + }; + + +@@ -237,11 +270,23 @@ + &gmac { + assigned-clocks = <&cru SCLK_MAC_SRC>; + assigned-clock-rates = <50000000>; ++ + clock_in_out = "output"; + phy-supply = <&vcc_phy>; + phy-mode = "rmii"; + phy-is-integrated; ++ ++ tx_delay = < 0x30 >; ++ rx_delay = < 0x10 >; ++ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&phy_pins>; ++ ++ snps,reset-gpio = <&gpio2 RK_PD0 GPIO_ACTIVE_LOW>; ++ snps,reset-active-low; ++ + status = "okay"; ++ + }; + + &gpu { +@@ -273,11 +318,13 @@ + broken-cd; + bus-width = <8>; + cap-mmc-highspeed; +- mmc-hs200-1_8v; + supports-emmc; + disable-wp; + non-removable; + num-slots = <1>; ++ max-frequency = <150000000>; ++ clock-frequency = <50000000>; ++ /delete-property/ clock-freq-min-max; + /delete-property/ default-sample-phase; + /delete-property/ pinctrl-names; + /delete-property/ pinctrl-0; +@@ -288,7 +335,7 @@ + cap-sd-highspeed; + card-detect-delay = <200>; + disable-wp; +- max-frequency = <50000000>; ++ max-frequency = <150000000>; + num-slots = <1>; + supports-sd; + pinctrl-names = "default"; +@@ -433,6 +480,7 @@ + status = "okay"; + + u2phy1_otg: otg-port { ++ phy-supply = <&vcc_host>; + status = "okay"; + }; + +@@ -443,6 +491,7 @@ + }; + + &usb_otg { ++ dr_mode = "host"; + status = "okay"; + }; + diff --git a/patch/kernel/rk322x-legacy/02-002-dtsi-fix-arch-sys-counter.patch b/patch/kernel/rk322x-legacy/02-002-dtsi-fix-arch-sys-counter.patch new file mode 100644 index 0000000000..80e678d374 --- /dev/null +++ b/patch/kernel/rk322x-legacy/02-002-dtsi-fix-arch-sys-counter.patch @@ -0,0 +1,12 @@ +diff --git a/arch/arm/boot/dts/rk322x.dtsi b/arch/arm/boot/dts/rk322x.dtsi +index 1f1e4e69..ec37b4d9 100644 +--- a/arch/arm/boot/dts/rk322x.dtsi ++++ b/arch/arm/boot/dts/rk322x.dtsi +@@ -262,6 +262,7 @@ + , + ; + clock-frequency = <24000000>; ++ arm,cpu-registers-not-fw-configured; + }; + + xin24m: oscillator { diff --git a/patch/kernel/rk322x-legacy/02-003-dtsi-adjust-gpu-node-for-r7p0.patch.disabled b/patch/kernel/rk322x-legacy/02-003-dtsi-adjust-gpu-node-for-r7p0.patch.disabled new file mode 100644 index 0000000000..5e1803a68f --- /dev/null +++ b/patch/kernel/rk322x-legacy/02-003-dtsi-adjust-gpu-node-for-r7p0.patch.disabled @@ -0,0 +1,62 @@ +diff --git a/arch/arm/boot/dts/rk322x.dtsi b/arch/arm/boot/dts/rk322x.dtsi +index af417ae37..a4108dde0 100644 +--- a/arch/arm/boot/dts/rk322x.dtsi ++++ b/arch/arm/boot/dts/rk322x.dtsi +@@ -774,23 +775,9 @@ + status = "disabled"; + }; + +- gpu: gpu@0x20001000 { +- compatible = "arm,mali400"; +- reg = <0x20001000 0x200>, +- <0x20000000 0x100>, +- <0x20003000 0x100>, +- <0x20008000 0x1100>, +- <0x20004000 0x100>, +- <0x2000A000 0x1100>, +- <0x20005000 0x100>; +- +- reg-names = "Mali_L2", +- "Mali_GP", +- "Mali_GP_MMU", +- "Mali_PP0", +- "Mali_PP0_MMU", +- "Mali_PP1", +- "Mali_PP1_MMU"; ++ gpu: gpu@20000000 { ++ compatible = "arm,mali-400"; ++ reg = <0x20000000 0x10000>; + + interrupts = , + , +@@ -799,16 +786,21 @@ + , + ; + +- interrupt-names = "Mali_GP_IRQ", +- "Mali_GP_MMU_IRQ", +- "Mali_PP0_IRQ", +- "Mali_PP0_MMU_IRQ", +- "Mali_PP1_IRQ", +- "Mali_PP1_MMU_IRQ"; +- clocks = <&cru ACLK_GPU>; +- #cooling-cells = <2>; /* min followed by max */ +- clock-names = "clk_mali"; ++ interrupt-names = "IRQGP", ++ "IRQGPMMU", ++ "IRQPP0", ++ "IRQPPMMU0", ++ "IRQPP1", ++ "IRQPPMMU1"; ++ ++ clocks = <&cru ACLK_GPU>, <&cru ACLK_GPU>, <&cru ACLK_GPU>; ++ clock-names = "clk_mali", "core", "bus"; ++ ++ resets = <&cru SRST_GPU_A>; ++ + operating-points-v2 = <&gpu_opp_table>; ++ ++ #cooling-cells = <2>; /* min followed by max */ + status = "disabled"; + + gpu_power_model: power_model { diff --git a/patch/kernel/rk322x-legacy/02-004-dts-makefile.patch b/patch/kernel/rk322x-legacy/02-004-dts-makefile.patch new file mode 100644 index 0000000000..33a060fad4 --- /dev/null +++ b/patch/kernel/rk322x-legacy/02-004-dts-makefile.patch @@ -0,0 +1,12 @@ +diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile +index 4d9f7b328..15d4a1da3 100644 +--- a/arch/arm/boot/dts/Makefile ++++ b/arch/arm/boot/dts/Makefile +@@ -530,6 +530,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += \ + rk3128h-evb-linux.dtb \ + rk3188-radxarock.dtb \ + rk3228-evb.dtb \ ++ rk322x-box.dtb \ + rk3229-at-3nod.dtb \ + rk3229-at-3nod-func.dtb \ + rk3229-at-gva.dtb \ diff --git a/patch/kernel/rk322x-legacy/02-005-dtsi-add-nand-pinctrls.patch b/patch/kernel/rk322x-legacy/02-005-dtsi-add-nand-pinctrls.patch new file mode 100644 index 0000000000..59d378e5f2 --- /dev/null +++ b/patch/kernel/rk322x-legacy/02-005-dtsi-add-nand-pinctrls.patch @@ -0,0 +1,79 @@ +diff --git a/arch/arm/boot/dts/rk322x.dtsi b/arch/arm/boot/dts/rk322x.dtsi +index af417ae37..80868dcda 100644 +--- a/arch/arm/boot/dts/rk322x.dtsi ++++ b/arch/arm/boot/dts/rk322x.dtsi +@@ -1386,6 +1386,74 @@ + }; + }; + ++ flash { ++ ++ flash_cs0: flash-cs0 { ++ rockchip,pins = ++ <2 RK_PA6 RK_FUNC_1 &pcfg_pull_up>; ++ }; ++ ++ flash_cs1: flash-cs1 { ++ rockchip,pins = ++ <0 RK_PC7 RK_FUNC_1 &pcfg_pull_up>; ++ }; ++ ++ flash_cs2: flash-cs2 { ++ rockchip,pins = ++ <1 RK_PC6 RK_FUNC_1 &pcfg_pull_up>; ++ }; ++ ++ flash_cs3: flash-cs3 { ++ rockchip,pins = ++ <1 RK_PC7 RK_FUNC_1 &pcfg_pull_up>; ++ }; ++ ++ flash_rdy: flash-rdy { ++ rockchip,pins = ++ <2 RK_PA4 RK_FUNC_1 &pcfg_pull_up>; ++ }; ++ ++ flash_ale: flash-ale { ++ rockchip,pins = ++ <2 RK_PA0 RK_FUNC_1 &pcfg_pull_down>; ++ }; ++ ++ flash_cle: flash-cle { ++ rockchip,pins = ++ <2 RK_PA1 RK_FUNC_1 &pcfg_pull_down>; ++ }; ++ ++ flash_wrn: flash-wrn { ++ rockchip,pins = ++ <2 RK_PA2 RK_FUNC_1 &pcfg_pull_up>; ++ }; ++ ++ flash_rdn: flash-rdn { ++ rockchip,pins = ++ <2 RK_PA3 RK_FUNC_1 &pcfg_pull_up>; ++ }; ++ ++ flash_bus8: flash-bus8 { ++ rockchip,pins = <1 RK_PD0 RK_FUNC_1 &pcfg_pull_up>, ++ <1 RK_PD1 RK_FUNC_1 &pcfg_pull_up>, ++ <1 RK_PD2 RK_FUNC_1 &pcfg_pull_up>, ++ <1 RK_PD3 RK_FUNC_1 &pcfg_pull_up>, ++ <1 RK_PD4 RK_FUNC_1 &pcfg_pull_up>, ++ <1 RK_PD5 RK_FUNC_1 &pcfg_pull_up>, ++ <1 RK_PD6 RK_FUNC_1 &pcfg_pull_up>, ++ <1 RK_PD7 RK_FUNC_1 &pcfg_pull_up>; ++ }; ++ ++ flash_dqs: flash-dqs { ++ rockchip,pins = <2 RK_PA7 RK_FUNC_1 &pcfg_pull_up>; ++ }; ++ ++ flash_wp: flash-wp { ++ rockchip,pins = <2 RK_PA5 RK_FUNC_1 &pcfg_pull_down>; ++ }; ++ ++ }; ++ + emmc { + emmc_clk: emmc-clk { + rockchip,pins = <2 7 RK_FUNC_2 &pcfg_pull_none>; diff --git a/patch/kernel/rk322x-legacy/arm64_makefile_fix_build_of_i-file_in_external_module_case.patch b/patch/kernel/rk322x-legacy/arm64_makefile_fix_build_of_i-file_in_external_module_case.patch new file mode 100644 index 0000000000..c43b6c03ba --- /dev/null +++ b/patch/kernel/rk322x-legacy/arm64_makefile_fix_build_of_i-file_in_external_module_case.patch @@ -0,0 +1,20 @@ +diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile +index 605f6cf4..08b797df 100644 +--- a/arch/arm64/Makefile ++++ b/arch/arm64/Makefile +@@ -141,6 +141,7 @@ archclean: + $(Q)$(MAKE) $(clean)=$(boot) + $(Q)$(MAKE) $(clean)=$(boot)/dts + ++ifeq ($(KBUILD_EXTMOD),) + # We need to generate vdso-offsets.h before compiling certain files in kernel/. + # In order to do that, we should use the archprepare target, but we can't since + # asm-offsets.h is included in some files used to generate vdso-offsets.h, and +@@ -150,6 +151,7 @@ archclean: + prepare: vdso_prepare + vdso_prepare: prepare0 + $(Q)$(MAKE) $(build)=arch/arm64/kernel/vdso include/generated/vdso-offsets.h ++endif + + define archhelp + echo '* Image.gz - Compressed kernel image (arch/$(ARCH)/boot/Image.gz)' diff --git a/patch/kernel/rk322x-legacy/board-rk322x-box.patch b/patch/kernel/rk322x-legacy/board-rk322x-box.patch new file mode 100644 index 0000000000..7dabde16f1 --- /dev/null +++ b/patch/kernel/rk322x-legacy/board-rk322x-box.patch @@ -0,0 +1,221 @@ +diff --git a/arch/arm/boot/dts/rk322x-box.dts b/arch/arm/boot/dts/rk322x-box.dts +new file mode 100644 +index 000000000..e5f09873c +--- /dev/null ++++ b/arch/arm/boot/dts/rk322x-box.dts +@@ -0,0 +1,215 @@ ++/* ++ * Copyright (c) 2017 Fuzhou Rockchip Electronics Co., Ltd ++ * ++ * This file is dual-licensed: you can use it either under the terms ++ * of the GPL or the X11 license, at your option. Note that this dual ++ * licensing only applies to this file, and not this project as a ++ * whole. ++ * ++ * a) This file is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation; either version 2 of the ++ * License, or (at your option) any later version. ++ * ++ * This file is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * Or, alternatively, ++ * ++ * b) Permission is hereby granted, free of charge, to any person ++ * obtaining a copy of this software and associated documentation ++ * files (the "Software"), to deal in the Software without ++ * restriction, including without limitation the rights to use, ++ * copy, modify, merge, publish, distribute, sublicense, and/or ++ * sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following ++ * conditions: ++ * ++ * The above copyright notice and this permission notice shall be ++ * included in all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES ++ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ++ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT ++ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, ++ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING ++ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ++ * OTHER DEALINGS IN THE SOFTWARE. ++ */ ++ ++/dts-v1/; ++ ++#include "rk3228a-box.dtsi" ++ ++/ { ++ ++ model = "Generic RK322x TV Box board"; ++ ++ gpio_leds: gpio-leds { ++ ++ compatible = "gpio-leds"; ++ ++ working { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&gpio_led_working>; ++ gpios = <&gpio3 RK_PC5 GPIO_ACTIVE_LOW>; ++ label = "working"; ++ default-state = "on"; ++ linux,default-trigger = "timer"; ++ }; ++ ++ }; ++ ++ sdio_pwrseq: sdio-pwrseq { ++ compatible = "mmc-pwrseq-simple"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&wifi_enable_h>; ++ reset-gpios = <&gpio2 26 GPIO_ACTIVE_LOW>; /* GPIO2_D2 */ ++ }; ++ ++}; ++ ++/** Integration to pin controller */ ++&pinctrl { ++ ++ pcfg_pull_up_12ma: pcfg-pull-up-12ma { ++ drive-strength = <12>; ++ bias-pull-up; ++ }; ++ ++ pcfg_pull_down_12ma: pcfg-pull-down-12ma { ++ drive-strength = <12>; ++ bias-pull-down; ++ }; ++ ++ pcfg_pull_none_12ma: pcfg-pull-none-12ma { ++ drive-strength = <12>; ++ bias-disable; ++ }; ++ ++ pcfg_pull_up_2ma: pcfg-pull-up-2ma { ++ drive-strength = <2>; ++ bias-pull-up; ++ }; ++ ++ pcfg_pull_down_2ma: pcfg-pull-down-2ma { ++ drive-strength = <2>; ++ bias-pull-down; ++ }; ++ ++ pcfg_pull_none_2ma: pcfg-pull-none-2ma { ++ drive-strength = <2>; ++ bias-disable; ++ }; ++ ++ /* ++ * Some rk322x electrical schemes report this kind of pull-up/down ++ * pin configurations. We set them here, but we don't use it in this ++ * device tree. These instead are useful for overlays, because they seem ++ * to increase stability on at least one board I got here ++ */ ++ sdmmc { ++ sdmmc_clk: sdmmc-clk { ++ rockchip,pins = <1 16 RK_FUNC_1 &pcfg_pull_down>; ++ }; ++ ++ sdmmc_cmd: sdmmc-cmd { ++ rockchip,pins = <1 15 RK_FUNC_1 &pcfg_pull_up>; ++ }; ++ ++ sdmmc_bus4: sdmmc-bus4 { ++ rockchip,pins = <1 18 RK_FUNC_1 &pcfg_pull_up>, ++ <1 19 RK_FUNC_1 &pcfg_pull_up>, ++ <1 20 RK_FUNC_1 &pcfg_pull_up>, ++ <1 21 RK_FUNC_1 &pcfg_pull_up>; ++ }; ++ }; ++ ++ /* ++ * Same as above, decreasing strength of SDIO pins seems to be benefical ++ * to stability ++ */ ++ sdio { ++ sdio_clk: sdio-clk { ++ rockchip,pins = <3 0 RK_FUNC_1 &pcfg_pull_down_2ma>; ++ }; ++ ++ sdio_cmd: sdio-cmd { ++ rockchip,pins = <3 1 RK_FUNC_1 &pcfg_pull_up_2ma>; ++ }; ++ ++ sdio_bus4: sdio-bus4 { ++ rockchip,pins = <3 2 RK_FUNC_1 &pcfg_pull_up_2ma>, ++ <3 3 RK_FUNC_1 &pcfg_pull_up_2ma>, ++ <3 4 RK_FUNC_1 &pcfg_pull_up_2ma>, ++ <3 5 RK_FUNC_1 &pcfg_pull_up_2ma>; ++ }; ++ }; ++ ++ /* ++ * Same drill as above, electrical schemes also report this pull-up/down ++ * configurations. ++ */ ++ emmc { ++ emmc_clk: emmc-clk { ++ rockchip,pins = <2 7 RK_FUNC_2 &pcfg_pull_up>; ++ }; ++ ++ emmc_cmd: emmc-cmd { ++ rockchip,pins = <1 22 RK_FUNC_2 &pcfg_pull_up>; ++ }; ++ ++ emmc_bus8: emmc-bus8 { ++ rockchip,pins = <1 24 RK_FUNC_2 &pcfg_pull_up>, ++ <1 25 RK_FUNC_2 &pcfg_pull_up>, ++ <1 26 RK_FUNC_2 &pcfg_pull_up>, ++ <1 27 RK_FUNC_2 &pcfg_pull_up>, ++ <1 28 RK_FUNC_2 &pcfg_pull_up>, ++ <1 29 RK_FUNC_2 &pcfg_pull_up>, ++ <1 30 RK_FUNC_2 &pcfg_pull_up>, ++ <1 31 RK_FUNC_2 &pcfg_pull_up>; ++ }; ++ ++ emmc_pwr: emmc-pwr { ++ rockchip,pins = <2 RK_PA5 RK_FUNC_2 &pcfg_pull_down>; ++ }; ++ ++ emmc_rst: emmc-rst { ++ rockchip,pins = <1 RK_PC7 RK_FUNC_2 &pcfg_pull_up>; ++ }; ++ ++ }; ++ ++ gpio { ++ gpio_led_working: gpio-led-working { ++ rockchip,pins = <3 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++}; ++ ++/** MMC and NAND controller and interfaces */ ++ ++&emmc { ++ status = "okay"; ++}; ++ ++&sdio { ++ mmc-pwrseq = <&sdio_pwrseq>; ++ status = "okay"; ++}; ++ ++&sdmmc { ++ status = "okay"; ++}; ++ ++&nandc { ++ status = "okay"; ++}; ++ ++&usb_otg { ++ dr_mode = "host"; ++}; diff --git a/patch/kernel/rk322x-legacy/general-add-overlay-compilation-support.patch b/patch/kernel/rk322x-legacy/general-add-overlay-compilation-support.patch new file mode 100644 index 0000000000..4090f07303 --- /dev/null +++ b/patch/kernel/rk322x-legacy/general-add-overlay-compilation-support.patch @@ -0,0 +1,129 @@ +diff --git a/arch/arm/Makefile b/arch/arm/Makefile +index 554985b52..c4629fc51 100644 +--- a/arch/arm/Makefile ++++ b/arch/arm/Makefile +@@ -338,6 +338,12 @@ $(INSTALL_TARGETS): + %.dtb: | scripts + $(Q)$(MAKE) $(build)=$(boot)/dts MACHINE=$(MACHINE) $(boot)/dts/$@ + ++%.dtbo: | scripts ++ $(Q)$(MAKE) $(build)=$(boot)/dts MACHINE=$(MACHINE) $(boot)/dts/$@ ++ ++%.scr: | scripts ++ $(Q)$(MAKE) $(build)=$(boot)/dts ARCH=$(ARCH) $(boot)/dts/$@ ++ + PHONY += dtbs dtbs_install + + dtbs: prepare scripts +diff --git a/arch/arm/boot/.gitignore b/arch/arm/boot/.gitignore +index ad7a0253e..e064e5f27 100644 +--- a/arch/arm/boot/.gitignore ++++ b/arch/arm/boot/.gitignore +@@ -3,5 +3,6 @@ zImage + xipImage + bootpImage + uImage +-*.dtb +-zImage-dtb +\ No newline at end of file ++*.dtb* ++*.scr ++zImage-dtb +diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile +index 4d9f7b328..743b62522 100644 +--- a/arch/arm/boot/dts/Makefile ++++ b/arch/arm/boot/dts/Makefile +@@ -850,7 +850,10 @@ DTB_LIST := $(dtb-y) + endif + + targets += dtbs dtbs_install +-targets += $(DTB_LIST) ++targets += $(dtb-y) + +-always := $(DTB_LIST) ++always := $(dtb-y) ++subdir-y := overlay + clean-files := *.dtb ++ ++dts-dirs += overlay +diff --git a/scripts/Makefile.dtbinst b/scripts/Makefile.dtbinst +index 1c15717e0..bcc0fc524 100644 +--- a/scripts/Makefile.dtbinst ++++ b/scripts/Makefile.dtbinst +@@ -29,6 +29,9 @@ ifeq ("$(dtbinst-root)", "$(obj)") + endif + + dtbinst-files := $(dtb-y) ++dtboinst-files := $(dtbo-y) ++script-files := $(scr-y) ++readme-files := $(dtbotxt-y) + dtbinst-dirs := $(dts-dirs) + + # Helper targets for Installing DTBs into the boot directory +@@ -37,15 +40,25 @@ quiet_cmd_dtb_install = INSTALL $< + + install-dir = $(patsubst $(dtbinst-root)%,$(INSTALL_DTBS_PATH)%,$(obj)) + +-$(dtbinst-files) $(dtbinst-dirs): | __dtbs_install_prep ++$(dtbinst-files) $(dtboinst-files) $(dtbinst-dirs): | __dtbs_install_prep + + $(dtbinst-files): %.dtb: $(obj)/%.dtb + $(call cmd,dtb_install,$(install-dir)) + ++ ++$(dtboinst-files): %.dtbo: $(obj)/%.dtbo ++ $(call cmd,dtb_install,$(install-dir)) ++ ++$(script-files): %.scr: $(obj)/%.scr ++ $(call cmd,dtb_install,$(install-dir)) ++ ++$(readme-files): %: $(src)/% ++ $(call cmd,dtb_install,$(install-dir)) ++ + $(dtbinst-dirs): + $(Q)$(MAKE) $(dtbinst)=$(obj)/$@ + +-PHONY += $(dtbinst-files) $(dtbinst-dirs) +-__dtbs_install: $(dtbinst-files) $(dtbinst-dirs) ++PHONY += $(dtbinst-files) $(dtboinst-files) $(script-files) $(readme-files) $(dtbinst-dirs) ++__dtbs_install: $(dtbinst-files) $(dtboinst-files) $(script-files) $(readme-files) $(dtbinst-dirs) + + .PHONY: $(PHONY) +diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib +index 3fb2aaa00..7956778c3 100644 +--- a/scripts/Makefile.lib ++++ b/scripts/Makefile.lib +@@ -270,6 +270,9 @@ cmd_gzip = (cat $(filter-out FORCE,$^) | gzip -n -f -9 > $@) || \ + # --------------------------------------------------------------------------- + DTC ?= $(objtree)/scripts/dtc/dtc + ++# Overlay support ++DTC_FLAGS += -@ -Wno-unit_address_format -Wno-simple_bus_reg ++ + # Generation of symbols for Android + ifeq ($(CONFIG_ANDROID),y) + DTC_FLAGS += -@ +@@ -319,6 +322,23 @@ cmd_dtc = mkdir -p $(dir ${dtc-tmp}) ; \ + $(obj)/%.dtb: $(src)/%.dts FORCE + $(call if_changed_dep,dtc) + ++quiet_cmd_dtco = DTCO $@ ++cmd_dtco = mkdir -p $(dir ${dtc-tmp}) ; \ ++ $(CPP) $(dtc_cpp_flags) -x assembler-with-cpp -o $(dtc-tmp) $< ; \ ++ $(DTC) -O dtb -o $@ -b 0 \ ++ -i $(dir $<) $(DTC_FLAGS) \ ++ -d $(depfile).dtc.tmp $(dtc-tmp) ; \ ++ cat $(depfile).pre.tmp $(depfile).dtc.tmp > $(depfile) ++ ++$(obj)/%.dtbo: $(src)/%.dts FORCE ++ $(call if_changed_dep,dtco) ++ ++quiet_cmd_scr = MKIMAGE $@ ++cmd_scr = mkimage -C none -A $(ARCH) -T script -d $< $@ ++ ++$(obj)/%.scr: $(src)/%.scr-cmd FORCE ++ $(call if_changed,scr) ++ + dtc-tmp = $(subst $(comma),_,$(dot-target).dts.tmp) + + # cat diff --git a/patch/kernel/rk322x-legacy/general-add-overlays.patch b/patch/kernel/rk322x-legacy/general-add-overlays.patch new file mode 100644 index 0000000000..381e2d5064 --- /dev/null +++ b/patch/kernel/rk322x-legacy/general-add-overlays.patch @@ -0,0 +1,307 @@ +diff --git a/arch/arm/boot/dts/overlay/Makefile b/arch/arm/boot/dts/overlay/Makefile +new file mode 100644 +index 000000000..f024e8db0 +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/Makefile +@@ -0,0 +1,20 @@ ++# SPDX-License-Identifier: GPL-2.0 ++dtbo-$(CONFIG_ARCH_ROCKCHIP) += \ ++ rk322x-emmc.dtbo \ ++ rk322x-nand.dtbo \ ++ rk322x-emmc-nand.dtbo \ ++ rk322x-led-conf1.dtbo \ ++ rk322x-led-conf2.dtbo \ ++ rk322x-cpu-hs.dtbo ++ ++scr-$(CONFIG_ARCH_ROCKCHIP) += \ ++ rk322x-fixup.scr ++ ++dtbotxt-$(CONFIG_ARCH_ROCKCHIP) += \ ++ README.rk322x-overlays ++ ++targets += $(dtbo-y) $(scr-y) $(dtbotxt-y) ++ ++always := $(dtbo-y) $(scr-y) $(dtbotxt-y) ++clean-files := *.dtbo *.scr ++ +diff --git a/arch/arm/boot/dts/overlay/README.rk322x-overlays b/arch/arm/boot/dts/overlay/README.rk322x-overlays +new file mode 100644 +index 000000000..d5bc7f3d5 +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/README.rk322x-overlays +@@ -0,0 +1,51 @@ ++This document describes overlays provided in the kernel packages ++For generic Armbian overlays documentation please see ++https://docs.armbian.com/User-Guide_Allwinner_overlays/ ++ ++### Platform: ++ ++rk322x (Rockchip) ++ ++### Provided overlays: ++ ++- rk322x-cpu-hs ++- rk322x-emmc ++- rk322x-nand ++- rk322x-emmc-nand ++- rk322x-led1-low ++- rk322x-led1-high ++- rk322x-led2-low ++- rk322x-led2-high ++ ++### Overlay details: ++ ++### rk322x-cpu-hs ++ ++Activates higher CPU speed (up to 1.4ghz) for rk3228b/rk3229 boxes ++ ++### emmc ++ ++Activates onboard emmc device node and deactivates the nand controller. ++Also sets up the pin controller default pull up/down configuration ++ ++### nand ++ ++Activates onboard nand device node and deactivates the emmc controller. ++Also sets up the pin controller default pull up/down configuration ++ ++### emmc-nand ++ ++Activates onboard nand and emmc devices. Usually they are alternative ++because manufacturers share the same pads so emmc and nand cannot be ++mixed together. Usually this works because the emmc and nand drivers ++can automatically guess what's in the pads, but may bring instabilities ++or misdetections. Also does not set up the pin controller default ++configuration, which in turn can be detrimental of stability and ++performance ++ ++### rk322x-led-conf* ++ ++Each device tree of this kind provides a different known wiring configuration ++(ie: gpio and active low/high) of the onboard leds. Each board manufacturer ++usually choose a different GPIO for the auxiliary led, but the main "working" ++led is always wired to the same gpio (although it may be active high or low) +diff --git a/arch/arm/boot/dts/overlay/rk322x-cpu-hs.dts b/arch/arm/boot/dts/overlay/rk322x-cpu-hs.dts +new file mode 100644 +index 000000000..1c2fc79e1 +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/rk322x-cpu-hs.dts +@@ -0,0 +1,28 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ ++ fragment@0 { ++ target = <&cpu0_opp_table>; ++ __overlay__ { ++ ++ opp-1296000000 { ++ opp-hz = /bits/ 64 <1296000000>; ++ opp-microvolt = <1325000 1325000 1400000>; ++ }; ++ opp-1392000000 { ++ opp-hz = /bits/ 64 <1392000000>; ++ opp-microvolt = <1350000 1350000 1400000>; ++ }; ++ /* ++ opp-1464000000 { ++ opp-hz = /bits/ 64 <1464000000>; ++ opp-microvolt = <1400000 1400000 1400000>; ++ }; ++ */ ++ ++ }; ++ }; ++ ++}; +diff --git a/arch/arm/boot/dts/overlay/rk322x-emmc-nand.dts b/arch/arm/boot/dts/overlay/rk322x-emmc-nand.dts +new file mode 100644 +index 000000000..b451da657 +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/rk322x-emmc-nand.dts +@@ -0,0 +1,22 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ ++ fragment@0 { ++ target = <&emmc>; ++ __overlay__ { ++ status = "okay"; ++ mmc-ddr-1_8v; ++ rockchip,default-sample-phase = <180>; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&nandc>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++}; +diff --git a/arch/arm/boot/dts/overlay/rk322x-emmc.dts b/arch/arm/boot/dts/overlay/rk322x-emmc.dts +new file mode 100644 +index 000000000..f3b262ef7 +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/rk322x-emmc.dts +@@ -0,0 +1,24 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ ++ fragment@0 { ++ target = <&emmc>; ++ __overlay__ { ++ status = "okay"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8 &emmc_pwr &emmc_rst>; ++ mmc-ddr-1_8v; ++ rockchip,default-sample-phase = <180>; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&nandc>; ++ __overlay__ { ++ status = "disabled"; ++ }; ++ }; ++ ++}; +diff --git a/arch/arm/boot/dts/overlay/rk322x-fixup.scr-cmd b/arch/arm/boot/dts/overlay/rk322x-fixup.scr-cmd +new file mode 100644 +index 000000000..d4c39e20a +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/rk322x-fixup.scr-cmd +@@ -0,0 +1,4 @@ ++# overlays fixup script ++# implements (or rather substitutes) overlay arguments functionality ++# using u-boot scripting, environment variables and "fdt" command ++ +diff --git a/arch/arm/boot/dts/overlay/rk322x-led-conf1.dts b/arch/arm/boot/dts/overlay/rk322x-led-conf1.dts +new file mode 100644 +index 000000000..053947ce8 +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/rk322x-led-conf1.dts +@@ -0,0 +1,41 @@ ++/dts-v1/; ++/plugin/; ++ ++#include ++#include ++ ++/ { ++ ++ fragment@0 { ++ target-path = "/gpio-leds"; ++ __overlay__ { ++ ++ working { ++ gpios = <&gpio3 RK_PC5 GPIO_ACTIVE_HIGH>; ++ linux,default-trigger = "none"; ++ }; ++ ++ auxiliary { ++ gpios = <&gpio0 RK_PA1 GPIO_ACTIVE_HIGH>; ++ label = "auxiliary"; ++ linux,default-trigger = "mmc2"; ++ default-state = "off"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&gpio_led_aux>; ++ }; ++ ++ }; ++ }; ++ ++ fragment@1 { ++ target-path = "/pinctrl/gpio"; ++ __overlay__ { ++ ++ gpio_led_aux: gpio-led-aux { ++ rockchip,pins = <0 RK_PA1 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ ++ }; ++ }; ++ ++}; +diff --git a/arch/arm/boot/dts/overlay/rk322x-led-conf2.dts b/arch/arm/boot/dts/overlay/rk322x-led-conf2.dts +new file mode 100644 +index 000000000..a3b0bfcee +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/rk322x-led-conf2.dts +@@ -0,0 +1,41 @@ ++/dts-v1/; ++/plugin/; ++ ++#include ++#include ++ ++/ { ++ ++ fragment@0 { ++ target-path = "/gpio-leds"; ++ __overlay__ { ++ ++ working { ++ gpios = <&gpio3 RK_PC5 GPIO_ACTIVE_LOW>; ++ linux,default-trigger = "none"; ++ }; ++ ++ auxiliary { ++ gpios = <&gpio1 RK_PA7 GPIO_ACTIVE_LOW>; ++ label = "auxiliary"; ++ linux,default-trigger = "mmc2"; ++ default-state = "off"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&gpio_led_aux>; ++ }; ++ ++ }; ++ }; ++ ++ fragment@1 { ++ target-path = "/pinctrl/gpio"; ++ __overlay__ { ++ ++ gpio_led_aux: gpio-led-aux { ++ rockchip,pins = <1 RK_PA7 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ ++ }; ++ }; ++ ++}; +diff --git a/arch/arm/boot/dts/overlay/rk322x-nand.dts b/arch/arm/boot/dts/overlay/rk322x-nand.dts +new file mode 100644 +index 000000000..5675f5b3d +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/rk322x-nand.dts +@@ -0,0 +1,22 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ ++ fragment@0 { ++ target = <&nandc>; ++ __overlay__ { ++ status = "okay"; ++ pinctrl-0 = <&flash_cs0 &flash_cs1 &flash_cs2 &flash_cs3 &flash_rdy &flash_ale &flash_cle &flash_wrn &flash_bus8 &flash_dqs &flash_wp>; ++ pinctrl-names = "default"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&emmc>; ++ __overlay__ { ++ status = "disabled"; ++ }; ++ }; ++ ++}; diff --git a/patch/u-boot/u-boot-rk322x/board_rk322x-box/rk322x-box-add-defconfig.patch b/patch/u-boot/u-boot-rk322x/board_rk322x-box/rk322x-box-add-defconfig.patch new file mode 100644 index 0000000000..4f03a08c2f --- /dev/null +++ b/patch/u-boot/u-boot-rk322x/board_rk322x-box/rk322x-box-add-defconfig.patch @@ -0,0 +1,117 @@ +diff --git a/configs/rk322x-box_defconfig b/configs/rk322x-box_defconfig +new file mode 100644 +index 00000000..950f122f +--- /dev/null ++++ b/configs/rk322x-box_defconfig +@@ -0,0 +1,111 @@ ++CONFIG_ARM=y ++CONFIG_ARCH_ROCKCHIP=y ++CONFIG_SYS_TEXT_BASE=0x61000000 ++CONFIG_SYS_MALLOC_F_LEN=0x2000 ++CONFIG_ROCKCHIP_RK322X=y ++CONFIG_SPL_ROCKCHIP_BACK_TO_BROM=y ++CONFIG_ROCKCHIP_SPL_RESERVE_IRAM=0x0 ++CONFIG_SPL_MMC_SUPPORT=y ++CONFIG_TPL_LDSCRIPT="arch/arm/mach-rockchip/u-boot-tpl.lds" ++CONFIG_TARGET_RK322X_BOX=y ++CONFIG_SPL_STACK_R_ADDR=0x60600000 ++CONFIG_NR_DRAM_BANKS=2 ++CONFIG_DEBUG_UART_BASE=0x11030000 ++CONFIG_DEBUG_UART_CLOCK=24000000 ++CONFIG_DEBUG_UART=y ++CONFIG_SPL_TEXT_BASE=0x60000000 ++CONFIG_LOCALVERSION="-armbian" ++# CONFIG_LOCALVERSION_AUTO is not set ++# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set ++CONFIG_FIT=y ++CONFIG_FIT_VERBOSE=y ++CONFIG_SPL_LOAD_FIT=y ++CONFIG_SPL_FIT_GENERATOR="arch/arm/mach-rockchip/fit_spl_optee.sh" ++CONFIG_SD_BOOT=y ++CONFIG_BOOTDELAY=0 ++CONFIG_USE_PREBOOT=y ++CONFIG_PREBOOT="usb start; usb stop; usb start" ++# CONFIG_CONSOLE_MUX is not set ++CONFIG_DEFAULT_FDT_FILE="rk322x-box.dtb" ++CONFIG_MISC_INIT_R=y ++# CONFIG_DISPLAY_CPUINFO is not set ++CONFIG_DISPLAY_BOARDINFO_LATE=y ++CONFIG_BOARD_EARLY_INIT_R=y ++# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set ++CONFIG_SPL_STACK_R=y ++CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x2000 ++CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x200 ++CONFIG_SPL_OPTEE=y ++CONFIG_CMD_GPIO=y ++CONFIG_CMD_GPT=y ++CONFIG_CMD_MMC=y ++CONFIG_CMD_USB=y ++CONFIG_CMD_ROCKUSB=y ++# CONFIG_CMD_SETEXPR is not set ++CONFIG_CMD_TIME=y ++CONFIG_SPL_OF_CONTROL=y ++CONFIG_TPL_OF_CONTROL=y ++CONFIG_DEFAULT_DEVICE_TREE="rk322x-box" ++CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents" ++CONFIG_ENV_IS_IN_EXT4=y ++CONFIG_ENV_EXT4_INTERFACE="mmc" ++CONFIG_ENV_EXT4_DEVICE_AND_PART="0:auto" ++CONFIG_ENV_EXT4_FILE="/boot/boot.env" ++CONFIG_NET_RANDOM_ETHADDR=y ++CONFIG_REGMAP=y ++CONFIG_SPL_REGMAP=y ++CONFIG_TPL_REGMAP=y ++CONFIG_SYSCON=y ++CONFIG_SPL_SYSCON=y ++CONFIG_TPL_SYSCON=y ++CONFIG_CLK=y ++CONFIG_SPL_CLK=y ++CONFIG_TPL_CLK=y ++CONFIG_FASTBOOT_BUF_SIZE=0x04000000 ++CONFIG_FASTBOOT_CMD_OEM_FORMAT=y ++CONFIG_ROCKCHIP_GPIO=y ++CONFIG_SYS_I2C_ROCKCHIP=y ++CONFIG_LED=y ++CONFIG_LED_GPIO=y ++CONFIG_MISC=y ++CONFIG_ROCKCHIP_EFUSE=y ++CONFIG_MMC_DW=y ++CONFIG_MMC_DW_ROCKCHIP=y ++CONFIG_DM_ETH=y ++CONFIG_ETH_DESIGNWARE=y ++CONFIG_GMAC_ROCKCHIP=y ++CONFIG_PHY=y ++CONFIG_PINCTRL=y ++CONFIG_RAM=y ++CONFIG_SPL_RAM=y ++CONFIG_TPL_RAM=y ++CONFIG_DM_RESET=y ++CONFIG_DEBUG_UART_SHIFT=2 ++CONFIG_DEBUG_UART_SKIP_INIT=y ++CONFIG_SYSRESET=y ++CONFIG_TEE=y ++CONFIG_OPTEE=y ++CONFIG_USB=y ++CONFIG_USB_EHCI_HCD=y ++CONFIG_USB_EHCI_GENERIC=y ++CONFIG_USB_DWC2=y ++CONFIG_ROCKCHIP_USB2_PHY=y ++CONFIG_USB_KEYBOARD=y ++CONFIG_USB_GADGET=y ++CONFIG_USB_GADGET_PRODUCT_NUM=0x320a ++CONFIG_USB_GADGET_DWC2_OTG=y ++CONFIG_USB_GADGET_VBUS_DRAW=500 ++CONFIG_USB_FUNCTION_MASS_STORAGE=y ++CONFIG_USB_FUNCTION_ROCKUSB=y ++CONFIG_DM_VIDEO=y ++# CONFIG_BACKLIGHT_PWM is not set ++# CONFIG_SYS_WHITE_ON_BLACK is not set ++CONFIG_VIDEO_ROCKCHIP=y ++CONFIG_DISPLAY_ROCKCHIP_HDMI=y ++CONFIG_TPL_TINY_MEMSET=y ++CONFIG_ERRNO_STR=y ++CONFIG_OF_LIBFDT_OVERLAY=y ++CONFIG_OPTEE_LOAD_ADDR=0x68400000 ++CONFIG_OPTEE_TZDRAM_SIZE=0x00200000 ++CONFIG_OPTEE_TZDRAM_BASE=0x68400000 ++CONFIG_BOOTM_OPTEE=y diff --git a/patch/u-boot/u-boot-rk322x/board_rk322x-box/rk322x-box-add-device-tree-makefile.patch b/patch/u-boot/u-boot-rk322x/board_rk322x-box/rk322x-box-add-device-tree-makefile.patch new file mode 100644 index 0000000000..069c65238a --- /dev/null +++ b/patch/u-boot/u-boot-rk322x/board_rk322x-box/rk322x-box-add-device-tree-makefile.patch @@ -0,0 +1,220 @@ +diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile +index 20dbc2ff..e6aa0b07 100644 +--- a/arch/arm/dts/Makefile ++++ b/arch/arm/dts/Makefile +@@ -75,7 +75,8 @@ dtb-$(CONFIG_ROCKCHIP_RK3188) += \ + rk3188-radxarock.dtb + + dtb-$(CONFIG_ROCKCHIP_RK322X) += \ +- rk3229-evb.dtb ++ rk3229-evb.dtb \ ++ rk322x-box.dtb + + dtb-$(CONFIG_ROCKCHIP_RK3288) += \ + rk3288-evb.dtb \ +diff --git a/arch/arm/mach-rockchip/rk322x/Kconfig b/arch/arm/mach-rockchip/rk322x/Kconfig +index 8a1f95f7..249add9b 100644 +--- a/arch/arm/mach-rockchip/rk322x/Kconfig ++++ b/arch/arm/mach-rockchip/rk322x/Kconfig +@@ -4,6 +4,10 @@ config TARGET_EVB_RK3229 + bool "EVB_RK3229" + select BOARD_LATE_INIT + ++config TARGET_RK322X_BOX ++ bool "RK322X-BOX" ++ select BOARD_LATE_INIT ++ + config SYS_SOC + default "rk322x" + +@@ -14,5 +18,6 @@ config SPL_SERIAL_SUPPORT + default y + + source "board/rockchip/evb_rk3229/Kconfig" ++source "board/rockchip/rk322x-box/Kconfig" + + endif +diff --git a/board/rockchip/rk322x-box/Kconfig b/board/rockchip/rk322x-box/Kconfig +new file mode 100644 +index 00000000..9ec0227e +--- /dev/null ++++ b/board/rockchip/rk322x-box/Kconfig +@@ -0,0 +1,15 @@ ++if TARGET_RK322X_BOX ++ ++config SYS_BOARD ++ default "rk322x-box" ++ ++config SYS_VENDOR ++ default "rockchip" ++ ++config SYS_CONFIG_NAME ++ default "rk322x-box" ++ ++config BOARD_SPECIFIC_OPTIONS # dummy ++ def_bool y ++ ++endif +diff --git a/board/rockchip/rk322x-box/MAINTAINERS b/board/rockchip/rk322x-box/MAINTAINERS +new file mode 100644 +index 00000000..dddc7865 +--- /dev/null ++++ b/board/rockchip/rk322x-box/MAINTAINERS +@@ -0,0 +1,6 @@ ++XT-MX4VR-V10 ++M: Paolo Sabatino ++S: Out of tree ++F: board/rockchip/rk322x-box ++F: include/configs/rk322x-box.h ++F: configs/rk322x-box_defconfig +diff --git a/board/rockchip/rk322x-box/Makefile b/board/rockchip/rk322x-box/Makefile +new file mode 100644 +index 00000000..965ff42c +--- /dev/null ++++ b/board/rockchip/rk322x-box/Makefile +@@ -0,0 +1,7 @@ ++# ++# (C) Copyright 2015 Google, Inc ++# ++# SPDX-License-Identifier: GPL-2.0+ ++# ++ ++obj-y += rk322x-box.o +diff --git a/board/rockchip/rk322x-box/README b/board/rockchip/rk322x-box/README +new file mode 100644 +index 00000000..9c047470 +--- /dev/null ++++ b/board/rockchip/rk322x-box/README +@@ -0,0 +1,72 @@ ++Get the Source and prebuild binary ++================================== ++ ++ > mkdir ~/rk322x-box ++ > cd ~/rk322x-box ++ > git clone git://git.denx.de/u-boot.git ++ > git clone https://github.com/OP-TEE/optee_os.git ++ > git clone https://github.com/rockchip-linux/rkbin.git ++ > git clone https://github.com/rockchip-linux/rkdeveloptool.git ++ ++Compile the OP-TEE ++=============== ++ ++ > cd optee_os ++ > make clean ++ > make CROSS_COMPILE_ta_arm32=arm-none-eabi- PLATFORM=rockchip-rk322x ++ Get tee.bin in this step, copy it to U-Boot root dir: ++ > cp out/arm-plat-rockchip/core/tee-pager.bin ../u-boot/tee.bin ++ ++Compile the U-Boot ++================== ++ ++ > cd ../u-boot ++ > export CROSS_COMPILE=arm-linux-gnueabihf- ++ > export ARCH=arm ++ > make rk322x-box_defconfig ++ > make ++ > make u-boot.itb ++ ++ Get tpl/u-boot-tpl.bin, spl/u-boot-spl.bin and u-boot.itb in this step. ++ ++Compile the rkdeveloptool ++======================= ++ Follow instructions in latest README ++ > cd ../rkflashtool ++ > autoreconf -i ++ > ./configure ++ > make ++ > sudo make install ++ ++ Get rkdeveloptool in you Host in this step. ++ ++Both origin binaries and Tool are ready now, choose either option 1 or ++option 2 to deploy U-Boot. ++ ++Package the image ++================= ++ ++ > cd ../u-boot ++ > tools/mkimage -n rk322x -T rksd -d tpl/u-boot-spl.bin idbloader.img ++ > cat spl/u-boot-spl.bin >> idbloader.img ++ ++ Get idbloader.img in this step. ++ ++Flash the image to eMMC ++======================= ++Power on(or reset with RESET KEY) with MASKROM KEY preesed, and then: ++ > cd .. ++ > rkdeveloptool db rkbin/rk32/rk322x_loader_v1.04.232.bin ++ > rkdeveloptool wl 64 u-boot/idbloader.img ++ > rkdeveloptool wl 0x4000 u-boot/u-boot.itb ++ > rkdeveloptool rd ++ ++Flash the image to SD card ++========================== ++ > dd if=u-boot/idbloader.img of=/dev/sdb seek=64 ++ > dd if=u-boot/u-boot.itb of=/dev/sdb seek=16384 ++ ++You should be able to get U-Boot log message with OP-TEE boot info. ++ ++For more detail, please reference to: ++http://opensource.rock-chips.com/wiki_Boot_option +diff --git a/include/configs/rk322x-box.h b/include/configs/rk322x-box.h +new file mode 100644 +index 00000000..a909aa19 +--- /dev/null ++++ b/include/configs/rk322x-box.h +@@ -0,0 +1,27 @@ ++/* SPDX-License-Identifier: GPL-2.0+ */ ++/* ++ * (C) Copyright 2017 Rockchip Electronics Co., Ltd ++ */ ++ ++#ifndef __CONFIG_H ++#define __CONFIG_H ++ ++#define ROCKCHIP_DEVICE_SETTINGS \ ++ "stdin=serial,usbkbd\0" \ ++ "stdout=serial,vidconsole\0" \ ++ "stderr=serial,vidconsole\0" ++ ++#include ++ ++#undef BOOT_TARGET_DEVICES ++ ++#define BOOT_TARGET_DEVICES(func) \ ++ func(MMC, mmc, 1) \ ++ func(USB, usb, 0) \ ++ func(MMC, mmc, 0) \ ++ func(PXE, pxe, na) \ ++ func(DHCP, dchp, na) ++ ++#define CONFIG_SYS_MMC_ENV_DEV 0 ++ ++#endif +diff --git a/board/rockchip/rk322x-box/rk322x-box.c b/board/rockchip/rk322x-box/rk322x-box.c +new file mode 100644 +index 00000000..ff7d8c98 +--- /dev/null ++++ b/board/rockchip/rk322x-box/rk322x-box.c +@@ -0,0 +1,21 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * (C) Copyright 2017 Rockchip Electronics Co., Ltd ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++int board_early_init_r(void) { ++ ++ /* LED setup */ ++ if (IS_ENABLED(CONFIG_LED)) ++ led_default_state(); ++ ++ return 0; ++ ++} ++ diff --git a/patch/u-boot/u-boot-rk322x/board_rk322x-box/rk322x-box-add-device-tree.patch b/patch/u-boot/u-boot-rk322x/board_rk322x-box/rk322x-box-add-device-tree.patch new file mode 100644 index 0000000000..d395b4e2f2 --- /dev/null +++ b/patch/u-boot/u-boot-rk322x/board_rk322x-box/rk322x-box-add-device-tree.patch @@ -0,0 +1,72 @@ +diff --git a/arch/arm/dts/rk322x-box.dts b/arch/arm/dts/rk322x-box.dts +new file mode 100755 +index 00000000..eb47f976 +--- /dev/null ++++ b/arch/arm/dts/rk322x-box.dts +@@ -0,0 +1,66 @@ ++// SPDX-License-Identifier: GPL-2.0+ OR X11 ++/* ++ * (C) Copyright 2017 Rockchip Electronics Co., Ltd. ++ */ ++ ++/dts-v1/; ++ ++#include "rk322x-generic-tvbox.dtsi" ++ ++/ { ++ model = "Generic Rockchip rk322x TV Box board"; ++ compatible = "rockchip,rk322x-box"; ++ ++}; ++ ++&leds { ++ ++ /* ++ Alternative led: some boards which have main led wired ++ as ACTIVE_LOW will not show anything during boot, thus ++ we put this gpio led as ACTIVE_HIGH, so at least one ++ may give some hint during boot. ++ Schematics say that this pin is connected to I2C0 data ++ bus, which is usually unused on rk322x boards ++ */ ++ ++ alt { ++ label = "alternative"; ++ gpios = <&gpio0 RK_PA1 GPIO_ACTIVE_HIGH>; ++ default-state = "on"; ++ }; ++ ++}; ++ ++&gmac { ++ ++ tx_delay = < 0x26 >; // Default is 0x30, but original dts proposes 0x26 ++ rx_delay = < 0x11 >; // Default is 0x10, but original dts proposes 0x11 ++ status = "okay"; ++ ++}; ++ ++&emmc { ++ ++ status = "okay"; ++ ++}; ++ ++&sdmmc { ++ ++ status = "okay"; ++ ++}; ++ ++&pinctrl { ++ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&gpio_leds>; ++ ++ gpio { ++ gpio_leds: gpio-leds { ++ rockchip,pins = <3 21 RK_FUNC_GPIO &pcfg_pull_down>; ++ }; ++ }; ++ ++}; diff --git a/patch/u-boot/u-boot-rk322x/dtsi-add-generic-tvbox.patch b/patch/u-boot/u-boot-rk322x/dtsi-add-generic-tvbox.patch new file mode 100644 index 0000000000..bb216273c3 --- /dev/null +++ b/patch/u-boot/u-boot-rk322x/dtsi-add-generic-tvbox.patch @@ -0,0 +1,157 @@ +diff --git a/arch/arm/dts/rk322x-generic-tvbox.dtsi b/arch/arm/dts/rk322x-generic-tvbox.dtsi +new file mode 100644 +index 00000000..a9733ebd +--- /dev/null ++++ b/arch/arm/dts/rk322x-generic-tvbox.dtsi +@@ -0,0 +1,151 @@ ++// SPDX-License-Identifier: GPL-2.0+ OR X11 ++/* ++ * (C) Copyright 2019 Paolo Sabatino ++ * ++ * Generic rk322x tv box device tree include file. ++ * ++ * This dtsi covers most of the common hardware included in generic tv boxes around the market. ++ * Include this dtsi in your configuration and make the necessary adjustments there for base support. ++ * ++ */ ++ ++/dts-v1/; ++ ++#include "rk322x.dtsi" ++ ++/ { ++ ++ chosen { ++ u-boot,dm-pre-reloc; ++ stdout-path = &uart2; ++ u-boot,spl-boot-order = "same-as-spl", &emmc, &sdmmc; ++ }; ++ ++ memory@60000000 { ++ device_type = "memory"; ++ reg = <0x60000000 0x40000000>; ++ }; ++ ++ leds: leds { ++ compatible = "gpio-leds"; ++ ++ /* ++ Main led is available on all boards. ++ Default state is honoured only if led_default_state() is called inside ++ an early init hook function. ++ */ ++ main { ++ label = "heartbeat"; ++ gpios = <&gpio3 RK_PC5 GPIO_ACTIVE_LOW>; ++ default-state = "on"; ++ linux,default-trigger = "heartbeat"; ++ }; ++ ++ }; ++ ++ vcc_sys: vcc-sys-regulator { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc_sys"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ }; ++ ++ vcc_phy: vcc-phy-regulator { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ regulator-name = "vcc_phy"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-always-on; ++ regulator-boot-on; ++ }; ++ ++ vcc_otg_vbus: otg-vbus-regulator { ++ compatible = "regulator-fixed"; ++ gpio = <&gpio3 RK_PC6 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&otg_vbus_drv>; ++ regulator-name = "vcc_otg_vbus"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ regulator-boot-on; ++ regulator-always-on; ++ enable-active-high; ++ vin-supply = <&vcc_sys>; ++ }; ++ ++}; ++ ++&gmac { ++ ++ assigned-clocks = <&cru SCLK_MAC_SRC>; ++ assigned-clock-rates = <50000000>; ++ ++ clock_in_out = "output"; ++ phy-supply = <&vcc_phy>; ++ phy-mode = "rmii"; ++ phy-is-integrated; ++ ++ tx_delay = < 0x30 >; // Default is 0x30, but original dts proposes 0x26 ++ rx_delay = < 0x10 >; // Default is 0x10, but original dts proposes 0x11 ++ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&phy_pins>; ++ ++ status = "okay"; ++ ++}; ++ ++&emmc { ++ ++ u-boot,dm-spl; ++ clock-frequency = <50000000>; ++ clock-freq-min-max = <400000 50000000>; ++ broken-cd; ++ cap-mmc-highspeed; ++ mmc-hs200-1_8v; ++ supports-emmc; ++ disable-wp; ++ non-removable; ++ /delete-property/ pinctrl-names; ++ /delete-property/ pinctrl-0; ++ status = "okay"; ++ ++}; ++ ++&sdmmc { ++ ++ u-boot,dm-spl; ++ bus-width = <4>; ++ cap-mmc-highspeed; ++ cap-sd-highspeed; ++ card-detect-delay = <200>; ++ disable-wp; ++ num-slots = <1>; ++ supports-sd; ++ ++ status = "okay"; ++ ++}; ++ ++&uart2 { ++ u-boot,dm-pre-reloc; ++ status = "okay"; ++}; ++ ++&usb20_otg { ++ vbus-supply = <&vcc_otg_vbus>; ++ status = "okay"; ++}; ++ ++&pinctrl { ++ ++ usb { ++ otg_vbus_drv: otg-vbus-drv { ++ rockchip,pins = <3 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++}; diff --git a/patch/u-boot/u-boot-rk322x/fix-tee-path.patch b/patch/u-boot/u-boot-rk322x/fix-tee-path.patch new file mode 100644 index 0000000000..aea8bbece9 --- /dev/null +++ b/patch/u-boot/u-boot-rk322x/fix-tee-path.patch @@ -0,0 +1,13 @@ +diff --git a/arch/arm/mach-rockchip/fit_spl_optee.sh b/arch/arm/mach-rockchip/fit_spl_optee.sh +index 4118472d..b7cbf958 100755 +--- a/arch/arm/mach-rockchip/fit_spl_optee.sh ++++ b/arch/arm/mach-rockchip/fit_spl_optee.sh +@@ -8,6 +8,8 @@ + # + # usage: $0 + ++TEE="../../../../packages/blobs/rockchip/rk322x_tee.bin" ++ + [ -z "$TEE" ] && TEE="tee.bin" + + if [ ! -f $TEE ]; then diff --git a/patch/u-boot/u-boot-rk322x/rockchip-device-settings.patch b/patch/u-boot/u-boot-rk322x/rockchip-device-settings.patch new file mode 100644 index 0000000000..9d8ad356b6 --- /dev/null +++ b/patch/u-boot/u-boot-rk322x/rockchip-device-settings.patch @@ -0,0 +1,12 @@ +diff --git a/include/configs/rk322x_common.h b/include/configs/rk322x_common.h +index 15bb8d63..093db403 100644 +--- a/include/configs/rk322x_common.h ++++ b/include/configs/rk322x_common.h +@@ -51,6 +51,7 @@ + "fdt_high=0x7fffffff\0" \ + "partitions=" PARTS_DEFAULT \ + ENV_MEM_LAYOUT_SETTINGS \ ++ ROCKCHIP_DEVICE_SETTINGS \ + BOOTENV + #endif + diff --git a/patch/u-boot/u-boot-rk322x/u-boot-1000-rockchip.patch b/patch/u-boot/u-boot-rk322x/u-boot-1000-rockchip.patch new file mode 100644 index 0000000000..4c2e4aa677 --- /dev/null +++ b/patch/u-boot/u-boot-rk322x/u-boot-1000-rockchip.patch @@ -0,0 +1,452 @@ +From e54b3dfd77c4f72064fd62dd69f8bcc010ed0ef0 Mon Sep 17 00:00:00 2001 +From: Francis Fan +Date: Tue, 7 Nov 2017 17:50:11 +0800 +Subject: [PATCH 1/3] rockchip: efuse: Support rk322x non-secure efuse. + +Change-Id: Ia25df975d21d7c97cf090f0d374074c2c5cd1a58 +Signed-off-by: Francis Fan +Signed-off-by: Cody Xie +--- + drivers/misc/rockchip-efuse.c | 75 +++++++++++++++++++++++++++++++++-- + 1 file changed, 71 insertions(+), 4 deletions(-) + +diff --git a/drivers/misc/rockchip-efuse.c b/drivers/misc/rockchip-efuse.c +index 2520c6a38e..36edf8d53d 100644 +--- a/drivers/misc/rockchip-efuse.c ++++ b/drivers/misc/rockchip-efuse.c +@@ -27,6 +27,17 @@ + #define RK3399_STROBE BIT(1) + #define RK3399_CSB BIT(0) + ++#define RK3288_A_SHIFT 6 ++#define RK3288_A_MASK 0x3ff ++#define RK3288_NFUSES 32 ++#define RK3288_BYTES_PER_FUSE 1 ++#define RK3288_PGENB BIT(3) ++#define RK3288_LOAD BIT(2) ++#define RK3288_STROBE BIT(1) ++#define RK3288_CSB BIT(0) ++ ++typedef int (*EFUSE_READ)(struct udevice *dev, int offset, void *buf, int size); ++ + struct rockchip_efuse_regs { + u32 ctrl; /* 0x00 efuse control register */ + u32 dout; /* 0x04 efuse data out register */ +@@ -53,7 +64,7 @@ static int dump_efuses(cmd_tbl_t *cmdtp, int flag, + */ + + struct udevice *dev; +- u8 fuses[128]; ++ u8 fuses[128] = {0}; + int ret; + + /* retrieve the device */ +@@ -77,7 +88,7 @@ static int dump_efuses(cmd_tbl_t *cmdtp, int flag, + } + + U_BOOT_CMD( +- rk3399_dump_efuses, 1, 1, dump_efuses, ++ rockchip_dump_efuses, 1, 1, dump_efuses, + "Dump the content of the efuses", + "" + ); +@@ -127,10 +138,59 @@ static int rockchip_rk3399_efuse_read(struct udevice *dev, int offset, + return 0; + } + ++static int rockchip_rk3288_efuse_read(struct udevice *dev, int offset, ++ void *buf, int size) ++{ ++ struct rockchip_efuse_platdata *plat = dev_get_platdata(dev); ++ struct rockchip_efuse_regs *efuse = ++ (struct rockchip_efuse_regs *)plat->base; ++ u8 *buffer = buf; ++ int max_size = RK3288_NFUSES * RK3288_BYTES_PER_FUSE; ++ ++ if (size > (max_size - offset)) ++ size = max_size - offset; ++ ++ /* Switch to read mode */ ++ writel(RK3288_LOAD | RK3288_PGENB, &efuse->ctrl); ++ udelay(1); ++ ++ while (size--) { ++ writel(readl(&efuse->ctrl) & ++ (~(RK3288_A_MASK << RK3288_A_SHIFT)), ++ &efuse->ctrl); ++ /* set addr */ ++ writel(readl(&efuse->ctrl) | ++ ((offset++ & RK3288_A_MASK) << RK3288_A_SHIFT), ++ &efuse->ctrl); ++ udelay(1); ++ /* strobe low to high */ ++ writel(readl(&efuse->ctrl) | ++ RK3288_STROBE, &efuse->ctrl); ++ ndelay(60); ++ /* read data */ ++ *buffer++ = readl(&efuse->dout); ++ /* reset strobe to low */ ++ writel(readl(&efuse->ctrl) & ++ (~RK3288_STROBE), &efuse->ctrl); ++ udelay(1); ++ } ++ ++ /* Switch to standby mode */ ++ writel(RK3288_PGENB | RK3288_CSB, &efuse->ctrl); ++ ++ return 0; ++} ++ + static int rockchip_efuse_read(struct udevice *dev, int offset, + void *buf, int size) + { +- return rockchip_rk3399_efuse_read(dev, offset, buf, size); ++ EFUSE_READ efuse_read = NULL; ++ ++ efuse_read = (EFUSE_READ)dev_get_driver_data(dev); ++ if (!efuse_read) ++ return -ENOSYS; ++ ++ return (*efuse_read)(dev, offset, buf, size); + } + + static const struct misc_ops rockchip_efuse_ops = { +@@ -146,7 +206,14 @@ static int rockchip_efuse_ofdata_to_platdata(struct udevice *dev) + } + + static const struct udevice_id rockchip_efuse_ids[] = { +- { .compatible = "rockchip,rk3399-efuse" }, ++ { ++ .compatible = "rockchip,rk3288-efuse", ++ .data = (ulong)&rockchip_rk3288_efuse_read, ++ }, ++ { ++ .compatible = "rockchip,rk3399-efuse", ++ .data = (ulong)&rockchip_rk3399_efuse_read, ++ }, + {} + }; + + +From d2794118b9ddbe8e76da4249d2de393476337e5b Mon Sep 17 00:00:00 2001 +From: Joseph Chen +Date: Thu, 2 Aug 2018 20:33:16 +0800 +Subject: [PATCH 2/3] rockchip: efuse: support rk3328 non-secure efuse + +Change-Id: Ie74764ef946b79c2e9f73e9082c1cb8bbc288abb +Signed-off-by: Joseph Chen +--- + drivers/misc/rockchip-efuse.c | 66 +++++++++++++++++++++++++++++++++++ + 1 file changed, 66 insertions(+) + +diff --git a/drivers/misc/rockchip-efuse.c b/drivers/misc/rockchip-efuse.c +index 36edf8d53d..f2d362cef8 100644 +--- a/drivers/misc/rockchip-efuse.c ++++ b/drivers/misc/rockchip-efuse.c +@@ -36,6 +36,13 @@ + #define RK3288_STROBE BIT(1) + #define RK3288_CSB BIT(0) + ++#define RK3328_INT_STATUS 0x0018 ++#define RK3328_DOUT 0x0020 ++#define RK3328_AUTO_CTRL 0x0024 ++#define RK3328_INT_FINISH BIT(0) ++#define RK3328_AUTO_ENB BIT(0) ++#define RK3328_AUTO_RD BIT(1) ++ + typedef int (*EFUSE_READ)(struct udevice *dev, int offset, void *buf, int size); + + struct rockchip_efuse_regs { +@@ -46,6 +53,10 @@ struct rockchip_efuse_regs { + u32 jtag_pass; /* 0x10 JTAG password */ + u32 strobe_finish_ctrl; + /* 0x14 efuse strobe finish control register */ ++ u32 int_status;/* 0x18 */ ++ u32 reserved; /* 0x1c */ ++ u32 dout2; /* 0x20 */ ++ u32 auto_ctrl; /* 0x24 */ + }; + + struct rockchip_efuse_platdata { +@@ -181,6 +192,57 @@ static int rockchip_rk3288_efuse_read(struct udevice *dev, int offset, + return 0; + } + ++static int rockchip_rk3328_efuse_read(struct udevice *dev, int offset, ++ void *buf, int size) ++{ ++ struct rockchip_efuse_platdata *plat = dev_get_platdata(dev); ++ struct rockchip_efuse_regs *efuse = ++ (struct rockchip_efuse_regs *)plat->base; ++ unsigned int addr_start, addr_end, addr_offset, addr_len; ++ u32 out_value, status; ++ u8 *buffer; ++ int ret = 0, i = 0, j = 0; ++ ++ /* Max non-secure Byte */ ++ if (size > 32) ++ size = 32; ++ ++ /* 128 Byte efuse, 96 Byte for secure, 32 Byte for non-secure */ ++ offset += 96; ++ addr_start = rounddown(offset, RK3399_BYTES_PER_FUSE) / ++ RK3399_BYTES_PER_FUSE; ++ addr_end = roundup(offset + size, RK3399_BYTES_PER_FUSE) / ++ RK3399_BYTES_PER_FUSE; ++ addr_offset = offset % RK3399_BYTES_PER_FUSE; ++ addr_len = addr_end - addr_start; ++ ++ buffer = calloc(1, sizeof(*buffer) * addr_len * RK3399_BYTES_PER_FUSE); ++ if (!buffer) ++ return -ENOMEM; ++ ++ for (j = 0; j < addr_len; j++) { ++ writel(RK3328_AUTO_RD | RK3328_AUTO_ENB | ++ ((addr_start++ & RK3399_A_MASK) << RK3399_A_SHIFT), ++ &efuse->auto_ctrl); ++ udelay(5); ++ status = readl(&efuse->int_status); ++ if (!(status & RK3328_INT_FINISH)) { ++ ret = -EIO; ++ goto err; ++ } ++ out_value = readl(&efuse->dout2); ++ writel(RK3328_INT_FINISH, &efuse->int_status); ++ ++ memcpy(&buffer[i], &out_value, RK3399_BYTES_PER_FUSE); ++ i += RK3399_BYTES_PER_FUSE; ++ } ++ memcpy(buf, buffer + addr_offset, size); ++err: ++ free(buffer); ++ ++ return ret; ++} ++ + static int rockchip_efuse_read(struct udevice *dev, int offset, + void *buf, int size) + { +@@ -210,6 +272,10 @@ static const struct udevice_id rockchip_efuse_ids[] = { + .compatible = "rockchip,rk3288-efuse", + .data = (ulong)&rockchip_rk3288_efuse_read, + }, ++ { ++ .compatible = "rockchip,rk3328-efuse", ++ .data = (ulong)&rockchip_rk3328_efuse_read, ++ }, + { + .compatible = "rockchip,rk3399-efuse", + .data = (ulong)&rockchip_rk3399_efuse_read, + +From 81fd1a75139801213cd29af46df7b282648f4559 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Thu, 23 Jan 2020 21:09:38 +0000 +Subject: [PATCH 3/3] WIP: rockchip: get serial and ethaddr from efuse + +--- + arch/arm/dts/rk3288.dtsi | 3 +-- + arch/arm/dts/rk3328.dtsi | 14 ++++++++++++++ + configs/evb-rk3328_defconfig | 3 +++ + configs/evb-rk3399_defconfig | 2 ++ + configs/miqi-rk3288_defconfig | 2 ++ + configs/rock64-rk3328_defconfig | 2 ++ + configs/tinker-rk3288_defconfig | 1 + + configs/tinker-s-rk3288_defconfig | 1 + + 8 files changed, 26 insertions(+), 2 deletions(-) + +diff --git a/arch/arm/dts/rk3288.dtsi b/arch/arm/dts/rk3288.dtsi +index 866fc08215..b0d1b2f90a 100644 +--- a/arch/arm/dts/rk3288.dtsi ++++ b/arch/arm/dts/rk3288.dtsi +@@ -910,8 +910,7 @@ + + efuse: efuse@ffb40000 { + compatible = "rockchip,rk3288-efuse"; +- reg = <0xffb40000 0x10000>; +- status = "disabled"; ++ reg = <0xffb40000 0x20>; + }; + + gic: interrupt-controller@ffc01000 { +diff --git a/arch/arm/dts/rk3328.dtsi b/arch/arm/dts/rk3328.dtsi +index 060c84e6c0..34c0b7de41 100644 +--- a/arch/arm/dts/rk3328.dtsi ++++ b/arch/arm/dts/rk3328.dtsi +@@ -337,6 +337,20 @@ + }; + }; + ++ efuse: efuse@ff260000 { ++ compatible = "rockchip,rk3328-efuse"; ++ reg = <0x0 0xff260000 0x0 0x80>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ clocks = <&cru SCLK_EFUSE>; ++ clock-names = "pclk_efuse"; ++ ++ /* Data cells */ ++ cpu_id: cpu-id@7 { ++ reg = <0x07 0x10>; ++ }; ++ }; ++ + saradc: saradc@ff280000 { + compatible = "rockchip,rk3328-saradc", "rockchip,saradc"; + reg = <0x0 0xff280000 0x0 0x100>; +diff --git a/configs/evb-rk3328_defconfig b/configs/evb-rk3328_defconfig +index 3db40a9a1a..edd1c41f09 100644 +--- a/configs/evb-rk3328_defconfig ++++ b/configs/evb-rk3328_defconfig +@@ -19,6 +19,7 @@ CONFIG_FIT=y + CONFIG_FIT_VERBOSE=y + CONFIG_SPL_LOAD_FIT=y + CONFIG_DEFAULT_FDT_FILE="rockchip/rk3328-evb.dtb" ++CONFIG_MISC_INIT_R=y + # CONFIG_DISPLAY_CPUINFO is not set + CONFIG_DISPLAY_BOARDINFO_LATE=y + # CONFIG_SPL_RAW_IMAGE_SUPPORT is not set +@@ -55,6 +56,8 @@ CONFIG_FASTBOOT_BUF_ADDR=0x800800 + CONFIG_FASTBOOT_CMD_OEM_FORMAT=y + CONFIG_ROCKCHIP_GPIO=y + CONFIG_SYS_I2C_ROCKCHIP=y ++CONFIG_MISC=y ++CONFIG_ROCKCHIP_EFUSE=y + CONFIG_MMC_DW=y + CONFIG_MMC_DW_ROCKCHIP=y + CONFIG_SF_DEFAULT_SPEED=20000000 +diff --git a/configs/evb-rk3399_defconfig b/configs/evb-rk3399_defconfig +index 8b8cdc5109..71c2daf8f5 100644 +--- a/configs/evb-rk3399_defconfig ++++ b/configs/evb-rk3399_defconfig +@@ -28,6 +28,8 @@ CONFIG_SYS_RELOC_GD_ENV_ADDR=y + CONFIG_NET_RANDOM_ETHADDR=y + CONFIG_ROCKCHIP_GPIO=y + CONFIG_SYS_I2C_ROCKCHIP=y ++CONFIG_MISC=y ++CONFIG_ROCKCHIP_EFUSE=y + CONFIG_MMC_DW=y + CONFIG_MMC_SDHCI=y + CONFIG_MMC_SDHCI_ROCKCHIP=y +diff --git a/configs/miqi-rk3288_defconfig b/configs/miqi-rk3288_defconfig +index cec8e42c5e..ac05d35392 100644 +--- a/configs/miqi-rk3288_defconfig ++++ b/configs/miqi-rk3288_defconfig +@@ -50,6 +50,8 @@ CONFIG_SPL_CLK=y + CONFIG_FASTBOOT_CMD_OEM_FORMAT=y + CONFIG_ROCKCHIP_GPIO=y + CONFIG_SYS_I2C_ROCKCHIP=y ++CONFIG_MISC=y ++CONFIG_ROCKCHIP_EFUSE=y + CONFIG_MMC_DW=y + CONFIG_MMC_DW_ROCKCHIP=y + CONFIG_MTD=y +diff --git a/configs/rock64-rk3328_defconfig b/configs/rock64-rk3328_defconfig +index 720b5e0424..c849bc4939 100644 +--- a/configs/rock64-rk3328_defconfig ++++ b/configs/rock64-rk3328_defconfig +@@ -54,6 +54,8 @@ CONFIG_FASTBOOT_BUF_ADDR=0x800800 + CONFIG_FASTBOOT_CMD_OEM_FORMAT=y + CONFIG_ROCKCHIP_GPIO=y + CONFIG_SYS_I2C_ROCKCHIP=y ++CONFIG_MISC=y ++CONFIG_ROCKCHIP_EFUSE=y + CONFIG_MMC_DW=y + CONFIG_MMC_DW_ROCKCHIP=y + CONFIG_SF_DEFAULT_SPEED=20000000 +diff --git a/configs/tinker-rk3288_defconfig b/configs/tinker-rk3288_defconfig +index 83c3450839..d586b509f6 100644 +--- a/configs/tinker-rk3288_defconfig ++++ b/configs/tinker-rk3288_defconfig +@@ -53,6 +53,7 @@ CONFIG_FASTBOOT_CMD_OEM_FORMAT=y + CONFIG_ROCKCHIP_GPIO=y + CONFIG_SYS_I2C_ROCKCHIP=y + CONFIG_MISC=y ++CONFIG_ROCKCHIP_EFUSE=y + CONFIG_I2C_EEPROM=y + CONFIG_MMC_DW=y + CONFIG_MMC_DW_ROCKCHIP=y +diff --git a/configs/tinker-s-rk3288_defconfig b/configs/tinker-s-rk3288_defconfig +index 4925b14821..91dcc76564 100644 +--- a/configs/tinker-s-rk3288_defconfig ++++ b/configs/tinker-s-rk3288_defconfig +@@ -53,6 +53,7 @@ CONFIG_FASTBOOT_CMD_OEM_FORMAT=y + CONFIG_ROCKCHIP_GPIO=y + CONFIG_SYS_I2C_ROCKCHIP=y + CONFIG_MISC=y ++CONFIG_ROCKCHIP_EFUSE=y + CONFIG_I2C_EEPROM=y + CONFIG_MMC_DW=y + CONFIG_MMC_DW_ROCKCHIP=y +diff --git a/include/dt-bindings/clock/rk3228-cru.h b/include/dt-bindings/clock/rk3228-cru.h +index 1217d5239f..2904303034 100644 +--- a/include/dt-bindings/clock/rk3228-cru.h ++++ b/include/dt-bindings/clock/rk3228-cru.h +@@ -67,6 +67,10 @@ + #define PCLK_GPIO1 321 + #define PCLK_GPIO2 322 + #define PCLK_GPIO3 323 ++#define PCLK_VIO_H2P 324 ++#define PCLK_HDCP 325 ++#define PCLK_EFUSE_1024 326 ++#define PCLK_EFUSE_256 327 + #define PCLK_GRF 329 + #define PCLK_I2C0 332 + #define PCLK_I2C1 333 +diff --git a/arch/arm/dts/rk322x.dtsi b/arch/arm/dts/rk322x.dtsi +index 4a8be5dabb..255e3a7a28 100644 +--- a/arch/arm/dts/rk322x.dtsi ++++ b/arch/arm/dts/rk322x.dtsi +@@ -212,6 +212,20 @@ + status = "disabled"; + }; + ++ efuse: efuse@11040000 { ++ compatible = "rockchip,rk3228-efuse", "rockchip,rk3288-efuse"; ++ reg = <0x11040000 0x20>; ++ clocks = <&cru PCLK_EFUSE_256>; ++ clock-names = "pclk_efuse"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ /* Data cells */ ++ cpu_id: cpu_id@7 { ++ reg = <0x7 0x10>; ++ }; ++ }; ++ + i2c0: i2c@11050000 { + compatible = "rockchip,rk3228-i2c"; + reg = <0x11050000 0x1000>; +diff --git a/configs/evb-rk3229_defconfig b/configs/evb-rk3229_defconfig +index 6b302e987c..3c0b82df1c 100644 +--- a/configs/evb-rk3229_defconfig ++++ b/configs/evb-rk3229_defconfig +@@ -32,6 +32,7 @@ CONFIG_CMD_TIME=y + CONFIG_SPL_OF_CONTROL=y + CONFIG_TPL_OF_CONTROL=y + CONFIG_DEFAULT_DEVICE_TREE="rk3229-evb" ++CONFIG_MISC_INIT_R=y + CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents" + CONFIG_ENV_IS_IN_MMC=y + CONFIG_SYS_RELOC_GD_ENV_ADDR=y +@@ -49,6 +50,8 @@ CONFIG_FASTBOOT_BUF_SIZE=0x04000000 + CONFIG_FASTBOOT_CMD_OEM_FORMAT=y + CONFIG_ROCKCHIP_GPIO=y + CONFIG_SYS_I2C_ROCKCHIP=y ++CONFIG_MISC=y ++CONFIG_ROCKCHIP_EFUSE=y + CONFIG_MMC_DW=y + CONFIG_MMC_DW_ROCKCHIP=y + CONFIG_MTD=y +diff --git a/drivers/misc/rockchip-efuse.c b/drivers/misc/rockchip-efuse.c +index f2d362ce..2aa9373f 100644 +--- a/drivers/misc/rockchip-efuse.c ++++ b/drivers/misc/rockchip-efuse.c +@@ -14,6 +14,7 @@ + #include + #include + #include ++#include + + #define RK3399_A_SHIFT 16 + #define RK3399_A_MASK 0x3ff diff --git a/patch/u-boot/u-boot-rk322x/u-boot-1001-rockchip-rmii-integrated-phy.patch b/patch/u-boot/u-boot-rk322x/u-boot-1001-rockchip-rmii-integrated-phy.patch new file mode 100644 index 0000000000..b10a7950a7 --- /dev/null +++ b/patch/u-boot/u-boot-rk322x/u-boot-1001-rockchip-rmii-integrated-phy.patch @@ -0,0 +1,902 @@ +diff --git a/arch/arm/dts/rk3229-evb.dts b/arch/arm/dts/rk3229-evb.dts +index 632cdc9bc3..f868524ae1 100644 +--- a/arch/arm/dts/rk3229-evb.dts ++++ b/arch/arm/dts/rk3229-evb.dts +@@ -50,19 +50,25 @@ + }; + + &gmac { +- assigned-clocks = <&cru SCLK_MAC_EXTCLK>, <&cru SCLK_MAC>; +- assigned-clock-parents = <&ext_gmac>, <&cru SCLK_MAC_EXTCLK>; +- clock_in_out = "input"; +- phy-supply = <&vcc_phy>; +- phy-mode = "rgmii"; +- pinctrl-names = "default"; +- pinctrl-0 = <&rgmii_pins>; +- snps,reset-gpio = <&gpio2 RK_PD0 GPIO_ACTIVE_LOW>; +- snps,reset-active-low; +- snps,reset-delays-us = <0 10000 1000000>; +- tx_delay = <0x30>; +- rx_delay = <0x10>; +- status = "okay"; ++ assigned-clocks = <&cru SCLK_MAC_SRC>; ++ assigned-clock-rates = <50000000>; ++ clock_in_out = "output"; ++ phy-supply = <&vcc_phy>; ++ phy-mode = "rmii"; ++ phy-handle = <&phy>; ++ status = "okay"; ++ ++ mdio { ++ compatible = "snps,dwmac-mdio"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ phy: phy@0 { ++ compatible = "ethernet-phy-id1234.d400", "ethernet-phy-ieee802.3-c22"; ++ reg = <0>; ++ phy-is-integrated; ++ }; ++ }; + }; + + &emmc { +diff --git a/arch/arm/dts/rk322x.dtsi b/arch/arm/dts/rk322x.dtsi +index 4a8be5dabb..3c2861f271 100644 +--- a/arch/arm/dts/rk322x.dtsi ++++ b/arch/arm/dts/rk322x.dtsi +@@ -448,13 +448,13 @@ + clocks = <&cru SCLK_MAC>, <&cru SCLK_MAC_RX>, + <&cru SCLK_MAC_TX>, <&cru SCLK_MAC_REF>, + <&cru SCLK_MAC_REFOUT>, <&cru ACLK_GMAC>, +- <&cru PCLK_GMAC>; ++ <&cru PCLK_GMAC>, <&cru SCLK_MAC_PHY>; + clock-names = "stmmaceth", "mac_clk_rx", + "mac_clk_tx", "clk_mac_ref", + "clk_mac_refout", "aclk_mac", +- "pclk_mac"; +- resets = <&cru SRST_GMAC>; +- reset-names = "stmmaceth"; ++ "pclk_mac", "clk_macphy"; ++ resets = <&cru SRST_GMAC>, <&cru SRST_MACPHY>; ++ reset-names = "stmmaceth", "mac-phy"; + rockchip,grf = <&grf>; + status = "disabled"; + }; +diff --git a/arch/arm/dts/rk3328-evb.dts b/arch/arm/dts/rk3328-evb.dts +index a2ee838fcd..704712a05e 100644 +--- a/arch/arm/dts/rk3328-evb.dts ++++ b/arch/arm/dts/rk3328-evb.dts +@@ -100,6 +100,16 @@ + pinctrl-0 = <&rgmiim1_pins>; + tx_delay = <0x26>; + rx_delay = <0x11>; ++ status = "disabled"; ++}; ++ ++&gmac2phy { ++ phy-supply = <&vcc_phy>; ++ clock_in_out = "output"; ++ assigned-clocks = <&cru SCLK_MAC2PHY_SRC>; ++ assigned-clock-rate = <50000000>; ++ assigned-clocks = <&cru SCLK_MAC2PHY>; ++ assigned-clock-parents = <&cru SCLK_MAC2PHY_SRC>; + status = "okay"; + }; + +diff --git a/arch/arm/dts/rk3328.dtsi b/arch/arm/dts/rk3328.dtsi +index 060c84e6c0..c9419db07f 100644 +--- a/arch/arm/dts/rk3328.dtsi ++++ b/arch/arm/dts/rk3328.dtsi +@@ -464,6 +464,41 @@ + status = "disabled"; + }; + ++ gmac2phy: ethernet@ff550000 { ++ compatible = "rockchip,rk3328-gmac"; ++ reg = <0x0 0xff550000 0x0 0x10000>; ++ rockchip,grf = <&grf>; ++ interrupts = ; ++ interrupt-names = "macirq"; ++ clocks = <&cru SCLK_MAC2PHY_SRC>, <&cru SCLK_MAC2PHY_RXTX>, ++ <&cru SCLK_MAC2PHY_RXTX>, <&cru SCLK_MAC2PHY_REF>, ++ <&cru ACLK_MAC2PHY>, <&cru PCLK_MAC2PHY>, ++ <&cru SCLK_MAC2PHY_OUT>; ++ clock-names = "stmmaceth", "mac_clk_rx", ++ "mac_clk_tx", "clk_mac_ref", ++ "aclk_mac", "pclk_mac", ++ "clk_macphy"; ++ resets = <&cru SRST_GMAC2PHY_A>, <&cru SRST_MACPHY>; ++ reset-names = "stmmaceth", "mac-phy"; ++ phy-mode = "rmii"; ++ phy-handle = <&phy>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&fephyled_rxm1 &fephyled_linkm1>; ++ status = "disabled"; ++ ++ mdio { ++ compatible = "snps,dwmac-mdio"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ phy: phy@0 { ++ compatible = "ethernet-phy-id1234.d400", "ethernet-phy-ieee802.3-c22"; ++ reg = <0>; ++ phy-is-integrated; ++ }; ++ }; ++ }; ++ + usb_host0_ehci: usb@ff5c0000 { + compatible = "generic-ehci"; + reg = <0x0 0xff5c0000 0x0 0x10000>; +diff --git a/arch/arm/include/asm/arch-rockchip/cru_rk322x.h b/arch/arm/include/asm/arch-rockchip/cru_rk322x.h +index c87c830716..15039c87be 100644 +--- a/arch/arm/include/asm/arch-rockchip/cru_rk322x.h ++++ b/arch/arm/include/asm/arch-rockchip/cru_rk322x.h +@@ -12,6 +12,7 @@ + + #define APLL_HZ (600 * MHz) + #define GPLL_HZ (594 * MHz) ++#define CPLL_HZ (500 * MHz) + + #define CORE_PERI_HZ 150000000 + #define CORE_ACLK_HZ 300000000 +diff --git a/configs/evb-rk3229_defconfig b/configs/evb-rk3229_defconfig +index f8e648bbb4..5fd2bd3ba2 100644 +--- a/configs/evb-rk3229_defconfig ++++ b/configs/evb-rk3229_defconfig +@@ -58,6 +58,8 @@ CONFIG_GMAC_ROCKCHIP=y + CONFIG_PHY=y + CONFIG_PINCTRL=y + CONFIG_RAM=y ++CONFIG_DM_RESET=y ++CONFIG_RESET_ROCKCHIP=y + CONFIG_SPL_RAM=y + CONFIG_TPL_RAM=y + CONFIG_BAUDRATE=1500000 +diff --git a/configs/evb-rk3328_defconfig b/configs/evb-rk3328_defconfig +index 5bbdc00214..19c09e4503 100644 +--- a/configs/evb-rk3328_defconfig ++++ b/configs/evb-rk3328_defconfig +@@ -71,6 +71,8 @@ CONFIG_DM_REGULATOR_FIXED=y + CONFIG_REGULATOR_RK8XX=y + CONFIG_PWM_ROCKCHIP=y + CONFIG_RAM=y ++CONFIG_DM_RESET=y ++CONFIG_RESET_ROCKCHIP=y + CONFIG_SPL_RAM=y + CONFIG_TPL_RAM=y + CONFIG_BAUDRATE=1500000 +diff --git a/doc/device-tree-bindings/net/phy.txt b/doc/device-tree-bindings/net/phy.txt +index 6599c667b5..ca1a4a8526 100644 +--- a/doc/device-tree-bindings/net/phy.txt ++++ b/doc/device-tree-bindings/net/phy.txt +@@ -8,6 +8,19 @@ Required properties: + + - reg : The ID number for the phy, usually a small integer + ++Optional Properties: ++ ++- compatible: Compatible list, may contain ++ "ethernet-phy-ieee802.3-c22" or "ethernet-phy-ieee802.3-c45" for ++ PHYs that implement IEEE802.3 clause 22 or IEEE802.3 clause 45 ++ specifications. If neither of these are specified, the default is to ++ assume clause 22. ++ ++- phy-is-integrated: If set, indicates that the PHY is integrated into the same ++ physical package as the Ethernet MAC. If needed, muxers should be configured ++ to ensure the integrated PHY is used. The absence of this property indicates ++ the muxers should be configured so that the external PHY is used. ++ + Example: + + ethernet-phy@0 { +diff --git a/drivers/clk/rockchip/clk_rk322x.c b/drivers/clk/rockchip/clk_rk322x.c +index ef33adbf29..c427e0438b 100644 +--- a/drivers/clk/rockchip/clk_rk322x.c ++++ b/drivers/clk/rockchip/clk_rk322x.c +@@ -38,6 +38,7 @@ enum { + /* use integer mode*/ + static const struct pll_div apll_init_cfg = PLL_DIVISORS(APLL_HZ, 1, 3, 1); + static const struct pll_div gpll_init_cfg = PLL_DIVISORS(GPLL_HZ, 2, 2, 1); ++static const struct pll_div cpll_init_cfg = PLL_DIVISORS(CPLL_HZ, 2, 3, 1); + + static int rkclk_set_pll(struct rk322x_cru *cru, enum rk_clk_id clk_id, + const struct pll_div *div) +@@ -87,11 +88,13 @@ static void rkclk_init(struct rk322x_cru *cru) + rk_clrsetreg(&cru->cru_mode_con, + GPLL_MODE_MASK | APLL_MODE_MASK, + GPLL_MODE_SLOW << GPLL_MODE_SHIFT | +- APLL_MODE_SLOW << APLL_MODE_SHIFT); ++ APLL_MODE_SLOW << APLL_MODE_SHIFT | ++ CPLL_MODE_SLOW << CPLL_MODE_SHIFT); + + /* init pll */ + rkclk_set_pll(cru, CLK_ARM, &apll_init_cfg); + rkclk_set_pll(cru, CLK_GENERAL, &gpll_init_cfg); ++ rkclk_set_pll(cru, CLK_CODEC, &cpll_init_cfg); + + /* + * select apll as cpu/core clock pll source and +@@ -164,7 +167,8 @@ static void rkclk_init(struct rk322x_cru *cru) + rk_clrsetreg(&cru->cru_mode_con, + GPLL_MODE_MASK | APLL_MODE_MASK, + GPLL_MODE_NORM << GPLL_MODE_SHIFT | +- APLL_MODE_NORM << APLL_MODE_SHIFT); ++ APLL_MODE_NORM << APLL_MODE_SHIFT | ++ CPLL_MODE_NORM << CPLL_MODE_SHIFT); + } + + /* Get pll rate by id */ +@@ -254,11 +258,10 @@ static ulong rk322x_mac_set_clk(struct rk322x_cru *cru, uint freq) + ulong pll_rate; + u8 div; + +- if ((con >> MAC_PLL_SEL_SHIFT) & MAC_PLL_SEL_MASK) ++ if (con & MAC_PLL_SEL_MASK) + pll_rate = GPLL_HZ; + else +- /* CPLL is not set */ +- return -EPERM; ++ pll_rate = CPLL_HZ; + + div = DIV_ROUND_UP(pll_rate, freq) - 1; + if (div <= 0x1f) +@@ -387,6 +390,7 @@ static ulong rk322x_clk_set_rate(struct clk *clk, ulong rate) + case CLK_DDR: + new_rate = rk322x_ddr_set_clk(priv->cru, rate); + break; ++ case SCLK_MAC_SRC: + case SCLK_MAC: + new_rate = rk322x_mac_set_clk(priv->cru, rate); + break; +diff --git a/drivers/clk/rockchip/clk_rk3328.c b/drivers/clk/rockchip/clk_rk3328.c +index 8e867c58df..ba2b34c626 100644 +--- a/drivers/clk/rockchip/clk_rk3328.c ++++ b/drivers/clk/rockchip/clk_rk3328.c +@@ -93,6 +93,14 @@ enum { + PCLK_DBG_DIV_SHIFT = 0, + PCLK_DBG_DIV_MASK = 0xF << PCLK_DBG_DIV_SHIFT, + ++ /* CLKSEL_CON26 */ ++ GMAC2PHY_PLL_SEL_SHIFT = 7, ++ GMAC2PHY_PLL_SEL_MASK = 1 << GMAC2PHY_PLL_SEL_SHIFT, ++ GMAC2PHY_PLL_SEL_CPLL = 0, ++ GMAC2PHY_PLL_SEL_GPLL = 1, ++ GMAC2PHY_CLK_DIV_MASK = 0x1f, ++ GMAC2PHY_CLK_DIV_SHIFT = 0, ++ + /* CLKSEL_CON27 */ + GMAC2IO_PLL_SEL_SHIFT = 7, + GMAC2IO_PLL_SEL_MASK = 1 << GMAC2IO_PLL_SEL_SHIFT, +@@ -440,6 +448,39 @@ static ulong rk3328_gmac2io_set_clk(struct rk3328_cru *cru, ulong rate) + return ret; + } + ++static ulong rk3328_gmac2phy_src_set_clk(struct rk3328_cru *cru, ulong rate) ++{ ++ u32 con = readl(&cru->clksel_con[26]); ++ ulong pll_rate; ++ u8 div; ++ ++ if ((con >> GMAC2PHY_PLL_SEL_SHIFT) & GMAC2PHY_PLL_SEL_GPLL) ++ pll_rate = GPLL_HZ; ++ else ++ pll_rate = CPLL_HZ; ++ ++ div = DIV_ROUND_UP(pll_rate, rate) - 1; ++ if (div <= 0x1f) ++ rk_clrsetreg(&cru->clksel_con[26], GMAC2PHY_CLK_DIV_MASK, ++ div << GMAC2PHY_CLK_DIV_SHIFT); ++ else ++ debug("Unsupported div for gmac:%d\n", div); ++ ++ return DIV_TO_RATE(pll_rate, div); ++} ++ ++static ulong rk3328_gmac2phy_set_clk(struct rk3328_cru *cru, ulong rate) ++{ ++ struct rk3328_grf_regs *grf; ++ ++ grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); ++ if (readl(&grf->mac_con[2]) & BIT(10)) ++ /* An external clock will always generate the right rate... */ ++ return rate; ++ else ++ return rk3328_gmac2phy_src_set_clk(cru, rate); ++} ++ + static ulong rk3328_mmc_get_clk(struct rk3328_cru *cru, uint clk_id) + { + u32 div, con, con_id; +@@ -608,6 +649,12 @@ static ulong rk3328_clk_set_rate(struct clk *clk, ulong rate) + case SCLK_MAC2IO: + ret = rk3328_gmac2io_set_clk(priv->cru, rate); + break; ++ case SCLK_MAC2PHY: ++ ret = rk3328_gmac2phy_set_clk(priv->cru, rate); ++ break; ++ case SCLK_MAC2PHY_SRC: ++ ret = rk3328_gmac2phy_src_set_clk(priv->cru, rate); ++ break; + case SCLK_PWM: + ret = rk3328_pwm_set_clk(priv->cru, rate); + break; +@@ -728,6 +775,43 @@ static int rk3328_gmac2io_ext_set_parent(struct clk *clk, struct clk *parent) + return -EINVAL; + } + ++static int rk3328_gmac2phy_set_parent(struct clk *clk, struct clk *parent) ++{ ++ struct rk3328_grf_regs *grf; ++ const char *clock_output_name; ++ int ret; ++ ++ grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); ++ ++ /* ++ * If the requested parent is in the same clock-controller and the id ++ * is SCLK_MAC2PHY_SRC ("clk_mac2phy_src"), switch to the internal clock. ++ */ ++ if ((parent->dev == clk->dev) && (parent->id == SCLK_MAC2PHY_SRC)) { ++ debug("%s: switching MAC CLK to SCLK_MAC2IO_PHY\n", __func__); ++ rk_clrreg(&grf->mac_con[2], BIT(10)); ++ return 0; ++ } ++ ++ /* ++ * Otherwise, we need to check the clock-output-names of the ++ * requested parent to see if the requested id is "phy_50m_out". ++ */ ++ ret = dev_read_string_index(parent->dev, "clock-output-names", ++ parent->id, &clock_output_name); ++ if (ret < 0) ++ return -ENODATA; ++ ++ /* If this is "phy_50m_out", switch to the external clock input */ ++ if (!strcmp(clock_output_name, "phy_50m_out")) { ++ debug("%s: switching MAC CLK to PHY_50M_OUT\n", __func__); ++ rk_setreg(&grf->mac_con[2], BIT(10)); ++ return 0; ++ } ++ ++ return -EINVAL; ++} ++ + static int rk3328_clk_set_parent(struct clk *clk, struct clk *parent) + { + switch (clk->id) { +@@ -735,6 +819,8 @@ static int rk3328_clk_set_parent(struct clk *clk, struct clk *parent) + return rk3328_gmac2io_set_parent(clk, parent); + case SCLK_MAC2IO_EXT: + return rk3328_gmac2io_ext_set_parent(clk, parent); ++ case SCLK_MAC2PHY: ++ return rk3328_gmac2phy_set_parent(clk, parent); + case DCLK_LCDC: + case SCLK_PDM: + case SCLK_RTC32K: +diff --git a/drivers/net/gmac_rockchip.c b/drivers/net/gmac_rockchip.c +index e152faf083..d3f6973043 100644 +--- a/drivers/net/gmac_rockchip.c ++++ b/drivers/net/gmac_rockchip.c +@@ -9,6 +9,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -23,6 +24,7 @@ + #include + #include + #include ++#include + #include + #include "designware.h" + +@@ -39,21 +41,29 @@ DECLARE_GLOBAL_DATA_PTR; + struct gmac_rockchip_platdata { + struct dw_eth_pdata dw_eth_pdata; + bool clock_input; ++ bool integrated_phy; ++ struct reset_ctl phy_reset; + int tx_delay; + int rx_delay; + }; + + struct rk_gmac_ops { +- int (*fix_mac_speed)(struct dw_eth_dev *priv); ++ int (*fix_rmii_speed)(struct gmac_rockchip_platdata *pdata, ++ struct dw_eth_dev *priv); ++ int (*fix_rgmii_speed)(struct gmac_rockchip_platdata *pdata, ++ struct dw_eth_dev *priv); + void (*set_to_rmii)(struct gmac_rockchip_platdata *pdata); + void (*set_to_rgmii)(struct gmac_rockchip_platdata *pdata); ++ void (*integrated_phy_powerup)(struct gmac_rockchip_platdata *pdata); + }; + + + static int gmac_rockchip_ofdata_to_platdata(struct udevice *dev) + { + struct gmac_rockchip_platdata *pdata = dev_get_platdata(dev); ++ struct ofnode_phandle_args args; + const char *string; ++ int ret; + + string = dev_read_string(dev, "clock_in_out"); + if (!strcmp(string, "input")) +@@ -61,6 +71,25 @@ static int gmac_rockchip_ofdata_to_platdata(struct udevice *dev) + else + pdata->clock_input = false; + ++ /* If phy-handle property is passed from DT, use it as the PHY */ ++ ret = dev_read_phandle_with_args(dev, "phy-handle", NULL, 0, 0, &args); ++ if (ret) { ++ debug("Cannot get phy phandle: ret=%d\n", ret); ++ pdata->integrated_phy = dev_read_bool(dev, "phy-is-integrated"); ++ } else { ++ debug("Found phy-handle subnode\n"); ++ pdata->integrated_phy = ofnode_read_bool(args.node, ++ "phy-is-integrated"); ++ } ++ ++ if (pdata->integrated_phy) { ++ ret = reset_get_by_name(dev, "mac-phy", &pdata->phy_reset); ++ if (ret) { ++ debug("No PHY reset control found: ret=%d\n", ret); ++ return ret; ++ } ++ } ++ + /* Check the new naming-style first... */ + pdata->tx_delay = dev_read_u32_default(dev, "tx_delay", -ENOENT); + pdata->rx_delay = dev_read_u32_default(dev, "rx_delay", -ENOENT); +@@ -74,7 +103,8 @@ static int gmac_rockchip_ofdata_to_platdata(struct udevice *dev) + return designware_eth_ofdata_to_platdata(dev); + } + +-static int px30_gmac_fix_mac_speed(struct dw_eth_dev *priv) ++static int px30_gmac_fix_rmii_speed(struct gmac_rockchip_platdata *pdata, ++ struct dw_eth_dev *priv) + { + struct px30_grf *grf; + struct clk clk_speed; +@@ -115,7 +145,43 @@ static int px30_gmac_fix_mac_speed(struct dw_eth_dev *priv) + return 0; + } + +-static int rk3228_gmac_fix_mac_speed(struct dw_eth_dev *priv) ++static int rk3228_gmac_fix_rmii_speed(struct gmac_rockchip_platdata *pdata, ++ struct dw_eth_dev *priv) ++{ ++ struct rk322x_grf *grf; ++ int clk; ++ enum { ++ RK3228_GMAC_RMII_CLK_MASK = BIT(7), ++ RK3228_GMAC_RMII_CLK_2_5M = 0, ++ RK3228_GMAC_RMII_CLK_25M = BIT(7), ++ ++ RK3228_GMAC_RMII_SPEED_MASK = BIT(2), ++ RK3228_GMAC_RMII_SPEED_10 = 0, ++ RK3228_GMAC_RMII_SPEED_100 = BIT(2), ++ }; ++ ++ switch (priv->phydev->speed) { ++ case 10: ++ clk = RK3228_GMAC_RMII_CLK_2_5M | RK3228_GMAC_RMII_SPEED_10; ++ break; ++ case 100: ++ clk = RK3228_GMAC_RMII_CLK_25M | RK3228_GMAC_RMII_SPEED_100; ++ break; ++ default: ++ debug("Unknown phy speed: %d\n", priv->phydev->speed); ++ return -EINVAL; ++ } ++ ++ grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); ++ rk_clrsetreg(&grf->mac_con[1], ++ RK3228_GMAC_RMII_CLK_MASK | RK3228_GMAC_RMII_SPEED_MASK, ++ clk); ++ ++ return 0; ++} ++ ++static int rk3228_gmac_fix_rgmii_speed(struct gmac_rockchip_platdata *pdata, ++ struct dw_eth_dev *priv) + { + struct rk322x_grf *grf; + int clk; +@@ -148,7 +214,8 @@ static int rk3228_gmac_fix_mac_speed(struct dw_eth_dev *priv) + return 0; + } + +-static int rk3288_gmac_fix_mac_speed(struct dw_eth_dev *priv) ++static int rk3288_gmac_fix_rgmii_speed(struct gmac_rockchip_platdata *pdata, ++ struct dw_eth_dev *priv) + { + struct rk3288_grf *grf; + int clk; +@@ -174,7 +241,8 @@ static int rk3288_gmac_fix_mac_speed(struct dw_eth_dev *priv) + return 0; + } + +-static int rk3308_gmac_fix_mac_speed(struct dw_eth_dev *priv) ++static int rk3308_gmac_fix_rmii_speed(struct gmac_rockchip_platdata *pdata, ++ struct dw_eth_dev *priv) + { + struct rk3308_grf *grf; + struct clk clk_speed; +@@ -215,7 +283,43 @@ static int rk3308_gmac_fix_mac_speed(struct dw_eth_dev *priv) + return 0; + } + +-static int rk3328_gmac_fix_mac_speed(struct dw_eth_dev *priv) ++static int rk3328_gmac_fix_rmii_speed(struct gmac_rockchip_platdata *pdata, ++ struct dw_eth_dev *priv) ++{ ++ struct rk3328_grf_regs *grf; ++ int clk; ++ enum { ++ RK3328_GMAC_RMII_CLK_MASK = BIT(7), ++ RK3328_GMAC_RMII_CLK_2_5M = 0, ++ RK3328_GMAC_RMII_CLK_25M = BIT(7), ++ ++ RK3328_GMAC_RMII_SPEED_MASK = BIT(2), ++ RK3328_GMAC_RMII_SPEED_10 = 0, ++ RK3328_GMAC_RMII_SPEED_100 = BIT(2), ++ }; ++ ++ switch (priv->phydev->speed) { ++ case 10: ++ clk = RK3328_GMAC_RMII_CLK_2_5M | RK3328_GMAC_RMII_SPEED_10; ++ break; ++ case 100: ++ clk = RK3328_GMAC_RMII_CLK_25M | RK3328_GMAC_RMII_SPEED_100; ++ break; ++ default: ++ debug("Unknown phy speed: %d\n", priv->phydev->speed); ++ return -EINVAL; ++ } ++ ++ grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); ++ rk_clrsetreg(pdata->integrated_phy ? &grf->mac_con[2] : &grf->mac_con[1], ++ RK3328_GMAC_RMII_CLK_MASK | RK3328_GMAC_RMII_SPEED_MASK, ++ clk); ++ ++ return 0; ++} ++ ++static int rk3328_gmac_fix_rgmii_speed(struct gmac_rockchip_platdata *pdata, ++ struct dw_eth_dev *priv) + { + struct rk3328_grf_regs *grf; + int clk; +@@ -248,7 +352,8 @@ static int rk3328_gmac_fix_mac_speed(struct dw_eth_dev *priv) + return 0; + } + +-static int rk3368_gmac_fix_mac_speed(struct dw_eth_dev *priv) ++static int rk3368_gmac_fix_rgmii_speed(struct gmac_rockchip_platdata *pdata, ++ struct dw_eth_dev *priv) + { + struct rk3368_grf *grf; + int clk; +@@ -280,7 +385,8 @@ static int rk3368_gmac_fix_mac_speed(struct dw_eth_dev *priv) + return 0; + } + +-static int rk3399_gmac_fix_mac_speed(struct dw_eth_dev *priv) ++static int rk3399_gmac_fix_rgmii_speed(struct gmac_rockchip_platdata *pdata, ++ struct dw_eth_dev *priv) + { + struct rk3399_grf_regs *grf; + int clk; +@@ -306,7 +412,8 @@ static int rk3399_gmac_fix_mac_speed(struct dw_eth_dev *priv) + return 0; + } + +-static int rv1108_set_rmii_speed(struct dw_eth_dev *priv) ++static int rv1108_gmac_fix_rmii_speed(struct gmac_rockchip_platdata *pdata, ++ struct dw_eth_dev *priv) + { + struct rv1108_grf *grf; + int clk, speed; +@@ -357,6 +464,28 @@ static void px30_gmac_set_to_rmii(struct gmac_rockchip_platdata *pdata) + PX30_GMAC_PHY_INTF_SEL_RMII); + } + ++static void rk3228_gmac_set_to_rmii(struct gmac_rockchip_platdata *pdata) ++{ ++ struct rk322x_grf *grf; ++ enum { ++ RK3228_GRF_CON_RMII_MODE_MASK = BIT(11), ++ RK3228_GRF_CON_RMII_MODE_SEL = BIT(11), ++ RK3228_RMII_MODE_MASK = BIT(10), ++ RK3228_RMII_MODE_SEL = BIT(10), ++ RK3228_GMAC_PHY_INTF_SEL_MASK = GENMASK(6, 4), ++ RK3228_GMAC_PHY_INTF_SEL_RMII = BIT(6), ++ }; ++ ++ grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); ++ rk_clrsetreg(&grf->mac_con[1], ++ RK3228_GRF_CON_RMII_MODE_MASK | ++ RK3228_RMII_MODE_MASK | ++ RK3228_GMAC_PHY_INTF_SEL_MASK, ++ RK3228_GRF_CON_RMII_MODE_SEL | ++ RK3228_RMII_MODE_SEL | ++ RK3228_GMAC_PHY_INTF_SEL_RMII); ++} ++ + static void rk3228_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata) + { + struct rk322x_grf *grf; +@@ -435,6 +564,25 @@ static void rk3308_gmac_set_to_rmii(struct gmac_rockchip_platdata *pdata) + RK3308_GMAC_PHY_INTF_SEL_RMII); + } + ++static void rk3328_gmac_set_to_rmii(struct gmac_rockchip_platdata *pdata) ++{ ++ struct rk3328_grf_regs *grf; ++ enum { ++ RK3328_RMII_MODE_MASK = BIT(9), ++ RK3328_RMII_MODE = BIT(9), ++ ++ RK3328_GMAC_PHY_INTF_SEL_MASK = GENMASK(6, 4), ++ RK3328_GMAC_PHY_INTF_SEL_RMII = BIT(6), ++ }; ++ ++ grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); ++ rk_clrsetreg(pdata->integrated_phy ? &grf->mac_con[2] : &grf->mac_con[1], ++ RK3328_RMII_MODE_MASK | ++ RK3328_GMAC_PHY_INTF_SEL_MASK, ++ RK3328_GMAC_PHY_INTF_SEL_RMII | ++ RK3328_RMII_MODE); ++} ++ + static void rk3328_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata) + { + struct rk3328_grf_regs *grf; +@@ -550,6 +698,126 @@ static void rv1108_gmac_set_to_rmii(struct gmac_rockchip_platdata *pdata) + RV1108_GMAC_PHY_INTF_SEL_RMII); + } + ++static void rk3228_gmac_integrated_phy_powerup(struct gmac_rockchip_platdata *pdata) ++{ ++ struct rk322x_grf *grf; ++ enum { ++ RK3228_GRF_CON_MUX_GMAC_INTEGRATED_PHY_MASK = BIT(15), ++ RK3228_GRF_CON_MUX_GMAC_INTEGRATED_PHY = BIT(15), ++ }; ++ enum { ++ RK3228_MACPHY_CFG_CLK_50M_MASK = BIT(14), ++ RK3228_MACPHY_CFG_CLK_50M = BIT(14), ++ ++ RK3228_MACPHY_RMII_MODE_MASK = GENMASK(7, 6), ++ RK3228_MACPHY_RMII_MODE = BIT(6), ++ ++ RK3228_MACPHY_ENABLE_MASK = BIT(0), ++ RK3228_MACPHY_DISENABLE = 0, ++ RK3228_MACPHY_ENABLE = BIT(0), ++ }; ++ enum { ++ RK3228_RK_GRF_CON2_MACPHY_ID_MASK = GENMASK(6, 0), ++ RK3228_RK_GRF_CON2_MACPHY_ID = 0x1234, ++ }; ++ enum { ++ RK3228_RK_GRF_CON3_MACPHY_ID_MASK = GENMASK(5, 0), ++ RK3228_RK_GRF_CON3_MACPHY_ID = 0x35, ++ }; ++ ++ grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); ++ rk_clrsetreg(&grf->con_iomux, ++ RK3228_GRF_CON_MUX_GMAC_INTEGRATED_PHY_MASK, ++ RK3228_GRF_CON_MUX_GMAC_INTEGRATED_PHY); ++ ++ rk_clrsetreg(&grf->macphy_con[2], ++ RK3228_RK_GRF_CON2_MACPHY_ID_MASK, ++ RK3228_RK_GRF_CON2_MACPHY_ID); ++ ++ rk_clrsetreg(&grf->macphy_con[3], ++ RK3228_RK_GRF_CON3_MACPHY_ID_MASK, ++ RK3228_RK_GRF_CON3_MACPHY_ID); ++ ++ /* disabled before trying to reset it */ ++ rk_clrsetreg(&grf->macphy_con[0], ++ RK3228_MACPHY_CFG_CLK_50M_MASK | ++ RK3228_MACPHY_RMII_MODE_MASK | ++ RK3228_MACPHY_ENABLE_MASK, ++ RK3228_MACPHY_CFG_CLK_50M | ++ RK3228_MACPHY_RMII_MODE | ++ RK3228_MACPHY_DISENABLE); ++ ++ reset_assert(&pdata->phy_reset); ++ udelay(10); ++ reset_deassert(&pdata->phy_reset); ++ udelay(10); ++ ++ rk_clrsetreg(&grf->macphy_con[0], ++ RK3228_MACPHY_ENABLE_MASK, ++ RK3228_MACPHY_ENABLE); ++ udelay(30 * 1000); ++} ++ ++static void rk3328_gmac_integrated_phy_powerup(struct gmac_rockchip_platdata *pdata) ++{ ++ struct rk3328_grf_regs *grf; ++ enum { ++ RK3328_GRF_CON_RMII_MODE_MASK = BIT(9), ++ RK3328_GRF_CON_RMII_MODE = BIT(9), ++ }; ++ enum { ++ RK3328_MACPHY_CFG_CLK_50M_MASK = BIT(14), ++ RK3328_MACPHY_CFG_CLK_50M = BIT(14), ++ ++ RK3328_MACPHY_RMII_MODE_MASK = GENMASK(7, 6), ++ RK3328_MACPHY_RMII_MODE = BIT(6), ++ ++ RK3328_MACPHY_ENABLE_MASK = BIT(0), ++ RK3328_MACPHY_DISENABLE = 0, ++ RK3328_MACPHY_ENABLE = BIT(0), ++ }; ++ enum { ++ RK3328_RK_GRF_CON2_MACPHY_ID_MASK = GENMASK(6, 0), ++ RK3328_RK_GRF_CON2_MACPHY_ID = 0x1234, ++ }; ++ enum { ++ RK3328_RK_GRF_CON3_MACPHY_ID_MASK = GENMASK(5, 0), ++ RK3328_RK_GRF_CON3_MACPHY_ID = 0x35, ++ }; ++ ++ grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); ++ rk_clrsetreg(&grf->macphy_con[1], ++ RK3328_GRF_CON_RMII_MODE_MASK, ++ RK3328_GRF_CON_RMII_MODE); ++ ++ rk_clrsetreg(&grf->macphy_con[2], ++ RK3328_RK_GRF_CON2_MACPHY_ID_MASK, ++ RK3328_RK_GRF_CON2_MACPHY_ID); ++ ++ rk_clrsetreg(&grf->macphy_con[3], ++ RK3328_RK_GRF_CON3_MACPHY_ID_MASK, ++ RK3328_RK_GRF_CON3_MACPHY_ID); ++ ++ /* disabled before trying to reset it */ ++ rk_clrsetreg(&grf->macphy_con[0], ++ RK3328_MACPHY_CFG_CLK_50M_MASK | ++ RK3328_MACPHY_RMII_MODE_MASK | ++ RK3328_MACPHY_ENABLE_MASK, ++ RK3328_MACPHY_CFG_CLK_50M | ++ RK3328_MACPHY_RMII_MODE | ++ RK3328_MACPHY_DISENABLE); ++ ++ reset_assert(&pdata->phy_reset); ++ udelay(10); ++ reset_deassert(&pdata->phy_reset); ++ udelay(10); ++ ++ rk_clrsetreg(&grf->macphy_con[0], ++ RK3328_MACPHY_ENABLE_MASK, ++ RK3328_MACPHY_ENABLE); ++ udelay(30 * 1000); ++} ++ + static int gmac_rockchip_probe(struct udevice *dev) + { + struct gmac_rockchip_platdata *pdata = dev_get_platdata(dev); +@@ -569,6 +837,9 @@ static int gmac_rockchip_probe(struct udevice *dev) + if (ret) + return ret; + ++ if (pdata->integrated_phy && ops->integrated_phy_powerup) ++ ops->integrated_phy_powerup(pdata); ++ + switch (eth_pdata->phy_interface) { + case PHY_INTERFACE_MODE_RGMII: + /* Set to RGMII mode */ +@@ -652,7 +923,7 @@ static int gmac_rockchip_probe(struct udevice *dev) + break; + + default: +- debug("NO interface defined!\n"); ++ debug("%s: no interface defined!\n", __func__); + return -ENXIO; + } + +@@ -661,18 +932,33 @@ static int gmac_rockchip_probe(struct udevice *dev) + + static int gmac_rockchip_eth_start(struct udevice *dev) + { +- struct eth_pdata *pdata = dev_get_platdata(dev); ++ struct eth_pdata *eth_pdata = dev_get_platdata(dev); + struct dw_eth_dev *priv = dev_get_priv(dev); + struct rk_gmac_ops *ops = + (struct rk_gmac_ops *)dev_get_driver_data(dev); ++ struct gmac_rockchip_platdata *pdata = dev_get_platdata(dev); + int ret; + +- ret = designware_eth_init(priv, pdata->enetaddr); +- if (ret) +- return ret; +- ret = ops->fix_mac_speed(priv); ++ ret = designware_eth_init(priv, eth_pdata->enetaddr); + if (ret) + return ret; ++ ++ switch (eth_pdata->phy_interface) { ++ case PHY_INTERFACE_MODE_RGMII: ++ ret = ops->fix_rgmii_speed(pdata, priv); ++ if (ret) ++ return ret; ++ break; ++ case PHY_INTERFACE_MODE_RMII: ++ ret = ops->fix_rmii_speed(pdata, priv); ++ if (ret) ++ return ret; ++ break; ++ default: ++ debug("%s: no interface defined!\n", __func__); ++ return -ENXIO; ++ } ++ + ret = designware_eth_enable(priv); + if (ret) + return ret; +@@ -690,42 +976,48 @@ const struct eth_ops gmac_rockchip_eth_ops = { + }; + + const struct rk_gmac_ops px30_gmac_ops = { +- .fix_mac_speed = px30_gmac_fix_mac_speed, ++ .fix_rmii_speed = px30_gmac_fix_rmii_speed, + .set_to_rmii = px30_gmac_set_to_rmii, + }; + + const struct rk_gmac_ops rk3228_gmac_ops = { +- .fix_mac_speed = rk3228_gmac_fix_mac_speed, ++ .fix_rmii_speed = rk3228_gmac_fix_rmii_speed, ++ .fix_rgmii_speed = rk3228_gmac_fix_rgmii_speed, ++ .set_to_rmii = rk3228_gmac_set_to_rmii, + .set_to_rgmii = rk3228_gmac_set_to_rgmii, ++ .integrated_phy_powerup = rk3228_gmac_integrated_phy_powerup, + }; + + const struct rk_gmac_ops rk3288_gmac_ops = { +- .fix_mac_speed = rk3288_gmac_fix_mac_speed, ++ .fix_rgmii_speed = rk3288_gmac_fix_rgmii_speed, + .set_to_rgmii = rk3288_gmac_set_to_rgmii, + }; + + const struct rk_gmac_ops rk3308_gmac_ops = { +- .fix_mac_speed = rk3308_gmac_fix_mac_speed, ++ .fix_rmii_speed = rk3308_gmac_fix_rmii_speed, + .set_to_rmii = rk3308_gmac_set_to_rmii, + }; + + const struct rk_gmac_ops rk3328_gmac_ops = { +- .fix_mac_speed = rk3328_gmac_fix_mac_speed, ++ .fix_rmii_speed = rk3328_gmac_fix_rmii_speed, ++ .fix_rgmii_speed = rk3328_gmac_fix_rgmii_speed, ++ .set_to_rmii = rk3328_gmac_set_to_rmii, + .set_to_rgmii = rk3328_gmac_set_to_rgmii, ++ .integrated_phy_powerup = rk3328_gmac_integrated_phy_powerup, + }; + + const struct rk_gmac_ops rk3368_gmac_ops = { +- .fix_mac_speed = rk3368_gmac_fix_mac_speed, ++ .fix_rgmii_speed = rk3368_gmac_fix_rgmii_speed, + .set_to_rgmii = rk3368_gmac_set_to_rgmii, + }; + + const struct rk_gmac_ops rk3399_gmac_ops = { +- .fix_mac_speed = rk3399_gmac_fix_mac_speed, ++ .fix_rgmii_speed = rk3399_gmac_fix_rgmii_speed, + .set_to_rgmii = rk3399_gmac_set_to_rgmii, + }; + + const struct rk_gmac_ops rv1108_gmac_ops = { +- .fix_mac_speed = rv1108_set_rmii_speed, ++ .fix_rmii_speed = rv1108_gmac_fix_rmii_speed, + .set_to_rmii = rv1108_gmac_set_to_rmii, + }; + diff --git a/patch/u-boot/u-boot-rk322x/u-boot-1002-rockchip-sdram-rk322x-fix-dram-bank-size-calculation.patch b/patch/u-boot/u-boot-rk322x/u-boot-1002-rockchip-sdram-rk322x-fix-dram-bank-size-calculation.patch new file mode 100644 index 0000000000..e7471e61c4 --- /dev/null +++ b/patch/u-boot/u-boot-rk322x/u-boot-1002-rockchip-sdram-rk322x-fix-dram-bank-size-calculation.patch @@ -0,0 +1,42 @@ +From a05e0306d9793da2bb76a6c712ae20ecc3af6d98 Mon Sep 17 00:00:00 2001 +From: Alex Bee +Date: Thu, 27 Feb 2020 13:50:52 +0100 +Subject: [PATCH] rockchip: sdram: fix dram_init_banksize with CONFIG_SPL_OPTEE + +Currently 2.5 GB is calculated as DRAM size for a 1 GB RK322x board when CONFIG_SPL_OPTEE is set. + +gd->bd->bi_dram[0].start (which is basically CONFIG_SYS_SDRAM_BASE) must not be taken into consideration +for calculation of second bank size, since this offset is already included in calculation of "top". +After applying this patch 992 MB (1024 MB -32 MB reserved for trustos) is calculated. + +Signed-off-by: Alex Bee +--- + arch/arm/mach-rockchip/sdram.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/arch/arm/mach-rockchip/sdram.c b/arch/arm/mach-rockchip/sdram.c +index 530644c043..05bc0c14e5 100644 +--- a/arch/arm/mach-rockchip/sdram.c ++++ b/arch/arm/mach-rockchip/sdram.c +@@ -55,16 +55,14 @@ int dram_init_banksize(void) + - CONFIG_SYS_SDRAM_BASE; + gd->bd->bi_dram[1].start = tos_parameter->tee_mem.phy_addr + + tos_parameter->tee_mem.size; +- gd->bd->bi_dram[1].size = gd->bd->bi_dram[0].start +- + top - gd->bd->bi_dram[1].start; ++ gd->bd->bi_dram[1].size = top - gd->bd->bi_dram[1].start; + } else { + gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE; + gd->bd->bi_dram[0].size = 0x8400000; + /* Reserve 32M for OPTEE with TA */ + gd->bd->bi_dram[1].start = CONFIG_SYS_SDRAM_BASE + + gd->bd->bi_dram[0].size + 0x2000000; +- gd->bd->bi_dram[1].size = gd->bd->bi_dram[0].start +- + top - gd->bd->bi_dram[1].start; ++ gd->bd->bi_dram[1].size = top - gd->bd->bi_dram[1].start; + } + #else + gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE; +-- +2.17.1 +