diff --git a/Documentation/kernel.md b/Documentation/kernel.md index 1ccfe2d69..3b31d1815 100644 --- a/Documentation/kernel.md +++ b/Documentation/kernel.md @@ -6,4 +6,4 @@ | Open Virtual Applicance | 4.14.82 | | Raspberry Pi | 4.14.81 | | Tinker Board | 4.14.82 | -| Odroid-C2 | 4.14.67 | +| Odroid-C2 | 4.18.20 | diff --git a/buildroot-external/board/hardkernel/odroid-c2/kernel.config b/buildroot-external/board/hardkernel/odroid-c2/kernel.config index b3e2996df..08fdc1b2f 100644 --- a/buildroot-external/board/hardkernel/odroid-c2/kernel.config +++ b/buildroot-external/board/hardkernel/odroid-c2/kernel.config @@ -1,110 +1,27 @@ -# -# Automatically generated file; DO NOT EDIT. -# Linux/arm64 4.14.14 Kernel Configuration -# -CONFIG_ARM64=y -CONFIG_64BIT=y -CONFIG_ARCH_PHYS_ADDR_T_64BIT=y -CONFIG_MMU=y -CONFIG_ARM64_PAGE_SHIFT=12 -CONFIG_ARM64_CONT_SHIFT=4 -CONFIG_ARCH_MMAP_RND_BITS_MIN=18 -CONFIG_ARCH_MMAP_RND_BITS_MAX=33 -CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=11 -CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=16 -CONFIG_STACKTRACE_SUPPORT=y -CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000 -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_TRACE_IRQFLAGS_SUPPORT=y -CONFIG_RWSEM_XCHGADD_ALGORITHM=y -CONFIG_GENERIC_BUG=y -CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y -CONFIG_GENERIC_HWEIGHT=y -CONFIG_GENERIC_CSUM=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_ZONE_DMA=y -CONFIG_HAVE_GENERIC_GUP=y -CONFIG_ARCH_DMA_ADDR_T_64BIT=y -CONFIG_NEED_DMA_MAP_STATE=y -CONFIG_NEED_SG_DMA_LENGTH=y -CONFIG_SMP=y -CONFIG_SWIOTLB=y -CONFIG_IOMMU_HELPER=y -CONFIG_KERNEL_MODE_NEON=y -CONFIG_FIX_EARLYCON_MEM=y -CONFIG_PGTABLE_LEVELS=4 -CONFIG_ARCH_SUPPORTS_UPROBES=y -CONFIG_ARCH_PROC_KCORE_TEXT=y -CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" -CONFIG_IRQ_WORK=y -CONFIG_BUILDTIME_EXTABLE_SORT=y -CONFIG_THREAD_INFO_IN_TASK=y # # General setup # -CONFIG_INIT_ENV_ARG_LIMIT=32 -CONFIG_CROSS_COMPILE="" -# CONFIG_COMPILE_TEST is not set -CONFIG_LOCALVERSION="" -CONFIG_LOCALVERSION_AUTO=y +# CONFIG_LOCALVERSION_AUTO is not set CONFIG_DEFAULT_HOSTNAME="(none)" -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 is not set CONFIG_AUDIT=y -CONFIG_HAVE_ARCH_AUDITSYSCALL=y -CONFIG_AUDITSYSCALL=y -CONFIG_AUDIT_WATCH=y -CONFIG_AUDIT_TREE=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_GENERIC_MSI_IRQ=y -CONFIG_GENERIC_MSI_IRQ_DOMAIN=y -CONFIG_HANDLE_DOMAIN_IRQ=y -# CONFIG_IRQ_DOMAIN_DEBUG is not set -CONFIG_IRQ_FORCED_THREADING=y -CONFIG_SPARSE_IRQ=y -# CONFIG_GENERIC_IRQ_DEBUGFS is not set -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 is not set 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_IRQ_TIME_ACCOUNTING=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_BSD_PROCESS_ACCT_V3=y CONFIG_TASKSTATS=y @@ -115,45 +32,19 @@ CONFIG_TASK_IO_ACCOUNTING=y # # RCU Subsystem # -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 -CONFIG_BUILD_BIN2C=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y -CONFIG_LOG_BUF_SHIFT=17 -CONFIG_LOG_CPU_MAX_BUF_SHIFT=12 -CONFIG_PRINTK_SAFE_LOG_BUF_SHIFT=13 -CONFIG_GENERIC_SCHED_CLOCK=y -CONFIG_ARCH_SUPPORTS_NUMA_BALANCING=y -CONFIG_CGROUPS=y -CONFIG_PAGE_COUNTER=y +CONFIG_NUMA_BALANCING=y CONFIG_MEMCG=y CONFIG_MEMCG_SWAP=y -CONFIG_MEMCG_SWAP_ENABLED=y CONFIG_BLK_CGROUP=y -# CONFIG_DEBUG_BLK_CGROUP is not set -CONFIG_CGROUP_WRITEBACK=y -CONFIG_CGROUP_SCHED=y -CONFIG_FAIR_GROUP_SCHED=y -# CONFIG_CFS_BANDWIDTH is not set -# CONFIG_RT_GROUP_SCHED is not set CONFIG_CGROUP_PIDS=y -# CONFIG_CGROUP_RDMA is not set -# CONFIG_CGROUP_FREEZER is not set CONFIG_CGROUP_HUGETLB=y CONFIG_CPUSETS=y -CONFIG_PROC_PID_CPUSET=y CONFIG_CGROUP_DEVICE=y CONFIG_CGROUP_CPUACCT=y CONFIG_CGROUP_PERF=y -# CONFIG_CGROUP_DEBUG is not set -# CONFIG_SOCK_CGROUP_DATA is not set -# CONFIG_CHECKPOINT_RESTORE is not set +CONFIG_SOCK_CGROUP_DATA=y CONFIG_NAMESPACES=y CONFIG_UTS_NS=y CONFIG_IPC_NS=y @@ -161,202 +52,55 @@ CONFIG_USER_NS=y CONFIG_PID_NS=y CONFIG_NET_NS=y CONFIG_SCHED_AUTOGROUP=y -# CONFIG_SYSFS_DEPRECATED is not set -# CONFIG_RELAY is not set 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_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_SYSCTL_EXCEPTION_TRACE=y -CONFIG_BPF=y -# CONFIG_EXPERT is not set -CONFIG_UID16=y -CONFIG_MULTIUSER=y -# CONFIG_SGETMASK_SYSCALL is not set -CONFIG_SYSFS_SYSCALL=y -# CONFIG_SYSCTL_SYSCALL is not set -CONFIG_POSIX_TIMERS=y -CONFIG_KALLSYMS=y CONFIG_KALLSYMS_ALL=y -# CONFIG_KALLSYMS_ABSOLUTE_PERCPU is not set -CONFIG_KALLSYMS_BASE_RELATIVE=y -CONFIG_PRINTK=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_BPF_SYSCALL is not set -CONFIG_SHMEM=y -CONFIG_AIO=y -CONFIG_ADVISE_SYSCALLS=y -# CONFIG_USERFAULTFD is not set -CONFIG_PCI_QUIRKS=y -CONFIG_MEMBARRIER=y -# CONFIG_EMBEDDED is not set -CONFIG_HAVE_PERF_EVENTS=y -# CONFIG_PC104 is not set # # Kernel Performance Events And Counters # -CONFIG_PERF_EVENTS=y -# CONFIG_DEBUG_PERF_USE_VMALLOC is not set -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_SLAB_MERGE_DEFAULT=y -# CONFIG_SLAB_FREELIST_RANDOM is not set -# CONFIG_SLAB_FREELIST_HARDENED is not set -CONFIG_SLUB_CPU_PARTIAL=y -# CONFIG_SYSTEM_DATA_VERIFICATION is not set CONFIG_PROFILING=y -CONFIG_CRASH_CORE=y -CONFIG_KEXEC_CORE=y -# CONFIG_KPROBES is not set +CONFIG_TRACEPOINTS=y CONFIG_JUMP_LABEL=y -# CONFIG_STATIC_KEYS_SELFTEST is not set -# CONFIG_UPROBES is not set -# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set -CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y -CONFIG_HAVE_KPROBES=y -CONFIG_HAVE_KRETPROBES=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_SET_MEMORY=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_HAVE_RCU_TABLE_FREE=y -CONFIG_HAVE_ALIGNED_STRUCT_PAGE=y -CONFIG_HAVE_CMPXCHG_LOCAL=y -CONFIG_HAVE_CMPXCHG_DOUBLE=y -CONFIG_ARCH_WANT_COMPAT_IPC_PARSE_VERSION=y -CONFIG_HAVE_ARCH_SECCOMP_FILTER=y -CONFIG_SECCOMP_FILTER=y -CONFIG_HAVE_GCC_PLUGINS=y -# CONFIG_GCC_PLUGINS is not set -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_THIN_ARCHIVES=y -CONFIG_HAVE_CONTEXT_TRACKING=y -CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y -CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y -CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE=y -CONFIG_HAVE_ARCH_HUGE_VMAP=y -CONFIG_MODULES_USE_ELF_RELA=y -CONFIG_ARCH_HAS_ELF_RANDOMIZE=y -CONFIG_HAVE_ARCH_MMAP_RND_BITS=y -CONFIG_ARCH_MMAP_RND_BITS=18 -CONFIG_HAVE_ARCH_MMAP_RND_COMPAT_BITS=y -CONFIG_ARCH_MMAP_RND_COMPAT_BITS=11 -# CONFIG_HAVE_ARCH_HASH is not set -# CONFIG_ISA_BUS_API is not set -CONFIG_CLONE_BACKWARDS=y -CONFIG_OLD_SIGSUSPEND3=y -CONFIG_COMPAT_OLD_SIGACTION=y -# CONFIG_CPU_NO_EFFICIENT_FFS is not set -CONFIG_HAVE_ARCH_VMAP_STACK=y -CONFIG_VMAP_STACK=y -# CONFIG_ARCH_OPTIONAL_KERNEL_RWX is not set -# CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT is not set -CONFIG_ARCH_HAS_STRICT_KERNEL_RWX=y -CONFIG_STRICT_KERNEL_RWX=y -CONFIG_ARCH_HAS_STRICT_MODULE_RWX=y -CONFIG_STRICT_MODULE_RWX=y -# CONFIG_REFCOUNT_FULL is not set +CONFIG_UPROBES=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 is not set CONFIG_MODULE_UNLOAD=y -# CONFIG_MODULE_FORCE_UNLOAD is not set -# 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_TRIM_UNUSED_KSYMS is not set -CONFIG_MODULES_TREE_LOOKUP=y -CONFIG_BLOCK=y -CONFIG_BLK_SCSI_REQUEST=y -CONFIG_BLK_DEV_BSG=y -CONFIG_BLK_DEV_BSGLIB=y CONFIG_BLK_DEV_INTEGRITY=y -# CONFIG_BLK_DEV_ZONED is not set -# CONFIG_BLK_DEV_THROTTLING is not set -# CONFIG_BLK_CMDLINE_PARSER is not set -# CONFIG_BLK_WBT is not set -CONFIG_BLK_DEBUG_FS=y -# CONFIG_BLK_SED_OPAL is not set # # Partition Types # -# CONFIG_PARTITION_ADVANCED is not set -CONFIG_MSDOS_PARTITION=y -CONFIG_EFI_PARTITION=y -CONFIG_BLOCK_COMPAT=y -CONFIG_BLK_MQ_PCI=y -CONFIG_BLK_MQ_VIRTIO=y +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 is not set +# 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_SYSV68_PARTITION is not set +# CONFIG_CMDLINE_PARTITION is not set # # IO Schedulers # -CONFIG_IOSCHED_NOOP=y # CONFIG_IOSCHED_DEADLINE is not set -CONFIG_IOSCHED_CFQ=y -# CONFIG_CFQ_GROUP_IOSCHED is not set -CONFIG_DEFAULT_CFQ=y -# CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="cfq" -CONFIG_MQ_IOSCHED_DEADLINE=y -CONFIG_MQ_IOSCHED_KYBER=y -# CONFIG_IOSCHED_BFQ is not set -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 # # Platform selection # -# CONFIG_ARCH_ACTIONS is not set # CONFIG_ARCH_SUNXI is not set # CONFIG_ARCH_ALPINE is not set # CONFIG_ARCH_BCM2835 is not set @@ -371,7 +115,6 @@ CONFIG_FREEZER=y CONFIG_ARCH_MESON=y # CONFIG_ARCH_MVEBU is not set # CONFIG_ARCH_QCOM is not set -# CONFIG_ARCH_REALTEK is not set # CONFIG_ARCH_ROCKCHIP is not set # CONFIG_ARCH_SEATTLE is not set # CONFIG_ARCH_RENESAS is not set @@ -382,7 +125,6 @@ CONFIG_ARCH_MESON=y # CONFIG_ARCH_THUNDER2 is not set # CONFIG_ARCH_UNIPHIER is not set # CONFIG_ARCH_VEXPRESS is not set -# CONFIG_ARCH_VULCAN is not set # CONFIG_ARCH_XGENE is not set # CONFIG_ARCH_ZX is not set # CONFIG_ARCH_ZYNQMP is not set @@ -391,64 +133,36 @@ CONFIG_ARCH_MESON=y # Bus support # CONFIG_PCI=y -CONFIG_PCI_DOMAINS=y -CONFIG_PCI_DOMAINS_GENERIC=y -CONFIG_PCI_SYSCALL=y -CONFIG_PCIEPORTBUS=y -CONFIG_PCIEAER=y -# CONFIG_PCIE_ECRC is not set -# CONFIG_PCIEAER_INJECT is not set -CONFIG_PCIEASPM=y -# CONFIG_PCIEASPM_DEBUG is not set -CONFIG_PCIEASPM_DEFAULT=y -# CONFIG_PCIEASPM_POWERSAVE is not set -# CONFIG_PCIEASPM_POWER_SUPERSAVE is not set -# CONFIG_PCIEASPM_PERFORMANCE is not set -CONFIG_PCIE_PME=y -# CONFIG_PCIE_DPC is not set -# CONFIG_PCIE_PTM is not set -CONFIG_PCI_BUS_ADDR_T_64BIT=y -CONFIG_PCI_MSI=y -CONFIG_PCI_MSI_IRQ_DOMAIN=y -# CONFIG_PCI_DEBUG is not set -# CONFIG_PCI_REALLOC_ENABLE_AUTO is not set -# CONFIG_PCI_STUB is not set -CONFIG_PCI_ATS=y -CONFIG_PCI_ECAM=y +# CONFIG_PCIEPORTBUS is not set CONFIG_PCI_IOV=y -# CONFIG_PCI_PRI is not set -# CONFIG_PCI_PASID is not set -CONFIG_PCI_LABEL=y -# CONFIG_HOTPLUG_PCI is not set +CONFIG_HOTPLUG_PCI=y +CONFIG_HOTPLUG_PCI_ACPI=y + +# +# Cadence PCIe controllers support +# # # DesignWare PCI Core Support # -CONFIG_PCIE_DW=y -CONFIG_PCIE_DW_HOST=y -# CONFIG_PCIE_DW_PLAT is not set -CONFIG_PCI_HISI=y +# CONFIG_PCI_HISI is not set # CONFIG_PCIE_KIRIN is not set # # PCI host controller drivers # -CONFIG_PCI_HOST_COMMON=y CONFIG_PCI_HOST_GENERIC=y -CONFIG_PCI_XGENE=y -CONFIG_PCI_XGENE_MSI=y +# CONFIG_PCI_XGENE is not set # CONFIG_PCI_HOST_THUNDER_PEM is not set # CONFIG_PCI_HOST_THUNDER_ECAM is not set # # PCI Endpoint # -# CONFIG_PCI_ENDPOINT is not set # # PCI switch controller drivers # -# CONFIG_PCI_SW_SWITCHTEC is not set # # Kernel Features @@ -457,167 +171,50 @@ CONFIG_PCI_XGENE_MSI=y # # ARM errata workarounds via the alternatives framework # -CONFIG_ARM64_ERRATUM_826319=y -CONFIG_ARM64_ERRATUM_827319=y -CONFIG_ARM64_ERRATUM_824069=y -CONFIG_ARM64_ERRATUM_819472=y -CONFIG_ARM64_ERRATUM_832075=y -CONFIG_ARM64_ERRATUM_845719=y -CONFIG_ARM64_ERRATUM_843419=y -CONFIG_CAVIUM_ERRATUM_22375=y -CONFIG_CAVIUM_ERRATUM_23154=y -CONFIG_CAVIUM_ERRATUM_27456=y -CONFIG_CAVIUM_ERRATUM_30115=y -CONFIG_QCOM_FALKOR_ERRATUM_1003=y -CONFIG_QCOM_FALKOR_ERRATUM_1009=y -CONFIG_QCOM_QDF2400_ERRATUM_0065=y -CONFIG_ARM64_4K_PAGES=y -# CONFIG_ARM64_16K_PAGES is not set -# CONFIG_ARM64_64K_PAGES is not set -# CONFIG_ARM64_VA_BITS_39 is not set +# CONFIG_QCOM_FALKOR_ERRATUM_1003 is not set +# CONFIG_QCOM_FALKOR_ERRATUM_1009 is not set +# CONFIG_QCOM_QDF2400_ERRATUM_0065 is not set +# CONFIG_SOCIONEXT_SYNQUACER_PREITS is not set +# CONFIG_HISILICON_ERRATUM_161600802 is not set +# CONFIG_QCOM_FALKOR_ERRATUM_E1041 is not set CONFIG_ARM64_VA_BITS_48=y -CONFIG_ARM64_VA_BITS=48 -# CONFIG_CPU_BIG_ENDIAN is not set CONFIG_SCHED_MC=y -# CONFIG_SCHED_SMT is not set -CONFIG_NR_CPUS=64 -CONFIG_HOTPLUG_CPU=y -# CONFIG_NUMA is not set -# CONFIG_PREEMPT_NONE is not set -# CONFIG_PREEMPT_VOLUNTARY is not set +CONFIG_NUMA=y CONFIG_PREEMPT=y -CONFIG_PREEMPT_COUNT=y -# CONFIG_HZ_100 is not set -CONFIG_HZ_250=y -# CONFIG_HZ_300 is not set -# CONFIG_HZ_1000 is not set -CONFIG_HZ=250 -CONFIG_SCHED_HRTICK=y -CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y -CONFIG_ARCH_HAS_HOLES_MEMORYMODEL=y -CONFIG_ARCH_SPARSEMEM_ENABLE=y -CONFIG_ARCH_SPARSEMEM_DEFAULT=y -CONFIG_ARCH_SELECT_MEMORY_MODEL=y -CONFIG_HAVE_ARCH_PFN_VALID=y -CONFIG_HW_PERF_EVENTS=y -CONFIG_SYS_SUPPORTS_HUGETLBFS=y -CONFIG_ARCH_WANT_HUGE_PMD_SHARE=y -CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y -CONFIG_SELECT_MEMORY_MODEL=y -CONFIG_SPARSEMEM_MANUAL=y -CONFIG_SPARSEMEM=y -CONFIG_HAVE_MEMORY_PRESENT=y -CONFIG_SPARSEMEM_EXTREME=y -CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y -CONFIG_SPARSEMEM_VMEMMAP=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_MEMORY_BALLOON=y -CONFIG_BALLOON_COMPACTION=y -CONFIG_COMPACTION=y -CONFIG_MIGRATION=y -CONFIG_PHYS_ADDR_T_64BIT=y -CONFIG_BOUNCE=y -CONFIG_MMU_NOTIFIER=y CONFIG_KSM=y -CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 -CONFIG_ARCH_SUPPORTS_MEMORY_FAILURE=y -# CONFIG_MEMORY_FAILURE is not set +CONFIG_MEMORY_FAILURE=y CONFIG_TRANSPARENT_HUGEPAGE=y -CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y -# CONFIG_TRANSPARENT_HUGEPAGE_MADVISE is not set -# CONFIG_ARCH_WANTS_THP_SWAP is not set -CONFIG_TRANSPARENT_HUGE_PAGECACHE=y -# 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 is not set -CONFIG_GENERIC_EARLY_IOREMAP=y -# CONFIG_IDLE_PAGE_TRACKING is not set -# CONFIG_PERCPU_STATS is not set CONFIG_SECCOMP=y CONFIG_PARAVIRT=y -# CONFIG_PARAVIRT_TIME_ACCOUNTING is not set CONFIG_KEXEC=y -# CONFIG_CRASH_DUMP is not set -CONFIG_XEN_DOM0=y +CONFIG_CRASH_DUMP=y CONFIG_XEN=y -CONFIG_FORCE_MAX_ZONEORDER=11 -# CONFIG_ARMV8_DEPRECATED is not set -# CONFIG_ARM64_SW_TTBR0_PAN is not set # # ARMv8.1 architectural features # -CONFIG_ARM64_HW_AFDBM=y -CONFIG_ARM64_PAN=y -# CONFIG_ARM64_LSE_ATOMICS is not set -CONFIG_ARM64_VHE=y # # ARMv8.2 architectural features # -CONFIG_ARM64_UAO=y -# CONFIG_ARM64_PMEM is not set -CONFIG_ARM64_MODULE_CMODEL_LARGE=y -# CONFIG_RANDOMIZE_BASE is not set # # Boot options # -# CONFIG_ARM64_ACPI_PARKING_PROTOCOL is not set -CONFIG_CMDLINE="" -# CONFIG_CMDLINE_FORCE is not set -CONFIG_EFI_STUB=y -CONFIG_EFI=y -CONFIG_DMI=y # # Userspace binary formats # -CONFIG_BINFMT_ELF=y -CONFIG_COMPAT_BINFMT_ELF=y -CONFIG_ELFCORE=y -# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set -CONFIG_BINFMT_SCRIPT=y -# CONFIG_HAVE_AOUT is not set -# CONFIG_BINFMT_MISC is not set -CONFIG_COREDUMP=y +CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y +CONFIG_BINFMT_MISC=y CONFIG_COMPAT=y -CONFIG_SYSVIPC_COMPAT=y # # Power management options # -CONFIG_SUSPEND=y -CONFIG_SUSPEND_FREEZER=y -CONFIG_HIBERNATE_CALLBACKS=y CONFIG_HIBERNATION=y -CONFIG_PM_STD_PARTITION="" -CONFIG_PM_SLEEP=y -CONFIG_PM_SLEEP_SMP=y -# CONFIG_PM_AUTOSLEEP is not set -# CONFIG_PM_WAKELOCKS is not set -CONFIG_PM=y -# CONFIG_PM_DEBUG is not set -CONFIG_PM_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_HIBERNATION_POSSIBLE=y -CONFIG_ARCH_HIBERNATION_HEADER=y -CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_WQ_POWER_EFFICIENT_DEFAULT=y # # CPU Power Management @@ -636,460 +233,658 @@ CONFIG_DT_IDLE_STATES=y # ARM CPU Idle Drivers # CONFIG_ARM_CPUIDLE=y -# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set # # CPU Frequency scaling # CONFIG_CPU_FREQ=y -# CONFIG_CPU_FREQ_STAT is not set -CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y -# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set -# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set -# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set -# 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 is not set -# CONFIG_CPU_FREQ_GOV_USERSPACE is not set -# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set -# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set -# CONFIG_CPU_FREQ_GOV_SCHEDUTIL is not set +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_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=m +CONFIG_CPU_FREQ_GOV_USERSPACE=m +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m # # CPU frequency scaling drivers # CONFIG_CPUFREQ_DT=y -CONFIG_CPUFREQ_DT_PLATDEV=y +CONFIG_ACPI_CPPC_CPUFREQ=m CONFIG_ARM_BIG_LITTLE_CPUFREQ=y -# CONFIG_ARM_DT_BL_CPUFREQ is not set -# CONFIG_ARM_KIRKWOOD_CPUFREQ is not set CONFIG_ARM_SCPI_CPUFREQ=y -# CONFIG_ACPI_CPPC_CPUFREQ is not set -# CONFIG_QORIQ_CPUFREQ is not set CONFIG_NET=y -CONFIG_NET_INGRESS=y +CONFIG_COMPAT_NETLINK_MESSAGES=y +CONFIG_NET_EGRESS=y # # Networking options # CONFIG_PACKET=y -# CONFIG_PACKET_DIAG is not set CONFIG_UNIX=y -# CONFIG_UNIX_DIAG is not set -# CONFIG_TLS is not set -CONFIG_XFRM=y -# CONFIG_XFRM_USER is not set -# CONFIG_XFRM_SUB_POLICY is not set -# CONFIG_XFRM_MIGRATE is not set -# CONFIG_XFRM_STATISTICS is not set -# CONFIG_NET_KEY is not set +CONFIG_XFRM_ALGO=y +CONFIG_XFRM_USER=m +CONFIG_XFRM_IPCOMP=m +CONFIG_NET_KEY=y +# CONFIG_NET_KEY_MIGRATE is not set CONFIG_INET=y CONFIG_IP_MULTICAST=y -# CONFIG_IP_ADVANCED_ROUTER is not set -# CONFIG_IP_PNP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE_DEMUX is not set +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_NET_IP_TUNNEL=m -# CONFIG_IP_MROUTE is not set -# CONFIG_SYN_COOKIES is not set -# CONFIG_NET_UDP_TUNNEL is not set -# CONFIG_NET_FOU is not set -# CONFIG_NET_FOU_IP_TUNNELS is not set -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_XFRM_TUNNEL is not set +CONFIG_SYN_COOKIES=y +CONFIG_NET_UDP_TUNNEL=m +CONFIG_INET_ESP=y +# CONFIG_INET_ESP_OFFLOAD is not set CONFIG_INET_TUNNEL=m -# CONFIG_INET_XFRM_MODE_TRANSPORT is not set -# CONFIG_INET_XFRM_MODE_TUNNEL is not set -# CONFIG_INET_XFRM_MODE_BEET is not set -CONFIG_INET_DIAG=y -CONFIG_INET_TCP_DIAG=y -# CONFIG_INET_UDP_DIAG is not set -# CONFIG_INET_RAW_DIAG is not set -# CONFIG_INET_DIAG_DESTROY is not set -# CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_CUBIC=y -CONFIG_DEFAULT_TCP_CONG="cubic" -# CONFIG_TCP_MD5SIG is not set +CONFIG_INET_UDP_DIAG=m +CONFIG_INET_RAW_DIAG=m +CONFIG_TCP_CONG_ADVANCED=y +CONFIG_TCP_CONG_BIC=m +CONFIG_TCP_CONG_WESTWOOD=m +CONFIG_TCP_CONG_HTCP=m +CONFIG_TCP_CONG_HSTCP=m +# CONFIG_TCP_CONG_HYBLA is not set +# CONFIG_TCP_CONG_VEGAS is not set +# CONFIG_TCP_CONG_NV is not set +CONFIG_TCP_CONG_SCALABLE=m +# CONFIG_TCP_CONG_LP is not set +# CONFIG_TCP_CONG_VENO is not set +# CONFIG_TCP_CONG_YEAH is not set +# CONFIG_TCP_CONG_ILLINOIS is not set +# CONFIG_TCP_CONG_DCTCP is not set +# CONFIG_TCP_CONG_CDG is not set +# CONFIG_TCP_CONG_BBR is not set +CONFIG_DEFAULT_CUBIC=y +# CONFIG_DEFAULT_RENO is not set CONFIG_IPV6=m -# CONFIG_IPV6_ROUTER_PREF is not set -# CONFIG_IPV6_OPTIMISTIC_DAD is not set -# CONFIG_INET6_AH is not set -# CONFIG_INET6_ESP is not set -# 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_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 is not set +CONFIG_INET6_IPCOMP=m +CONFIG_IPV6_MIP6=m +CONFIG_INET6_XFRM_TUNNEL=m +CONFIG_INET6_TUNNEL=m CONFIG_INET6_XFRM_MODE_TRANSPORT=m CONFIG_INET6_XFRM_MODE_TUNNEL=m CONFIG_INET6_XFRM_MODE_BEET=m -# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set -# CONFIG_IPV6_VTI is not set +CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m +CONFIG_IPV6_VTI=m CONFIG_IPV6_SIT=m -# CONFIG_IPV6_SIT_6RD is not set -CONFIG_IPV6_NDISC_NODETYPE=y -# CONFIG_IPV6_TUNNEL is not set -# CONFIG_IPV6_FOU is not set -# CONFIG_IPV6_FOU_TUNNEL is not set -# CONFIG_IPV6_MULTIPLE_TABLES is not set -# CONFIG_IPV6_MROUTE is not set -# CONFIG_IPV6_SEG6_LWTUNNEL is not set -# CONFIG_IPV6_SEG6_HMAC is not set -# CONFIG_NETLABEL is not set -# CONFIG_NETWORK_SECMARK is not set -CONFIG_NET_PTP_CLASSIFY=y -# CONFIG_NETWORK_PHY_TIMESTAMPING is not set +CONFIG_IPV6_SIT_6RD=y +CONFIG_IPV6_TUNNEL=m +CONFIG_IPV6_MULTIPLE_TABLES=y +CONFIG_IPV6_SUBTREES=y +CONFIG_IPV6_MROUTE=y +CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y +CONFIG_IPV6_PIMSM_V2=y +CONFIG_NETLABEL=y +CONFIG_NETWORK_SECMARK=y CONFIG_NETFILTER=y -CONFIG_NETFILTER_ADVANCED=y # # Core Netfilter Configuration # -CONFIG_NETFILTER_INGRESS=y -# CONFIG_NETFILTER_NETLINK_ACCT is not set -# CONFIG_NETFILTER_NETLINK_QUEUE is not set -# CONFIG_NETFILTER_NETLINK_LOG is not set +CONFIG_NETFILTER_NETLINK=m +CONFIG_NETFILTER_FAMILY_ARP=y +CONFIG_NETFILTER_NETLINK_ACCT=m +CONFIG_NETFILTER_NETLINK_QUEUE=m +CONFIG_NETFILTER_NETLINK_LOG=m CONFIG_NF_CONNTRACK=m -CONFIG_NF_LOG_COMMON=m -# CONFIG_NF_LOG_NETDEV is not set -# CONFIG_NF_CONNTRACK_MARK is not set -CONFIG_NF_CONNTRACK_PROCFS=y +CONFIG_NETFILTER_CONNCOUNT=m +CONFIG_NF_CONNTRACK_MARK=y +CONFIG_NF_CONNTRACK_SECMARK=y +CONFIG_NF_CONNTRACK_ZONES=y CONFIG_NF_CONNTRACK_EVENTS=y -# CONFIG_NF_CONNTRACK_TIMEOUT is not set -# CONFIG_NF_CONNTRACK_TIMESTAMP is not set -CONFIG_NF_CT_PROTO_DCCP=y -CONFIG_NF_CT_PROTO_SCTP=y -CONFIG_NF_CT_PROTO_UDPLITE=y -# CONFIG_NF_CONNTRACK_AMANDA is not set -# CONFIG_NF_CONNTRACK_FTP is not set -# CONFIG_NF_CONNTRACK_H323 is not set -# CONFIG_NF_CONNTRACK_IRC is not set -# CONFIG_NF_CONNTRACK_NETBIOS_NS is not set -# CONFIG_NF_CONNTRACK_SNMP is not set -# CONFIG_NF_CONNTRACK_PPTP is not set -# CONFIG_NF_CONNTRACK_SANE is not set -# CONFIG_NF_CONNTRACK_SIP is not set -# CONFIG_NF_CONNTRACK_TFTP is not set -# CONFIG_NF_CT_NETLINK is not set -# CONFIG_NF_CT_NETLINK_TIMEOUT is not set -CONFIG_NF_NAT=m -CONFIG_NF_NAT_NEEDED=y -CONFIG_NF_NAT_PROTO_DCCP=y -CONFIG_NF_NAT_PROTO_UDPLITE=y -CONFIG_NF_NAT_PROTO_SCTP=y -# CONFIG_NF_NAT_AMANDA is not set -# CONFIG_NF_NAT_FTP is not set -# CONFIG_NF_NAT_IRC is not set -# CONFIG_NF_NAT_SIP is not set -# CONFIG_NF_NAT_TFTP is not set -# CONFIG_NF_NAT_REDIRECT is not set -# CONFIG_NF_TABLES is not set -CONFIG_NETFILTER_XTABLES=m +CONFIG_NF_CONNTRACK_TIMEOUT=y +CONFIG_NF_CONNTRACK_TIMESTAMP=y +CONFIG_NF_CONNTRACK_LABELS=y +CONFIG_NF_CT_PROTO_GRE=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_NETFILTER_NETLINK_GLUE_CT is not set +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_NETFILTER_SYNPROXY=m +CONFIG_NF_TABLES=m +CONFIG_NF_TABLES_INET=y +CONFIG_NF_TABLES_NETDEV=y +CONFIG_NFT_EXTHDR=m +CONFIG_NFT_META=m +CONFIG_NFT_RT=m +CONFIG_NFT_NUMGEN=m +CONFIG_NFT_CT=m +CONFIG_NFT_SET_RBTREE=m +CONFIG_NFT_SET_HASH=m +CONFIG_NFT_SET_BITMAP=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_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_NF_DUP_NETDEV=m +CONFIG_NFT_DUP_NETDEV=m +CONFIG_NFT_FWD_NETDEV=m +# CONFIG_NFT_FIB_NETDEV is not set +# CONFIG_NF_FLOW_TABLE is not set # # Xtables combined modules # -# CONFIG_NETFILTER_XT_MARK is not set -# CONFIG_NETFILTER_XT_CONNMARK is not set +CONFIG_NETFILTER_XT_MARK=m +CONFIG_NETFILTER_XT_CONNMARK=m +CONFIG_NETFILTER_XT_SET=m # # Xtables targets # -# CONFIG_NETFILTER_XT_TARGET_AUDIT is not set +CONFIG_NETFILTER_XT_TARGET_AUDIT=m CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m -# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set -# CONFIG_NETFILTER_XT_TARGET_CONNMARK is not set -# CONFIG_NETFILTER_XT_TARGET_DSCP is not set -# CONFIG_NETFILTER_XT_TARGET_HL is not set -# CONFIG_NETFILTER_XT_TARGET_HMARK is not set -# CONFIG_NETFILTER_XT_TARGET_IDLETIMER is not set -# CONFIG_NETFILTER_XT_TARGET_LED is not set +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 is not set -CONFIG_NETFILTER_XT_NAT=m -# CONFIG_NETFILTER_XT_TARGET_NETMAP is not set -# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set -# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set -# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set -# CONFIG_NETFILTER_XT_TARGET_REDIRECT is not set -# CONFIG_NETFILTER_XT_TARGET_TEE is not set -# CONFIG_NETFILTER_XT_TARGET_TPROXY is not set -# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set -# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set +CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_TARGET_NETMAP=m +CONFIG_NETFILTER_XT_TARGET_NFLOG=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +CONFIG_NETFILTER_XT_TARGET_NOTRACK=m +CONFIG_NETFILTER_XT_TARGET_RATEEST=m +CONFIG_NETFILTER_XT_TARGET_REDIRECT=m +CONFIG_NETFILTER_XT_TARGET_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 is not set -# CONFIG_NETFILTER_XT_MATCH_CGROUP is not set -# CONFIG_NETFILTER_XT_MATCH_CLUSTER is not set -# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set -# CONFIG_NETFILTER_XT_MATCH_CONNBYTES is not set -# CONFIG_NETFILTER_XT_MATCH_CONNLABEL is not set -# CONFIG_NETFILTER_XT_MATCH_CONNLIMIT is not set -# CONFIG_NETFILTER_XT_MATCH_CONNMARK is not set +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 is not set -# CONFIG_NETFILTER_XT_MATCH_DCCP is not set -# CONFIG_NETFILTER_XT_MATCH_DEVGROUP is not set -# CONFIG_NETFILTER_XT_MATCH_DSCP is not set -# CONFIG_NETFILTER_XT_MATCH_ECN is not set -# CONFIG_NETFILTER_XT_MATCH_ESP is not set -# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set -# CONFIG_NETFILTER_XT_MATCH_HELPER is not set -# CONFIG_NETFILTER_XT_MATCH_HL is not set -# CONFIG_NETFILTER_XT_MATCH_IPCOMP is not set -# CONFIG_NETFILTER_XT_MATCH_IPRANGE is not set -# CONFIG_NETFILTER_XT_MATCH_L2TP is not set -# CONFIG_NETFILTER_XT_MATCH_LENGTH is not set -# CONFIG_NETFILTER_XT_MATCH_LIMIT is not set -# CONFIG_NETFILTER_XT_MATCH_MAC is not set -# CONFIG_NETFILTER_XT_MATCH_MARK is not set -# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set -# CONFIG_NETFILTER_XT_MATCH_NFACCT is not set -# CONFIG_NETFILTER_XT_MATCH_OWNER is not set -# CONFIG_NETFILTER_XT_MATCH_POLICY is not set -# CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set -# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set -# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set -# CONFIG_NETFILTER_XT_MATCH_REALM is not set -# CONFIG_NETFILTER_XT_MATCH_RECENT is not set -# CONFIG_NETFILTER_XT_MATCH_SCTP is not set -# CONFIG_NETFILTER_XT_MATCH_STATE is not set -# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set -# CONFIG_NETFILTER_XT_MATCH_STRING is not set -# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set -# CONFIG_NETFILTER_XT_MATCH_TIME is not set -# CONFIG_NETFILTER_XT_MATCH_U32 is not set -# CONFIG_IP_SET is not set -# CONFIG_IP_VS is not set +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 +CONFIG_IP_SET=m +CONFIG_IP_SET_MAX=256 +CONFIG_IP_SET_BITMAP_IP=m +CONFIG_IP_SET_BITMAP_IPMAC=m +CONFIG_IP_SET_BITMAP_PORT=m +CONFIG_IP_SET_HASH_IP=m +CONFIG_IP_SET_HASH_IPMARK=m +CONFIG_IP_SET_HASH_IPPORT=m +CONFIG_IP_SET_HASH_IPPORTIP=m +CONFIG_IP_SET_HASH_IPPORTNET=m +CONFIG_IP_SET_HASH_IPMAC=m +CONFIG_IP_SET_HASH_MAC=m +CONFIG_IP_SET_HASH_NETPORTNET=m +CONFIG_IP_SET_HASH_NET=m +CONFIG_IP_SET_HASH_NETNET=m +CONFIG_IP_SET_HASH_NETPORT=m +CONFIG_IP_SET_HASH_NETIFACE=m +CONFIG_IP_SET_LIST_SET=m +CONFIG_IP_VS=m +CONFIG_IP_VS_IPV6=y +# CONFIG_IP_VS_DEBUG is not set +CONFIG_IP_VS_TAB_BITS=12 + +# +# IPVS transport protocol load balancing support +# +CONFIG_IP_VS_PROTO_TCP=y +CONFIG_IP_VS_PROTO_UDP=y +CONFIG_IP_VS_PROTO_AH_ESP=y +CONFIG_IP_VS_PROTO_ESP=y +CONFIG_IP_VS_PROTO_AH=y +CONFIG_IP_VS_PROTO_SCTP=y + +# +# IPVS scheduler +# +CONFIG_IP_VS_RR=m +CONFIG_IP_VS_WRR=m +CONFIG_IP_VS_LC=m +CONFIG_IP_VS_WLC=m +# CONFIG_IP_VS_FO is not set +# CONFIG_IP_VS_OVF is not set +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_SOCKET_IPV4 is not set -# CONFIG_NF_DUP_IPV4 is not set -# CONFIG_NF_LOG_ARP is not set -CONFIG_NF_LOG_IPV4=m -CONFIG_NF_REJECT_IPV4=m -CONFIG_NF_NAT_IPV4=m -CONFIG_NF_NAT_MASQUERADE_IPV4=m -# CONFIG_NF_NAT_PPTP is not set -# CONFIG_NF_NAT_H323 is not set +CONFIG_NF_SOCKET_IPV4=m +CONFIG_NF_TABLES_IPV4=y +CONFIG_NFT_CHAIN_ROUTE_IPV4=m +CONFIG_NFT_REJECT_IPV4=m +CONFIG_NFT_DUP_IPV4=m +CONFIG_NFT_FIB_IPV4=m +CONFIG_NF_TABLES_ARP=y +CONFIG_NF_DUP_IPV4=m +CONFIG_NFT_CHAIN_NAT_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 is not set -# CONFIG_IP_NF_MATCH_ECN is not set -# CONFIG_IP_NF_MATCH_RPFILTER is not set -# CONFIG_IP_NF_MATCH_TTL is not set +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 is not set +CONFIG_IP_NF_TARGET_SYNPROXY=m CONFIG_IP_NF_NAT=m CONFIG_IP_NF_TARGET_MASQUERADE=m -# CONFIG_IP_NF_TARGET_NETMAP is not set -# CONFIG_IP_NF_TARGET_REDIRECT is not set +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_REDIRECT=m CONFIG_IP_NF_MANGLE=m -# CONFIG_IP_NF_TARGET_CLUSTERIP is not set -# CONFIG_IP_NF_TARGET_ECN is not set -# CONFIG_IP_NF_TARGET_TTL is not set -# CONFIG_IP_NF_RAW is not set -# CONFIG_IP_NF_SECURITY is not set -# CONFIG_IP_NF_ARPTABLES is not set +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=m CONFIG_NF_CONNTRACK_IPV6=m -# CONFIG_NF_SOCKET_IPV6 is not set -# CONFIG_NF_DUP_IPV6 is not set -CONFIG_NF_REJECT_IPV6=m -CONFIG_NF_LOG_IPV6=m -CONFIG_NF_NAT_IPV6=m -CONFIG_NF_NAT_MASQUERADE_IPV6=m +CONFIG_NF_SOCKET_IPV6=m +CONFIG_NF_TABLES_IPV6=y +CONFIG_NFT_CHAIN_ROUTE_IPV6=m +CONFIG_NFT_REJECT_IPV6=m +CONFIG_NFT_DUP_IPV6=m +CONFIG_NFT_FIB_IPV6=m +CONFIG_NF_DUP_IPV6=m +CONFIG_NFT_CHAIN_NAT_IPV6=m +CONFIG_NFT_MASQ_IPV6=m +CONFIG_NFT_REDIR_IPV6=m CONFIG_IP6_NF_IPTABLES=m -# CONFIG_IP6_NF_MATCH_AH is not set -# CONFIG_IP6_NF_MATCH_EUI64 is not set -# CONFIG_IP6_NF_MATCH_FRAG is not set -# CONFIG_IP6_NF_MATCH_OPTS is not set -# CONFIG_IP6_NF_MATCH_HL is not set -# CONFIG_IP6_NF_MATCH_IPV6HEADER is not set -# CONFIG_IP6_NF_MATCH_MH is not set -# CONFIG_IP6_NF_MATCH_RPFILTER is not set -# CONFIG_IP6_NF_MATCH_RT is not set -# CONFIG_IP6_NF_TARGET_HL is not set +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_TARGET_HL=m CONFIG_IP6_NF_FILTER=m CONFIG_IP6_NF_TARGET_REJECT=m -# CONFIG_IP6_NF_TARGET_SYNPROXY is not set +CONFIG_IP6_NF_TARGET_SYNPROXY=m CONFIG_IP6_NF_MANGLE=m -# CONFIG_IP6_NF_RAW is not set -# CONFIG_IP6_NF_SECURITY is not set +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 is not set -# 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_BRIDGE is not set -CONFIG_HAVE_NET_DSA=y -# CONFIG_NET_DSA is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# 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 is not set -# CONFIG_DCB is not set -CONFIG_DNS_RESOLVER=y -# CONFIG_BATMAN_ADV is not set -# CONFIG_OPENVSWITCH is not set -# CONFIG_VSOCKETS is not set -# CONFIG_NETLINK_DIAG is not set -# CONFIG_MPLS is not set -# CONFIG_NET_NSH is not set -# CONFIG_HSR is not set -# CONFIG_NET_SWITCHDEV is not set -# CONFIG_NET_L3_MASTER_DEV is not set -# CONFIG_NET_NCSI is not set -CONFIG_RPS=y -CONFIG_RFS_ACCEL=y -CONFIG_XPS=y -# CONFIG_CGROUP_NET_PRIO is not set -# CONFIG_CGROUP_NET_CLASSID is not set -CONFIG_NET_RX_BUSY_POLL=y -CONFIG_BQL=y +CONFIG_IP6_NF_TARGET_NPT=m +CONFIG_NF_TABLES_BRIDGE=y +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_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=y +CONFIG_INET_SCTP_DIAG=m +CONFIG_L2TP=m +CONFIG_L2TP_DEBUGFS=m +CONFIG_L2TP_V3=y +CONFIG_L2TP_IP=m +CONFIG_L2TP_ETH=m +CONFIG_BRIDGE=m +CONFIG_BRIDGE_VLAN_FILTERING=y +CONFIG_VLAN_8021Q=m +CONFIG_VLAN_8021Q_GVRP=y +CONFIG_VLAN_8021Q_MVRP=y +CONFIG_PHONET=y +CONFIG_NET_SCHED=y + +# +# Queueing/Scheduling +# +CONFIG_NET_SCH_CBQ=m +CONFIG_NET_SCH_HTB=m +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_CBS 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_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=m +CONFIG_NET_SCH_PLUG=m +# CONFIG_NET_SCH_DEFAULT is not set + +# +# 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=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 is not set +# CONFIG_NET_CLS_MATCHALL is not set +CONFIG_NET_EMATCH=y +CONFIG_NET_EMATCH_STACK=32 +CONFIG_NET_EMATCH_CMP=m +CONFIG_NET_EMATCH_NBYTE=m +CONFIG_NET_EMATCH_U32=y +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=y +CONFIG_NET_ACT_GACT=y +CONFIG_GACT_PROB=y +CONFIG_NET_ACT_MIRRED=y +# CONFIG_NET_ACT_SAMPLE is not set +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 is not set +# CONFIG_NET_ACT_BPF is not set +# CONFIG_NET_ACT_CONNMARK is not set +# CONFIG_NET_ACT_SKBMOD is not set +# CONFIG_NET_ACT_IFE is not set +# CONFIG_NET_ACT_TUNNEL_KEY is not set +CONFIG_NET_CLS_IND=y +CONFIG_NET_SCH_FIFO=y +CONFIG_CGROUP_NET_PRIO=y +CONFIG_CGROUP_NET_CLASSID=y CONFIG_BPF_JIT=y -CONFIG_NET_FLOW_LIMIT=y # # Network testing # -# CONFIG_NET_PKTGEN is not set -# CONFIG_HAMRADIO is not set -# CONFIG_CAN is not set -# CONFIG_BT is not set -# CONFIG_AF_RXRPC is not set -# CONFIG_AF_KCM is not set -# CONFIG_STREAM_PARSER is not set -CONFIG_WIRELESS=y +# CONFIG_NET_DROP_MONITOR is not set +CONFIG_CAN=m +CONFIG_CAN_RAW=m +CONFIG_CAN_BCM=m +CONFIG_CAN_GW=m + +# +# CAN Device Drivers +# +# CONFIG_CAN_VCAN is not set +# CONFIG_CAN_VXCAN is not set +CONFIG_CAN_SLCAN=m +CONFIG_CAN_DEV=m +CONFIG_CAN_CALC_BITTIMING=y +# CONFIG_CAN_LEDS is not set +# CONFIG_CAN_GRCAN is not set +# CONFIG_CAN_XILINXCAN is not set +# CONFIG_CAN_C_CAN is not set +# CONFIG_CAN_CC770 is not set +# CONFIG_CAN_IFI_CANFD is not set +# CONFIG_CAN_M_CAN is not set +# CONFIG_CAN_PEAK_PCIEFD is not set +# CONFIG_CAN_SJA1000 is not set +# CONFIG_CAN_SOFTING is not set + +# +# CAN SPI interfaces +# +# CONFIG_CAN_HI311X is not set +# CONFIG_CAN_MCP251X is not set + +# +# CAN USB interfaces +# +CONFIG_CAN_EMS_USB=m +CONFIG_CAN_ESD_USB2=m +CONFIG_CAN_GS_USB=m +CONFIG_CAN_KVASER_USB=m +CONFIG_CAN_PEAK_USB=m +CONFIG_CAN_8DEV_USB=m +CONFIG_CAN_MCBA_USB=m +# CONFIG_CAN_DEBUG_DEVICES is not set +CONFIG_BT=m +CONFIG_BT_HIDP=m +# CONFIG_BT_HS is not set +# CONFIG_BT_LE is not set +CONFIG_BT_LEDS=y +# CONFIG_BT_DEBUGFS is not set + +# +# Bluetooth device drivers +# +CONFIG_BT_INTEL=m +CONFIG_BT_BCM=m +CONFIG_BT_RTL=m +CONFIG_BT_HCIBTUSB=m +# CONFIG_BT_HCIBTUSB_AUTOSUSPEND is not set +CONFIG_BT_HCIBTUSB_BCM=y +CONFIG_BT_HCIBTUSB_RTL=y +CONFIG_BT_HCIUART=m +CONFIG_BT_HCIUART_H4=y +CONFIG_BT_HCIUART_LL=y +CONFIG_BT_HCIBCM203X=m +CONFIG_BT_HCIBPA10X=m +CONFIG_BT_HCIBFUSB=m +CONFIG_BT_ATH3K=m +CONFIG_FIB_RULES=y +CONFIG_WIRELESS_EXT=y +CONFIG_WEXT_CORE=y +CONFIG_WEXT_PROC=y +CONFIG_WEXT_PRIV=y CONFIG_CFG80211=m -# CONFIG_NL80211_TESTMODE is not set -# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set -CONFIG_CFG80211_DEFAULT_PS=y -# CONFIG_CFG80211_DEBUGFS is not set -# CONFIG_CFG80211_INTERNAL_REGDB is not set -CONFIG_CFG80211_CRDA_SUPPORT=y -# CONFIG_CFG80211_WEXT is not set -# CONFIG_LIB80211 is not set +CONFIG_CFG80211_WEXT=y CONFIG_MAC80211=m -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 is not set +CONFIG_MAC80211_MESH=y CONFIG_MAC80211_LEDS=y -# CONFIG_MAC80211_DEBUGFS is not set -# CONFIG_MAC80211_MESSAGE_TRACING is not set -# CONFIG_MAC80211_DEBUG_MENU is not set -CONFIG_MAC80211_STA_HASH_MAX_SIZE=0 -# CONFIG_WIMAX is not set CONFIG_RFKILL=m -CONFIG_RFKILL_LEDS=y -CONFIG_RFKILL_INPUT=y -# CONFIG_RFKILL_GPIO is not set -# CONFIG_NET_9P is not set -# CONFIG_CAIF is not set -# CONFIG_CEPH_LIB is not set -# CONFIG_NFC is not set -# CONFIG_PSAMPLE is not set -# CONFIG_NET_IFE is not set -# CONFIG_LWTUNNEL is not set -CONFIG_DST_CACHE=y -CONFIG_GRO_CELLS=y -# CONFIG_NET_DEVLINK is not set -CONFIG_MAY_USE_DEVLINK=y -CONFIG_HAVE_EBPF_JIT=y +CONFIG_NET_9P=y +CONFIG_NET_9P_VIRTIO=y +CONFIG_NFC=m +CONFIG_NFC_DIGITAL=m +CONFIG_NFC_NCI=m +# CONFIG_NFC_NCI_SPI is not set +# CONFIG_NFC_NCI_UART is not set +CONFIG_NFC_HCI=m +# CONFIG_NFC_SHDLC is not set + +# +# Near Field Communication (NFC) devices +# +# CONFIG_NFC_TRF7970A is not set +# CONFIG_NFC_SIM is not set +# CONFIG_NFC_PORT100 is not set +# CONFIG_NFC_FDP is not set +CONFIG_NFC_PN533=m +CONFIG_NFC_PN533_USB=m +# CONFIG_NFC_PN533_I2C is not set +CONFIG_NFC_MRVL=m +CONFIG_NFC_MRVL_USB=m +# CONFIG_NFC_MRVL_I2C is not set +# CONFIG_NFC_ST_NCI_I2C is not set +# CONFIG_NFC_ST_NCI_SPI is not set +# CONFIG_NFC_NXP_NCI is not set +# CONFIG_NFC_S3FWRN5_I2C is not set +# CONFIG_NFC_ST95HF is not set # # Device Drivers # -CONFIG_ARM_AMBA=y # # Generic Driver Options # -CONFIG_UEVENT_HELPER=y CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" 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_ALLOW_DEV_COREDUMP=y -# CONFIG_DEBUG_DRIVER is not set -# CONFIG_DEBUG_DEVRES is not set -# CONFIG_DEBUG_TEST_DRIVER_REMOVE is not set -# CONFIG_TEST_ASYNC_DRIVER_PROBE is not set -CONFIG_SYS_HYPERVISOR=y -# CONFIG_GENERIC_CPU_DEVICES is not set -CONFIG_GENERIC_CPU_AUTOPROBE=y -CONFIG_SOC_BUS=y -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_DMA_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 -CONFIG_GENERIC_ARCH_TOPOLOGY=y # # Bus devices # -# CONFIG_ARM_CCI400_PMU is not set -# CONFIG_ARM_CCI5xx_PMU is not set -# CONFIG_ARM_CCN is not set # CONFIG_BRCMSTB_GISB_ARB is not set -# CONFIG_SIMPLE_PM_BUS is not set CONFIG_VEXPRESS_CONFIG=y -# CONFIG_CONNECTOR is not set +CONFIG_CONNECTOR=m CONFIG_MTD=y -# CONFIG_MTD_TESTS is not set -# CONFIG_MTD_REDBOOT_PARTS is not set -# CONFIG_MTD_CMDLINE_PARTS is not set -# CONFIG_MTD_AFS_PARTS is not set -CONFIG_MTD_OF_PARTS=y -# CONFIG_MTD_AR7_PARTS is not set # # Partition parsers @@ -1098,170 +893,63 @@ CONFIG_MTD_OF_PARTS=y # # User Modules And Translation Layers # -# CONFIG_MTD_BLOCK is not set -# CONFIG_MTD_BLOCK_RO is not set -# CONFIG_FTL is not set -# CONFIG_NFTL is not set -# CONFIG_INFTL is not set -# CONFIG_RFD_FTL is not set -# CONFIG_SSFDC is not set -# CONFIG_SM_FTL is not set -# CONFIG_MTD_OOPS is not set -# CONFIG_MTD_SWAP is not set -# CONFIG_MTD_PARTITIONED_MASTER is not set +CONFIG_MTD_BLOCK=y # # RAM/ROM/Flash chip drivers # -# CONFIG_MTD_CFI is not set -# CONFIG_MTD_JEDECPROBE is not set -CONFIG_MTD_MAP_BANK_WIDTH_1=y -CONFIG_MTD_MAP_BANK_WIDTH_2=y -CONFIG_MTD_MAP_BANK_WIDTH_4=y -# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set -CONFIG_MTD_CFI_I1=y -CONFIG_MTD_CFI_I2=y -# CONFIG_MTD_CFI_I4 is not set -# CONFIG_MTD_CFI_I8 is not set -# CONFIG_MTD_RAM is not set -# CONFIG_MTD_ROM is not set -# CONFIG_MTD_ABSENT is not set # # Mapping drivers for chip access # -# CONFIG_MTD_COMPLEX_MAPPINGS is not set -# CONFIG_MTD_INTEL_VR_NOR is not set -# CONFIG_MTD_PLATRAM is not set # # Self-contained MTD device drivers # -# CONFIG_MTD_PMC551 is not set -# CONFIG_MTD_DATAFLASH is not set CONFIG_MTD_M25P80=y -# CONFIG_MTD_MCHP23K256 is not set -# CONFIG_MTD_SST25L is not set -# CONFIG_MTD_SLRAM is not set -# CONFIG_MTD_PHRAM is not set -# CONFIG_MTD_MTDRAM is not set -# CONFIG_MTD_BLOCK2MTD is not set # # Disk-On-Chip Device Drivers # -# CONFIG_MTD_DOCG3 is not set -# CONFIG_MTD_NAND is not set -# CONFIG_MTD_ONENAND is not set +CONFIG_MTD_NAND=y +CONFIG_MTD_NAND_DENALI_DT=y # # LPDDR & LPDDR2 PCM memory drivers # -# CONFIG_MTD_LPDDR is not set CONFIG_MTD_SPI_NOR=y -# CONFIG_MTD_MT81xx_NOR is not set -CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y -# CONFIG_MTD_UBI 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_ADDRESS=y -CONFIG_OF_ADDRESS_PCI=y -CONFIG_OF_IRQ=y -CONFIG_OF_NET=y -CONFIG_OF_MDIO=y -CONFIG_OF_PCI=y -CONFIG_OF_PCI_IRQ=y -CONFIG_OF_RESERVED_MEM=y -# CONFIG_OF_OVERLAY is not set -# CONFIG_PARPORT is not set -CONFIG_PNP=y -CONFIG_PNP_DEBUG_MESSAGES=y # # Protocols # -CONFIG_PNPACPI=y -CONFIG_BLK_DEV=y -# CONFIG_BLK_DEV_NULL_BLK is not set -# CONFIG_BLK_DEV_PCIESSD_MTIP32XX is not set -# CONFIG_BLK_DEV_DAC960 is not set -# CONFIG_BLK_DEV_UMEM is not set -# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_CDROM=m 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=m -# CONFIG_BLK_DEV_SKD is not set -# CONFIG_BLK_DEV_SX8 is not set -# CONFIG_BLK_DEV_RAM is not set -# CONFIG_CDROM_PKTCDVD is not set -# CONFIG_ATA_OVER_ETH is not set -CONFIG_XEN_BLKDEV_FRONTEND=y -# CONFIG_XEN_BLKDEV_BACKEND is not set CONFIG_VIRTIO_BLK=y -# CONFIG_VIRTIO_BLK_SCSI is not set -# CONFIG_BLK_DEV_RBD is not set -# CONFIG_BLK_DEV_RSXX is not set -# CONFIG_BLK_DEV_NVME is not set -# CONFIG_NVME_FC is not set -# CONFIG_NVME_TARGET is not set + +# +# NVME Support +# +CONFIG_BLK_DEV_NVME=m # # Misc devices # -# CONFIG_SENSORS_LIS3LV02D is not set -# CONFIG_AD525X_DPOT is not set -# CONFIG_DUMMY_IRQ is not set -# CONFIG_PHANTOM is not set -# CONFIG_SGI_IOC4 is not set -# CONFIG_TIFM_CORE is not set -# CONFIG_ICS932S401 is not set -# CONFIG_ENCLOSURE_SERVICES is not set -# CONFIG_HP_ILO is not set -# CONFIG_APDS9802ALS is not set -# CONFIG_ISL29003 is not set -# CONFIG_ISL29020 is not set -# CONFIG_SENSORS_TSL2550 is not set -# CONFIG_SENSORS_BH1770 is not set -# CONFIG_SENSORS_APDS990X is not set -# CONFIG_HMC6352 is not set -# CONFIG_DS1682 is not set -# CONFIG_TI_DAC7512 is not set -# CONFIG_USB_SWITCH_FSA9480 is not set -# CONFIG_LATTICE_ECP3_CONFIG is not set CONFIG_SRAM=y CONFIG_VEXPRESS_SYSCFG=y -# CONFIG_PCI_ENDPOINT_TEST is not set -# CONFIG_C2PORT is not set # # EEPROM support # -# CONFIG_EEPROM_AT24 is not set CONFIG_EEPROM_AT25=m -# CONFIG_EEPROM_LEGACY is not set -# CONFIG_EEPROM_MAX6875 is not set -# CONFIG_EEPROM_93CX6 is not set -# CONFIG_EEPROM_93XX46 is not set -# CONFIG_EEPROM_IDT_89HPESX is not set -# CONFIG_CB710_CORE is not set # # Texas Instruments shared transport line discipline # -# CONFIG_TI_ST is not set -# CONFIG_SENSORS_LIS3_I2C is not set # -# Altera FPGA firmware download module +# Intel MIC & related support # -# CONFIG_ALTERA_STAPL is not set # # Intel MIC Bus Driver @@ -1294,127 +982,142 @@ CONFIG_EEPROM_AT25=m # # VOP Driver # -# CONFIG_GENWQE is not set -# CONFIG_ECHO is not set -# CONFIG_CXL_BASE is not set -# CONFIG_CXL_AFU_DRIVER_OPS is not set -# CONFIG_CXL_LIB 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_NETLINK=y # CONFIG_SCSI_PROC_FS is not set # # SCSI support type (disk, tape, CD-ROM) # CONFIG_BLK_DEV_SD=y -# CONFIG_CHR_DEV_ST is not set -# CONFIG_CHR_DEV_OSST is not set -# CONFIG_BLK_DEV_SR 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 +CONFIG_BLK_DEV_SR=m +CONFIG_BLK_DEV_SR_VENDOR=y +CONFIG_CHR_DEV_SG=m # # SCSI Transports # -# CONFIG_SCSI_SPI_ATTRS is not set -# CONFIG_SCSI_FC_ATTRS is not set -# CONFIG_SCSI_ISCSI_ATTRS is not set +CONFIG_SCSI_FC_ATTRS=m +CONFIG_SCSI_ISCSI_ATTRS=m CONFIG_SCSI_SAS_ATTRS=y CONFIG_SCSI_SAS_LIBSAS=y +CONFIG_SCSI_SAS_ATA=y CONFIG_SCSI_SAS_HOST_SMP=y -# CONFIG_SCSI_SRP_ATTRS is not set -CONFIG_SCSI_LOWLEVEL=y -# CONFIG_ISCSI_TCP is not set -# CONFIG_ISCSI_BOOT_SYSFS is not set -# CONFIG_SCSI_CXGB3_ISCSI is not set -# CONFIG_SCSI_CXGB4_ISCSI is not set -# CONFIG_SCSI_BNX2_ISCSI is not set -# CONFIG_BE2ISCSI is not set -# CONFIG_BLK_DEV_3W_XXXX_RAID is not set -# CONFIG_SCSI_HPSA is not set -# CONFIG_SCSI_3W_9XXX is not set -# CONFIG_SCSI_3W_SAS is not set -# CONFIG_SCSI_ACARD is not set -# CONFIG_SCSI_AACRAID is not set -# CONFIG_SCSI_AIC7XXX is not set -# CONFIG_SCSI_AIC79XX is not set -# CONFIG_SCSI_AIC94XX is not set -# CONFIG_SCSI_MVSAS is not set -# CONFIG_SCSI_MVUMI is not set -# CONFIG_SCSI_ADVANSYS is not set -# CONFIG_SCSI_ARCMSR is not set -# CONFIG_SCSI_ESAS2R is not set -# CONFIG_MEGARAID_NEWGEN is not set -# CONFIG_MEGARAID_LEGACY is not set -# CONFIG_MEGARAID_SAS is not set -# CONFIG_SCSI_MPT3SAS is not set -# CONFIG_SCSI_MPT2SAS is not set -# CONFIG_SCSI_SMARTPQI is not set -# CONFIG_SCSI_UFSHCD is not set -# CONFIG_SCSI_HPTIOP is not set -# CONFIG_XEN_SCSI_FRONTEND is not set -# CONFIG_SCSI_SNIC is not set -# CONFIG_SCSI_DMX3191D is not set -# CONFIG_SCSI_FUTURE_DOMAIN is not set -# CONFIG_SCSI_IPS is not set -# CONFIG_SCSI_INITIO is not set -# CONFIG_SCSI_INIA100 is not set -# CONFIG_SCSI_STEX is not set -# CONFIG_SCSI_SYM53C8XX_2 is not set -# CONFIG_SCSI_QLOGIC_1280 is not set -# CONFIG_SCSI_QLA_ISCSI is not set -# CONFIG_SCSI_DC395x is not set -# CONFIG_SCSI_AM53C974 is not set -# CONFIG_SCSI_WD719X is not set -# CONFIG_SCSI_DEBUG is not set -# CONFIG_SCSI_PMCRAID is not set -# CONFIG_SCSI_PM8001 is not set -# CONFIG_SCSI_VIRTIO is not set -# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set -# CONFIG_SCSI_DH is not set -# CONFIG_SCSI_OSD_INITIATOR is not set -CONFIG_HAVE_PATA_PLATFORM=y -# CONFIG_ATA is not set -# CONFIG_MD is not set -# CONFIG_TARGET_CORE is not set -# CONFIG_FUSION is not set +CONFIG_ISCSI_TCP=m +CONFIG_ISCSI_BOOT_SYSFS=m +# CONFIG_SCSI_BNX2X_FCOE is not set +# CONFIG_SCSI_HISI_SAS is not set +CONFIG_LIBFC=m +CONFIG_LIBFCOE=m +# CONFIG_FCOE is not set +# CONFIG_SCSI_QLA_FC is not set +# CONFIG_SCSI_LPFC is not set +# CONFIG_SCSI_BFA_FC is not set +# CONFIG_SCSI_CHELSIO_FCOE is not set +CONFIG_ATA=y + +# +# Controllers with non-SFF native interface +# +CONFIG_SATA_AHCI=y +CONFIG_SATA_AHCI_PLATFORM=y +CONFIG_AHCI_CEVA=y +# CONFIG_AHCI_QORIQ is not set +CONFIG_SATA_SIL24=y + +# +# SFF controllers with custom DMA interface +# + +# +# SATA SFF controllers with BMDMA +# + +# +# PATA SFF controllers with BMDMA +# + +# +# PIO-only SFF controllers +# +CONFIG_PATA_PLATFORM=y +CONFIG_PATA_OF_PLATFORM=y + +# +# Generic fallback / legacy drivers +# +CONFIG_MD=y +CONFIG_BLK_DEV_MD=m +CONFIG_MD_LINEAR=m +CONFIG_MD_RAID0=m +CONFIG_MD_RAID1=m +CONFIG_MD_RAID10=m +CONFIG_MD_RAID456=m +CONFIG_MD_MULTIPATH=m +CONFIG_MD_FAULTY=m +CONFIG_BCACHE=m +# CONFIG_BCACHE_DEBUG is not set +# CONFIG_BCACHE_CLOSURES_DEBUG is not set +CONFIG_BLK_DEV_DM_BUILTIN=y +CONFIG_BLK_DEV_DM=m +# CONFIG_DM_MQ_DEFAULT is not set +# CONFIG_DM_DEBUG is not set +CONFIG_DM_BUFIO=m +# CONFIG_DM_DEBUG_BLOCK_MANAGER_LOCKING is not set +CONFIG_DM_BIO_PRISON=m +CONFIG_DM_PERSISTENT_DATA=m +# CONFIG_DM_UNSTRIPED is not set +CONFIG_DM_CRYPT=m +CONFIG_DM_SNAPSHOT=m +CONFIG_DM_THIN_PROVISIONING=m +CONFIG_DM_CACHE=m +CONFIG_DM_CACHE_SMQ=m +# CONFIG_DM_ERA is not set +CONFIG_DM_MIRROR=m +CONFIG_DM_LOG_USERSPACE=m +CONFIG_DM_RAID=m +CONFIG_DM_ZERO=m +CONFIG_DM_MULTIPATH=m +CONFIG_DM_MULTIPATH_QL=m +CONFIG_DM_MULTIPATH_ST=m +CONFIG_DM_DELAY=m +CONFIG_DM_UEVENT=y +CONFIG_DM_FLAKEY=m +CONFIG_DM_VERITY=m +# CONFIG_DM_VERITY_FEC is not set +CONFIG_DM_SWITCH=m +# CONFIG_DM_LOG_WRITES is not set +# CONFIG_DM_INTEGRITY is not set # # IEEE 1394 (FireWire) support # -# CONFIG_FIREWIRE is not set -# CONFIG_FIREWIRE_NOSY is not set CONFIG_NETDEVICES=y -CONFIG_MII=m -CONFIG_NET_CORE=y -# CONFIG_BONDING is not set -# CONFIG_DUMMY is not set -# CONFIG_EQUALIZER is not set -# CONFIG_NET_FC is not set -# CONFIG_NET_TEAM is not set -# CONFIG_MACVLAN is not set -# CONFIG_VXLAN is not set -# CONFIG_MACSEC is not set -# CONFIG_NETCONSOLE is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set -# CONFIG_TUN is not set -# CONFIG_TUN_VNET_CROSS_LE is not set -# CONFIG_VETH is not set -# CONFIG_VIRTIO_NET is not set -# CONFIG_NLMON is not set -# CONFIG_ARCNET is not set +CONFIG_BONDING=m +CONFIG_DUMMY=m +# CONFIG_IFB is not set +CONFIG_NET_TEAM=m +CONFIG_NET_TEAM_MODE_BROADCAST=m +CONFIG_NET_TEAM_MODE_ROUNDROBIN=m +CONFIG_NET_TEAM_MODE_RANDOM=m +CONFIG_NET_TEAM_MODE_ACTIVEBACKUP=m +CONFIG_NET_TEAM_MODE_LOADBALANCE=m +CONFIG_MACVLAN=m +CONFIG_MACVTAP=m +CONFIG_VXLAN=m +# CONFIG_GENEVE is not set +# CONFIG_GTP is not set +CONFIG_NETCONSOLE=y +CONFIG_NETCONSOLE_DYNAMIC=y +CONFIG_NETPOLL=y +CONFIG_NET_POLL_CONTROLLER=y +CONFIG_TUN=y +CONFIG_VETH=m +CONFIG_VIRTIO_NET=y +CONFIG_NLMON=m # # CAIF transport drivers @@ -1423,473 +1126,319 @@ CONFIG_NET_CORE=y # # Distributed Switch Architecture drivers # -CONFIG_ETHERNET=y -# CONFIG_NET_VENDOR_3COM is not set -# CONFIG_NET_VENDOR_ADAPTEC is not set -# CONFIG_NET_VENDOR_AGERE is not set -# CONFIG_NET_VENDOR_ALACRITECH is not set -# CONFIG_NET_VENDOR_ALTEON is not set -# CONFIG_ALTERA_TSE is not set -# CONFIG_NET_VENDOR_AMAZON is not set -# CONFIG_NET_VENDOR_AMD is not set -# CONFIG_NET_VENDOR_AQUANTIA is not set -# CONFIG_NET_VENDOR_ARC is not set -# CONFIG_NET_VENDOR_ATHEROS is not set -# CONFIG_NET_VENDOR_AURORA is not set -# CONFIG_NET_CADENCE is not set -# CONFIG_NET_VENDOR_BROADCOM is not set -# CONFIG_NET_VENDOR_BROCADE is not set -# CONFIG_NET_VENDOR_CAVIUM is not set -# CONFIG_NET_VENDOR_CHELSIO is not set -# CONFIG_NET_VENDOR_CISCO is not set -# CONFIG_DNET is not set -# CONFIG_NET_VENDOR_DEC is not set -# CONFIG_NET_VENDOR_DLINK is not set -# CONFIG_NET_VENDOR_EMULEX is not set -# CONFIG_NET_VENDOR_EZCHIP is not set -# CONFIG_NET_VENDOR_EXAR is not set -# CONFIG_NET_VENDOR_HISILICON is not set -# CONFIG_NET_VENDOR_HP is not set -# CONFIG_NET_VENDOR_HUAWEI is not set -# CONFIG_NET_VENDOR_INTEL is not set -# CONFIG_JME 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_MYRI is not set -# CONFIG_FEALNX is not set -# CONFIG_NET_VENDOR_NATSEMI is not set -# CONFIG_NET_VENDOR_NETRONOME is not set -# CONFIG_NET_VENDOR_NVIDIA is not set -# CONFIG_NET_VENDOR_OKI is not set -# CONFIG_ETHOC is not set -# CONFIG_NET_PACKET_ENGINE is not set -# CONFIG_NET_VENDOR_QLOGIC is not set -# CONFIG_NET_VENDOR_QUALCOMM is not set -# CONFIG_NET_VENDOR_REALTEK is not set -# CONFIG_NET_VENDOR_RENESAS is not set -# CONFIG_NET_VENDOR_RDC 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_SILAN is not set -# CONFIG_NET_VENDOR_SIS is not set -# CONFIG_NET_VENDOR_SOLARFLARE is not set -# CONFIG_NET_VENDOR_SMSC is not set -CONFIG_NET_VENDOR_STMICRO=y +CONFIG_AMD_XGBE=y +CONFIG_MACB=y +# CONFIG_THUNDER_NIC_PF is not set +# CONFIG_THUNDER_NIC_BGX is not set +# CONFIG_THUNDER_NIC_RGX is not set +CONFIG_HNS_DSAF=y +CONFIG_HNS_ENET=y +CONFIG_E1000E=y +CONFIG_IGB=y +CONFIG_IGBVF=y +# CONFIG_MVMDIO is not set +CONFIG_SKY2=y +# CONFIG_QCOM_EMAC is not set +CONFIG_SMC91X=y +CONFIG_SMSC911X=y CONFIG_STMMAC_ETH=m -CONFIG_STMMAC_PLATFORM=m -# CONFIG_DWMAC_DWC_QOS_ETH is not set -CONFIG_DWMAC_GENERIC=m -CONFIG_DWMAC_MESON=m -# CONFIG_STMMAC_PCI is not set -# CONFIG_NET_VENDOR_SUN is not set -# CONFIG_NET_VENDOR_TEHUTI is not set -# CONFIG_NET_VENDOR_TI is not set -# CONFIG_NET_VENDOR_VIA is not set -# CONFIG_NET_VENDOR_WIZNET is not set -# CONFIG_NET_VENDOR_SYNOPSYS is not set -# CONFIG_FDDI is not set -# CONFIG_HIPPI is not set -# CONFIG_NET_SB1000 is not set -CONFIG_MDIO_DEVICE=y -CONFIG_MDIO_BUS=y -# CONFIG_MDIO_BCM_UNIMAC is not set -# CONFIG_MDIO_BITBANG is not set -# CONFIG_MDIO_BUS_MUX_GPIO is not set -# CONFIG_MDIO_BUS_MUX_MMIOREG is not set -# CONFIG_MDIO_HISI_FEMAC is not set -# CONFIG_MDIO_OCTEON is not set +CONFIG_MDIO_BITBANG=y +CONFIG_MDIO_BUS_MUX_MMIOREG=y +# CONFIG_MDIO_GPIO is not set # CONFIG_MDIO_THUNDER is not set -CONFIG_PHYLIB=y -CONFIG_SWPHY=y -# CONFIG_LED_TRIGGER_PHY is not set # # MII PHY device drivers # -# CONFIG_AMD_PHY is not set -# CONFIG_AQUANTIA_PHY is not set -# CONFIG_AT803X_PHY is not set -# CONFIG_BCM7XXX_PHY is not set -# CONFIG_BCM87XX_PHY is not set -# CONFIG_BROADCOM_PHY is not set -# CONFIG_CICADA_PHY is not set -# CONFIG_CORTINA_PHY is not set -# CONFIG_DAVICOM_PHY is not set -# CONFIG_DP83848_PHY is not set -# CONFIG_DP83867_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_MESON_GXL_PHY=m +CONFIG_AT803X_PHY=m +CONFIG_MARVELL_PHY=m +CONFIG_MARVELL_10G_PHY=m +CONFIG_MESON_GXL_PHY=y CONFIG_MICREL_PHY=y -# CONFIG_MICROCHIP_PHY is not set -# CONFIG_MICROSEMI_PHY is not set -# CONFIG_NATIONAL_PHY is not set -# CONFIG_QSEMI_PHY is not set -CONFIG_REALTEK_PHY=m +CONFIG_MICROCHIP_PHY=m +CONFIG_REALTEK_PHY=y # CONFIG_ROCKCHIP_PHY is not set -# CONFIG_SMSC_PHY is not set -# CONFIG_STE10XP is not set -# CONFIG_TERANETICS_PHY is not set -# CONFIG_VITESSE_PHY is not set -# CONFIG_XILINX_GMII2RGMII is not set -# CONFIG_MICREL_KS8995MA is not set -# CONFIG_PPP is not set -# CONFIG_SLIP is not set -# CONFIG_USB_NET_DRIVERS is not set -CONFIG_WLAN=y -CONFIG_WLAN_VENDOR_ADMTEK=y -# CONFIG_ADM8211 is not set -CONFIG_WLAN_VENDOR_ATH=y -# CONFIG_ATH_DEBUG is not set -# CONFIG_ATH5K is not set -# CONFIG_ATH5K_PCI is not set -# CONFIG_ATH9K is not set -# CONFIG_ATH9K_HTC is not set -# CONFIG_CARL9170 is not set -# CONFIG_ATH6KL is not set -# CONFIG_AR5523 is not set -# CONFIG_WIL6210 is not set -# CONFIG_ATH10K is not set -# CONFIG_WCN36XX is not set -CONFIG_WLAN_VENDOR_ATMEL=y -# CONFIG_ATMEL is not set -# CONFIG_AT76C50X_USB is not set -CONFIG_WLAN_VENDOR_BROADCOM=y -# CONFIG_B43 is not set -# CONFIG_B43LEGACY is not set -CONFIG_BRCMUTIL=m -# CONFIG_BRCMSMAC 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_PPPOE=m +CONFIG_PPPOL2TP=m +CONFIG_PPP_ASYNC=m +CONFIG_PPP_SYNC_TTY=m +CONFIG_SLHC=m +CONFIG_USB_CATC=m +CONFIG_USB_KAWETH=m +CONFIG_USB_PEGASUS=m +CONFIG_USB_RTL8150=m +CONFIG_USB_RTL8152=m +CONFIG_USB_LAN78XX=m +CONFIG_USB_USBNET=m +CONFIG_USB_NET_CDC_EEM=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_PLUSB=m +CONFIG_USB_NET_MCS7830=m +CONFIG_USB_NET_RNDIS_HOST=m +CONFIG_USB_ALI_M5632=y +CONFIG_USB_AN2720=y +CONFIG_USB_EPSON2888=y +CONFIG_USB_KC2190=y +CONFIG_USB_NET_CX82310_ETH=m +CONFIG_USB_NET_KALMIA=m +CONFIG_USB_NET_QMI_WWAN=m +CONFIG_USB_HSO=m +CONFIG_USB_NET_INT51X1=m +CONFIG_USB_CDC_PHONET=m +CONFIG_USB_IPHETH=m +CONFIG_USB_SIERRA_NET=m +CONFIG_USB_VL600=m +CONFIG_USB_NET_CH9200=m +CONFIG_ATH_COMMON=m +CONFIG_ATH9K_HW=m +CONFIG_ATH9K_COMMON=m +CONFIG_ATH9K_BTCOEX_SUPPORT=y +CONFIG_ATH9K_HTC=m +# CONFIG_ATH9K_HTC_DEBUGFS is not set +CONFIG_CARL9170=m +CONFIG_CARL9170_LEDS=y +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_BRCMFMAC=m -CONFIG_BRCMFMAC_PROTO_BCDC=y -CONFIG_BRCMFMAC_SDIO=y -# CONFIG_BRCMFMAC_USB is not set -# CONFIG_BRCMFMAC_PCIE 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_IPW2100 is not set -# CONFIG_IPW2200 is not set -# CONFIG_IWL4965 is not set -# CONFIG_IWL3945 is not set -# CONFIG_IWLWIFI is not set -CONFIG_WLAN_VENDOR_INTERSIL=y -# CONFIG_HOSTAP is not set -# CONFIG_HERMES is not set -# CONFIG_P54_COMMON is not set -# CONFIG_PRISM54 is not set -CONFIG_WLAN_VENDOR_MARVELL=y -# CONFIG_LIBERTAS is not set -# CONFIG_LIBERTAS_THINFIRM is not set -# CONFIG_MWIFIEX is not set -# CONFIG_MWL8K is not set -CONFIG_WLAN_VENDOR_MEDIATEK=y -# CONFIG_MT7601U is not set -CONFIG_WLAN_VENDOR_RALINK=y -# CONFIG_RT2X00 is not set -CONFIG_WLAN_VENDOR_REALTEK=y -# CONFIG_RTL8180 is not set -# CONFIG_RTL8187 is not set -CONFIG_RTL_CARDS=m -# CONFIG_RTL8192CE is not set -# CONFIG_RTL8192SE is not set -# CONFIG_RTL8192DE is not set -# CONFIG_RTL8723AE is not set -# CONFIG_RTL8723BE is not set -# CONFIG_RTL8188EE is not set -# CONFIG_RTL8192EE is not set -# CONFIG_RTL8821AE is not set -# CONFIG_RTL8192CU is not set -# CONFIG_RTL8XXXU is not set -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_RT2X00=m +# CONFIG_RT2400PCI is not set +# CONFIG_RT2500PCI is not set +# CONFIG_RT61PCI is not set +# CONFIG_RT2800PCI is not set +CONFIG_RT2500USB=m +CONFIG_RT73USB=m +CONFIG_RT2800USB=m +CONFIG_RT2800USB_RT33XX=y +CONFIG_RT2800USB_RT35XX=y +CONFIG_RT2800USB_RT3573=y +CONFIG_RT2800USB_RT53XX=y +CONFIG_RT2800USB_RT55XX=y +CONFIG_RT2800USB_UNKNOWN=y +CONFIG_RT2800_LIB=m +CONFIG_RT2X00_LIB_USB=m +CONFIG_RT2X00_LIB=m +CONFIG_RT2X00_LIB_FIRMWARE=y +CONFIG_RT2X00_LIB_CRYPTO=y +CONFIG_RT2X00_LIB_LEDS=y +# CONFIG_RT2X00_DEBUG is not set CONFIG_WL18XX=m -CONFIG_WLCORE=m -# CONFIG_WLCORE_SPI is not set CONFIG_WLCORE_SDIO=m -CONFIG_WILINK_PLATFORM_DATA=y -CONFIG_WLAN_VENDOR_ZYDAS=y -# CONFIG_USB_ZD1201 is not set -# CONFIG_ZD1211RW is not set -CONFIG_WLAN_VENDOR_QUANTENNA=y -# CONFIG_QTNFMAC_PEARL_PCIE is not set -# CONFIG_MAC80211_HWSIM is not set -# CONFIG_USB_NET_RNDIS_WLAN is not set +CONFIG_USB_NET_RNDIS_WLAN=m # # Enable WiMAX (Networking options) to see the WiMAX drivers # -# CONFIG_WAN is not set -# CONFIG_XEN_NETDEV_FRONTEND is not set -# CONFIG_XEN_NETDEV_BACKEND is not set -# CONFIG_VMXNET3 is not set -# CONFIG_FUJITSU_ES 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 is not set -# CONFIG_INPUT_POLLDEV is not set -# CONFIG_INPUT_SPARSEKMAP is not set -# CONFIG_INPUT_MATRIXKMAP is not set +CONFIG_INPUT_FF_MEMLESS=m # # Userland interfaces # -CONFIG_INPUT_MOUSEDEV=y -CONFIG_INPUT_MOUSEDEV_PSAUX=y -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -# CONFIG_INPUT_JOYDEV is not set 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_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_ADC=m CONFIG_KEYBOARD_GPIO=y -# CONFIG_KEYBOARD_GPIO_POLLED is not set -# CONFIG_KEYBOARD_TCA6416 is not set -# CONFIG_KEYBOARD_TCA8418 is not set -# CONFIG_KEYBOARD_MATRIX is not set -# CONFIG_KEYBOARD_LM8323 is not set -# CONFIG_KEYBOARD_LM8333 is not set -# CONFIG_KEYBOARD_MAX7359 is not set -# CONFIG_KEYBOARD_MCS is not set -# CONFIG_KEYBOARD_MPR121 is not set -# CONFIG_KEYBOARD_NEWTON is not set -# CONFIG_KEYBOARD_OPENCORES is not set -# CONFIG_KEYBOARD_SAMSUNG is not set -# CONFIG_KEYBOARD_STOWAWAY is not set -# CONFIG_KEYBOARD_SUNKBD is not set -# CONFIG_KEYBOARD_OMAP4 is not set -# CONFIG_KEYBOARD_TM2_TOUCHKEY is not set -# 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=y -CONFIG_MOUSE_PS2_ALPS=y -CONFIG_MOUSE_PS2_BYD=y -CONFIG_MOUSE_PS2_LOGIPS2PP=y -CONFIG_MOUSE_PS2_SYNAPTICS=y -CONFIG_MOUSE_PS2_SYNAPTICS_SMBUS=y -CONFIG_MOUSE_PS2_CYPRESS=y -CONFIG_MOUSE_PS2_TRACKPOINT=y -# CONFIG_MOUSE_PS2_ELANTECH is not set -# CONFIG_MOUSE_PS2_SENTELIC is not set -# CONFIG_MOUSE_PS2_TOUCHKIT is not set -CONFIG_MOUSE_PS2_FOCALTECH=y -CONFIG_MOUSE_PS2_SMBUS=y -# CONFIG_MOUSE_SERIAL is not set -# CONFIG_MOUSE_APPLETOUCH is not set -# CONFIG_MOUSE_BCM5974 is not set -# CONFIG_MOUSE_CYAPA is not set -# CONFIG_MOUSE_ELAN_I2C is not set -# CONFIG_MOUSE_VSXXXAA is not set -# CONFIG_MOUSE_GPIO is not set -# CONFIG_MOUSE_SYNAPTICS_I2C is not set -# CONFIG_MOUSE_SYNAPTICS_USB is not set -# CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_TABLET is not set -# CONFIG_INPUT_TOUCHSCREEN is not set +CONFIG_KEYBOARD_CROS_EC=y +CONFIG_MOUSE_APPLETOUCH=m +CONFIG_MOUSE_BCM5974=m +CONFIG_MOUSE_SYNAPTICS_USB=m +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=m +CONFIG_JOYSTICK_IFORCE_USB=y +CONFIG_JOYSTICK_IFORCE_232=y +# CONFIG_JOYSTICK_WARRIOR is not set +# CONFIG_JOYSTICK_MAGELLAN is not set +# CONFIG_JOYSTICK_SPACEORB is not set +# CONFIG_JOYSTICK_SPACEBALL is not set +# CONFIG_JOYSTICK_STINGER is not set +# CONFIG_JOYSTICK_TWIDJOY is not set +# CONFIG_JOYSTICK_ZHENHUA is not set +# CONFIG_JOYSTICK_AS5011 is not set +# CONFIG_JOYSTICK_JOYDUMP is not set +CONFIG_JOYSTICK_XPAD=m +CONFIG_JOYSTICK_XPAD_FF=y +CONFIG_JOYSTICK_XPAD_LEDS=y +# CONFIG_JOYSTICK_PSXPAD_SPI is not set +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_PROPERTIES=y +# CONFIG_TOUCHSCREEN_ADS7846 is not set +# CONFIG_TOUCHSCREEN_AD7877 is not set +# CONFIG_TOUCHSCREEN_AD7879 is not set +# CONFIG_TOUCHSCREEN_AR1021_I2C is not set +# CONFIG_TOUCHSCREEN_ATMEL_MXT is not set +# CONFIG_TOUCHSCREEN_AUO_PIXCIR is not set +# CONFIG_TOUCHSCREEN_BU21013 is not set +# 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 is not set +# 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=m +CONFIG_TOUCHSCREEN_USB_EGALAX=y +CONFIG_TOUCHSCREEN_USB_PANJIT=y +CONFIG_TOUCHSCREEN_USB_3M=y +CONFIG_TOUCHSCREEN_USB_ITM=y +CONFIG_TOUCHSCREEN_USB_ETURBO=y +CONFIG_TOUCHSCREEN_USB_GUNZE=y +CONFIG_TOUCHSCREEN_USB_DMC_TSC10=y +CONFIG_TOUCHSCREEN_USB_IRTOUCH=y +CONFIG_TOUCHSCREEN_USB_IDEALTEK=y +CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH=y +CONFIG_TOUCHSCREEN_USB_GOTOP=y +CONFIG_TOUCHSCREEN_USB_JASTEC=y +CONFIG_TOUCHSCREEN_USB_ELO=y +CONFIG_TOUCHSCREEN_USB_E2I=y +CONFIG_TOUCHSCREEN_USB_ZYTRONIC=y +CONFIG_TOUCHSCREEN_USB_ETT_TC45USB=y +CONFIG_TOUCHSCREEN_USB_NEXIO=y +CONFIG_TOUCHSCREEN_USB_EASYTOUCH=y +# CONFIG_TOUCHSCREEN_TOUCHIT213 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 is not set +# CONFIG_TOUCHSCREEN_ZFORCE is not set +# CONFIG_TOUCHSCREEN_ROHM_BU21023 is not set +CONFIG_TOUCHSCREEN_DWAV_USB_MT=m +CONFIG_TOUCHSCREEN_SX865X=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_MMA8450 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_GPIO_DECODER 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 is not set -# 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_XEN_KBDDEV_FRONTEND=y -# 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 -# CONFIG_RMI4_CORE is not set # # Hardware I/O ports # -CONFIG_SERIO=y -# CONFIG_SERIO_SERPORT is not set +CONFIG_SERIO_SERPORT=m CONFIG_SERIO_AMBAKMI=y -# CONFIG_SERIO_PCIPS2 is not set -CONFIG_SERIO_LIBPS2=y -# CONFIG_SERIO_RAW is not set -# CONFIG_SERIO_ALTERA_PS2 is not set -# CONFIG_SERIO_PS2MULT is not set -# CONFIG_SERIO_ARC_PS2 is not set -# CONFIG_SERIO_APBPS2 is not set -# CONFIG_SERIO_GPIO_PS2 is not set -# CONFIG_USERIO is not set -# CONFIG_GAMEPORT is not set +CONFIG_GAMEPORT=m +# CONFIG_GAMEPORT_NS558 is not set +# CONFIG_GAMEPORT_L4 is not set +# CONFIG_GAMEPORT_EMU10K1 is not set +# CONFIG_GAMEPORT_FM801 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_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=16 -# CONFIG_SERIAL_NONSTANDARD is not set -# CONFIG_NOZOMI is not set -# CONFIG_N_GSM is not set -# CONFIG_TRACE_SINK is not set -CONFIG_DEVMEM=y # # Serial drivers # -CONFIG_SERIAL_EARLYCON=y CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=y -CONFIG_SERIAL_8250_PNP=y -# CONFIG_SERIAL_8250_FINTEK is not set CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_DMA=y -CONFIG_SERIAL_8250_PCI=y -CONFIG_SERIAL_8250_EXAR=y -CONFIG_SERIAL_8250_NR_UARTS=4 -CONFIG_SERIAL_8250_RUNTIME_UARTS=4 CONFIG_SERIAL_8250_EXTENDED=y -# CONFIG_SERIAL_8250_MANY_PORTS is not set -# CONFIG_SERIAL_8250_ASPEED_VUART is not set CONFIG_SERIAL_8250_SHARE_IRQ=y -# CONFIG_SERIAL_8250_DETECT_IRQ is not set -# CONFIG_SERIAL_8250_RSA is not set -CONFIG_SERIAL_8250_FSL=y CONFIG_SERIAL_8250_DW=y -# CONFIG_SERIAL_8250_RT288X is not set -# CONFIG_SERIAL_8250_MOXA is not set CONFIG_SERIAL_OF_PLATFORM=y # # Non-8250 serial port support # -# CONFIG_SERIAL_AMBA_PL010 is not set CONFIG_SERIAL_AMBA_PL011=y CONFIG_SERIAL_AMBA_PL011_CONSOLE=y -# CONFIG_SERIAL_EARLYCON_ARM_SEMIHOST is not set +# CONFIG_SERIAL_KGDB_NMI is not set CONFIG_SERIAL_MESON=y CONFIG_SERIAL_MESON_CONSOLE=y -# CONFIG_SERIAL_MAX3100 is not set -# CONFIG_SERIAL_MAX310X is not set -# CONFIG_SERIAL_UARTLITE is not set -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -# CONFIG_SERIAL_JSM is not set -# CONFIG_SERIAL_SCCNXP is not set -# CONFIG_SERIAL_SC16IS7XX is not set -# CONFIG_SERIAL_ALTERA_JTAGUART is not set -# CONFIG_SERIAL_ALTERA_UART is not set -# CONFIG_SERIAL_IFX6X60 is not set +CONFIG_CONSOLE_POLL=y CONFIG_SERIAL_XILINX_PS_UART=y CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=y -# CONFIG_SERIAL_ARC is not set -# CONFIG_SERIAL_RP2 is not set -# CONFIG_SERIAL_FSL_LPUART is not set -# CONFIG_SERIAL_CONEXANT_DIGICOLOR is not set -# CONFIG_SERIAL_DEV_BUS is not set -CONFIG_HVC_DRIVER=y -CONFIG_HVC_IRQ=y -CONFIG_HVC_XEN=y -CONFIG_HVC_XEN_FRONTEND=y -# CONFIG_HVC_DCC is not set +CONFIG_SERIAL_DEV_BUS=y +CONFIG_SERIAL_DEV_CTRL_TTYPORT=y CONFIG_VIRTIO_CONSOLE=y -# CONFIG_IPMI_HANDLER is not set -CONFIG_HW_RANDOM=m -# CONFIG_HW_RANDOM_TIMERIOMEM is not set -# CONFIG_HW_RANDOM_VIRTIO is not set -CONFIG_HW_RANDOM_MESON=m +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_MESON=y CONFIG_HW_RANDOM_CAVIUM=m -# CONFIG_R3964 is not set -# CONFIG_APPLICOM is not set # # PCMCIA character devices # -# CONFIG_RAW_DRIVER is not set -# CONFIG_HPET is not set -# CONFIG_TCG_TPM is not set -CONFIG_DEVPORT=y -# CONFIG_XILLYBUS is not set # # I2C support # CONFIG_I2C=y -CONFIG_ACPI_I2C_OPREGION=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_GPMUX is not set -# CONFIG_I2C_MUX_LTC4306 is not set -# CONFIG_I2C_MUX_PCA9541 is not set CONFIG_I2C_MUX_PCA954x=y -# CONFIG_I2C_MUX_PINCTRL is not set -# CONFIG_I2C_MUX_REG is not set -# CONFIG_I2C_DEMUX_PINCTRL is not set -# CONFIG_I2C_MUX_MLXCPLD is not set -CONFIG_I2C_HELPER_AUTO=y -CONFIG_I2C_ALGOBIT=m # # I2C Hardware Bus support @@ -1898,110 +1447,48 @@ CONFIG_I2C_ALGOBIT=m # # PC SMBus host controller drivers # -# CONFIG_I2C_ALI1535 is not set -# CONFIG_I2C_ALI1563 is not set -# CONFIG_I2C_ALI15X3 is not set -# CONFIG_I2C_AMD756 is not set -# CONFIG_I2C_AMD8111 is not set -# CONFIG_I2C_I801 is not set -# CONFIG_I2C_ISCH is not set -# CONFIG_I2C_PIIX4 is not set -# CONFIG_I2C_NFORCE2 is not set -# CONFIG_I2C_SIS5595 is not set -# CONFIG_I2C_SIS630 is not set -# CONFIG_I2C_SIS96X is not set -# CONFIG_I2C_VIA is not set -# CONFIG_I2C_VIAPRO is not set # # ACPI drivers # -# CONFIG_I2C_SCMI is not set # # I2C system bus drivers (mostly embedded / system-on-chip) # -# CONFIG_I2C_CADENCE is not set -# CONFIG_I2C_CBUS_GPIO is not set -CONFIG_I2C_DESIGNWARE_CORE=y CONFIG_I2C_DESIGNWARE_PLATFORM=y -# CONFIG_I2C_DESIGNWARE_SLAVE is not set -# CONFIG_I2C_DESIGNWARE_PCI is not set -# CONFIG_I2C_EMEV2 is not set -# CONFIG_I2C_GPIO is not set CONFIG_I2C_MESON=y -# 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_THUNDERX is not set -# CONFIG_I2C_XILINX is not set +# CONFIG_I2C_RK3X 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 +CONFIG_I2C_TINY_USB=m # # Other I2C/SMBus bus drivers # -# CONFIG_I2C_STUB is not set +CONFIG_I2C_CROS_EC_TUNNEL=y 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 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_AXI_SPI_ENGINE is not set -# CONFIG_SPI_BITBANG is not set -# CONFIG_SPI_CADENCE is not set -# CONFIG_SPI_DESIGNWARE is not set -# CONFIG_SPI_GPIO is not set -# CONFIG_SPI_FSL_SPI is not set -CONFIG_SPI_MESON_SPICC=m -CONFIG_SPI_MESON_SPIFC=m -# CONFIG_SPI_OC_TINY is not set +CONFIG_SPI_MESON_SPICC=y +CONFIG_SPI_MESON_SPIFC=y CONFIG_SPI_PL022=y -# CONFIG_SPI_PXA2XX is not set -# CONFIG_SPI_PXA2XX_PCI is not set # CONFIG_SPI_ROCKCHIP is not set -# CONFIG_SPI_SC18IS602 is not set -# CONFIG_SPI_THUNDERX is not set -# CONFIG_SPI_XCOMM is not set -# CONFIG_SPI_XILINX is not set -# CONFIG_SPI_ZYNQMP_GQSPI is not set # # SPI Protocol Masters # CONFIG_SPI_SPIDEV=m -# CONFIG_SPI_LOOPBACK_TEST is not set -# CONFIG_SPI_TLE62X0 is not set -# CONFIG_SPI_SLAVE is not set CONFIG_SPMI=y -# 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 is not set -# CONFIG_PPS_CLIENT_GPIO is not set # # PPS generators support @@ -2010,66 +1497,27 @@ CONFIG_PPS=y # # 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_GENERIC_PINCTRL_GROUPS=y -CONFIG_PINMUX=y -CONFIG_GENERIC_PINMUX_FUNCTIONS=y -CONFIG_PINCONF=y -CONFIG_GENERIC_PINCONF=y -# CONFIG_DEBUG_PINCTRL is not set -# CONFIG_PINCTRL_AMD is not set -# CONFIG_PINCTRL_MCP23S08 is not set -CONFIG_PINCTRL_MESON=y CONFIG_PINCTRL_SINGLE=y -# CONFIG_PINCTRL_SX150X is not set CONFIG_PINCTRL_MAX77620=y -# CONFIG_PINCTRL_RK805 is not set -CONFIG_GPIOLIB=y -CONFIG_OF_GPIO=y -CONFIG_GPIO_ACPI=y -CONFIG_GPIOLIB_IRQCHIP=y -# CONFIG_DEBUG_GPIO is not set 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_AMDPT is not set CONFIG_GPIO_DWAPB=y -# CONFIG_GPIO_EXAR is not set -# CONFIG_GPIO_FTGPIO010 is not set CONFIG_GPIO_GENERIC_PLATFORM=y -# CONFIG_GPIO_GRGPIO is not set -# CONFIG_GPIO_MOCKUP is not set CONFIG_GPIO_PL061=y -# CONFIG_GPIO_SYSCON is not set -CONFIG_GPIO_XGENE=y -# CONFIG_GPIO_XILINX is not set +# CONFIG_GPIO_XGENE 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=y CONFIG_GPIO_PCA953X_IRQ=y -# CONFIG_GPIO_PCF857X is not set -# CONFIG_GPIO_SX150X is not set -# CONFIG_GPIO_TPIC2810 is not set # # MFD GPIO expanders @@ -2079,212 +1527,42 @@ CONFIG_GPIO_MAX77620=y # # PCI GPIO expanders # -# CONFIG_GPIO_BT8XX is not set -# CONFIG_GPIO_PCI_IDIO_16 is not set -# CONFIG_GPIO_RDC321X is not set # # SPI GPIO expanders # -# CONFIG_GPIO_74X164 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 # # USB GPIO expanders # -# CONFIG_W1 is not set -# CONFIG_POWER_AVS 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 is not set -# CONFIG_POWER_RESET_LTC2952 is not set -# CONFIG_POWER_RESET_RESTART is not set +CONFIG_POWER_RESET_GPIO=y +CONFIG_POWER_RESET_GPIO_RESTART=y +CONFIG_POWER_RESET_RESTART=y CONFIG_POWER_RESET_VEXPRESS=y -CONFIG_POWER_RESET_XGENE=y +# CONFIG_POWER_RESET_XGENE is not set CONFIG_POWER_RESET_SYSCON=y -# CONFIG_POWER_RESET_SYSCON_POWEROFF is not set -# CONFIG_SYSCON_REBOOT_MODE 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_LEGO_EV3 is not set -# CONFIG_BATTERY_SBS is not set -# CONFIG_CHARGER_SBS is not set +CONFIG_POWER_RESET_SYSCON_POWEROFF=y +CONFIG_SYSCON_REBOOT_MODE=y CONFIG_BATTERY_BQ27XXX=y -CONFIG_BATTERY_BQ27XXX_I2C=y -# CONFIG_BATTERY_BQ27XXX_DT_UPDATES_NVM 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 is not set # CONFIG_CHARGER_MANAGER is not set -# CONFIG_CHARGER_LTC3651 is not set -# CONFIG_CHARGER_DETECTOR_MAX14656 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_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_ARM_SCPI=y -# 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_I5K_AMB 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 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_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_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=m -# 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_SHT3x is not set -# CONFIG_SENSORS_SHTC1 is not set -# CONFIG_SENSORS_SIS5595 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_STTS751 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=m -# 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_VEXPRESS is not set -# CONFIG_SENSORS_VIA686A is not set -# CONFIG_SENSORS_VT1211 is not set -# CONFIG_SENSORS_VT8231 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 # # ACPI drivers # -# CONFIG_SENSORS_ACPI_POWER is not set CONFIG_THERMAL=y CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0 CONFIG_THERMAL_HWMON=y CONFIG_THERMAL_OF=y -# CONFIG_THERMAL_WRITABLE_TRIPS is not set +CONFIG_THERMAL_WRITABLE_TRIPS=y CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y # CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set # CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set @@ -2295,7 +1573,8 @@ CONFIG_THERMAL_GOV_STEP_WISE=y # CONFIG_THERMAL_GOV_USER_SPACE is not set CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y CONFIG_CPU_THERMAL=y -# CONFIG_CLOCK_THERMAL is not set +CONFIG_CLOCK_THERMAL=y +CONFIG_DEVFREQ_THERMAL=y CONFIG_THERMAL_EMULATION=y # CONFIG_MAX77620_THERMAL is not set # CONFIG_QORIQ_THERMAL is not set @@ -2306,169 +1585,50 @@ CONFIG_THERMAL_EMULATION=y # CONFIG_QCOM_SPMI_TEMP_ALARM is not set # 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_SYSFS is not set # # Watchdog Device Drivers # -# CONFIG_SOFT_WATCHDOG is not set -# CONFIG_GPIO_WATCHDOG is not set -# CONFIG_WDAT_WDT is not set -# CONFIG_XILINX_WATCHDOG is not set -# CONFIG_ZIIRAVE_WATCHDOG is not set -# CONFIG_ARM_SP805_WATCHDOG is not set -# CONFIG_ARM_SBSA_WATCHDOG is not set -# CONFIG_CADENCE_WATCHDOG is not set -# CONFIG_DW_WATCHDOG is not set -# CONFIG_MAX63XX_WATCHDOG is not set -# CONFIG_MAX77620_WATCHDOG is not set -CONFIG_MESON_GXBB_WATCHDOG=m -CONFIG_MESON_WATCHDOG=m -# CONFIG_ALIM7101_WDT is not set -# CONFIG_I6300ESB_WDT is not set -# CONFIG_MEN_A21_WDT is not set -# CONFIG_XEN_WDT is not set +CONFIG_MESON_GXBB_WATCHDOG=y +CONFIG_MESON_WATCHDOG=y # # PCI-based Watchdog Cards # -# CONFIG_PCIPCWATCHDOG is not set -# CONFIG_WDTPCI is not set # # USB-based Watchdog Cards # -# CONFIG_USBPCWATCHDOG is not set # # Watchdog Pretimeout Governors # -# CONFIG_WATCHDOG_PRETIMEOUT_GOV is not set -CONFIG_SSB_POSSIBLE=y - -# -# Sonics Silicon Backplane -# -# 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_CROS_EC 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_LPC_ICH is not set -# CONFIG_LPC_SCH is not set -# CONFIG_MFD_JANZ_CMODIO is not set -# CONFIG_MFD_KEMPLD is not set -# CONFIG_MFD_88PM800 is not set -# CONFIG_MFD_88PM805 is not set -# CONFIG_MFD_88PM860X is not set -# CONFIG_MFD_MAX14577 is not set +CONFIG_MFD_CROS_EC=y +CONFIG_MFD_CROS_EC_I2C=y +CONFIG_MFD_CROS_EC_SPI=y +CONFIG_MFD_HI6421_PMIC=y CONFIG_MFD_MAX77620=y -# 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 is not set -# CONFIG_MFD_VIPERBOARD is not set -# CONFIG_MFD_RETU is not set -# CONFIG_MFD_PCF50633 is not set -# CONFIG_MFD_RDC321X is not set -# CONFIG_MFD_RTSX_PCI is not set -# CONFIG_MFD_RT5033 is not set -# CONFIG_MFD_RTSX_USB is not set -# CONFIG_MFD_RC5T583 is not set CONFIG_MFD_RK808=y -# CONFIG_MFD_RN5T618 is not set CONFIG_MFD_SEC_CORE=y -# CONFIG_MFD_SI476X_CORE is not set -# CONFIG_MFD_SM501 is not set -# CONFIG_MFD_SKY81452 is not set -# CONFIG_MFD_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_TPS68470 is not set -# CONFIG_MFD_TI_LP873X is not set -# CONFIG_MFD_TI_LP87565 is not set -# CONFIG_MFD_TPS65218 is not set -# CONFIG_MFD_TPS6586X is not set -# CONFIG_MFD_TPS65910 is not set -# CONFIG_MFD_TPS65912_I2C is not set -# CONFIG_MFD_TPS65912_SPI is not set -# CONFIG_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_VX855 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_VEXPRESS_SYSREG=y CONFIG_REGULATOR=y # CONFIG_REGULATOR_DEBUG is not set CONFIG_REGULATOR_FIXED_VOLTAGE=y -# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set +CONFIG_REGULATOR_VIRTUAL_CONSUMER=m # CONFIG_REGULATOR_USERSPACE_CONSUMER is not set # CONFIG_REGULATOR_ACT8865 is not set # 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 is not set +CONFIG_REGULATOR_FAN53555=y CONFIG_REGULATOR_GPIO=y +CONFIG_REGULATOR_HI6421V530=y # CONFIG_REGULATOR_ISL9305 is not set # CONFIG_REGULATOR_ISL6271A is not set # CONFIG_REGULATOR_LP3971 is not set @@ -2489,7 +1649,7 @@ CONFIG_REGULATOR_MAX77620=y # CONFIG_REGULATOR_PV88080 is not set # CONFIG_REGULATOR_PV88090 is not set CONFIG_REGULATOR_PWM=y -CONFIG_REGULATOR_QCOM_SPMI=y +# CONFIG_REGULATOR_QCOM_SPMI is not set CONFIG_REGULATOR_RK808=y # CONFIG_REGULATOR_S2MPA01 is not set CONFIG_REGULATOR_S2MPS11=y @@ -2502,44 +1662,455 @@ CONFIG_REGULATOR_S2MPS11=y # CONFIG_REGULATOR_TPS6524X is not set # CONFIG_REGULATOR_VCTRL is not set # CONFIG_REGULATOR_VEXPRESS is not set -CONFIG_CEC_CORE=m -CONFIG_CEC_NOTIFIER=y -# CONFIG_RC_CORE is not set -CONFIG_MEDIA_SUPPORT=m +CONFIG_CEC_CORE=y +CONFIG_RC_CORE=y +CONFIG_RC_MAP=m +CONFIG_LIRC=y +CONFIG_RC_DECODERS=y +CONFIG_IR_NEC_DECODER=m +CONFIG_IR_RC5_DECODER=m +CONFIG_IR_RC6_DECODER=m +CONFIG_IR_JVC_DECODER=m +CONFIG_IR_SONY_DECODER=m +CONFIG_IR_SANYO_DECODER=m +CONFIG_IR_SHARP_DECODER=m +CONFIG_IR_MCE_KBD_DECODER=m +CONFIG_IR_XMP_DECODER=m +CONFIG_RC_DEVICES=y +CONFIG_RC_ATI_REMOTE=m +CONFIG_IR_IMON=m +CONFIG_IR_MCEUSB=m +CONFIG_IR_MESON=y +CONFIG_IR_REDRAT3=m +# CONFIG_IR_SPI is not set +CONFIG_IR_STREAMZAP=m +CONFIG_IR_IGUANA=m +CONFIG_IR_TTUSBIR=m +# CONFIG_IR_GPIO_TX is not set +# CONFIG_IR_PWM_TX is not set +CONFIG_MEDIA_SUPPORT=y # # Multimedia core support # -# CONFIG_MEDIA_CAMERA_SUPPORT is not set -# CONFIG_MEDIA_ANALOG_TV_SUPPORT is not set -# CONFIG_MEDIA_DIGITAL_TV_SUPPORT is not set -# CONFIG_MEDIA_RADIO_SUPPORT is not set -# CONFIG_MEDIA_SDR_SUPPORT is not set +CONFIG_MEDIA_CAMERA_SUPPORT=y +CONFIG_MEDIA_ANALOG_TV_SUPPORT=y +CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y CONFIG_MEDIA_CEC_SUPPORT=y -# CONFIG_VIDEO_ADV_DEBUG is not set -# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set -# CONFIG_TTPCI_EEPROM is not set +CONFIG_MEDIA_CEC_RC=y +CONFIG_MEDIA_CONTROLLER=y +CONFIG_VIDEO_DEV=y +CONFIG_VIDEO_V4L2_SUBDEV_API=y +CONFIG_VIDEO_V4L2=y +CONFIG_VIDEO_TUNER=m +CONFIG_V4L2_MEM2MEM_DEV=y +CONFIG_V4L2_FWNODE=m +CONFIG_VIDEOBUF_GEN=m +CONFIG_VIDEOBUF_VMALLOC=m +CONFIG_VIDEOBUF_DVB=m +CONFIG_VIDEOBUF2_CORE=y +CONFIG_VIDEOBUF2_V4L2=y +CONFIG_VIDEOBUF2_MEMOPS=y +CONFIG_VIDEOBUF2_DMA_CONTIG=y +CONFIG_DVB_NET=y +CONFIG_TTPCI_EEPROM=m # # Media drivers # -# CONFIG_MEDIA_USB_SUPPORT is not set -# CONFIG_MEDIA_PCI_SUPPORT is not set +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 is not set +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 is not set +CONFIG_VIDEO_USBVISION=m +CONFIG_VIDEO_STK1160_COMMON=m +CONFIG_VIDEO_STK1160=m +CONFIG_VIDEO_GO7007=m +CONFIG_VIDEO_GO7007_USB=m +CONFIG_VIDEO_GO7007_LOADER=m +CONFIG_VIDEO_GO7007_USB_S2250_BOARD=m + +# +# Analog/digital TV USB devices +# +CONFIG_VIDEO_AU0828=m +CONFIG_VIDEO_AU0828_V4L2=y +# CONFIG_VIDEO_AU0828_RC 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_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_FRIIO=m +CONFIG_DVB_USB_AZ6027=m +CONFIG_DVB_USB_TECHNISAT_USB2=m +CONFIG_DVB_USB_V2=m +CONFIG_DVB_USB_AF9015=m +CONFIG_DVB_USB_AF9035=m +CONFIG_DVB_USB_ANYSEE=m +CONFIG_DVB_USB_AU6610=m +CONFIG_DVB_USB_AZ6007=m +CONFIG_DVB_USB_CE6230=m +CONFIG_DVB_USB_EC168=m +CONFIG_DVB_USB_GL861=m +CONFIG_DVB_USB_LME2510=m +CONFIG_DVB_USB_MXL111SF=m +CONFIG_DVB_USB_RTL28XXU=m +CONFIG_DVB_USB_DVBSKY=m +CONFIG_DVB_USB_ZD1301=m +CONFIG_DVB_TTUSB_BUDGET=m +CONFIG_DVB_TTUSB_DEC=m +CONFIG_SMS_USB_DRV=m +CONFIG_DVB_B2C2_FLEXCOP_USB=m +# CONFIG_DVB_B2C2_FLEXCOP_USB_DEBUG is not set +CONFIG_DVB_AS102=m + +# +# Webcam, TV (analog/digital) USB devices +# +CONFIG_VIDEO_EM28XX=m +CONFIG_VIDEO_EM28XX_V4L2=m +CONFIG_VIDEO_EM28XX_ALSA=m +CONFIG_VIDEO_EM28XX_DVB=m +CONFIG_VIDEO_EM28XX_RC=m + +# +# USB HDMI CEC adapters +# +CONFIG_USB_PULSE8_CEC=m +CONFIG_USB_RAINSHADOW_CEC=m +CONFIG_V4L_PLATFORM_DRIVERS=y +CONFIG_V4L_MEM2MEM_DRIVERS=y +CONFIG_VIDEO_AML_MESON_VDEC=y +CONFIG_VIDEO_MESON_VDEC=y CONFIG_CEC_PLATFORM_DRIVERS=y CONFIG_VIDEO_MESON_AO_CEC=m # # Supported MMC/SDIO adapters # -# CONFIG_CYPRESS_FIRMWARE is not set +CONFIG_MEDIA_COMMON_OPTIONS=y + +# +# common driver options +# +CONFIG_VIDEO_CX2341X=m +CONFIG_VIDEO_TVEEPROM=m +CONFIG_CYPRESS_FIRMWARE=m +CONFIG_DVB_B2C2_FLEXCOP=m +CONFIG_SMS_SIANO_MDTV=m +CONFIG_SMS_SIANO_RC=y # # Media ancillary drivers (tuners, sensors, i2c, spi, frontends) # # -# Customise DVB Frontends +# Audio decoders, processors and mixers # +CONFIG_VIDEO_MSP3400=m +CONFIG_VIDEO_CS53L32A=m +CONFIG_VIDEO_UDA1342=m +CONFIG_VIDEO_WM8775=m +CONFIG_VIDEO_SONY_BTF_MPX=m + +# +# RDS decoders +# + +# +# Video decoders +# +CONFIG_VIDEO_SAA711X=m +CONFIG_VIDEO_TVP5150=m +CONFIG_VIDEO_TW2804=m +CONFIG_VIDEO_TW9903=m +CONFIG_VIDEO_TW9906=m + +# +# Video and audio decoders +# +CONFIG_VIDEO_CX25840=m + +# +# Video encoders +# + +# +# Camera sensor devices +# +CONFIG_VIDEO_OV2640=m +CONFIG_VIDEO_OV7640=m +CONFIG_VIDEO_MT9V011=m + +# +# Flash devices +# + +# +# Video improvement chips +# + +# +# Audio/Video compression chips +# + +# +# SDR tuner chips +# + +# +# Miscellaneous helper chips +# + +# +# Sensors used on soc_camera driver +# +CONFIG_MEDIA_TUNER_TDA18250=m +CONFIG_MEDIA_TUNER_MT2060=m +CONFIG_MEDIA_TUNER_MT2063=m +CONFIG_MEDIA_TUNER_MT2266=m +CONFIG_MEDIA_TUNER_QT1010=m +CONFIG_MEDIA_TUNER_MXL5005S=m +CONFIG_MEDIA_TUNER_MXL5007T=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_TUA9001=m +CONFIG_MEDIA_TUNER_SI2157=m +CONFIG_MEDIA_TUNER_IT913X=m +CONFIG_MEDIA_TUNER_R820T=m +CONFIG_MEDIA_TUNER_QM1D1C0042=m + +# +# 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 +CONFIG_DVB_MN88472=m +CONFIG_DVB_MN88473=m + +# +# DVB-S (satellite) frontends +# +CONFIG_DVB_CX24123=m +CONFIG_DVB_MT312=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_TUNER_ITD1000=m +CONFIG_DVB_TUNER_CX24113=m +CONFIG_DVB_TDA826X=m +CONFIG_DVB_CX24116=m +CONFIG_DVB_CX24120=m +CONFIG_DVB_SI21XX=m +CONFIG_DVB_TS2020=m +CONFIG_DVB_DS3000=m +CONFIG_DVB_TDA10071=m + +# +# DVB-T (terrestrial) frontends +# +CONFIG_DVB_CX22700=m +CONFIG_DVB_CX22702=m +CONFIG_DVB_DRXD=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_TDA10048=m +CONFIG_DVB_AF9013=m +CONFIG_DVB_EC100=m +CONFIG_DVB_CXD2820R=m +CONFIG_DVB_RTL2830=m +CONFIG_DVB_RTL2832=m +CONFIG_DVB_SI2168=m +CONFIG_DVB_AS102_FE=m +CONFIG_DVB_ZD1301_DEMOD=m +CONFIG_DVB_GP8PSK_FE=m + +# +# DVB-C (cable) frontends +# +CONFIG_DVB_VES1820=m +CONFIG_DVB_TDA10023=m +CONFIG_DVB_STV0297=m + +# +# ATSC (North American/Korean Terrestrial/Cable DTV) frontends +# +CONFIG_DVB_NXT200X=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_LNBP21=m +CONFIG_DVB_LNBP22=m +CONFIG_DVB_ISL6421=m +CONFIG_DVB_ISL6423=m +CONFIG_DVB_A8293=m +CONFIG_DVB_SP2=m +CONFIG_DVB_LGS8GXX=m +CONFIG_DVB_ATBM8830=m +CONFIG_DVB_IX2505V=m +CONFIG_DVB_M88RS2000=m +CONFIG_DVB_AF9033=m # # Tools to develop new frontends @@ -2548,363 +2119,177 @@ CONFIG_VIDEO_MESON_AO_CEC=m # # Graphics support # -CONFIG_VGA_ARB=y -CONFIG_VGA_ARB_MAX_GPUS=16 -CONFIG_DRM=m -CONFIG_DRM_MIPI_DSI=y -# CONFIG_DRM_DP_AUX_CHARDEV is not set -# CONFIG_DRM_DEBUG_MM_SELFTEST is not set -CONFIG_DRM_KMS_HELPER=m +CONFIG_DRM=y +# CONFIG_DRM_DEBUG_MM is not set +CONFIG_DRM_KMS_HELPER=y CONFIG_DRM_KMS_FB_HELPER=y CONFIG_DRM_FBDEV_EMULATION=y -CONFIG_DRM_FBDEV_OVERALLOC=100 -# CONFIG_DRM_LOAD_EDID_FIRMWARE is not set -CONFIG_DRM_GEM_CMA_HELPER=y -CONFIG_DRM_KMS_CMA_HELPER=y +CONFIG_DRM_FBDEV_OVERALLOC=200 # # I2C encoder or helper chips # -CONFIG_DRM_I2C_CH7006=m -CONFIG_DRM_I2C_SIL164=m -# CONFIG_DRM_I2C_NXP_TDA998X is not set -# CONFIG_DRM_HDLCD is not set -# CONFIG_DRM_MALI_DISPLAY is not set -# CONFIG_DRM_RADEON is not set -# CONFIG_DRM_AMDGPU is not set +# CONFIG_DRM_I2C_CH7006 is not set +# CONFIG_DRM_I2C_SIL164 is not set # # ACP (Audio CoProcessor) Configuration # + +# +# AMD Library routines +# # CONFIG_DRM_NOUVEAU is not set -# CONFIG_DRM_VGEM is not set -# CONFIG_DRM_UDL is not set -# CONFIG_DRM_AST is not set -# CONFIG_DRM_MGAG200 is not set -# CONFIG_DRM_CIRRUS_QEMU is not set -# CONFIG_DRM_RCAR_DW_HDMI is not set -# CONFIG_DRM_QXL is not set -# CONFIG_DRM_BOCHS is not set -# CONFIG_DRM_VIRTIO_GPU is not set -CONFIG_DRM_PANEL=y # # Display Panels # -# CONFIG_DRM_PANEL_LVDS is not set CONFIG_DRM_PANEL_SIMPLE=m -# CONFIG_DRM_PANEL_INNOLUX_P079ZCA is not set -# CONFIG_DRM_PANEL_JDI_LT070ME05000 is not set -# CONFIG_DRM_PANEL_SAMSUNG_LD9040 is not set -# CONFIG_DRM_PANEL_LG_LG4573 is not set -# CONFIG_DRM_PANEL_PANASONIC_VVX10F034N00 is not set -# CONFIG_DRM_PANEL_SAMSUNG_S6E3HA2 is not set -# CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0 is not set -# CONFIG_DRM_PANEL_SHARP_LQ101R1SX01 is not set -# CONFIG_DRM_PANEL_SHARP_LS043T1LE01 is not set -# CONFIG_DRM_PANEL_SITRONIX_ST7789V is not set -CONFIG_DRM_BRIDGE=y -CONFIG_DRM_PANEL_BRIDGE=y # # Display Interface Bridges # -# CONFIG_DRM_ANALOGIX_ANX78XX is not set -# CONFIG_DRM_DUMB_VGA_DAC is not set -# CONFIG_DRM_LVDS_ENCODER 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_TOSHIBA_TC358767 is not set -# CONFIG_DRM_TI_TFP410 is not set CONFIG_DRM_I2C_ADV7511=m -CONFIG_DRM_I2C_ADV7533=y -CONFIG_DRM_DW_HDMI=m -# CONFIG_DRM_DW_HDMI_CEC is not set -# CONFIG_DRM_ARCPGU is not set +CONFIG_DRM_DW_HDMI=y +CONFIG_DRM_DW_HDMI_I2S_AUDIO=y +CONFIG_DRM_DW_HDMI_CEC=m # CONFIG_DRM_HISI_HIBMC is not set # CONFIG_DRM_HISI_KIRIN is not set -# CONFIG_DRM_MXSFB is not set -CONFIG_DRM_MESON=m -CONFIG_DRM_MESON_DW_HDMI=m -# CONFIG_DRM_TINYDRM is not set -# CONFIG_DRM_PL111 is not set -# CONFIG_DRM_LEGACY is not set -# CONFIG_DRM_LIB_RANDOM is not set +CONFIG_DRM_MESON=y +CONFIG_DRM_MESON_DW_HDMI=y +CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y # # Frame buffer Devices # CONFIG_FB=y -# CONFIG_FIRMWARE_EDID is not set -CONFIG_FB_CMDLINE=y -CONFIG_FB_NOTIFY=y -# CONFIG_FB_DDC is not set -# CONFIG_FB_BOOT_VESA_SUPPORT is not set -CONFIG_FB_CFB_FILLRECT=m -CONFIG_FB_CFB_COPYAREA=m -CONFIG_FB_CFB_IMAGEBLIT=m -# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set -CONFIG_FB_SYS_FILLRECT=m -CONFIG_FB_SYS_COPYAREA=m -CONFIG_FB_SYS_IMAGEBLIT=m -# CONFIG_FB_PROVIDE_GET_FB_UNMAPPED_AREA is not set -# CONFIG_FB_FOREIGN_ENDIAN is not set -CONFIG_FB_SYS_FOPS=m -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_CIRRUS is not set -# CONFIG_FB_PM2 is not set -# CONFIG_FB_ARMCLCD is not set -# CONFIG_FB_CYBER2000 is not set -# CONFIG_FB_ASILIANT is not set -# CONFIG_FB_IMSTT is not set -# CONFIG_FB_EFI is not set -# CONFIG_FB_OPENCORES is not set -# CONFIG_FB_S1D13XXX is not set -# CONFIG_FB_NVIDIA is not set -# CONFIG_FB_RIVA is not set -# CONFIG_FB_I740 is not set -# CONFIG_FB_MATROX is not set -# CONFIG_FB_RADEON is not set -# CONFIG_FB_ATY128 is not set -# CONFIG_FB_ATY is not set -# CONFIG_FB_S3 is not set -# CONFIG_FB_SAVAGE is not set -# CONFIG_FB_SIS is not set -# CONFIG_FB_NEOMAGIC is not set -# CONFIG_FB_KYRO is not set -# CONFIG_FB_3DFX is not set -# CONFIG_FB_VOODOO1 is not set -# CONFIG_FB_VT8623 is not set -# CONFIG_FB_TRIDENT is not set -# CONFIG_FB_ARK is not set -# CONFIG_FB_PM3 is not set -# CONFIG_FB_CARMINE is not set -# CONFIG_FB_SMSCUFX is not set -# CONFIG_FB_UDL is not set -# CONFIG_FB_IBM_GXT4500 is not set -# CONFIG_FB_VIRTUAL is not set -# CONFIG_XEN_FBDEV_FRONTEND is not set -# CONFIG_FB_METRONOME is not set -# CONFIG_FB_MB862XX 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_FB_SM712 is not set -CONFIG_BACKLIGHT_LCD_SUPPORT=y -CONFIG_LCD_CLASS_DEVICE=m -# CONFIG_LCD_L4F00242T03 is not set -# CONFIG_LCD_LMS283GF05 is not set -# CONFIG_LCD_LTV350QV is not set -# CONFIG_LCD_ILI922X is not set -# CONFIG_LCD_ILI9320 is not set -# CONFIG_LCD_TDO24M is not set -# CONFIG_LCD_VGG2432A4 is not set -# CONFIG_LCD_PLATFORM is not set -# CONFIG_LCD_S6E63M0 is not set -# CONFIG_LCD_LD9040 is not set -# CONFIG_LCD_AMS369FG06 is not set -# CONFIG_LCD_LMS501KF03 is not set -# CONFIG_LCD_HX8357 is not set -CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_FB_ARMCLCD=y +# CONFIG_FB_UVESA is not set CONFIG_BACKLIGHT_GENERIC=m -# CONFIG_BACKLIGHT_PWM is not set -# 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_PWM=m CONFIG_BACKLIGHT_LP855X=m -# 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_VGASTATE is not set -CONFIG_VIDEOMODE_HELPERS=y -CONFIG_HDMI=y # # Console display driver support # -CONFIG_DUMMY_CONSOLE=y -CONFIG_DUMMY_CONSOLE_COLUMNS=80 -CONFIG_DUMMY_CONSOLE_ROWS=25 CONFIG_FRAMEBUFFER_CONSOLE=y -CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y -# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set CONFIG_LOGO=y # CONFIG_LOGO_LINUX_MONO is not set # CONFIG_LOGO_LINUX_VGA16 is not set -CONFIG_LOGO_LINUX_CLUT224=y -# CONFIG_SOUND is not set +CONFIG_SOUND=y +CONFIG_SND=y +CONFIG_SND_HWDEP=m +CONFIG_SND_RAWMIDI=m +CONFIG_SND_VMASTER=y + +# +# HD-Audio +# +CONFIG_SND_USB_AUDIO=m +CONFIG_SND_USB_UA101=m +CONFIG_SND_USB_CAIAQ=m +CONFIG_SND_USB_CAIAQ_INPUT=y +CONFIG_SND_USB_6FIRE=m +CONFIG_SND_USB_HIFACE=m +CONFIG_SND_SOC=y + +# +# SoC Audio for Freescale CPUs +# + +# +# Common SoC Audio options for Freescale CPUs: +# +CONFIG_SND_SOC_MESON=y +CONFIG_SND_SOC_MESON_I2S=y + +# +# STMicroelectronics STM32 SOC audio support +# + +# +# CODEC drivers +# +CONFIG_SND_SOC_AK4613=m +CONFIG_SND_SOC_DIO2125=m +CONFIG_SND_SOC_HDMI_CODEC=y +CONFIG_SND_SOC_ES7134=m +CONFIG_SND_SOC_PCM512x=m +CONFIG_SND_SOC_PCM512x_I2C=m +CONFIG_SND_SOC_SPDIF=m +CONFIG_SND_SIMPLE_CARD=y +CONFIG_SND_SIMPLE_SCU_CARD=m # # HID support # -CONFIG_HID=y -# CONFIG_HID_BATTERY_STRENGTH is not set -# CONFIG_HIDRAW is not set -# CONFIG_UHID is not set -CONFIG_HID_GENERIC=y # # Special HID drivers # CONFIG_HID_A4TECH=y -# CONFIG_HID_ACCUTOUCH is not set -# CONFIG_HID_ACRUX is not set CONFIG_HID_APPLE=y -# CONFIG_HID_APPLEIR is not set -# CONFIG_HID_ASUS is not set -# CONFIG_HID_AUREAL is not set +CONFIG_HID_APPLEIR=m CONFIG_HID_BELKIN=y -# CONFIG_HID_BETOP_FF is not set CONFIG_HID_CHERRY=y CONFIG_HID_CHICONY=y -# CONFIG_HID_CORSAIR is not set -# CONFIG_HID_CMEDIA is not set CONFIG_HID_CYPRESS=y -# CONFIG_HID_DRAGONRISE is not set -# CONFIG_HID_EMS_FF is not set -# CONFIG_HID_ELECOM is not set -# CONFIG_HID_ELO is not set +CONFIG_HID_ELO=m CONFIG_HID_EZKEY=y -# CONFIG_HID_GEMBIRD is not set -# CONFIG_HID_GFRM is not set -# CONFIG_HID_HOLTEK is not set -# CONFIG_HID_GT683R is not set -# CONFIG_HID_KEYTOUCH is not set -# CONFIG_HID_KYE is not set -# CONFIG_HID_UCLOGIC is not set -# CONFIG_HID_WALTOP is not set -# CONFIG_HID_GYRATION is not set -# CONFIG_HID_ICADE is not set -CONFIG_HID_ITE=y -# CONFIG_HID_TWINHAN is not set +CONFIG_HID_HOLTEK=m +CONFIG_HOLTEK_FF=y +CONFIG_HID_UCLOGIC=m CONFIG_HID_KENSINGTON=y -# CONFIG_HID_LCPOWER is not set -# CONFIG_HID_LED is not set -# CONFIG_HID_LENOVO is not set CONFIG_HID_LOGITECH=y # CONFIG_HID_LOGITECH_HIDPP is not set # CONFIG_LOGITECH_FF is not set # CONFIG_LOGIRUMBLEPAD2_FF is not set # CONFIG_LOGIG940_FF is not set # CONFIG_LOGIWHEELS_FF is not set -# CONFIG_HID_MAGICMOUSE is not set -# CONFIG_HID_MAYFLASH is not set CONFIG_HID_MICROSOFT=y CONFIG_HID_MONTEREY=y -# CONFIG_HID_MULTITOUCH is not set -# CONFIG_HID_NTI is not set -# CONFIG_HID_NTRIG is not set -# CONFIG_HID_ORTEK is not set -# CONFIG_HID_PANTHERLORD is not set -# CONFIG_HID_PENMOUNT is not set -# CONFIG_HID_PETALYNX is not set -# CONFIG_HID_PICOLCD is not set -# CONFIG_HID_PLANTRONICS is not set -# CONFIG_HID_PRIMAX is not set -# CONFIG_HID_RETRODE is not set -# CONFIG_HID_ROCCAT is not set -# CONFIG_HID_SAITEK is not set -# CONFIG_HID_SAMSUNG is not set -# CONFIG_HID_SONY is not set -# CONFIG_HID_SPEEDLINK is not set -# CONFIG_HID_STEELSERIES is not set -# CONFIG_HID_SUNPLUS is not set -# CONFIG_HID_RMI is not set -# CONFIG_HID_GREENASIA is not set -# CONFIG_HID_SMARTJOYPLUS is not set -# CONFIG_HID_TIVO is not set -# CONFIG_HID_TOPSEED is not set -# CONFIG_HID_THINGM is not set -# CONFIG_HID_THRUSTMASTER is not set -# CONFIG_HID_UDRAW_PS3 is not set -# CONFIG_HID_WACOM is not set -# CONFIG_HID_WIIMOTE is not set -# CONFIG_HID_XINMO is not set -# CONFIG_HID_ZEROPLUS is not set -# CONFIG_HID_ZYDACRON is not set -# CONFIG_HID_SENSOR_HUB is not set -# CONFIG_HID_ALPS is not set +CONFIG_HID_NTRIG=m +CONFIG_HID_ROCCAT=m +CONFIG_HID_SONY=m +CONFIG_SONY_FF=y +CONFIG_HID_WACOM=m # # USB HID support # -CONFIG_USB_HID=y -# CONFIG_HID_PID is not set -# CONFIG_USB_HIDDEV is not set +CONFIG_HID_PID=y +CONFIG_USB_HIDDEV=y # # I2C HID support # -# CONFIG_I2C_HID is not set -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_PCI=y -# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set # # Miscellaneous USB options # -CONFIG_USB_DEFAULT_PERSIST=y -# 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_MON is not set -# CONFIG_USB_WUSB_CBAF is not set +CONFIG_USB_MON=m # # USB Host Controller Drivers # -# CONFIG_USB_C67X00_HCD is not set CONFIG_USB_XHCI_HCD=y -CONFIG_USB_XHCI_PCI=y -CONFIG_USB_XHCI_PLATFORM=y CONFIG_USB_EHCI_HCD=y -CONFIG_USB_EHCI_ROOT_HUB_TT=y -CONFIG_USB_EHCI_TT_NEWSCHED=y -CONFIG_USB_EHCI_PCI=y CONFIG_USB_EHCI_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_PCI=y CONFIG_USB_OHCI_HCD_PLATFORM=y -# CONFIG_USB_UHCI_HCD is not set -# 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 is not set -# CONFIG_USB_PRINTER is not set -# CONFIG_USB_WDM is not set -# CONFIG_USB_TMC is not set +CONFIG_USB_ACM=m +CONFIG_USB_PRINTER=m +CONFIG_USB_WDM=m # # NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may @@ -2914,435 +2299,333 @@ CONFIG_USB_OHCI_HCD_PLATFORM=y # 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 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_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 is not set +# CONFIG_USBIP_DEBUG is not set +CONFIG_USB_MUSB_HDRC=y + +# +# Platform Glue Layer +# + +# +# MUSB DMA mode +# CONFIG_USB_DWC3=y -# CONFIG_USB_DWC3_HOST is not set -# CONFIG_USB_DWC3_GADGET is not set -CONFIG_USB_DWC3_DUAL_ROLE=y # # Platform Glue Driver Support # -# CONFIG_USB_DWC3_PCI is not set -CONFIG_USB_DWC3_OF_SIMPLE=y CONFIG_USB_DWC2=y -# CONFIG_USB_DWC2_HOST is not set # # Gadget/Dual-role mode requires USB Gadget support to be enabled # -# CONFIG_USB_DWC2_PERIPHERAL is not set -CONFIG_USB_DWC2_DUAL_ROLE=y -# CONFIG_USB_DWC2_PCI is not set -# CONFIG_USB_DWC2_DEBUG is not set -# CONFIG_USB_DWC2_TRACK_MISSED_SOFS is not set CONFIG_USB_CHIPIDEA=y -CONFIG_USB_CHIPIDEA_OF=y CONFIG_USB_CHIPIDEA_UDC=y CONFIG_USB_CHIPIDEA_HOST=y +CONFIG_USB_CHIPIDEA_ULPI=y CONFIG_USB_ISP1760=y -CONFIG_USB_ISP1760_HCD=y -CONFIG_USB_ISP1761_UDC=y -# CONFIG_USB_ISP1760_HOST_ROLE is not set -# CONFIG_USB_ISP1760_GADGET_ROLE is not set -CONFIG_USB_ISP1760_DUAL_ROLE=y # # USB port drivers # -# CONFIG_USB_SERIAL is not set +CONFIG_USB_SERIAL=y +# CONFIG_USB_SERIAL_CONSOLE is not set +CONFIG_USB_SERIAL_GENERIC=y +CONFIG_USB_SERIAL_SIMPLE=m +CONFIG_USB_SERIAL_AIRCABLE=m +CONFIG_USB_SERIAL_ARK3116=m +CONFIG_USB_SERIAL_BELKIN=m +CONFIG_USB_SERIAL_CH341=m +CONFIG_USB_SERIAL_WHITEHEAT=m +CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m +CONFIG_USB_SERIAL_CP210X=m +CONFIG_USB_SERIAL_CYPRESS_M8=m +CONFIG_USB_SERIAL_EMPEG=m +CONFIG_USB_SERIAL_FTDI_SIO=m +CONFIG_USB_SERIAL_VISOR=m +CONFIG_USB_SERIAL_IPAQ=m +CONFIG_USB_SERIAL_IR=m +CONFIG_USB_SERIAL_EDGEPORT=m +CONFIG_USB_SERIAL_EDGEPORT_TI=m +CONFIG_USB_SERIAL_F81232=m +CONFIG_USB_SERIAL_F8153X=m +CONFIG_USB_SERIAL_GARMIN=m +CONFIG_USB_SERIAL_IPW=m +CONFIG_USB_SERIAL_IUU=m +CONFIG_USB_SERIAL_KEYSPAN_PDA=m +CONFIG_USB_SERIAL_KEYSPAN=m +CONFIG_USB_SERIAL_KLSI=m +CONFIG_USB_SERIAL_KOBIL_SCT=m +CONFIG_USB_SERIAL_MCT_U232=m +CONFIG_USB_SERIAL_METRO=m +CONFIG_USB_SERIAL_MOS7720=m +CONFIG_USB_SERIAL_MOS7840=m +CONFIG_USB_SERIAL_MXUPORT=m +CONFIG_USB_SERIAL_NAVMAN=m +CONFIG_USB_SERIAL_PL2303=m +CONFIG_USB_SERIAL_OTI6858=m +CONFIG_USB_SERIAL_QCAUX=m +CONFIG_USB_SERIAL_QUALCOMM=m +CONFIG_USB_SERIAL_SPCP8X5=m +CONFIG_USB_SERIAL_SAFE=m +CONFIG_USB_SERIAL_SAFE_PADDED=y +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 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_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 is not set -# CONFIG_USB_HUB_USB251XB is not set +CONFIG_USB_EMI62=m +CONFIG_USB_EMI26=m +CONFIG_USB_SEVSEG=m +CONFIG_USB_RIO500=m +CONFIG_USB_LEGOTOWER=m +CONFIG_USB_LCD=m +CONFIG_USB_CYTHERM=m +CONFIG_USB_APPLEDISPLAY=m +CONFIG_USB_SISUSBVGA=m +CONFIG_USB_SISUSBVGA_CON=y +CONFIG_USB_LD=m +CONFIG_USB_TRANCEVIBRATOR=m +CONFIG_USB_IOWARRIOR=m +CONFIG_USB_ISIGHTFW=m +CONFIG_USB_YUREX=m +CONFIG_USB_EZUSB_FX2=m CONFIG_USB_HSIC_USB3503=y -# CONFIG_USB_HSIC_USB4604 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_NOP_USB_XCEIV is not set -# CONFIG_USB_GPIO_VBUS is not set -# CONFIG_USB_ISP1301 is not set +CONFIG_NOP_USB_XCEIV=y CONFIG_USB_ULPI=y -CONFIG_USB_ULPI_VIEWPORT=y 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_FOTG210_UDC is not set -# CONFIG_USB_GR_UDC is not set -# CONFIG_USB_R8A66597 is not set -# CONFIG_USB_PXA27X is not set -# CONFIG_USB_MV_UDC is not set -# CONFIG_USB_MV_U3D is not set -CONFIG_USB_SNP_CORE=y -CONFIG_USB_SNP_UDC_PLAT=y -# CONFIG_USB_M66592 is not set +# CONFIG_USB_SNP_UDC_PLAT is not set # CONFIG_USB_BDC_UDC is not set -# CONFIG_USB_AMD5536UDC is not set -# CONFIG_USB_NET2272 is not set -# CONFIG_USB_NET2280 is not set -# CONFIG_USB_GOKU is not set -# CONFIG_USB_EG20T is not set -# CONFIG_USB_GADGET_XILINX is not set -# CONFIG_USB_DUMMY_HCD is not set -# CONFIG_USB_CONFIGFS is not set - -# -# USB Power Delivery and Type-C drivers -# -# CONFIG_TYPEC_UCSI is not set -# CONFIG_USB_LED_TRIG is not set -# CONFIG_USB_ULPI_BUS is not set -# CONFIG_UWB is not set +CONFIG_USB_LIBCOMPOSITE=m +CONFIG_USB_F_ACM=m +CONFIG_USB_F_SS_LB=m +CONFIG_USB_U_SERIAL=m +CONFIG_USB_U_ETHER=m +CONFIG_USB_U_AUDIO=m +CONFIG_USB_F_SERIAL=m +CONFIG_USB_F_OBEX=m +CONFIG_USB_F_NCM=m +CONFIG_USB_F_ECM=m +CONFIG_USB_F_PHONET=m +CONFIG_USB_F_EEM=m +CONFIG_USB_F_SUBSET=m +CONFIG_USB_F_RNDIS=m +CONFIG_USB_F_MASS_STORAGE=m +CONFIG_USB_F_FS=m +CONFIG_USB_F_UAC1=m +CONFIG_USB_F_UVC=m +CONFIG_USB_F_MIDI=m +CONFIG_USB_F_HID=m +CONFIG_USB_F_PRINTER=m +CONFIG_USB_CONFIGFS=m +CONFIG_USB_CONFIGFS_SERIAL=y +CONFIG_USB_CONFIGFS_ACM=y +CONFIG_USB_CONFIGFS_OBEX=y +CONFIG_USB_CONFIGFS_NCM=y +CONFIG_USB_CONFIGFS_ECM=y +CONFIG_USB_CONFIGFS_ECM_SUBSET=y +CONFIG_USB_CONFIGFS_RNDIS=y +CONFIG_USB_CONFIGFS_EEM=y +CONFIG_USB_CONFIGFS_PHONET=y +CONFIG_USB_CONFIGFS_MASS_STORAGE=y +CONFIG_USB_CONFIGFS_F_LB_SS=y +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=m +# CONFIG_USB_ZERO_HNPTEST is not set +CONFIG_USB_AUDIO=m +CONFIG_GADGET_UAC1=y +# CONFIG_GADGET_UAC1_LEGACY is not set +CONFIG_USB_ETH=m +CONFIG_USB_ETH_RNDIS=y +CONFIG_USB_ETH_EEM=y +CONFIG_USB_G_NCM=m +CONFIG_USB_GADGETFS=m +CONFIG_USB_FUNCTIONFS=m +CONFIG_USB_FUNCTIONFS_ETH=y +CONFIG_USB_FUNCTIONFS_RNDIS=y +# CONFIG_USB_FUNCTIONFS_GENERIC is not set +CONFIG_USB_MASS_STORAGE=m +CONFIG_USB_G_SERIAL=m +CONFIG_USB_MIDI_GADGET=m +CONFIG_USB_G_PRINTER=m +CONFIG_USB_CDC_COMPOSITE=m +CONFIG_USB_G_NOKIA=m +CONFIG_USB_G_ACM_MS=m +CONFIG_USB_G_MULTI=m +CONFIG_USB_G_MULTI_RNDIS=y +# CONFIG_USB_G_MULTI_CDC is not set +CONFIG_USB_G_HID=m +# CONFIG_USB_G_DBGP is not set +CONFIG_USB_G_WEBCAM=m +CONFIG_USB_ULPI_BUS=y CONFIG_MMC=y -CONFIG_PWRSEQ_EMMC=y -CONFIG_PWRSEQ_SIMPLE=y -CONFIG_MMC_BLOCK=y CONFIG_MMC_BLOCK_MINORS=32 -# CONFIG_SDIO_UART is not set -# CONFIG_MMC_TEST is not set # # MMC/SD/SDIO Host Controller Drivers # -# CONFIG_MMC_DEBUG is not set CONFIG_MMC_ARMMMCI=y CONFIG_MMC_SDHCI=y -# CONFIG_MMC_SDHCI_PCI is not set CONFIG_MMC_SDHCI_ACPI=y CONFIG_MMC_SDHCI_PLTFM=y CONFIG_MMC_SDHCI_OF_ARASAN=y -# CONFIG_MMC_SDHCI_OF_AT91 is not set -# CONFIG_MMC_SDHCI_CADENCE is not set -# CONFIG_MMC_SDHCI_F_SDH30 is not set +CONFIG_MMC_SDHCI_CADENCE=y CONFIG_MMC_MESON_GX=y -# CONFIG_MMC_TIFM_SD is not set CONFIG_MMC_SPI=y -# CONFIG_MMC_CB710 is not set -# CONFIG_MMC_VIA_SDMMC is not set -# CONFIG_MMC_CAVIUM_THUNDERX is not set CONFIG_MMC_DW=y -CONFIG_MMC_DW_PLTFM=y -CONFIG_MMC_DW_EXYNOS=y +# CONFIG_MMC_DW_EXYNOS is not set CONFIG_MMC_DW_K3=y -# CONFIG_MMC_DW_PCI is not set -# CONFIG_MMC_VUB300 is not set -# CONFIG_MMC_USHC is not set -# CONFIG_MMC_USDHI6ROL0 is not set -# CONFIG_MMC_TOSHIBA_PCI is not set -# CONFIG_MMC_MTK is not set -# CONFIG_MMC_SDHCI_XENON is not set -# CONFIG_MEMSTICK is not set +CONFIG_MMC_SDHCI_XENON=y 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_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_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_PWM=y # 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_IS31FL319X is not set -# CONFIG_LEDS_IS31FL32XX is not set # # LED driver for blink(1) USB RGB LED is under Special HID drivers (HID_THINGM) # -# CONFIG_LEDS_BLINKM is not set CONFIG_LEDS_SYSCON=y -# CONFIG_LEDS_USER is not set # # LED Triggers # -CONFIG_LEDS_TRIGGERS=y -# CONFIG_LEDS_TRIGGER_TIMER is not set -# CONFIG_LEDS_TRIGGER_ONESHOT is not set -# CONFIG_LEDS_TRIGGER_MTD is not set +CONFIG_LEDS_TRIGGER_DISK=y CONFIG_LEDS_TRIGGER_HEARTBEAT=y -# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set CONFIG_LEDS_TRIGGER_CPU=y -# CONFIG_LEDS_TRIGGER_GPIO is not set -# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set +CONFIG_LEDS_TRIGGER_DEFAULT_ON=y # # iptables trigger is under Netfilter config (LED target) # -# CONFIG_LEDS_TRIGGER_TRANSIENT is not set -# CONFIG_LEDS_TRIGGER_CAMERA is not set -# CONFIG_LEDS_TRIGGER_PANIC is not set -# CONFIG_ACCESSIBILITY is not set -# CONFIG_INFINIBAND is not set -CONFIG_EDAC_SUPPORT=y -# CONFIG_EDAC is not set -CONFIG_RTC_LIB=y +CONFIG_LEDS_TRIGGER_PANIC=y +CONFIG_EDAC=y +CONFIG_EDAC_GHES=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_ABX80X is not set -# CONFIG_RTC_DRV_DS1307 is not set -# CONFIG_RTC_DRV_DS1374 is not set -# CONFIG_RTC_DRV_DS1672 is not set -# CONFIG_RTC_DRV_HYM8563 is not set -# CONFIG_RTC_DRV_MAX6900 is not set CONFIG_RTC_DRV_MAX77686=y CONFIG_RTC_DRV_RK808=m -# CONFIG_RTC_DRV_RS5C372 is not set -# CONFIG_RTC_DRV_ISL1208 is not set -# CONFIG_RTC_DRV_ISL12022 is not set -# CONFIG_RTC_DRV_X1205 is not set -# CONFIG_RTC_DRV_PCF8523 is not set -# CONFIG_RTC_DRV_PCF85063 is not set -# CONFIG_RTC_DRV_PCF8563 is not set -# CONFIG_RTC_DRV_PCF8583 is not set -# CONFIG_RTC_DRV_M41T80 is not set -# CONFIG_RTC_DRV_BQ32K is not set -# CONFIG_RTC_DRV_S35390A is not set -# CONFIG_RTC_DRV_FM3130 is not set -# CONFIG_RTC_DRV_RX8010 is not set -# CONFIG_RTC_DRV_RX8581 is not set -# CONFIG_RTC_DRV_RX8025 is not set -# CONFIG_RTC_DRV_EM3027 is not set -# CONFIG_RTC_DRV_RV8803 is not set CONFIG_RTC_DRV_S5M=y # # SPI RTC drivers # -# CONFIG_RTC_DRV_M41T93 is not set -# CONFIG_RTC_DRV_M41T94 is not set -# CONFIG_RTC_DRV_DS1302 is not set -# CONFIG_RTC_DRV_DS1305 is not set -# CONFIG_RTC_DRV_DS1343 is not set -# CONFIG_RTC_DRV_DS1347 is not set -# CONFIG_RTC_DRV_DS1390 is not set -# CONFIG_RTC_DRV_MAX6916 is not set -# CONFIG_RTC_DRV_R9701 is not set -# CONFIG_RTC_DRV_RX4581 is not set -# CONFIG_RTC_DRV_RX6110 is not set -# CONFIG_RTC_DRV_RS5C348 is not set -# CONFIG_RTC_DRV_MAX6902 is not set -# CONFIG_RTC_DRV_PCF2123 is not set -# CONFIG_RTC_DRV_MCP795 is not set -CONFIG_RTC_I2C_AND_SPI=y # # SPI and I2C RTC drivers # CONFIG_RTC_DRV_DS3232=y -CONFIG_RTC_DRV_DS3232_HWMON=y -# CONFIG_RTC_DRV_PCF2127 is not set -# CONFIG_RTC_DRV_RV3029C2 is not set # # Platform RTC drivers # -# CONFIG_RTC_DRV_DS1286 is not set -# CONFIG_RTC_DRV_DS1511 is not set -# CONFIG_RTC_DRV_DS1553 is not set -# CONFIG_RTC_DRV_DS1685_FAMILY is not set -# CONFIG_RTC_DRV_DS1742 is not set -# CONFIG_RTC_DRV_DS2404 is not set CONFIG_RTC_DRV_EFI=y -# CONFIG_RTC_DRV_STK17TA8 is not set -# CONFIG_RTC_DRV_M48T86 is not set -# CONFIG_RTC_DRV_M48T35 is not set -# CONFIG_RTC_DRV_M48T59 is not set -# CONFIG_RTC_DRV_MSM6242 is not set -# CONFIG_RTC_DRV_BQ4802 is not set -# CONFIG_RTC_DRV_RP5C01 is not set -# CONFIG_RTC_DRV_V3020 is not set -# CONFIG_RTC_DRV_ZYNQMP is not set # # on-CPU RTC drivers # -# CONFIG_RTC_DRV_PL030 is not set CONFIG_RTC_DRV_PL031=y -# CONFIG_RTC_DRV_FTRTC010 is not set -# CONFIG_RTC_DRV_SNVS is not set -# CONFIG_RTC_DRV_R7301 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_ACPI=y -CONFIG_DMA_OF=y -# CONFIG_ALTERA_MSGDMA is not set -# CONFIG_AMBA_PL08X is not set -# CONFIG_FSL_EDMA is not set -# CONFIG_INTEL_IDMA64 is not set -# CONFIG_MV_XOR_V2 is not set -# CONFIG_PL330_DMA is not set -# CONFIG_XILINX_DMA is not set -# CONFIG_XILINX_ZYNQMP_DMA is not set +CONFIG_BCM_SBA_RAID=m +CONFIG_MV_XOR_V2=y +CONFIG_PL330_DMA=y # CONFIG_QCOM_HIDMA_MGMT is not set # CONFIG_QCOM_HIDMA is not set -# CONFIG_DW_DMAC is not set -# CONFIG_DW_DMAC_PCI is not set # # DMA Clients # -# CONFIG_ASYNC_TX_DMA is not set -# CONFIG_DMATEST is not set # # DMABUF options # -CONFIG_SYNC_FILE=y -# CONFIG_SW_SYNC is not set -# CONFIG_AUXDISPLAY is not set -# CONFIG_UIO is not set -# CONFIG_VFIO is not set -# CONFIG_VIRT_DRIVERS is not set -CONFIG_VIRTIO=y - -# -# Virtio drivers -# +CONFIG_VFIO=y +CONFIG_VFIO_PCI=y CONFIG_VIRTIO_PCI=y -CONFIG_VIRTIO_PCI_LEGACY=y CONFIG_VIRTIO_BALLOON=y -# CONFIG_VIRTIO_INPUT is not set CONFIG_VIRTIO_MMIO=y -# CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES is not set # # Microsoft Hyper-V guest support # -# CONFIG_HYPERV_TSCPAGE is not set # # Xen driver support # -CONFIG_XEN_BALLOON=y -CONFIG_XEN_SCRUB_PAGES=y -CONFIG_XEN_DEV_EVTCHN=y -CONFIG_XEN_BACKEND=y -CONFIG_XENFS=y -CONFIG_XEN_COMPAT_XENFS=y -CONFIG_XEN_SYS_HYPERVISOR=y -CONFIG_XEN_XENBUS_FRONTEND=y CONFIG_XEN_GNTDEV=y CONFIG_XEN_GRANT_DEV_ALLOC=y -CONFIG_SWIOTLB_XEN=y -# CONFIG_XEN_PVCALLS_BACKEND is not set -CONFIG_XEN_PRIVCMD=y -CONFIG_XEN_EFI=y -CONFIG_XEN_AUTO_XLATE=y CONFIG_STAGING=y # CONFIG_IRDA is not set -# CONFIG_PRISM2_USB is not set +# CONFIG_IPX is not set +# CONFIG_NCP_FS is not set +CONFIG_PRISM2_USB=m # CONFIG_COMEDI is not set # CONFIG_RTL8192U is not set # CONFIG_RTLLIB is not set # CONFIG_RTL8723BS is not set -# CONFIG_R8712U is not set -# CONFIG_R8188EU is not set +CONFIG_R8712U=m +CONFIG_R8188EU=m +CONFIG_88EU_AP_MODE=y # CONFIG_R8822BE is not set # CONFIG_RTS5208 is not set # CONFIG_VT6655 is not set @@ -3428,18 +2711,54 @@ CONFIG_STAGING=y # Speakup console speech # # CONFIG_SPEAKUP is not set -# CONFIG_STAGING_MEDIA is not set +CONFIG_STAGING_MEDIA=y +# CONFIG_DVB_CXD2099 is not set # # Android # # CONFIG_STAGING_BOARD is not set # CONFIG_LTE_GDM724X is not set +# CONFIG_MTD_SPINAND_MT29F is not set # CONFIG_LNET is not set # CONFIG_DGNC 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 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_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_FB_FLEX=m +CONFIG_FB_TFT_FBTFT_DEVICE=m # CONFIG_WILC1000_SDIO is not set # CONFIG_WILC1000_SPI is not set # CONFIG_MOST is not set @@ -3450,13 +2769,7 @@ CONFIG_STAGING=y # # USB Power Delivery and Type-C drivers # -# CONFIG_TYPEC_TCPM is not set # CONFIG_PI433 is not set -# CONFIG_GOLDFISH is not set -# CONFIG_CHROME_PLATFORMS is not set -CONFIG_CLKDEV_LOOKUP=y -CONFIG_HAVE_CLK_PREPARE=y -CONFIG_COMMON_CLK=y # # Common Clock Framework @@ -3464,76 +2777,38 @@ CONFIG_COMMON_CLK=y CONFIG_COMMON_CLK_VERSATILE=y CONFIG_CLK_SP810=y CONFIG_CLK_VEXPRESS_OSC=y -# CONFIG_CLK_HSDK is not set -# CONFIG_COMMON_CLK_MAX77686 is not set CONFIG_COMMON_CLK_RK808=y CONFIG_COMMON_CLK_SCPI=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_CDCE706 is not set -# CONFIG_COMMON_CLK_CDCE925 is not set CONFIG_COMMON_CLK_CS2000_CP=y CONFIG_COMMON_CLK_S2MPS11=y -CONFIG_CLK_QORIQ=y -CONFIG_COMMON_CLK_XGENE=y -# CONFIG_COMMON_CLK_NXP is not set +# CONFIG_CLK_QORIQ is not set +# CONFIG_COMMON_CLK_XGENE is not set CONFIG_COMMON_CLK_PWM=y -# CONFIG_COMMON_CLK_PXA is not set -# CONFIG_COMMON_CLK_PIC32 is not set -# CONFIG_COMMON_CLK_VC5 is not set -CONFIG_COMMON_CLK_AMLOGIC=y -CONFIG_COMMON_CLK_GXBB=y CONFIG_HWSPINLOCK=y # # Clock Source drivers # -CONFIG_TIMER_OF=y -CONFIG_TIMER_ACPI=y -CONFIG_TIMER_PROBE=y CONFIG_CLKSRC_MMIO=y -CONFIG_ARM_ARCH_TIMER=y -CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y -CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND=y -CONFIG_FSL_ERRATUM_A008585=y -CONFIG_HISILICON_ERRATUM_161010101=y -CONFIG_ARM64_ERRATUM_858921=y +# CONFIG_HISILICON_ERRATUM_161010101 is not set CONFIG_ARM_TIMER_SP804=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_CLKSRC_VERSATILE=y CONFIG_MAILBOX=y CONFIG_ARM_MHU=y CONFIG_PLATFORM_MHU=y # CONFIG_PL320_MBOX is not set -# CONFIG_PCC is not set # CONFIG_ALTERA_MBOX is not set # CONFIG_MAILBOX_TEST is not set -# CONFIG_BCM_FLEXRM_MBOX 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 -CONFIG_IOMMU_IOVA=y -CONFIG_OF_IOMMU=y -CONFIG_IOMMU_DMA=y CONFIG_ARM_SMMU=y -# CONFIG_ARM_SMMU_V3 is not set +CONFIG_ARM_SMMU_V3=y # # Remoteproc drivers # -# CONFIG_REMOTEPROC is not set # # Rpmsg drivers @@ -3547,7 +2822,6 @@ CONFIG_ARM_SMMU=y # # Amlogic SoC drivers # -CONFIG_MESON_GX_SOCINFO=y # # Broadcom SoC drivers @@ -3562,113 +2836,48 @@ CONFIG_MESON_GX_SOCINFO=y # Qualcomm SoC drivers # # CONFIG_SUNXI_SRAM is not set -# CONFIG_SOC_TI is not set -# CONFIG_PM_DEVFREQ is not set -CONFIG_EXTCON=y + +# +# Xilinx SoC drivers +# +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 +# CONFIG_DEVFREQ_GOV_PASSIVE is not set + +# +# DEVFREQ Drivers +# +# CONFIG_PM_DEVFREQ_EVENT is not set # # Extcon Device Drivers # -# CONFIG_EXTCON_ADC_JACK is not set -# CONFIG_EXTCON_GPIO is not set -# CONFIG_EXTCON_MAX3355 is not set -# CONFIG_EXTCON_RT8973A is not set -# CONFIG_EXTCON_SM5502 is not set CONFIG_EXTCON_USB_GPIO=y -# CONFIG_MEMORY is not set CONFIG_IIO=y -# CONFIG_IIO_BUFFER is not set -# CONFIG_IIO_CONFIGFS is not set -# CONFIG_IIO_TRIGGER is not set -# CONFIG_IIO_SW_DEVICE is not set -# CONFIG_IIO_SW_TRIGGER is not set # # Accelerometers # -# CONFIG_ADXL345_I2C is not set -# CONFIG_ADXL345_SPI is not set -# CONFIG_BMA180 is not set -# CONFIG_BMA220 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_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 # # 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_AD7766 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_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_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_MESON_SARADC=y -# CONFIG_NAU7802 is not set -# CONFIG_QCOM_SPMI_IADC is not set -# CONFIG_QCOM_SPMI_VADC 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_ADS8688 is not set -# CONFIG_TI_TLC4541 is not set -# CONFIG_VF610_ADC is not set # # Amplifiers # -# CONFIG_AD8366 is not set # # Chemical Sensors # -# CONFIG_ATLAS_PH_SENSOR is not set -# CONFIG_CCS811 is not set -# CONFIG_IAQCORE is not set -# CONFIG_VZ89X is not set # # Hid Sensor IIO Common @@ -3677,7 +2886,6 @@ CONFIG_MESON_SARADC=y # # SSP Sensor Common # -# CONFIG_IIO_SSP_SENSORHUB is not set # # Counters @@ -3686,31 +2894,6 @@ CONFIG_MESON_SARADC=y # # 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_LTC2632 is not set -# CONFIG_AD5686 is not set -# CONFIG_AD5755 is not set -# 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_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_VF610_DAC is not set # # IIO dummy driver @@ -3723,25 +2906,14 @@ CONFIG_MESON_SARADC=y # # 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_MPU3050_I2C is not set -# CONFIG_IIO_ST_GYRO_3AXIS is not set -# CONFIG_ITG3200 is not set # # Health Sensors @@ -3750,89 +2922,26 @@ CONFIG_MESON_SARADC=y # # Heart Rate Monitors # -# CONFIG_AFE4403 is not set -# CONFIG_AFE4404 is not set -# CONFIG_MAX30100 is not set -# CONFIG_MAX30102 is not set # # Humidity sensors # -# CONFIG_AM2315 is not set -# CONFIG_DHT11 is not set -# CONFIG_HDC100X is not set -# CONFIG_HTS221 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_BMI160_I2C is not set -# CONFIG_BMI160_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 # # Light sensors # -# CONFIG_ACPI_ALS is not set -# 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_BH1780 is not set -# CONFIG_CM32181 is not set -# CONFIG_CM3232 is not set -# CONFIG_CM3323 is not set -# CONFIG_CM3605 is not set -# CONFIG_CM36651 is not set -# CONFIG_GP2AP020A00F is not set -# CONFIG_SENSORS_ISL29018 is not set -# CONFIG_SENSORS_ISL29028 is not set -# CONFIG_ISL29125 is not set -# CONFIG_JSA1212 is not set -# CONFIG_RPR0521 is not set -# CONFIG_LTR501 is not set -# CONFIG_MAX44000 is not set -# CONFIG_OPT3001 is not set -# CONFIG_PA12203001 is not set -# CONFIG_SI1145 is not set -# CONFIG_STK3310 is not set -# CONFIG_TCS3414 is not set -# CONFIG_TCS3472 is not set -# CONFIG_SENSORS_TSL2563 is not set -# CONFIG_TSL2583 is not set -# CONFIG_TSL4531 is not set -# CONFIG_US5182D is not set -# CONFIG_VCNL4000 is not set -# CONFIG_VEML6070 is not set -# CONFIG_VL6180 is not set # # 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_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 # # Multiplexers # -# CONFIG_IIO_MUX is not set # # Inclinometer sensors @@ -3841,333 +2950,212 @@ CONFIG_MESON_SARADC=y # # Digital potentiometers # -# CONFIG_DS1803 is not set -# CONFIG_MAX5481 is not set -# CONFIG_MAX5487 is not set -# CONFIG_MCP4131 is not set -# CONFIG_MCP4531 is not set -# CONFIG_TPL0102 is not set # # Digital potentiostats # -# CONFIG_LMP91000 is not set # # Pressure sensors # -# CONFIG_ABP060MG is not set -# CONFIG_BMP280 is not set -# 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 # # Lightning sensors # -# CONFIG_AS3935 is not set # # Proximity and distance sensors # -# CONFIG_LIDAR_LITE_V2 is not set -# CONFIG_SRF04 is not set -# CONFIG_SX9500 is not set -# CONFIG_SRF08 is not set # # Temperature sensors # -# CONFIG_MAXIM_THERMOCOUPLE is not set -# CONFIG_MLX90614 is not set -# CONFIG_TMP006 is not set -# CONFIG_TMP007 is not set -# CONFIG_TSYS01 is not set -# CONFIG_TSYS02D is not set -# CONFIG_NTB is not set -# CONFIG_VME_BUS is not set CONFIG_PWM=y -CONFIG_PWM_SYSFS=y -# CONFIG_PWM_FSL_FTM is not set -CONFIG_PWM_MESON=m -# CONFIG_PWM_PCA9685 is not set -CONFIG_IRQCHIP=y -CONFIG_ARM_GIC=y -CONFIG_ARM_GIC_MAX_NR=1 -CONFIG_ARM_GIC_V2M=y -CONFIG_ARM_GIC_V3=y -CONFIG_ARM_GIC_V3_ITS=y -CONFIG_PARTITION_PERCPU=y -# CONFIG_IPACK_BUS is not set -CONFIG_RESET_CONTROLLER=y -# CONFIG_RESET_ATH79 is not set +CONFIG_PWM_CROS_EC=m +CONFIG_PWM_MESON=y + +# +# IRQ chip support +# # CONFIG_RESET_BERLIN is not set -# CONFIG_RESET_IMX7 is not set -# CONFIG_RESET_LANTIQ is not set -# CONFIG_RESET_LPC18XX is not set -CONFIG_RESET_MESON=y -# CONFIG_RESET_PISTACHIO is not set -# CONFIG_RESET_SOCFPGA is not set -# CONFIG_RESET_STM32 is not set +# CONFIG_RESET_SIMPLE is not set # CONFIG_RESET_SUNXI is not set -# CONFIG_RESET_TI_SYSCON is not set -# CONFIG_RESET_ZYNQ is not set # CONFIG_RESET_TEGRA_BPMP is not set -# CONFIG_FMC is not set # # PHY Subsystem # -CONFIG_GENERIC_PHY=y -CONFIG_PHY_XGENE=y -CONFIG_PHY_MESON8B_USB2=y -CONFIG_PHY_MESON_GXL_USB2=y -# CONFIG_BCM_KONA_USB2_PHY 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_SAMSUNG_USB2=y -# CONFIG_PHY_EXYNOS4210_USB2 is not set -# CONFIG_PHY_EXYNOS4X12_USB2 is not set -# CONFIG_PHY_EXYNOS5250_USB2 is not set -# CONFIG_POWERCAP is not set -# CONFIG_MCB is not set +# CONFIG_PHY_XGENE is not set +# CONFIG_PHY_QCOM_USB_HS is not set +# CONFIG_PHY_SAMSUNG_USB2 is not set # # Performance monitor support # -CONFIG_ARM_PMU=y -CONFIG_ARM_PMU_ACPI=y CONFIG_RAS=y # # Android # -# CONFIG_ANDROID is not set -# CONFIG_LIBNVDIMM is not set -# CONFIG_DAX is not set +CONFIG_DAX=m +# CONFIG_DEV_DAX is not set CONFIG_NVMEM=y -# CONFIG_MESON_EFUSE is not set -# CONFIG_STM is not set -# CONFIG_INTEL_TH is not set -# CONFIG_FPGA is not set +CONFIG_MESON_EFUSE=y +CONFIG_TEE=y # -# FSI support +# TEE drivers # -# CONFIG_FSI is not set -# CONFIG_TEE is not set +CONFIG_OPTEE=y # # Firmware Drivers # -CONFIG_ARM_PSCI_FW=y -# CONFIG_ARM_PSCI_CHECKER is not set CONFIG_ARM_SCPI_PROTOCOL=y -CONFIG_ARM_SCPI_POWER_DOMAIN=y -# CONFIG_FIRMWARE_MEMMAP is not set -CONFIG_DMIID=y -# CONFIG_DMI_SYSFS is not set -# CONFIG_FW_CFG_SYSFS is not set -CONFIG_HAVE_ARM_SMCCC=y -# CONFIG_GOOGLE_FIRMWARE is not set # # EFI (Extensible Firmware Interface) Support # -# CONFIG_EFI_VARS is not set -CONFIG_EFI_ESRT=y -CONFIG_EFI_PARAMS_FROM_FDT=y -CONFIG_EFI_RUNTIME_WRAPPERS=y -CONFIG_EFI_ARMSTUB=y -# CONFIG_EFI_CAPSULE_LOADER is not set -# CONFIG_EFI_TEST is not set -# CONFIG_RESET_ATTACK_MITIGATION is not set -# CONFIG_EFI_DEV_PATH_PARSER is not set -CONFIG_MESON_SM=y +CONFIG_EFI_CAPSULE_LOADER=y # # Tegra firmware driver # CONFIG_ACPI=y -CONFIG_ACPI_GENERIC_GSI=y -CONFIG_ACPI_CCA_REQUIRED=y -# CONFIG_ACPI_DEBUGGER is not set -CONFIG_ACPI_SPCR_TABLE=y -# CONFIG_ACPI_EC_DEBUGFS is not set -CONFIG_ACPI_BUTTON=y -CONFIG_ACPI_FAN=y -# CONFIG_ACPI_DOCK is not set -CONFIG_ACPI_PROCESSOR_IDLE=y -CONFIG_ACPI_MCFG=y -CONFIG_ACPI_PROCESSOR=y -CONFIG_ACPI_HOTPLUG_CPU=y -CONFIG_ACPI_THERMAL=y -# CONFIG_ACPI_CUSTOM_DSDT is not set -CONFIG_ARCH_HAS_ACPI_TABLE_UPGRADE=y -CONFIG_ACPI_TABLE_UPGRADE=y -# CONFIG_ACPI_DEBUG is not set -# CONFIG_ACPI_PCI_SLOT is not set -CONFIG_ACPI_CONTAINER=y -# CONFIG_ACPI_HED is not set -# CONFIG_ACPI_CUSTOM_METHOD is not set -# CONFIG_ACPI_BGRT is not set -CONFIG_ACPI_REDUCED_HARDWARE_ONLY=y -CONFIG_HAVE_ACPI_APEI=y -# CONFIG_ACPI_APEI is not set -# CONFIG_PMIC_OPREGION is not set -# CONFIG_ACPI_CONFIGFS is not set -CONFIG_ACPI_IORT=y -CONFIG_ACPI_GTDT=y +CONFIG_ACPI_APEI=y +CONFIG_ACPI_APEI_GHES=y +CONFIG_ACPI_APEI_MEMORY_FAILURE=y +CONFIG_ACPI_APEI_EINJ=y # # File systems # -CONFIG_DCACHE_WORD_ACCESS=y -# CONFIG_EXT2_FS is not set -# CONFIG_EXT3_FS is not set -CONFIG_EXT4_FS=y -CONFIG_EXT4_USE_FOR_EXT2=y +CONFIG_EXT2_FS=y +CONFIG_EXT3_FS=y CONFIG_EXT4_FS_POSIX_ACL=y -# CONFIG_EXT4_FS_SECURITY is not set -# 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 is not set -# CONFIG_JFS_FS is not set -# CONFIG_XFS_FS is not set -# CONFIG_GFS2_FS is not set -# CONFIG_OCFS2_FS is not set -# CONFIG_BTRFS_FS is not set -# CONFIG_NILFS2_FS is not set -# CONFIG_F2FS_FS is not set -# CONFIG_FS_DAX 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 is not set -CONFIG_FSNOTIFY=y -CONFIG_DNOTIFY=y -CONFIG_INOTIFY_USER=y +CONFIG_EXT4_FS_SECURITY=y +CONFIG_REISERFS_FS=m +# CONFIG_REISERFS_CHECK is not set +CONFIG_REISERFS_PROC_INFO=y +CONFIG_REISERFS_FS_XATTR=y +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y +CONFIG_XFS_FS=m +CONFIG_XFS_QUOTA=y +CONFIG_XFS_POSIX_ACL=y +# CONFIG_XFS_RT is not set +# CONFIG_XFS_ONLINE_SCRUB is not set +# CONFIG_XFS_WARN is not set +# CONFIG_XFS_DEBUG is not set +CONFIG_BTRFS_FS=m +CONFIG_BTRFS_FS_POSIX_ACL=y +CONFIG_F2FS_FS=m +CONFIG_F2FS_STAT_FS=y +CONFIG_F2FS_FS_XATTR=y +# CONFIG_F2FS_FS_POSIX_ACL is not set +# CONFIG_F2FS_FS_SECURITY is not set +# CONFIG_F2FS_CHECK_FS is not set +# CONFIG_F2FS_FS_ENCRYPTION is not set +# CONFIG_F2FS_IO_TRACE is not set +# CONFIG_F2FS_FAULT_INJECTION is not set CONFIG_FANOTIFY=y CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y CONFIG_QUOTA=y -# CONFIG_QUOTA_NETLINK_INTERFACE is not set -# CONFIG_PRINT_QUOTA_WARNING is not set -# CONFIG_QUOTA_DEBUG is not set -# CONFIG_QFMT_V1 is not set -# CONFIG_QFMT_V2 is not set -CONFIG_QUOTACTL=y -# CONFIG_AUTOFS4_FS is not set -# CONFIG_FUSE_FS is not set -# CONFIG_OVERLAY_FS is not set +CONFIG_QUOTA_TREE=y +CONFIG_QFMT_V2=y +CONFIG_AUTOFS4_FS=y +CONFIG_FUSE_FS=m +CONFIG_CUSE=m +CONFIG_OVERLAY_FS=m # # Caches # -# CONFIG_FSCACHE is not set +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 is not set -# CONFIG_UDF_FS is not set +CONFIG_ISO9660_FS=m +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +CONFIG_UDF_FS=m +CONFIG_UDF_NLS=y # # DOS/FAT/NT Filesystems # -CONFIG_FAT_FS=y -# CONFIG_MSDOS_FS is not set +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 is not set +CONFIG_NTFS_FS=m +# CONFIG_NTFS_DEBUG is not set +CONFIG_NTFS_RW=y # # Pseudo filesystems # -CONFIG_PROC_FS=y -# CONFIG_PROC_KCORE is not set -CONFIG_PROC_SYSCTL=y -CONFIG_PROC_PAGE_MONITOR=y -# CONFIG_PROC_CHILDREN is not set -CONFIG_KERNFS=y -CONFIG_SYSFS=y +CONFIG_PROC_KCORE=y CONFIG_TMPFS=y -# CONFIG_TMPFS_POSIX_ACL is not set -# CONFIG_TMPFS_XATTR is not set +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_TMPFS_XATTR=y CONFIG_HUGETLBFS=y -CONFIG_HUGETLB_PAGE=y -CONFIG_ARCH_HAS_GIGANTIC_PAGE=y CONFIG_CONFIGFS_FS=y CONFIG_EFIVAR_FS=y -# CONFIG_MISC_FILESYSTEMS is not set -# CONFIG_NETWORK_FILESYSTEMS is not set -CONFIG_NLS=y -CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_ECRYPT_FS=m +CONFIG_ECRYPT_FS_MESSAGING=y +CONFIG_HFS_FS=m +CONFIG_HFSPLUS_FS=m +# CONFIG_HFSPLUS_FS_POSIX_ACL is not set +CONFIG_CRAMFS=y +CONFIG_CRAMFS_BLOCKDEV=y +# CONFIG_CRAMFS_MTD is not set +CONFIG_SQUASHFS=y +CONFIG_SQUASHFS_XATTR=y +CONFIG_SQUASHFS_LZO=y +CONFIG_SQUASHFS_XZ=y +# CONFIG_PSTORE_FTRACE is not set +CONFIG_NFS_FS=y +CONFIG_NFS_V4=y +CONFIG_NFS_V4_1=y +CONFIG_NFS_V4_2=y +CONFIG_PNFS_BLOCK=m +CONFIG_ROOT_NFS=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_SECURITY_LABEL is not set +# CONFIG_NFSD_FAULT_INJECTION is not set +CONFIG_NFS_ACL_SUPPORT=m +CONFIG_RPCSEC_GSS_KRB5=m +CONFIG_CIFS=m +# CONFIG_CIFS_STATS is not set +# CONFIG_CIFS_WEAK_PW_HASH is not set +# CONFIG_CIFS_UPCALL is not set +CONFIG_CIFS_XATTR=y +# CONFIG_CIFS_POSIX is not set +# CONFIG_CIFS_ACL is not set +CONFIG_CIFS_DEBUG=y +# CONFIG_CIFS_DEBUG2 is not set +# CONFIG_CIFS_DEBUG_DUMP_KEYS is not set +CONFIG_CIFS_DFS_UPCALL=y +# CONFIG_CIFS_SMB311 is not set +# CONFIG_CIFS_FSCACHE is not set +CONFIG_9P_FS=y CONFIG_NLS_CODEPAGE_437=y -# CONFIG_NLS_CODEPAGE_737 is not set -# CONFIG_NLS_CODEPAGE_775 is not set -# CONFIG_NLS_CODEPAGE_850 is not set -# 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 is not set 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 is not set -# CONFIG_DLM is not set -# CONFIG_VIRTUALIZATION is not set +CONFIG_NLS_UTF8=y +CONFIG_VIRTUALIZATION=y +CONFIG_KVM=y # # Kernel hacking @@ -4177,445 +3165,160 @@ CONFIG_NLS_ISO8859_1=y # printk and dmesg options # CONFIG_PRINTK_TIME=y -CONFIG_CONSOLE_LOGLEVEL_DEFAULT=7 -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=y -# CONFIG_DEBUG_INFO_REDUCED is not set -# CONFIG_DEBUG_INFO_SPLIT is not set -# CONFIG_DEBUG_INFO_DWARF4 is not set -# CONFIG_GDB_SCRIPTS is not set -CONFIG_ENABLE_WARN_DEPRECATED=y -CONFIG_ENABLE_MUST_CHECK=y -CONFIG_FRAME_WARN=2048 -# 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_ARCH_WANT_FRAME_POINTERS=y -CONFIG_FRAME_POINTER=y -# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set CONFIG_MAGIC_SYSRQ=y -CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0x1 -CONFIG_MAGIC_SYSRQ_SERIAL=y CONFIG_DEBUG_KERNEL=y # # Memory Debugging # -# CONFIG_PAGE_EXTENSION is not set -# CONFIG_DEBUG_PAGEALLOC is not set -# CONFIG_PAGE_POISONING 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_DEBUG_VM is not set -CONFIG_ARCH_HAS_DEBUG_VIRTUAL=y -# CONFIG_DEBUG_VIRTUAL is not set -CONFIG_DEBUG_MEMORY_INIT=y -# CONFIG_DEBUG_PER_CPU_MAPS is not set -CONFIG_HAVE_ARCH_KASAN=y -# CONFIG_KASAN is not set -CONFIG_ARCH_HAS_KCOV=y -# CONFIG_KCOV is not set -# CONFIG_DEBUG_SHIRQ is not set +# CONFIG_DEBUG_PAGE_REF is not set # # Debug Lockups and Hangs # -# CONFIG_SOFTLOCKUP_DETECTOR is not set -CONFIG_DETECT_HUNG_TASK=y -CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=120 -# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set -CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 -# CONFIG_WQ_WATCHDOG is not set -# CONFIG_PANIC_ON_OOPS is not set -CONFIG_PANIC_ON_OOPS_VALUE=0 -CONFIG_PANIC_TIMEOUT=0 # CONFIG_SCHED_DEBUG is not set -CONFIG_SCHED_INFO=y -# CONFIG_SCHEDSTATS is not set -# CONFIG_SCHED_STACK_END_CHECK is not set -# CONFIG_DEBUG_TIMEKEEPING is not set +CONFIG_SCHEDSTATS=y # CONFIG_DEBUG_PREEMPT is not set # # Lock Debugging (spinlocks, mutexes, etc...) # -# CONFIG_DEBUG_RT_MUTEXES is not set -# CONFIG_DEBUG_SPINLOCK is not set -# CONFIG_DEBUG_MUTEXES is not set -# CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set -# CONFIG_DEBUG_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_WW_MUTEX_SELFTEST is not set -# CONFIG_STACKTRACE is not set -# CONFIG_WARN_ALL_UNSEEDED_RANDOM is not set -# CONFIG_DEBUG_KOBJECT is not set -CONFIG_HAVE_DEBUG_BUGVERBOSE=y -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 is not set +CONFIG_STACKTRACE=y # # RCU Debugging # -# CONFIG_PROVE_RCU is not set -# CONFIG_TORTURE_TEST is not set -# CONFIG_RCU_PERF_TEST is not set -# CONFIG_RCU_TORTURE_TEST is not set -CONFIG_RCU_CPU_STALL_TIMEOUT=21 -# CONFIG_RCU_TRACE is not set -# CONFIG_RCU_EQS_DEBUG is not set -# 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_NOTIFIER_ERROR_INJECTION is not set -# CONFIG_FAULT_INJECTION is not set -# CONFIG_LATENCYTOP is not set -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_TRACING_SUPPORT=y -# CONFIG_FTRACE is not set -# CONFIG_DMA_API_DEBUG is not set - -# -# Runtime Testing -# -# CONFIG_LKDTM is not set -# CONFIG_TEST_LIST_SORT is not set -# CONFIG_TEST_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_BITMAP is not set -# CONFIG_TEST_UUID is not set -# CONFIG_TEST_RHASHTABLE is not set -# CONFIG_TEST_HASH 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_SYSCTL is not set -# CONFIG_TEST_UDELAY is not set -# CONFIG_TEST_STATIC_KEYS is not set -# CONFIG_TEST_KMOD is not set +CONFIG_NOP_TRACER=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_FTRACE=y +CONFIG_FUNCTION_TRACER=y +CONFIG_FUNCTION_GRAPH_TRACER=y +# 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=y +# 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=y +# CONFIG_BLK_DEV_IO_TRACE is not set +CONFIG_UPROBE_EVENTS=y +CONFIG_PROBE_EVENTS=y +CONFIG_DYNAMIC_FTRACE=y +CONFIG_FUNCTION_PROFILER=y +CONFIG_FTRACE_MCOUNT_RECORD=y +# CONFIG_FTRACE_STARTUP_TEST is not set +# CONFIG_HIST_TRIGGERS 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_EVAL_MAP_FILE is not set +CONFIG_TRACING_EVENTS_GPIO=y +# CONFIG_ASYNC_RAID6_TEST is not set CONFIG_MEMTEST=y -# CONFIG_BUG_ON_DATA_CORRUPTION is not set -# CONFIG_SAMPLES is not set -CONFIG_HAVE_ARCH_KGDB=y -# CONFIG_KGDB is not set -CONFIG_ARCH_HAS_UBSAN_SANITIZE_ALL=y -# CONFIG_ARCH_WANTS_UBSAN_NO_NULL is not set -# CONFIG_UBSAN is not set -CONFIG_ARCH_HAS_DEVMEM_IS_ALLOWED=y -# CONFIG_STRICT_DEVMEM is not set -# CONFIG_ARM64_PTDUMP_CORE is not set -# CONFIG_ARM64_PTDUMP_DEBUGFS is not set -# CONFIG_PID_IN_CONTEXTIDR is not set -# CONFIG_ARM64_RANDOMIZE_TEXT_OFFSET is not set -# CONFIG_DEBUG_WX is not set -# CONFIG_DEBUG_ALIGN_RODATA is not set -# CONFIG_DEBUG_EFI is not set -# CONFIG_ARM64_RELOC_TEST is not set -# CONFIG_CORESIGHT is not set +CONFIG_KGDB=y +CONFIG_KGDB_SERIAL_CONSOLE=y +CONFIG_KGDB_TESTS=y +# CONFIG_KGDB_TESTS_ON_BOOT is not set +# CONFIG_KGDB_KDB is not set # # Security options # -CONFIG_KEYS=y -CONFIG_KEYS_COMPAT=y -# CONFIG_PERSISTENT_KEYRINGS is not set # CONFIG_BIG_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_SECURITY_WRITABLE_HOOKS is not set -# CONFIG_SECURITYFS is not set -# CONFIG_SECURITY_NETWORK is not set -# CONFIG_SECURITY_PATH is not set -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_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 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_DEFAULT_SECURITY="" -CONFIG_CRYPTO=y +CONFIG_ASYNC_CORE=m +CONFIG_ASYNC_MEMCPY=m +CONFIG_ASYNC_XOR=m +CONFIG_ASYNC_PQ=m +CONFIG_ASYNC_RAID6_RECOV=m # # 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_AKCIPHER2=y -CONFIG_CRYPTO_KPP2=y -CONFIG_CRYPTO_ACOMP2=y -# CONFIG_CRYPTO_RSA is not set -# CONFIG_CRYPTO_DH is not set -CONFIG_CRYPTO_ECDH=m -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=y -# CONFIG_CRYPTO_MCRYPTD is not set -CONFIG_CRYPTO_AUTHENC=m -# CONFIG_CRYPTO_TEST is not set -CONFIG_CRYPTO_SIMD=y -CONFIG_CRYPTO_ENGINE=m +CONFIG_CRYPTO_AUTHENC=y # # Authenticated Encryption with Associated Data # -CONFIG_CRYPTO_CCM=m -CONFIG_CRYPTO_GCM=m -# CONFIG_CRYPTO_CHACHA20POLY1305 is not set -CONFIG_CRYPTO_SEQIV=m CONFIG_CRYPTO_ECHAINIV=y # # Block modes # -# CONFIG_CRYPTO_CBC is not set -CONFIG_CRYPTO_CTR=m -# CONFIG_CRYPTO_CTS is not set -CONFIG_CRYPTO_ECB=m -# CONFIG_CRYPTO_LRW is not set -# CONFIG_CRYPTO_PCBC is not set -# CONFIG_CRYPTO_XTS is not set -# CONFIG_CRYPTO_KEYWRAP is not set +CONFIG_CRYPTO_CBC=y +CONFIG_CRYPTO_CTS=m # # Hash modes # -CONFIG_CRYPTO_CMAC=m -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_CRC32=m CONFIG_CRYPTO_CRCT10DIF=y -CONFIG_CRYPTO_GHASH=m -# CONFIG_CRYPTO_POLY1305 is not set -# CONFIG_CRYPTO_MD4 is not set -CONFIG_CRYPTO_MD5=m -# CONFIG_CRYPTO_MICHAEL_MIC is not set -# 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_MD4=m +CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_SHA512=m -# CONFIG_CRYPTO_SHA3 is not set -# CONFIG_CRYPTO_TGR192 is not set -# CONFIG_CRYPTO_WP512 is not set # # Ciphers # -CONFIG_CRYPTO_AES=y -# CONFIG_CRYPTO_AES_TI is not set -# CONFIG_CRYPTO_ANUBIS is not set -CONFIG_CRYPTO_ARC4=m -# 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=m -# 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 +CONFIG_CRYPTO_DES=y # # Compression # -# CONFIG_CRYPTO_DEFLATE is not set -# CONFIG_CRYPTO_LZO is not set -# CONFIG_CRYPTO_842 is not set -# CONFIG_CRYPTO_LZ4 is not set -# CONFIG_CRYPTO_LZ4HC is not set +CONFIG_CRYPTO_DEFLATE=m # # Random Number Generation # CONFIG_CRYPTO_ANSI_CPRNG=y -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_HASH is not set -# CONFIG_CRYPTO_USER_API_SKCIPHER is not set -# CONFIG_CRYPTO_USER_API_RNG is not set -# CONFIG_CRYPTO_USER_API_AEAD is not set -CONFIG_CRYPTO_HW=y -# CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_DESC is not set -# CONFIG_CRYPTO_DEV_CCP is not set -# CONFIG_CRYPTO_DEV_NITROX_CNN55XX is not set -# CONFIG_CRYPTO_DEV_CAVIUM_ZIP is not set -CONFIG_CRYPTO_DEV_VIRTIO=m -# CONFIG_ASYMMETRIC_KEY_TYPE is not set # # Certificates for signature checking # -# CONFIG_SYSTEM_BLACKLIST_KEYRING is not set CONFIG_ARM64_CRYPTO=y CONFIG_CRYPTO_SHA256_ARM64=y -# CONFIG_CRYPTO_SHA512_ARM64 is not set +CONFIG_CRYPTO_SHA512_ARM64=m CONFIG_CRYPTO_SHA1_ARM64_CE=y CONFIG_CRYPTO_SHA2_ARM64_CE=y CONFIG_CRYPTO_GHASH_ARM64_CE=y -# CONFIG_CRYPTO_CRCT10DIF_ARM64_CE is not set -# CONFIG_CRYPTO_CRC32_ARM64_CE is not set +CONFIG_CRYPTO_CRCT10DIF_ARM64_CE=m +CONFIG_CRYPTO_CRC32_ARM64_CE=m CONFIG_CRYPTO_AES_ARM64=y CONFIG_CRYPTO_AES_ARM64_CE=y CONFIG_CRYPTO_AES_ARM64_CE_CCM=y CONFIG_CRYPTO_AES_ARM64_CE_BLK=y -# CONFIG_CRYPTO_AES_ARM64_NEON_BLK is not set -# CONFIG_CRYPTO_CHACHA20_NEON is not set -# CONFIG_CRYPTO_AES_ARM64_BS is not set -# CONFIG_BINARY_PRINTF is not set +CONFIG_CRYPTO_AES_ARM64_NEON_BLK=m +CONFIG_CRYPTO_CHACHA20_NEON=m +CONFIG_CRYPTO_AES_ARM64_BS=m +CONFIG_BINARY_PRINTF=y # # Library routines # -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 is not set -CONFIG_CRC16=y +CONFIG_CRC_CCITT=m 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_CRC4 is not set CONFIG_CRC7=y -CONFIG_LIBCRC32C=m -# CONFIG_CRC8 is not set -CONFIG_AUDIT_GENERIC=y -CONFIG_AUDIT_ARCH_COMPAT_GENERIC=y -CONFIG_AUDIT_COMPAT_GENERIC=y -# CONFIG_RANDOM32_SELFTEST is not set -CONFIG_ZLIB_INFLATE=y -CONFIG_LZO_COMPRESS=y -CONFIG_LZO_DECOMPRESS=y -CONFIG_LZ4_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_RADIX_TREE_MULTIORDER=y -CONFIG_ASSOCIATIVE_ARRAY=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT_MAP=y -CONFIG_HAS_DMA=y -# CONFIG_DMA_NOOP_OPS is not set -# CONFIG_DMA_VIRT_OPS is not set -CONFIG_CPU_RMAP=y -CONFIG_DQL=y -CONFIG_GLOB=y -# CONFIG_GLOB_SELFTEST is not set -CONFIG_NLATTR=y -# CONFIG_CORDIC is not set -# CONFIG_DDR is not set -# CONFIG_IRQ_POLL is not set -CONFIG_LIBFDT=y -CONFIG_UCS2_STRING=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_SG_POOL=y -CONFIG_ARCH_HAS_SG_CHAIN=y -CONFIG_SBITMAP=y -# CONFIG_STRING_SELFTEST is not set +CONFIG_TEXTSEARCH=y +CONFIG_TEXTSEARCH_KMP=m +CONFIG_TEXTSEARCH_BM=m +CONFIG_TEXTSEARCH_FSM=m diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/README b/buildroot-external/board/hardkernel/odroid-c2/patches/README index 2921b8a94..0eafac24c 100644 --- a/buildroot-external/board/hardkernel/odroid-c2/patches/README +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/README @@ -1,2 +1,2 @@ -kernel patches from -https://github.com/superna9999/meta-meson/tree/sumo/recipes-kernel/linux/linux-yocto-meson64-4.14 +kernel patches from scpcom +https://forum.odroid.com/viewtopic.php?f=135&t=22717&start=900#p233963 diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/000_arm64-set-default-target-to-Image.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/000_arm64-set-default-target-to-Image.patch new file mode 100644 index 000000000..51bf570c2 --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/000_arm64-set-default-target-to-Image.patch @@ -0,0 +1,13 @@ +diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile +index f839ecd9..cd276162 100644 +--- a/arch/arm64/Makefile ++++ b/arch/arm64/Makefile +@@ -103,7 +103,7 @@ core-$(CONFIG_EFI_STUB) += $(objtree)/drivers/firmware/efi/libstub/lib.a + + # Default target when executing plain make + boot := arch/arm64/boot +-KBUILD_IMAGE := $(boot)/Image.gz ++KBUILD_IMAGE := $(boot)/Image + KBUILD_DTBS := dtbs + + all: Image.gz $(KBUILD_DTBS) diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/001_linux-4.18.y-v4l-0001-dt-bindings-soc-amlogic-add_meson-canvas_documentation.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/001_linux-4.18.y-v4l-0001-dt-bindings-soc-amlogic-add_meson-canvas_documentation.patch new file mode 100644 index 000000000..8e0675a2b --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/001_linux-4.18.y-v4l-0001-dt-bindings-soc-amlogic-add_meson-canvas_documentation.patch @@ -0,0 +1,49 @@ +From 4796e434b5785e3d9f95e988363c407b1e09bb91 Mon Sep 17 00:00:00 2001 +From: Maxime Jourdan +Date: Sat, 28 Jul 2018 22:40:27 +0200 +Subject: [PATCH] dt-bindings: soc: amlogic: add meson-canvas documentation + +DT bindings doc for amlogic,meson-canvas + +Reviewed-by: Jerome Brunet +Signed-off-by: Maxime Jourdan +--- + .../bindings/soc/amlogic/amlogic,canvas.txt | 29 +++++++++++++++++++ + 1 file changed, 29 insertions(+) + create mode 100644 Documentation/devicetree/bindings/soc/amlogic/amlogic,canvas.txt + +diff --git a/Documentation/devicetree/bindings/soc/amlogic/amlogic,canvas.txt b/Documentation/devicetree/bindings/soc/amlogic/amlogic,canvas.txt +new file mode 100644 +index 0000000000000..436d2106e80da +--- /dev/null ++++ b/Documentation/devicetree/bindings/soc/amlogic/amlogic,canvas.txt +@@ -0,0 +1,29 @@ ++Amlogic Canvas ++================================ ++ ++A canvas is a collection of metadata that describes a pixel buffer. ++Those metadata include: width, height, phyaddr, wrapping, block mode ++and endianness. ++ ++Many IPs within Amlogic SoCs rely on canvas indexes to read/write pixel data ++rather than use the phy addresses directly. For instance, this is the case for ++the video decoders and the display. ++ ++Amlogic SoCs have 256 canvas. ++ ++Device Tree Bindings: ++--------------------- ++ ++Video Lookup Table ++-------------------------- ++ ++Required properties: ++- compatible: "amlogic,canvas" ++- reg: Base physical address and size of the canvas registers. ++ ++Example: ++ ++canvas: video-lut@48 { ++ compatible = "amlogic,canvas"; ++ reg = <0x0 0x48 0x0 0x14>; ++}; diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/002_linux-4.18.y-v4l-0002-soc-amlogic-add_meson-canvas_driver.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/002_linux-4.18.y-v4l-0002-soc-amlogic-add_meson-canvas_driver.patch new file mode 100644 index 000000000..e09fd826d --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/002_linux-4.18.y-v4l-0002-soc-amlogic-add_meson-canvas_driver.patch @@ -0,0 +1,313 @@ +From 21c3e7d31208b0c4fb4a6c0a8c52e6820a40596a Mon Sep 17 00:00:00 2001 +From: Maxime Jourdan +Date: Fri, 20 Apr 2018 13:17:07 +0200 +Subject: [PATCH] soc: amlogic: add meson-canvas driver + +Amlogic SoCs have a repository of 256 canvas which they use to +describe pixel buffers. + +They contain metadata like width, height, block mode, endianness [..] + +Many IPs within those SoCs like vdec/vpu rely on those canvas to read/write +pixels. + +Reviewed-by: Jerome Brunet +Tested-by: Neil Armstrong +Signed-off-by: Maxime Jourdan +--- + drivers/soc/amlogic/Kconfig | 7 + + drivers/soc/amlogic/Makefile | 1 + + drivers/soc/amlogic/meson-canvas.c | 185 +++++++++++++++++++++++ + include/linux/soc/amlogic/meson-canvas.h | 65 ++++++++ + 4 files changed, 258 insertions(+) + create mode 100644 drivers/soc/amlogic/meson-canvas.c + create mode 100644 include/linux/soc/amlogic/meson-canvas.h + +diff --git a/drivers/soc/amlogic/Kconfig b/drivers/soc/amlogic/Kconfig +index b04f6e4aedbc1..2f282b4729120 100644 +--- a/drivers/soc/amlogic/Kconfig ++++ b/drivers/soc/amlogic/Kconfig +@@ -1,5 +1,12 @@ + menu "Amlogic SoC drivers" + ++config MESON_CANVAS ++ tristate "Amlogic Meson Canvas driver" ++ depends on ARCH_MESON || COMPILE_TEST ++ default n ++ help ++ Say yes to support the canvas IP for Amlogic SoCs. ++ + config MESON_GX_SOCINFO + bool "Amlogic Meson GX SoC Information driver" + depends on ARCH_MESON || COMPILE_TEST +diff --git a/drivers/soc/amlogic/Makefile b/drivers/soc/amlogic/Makefile +index 8fa321893928d..0ab16d35ac36d 100644 +--- a/drivers/soc/amlogic/Makefile ++++ b/drivers/soc/amlogic/Makefile +@@ -1,3 +1,4 @@ ++obj-$(CONFIG_MESON_CANVAS) += meson-canvas.o + obj-$(CONFIG_MESON_GX_SOCINFO) += meson-gx-socinfo.o + obj-$(CONFIG_MESON_GX_PM_DOMAINS) += meson-gx-pwrc-vpu.o + obj-$(CONFIG_MESON_MX_SOCINFO) += meson-mx-socinfo.o +diff --git a/drivers/soc/amlogic/meson-canvas.c b/drivers/soc/amlogic/meson-canvas.c +new file mode 100644 +index 0000000000000..fce33ca76bb62 +--- /dev/null ++++ b/drivers/soc/amlogic/meson-canvas.c +@@ -0,0 +1,185 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright (C) 2018 BayLibre, SAS ++ * Copyright (C) 2015 Amlogic, Inc. All rights reserved. ++ * Copyright (C) 2014 Endless Mobile ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define NUM_CANVAS 256 ++ ++/* DMC Registers */ ++#define DMC_CAV_LUT_DATAL 0x00 ++ #define CANVAS_WIDTH_LBIT 29 ++ #define CANVAS_WIDTH_LWID 3 ++#define DMC_CAV_LUT_DATAH 0x04 ++ #define CANVAS_WIDTH_HBIT 0 ++ #define CANVAS_HEIGHT_BIT 9 ++ #define CANVAS_WRAP_BIT 22 ++ #define CANVAS_BLKMODE_BIT 24 ++ #define CANVAS_ENDIAN_BIT 26 ++#define DMC_CAV_LUT_ADDR 0x08 ++ #define CANVAS_LUT_WR_EN BIT(9) ++ #define CANVAS_LUT_RD_EN BIT(8) ++ ++struct meson_canvas { ++ struct device *dev; ++ void __iomem *reg_base; ++ spinlock_t lock; /* canvas device lock */ ++ u8 used[NUM_CANVAS]; ++}; ++ ++static void canvas_write(struct meson_canvas *canvas, u32 reg, u32 val) ++{ ++ writel_relaxed(val, canvas->reg_base + reg); ++} ++ ++static u32 canvas_read(struct meson_canvas *canvas, u32 reg) ++{ ++ return readl_relaxed(canvas->reg_base + reg); ++} ++ ++struct meson_canvas *meson_canvas_get(struct device *dev) ++{ ++ struct device_node *canvas_node; ++ struct platform_device *canvas_pdev; ++ ++ canvas_node = of_parse_phandle(dev->of_node, "amlogic,canvas", 0); ++ if (!canvas_node) ++ return ERR_PTR(-ENODEV); ++ ++ canvas_pdev = of_find_device_by_node(canvas_node); ++ if (!canvas_pdev) ++ return ERR_PTR(-EPROBE_DEFER); ++ ++ return dev_get_drvdata(&canvas_pdev->dev); ++} ++EXPORT_SYMBOL_GPL(meson_canvas_get); ++ ++int meson_canvas_config(struct meson_canvas *canvas, u8 canvas_index, ++ u32 addr, u32 stride, u32 height, ++ unsigned int wrap, ++ unsigned int blkmode, ++ unsigned int endian) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&canvas->lock, flags); ++ if (!canvas->used[canvas_index]) { ++ dev_err(canvas->dev, ++ "Trying to setup non allocated canvas %u\n", ++ canvas_index); ++ spin_unlock_irqrestore(&canvas->lock, flags); ++ return -EINVAL; ++ } ++ ++ canvas_write(canvas, DMC_CAV_LUT_DATAL, ++ ((addr + 7) >> 3) | ++ (((stride + 7) >> 3) << CANVAS_WIDTH_LBIT)); ++ ++ canvas_write(canvas, DMC_CAV_LUT_DATAH, ++ ((((stride + 7) >> 3) >> CANVAS_WIDTH_LWID) << ++ CANVAS_WIDTH_HBIT) | ++ (height << CANVAS_HEIGHT_BIT) | ++ (wrap << CANVAS_WRAP_BIT) | ++ (blkmode << CANVAS_BLKMODE_BIT) | ++ (endian << CANVAS_ENDIAN_BIT)); ++ ++ canvas_write(canvas, DMC_CAV_LUT_ADDR, ++ CANVAS_LUT_WR_EN | canvas_index); ++ ++ /* Force a read-back to make sure everything is flushed. */ ++ canvas_read(canvas, DMC_CAV_LUT_DATAH); ++ spin_unlock_irqrestore(&canvas->lock, flags); ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(meson_canvas_config); ++ ++int meson_canvas_alloc(struct meson_canvas *canvas, u8 *canvas_index) ++{ ++ int i; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&canvas->lock, flags); ++ for (i = 0; i < NUM_CANVAS; ++i) { ++ if (!canvas->used[i]) { ++ canvas->used[i] = 1; ++ spin_unlock_irqrestore(&canvas->lock, flags); ++ *canvas_index = i; ++ return 0; ++ } ++ } ++ spin_unlock_irqrestore(&canvas->lock, flags); ++ ++ dev_err(canvas->dev, "No more canvas available\n"); ++ return -ENODEV; ++} ++EXPORT_SYMBOL_GPL(meson_canvas_alloc); ++ ++int meson_canvas_free(struct meson_canvas *canvas, u8 canvas_index) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&canvas->lock, flags); ++ if (!canvas->used[canvas_index]) { ++ dev_err(canvas->dev, ++ "Trying to free unused canvas %u\n", canvas_index); ++ spin_unlock_irqrestore(&canvas->lock, flags); ++ return -EINVAL; ++ } ++ canvas->used[canvas_index] = 0; ++ spin_unlock_irqrestore(&canvas->lock, flags); ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(meson_canvas_free); ++ ++static int meson_canvas_probe(struct platform_device *pdev) ++{ ++ struct resource *res; ++ struct meson_canvas *canvas; ++ struct device *dev = &pdev->dev; ++ ++ canvas = devm_kzalloc(dev, sizeof(*canvas), GFP_KERNEL); ++ if (!canvas) ++ return -ENOMEM; ++ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ canvas->reg_base = devm_ioremap_resource(dev, res); ++ if (IS_ERR(canvas->reg_base)) ++ return PTR_ERR(canvas->reg_base); ++ ++ canvas->dev = dev; ++ spin_lock_init(&canvas->lock); ++ dev_set_drvdata(dev, canvas); ++ ++ return 0; ++} ++ ++static const struct of_device_id canvas_dt_match[] = { ++ { .compatible = "amlogic,canvas" }, ++ {} ++}; ++MODULE_DEVICE_TABLE(of, canvas_dt_match); ++ ++static struct platform_driver meson_canvas_driver = { ++ .probe = meson_canvas_probe, ++ .driver = { ++ .name = "amlogic-canvas", ++ .of_match_table = canvas_dt_match, ++ }, ++}; ++module_platform_driver(meson_canvas_driver); ++ ++MODULE_DESCRIPTION("Amlogic Canvas driver"); ++MODULE_AUTHOR("Maxime Jourdan "); ++MODULE_LICENSE("GPL"); +diff --git a/include/linux/soc/amlogic/meson-canvas.h b/include/linux/soc/amlogic/meson-canvas.h +new file mode 100644 +index 0000000000000..b4dde2fbeb3fb +--- /dev/null ++++ b/include/linux/soc/amlogic/meson-canvas.h +@@ -0,0 +1,65 @@ ++/* SPDX-License-Identifier: GPL-2.0+ */ ++/* ++ * Copyright (C) 2018 BayLibre, SAS ++ */ ++#ifndef __SOC_MESON_CANVAS_H ++#define __SOC_MESON_CANVAS_H ++ ++#include ++ ++#define MESON_CANVAS_WRAP_NONE 0x00 ++#define MESON_CANVAS_WRAP_X 0x01 ++#define MESON_CANVAS_WRAP_Y 0x02 ++ ++#define MESON_CANVAS_BLKMODE_LINEAR 0x00 ++#define MESON_CANVAS_BLKMODE_32x32 0x01 ++#define MESON_CANVAS_BLKMODE_64x64 0x02 ++ ++#define MESON_CANVAS_ENDIAN_SWAP16 0x1 ++#define MESON_CANVAS_ENDIAN_SWAP32 0x3 ++#define MESON_CANVAS_ENDIAN_SWAP64 0x7 ++#define MESON_CANVAS_ENDIAN_SWAP128 0xf ++ ++struct meson_canvas; ++ ++/** ++ * meson_canvas_get() - get a canvas provider instance ++ * ++ * @dev: consumer device pointer ++ */ ++struct meson_canvas *meson_canvas_get(struct device *dev); ++ ++/** ++ * meson_canvas_alloc() - take ownership of a canvas ++ * ++ * @canvas: canvas provider instance retrieved from meson_canvas_get() ++ * @canvas_index: will be filled with the canvas ID ++ */ ++int meson_canvas_alloc(struct meson_canvas *canvas, u8 *canvas_index); ++ ++/** ++ * meson_canvas_free() - remove ownership from a canvas ++ * ++ * @canvas: canvas provider instance retrieved from meson_canvas_get() ++ * @canvas_index: canvas ID that was obtained via meson_canvas_alloc() ++ */ ++int meson_canvas_free(struct meson_canvas *canvas, u8 canvas_index); ++ ++/** ++ * meson_canvas_config() - configure a canvas ++ * ++ * @canvas: canvas provider instance retrieved from meson_canvas_get() ++ * @canvas_index: canvas ID that was obtained via meson_canvas_alloc() ++ * @addr: physical address to the pixel buffer ++ * @stride: width of the buffer ++ * @height: height of the buffer ++ * @wrap: undocumented ++ * @blkmode: block mode (linear, 32x32, 64x64) ++ * @endian: byte swapping (swap16, swap32, swap64, swap128) ++ */ ++int meson_canvas_config(struct meson_canvas *canvas, u8 canvas_index, ++ u32 addr, u32 stride, u32 height, ++ unsigned int wrap, unsigned int blkmode, ++ unsigned int endian); ++ ++#endif diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/003_linux-4.18.y-v4l-0003-arm64-dts-meson-gx-add_dmcbus_and_canvas_nodes..patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/003_linux-4.18.y-v4l-0003-arm64-dts-meson-gx-add_dmcbus_and_canvas_nodes..patch new file mode 100644 index 000000000..e148eb20f --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/003_linux-4.18.y-v4l-0003-arm64-dts-meson-gx-add_dmcbus_and_canvas_nodes..patch @@ -0,0 +1,38 @@ +From e4c19f493a541cd00df42c02ec8f544f9835cbe5 Mon Sep 17 00:00:00 2001 +From: Maxime Jourdan +Date: Fri, 20 Apr 2018 16:09:09 +0200 +Subject: [PATCH] ARM64: dts: meson-gx: add dmcbus and canvas nodes. + +DMC is a small memory region with various registers, +including the ones needed for the canvas module. + +Reviewed-by: Jerome Brunet +Signed-off-by: Maxime Jourdan +--- + arch/arm64/boot/dts/amlogic/meson-gx.dtsi | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi +index b8dc4dbb391b6..5dd63ecf8b05b 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi +@@ -423,6 +423,19 @@ + }; + }; + ++ dmcbus: bus@c8838000 { ++ compatible = "simple-bus"; ++ reg = <0x0 0xc8838000 0x0 0x400>; ++ #address-cells = <2>; ++ #size-cells = <2>; ++ ranges = <0x0 0x0 0x0 0xc8838000 0x0 0x400>; ++ ++ canvas: video-lut@48 { ++ compatible = "amlogic,canvas"; ++ reg = <0x0 0x48 0x0 0x14>; ++ }; ++ }; ++ + hiubus: bus@c883c000 { + compatible = "simple-bus"; + reg = <0x0 0xc883c000 0x0 0x2000>; diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/004_linux-4.18.y-v4l-0004-drm_meson-convert_to_the_new_canvas_module.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/004_linux-4.18.y-v4l-0004-drm_meson-convert_to_the_new_canvas_module.patch new file mode 100644 index 000000000..d7a91b420 --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/004_linux-4.18.y-v4l-0004-drm_meson-convert_to_the_new_canvas_module.patch @@ -0,0 +1,366 @@ +From 665dbad80386dcb9ac78ec6153d8d518da9bb50e Mon Sep 17 00:00:00 2001 +From: Maxime Jourdan +Date: Fri, 20 Apr 2018 16:22:17 +0200 +Subject: [PATCH] drm/meson: convert to the new canvas module + +This removes the meson_canvas files within the meson/drm layer +and makes use of the new canvas module that is referenced in the dts. + +Canvases can be used by different IPs and modules, and it is as such +preferable to rely on a module that can safely dispatch canvases on +demand. + +Signed-off-by: Maxime Jourdan +--- + .../bindings/display/amlogic,meson-vpu.txt | 9 +-- + arch/arm64/boot/dts/amlogic/meson-gx.dtsi | 7 +- + drivers/gpu/drm/meson/Kconfig | 1 + + drivers/gpu/drm/meson/Makefile | 2 +- + drivers/gpu/drm/meson/meson_canvas.c | 70 ------------------- + drivers/gpu/drm/meson/meson_canvas.h | 42 ----------- + drivers/gpu/drm/meson/meson_crtc.c | 9 ++- + drivers/gpu/drm/meson/meson_drv.c | 22 ++---- + drivers/gpu/drm/meson/meson_drv.h | 5 +- + drivers/gpu/drm/meson/meson_plane.c | 3 +- + drivers/gpu/drm/meson/meson_viu.c | 1 - + 11 files changed, 26 insertions(+), 145 deletions(-) + delete mode 100644 drivers/gpu/drm/meson/meson_canvas.c + delete mode 100644 drivers/gpu/drm/meson/meson_canvas.h + +diff --git a/Documentation/devicetree/bindings/display/amlogic,meson-vpu.txt b/Documentation/devicetree/bindings/display/amlogic,meson-vpu.txt +index 057b81335775e..60b6e13986365 100644 +--- a/Documentation/devicetree/bindings/display/amlogic,meson-vpu.txt ++++ b/Documentation/devicetree/bindings/display/amlogic,meson-vpu.txt +@@ -60,9 +60,9 @@ Required properties: + - reg: base address and size of he following memory-mapped regions : + - vpu + - hhi +- - dmc + - reg-names: should contain the names of the previous memory regions + - interrupts: should contain the VENC Vsync interrupt number ++- amlogic,canvas: should point to a meson canvas provider node + + Optional properties: + - power-domains: Optional phandle to associated power domain as described in +@@ -98,13 +98,14 @@ tv-connector { + vpu: vpu@d0100000 { + compatible = "amlogic,meson-gxbb-vpu"; + reg = <0x0 0xd0100000 0x0 0x100000>, +- <0x0 0xc883c000 0x0 0x1000>, +- <0x0 0xc8838000 0x0 0x1000>; +- reg-names = "vpu", "hhi", "dmc"; ++ <0x0 0xc883c000 0x0 0x1000>; ++ reg-names = "vpu", "hhi"; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + ++ amlogic,canvas = <&canvas>; ++ + /* CVBS VDAC output port */ + port@0 { + reg = <0>; +diff --git a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi +index 5dd63ecf8b05b..737b741df0355 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi +@@ -499,13 +499,14 @@ + vpu: vpu@d0100000 { + compatible = "amlogic,meson-gx-vpu"; + reg = <0x0 0xd0100000 0x0 0x100000>, +- <0x0 0xc883c000 0x0 0x1000>, +- <0x0 0xc8838000 0x0 0x1000>; +- reg-names = "vpu", "hhi", "dmc"; ++ <0x0 0xc883c000 0x0 0x1000>; ++ reg-names = "vpu", "hhi"; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + ++ amlogic,canvas = <&canvas>; ++ + /* CVBS VDAC output port */ + cvbs_vdac_port: port@0 { + reg = <0>; +diff --git a/drivers/gpu/drm/meson/Kconfig b/drivers/gpu/drm/meson/Kconfig +index 3ce51d8dfe1c8..c28b69f485555 100644 +--- a/drivers/gpu/drm/meson/Kconfig ++++ b/drivers/gpu/drm/meson/Kconfig +@@ -7,6 +7,7 @@ config DRM_MESON + select DRM_GEM_CMA_HELPER + select VIDEOMODE_HELPERS + select REGMAP_MMIO ++ select MESON_CANVAS + + config DRM_MESON_DW_HDMI + tristate "HDMI Synopsys Controller support for Amlogic Meson Display" +diff --git a/drivers/gpu/drm/meson/Makefile b/drivers/gpu/drm/meson/Makefile +index c5c4cc362f024..bd67429185ff7 100644 +--- a/drivers/gpu/drm/meson/Makefile ++++ b/drivers/gpu/drm/meson/Makefile +@@ -1,5 +1,5 @@ + meson-drm-y := meson_drv.o meson_plane.o meson_crtc.o meson_venc_cvbs.o +-meson-drm-y += meson_viu.o meson_vpp.o meson_venc.o meson_vclk.o meson_canvas.o ++meson-drm-y += meson_viu.o meson_vpp.o meson_venc.o meson_vclk.o + + obj-$(CONFIG_DRM_MESON) += meson-drm.o + obj-$(CONFIG_DRM_MESON_DW_HDMI) += meson_dw_hdmi.o +diff --git a/drivers/gpu/drm/meson/meson_canvas.c b/drivers/gpu/drm/meson/meson_canvas.c +deleted file mode 100644 +index 08f6073d967e0..0000000000000 +--- a/drivers/gpu/drm/meson/meson_canvas.c ++++ /dev/null +@@ -1,70 +0,0 @@ +-/* +- * Copyright (C) 2016 BayLibre, SAS +- * Author: Neil Armstrong +- * Copyright (C) 2015 Amlogic, Inc. All rights reserved. +- * Copyright (C) 2014 Endless Mobile +- * +- * 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. +- * +- * 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. +- * +- * You should have received a copy of the GNU General Public License +- * along with this program; if not, see . +- */ +- +-#include +-#include +-#include "meson_drv.h" +-#include "meson_canvas.h" +-#include "meson_registers.h" +- +-/** +- * DOC: Canvas +- * +- * CANVAS is a memory zone where physical memory frames information +- * are stored for the VIU to scanout. +- */ +- +-/* DMC Registers */ +-#define DMC_CAV_LUT_DATAL 0x48 /* 0x12 offset in data sheet */ +-#define CANVAS_WIDTH_LBIT 29 +-#define CANVAS_WIDTH_LWID 3 +-#define DMC_CAV_LUT_DATAH 0x4c /* 0x13 offset in data sheet */ +-#define CANVAS_WIDTH_HBIT 0 +-#define CANVAS_HEIGHT_BIT 9 +-#define CANVAS_BLKMODE_BIT 24 +-#define DMC_CAV_LUT_ADDR 0x50 /* 0x14 offset in data sheet */ +-#define CANVAS_LUT_WR_EN (0x2 << 8) +-#define CANVAS_LUT_RD_EN (0x1 << 8) +- +-void meson_canvas_setup(struct meson_drm *priv, +- uint32_t canvas_index, uint32_t addr, +- uint32_t stride, uint32_t height, +- unsigned int wrap, +- unsigned int blkmode) +-{ +- unsigned int val; +- +- regmap_write(priv->dmc, DMC_CAV_LUT_DATAL, +- (((addr + 7) >> 3)) | +- (((stride + 7) >> 3) << CANVAS_WIDTH_LBIT)); +- +- regmap_write(priv->dmc, DMC_CAV_LUT_DATAH, +- ((((stride + 7) >> 3) >> CANVAS_WIDTH_LWID) << +- CANVAS_WIDTH_HBIT) | +- (height << CANVAS_HEIGHT_BIT) | +- (wrap << 22) | +- (blkmode << CANVAS_BLKMODE_BIT)); +- +- regmap_write(priv->dmc, DMC_CAV_LUT_ADDR, +- CANVAS_LUT_WR_EN | canvas_index); +- +- /* Force a read-back to make sure everything is flushed. */ +- regmap_read(priv->dmc, DMC_CAV_LUT_DATAH, &val); +-} +diff --git a/drivers/gpu/drm/meson/meson_canvas.h b/drivers/gpu/drm/meson/meson_canvas.h +deleted file mode 100644 +index af1759da4b275..0000000000000 +--- a/drivers/gpu/drm/meson/meson_canvas.h ++++ /dev/null +@@ -1,42 +0,0 @@ +-/* +- * Copyright (C) 2016 BayLibre, SAS +- * Author: Neil Armstrong +- * Copyright (C) 2014 Endless Mobile +- * +- * 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. +- * +- * 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. +- * +- * You should have received a copy of the GNU General Public License +- * along with this program; if not, see . +- */ +- +-/* Canvas LUT Memory */ +- +-#ifndef __MESON_CANVAS_H +-#define __MESON_CANVAS_H +- +-#define MESON_CANVAS_ID_OSD1 0x4e +- +-/* Canvas configuration. */ +-#define MESON_CANVAS_WRAP_NONE 0x00 +-#define MESON_CANVAS_WRAP_X 0x01 +-#define MESON_CANVAS_WRAP_Y 0x02 +- +-#define MESON_CANVAS_BLKMODE_LINEAR 0x00 +-#define MESON_CANVAS_BLKMODE_32x32 0x01 +-#define MESON_CANVAS_BLKMODE_64x64 0x02 +- +-void meson_canvas_setup(struct meson_drm *priv, +- uint32_t canvas_index, uint32_t addr, +- uint32_t stride, uint32_t height, +- unsigned int wrap, +- unsigned int blkmode); +- +-#endif /* __MESON_CANVAS_H */ +diff --git a/drivers/gpu/drm/meson/meson_crtc.c b/drivers/gpu/drm/meson/meson_crtc.c +index 05520202c9677..1ca9c6c45f9b9 100644 +--- a/drivers/gpu/drm/meson/meson_crtc.c ++++ b/drivers/gpu/drm/meson/meson_crtc.c +@@ -36,7 +36,6 @@ + #include "meson_venc.h" + #include "meson_vpp.h" + #include "meson_viu.h" +-#include "meson_canvas.h" + #include "meson_registers.h" + + /* CRTC definition */ +@@ -193,10 +192,10 @@ void meson_crtc_irq(struct meson_drm *priv) + } else + meson_vpp_disable_interlace_vscaler_osd1(priv); + +- meson_canvas_setup(priv, MESON_CANVAS_ID_OSD1, +- priv->viu.osd1_addr, priv->viu.osd1_stride, +- priv->viu.osd1_height, MESON_CANVAS_WRAP_NONE, +- MESON_CANVAS_BLKMODE_LINEAR); ++ meson_canvas_config(priv->canvas, priv->canvas_id_osd1, ++ priv->viu.osd1_addr, priv->viu.osd1_stride, ++ priv->viu.osd1_height, MESON_CANVAS_WRAP_NONE, ++ MESON_CANVAS_BLKMODE_LINEAR, 0); + + /* Enable OSD1 */ + writel_bits_relaxed(VPP_OSD1_POSTBLEND, VPP_OSD1_POSTBLEND, +diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c +index d3443125e6616..fb5b0e3c5efce 100644 +--- a/drivers/gpu/drm/meson/meson_drv.c ++++ b/drivers/gpu/drm/meson/meson_drv.c +@@ -47,7 +47,6 @@ + #include "meson_vpp.h" + #include "meson_viu.h" + #include "meson_venc.h" +-#include "meson_canvas.h" + #include "meson_registers.h" + + #define DRIVER_NAME "meson" +@@ -216,25 +215,15 @@ static int meson_drv_bind_master(struct device *dev, bool has_components) + goto free_drm; + } + +- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dmc"); +- if (!res) { +- ret = -EINVAL; +- goto free_drm; +- } +- /* Simply ioremap since it may be a shared register zone */ +- regs = devm_ioremap(dev, res->start, resource_size(res)); +- if (!regs) { +- ret = -EADDRNOTAVAIL; ++ priv->canvas = meson_canvas_get(dev); ++ if (IS_ERR(priv->canvas)) { ++ ret = PTR_ERR(priv->canvas); + goto free_drm; + } + +- priv->dmc = devm_regmap_init_mmio(dev, regs, +- &meson_regmap_config); +- if (IS_ERR(priv->dmc)) { +- dev_err(&pdev->dev, "Couldn't create the DMC regmap\n"); +- ret = PTR_ERR(priv->dmc); ++ ret = meson_canvas_alloc(priv->canvas, &priv->canvas_id_osd1); ++ if (ret) + goto free_drm; +- } + + priv->vsync_irq = platform_get_irq(pdev, 0); + +@@ -315,6 +304,7 @@ static void meson_drv_unbind(struct device *dev) + struct drm_device *drm = dev_get_drvdata(dev); + struct meson_drm *priv = drm->dev_private; + ++ meson_canvas_free(priv->canvas, priv->canvas_id_osd1); + drm_dev_unregister(drm); + drm_kms_helper_poll_fini(drm); + drm_fbdev_cma_fini(priv->fbdev); +diff --git a/drivers/gpu/drm/meson/meson_drv.h b/drivers/gpu/drm/meson/meson_drv.h +index 8450d6ac8c9bc..9e902a6df7843 100644 +--- a/drivers/gpu/drm/meson/meson_drv.h ++++ b/drivers/gpu/drm/meson/meson_drv.h +@@ -22,15 +22,18 @@ + #include + #include + #include ++#include + #include + + struct meson_drm { + struct device *dev; + void __iomem *io_base; + struct regmap *hhi; +- struct regmap *dmc; + int vsync_irq; + ++ struct meson_canvas *canvas; ++ u8 canvas_id_osd1; ++ + struct drm_device *drm; + struct drm_crtc *crtc; + struct drm_fbdev_cma *fbdev; +diff --git a/drivers/gpu/drm/meson/meson_plane.c b/drivers/gpu/drm/meson/meson_plane.c +index 12c80dfcff59b..8745f9209625b 100644 +--- a/drivers/gpu/drm/meson/meson_plane.c ++++ b/drivers/gpu/drm/meson/meson_plane.c +@@ -36,7 +36,6 @@ + #include "meson_plane.h" + #include "meson_vpp.h" + #include "meson_viu.h" +-#include "meson_canvas.h" + #include "meson_registers.h" + + struct meson_plane { +@@ -105,7 +104,7 @@ static void meson_plane_atomic_update(struct drm_plane *plane, + OSD_BLK0_ENABLE; + + /* Set up BLK0 to point to the right canvas */ +- priv->viu.osd1_blk0_cfg[0] = ((MESON_CANVAS_ID_OSD1 << OSD_CANVAS_SEL) | ++ priv->viu.osd1_blk0_cfg[0] = ((priv->canvas_id_osd1 << OSD_CANVAS_SEL) | + OSD_ENDIANNESS_LE); + + /* On GXBB, Use the old non-HDR RGB2YUV converter */ +diff --git a/drivers/gpu/drm/meson/meson_viu.c b/drivers/gpu/drm/meson/meson_viu.c +index 6bcfa527c1801..5b48c4c0985b5 100644 +--- a/drivers/gpu/drm/meson/meson_viu.c ++++ b/drivers/gpu/drm/meson/meson_viu.c +@@ -25,7 +25,6 @@ + #include "meson_viu.h" + #include "meson_vpp.h" + #include "meson_venc.h" +-#include "meson_canvas.h" + #include "meson_registers.h" + + /** diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/005_linux-4.18.y-v4l-0005-dt-bindings-media-add_amlogic_video_decoder_bindings.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/005_linux-4.18.y-v4l-0005-dt-bindings-media-add_amlogic_video_decoder_bindings.patch new file mode 100644 index 000000000..389e3486b --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/005_linux-4.18.y-v4l-0005-dt-bindings-media-add_amlogic_video_decoder_bindings.patch @@ -0,0 +1,82 @@ +From 0ceff9fb866173338b3ca79657ce6bf9aa3b2a9a Mon Sep 17 00:00:00 2001 +From: Maxime Jourdan +Date: Wed, 29 Aug 2018 15:05:05 +0200 +Subject: [PATCH] dt-bindings: media: add Amlogic Video Decoder Bindings + +Add documentation for the meson vdec dts node. + +Signed-off-by: Maxime Jourdan +--- + .../bindings/media/amlogic,vdec.txt | 63 +++++++++++++++++++ + 1 file changed, 63 insertions(+) + create mode 100644 Documentation/devicetree/bindings/media/amlogic,vdec.txt + +diff --git a/Documentation/devicetree/bindings/media/amlogic,vdec.txt b/Documentation/devicetree/bindings/media/amlogic,vdec.txt +new file mode 100644 +index 0000000000000..c6450f2e7f28f +--- /dev/null ++++ b/Documentation/devicetree/bindings/media/amlogic,vdec.txt +@@ -0,0 +1,63 @@ ++Amlogic Video Decoder ++================================ ++ ++The VDEC IP is composed of the following blocks : ++ ++- ESPARSER is a bitstream parser that outputs to a VIFIFO. Further VDEC blocks ++then feed from this VIFIFO. ++- VDEC_1 can decode MPEG-1, MPEG-2, MPEG-4 part 2, H.263, H.264. ++- VDEC_2 is used as a helper for corner cases like H.264 4K on older SoCs. ++It is not handled by this driver. ++- VDEC_HCODEC is the H.264 encoding block. It is not handled by this driver. ++- VDEC_HEVC can decode HEVC and VP9. ++ ++Device Tree Bindings: ++--------------------- ++ ++VDEC: Video Decoder ++-------------------------- ++ ++Required properties: ++- compatible: value should be different for each SoC family as : ++ - GXBB (S905) : "amlogic,gxbb-vdec" ++ - GXL (S905X, S905D) : "amlogic,gxl-vdec" ++ - GXM (S912) : "amlogic,gxm-vdec" ++- reg: base address and size of he following memory-mapped regions : ++ - dos ++ - esparser ++- reg-names: should contain the names of the previous memory regions ++- interrupts: should contain the vdec and esparser IRQs. ++- amlogic,ao-sysctrl: should point to the AOBUS sysctrl node ++- amlogic,canvas: should point to a canvas provider node ++- clocks: should contain the following clocks : ++ - dos_parser ++ - dos ++ - vdec_1 ++ - vdec_hevc ++- clock-names: should contain the names of the previous clocks ++- resets: should contain the parser reset. ++- reset-names: should be "esparser". ++ ++Example: ++ ++vdec: video-decoder@c8820000 { ++ compatible = "amlogic,gxbb-vdec"; ++ reg = <0x0 0xc8820000 0x0 0x10000>, ++ <0x0 0xc110a580 0x0 0xe4>; ++ reg-names = "dos", "esparser"; ++ ++ interrupts = , ++ ; ++ ++ amlogic,ao-sysctrl = <&sysctrl_AO>; ++ amlogic,canvas = <&canvas>; ++ ++ clocks = <&clkc CLKID_DOS_PARSER>, ++ <&clkc CLKID_DOS>, ++ <&clkc CLKID_VDEC_1>, ++ <&clkc CLKID_VDEC_HEVC>; ++ clock-names = "dos_parser", "dos", "vdec_1", "vdec_hevc"; ++ ++ resets = <&reset RESET_PARSER>; ++ reset-names = "esparser"; ++}; diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/006_linux-4.18.y-v4l-0006-media-meson-add_v4l2_m2m_video_decoder_driver.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/006_linux-4.18.y-v4l-0006-media-meson-add_v4l2_m2m_video_decoder_driver.patch new file mode 100644 index 000000000..3ef259e6a --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/006_linux-4.18.y-v4l-0006-media-meson-add_v4l2_m2m_video_decoder_driver.patch @@ -0,0 +1,2844 @@ +From c975acbed7ff7904523600a4fd5e4b45b4c41ec3 Mon Sep 17 00:00:00 2001 +From: Maxime Jourdan +Date: Wed, 29 Aug 2018 15:17:22 +0200 +Subject: [PATCH] media: meson: add v4l2 m2m video decoder driver + +Amlogic SoCs feature a powerful video decoder unit able to +decode many formats, with a performance of usually up to 4k60. + +This is a driver for this IP that is based around the v4l2 m2m framework. + +It features decoding for: +- MPEG 1 +- MPEG 2 + +Supported SoCs are: GXBB (S905), GXL (S905X/W/D), GXM (S912) + +There is also a hardware bitstream parser (ESPARSER) that is handled here. + +Signed-off-by: Maxime Jourdan +--- + drivers/media/platform/Kconfig | 10 + + drivers/media/platform/meson/Makefile | 1 + + drivers/media/platform/meson/vdec/Makefile | 8 + + .../media/platform/meson/vdec/codec_mpeg12.c | 170 +++ + .../media/platform/meson/vdec/codec_mpeg12.h | 14 + + drivers/media/platform/meson/vdec/dos_regs.h | 98 ++ + drivers/media/platform/meson/vdec/esparser.c | 368 +++++++ + drivers/media/platform/meson/vdec/esparser.h | 28 + + drivers/media/platform/meson/vdec/vdec.c | 988 ++++++++++++++++++ + drivers/media/platform/meson/vdec/vdec.h | 234 +++++ + drivers/media/platform/meson/vdec/vdec_1.c | 228 ++++ + drivers/media/platform/meson/vdec/vdec_1.h | 14 + + .../media/platform/meson/vdec/vdec_helpers.c | 354 +++++++ + .../media/platform/meson/vdec/vdec_helpers.h | 45 + + .../media/platform/meson/vdec/vdec_platform.c | 101 ++ + .../media/platform/meson/vdec/vdec_platform.h | 30 + + 16 files changed, 2691 insertions(+) + create mode 100644 drivers/media/platform/meson/vdec/Makefile + create mode 100644 drivers/media/platform/meson/vdec/codec_mpeg12.c + create mode 100644 drivers/media/platform/meson/vdec/codec_mpeg12.h + create mode 100644 drivers/media/platform/meson/vdec/dos_regs.h + create mode 100644 drivers/media/platform/meson/vdec/esparser.c + create mode 100644 drivers/media/platform/meson/vdec/esparser.h + create mode 100644 drivers/media/platform/meson/vdec/vdec.c + create mode 100644 drivers/media/platform/meson/vdec/vdec.h + create mode 100644 drivers/media/platform/meson/vdec/vdec_1.c + create mode 100644 drivers/media/platform/meson/vdec/vdec_1.h + create mode 100644 drivers/media/platform/meson/vdec/vdec_helpers.c + create mode 100644 drivers/media/platform/meson/vdec/vdec_helpers.h + create mode 100644 drivers/media/platform/meson/vdec/vdec_platform.c + create mode 100644 drivers/media/platform/meson/vdec/vdec_platform.h + +diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig +index 2728376b04b53..1c33d95dd92f9 100644 +--- a/drivers/media/platform/Kconfig ++++ b/drivers/media/platform/Kconfig +@@ -482,6 +482,16 @@ config VIDEO_QCOM_VENUS + on various Qualcomm SoCs. + To compile this driver as a module choose m here. + ++config VIDEO_MESON_VDEC ++ tristate "Amlogic video decoder driver" ++ depends on VIDEO_DEV && VIDEO_V4L2 && HAS_DMA ++ depends on (ARCH_MESON) || COMPILE_TEST ++ select VIDEOBUF2_DMA_CONTIG ++ select V4L2_MEM2MEM_DEV ++ select MESON_CANVAS ++ help ++ Support for the video decoder found in gxbb/gxl/gxm chips. ++ + endif # V4L_MEM2MEM_DRIVERS + + # TI VIDEO PORT Helper Modules +diff --git a/drivers/media/platform/meson/Makefile b/drivers/media/platform/meson/Makefile +index 597beb8f34d15..f7c6e1031f25d 100644 +--- a/drivers/media/platform/meson/Makefile ++++ b/drivers/media/platform/meson/Makefile +@@ -1 +1,2 @@ + obj-$(CONFIG_VIDEO_MESON_AO_CEC) += ao-cec.o ++obj-$(CONFIG_VIDEO_MESON_VDEC) += vdec/ +diff --git a/drivers/media/platform/meson/vdec/Makefile b/drivers/media/platform/meson/vdec/Makefile +new file mode 100644 +index 0000000000000..6bea129084b76 +--- /dev/null ++++ b/drivers/media/platform/meson/vdec/Makefile +@@ -0,0 +1,8 @@ ++# SPDX-License-Identifier: GPL-2.0 ++# Makefile for Amlogic meson video decoder driver ++ ++meson-vdec-objs = esparser.o vdec.o vdec_helpers.o vdec_platform.o ++meson-vdec-objs += vdec_1.o ++meson-vdec-objs += codec_mpeg12.o ++ ++obj-$(CONFIG_VIDEO_MESON_VDEC) += meson-vdec.o +diff --git a/drivers/media/platform/meson/vdec/codec_mpeg12.c b/drivers/media/platform/meson/vdec/codec_mpeg12.c +new file mode 100644 +index 0000000000000..18709319cff7f +--- /dev/null ++++ b/drivers/media/platform/meson/vdec/codec_mpeg12.c +@@ -0,0 +1,170 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright (C) 2018 BayLibre, SAS ++ * Author: Maxime Jourdan ++ */ ++ ++#include ++#include ++ ++#include "vdec_helpers.h" ++#include "dos_regs.h" ++ ++#define SIZE_WORKSPACE SZ_128K ++/* Offset substracted by the firmware from the workspace paddr */ ++#define WORKSPACE_OFFSET (5 * SZ_1K) ++ ++/* map firmware registers to known MPEG1/2 functions */ ++#define MREG_SEQ_INFO AV_SCRATCH_4 ++#define MREG_PIC_INFO AV_SCRATCH_5 ++#define MREG_PIC_WIDTH AV_SCRATCH_6 ++#define MREG_PIC_HEIGHT AV_SCRATCH_7 ++#define MREG_BUFFERIN AV_SCRATCH_8 ++#define MREG_BUFFEROUT AV_SCRATCH_9 ++#define MREG_CMD AV_SCRATCH_A ++#define MREG_CO_MV_START AV_SCRATCH_B ++#define MREG_ERROR_COUNT AV_SCRATCH_C ++#define MREG_FRAME_OFFSET AV_SCRATCH_D ++#define MREG_WAIT_BUFFER AV_SCRATCH_E ++#define MREG_FATAL_ERROR AV_SCRATCH_F ++ ++#define PICINFO_PROG 0x00008000 ++#define PICINFO_TOP_FIRST 0x00002000 ++ ++struct codec_mpeg12 { ++ /* Buffer for the MPEG1/2 Workspace */ ++ void *workspace_vaddr; ++ dma_addr_t workspace_paddr; ++}; ++ ++static int codec_mpeg12_can_recycle(struct amvdec_core *core) ++{ ++ return !amvdec_read_dos(core, MREG_BUFFERIN); ++} ++ ++static void codec_mpeg12_recycle(struct amvdec_core *core, u32 buf_idx) ++{ ++ amvdec_write_dos(core, MREG_BUFFERIN, buf_idx + 1); ++} ++ ++static int codec_mpeg12_start(struct amvdec_session *sess) ++{ ++ struct amvdec_core *core = sess->core; ++ struct codec_mpeg12 *mpeg12 = sess->priv; ++ int ret; ++ ++ mpeg12 = kzalloc(sizeof(*mpeg12), GFP_KERNEL); ++ if (!mpeg12) ++ return -ENOMEM; ++ ++ /* Allocate some memory for the MPEG1/2 decoder's state */ ++ mpeg12->workspace_vaddr = dma_alloc_coherent(core->dev, SIZE_WORKSPACE, ++ &mpeg12->workspace_paddr, ++ GFP_KERNEL); ++ if (!mpeg12->workspace_vaddr) { ++ dev_err(core->dev, "Failed to request MPEG 1/2 Workspace\n"); ++ ret = -ENOMEM; ++ goto free_mpeg12; ++ } ++ ++ ret = amvdec_set_canvases(sess, (u32[]){ AV_SCRATCH_0, 0 }, ++ (u32[]){ 8, 0 }); ++ if (ret) ++ goto free_workspace; ++ ++ amvdec_write_dos(core, POWER_CTL_VLD, BIT(4)); ++ amvdec_write_dos(core, MREG_CO_MV_START, ++ mpeg12->workspace_paddr + WORKSPACE_OFFSET); ++ ++ amvdec_write_dos(core, MPEG1_2_REG, 0); ++ amvdec_write_dos(core, PSCALE_CTRL, 0); ++ amvdec_write_dos(core, PIC_HEAD_INFO, 0x380); ++ amvdec_write_dos(core, M4_CONTROL_REG, 0); ++ amvdec_write_dos(core, MREG_BUFFERIN, 0); ++ amvdec_write_dos(core, MREG_BUFFEROUT, 0); ++ amvdec_write_dos(core, MREG_CMD, (sess->width << 16) | sess->height); ++ amvdec_write_dos(core, MREG_ERROR_COUNT, 0); ++ amvdec_write_dos(core, MREG_FATAL_ERROR, 0); ++ amvdec_write_dos(core, MREG_WAIT_BUFFER, 0); ++ ++ sess->keyframe_found = 1; ++ sess->priv = mpeg12; ++ ++ return 0; ++ ++free_workspace: ++ dma_free_coherent(core->dev, SIZE_WORKSPACE, mpeg12->workspace_vaddr, ++ mpeg12->workspace_paddr); ++free_mpeg12: ++ kfree(mpeg12); ++ ++ return ret; ++} ++ ++static int codec_mpeg12_stop(struct amvdec_session *sess) ++{ ++ struct codec_mpeg12 *mpeg12 = sess->priv; ++ struct amvdec_core *core = sess->core; ++ ++ if (mpeg12->workspace_vaddr) ++ dma_free_coherent(core->dev, SIZE_WORKSPACE, ++ mpeg12->workspace_vaddr, ++ mpeg12->workspace_paddr); ++ ++ return 0; ++} ++ ++static irqreturn_t codec_mpeg12_threaded_isr(struct amvdec_session *sess) ++{ ++ struct amvdec_core *core = sess->core; ++ u32 reg; ++ u32 pic_info; ++ u32 is_progressive; ++ u32 buffer_index; ++ u32 field = V4L2_FIELD_NONE; ++ ++ amvdec_write_dos(core, ASSIST_MBOX1_CLR_REG, 1); ++ reg = amvdec_read_dos(core, MREG_FATAL_ERROR); ++ if (reg == 1) { ++ dev_err(core->dev, "MPEG1/2 fatal error\n"); ++ amvdec_abort(sess); ++ return IRQ_HANDLED; ++ } ++ ++ reg = amvdec_read_dos(core, MREG_BUFFEROUT); ++ if (!reg) ++ return IRQ_HANDLED; ++ ++ /* Unclear what this means */ ++ if ((reg & GENMASK(23, 17)) == GENMASK(23, 17)) ++ goto end; ++ ++ pic_info = amvdec_read_dos(core, MREG_PIC_INFO); ++ is_progressive = pic_info & PICINFO_PROG; ++ ++ if (!is_progressive) ++ field = (pic_info & PICINFO_TOP_FIRST) ? ++ V4L2_FIELD_INTERLACED_TB : ++ V4L2_FIELD_INTERLACED_BT; ++ ++ buffer_index = ((reg & 0xf) - 1) & 7; ++ amvdec_dst_buf_done_idx(sess, buffer_index, field); ++ ++end: ++ amvdec_write_dos(core, MREG_BUFFEROUT, 0); ++ return IRQ_HANDLED; ++} ++ ++static irqreturn_t codec_mpeg12_isr(struct amvdec_session *sess) ++{ ++ return IRQ_WAKE_THREAD; ++} ++ ++struct amvdec_codec_ops codec_mpeg12_ops = { ++ .start = codec_mpeg12_start, ++ .stop = codec_mpeg12_stop, ++ .isr = codec_mpeg12_isr, ++ .threaded_isr = codec_mpeg12_threaded_isr, ++ .can_recycle = codec_mpeg12_can_recycle, ++ .recycle = codec_mpeg12_recycle, ++}; +diff --git a/drivers/media/platform/meson/vdec/codec_mpeg12.h b/drivers/media/platform/meson/vdec/codec_mpeg12.h +new file mode 100644 +index 0000000000000..43cab5f39ca05 +--- /dev/null ++++ b/drivers/media/platform/meson/vdec/codec_mpeg12.h +@@ -0,0 +1,14 @@ ++/* SPDX-License-Identifier: GPL-2.0+ */ ++/* ++ * Copyright (C) 2018 BayLibre, SAS ++ * Author: Maxime Jourdan ++ */ ++ ++#ifndef __MESON_VDEC_CODEC_MPEG12_H_ ++#define __MESON_VDEC_CODEC_MPEG12_H_ ++ ++#include "vdec.h" ++ ++extern struct amvdec_codec_ops codec_mpeg12_ops; ++ ++#endif +diff --git a/drivers/media/platform/meson/vdec/dos_regs.h b/drivers/media/platform/meson/vdec/dos_regs.h +new file mode 100644 +index 0000000000000..abd810542dbb5 +--- /dev/null ++++ b/drivers/media/platform/meson/vdec/dos_regs.h +@@ -0,0 +1,98 @@ ++/* SPDX-License-Identifier: GPL-2.0+ */ ++/* ++ * Copyright (C) 2018 BayLibre, SAS ++ * Author: Maxime Jourdan ++ */ ++ ++#ifndef __MESON_VDEC_DOS_REGS_H_ ++#define __MESON_VDEC_DOS_REGS_H_ ++ ++/* DOS registers */ ++#define VDEC_ASSIST_AMR1_INT8 0x00b4 ++ ++#define ASSIST_MBOX1_CLR_REG 0x01d4 ++#define ASSIST_MBOX1_MASK 0x01d8 ++ ++#define MPSR 0x0c04 ++#define MCPU_INTR_MSK 0x0c10 ++#define CPSR 0x0c84 ++ ++#define IMEM_DMA_CTRL 0x0d00 ++#define IMEM_DMA_ADR 0x0d04 ++#define IMEM_DMA_COUNT 0x0d08 ++#define LMEM_DMA_CTRL 0x0d40 ++ ++#define MC_STATUS0 0x2424 ++#define MC_CTRL1 0x242c ++ ++#define PSCALE_RST 0x2440 ++#define PSCALE_CTRL 0x2444 ++#define PSCALE_BMEM_ADDR 0x247c ++#define PSCALE_BMEM_DAT 0x2480 ++ ++#define DBLK_CTRL 0x2544 ++#define DBLK_STATUS 0x254c ++ ++#define GCLK_EN 0x260c ++#define MDEC_PIC_DC_CTRL 0x2638 ++#define MDEC_PIC_DC_STATUS 0x263c ++#define ANC0_CANVAS_ADDR 0x2640 ++#define MDEC_PIC_DC_THRESH 0x26e0 ++ ++/* Firmware interface registers */ ++#define AV_SCRATCH_0 0x2700 ++#define AV_SCRATCH_1 0x2704 ++#define AV_SCRATCH_2 0x2708 ++#define AV_SCRATCH_3 0x270c ++#define AV_SCRATCH_4 0x2710 ++#define AV_SCRATCH_5 0x2714 ++#define AV_SCRATCH_6 0x2718 ++#define AV_SCRATCH_7 0x271c ++#define AV_SCRATCH_8 0x2720 ++#define AV_SCRATCH_9 0x2724 ++#define AV_SCRATCH_A 0x2728 ++#define AV_SCRATCH_B 0x272c ++#define AV_SCRATCH_C 0x2730 ++#define AV_SCRATCH_D 0x2734 ++#define AV_SCRATCH_E 0x2738 ++#define AV_SCRATCH_F 0x273c ++#define AV_SCRATCH_G 0x2740 ++#define AV_SCRATCH_H 0x2744 ++#define AV_SCRATCH_I 0x2748 ++#define AV_SCRATCH_J 0x274c ++#define AV_SCRATCH_K 0x2750 ++#define AV_SCRATCH_L 0x2754 ++ ++#define MPEG1_2_REG 0x3004 ++#define PIC_HEAD_INFO 0x300c ++#define POWER_CTL_VLD 0x3020 ++#define M4_CONTROL_REG 0x30a4 ++ ++/* Stream Buffer (stbuf) regs */ ++#define VLD_MEM_VIFIFO_START_PTR 0x3100 ++#define VLD_MEM_VIFIFO_CURR_PTR 0x3104 ++#define VLD_MEM_VIFIFO_END_PTR 0x3108 ++#define VLD_MEM_VIFIFO_CONTROL 0x3110 ++ #define MEM_FIFO_CNT_BIT 16 ++ #define MEM_FILL_ON_LEVEL BIT(10) ++ #define MEM_CTRL_EMPTY_EN BIT(2) ++ #define MEM_CTRL_FILL_EN BIT(1) ++#define VLD_MEM_VIFIFO_WP 0x3114 ++#define VLD_MEM_VIFIFO_RP 0x3118 ++#define VLD_MEM_VIFIFO_LEVEL 0x311c ++#define VLD_MEM_VIFIFO_BUF_CNTL 0x3120 ++ #define MEM_BUFCTRL_MANUAL BIT(1) ++#define VLD_MEM_VIFIFO_WRAP_COUNT 0x3144 ++ ++#define DCAC_DMA_CTRL 0x3848 ++ ++#define DOS_SW_RESET0 0xfc00 ++#define DOS_GCLK_EN0 0xfc04 ++#define DOS_GEN_CTRL0 0xfc08 ++#define DOS_MEM_PD_VDEC 0xfcc0 ++#define DOS_MEM_PD_HEVC 0xfccc ++#define DOS_SW_RESET3 0xfcd0 ++#define DOS_GCLK_EN3 0xfcd4 ++#define DOS_VDEC_MCRCC_STALL_CTRL 0xfd00 ++ ++#endif +diff --git a/drivers/media/platform/meson/vdec/esparser.c b/drivers/media/platform/meson/vdec/esparser.c +new file mode 100644 +index 0000000000000..098c7d76ad3fe +--- /dev/null ++++ b/drivers/media/platform/meson/vdec/esparser.c +@@ -0,0 +1,368 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright (C) 2018 BayLibre, SAS ++ * Author: Maxime Jourdan ++ * ++ * The Elementary Stream Parser is a HW bitstream parser. ++ * It reads bitstream buffers and feeds them to the VIFIFO ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "dos_regs.h" ++#include "esparser.h" ++#include "vdec_helpers.h" ++ ++/* PARSER REGS (CBUS) */ ++#define PARSER_CONTROL 0x00 ++ #define ES_PACK_SIZE_BIT 8 ++ #define ES_WRITE BIT(5) ++ #define ES_SEARCH BIT(1) ++ #define ES_PARSER_START BIT(0) ++#define PARSER_FETCH_ADDR 0x4 ++#define PARSER_FETCH_CMD 0x8 ++#define PARSER_CONFIG 0x14 ++ #define PS_CFG_MAX_FETCH_CYCLE_BIT 0 ++ #define PS_CFG_STARTCODE_WID_24_BIT 10 ++ #define PS_CFG_MAX_ES_WR_CYCLE_BIT 12 ++ #define PS_CFG_PFIFO_EMPTY_CNT_BIT 16 ++#define PFIFO_WR_PTR 0x18 ++#define PFIFO_RD_PTR 0x1c ++#define PARSER_SEARCH_PATTERN 0x24 ++ #define ES_START_CODE_PATTERN 0x00000100 ++#define PARSER_SEARCH_MASK 0x28 ++ #define ES_START_CODE_MASK 0xffffff00 ++ #define FETCH_ENDIAN_BIT 27 ++#define PARSER_INT_ENABLE 0x2c ++ #define PARSER_INT_HOST_EN_BIT 8 ++#define PARSER_INT_STATUS 0x30 ++ #define PARSER_INTSTAT_SC_FOUND 1 ++#define PARSER_ES_CONTROL 0x5c ++#define PARSER_VIDEO_START_PTR 0x80 ++#define PARSER_VIDEO_END_PTR 0x84 ++#define PARSER_VIDEO_HOLE 0x90 ++ ++#define SEARCH_PATTERN_LEN 512 ++#define MIN_PACKET_SIZE (4 * SZ_1K) ++ ++/* Buffer to send to the ESPARSER to signal End Of Stream. ++ * Credits to Endless Mobile. ++ */ ++#define EOS_TAIL_BUF_SIZE 1024 ++static const u8 eos_tail_data[EOS_TAIL_BUF_SIZE] = { ++ 0x00, 0x00, 0x00, 0x01, 0x06, 0x05, 0xff, 0xe4, 0xdc, 0x45, 0xe9, 0xbd, ++ 0xe6, 0xd9, 0x48, 0xb7, 0x96, 0x2c, 0xd8, 0x20, 0xd9, 0x23, 0xee, 0xef, ++ 0x78, 0x32, 0x36, 0x34, 0x20, 0x2d, 0x20, 0x63, 0x6f, 0x72, 0x65, 0x20, ++ 0x36, 0x37, 0x20, 0x72, 0x31, 0x31, 0x33, 0x30, 0x20, 0x38, 0x34, 0x37, ++ 0x35, 0x39, 0x37, 0x37, 0x20, 0x2d, 0x20, 0x48, 0x2e, 0x32, 0x36, 0x34, ++ 0x2f, 0x4d, 0x50, 0x45, 0x47, 0x2d, 0x34, 0x20, 0x41, 0x56, 0x43, 0x20, ++ 0x63, 0x6f, 0x64, 0x65, 0x63, 0x20, 0x2d, 0x20, 0x43, 0x6f, 0x70, 0x79, ++ 0x6c, 0x65, 0x66, 0x74, 0x20, 0x32, 0x30, 0x30, 0x33, 0x2d, 0x32, 0x30, ++ 0x30, 0x39, 0x20, 0x2d, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, ++ 0x77, 0x77, 0x77, 0x2e, 0x76, 0x69, 0x64, 0x65, 0x6f, 0x6c, 0x61, 0x6e, ++ 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x78, 0x32, 0x36, 0x34, 0x2e, 0x68, 0x74, ++ 0x6d, 0x6c, 0x20, 0x2d, 0x20, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, ++ 0x3a, 0x20, 0x63, 0x61, 0x62, 0x61, 0x63, 0x3d, 0x31, 0x20, 0x72, 0x65, ++ 0x66, 0x3d, 0x31, 0x20, 0x64, 0x65, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x3d, ++ 0x31, 0x3a, 0x30, 0x3a, 0x30, 0x20, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x73, ++ 0x65, 0x3d, 0x30, 0x78, 0x31, 0x3a, 0x30, 0x78, 0x31, 0x31, 0x31, 0x20, ++ 0x6d, 0x65, 0x3d, 0x68, 0x65, 0x78, 0x20, 0x73, 0x75, 0x62, 0x6d, 0x65, ++ 0x3d, 0x36, 0x20, 0x70, 0x73, 0x79, 0x5f, 0x72, 0x64, 0x3d, 0x31, 0x2e, ++ 0x30, 0x3a, 0x30, 0x2e, 0x30, 0x20, 0x6d, 0x69, 0x78, 0x65, 0x64, 0x5f, ++ 0x72, 0x65, 0x66, 0x3d, 0x30, 0x20, 0x6d, 0x65, 0x5f, 0x72, 0x61, 0x6e, ++ 0x67, 0x65, 0x3d, 0x31, 0x36, 0x20, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x61, ++ 0x5f, 0x6d, 0x65, 0x3d, 0x31, 0x20, 0x74, 0x72, 0x65, 0x6c, 0x6c, 0x69, ++ 0x73, 0x3d, 0x30, 0x20, 0x38, 0x78, 0x38, 0x64, 0x63, 0x74, 0x3d, 0x30, ++ 0x20, 0x63, 0x71, 0x6d, 0x3d, 0x30, 0x20, 0x64, 0x65, 0x61, 0x64, 0x7a, ++ 0x6f, 0x6e, 0x65, 0x3d, 0x32, 0x31, 0x2c, 0x31, 0x31, 0x20, 0x63, 0x68, ++ 0x72, 0x6f, 0x6d, 0x61, 0x5f, 0x71, 0x70, 0x5f, 0x6f, 0x66, 0x66, 0x73, ++ 0x65, 0x74, 0x3d, 0x2d, 0x32, 0x20, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, ++ 0x73, 0x3d, 0x31, 0x20, 0x6e, 0x72, 0x3d, 0x30, 0x20, 0x64, 0x65, 0x63, ++ 0x69, 0x6d, 0x61, 0x74, 0x65, 0x3d, 0x31, 0x20, 0x6d, 0x62, 0x61, 0x66, ++ 0x66, 0x3d, 0x30, 0x20, 0x62, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x3d, ++ 0x30, 0x20, 0x6b, 0x65, 0x79, 0x69, 0x6e, 0x74, 0x3d, 0x32, 0x35, 0x30, ++ 0x20, 0x6b, 0x65, 0x79, 0x69, 0x6e, 0x74, 0x5f, 0x6d, 0x69, 0x6e, 0x3d, ++ 0x32, 0x35, 0x20, 0x73, 0x63, 0x65, 0x6e, 0x65, 0x63, 0x75, 0x74, 0x3d, ++ 0x34, 0x30, 0x20, 0x72, 0x63, 0x3d, 0x61, 0x62, 0x72, 0x20, 0x62, 0x69, ++ 0x74, 0x72, 0x61, 0x74, 0x65, 0x3d, 0x31, 0x30, 0x20, 0x72, 0x61, 0x74, ++ 0x65, 0x74, 0x6f, 0x6c, 0x3d, 0x31, 0x2e, 0x30, 0x20, 0x71, 0x63, 0x6f, ++ 0x6d, 0x70, 0x3d, 0x30, 0x2e, 0x36, 0x30, 0x20, 0x71, 0x70, 0x6d, 0x69, ++ 0x6e, 0x3d, 0x31, 0x30, 0x20, 0x71, 0x70, 0x6d, 0x61, 0x78, 0x3d, 0x35, ++ 0x31, 0x20, 0x71, 0x70, 0x73, 0x74, 0x65, 0x70, 0x3d, 0x34, 0x20, 0x69, ++ 0x70, 0x5f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x3d, 0x31, 0x2e, 0x34, 0x30, ++ 0x20, 0x61, 0x71, 0x3d, 0x31, 0x3a, 0x31, 0x2e, 0x30, 0x30, 0x00, 0x80, ++ 0x00, 0x00, 0x00, 0x01, 0x67, 0x4d, 0x40, 0x0a, 0x9a, 0x74, 0xf4, 0x20, ++ 0x00, 0x00, 0x03, 0x00, 0x20, 0x00, 0x00, 0x06, 0x51, 0xe2, 0x44, 0xd4, ++ 0x00, 0x00, 0x00, 0x01, 0x68, 0xee, 0x32, 0xc8, 0x00, 0x00, 0x00, 0x01, ++ 0x65, 0x88, 0x80, 0x20, 0x00, 0x08, 0x7f, 0xea, 0x6a, 0xe2, 0x99, 0xb6, ++ 0x57, 0xae, 0x49, 0x30, 0xf5, 0xfe, 0x5e, 0x46, 0x0b, 0x72, 0x44, 0xc4, ++ 0xe1, 0xfc, 0x62, 0xda, 0xf1, 0xfb, 0xa2, 0xdb, 0xd6, 0xbe, 0x5c, 0xd7, ++ 0x24, 0xa3, 0xf5, 0xb9, 0x2f, 0x57, 0x16, 0x49, 0x75, 0x47, 0x77, 0x09, ++ 0x5c, 0xa1, 0xb4, 0xc3, 0x4f, 0x60, 0x2b, 0xb0, 0x0c, 0xc8, 0xd6, 0x66, ++ 0xba, 0x9b, 0x82, 0x29, 0x33, 0x92, 0x26, 0x99, 0x31, 0x1c, 0x7f, 0x9b ++}; ++ ++static DECLARE_WAIT_QUEUE_HEAD(wq); ++static int search_done; ++ ++static irqreturn_t esparser_isr(int irq, void *dev) ++{ ++ int int_status; ++ struct amvdec_core *core = dev; ++ ++ int_status = amvdec_read_parser(core, PARSER_INT_STATUS); ++ amvdec_write_parser(core, PARSER_INT_STATUS, int_status); ++ ++ if (int_status & PARSER_INTSTAT_SC_FOUND) { ++ amvdec_write_parser(core, PFIFO_RD_PTR, 0); ++ amvdec_write_parser(core, PFIFO_WR_PTR, 0); ++ search_done = 1; ++ wake_up_interruptible(&wq); ++ } ++ ++ return IRQ_HANDLED; ++} ++ ++/* Pad the packet to at least 4KiB bytes otherwise the VDEC unit won't trigger ++ * ISRs. ++ * Also append a start code 000001ff at the end to trigger ++ * the ESPARSER interrupt. ++ */ ++static u32 esparser_pad_start_code(struct vb2_buffer *vb) ++{ ++ u32 payload_size = vb2_get_plane_payload(vb, 0); ++ u32 pad_size = 0; ++ u8 *vaddr = vb2_plane_vaddr(vb, 0) + payload_size; ++ ++ if (payload_size < MIN_PACKET_SIZE) { ++ pad_size = MIN_PACKET_SIZE - payload_size; ++ memset(vaddr, 0, pad_size); ++ } ++ ++ memset(vaddr + pad_size, 0, SEARCH_PATTERN_LEN); ++ vaddr[pad_size] = 0x00; ++ vaddr[pad_size + 1] = 0x00; ++ vaddr[pad_size + 2] = 0x01; ++ vaddr[pad_size + 3] = 0xff; ++ ++ return pad_size; ++} ++ ++static int ++esparser_write_data(struct amvdec_core *core, dma_addr_t addr, u32 size) ++{ ++ amvdec_write_parser(core, PFIFO_RD_PTR, 0); ++ amvdec_write_parser(core, PFIFO_WR_PTR, 0); ++ amvdec_write_parser(core, PARSER_CONTROL, ++ ES_WRITE | ++ ES_PARSER_START | ++ ES_SEARCH | ++ (size << ES_PACK_SIZE_BIT)); ++ ++ amvdec_write_parser(core, PARSER_FETCH_ADDR, addr); ++ amvdec_write_parser(core, PARSER_FETCH_CMD, ++ (7 << FETCH_ENDIAN_BIT) | ++ (size + SEARCH_PATTERN_LEN)); ++ ++ search_done = 0; ++ return wait_event_interruptible_timeout(wq, search_done, (HZ / 5)); ++} ++ ++static u32 esparser_vififo_get_free_space(struct amvdec_session *sess) ++{ ++ u32 vififo_usage; ++ struct amvdec_ops *vdec_ops = sess->fmt_out->vdec_ops; ++ struct amvdec_core *core = sess->core; ++ ++ vififo_usage = vdec_ops->vififo_level(sess); ++ vififo_usage += amvdec_read_parser(core, PARSER_VIDEO_HOLE); ++ vififo_usage += (6 * SZ_1K); ++ ++ if (vififo_usage > sess->vififo_size) { ++ dev_warn(sess->core->dev, ++ "VIFIFO usage (%u) > VIFIFO size (%u)\n", ++ vififo_usage, sess->vififo_size); ++ return 0; ++ } ++ ++ return sess->vififo_size - vififo_usage; ++} ++ ++int esparser_queue_eos(struct amvdec_core *core) ++{ ++ struct device *dev = core->dev; ++ void *eos_vaddr; ++ dma_addr_t eos_paddr; ++ int ret; ++ ++ eos_vaddr = dma_alloc_coherent(dev, ++ EOS_TAIL_BUF_SIZE + SEARCH_PATTERN_LEN, ++ &eos_paddr, GFP_KERNEL); ++ if (!eos_vaddr) ++ return -ENOMEM; ++ ++ memset(eos_vaddr, 0, EOS_TAIL_BUF_SIZE + SEARCH_PATTERN_LEN); ++ memcpy(eos_vaddr, eos_tail_data, sizeof(eos_tail_data)); ++ ret = esparser_write_data(core, eos_paddr, EOS_TAIL_BUF_SIZE); ++ dma_free_coherent(dev, EOS_TAIL_BUF_SIZE + SEARCH_PATTERN_LEN, ++ eos_vaddr, eos_paddr); ++ ++ return ret; ++} ++ ++static int ++esparser_queue(struct amvdec_session *sess, struct vb2_v4l2_buffer *vbuf) ++{ ++ int ret; ++ struct vb2_buffer *vb = &vbuf->vb2_buf; ++ struct amvdec_core *core = sess->core; ++ struct amvdec_codec_ops *codec_ops = sess->fmt_out->codec_ops; ++ u32 num_dst_bufs = 0; ++ u32 payload_size = vb2_get_plane_payload(vb, 0); ++ dma_addr_t phy = vb2_dma_contig_plane_dma_addr(vb, 0); ++ u32 pad_size; ++ ++ if (!payload_size) { ++ esparser_queue_eos(core); ++ return 0; ++ } ++ ++ if (codec_ops->num_pending_bufs) ++ num_dst_bufs = codec_ops->num_pending_bufs(sess); ++ ++ num_dst_bufs += v4l2_m2m_num_dst_bufs_ready(sess->m2m_ctx); ++ ++ if (esparser_vififo_get_free_space(sess) < payload_size || ++ atomic_read(&sess->esparser_queued_bufs) >= num_dst_bufs) ++ return -EAGAIN; ++ ++ v4l2_m2m_src_buf_remove_by_buf(sess->m2m_ctx, vbuf); ++ amvdec_add_ts_reorder(sess, vb->timestamp); ++ dev_dbg(core->dev, "esparser: Queuing ts = %llu ; pld_size = %u\n", ++ vb->timestamp, payload_size); ++ ++ pad_size = esparser_pad_start_code(vb); ++ ret = esparser_write_data(core, phy, payload_size + pad_size); ++ ++ if (ret > 0) { ++ /* We need to wait until we parse/decode the first keyframe. ++ * All buffers prior to the first keyframe must be dropped. ++ */ ++ if (!sess->keyframe_found) ++ usleep_range(1000, 2000); ++ ++ if (sess->keyframe_found) ++ atomic_inc(&sess->esparser_queued_bufs); ++ else ++ amvdec_remove_ts(sess, vb->timestamp); ++ ++ vbuf->flags = 0; ++ vbuf->field = V4L2_FIELD_NONE; ++ v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_DONE); ++ return 0; ++ } ++ ++ dev_warn(core->dev, "esparser: input parsing error\n"); ++ amvdec_remove_ts(sess, vb->timestamp); ++ v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR); ++ amvdec_write_parser(core, PARSER_FETCH_CMD, 0); ++ ++ return 0; ++} ++ ++void esparser_queue_all_src(struct work_struct *work) ++{ ++ struct v4l2_m2m_buffer *buf, *n; ++ struct amvdec_session *sess = ++ container_of(work, struct amvdec_session, esparser_queue_work); ++ ++ mutex_lock(&sess->lock); ++ v4l2_m2m_for_each_src_buf_safe(sess->m2m_ctx, buf, n) { ++ if (esparser_queue(sess, &buf->vb) < 0) ++ break; ++ ++ /* Some codecs don't like having data queued in too fast */ ++ usleep_range(1000, 2000); ++ } ++ mutex_unlock(&sess->lock); ++} ++ ++int esparser_power_up(struct amvdec_session *sess) ++{ ++ struct amvdec_core *core = sess->core; ++ struct amvdec_ops *vdec_ops = sess->fmt_out->vdec_ops; ++ ++ reset_control_reset(core->esparser_reset); ++ amvdec_write_parser(core, PARSER_CONFIG, ++ (10 << PS_CFG_PFIFO_EMPTY_CNT_BIT) | ++ (1 << PS_CFG_MAX_ES_WR_CYCLE_BIT) | ++ (16 << PS_CFG_MAX_FETCH_CYCLE_BIT)); ++ ++ amvdec_write_parser(core, PFIFO_RD_PTR, 0); ++ amvdec_write_parser(core, PFIFO_WR_PTR, 0); ++ ++ amvdec_write_parser(core, PARSER_SEARCH_PATTERN, ++ ES_START_CODE_PATTERN); ++ amvdec_write_parser(core, PARSER_SEARCH_MASK, ES_START_CODE_MASK); ++ ++ amvdec_write_parser(core, PARSER_CONFIG, ++ (10 << PS_CFG_PFIFO_EMPTY_CNT_BIT) | ++ (1 << PS_CFG_MAX_ES_WR_CYCLE_BIT) | ++ (16 << PS_CFG_MAX_FETCH_CYCLE_BIT) | ++ (2 << PS_CFG_STARTCODE_WID_24_BIT)); ++ ++ amvdec_write_parser(core, PARSER_CONTROL, ++ (ES_SEARCH | ES_PARSER_START)); ++ ++ amvdec_write_parser(core, PARSER_VIDEO_START_PTR, sess->vififo_paddr); ++ amvdec_write_parser(core, PARSER_VIDEO_END_PTR, ++ sess->vififo_paddr + sess->vififo_size - 8); ++ amvdec_write_parser(core, PARSER_ES_CONTROL, ++ amvdec_read_parser(core, PARSER_ES_CONTROL) & ~1); ++ ++ if (vdec_ops->conf_esparser) ++ vdec_ops->conf_esparser(sess); ++ ++ amvdec_write_parser(core, PARSER_INT_STATUS, 0xffff); ++ amvdec_write_parser(core, PARSER_INT_ENABLE, ++ BIT(PARSER_INT_HOST_EN_BIT)); ++ ++ return 0; ++} ++ ++int esparser_init(struct platform_device *pdev, struct amvdec_core *core) ++{ ++ struct device *dev = &pdev->dev; ++ int ret; ++ int irq; ++ ++ irq = platform_get_irq(pdev, 1); ++ if (irq < 0) { ++ dev_err(dev, "Failed getting ESPARSER IRQ from dtb\n"); ++ return irq; ++ } ++ ++ ret = devm_request_irq(dev, irq, esparser_isr, IRQF_SHARED, ++ "esparserirq", core); ++ if (ret) { ++ dev_err(dev, "Failed requesting ESPARSER IRQ\n"); ++ return ret; ++ } ++ ++ core->esparser_reset = ++ devm_reset_control_get_exclusive(dev, "esparser"); ++ if (IS_ERR(core->esparser_reset)) { ++ dev_err(dev, "Failed to get esparser_reset\n"); ++ return PTR_ERR(core->esparser_reset); ++ } ++ ++ return 0; ++} +diff --git a/drivers/media/platform/meson/vdec/esparser.h b/drivers/media/platform/meson/vdec/esparser.h +new file mode 100644 +index 0000000000000..22c2ac5c6d35b +--- /dev/null ++++ b/drivers/media/platform/meson/vdec/esparser.h +@@ -0,0 +1,28 @@ ++/* SPDX-License-Identifier: GPL-2.0+ */ ++/* ++ * Copyright (C) 2018 BayLibre, SAS ++ * Author: Maxime Jourdan ++ */ ++ ++#ifndef __MESON_VDEC_ESPARSER_H_ ++#define __MESON_VDEC_ESPARSER_H_ ++ ++#include "vdec.h" ++ ++int esparser_init(struct platform_device *pdev, struct amvdec_core *core); ++int esparser_power_up(struct amvdec_session *sess); ++ ++/** ++ * esparser_queue_eos() - write End Of Stream sequence to the ESPARSER ++ * ++ * @core vdec core struct ++ */ ++int esparser_queue_eos(struct amvdec_core *core); ++ ++/** ++ * esparser_queue_all_src() - work handler that writes as many src buffers ++ * as possible to the ESPARSER ++ */ ++void esparser_queue_all_src(struct work_struct *work); ++ ++#endif +diff --git a/drivers/media/platform/meson/vdec/vdec.c b/drivers/media/platform/meson/vdec/vdec.c +new file mode 100644 +index 0000000000000..32e1e22282970 +--- /dev/null ++++ b/drivers/media/platform/meson/vdec/vdec.c +@@ -0,0 +1,988 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright (C) 2018 BayLibre, SAS ++ * Author: Maxime Jourdan ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "vdec.h" ++#include "esparser.h" ++#include "vdec_helpers.h" ++ ++struct dummy_buf { ++ struct vb2_v4l2_buffer vb; ++ struct list_head list; ++}; ++ ++/* 16 MiB for parsed bitstream swap exchange */ ++#define SIZE_VIFIFO SZ_16M ++ ++static u32 get_output_size(u32 width, u32 height) ++{ ++ return ALIGN(width * height, SZ_64K); ++} ++ ++u32 amvdec_get_output_size(struct amvdec_session *sess) ++{ ++ return get_output_size(sess->width, sess->height); ++} ++EXPORT_SYMBOL_GPL(amvdec_get_output_size); ++ ++static int vdec_codec_needs_recycle(struct amvdec_session *sess) ++{ ++ struct amvdec_codec_ops *codec_ops = sess->fmt_out->codec_ops; ++ ++ return codec_ops->can_recycle && codec_ops->recycle; ++} ++ ++static int vdec_recycle_thread(void *data) ++{ ++ struct amvdec_session *sess = data; ++ struct amvdec_core *core = sess->core; ++ struct amvdec_codec_ops *codec_ops = sess->fmt_out->codec_ops; ++ struct amvdec_buffer *tmp, *n; ++ ++ while (!kthread_should_stop()) { ++ mutex_lock(&sess->bufs_recycle_lock); ++ list_for_each_entry_safe(tmp, n, &sess->bufs_recycle, list) { ++ if (!codec_ops->can_recycle(core)) ++ break; ++ ++ codec_ops->recycle(core, tmp->vb->index); ++ dev_dbg(core->dev, "Buffer %d recycled\n", ++ tmp->vb->index); ++ list_del(&tmp->list); ++ kfree(tmp); ++ } ++ mutex_unlock(&sess->bufs_recycle_lock); ++ ++ usleep_range(5000, 10000); ++ } ++ ++ return 0; ++} ++ ++static int vdec_poweron(struct amvdec_session *sess) ++{ ++ int ret; ++ struct amvdec_ops *vdec_ops = sess->fmt_out->vdec_ops; ++ ++ ret = clk_prepare_enable(sess->core->dos_parser_clk); ++ if (ret) ++ return ret; ++ ++ ret = clk_prepare_enable(sess->core->dos_clk); ++ if (ret) ++ goto disable_dos_parser; ++ ++ ret = vdec_ops->start(sess); ++ if (ret) ++ goto disable_dos; ++ ++ esparser_power_up(sess); ++ ++ return 0; ++ ++disable_dos: ++ clk_disable_unprepare(sess->core->dos_clk); ++disable_dos_parser: ++ clk_disable_unprepare(sess->core->dos_parser_clk); ++ ++ return ret; ++} ++ ++static void vdec_wait_inactive(struct amvdec_session *sess) ++{ ++ /* We consider 50ms with no IRQ to be inactive. */ ++ while (time_is_after_jiffies64(sess->last_irq_jiffies + ++ msecs_to_jiffies(50))) ++ msleep(25); ++} ++ ++static void vdec_poweroff(struct amvdec_session *sess) ++{ ++ struct amvdec_ops *vdec_ops = sess->fmt_out->vdec_ops; ++ struct amvdec_codec_ops *codec_ops = sess->fmt_out->codec_ops; ++ ++ vdec_wait_inactive(sess); ++ if (codec_ops->drain) ++ codec_ops->drain(sess); ++ ++ vdec_ops->stop(sess); ++ clk_disable_unprepare(sess->core->dos_clk); ++ clk_disable_unprepare(sess->core->dos_parser_clk); ++} ++ ++static void ++vdec_queue_recycle(struct amvdec_session *sess, struct vb2_buffer *vb) ++{ ++ struct amvdec_buffer *new_buf; ++ ++ new_buf = kmalloc(sizeof(*new_buf), GFP_KERNEL); ++ new_buf->vb = vb; ++ ++ mutex_lock(&sess->bufs_recycle_lock); ++ list_add_tail(&new_buf->list, &sess->bufs_recycle); ++ mutex_unlock(&sess->bufs_recycle_lock); ++} ++ ++static void vdec_m2m_device_run(void *priv) ++{ ++ struct amvdec_session *sess = priv; ++ ++ schedule_work(&sess->esparser_queue_work); ++} ++ ++static void vdec_m2m_job_abort(void *priv) ++{ ++ struct amvdec_session *sess = priv; ++ ++ v4l2_m2m_job_finish(sess->m2m_dev, sess->m2m_ctx); ++} ++ ++static const struct v4l2_m2m_ops vdec_m2m_ops = { ++ .device_run = vdec_m2m_device_run, ++ .job_abort = vdec_m2m_job_abort, ++}; ++ ++static int vdec_queue_setup(struct vb2_queue *q, ++ unsigned int *num_buffers, unsigned int *num_planes, ++ unsigned int sizes[], struct device *alloc_devs[]) ++{ ++ struct amvdec_session *sess = vb2_get_drv_priv(q); ++ struct amvdec_core *core = sess->core; ++ const struct amvdec_format *fmt_out = sess->fmt_out; ++ u32 pixfmt_cap = sess->pixfmt_cap; ++ ++ switch (q->type) { ++ case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: ++ sizes[0] = amvdec_get_output_size(sess); ++ *num_planes = 1; ++ break; ++ case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: ++ if (pixfmt_cap == V4L2_PIX_FMT_NV12M) { ++ sizes[0] = amvdec_get_output_size(sess); ++ sizes[1] = amvdec_get_output_size(sess) / 2; ++ *num_planes = 2; ++ } else if (pixfmt_cap == V4L2_PIX_FMT_YUV420M) { ++ sizes[0] = amvdec_get_output_size(sess); ++ sizes[1] = amvdec_get_output_size(sess) / 4; ++ sizes[2] = amvdec_get_output_size(sess) / 4; ++ *num_planes = 3; ++ } ++ *num_buffers = min(max(*num_buffers, fmt_out->min_buffers), ++ fmt_out->max_buffers); ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ mutex_lock(&core->lock); ++ if (core->cur_sess && core->cur_sess != sess) { ++ mutex_unlock(&core->lock); ++ return -EBUSY; ++ } ++ ++ core->cur_sess = sess; ++ mutex_unlock(&core->lock); ++ ++ return 0; ++} ++ ++static void vdec_vb2_buf_queue(struct vb2_buffer *vb) ++{ ++ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); ++ struct amvdec_session *sess = vb2_get_drv_priv(vb->vb2_queue); ++ struct v4l2_m2m_ctx *m2m_ctx = sess->m2m_ctx; ++ ++ mutex_lock(&sess->lock); ++ v4l2_m2m_buf_queue(m2m_ctx, vbuf); ++ ++ if (!sess->streamon_out || !sess->streamon_cap) ++ goto unlock; ++ ++ if (vb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE && ++ vdec_codec_needs_recycle(sess)) ++ vdec_queue_recycle(sess, vb); ++ ++ schedule_work(&sess->esparser_queue_work); ++unlock: ++ mutex_unlock(&sess->lock); ++} ++ ++static int vdec_start_streaming(struct vb2_queue *q, unsigned int count) ++{ ++ struct amvdec_session *sess = vb2_get_drv_priv(q); ++ struct vb2_v4l2_buffer *buf; ++ int ret; ++ ++ mutex_lock(&sess->lock); ++ ++ if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) ++ sess->streamon_out = 1; ++ else ++ sess->streamon_cap = 1; ++ ++ if (!sess->streamon_out || !sess->streamon_cap) { ++ mutex_unlock(&sess->lock); ++ return 0; ++ } ++ ++ sess->vififo_size = SIZE_VIFIFO; ++ sess->vififo_vaddr = ++ dma_alloc_coherent(sess->core->dev, sess->vififo_size, ++ &sess->vififo_paddr, GFP_KERNEL); ++ if (!sess->vififo_vaddr) { ++ dev_err(sess->core->dev, "Failed to request VIFIFO buffer\n"); ++ ret = -ENOMEM; ++ goto bufs_done; ++ } ++ ++ sess->should_stop = 0; ++ sess->keyframe_found = 0; ++ atomic_set(&sess->esparser_queued_bufs, 0); ++ ret = vdec_poweron(sess); ++ if (ret) ++ goto vififo_free; ++ ++ sess->sequence_cap = 0; ++ if (vdec_codec_needs_recycle(sess)) ++ sess->recycle_thread = kthread_run(vdec_recycle_thread, sess, ++ "vdec_recycle"); ++ mutex_unlock(&sess->lock); ++ ++ return 0; ++ ++vififo_free: ++ dma_free_coherent(sess->core->dev, sess->vififo_size, ++ sess->vififo_vaddr, sess->vififo_paddr); ++bufs_done: ++ while ((buf = v4l2_m2m_src_buf_remove(sess->m2m_ctx))) ++ v4l2_m2m_buf_done(buf, VB2_BUF_STATE_QUEUED); ++ while ((buf = v4l2_m2m_dst_buf_remove(sess->m2m_ctx))) ++ v4l2_m2m_buf_done(buf, VB2_BUF_STATE_QUEUED); ++ ++ if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) ++ sess->streamon_out = 0; ++ else ++ sess->streamon_cap = 0; ++ mutex_unlock(&sess->lock); ++ return ret; ++} ++ ++static void vdec_free_canvas(struct amvdec_session *sess) ++{ ++ int i; ++ ++ for (i = 0; i < sess->canvas_num; ++i) ++ meson_canvas_free(sess->core->canvas, sess->canvas_alloc[i]); ++ ++ sess->canvas_num = 0; ++} ++ ++static void vdec_reset_timestamps(struct amvdec_session *sess) ++{ ++ struct amvdec_timestamp *tmp, *n; ++ ++ list_for_each_entry_safe(tmp, n, &sess->timestamps, list) { ++ list_del(&tmp->list); ++ kfree(tmp); ++ } ++} ++ ++static void vdec_reset_bufs_recycle(struct amvdec_session *sess) ++{ ++ struct amvdec_buffer *tmp, *n; ++ ++ list_for_each_entry_safe(tmp, n, &sess->bufs_recycle, list) { ++ list_del(&tmp->list); ++ kfree(tmp); ++ } ++} ++ ++static void vdec_stop_streaming(struct vb2_queue *q) ++{ ++ struct amvdec_session *sess = vb2_get_drv_priv(q); ++ struct vb2_v4l2_buffer *buf; ++ ++ mutex_lock(&sess->lock); ++ ++ if (sess->streamon_out && sess->streamon_cap) { ++ if (vdec_codec_needs_recycle(sess)) ++ kthread_stop(sess->recycle_thread); ++ ++ vdec_poweroff(sess); ++ vdec_free_canvas(sess); ++ dma_free_coherent(sess->core->dev, sess->vififo_size, ++ sess->vififo_vaddr, sess->vififo_paddr); ++ vdec_reset_timestamps(sess); ++ vdec_reset_bufs_recycle(sess); ++ kfree(sess->priv); ++ sess->priv = NULL; ++ } ++ ++ if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { ++ while ((buf = v4l2_m2m_src_buf_remove(sess->m2m_ctx))) ++ v4l2_m2m_buf_done(buf, VB2_BUF_STATE_ERROR); ++ ++ sess->streamon_out = 0; ++ } else { ++ while ((buf = v4l2_m2m_dst_buf_remove(sess->m2m_ctx))) ++ v4l2_m2m_buf_done(buf, VB2_BUF_STATE_ERROR); ++ ++ sess->streamon_cap = 0; ++ } ++ ++ mutex_unlock(&sess->lock); ++} ++ ++static const struct vb2_ops vdec_vb2_ops = { ++ .queue_setup = vdec_queue_setup, ++ .start_streaming = vdec_start_streaming, ++ .stop_streaming = vdec_stop_streaming, ++ .buf_queue = vdec_vb2_buf_queue, ++}; ++ ++static int ++vdec_querycap(struct file *file, void *fh, struct v4l2_capability *cap) ++{ ++ strlcpy(cap->driver, "meson-vdec", sizeof(cap->driver)); ++ strlcpy(cap->card, "Amlogic Video Decoder", sizeof(cap->card)); ++ strlcpy(cap->bus_info, "platform:meson-vdec", sizeof(cap->bus_info)); ++ ++ return 0; ++} ++ ++static const struct amvdec_format * ++find_format(const struct amvdec_format *fmts, u32 size, u32 pixfmt) ++{ ++ unsigned int i; ++ ++ for (i = 0; i < size; i++) { ++ if (fmts[i].pixfmt == pixfmt) ++ return &fmts[i]; ++ } ++ ++ return NULL; ++} ++ ++static unsigned int ++vdec_supports_pixfmt_cap(const struct amvdec_format *fmt_out, u32 pixfmt_cap) ++{ ++ int i; ++ ++ for (i = 0; fmt_out->pixfmts_cap[i]; i++) ++ if (fmt_out->pixfmts_cap[i] == pixfmt_cap) ++ return 1; ++ ++ return 0; ++} ++ ++static const struct amvdec_format * ++vdec_try_fmt_common(struct amvdec_session *sess, u32 size, ++ struct v4l2_format *f) ++{ ++ struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp; ++ struct v4l2_plane_pix_format *pfmt = pixmp->plane_fmt; ++ const struct amvdec_format *fmts = sess->core->platform->formats; ++ const struct amvdec_format *fmt_out; ++ ++ memset(pfmt[0].reserved, 0, sizeof(pfmt[0].reserved)); ++ memset(pixmp->reserved, 0, sizeof(pixmp->reserved)); ++ ++ if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { ++ fmt_out = find_format(fmts, size, pixmp->pixelformat); ++ if (!fmt_out) { ++ pixmp->pixelformat = V4L2_PIX_FMT_MPEG2; ++ fmt_out = find_format(fmts, size, pixmp->pixelformat); ++ pixmp->width = 1280; ++ pixmp->height = 720; ++ } ++ ++ pfmt[0].sizeimage = ++ get_output_size(pixmp->width, pixmp->height); ++ pfmt[0].bytesperline = 0; ++ pixmp->num_planes = 1; ++ } else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { ++ fmt_out = sess->fmt_out; ++ if (!vdec_supports_pixfmt_cap(fmt_out, pixmp->pixelformat)) ++ pixmp->pixelformat = fmt_out->pixfmts_cap[0]; ++ ++ memset(pfmt[1].reserved, 0, sizeof(pfmt[1].reserved)); ++ if (pixmp->pixelformat == V4L2_PIX_FMT_NV12M) { ++ pfmt[0].sizeimage = ++ get_output_size(pixmp->width, pixmp->height); ++ pfmt[0].bytesperline = ALIGN(pixmp->width, 64); ++ ++ pfmt[1].sizeimage = ++ get_output_size(pixmp->width, pixmp->height) / 2; ++ pfmt[1].bytesperline = ALIGN(pixmp->width, 64); ++ pixmp->num_planes = 2; ++ } else if (pixmp->pixelformat == V4L2_PIX_FMT_YUV420M) { ++ pfmt[0].sizeimage = ++ get_output_size(pixmp->width, pixmp->height); ++ pfmt[0].bytesperline = ALIGN(pixmp->width, 64); ++ ++ pfmt[1].sizeimage = ++ get_output_size(pixmp->width, pixmp->height) / 4; ++ pfmt[1].bytesperline = ALIGN(pixmp->width, 64) / 2; ++ ++ pfmt[2].sizeimage = ++ get_output_size(pixmp->width, pixmp->height) / 4; ++ pfmt[2].bytesperline = ALIGN(pixmp->width, 64) / 2; ++ pixmp->num_planes = 3; ++ } ++ } else { ++ return NULL; ++ } ++ ++ pixmp->width = clamp(pixmp->width, (u32)256, fmt_out->max_width); ++ pixmp->height = clamp(pixmp->height, (u32)144, fmt_out->max_height); ++ ++ if (pixmp->field == V4L2_FIELD_ANY) ++ pixmp->field = V4L2_FIELD_NONE; ++ ++ pixmp->flags = 0; ++ ++ return fmt_out; ++} ++ ++static int vdec_try_fmt(struct file *file, void *fh, struct v4l2_format *f) ++{ ++ struct amvdec_session *sess = ++ container_of(file->private_data, struct amvdec_session, fh); ++ ++ vdec_try_fmt_common(sess, sess->core->platform->num_formats, f); ++ ++ return 0; ++} ++ ++static int vdec_g_fmt(struct file *file, void *fh, struct v4l2_format *f) ++{ ++ struct amvdec_session *sess = ++ container_of(file->private_data, struct amvdec_session, fh); ++ struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp; ++ ++ if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) ++ pixmp->pixelformat = sess->pixfmt_cap; ++ else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) ++ pixmp->pixelformat = sess->fmt_out->pixfmt; ++ ++ if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { ++ pixmp->width = sess->width; ++ pixmp->height = sess->height; ++ pixmp->colorspace = sess->colorspace; ++ pixmp->ycbcr_enc = sess->ycbcr_enc; ++ pixmp->quantization = sess->quantization; ++ pixmp->xfer_func = sess->xfer_func; ++ } else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { ++ pixmp->width = sess->width; ++ pixmp->height = sess->height; ++ } ++ ++ vdec_try_fmt_common(sess, sess->core->platform->num_formats, f); ++ ++ return 0; ++} ++ ++static int vdec_s_fmt(struct file *file, void *fh, struct v4l2_format *f) ++{ ++ struct amvdec_session *sess = ++ container_of(file->private_data, struct amvdec_session, fh); ++ struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp; ++ u32 num_formats = sess->core->platform->num_formats; ++ const struct amvdec_format *fmt_out; ++ struct v4l2_pix_format_mplane orig_pixmp; ++ struct v4l2_format format; ++ u32 pixfmt_out = 0, pixfmt_cap = 0; ++ ++ orig_pixmp = *pixmp; ++ ++ fmt_out = vdec_try_fmt_common(sess, num_formats, f); ++ ++ if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { ++ pixfmt_out = pixmp->pixelformat; ++ pixfmt_cap = sess->pixfmt_cap; ++ } else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { ++ pixfmt_cap = pixmp->pixelformat; ++ pixfmt_out = sess->fmt_out->pixfmt; ++ } ++ ++ memset(&format, 0, sizeof(format)); ++ ++ format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; ++ format.fmt.pix_mp.pixelformat = pixfmt_out; ++ format.fmt.pix_mp.width = orig_pixmp.width; ++ format.fmt.pix_mp.height = orig_pixmp.height; ++ vdec_try_fmt_common(sess, num_formats, &format); ++ ++ if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { ++ sess->width = format.fmt.pix_mp.width; ++ sess->height = format.fmt.pix_mp.height; ++ sess->colorspace = pixmp->colorspace; ++ sess->ycbcr_enc = pixmp->ycbcr_enc; ++ sess->quantization = pixmp->quantization; ++ sess->xfer_func = pixmp->xfer_func; ++ } ++ ++ memset(&format, 0, sizeof(format)); ++ ++ format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; ++ format.fmt.pix_mp.pixelformat = pixfmt_cap; ++ format.fmt.pix_mp.width = orig_pixmp.width; ++ format.fmt.pix_mp.height = orig_pixmp.height; ++ vdec_try_fmt_common(sess, num_formats, &format); ++ ++ sess->width = format.fmt.pix_mp.width; ++ sess->height = format.fmt.pix_mp.height; ++ ++ if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) ++ sess->fmt_out = fmt_out; ++ else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) ++ sess->pixfmt_cap = format.fmt.pix_mp.pixelformat; ++ ++ return 0; ++} ++ ++static int vdec_enum_fmt(struct file *file, void *fh, struct v4l2_fmtdesc *f) ++{ ++ struct amvdec_session *sess = ++ container_of(file->private_data, struct amvdec_session, fh); ++ const struct vdec_platform *platform = sess->core->platform; ++ const struct amvdec_format *fmt_out; ++ ++ memset(f->reserved, 0, sizeof(f->reserved)); ++ ++ if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { ++ if (f->index >= platform->num_formats) ++ return -EINVAL; ++ ++ fmt_out = &platform->formats[f->index]; ++ f->pixelformat = fmt_out->pixfmt; ++ } else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { ++ fmt_out = sess->fmt_out; ++ if (f->index >= 4 || !fmt_out->pixfmts_cap[f->index]) ++ return -EINVAL; ++ ++ f->pixelformat = fmt_out->pixfmts_cap[f->index]; ++ } else { ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static int vdec_enum_framesizes(struct file *file, void *fh, ++ struct v4l2_frmsizeenum *fsize) ++{ ++ struct amvdec_session *sess = ++ container_of(file->private_data, struct amvdec_session, fh); ++ const struct amvdec_format *formats = sess->core->platform->formats; ++ const struct amvdec_format *fmt; ++ u32 num_formats = sess->core->platform->num_formats; ++ ++ fmt = find_format(formats, num_formats, fsize->pixel_format); ++ if (!fmt || fsize->index) ++ return -EINVAL; ++ ++ fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE; ++ ++ fsize->stepwise.min_width = 256; ++ fsize->stepwise.max_width = fmt->max_width; ++ fsize->stepwise.step_width = 1; ++ fsize->stepwise.min_height = 144; ++ fsize->stepwise.max_height = fmt->max_height; ++ fsize->stepwise.step_height = 1; ++ ++ return 0; ++} ++ ++static int ++vdec_try_decoder_cmd(struct file *file, void *fh, struct v4l2_decoder_cmd *cmd) ++{ ++ switch (cmd->cmd) { ++ case V4L2_DEC_CMD_STOP: ++ if (cmd->flags & V4L2_DEC_CMD_STOP_TO_BLACK) ++ return -EINVAL; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static int ++vdec_decoder_cmd(struct file *file, void *fh, struct v4l2_decoder_cmd *cmd) ++{ ++ struct amvdec_session *sess = ++ container_of(file->private_data, struct amvdec_session, fh); ++ struct amvdec_codec_ops *codec_ops = sess->fmt_out->codec_ops; ++ int ret; ++ ++ ret = vdec_try_decoder_cmd(file, fh, cmd); ++ if (ret) ++ return ret; ++ ++ if (!(sess->streamon_out & sess->streamon_cap)) ++ goto unlock; ++ ++ dev_dbg(sess->core->dev, "Received V4L2_DEC_CMD_STOP\n"); ++ sess->should_stop = 1; ++ ++ vdec_wait_inactive(sess); ++ ++ mutex_lock(&sess->lock); ++ if (codec_ops->drain) ++ codec_ops->drain(sess); ++ else ++ esparser_queue_eos(sess->core); ++ ++unlock: ++ mutex_unlock(&sess->lock); ++ return ret; ++} ++ ++static int vdec_subscribe_event(struct v4l2_fh *fh, ++ const struct v4l2_event_subscription *sub) ++{ ++ switch (sub->type) { ++ case V4L2_EVENT_EOS: ++ return v4l2_event_subscribe(fh, sub, 2, NULL); ++ default: ++ return -EINVAL; ++ } ++} ++ ++static const struct v4l2_ioctl_ops vdec_ioctl_ops = { ++ .vidioc_querycap = vdec_querycap, ++ .vidioc_enum_fmt_vid_cap_mplane = vdec_enum_fmt, ++ .vidioc_enum_fmt_vid_out_mplane = vdec_enum_fmt, ++ .vidioc_s_fmt_vid_cap_mplane = vdec_s_fmt, ++ .vidioc_s_fmt_vid_out_mplane = vdec_s_fmt, ++ .vidioc_g_fmt_vid_cap_mplane = vdec_g_fmt, ++ .vidioc_g_fmt_vid_out_mplane = vdec_g_fmt, ++ .vidioc_try_fmt_vid_cap_mplane = vdec_try_fmt, ++ .vidioc_try_fmt_vid_out_mplane = vdec_try_fmt, ++ .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs, ++ .vidioc_querybuf = v4l2_m2m_ioctl_querybuf, ++ .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs, ++ .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf, ++ .vidioc_qbuf = v4l2_m2m_ioctl_qbuf, ++ .vidioc_expbuf = v4l2_m2m_ioctl_expbuf, ++ .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf, ++ .vidioc_streamon = v4l2_m2m_ioctl_streamon, ++ .vidioc_streamoff = v4l2_m2m_ioctl_streamoff, ++ .vidioc_enum_framesizes = vdec_enum_framesizes, ++ .vidioc_subscribe_event = vdec_subscribe_event, ++ .vidioc_unsubscribe_event = v4l2_event_unsubscribe, ++ .vidioc_try_decoder_cmd = vdec_try_decoder_cmd, ++ .vidioc_decoder_cmd = vdec_decoder_cmd, ++}; ++ ++static int m2m_queue_init(void *priv, struct vb2_queue *src_vq, ++ struct vb2_queue *dst_vq) ++{ ++ struct amvdec_session *sess = priv; ++ int ret; ++ ++ src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; ++ src_vq->io_modes = VB2_MMAP | VB2_DMABUF; ++ src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; ++ src_vq->ops = &vdec_vb2_ops; ++ src_vq->mem_ops = &vb2_dma_contig_memops; ++ src_vq->drv_priv = sess; ++ src_vq->buf_struct_size = sizeof(struct dummy_buf); ++ src_vq->allow_zero_bytesused = 1; ++ src_vq->min_buffers_needed = 1; ++ src_vq->dev = sess->core->dev; ++ ret = vb2_queue_init(src_vq); ++ if (ret) ++ return ret; ++ ++ dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; ++ dst_vq->io_modes = VB2_MMAP | VB2_DMABUF; ++ dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; ++ dst_vq->ops = &vdec_vb2_ops; ++ dst_vq->mem_ops = &vb2_dma_contig_memops; ++ dst_vq->drv_priv = sess; ++ dst_vq->buf_struct_size = sizeof(struct dummy_buf); ++ dst_vq->allow_zero_bytesused = 1; ++ dst_vq->min_buffers_needed = 1; ++ dst_vq->dev = sess->core->dev; ++ ret = vb2_queue_init(dst_vq); ++ if (ret) { ++ vb2_queue_release(src_vq); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static int vdec_open(struct file *file) ++{ ++ struct amvdec_core *core = video_drvdata(file); ++ struct device *dev = core->dev; ++ const struct amvdec_format *formats = core->platform->formats; ++ struct amvdec_session *sess; ++ int ret; ++ ++ sess = kzalloc(sizeof(*sess), GFP_KERNEL); ++ if (!sess) { ++ mutex_unlock(&core->lock); ++ return -ENOMEM; ++ } ++ ++ sess->core = core; ++ ++ sess->m2m_dev = v4l2_m2m_init(&vdec_m2m_ops); ++ if (IS_ERR(sess->m2m_dev)) { ++ dev_err(dev, "Fail to v4l2_m2m_init\n"); ++ ret = PTR_ERR(sess->m2m_dev); ++ goto err_free_sess; ++ } ++ ++ sess->m2m_ctx = v4l2_m2m_ctx_init(sess->m2m_dev, sess, m2m_queue_init); ++ if (IS_ERR(sess->m2m_ctx)) { ++ dev_err(dev, "Fail to v4l2_m2m_ctx_init\n"); ++ ret = PTR_ERR(sess->m2m_ctx); ++ goto err_m2m_release; ++ } ++ ++ sess->pixfmt_cap = formats[0].pixfmts_cap[0]; ++ sess->fmt_out = &formats[0]; ++ sess->width = 1280; ++ sess->height = 720; ++ ++ INIT_LIST_HEAD(&sess->timestamps); ++ INIT_LIST_HEAD(&sess->bufs_recycle); ++ INIT_WORK(&sess->esparser_queue_work, esparser_queue_all_src); ++ mutex_init(&sess->lock); ++ mutex_init(&sess->bufs_recycle_lock); ++ spin_lock_init(&sess->ts_spinlock); ++ ++ v4l2_fh_init(&sess->fh, core->vdev_dec); ++ v4l2_fh_add(&sess->fh); ++ sess->fh.m2m_ctx = sess->m2m_ctx; ++ file->private_data = &sess->fh; ++ ++ return 0; ++ ++err_m2m_release: ++ v4l2_m2m_release(sess->m2m_dev); ++err_free_sess: ++ kfree(sess); ++ return ret; ++} ++ ++static int vdec_close(struct file *file) ++{ ++ struct amvdec_session *sess = ++ container_of(file->private_data, struct amvdec_session, fh); ++ struct amvdec_core *core = sess->core; ++ ++ v4l2_m2m_ctx_release(sess->m2m_ctx); ++ v4l2_m2m_release(sess->m2m_dev); ++ v4l2_fh_del(&sess->fh); ++ v4l2_fh_exit(&sess->fh); ++ ++ mutex_destroy(&sess->lock); ++ mutex_destroy(&sess->bufs_recycle_lock); ++ ++ kfree(sess); ++ ++ if (core->cur_sess == sess) ++ core->cur_sess = NULL; ++ ++ return 0; ++} ++ ++static const struct v4l2_file_operations vdec_fops = { ++ .owner = THIS_MODULE, ++ .open = vdec_open, ++ .release = vdec_close, ++ .unlocked_ioctl = video_ioctl2, ++ .poll = v4l2_m2m_fop_poll, ++ .mmap = v4l2_m2m_fop_mmap, ++#ifdef CONFIG_COMPAT ++ .compat_ioctl32 = v4l2_compat_ioctl32, ++#endif ++}; ++ ++static irqreturn_t vdec_isr(int irq, void *data) ++{ ++ struct amvdec_core *core = data; ++ struct amvdec_session *sess = core->cur_sess; ++ ++ sess->last_irq_jiffies = get_jiffies_64(); ++ ++ return sess->fmt_out->codec_ops->isr(sess); ++} ++ ++static irqreturn_t vdec_threaded_isr(int irq, void *data) ++{ ++ struct amvdec_core *core = data; ++ struct amvdec_session *sess = core->cur_sess; ++ ++ return sess->fmt_out->codec_ops->threaded_isr(sess); ++} ++ ++static const struct of_device_id vdec_dt_match[] = { ++ { .compatible = "amlogic,gxbb-vdec", ++ .data = &vdec_platform_gxbb }, ++ { .compatible = "amlogic,gxm-vdec", ++ .data = &vdec_platform_gxm }, ++ { .compatible = "amlogic,gxl-vdec", ++ .data = &vdec_platform_gxl }, ++ {} ++}; ++MODULE_DEVICE_TABLE(of, vdec_dt_match); ++ ++static int vdec_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct video_device *vdev; ++ struct amvdec_core *core; ++ struct resource *r; ++ const struct of_device_id *of_id; ++ int irq; ++ int ret; ++ ++ core = devm_kzalloc(dev, sizeof(*core), GFP_KERNEL); ++ if (!core) ++ return -ENOMEM; ++ ++ core->dev = dev; ++ platform_set_drvdata(pdev, core); ++ ++ r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dos"); ++ core->dos_base = devm_ioremap_resource(dev, r); ++ if (IS_ERR(core->dos_base)) { ++ dev_err(dev, "Couldn't remap DOS memory\n"); ++ return PTR_ERR(core->dos_base); ++ } ++ ++ r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "esparser"); ++ core->esparser_base = devm_ioremap_resource(dev, r); ++ if (IS_ERR(core->esparser_base)) { ++ dev_err(dev, "Couldn't remap ESPARSER memory\n"); ++ return PTR_ERR(core->esparser_base); ++ } ++ ++ core->regmap_ao = syscon_regmap_lookup_by_phandle(dev->of_node, ++ "amlogic,ao-sysctrl"); ++ if (IS_ERR(core->regmap_ao)) { ++ dev_err(dev, "Couldn't regmap AO sysctrl\n"); ++ return PTR_ERR(core->regmap_ao); ++ } ++ ++ core->canvas = meson_canvas_get(dev); ++ if (!core->canvas) ++ return PTR_ERR(core->canvas); ++ ++ core->dos_parser_clk = devm_clk_get(dev, "dos_parser"); ++ if (IS_ERR(core->dos_parser_clk)) ++ return -EPROBE_DEFER; ++ ++ core->dos_clk = devm_clk_get(dev, "dos"); ++ if (IS_ERR(core->dos_clk)) ++ return -EPROBE_DEFER; ++ ++ core->vdec_1_clk = devm_clk_get(dev, "vdec_1"); ++ if (IS_ERR(core->vdec_1_clk)) ++ return -EPROBE_DEFER; ++ ++ core->vdec_hevc_clk = devm_clk_get(dev, "vdec_hevc"); ++ if (IS_ERR(core->vdec_hevc_clk)) ++ return -EPROBE_DEFER; ++ ++ irq = platform_get_irq(pdev, 0); ++ if (irq < 0) ++ return irq; ++ ++ ret = devm_request_threaded_irq(core->dev, irq, vdec_isr, ++ vdec_threaded_isr, IRQF_ONESHOT, ++ "vdec", core); ++ if (ret) ++ return ret; ++ ++ ret = esparser_init(pdev, core); ++ if (ret) ++ return ret; ++ ++ ret = v4l2_device_register(dev, &core->v4l2_dev); ++ if (ret) { ++ dev_err(dev, "Couldn't register v4l2 device\n"); ++ return -ENOMEM; ++ } ++ ++ vdev = video_device_alloc(); ++ if (!vdev) { ++ ret = -ENOMEM; ++ goto err_vdev_release; ++ } ++ ++ strlcpy(vdev->name, "meson-video-decoder", sizeof(vdev->name)); ++ vdev->release = video_device_release; ++ vdev->fops = &vdec_fops; ++ vdev->ioctl_ops = &vdec_ioctl_ops; ++ vdev->vfl_dir = VFL_DIR_M2M; ++ vdev->v4l2_dev = &core->v4l2_dev; ++ vdev->device_caps = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING; ++ ++ ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1); ++ if (ret) { ++ dev_err(dev, "Failed registering video device\n"); ++ goto err_vdev_release; ++ } ++ ++ of_id = of_match_node(vdec_dt_match, dev->of_node); ++ core->platform = of_id->data; ++ core->vdev_dec = vdev; ++ core->dev_dec = dev; ++ mutex_init(&core->lock); ++ ++ video_set_drvdata(vdev, core); ++ ++ return 0; ++ ++err_vdev_release: ++ video_device_release(vdev); ++ return ret; ++} ++ ++static int vdec_remove(struct platform_device *pdev) ++{ ++ struct amvdec_core *core = platform_get_drvdata(pdev); ++ ++ video_unregister_device(core->vdev_dec); ++ ++ return 0; ++} ++ ++static struct platform_driver meson_vdec_driver = { ++ .probe = vdec_probe, ++ .remove = vdec_remove, ++ .driver = { ++ .name = "meson-vdec", ++ .of_match_table = vdec_dt_match, ++ }, ++}; ++module_platform_driver(meson_vdec_driver); ++ ++MODULE_DESCRIPTION("Meson video decoder driver for GXBB/GXL/GXM"); ++MODULE_AUTHOR("Maxime Jourdan "); ++MODULE_LICENSE("GPL"); +diff --git a/drivers/media/platform/meson/vdec/vdec.h b/drivers/media/platform/meson/vdec/vdec.h +new file mode 100644 +index 0000000000000..8250fb82dfabe +--- /dev/null ++++ b/drivers/media/platform/meson/vdec/vdec.h +@@ -0,0 +1,234 @@ ++/* SPDX-License-Identifier: GPL-2.0+ */ ++/* ++ * Copyright (C) 2018 BayLibre, SAS ++ * Author: Maxime Jourdan ++ */ ++ ++#ifndef __MESON_VDEC_CORE_H_ ++#define __MESON_VDEC_CORE_H_ ++ ++/* 32 buffers in 3-plane YUV420 */ ++#define MAX_CANVAS (32 * 3) ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "vdec_platform.h" ++ ++struct amvdec_buffer { ++ struct list_head list; ++ struct vb2_buffer *vb; ++}; ++ ++struct amvdec_timestamp { ++ struct list_head list; ++ u64 ts; ++}; ++ ++struct amvdec_session; ++ ++/** ++ * struct amvdec_core - device parameters, singleton ++ * ++ * @dos_base: DOS memory base address ++ * @esparser_base: PARSER memory base address ++ * @regmap_ao: regmap for the AO bus ++ * @dev: core device ++ * @dev_dec: decoder device ++ * @platform: platform-specific data ++ * @canvas: canvas provider reference ++ * @dos_parser_clk: DOS_PARSER clock ++ * @dos_clk: DOS clock ++ * @vdec_1_clk: VDEC_1 clock ++ * @vdec_hevc_clk: VDEC_HEVC clock ++ * @esparser_reset: RESET for the PARSER ++ * @vdec_dec: video device for the decoder ++ * @v4l2_dev: v4l2 device ++ * @cur_sess: current decoding session ++ * @lock: lock for this structure ++ */ ++struct amvdec_core { ++ void __iomem *dos_base; ++ void __iomem *esparser_base; ++ struct regmap *regmap_ao; ++ ++ struct device *dev; ++ struct device *dev_dec; ++ const struct vdec_platform *platform; ++ ++ struct meson_canvas *canvas; ++ ++ struct clk *dos_parser_clk; ++ struct clk *dos_clk; ++ struct clk *vdec_1_clk; ++ struct clk *vdec_hevc_clk; ++ ++ struct reset_control *esparser_reset; ++ ++ struct video_device *vdev_dec; ++ struct v4l2_device v4l2_dev; ++ ++ struct amvdec_session *cur_sess; ++ struct mutex lock; ++}; ++ ++/** ++ * struct amvdec_ops - vdec operations ++ * ++ * @start: mandatory call when the vdec needs to initialize ++ * @stop: mandatory call when the vdec needs to stop ++ * @conf_esparser: mandatory call to let the vdec configure the ESPARSER ++ * @vififo_level: mandatory call to get the current amount of data ++ * in the VIFIFO ++ */ ++struct amvdec_ops { ++ int (*start)(struct amvdec_session *sess); ++ int (*stop)(struct amvdec_session *sess); ++ void (*conf_esparser)(struct amvdec_session *sess); ++ u32 (*vififo_level)(struct amvdec_session *sess); ++}; ++ ++/** ++ * struct amvdec_codec_ops - codec operations ++ * ++ * @start: mandatory call when the codec needs to initialize ++ * @stop: mandatory call when the codec needs to stop ++ * @load_extended_firmware: optional call to load additional firmware bits ++ * @num_pending_bufs: optional call to get the number of dst buffers on hold ++ * @can_recycle: optional call to know if the codec is ready to recycle ++ * a dst buffer ++ * @recycle: optional call to tell the codec to recycle a dst buffer. Must go ++ * in pair with can_recycle ++ * @drain: optional call if the codec has a custom way of draining ++ * @isr: mandatory call when the ISR triggers ++ * @threaded_isr: mandatory call for the threaded ISR ++ */ ++struct amvdec_codec_ops { ++ int (*start)(struct amvdec_session *sess); ++ int (*stop)(struct amvdec_session *sess); ++ int (*load_extended_firmware)(struct amvdec_session *sess, ++ const u8 *data, u32 len); ++ u32 (*num_pending_bufs)(struct amvdec_session *sess); ++ int (*can_recycle)(struct amvdec_core *core); ++ void (*recycle)(struct amvdec_core *core, u32 buf_idx); ++ void (*drain)(struct amvdec_session *sess); ++ irqreturn_t (*isr)(struct amvdec_session *sess); ++ irqreturn_t (*threaded_isr)(struct amvdec_session *sess); ++}; ++ ++/** ++ * struct amvdec_format - describes one of the OUTPUT (src) format supported ++ * ++ * @pixfmt: V4L2 pixel format ++ * @min_buffers: minimum amount of CAPTURE (dst) buffers ++ * @max_buffers: maximum amount of CAPTURE (dst) buffers ++ * @max_width: maximum picture width supported ++ * @max_height: maximum picture height supported ++ * @vdec_ops: the VDEC operations that support this format ++ * @codec_ops: the codec operations that support this format ++ * @firmware_path: Path to the firmware that supports this format ++ * @pixfmts_cap: list of CAPTURE pixel formats available with pixfmt ++ */ ++struct amvdec_format { ++ u32 pixfmt; ++ u32 min_buffers; ++ u32 max_buffers; ++ u32 max_width; ++ u32 max_height; ++ ++ struct amvdec_ops *vdec_ops; ++ struct amvdec_codec_ops *codec_ops; ++ ++ char *firmware_path; ++ u32 pixfmts_cap[4]; ++}; ++ ++/** ++ * struct amvdec_session - decoding session parameters ++ * ++ * @core: reference to the vdec core struct ++ * @fh: v4l2 file handle ++ * @m2m_dev: v4l2 m2m device ++ * @m2m_ctx: v4l2 m2m context ++ * @lock: session lock ++ * @fmt_out: vdec pixel format for the OUTPUT queue ++ * @pixfmt_cap: V4L2 pixel format for the CAPTURE queue ++ * @width: current picture width ++ * @height: current picture height ++ * @colorspace: current colorspace ++ * @ycbcr_enc: current ycbcr_enc ++ * @quantization: current quantization ++ * @xfer_func: current transfer function ++ * @esparser_queued_bufs: number of buffers currently queued into ESPARSER ++ * @esparser_queue_work: work struct for the ESPARSER to process src buffers ++ * @streamon_cap: stream on flag for capture queue ++ * @streamon_out: stream on flag for output queue ++ * @sequence_cap: capture sequence counter ++ * @should_stop: flag set is userspacec signaled EOS via command ++ * or empty buffer ++ * @keyframe_found: flag set once a keyframe has been parsed ++ * @canvas_alloc: array of all the canvas IDs allocated ++ * @canvas_num: number of canvas IDs allocated ++ * @vififo_vaddr: virtual address for the VIFIFO ++ * @vififo_paddr: physical address for the VIFIFO ++ * @vififo_size: size of the VIFIFO dma alloc ++ * @bufs_recycle: list of buffers that need to be recycled ++ * @bufs_recycle_lock: lock for the bufs_recycle list ++ * @recycle_thread: task struct for the recycling thread ++ * @timestamps: chronological list of src timestamps ++ * @ts_spinlock: spinlock for the timestamps list ++ * @last_irq_jiffies: tracks last time the vdec triggered an IRQ ++ * @priv: codec private data ++ */ ++struct amvdec_session { ++ struct amvdec_core *core; ++ ++ struct v4l2_fh fh; ++ struct v4l2_m2m_dev *m2m_dev; ++ struct v4l2_m2m_ctx *m2m_ctx; ++ struct mutex lock; ++ ++ const struct amvdec_format *fmt_out; ++ u32 pixfmt_cap; ++ ++ u32 width; ++ u32 height; ++ u32 colorspace; ++ u8 ycbcr_enc; ++ u8 quantization; ++ u8 xfer_func; ++ ++ atomic_t esparser_queued_bufs; ++ struct work_struct esparser_queue_work; ++ ++ unsigned int streamon_cap, streamon_out; ++ unsigned int sequence_cap; ++ unsigned int should_stop; ++ unsigned int keyframe_found; ++ ++ u8 canvas_alloc[MAX_CANVAS]; ++ u32 canvas_num; ++ ++ void *vififo_vaddr; ++ dma_addr_t vififo_paddr; ++ u32 vififo_size; ++ ++ struct list_head bufs_recycle; ++ struct mutex bufs_recycle_lock; ++ struct task_struct *recycle_thread; ++ ++ struct list_head timestamps; ++ spinlock_t ts_spinlock; ++ ++ u64 last_irq_jiffies; ++ ++ void *priv; ++}; ++ ++u32 amvdec_get_output_size(struct amvdec_session *sess); ++ ++#endif +diff --git a/drivers/media/platform/meson/vdec/vdec_1.c b/drivers/media/platform/meson/vdec/vdec_1.c +new file mode 100644 +index 0000000000000..29f6305a6276b +--- /dev/null ++++ b/drivers/media/platform/meson/vdec/vdec_1.c +@@ -0,0 +1,228 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright (C) 2018 BayLibre, SAS ++ * Author: Maxime Jourdan ++ * ++ * VDEC_1 is a video decoding block that allows decoding of ++ * MPEG 1/2/4, H.263, H.264, MJPEG, VC1 ++ */ ++ ++#include ++#include ++ ++#include "vdec_1.h" ++#include "vdec_helpers.h" ++#include "dos_regs.h" ++ ++/* AO Registers */ ++#define AO_RTI_GEN_PWR_SLEEP0 0xe8 ++#define AO_RTI_GEN_PWR_ISO0 0xec ++ #define GEN_PWR_VDEC_1 (BIT(3) | BIT(2)) ++ ++#define MC_SIZE (4096 * 4) ++ ++static int ++vdec_1_load_firmware(struct amvdec_session *sess, const char *fwname) ++{ ++ const struct firmware *fw; ++ struct amvdec_core *core = sess->core; ++ struct device *dev = core->dev_dec; ++ struct amvdec_codec_ops *codec_ops = sess->fmt_out->codec_ops; ++ static void *mc_addr; ++ static dma_addr_t mc_addr_map; ++ int ret; ++ u32 i = 1000; ++ ++ ret = request_firmware(&fw, fwname, dev); ++ if (ret < 0) ++ return -EINVAL; ++ ++ if (fw->size < MC_SIZE) { ++ dev_err(dev, "Firmware size %zu is too small. Expected %u.\n", ++ fw->size, MC_SIZE); ++ ret = -EINVAL; ++ goto release_firmware; ++ } ++ ++ mc_addr = dma_alloc_coherent(core->dev, MC_SIZE, ++ &mc_addr_map, GFP_KERNEL); ++ if (!mc_addr) { ++ dev_err(dev, ++ "Failed allocating memory for firmware loading\n"); ++ ret = -ENOMEM; ++ goto release_firmware; ++ } ++ ++ memcpy(mc_addr, fw->data, MC_SIZE); ++ ++ amvdec_write_dos(core, MPSR, 0); ++ amvdec_write_dos(core, CPSR, 0); ++ ++ amvdec_clear_dos_bits(core, MDEC_PIC_DC_CTRL, BIT(31)); ++ ++ amvdec_write_dos(core, IMEM_DMA_ADR, mc_addr_map); ++ amvdec_write_dos(core, IMEM_DMA_COUNT, MC_SIZE / 4); ++ amvdec_write_dos(core, IMEM_DMA_CTRL, (0x8000 | (7 << 16))); ++ ++ while (--i && amvdec_read_dos(core, IMEM_DMA_CTRL) & 0x8000) { } ++ ++ if (i == 0) { ++ dev_err(dev, "Firmware load fail (DMA hang?)\n"); ++ ret = -EINVAL; ++ goto free_mc; ++ } ++ ++ if (codec_ops->load_extended_firmware) ++ codec_ops->load_extended_firmware(sess, fw->data + MC_SIZE, ++ fw->size - MC_SIZE); ++ ++free_mc: ++ dma_free_coherent(core->dev, MC_SIZE, mc_addr, mc_addr_map); ++release_firmware: ++ release_firmware(fw); ++ return ret; ++} ++ ++int vdec_1_stbuf_power_up(struct amvdec_session *sess) ++{ ++ struct amvdec_core *core = sess->core; ++ ++ amvdec_write_dos(core, VLD_MEM_VIFIFO_CONTROL, 0); ++ amvdec_write_dos(core, VLD_MEM_VIFIFO_WRAP_COUNT, 0); ++ amvdec_write_dos(core, POWER_CTL_VLD, BIT(4)); ++ ++ amvdec_write_dos(core, VLD_MEM_VIFIFO_START_PTR, sess->vififo_paddr); ++ amvdec_write_dos(core, VLD_MEM_VIFIFO_CURR_PTR, sess->vififo_paddr); ++ amvdec_write_dos(core, VLD_MEM_VIFIFO_END_PTR, ++ sess->vififo_paddr + sess->vififo_size - 8); ++ ++ amvdec_write_dos_bits(core, VLD_MEM_VIFIFO_CONTROL, 1); ++ amvdec_clear_dos_bits(core, VLD_MEM_VIFIFO_CONTROL, 1); ++ ++ amvdec_write_dos(core, VLD_MEM_VIFIFO_BUF_CNTL, MEM_BUFCTRL_MANUAL); ++ amvdec_write_dos(core, VLD_MEM_VIFIFO_WP, sess->vififo_paddr); ++ ++ amvdec_write_dos_bits(core, VLD_MEM_VIFIFO_BUF_CNTL, 1); ++ amvdec_clear_dos_bits(core, VLD_MEM_VIFIFO_BUF_CNTL, 1); ++ ++ amvdec_write_dos_bits(core, VLD_MEM_VIFIFO_CONTROL, ++ (0x11 << MEM_FIFO_CNT_BIT) | MEM_FILL_ON_LEVEL | ++ MEM_CTRL_FILL_EN | MEM_CTRL_EMPTY_EN); ++ ++ return 0; ++} ++ ++static void vdec_1_conf_esparser(struct amvdec_session *sess) ++{ ++ struct amvdec_core *core = sess->core; ++ ++ /* VDEC_1 specific ESPARSER stuff */ ++ amvdec_write_dos(core, DOS_GEN_CTRL0, 0); ++ amvdec_write_dos(core, VLD_MEM_VIFIFO_BUF_CNTL, 1); ++ amvdec_clear_dos_bits(core, VLD_MEM_VIFIFO_BUF_CNTL, 1); ++} ++ ++static u32 vdec_1_vififo_level(struct amvdec_session *sess) ++{ ++ struct amvdec_core *core = sess->core; ++ ++ return amvdec_read_dos(core, VLD_MEM_VIFIFO_LEVEL); ++} ++ ++static int vdec_1_stop(struct amvdec_session *sess) ++{ ++ struct amvdec_core *core = sess->core; ++ struct amvdec_codec_ops *codec_ops = sess->fmt_out->codec_ops; ++ ++ amvdec_write_dos(core, MPSR, 0); ++ amvdec_write_dos(core, CPSR, 0); ++ amvdec_write_dos(core, ASSIST_MBOX1_MASK, 0); ++ ++ amvdec_write_dos(core, DOS_SW_RESET0, BIT(12) | BIT(11)); ++ amvdec_write_dos(core, DOS_SW_RESET0, 0); ++ amvdec_read_dos(core, DOS_SW_RESET0); ++ ++ /* enable vdec1 isolation */ ++ regmap_write(core->regmap_ao, AO_RTI_GEN_PWR_ISO0, 0xc0); ++ /* power off vdec1 memories */ ++ amvdec_write_dos(core, DOS_MEM_PD_VDEC, 0xffffffff); ++ /* power off vdec1 */ ++ regmap_update_bits(core->regmap_ao, AO_RTI_GEN_PWR_SLEEP0, ++ GEN_PWR_VDEC_1, GEN_PWR_VDEC_1); ++ ++ clk_disable_unprepare(core->vdec_1_clk); ++ ++ if (sess->priv) ++ codec_ops->stop(sess); ++ ++ return 0; ++} ++ ++static int vdec_1_start(struct amvdec_session *sess) ++{ ++ int ret; ++ struct amvdec_core *core = sess->core; ++ struct amvdec_codec_ops *codec_ops = sess->fmt_out->codec_ops; ++ ++ /* Configure the vdec clk to the maximum available */ ++ clk_set_rate(core->vdec_1_clk, 666666666); ++ ret = clk_prepare_enable(core->vdec_1_clk); ++ if (ret) ++ return ret; ++ ++ regmap_update_bits(core->regmap_ao, AO_RTI_GEN_PWR_SLEEP0, ++ GEN_PWR_VDEC_1, 0); ++ udelay(10); ++ ++ /* Reset VDEC1 */ ++ amvdec_write_dos(core, DOS_SW_RESET0, 0xfffffffc); ++ amvdec_write_dos(core, DOS_SW_RESET0, 0x00000000); ++ ++ amvdec_write_dos(core, DOS_GCLK_EN0, 0x3ff); ++ ++ /* enable VDEC Memories */ ++ amvdec_write_dos(core, DOS_MEM_PD_VDEC, 0); ++ /* Remove VDEC1 Isolation */ ++ regmap_write(core->regmap_ao, AO_RTI_GEN_PWR_ISO0, 0); ++ /* Reset DOS top registers */ ++ amvdec_write_dos(core, DOS_VDEC_MCRCC_STALL_CTRL, 0); ++ ++ amvdec_write_dos(core, GCLK_EN, 0x3ff); ++ amvdec_clear_dos_bits(core, MDEC_PIC_DC_CTRL, BIT(31)); ++ ++ vdec_1_stbuf_power_up(sess); ++ ++ ret = vdec_1_load_firmware(sess, sess->fmt_out->firmware_path); ++ if (ret) ++ goto stop; ++ ++ ret = codec_ops->start(sess); ++ if (ret) ++ goto stop; ++ ++ /* Enable IRQ */ ++ amvdec_write_dos(core, ASSIST_MBOX1_CLR_REG, 1); ++ amvdec_write_dos(core, ASSIST_MBOX1_MASK, 1); ++ ++ /* Enable 2-plane output */ ++ if (sess->pixfmt_cap == V4L2_PIX_FMT_NV12M) ++ amvdec_write_dos_bits(core, MDEC_PIC_DC_CTRL, BIT(17)); ++ ++ /* Enable firmware processor */ ++ amvdec_write_dos(core, MPSR, 1); ++ /* Let the firmware settle */ ++ udelay(10); ++ ++ return 0; ++ ++stop: ++ vdec_1_stop(sess); ++ return ret; ++} ++ ++struct amvdec_ops vdec_1_ops = { ++ .start = vdec_1_start, ++ .stop = vdec_1_stop, ++ .conf_esparser = vdec_1_conf_esparser, ++ .vififo_level = vdec_1_vififo_level, ++}; +diff --git a/drivers/media/platform/meson/vdec/vdec_1.h b/drivers/media/platform/meson/vdec/vdec_1.h +new file mode 100644 +index 0000000000000..042d930c40d77 +--- /dev/null ++++ b/drivers/media/platform/meson/vdec/vdec_1.h +@@ -0,0 +1,14 @@ ++/* SPDX-License-Identifier: GPL-2.0+ */ ++/* ++ * Copyright (C) 2018 BayLibre, SAS ++ * Author: Maxime Jourdan ++ */ ++ ++#ifndef __MESON_VDEC_VDEC_1_H_ ++#define __MESON_VDEC_VDEC_1_H_ ++ ++#include "vdec.h" ++ ++extern struct amvdec_ops vdec_1_ops; ++ ++#endif +diff --git a/drivers/media/platform/meson/vdec/vdec_helpers.c b/drivers/media/platform/meson/vdec/vdec_helpers.c +new file mode 100644 +index 0000000000000..6151076297655 +--- /dev/null ++++ b/drivers/media/platform/meson/vdec/vdec_helpers.c +@@ -0,0 +1,354 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright (C) 2018 BayLibre, SAS ++ * Author: Maxime Jourdan ++ */ ++ ++#include ++#include ++#include ++ ++#include "vdec_helpers.h" ++ ++#define NUM_CANVAS_NV12 2 ++#define NUM_CANVAS_YUV420 3 ++ ++u32 amvdec_read_dos(struct amvdec_core *core, u32 reg) ++{ ++ return readl_relaxed(core->dos_base + reg); ++} ++EXPORT_SYMBOL_GPL(amvdec_read_dos); ++ ++void amvdec_write_dos(struct amvdec_core *core, u32 reg, u32 val) ++{ ++ writel_relaxed(val, core->dos_base + reg); ++} ++EXPORT_SYMBOL_GPL(amvdec_write_dos); ++ ++void amvdec_write_dos_bits(struct amvdec_core *core, u32 reg, u32 val) ++{ ++ amvdec_write_dos(core, reg, amvdec_read_dos(core, reg) | val); ++} ++EXPORT_SYMBOL_GPL(amvdec_write_dos_bits); ++ ++void amvdec_clear_dos_bits(struct amvdec_core *core, u32 reg, u32 val) ++{ ++ amvdec_write_dos(core, reg, amvdec_read_dos(core, reg) & ~val); ++} ++EXPORT_SYMBOL_GPL(amvdec_clear_dos_bits); ++ ++u32 amvdec_read_parser(struct amvdec_core *core, u32 reg) ++{ ++ return readl_relaxed(core->esparser_base + reg); ++} ++EXPORT_SYMBOL_GPL(amvdec_read_parser); ++ ++void amvdec_write_parser(struct amvdec_core *core, u32 reg, u32 val) ++{ ++ writel_relaxed(val, core->esparser_base + reg); ++} ++EXPORT_SYMBOL_GPL(amvdec_write_parser); ++ ++static int canvas_alloc(struct amvdec_session *sess, u8 *canvas_id) ++{ ++ int ret; ++ ++ if (sess->canvas_num >= MAX_CANVAS) { ++ dev_err(sess->core->dev, "Reached max number of canvas\n"); ++ return -ENOMEM; ++ } ++ ++ ret = meson_canvas_alloc(sess->core->canvas, canvas_id); ++ if (ret) ++ return ret; ++ ++ sess->canvas_alloc[sess->canvas_num++] = *canvas_id; ++ return 0; ++} ++ ++static int set_canvas_yuv420m(struct amvdec_session *sess, ++ struct vb2_buffer *vb, u32 width, ++ u32 height, u32 reg) ++{ ++ struct amvdec_core *core = sess->core; ++ u8 canvas_id[NUM_CANVAS_YUV420]; /* Y U V */ ++ dma_addr_t buf_paddr[NUM_CANVAS_YUV420]; /* Y U V */ ++ int ret, i; ++ ++ for (i = 0; i < NUM_CANVAS_YUV420; ++i) { ++ ret = canvas_alloc(sess, &canvas_id[i]); ++ if (ret) ++ return ret; ++ ++ buf_paddr[i] = ++ vb2_dma_contig_plane_dma_addr(vb, i); ++ } ++ ++ /* Y plane */ ++ meson_canvas_config(core->canvas, canvas_id[0], buf_paddr[0], ++ width, height, MESON_CANVAS_WRAP_NONE, ++ MESON_CANVAS_BLKMODE_LINEAR, ++ MESON_CANVAS_ENDIAN_SWAP64); ++ ++ /* U plane */ ++ meson_canvas_config(core->canvas, canvas_id[1], buf_paddr[1], ++ width / 2, height / 2, MESON_CANVAS_WRAP_NONE, ++ MESON_CANVAS_BLKMODE_LINEAR, ++ MESON_CANVAS_ENDIAN_SWAP64); ++ ++ /* V plane */ ++ meson_canvas_config(core->canvas, canvas_id[2], buf_paddr[2], ++ width / 2, height / 2, MESON_CANVAS_WRAP_NONE, ++ MESON_CANVAS_BLKMODE_LINEAR, ++ MESON_CANVAS_ENDIAN_SWAP64); ++ ++ amvdec_write_dos(core, reg, ++ ((canvas_id[2]) << 16) | ++ ((canvas_id[1]) << 8) | ++ (canvas_id[0])); ++ ++ return 0; ++} ++ ++static int set_canvas_nv12m(struct amvdec_session *sess, ++ struct vb2_buffer *vb, u32 width, ++ u32 height, u32 reg) ++{ ++ struct amvdec_core *core = sess->core; ++ u8 canvas_id[NUM_CANVAS_NV12]; /* Y U/V */ ++ dma_addr_t buf_paddr[NUM_CANVAS_NV12]; /* Y U/V */ ++ int ret, i; ++ ++ for (i = 0; i < NUM_CANVAS_NV12; ++i) { ++ ret = canvas_alloc(sess, &canvas_id[i]); ++ if (ret) ++ return ret; ++ ++ buf_paddr[i] = ++ vb2_dma_contig_plane_dma_addr(vb, i); ++ } ++ ++ /* Y plane */ ++ meson_canvas_config(core->canvas, canvas_id[0], buf_paddr[0], ++ width, height, MESON_CANVAS_WRAP_NONE, ++ MESON_CANVAS_BLKMODE_LINEAR, ++ MESON_CANVAS_ENDIAN_SWAP64); ++ ++ /* U/V plane */ ++ meson_canvas_config(core->canvas, canvas_id[1], buf_paddr[1], ++ width, height / 2, MESON_CANVAS_WRAP_NONE, ++ MESON_CANVAS_BLKMODE_LINEAR, ++ MESON_CANVAS_ENDIAN_SWAP64); ++ ++ amvdec_write_dos(core, reg, ++ ((canvas_id[1]) << 16) | ++ ((canvas_id[1]) << 8) | ++ (canvas_id[0])); ++ ++ return 0; ++} ++ ++int amvdec_set_canvases(struct amvdec_session *sess, ++ u32 reg_base[], u32 reg_num[]) ++{ ++ struct v4l2_m2m_buffer *buf; ++ u32 pixfmt = sess->pixfmt_cap; ++ u32 width = ALIGN(sess->width, 64); ++ u32 height = ALIGN(sess->height, 64); ++ u32 reg_cur = reg_base[0]; ++ u32 reg_num_cur = 0; ++ u32 reg_base_cur = 0; ++ int ret; ++ ++ v4l2_m2m_for_each_dst_buf(sess->m2m_ctx, buf) { ++ if (!reg_base[reg_base_cur]) ++ return -EINVAL; ++ ++ reg_cur = reg_base[reg_base_cur] + reg_num_cur * 4; ++ ++ switch (pixfmt) { ++ case V4L2_PIX_FMT_NV12M: ++ ret = set_canvas_nv12m(sess, &buf->vb.vb2_buf, width, ++ height, reg_cur); ++ if (ret) ++ return ret; ++ break; ++ case V4L2_PIX_FMT_YUV420M: ++ ret = set_canvas_yuv420m(sess, &buf->vb.vb2_buf, width, ++ height, reg_cur); ++ if (ret) ++ return ret; ++ break; ++ default: ++ dev_err(sess->core->dev, "Unsupported pixfmt %08X\n", ++ pixfmt); ++ return -EINVAL; ++ }; ++ ++ reg_num_cur++; ++ if (reg_num_cur >= reg_num[reg_base_cur]) { ++ reg_base_cur++; ++ reg_num_cur = 0; ++ } ++ } ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(amvdec_set_canvases); ++ ++void amvdec_dst_buf_done(struct amvdec_session *sess, ++ struct vb2_v4l2_buffer *vbuf, u32 field) ++{ ++ struct device *dev = sess->core->dev_dec; ++ struct amvdec_timestamp *tmp; ++ struct list_head *timestamps = &sess->timestamps; ++ u32 output_size = amvdec_get_output_size(sess); ++ unsigned long flags; ++ ++ spin_lock_irqsave(&sess->ts_spinlock, flags); ++ if (list_empty(timestamps)) { ++ dev_err(dev, "Buffer %u done but list is empty\n", ++ vbuf->vb2_buf.index); ++ ++ v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR); ++ amvdec_abort(sess); ++ spin_unlock_irqrestore(&sess->ts_spinlock, flags); ++ goto end; ++ } ++ ++ tmp = list_first_entry(timestamps, struct amvdec_timestamp, list); ++ ++ switch (sess->pixfmt_cap) { ++ case V4L2_PIX_FMT_NV12M: ++ vbuf->vb2_buf.planes[0].bytesused = output_size; ++ vbuf->vb2_buf.planes[1].bytesused = output_size / 2; ++ break; ++ case V4L2_PIX_FMT_YUV420M: ++ vbuf->vb2_buf.planes[0].bytesused = output_size; ++ vbuf->vb2_buf.planes[1].bytesused = output_size / 4; ++ vbuf->vb2_buf.planes[2].bytesused = output_size / 4; ++ break; ++ } ++ vbuf->vb2_buf.timestamp = tmp->ts; ++ vbuf->sequence = sess->sequence_cap++; ++ ++ list_del(&tmp->list); ++ kfree(tmp); ++ spin_unlock_irqrestore(&sess->ts_spinlock, flags); ++ ++ atomic_dec(&sess->esparser_queued_bufs); ++ ++ if (sess->should_stop && list_empty(timestamps)) { ++ const struct v4l2_event ev = { .type = V4L2_EVENT_EOS }; ++ ++ dev_dbg(dev, "Signaling EOS\n"); ++ v4l2_event_queue_fh(&sess->fh, &ev); ++ vbuf->flags |= V4L2_BUF_FLAG_LAST; ++ } else if (sess->should_stop) ++ dev_dbg(dev, "should_stop, %u bufs remain\n", ++ atomic_read(&sess->esparser_queued_bufs)); ++ ++ vbuf->field = field; ++ v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_DONE); ++ ++end: ++ /* Buffer done probably means the vififo got freed */ ++ schedule_work(&sess->esparser_queue_work); ++} ++EXPORT_SYMBOL_GPL(amvdec_dst_buf_done); ++ ++void ++amvdec_dst_buf_done_idx(struct amvdec_session *sess, u32 buf_idx, u32 field) ++{ ++ struct vb2_v4l2_buffer *vbuf; ++ struct device *dev = sess->core->dev_dec; ++ ++ vbuf = v4l2_m2m_dst_buf_remove_by_idx(sess->m2m_ctx, buf_idx); ++ if (!vbuf) { ++ dev_err(dev, ++ "Buffer %u done but it doesn't exist in m2m_ctx\n", ++ buf_idx); ++ amvdec_rm_first_ts(sess); ++ return; ++ } ++ ++ amvdec_dst_buf_done(sess, vbuf, field); ++} ++EXPORT_SYMBOL_GPL(amvdec_dst_buf_done_idx); ++ ++void amvdec_add_ts_reorder(struct amvdec_session *sess, u64 ts) ++{ ++ struct amvdec_timestamp *new_ts, *tmp; ++ unsigned long flags; ++ ++ new_ts = kmalloc(sizeof(*new_ts), GFP_KERNEL); ++ new_ts->ts = ts; ++ ++ spin_lock_irqsave(&sess->ts_spinlock, flags); ++ ++ if (list_empty(&sess->timestamps)) ++ goto add_tail; ++ ++ list_for_each_entry(tmp, &sess->timestamps, list) { ++ if (ts < tmp->ts) { ++ list_add_tail(&new_ts->list, &tmp->list); ++ goto unlock; ++ } ++ } ++ ++add_tail: ++ list_add_tail(&new_ts->list, &sess->timestamps); ++unlock: ++ spin_unlock_irqrestore(&sess->ts_spinlock, flags); ++} ++EXPORT_SYMBOL_GPL(amvdec_add_ts_reorder); ++ ++void amvdec_remove_ts(struct amvdec_session *sess, u64 ts) ++{ ++ struct amvdec_timestamp *tmp; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&sess->ts_spinlock, flags); ++ list_for_each_entry(tmp, &sess->timestamps, list) { ++ if (tmp->ts == ts) { ++ list_del(&tmp->list); ++ kfree(tmp); ++ goto unlock; ++ } ++ } ++ dev_warn(sess->core->dev_dec, ++ "Couldn't remove buffer with timestamp %llu from list\n", ts); ++ ++unlock: ++ spin_unlock_irqrestore(&sess->ts_spinlock, flags); ++} ++EXPORT_SYMBOL_GPL(amvdec_remove_ts); ++ ++void amvdec_rm_first_ts(struct amvdec_session *sess) ++{ ++ unsigned long flags; ++ struct amvdec_buffer *tmp; ++ struct device *dev = sess->core->dev_dec; ++ ++ spin_lock_irqsave(&sess->ts_spinlock, flags); ++ if (list_empty(&sess->timestamps)) { ++ dev_err(dev, "Can't rm first timestamp: list empty\n"); ++ goto unlock; ++ } ++ ++ tmp = list_first_entry(&sess->timestamps, struct amvdec_buffer, list); ++ list_del(&tmp->list); ++ kfree(tmp); ++ atomic_dec(&sess->esparser_queued_bufs); ++ ++unlock: ++ spin_unlock_irqrestore(&sess->ts_spinlock, flags); ++} ++ ++void amvdec_abort(struct amvdec_session *sess) ++{ ++ dev_info(sess->core->dev, "Aborting decoding session!\n"); ++ vb2_queue_error(&sess->m2m_ctx->cap_q_ctx.q); ++ vb2_queue_error(&sess->m2m_ctx->out_q_ctx.q); ++} ++EXPORT_SYMBOL_GPL(amvdec_abort); +diff --git a/drivers/media/platform/meson/vdec/vdec_helpers.h b/drivers/media/platform/meson/vdec/vdec_helpers.h +new file mode 100644 +index 0000000000000..352c6b4c4b84c +--- /dev/null ++++ b/drivers/media/platform/meson/vdec/vdec_helpers.h +@@ -0,0 +1,45 @@ ++/* SPDX-License-Identifier: GPL-2.0+ */ ++/* ++ * Copyright (C) 2018 BayLibre, SAS ++ * Author: Maxime Jourdan ++ */ ++ ++#ifndef __MESON_VDEC_HELPERS_H_ ++#define __MESON_VDEC_HELPERS_H_ ++ ++#include "vdec.h" ++ ++/** ++ * amvdec_set_canvases() - Map VB2 buffers to canvases ++ * ++ * @sess: current session ++ * @reg_base: Registry bases of where to write the canvas indexes ++ * @reg_num: number of contiguous registers after each reg_base (including it) ++ */ ++int amvdec_set_canvases(struct amvdec_session *sess, ++ u32 reg_base[], u32 reg_num[]); ++ ++u32 amvdec_read_dos(struct amvdec_core *core, u32 reg); ++void amvdec_write_dos(struct amvdec_core *core, u32 reg, u32 val); ++void amvdec_write_dos_bits(struct amvdec_core *core, u32 reg, u32 val); ++void amvdec_clear_dos_bits(struct amvdec_core *core, u32 reg, u32 val); ++u32 amvdec_read_parser(struct amvdec_core *core, u32 reg); ++void amvdec_write_parser(struct amvdec_core *core, u32 reg, u32 val); ++ ++void amvdec_dst_buf_done_idx(struct amvdec_session *sess, u32 buf_idx, ++ u32 field); ++void amvdec_dst_buf_done(struct amvdec_session *sess, ++ struct vb2_v4l2_buffer *vbuf, u32 field); ++ ++/** ++ * amvdec_add_ts_reorder() - Add a timestamp to the list in chronological order ++ * ++ * @sess: current session ++ * @ts: timestamp to add ++ */ ++void amvdec_add_ts_reorder(struct amvdec_session *sess, u64 ts); ++void amvdec_remove_ts(struct amvdec_session *sess, u64 ts); ++void amvdec_rm_first_ts(struct amvdec_session *sess); ++ ++void amvdec_abort(struct amvdec_session *sess); ++#endif +diff --git a/drivers/media/platform/meson/vdec/vdec_platform.c b/drivers/media/platform/meson/vdec/vdec_platform.c +new file mode 100644 +index 0000000000000..46eeb7426f547 +--- /dev/null ++++ b/drivers/media/platform/meson/vdec/vdec_platform.c +@@ -0,0 +1,101 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright (C) 2018 BayLibre, SAS ++ * Author: Maxime Jourdan ++ */ ++ ++#include "vdec_platform.h" ++#include "vdec.h" ++ ++#include "vdec_1.h" ++#include "codec_mpeg12.h" ++ ++static const struct amvdec_format vdec_formats_gxbb[] = { ++ { ++ .pixfmt = V4L2_PIX_FMT_MPEG1, ++ .min_buffers = 8, ++ .max_buffers = 8, ++ .max_width = 1920, ++ .max_height = 1080, ++ .vdec_ops = &vdec_1_ops, ++ .codec_ops = &codec_mpeg12_ops, ++ .firmware_path = "meson/gx/vmpeg12_mc", ++ .pixfmts_cap = { V4L2_PIX_FMT_NV12M, V4L2_PIX_FMT_YUV420M, 0 }, ++ }, { ++ .pixfmt = V4L2_PIX_FMT_MPEG2, ++ .min_buffers = 8, ++ .max_buffers = 8, ++ .max_width = 1920, ++ .max_height = 1080, ++ .vdec_ops = &vdec_1_ops, ++ .codec_ops = &codec_mpeg12_ops, ++ .firmware_path = "meson/gx/vmpeg12_mc", ++ .pixfmts_cap = { V4L2_PIX_FMT_NV12M, V4L2_PIX_FMT_YUV420M, 0 }, ++ }, ++}; ++ ++static const struct amvdec_format vdec_formats_gxl[] = { ++ { ++ .pixfmt = V4L2_PIX_FMT_MPEG1, ++ .min_buffers = 8, ++ .max_buffers = 8, ++ .max_width = 1920, ++ .max_height = 1080, ++ .vdec_ops = &vdec_1_ops, ++ .codec_ops = &codec_mpeg12_ops, ++ .firmware_path = "meson/gx/vmpeg12_mc", ++ .pixfmts_cap = { V4L2_PIX_FMT_NV12M, V4L2_PIX_FMT_YUV420M, 0 }, ++ }, { ++ .pixfmt = V4L2_PIX_FMT_MPEG2, ++ .min_buffers = 8, ++ .max_buffers = 8, ++ .max_width = 1920, ++ .max_height = 1080, ++ .vdec_ops = &vdec_1_ops, ++ .codec_ops = &codec_mpeg12_ops, ++ .firmware_path = "meson/gx/vmpeg12_mc", ++ .pixfmts_cap = { V4L2_PIX_FMT_NV12M, V4L2_PIX_FMT_YUV420M, 0 }, ++ }, ++}; ++ ++static const struct amvdec_format vdec_formats_gxm[] = { ++ { ++ .pixfmt = V4L2_PIX_FMT_MPEG1, ++ .min_buffers = 8, ++ .max_buffers = 8, ++ .max_width = 1920, ++ .max_height = 1080, ++ .vdec_ops = &vdec_1_ops, ++ .codec_ops = &codec_mpeg12_ops, ++ .firmware_path = "meson/gx/vmpeg12_mc", ++ .pixfmts_cap = { V4L2_PIX_FMT_NV12M, V4L2_PIX_FMT_YUV420M, 0 }, ++ }, { ++ .pixfmt = V4L2_PIX_FMT_MPEG2, ++ .min_buffers = 8, ++ .max_buffers = 8, ++ .max_width = 1920, ++ .max_height = 1080, ++ .vdec_ops = &vdec_1_ops, ++ .codec_ops = &codec_mpeg12_ops, ++ .firmware_path = "meson/gx/vmpeg12_mc", ++ .pixfmts_cap = { V4L2_PIX_FMT_NV12M, V4L2_PIX_FMT_YUV420M, 0 }, ++ }, ++}; ++ ++const struct vdec_platform vdec_platform_gxbb = { ++ .formats = vdec_formats_gxbb, ++ .num_formats = ARRAY_SIZE(vdec_formats_gxbb), ++ .revision = VDEC_REVISION_GXBB, ++}; ++ ++const struct vdec_platform vdec_platform_gxl = { ++ .formats = vdec_formats_gxl, ++ .num_formats = ARRAY_SIZE(vdec_formats_gxl), ++ .revision = VDEC_REVISION_GXL, ++}; ++ ++const struct vdec_platform vdec_platform_gxm = { ++ .formats = vdec_formats_gxm, ++ .num_formats = ARRAY_SIZE(vdec_formats_gxm), ++ .revision = VDEC_REVISION_GXM, ++}; +diff --git a/drivers/media/platform/meson/vdec/vdec_platform.h b/drivers/media/platform/meson/vdec/vdec_platform.h +new file mode 100644 +index 0000000000000..f6025326db1d6 +--- /dev/null ++++ b/drivers/media/platform/meson/vdec/vdec_platform.h +@@ -0,0 +1,30 @@ ++/* SPDX-License-Identifier: GPL-2.0+ */ ++/* ++ * Copyright (C) 2018 BayLibre, SAS ++ * Author: Maxime Jourdan ++ */ ++ ++#ifndef __MESON_VDEC_PLATFORM_H_ ++#define __MESON_VDEC_PLATFORM_H_ ++ ++#include "vdec.h" ++ ++struct amvdec_format; ++ ++enum vdec_revision { ++ VDEC_REVISION_GXBB, ++ VDEC_REVISION_GXL, ++ VDEC_REVISION_GXM, ++}; ++ ++struct vdec_platform { ++ const struct amvdec_format *formats; ++ const u32 num_formats; ++ enum vdec_revision revision; ++}; ++ ++extern const struct vdec_platform vdec_platform_gxbb; ++extern const struct vdec_platform vdec_platform_gxm; ++extern const struct vdec_platform vdec_platform_gxl; ++ ++#endif diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/007_linux-4.18.y-v4l-0007-arm64-dts-meson-gx-add_vdec_entry.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/007_linux-4.18.y-v4l-0007-arm64-dts-meson-gx-add_vdec_entry.patch new file mode 100644 index 000000000..e5d678fb4 --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/007_linux-4.18.y-v4l-0007-arm64-dts-meson-gx-add_vdec_entry.patch @@ -0,0 +1,36 @@ +From b73062fd0c0c9630ad00ec5c0e9880798a994875 Mon Sep 17 00:00:00 2001 +From: Maxime Jourdan +Date: Wed, 29 Aug 2018 15:24:02 +0200 +Subject: [PATCH] ARM64: dts: meson-gx: add vdec entry + +Add the video decoder dts entry + +Signed-off-by: Maxime Jourdan +--- + arch/arm64/boot/dts/amlogic/meson-gx.dtsi | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi +index 737b741df0355..d9e0fea71dbe3 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi +@@ -410,6 +410,19 @@ + }; + }; + ++ vdec: video-decoder@c8820000 { ++ compatible = "amlogic,gx-vdec"; ++ reg = <0x0 0xc8820000 0x0 0x10000>, ++ <0x0 0xc110a580 0x0 0xe4>; ++ reg-names = "dos", "esparser"; ++ ++ interrupts = , ++ ; ++ ++ amlogic,ao-sysctrl = <&sysctrl_AO>; ++ amlogic,canvas = <&canvas>; ++ }; ++ + periphs: periphs@c8834000 { + compatible = "simple-bus"; + reg = <0x0 0xc8834000 0x0 0x2000>; diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/008_linux-4.18.y-v4l-0008-arm64-dts-meson-add_vdec_entries.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/008_linux-4.18.y-v4l-0008-arm64-dts-meson-add_vdec_entries.patch new file mode 100644 index 000000000..2fe470c4b --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/008_linux-4.18.y-v4l-0008-arm64-dts-meson-add_vdec_entries.patch @@ -0,0 +1,64 @@ +From c7b0311f4676661ad445f9e36c669886f1bc7835 Mon Sep 17 00:00:00 2001 +From: Maxime Jourdan +Date: Wed, 29 Aug 2018 15:24:22 +0200 +Subject: [PATCH] ARM64: dts: meson: add vdec entries + +This enables the video decoder for gxbb, gxl and gxm chips + +Signed-off-by: Maxime Jourdan +--- + arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi | 11 +++++++++++ + arch/arm64/boot/dts/amlogic/meson-gxl.dtsi | 11 +++++++++++ + arch/arm64/boot/dts/amlogic/meson-gxm.dtsi | 4 ++++ + 3 files changed, 26 insertions(+) + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi +index 98cbba6809caa..daee53a755d75 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi +@@ -774,3 +774,14 @@ + compatible = "amlogic,meson-gxbb-vpu", "amlogic,meson-gx-vpu"; + power-domains = <&pwrc_vpu>; + }; ++ ++&vdec { ++ compatible = "amlogic,gxbb-vdec"; ++ clocks = <&clkc CLKID_DOS_PARSER>, ++ <&clkc CLKID_DOS>, ++ <&clkc CLKID_VDEC_1>, ++ <&clkc CLKID_VDEC_HEVC>; ++ clock-names = "dos_parser", "dos", "vdec_1", "vdec_hevc"; ++ resets = <&reset RESET_PARSER>; ++ reset-names = "esparser"; ++}; +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi +index c87a80e9bcc6a..bfd65d1a89591 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi +@@ -775,3 +775,14 @@ + compatible = "amlogic,meson-gxl-vpu", "amlogic,meson-gx-vpu"; + power-domains = <&pwrc_vpu>; + }; ++ ++&vdec { ++ compatible = "amlogic,gxl-vdec"; ++ clocks = <&clkc CLKID_DOS_PARSER>, ++ <&clkc CLKID_DOS>, ++ <&clkc CLKID_VDEC_1>, ++ <&clkc CLKID_VDEC_HEVC>; ++ clock-names = "dos_parser", "dos", "vdec_1", "vdec_hevc"; ++ resets = <&reset RESET_PARSER>; ++ reset-names = "esparser"; ++}; +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxm.dtsi +index 247888d68a3aa..2f356495be5ef 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxm.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gxm.dtsi +@@ -117,3 +117,7 @@ + &dwc3 { + phys = <&usb3_phy>, <&usb2_phy0>, <&usb2_phy1>, <&usb2_phy2>; + }; ++ ++&vdec { ++ compatible = "amlogic,gxm-vdec"; ++}; diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/009_linux-4.18.y-v4l-0009-media-meson-vdec-add_h.264_decoding_support.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/009_linux-4.18.y-v4l-0009-media-meson-vdec-add_h.264_decoding_support.patch new file mode 100644 index 000000000..eeb39e22b --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/009_linux-4.18.y-v4l-0009-media-meson-vdec-add_h.264_decoding_support.patch @@ -0,0 +1,466 @@ +From 9d2683700060a36200da3b296671485b7fec747f Mon Sep 17 00:00:00 2001 +From: Maxime Jourdan +Date: Wed, 29 Aug 2018 15:42:56 +0200 +Subject: [PATCH] media: meson: vdec: add H.264 decoding support + +Add support for V4L2_PIX_FMT_H264 +--- + drivers/media/platform/meson/vdec/Makefile | 2 +- + .../media/platform/meson/vdec/codec_h264.c | 354 ++++++++++++++++++ + .../media/platform/meson/vdec/codec_h264.h | 13 + + .../media/platform/meson/vdec/vdec_platform.c | 31 ++ + 4 files changed, 399 insertions(+), 1 deletion(-) + create mode 100644 drivers/media/platform/meson/vdec/codec_h264.c + create mode 100644 drivers/media/platform/meson/vdec/codec_h264.h + +diff --git a/drivers/media/platform/meson/vdec/Makefile b/drivers/media/platform/meson/vdec/Makefile +index 6bea129084b76..711d990c760e0 100644 +--- a/drivers/media/platform/meson/vdec/Makefile ++++ b/drivers/media/platform/meson/vdec/Makefile +@@ -3,6 +3,6 @@ + + meson-vdec-objs = esparser.o vdec.o vdec_helpers.o vdec_platform.o + meson-vdec-objs += vdec_1.o +-meson-vdec-objs += codec_mpeg12.o ++meson-vdec-objs += codec_mpeg12.o codec_h264.o + + obj-$(CONFIG_VIDEO_MESON_VDEC) += meson-vdec.o +diff --git a/drivers/media/platform/meson/vdec/codec_h264.c b/drivers/media/platform/meson/vdec/codec_h264.c +new file mode 100644 +index 0000000000000..7c47ec35efa54 +--- /dev/null ++++ b/drivers/media/platform/meson/vdec/codec_h264.c +@@ -0,0 +1,354 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright (C) 2018 Maxime Jourdan ++ */ ++ ++#include ++#include ++ ++#include "vdec_helpers.h" ++#include "dos_regs.h" ++ ++#define SIZE_EXT_FW (20 * SZ_1K) ++#define SIZE_WORKSPACE 0x1ee000 ++#define SIZE_SEI (8 * SZ_1K) ++ ++/* Offset added by the firmware which must be substracted ++ * from the workspace phyaddr ++ */ ++#define WORKSPACE_BUF_OFFSET 0x1000000 ++ ++#define SEI_DATA_READY BIT(15) ++ ++/* ISR status */ ++#define CMD_SET_PARAM 1 ++#define CMD_FRAMES_READY 2 ++#define CMD_FATAL_ERROR 6 ++#define CMD_BAD_WIDTH 7 ++#define CMD_BAD_HEIGHT 8 ++ ++/* Picture type */ ++#define PIC_SINGLE_FRAME 0 ++#define PIC_TOP_BOT_TOP 1 ++#define PIC_BOT_TOP_BOT 2 ++#define PIC_DOUBLE_FRAME 3 ++#define PIC_TRIPLE_FRAME 4 ++#define PIC_TOP_BOT 5 ++#define PIC_BOT_TOP 6 ++#define PIC_INVALID 7 ++ ++/* Size of Motion Vector per macroblock */ ++#define MB_MV_SIZE 96 ++ ++struct codec_h264 { ++ /* H.264 decoder requires an extended firmware */ ++ void *ext_fw_vaddr; ++ dma_addr_t ext_fw_paddr; ++ ++ /* Buffer for the H.264 Workspace */ ++ void *workspace_vaddr; ++ dma_addr_t workspace_paddr; ++ ++ /* Buffer for the H.264 references MV */ ++ void *ref_vaddr; ++ dma_addr_t ref_paddr; ++ u32 ref_size; ++ ++ /* Buffer for parsed SEI data */ ++ void *sei_vaddr; ++ dma_addr_t sei_paddr; ++ ++ int received_0; ++}; ++ ++static int codec_h264_can_recycle(struct amvdec_core *core) ++{ ++ return !amvdec_read_dos(core, AV_SCRATCH_7) || ++ !amvdec_read_dos(core, AV_SCRATCH_8); ++} ++ ++static void codec_h264_recycle(struct amvdec_core *core, u32 buf_idx) ++{ ++ /* Tell the decoder he can recycle this buffer. ++ * AV_SCRATCH_8 serves the same purpose. ++ */ ++ if (!amvdec_read_dos(core, AV_SCRATCH_7)) ++ amvdec_write_dos(core, AV_SCRATCH_7, buf_idx + 1); ++ else ++ amvdec_write_dos(core, AV_SCRATCH_8, buf_idx + 1); ++} ++ ++static int codec_h264_start(struct amvdec_session *sess) { ++ u32 workspace_offset; ++ struct amvdec_core *core = sess->core; ++ struct codec_h264 *h264 = sess->priv; ++ ++ /* Allocate some memory for the H.264 decoder's state */ ++ h264->workspace_vaddr = ++ dma_alloc_coherent(core->dev, SIZE_WORKSPACE, &h264->workspace_paddr, GFP_KERNEL); ++ if (!h264->workspace_vaddr) { ++ dev_err(core->dev, "Failed to alloc H.264 Workspace\n"); ++ return -ENOMEM; ++ } ++ ++ /* Allocate some memory for the H.264 SEI dump */ ++ h264->sei_vaddr = ++ dma_alloc_coherent(core->dev, SIZE_SEI, &h264->sei_paddr, GFP_KERNEL); ++ if (!h264->sei_vaddr) { ++ dev_err(core->dev, "Failed to alloc H.264 SEI\n"); ++ return -ENOMEM; ++ } ++ ++ amvdec_write_dos_bits(core, POWER_CTL_VLD, BIT(9) | BIT(6)); ++ ++ amvdec_write_dos(core, PSCALE_CTRL, 0); ++ amvdec_write_dos(core, AV_SCRATCH_0, 0); ++ ++ workspace_offset = h264->workspace_paddr - WORKSPACE_BUF_OFFSET; ++ amvdec_write_dos(core, AV_SCRATCH_1, workspace_offset); ++ amvdec_write_dos(core, AV_SCRATCH_G, h264->ext_fw_paddr); ++ amvdec_write_dos(core, AV_SCRATCH_I, h264->sei_paddr - workspace_offset); ++ ++ amvdec_write_dos(core, AV_SCRATCH_7, 0); ++ amvdec_write_dos(core, AV_SCRATCH_8, 0); ++ amvdec_write_dos(core, AV_SCRATCH_9, 0); ++ ++ /* Enable "error correction" */ ++ amvdec_write_dos(core, AV_SCRATCH_F, (amvdec_read_dos(core, AV_SCRATCH_F) & 0xffffffc3) | BIT(4) | BIT(7)); ++ ++ amvdec_write_dos(core, MDEC_PIC_DC_THRESH, 0x404038aa); ++ ++ return 0; ++} ++ ++static int codec_h264_stop(struct amvdec_session *sess) ++{ ++ struct codec_h264 *h264 = sess->priv; ++ struct amvdec_core *core = sess->core; ++ ++ if (h264->ext_fw_vaddr) ++ dma_free_coherent(core->dev, SIZE_EXT_FW, ++ h264->ext_fw_vaddr, h264->ext_fw_paddr); ++ ++ if (h264->workspace_vaddr) ++ dma_free_coherent(core->dev, SIZE_WORKSPACE, ++ h264->workspace_vaddr, h264->workspace_paddr); ++ ++ if (h264->ref_vaddr) ++ dma_free_coherent(core->dev, h264->ref_size, ++ h264->ref_vaddr, h264->ref_paddr); ++ ++ if (h264->sei_vaddr) ++ dma_free_coherent(core->dev, SIZE_SEI, ++ h264->sei_vaddr, h264->sei_paddr); ++ ++ return 0; ++} ++ ++static int codec_h264_load_extended_firmware(struct amvdec_session *sess, const u8 *data, u32 len) ++{ ++ struct codec_h264 *h264; ++ struct amvdec_core *core = sess->core; ++ ++ h264 = kzalloc(sizeof(*h264), GFP_KERNEL); ++ if (!h264) ++ return -ENOMEM; ++ ++ sess->priv = h264; ++ ++ if (len < SIZE_EXT_FW) ++ return -EINVAL; ++ ++ h264->ext_fw_vaddr = dma_alloc_coherent(core->dev, SIZE_EXT_FW, ++ &h264->ext_fw_paddr, GFP_KERNEL); ++ if (!h264->ext_fw_vaddr) { ++ dev_err(core->dev, "Failed to alloc H.264 extended fw\n"); ++ return -ENOMEM; ++ } ++ ++ memcpy(h264->ext_fw_vaddr, data, SIZE_EXT_FW); ++ ++ return 0; ++} ++ ++/* Configure the H.264 decoder when the esparser finished parsing ++ * the first keyframe ++ */ ++static void codec_h264_set_param(struct amvdec_session *sess) { ++ struct amvdec_core *core = sess->core; ++ struct codec_h264 *h264 = sess->priv; ++ u32 max_reference_size; ++ u32 parsed_info, mb_width, mb_height, mb_total; ++ u32 actual_dpb_size = v4l2_m2m_num_dst_bufs_ready(sess->m2m_ctx); ++ u32 max_dpb_size = 4; ++ ++ sess->keyframe_found = 1; ++ ++ amvdec_write_dos(core, AV_SCRATCH_7, 0); ++ amvdec_write_dos(core, AV_SCRATCH_8, 0); ++ amvdec_write_dos(core, AV_SCRATCH_9, 0); ++ ++ parsed_info = amvdec_read_dos(core, AV_SCRATCH_1); ++ ++ /* Total number of 16x16 macroblocks */ ++ mb_total = (parsed_info >> 8) & 0xffff; ++ ++ /* Number of macroblocks per line */ ++ mb_width = parsed_info & 0xff; ++ ++ /* Number of macroblock lines */ ++ mb_height = mb_total / mb_width; ++ ++ max_reference_size = (parsed_info >> 24) & 0x7f; ++ ++ /* Align to a multiple of 4 macroblocks */ ++ mb_width = ALIGN(mb_width, 4); ++ mb_height = ALIGN(mb_height, 4); ++ mb_total = mb_width * mb_height; ++ ++ amvdec_set_canvases(sess, (u32[]){ ANC0_CANVAS_ADDR, 0 }, ++ (u32[]){ 24, 0 }); ++ ++ if (max_reference_size > max_dpb_size) ++ max_dpb_size = max_reference_size; ++ ++ max_reference_size++; ++ dev_dbg(core->dev, ++ "max_ref_size = %u; max_dpb_size = %u; actual_dpb_size = %u\n", ++ max_reference_size, max_dpb_size, actual_dpb_size); ++ ++ h264->ref_size = mb_total * MB_MV_SIZE * max_reference_size; ++ h264->ref_vaddr = dma_alloc_coherent(core->dev, h264->ref_size, ++ &h264->ref_paddr, GFP_KERNEL); ++ if (!h264->ref_vaddr) { ++ dev_err(core->dev, "Failed to alloc refs (%u)\n", ++ h264->ref_size); ++ amvdec_abort(sess); ++ return; ++ } ++ ++ /* Address to store the references' MVs */ ++ amvdec_write_dos(core, AV_SCRATCH_1, h264->ref_paddr); ++ /* End of ref MV */ ++ amvdec_write_dos(core, AV_SCRATCH_4, h264->ref_paddr + h264->ref_size); ++ ++ amvdec_write_dos(core, AV_SCRATCH_0, (max_reference_size << 24) | ++ (actual_dpb_size << 16) | ++ (max_dpb_size << 8)); ++} ++ ++static void codec_h264_frames_ready(struct amvdec_session *sess, u32 status) ++{ ++ struct amvdec_core *core = sess->core; ++ struct codec_h264 *h264 = sess->priv; ++ int error_count; ++ int num_frames; ++ int i; ++ ++ error_count = amvdec_read_dos(core, AV_SCRATCH_D); ++ num_frames = (status >> 8) & 0xff; ++ if (error_count) { ++ dev_warn(core->dev, ++ "decoder error(s) happened, count %d\n", error_count); ++ amvdec_write_dos(core, AV_SCRATCH_D, 0); ++ } ++ ++ for (i = 0; i < num_frames; i++) { ++ u32 frame_status = amvdec_read_dos(core, AV_SCRATCH_1 + i * 4); ++ u32 buffer_index = frame_status & 0x1f; ++ u32 error = frame_status & 0x200; ++ u32 pic_struct = (frame_status >> 5) & 0x7; ++ u32 field = V4L2_FIELD_NONE; ++ ++ /* A buffer decode error means it was decoded, ++ * but part of the picture will have artifacts. ++ * Typical reason is a temporarily corrupted bitstream ++ */ ++ if (error) ++ dev_info(core->dev, "Buffer %d decode error\n", ++ buffer_index); ++ ++ if (pic_struct == PIC_TOP_BOT) ++ field = V4L2_FIELD_INTERLACED_TB; ++ else if (pic_struct == PIC_BOT_TOP) ++ field = V4L2_FIELD_INTERLACED_BT; ++ ++ amvdec_dst_buf_done_idx(sess, buffer_index, field); ++ ++ if (field != V4L2_FIELD_NONE && !h264->received_0) ++ amvdec_rm_first_ts(sess); ++ ++ h264->received_0 = 0; ++ } ++} ++ ++static irqreturn_t codec_h264_threaded_isr(struct amvdec_session *sess) ++{ ++ struct amvdec_core *core = sess->core; ++ struct codec_h264 *h264 = sess->priv; ++ u32 status; ++ u32 size; ++ u8 cmd; ++ ++ status = amvdec_read_dos(core, AV_SCRATCH_0); ++ cmd = status & 0xff; ++ ++ switch (cmd) { ++ case CMD_SET_PARAM: ++ codec_h264_set_param(sess); ++ break; ++ case CMD_FRAMES_READY: ++ codec_h264_frames_ready(sess, status); ++ break; ++ case CMD_FATAL_ERROR: ++ dev_err(core->dev, "H.264 decoder fatal error\n"); ++ goto abort; ++ case CMD_BAD_WIDTH: ++ size = (amvdec_read_dos(core, AV_SCRATCH_1) + 1) * 16; ++ dev_err(core->dev, "Unsupported video width: %u\n", size); ++ goto abort; ++ case CMD_BAD_HEIGHT: ++ size = (amvdec_read_dos(core, AV_SCRATCH_1) + 1) * 16; ++ dev_err(core->dev, "Unsupported video height: %u\n", size); ++ goto abort; ++ case 0: ++ h264->received_0 = 1; ++ break; ++ case 9: /* Unused but not worth printing for */ ++ break; ++ default: ++ dev_info(core->dev, "Unexpected H264 ISR: %08X\n", cmd); ++ break; ++ } ++ ++ if (cmd && cmd != CMD_SET_PARAM) ++ amvdec_write_dos(core, AV_SCRATCH_0, 0); ++ ++ /* Decoder has some SEI data for us ; ignore */ ++ if (amvdec_read_dos(core, AV_SCRATCH_J) & SEI_DATA_READY) ++ amvdec_write_dos(core, AV_SCRATCH_J, 0); ++ ++ return IRQ_HANDLED; ++abort: ++ amvdec_abort(sess); ++ return IRQ_HANDLED; ++} ++ ++static irqreturn_t codec_h264_isr(struct amvdec_session *sess) ++{ ++ struct amvdec_core *core = sess->core; ++ ++ amvdec_write_dos(core, ASSIST_MBOX1_CLR_REG, 1); ++ ++ return IRQ_WAKE_THREAD; ++} ++ ++struct amvdec_codec_ops codec_h264_ops = { ++ .start = codec_h264_start, ++ .stop = codec_h264_stop, ++ .load_extended_firmware = codec_h264_load_extended_firmware, ++ .isr = codec_h264_isr, ++ .threaded_isr = codec_h264_threaded_isr, ++ .can_recycle = codec_h264_can_recycle, ++ .recycle = codec_h264_recycle, ++}; +diff --git a/drivers/media/platform/meson/vdec/codec_h264.h b/drivers/media/platform/meson/vdec/codec_h264.h +new file mode 100644 +index 0000000000000..7a1597611faff +--- /dev/null ++++ b/drivers/media/platform/meson/vdec/codec_h264.h +@@ -0,0 +1,13 @@ ++/* SPDX-License-Identifier: GPL-2.0+ */ ++/* ++ * Copyright (C) 2018 Maxime Jourdan ++ */ ++ ++#ifndef __MESON_VDEC_CODEC_H264_H_ ++#define __MESON_VDEC_CODEC_H264_H_ ++ ++#include "vdec.h" ++ ++extern struct amvdec_codec_ops codec_h264_ops; ++ ++#endif +\ No newline at end of file +diff --git a/drivers/media/platform/meson/vdec/vdec_platform.c b/drivers/media/platform/meson/vdec/vdec_platform.c +index 46eeb7426f547..9f7872feef74d 100644 +--- a/drivers/media/platform/meson/vdec/vdec_platform.c ++++ b/drivers/media/platform/meson/vdec/vdec_platform.c +@@ -9,9 +9,20 @@ + + #include "vdec_1.h" + #include "codec_mpeg12.h" ++#include "codec_h264.h" + + static const struct amvdec_format vdec_formats_gxbb[] = { + { ++ .pixfmt = V4L2_PIX_FMT_H264, ++ .min_buffers = 21, ++ .max_buffers = 24, ++ .max_width = 1920, ++ .max_height = 1080, ++ .vdec_ops = &vdec_1_ops, ++ .codec_ops = &codec_h264_ops, ++ .firmware_path = "meson/gxbb/vh264_mc", ++ .pixfmts_cap = { V4L2_PIX_FMT_NV12M, V4L2_PIX_FMT_YUV420M, 0 }, ++ }, { + .pixfmt = V4L2_PIX_FMT_MPEG1, + .min_buffers = 8, + .max_buffers = 8, +@@ -36,6 +47,16 @@ static const struct amvdec_format vdec_formats_gxbb[] = { + + static const struct amvdec_format vdec_formats_gxl[] = { + { ++ .pixfmt = V4L2_PIX_FMT_H264, ++ .min_buffers = 21, ++ .max_buffers = 24, ++ .max_width = 1920, ++ .max_height = 1080, ++ .vdec_ops = &vdec_1_ops, ++ .codec_ops = &codec_h264_ops, ++ .firmware_path = "meson/gxl/vh264_mc", ++ .pixfmts_cap = { V4L2_PIX_FMT_NV12M, V4L2_PIX_FMT_YUV420M, 0 }, ++ }, { + .pixfmt = V4L2_PIX_FMT_MPEG1, + .min_buffers = 8, + .max_buffers = 8, +@@ -60,6 +81,16 @@ static const struct amvdec_format vdec_formats_gxl[] = { + + static const struct amvdec_format vdec_formats_gxm[] = { + { ++ .pixfmt = V4L2_PIX_FMT_H264, ++ .min_buffers = 21, ++ .max_buffers = 24, ++ .max_width = 1920, ++ .max_height = 1080, ++ .vdec_ops = &vdec_1_ops, ++ .codec_ops = &codec_h264_ops, ++ .firmware_path = "meson/gxm/vh264_mc", ++ .pixfmts_cap = { V4L2_PIX_FMT_NV12M, V4L2_PIX_FMT_YUV420M, 0 }, ++ }, { + .pixfmt = V4L2_PIX_FMT_MPEG1, + .min_buffers = 8, + .max_buffers = 8, diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/010_linux-4.18.y-v4l-0010-media-meson-vdec-add_mpeg4_decoding_support.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/010_linux-4.18.y-v4l-0010-media-meson-vdec-add_mpeg4_decoding_support.patch new file mode 100644 index 000000000..067f6d5ef --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/010_linux-4.18.y-v4l-0010-media-meson-vdec-add_mpeg4_decoding_support.patch @@ -0,0 +1,304 @@ +From 4e628eee07aed9d006a4c4b4a75d41f05924b4c8 Mon Sep 17 00:00:00 2001 +From: Maxime Jourdan +Date: Wed, 29 Aug 2018 16:01:55 +0200 +Subject: [PATCH] media: meson: vdec: add MPEG4 decoding support + +Add support for V4L2_PIX_FMT_MPEG4, V4L2_PIX_FMT_XVID and +V4L2_PIX_FMT_H.263 +--- + drivers/media/platform/meson/vdec/Makefile | 2 +- + .../media/platform/meson/vdec/codec_mpeg4.c | 131 ++++++++++++++++++ + .../media/platform/meson/vdec/codec_mpeg4.h | 13 ++ + .../media/platform/meson/vdec/vdec_platform.c | 91 ++++++++++++ + 4 files changed, 236 insertions(+), 1 deletion(-) + create mode 100644 drivers/media/platform/meson/vdec/codec_mpeg4.c + create mode 100644 drivers/media/platform/meson/vdec/codec_mpeg4.h + +diff --git a/drivers/media/platform/meson/vdec/Makefile b/drivers/media/platform/meson/vdec/Makefile +index 711d990c760e0..f167a61acb36d 100644 +--- a/drivers/media/platform/meson/vdec/Makefile ++++ b/drivers/media/platform/meson/vdec/Makefile +@@ -3,6 +3,6 @@ + + meson-vdec-objs = esparser.o vdec.o vdec_helpers.o vdec_platform.o + meson-vdec-objs += vdec_1.o +-meson-vdec-objs += codec_mpeg12.o codec_h264.o ++meson-vdec-objs += codec_mpeg12.o codec_h264.o codec_mpeg4.o + + obj-$(CONFIG_VIDEO_MESON_VDEC) += meson-vdec.o +diff --git a/drivers/media/platform/meson/vdec/codec_mpeg4.c b/drivers/media/platform/meson/vdec/codec_mpeg4.c +new file mode 100644 +index 0000000000000..c6db2640c91a7 +--- /dev/null ++++ b/drivers/media/platform/meson/vdec/codec_mpeg4.c +@@ -0,0 +1,131 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright (C) 2018 Maxime Jourdan ++ */ ++ ++#include ++#include ++ ++#include "vdec_helpers.h" ++#include "dos_regs.h" ++ ++#define SIZE_WORKSPACE SZ_1M ++/* Offset added by firmware, to substract from workspace paddr */ ++#define DCAC_BUFF_START_IP 0x02b00000 ++ ++/* map FW registers to known MPEG4 functions */ ++#define MP4_PIC_RATIO AV_SCRATCH_5 ++#define MP4_ERR_COUNT AV_SCRATCH_6 ++#define MP4_PIC_WH AV_SCRATCH_7 ++#define MREG_BUFFERIN AV_SCRATCH_8 ++#define MREG_BUFFEROUT AV_SCRATCH_9 ++#define MP4_NOT_CODED_CNT AV_SCRATCH_A ++#define MP4_VOP_TIME_INC AV_SCRATCH_B ++#define MP4_OFFSET_REG AV_SCRATCH_C ++#define MP4_SYS_RATE AV_SCRATCH_E ++#define MEM_OFFSET_REG AV_SCRATCH_F ++#define MREG_FATAL_ERROR AV_SCRATCH_L ++ ++struct codec_mpeg4 { ++ /* Buffer for the MPEG4 Workspace */ ++ void *workspace_vaddr; ++ dma_addr_t workspace_paddr; ++}; ++ ++static int codec_mpeg4_can_recycle(struct amvdec_core *core) ++{ ++ return !amvdec_read_dos(core, MREG_BUFFERIN); ++} ++ ++static void codec_mpeg4_recycle(struct amvdec_core *core, u32 buf_idx) ++{ ++ amvdec_write_dos(core, MREG_BUFFERIN, ~(1 << buf_idx)); ++} ++ ++static int codec_mpeg4_start(struct amvdec_session *sess) { ++ struct amvdec_core *core = sess->core; ++ struct codec_mpeg4 *mpeg4 = sess->priv; ++ int ret; ++ ++ mpeg4 = kzalloc(sizeof(*mpeg4), GFP_KERNEL); ++ if (!mpeg4) ++ return -ENOMEM; ++ ++ sess->priv = mpeg4; ++ ++ /* Allocate some memory for the MPEG4 decoder's state */ ++ mpeg4->workspace_vaddr = dma_alloc_coherent(core->dev, SIZE_WORKSPACE, ++ &mpeg4->workspace_paddr, ++ GFP_KERNEL); ++ if (!mpeg4->workspace_vaddr) { ++ dev_err(core->dev, "Failed to request MPEG4 Workspace\n"); ++ ret = -ENOMEM; ++ goto free_mpeg4; ++ } ++ ++ amvdec_set_canvases(sess, (u32[]){ AV_SCRATCH_0, AV_SCRATCH_G, 0 }, ++ (u32[]){ 4, 4, 0 }); ++ ++ amvdec_write_dos(core, MEM_OFFSET_REG, ++ mpeg4->workspace_paddr - DCAC_BUFF_START_IP); ++ amvdec_write_dos(core, PSCALE_CTRL, 0); ++ amvdec_write_dos(core, MP4_NOT_CODED_CNT, 0); ++ amvdec_write_dos(core, MREG_BUFFERIN, 0); ++ amvdec_write_dos(core, MREG_BUFFEROUT, 0); ++ amvdec_write_dos(core, MREG_FATAL_ERROR, 0); ++ amvdec_write_dos(core, MDEC_PIC_DC_THRESH, 0x404038aa); ++ ++ return 0; ++ ++free_mpeg4: ++ kfree(mpeg4); ++ return ret; ++} ++ ++static int codec_mpeg4_stop(struct amvdec_session *sess) ++{ ++ struct codec_mpeg4 *mpeg4 = sess->priv; ++ struct amvdec_core *core = sess->core; ++ ++ if (mpeg4->workspace_vaddr) { ++ dma_free_coherent(core->dev, SIZE_WORKSPACE, ++ mpeg4->workspace_vaddr, ++ mpeg4->workspace_paddr); ++ mpeg4->workspace_vaddr = 0; ++ } ++ ++ return 0; ++} ++ ++static irqreturn_t codec_mpeg4_isr(struct amvdec_session *sess) ++{ ++ u32 reg; ++ u32 buffer_index; ++ struct amvdec_core *core = sess->core; ++ ++ reg = amvdec_read_dos(core, MREG_FATAL_ERROR); ++ if (reg == 1) ++ dev_err(core->dev, "mpeg4 fatal error\n"); ++ ++ reg = amvdec_read_dos(core, MREG_BUFFEROUT); ++ if (reg) { ++ sess->keyframe_found = 1; ++ amvdec_read_dos(core, MP4_NOT_CODED_CNT); ++ amvdec_read_dos(core, MP4_VOP_TIME_INC); ++ buffer_index = reg & 0x7; ++ amvdec_dst_buf_done_idx(sess, buffer_index, V4L2_FIELD_NONE); ++ amvdec_write_dos(core, MREG_BUFFEROUT, 0); ++ } ++ ++ amvdec_write_dos(core, ASSIST_MBOX1_CLR_REG, 1); ++ ++ return IRQ_HANDLED; ++} ++ ++struct amvdec_codec_ops codec_mpeg4_ops = { ++ .start = codec_mpeg4_start, ++ .stop = codec_mpeg4_stop, ++ .isr = codec_mpeg4_isr, ++ .can_recycle = codec_mpeg4_can_recycle, ++ .recycle = codec_mpeg4_recycle, ++}; +diff --git a/drivers/media/platform/meson/vdec/codec_mpeg4.h b/drivers/media/platform/meson/vdec/codec_mpeg4.h +new file mode 100644 +index 0000000000000..b91b264131854 +--- /dev/null ++++ b/drivers/media/platform/meson/vdec/codec_mpeg4.h +@@ -0,0 +1,13 @@ ++/* SPDX-License-Identifier: GPL-2.0+ */ ++/* ++ * Copyright (C) 2018 Maxime Jourdan ++ */ ++ ++#ifndef __MESON_VDEC_CODEC_MPEG4_H_ ++#define __MESON_VDEC_CODEC_MPEG4_H_ ++ ++#include "vdec.h" ++ ++extern struct amvdec_codec_ops codec_mpeg4_ops; ++ ++#endif +\ No newline at end of file +diff --git a/drivers/media/platform/meson/vdec/vdec_platform.c b/drivers/media/platform/meson/vdec/vdec_platform.c +index 9f7872feef74d..135d7566d716a 100644 +--- a/drivers/media/platform/meson/vdec/vdec_platform.c ++++ b/drivers/media/platform/meson/vdec/vdec_platform.c +@@ -10,9 +10,40 @@ + #include "vdec_1.h" + #include "codec_mpeg12.h" + #include "codec_h264.h" ++#include "codec_mpeg4.h" + + static const struct amvdec_format vdec_formats_gxbb[] = { + { ++ .pixfmt = V4L2_PIX_FMT_MPEG4, ++ .min_buffers = 8, ++ .max_buffers = 8, ++ .max_width = 1920, ++ .max_height = 1080, ++ .vdec_ops = &vdec_1_ops, ++ .codec_ops = &codec_mpeg4_ops, ++ .firmware_path = "meson/gx/vmpeg4_mc_5", ++ .pixfmts_cap = { V4L2_PIX_FMT_NV12M, V4L2_PIX_FMT_YUV420M, 0 }, ++ }, { ++ .pixfmt = V4L2_PIX_FMT_H263, ++ .min_buffers = 8, ++ .max_buffers = 8, ++ .max_width = 1920, ++ .max_height = 1080, ++ .vdec_ops = &vdec_1_ops, ++ .codec_ops = &codec_mpeg4_ops, ++ .firmware_path = "meson/gx/h263_mc", ++ .pixfmts_cap = { V4L2_PIX_FMT_NV12M, V4L2_PIX_FMT_YUV420M, 0 }, ++ }, { ++ .pixfmt = V4L2_PIX_FMT_XVID, ++ .min_buffers = 8, ++ .max_buffers = 8, ++ .max_width = 1920, ++ .max_height = 1080, ++ .vdec_ops = &vdec_1_ops, ++ .codec_ops = &codec_mpeg4_ops, ++ .firmware_path = "meson/gx/vmpeg4_mc_5", ++ .pixfmts_cap = { V4L2_PIX_FMT_NV12M, V4L2_PIX_FMT_YUV420M, 0 }, ++ }, { + .pixfmt = V4L2_PIX_FMT_H264, + .min_buffers = 21, + .max_buffers = 24, +@@ -47,6 +78,36 @@ static const struct amvdec_format vdec_formats_gxbb[] = { + + static const struct amvdec_format vdec_formats_gxl[] = { + { ++ .pixfmt = V4L2_PIX_FMT_MPEG4, ++ .min_buffers = 8, ++ .max_buffers = 8, ++ .max_width = 1920, ++ .max_height = 1080, ++ .vdec_ops = &vdec_1_ops, ++ .codec_ops = &codec_mpeg4_ops, ++ .firmware_path = "meson/gx/vmpeg4_mc_5", ++ .pixfmts_cap = { V4L2_PIX_FMT_NV12M, V4L2_PIX_FMT_YUV420M, 0 }, ++ }, { ++ .pixfmt = V4L2_PIX_FMT_H263, ++ .min_buffers = 8, ++ .max_buffers = 8, ++ .max_width = 1920, ++ .max_height = 1080, ++ .vdec_ops = &vdec_1_ops, ++ .codec_ops = &codec_mpeg4_ops, ++ .firmware_path = "meson/gx/h263_mc", ++ .pixfmts_cap = { V4L2_PIX_FMT_NV12M, V4L2_PIX_FMT_YUV420M, 0 }, ++ }, { ++ .pixfmt = V4L2_PIX_FMT_XVID, ++ .min_buffers = 8, ++ .max_buffers = 8, ++ .max_width = 1920, ++ .max_height = 1080, ++ .vdec_ops = &vdec_1_ops, ++ .codec_ops = &codec_mpeg4_ops, ++ .firmware_path = "meson/gx/vmpeg4_mc_5", ++ .pixfmts_cap = { V4L2_PIX_FMT_NV12M, V4L2_PIX_FMT_YUV420M, 0 }, ++ }, { + .pixfmt = V4L2_PIX_FMT_H264, + .min_buffers = 21, + .max_buffers = 24, +@@ -81,6 +142,36 @@ static const struct amvdec_format vdec_formats_gxl[] = { + + static const struct amvdec_format vdec_formats_gxm[] = { + { ++ .pixfmt = V4L2_PIX_FMT_MPEG4, ++ .min_buffers = 8, ++ .max_buffers = 8, ++ .max_width = 1920, ++ .max_height = 1080, ++ .vdec_ops = &vdec_1_ops, ++ .codec_ops = &codec_mpeg4_ops, ++ .firmware_path = "meson/gx/vmpeg4_mc_5", ++ .pixfmts_cap = { V4L2_PIX_FMT_NV12M, V4L2_PIX_FMT_YUV420M, 0 }, ++ }, { ++ .pixfmt = V4L2_PIX_FMT_H263, ++ .min_buffers = 8, ++ .max_buffers = 8, ++ .max_width = 1920, ++ .max_height = 1080, ++ .vdec_ops = &vdec_1_ops, ++ .codec_ops = &codec_mpeg4_ops, ++ .firmware_path = "meson/gx/h263_mc", ++ .pixfmts_cap = { V4L2_PIX_FMT_NV12M, V4L2_PIX_FMT_YUV420M, 0 }, ++ }, { ++ .pixfmt = V4L2_PIX_FMT_XVID, ++ .min_buffers = 8, ++ .max_buffers = 8, ++ .max_width = 1920, ++ .max_height = 1080, ++ .vdec_ops = &vdec_1_ops, ++ .codec_ops = &codec_mpeg4_ops, ++ .firmware_path = "meson/gx/vmpeg4_mc_5", ++ .pixfmts_cap = { V4L2_PIX_FMT_NV12M, V4L2_PIX_FMT_YUV420M, 0 }, ++ }, { + .pixfmt = V4L2_PIX_FMT_H264, + .min_buffers = 21, + .max_buffers = 24, diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/011_linux-4.18.y-v4l-0011-media-meson-vdec-add_mjpeg_decoding_support.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/011_linux-4.18.y-v4l-0011-media-meson-vdec-add_mjpeg_decoding_support.patch new file mode 100644 index 000000000..64b92694e --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/011_linux-4.18.y-v4l-0011-media-meson-vdec-add_mjpeg_decoding_support.patch @@ -0,0 +1,249 @@ +From 920fefae2df25f616552de3c842965f671dd9bae Mon Sep 17 00:00:00 2001 +From: Maxime Jourdan +Date: Wed, 29 Aug 2018 16:05:28 +0200 +Subject: [PATCH] media: meson: vdec: add MJPEG decoding support + +Add support for V4L2_PIX_FMT_MJPEG +--- + drivers/media/platform/meson/vdec/Makefile | 2 +- + .../media/platform/meson/vdec/codec_mjpeg.c | 137 ++++++++++++++++++ + .../media/platform/meson/vdec/codec_mjpeg.h | 13 ++ + .../media/platform/meson/vdec/vdec_platform.c | 31 ++++ + 4 files changed, 182 insertions(+), 1 deletion(-) + create mode 100644 drivers/media/platform/meson/vdec/codec_mjpeg.c + create mode 100644 drivers/media/platform/meson/vdec/codec_mjpeg.h + +diff --git a/drivers/media/platform/meson/vdec/Makefile b/drivers/media/platform/meson/vdec/Makefile +index f167a61acb36d..20c23f9015ebd 100644 +--- a/drivers/media/platform/meson/vdec/Makefile ++++ b/drivers/media/platform/meson/vdec/Makefile +@@ -3,6 +3,6 @@ + + meson-vdec-objs = esparser.o vdec.o vdec_helpers.o vdec_platform.o + meson-vdec-objs += vdec_1.o +-meson-vdec-objs += codec_mpeg12.o codec_h264.o codec_mpeg4.o ++meson-vdec-objs += codec_mpeg12.o codec_h264.o codec_mpeg4.o codec_mjpeg.o + + obj-$(CONFIG_VIDEO_MESON_VDEC) += meson-vdec.o +diff --git a/drivers/media/platform/meson/vdec/codec_mjpeg.c b/drivers/media/platform/meson/vdec/codec_mjpeg.c +new file mode 100644 +index 0000000000000..f632c51c8fffe +--- /dev/null ++++ b/drivers/media/platform/meson/vdec/codec_mjpeg.c +@@ -0,0 +1,137 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright (C) 2018 Maxime Jourdan ++ */ ++ ++#include ++#include ++ ++#include "vdec_helpers.h" ++#include "dos_regs.h" ++ ++/* map FW registers to known MJPEG functions */ ++#define MREG_DECODE_PARAM AV_SCRATCH_2 ++#define MREG_TO_AMRISC AV_SCRATCH_8 ++#define MREG_FROM_AMRISC AV_SCRATCH_9 ++ ++static int codec_mjpeg_can_recycle(struct amvdec_core *core) ++{ ++ return !amvdec_read_dos(core, MREG_TO_AMRISC); ++} ++ ++static void codec_mjpeg_recycle(struct amvdec_core *core, u32 buf_idx) ++{ ++ amvdec_write_dos(core, MREG_TO_AMRISC, buf_idx + 1); ++} ++ ++/* 4 point triangle */ ++static const uint32_t filt_coef[] = { ++ 0x20402000, 0x20402000, 0x1f3f2101, 0x1f3f2101, ++ 0x1e3e2202, 0x1e3e2202, 0x1d3d2303, 0x1d3d2303, ++ 0x1c3c2404, 0x1c3c2404, 0x1b3b2505, 0x1b3b2505, ++ 0x1a3a2606, 0x1a3a2606, 0x19392707, 0x19392707, ++ 0x18382808, 0x18382808, 0x17372909, 0x17372909, ++ 0x16362a0a, 0x16362a0a, 0x15352b0b, 0x15352b0b, ++ 0x14342c0c, 0x14342c0c, 0x13332d0d, 0x13332d0d, ++ 0x12322e0e, 0x12322e0e, 0x11312f0f, 0x11312f0f, ++ 0x10303010 ++}; ++ ++static void codec_mjpeg_init_scaler(struct amvdec_core *core) ++{ ++ int i; ++ ++ /* PSCALE cbus bmem enable */ ++ amvdec_write_dos(core, PSCALE_CTRL, 0xc000); ++ ++ amvdec_write_dos(core, PSCALE_BMEM_ADDR, 0); ++ for (i = 0; i < ARRAY_SIZE(filt_coef); ++i) { ++ amvdec_write_dos(core, PSCALE_BMEM_DAT, 0); ++ amvdec_write_dos(core, PSCALE_BMEM_DAT, filt_coef[i]); ++ } ++ ++ amvdec_write_dos(core, PSCALE_BMEM_ADDR, 74); ++ amvdec_write_dos(core, PSCALE_BMEM_DAT, 0x0008); ++ amvdec_write_dos(core, PSCALE_BMEM_DAT, 0x60000000); ++ ++ amvdec_write_dos(core, PSCALE_BMEM_ADDR, 82); ++ amvdec_write_dos(core, PSCALE_BMEM_DAT, 0x0008); ++ amvdec_write_dos(core, PSCALE_BMEM_DAT, 0x60000000); ++ ++ amvdec_write_dos(core, PSCALE_BMEM_ADDR, 78); ++ amvdec_write_dos(core, PSCALE_BMEM_DAT, 0x0008); ++ amvdec_write_dos(core, PSCALE_BMEM_DAT, 0x60000000); ++ ++ amvdec_write_dos(core, PSCALE_BMEM_ADDR, 86); ++ amvdec_write_dos(core, PSCALE_BMEM_DAT, 0x0008); ++ amvdec_write_dos(core, PSCALE_BMEM_DAT, 0x60000000); ++ ++ amvdec_write_dos(core, PSCALE_BMEM_ADDR, 73); ++ amvdec_write_dos(core, PSCALE_BMEM_DAT, 0x10000); ++ amvdec_write_dos(core, PSCALE_BMEM_ADDR, 81); ++ amvdec_write_dos(core, PSCALE_BMEM_DAT, 0x10000); ++ ++ amvdec_write_dos(core, PSCALE_BMEM_ADDR, 77); ++ amvdec_write_dos(core, PSCALE_BMEM_DAT, 0x10000); ++ amvdec_write_dos(core, PSCALE_BMEM_ADDR, 85); ++ amvdec_write_dos(core, PSCALE_BMEM_DAT, 0x10000); ++ ++ amvdec_write_dos(core, PSCALE_RST, 0x7); ++ amvdec_write_dos(core, PSCALE_RST, 0); ++} ++ ++static int codec_mjpeg_start(struct amvdec_session *sess) ++{ ++ struct amvdec_core *core = sess->core; ++ ++ amvdec_write_dos(core, AV_SCRATCH_0, 12); ++ amvdec_write_dos(core, AV_SCRATCH_1, 0x031a); ++ ++ amvdec_set_canvases(sess, (u32[]){ AV_SCRATCH_4, 0 }, ++ (u32[]){ 4, 0 }); ++ codec_mjpeg_init_scaler(core); ++ ++ amvdec_write_dos(core, MREG_TO_AMRISC, 0); ++ amvdec_write_dos(core, MREG_FROM_AMRISC, 0); ++ amvdec_write_dos(core, MCPU_INTR_MSK, 0xffff); ++ amvdec_write_dos(core, MREG_DECODE_PARAM, ++ (sess->height << 4) | 0x8000); ++ amvdec_write_dos(core, VDEC_ASSIST_AMR1_INT8, 8); ++ ++ /* Intra-only codec */ ++ sess->keyframe_found = 1; ++ ++ return 0; ++} ++ ++static int codec_mjpeg_stop(struct amvdec_session *sess) ++{ ++ return 0; ++} ++ ++static irqreturn_t codec_mjpeg_isr(struct amvdec_session *sess) ++{ ++ u32 reg; ++ u32 buffer_index; ++ struct amvdec_core *core = sess->core; ++ ++ amvdec_write_dos(core, ASSIST_MBOX1_CLR_REG, 1); ++ ++ reg = amvdec_read_dos(core, MREG_FROM_AMRISC); ++ if (!(reg & 0x7)) ++ return IRQ_HANDLED; ++ ++ buffer_index = ((reg & 0x7) - 1) & 3; ++ amvdec_dst_buf_done_idx(sess, buffer_index, V4L2_FIELD_NONE); ++ ++ amvdec_write_dos(core, MREG_FROM_AMRISC, 0); ++ return IRQ_HANDLED; ++} ++ ++struct amvdec_codec_ops codec_mjpeg_ops = { ++ .start = codec_mjpeg_start, ++ .stop = codec_mjpeg_stop, ++ .isr = codec_mjpeg_isr, ++ .can_recycle = codec_mjpeg_can_recycle, ++ .recycle = codec_mjpeg_recycle, ++}; +diff --git a/drivers/media/platform/meson/vdec/codec_mjpeg.h b/drivers/media/platform/meson/vdec/codec_mjpeg.h +new file mode 100644 +index 0000000000000..cc1cf731050d1 +--- /dev/null ++++ b/drivers/media/platform/meson/vdec/codec_mjpeg.h +@@ -0,0 +1,13 @@ ++/* SPDX-License-Identifier: GPL-2.0+ */ ++/* ++ * Copyright (C) 2018 Maxime Jourdan ++ */ ++ ++#ifndef __MESON_VDEC_CODEC_MJPEG_H_ ++#define __MESON_VDEC_CODEC_MJPEG_H_ ++ ++#include "vdec.h" ++ ++extern struct amvdec_codec_ops codec_mjpeg_ops; ++ ++#endif +\ No newline at end of file +diff --git a/drivers/media/platform/meson/vdec/vdec_platform.c b/drivers/media/platform/meson/vdec/vdec_platform.c +index 135d7566d716a..1181832b5fe1e 100644 +--- a/drivers/media/platform/meson/vdec/vdec_platform.c ++++ b/drivers/media/platform/meson/vdec/vdec_platform.c +@@ -11,9 +11,20 @@ + #include "codec_mpeg12.h" + #include "codec_h264.h" + #include "codec_mpeg4.h" ++#include "codec_mjpeg.h" + + static const struct amvdec_format vdec_formats_gxbb[] = { + { ++ .pixfmt = V4L2_PIX_FMT_MJPEG, ++ .min_buffers = 4, ++ .max_buffers = 4, ++ .max_width = 1920, ++ .max_height = 1080, ++ .vdec_ops = &vdec_1_ops, ++ .codec_ops = &codec_mjpeg_ops, ++ .firmware_path = "meson/gx/vmjpeg_mc", ++ .pixfmts_cap = { V4L2_PIX_FMT_YUV420M, 0 }, ++ }, { + .pixfmt = V4L2_PIX_FMT_MPEG4, + .min_buffers = 8, + .max_buffers = 8, +@@ -78,6 +89,16 @@ static const struct amvdec_format vdec_formats_gxbb[] = { + + static const struct amvdec_format vdec_formats_gxl[] = { + { ++ .pixfmt = V4L2_PIX_FMT_MJPEG, ++ .min_buffers = 4, ++ .max_buffers = 4, ++ .max_width = 1920, ++ .max_height = 1080, ++ .vdec_ops = &vdec_1_ops, ++ .codec_ops = &codec_mjpeg_ops, ++ .firmware_path = "meson/gx/vmjpeg_mc", ++ .pixfmts_cap = { V4L2_PIX_FMT_YUV420M, 0 }, ++ }, { + .pixfmt = V4L2_PIX_FMT_MPEG4, + .min_buffers = 8, + .max_buffers = 8, +@@ -142,6 +163,16 @@ static const struct amvdec_format vdec_formats_gxl[] = { + + static const struct amvdec_format vdec_formats_gxm[] = { + { ++ .pixfmt = V4L2_PIX_FMT_MJPEG, ++ .min_buffers = 4, ++ .max_buffers = 4, ++ .max_width = 1920, ++ .max_height = 1080, ++ .vdec_ops = &vdec_1_ops, ++ .codec_ops = &codec_mjpeg_ops, ++ .firmware_path = "meson/gx/vmjpeg_mc", ++ .pixfmts_cap = { V4L2_PIX_FMT_YUV420M, 0 }, ++ }, { + .pixfmt = V4L2_PIX_FMT_MPEG4, + .min_buffers = 8, + .max_buffers = 8, diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/012_linux-4.18.y-v4l-0012-media-videodev2.h_add_amlogic_compressed_format.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/012_linux-4.18.y-v4l-0012-media-videodev2.h_add_amlogic_compressed_format.patch new file mode 100644 index 000000000..0ce67418c --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/012_linux-4.18.y-v4l-0012-media-videodev2.h_add_amlogic_compressed_format.patch @@ -0,0 +1,26 @@ +From 4f40ed63fe484c78d02e3d0583a7f44f815980f3 Mon Sep 17 00:00:00 2001 +From: Maxime Jourdan +Date: Wed, 29 Aug 2018 18:36:09 +0200 +Subject: [PATCH] media: videodev2.h; Add Amlogic compressed format + +Add V4L2_PIX_FMT_AM21C which is a lossless, compressed framebuffer +format. + +It is used by the video decoding and the display IP on many Amlogic +SoCs. +--- + include/uapi/linux/videodev2.h | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h +index 600877be5c229..0568053e3aff9 100644 +--- a/include/uapi/linux/videodev2.h ++++ b/include/uapi/linux/videodev2.h +@@ -668,6 +668,7 @@ struct v4l2_pix_format { + #define V4L2_PIX_FMT_Y12I v4l2_fourcc('Y', '1', '2', 'I') /* Greyscale 12-bit L/R interleaved */ + #define V4L2_PIX_FMT_Z16 v4l2_fourcc('Z', '1', '6', ' ') /* Depth data 16-bit */ + #define V4L2_PIX_FMT_MT21C v4l2_fourcc('M', 'T', '2', '1') /* Mediatek compressed block mode */ ++#define V4L2_PIX_FMT_AM21C v4l2_fourcc('A', 'M', '2', '1') /* Amlogic compressed block mode */ + #define V4L2_PIX_FMT_INZI v4l2_fourcc('I', 'N', 'Z', 'I') /* Intel Planar Greyscale 10-bit and Depth 16-bit */ + + /* 10bit raw bayer packed, 32 bytes for every 25 pixels, last LSB 6 bits unused */ diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/013_linux-4.18.y-v4l-0013-media-meson-vdec-add_v4l2_pix_fmt_am21c_support.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/013_linux-4.18.y-v4l-0013-media-meson-vdec-add_v4l2_pix_fmt_am21c_support.patch new file mode 100644 index 000000000..bec43de46 --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/013_linux-4.18.y-v4l-0013-media-meson-vdec-add_v4l2_pix_fmt_am21c_support.patch @@ -0,0 +1,103 @@ +From 88eb5d85f62d7a41559f3b9c15ec69b07c4ee005 Mon Sep 17 00:00:00 2001 +From: Maxime Jourdan +Date: Wed, 29 Aug 2018 18:46:31 +0200 +Subject: [PATCH] media: meson: vdec: add V4L2_PIX_FMT_AM21C support + +Support the lossless, framebuffer compression format from Amlogic. + +Signed-off-by: Maxime Jourdan +--- + drivers/media/platform/meson/vdec/vdec.c | 7 +++++ + .../media/platform/meson/vdec/vdec_helpers.c | 31 +++++++++++++++++++ + .../media/platform/meson/vdec/vdec_helpers.h | 4 +++ + 3 files changed, 42 insertions(+) + +diff --git a/drivers/media/platform/meson/vdec/vdec.c b/drivers/media/platform/meson/vdec/vdec.c +index 32e1e22282970..d5f8fed2886f5 100644 +--- a/drivers/media/platform/meson/vdec/vdec.c ++++ b/drivers/media/platform/meson/vdec/vdec.c +@@ -182,6 +182,9 @@ static int vdec_queue_setup(struct vb2_queue *q, + sizes[1] = amvdec_get_output_size(sess) / 4; + sizes[2] = amvdec_get_output_size(sess) / 4; + *num_planes = 3; ++ } else if (pixfmt_cap == V4L2_PIX_FMT_AM21C) { ++ sizes[0] = amvdec_am21c_size(sess->width, sess->height); ++ *num_planes = 1; + } + *num_buffers = min(max(*num_buffers, fmt_out->min_buffers), + fmt_out->max_buffers); +@@ -444,6 +447,10 @@ vdec_try_fmt_common(struct amvdec_session *sess, u32 size, + get_output_size(pixmp->width, pixmp->height) / 4; + pfmt[2].bytesperline = ALIGN(pixmp->width, 64) / 2; + pixmp->num_planes = 3; ++ } else if (pixmp->pixelformat == V4L2_PIX_FMT_AM21C) { ++ pfmt[0].sizeimage = ++ amvdec_am21c_size(pixmp->width, pixmp->height); ++ pfmt[0].bytesperline = 0; + } + } else { + return NULL; +diff --git a/drivers/media/platform/meson/vdec/vdec_helpers.c b/drivers/media/platform/meson/vdec/vdec_helpers.c +index 6151076297655..1c3a015eb3b33 100644 +--- a/drivers/media/platform/meson/vdec/vdec_helpers.c ++++ b/drivers/media/platform/meson/vdec/vdec_helpers.c +@@ -49,6 +49,33 @@ void amvdec_write_parser(struct amvdec_core *core, u32 reg, u32 val) + } + EXPORT_SYMBOL_GPL(amvdec_write_parser); + ++/* 4 KiB per 64x32 block */ ++u32 amvdec_am21c_body_size(u32 width, u32 height) ++{ ++ u32 width_64 = ALIGN(width, 64) / 64; ++ u32 height_32 = ALIGN(height, 32) / 32; ++ ++ return SZ_4K * width_64 * height_32; ++} ++EXPORT_SYMBOL_GPL(amvdec_am21c_body_size); ++ ++/* 32 bytes per 128x64 block */ ++u32 amvdec_am21c_head_size(u32 width, u32 height) ++{ ++ u32 width_128 = ALIGN(width, 128) / 128; ++ u32 height_64 = ALIGN(height, 64) / 64; ++ ++ return 32 * width_128 * height_64; ++} ++EXPORT_SYMBOL_GPL(amvdec_am21c_head_size); ++ ++u32 amvdec_am21c_size(u32 width, u32 height) ++{ ++ return ALIGN(amvdec_am21c_body_size(width, height) + ++ amvdec_am21c_head_size(width, height), SZ_64K); ++} ++EXPORT_SYMBOL_GPL(amvdec_am21c_size); ++ + static int canvas_alloc(struct amvdec_session *sess, u8 *canvas_id) + { + int ret; +@@ -228,6 +255,10 @@ void amvdec_dst_buf_done(struct amvdec_session *sess, + vbuf->vb2_buf.planes[1].bytesused = output_size / 4; + vbuf->vb2_buf.planes[2].bytesused = output_size / 4; + break; ++ case V4L2_PIX_FMT_AM21C: ++ vbuf->vb2_buf.planes[0].bytesused = ++ amvdec_am21c_size(sess->width, sess->height); ++ break; + } + vbuf->vb2_buf.timestamp = tmp->ts; + vbuf->sequence = sess->sequence_cap++; +diff --git a/drivers/media/platform/meson/vdec/vdec_helpers.h b/drivers/media/platform/meson/vdec/vdec_helpers.h +index 352c6b4c4b84c..d8a4a2c563af0 100644 +--- a/drivers/media/platform/meson/vdec/vdec_helpers.h ++++ b/drivers/media/platform/meson/vdec/vdec_helpers.h +@@ -26,6 +26,10 @@ void amvdec_clear_dos_bits(struct amvdec_core *core, u32 reg, u32 val); + u32 amvdec_read_parser(struct amvdec_core *core, u32 reg); + void amvdec_write_parser(struct amvdec_core *core, u32 reg, u32 val); + ++u32 amvdec_am21c_body_size(u32 width, u32 height); ++u32 amvdec_am21c_head_size(u32 width, u32 height); ++u32 amvdec_am21c_size(u32 width, u32 height); ++ + void amvdec_dst_buf_done_idx(struct amvdec_session *sess, u32 buf_idx, + u32 field); + void amvdec_dst_buf_done(struct amvdec_session *sess, diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/014_linux-4.18.y-v4l-0014-media-meson-vdec-add_hevc_decoding_support.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/014_linux-4.18.y-v4l-0014-media-meson-vdec-add_hevc_decoding_support.patch new file mode 100644 index 000000000..c178dad35 --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/014_linux-4.18.y-v4l-0014-media-meson-vdec-add_hevc_decoding_support.patch @@ -0,0 +1,2617 @@ +From 3ff8b6ea023464f8de12835ed90211e3f66ed0f4 Mon Sep 17 00:00:00 2001 +From: Maxime Jourdan +Date: Wed, 29 Aug 2018 18:48:35 +0200 +Subject: [PATCH] media: meson: vdec: add HEVC decoding support + +Add support for V4L2_PIX_FMT_HEVC +--- + drivers/media/platform/meson/vdec/Makefile | 4 +- + .../media/platform/meson/vdec/codec_hevc.c | 1517 +++++++++++++++++ + .../media/platform/meson/vdec/codec_hevc.h | 13 + + drivers/media/platform/meson/vdec/hevc_regs.h | 742 ++++++++ + drivers/media/platform/meson/vdec/vdec_hevc.c | 191 +++ + drivers/media/platform/meson/vdec/vdec_hevc.h | 22 + + .../media/platform/meson/vdec/vdec_platform.c | 32 + + 7 files changed, 2519 insertions(+), 2 deletions(-) + create mode 100644 drivers/media/platform/meson/vdec/codec_hevc.c + create mode 100644 drivers/media/platform/meson/vdec/codec_hevc.h + create mode 100644 drivers/media/platform/meson/vdec/hevc_regs.h + create mode 100644 drivers/media/platform/meson/vdec/vdec_hevc.c + create mode 100644 drivers/media/platform/meson/vdec/vdec_hevc.h + +diff --git a/drivers/media/platform/meson/vdec/Makefile b/drivers/media/platform/meson/vdec/Makefile +index 20c23f9015ebd..f34b7a2961511 100644 +--- a/drivers/media/platform/meson/vdec/Makefile ++++ b/drivers/media/platform/meson/vdec/Makefile +@@ -2,7 +2,7 @@ + # Makefile for Amlogic meson video decoder driver + + meson-vdec-objs = esparser.o vdec.o vdec_helpers.o vdec_platform.o +-meson-vdec-objs += vdec_1.o +-meson-vdec-objs += codec_mpeg12.o codec_h264.o codec_mpeg4.o codec_mjpeg.o ++meson-vdec-objs += vdec_1.o vdec_hevc.o ++meson-vdec-objs += codec_mpeg12.o codec_h264.o codec_mpeg4.o codec_mjpeg.o codec_hevc.o + + obj-$(CONFIG_VIDEO_MESON_VDEC) += meson-vdec.o +diff --git a/drivers/media/platform/meson/vdec/codec_hevc.c b/drivers/media/platform/meson/vdec/codec_hevc.c +new file mode 100644 +index 0000000000000..5e69717ba0570 +--- /dev/null ++++ b/drivers/media/platform/meson/vdec/codec_hevc.c +@@ -0,0 +1,1517 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright (C) 2018 Maxime Jourdan ++ * Copyright (C) 2015 Amlogic, Inc. All rights reserved. ++ */ ++ ++#include ++#include ++ ++#include "codec_hevc.h" ++#include "dos_regs.h" ++#include "hevc_regs.h" ++#include "vdec_helpers.h" ++ ++/* HEVC reg mapping */ ++#define HEVC_DEC_STATUS_REG HEVC_ASSIST_SCRATCH_0 ++ #define HEVC_ACTION_DONE 0xff ++#define HEVC_RPM_BUFFER HEVC_ASSIST_SCRATCH_1 ++#define HEVC_DECODE_INFO HEVC_ASSIST_SCRATCH_1 ++#define HEVC_SHORT_TERM_RPS HEVC_ASSIST_SCRATCH_2 ++#define HEVC_VPS_BUFFER HEVC_ASSIST_SCRATCH_3 ++#define HEVC_SPS_BUFFER HEVC_ASSIST_SCRATCH_4 ++#define HEVC_PPS_BUFFER HEVC_ASSIST_SCRATCH_5 ++#define HEVC_SAO_UP HEVC_ASSIST_SCRATCH_6 ++#define HEVC_STREAM_SWAP_BUFFER HEVC_ASSIST_SCRATCH_7 ++#define H265_MMU_MAP_BUFFER HEVC_ASSIST_SCRATCH_7 ++#define HEVC_STREAM_SWAP_BUFFER2 HEVC_ASSIST_SCRATCH_8 ++#define HEVC_sao_mem_unit HEVC_ASSIST_SCRATCH_9 ++#define HEVC_SAO_ABV HEVC_ASSIST_SCRATCH_A ++#define HEVC_sao_vb_size HEVC_ASSIST_SCRATCH_B ++#define HEVC_SAO_VB HEVC_ASSIST_SCRATCH_C ++#define HEVC_SCALELUT HEVC_ASSIST_SCRATCH_D ++#define HEVC_WAIT_FLAG HEVC_ASSIST_SCRATCH_E ++#define RPM_CMD_REG HEVC_ASSIST_SCRATCH_F ++#define LMEM_DUMP_ADR HEVC_ASSIST_SCRATCH_F ++#define DEBUG_REG1 HEVC_ASSIST_SCRATCH_G ++#define HEVC_DECODE_MODE2 HEVC_ASSIST_SCRATCH_H ++#define NAL_SEARCH_CTL HEVC_ASSIST_SCRATCH_I ++#define HEVC_DECODE_MODE HEVC_ASSIST_SCRATCH_J ++ #define DECODE_MODE_SINGLE 0 ++#define DECODE_STOP_POS HEVC_ASSIST_SCRATCH_K ++#define HEVC_AUX_ADR HEVC_ASSIST_SCRATCH_L ++#define HEVC_AUX_DATA_SIZE HEVC_ASSIST_SCRATCH_M ++#define HEVC_DECODE_SIZE HEVC_ASSIST_SCRATCH_N ++ ++#define HEVCD_MPP_ANC2AXI_TBL_DATA (0x3464 * 4) ++ ++#define HEVC_CM_BODY_START_ADDR (0x3626 * 4) ++#define HEVC_CM_BODY_LENGTH (0x3627 * 4) ++#define HEVC_CM_HEADER_LENGTH (0x3629 * 4) ++#define HEVC_CM_HEADER_OFFSET (0x362b * 4) ++ ++#define AMRISC_MAIN_REQ 0x04 ++ ++/* HEVC Constants */ ++#define MAX_REF_PIC_NUM 24 ++#define MAX_REF_ACTIVE 16 ++#define MPRED_MV_BUF_SIZE 0x120000 ++#define MAX_TILE_COL_NUM 10 ++#define MAX_TILE_ROW_NUM 20 ++#define MAX_SLICE_NUM 800 ++#define INVALID_POC 0x80000000 ++ ++/* HEVC Workspace layout */ ++#define IPP_OFFSET 0x00 ++#define SAO_ABV_OFFSET (IPP_OFFSET + 0x4000) ++#define SAO_VB_OFFSET (SAO_ABV_OFFSET + 0x30000) ++#define SH_TM_RPS_OFFSET (SAO_VB_OFFSET + 0x30000) ++#define VPS_OFFSET (SH_TM_RPS_OFFSET + 0x800) ++#define SPS_OFFSET (VPS_OFFSET + 0x800) ++#define PPS_OFFSET (SPS_OFFSET + 0x800) ++#define SAO_UP_OFFSET (PPS_OFFSET + 0x2000) ++#define SWAP_BUF_OFFSET (SAO_UP_OFFSET + 0x800) ++#define SWAP_BUF2_OFFSET (SWAP_BUF_OFFSET + 0x800) ++#define SCALELUT_OFFSET (SWAP_BUF2_OFFSET + 0x800) ++#define DBLK_PARA_OFFSET (SCALELUT_OFFSET + 0x8000) ++#define DBLK_DATA_OFFSET (DBLK_PARA_OFFSET + 0x20000) ++#define MMU_VBH_OFFSET (DBLK_DATA_OFFSET + 0x40000) ++#define MPRED_ABV_OFFSET (MMU_VBH_OFFSET + 0x5000) ++#define MPRED_MV_OFFSET (MPRED_ABV_OFFSET + 0x8000) ++#define RPM_OFFSET (MPRED_MV_OFFSET + MPRED_MV_BUF_SIZE * MAX_REF_PIC_NUM) ++#define LMEM_OFFSET (RPM_OFFSET + 0x100) ++ ++/* ISR decode status */ ++#define HEVC_DEC_IDLE 0x0 ++#define HEVC_NAL_UNIT_VPS 0x1 ++#define HEVC_NAL_UNIT_SPS 0x2 ++#define HEVC_NAL_UNIT_PPS 0x3 ++#define HEVC_NAL_UNIT_CODED_SLICE_SEGMENT 0x4 ++#define HEVC_CODED_SLICE_SEGMENT_DAT 0x5 ++#define HEVC_SLICE_DECODING 0x6 ++#define HEVC_NAL_UNIT_SEI 0x7 ++#define HEVC_SLICE_SEGMENT_DONE 0x8 ++#define HEVC_NAL_SEARCH_DONE 0x9 ++#define HEVC_DECPIC_DATA_DONE 0xa ++#define HEVC_DECPIC_DATA_ERROR 0xb ++#define HEVC_SEI_DAT 0xc ++#define HEVC_SEI_DAT_DONE 0xd ++ ++/* RPM misc_flag0 */ ++#define PCM_LOOP_FILTER_DISABLED_FLAG_BIT 0 ++#define PCM_ENABLE_FLAG_BIT 1 ++#define LOOP_FILER_ACROSS_TILES_ENABLED_FLAG_BIT 2 ++#define PPS_LOOP_FILTER_ACROSS_SLICES_ENABLED_FLAG_BIT 3 ++#define DEBLOCKING_FILTER_OVERRIDE_ENABLED_FLAG_BIT 4 ++#define PPS_DEBLOCKING_FILTER_DISABLED_FLAG_BIT 5 ++#define DEBLOCKING_FILTER_OVERRIDE_FLAG_BIT 6 ++#define SLICE_DEBLOCKING_FILTER_DISABLED_FLAG_BIT 7 ++#define SLICE_SAO_LUMA_FLAG_BIT 8 ++#define SLICE_SAO_CHROMA_FLAG_BIT 9 ++#define SLICE_LOOP_FILTER_ACROSS_SLICES_ENABLED_FLAG_BIT 10 ++ ++/* Buffer sizes */ ++#define SIZE_WORKSPACE ALIGN(LMEM_OFFSET + 0xA00, 64 * SZ_1K) ++#define SIZE_AUX (SZ_1K * 16) ++#define SIZE_FRAME_MMU (0x1200 * 4) ++#define RPM_SIZE 0x80 ++#define RPS_USED_BIT 14 ++ ++#define PARSER_CMD_SKIP_CFG_0 0x0000090b ++#define PARSER_CMD_SKIP_CFG_1 0x1b14140f ++#define PARSER_CMD_SKIP_CFG_2 0x001b1910 ++static const u16 parser_cmd[] = { ++ 0x0401, 0x8401, 0x0800, 0x0402, ++ 0x9002, 0x1423, 0x8CC3, 0x1423, ++ 0x8804, 0x9825, 0x0800, 0x04FE, ++ 0x8406, 0x8411, 0x1800, 0x8408, ++ 0x8409, 0x8C2A, 0x9C2B, 0x1C00, ++ 0x840F, 0x8407, 0x8000, 0x8408, ++ 0x2000, 0xA800, 0x8410, 0x04DE, ++ 0x840C, 0x840D, 0xAC00, 0xA000, ++ 0x08C0, 0x08E0, 0xA40E, 0xFC00, ++ 0x7C00 ++}; ++ ++/* Data received from the HW in this form, do not rearrange */ ++union rpm_param { ++ struct { ++ u16 data[RPM_SIZE]; ++ } l; ++ struct { ++ u16 CUR_RPS[MAX_REF_ACTIVE]; ++ u16 num_ref_idx_l0_active; ++ u16 num_ref_idx_l1_active; ++ u16 slice_type; ++ u16 slice_temporal_mvp_enable_flag; ++ u16 dependent_slice_segment_flag; ++ u16 slice_segment_address; ++ u16 num_title_rows_minus1; ++ u16 pic_width_in_luma_samples; ++ u16 pic_height_in_luma_samples; ++ u16 log2_min_coding_block_size_minus3; ++ u16 log2_diff_max_min_coding_block_size; ++ u16 log2_max_pic_order_cnt_lsb_minus4; ++ u16 POClsb; ++ u16 collocated_from_l0_flag; ++ u16 collocated_ref_idx; ++ u16 log2_parallel_merge_level; ++ u16 five_minus_max_num_merge_cand; ++ u16 sps_num_reorder_pics_0; ++ u16 modification_flag; ++ u16 tiles_flags; ++ u16 num_tile_columns_minus1; ++ u16 num_tile_rows_minus1; ++ u16 tile_width[8]; ++ u16 tile_height[8]; ++ u16 misc_flag0; ++ u16 pps_beta_offset_div2; ++ u16 pps_tc_offset_div2; ++ u16 slice_beta_offset_div2; ++ u16 slice_tc_offset_div2; ++ u16 pps_cb_qp_offset; ++ u16 pps_cr_qp_offset; ++ u16 first_slice_segment_in_pic_flag; ++ u16 m_temporalId; ++ u16 m_nalUnitType; ++ u16 vui_num_units_in_tick_hi; ++ u16 vui_num_units_in_tick_lo; ++ u16 vui_time_scale_hi; ++ u16 vui_time_scale_lo; ++ u16 bit_depth; ++ u16 profile_etc; ++ u16 sei_frame_field_info; ++ u16 video_signal_type; ++ u16 modification_list[0x20]; ++ u16 conformance_window_flag; ++ u16 conf_win_left_offset; ++ u16 conf_win_right_offset; ++ u16 conf_win_top_offset; ++ u16 conf_win_bottom_offset; ++ u16 chroma_format_idc; ++ u16 color_description; ++ u16 aspect_ratio_idc; ++ u16 sar_width; ++ u16 sar_height; ++ } p; ++}; ++ ++enum nal_unit_type { ++ NAL_UNIT_CODED_SLICE_BLA = 16, ++ NAL_UNIT_CODED_SLICE_BLANT = 17, ++ NAL_UNIT_CODED_SLICE_BLA_N_LP = 18, ++ NAL_UNIT_CODED_SLICE_IDR = 19, ++ NAL_UNIT_CODED_SLICE_IDR_N_LP = 20, ++}; ++ ++enum slice_type { ++ B_SLICE = 0, ++ P_SLICE = 1, ++ I_SLICE = 2, ++}; ++ ++/* A frame being decoded */ ++struct hevc_frame { ++ struct list_head list; ++ struct vb2_v4l2_buffer *vbuf; ++ u32 poc; ++ ++ int referenced; ++ u32 num_reorder_pic; ++ ++ u32 cur_slice_idx; ++ u32 cur_slice_type; ++ ++ /* 2 lists (L0/L1) ; 800 slices ; 16 refs */ ++ u32 ref_poc_list[2][MAX_SLICE_NUM][MAX_REF_ACTIVE]; ++ u32 ref_num[2]; ++}; ++ ++struct hevc_tile { ++ int width; ++ int height; ++ int start_cu_x; ++ int start_cu_y; ++ ++ dma_addr_t sao_vb_start_addr; ++ dma_addr_t sao_abv_start_addr; ++}; ++ ++struct codec_hevc { ++ /* Current decoding status provided by the ISR */ ++ u32 dec_status; ++ ++ struct mutex lock; ++ ++ /* Buffer for the HEVC Workspace */ ++ void *workspace_vaddr; ++ dma_addr_t workspace_paddr; ++ ++ /* AUX buffer */ ++ void *aux_vaddr; ++ dma_addr_t aux_paddr; ++ ++ /* Frame MMU buffer (>= GXL) ; unused for now */ ++ void *frame_mmu_vaddr; ++ dma_addr_t frame_mmu_paddr; ++ ++ /* Contains many information parsed from the bitstream */ ++ union rpm_param rpm_param; ++ ++ /* Information computed from the RPM */ ++ u32 lcu_size; // Largest Coding Unit ++ u32 lcu_x_num; ++ u32 lcu_y_num; ++ u32 lcu_total; ++ ++ /* Current Frame being handled */ ++ struct hevc_frame *cur_frame; ++ u32 curr_poc; ++ /* Collocated Reference Picture */ ++ struct hevc_frame *col_frame; ++ u32 col_poc; ++ ++ /* All ref frames used by the HW at a given time */ ++ struct list_head ref_frames_list; ++ u32 frames_num; ++ ++ /* Resolution reported by the hardware */ ++ u32 width; ++ u32 height; ++ ++ u32 iPrevTid0POC; ++ u32 slice_segment_addr; ++ u32 slice_addr; ++ u32 ldc_flag; ++ ++ /* Tiles */ ++ u32 num_tile_col; ++ u32 num_tile_row; ++ struct hevc_tile m_tile[MAX_TILE_ROW_NUM][MAX_TILE_COL_NUM]; ++ u32 tile_start_lcu_x; ++ u32 tile_start_lcu_y; ++ u32 tile_width_lcu; ++ u32 tile_height_lcu; ++ ++ /* Whether we detected the bitstream as 10-bit */ ++ int is_10bit; ++ ++ /* Whether we already configured the buffer list in HW */ ++ int is_buflist_init; ++ ++ /* In case of downsampling (decoding with FBC but outputting in NV12M), ++ * we need to allocate additional buffers for FBC. ++ */ ++ void *fbc_buffer_vaddr[24]; ++ dma_addr_t fbc_buffer_paddr[24]; ++}; ++ ++/* Returns 1 if we must use framebuffer compression */ ++static int codec_hevc_use_fbc(struct amvdec_session *sess) ++{ ++ struct codec_hevc *hevc = sess->priv; ++ return sess->pixfmt_cap == V4L2_PIX_FMT_AM21C || hevc->is_10bit; ++} ++ ++/* Returns 1 if we are decoding 10-bit but outputting 8-bit NV12 */ ++static int codec_hevc_use_downsample(struct amvdec_session *sess) ++{ ++ struct codec_hevc *hevc = sess->priv; ++ return sess->pixfmt_cap == V4L2_PIX_FMT_NV12M && hevc->is_10bit; ++} ++ ++static u32 codec_hevc_num_pending_bufs(struct amvdec_session *sess) ++{ ++ struct codec_hevc *hevc; ++ u32 ret; ++ ++ hevc = sess->priv; ++ if (!hevc) ++ return 0; ++ ++ mutex_lock(&hevc->lock); ++ ret = hevc->frames_num; ++ mutex_unlock(&hevc->lock); ++ ++ return ret; ++} ++ ++/* Update the L0 and L1 reference lists for a given frame */ ++static void codec_hevc_update_frame_refs(struct amvdec_session *sess, struct hevc_frame *frame) ++{ ++ struct codec_hevc *hevc = sess->priv; ++ union rpm_param *params = &hevc->rpm_param; ++ int i; ++ int num_neg = 0; ++ int num_pos = 0; ++ int total_num; ++ int num_ref_idx_l0_active = ++ (params->p.num_ref_idx_l0_active > MAX_REF_ACTIVE) ? ++ MAX_REF_ACTIVE : params->p.num_ref_idx_l0_active; ++ int num_ref_idx_l1_active = ++ (params->p.num_ref_idx_l1_active > MAX_REF_ACTIVE) ? ++ MAX_REF_ACTIVE : params->p.num_ref_idx_l1_active; ++ int ref_picset0[MAX_REF_ACTIVE] = { 0 }; ++ int ref_picset1[MAX_REF_ACTIVE] = { 0 }; ++ ++ for (i = 0; i < MAX_REF_ACTIVE; i++) { ++ frame->ref_poc_list[0][frame->cur_slice_idx][i] = 0; ++ frame->ref_poc_list[1][frame->cur_slice_idx][i] = 0; ++ } ++ ++ for (i = 0; i < MAX_REF_ACTIVE; i++) { ++ u16 cur_rps = params->p.CUR_RPS[i]; ++ int delt = cur_rps & ((1 << (RPS_USED_BIT - 1)) - 1); ++ ++ if (cur_rps & 0x8000) ++ break; ++ ++ if (!((cur_rps >> RPS_USED_BIT) & 1)) ++ continue; ++ ++ if ((cur_rps >> (RPS_USED_BIT - 1)) & 1) { ++ ref_picset0[num_neg] = ++ frame->poc - ((1 << (RPS_USED_BIT - 1)) - delt); ++ num_neg++; ++ } else { ++ ref_picset1[num_pos] = frame->poc + delt; ++ num_pos++; ++ } ++ } ++ ++ total_num = num_neg + num_pos; ++ ++ if (total_num <= 0) ++ goto end; ++ ++ for (i = 0; i < num_ref_idx_l0_active; i++) { ++ int cidx; ++ if (params->p.modification_flag & 0x1) ++ cidx = params->p.modification_list[i]; ++ else ++ cidx = i % total_num; ++ ++ frame->ref_poc_list[0][frame->cur_slice_idx][i] = ++ cidx >= num_neg ? ref_picset1[cidx - num_neg] : ++ ref_picset0[cidx]; ++ } ++ ++ if (params->p.slice_type != B_SLICE) ++ goto end; ++ ++ if (params->p.modification_flag & 0x2) { ++ for (i = 0; i < num_ref_idx_l1_active; i++) { ++ int cidx; ++ if (params->p.modification_flag & 0x1) ++ cidx = ++ params->p.modification_list[num_ref_idx_l0_active + i]; ++ else ++ cidx = params->p.modification_list[i]; ++ ++ frame->ref_poc_list[1][frame->cur_slice_idx][i] = ++ (cidx >= num_pos) ? ref_picset0[cidx - num_pos] ++ : ref_picset1[cidx]; ++ } ++ } else { ++ for (i = 0; i < num_ref_idx_l1_active; i++) { ++ int cidx = i % total_num; ++ frame->ref_poc_list[1][frame->cur_slice_idx][i] = ++ cidx >= num_pos ? ref_picset0[cidx - num_pos] : ++ ref_picset1[cidx]; ++ } ++ } ++ ++end: ++ frame->ref_num[0] = num_ref_idx_l0_active; ++ frame->ref_num[1] = num_ref_idx_l1_active; ++ ++ dev_dbg(sess->core->dev, ++ "Frame %u; slice %u; slice_type %u; num_l0 %u; num_l1 %u\n", ++ frame->poc, frame->cur_slice_idx, params->p.slice_type, ++ frame->ref_num[0], frame->ref_num[1]); ++} ++ ++static void codec_hevc_update_ldc_flag(struct codec_hevc *hevc) ++{ ++ struct hevc_frame *frame = hevc->cur_frame; ++ u32 slice_type = frame->cur_slice_type; ++ int i; ++ ++ hevc->ldc_flag = 0; ++ ++ if (slice_type == I_SLICE) ++ return; ++ ++ hevc->ldc_flag = 1; ++ for (i = 0; (i < frame->ref_num[0]) && hevc->ldc_flag; i++) { ++ if (frame->ref_poc_list[0][frame->cur_slice_idx][i] > frame->poc) { ++ hevc->ldc_flag = 0; ++ break; ++ } ++ } ++ ++ if (slice_type == P_SLICE) ++ return; ++ ++ for (i = 0; (i < frame->ref_num[1]) && hevc->ldc_flag; i++) { ++ if (frame->ref_poc_list[1][frame->cur_slice_idx][i] > frame->poc) { ++ hevc->ldc_flag = 0; ++ break; ++ } ++ } ++} ++ ++/* Tag "old" frames that are no longer referenced */ ++static void codec_hevc_update_referenced(struct codec_hevc *hevc) ++{ ++ union rpm_param *param = &hevc->rpm_param; ++ struct hevc_frame *frame; ++ int i; ++ u32 curr_poc = hevc->curr_poc; ++ ++ list_for_each_entry(frame, &hevc->ref_frames_list, list) { ++ int is_referenced = 0; ++ u32 poc_tmp; ++ ++ if (!frame->referenced) ++ continue; ++ ++ for (i = 0; i < MAX_REF_ACTIVE; i++) { ++ int delt; ++ if (param->p.CUR_RPS[i] & 0x8000) ++ break; ++ ++ delt = param->p.CUR_RPS[i] & ((1 << (RPS_USED_BIT - 1)) - 1); ++ if (param->p.CUR_RPS[i] & (1 << (RPS_USED_BIT - 1))) { ++ poc_tmp = curr_poc - ((1 << (RPS_USED_BIT - 1)) - delt); ++ } else ++ poc_tmp = curr_poc + delt; ++ if (poc_tmp == frame->poc) { ++ is_referenced = 1; ++ break; ++ } ++ } ++ ++ frame->referenced = is_referenced; ++ } ++} ++ ++static struct hevc_frame *codec_hevc_get_lowest_poc_frame(struct codec_hevc *hevc) ++{ ++ struct hevc_frame *tmp, *ret = NULL; ++ u32 poc = INT_MAX; ++ ++ list_for_each_entry(tmp, &hevc->ref_frames_list, list) { ++ if (tmp->poc < poc) { ++ ret = tmp; ++ poc = tmp->poc; ++ } ++ } ++ ++ return ret; ++} ++ ++/* Try to output as many frames as possible */ ++static void codec_hevc_output_frames(struct amvdec_session *sess) ++{ ++ struct hevc_frame *tmp; ++ struct codec_hevc *hevc = sess->priv; ++ ++ while ((tmp = codec_hevc_get_lowest_poc_frame(hevc))) { ++ if (hevc->curr_poc && ++ (tmp->referenced || tmp->num_reorder_pic >= hevc->frames_num)) ++ break; ++ ++ dev_dbg(sess->core->dev, "DONE frame poc %u; vbuf %u\n", ++ tmp->poc, tmp->vbuf->vb2_buf.index); ++ amvdec_dst_buf_done(sess, tmp->vbuf, V4L2_FIELD_NONE); ++ list_del(&tmp->list); ++ kfree(tmp); ++ hevc->frames_num--; ++ } ++} ++ ++/* Configure frame buffer decompression */ ++static void codec_hevc_setup_decode_head(struct amvdec_session *sess) ++{ ++ struct amvdec_core *core = sess->core; ++ u32 body_size = amvdec_am21c_body_size(sess->width, sess->height); ++ u32 head_size = amvdec_am21c_head_size(sess->width, sess->height); ++ ++ if (!codec_hevc_use_fbc(sess)) { ++ /* Enable 2-plane reference read mode for MC */ ++ amvdec_write_dos(core, HEVCD_MPP_DECOMP_CTL1, BIT(31)); ++ return; ++ } ++ ++ amvdec_write_dos(core, HEVCD_MPP_DECOMP_CTL1, 0); ++ amvdec_write_dos(core, HEVCD_MPP_DECOMP_CTL2, body_size / 32); ++ amvdec_write_dos(core, HEVC_CM_BODY_LENGTH, body_size); ++ amvdec_write_dos(core, HEVC_CM_HEADER_OFFSET, body_size); ++ amvdec_write_dos(core, HEVC_CM_HEADER_LENGTH, head_size); ++} ++ ++static void codec_hevc_setup_buffers_gxbb(struct amvdec_session *sess) ++{ ++ struct amvdec_core *core = sess->core; ++ struct codec_hevc *hevc = sess->priv; ++ struct v4l2_m2m_buffer *buf; ++ u32 buf_num = v4l2_m2m_num_dst_bufs_ready(sess->m2m_ctx); ++ dma_addr_t buf_y_paddr = 0; ++ dma_addr_t buf_uv_paddr = 0; ++ u32 idx = 0; ++ u32 val; ++ int i; ++ ++ amvdec_write_dos(core, HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR, 0); ++ ++ v4l2_m2m_for_each_dst_buf(sess->m2m_ctx, buf) { ++ idx = buf->vb.vb2_buf.index; ++ ++ if (codec_hevc_use_downsample(sess)) ++ buf_y_paddr = hevc->fbc_buffer_paddr[idx]; ++ else ++ buf_y_paddr = vb2_dma_contig_plane_dma_addr(&buf->vb.vb2_buf, 0); ++ ++ if (codec_hevc_use_fbc(sess)) { ++ val = buf_y_paddr | (idx << 8) | 1; ++ amvdec_write_dos(core, HEVCD_MPP_ANC2AXI_TBL_CMD_ADDR, val); ++ } else if (sess->pixfmt_cap == V4L2_PIX_FMT_NV12M) { ++ buf_uv_paddr = vb2_dma_contig_plane_dma_addr(&buf->vb.vb2_buf, 1); ++ val = buf_y_paddr | ((idx * 2) << 8) | 1; ++ amvdec_write_dos(core, HEVCD_MPP_ANC2AXI_TBL_CMD_ADDR, val); ++ val = buf_uv_paddr | ((idx * 2 + 1) << 8) | 1; ++ amvdec_write_dos(core, HEVCD_MPP_ANC2AXI_TBL_CMD_ADDR, val); ++ } ++ } ++ ++ if (codec_hevc_use_fbc(sess)) ++ val = buf_y_paddr | (idx << 8) | 1; ++ else ++ val = buf_y_paddr | ((idx * 2) << 8) | 1; ++ ++ /* Fill the remaining unused slots with the last buffer's Y addr */ ++ for (i = buf_num; i < MAX_REF_PIC_NUM; ++i) ++ amvdec_write_dos(core, HEVCD_MPP_ANC2AXI_TBL_CMD_ADDR, val); ++ ++ amvdec_write_dos(core, HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR, 1); ++ amvdec_write_dos(core, HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, 1); ++ for (i = 0; i < 32; ++i) ++ amvdec_write_dos(core, HEVCD_MPP_ANC_CANVAS_DATA_ADDR, 0); ++} ++ ++static void codec_hevc_setup_buffers_gxl(struct amvdec_session *sess) ++{ ++ struct amvdec_core *core = sess->core; ++ struct codec_hevc *hevc = sess->priv; ++ struct v4l2_m2m_buffer *buf; ++ u32 buf_num = v4l2_m2m_num_dst_bufs_ready(sess->m2m_ctx); ++ dma_addr_t buf_y_paddr = 0; ++ dma_addr_t buf_uv_paddr = 0; ++ int i; ++ ++ amvdec_write_dos(core, HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR, BIT(2) | BIT(1)); ++ ++ v4l2_m2m_for_each_dst_buf(sess->m2m_ctx, buf) { ++ u32 idx = buf->vb.vb2_buf.index; ++ ++ if (codec_hevc_use_downsample(sess)) ++ buf_y_paddr = hevc->fbc_buffer_paddr[idx]; ++ else ++ buf_y_paddr = vb2_dma_contig_plane_dma_addr(&buf->vb.vb2_buf, 0); ++ ++ amvdec_write_dos(core, HEVCD_MPP_ANC2AXI_TBL_DATA, buf_y_paddr >> 5); ++ if (!codec_hevc_use_fbc(sess)) { ++ buf_uv_paddr = vb2_dma_contig_plane_dma_addr(&buf->vb.vb2_buf, 1); ++ amvdec_write_dos(core, HEVCD_MPP_ANC2AXI_TBL_DATA, buf_uv_paddr >> 5); ++ } ++ } ++ ++ /* Fill the remaining unused slots with the last buffer's Y addr */ ++ for (i = buf_num; i < MAX_REF_PIC_NUM; ++i) { ++ amvdec_write_dos(core, HEVCD_MPP_ANC2AXI_TBL_DATA, buf_y_paddr >> 5); ++ if (!codec_hevc_use_fbc(sess)) ++ amvdec_write_dos(core, HEVCD_MPP_ANC2AXI_TBL_DATA, buf_uv_paddr >> 5); ++ } ++ ++ amvdec_write_dos(core, HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR, 1); ++ amvdec_write_dos(core, HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, 1); ++ for (i = 0; i < 32; ++i) ++ amvdec_write_dos(core, HEVCD_MPP_ANC_CANVAS_DATA_ADDR, 0); ++} ++ ++static void codec_hevc_free_fbc_buffers(struct amvdec_session *sess) ++{ ++ struct codec_hevc *hevc = sess->priv; ++ struct device *dev = sess->core->dev; ++ int i; ++ ++ for (i = 0; i < 24; ++i) ++ if (hevc->fbc_buffer_vaddr[i]) { ++ dma_free_coherent(dev, amvdec_am21c_size(sess->width, sess->height), hevc->fbc_buffer_vaddr[i], hevc->fbc_buffer_paddr[i]); ++ hevc->fbc_buffer_vaddr[i] = NULL; ++ } ++} ++ ++static int codec_hevc_alloc_fbc_buffers(struct amvdec_session *sess) ++{ ++ struct codec_hevc *hevc = sess->priv; ++ struct device *dev = sess->core->dev; ++ struct v4l2_m2m_buffer *buf; ++ ++ v4l2_m2m_for_each_dst_buf(sess->m2m_ctx, buf) { ++ u32 idx = buf->vb.vb2_buf.index; ++ hevc->fbc_buffer_vaddr[idx] = dma_alloc_coherent(dev, amvdec_am21c_size(sess->width, sess->height), &hevc->fbc_buffer_paddr[idx], GFP_KERNEL); ++ if (!hevc->fbc_buffer_vaddr[idx]) { ++ dev_err(dev, "Couldn't allocate FBC buffer %u\n", idx); ++ codec_hevc_free_fbc_buffers(sess); ++ return -ENOMEM; ++ } ++ } ++ ++ return 0; ++} ++ ++static int codec_hevc_setup_buffers(struct amvdec_session *sess) ++{ ++ struct amvdec_core *core = sess->core; ++ int ret; ++ ++ if (codec_hevc_use_downsample(sess)) { ++ ret = codec_hevc_alloc_fbc_buffers(sess); ++ if (ret) ++ return ret; ++ } ++ ++ if (core->platform->revision == VDEC_REVISION_GXBB) ++ codec_hevc_setup_buffers_gxbb(sess); ++ else ++ codec_hevc_setup_buffers_gxl(sess); ++ ++ return 0; ++} ++ ++static int ++codec_hevc_setup_workspace(struct amvdec_core *core, struct codec_hevc *hevc) ++{ ++ dma_addr_t wkaddr; ++ ++ /* Allocate some memory for the HEVC decoder's state */ ++ hevc->workspace_vaddr = dma_alloc_coherent(core->dev, SIZE_WORKSPACE, &wkaddr, GFP_KERNEL); ++ if (!hevc->workspace_vaddr) { ++ dev_err(core->dev, "Failed to allocate HEVC Workspace\n"); ++ return -ENOMEM; ++ } ++ ++ hevc->workspace_paddr = wkaddr; ++ ++ amvdec_write_dos(core, HEVCD_IPP_LINEBUFF_BASE, wkaddr + IPP_OFFSET); ++ amvdec_write_dos(core, HEVC_RPM_BUFFER, wkaddr + RPM_OFFSET); ++ amvdec_write_dos(core, HEVC_SHORT_TERM_RPS, wkaddr + SH_TM_RPS_OFFSET); ++ amvdec_write_dos(core, HEVC_VPS_BUFFER, wkaddr + VPS_OFFSET); ++ amvdec_write_dos(core, HEVC_SPS_BUFFER, wkaddr + SPS_OFFSET); ++ amvdec_write_dos(core, HEVC_PPS_BUFFER, wkaddr + PPS_OFFSET); ++ amvdec_write_dos(core, HEVC_SAO_UP, wkaddr + SAO_UP_OFFSET); ++ ++ /* No MMU */ ++ amvdec_write_dos(core, HEVC_STREAM_SWAP_BUFFER, ++ wkaddr + SWAP_BUF_OFFSET); ++ amvdec_write_dos(core, HEVC_STREAM_SWAP_BUFFER2, ++ wkaddr + SWAP_BUF2_OFFSET); ++ amvdec_write_dos(core, HEVC_SCALELUT, wkaddr + SCALELUT_OFFSET); ++ amvdec_write_dos(core, HEVC_DBLK_CFG4, wkaddr + DBLK_PARA_OFFSET); ++ amvdec_write_dos(core, HEVC_DBLK_CFG5, wkaddr + DBLK_DATA_OFFSET); ++ ++ return 0; ++} ++ ++static int codec_hevc_start(struct amvdec_session *sess) ++{ ++ struct amvdec_core *core = sess->core; ++ struct codec_hevc *hevc; ++ int ret; ++ int i; ++ ++ hevc = kzalloc(sizeof(*hevc), GFP_KERNEL); ++ if (!hevc) ++ return -ENOMEM; ++ ++ INIT_LIST_HEAD(&hevc->ref_frames_list); ++ hevc->curr_poc = INVALID_POC; ++ ++ ret = codec_hevc_setup_workspace(core, hevc); ++ if (ret) ++ goto free_hevc; ++ ++ amvdec_write_dos(core, HEVC_PARSER_VERSION, 0x5a5a55aa); ++ amvdec_write_dos(core, DOS_SW_RESET3, BIT(14)); ++ amvdec_write_dos(core, HEVC_CABAC_CONTROL, 0); ++ amvdec_write_dos(core, HEVC_PARSER_CORE_CONTROL, 0); ++ amvdec_write_dos(core, HEVC_STREAM_CONTROL, amvdec_read_dos(core, HEVC_STREAM_CONTROL) | 1); ++ amvdec_write_dos(core, HEVC_SHIFT_STARTCODE, 0x00000100); ++ amvdec_write_dos(core, HEVC_SHIFT_EMULATECODE, 0x00000300); ++ writel_relaxed((amvdec_read_dos(core, HEVC_PARSER_INT_CONTROL) & 0x03ffffff) | ++ (3 << 29) | (2 << 26) | BIT(24) | BIT(22) | BIT(7) | BIT(4) | 1, core->dos_base + HEVC_PARSER_INT_CONTROL); ++ amvdec_write_dos(core, HEVC_SHIFT_STATUS, amvdec_read_dos(core, HEVC_SHIFT_STATUS) | BIT(1) | 1); ++ amvdec_write_dos(core, HEVC_SHIFT_CONTROL, (3 << 6) | (2 << 4) | (2 << 1) | 1); ++ amvdec_write_dos(core, HEVC_CABAC_CONTROL, 1); ++ amvdec_write_dos(core, HEVC_PARSER_CORE_CONTROL, 1); ++ amvdec_write_dos(core, HEVC_DEC_STATUS_REG, 0); ++ ++ amvdec_write_dos(core, HEVC_IQIT_SCALELUT_WR_ADDR, 0); ++ for (i = 0; i < 1024; ++i) ++ amvdec_write_dos(core, HEVC_IQIT_SCALELUT_DATA, 0); ++ ++ amvdec_write_dos(core, HEVC_DECODE_SIZE, 0); ++ ++ amvdec_write_dos(core, HEVC_PARSER_CMD_WRITE, BIT(16)); ++ for (i = 0; i < ARRAY_SIZE(parser_cmd); ++i) ++ amvdec_write_dos(core, HEVC_PARSER_CMD_WRITE, parser_cmd[i]); ++ ++ amvdec_write_dos(core, HEVC_PARSER_CMD_SKIP_0, PARSER_CMD_SKIP_CFG_0); ++ amvdec_write_dos(core, HEVC_PARSER_CMD_SKIP_1, PARSER_CMD_SKIP_CFG_1); ++ amvdec_write_dos(core, HEVC_PARSER_CMD_SKIP_2, PARSER_CMD_SKIP_CFG_2); ++ amvdec_write_dos(core, HEVC_PARSER_IF_CONTROL, BIT(5) | BIT(2) | 1); ++ ++ amvdec_write_dos(core, HEVCD_IPP_TOP_CNTL, 1); ++ amvdec_write_dos(core, HEVCD_IPP_TOP_CNTL, BIT(1)); ++ ++ amvdec_write_dos(core, HEVC_WAIT_FLAG, 1); ++ ++ /* clear mailbox interrupt */ ++ amvdec_write_dos(core, HEVC_ASSIST_MBOX1_CLR_REG, 1); ++ /* enable mailbox interrupt */ ++ amvdec_write_dos(core, HEVC_ASSIST_MBOX1_MASK, 1); ++ /* disable PSCALE for hardware sharing */ ++ amvdec_write_dos(core, HEVC_PSCALE_CTRL, 0); ++ /* Let the uCode do all the parsing */ ++ amvdec_write_dos(core, NAL_SEARCH_CTL, 0xc); ++ ++ amvdec_write_dos(core, DECODE_STOP_POS, 0); ++ amvdec_write_dos(core, HEVC_DECODE_MODE, DECODE_MODE_SINGLE); ++ amvdec_write_dos(core, HEVC_DECODE_MODE2, 0); ++ ++ /* AUX buffers */ ++ hevc->aux_vaddr = dma_alloc_coherent(core->dev, SIZE_AUX, &hevc->aux_paddr, GFP_KERNEL); ++ if (!hevc->aux_vaddr) { ++ dev_err(core->dev, "Failed to request HEVC AUX\n"); ++ ret = -ENOMEM; ++ goto free_hevc; ++ } ++ ++ amvdec_write_dos(core, HEVC_AUX_ADR, hevc->aux_paddr); ++ amvdec_write_dos(core, HEVC_AUX_DATA_SIZE, (((SIZE_AUX) >> 4) << 16) | 0); ++ mutex_init(&hevc->lock); ++ sess->priv = hevc; ++ ++ return 0; ++ ++free_hevc: ++ kfree(hevc); ++ return ret; ++} ++ ++static void codec_hevc_flush_output(struct amvdec_session *sess) ++{ ++ struct codec_hevc *hevc = sess->priv; ++ struct hevc_frame *tmp; ++ ++ while (!list_empty(&hevc->ref_frames_list)) { ++ tmp = codec_hevc_get_lowest_poc_frame(hevc); ++ amvdec_dst_buf_done(sess, tmp->vbuf, V4L2_FIELD_NONE); ++ list_del(&tmp->list); ++ kfree(tmp); ++ hevc->frames_num--; ++ } ++} ++ ++static int codec_hevc_stop(struct amvdec_session *sess) ++{ ++ struct codec_hevc *hevc = sess->priv; ++ struct amvdec_core *core = sess->core; ++ ++ mutex_lock(&hevc->lock); ++ codec_hevc_flush_output(sess); ++ ++ if (hevc->workspace_vaddr) ++ dma_free_coherent(core->dev, SIZE_WORKSPACE, ++ hevc->workspace_vaddr, ++ hevc->workspace_paddr); ++ ++ if (hevc->frame_mmu_vaddr) ++ dma_free_coherent(core->dev, SIZE_FRAME_MMU, ++ hevc->frame_mmu_vaddr, ++ hevc->frame_mmu_paddr); ++ ++ if (hevc->aux_vaddr) ++ dma_free_coherent(core->dev, SIZE_AUX, ++ hevc->aux_vaddr, hevc->aux_paddr); ++ ++ codec_hevc_free_fbc_buffers(sess); ++ mutex_unlock(&hevc->lock); ++ mutex_destroy(&hevc->lock); ++ ++ return 0; ++} ++ ++static void codec_hevc_update_tiles(struct amvdec_session *sess) ++{ ++ struct codec_hevc *hevc = sess->priv; ++ struct amvdec_core *core = sess->core; ++ u32 sao_mem_unit = (hevc->lcu_size == 16 ? 9 : hevc->lcu_size == 32 ? 14 : 24) << 4; ++ u32 pic_height_cu = (hevc->height + hevc->lcu_size - 1) / hevc->lcu_size; ++ u32 pic_width_cu = (hevc->width + hevc->lcu_size - 1) / hevc->lcu_size; ++ u32 sao_vb_size = (sao_mem_unit + (2 << 4)) * pic_height_cu; ++ u32 tiles_flags = hevc->rpm_param.p.tiles_flags; ++ ++ if (tiles_flags & 1) { ++ /* TODO; */ ++ dev_err(core->dev, "Bitstream uses tiles, NotImplemented!\n"); ++ return; ++ } ++ ++ hevc->num_tile_col = 1; ++ hevc->num_tile_row = 1; ++ hevc->m_tile[0][0].width = pic_width_cu; ++ hevc->m_tile[0][0].height = pic_height_cu; ++ hevc->m_tile[0][0].start_cu_x = 0; ++ hevc->m_tile[0][0].start_cu_y = 0; ++ hevc->m_tile[0][0].sao_vb_start_addr = hevc->workspace_paddr + SAO_VB_OFFSET; ++ hevc->m_tile[0][0].sao_abv_start_addr = hevc->workspace_paddr + SAO_ABV_OFFSET; ++ ++ hevc->tile_start_lcu_x = 0; ++ hevc->tile_start_lcu_y = 0; ++ hevc->tile_width_lcu = pic_width_cu; ++ hevc->tile_height_lcu = pic_height_cu; ++ ++ amvdec_write_dos(core, HEVC_sao_mem_unit, sao_mem_unit); ++ amvdec_write_dos(core, HEVC_SAO_ABV, hevc->workspace_paddr + SAO_ABV_OFFSET); ++ amvdec_write_dos(core, HEVC_sao_vb_size, sao_vb_size); ++ amvdec_write_dos(core, HEVC_SAO_VB, hevc->workspace_paddr + SAO_VB_OFFSET); ++} ++ ++static struct hevc_frame * codec_hevc_get_frame_by_poc(struct codec_hevc *hevc, u32 poc) ++{ ++ struct hevc_frame *tmp; ++ ++ list_for_each_entry(tmp, &hevc->ref_frames_list, list) { ++ if (tmp->poc == poc) ++ return tmp; ++ } ++ ++ return NULL; ++} ++ ++static struct hevc_frame * codec_hevc_prepare_new_frame(struct amvdec_session *sess) ++{ ++ struct vb2_v4l2_buffer *vbuf; ++ struct hevc_frame *new_frame = NULL; ++ struct codec_hevc *hevc = sess->priv; ++ union rpm_param *params = &hevc->rpm_param; ++ ++ new_frame = kzalloc(sizeof(*new_frame), GFP_KERNEL); ++ if (!new_frame) ++ return NULL; ++ ++ vbuf = v4l2_m2m_dst_buf_remove(sess->m2m_ctx); ++ if (!vbuf) { ++ dev_err(sess->core->dev, "No dst buffer available\n"); ++ return NULL; ++ } ++ ++ new_frame->vbuf = vbuf; ++ new_frame->referenced = 1; ++ new_frame->poc = hevc->curr_poc; ++ new_frame->cur_slice_type = params->p.slice_type; ++ new_frame->num_reorder_pic = params->p.sps_num_reorder_pics_0; ++ ++ list_add_tail(&new_frame->list, &hevc->ref_frames_list); ++ hevc->frames_num++; ++ ++ return new_frame; ++} ++ ++static void codec_hevc_set_sao(struct amvdec_session *sess, struct hevc_frame *frame) ++{ ++ struct amvdec_core *core = sess->core; ++ struct codec_hevc *hevc = sess->priv; ++ union rpm_param *param = &hevc->rpm_param; ++ dma_addr_t buf_y_paddr; ++ dma_addr_t buf_u_v_paddr; ++ u32 misc_flag0 = param->p.misc_flag0; ++ u32 slice_deblocking_filter_disabled_flag; ++ u32 val, val_2; ++ ++ val = (amvdec_read_dos(core, HEVC_SAO_CTRL0) & ~0xf) | ++ ilog2(hevc->lcu_size); ++ amvdec_write_dos(core, HEVC_SAO_CTRL0, val); ++ ++ amvdec_write_dos(core, HEVC_SAO_PIC_SIZE, ++ hevc->width | (hevc->height << 16)); ++ amvdec_write_dos(core, HEVC_SAO_PIC_SIZE_LCU, ++ (hevc->lcu_x_num - 1) | (hevc->lcu_y_num - 1) << 16); ++ ++ if (codec_hevc_use_downsample(sess)) ++ buf_y_paddr = ++ hevc->fbc_buffer_paddr[frame->vbuf->vb2_buf.index]; ++ else ++ buf_y_paddr = ++ vb2_dma_contig_plane_dma_addr(&frame->vbuf->vb2_buf, 0); ++ ++ if (codec_hevc_use_fbc(sess)) { ++ val = amvdec_read_dos(core, HEVC_SAO_CTRL5) & ~0xff0200; ++ amvdec_write_dos(core, HEVC_SAO_CTRL5, val); ++ amvdec_write_dos(core, HEVC_CM_BODY_START_ADDR, buf_y_paddr); ++ } ++ ++ if (sess->pixfmt_cap == V4L2_PIX_FMT_NV12M) { ++ buf_y_paddr = ++ vb2_dma_contig_plane_dma_addr(&frame->vbuf->vb2_buf, 0); ++ buf_u_v_paddr = ++ vb2_dma_contig_plane_dma_addr(&frame->vbuf->vb2_buf, 1); ++ amvdec_write_dos(core, HEVC_SAO_Y_START_ADDR, buf_y_paddr); ++ amvdec_write_dos(core, HEVC_SAO_C_START_ADDR, buf_u_v_paddr); ++ amvdec_write_dos(core, HEVC_SAO_Y_WPTR, buf_y_paddr); ++ amvdec_write_dos(core, HEVC_SAO_C_WPTR, buf_u_v_paddr); ++ } ++ ++ amvdec_write_dos(core, HEVC_SAO_Y_LENGTH, amvdec_get_output_size(sess)); ++ amvdec_write_dos(core, HEVC_SAO_C_LENGTH, ++ (amvdec_get_output_size(sess) / 2)); ++ ++ if (frame->cur_slice_idx == 0) { ++ amvdec_write_dos(core, HEVC_DBLK_CFG2, hevc->width | (hevc->height << 16)); ++ ++ val = 0; ++ if ((misc_flag0 >> PCM_ENABLE_FLAG_BIT) & 0x1) ++ val |= ((misc_flag0 >> PCM_LOOP_FILTER_DISABLED_FLAG_BIT) & 0x1) << 3; ++ ++ val |= (param->p.pps_cb_qp_offset & 0x1f) << 4; ++ val |= (param->p.pps_cr_qp_offset & 0x1f) << 9; ++ val |= (hevc->lcu_size == 64) ? 0 : ((hevc->lcu_size == 32) ? 1 : 2); ++ amvdec_write_dos(core, HEVC_DBLK_CFG1, val); ++ } ++ ++ val = amvdec_read_dos(core, HEVC_SAO_CTRL1) & ~0x3ff3; ++ val |= 0xff0; /* Set endianness for 2-bytes swaps (nv12) */ ++ if (!codec_hevc_use_fbc(sess)) ++ val |= BIT(0); /* disable cm compression */ ++ else if (sess->pixfmt_cap == V4L2_PIX_FMT_AM21C) ++ val |= BIT(1); /* Disable double write */ ++ ++ amvdec_write_dos(core, HEVC_SAO_CTRL1, val); ++ ++ if (!codec_hevc_use_fbc(sess)) { ++ /* no downscale for NV12 */ ++ val = amvdec_read_dos(core, HEVC_SAO_CTRL5) & ~0xff0000; ++ amvdec_write_dos(core, HEVC_SAO_CTRL5, val); ++ } ++ ++ val = amvdec_read_dos(core, HEVCD_IPP_AXIIF_CONFIG) & ~0x30; ++ val |= 0xf; ++ amvdec_write_dos(core, HEVCD_IPP_AXIIF_CONFIG, val); ++ ++ val = 0; ++ val_2 = amvdec_read_dos(core, HEVC_SAO_CTRL0); ++ val_2 &= (~0x300); ++ ++ /* TODO: handle tiles here if enabled */ ++ slice_deblocking_filter_disabled_flag = (misc_flag0 >> ++ SLICE_DEBLOCKING_FILTER_DISABLED_FLAG_BIT) & 0x1; ++ if ((misc_flag0 & (1 << DEBLOCKING_FILTER_OVERRIDE_ENABLED_FLAG_BIT)) ++ && (misc_flag0 & (1 << DEBLOCKING_FILTER_OVERRIDE_FLAG_BIT))) { ++ val |= slice_deblocking_filter_disabled_flag << 2; ++ ++ if (!slice_deblocking_filter_disabled_flag) { ++ val |= (param->p.slice_beta_offset_div2 & 0xf) << 3; ++ val |= (param->p.slice_tc_offset_div2 & 0xf) << 7; ++ } ++ } else { ++ val |= ++ ((misc_flag0 >> ++ PPS_DEBLOCKING_FILTER_DISABLED_FLAG_BIT) & 0x1) << 2; ++ ++ if (((misc_flag0 >> PPS_DEBLOCKING_FILTER_DISABLED_FLAG_BIT) & ++ 0x1) == 0) { ++ val |= (param->p.pps_beta_offset_div2 & 0xf) << 3; ++ val |= (param->p.pps_tc_offset_div2 & 0xf) << 7; ++ } ++ } ++ if ((misc_flag0 & (1 << PPS_LOOP_FILTER_ACROSS_SLICES_ENABLED_FLAG_BIT)) ++ && ((misc_flag0 & (1 << SLICE_SAO_LUMA_FLAG_BIT)) ++ || (misc_flag0 & (1 << SLICE_SAO_CHROMA_FLAG_BIT)) ++ || (!slice_deblocking_filter_disabled_flag))) { ++ val |= ++ ((misc_flag0 >> ++ SLICE_LOOP_FILTER_ACROSS_SLICES_ENABLED_FLAG_BIT) ++ & 0x1) << 1; ++ val_2 |= ++ ((misc_flag0 >> ++ SLICE_LOOP_FILTER_ACROSS_SLICES_ENABLED_FLAG_BIT) ++ & 0x1) << 9; ++ } else { ++ val |= ++ ((misc_flag0 >> ++ PPS_LOOP_FILTER_ACROSS_SLICES_ENABLED_FLAG_BIT) ++ & 0x1) << 1; ++ val_2 |= ++ ((misc_flag0 >> ++ PPS_LOOP_FILTER_ACROSS_SLICES_ENABLED_FLAG_BIT) ++ & 0x1) << 9; ++ } ++ ++ amvdec_write_dos(core, HEVC_DBLK_CFG9, val); ++ amvdec_write_dos(core, HEVC_SAO_CTRL0, val_2); ++} ++ ++static dma_addr_t codec_hevc_get_frame_mv_paddr(struct codec_hevc *hevc, struct hevc_frame *frame) ++{ ++ return hevc->workspace_paddr + MPRED_MV_OFFSET + ++ (frame->vbuf->vb2_buf.index * MPRED_MV_BUF_SIZE); ++} ++ ++/* Update the necessary information for motion prediction with the current slice */ ++static void codec_hevc_set_mpred(struct amvdec_session *sess, struct hevc_frame *frame, struct hevc_frame *col_frame) ++{ ++ struct amvdec_core *core = sess->core; ++ struct codec_hevc *hevc = sess->priv; ++ union rpm_param *param = &hevc->rpm_param; ++ u32 *ref_num = frame->ref_num; ++ u32 *ref_poc_l0 = frame->ref_poc_list[0][frame->cur_slice_idx]; ++ u32 *ref_poc_l1 = frame->ref_poc_list[1][frame->cur_slice_idx]; ++ u32 lcu_size_log2 = ilog2(hevc->lcu_size); ++ u32 mv_mem_unit = lcu_size_log2 == 6 ? 0x200 : lcu_size_log2 == 5 ? 0x80 : 0x20; ++ u32 slice_segment_address = param->p.slice_segment_address; ++ u32 max_num_merge_cand = 5 - param->p.five_minus_max_num_merge_cand; ++ u32 plevel = param->p.log2_parallel_merge_level; ++ u32 col_from_l0_flag = param->p.collocated_from_l0_flag; ++ u32 tmvp_flag = param->p.slice_temporal_mvp_enable_flag; ++ u32 is_next_slice_segment = param->p.dependent_slice_segment_flag ? 1 : 0; ++ u32 slice_type = param->p.slice_type; ++ dma_addr_t col_mv_rd_start_addr, col_mv_rd_ptr, col_mv_rd_end_addr; ++ dma_addr_t mpred_mv_wr_ptr; ++ u32 mv_rd_en = 1; ++ u32 val; ++ int i; ++ ++ val = amvdec_read_dos(core, HEVC_MPRED_CURR_LCU); ++ ++ col_mv_rd_start_addr = codec_hevc_get_frame_mv_paddr(hevc, col_frame); ++ mpred_mv_wr_ptr = codec_hevc_get_frame_mv_paddr(hevc, frame) + (hevc->slice_addr * mv_mem_unit); ++ col_mv_rd_ptr = col_mv_rd_start_addr + (hevc->slice_addr * mv_mem_unit); ++ col_mv_rd_end_addr = col_mv_rd_start_addr + ((hevc->lcu_x_num * hevc->lcu_y_num) * mv_mem_unit); ++ ++ amvdec_write_dos(core, HEVC_MPRED_MV_WR_START_ADDR, codec_hevc_get_frame_mv_paddr(hevc, frame)); ++ amvdec_write_dos(core, HEVC_MPRED_MV_RD_START_ADDR, col_mv_rd_start_addr); ++ ++ val = ((hevc->lcu_x_num - hevc->tile_width_lcu) * mv_mem_unit); ++ amvdec_write_dos(core, HEVC_MPRED_MV_WR_ROW_JUMP, val); ++ amvdec_write_dos(core, HEVC_MPRED_MV_RD_ROW_JUMP, val); ++ ++ if (slice_type == I_SLICE) ++ mv_rd_en = 0; ++ ++ val = slice_type | ++ BIT(3) | /* new tile */ ++ is_next_slice_segment << 4 | ++ tmvp_flag << 5 | ++ hevc->ldc_flag << 6 | ++ col_from_l0_flag << 7 | ++ BIT(9) | ++ BIT(10) | ++ mv_rd_en << 11 | ++ BIT(13) | ++ lcu_size_log2 << 16 | ++ 3 << 20 | plevel << 24; ++ ++ if (slice_segment_address == 0) ++ val |= BIT(2); /* new frame */ ++ ++ amvdec_write_dos(core, HEVC_MPRED_CTRL0, val); ++ ++ val = max_num_merge_cand | 2 << 4 | 3 << 8 | 5 << 12 | 36 << 16; ++ amvdec_write_dos(core, HEVC_MPRED_CTRL1, val); ++ ++ amvdec_write_dos(core, HEVC_MPRED_PIC_SIZE, hevc->width | (hevc->height << 16)); ++ ++ val = ((hevc->lcu_x_num - 1) | (hevc->lcu_y_num - 1) << 16); ++ amvdec_write_dos(core, HEVC_MPRED_PIC_SIZE_LCU, val); ++ val = (hevc->tile_start_lcu_x | hevc->tile_start_lcu_y << 16); ++ amvdec_write_dos(core, HEVC_MPRED_TILE_START, val); ++ val = (hevc->tile_width_lcu | hevc->tile_height_lcu << 16); ++ amvdec_write_dos(core, HEVC_MPRED_TILE_SIZE_LCU, val); ++ ++ amvdec_write_dos(core, HEVC_MPRED_REF_NUM, (ref_num[1] << 8) | ref_num[0]); ++ amvdec_write_dos(core, HEVC_MPRED_REF_EN_L0, (1 << ref_num[0]) - 1); ++ amvdec_write_dos(core, HEVC_MPRED_REF_EN_L1, (1 << ref_num[1]) - 1); ++ ++ amvdec_write_dos(core, HEVC_MPRED_CUR_POC, hevc->curr_poc); ++ amvdec_write_dos(core, HEVC_MPRED_COL_POC, hevc->col_poc); ++ ++ for (i = 0; i < MAX_REF_ACTIVE; ++i) { ++ amvdec_write_dos(core, HEVC_MPRED_L0_REF00_POC + i * 4, ref_poc_l0[i]); ++ amvdec_write_dos(core, HEVC_MPRED_L1_REF00_POC + i * 4, ref_poc_l1[i]); ++ } ++ ++ if (slice_segment_address == 0) { ++ amvdec_write_dos(core, HEVC_MPRED_ABV_START_ADDR, ++ hevc->workspace_paddr + MPRED_ABV_OFFSET); ++ amvdec_write_dos(core, HEVC_MPRED_MV_WPTR, mpred_mv_wr_ptr); ++ amvdec_write_dos(core, HEVC_MPRED_MV_RPTR, col_mv_rd_start_addr); ++ } else { ++ amvdec_write_dos(core, HEVC_MPRED_MV_RPTR, col_mv_rd_ptr); ++ } ++ ++ amvdec_write_dos(core, HEVC_MPRED_MV_RD_END_ADDR, col_mv_rd_end_addr); ++} ++ ++/* motion compensation reference cache controller */ ++static void codec_hevc_set_mcrcc(struct amvdec_session *sess) ++{ ++ struct amvdec_core *core = sess->core; ++ struct codec_hevc *hevc = sess->priv; ++ u32 val, val_2; ++ int l0_cnt = 0; ++ int l1_cnt = 0x7fff; ++ ++ if (!codec_hevc_use_fbc(sess)) { ++ l0_cnt = hevc->cur_frame->ref_num[0]; ++ l1_cnt = hevc->cur_frame->ref_num[1]; ++ } ++ ++ /* reset mcrcc */ ++ amvdec_write_dos(core, HEVCD_MCRCC_CTL1, 0x02); ++ ++ if (hevc->cur_frame->cur_slice_type == I_SLICE) { ++ /* remove reset -- disables clock */ ++ amvdec_write_dos(core, HEVCD_MCRCC_CTL1, 0); ++ return; ++ } ++ ++ if (hevc->cur_frame->cur_slice_type == P_SLICE) { ++ amvdec_write_dos(core, HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, BIT(1)); ++ val = amvdec_read_dos(core, HEVCD_MPP_ANC_CANVAS_DATA_ADDR); ++ val &= 0xffff; ++ val |= (val << 16); ++ amvdec_write_dos(core, HEVCD_MCRCC_CTL2, val); ++ ++ if (l0_cnt == 1) { ++ amvdec_write_dos(core, HEVCD_MCRCC_CTL3, val); ++ } else { ++ val = amvdec_read_dos(core, HEVCD_MPP_ANC_CANVAS_DATA_ADDR); ++ val &= 0xffff; ++ val |= (val << 16); ++ amvdec_write_dos(core, HEVCD_MCRCC_CTL3, val); ++ } ++ } else { /* B_SLICE */ ++ amvdec_write_dos(core, HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, 0); ++ val = amvdec_read_dos(core, HEVCD_MPP_ANC_CANVAS_DATA_ADDR); ++ val &= 0xffff; ++ val |= (val << 16); ++ amvdec_write_dos(core, HEVCD_MCRCC_CTL2, val); ++ ++ amvdec_write_dos(core, HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, (16 << 8) | BIT(1)); ++ val_2 = amvdec_read_dos(core, HEVCD_MPP_ANC_CANVAS_DATA_ADDR); ++ val_2 &= 0xffff; ++ val_2 |= (val_2 << 16); ++ if (val == val_2 && l1_cnt > 1) { ++ val_2 = amvdec_read_dos(core, HEVCD_MPP_ANC_CANVAS_DATA_ADDR); ++ val_2 &= 0xffff; ++ val_2 |= (val_2 << 16); ++ } ++ amvdec_write_dos(core, HEVCD_MCRCC_CTL3, val); ++ } ++ ++ /* enable mcrcc progressive-mode */ ++ amvdec_write_dos(core, HEVCD_MCRCC_CTL1, 0xff0); ++} ++ ++static void codec_hevc_set_ref_list(struct amvdec_session *sess, ++ u32 ref_num, u32 *ref_poc_list) ++{ ++ struct codec_hevc *hevc = sess->priv; ++ struct hevc_frame *ref_frame; ++ struct amvdec_core *core = sess->core; ++ int i; ++ u32 buf_id_y; ++ u32 buf_id_uv; ++ ++ for (i = 0; i < ref_num; i++) { ++ ref_frame = codec_hevc_get_frame_by_poc(hevc, ref_poc_list[i]); ++ ++ if (!ref_frame) { ++ dev_warn(core->dev, "Couldn't find ref. frame %u\n", ++ ref_poc_list[i]); ++ continue; ++ } ++ ++ if (codec_hevc_use_fbc(sess)) { ++ buf_id_y = buf_id_uv = ref_frame->vbuf->vb2_buf.index; ++ } else { ++ buf_id_y = ref_frame->vbuf->vb2_buf.index * 2; ++ buf_id_uv = buf_id_y + 1; ++ } ++ ++ writel_relaxed((buf_id_uv << 16) | ++ (buf_id_uv << 8) | ++ buf_id_y, ++ core->dos_base + HEVCD_MPP_ANC_CANVAS_DATA_ADDR); ++ } ++} ++ ++static void codec_hevc_set_mc(struct amvdec_session *sess, struct hevc_frame *frame) ++{ ++ struct amvdec_core *core = sess->core; ++ ++ if (frame->cur_slice_type == I_SLICE) ++ return; ++ ++ amvdec_write_dos(core, HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, 1); ++ codec_hevc_set_ref_list(sess, frame->ref_num[0], ++ frame->ref_poc_list[0][frame->cur_slice_idx]); ++ ++ if (frame->cur_slice_type == P_SLICE) ++ return; ++ ++ amvdec_write_dos(core, HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, (16 << 8) | 1); ++ codec_hevc_set_ref_list(sess, frame->ref_num[1], ++ frame->ref_poc_list[1][frame->cur_slice_idx]); ++} ++ ++static void codec_hevc_update_col_frame(struct codec_hevc *hevc) ++{ ++ struct hevc_frame *cur_frame = hevc->cur_frame; ++ union rpm_param *param = &hevc->rpm_param; ++ u32 list_no = 0; ++ u32 col_ref = param->p.collocated_ref_idx; ++ u32 col_from_l0 = param->p.collocated_from_l0_flag; ++ ++ if (cur_frame->cur_slice_type == B_SLICE) ++ list_no = 1 - col_from_l0; ++ ++ if (col_ref >= cur_frame->ref_num[list_no]) ++ hevc->col_poc = INVALID_POC; ++ else ++ hevc->col_poc = cur_frame->ref_poc_list[list_no][cur_frame->cur_slice_idx][col_ref]; ++ ++ if (cur_frame->cur_slice_type == I_SLICE) ++ goto end; ++ ++ if (hevc->col_poc != INVALID_POC) ++ hevc->col_frame = codec_hevc_get_frame_by_poc(hevc, hevc->col_poc); ++ else ++ hevc->col_frame = hevc->cur_frame; ++ ++end: ++ if (!hevc->col_frame) ++ hevc->col_frame = hevc->cur_frame; ++} ++ ++static void codec_hevc_update_pocs(struct amvdec_session *sess) ++{ ++ struct codec_hevc *hevc = sess->priv; ++ union rpm_param *param = &hevc->rpm_param; ++ u32 nal_unit_type = param->p.m_nalUnitType; ++ u32 temporal_id = param->p.m_temporalId & 0x7; ++ int max_poc_lsb = 1 << (param->p.log2_max_pic_order_cnt_lsb_minus4 + 4); ++ int prev_poc_lsb; ++ int prev_poc_msb; ++ int poc_msb; ++ int poc_lsb = param->p.POClsb; ++ ++ if (nal_unit_type == NAL_UNIT_CODED_SLICE_IDR || ++ nal_unit_type == NAL_UNIT_CODED_SLICE_IDR_N_LP) { ++ hevc->curr_poc = 0; ++ if ((temporal_id - 1) == 0) ++ hevc->iPrevTid0POC = hevc->curr_poc; ++ ++ return; ++ } ++ ++ prev_poc_lsb = hevc->iPrevTid0POC % max_poc_lsb; ++ prev_poc_msb = hevc->iPrevTid0POC - prev_poc_lsb; ++ ++ if ((poc_lsb < prev_poc_lsb) && ((prev_poc_lsb - poc_lsb) >= (max_poc_lsb / 2))) ++ poc_msb = prev_poc_msb + max_poc_lsb; ++ else if ((poc_lsb > prev_poc_lsb) && ((poc_lsb - prev_poc_lsb) > (max_poc_lsb / 2))) ++ poc_msb = prev_poc_msb - max_poc_lsb; ++ else ++ poc_msb = prev_poc_msb; ++ ++ if (nal_unit_type == NAL_UNIT_CODED_SLICE_BLA || ++ nal_unit_type == NAL_UNIT_CODED_SLICE_BLANT || ++ nal_unit_type == NAL_UNIT_CODED_SLICE_BLA_N_LP) ++ poc_msb = 0; ++ ++ hevc->curr_poc = (poc_msb + poc_lsb); ++ if ((temporal_id - 1) == 0) ++ hevc->iPrevTid0POC = hevc->curr_poc; ++} ++ ++static void codec_hevc_process_segment_header(struct amvdec_session *sess) ++{ ++ struct codec_hevc *hevc = sess->priv; ++ union rpm_param *param = &hevc->rpm_param; ++ ++ if (param->p.first_slice_segment_in_pic_flag == 0) { ++ hevc->slice_segment_addr = param->p.slice_segment_address; ++ if (!param->p.dependent_slice_segment_flag) ++ hevc->slice_addr = hevc->slice_segment_addr; ++ } else { ++ hevc->slice_segment_addr = 0; ++ hevc->slice_addr = 0; ++ } ++ ++ codec_hevc_update_pocs(sess); ++} ++ ++static int codec_hevc_process_segment(struct amvdec_session *sess) ++{ ++ struct codec_hevc *hevc = sess->priv; ++ struct amvdec_core *core = sess->core; ++ union rpm_param *param = &hevc->rpm_param; ++ u32 slice_segment_address = param->p.slice_segment_address; ++ ++ /* First slice: new frame */ ++ if (slice_segment_address == 0) { ++ codec_hevc_update_referenced(hevc); ++ codec_hevc_output_frames(sess); ++ ++ hevc->cur_frame = codec_hevc_prepare_new_frame(sess); ++ if (!hevc->cur_frame) ++ return -1; ++ ++ codec_hevc_update_tiles(sess); ++ } else { ++ hevc->cur_frame->cur_slice_idx++; ++ } ++ ++ codec_hevc_update_frame_refs(sess, hevc->cur_frame); ++ codec_hevc_update_col_frame(hevc); ++ codec_hevc_update_ldc_flag(hevc); ++ codec_hevc_set_mc(sess, hevc->cur_frame); ++ codec_hevc_set_mcrcc(sess); ++ codec_hevc_set_mpred(sess, hevc->cur_frame, hevc->col_frame); ++ codec_hevc_set_sao(sess, hevc->cur_frame); ++ ++ amvdec_write_dos(core, HEVC_WAIT_FLAG, amvdec_read_dos(core, HEVC_WAIT_FLAG) | 2); ++ amvdec_write_dos(core, HEVC_DEC_STATUS_REG, HEVC_CODED_SLICE_SEGMENT_DAT); ++ ++ /* Interrupt the firmware's processor */ ++ amvdec_write_dos(core, HEVC_MCPU_INTR_REQ, AMRISC_MAIN_REQ); ++ ++ return 0; ++} ++ ++static int codec_hevc_process_rpm(struct amvdec_session *sess) ++{ ++ struct amvdec_core *core = sess->core; ++ struct codec_hevc *hevc = sess->priv; ++ union rpm_param *rpm_param = &hevc->rpm_param; ++ u32 lcu_x_num_div, lcu_y_num_div; ++ ++ if (rpm_param->p.bit_depth) ++ hevc->is_10bit = 1; ++ ++ hevc->width = rpm_param->p.pic_width_in_luma_samples; ++ hevc->height = rpm_param->p.pic_height_in_luma_samples; ++ ++ /*if (hevc->width != sess->width || ++ hevc->height != sess->height) { ++ dev_err(sess->core->dev_dec, ++ "Size mismatch: bitstream %ux%u ; driver %ux%u\n", ++ hevc->width, hevc->height, ++ sess->width, sess->height); ++ return -EINVAL; ++ }*/ ++ ++ hevc->lcu_size = 1 << (rpm_param->p.log2_min_coding_block_size_minus3 + ++ 3 + rpm_param->p.log2_diff_max_min_coding_block_size); ++ ++ lcu_x_num_div = (hevc->width / hevc->lcu_size); ++ lcu_y_num_div = (hevc->height / hevc->lcu_size); ++ hevc->lcu_x_num = ((hevc->width % hevc->lcu_size) == 0) ? lcu_x_num_div : lcu_x_num_div + 1; ++ hevc->lcu_y_num = ((hevc->height % hevc->lcu_size) == 0) ? lcu_y_num_div : lcu_y_num_div + 1; ++ hevc->lcu_total = hevc->lcu_x_num * hevc->lcu_y_num; ++ ++ dev_dbg(core->dev, "lcu_size = %u ; lcu_x_num = %u; lcu_y_num = %u", ++ hevc->lcu_size, hevc->lcu_x_num, hevc->lcu_y_num); ++ ++ return 0; ++} ++ ++/* The RPM section within the workspace contains ++ * many information regarding the parsed bitstream ++ */ ++static void codec_hevc_fetch_rpm(struct amvdec_session *sess) ++{ ++ struct codec_hevc *hevc = sess->priv; ++ u16 *rpm_vaddr = hevc->workspace_vaddr + RPM_OFFSET; ++ int i, j; ++ ++ for (i = 0; i < RPM_SIZE; i += 4) ++ for (j = 0; j < 4; j++) ++ hevc->rpm_param.l.data[i + j] = rpm_vaddr[i + 3 - j]; ++} ++ ++static irqreturn_t codec_hevc_threaded_isr(struct amvdec_session *sess) ++{ ++ struct amvdec_core *core = sess->core; ++ struct codec_hevc *hevc; ++ ++ hevc = sess->priv; ++ if (!hevc) ++ return IRQ_HANDLED; ++ ++ mutex_lock(&hevc->lock); ++ if (hevc->dec_status != HEVC_SLICE_SEGMENT_DONE) { ++ dev_err(core->dev_dec, "Unrecognized dec_status: %08X\n", ++ hevc->dec_status); ++ amvdec_abort(sess); ++ goto unlock; ++ } ++ ++ sess->keyframe_found = 1; ++ codec_hevc_fetch_rpm(sess); ++ if (codec_hevc_process_rpm(sess)) { ++ amvdec_abort(sess); ++ goto unlock; ++ } ++ ++ if (!hevc->is_buflist_init) { ++ if (codec_hevc_setup_buffers(sess)) { ++ amvdec_abort(sess); ++ goto unlock; ++ } ++ ++ codec_hevc_setup_decode_head(sess); ++ hevc->is_buflist_init = 1; ++ } ++ ++ codec_hevc_process_segment_header(sess); ++ if (codec_hevc_process_segment(sess)) ++ amvdec_abort(sess); ++ ++unlock: ++ mutex_unlock(&hevc->lock); ++ return IRQ_HANDLED; ++} ++ ++static irqreturn_t codec_hevc_isr(struct amvdec_session *sess) ++{ ++ struct amvdec_core *core = sess->core; ++ struct codec_hevc *hevc = sess->priv; ++ ++ hevc->dec_status = amvdec_read_dos(core, HEVC_DEC_STATUS_REG); ++ ++ return IRQ_WAKE_THREAD; ++} ++ ++struct amvdec_codec_ops codec_hevc_ops = { ++ .start = codec_hevc_start, ++ .stop = codec_hevc_stop, ++ .isr = codec_hevc_isr, ++ .threaded_isr = codec_hevc_threaded_isr, ++ .num_pending_bufs = codec_hevc_num_pending_bufs, ++ .drain = codec_hevc_flush_output, ++}; +diff --git a/drivers/media/platform/meson/vdec/codec_hevc.h b/drivers/media/platform/meson/vdec/codec_hevc.h +new file mode 100644 +index 0000000000000..5017e874e3ddc +--- /dev/null ++++ b/drivers/media/platform/meson/vdec/codec_hevc.h +@@ -0,0 +1,13 @@ ++/* SPDX-License-Identifier: GPL-2.0+ */ ++/* ++ * Copyright (C) 2018 Maxime Jourdan ++ */ ++ ++#ifndef __MESON_VDEC_CODEC_HEVC_H_ ++#define __MESON_VDEC_CODEC_HEVC_H_ ++ ++#include "vdec.h" ++ ++extern struct amvdec_codec_ops codec_hevc_ops; ++ ++#endif +\ No newline at end of file +diff --git a/drivers/media/platform/meson/vdec/hevc_regs.h b/drivers/media/platform/meson/vdec/hevc_regs.h +new file mode 100644 +index 0000000000000..ae9b38e463f7e +--- /dev/null ++++ b/drivers/media/platform/meson/vdec/hevc_regs.h +@@ -0,0 +1,742 @@ ++/* SPDX-License-Identifier: GPL-2.0+ */ ++/* ++ * Copyright (C) 2015 Amlogic, Inc. All rights reserved. ++ */ ++ ++#ifndef HEVC_REGS_HEADERS__ ++#define HEVC_REGS_HEADERS__ ++/*add from M8M2*/ ++#define HEVC_ASSIST_AFIFO_CTRL (0x3001 * 4) ++#define HEVC_ASSIST_AFIFO_CTRL1 (0x3002 * 4) ++#define HEVC_ASSIST_GCLK_EN (0x3003 * 4) ++#define HEVC_ASSIST_SW_RESET (0x3004 * 4) ++#define HEVC_ASSIST_AMR1_INT0 (0x3025 * 4) ++#define HEVC_ASSIST_AMR1_INT1 (0x3026 * 4) ++#define HEVC_ASSIST_AMR1_INT2 (0x3027 * 4) ++#define HEVC_ASSIST_AMR1_INT3 (0x3028 * 4) ++#define HEVC_ASSIST_AMR1_INT4 (0x3029 * 4) ++#define HEVC_ASSIST_AMR1_INT5 (0x302a * 4) ++#define HEVC_ASSIST_AMR1_INT6 (0x302b * 4) ++#define HEVC_ASSIST_AMR1_INT7 (0x302c * 4) ++#define HEVC_ASSIST_AMR1_INT8 (0x302d * 4) ++#define HEVC_ASSIST_AMR1_INT9 (0x302e * 4) ++#define HEVC_ASSIST_AMR1_INTA (0x302f * 4) ++#define HEVC_ASSIST_AMR1_INTB (0x3030 * 4) ++#define HEVC_ASSIST_AMR1_INTC (0x3031 * 4) ++#define HEVC_ASSIST_AMR1_INTD (0x3032 * 4) ++#define HEVC_ASSIST_AMR1_INTE (0x3033 * 4) ++#define HEVC_ASSIST_AMR1_INTF (0x3034 * 4) ++#define HEVC_ASSIST_AMR2_INT0 (0x3035 * 4) ++#define HEVC_ASSIST_AMR2_INT1 (0x3036 * 4) ++#define HEVC_ASSIST_AMR2_INT2 (0x3037 * 4) ++#define HEVC_ASSIST_AMR2_INT3 (0x3038 * 4) ++#define HEVC_ASSIST_AMR2_INT4 (0x3039 * 4) ++#define HEVC_ASSIST_AMR2_INT5 (0x303a * 4) ++#define HEVC_ASSIST_AMR2_INT6 (0x303b * 4) ++#define HEVC_ASSIST_AMR2_INT7 (0x303c * 4) ++#define HEVC_ASSIST_AMR2_INT8 (0x303d * 4) ++#define HEVC_ASSIST_AMR2_INT9 (0x303e * 4) ++#define HEVC_ASSIST_AMR2_INTA (0x303f * 4) ++#define HEVC_ASSIST_AMR2_INTB (0x3040 * 4) ++#define HEVC_ASSIST_AMR2_INTC (0x3041 * 4) ++#define HEVC_ASSIST_AMR2_INTD (0x3042 * 4) ++#define HEVC_ASSIST_AMR2_INTE (0x3043 * 4) ++#define HEVC_ASSIST_AMR2_INTF (0x3044 * 4) ++#define HEVC_ASSIST_MBX_SSEL (0x3045 * 4) ++#define HEVC_ASSIST_TIMER0_LO (0x3060 * 4) ++#define HEVC_ASSIST_TIMER0_HI (0x3061 * 4) ++#define HEVC_ASSIST_TIMER1_LO (0x3062 * 4) ++#define HEVC_ASSIST_TIMER1_HI (0x3063 * 4) ++#define HEVC_ASSIST_DMA_INT (0x3064 * 4) ++#define HEVC_ASSIST_DMA_INT_MSK (0x3065 * 4) ++#define HEVC_ASSIST_DMA_INT2 (0x3066 * 4) ++#define HEVC_ASSIST_DMA_INT_MSK2 (0x3067 * 4) ++#define HEVC_ASSIST_MBOX0_IRQ_REG (0x3070 * 4) ++#define HEVC_ASSIST_MBOX0_CLR_REG (0x3071 * 4) ++#define HEVC_ASSIST_MBOX0_MASK (0x3072 * 4) ++#define HEVC_ASSIST_MBOX0_FIQ_SEL (0x3073 * 4) ++#define HEVC_ASSIST_MBOX1_IRQ_REG (0x3074 * 4) ++#define HEVC_ASSIST_MBOX1_CLR_REG (0x3075 * 4) ++#define HEVC_ASSIST_MBOX1_MASK (0x3076 * 4) ++#define HEVC_ASSIST_MBOX1_FIQ_SEL (0x3077 * 4) ++#define HEVC_ASSIST_MBOX2_IRQ_REG (0x3078 * 4) ++#define HEVC_ASSIST_MBOX2_CLR_REG (0x3079 * 4) ++#define HEVC_ASSIST_MBOX2_MASK (0x307a * 4) ++#define HEVC_ASSIST_MBOX2_FIQ_SEL (0x307b * 4) ++#define HEVC_ASSIST_AXI_CTRL (0x307c * 4) ++#define HEVC_ASSIST_AXI_STATUS (0x307d * 4) ++#define HEVC_ASSIST_SCRATCH_0 (0x30c0 * 4) ++#define HEVC_ASSIST_SCRATCH_1 (0x30c1 * 4) ++#define HEVC_ASSIST_SCRATCH_2 (0x30c2 * 4) ++#define HEVC_ASSIST_SCRATCH_3 (0x30c3 * 4) ++#define HEVC_ASSIST_SCRATCH_4 (0x30c4 * 4) ++#define HEVC_ASSIST_SCRATCH_5 (0x30c5 * 4) ++#define HEVC_ASSIST_SCRATCH_6 (0x30c6 * 4) ++#define HEVC_ASSIST_SCRATCH_7 (0x30c7 * 4) ++#define HEVC_ASSIST_SCRATCH_8 (0x30c8 * 4) ++#define HEVC_ASSIST_SCRATCH_9 (0x30c9 * 4) ++#define HEVC_ASSIST_SCRATCH_A (0x30ca * 4) ++#define HEVC_ASSIST_SCRATCH_B (0x30cb * 4) ++#define HEVC_ASSIST_SCRATCH_C (0x30cc * 4) ++#define HEVC_ASSIST_SCRATCH_D (0x30cd * 4) ++#define HEVC_ASSIST_SCRATCH_E (0x30ce * 4) ++#define HEVC_ASSIST_SCRATCH_F (0x30cf * 4) ++#define HEVC_ASSIST_SCRATCH_G (0x30d0 * 4) ++#define HEVC_ASSIST_SCRATCH_H (0x30d1 * 4) ++#define HEVC_ASSIST_SCRATCH_I (0x30d2 * 4) ++#define HEVC_ASSIST_SCRATCH_J (0x30d3 * 4) ++#define HEVC_ASSIST_SCRATCH_K (0x30d4 * 4) ++#define HEVC_ASSIST_SCRATCH_L (0x30d5 * 4) ++#define HEVC_ASSIST_SCRATCH_M (0x30d6 * 4) ++#define HEVC_ASSIST_SCRATCH_N (0x30d7 * 4) ++#define HEVC_PARSER_VERSION (0x3100 * 4) ++#define HEVC_STREAM_CONTROL (0x3101 * 4) ++#define HEVC_STREAM_START_ADDR (0x3102 * 4) ++#define HEVC_STREAM_END_ADDR (0x3103 * 4) ++#define HEVC_STREAM_WR_PTR (0x3104 * 4) ++#define HEVC_STREAM_RD_PTR (0x3105 * 4) ++#define HEVC_STREAM_LEVEL (0x3106 * 4) ++#define HEVC_STREAM_FIFO_CTL (0x3107 * 4) ++#define HEVC_SHIFT_CONTROL (0x3108 * 4) ++#define HEVC_SHIFT_STARTCODE (0x3109 * 4) ++#define HEVC_SHIFT_EMULATECODE (0x310a * 4) ++#define HEVC_SHIFT_STATUS (0x310b * 4) ++#define HEVC_SHIFTED_DATA (0x310c * 4) ++#define HEVC_SHIFT_BYTE_COUNT (0x310d * 4) ++#define HEVC_SHIFT_COMMAND (0x310e * 4) ++#define HEVC_ELEMENT_RESULT (0x310f * 4) ++#define HEVC_CABAC_CONTROL (0x3110 * 4) ++#define HEVC_PARSER_SLICE_INFO (0x3111 * 4) ++#define HEVC_PARSER_CMD_WRITE (0x3112 * 4) ++#define HEVC_PARSER_CORE_CONTROL (0x3113 * 4) ++#define HEVC_PARSER_CMD_FETCH (0x3114 * 4) ++#define HEVC_PARSER_CMD_STATUS (0x3115 * 4) ++#define HEVC_PARSER_LCU_INFO (0x3116 * 4) ++#define HEVC_PARSER_HEADER_INFO (0x3117 * 4) ++#define HEVC_PARSER_RESULT_0 (0x3118 * 4) ++#define HEVC_PARSER_RESULT_1 (0x3119 * 4) ++#define HEVC_PARSER_RESULT_2 (0x311a * 4) ++#define HEVC_PARSER_RESULT_3 (0x311b * 4) ++#define HEVC_CABAC_TOP_INFO (0x311c * 4) ++#define HEVC_CABAC_TOP_INFO_2 (0x311d * 4) ++#define HEVC_CABAC_LEFT_INFO (0x311e * 4) ++#define HEVC_CABAC_LEFT_INFO_2 (0x311f * 4) ++#define HEVC_PARSER_INT_CONTROL (0x3120 * 4) ++#define HEVC_PARSER_INT_STATUS (0x3121 * 4) ++#define HEVC_PARSER_IF_CONTROL (0x3122 * 4) ++#define HEVC_PARSER_PICTURE_SIZE (0x3123 * 4) ++#define HEVC_PARSER_LCU_START (0x3124 * 4) ++#define HEVC_PARSER_HEADER_INFO2 (0x3125 * 4) ++#define HEVC_PARSER_QUANT_READ (0x3126 * 4) ++#define HEVC_PARSER_RESERVED_27 (0x3127 * 4) ++#define HEVC_PARSER_CMD_SKIP_0 (0x3128 * 4) ++#define HEVC_PARSER_CMD_SKIP_1 (0x3129 * 4) ++#define HEVC_PARSER_CMD_SKIP_2 (0x312a * 4) ++#define HEVC_PARSER_MANUAL_CMD (0x312b * 4) ++#define HEVC_PARSER_MEM_RD_ADDR (0x312c * 4) ++#define HEVC_PARSER_MEM_WR_ADDR (0x312d * 4) ++#define HEVC_PARSER_MEM_RW_DATA (0x312e * 4) ++#define HEVC_SAO_IF_STATUS (0x3130 * 4) ++#define HEVC_SAO_IF_DATA_Y (0x3131 * 4) ++#define HEVC_SAO_IF_DATA_U (0x3132 * 4) ++#define HEVC_SAO_IF_DATA_V (0x3133 * 4) ++#define HEVC_STREAM_SWAP_ADDR (0x3134 * 4) ++#define HEVC_STREAM_SWAP_CTRL (0x3135 * 4) ++#define HEVC_IQIT_IF_WAIT_CNT (0x3136 * 4) ++#define HEVC_MPRED_IF_WAIT_CNT (0x3137 * 4) ++#define HEVC_SAO_IF_WAIT_CNT (0x3138 * 4) ++#define HEVC_PARSER_DEBUG_IDX (0x313e * 4) ++#define HEVC_PARSER_DEBUG_DAT (0x313f * 4) ++#define HEVC_MPRED_VERSION (0x3200 * 4) ++#define HEVC_MPRED_CTRL0 (0x3201 * 4) ++#define HEVC_MPRED_CTRL1 (0x3202 * 4) ++#define HEVC_MPRED_INT_EN (0x3203 * 4) ++#define HEVC_MPRED_INT_STATUS (0x3204 * 4) ++#define HEVC_MPRED_PIC_SIZE (0x3205 * 4) ++#define HEVC_MPRED_PIC_SIZE_LCU (0x3206 * 4) ++#define HEVC_MPRED_TILE_START (0x3207 * 4) ++#define HEVC_MPRED_TILE_SIZE_LCU (0x3208 * 4) ++#define HEVC_MPRED_REF_NUM (0x3209 * 4) ++#define HEVC_MPRED_LT_REF (0x320a * 4) ++#define HEVC_MPRED_LT_COLREF (0x320b * 4) ++#define HEVC_MPRED_REF_EN_L0 (0x320c * 4) ++#define HEVC_MPRED_REF_EN_L1 (0x320d * 4) ++#define HEVC_MPRED_COLREF_EN_L0 (0x320e * 4) ++#define HEVC_MPRED_COLREF_EN_L1 (0x320f * 4) ++#define HEVC_MPRED_AXI_WCTRL (0x3210 * 4) ++#define HEVC_MPRED_AXI_RCTRL (0x3211 * 4) ++#define HEVC_MPRED_ABV_START_ADDR (0x3212 * 4) ++#define HEVC_MPRED_MV_WR_START_ADDR (0x3213 * 4) ++#define HEVC_MPRED_MV_RD_START_ADDR (0x3214 * 4) ++#define HEVC_MPRED_MV_WPTR (0x3215 * 4) ++#define HEVC_MPRED_MV_RPTR (0x3216 * 4) ++#define HEVC_MPRED_MV_WR_ROW_JUMP (0x3217 * 4) ++#define HEVC_MPRED_MV_RD_ROW_JUMP (0x3218 * 4) ++#define HEVC_MPRED_CURR_LCU (0x3219 * 4) ++#define HEVC_MPRED_ABV_WPTR (0x321a * 4) ++#define HEVC_MPRED_ABV_RPTR (0x321b * 4) ++#define HEVC_MPRED_CTRL2 (0x321c * 4) ++#define HEVC_MPRED_CTRL3 (0x321d * 4) ++#define HEVC_MPRED_MV_WLCUY (0x321e * 4) ++#define HEVC_MPRED_MV_RLCUY (0x321f * 4) ++#define HEVC_MPRED_L0_REF00_POC (0x3220 * 4) ++#define HEVC_MPRED_L0_REF01_POC (0x3221 * 4) ++#define HEVC_MPRED_L0_REF02_POC (0x3222 * 4) ++#define HEVC_MPRED_L0_REF03_POC (0x3223 * 4) ++#define HEVC_MPRED_L0_REF04_POC (0x3224 * 4) ++#define HEVC_MPRED_L0_REF05_POC (0x3225 * 4) ++#define HEVC_MPRED_L0_REF06_POC (0x3226 * 4) ++#define HEVC_MPRED_L0_REF07_POC (0x3227 * 4) ++#define HEVC_MPRED_L0_REF08_POC (0x3228 * 4) ++#define HEVC_MPRED_L0_REF09_POC (0x3229 * 4) ++#define HEVC_MPRED_L0_REF10_POC (0x322a * 4) ++#define HEVC_MPRED_L0_REF11_POC (0x322b * 4) ++#define HEVC_MPRED_L0_REF12_POC (0x322c * 4) ++#define HEVC_MPRED_L0_REF13_POC (0x322d * 4) ++#define HEVC_MPRED_L0_REF14_POC (0x322e * 4) ++#define HEVC_MPRED_L0_REF15_POC (0x322f * 4) ++#define HEVC_MPRED_L1_REF00_POC (0x3230 * 4) ++#define HEVC_MPRED_L1_REF01_POC (0x3231 * 4) ++#define HEVC_MPRED_L1_REF02_POC (0x3232 * 4) ++#define HEVC_MPRED_L1_REF03_POC (0x3233 * 4) ++#define HEVC_MPRED_L1_REF04_POC (0x3234 * 4) ++#define HEVC_MPRED_L1_REF05_POC (0x3235 * 4) ++#define HEVC_MPRED_L1_REF06_POC (0x3236 * 4) ++#define HEVC_MPRED_L1_REF07_POC (0x3237 * 4) ++#define HEVC_MPRED_L1_REF08_POC (0x3238 * 4) ++#define HEVC_MPRED_L1_REF09_POC (0x3239 * 4) ++#define HEVC_MPRED_L1_REF10_POC (0x323a * 4) ++#define HEVC_MPRED_L1_REF11_POC (0x323b * 4) ++#define HEVC_MPRED_L1_REF12_POC (0x323c * 4) ++#define HEVC_MPRED_L1_REF13_POC (0x323d * 4) ++#define HEVC_MPRED_L1_REF14_POC (0x323e * 4) ++#define HEVC_MPRED_L1_REF15_POC (0x323f * 4) ++#define HEVC_MPRED_PIC_SIZE_EXT (0x3240 * 4) ++#define HEVC_MPRED_DBG_MODE0 (0x3241 * 4) ++#define HEVC_MPRED_DBG_MODE1 (0x3242 * 4) ++#define HEVC_MPRED_DBG2_MODE (0x3243 * 4) ++#define HEVC_MPRED_IMP_CMD0 (0x3244 * 4) ++#define HEVC_MPRED_IMP_CMD1 (0x3245 * 4) ++#define HEVC_MPRED_IMP_CMD2 (0x3246 * 4) ++#define HEVC_MPRED_IMP_CMD3 (0x3247 * 4) ++#define HEVC_MPRED_DBG2_DATA_0 (0x3248 * 4) ++#define HEVC_MPRED_DBG2_DATA_1 (0x3249 * 4) ++#define HEVC_MPRED_DBG2_DATA_2 (0x324a * 4) ++#define HEVC_MPRED_DBG2_DATA_3 (0x324b * 4) ++#define HEVC_MPRED_DBG_DATA_0 (0x3250 * 4) ++#define HEVC_MPRED_DBG_DATA_1 (0x3251 * 4) ++#define HEVC_MPRED_DBG_DATA_2 (0x3252 * 4) ++#define HEVC_MPRED_DBG_DATA_3 (0x3253 * 4) ++#define HEVC_MPRED_DBG_DATA_4 (0x3254 * 4) ++#define HEVC_MPRED_DBG_DATA_5 (0x3255 * 4) ++#define HEVC_MPRED_DBG_DATA_6 (0x3256 * 4) ++#define HEVC_MPRED_DBG_DATA_7 (0x3257 * 4) ++#define HEVC_MPRED_CUR_POC (0x3260 * 4) ++#define HEVC_MPRED_COL_POC (0x3261 * 4) ++#define HEVC_MPRED_MV_RD_END_ADDR (0x3262 * 4) ++#define HEVCD_IPP_TOP_CNTL (0x3400 * 4) ++#define HEVCD_IPP_TOP_STATUS (0x3401 * 4) ++#define HEVCD_IPP_TOP_FRMCONFIG (0x3402 * 4) ++#define HEVCD_IPP_TOP_TILECONFIG1 (0x3403 * 4) ++#define HEVCD_IPP_TOP_TILECONFIG2 (0x3404 * 4) ++#define HEVCD_IPP_TOP_TILECONFIG3 (0x3405 * 4) ++#define HEVCD_IPP_TOP_LCUCONFIG (0x3406 * 4) ++#define HEVCD_IPP_TOP_FRMCTL (0x3407 * 4) ++#define HEVCD_IPP_CONFIG (0x3408 * 4) ++#define HEVCD_IPP_LINEBUFF_BASE (0x3409 * 4) ++#define HEVCD_IPP_INTR_MASK (0x340a * 4) ++#define HEVCD_IPP_AXIIF_CONFIG (0x340b * 4) ++#define HEVCD_IPP_BITDEPTH_CONFIG (0x340c * 4) ++#define HEVCD_IPP_SWMPREDIF_CONFIG (0x3410 * 4) ++#define HEVCD_IPP_SWMPREDIF_STATUS (0x3411 * 4) ++#define HEVCD_IPP_SWMPREDIF_CTBINFO (0x3412 * 4) ++#define HEVCD_IPP_SWMPREDIF_PUINFO0 (0x3413 * 4) ++#define HEVCD_IPP_SWMPREDIF_PUINFO1 (0x3414 * 4) ++#define HEVCD_IPP_SWMPREDIF_PUINFO2 (0x3415 * 4) ++#define HEVCD_IPP_SWMPREDIF_PUINFO3 (0x3416 * 4) ++#define HEVCD_IPP_DYNCLKGATE_CONFIG (0x3420 * 4) ++#define HEVCD_IPP_DYNCLKGATE_STATUS (0x3421 * 4) ++#define HEVCD_IPP_DBG_SEL (0x3430 * 4) ++#define HEVCD_IPP_DBG_DATA (0x3431 * 4) ++#define HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR (0x3460 * 4) ++#define HEVCD_MPP_ANC2AXI_TBL_CMD_ADDR (0x3461 * 4) ++#define HEVCD_MPP_ANC2AXI_TBL_WDATA_ADDR (0x3462 * 4) ++#define HEVCD_MPP_ANC2AXI_TBL_RDATA_ADDR (0x3463 * 4) ++#define HEVCD_MPP_WEIGHTPRED_CNTL_ADDR (0x347b * 4) ++#define HEVCD_MPP_L0_WEIGHT_FLAG_ADDR (0x347c * 4) ++#define HEVCD_MPP_L1_WEIGHT_FLAG_ADDR (0x347d * 4) ++#define HEVCD_MPP_YLOG2WGHTDENOM_ADDR (0x347e * 4) ++#define HEVCD_MPP_DELTACLOG2WGHTDENOM_ADDR (0x347f * 4) ++#define HEVCD_MPP_WEIGHT_ADDR (0x3480 * 4) ++#define HEVCD_MPP_WEIGHT_DATA (0x3481 * 4) ++#define HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR (0x34c0 * 4) ++#define HEVCD_MPP_ANC_CANVAS_DATA_ADDR (0x34c1 * 4) ++#define HEVCD_MPP_DECOMP_CTL1 (0x34c2 * 4) ++#define HEVCD_MPP_DECOMP_CTL2 (0x34c3 * 4) ++#define HEVCD_MCRCC_CTL1 (0x34f0 * 4) ++#define HEVCD_MCRCC_CTL2 (0x34f1 * 4) ++#define HEVCD_MCRCC_CTL3 (0x34f2 * 4) ++#define HEVCD_MCRCC_PERFMON_CTL (0x34f3 * 4) ++#define HEVCD_MCRCC_PERFMON_DATA (0x34f4 * 4) ++#define HEVC_DBLK_CFG0 (0x3500 * 4) ++#define HEVC_DBLK_CFG1 (0x3501 * 4) ++#define HEVC_DBLK_CFG2 (0x3502 * 4) ++#define HEVC_DBLK_CFG3 (0x3503 * 4) ++#define HEVC_DBLK_CFG4 (0x3504 * 4) ++#define HEVC_DBLK_CFG5 (0x3505 * 4) ++#define HEVC_DBLK_CFG6 (0x3506 * 4) ++#define HEVC_DBLK_CFG7 (0x3507 * 4) ++#define HEVC_DBLK_CFG8 (0x3508 * 4) ++#define HEVC_DBLK_CFG9 (0x3509 * 4) ++#define HEVC_DBLK_CFGA (0x350a * 4) ++#define HEVC_DBLK_STS0 (0x350b * 4) ++#define HEVC_DBLK_STS1 (0x350c * 4) ++#define HEVC_SAO_VERSION (0x3600 * 4) ++#define HEVC_SAO_CTRL0 (0x3601 * 4) ++#define HEVC_SAO_CTRL1 (0x3602 * 4) ++#define HEVC_SAO_INT_EN (0x3603 * 4) ++#define HEVC_SAO_INT_STATUS (0x3604 * 4) ++#define HEVC_SAO_PIC_SIZE (0x3605 * 4) ++#define HEVC_SAO_PIC_SIZE_LCU (0x3606 * 4) ++#define HEVC_SAO_TILE_START (0x3607 * 4) ++#define HEVC_SAO_TILE_SIZE_LCU (0x3608 * 4) ++#define HEVC_SAO_AXI_WCTRL (0x3609 * 4) ++#define HEVC_SAO_AXI_RCTRL (0x360a * 4) ++#define HEVC_SAO_Y_START_ADDR (0x360b * 4) ++#define HEVC_SAO_Y_LENGTH (0x360c * 4) ++#define HEVC_SAO_C_START_ADDR (0x360d * 4) ++#define HEVC_SAO_C_LENGTH (0x360e * 4) ++#define HEVC_SAO_Y_WPTR (0x360f * 4) ++#define HEVC_SAO_C_WPTR (0x3610 * 4) ++#define HEVC_SAO_ABV_START_ADDR (0x3611 * 4) ++#define HEVC_SAO_VB_WR_START_ADDR (0x3612 * 4) ++#define HEVC_SAO_VB_RD_START_ADDR (0x3613 * 4) ++#define HEVC_SAO_ABV_WPTR (0x3614 * 4) ++#define HEVC_SAO_ABV_RPTR (0x3615 * 4) ++#define HEVC_SAO_VB_WPTR (0x3616 * 4) ++#define HEVC_SAO_VB_RPTR (0x3617 * 4) ++#define HEVC_SAO_DBG_MODE0 (0x361e * 4) ++#define HEVC_SAO_DBG_MODE1 (0x361f * 4) ++#define HEVC_SAO_CTRL2 (0x3620 * 4) ++#define HEVC_SAO_CTRL3 (0x3621 * 4) ++#define HEVC_SAO_CTRL4 (0x3622 * 4) ++#define HEVC_SAO_CTRL5 (0x3623 * 4) ++#define HEVC_SAO_CTRL6 (0x3624 * 4) ++#define HEVC_SAO_CTRL7 (0x3625 * 4) ++#define HEVC_SAO_DBG_DATA_0 (0x3630 * 4) ++#define HEVC_SAO_DBG_DATA_1 (0x3631 * 4) ++#define HEVC_SAO_DBG_DATA_2 (0x3632 * 4) ++#define HEVC_SAO_DBG_DATA_3 (0x3633 * 4) ++#define HEVC_SAO_DBG_DATA_4 (0x3634 * 4) ++#define HEVC_SAO_DBG_DATA_5 (0x3635 * 4) ++#define HEVC_SAO_DBG_DATA_6 (0x3636 * 4) ++#define HEVC_SAO_DBG_DATA_7 (0x3637 * 4) ++#define HEVC_IQIT_CLK_RST_CTRL (0x3700 * 4) ++#define HEVC_IQIT_DEQUANT_CTRL (0x3701 * 4) ++#define HEVC_IQIT_SCALELUT_WR_ADDR (0x3702 * 4) ++#define HEVC_IQIT_SCALELUT_RD_ADDR (0x3703 * 4) ++#define HEVC_IQIT_SCALELUT_DATA (0x3704 * 4) ++#define HEVC_IQIT_SCALELUT_IDX_4 (0x3705 * 4) ++#define HEVC_IQIT_SCALELUT_IDX_8 (0x3706 * 4) ++#define HEVC_IQIT_SCALELUT_IDX_16_32 (0x3707 * 4) ++#define HEVC_IQIT_STAT_GEN0 (0x3708 * 4) ++#define HEVC_QP_WRITE (0x3709 * 4) ++#define HEVC_IQIT_STAT_GEN1 (0x370a * 4) ++/**/ ++ ++/*add from M8M2*/ ++#define HEVC_MC_CTRL_REG (0x3900 * 4) ++#define HEVC_MC_MB_INFO (0x3901 * 4) ++#define HEVC_MC_PIC_INFO (0x3902 * 4) ++#define HEVC_MC_HALF_PEL_ONE (0x3903 * 4) ++#define HEVC_MC_HALF_PEL_TWO (0x3904 * 4) ++#define HEVC_POWER_CTL_MC (0x3905 * 4) ++#define HEVC_MC_CMD (0x3906 * 4) ++#define HEVC_MC_CTRL0 (0x3907 * 4) ++#define HEVC_MC_PIC_W_H (0x3908 * 4) ++#define HEVC_MC_STATUS0 (0x3909 * 4) ++#define HEVC_MC_STATUS1 (0x390a * 4) ++#define HEVC_MC_CTRL1 (0x390b * 4) ++#define HEVC_MC_MIX_RATIO0 (0x390c * 4) ++#define HEVC_MC_MIX_RATIO1 (0x390d * 4) ++#define HEVC_MC_DP_MB_XY (0x390e * 4) ++#define HEVC_MC_OM_MB_XY (0x390f * 4) ++#define HEVC_PSCALE_RST (0x3910 * 4) ++#define HEVC_PSCALE_CTRL (0x3911 * 4) ++#define HEVC_PSCALE_PICI_W (0x3912 * 4) ++#define HEVC_PSCALE_PICI_H (0x3913 * 4) ++#define HEVC_PSCALE_PICO_W (0x3914 * 4) ++#define HEVC_PSCALE_PICO_H (0x3915 * 4) ++#define HEVC_PSCALE_PICO_START_X (0x3916 * 4) ++#define HEVC_PSCALE_PICO_START_Y (0x3917 * 4) ++#define HEVC_PSCALE_DUMMY (0x3918 * 4) ++#define HEVC_PSCALE_FILT0_COEF0 (0x3919 * 4) ++#define HEVC_PSCALE_FILT0_COEF1 (0x391a * 4) ++#define HEVC_PSCALE_CMD_CTRL (0x391b * 4) ++#define HEVC_PSCALE_CMD_BLK_X (0x391c * 4) ++#define HEVC_PSCALE_CMD_BLK_Y (0x391d * 4) ++#define HEVC_PSCALE_STATUS (0x391e * 4) ++#define HEVC_PSCALE_BMEM_ADDR (0x391f * 4) ++#define HEVC_PSCALE_BMEM_DAT (0x3920 * 4) ++#define HEVC_PSCALE_DRAM_BUF_CTRL (0x3921 * 4) ++#define HEVC_PSCALE_MCMD_CTRL (0x3922 * 4) ++#define HEVC_PSCALE_MCMD_XSIZE (0x3923 * 4) ++#define HEVC_PSCALE_MCMD_YSIZE (0x3924 * 4) ++#define HEVC_PSCALE_RBUF_START_BLKX (0x3925 * 4) ++#define HEVC_PSCALE_RBUF_START_BLKY (0x3926 * 4) ++#define HEVC_PSCALE_PICO_SHIFT_XY (0x3928 * 4) ++#define HEVC_PSCALE_CTRL1 (0x3929 * 4) ++#define HEVC_PSCALE_SRCKEY_CTRL0 (0x392a * 4) ++#define HEVC_PSCALE_SRCKEY_CTRL1 (0x392b * 4) ++#define HEVC_PSCALE_CANVAS_RD_ADDR (0x392c * 4) ++#define HEVC_PSCALE_CANVAS_WR_ADDR (0x392d * 4) ++#define HEVC_PSCALE_CTRL2 (0x392e * 4) ++#define HEVC_HDEC_MC_OMEM_AUTO (0x3930 * 4) ++#define HEVC_HDEC_MC_MBRIGHT_IDX (0x3931 * 4) ++#define HEVC_HDEC_MC_MBRIGHT_RD (0x3932 * 4) ++#define HEVC_MC_MPORT_CTRL (0x3940 * 4) ++#define HEVC_MC_MPORT_DAT (0x3941 * 4) ++#define HEVC_MC_WT_PRED_CTRL (0x3942 * 4) ++#define HEVC_MC_MBBOT_ST_EVEN_ADDR (0x3944 * 4) ++#define HEVC_MC_MBBOT_ST_ODD_ADDR (0x3945 * 4) ++#define HEVC_MC_DPDN_MB_XY (0x3946 * 4) ++#define HEVC_MC_OMDN_MB_XY (0x3947 * 4) ++#define HEVC_MC_HCMDBUF_H (0x3948 * 4) ++#define HEVC_MC_HCMDBUF_L (0x3949 * 4) ++#define HEVC_MC_HCMD_H (0x394a * 4) ++#define HEVC_MC_HCMD_L (0x394b * 4) ++#define HEVC_MC_IDCT_DAT (0x394c * 4) ++#define HEVC_MC_CTRL_GCLK_CTRL (0x394d * 4) ++#define HEVC_MC_OTHER_GCLK_CTRL (0x394e * 4) ++#define HEVC_MC_CTRL2 (0x394f * 4) ++#define HEVC_MDEC_PIC_DC_CTRL (0x398e * 4) ++#define HEVC_MDEC_PIC_DC_STATUS (0x398f * 4) ++#define HEVC_ANC0_CANVAS_ADDR (0x3990 * 4) ++#define HEVC_ANC1_CANVAS_ADDR (0x3991 * 4) ++#define HEVC_ANC2_CANVAS_ADDR (0x3992 * 4) ++#define HEVC_ANC3_CANVAS_ADDR (0x3993 * 4) ++#define HEVC_ANC4_CANVAS_ADDR (0x3994 * 4) ++#define HEVC_ANC5_CANVAS_ADDR (0x3995 * 4) ++#define HEVC_ANC6_CANVAS_ADDR (0x3996 * 4) ++#define HEVC_ANC7_CANVAS_ADDR (0x3997 * 4) ++#define HEVC_ANC8_CANVAS_ADDR (0x3998 * 4) ++#define HEVC_ANC9_CANVAS_ADDR (0x3999 * 4) ++#define HEVC_ANC10_CANVAS_ADDR (0x399a * 4) ++#define HEVC_ANC11_CANVAS_ADDR (0x399b * 4) ++#define HEVC_ANC12_CANVAS_ADDR (0x399c * 4) ++#define HEVC_ANC13_CANVAS_ADDR (0x399d * 4) ++#define HEVC_ANC14_CANVAS_ADDR (0x399e * 4) ++#define HEVC_ANC15_CANVAS_ADDR (0x399f * 4) ++#define HEVC_ANC16_CANVAS_ADDR (0x39a0 * 4) ++#define HEVC_ANC17_CANVAS_ADDR (0x39a1 * 4) ++#define HEVC_ANC18_CANVAS_ADDR (0x39a2 * 4) ++#define HEVC_ANC19_CANVAS_ADDR (0x39a3 * 4) ++#define HEVC_ANC20_CANVAS_ADDR (0x39a4 * 4) ++#define HEVC_ANC21_CANVAS_ADDR (0x39a5 * 4) ++#define HEVC_ANC22_CANVAS_ADDR (0x39a6 * 4) ++#define HEVC_ANC23_CANVAS_ADDR (0x39a7 * 4) ++#define HEVC_ANC24_CANVAS_ADDR (0x39a8 * 4) ++#define HEVC_ANC25_CANVAS_ADDR (0x39a9 * 4) ++#define HEVC_ANC26_CANVAS_ADDR (0x39aa * 4) ++#define HEVC_ANC27_CANVAS_ADDR (0x39ab * 4) ++#define HEVC_ANC28_CANVAS_ADDR (0x39ac * 4) ++#define HEVC_ANC29_CANVAS_ADDR (0x39ad * 4) ++#define HEVC_ANC30_CANVAS_ADDR (0x39ae * 4) ++#define HEVC_ANC31_CANVAS_ADDR (0x39af * 4) ++#define HEVC_DBKR_CANVAS_ADDR (0x39b0 * 4) ++#define HEVC_DBKW_CANVAS_ADDR (0x39b1 * 4) ++#define HEVC_REC_CANVAS_ADDR (0x39b2 * 4) ++#define HEVC_CURR_CANVAS_CTRL (0x39b3 * 4) ++#define HEVC_MDEC_PIC_DC_THRESH (0x39b8 * 4) ++#define HEVC_MDEC_PICR_BUF_STATUS (0x39b9 * 4) ++#define HEVC_MDEC_PICW_BUF_STATUS (0x39ba * 4) ++#define HEVC_MCW_DBLK_WRRSP_CNT (0x39bb * 4) ++#define HEVC_MC_MBBOT_WRRSP_CNT (0x39bc * 4) ++#define HEVC_MDEC_PICW_BUF2_STATUS (0x39bd * 4) ++#define HEVC_WRRSP_FIFO_PICW_DBK (0x39be * 4) ++#define HEVC_WRRSP_FIFO_PICW_MC (0x39bf * 4) ++#define HEVC_AV_SCRATCH_0 (0x39c0 * 4) ++#define HEVC_AV_SCRATCH_1 (0x39c1 * 4) ++#define HEVC_AV_SCRATCH_2 (0x39c2 * 4) ++#define HEVC_AV_SCRATCH_3 (0x39c3 * 4) ++#define HEVC_AV_SCRATCH_4 (0x39c4 * 4) ++#define HEVC_AV_SCRATCH_5 (0x39c5 * 4) ++#define HEVC_AV_SCRATCH_6 (0x39c6 * 4) ++#define HEVC_AV_SCRATCH_7 (0x39c7 * 4) ++#define HEVC_AV_SCRATCH_8 (0x39c8 * 4) ++#define HEVC_AV_SCRATCH_9 (0x39c9 * 4) ++#define HEVC_AV_SCRATCH_A (0x39ca * 4) ++#define HEVC_AV_SCRATCH_B (0x39cb * 4) ++#define HEVC_AV_SCRATCH_C (0x39cc * 4) ++#define HEVC_AV_SCRATCH_D (0x39cd * 4) ++#define HEVC_AV_SCRATCH_E (0x39ce * 4) ++#define HEVC_AV_SCRATCH_F (0x39cf * 4) ++#define HEVC_AV_SCRATCH_G (0x39d0 * 4) ++#define HEVC_AV_SCRATCH_H (0x39d1 * 4) ++#define HEVC_AV_SCRATCH_I (0x39d2 * 4) ++#define HEVC_AV_SCRATCH_J (0x39d3 * 4) ++#define HEVC_AV_SCRATCH_K (0x39d4 * 4) ++#define HEVC_AV_SCRATCH_L (0x39d5 * 4) ++#define HEVC_AV_SCRATCH_M (0x39d6 * 4) ++#define HEVC_AV_SCRATCH_N (0x39d7 * 4) ++#define HEVC_WRRSP_CO_MB (0x39d8 * 4) ++#define HEVC_WRRSP_DCAC (0x39d9 * 4) ++#define HEVC_WRRSP_VLD (0x39da * 4) ++#define HEVC_MDEC_DOUBLEW_CFG0 (0x39db * 4) ++#define HEVC_MDEC_DOUBLEW_CFG1 (0x39dc * 4) ++#define HEVC_MDEC_DOUBLEW_CFG2 (0x39dd * 4) ++#define HEVC_MDEC_DOUBLEW_CFG3 (0x39de * 4) ++#define HEVC_MDEC_DOUBLEW_CFG4 (0x39df * 4) ++#define HEVC_MDEC_DOUBLEW_CFG5 (0x39e0 * 4) ++#define HEVC_MDEC_DOUBLEW_CFG6 (0x39e1 * 4) ++#define HEVC_MDEC_DOUBLEW_CFG7 (0x39e2 * 4) ++#define HEVC_MDEC_DOUBLEW_STATUS (0x39e3 * 4) ++#define HEVC_DBLK_RST (0x3950 * 4) ++#define HEVC_DBLK_CTRL (0x3951 * 4) ++#define HEVC_DBLK_MB_WID_HEIGHT (0x3952 * 4) ++#define HEVC_DBLK_STATUS (0x3953 * 4) ++#define HEVC_DBLK_CMD_CTRL (0x3954 * 4) ++#define HEVC_DBLK_MB_XY (0x3955 * 4) ++#define HEVC_DBLK_QP (0x3956 * 4) ++#define HEVC_DBLK_Y_BHFILT (0x3957 * 4) ++#define HEVC_DBLK_Y_BHFILT_HIGH (0x3958 * 4) ++#define HEVC_DBLK_Y_BVFILT (0x3959 * 4) ++#define HEVC_DBLK_CB_BFILT (0x395a * 4) ++#define HEVC_DBLK_CR_BFILT (0x395b * 4) ++#define HEVC_DBLK_Y_HFILT (0x395c * 4) ++#define HEVC_DBLK_Y_HFILT_HIGH (0x395d * 4) ++#define HEVC_DBLK_Y_VFILT (0x395e * 4) ++#define HEVC_DBLK_CB_FILT (0x395f * 4) ++#define HEVC_DBLK_CR_FILT (0x3960 * 4) ++#define HEVC_DBLK_BETAX_QP_SEL (0x3961 * 4) ++#define HEVC_DBLK_CLIP_CTRL0 (0x3962 * 4) ++#define HEVC_DBLK_CLIP_CTRL1 (0x3963 * 4) ++#define HEVC_DBLK_CLIP_CTRL2 (0x3964 * 4) ++#define HEVC_DBLK_CLIP_CTRL3 (0x3965 * 4) ++#define HEVC_DBLK_CLIP_CTRL4 (0x3966 * 4) ++#define HEVC_DBLK_CLIP_CTRL5 (0x3967 * 4) ++#define HEVC_DBLK_CLIP_CTRL6 (0x3968 * 4) ++#define HEVC_DBLK_CLIP_CTRL7 (0x3969 * 4) ++#define HEVC_DBLK_CLIP_CTRL8 (0x396a * 4) ++#define HEVC_DBLK_STATUS1 (0x396b * 4) ++#define HEVC_DBLK_GCLK_FREE (0x396c * 4) ++#define HEVC_DBLK_GCLK_OFF (0x396d * 4) ++#define HEVC_DBLK_AVSFLAGS (0x396e * 4) ++#define HEVC_DBLK_CBPY (0x3970 * 4) ++#define HEVC_DBLK_CBPY_ADJ (0x3971 * 4) ++#define HEVC_DBLK_CBPC (0x3972 * 4) ++#define HEVC_DBLK_CBPC_ADJ (0x3973 * 4) ++#define HEVC_DBLK_VHMVD (0x3974 * 4) ++#define HEVC_DBLK_STRONG (0x3975 * 4) ++#define HEVC_DBLK_RV8_QUANT (0x3976 * 4) ++#define HEVC_DBLK_CBUS_HCMD2 (0x3977 * 4) ++#define HEVC_DBLK_CBUS_HCMD1 (0x3978 * 4) ++#define HEVC_DBLK_CBUS_HCMD0 (0x3979 * 4) ++#define HEVC_DBLK_VLD_HCMD2 (0x397a * 4) ++#define HEVC_DBLK_VLD_HCMD1 (0x397b * 4) ++#define HEVC_DBLK_VLD_HCMD0 (0x397c * 4) ++#define HEVC_DBLK_OST_YBASE (0x397d * 4) ++#define HEVC_DBLK_OST_CBCRDIFF (0x397e * 4) ++#define HEVC_DBLK_CTRL1 (0x397f * 4) ++#define HEVC_MCRCC_CTL1 (0x3980 * 4) ++#define HEVC_MCRCC_CTL2 (0x3981 * 4) ++#define HEVC_MCRCC_CTL3 (0x3982 * 4) ++#define HEVC_GCLK_EN (0x3983 * 4) ++#define HEVC_MDEC_SW_RESET (0x3984 * 4) ++ ++/*add from M8M2*/ ++#define HEVC_VLD_STATUS_CTRL (0x3c00 * 4) ++#define HEVC_MPEG1_2_REG (0x3c01 * 4) ++#define HEVC_F_CODE_REG (0x3c02 * 4) ++#define HEVC_PIC_HEAD_INFO (0x3c03 * 4) ++#define HEVC_SLICE_VER_POS_PIC_TYPE (0x3c04 * 4) ++#define HEVC_QP_VALUE_REG (0x3c05 * 4) ++#define HEVC_MBA_INC (0x3c06 * 4) ++#define HEVC_MB_MOTION_MODE (0x3c07 * 4) ++#define HEVC_POWER_CTL_VLD (0x3c08 * 4) ++#define HEVC_MB_WIDTH (0x3c09 * 4) ++#define HEVC_SLICE_QP (0x3c0a * 4) ++#define HEVC_PRE_START_CODE (0x3c0b * 4) ++#define HEVC_SLICE_START_BYTE_01 (0x3c0c * 4) ++#define HEVC_SLICE_START_BYTE_23 (0x3c0d * 4) ++#define HEVC_RESYNC_MARKER_LENGTH (0x3c0e * 4) ++#define HEVC_DECODER_BUFFER_INFO (0x3c0f * 4) ++#define HEVC_FST_FOR_MV_X (0x3c10 * 4) ++#define HEVC_FST_FOR_MV_Y (0x3c11 * 4) ++#define HEVC_SCD_FOR_MV_X (0x3c12 * 4) ++#define HEVC_SCD_FOR_MV_Y (0x3c13 * 4) ++#define HEVC_FST_BAK_MV_X (0x3c14 * 4) ++#define HEVC_FST_BAK_MV_Y (0x3c15 * 4) ++#define HEVC_SCD_BAK_MV_X (0x3c16 * 4) ++#define HEVC_SCD_BAK_MV_Y (0x3c17 * 4) ++#define HEVC_VLD_DECODE_CONTROL (0x3c18 * 4) ++#define HEVC_VLD_REVERVED_19 (0x3c19 * 4) ++#define HEVC_VIFF_BIT_CNT (0x3c1a * 4) ++#define HEVC_BYTE_ALIGN_PEAK_HI (0x3c1b * 4) ++#define HEVC_BYTE_ALIGN_PEAK_LO (0x3c1c * 4) ++#define HEVC_NEXT_ALIGN_PEAK (0x3c1d * 4) ++#define HEVC_VC1_CONTROL_REG (0x3c1e * 4) ++#define HEVC_PMV1_X (0x3c20 * 4) ++#define HEVC_PMV1_Y (0x3c21 * 4) ++#define HEVC_PMV2_X (0x3c22 * 4) ++#define HEVC_PMV2_Y (0x3c23 * 4) ++#define HEVC_PMV3_X (0x3c24 * 4) ++#define HEVC_PMV3_Y (0x3c25 * 4) ++#define HEVC_PMV4_X (0x3c26 * 4) ++#define HEVC_PMV4_Y (0x3c27 * 4) ++#define HEVC_M4_TABLE_SELECT (0x3c28 * 4) ++#define HEVC_M4_CONTROL_REG (0x3c29 * 4) ++#define HEVC_BLOCK_NUM (0x3c2a * 4) ++#define HEVC_PATTERN_CODE (0x3c2b * 4) ++#define HEVC_MB_INFO (0x3c2c * 4) ++#define HEVC_VLD_DC_PRED (0x3c2d * 4) ++#define HEVC_VLD_ERROR_MASK (0x3c2e * 4) ++#define HEVC_VLD_DC_PRED_C (0x3c2f * 4) ++#define HEVC_LAST_SLICE_MV_ADDR (0x3c30 * 4) ++#define HEVC_LAST_MVX (0x3c31 * 4) ++#define HEVC_LAST_MVY (0x3c32 * 4) ++#define HEVC_VLD_C38 (0x3c38 * 4) ++#define HEVC_VLD_C39 (0x3c39 * 4) ++#define HEVC_VLD_STATUS (0x3c3a * 4) ++#define HEVC_VLD_SHIFT_STATUS (0x3c3b * 4) ++#define HEVC_VOFF_STATUS (0x3c3c * 4) ++#define HEVC_VLD_C3D (0x3c3d * 4) ++#define HEVC_VLD_DBG_INDEX (0x3c3e * 4) ++#define HEVC_VLD_DBG_DATA (0x3c3f * 4) ++#define HEVC_VLD_MEM_VIFIFO_START_PTR (0x3c40 * 4) ++#define HEVC_VLD_MEM_VIFIFO_CURR_PTR (0x3c41 * 4) ++#define HEVC_VLD_MEM_VIFIFO_END_PTR (0x3c42 * 4) ++#define HEVC_VLD_MEM_VIFIFO_BYTES_AVAIL (0x3c43 * 4) ++#define HEVC_VLD_MEM_VIFIFO_CONTROL (0x3c44 * 4) ++#define HEVC_VLD_MEM_VIFIFO_WP (0x3c45 * 4) ++#define HEVC_VLD_MEM_VIFIFO_RP (0x3c46 * 4) ++#define HEVC_VLD_MEM_VIFIFO_LEVEL (0x3c47 * 4) ++#define HEVC_VLD_MEM_VIFIFO_BUF_CNTL (0x3c48 * 4) ++#define HEVC_VLD_TIME_STAMP_CNTL (0x3c49 * 4) ++#define HEVC_VLD_TIME_STAMP_SYNC_0 (0x3c4a * 4) ++#define HEVC_VLD_TIME_STAMP_SYNC_1 (0x3c4b * 4) ++#define HEVC_VLD_TIME_STAMP_0 (0x3c4c * 4) ++#define HEVC_VLD_TIME_STAMP_1 (0x3c4d * 4) ++#define HEVC_VLD_TIME_STAMP_2 (0x3c4e * 4) ++#define HEVC_VLD_TIME_STAMP_3 (0x3c4f * 4) ++#define HEVC_VLD_TIME_STAMP_LENGTH (0x3c50 * 4) ++#define HEVC_VLD_MEM_VIFIFO_WRAP_COUNT (0x3c51 * 4) ++#define HEVC_VLD_MEM_VIFIFO_MEM_CTL (0x3c52 * 4) ++#define HEVC_VLD_MEM_VBUF_RD_PTR (0x3c53 * 4) ++#define HEVC_VLD_MEM_VBUF2_RD_PTR (0x3c54 * 4) ++#define HEVC_VLD_MEM_SWAP_ADDR (0x3c55 * 4) ++#define HEVC_VLD_MEM_SWAP_CTL (0x3c56 * 4) ++/**/ ++ ++/*add from M8M2*/ ++#define HEVC_VCOP_CTRL_REG (0x3e00 * 4) ++#define HEVC_QP_CTRL_REG (0x3e01 * 4) ++#define HEVC_INTRA_QUANT_MATRIX (0x3e02 * 4) ++#define HEVC_NON_I_QUANT_MATRIX (0x3e03 * 4) ++#define HEVC_DC_SCALER (0x3e04 * 4) ++#define HEVC_DC_AC_CTRL (0x3e05 * 4) ++#define HEVC_DC_AC_SCALE_MUL (0x3e06 * 4) ++#define HEVC_DC_AC_SCALE_DIV (0x3e07 * 4) ++#define HEVC_POWER_CTL_IQIDCT (0x3e08 * 4) ++#define HEVC_RV_AI_Y_X (0x3e09 * 4) ++#define HEVC_RV_AI_U_X (0x3e0a * 4) ++#define HEVC_RV_AI_V_X (0x3e0b * 4) ++#define HEVC_RV_AI_MB_COUNT (0x3e0c * 4) ++#define HEVC_NEXT_INTRA_DMA_ADDRESS (0x3e0d * 4) ++#define HEVC_IQIDCT_CONTROL (0x3e0e * 4) ++#define HEVC_IQIDCT_DEBUG_INFO_0 (0x3e0f * 4) ++#define HEVC_DEBLK_CMD (0x3e10 * 4) ++#define HEVC_IQIDCT_DEBUG_IDCT (0x3e11 * 4) ++#define HEVC_DCAC_DMA_CTRL (0x3e12 * 4) ++#define HEVC_DCAC_DMA_ADDRESS (0x3e13 * 4) ++#define HEVC_DCAC_CPU_ADDRESS (0x3e14 * 4) ++#define HEVC_DCAC_CPU_DATA (0x3e15 * 4) ++#define HEVC_DCAC_MB_COUNT (0x3e16 * 4) ++#define HEVC_IQ_QUANT (0x3e17 * 4) ++#define HEVC_VC1_BITPLANE_CTL (0x3e18 * 4) ++ ++ ++/*add from M8M2*/ ++#define HEVC_MSP (0x3300 * 4) ++#define HEVC_MPSR (0x3301 * 4) ++#define HEVC_MINT_VEC_BASE (0x3302 * 4) ++#define HEVC_MCPU_INTR_GRP (0x3303 * 4) ++#define HEVC_MCPU_INTR_MSK (0x3304 * 4) ++#define HEVC_MCPU_INTR_REQ (0x3305 * 4) ++#define HEVC_MPC_P (0x3306 * 4) ++#define HEVC_MPC_D (0x3307 * 4) ++#define HEVC_MPC_E (0x3308 * 4) ++#define HEVC_MPC_W (0x3309 * 4) ++#define HEVC_MINDEX0_REG (0x330a * 4) ++#define HEVC_MINDEX1_REG (0x330b * 4) ++#define HEVC_MINDEX2_REG (0x330c * 4) ++#define HEVC_MINDEX3_REG (0x330d * 4) ++#define HEVC_MINDEX4_REG (0x330e * 4) ++#define HEVC_MINDEX5_REG (0x330f * 4) ++#define HEVC_MINDEX6_REG (0x3310 * 4) ++#define HEVC_MINDEX7_REG (0x3311 * 4) ++#define HEVC_MMIN_REG (0x3312 * 4) ++#define HEVC_MMAX_REG (0x3313 * 4) ++#define HEVC_MBREAK0_REG (0x3314 * 4) ++#define HEVC_MBREAK1_REG (0x3315 * 4) ++#define HEVC_MBREAK2_REG (0x3316 * 4) ++#define HEVC_MBREAK3_REG (0x3317 * 4) ++#define HEVC_MBREAK_TYPE (0x3318 * 4) ++#define HEVC_MBREAK_CTRL (0x3319 * 4) ++#define HEVC_MBREAK_STAUTS (0x331a * 4) ++#define HEVC_MDB_ADDR_REG (0x331b * 4) ++#define HEVC_MDB_DATA_REG (0x331c * 4) ++#define HEVC_MDB_CTRL (0x331d * 4) ++#define HEVC_MSFTINT0 (0x331e * 4) ++#define HEVC_MSFTINT1 (0x331f * 4) ++#define HEVC_CSP (0x3320 * 4) ++#define HEVC_CPSR (0x3321 * 4) ++#define HEVC_CINT_VEC_BASE (0x3322 * 4) ++#define HEVC_CCPU_INTR_GRP (0x3323 * 4) ++#define HEVC_CCPU_INTR_MSK (0x3324 * 4) ++#define HEVC_CCPU_INTR_REQ (0x3325 * 4) ++#define HEVC_CPC_P (0x3326 * 4) ++#define HEVC_CPC_D (0x3327 * 4) ++#define HEVC_CPC_E (0x3328 * 4) ++#define HEVC_CPC_W (0x3329 * 4) ++#define HEVC_CINDEX0_REG (0x332a * 4) ++#define HEVC_CINDEX1_REG (0x332b * 4) ++#define HEVC_CINDEX2_REG (0x332c * 4) ++#define HEVC_CINDEX3_REG (0x332d * 4) ++#define HEVC_CINDEX4_REG (0x332e * 4) ++#define HEVC_CINDEX5_REG (0x332f * 4) ++#define HEVC_CINDEX6_REG (0x3330 * 4) ++#define HEVC_CINDEX7_REG (0x3331 * 4) ++#define HEVC_CMIN_REG (0x3332 * 4) ++#define HEVC_CMAX_REG (0x3333 * 4) ++#define HEVC_CBREAK0_REG (0x3334 * 4) ++#define HEVC_CBREAK1_REG (0x3335 * 4) ++#define HEVC_CBREAK2_REG (0x3336 * 4) ++#define HEVC_CBREAK3_REG (0x3337 * 4) ++#define HEVC_CBREAK_TYPE (0x3338 * 4) ++#define HEVC_CBREAK_CTRL (0x3339 * 4) ++#define HEVC_CBREAK_STAUTS (0x333a * 4) ++#define HEVC_CDB_ADDR_REG (0x333b * 4) ++#define HEVC_CDB_DATA_REG (0x333c * 4) ++#define HEVC_CDB_CTRL (0x333d * 4) ++#define HEVC_CSFTINT0 (0x333e * 4) ++#define HEVC_CSFTINT1 (0x333f * 4) ++#define HEVC_IMEM_DMA_CTRL (0x3340 * 4) ++#define HEVC_IMEM_DMA_ADR (0x3341 * 4) ++#define HEVC_IMEM_DMA_COUNT (0x3342 * 4) ++#define HEVC_WRRSP_IMEM (0x3343 * 4) ++#define HEVC_LMEM_DMA_CTRL (0x3350 * 4) ++#define HEVC_LMEM_DMA_ADR (0x3351 * 4) ++#define HEVC_LMEM_DMA_COUNT (0x3352 * 4) ++#define HEVC_WRRSP_LMEM (0x3353 * 4) ++#define HEVC_MAC_CTRL1 (0x3360 * 4) ++#define HEVC_ACC0REG1 (0x3361 * 4) ++#define HEVC_ACC1REG1 (0x3362 * 4) ++#define HEVC_MAC_CTRL2 (0x3370 * 4) ++#define HEVC_ACC0REG2 (0x3371 * 4) ++#define HEVC_ACC1REG2 (0x3372 * 4) ++#define HEVC_CPU_TRACE (0x3380 * 4) ++/**/ ++ ++#endif ++ +diff --git a/drivers/media/platform/meson/vdec/vdec_hevc.c b/drivers/media/platform/meson/vdec/vdec_hevc.c +new file mode 100644 +index 0000000000000..8872f58d39fea +--- /dev/null ++++ b/drivers/media/platform/meson/vdec/vdec_hevc.c +@@ -0,0 +1,191 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright (C) 2018 Maxime Jourdan ++ * ++ * VDEC_HEVC is a video decoding block that allows decoding of ++ * HEVC, VP9 ++ */ ++ ++#include ++#include ++ ++#include "vdec_1.h" ++#include "vdec_helpers.h" ++#include "hevc_regs.h" ++#include "dos_regs.h" ++ ++/* AO Registers */ ++#define AO_RTI_GEN_PWR_SLEEP0 0xe8 ++#define AO_RTI_GEN_PWR_ISO0 0xec ++ #define GEN_PWR_VDEC_HEVC (BIT(7) | BIT(6)) ++ ++#define MC_SIZE (4096 * 4) ++ ++static int vdec_hevc_load_firmware(struct amvdec_session *sess, const char* fwname) ++{ ++ struct amvdec_core *core = sess->core; ++ struct device *dev = core->dev_dec; ++ const struct firmware *fw; ++ static void *mc_addr; ++ static dma_addr_t mc_addr_map; ++ int ret; ++ u32 i = 100; ++ ++ ret = request_firmware(&fw, fwname, dev); ++ if (ret < 0) { ++ dev_err(dev, "Unable to request firmware %s\n", fwname); ++ return ret; ++ } ++ ++ if (fw->size < MC_SIZE) { ++ dev_err(dev, "Firmware size %zu is too small. Expected %u.\n", ++ fw->size, MC_SIZE); ++ ret = -EINVAL; ++ goto release_firmware; ++ } ++ ++ mc_addr = dma_alloc_coherent(core->dev, MC_SIZE, &mc_addr_map, GFP_KERNEL); ++ if (!mc_addr) { ++ dev_err(dev, "Failed allocating memory for firmware loading\n"); ++ ret = -ENOMEM; ++ goto release_firmware; ++ } ++ ++ memcpy(mc_addr, fw->data, MC_SIZE); ++ ++ amvdec_write_dos(core, HEVC_MPSR, 0); ++ amvdec_write_dos(core, HEVC_CPSR, 0); ++ ++ amvdec_write_dos(core, HEVC_IMEM_DMA_ADR, mc_addr_map); ++ amvdec_write_dos(core, HEVC_IMEM_DMA_COUNT, MC_SIZE / 4); ++ amvdec_write_dos(core, HEVC_IMEM_DMA_CTRL, (0x8000 | (7 << 16))); ++ ++ while (--i && readl(core->dos_base + HEVC_IMEM_DMA_CTRL) & 0x8000) { } ++ ++ if (i == 0) { ++ dev_err(dev, "Firmware load fail (DMA hang?)\n"); ++ ret = -ENODEV; ++ } ++ ++ dma_free_coherent(core->dev, MC_SIZE, mc_addr, mc_addr_map); ++release_firmware: ++ release_firmware(fw); ++ return ret; ++} ++ ++static void vdec_hevc_stbuf_init(struct amvdec_session *sess) ++{ ++ struct amvdec_core *core = sess->core; ++ ++ amvdec_write_dos(core, HEVC_STREAM_CONTROL, amvdec_read_dos(core, HEVC_STREAM_CONTROL) & ~1); ++ amvdec_write_dos(core, HEVC_STREAM_START_ADDR, sess->vififo_paddr); ++ amvdec_write_dos(core, HEVC_STREAM_END_ADDR, sess->vififo_paddr + sess->vififo_size); ++ amvdec_write_dos(core, HEVC_STREAM_RD_PTR, sess->vififo_paddr); ++ amvdec_write_dos(core, HEVC_STREAM_WR_PTR, sess->vififo_paddr); ++} ++ ++/* VDEC_HEVC specific ESPARSER configuration */ ++static void vdec_hevc_conf_esparser(struct amvdec_session *sess) ++{ ++ struct amvdec_core *core = sess->core; ++ ++ /* set vififo_vbuf_rp_sel=>vdec_hevc */ ++ amvdec_write_dos(core, DOS_GEN_CTRL0, 3 << 1); ++ amvdec_write_dos(core, HEVC_STREAM_CONTROL, amvdec_read_dos(core, HEVC_STREAM_CONTROL) | BIT(3)); ++ amvdec_write_dos(core, HEVC_STREAM_CONTROL, amvdec_read_dos(core, HEVC_STREAM_CONTROL) | 1); ++ amvdec_write_dos(core, HEVC_STREAM_FIFO_CTL, amvdec_read_dos(core, HEVC_STREAM_FIFO_CTL) | BIT(29)); ++} ++ ++static u32 vdec_hevc_vififo_level(struct amvdec_session *sess) ++{ ++ return readl_relaxed(sess->core->dos_base + HEVC_STREAM_LEVEL); ++} ++ ++static int vdec_hevc_stop(struct amvdec_session *sess) ++{ ++ struct amvdec_core *core = sess->core; ++ struct amvdec_codec_ops *codec_ops = sess->fmt_out->codec_ops; ++ ++ /* Disable interrupt */ ++ amvdec_write_dos(core, HEVC_ASSIST_MBOX1_MASK, 0); ++ /* Disable firmware processor */ ++ amvdec_write_dos(core, HEVC_MPSR, 0); ++ ++ if (sess->priv) ++ codec_ops->stop(sess); ++ ++ /* Enable VDEC_HEVC Isolation */ ++ regmap_update_bits(core->regmap_ao, AO_RTI_GEN_PWR_ISO0, 0xc00, 0xc00); ++ ++ /* VDEC_HEVC Memories */ ++ amvdec_write_dos(core, DOS_MEM_PD_HEVC, 0xffffffffUL); ++ ++ regmap_update_bits(core->regmap_ao, AO_RTI_GEN_PWR_SLEEP0, ++ GEN_PWR_VDEC_HEVC, GEN_PWR_VDEC_HEVC); ++ ++ clk_disable_unprepare(core->vdec_hevc_clk); ++ ++ return 0; ++} ++ ++static int vdec_hevc_start(struct amvdec_session *sess) ++{ ++ int ret; ++ struct amvdec_core *core = sess->core; ++ struct amvdec_codec_ops *codec_ops = sess->fmt_out->codec_ops; ++ ++ clk_set_rate(core->vdec_hevc_clk, 666666666); ++ ret = clk_prepare_enable(core->vdec_hevc_clk); ++ if (ret) ++ return ret; ++ ++ regmap_update_bits(core->regmap_ao, AO_RTI_GEN_PWR_SLEEP0, ++ GEN_PWR_VDEC_HEVC, 0); ++ udelay(10); ++ ++ /* Reset VDEC_HEVC*/ ++ amvdec_write_dos(core, DOS_SW_RESET3, 0xffffffff); ++ amvdec_write_dos(core, DOS_SW_RESET3, 0x00000000); ++ ++ amvdec_write_dos(core, DOS_GCLK_EN3, 0xffffffff); ++ ++ /* VDEC_HEVC Memories */ ++ amvdec_write_dos(core, DOS_MEM_PD_HEVC, 0x00000000); ++ ++ /* Remove VDEC_HEVC Isolation */ ++ regmap_update_bits(core->regmap_ao, AO_RTI_GEN_PWR_ISO0, 0xc00, 0); ++ ++ amvdec_write_dos(core, DOS_SW_RESET3, 0xffffffff); ++ amvdec_write_dos(core, DOS_SW_RESET3, 0x00000000); ++ ++ vdec_hevc_stbuf_init(sess); ++ ++ ret = vdec_hevc_load_firmware(sess, sess->fmt_out->firmware_path); ++ if (ret) ++ goto stop; ++ ++ ret = codec_ops->start(sess); ++ if (ret) ++ goto stop; ++ ++ amvdec_write_dos(core, DOS_SW_RESET3, BIT(12)|BIT(11)); ++ amvdec_write_dos(core, DOS_SW_RESET3, 0); ++ amvdec_read_dos(core, DOS_SW_RESET3); ++ ++ amvdec_write_dos(core, HEVC_MPSR, 1); ++ /* Let the firmware settle */ ++ udelay(10); ++ ++ return 0; ++ ++stop: ++ vdec_hevc_stop(sess); ++ return ret; ++} ++ ++struct amvdec_ops vdec_hevc_ops = { ++ .start = vdec_hevc_start, ++ .stop = vdec_hevc_stop, ++ .conf_esparser = vdec_hevc_conf_esparser, ++ .vififo_level = vdec_hevc_vififo_level, ++}; +\ No newline at end of file +diff --git a/drivers/media/platform/meson/vdec/vdec_hevc.h b/drivers/media/platform/meson/vdec/vdec_hevc.h +new file mode 100644 +index 0000000000000..f1ccad7d5f949 +--- /dev/null ++++ b/drivers/media/platform/meson/vdec/vdec_hevc.h +@@ -0,0 +1,22 @@ ++/* ++ * Copyright (C) 2018 Maxime Jourdan ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 and ++ * only 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 __MESON_VDEC_VDEC_HEVC_H_ ++#define __MESON_VDEC_VDEC_HEVC_H_ ++ ++#include "vdec.h" ++ ++extern struct amvdec_ops vdec_hevc_ops; ++ ++#endif +\ No newline at end of file +diff --git a/drivers/media/platform/meson/vdec/vdec_platform.c b/drivers/media/platform/meson/vdec/vdec_platform.c +index 1181832b5fe1e..a8d03426e53d0 100644 +--- a/drivers/media/platform/meson/vdec/vdec_platform.c ++++ b/drivers/media/platform/meson/vdec/vdec_platform.c +@@ -8,13 +8,25 @@ + #include "vdec.h" + + #include "vdec_1.h" ++#include "vdec_hevc.h" + #include "codec_mpeg12.h" + #include "codec_h264.h" + #include "codec_mpeg4.h" + #include "codec_mjpeg.h" ++#include "codec_hevc.h" + + static const struct amvdec_format vdec_formats_gxbb[] = { + { ++ .pixfmt = V4L2_PIX_FMT_HEVC, ++ .min_buffers = 16, ++ .max_buffers = 24, ++ .max_width = 3840, ++ .max_height = 2160, ++ .vdec_ops = &vdec_hevc_ops, ++ .codec_ops = &codec_hevc_ops, ++ .firmware_path = "meson/gx/vh265_mc", ++ .pixfmts_cap = { V4L2_PIX_FMT_NV12M, V4L2_PIX_FMT_AM21C, 0 }, ++ }, { + .pixfmt = V4L2_PIX_FMT_MJPEG, + .min_buffers = 4, + .max_buffers = 4, +@@ -89,6 +101,16 @@ static const struct amvdec_format vdec_formats_gxbb[] = { + + static const struct amvdec_format vdec_formats_gxl[] = { + { ++ .pixfmt = V4L2_PIX_FMT_HEVC, ++ .min_buffers = 16, ++ .max_buffers = 24, ++ .max_width = 3840, ++ .max_height = 2160, ++ .vdec_ops = &vdec_hevc_ops, ++ .codec_ops = &codec_hevc_ops, ++ .firmware_path = "meson/gx/vh265_mc", ++ .pixfmts_cap = { V4L2_PIX_FMT_NV12M, V4L2_PIX_FMT_AM21C, 0 }, ++ }, { + .pixfmt = V4L2_PIX_FMT_MJPEG, + .min_buffers = 4, + .max_buffers = 4, +@@ -163,6 +185,16 @@ static const struct amvdec_format vdec_formats_gxl[] = { + + static const struct amvdec_format vdec_formats_gxm[] = { + { ++ .pixfmt = V4L2_PIX_FMT_HEVC, ++ .min_buffers = 16, ++ .max_buffers = 24, ++ .max_width = 3840, ++ .max_height = 2160, ++ .vdec_ops = &vdec_hevc_ops, ++ .codec_ops = &codec_hevc_ops, ++ .firmware_path = "meson/gx/vh265_mc", ++ .pixfmts_cap = { V4L2_PIX_FMT_NV12M, V4L2_PIX_FMT_AM21C, 0 }, ++ }, { + .pixfmt = V4L2_PIX_FMT_MJPEG, + .min_buffers = 4, + .max_buffers = 4, diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/015_linux-4.18.y-v4l-0015-mpeg4-fixes_and_cleanups.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/015_linux-4.18.y-v4l-0015-mpeg4-fixes_and_cleanups.patch new file mode 100644 index 000000000..5d3c4c4e7 --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/015_linux-4.18.y-v4l-0015-mpeg4-fixes_and_cleanups.patch @@ -0,0 +1,127 @@ +From 36c532fff8000ef7a125b9260753a374ec746426 Mon Sep 17 00:00:00 2001 +From: Maxime Jourdan +Date: Fri, 31 Aug 2018 14:03:23 +0200 +Subject: [PATCH] mpeg4: fixes & cleanups + +* Remove unused registers +* Use constants for bits and masks +* abort on fatal error +* Don't set sess->priv until the end +--- + .../media/platform/meson/vdec/codec_mpeg4.c | 59 +++++++++++-------- + 1 file changed, 33 insertions(+), 26 deletions(-) + +diff --git a/drivers/media/platform/meson/vdec/codec_mpeg4.c b/drivers/media/platform/meson/vdec/codec_mpeg4.c +index c6db2640c91a7..b28e3d477df0d 100644 +--- a/drivers/media/platform/meson/vdec/codec_mpeg4.c ++++ b/drivers/media/platform/meson/vdec/codec_mpeg4.c +@@ -13,18 +13,16 @@ + /* Offset added by firmware, to substract from workspace paddr */ + #define DCAC_BUFF_START_IP 0x02b00000 + +-/* map FW registers to known MPEG4 functions */ +-#define MP4_PIC_RATIO AV_SCRATCH_5 +-#define MP4_ERR_COUNT AV_SCRATCH_6 +-#define MP4_PIC_WH AV_SCRATCH_7 +-#define MREG_BUFFERIN AV_SCRATCH_8 +-#define MREG_BUFFEROUT AV_SCRATCH_9 +-#define MP4_NOT_CODED_CNT AV_SCRATCH_A +-#define MP4_VOP_TIME_INC AV_SCRATCH_B +-#define MP4_OFFSET_REG AV_SCRATCH_C +-#define MP4_SYS_RATE AV_SCRATCH_E +-#define MEM_OFFSET_REG AV_SCRATCH_F +-#define MREG_FATAL_ERROR AV_SCRATCH_L ++/* map firmware registers to known MPEG4 functions */ ++#define MREG_BUFFERIN AV_SCRATCH_8 ++#define MREG_BUFFEROUT AV_SCRATCH_9 ++#define MP4_NOT_CODED_CNT AV_SCRATCH_A ++#define MEM_OFFSET_REG AV_SCRATCH_F ++#define MREG_FATAL_ERROR AV_SCRATCH_L ++ ++#define BUF_IDX_MASK GENMASK(2, 0) ++#define INTERLACE_FLAG BIT(7) ++#define TOP_FIELD_FIRST_FLAG BIT(6) + + struct codec_mpeg4 { + /* Buffer for the MPEG4 Workspace */ +@@ -39,7 +37,7 @@ static int codec_mpeg4_can_recycle(struct amvdec_core *core) + + static void codec_mpeg4_recycle(struct amvdec_core *core, u32 buf_idx) + { +- amvdec_write_dos(core, MREG_BUFFERIN, ~(1 << buf_idx)); ++ amvdec_write_dos(core, MREG_BUFFERIN, ~BIT(buf_idx)); + } + + static int codec_mpeg4_start(struct amvdec_session *sess) { +@@ -51,8 +49,6 @@ static int codec_mpeg4_start(struct amvdec_session *sess) { + if (!mpeg4) + return -ENOMEM; + +- sess->priv = mpeg4; +- + /* Allocate some memory for the MPEG4 decoder's state */ + mpeg4->workspace_vaddr = dma_alloc_coherent(core->dev, SIZE_WORKSPACE, + &mpeg4->workspace_paddr, +@@ -63,6 +59,7 @@ static int codec_mpeg4_start(struct amvdec_session *sess) { + goto free_mpeg4; + } + ++ /* Canvas regs: AV_SCRATCH_0-AV_SCRATCH_4;AV_SCRATCH_G-AV_SCRATCH_J */ + amvdec_set_canvases(sess, (u32[]){ AV_SCRATCH_0, AV_SCRATCH_G, 0 }, + (u32[]){ 4, 4, 0 }); + +@@ -75,6 +72,8 @@ static int codec_mpeg4_start(struct amvdec_session *sess) { + amvdec_write_dos(core, MREG_FATAL_ERROR, 0); + amvdec_write_dos(core, MDEC_PIC_DC_THRESH, 0x404038aa); + ++ sess->priv = mpeg4; ++ + return 0; + + free_mpeg4: +@@ -99,26 +98,34 @@ static int codec_mpeg4_stop(struct amvdec_session *sess) + + static irqreturn_t codec_mpeg4_isr(struct amvdec_session *sess) + { ++ struct amvdec_core *core = sess->core; + u32 reg; + u32 buffer_index; +- struct amvdec_core *core = sess->core; ++ u32 field = V4L2_FIELD_NONE; + + reg = amvdec_read_dos(core, MREG_FATAL_ERROR); +- if (reg == 1) ++ if (reg == 1) { + dev_err(core->dev, "mpeg4 fatal error\n"); ++ amvdec_abort(sess); ++ return IRQ_HANDLED; ++ } + + reg = amvdec_read_dos(core, MREG_BUFFEROUT); +- if (reg) { +- sess->keyframe_found = 1; +- amvdec_read_dos(core, MP4_NOT_CODED_CNT); +- amvdec_read_dos(core, MP4_VOP_TIME_INC); +- buffer_index = reg & 0x7; +- amvdec_dst_buf_done_idx(sess, buffer_index, V4L2_FIELD_NONE); +- amvdec_write_dos(core, MREG_BUFFEROUT, 0); +- } ++ if (!reg) ++ goto end; + +- amvdec_write_dos(core, ASSIST_MBOX1_CLR_REG, 1); ++ sess->keyframe_found = 1; ++ buffer_index = reg & BUF_IDX_MASK; ++ if (reg & INTERLACE_FLAG) ++ field = (reg & TOP_FIELD_FIRST_FLAG) ? ++ V4L2_FIELD_INTERLACED_TB : ++ V4L2_FIELD_INTERLACED_BT; + ++ amvdec_dst_buf_done_idx(sess, buffer_index, field); ++ amvdec_write_dos(core, MREG_BUFFEROUT, 0); ++ ++end: ++ amvdec_write_dos(core, ASSIST_MBOX1_CLR_REG, 1); + return IRQ_HANDLED; + } + diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/016_linux-4.18.y-v4l-0016-h.264-fixes_and_cleanups.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/016_linux-4.18.y-v4l-0016-h.264-fixes_and_cleanups.patch new file mode 100644 index 000000000..07985c9f4 --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/016_linux-4.18.y-v4l-0016-h.264-fixes_and_cleanups.patch @@ -0,0 +1,117 @@ +From 89c2edfb991fb85fab722d087e98a40758f8ff8c Mon Sep 17 00:00:00 2001 +From: Maxime Jourdan +Date: Fri, 31 Aug 2018 14:04:10 +0200 +Subject: [PATCH] H.264: fixes & cleanups + +* fix GXL and GXM max width/height +* 80+ lines +* remove unused defines +--- + .../media/platform/meson/vdec/codec_h264.c | 24 +++++++++---------- + .../media/platform/meson/vdec/vdec_platform.c | 8 +++---- + 2 files changed, 15 insertions(+), 17 deletions(-) + +diff --git a/drivers/media/platform/meson/vdec/codec_h264.c b/drivers/media/platform/meson/vdec/codec_h264.c +index 7c47ec35efa54..decd3c601cde3 100644 +--- a/drivers/media/platform/meson/vdec/codec_h264.c ++++ b/drivers/media/platform/meson/vdec/codec_h264.c +@@ -28,14 +28,8 @@ + #define CMD_BAD_HEIGHT 8 + + /* Picture type */ +-#define PIC_SINGLE_FRAME 0 +-#define PIC_TOP_BOT_TOP 1 +-#define PIC_BOT_TOP_BOT 2 +-#define PIC_DOUBLE_FRAME 3 +-#define PIC_TRIPLE_FRAME 4 + #define PIC_TOP_BOT 5 + #define PIC_BOT_TOP 6 +-#define PIC_INVALID 7 + + /* Size of Motion Vector per macroblock */ + #define MB_MV_SIZE 96 +@@ -84,16 +78,16 @@ static int codec_h264_start(struct amvdec_session *sess) { + struct codec_h264 *h264 = sess->priv; + + /* Allocate some memory for the H.264 decoder's state */ +- h264->workspace_vaddr = +- dma_alloc_coherent(core->dev, SIZE_WORKSPACE, &h264->workspace_paddr, GFP_KERNEL); ++ h264->workspace_vaddr = dma_alloc_coherent(core->dev, SIZE_WORKSPACE, ++ &h264->workspace_paddr, GFP_KERNEL); + if (!h264->workspace_vaddr) { + dev_err(core->dev, "Failed to alloc H.264 Workspace\n"); + return -ENOMEM; + } + + /* Allocate some memory for the H.264 SEI dump */ +- h264->sei_vaddr = +- dma_alloc_coherent(core->dev, SIZE_SEI, &h264->sei_paddr, GFP_KERNEL); ++ h264->sei_vaddr = dma_alloc_coherent(core->dev, SIZE_SEI, ++ &h264->sei_paddr, GFP_KERNEL); + if (!h264->sei_vaddr) { + dev_err(core->dev, "Failed to alloc H.264 SEI\n"); + return -ENOMEM; +@@ -114,7 +108,9 @@ static int codec_h264_start(struct amvdec_session *sess) { + amvdec_write_dos(core, AV_SCRATCH_9, 0); + + /* Enable "error correction" */ +- amvdec_write_dos(core, AV_SCRATCH_F, (amvdec_read_dos(core, AV_SCRATCH_F) & 0xffffffc3) | BIT(4) | BIT(7)); ++ amvdec_write_dos(core, AV_SCRATCH_F, ++ (amvdec_read_dos(core, AV_SCRATCH_F) & 0xffffffc3) | ++ BIT(4) | BIT(7)); + + amvdec_write_dos(core, MDEC_PIC_DC_THRESH, 0x404038aa); + +@@ -145,7 +141,8 @@ static int codec_h264_stop(struct amvdec_session *sess) + return 0; + } + +-static int codec_h264_load_extended_firmware(struct amvdec_session *sess, const u8 *data, u32 len) ++static int codec_h264_load_extended_firmware(struct amvdec_session *sess, ++ const u8 *data, u32 len) + { + struct codec_h264 *h264; + struct amvdec_core *core = sess->core; +@@ -160,7 +157,7 @@ static int codec_h264_load_extended_firmware(struct amvdec_session *sess, const + return -EINVAL; + + h264->ext_fw_vaddr = dma_alloc_coherent(core->dev, SIZE_EXT_FW, +- &h264->ext_fw_paddr, GFP_KERNEL); ++ &h264->ext_fw_paddr, GFP_KERNEL); + if (!h264->ext_fw_vaddr) { + dev_err(core->dev, "Failed to alloc H.264 extended fw\n"); + return -ENOMEM; +@@ -275,6 +272,7 @@ static void codec_h264_frames_ready(struct amvdec_session *sess, u32 status) + + amvdec_dst_buf_done_idx(sess, buffer_index, field); + ++ /* 2 src packets per dst frame ; delete additional timestamp */ + if (field != V4L2_FIELD_NONE && !h264->received_0) + amvdec_rm_first_ts(sess); + +diff --git a/drivers/media/platform/meson/vdec/vdec_platform.c b/drivers/media/platform/meson/vdec/vdec_platform.c +index a8d03426e53d0..99dd3ae9c463b 100644 +--- a/drivers/media/platform/meson/vdec/vdec_platform.c ++++ b/drivers/media/platform/meson/vdec/vdec_platform.c +@@ -154,8 +154,8 @@ static const struct amvdec_format vdec_formats_gxl[] = { + .pixfmt = V4L2_PIX_FMT_H264, + .min_buffers = 21, + .max_buffers = 24, +- .max_width = 1920, +- .max_height = 1080, ++ .max_width = 3840, ++ .max_height = 2160, + .vdec_ops = &vdec_1_ops, + .codec_ops = &codec_h264_ops, + .firmware_path = "meson/gxl/vh264_mc", +@@ -238,8 +238,8 @@ static const struct amvdec_format vdec_formats_gxm[] = { + .pixfmt = V4L2_PIX_FMT_H264, + .min_buffers = 21, + .max_buffers = 24, +- .max_width = 1920, +- .max_height = 1080, ++ .max_width = 3840, ++ .max_height = 2160, + .vdec_ops = &vdec_1_ops, + .codec_ops = &codec_h264_ops, + .firmware_path = "meson/gxm/vh264_mc", diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/017_linux-4.18.y-v4l-1001-WIP-drm-meson-support_overlay_plane_for_video_rendering.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/017_linux-4.18.y-v4l-1001-WIP-drm-meson-support_overlay_plane_for_video_rendering.patch new file mode 100644 index 000000000..f688e981c --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/017_linux-4.18.y-v4l-1001-WIP-drm-meson-support_overlay_plane_for_video_rendering.patch @@ -0,0 +1,1146 @@ +From e7d20033306bbbb66fd83fb98795e573d70d8f7b Mon Sep 17 00:00:00 2001 +From: Neil Armstrong +Date: Thu, 2 Aug 2018 10:00:01 +0200 +Subject: [PATCH] [WIP] drm/meson: Support Overlay plane for video rendering + +The Amlogic Meson GX SoCs support an Overlay plane behind the primary +plan for video rendering. +This Overlay plane support various YUV layouts and a non-alpha RGB32 +layout. +--- + drivers/gpu/drm/meson/Makefile | 2 +- + drivers/gpu/drm/meson/meson_crtc.c | 172 ++++++- + drivers/gpu/drm/meson/meson_drv.c | 14 + + drivers/gpu/drm/meson/meson_drv.h | 52 +++ + drivers/gpu/drm/meson/meson_overlay.c | 595 ++++++++++++++++++++++++ + drivers/gpu/drm/meson/meson_overlay.h | 14 + + drivers/gpu/drm/meson/meson_registers.h | 3 + + drivers/gpu/drm/meson/meson_viu.c | 15 + + drivers/gpu/drm/meson/meson_vpp.c | 44 +- + drivers/soc/amlogic/meson-gx-pwrc-vpu.c | 8 +- + 10 files changed, 912 insertions(+), 7 deletions(-) + create mode 100644 drivers/gpu/drm/meson/meson_overlay.c + create mode 100644 drivers/gpu/drm/meson/meson_overlay.h + +diff --git a/drivers/gpu/drm/meson/Makefile b/drivers/gpu/drm/meson/Makefile +index bd67429185ff7..d4ea82fc493b6 100644 +--- a/drivers/gpu/drm/meson/Makefile ++++ b/drivers/gpu/drm/meson/Makefile +@@ -1,5 +1,5 @@ + meson-drm-y := meson_drv.o meson_plane.o meson_crtc.o meson_venc_cvbs.o +-meson-drm-y += meson_viu.o meson_vpp.o meson_venc.o meson_vclk.o ++meson-drm-y += meson_viu.o meson_vpp.o meson_venc.o meson_vclk.o meson_overlay.o + + obj-$(CONFIG_DRM_MESON) += meson-drm.o + obj-$(CONFIG_DRM_MESON_DW_HDMI) += meson_dw_hdmi.o +diff --git a/drivers/gpu/drm/meson/meson_crtc.c b/drivers/gpu/drm/meson/meson_crtc.c +index 1ca9c6c45f9b9..a4b9463f8125a 100644 +--- a/drivers/gpu/drm/meson/meson_crtc.c ++++ b/drivers/gpu/drm/meson/meson_crtc.c +@@ -25,6 +25,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -97,6 +98,10 @@ static void meson_crtc_atomic_enable(struct drm_crtc *crtc, + writel(crtc_state->mode.hdisplay, + priv->io_base + _REG(VPP_POSTBLEND_H_SIZE)); + ++ /* VD1 Preblend vertical start/end */ ++ writel(FIELD_PREP(GENMASK(11, 0), 2303), ++ priv->io_base + _REG(VPP_PREBLEND_VD1_V_START_END)); ++ + writel_bits_relaxed(VPP_POSTBLEND_ENABLE, VPP_POSTBLEND_ENABLE, + priv->io_base + _REG(VPP_MISC)); + +@@ -109,11 +114,17 @@ static void meson_crtc_atomic_disable(struct drm_crtc *crtc, + struct meson_crtc *meson_crtc = to_meson_crtc(crtc); + struct meson_drm *priv = meson_crtc->priv; + ++ DRM_DEBUG_DRIVER("\n"); ++ + priv->viu.osd1_enabled = false; + priv->viu.osd1_commit = false; + ++ priv->viu.vd1_enabled = false; ++ priv->viu.vd1_commit = false; ++ + /* Disable VPP Postblend */ +- writel_bits_relaxed(VPP_POSTBLEND_ENABLE, 0, ++ writel_bits_relaxed(VPP_OSD1_POSTBLEND | VPP_VD1_POSTBLEND | ++ VPP_VD1_PREBLEND | VPP_POSTBLEND_ENABLE, 0, + priv->io_base + _REG(VPP_MISC)); + + if (crtc->state->event && !crtc->state->active) { +@@ -148,6 +159,7 @@ static void meson_crtc_atomic_flush(struct drm_crtc *crtc, + struct meson_drm *priv = meson_crtc->priv; + + priv->viu.osd1_commit = true; ++ priv->viu.vd1_commit = true; + } + + static const struct drm_crtc_helper_funcs meson_crtc_helper_funcs = { +@@ -204,6 +216,164 @@ void meson_crtc_irq(struct meson_drm *priv) + priv->viu.osd1_commit = false; + } + ++ /* Update the VD1 registers */ ++ if (priv->viu.vd1_enabled && priv->viu.vd1_commit) { ++ ++ switch (priv->viu.vd1_planes) { ++ case 3: ++ meson_canvas_config(priv->canvas, priv->canvas_id_vd1_2, ++ priv->viu.vd1_addr2, priv->viu.vd1_stride2, ++ priv->viu.vd1_height2, MESON_CANVAS_WRAP_NONE, ++ MESON_CANVAS_BLKMODE_LINEAR, MESON_CANVAS_ENDIAN_SWAP64); ++ case 2: ++ meson_canvas_config(priv->canvas, priv->canvas_id_vd1_1, ++ priv->viu.vd1_addr1, priv->viu.vd1_stride1, ++ priv->viu.vd1_height1, MESON_CANVAS_WRAP_NONE, ++ MESON_CANVAS_BLKMODE_LINEAR, MESON_CANVAS_ENDIAN_SWAP64); ++ case 1: ++ meson_canvas_config(priv->canvas, priv->canvas_id_vd1_0, ++ priv->viu.vd1_addr0, priv->viu.vd1_stride0, ++ priv->viu.vd1_height0, MESON_CANVAS_WRAP_NONE, ++ MESON_CANVAS_BLKMODE_LINEAR, MESON_CANVAS_ENDIAN_SWAP64); ++ }; ++ ++ writel_relaxed(priv->viu.vd1_if0_gen_reg, ++ priv->io_base + _REG(VD1_IF0_GEN_REG)); ++ writel_relaxed(priv->viu.vd1_if0_gen_reg, ++ priv->io_base + _REG(VD2_IF0_GEN_REG)); ++ writel_relaxed(priv->viu.vd1_if0_gen_reg2, ++ priv->io_base + _REG(VD1_IF0_GEN_REG2)); ++ writel_relaxed(priv->viu.viu_vd1_fmt_ctrl, ++ priv->io_base + _REG(VIU_VD1_FMT_CTRL)); ++ writel_relaxed(priv->viu.viu_vd1_fmt_ctrl, ++ priv->io_base + _REG(VIU_VD2_FMT_CTRL)); ++ writel_relaxed(priv->viu.viu_vd1_fmt_w, ++ priv->io_base + _REG(VIU_VD1_FMT_W)); ++ writel_relaxed(priv->viu.viu_vd1_fmt_w, ++ priv->io_base + _REG(VIU_VD2_FMT_W)); ++ writel_relaxed(priv->viu.vd1_if0_canvas0, ++ priv->io_base + _REG(VD1_IF0_CANVAS0)); ++ writel_relaxed(priv->viu.vd1_if0_canvas0, ++ priv->io_base + _REG(VD1_IF0_CANVAS1)); ++ writel_relaxed(priv->viu.vd1_if0_canvas0, ++ priv->io_base + _REG(VD2_IF0_CANVAS0)); ++ writel_relaxed(priv->viu.vd1_if0_canvas0, ++ priv->io_base + _REG(VD2_IF0_CANVAS1)); ++ writel_relaxed(priv->viu.vd1_if0_luma_x0, ++ priv->io_base + _REG(VD1_IF0_LUMA_X0)); ++ writel_relaxed(priv->viu.vd1_if0_luma_x0, ++ priv->io_base + _REG(VD1_IF0_LUMA_X1)); ++ writel_relaxed(priv->viu.vd1_if0_luma_x0, ++ priv->io_base + _REG(VD2_IF0_LUMA_X0)); ++ writel_relaxed(priv->viu.vd1_if0_luma_x0, ++ priv->io_base + _REG(VD2_IF0_LUMA_X1)); ++ writel_relaxed(priv->viu.vd1_if0_luma_y0, ++ priv->io_base + _REG(VD1_IF0_LUMA_Y0)); ++ writel_relaxed(priv->viu.vd1_if0_luma_y0, ++ priv->io_base + _REG(VD1_IF0_LUMA_Y1)); ++ writel_relaxed(priv->viu.vd1_if0_luma_y0, ++ priv->io_base + _REG(VD2_IF0_LUMA_Y0)); ++ writel_relaxed(priv->viu.vd1_if0_luma_y0, ++ priv->io_base + _REG(VD2_IF0_LUMA_Y1)); ++ writel_relaxed(priv->viu.vd1_if0_chroma_x0, ++ priv->io_base + _REG(VD1_IF0_CHROMA_X0)); ++ writel_relaxed(priv->viu.vd1_if0_chroma_x0, ++ priv->io_base + _REG(VD1_IF0_CHROMA_X1)); ++ writel_relaxed(priv->viu.vd1_if0_chroma_x0, ++ priv->io_base + _REG(VD2_IF0_CHROMA_X0)); ++ writel_relaxed(priv->viu.vd1_if0_chroma_x0, ++ priv->io_base + _REG(VD2_IF0_CHROMA_X1)); ++ writel_relaxed(priv->viu.vd1_if0_chroma_y0, ++ priv->io_base + _REG(VD1_IF0_CHROMA_Y0)); ++ writel_relaxed(priv->viu.vd1_if0_chroma_y0, ++ priv->io_base + _REG(VD1_IF0_CHROMA_Y1)); ++ writel_relaxed(priv->viu.vd1_if0_chroma_y0, ++ priv->io_base + _REG(VD2_IF0_CHROMA_Y0)); ++ writel_relaxed(priv->viu.vd1_if0_chroma_y0, ++ priv->io_base + _REG(VD2_IF0_CHROMA_Y1)); ++ writel_relaxed(priv->viu.vd1_if0_repeat_loop, ++ priv->io_base + _REG(VD1_IF0_RPT_LOOP)); ++ writel_relaxed(priv->viu.vd1_if0_repeat_loop, ++ priv->io_base + _REG(VD2_IF0_RPT_LOOP)); ++ writel_relaxed(priv->viu.vd1_if0_luma0_rpt_pat, ++ priv->io_base + _REG(VD1_IF0_LUMA0_RPT_PAT)); ++ writel_relaxed(priv->viu.vd1_if0_luma0_rpt_pat, ++ priv->io_base + _REG(VD2_IF0_LUMA0_RPT_PAT)); ++ writel_relaxed(priv->viu.vd1_if0_luma0_rpt_pat, ++ priv->io_base + _REG(VD1_IF0_LUMA1_RPT_PAT)); ++ writel_relaxed(priv->viu.vd1_if0_luma0_rpt_pat, ++ priv->io_base + _REG(VD2_IF0_LUMA1_RPT_PAT)); ++ writel_relaxed(priv->viu.vd1_if0_chroma0_rpt_pat, ++ priv->io_base + _REG(VD1_IF0_CHROMA0_RPT_PAT)); ++ writel_relaxed(priv->viu.vd1_if0_chroma0_rpt_pat, ++ priv->io_base + _REG(VD2_IF0_CHROMA0_RPT_PAT)); ++ writel_relaxed(priv->viu.vd1_if0_chroma0_rpt_pat, ++ priv->io_base + _REG(VD1_IF0_CHROMA1_RPT_PAT)); ++ writel_relaxed(priv->viu.vd1_if0_chroma0_rpt_pat, ++ priv->io_base + _REG(VD2_IF0_CHROMA1_RPT_PAT)); ++ writel_relaxed(0, priv->io_base + _REG(VD1_IF0_LUMA_PSEL)); ++ writel_relaxed(0, priv->io_base + _REG(VD1_IF0_CHROMA_PSEL)); ++ writel_relaxed(0, priv->io_base + _REG(VD2_IF0_LUMA_PSEL)); ++ writel_relaxed(0, priv->io_base + _REG(VD2_IF0_CHROMA_PSEL)); ++ writel_relaxed(priv->viu.vd1_range_map_y, ++ priv->io_base + _REG(VD1_IF0_RANGE_MAP_Y)); ++ writel_relaxed(priv->viu.vd1_range_map_cb, ++ priv->io_base + _REG(VD1_IF0_RANGE_MAP_CB)); ++ writel_relaxed(priv->viu.vd1_range_map_cr, ++ priv->io_base + _REG(VD1_IF0_RANGE_MAP_CR)); ++ writel_relaxed(0x78404, ++ priv->io_base + _REG(VPP_SC_MISC)); ++ writel_relaxed(priv->viu.vpp_pic_in_height, ++ priv->io_base + _REG(VPP_PIC_IN_HEIGHT)); ++ writel_relaxed(priv->viu.vpp_postblend_vd1_h_start_end, ++ priv->io_base + _REG(VPP_POSTBLEND_VD1_H_START_END)); ++ writel_relaxed(priv->viu.vpp_blend_vd2_h_start_end, ++ priv->io_base + _REG(VPP_BLEND_VD2_H_START_END)); ++ writel_relaxed(priv->viu.vpp_postblend_vd1_v_start_end, ++ priv->io_base + _REG(VPP_POSTBLEND_VD1_V_START_END)); ++ writel_relaxed(priv->viu.vpp_blend_vd2_v_start_end, ++ priv->io_base + _REG(VPP_BLEND_VD2_V_START_END)); ++ writel_relaxed(priv->viu.vpp_hsc_region12_startp, ++ priv->io_base + _REG(VPP_HSC_REGION12_STARTP)); ++ writel_relaxed(priv->viu.vpp_hsc_region34_startp, ++ priv->io_base + _REG(VPP_HSC_REGION34_STARTP)); ++ writel_relaxed(priv->viu.vpp_hsc_region4_endp, ++ priv->io_base + _REG(VPP_HSC_REGION4_ENDP)); ++ writel_relaxed(priv->viu.vpp_hsc_start_phase_step, ++ priv->io_base + _REG(VPP_HSC_START_PHASE_STEP)); ++ writel_relaxed(priv->viu.vpp_hsc_region1_phase_slope, ++ priv->io_base + _REG(VPP_HSC_REGION1_PHASE_SLOPE)); ++ writel_relaxed(priv->viu.vpp_hsc_region3_phase_slope, ++ priv->io_base + _REG(VPP_HSC_REGION3_PHASE_SLOPE)); ++ writel_relaxed(priv->viu.vpp_line_in_length, ++ priv->io_base + _REG(VPP_LINE_IN_LENGTH)); ++ writel_relaxed(priv->viu.vpp_preblend_h_size, ++ priv->io_base + _REG(VPP_PREBLEND_H_SIZE)); ++ writel_relaxed(priv->viu.vpp_vsc_region12_startp, ++ priv->io_base + _REG(VPP_VSC_REGION12_STARTP)); ++ writel_relaxed(priv->viu.vpp_vsc_region34_startp, ++ priv->io_base + _REG(VPP_VSC_REGION34_STARTP)); ++ writel_relaxed(priv->viu.vpp_vsc_region4_endp, ++ priv->io_base + _REG(VPP_VSC_REGION4_ENDP)); ++ writel_relaxed(priv->viu.vpp_vsc_start_phase_step, ++ priv->io_base + _REG(VPP_VSC_START_PHASE_STEP)); ++ writel_relaxed(priv->viu.vpp_vsc_ini_phase, ++ priv->io_base + _REG(VPP_VSC_INI_PHASE)); ++ writel_relaxed(priv->viu.vpp_vsc_phase_ctrl, ++ priv->io_base + _REG(VPP_VSC_PHASE_CTRL)); ++ writel_relaxed(priv->viu.vpp_hsc_phase_ctrl, ++ priv->io_base + _REG(VPP_HSC_PHASE_CTRL)); ++ writel_relaxed(0x00000042, ++ priv->io_base + _REG(VPP_SCALE_COEF_IDX)); ++ ++ /* Enable VD1 */ ++ writel_bits_relaxed(VPP_VD1_PREBLEND | VPP_VD1_POSTBLEND | VPP_COLOR_MNG_ENABLE, ++ VPP_VD1_PREBLEND | VPP_VD1_POSTBLEND | VPP_COLOR_MNG_ENABLE, ++ priv->io_base + _REG(VPP_MISC)); ++ ++ priv->viu.vd1_commit = false; ++ } ++ + drm_crtc_handle_vblank(priv->crtc); + + spin_lock_irqsave(&priv->drm->event_lock, flags); +diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c +index fb5b0e3c5efce..04b634eade20d 100644 +--- a/drivers/gpu/drm/meson/meson_drv.c ++++ b/drivers/gpu/drm/meson/meson_drv.c +@@ -41,6 +41,7 @@ + + #include "meson_drv.h" + #include "meson_plane.h" ++#include "meson_overlay.h" + #include "meson_crtc.h" + #include "meson_venc_cvbs.h" + +@@ -222,6 +223,15 @@ static int meson_drv_bind_master(struct device *dev, bool has_components) + } + + ret = meson_canvas_alloc(priv->canvas, &priv->canvas_id_osd1); ++ if (ret) ++ goto free_drm; ++ ret = meson_canvas_alloc(priv->canvas, &priv->canvas_id_vd1_0); ++ if (ret) ++ goto free_drm; ++ ret = meson_canvas_alloc(priv->canvas, &priv->canvas_id_vd1_1); ++ if (ret) ++ goto free_drm; ++ ret = meson_canvas_alloc(priv->canvas, &priv->canvas_id_vd1_2); + if (ret) + goto free_drm; + +@@ -261,6 +271,10 @@ static int meson_drv_bind_master(struct device *dev, bool has_components) + if (ret) + goto free_drm; + ++ ret = meson_overlay_create(priv); ++ if (ret) ++ goto free_drm; ++ + ret = meson_crtc_create(priv); + if (ret) + goto free_drm; +diff --git a/drivers/gpu/drm/meson/meson_drv.h b/drivers/gpu/drm/meson/meson_drv.h +index 9e902a6df7843..cc2288cc3858e 100644 +--- a/drivers/gpu/drm/meson/meson_drv.h ++++ b/drivers/gpu/drm/meson/meson_drv.h +@@ -33,11 +33,15 @@ struct meson_drm { + + struct meson_canvas *canvas; + u8 canvas_id_osd1; ++ u8 canvas_id_vd1_0; ++ u8 canvas_id_vd1_1; ++ u8 canvas_id_vd1_2; + + struct drm_device *drm; + struct drm_crtc *crtc; + struct drm_fbdev_cma *fbdev; + struct drm_plane *primary_plane; ++ struct drm_plane *overlay_plane; + + /* Components Data */ + struct { +@@ -49,6 +53,54 @@ struct meson_drm { + uint32_t osd1_addr; + uint32_t osd1_stride; + uint32_t osd1_height; ++ ++ bool vd1_enabled; ++ bool vd1_commit; ++ unsigned int vd1_planes; ++ uint32_t vd1_if0_gen_reg; ++ uint32_t vd1_if0_luma_x0; ++ uint32_t vd1_if0_luma_y0; ++ uint32_t vd1_if0_chroma_x0; ++ uint32_t vd1_if0_chroma_y0; ++ uint32_t vd1_if0_repeat_loop; ++ uint32_t vd1_if0_luma0_rpt_pat; ++ uint32_t vd1_if0_chroma0_rpt_pat; ++ uint32_t vd1_range_map_y; ++ uint32_t vd1_range_map_cb; ++ uint32_t vd1_range_map_cr; ++ uint32_t viu_vd1_fmt_w; ++ uint32_t vd1_if0_canvas0; ++ uint32_t vd1_if0_gen_reg2; ++ uint32_t viu_vd1_fmt_ctrl; ++ uint32_t vd1_addr0; ++ uint32_t vd1_addr1; ++ uint32_t vd1_addr2; ++ uint32_t vd1_stride0; ++ uint32_t vd1_stride1; ++ uint32_t vd1_stride2; ++ uint32_t vd1_height0; ++ uint32_t vd1_height1; ++ uint32_t vd1_height2; ++ uint32_t vpp_pic_in_height; ++ uint32_t vpp_postblend_vd1_h_start_end; ++ uint32_t vpp_postblend_vd1_v_start_end; ++ uint32_t vpp_hsc_region12_startp; ++ uint32_t vpp_hsc_region34_startp; ++ uint32_t vpp_hsc_region4_endp; ++ uint32_t vpp_hsc_start_phase_step; ++ uint32_t vpp_hsc_region1_phase_slope; ++ uint32_t vpp_hsc_region3_phase_slope; ++ uint32_t vpp_line_in_length; ++ uint32_t vpp_preblend_h_size; ++ uint32_t vpp_vsc_region12_startp; ++ uint32_t vpp_vsc_region34_startp; ++ uint32_t vpp_vsc_region4_endp; ++ uint32_t vpp_vsc_start_phase_step; ++ uint32_t vpp_vsc_ini_phase; ++ uint32_t vpp_vsc_phase_ctrl; ++ uint32_t vpp_hsc_phase_ctrl; ++ uint32_t vpp_blend_vd2_h_start_end; ++ uint32_t vpp_blend_vd2_v_start_end; + } viu; + + struct { +diff --git a/drivers/gpu/drm/meson/meson_overlay.c b/drivers/gpu/drm/meson/meson_overlay.c +new file mode 100644 +index 0000000000000..ea7261aa2bdd5 +--- /dev/null ++++ b/drivers/gpu/drm/meson/meson_overlay.c +@@ -0,0 +1,595 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright (C) 2018 BayLibre, SAS ++ * Author: Neil Armstrong ++ * Copyright (C) 2015 Amlogic, Inc. All rights reserved. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "meson_overlay.h" ++#include "meson_vpp.h" ++#include "meson_viu.h" ++#include "meson_registers.h" ++ ++/* VD1_IF0_GEN_REG */ ++#define VD_URGENT_CHROMA BIT(28) ++#define VD_URGENT_LUMA BIT(27) ++#define VD_HOLD_LINES(lines) FIELD_PREP(GENMASK(24, 19), lines) ++#define VD_DEMUX_MODE_RGB BIT(16) ++#define VD_BYTES_PER_PIXEL(val) FIELD_PREP(GENMASK(15, 14), val) ++#define VD_CHRO_RPT_LASTL_CTRL BIT(6) ++#define VD_LITTLE_ENDIAN BIT(4) ++#define VD_SEPARATE_EN BIT(1) ++#define VD_ENABLE BIT(0) ++ ++/* VD1_IF0_CANVAS0 */ ++#define CANVAS_ADDR2(addr) FIELD_PREP(GENMASK(23, 16), addr) ++#define CANVAS_ADDR1(addr) FIELD_PREP(GENMASK(15, 8), addr) ++#define CANVAS_ADDR0(addr) FIELD_PREP(GENMASK(7, 0), addr) ++ ++/* VD1_IF0_LUMA_X0 VD1_IF0_CHROMA_X0 */ ++#define VD_X_START(value) FIELD_PREP(GENMASK(14, 0), value) ++#define VD_X_END(value) FIELD_PREP(GENMASK(30, 16), value) ++ ++/* VD1_IF0_LUMA_Y0 VD1_IF0_CHROMA_Y0 */ ++#define VD_Y_START(value) FIELD_PREP(GENMASK(12, 0), value) ++#define VD_Y_END(value) FIELD_PREP(GENMASK(28, 16), value) ++ ++/* VD1_IF0_GEN_REG2 */ ++#define VD_COLOR_MAP(value) FIELD_PREP(GENMASK(1, 0), value) ++ ++/* VIU_VD1_FMT_CTRL */ ++#define VD_HORZ_Y_C_RATIO(value) FIELD_PREP(GENMASK(22, 21), value) ++#define VD_HORZ_FMT_EN BIT(20) ++#define VD_VERT_RPT_LINE0 BIT(16) ++#define VD_VERT_INITIAL_PHASE(value) FIELD_PREP(GENMASK(11, 8), value) ++#define VD_VERT_PHASE_STEP(value) FIELD_PREP(GENMASK(7, 1), value) ++#define VD_VERT_FMT_EN BIT(0) ++ ++/* VPP_POSTBLEND_VD1_H_START_END */ ++#define VD_H_END(value) FIELD_PREP(GENMASK(11, 0), value) ++#define VD_H_START(value) FIELD_PREP(GENMASK(27, 16), value) ++ ++/* VPP_POSTBLEND_VD1_V_START_END */ ++#define VD_V_END(value) FIELD_PREP(GENMASK(11, 0), value) ++#define VD_V_START(value) FIELD_PREP(GENMASK(27, 16), value) ++ ++/* VPP_BLEND_VD2_V_START_END */ ++#define VD2_V_END(value) FIELD_PREP(GENMASK(11, 0), value) ++#define VD2_V_START(value) FIELD_PREP(GENMASK(27, 16), value) ++ ++/* VIU_VD1_FMT_W */ ++#define VD_V_WIDTH(value) FIELD_PREP(GENMASK(11, 0), value) ++#define VD_H_WIDTH(value) FIELD_PREP(GENMASK(27, 16), value) ++ ++/* VPP_HSC_REGION12_STARTP VPP_HSC_REGION34_STARTP */ ++#define VD_REGION24_START(value) FIELD_PREP(GENMASK(11, 0), value) ++#define VD_REGION13_END(value) FIELD_PREP(GENMASK(27, 16), value) ++ ++struct meson_overlay { ++ struct drm_plane base; ++ struct meson_drm *priv; ++}; ++#define to_meson_overlay(x) container_of(x, struct meson_overlay, base) ++ ++#define FRAC_16_16(mult, div) (((mult) << 16) / (div)) ++ ++static int meson_overlay_atomic_check(struct drm_plane *plane, ++ struct drm_plane_state *state) ++{ ++ struct drm_crtc_state *crtc_state; ++ ++ if (!state->crtc) ++ return 0; ++ ++ crtc_state = drm_atomic_get_crtc_state(state->state, state->crtc); ++ if (IS_ERR(crtc_state)) ++ return PTR_ERR(crtc_state); ++ ++ return drm_atomic_helper_check_plane_state(state, crtc_state, ++ FRAC_16_16(1, 5), ++ FRAC_16_16(5, 1), ++ true, true); ++} ++ ++/* Takes a fixed 16.16 number and converts it to integer. */ ++static inline int64_t fixed16_to_int(int64_t value) ++{ ++ return value >> 16; ++} ++ ++static const uint8_t skip_tab[6] = {0x24, 0x04, 0x68, 0x48, 0x28, 0x08}; ++ ++static void meson_overlay_get_vertical_phase(unsigned ratio_y, ++ int *phase, ++ int *repeat, ++ bool interlace) ++{ ++ int offset_in = 0; ++ int offset_out = 0; ++ int repeat_skip = 0; ++ ++ if (!interlace && ratio_y > (1 << 18)) { ++ offset_out = (1 * ratio_y) >> 10; ++ } ++ ++ while ((offset_in + (4 << 8)) <= offset_out) { ++ repeat_skip++; ++ offset_in += 4 << 8; ++ } ++ ++ *phase = (offset_out - offset_in) >> 2; ++ ++ if (*phase > 0x100) ++ repeat_skip++; ++ ++ *phase = *phase & 0xff; ++ ++ if (repeat_skip > 5) ++ repeat_skip = 5; ++ ++ *repeat = skip_tab[repeat_skip]; ++} ++ ++static void meson_overlay_setup_scaler_params(struct meson_drm *priv, ++ struct drm_plane *plane, ++ bool interlace_mode) ++{ ++ struct drm_plane_state *state = plane->state; ++ struct drm_crtc_state *crtc_state = priv->crtc->state; ++ int video_top, video_left, video_width, video_height; ++ unsigned int crop_top, crop_left; ++ unsigned int crtc_height, crtc_width; ++ unsigned int vd_start_lines, vd_end_lines; ++ unsigned int hd_start_lines, hd_end_lines; ++ unsigned int vsc_startp, vsc_endp; ++ unsigned int hsc_startp, hsc_endp; ++ unsigned int ratio_x, ratio_y; ++ unsigned int w_in, h_in; ++ int vphase, vphase_repeat_skip; ++ int temp_height, temp_width; ++ int temp, start, end; ++ ++ if (!crtc_state) { ++ DRM_ERROR("Invalid crtc_state\n"); ++ return; ++ } ++ ++ crtc_height = crtc_state->mode.vdisplay; ++ crtc_width = crtc_state->mode.hdisplay; ++ ++ w_in = fixed16_to_int(state->src_w); ++ h_in = fixed16_to_int(state->src_h); ++ crop_top = fixed16_to_int(state->src_x); ++ crop_left = fixed16_to_int(state->src_x); ++ ++ video_top = state->crtc_y; ++ video_left = state->crtc_x; ++ video_width = state->crtc_w; ++ video_height = state->crtc_h; ++ ++ DRM_DEBUG("crtc_width %d crtc_height %d interlace %d\n", ++ crtc_width, crtc_height, interlace_mode); ++ DRM_DEBUG("w_in %d h_in %d crop_top %d crop_left %d\n", ++ w_in, h_in, crop_top, crop_left); ++ DRM_DEBUG("video top %d left %d width %d height %d\n", ++ video_top, video_left, video_width, video_height); ++ ++ ratio_x = (w_in << 18) / video_width; ++ ratio_y = (h_in << 18) / video_height; ++ ++ /* TOFIX Interlace output */ ++ if (interlace_mode) ++ ratio_y <<= 1; ++ ++ if (ratio_x * video_width < (w_in << 18)) ++ ratio_x++; ++ ++ DRM_DEBUG("ratio x 0x%x y 0x%x\n", ratio_x, ratio_y); ++ ++ meson_overlay_get_vertical_phase(ratio_y, &vphase, &vphase_repeat_skip, ++ interlace_mode); ++ ++ DRM_DEBUG("vphase 0x%x skip %d\n", vphase, vphase_repeat_skip); ++ ++ /* Vertical */ ++ ++ start = video_top + video_height / 2 - ((h_in << 17) / ratio_x); ++ end = (h_in << 18) / ratio_y + start - 1; ++ ++ if (video_top < 0 && start < 0) ++ vd_start_lines = (-(start) * ratio_y) >> 18; ++ else if (start < video_top) ++ vd_start_lines = ((video_top - start) * ratio_y) >> 18; ++ else ++ vd_start_lines = 0; ++ ++ if (video_top < 0) ++ temp_height = min_t(unsigned int, (video_top + video_height - 1), ++ (crtc_height - 1)); ++ else ++ temp_height = min_t(unsigned int, (video_top + video_height - 1), ++ (crtc_height - 1)) - video_top + 1; ++ ++ temp = vd_start_lines + (temp_height * ratio_y >> 18); ++ vd_end_lines = (temp <= (h_in - 1)) ? temp : (h_in - 1); ++ ++ vd_start_lines += crop_left; ++ vd_end_lines += crop_left; ++ ++ if (interlace_mode) { ++ start >>= 1; ++ end >>= 1; ++ } ++ ++ vsc_startp = max_t(int, start, ++ max_t(int, 0, video_top)); ++ vsc_endp = min_t(int, end, ++ min_t(int, crtc_height - 1, ++ video_top + video_height - 1)); ++ ++ DRM_DEBUG("vsc startp %d endp %d start_lines %d end_lines %d\n", ++ vsc_startp, vsc_endp, vd_start_lines, vd_end_lines); ++ ++ /* Horizontal */ ++ ++ start = video_left + video_width / 2 - ((w_in << 17) / ratio_x); ++ end = (w_in << 18) / ratio_x + start - 1; ++ ++ if (video_left < 0 && start < 0) ++ hd_start_lines = (-(start) * ratio_x) >> 18; ++ else if (start < video_left) ++ hd_start_lines = ((video_left - start) * ratio_x) >> 18; ++ else ++ hd_start_lines = 0; ++ ++ if (video_left < 0) ++ temp_width = min_t(unsigned int, (video_left + video_width - 1), ++ (crtc_width - 1)); ++ else ++ temp_width = min_t(unsigned int, (video_left + video_width - 1), ++ (crtc_width - 1)) - video_left + 1; ++ ++ temp = hd_start_lines + (temp_width * ratio_x >> 18); ++ hd_end_lines = (temp <= (w_in - 1)) ? temp : (w_in - 1); ++ ++ priv->viu.vpp_line_in_length = hd_end_lines - hd_start_lines + 1; ++ hsc_startp = max_t(int, start, ++ max_t(int, 0, video_left)); ++ hsc_endp = min_t(int, end, ++ min_t(int, crtc_width - 1, ++ video_left + video_width - 1)); ++ ++ hd_start_lines += crop_top; ++ hd_end_lines += crop_top; ++ ++ DRM_DEBUG("hsc startp %d endp %d start_lines %d end_lines %d\n", ++ hsc_startp, hsc_endp, hd_start_lines, hd_end_lines); ++ ++ priv->viu.vpp_vsc_start_phase_step = ratio_y << 6; ++ ++ priv->viu.vpp_vsc_ini_phase = vphase << 8; ++ priv->viu.vpp_vsc_phase_ctrl = (1 << 13) | (4 << 8) | ++ vphase_repeat_skip; ++ ++ priv->viu.vd1_if0_luma_x0 = VD_X_START(hd_start_lines) | ++ VD_X_END(hd_end_lines); ++ priv->viu.vd1_if0_chroma_x0 = VD_X_START(hd_start_lines >> 1) | ++ VD_X_END(hd_end_lines >> 1); ++ ++ priv->viu.viu_vd1_fmt_w = VD_H_WIDTH(hd_end_lines - hd_start_lines + 1) | ++ VD_V_WIDTH(hd_end_lines/2 - hd_start_lines/2 + 1); ++ ++ priv->viu.vd1_if0_luma_y0 = VD_Y_START(vd_start_lines) | ++ VD_Y_END(vd_end_lines); ++ ++ priv->viu.vd1_if0_chroma_y0 = VD_Y_START(vd_start_lines >> 1) | ++ VD_Y_END(vd_end_lines >> 1); ++ ++ priv->viu.vpp_pic_in_height = h_in; ++ ++ priv->viu.vpp_postblend_vd1_h_start_end = VD_H_START(hsc_startp) | ++ VD_H_END(hsc_endp); ++ priv->viu.vpp_blend_vd2_h_start_end = VD_H_START(hd_start_lines) | ++ VD_H_END(hd_end_lines); ++ priv->viu.vpp_hsc_region12_startp = VD_REGION13_END(0) | ++ VD_REGION24_START(hsc_startp); ++ priv->viu.vpp_hsc_region34_startp = VD_REGION13_END(hsc_startp) | ++ VD_REGION24_START(hsc_endp - hsc_startp); ++ priv->viu.vpp_hsc_region4_endp = hsc_endp - hsc_startp; ++ priv->viu.vpp_hsc_start_phase_step = ratio_x << 6; ++ priv->viu.vpp_hsc_region1_phase_slope = 0; ++ priv->viu.vpp_hsc_region3_phase_slope = 0; ++ priv->viu.vpp_hsc_phase_ctrl = (1 << 21) | (4 << 16); ++ ++ priv->viu.vpp_line_in_length = hd_end_lines - hd_start_lines + 1; ++ priv->viu.vpp_preblend_h_size = hd_end_lines - hd_start_lines + 1; ++ ++ priv->viu.vpp_postblend_vd1_v_start_end = VD_V_START(vsc_startp) | ++ VD_V_END(vsc_endp); ++ priv->viu.vpp_blend_vd2_v_start_end = ++ VD2_V_START((vd_end_lines + 1) >> 1) | ++ VD2_V_END(vd_end_lines); ++ ++ priv->viu.vpp_vsc_region12_startp = 0; ++ priv->viu.vpp_vsc_region34_startp = ++ VD_REGION13_END(vsc_endp - vsc_startp) | ++ VD_REGION24_START(vsc_endp - vsc_startp); ++ priv->viu.vpp_vsc_region4_endp = vsc_endp - vsc_startp; ++ priv->viu.vpp_vsc_start_phase_step = ratio_y << 6; ++} ++ ++static void meson_overlay_atomic_update(struct drm_plane *plane, ++ struct drm_plane_state *old_state) ++{ ++ struct meson_overlay *meson_overlay = to_meson_overlay(plane); ++ struct drm_plane_state *state = plane->state; ++ struct drm_framebuffer *fb = state->fb; ++ struct meson_drm *priv = meson_overlay->priv; ++ struct drm_gem_cma_object *gem; ++ unsigned long flags; ++ bool interlace_mode; ++ ++ DRM_DEBUG_DRIVER("\n"); ++ ++ interlace_mode = state->crtc->mode.flags & DRM_MODE_FLAG_INTERLACE; ++ ++ /* ++ * Update Coordinates ++ * Update Formats ++ * Update Buffer ++ * Enable Plane ++ */ ++ spin_lock_irqsave(&priv->drm->event_lock, flags); ++ ++ priv->viu.vd1_if0_gen_reg = VD_URGENT_CHROMA | ++ VD_URGENT_LUMA | ++ VD_HOLD_LINES(9) | ++ VD_CHRO_RPT_LASTL_CTRL | ++ VD_ENABLE; ++ ++ /* Setup scaler params */ ++ meson_overlay_setup_scaler_params(priv, plane, interlace_mode); ++ ++ //VD1_IF0_CANVAS1=0 ++ //VD1_IF0_CHROMA_X1=0 ++ //VD1_IF0_CHROMA_Y1=0 ++ priv->viu.vd1_if0_repeat_loop = 0; ++ priv->viu.vd1_if0_luma0_rpt_pat = interlace_mode ? 8 : 0; ++ priv->viu.vd1_if0_chroma0_rpt_pat = interlace_mode ? 8 : 0; ++ //VD1_IF0_LUMA1_RPT_PAT=0 ++ //VD1_IF0_CHROMA1_RPT_PAT=0 ++ //VD1_IF0_LUMA_PSEL=0 ++ //VD1_IF0_CHROMA_PSEL=0 ++ //VD1_IF0_DUMMY_PIXEL=? ++ priv->viu.vd1_range_map_y = 0; ++ priv->viu.vd1_range_map_cb = 0; ++ priv->viu.vd1_range_map_cr = 0; ++ ++ /* Default values for RGB888/YUV444 */ ++ priv->viu.vd1_if0_gen_reg2 = 0; ++ priv->viu.viu_vd1_fmt_ctrl = 0; ++ ++ switch (fb->format->format) { ++ case DRM_FORMAT_RGB888: ++ /* TOFIX enable RGB2YUV somewhere ! */ ++ priv->viu.vd1_if0_gen_reg |= VD_DEMUX_MODE_RGB | ++ VD_BYTES_PER_PIXEL(2); ++ priv->viu.vd1_if0_canvas0 = ++ CANVAS_ADDR2(priv->canvas_id_vd1_0) | ++ CANVAS_ADDR1(priv->canvas_id_vd1_0) | ++ CANVAS_ADDR0(priv->canvas_id_vd1_0); ++ break; ++ case DRM_FORMAT_YUYV: ++ priv->viu.vd1_if0_gen_reg |= VD_BYTES_PER_PIXEL(1); ++ priv->viu.vd1_if0_canvas0 = ++ CANVAS_ADDR2(priv->canvas_id_vd1_0) | ++ CANVAS_ADDR1(priv->canvas_id_vd1_0) | ++ CANVAS_ADDR0(priv->canvas_id_vd1_0); ++ priv->viu.viu_vd1_fmt_ctrl = VD_HORZ_Y_C_RATIO(1) | /* /2 */ ++ VD_HORZ_FMT_EN | ++ VD_VERT_RPT_LINE0 | ++ VD_VERT_INITIAL_PHASE(12) | ++ VD_VERT_PHASE_STEP(16) | /* /2 */ ++ VD_VERT_FMT_EN; ++ break; ++ case DRM_FORMAT_NV12: ++ case DRM_FORMAT_NV21: ++ priv->viu.vd1_if0_gen_reg |= VD_SEPARATE_EN; ++ priv->viu.vd1_if0_canvas0 = ++ CANVAS_ADDR2(priv->canvas_id_vd1_1) | ++ CANVAS_ADDR1(priv->canvas_id_vd1_1) | ++ CANVAS_ADDR0(priv->canvas_id_vd1_0); ++ if (fb->format->format == DRM_FORMAT_NV12) ++ priv->viu.vd1_if0_gen_reg2 = VD_COLOR_MAP(1); ++ else ++ priv->viu.vd1_if0_gen_reg2 = VD_COLOR_MAP(2); ++ priv->viu.viu_vd1_fmt_ctrl = VD_HORZ_Y_C_RATIO(1) | /* /2 */ ++ VD_HORZ_FMT_EN | ++ VD_VERT_RPT_LINE0 | ++ VD_VERT_INITIAL_PHASE(12) | ++ VD_VERT_PHASE_STEP(8) | /* /4 */ ++ VD_VERT_FMT_EN; ++ break; ++ case DRM_FORMAT_YUV444: ++ case DRM_FORMAT_YUV422: ++ case DRM_FORMAT_YUV420: ++ case DRM_FORMAT_YUV411: ++ case DRM_FORMAT_YUV410: ++ priv->viu.vd1_if0_gen_reg |= VD_SEPARATE_EN; ++ priv->viu.vd1_if0_canvas0 = ++ CANVAS_ADDR2(priv->canvas_id_vd1_2) | ++ CANVAS_ADDR1(priv->canvas_id_vd1_1) | ++ CANVAS_ADDR0(priv->canvas_id_vd1_0); ++ switch (fb->format->format) { ++ case DRM_FORMAT_YUV422: ++ priv->viu.viu_vd1_fmt_ctrl = ++ VD_HORZ_Y_C_RATIO(1) | /* /2 */ ++ VD_HORZ_FMT_EN | ++ VD_VERT_RPT_LINE0 | ++ VD_VERT_INITIAL_PHASE(12) | ++ VD_VERT_PHASE_STEP(16) | /* /2 */ ++ VD_VERT_FMT_EN; ++ break; ++ case DRM_FORMAT_YUV420: ++ priv->viu.viu_vd1_fmt_ctrl = ++ VD_HORZ_Y_C_RATIO(1) | /* /2 */ ++ VD_HORZ_FMT_EN | ++ VD_VERT_RPT_LINE0 | ++ VD_VERT_INITIAL_PHASE(12) | ++ VD_VERT_PHASE_STEP(8) | /* /4 */ ++ VD_VERT_FMT_EN; ++ break; ++ case DRM_FORMAT_YUV411: ++ priv->viu.viu_vd1_fmt_ctrl = ++ VD_HORZ_Y_C_RATIO(2) | /* /4 */ ++ VD_HORZ_FMT_EN | ++ VD_VERT_RPT_LINE0 | ++ VD_VERT_INITIAL_PHASE(12) | ++ VD_VERT_PHASE_STEP(16) | /* /2 */ ++ VD_VERT_FMT_EN; ++ break; ++ case DRM_FORMAT_YUV410: ++ priv->viu.viu_vd1_fmt_ctrl = ++ VD_HORZ_Y_C_RATIO(2) | /* /4 */ ++ VD_HORZ_FMT_EN | ++ VD_VERT_RPT_LINE0 | ++ VD_VERT_INITIAL_PHASE(12) | ++ VD_VERT_PHASE_STEP(8) | /* /4 */ ++ VD_VERT_FMT_EN; ++ break; ++ } ++ break; ++ } ++ ++ /* Update Canvas with buffer address */ ++ priv->viu.vd1_planes = drm_format_num_planes(fb->format->format); ++ ++ switch (priv->viu.vd1_planes) { ++ case 3: ++ gem = drm_fb_cma_get_gem_obj(fb, 2); ++ priv->viu.vd1_addr2 = gem->paddr + fb->offsets[2]; ++ priv->viu.vd1_stride2 = fb->pitches[2]; ++ priv->viu.vd1_height2 = ++ drm_format_plane_height(fb->height, ++ fb->format->format, 2); ++ DRM_DEBUG("plane 2 addr 0x%x stride %d height %d\n", ++ priv->viu.vd1_addr2, ++ priv->viu.vd1_stride2, ++ priv->viu.vd1_height2); ++ case 2: ++ gem = drm_fb_cma_get_gem_obj(fb, 1); ++ priv->viu.vd1_addr1 = gem->paddr + fb->offsets[1]; ++ priv->viu.vd1_stride1 = fb->pitches[1]; ++ priv->viu.vd1_height1 = ++ drm_format_plane_height(fb->height, ++ fb->format->format, 1); ++ DRM_DEBUG("plane 1 addr 0x%x stride %d height %d\n", ++ priv->viu.vd1_addr1, ++ priv->viu.vd1_stride1, ++ priv->viu.vd1_height1); ++ case 1: ++ gem = drm_fb_cma_get_gem_obj(fb, 0); ++ priv->viu.vd1_addr0 = gem->paddr + fb->offsets[0]; ++ priv->viu.vd1_stride0 = fb->pitches[0]; ++ priv->viu.vd1_height0 = ++ drm_format_plane_height(fb->height, ++ fb->format->format, 0); ++ DRM_DEBUG("plane 0 addr 0x%x stride %d height %d\n", ++ priv->viu.vd1_addr0, ++ priv->viu.vd1_stride0, ++ priv->viu.vd1_height0); ++ } ++ ++ priv->viu.vd1_enabled = true; ++ ++ spin_unlock_irqrestore(&priv->drm->event_lock, flags); ++ ++ DRM_DEBUG_DRIVER("\n"); ++} ++ ++static void meson_overlay_atomic_disable(struct drm_plane *plane, ++ struct drm_plane_state *old_state) ++{ ++ struct meson_overlay *meson_overlay = to_meson_overlay(plane); ++ struct meson_drm *priv = meson_overlay->priv; ++ ++ DRM_DEBUG_DRIVER("\n"); ++ ++ priv->viu.vd1_enabled = false; ++ ++ /* Disable VD1 */ ++ writel_bits_relaxed(VPP_VD1_POSTBLEND | VPP_VD1_PREBLEND, 0, ++ priv->io_base + _REG(VPP_MISC)); ++ ++} ++ ++static const struct drm_plane_helper_funcs meson_overlay_helper_funcs = { ++ .atomic_check = meson_overlay_atomic_check, ++ .atomic_disable = meson_overlay_atomic_disable, ++ .atomic_update = meson_overlay_atomic_update, ++}; ++ ++static const struct drm_plane_funcs meson_overlay_funcs = { ++ .update_plane = drm_atomic_helper_update_plane, ++ .disable_plane = drm_atomic_helper_disable_plane, ++ .destroy = drm_plane_cleanup, ++ .reset = drm_atomic_helper_plane_reset, ++ .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, ++ .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, ++}; ++ ++static const uint32_t supported_drm_formats[] = { ++ DRM_FORMAT_RGB888, ++ DRM_FORMAT_YUYV, ++ DRM_FORMAT_NV12, ++ DRM_FORMAT_NV21, ++ DRM_FORMAT_YUV444, ++ DRM_FORMAT_YUV422, ++ DRM_FORMAT_YUV420, ++ DRM_FORMAT_YUV411, ++ DRM_FORMAT_YUV410, ++}; ++ ++int meson_overlay_create(struct meson_drm *priv) ++{ ++ struct meson_overlay *meson_overlay; ++ struct drm_plane *plane; ++ ++ DRM_DEBUG_DRIVER("\n"); ++ ++ meson_overlay = devm_kzalloc(priv->drm->dev, sizeof(*meson_overlay), ++ GFP_KERNEL); ++ if (!meson_overlay) ++ return -ENOMEM; ++ ++ meson_overlay->priv = priv; ++ plane = &meson_overlay->base; ++ ++ drm_universal_plane_init(priv->drm, plane, 0xFF, ++ &meson_overlay_funcs, ++ supported_drm_formats, ++ ARRAY_SIZE(supported_drm_formats), ++ NULL, ++ DRM_PLANE_TYPE_OVERLAY, "meson_overlay_plane"); ++ ++ drm_plane_helper_add(plane, &meson_overlay_helper_funcs); ++ ++ priv->overlay_plane = plane; ++ ++ DRM_DEBUG_DRIVER("\n"); ++ ++ return 0; ++} +diff --git a/drivers/gpu/drm/meson/meson_overlay.h b/drivers/gpu/drm/meson/meson_overlay.h +new file mode 100644 +index 0000000000000..0fd63dabcb964 +--- /dev/null ++++ b/drivers/gpu/drm/meson/meson_overlay.h +@@ -0,0 +1,14 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright (C) 2018 BayLibre, SAS ++ * Author: Neil Armstrong ++ */ ++ ++#ifndef __MESON_OVERLAY_H ++#define __MESON_OVERLAY_H ++ ++#include "meson_drv.h" ++ ++int meson_overlay_create(struct meson_drm *priv); ++ ++#endif /* __MESON_OVERLAY_H */ +diff --git a/drivers/gpu/drm/meson/meson_registers.h b/drivers/gpu/drm/meson/meson_registers.h +index bca87143e5488..5c7e02c703bc7 100644 +--- a/drivers/gpu/drm/meson/meson_registers.h ++++ b/drivers/gpu/drm/meson/meson_registers.h +@@ -286,6 +286,7 @@ + #define VIU_OSD1_MATRIX_COEF22_30 0x1a9d + #define VIU_OSD1_MATRIX_COEF31_32 0x1a9e + #define VIU_OSD1_MATRIX_COEF40_41 0x1a9f ++#define VD1_IF0_GEN_REG3 0x1aa7 + #define VIU_OSD1_EOTF_CTL 0x1ad4 + #define VIU_OSD1_EOTF_COEF00_01 0x1ad5 + #define VIU_OSD1_EOTF_COEF02_10 0x1ad6 +@@ -297,6 +298,7 @@ + #define VIU_OSD1_OETF_CTL 0x1adc + #define VIU_OSD1_OETF_LUT_ADDR_PORT 0x1add + #define VIU_OSD1_OETF_LUT_DATA_PORT 0x1ade ++#define AFBC_ENABLE 0x1ae0 + + /* vpp */ + #define VPP_DUMMY_DATA 0x1d00 +@@ -349,6 +351,7 @@ + #define VPP_VD2_PREBLEND BIT(15) + #define VPP_OSD1_PREBLEND BIT(16) + #define VPP_OSD2_PREBLEND BIT(17) ++#define VPP_COLOR_MNG_ENABLE BIT(28) + #define VPP_OFIFO_SIZE 0x1d27 + #define VPP_FIFO_STATUS 0x1d28 + #define VPP_SMOKE_CTRL 0x1d29 +diff --git a/drivers/gpu/drm/meson/meson_viu.c b/drivers/gpu/drm/meson/meson_viu.c +index 5b48c4c0985b5..a423e7a61bf2c 100644 +--- a/drivers/gpu/drm/meson/meson_viu.c ++++ b/drivers/gpu/drm/meson/meson_viu.c +@@ -328,6 +328,21 @@ void meson_viu_init(struct meson_drm *priv) + 0xff << OSD_REPLACE_SHIFT, + priv->io_base + _REG(VIU_OSD2_CTRL_STAT2)); + ++ /* Disable VD1 AFBC */ ++ /* di_mif0_en=0 mif0_to_vpp_en=0 di_mad_en=0 */ ++ writel_bits_relaxed(0x7 << 16, 0, ++ priv->io_base + _REG(VIU_MISC_CTRL0)); ++ /* afbc vd1 set=0 */ ++ writel_bits_relaxed(BIT(20), 0, ++ priv->io_base + _REG(VIU_MISC_CTRL0)); ++ writel_relaxed(0, priv->io_base + _REG(AFBC_ENABLE)); ++ ++ writel_relaxed(0x00FF00C0, ++ priv->io_base + _REG(VD1_IF0_LUMA_FIFO_SIZE)); ++ writel_relaxed(0x00FF00C0, ++ priv->io_base + _REG(VD2_IF0_LUMA_FIFO_SIZE)); ++ ++ + priv->viu.osd1_enabled = false; + priv->viu.osd1_commit = false; + priv->viu.osd1_interlace = false; +diff --git a/drivers/gpu/drm/meson/meson_vpp.c b/drivers/gpu/drm/meson/meson_vpp.c +index 27356f81a0abe..5dc24a99e978b 100644 +--- a/drivers/gpu/drm/meson/meson_vpp.c ++++ b/drivers/gpu/drm/meson/meson_vpp.c +@@ -122,6 +122,31 @@ static void meson_vpp_write_scaling_filter_coefs(struct meson_drm *priv, + priv->io_base + _REG(VPP_OSD_SCALE_COEF)); + } + ++static const uint32_t vpp_filter_coefs_bicubic[] = { ++ 0x00800000, 0x007f0100, 0xff7f0200, 0xfe7f0300, ++ 0xfd7e0500, 0xfc7e0600, 0xfb7d0800, 0xfb7c0900, ++ 0xfa7b0b00, 0xfa7a0dff, 0xf9790fff, 0xf97711ff, ++ 0xf87613ff, 0xf87416fe, 0xf87218fe, 0xf8701afe, ++ 0xf76f1dfd, 0xf76d1ffd, 0xf76b21fd, 0xf76824fd, ++ 0xf76627fc, 0xf76429fc, 0xf7612cfc, 0xf75f2ffb, ++ 0xf75d31fb, 0xf75a34fb, 0xf75837fa, 0xf7553afa, ++ 0xf8523cfa, 0xf8503ff9, 0xf84d42f9, 0xf84a45f9, ++ 0xf84848f8 ++}; ++ ++static void meson_vpp_write_vd_scaling_filter_coefs(struct meson_drm *priv, ++ const unsigned int *coefs, ++ bool is_horizontal) ++{ ++ int i; ++ ++ writel_relaxed(is_horizontal ? BIT(8) : 0, ++ priv->io_base + _REG(VPP_SCALE_COEF_IDX)); ++ for (i = 0; i < 33; i++) ++ writel_relaxed(coefs[i], ++ priv->io_base + _REG(VPP_SCALE_COEF)); ++} ++ + void meson_vpp_init(struct meson_drm *priv) + { + /* set dummy data default YUV black */ +@@ -150,17 +175,34 @@ void meson_vpp_init(struct meson_drm *priv) + + /* Force all planes off */ + writel_bits_relaxed(VPP_OSD1_POSTBLEND | VPP_OSD2_POSTBLEND | +- VPP_VD1_POSTBLEND | VPP_VD2_POSTBLEND, 0, ++ VPP_VD1_POSTBLEND | VPP_VD2_POSTBLEND | ++ VPP_VD1_PREBLEND | VPP_VD2_PREBLEND, 0, + priv->io_base + _REG(VPP_MISC)); + ++ /* Setup default VD settings */ ++ writel_relaxed(4096, ++ priv->io_base + _REG(VPP_PREBLEND_VD1_H_START_END)); ++ writel_relaxed(4096, ++ priv->io_base + _REG(VPP_BLEND_VD2_H_START_END)); ++ + /* Disable Scalers */ + writel_relaxed(0, priv->io_base + _REG(VPP_OSD_SC_CTRL0)); + writel_relaxed(0, priv->io_base + _REG(VPP_OSD_VSC_CTRL0)); + writel_relaxed(0, priv->io_base + _REG(VPP_OSD_HSC_CTRL0)); ++ writel_relaxed(4 | (4 << 8) | BIT(15), ++ priv->io_base + _REG(VPP_SC_MISC)); ++ ++ writel_relaxed(1, priv->io_base + _REG(VPP_VADJ_CTRL)); + + /* Write in the proper filter coefficients. */ + meson_vpp_write_scaling_filter_coefs(priv, + vpp_filter_coefs_4point_bspline, false); + meson_vpp_write_scaling_filter_coefs(priv, + vpp_filter_coefs_4point_bspline, true); ++ ++ /* Write the VD proper filter coefficients. */ ++ meson_vpp_write_vd_scaling_filter_coefs(priv, vpp_filter_coefs_bicubic, ++ false); ++ meson_vpp_write_vd_scaling_filter_coefs(priv, vpp_filter_coefs_bicubic, ++ true); + } +diff --git a/drivers/soc/amlogic/meson-gx-pwrc-vpu.c b/drivers/soc/amlogic/meson-gx-pwrc-vpu.c +index 6289965c42e98..05421d029dff9 100644 +--- a/drivers/soc/amlogic/meson-gx-pwrc-vpu.c ++++ b/drivers/soc/amlogic/meson-gx-pwrc-vpu.c +@@ -54,12 +54,12 @@ static int meson_gx_pwrc_vpu_power_off(struct generic_pm_domain *genpd) + /* Power Down Memories */ + for (i = 0; i < 32; i += 2) { + regmap_update_bits(pd->regmap_hhi, HHI_VPU_MEM_PD_REG0, +- 0x2 << i, 0x3 << i); ++ 0x3 << i, 0x3 << i); + udelay(5); + } + for (i = 0; i < 32; i += 2) { + regmap_update_bits(pd->regmap_hhi, HHI_VPU_MEM_PD_REG1, +- 0x2 << i, 0x3 << i); ++ 0x3 << i, 0x3 << i); + udelay(5); + } + for (i = 8; i < 16; i++) { +@@ -108,13 +108,13 @@ static int meson_gx_pwrc_vpu_power_on(struct generic_pm_domain *genpd) + /* Power Up Memories */ + for (i = 0; i < 32; i += 2) { + regmap_update_bits(pd->regmap_hhi, HHI_VPU_MEM_PD_REG0, +- 0x2 << i, 0); ++ 0x3 << i, 0); + udelay(5); + } + + for (i = 0; i < 32; i += 2) { + regmap_update_bits(pd->regmap_hhi, HHI_VPU_MEM_PD_REG1, +- 0x2 << i, 0); ++ 0x3 << i, 0); + udelay(5); + } + diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/018_linux-4.18-yocto-meson64-0001-ARM64-dts-meson-gxbb-nanopi-k2-Add-HDMI-CEC-and-CVBS.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/018_linux-4.18-yocto-meson64-0001-ARM64-dts-meson-gxbb-nanopi-k2-Add-HDMI-CEC-and-CVBS.patch new file mode 100644 index 000000000..aad63ba8f --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/018_linux-4.18-yocto-meson64-0001-ARM64-dts-meson-gxbb-nanopi-k2-Add-HDMI-CEC-and-CVBS.patch @@ -0,0 +1,81 @@ +From 6c5aaf27886c9b308e9c4e4d613990e540f23ec8 Mon Sep 17 00:00:00 2001 +From: Neil Armstrong +Date: Tue, 26 Jun 2018 09:37:39 +0200 +Subject: [PATCH] ARM64: dts: meson-gxbb-nanopi-k2: Add HDMI, CEC and CVBS + nodes + +The Amlogic Meson GXBB based Nanopi-K2 board has an HDMI connector +with CEC and CVBS available on the 40pin header. +This patch adds the nodes to enable HDMI, CEC and CVBS functionnalities. + +Signed-off-by: Neil Armstrong +--- + .../boot/dts/amlogic/meson-gxbb-nanopi-k2.dts | 48 ++++++++++++++++++++++ + 1 file changed, 48 insertions(+) + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts +index 7d5709c..cbe99bd 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts +@@ -106,6 +106,42 @@ + compatible = "mmc-pwrseq-emmc"; + reset-gpios = <&gpio BOOT_9 GPIO_ACTIVE_LOW>; + }; ++ ++ /* CVBS is available on CON1 pin 36, disabled by default */ ++ cvbs-connector { ++ compatible = "composite-video-connector"; ++ status = "disabled"; ++ ++ port { ++ cvbs_connector_in: endpoint { ++ remote-endpoint = <&cvbs_vdac_out>; ++ }; ++ }; ++ }; ++ ++ hdmi-connector { ++ compatible = "hdmi-connector"; ++ type = "a"; ++ ++ port { ++ hdmi_connector_in: endpoint { ++ remote-endpoint = <&hdmi_tx_tmds_out>; ++ }; ++ }; ++ }; ++}; ++ ++&cec_AO { ++ status = "okay"; ++ pinctrl-0 = <&ao_cec_pins>; ++ pinctrl-names = "default"; ++ hdmi-phandle = <&hdmi_tx>; ++}; ++ ++&cvbs_vdac_port { ++ cvbs_vdac_out: endpoint { ++ remote-endpoint = <&cvbs_connector_in>; ++ }; + }; + + ðmac { +@@ -137,6 +173,18 @@ + }; + }; + ++&hdmi_tx { ++ status = "okay"; ++ pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>; ++ pinctrl-names = "default"; ++}; ++ ++&hdmi_tx_tmds_port { ++ hdmi_tx_tmds_out: endpoint { ++ remote-endpoint = <&hdmi_connector_in>; ++ }; ++}; ++ + &ir { + status = "okay"; + pinctrl-0 = <&remote_input_ao_pins>; diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/020_linux-4.18-yocto-meson64-0003-ARM64-defconfig-enable-CEC-support.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/020_linux-4.18-yocto-meson64-0003-ARM64-defconfig-enable-CEC-support.patch new file mode 100644 index 000000000..7c0471753 --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/020_linux-4.18-yocto-meson64-0003-ARM64-defconfig-enable-CEC-support.patch @@ -0,0 +1,44 @@ +From e41c06328d1cd0989899d6a0897c6857d0cf9a4b Mon Sep 17 00:00:00 2001 +From: Jerome Brunet +Date: Mon, 13 Nov 2017 12:09:40 +0100 +Subject: [PATCH] ARM64: defconfig: enable CEC support + +Turn on CONFIG_CEC_SUPPORT and CONFIG_CEC_PLATFORM_DRIVERS +Turn on CONFIG_VIDEO_MESON_AO_CEC as module +Turn on CONFIG_DRM_DW_HDMI_CEC as module + +Signed-off-by: Jerome Brunet +Signed-off-by: Neil Armstrong +--- + arch/arm64/configs/defconfig | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig +index f9a186f..2584605 100644 +--- a/arch/arm64/configs/defconfig ++++ b/arch/arm64/configs/defconfig +@@ -402,6 +402,7 @@ CONFIG_MEDIA_SUPPORT=m + CONFIG_MEDIA_CAMERA_SUPPORT=y + CONFIG_MEDIA_ANALOG_TV_SUPPORT=y + CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y ++CONFIG_MEDIA_CEC_SUPPORT=y + CONFIG_MEDIA_CONTROLLER=y + CONFIG_VIDEO_V4L2_SUBDEV_API=y + # CONFIG_DVB_NET is not set +@@ -411,6 +412,8 @@ CONFIG_VIDEO_SAMSUNG_S5P_MFC=m + CONFIG_VIDEO_SAMSUNG_EXYNOS_GSC=m + CONFIG_VIDEO_RENESAS_FCP=m + CONFIG_VIDEO_RENESAS_VSP1=m ++CONFIG_CEC_PLATFORM_DRIVERS=y ++CONFIG_VIDEO_MESON_AO_CEC=m + CONFIG_DRM=m + CONFIG_DRM_NOUVEAU=m + CONFIG_DRM_EXYNOS=m +@@ -431,6 +434,7 @@ CONFIG_DRM_RCAR_LVDS=m + CONFIG_DRM_TEGRA=m + CONFIG_DRM_PANEL_SIMPLE=m + CONFIG_DRM_I2C_ADV7511=m ++CONFIG_DRM_DW_HDMI_CEC=m + CONFIG_DRM_VC4=m + CONFIG_DRM_HISI_HIBMC=m + CONFIG_DRM_HISI_KIRIN=m diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/021_linux-4.18-yocto-meson64-0004-clk-meson-switch-gxbb-cts-amclk-div-to-the-generic-d.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/021_linux-4.18-yocto-meson64-0004-clk-meson-switch-gxbb-cts-amclk-div-to-the-generic-d.patch new file mode 100644 index 000000000..e2b3860f5 --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/021_linux-4.18-yocto-meson64-0004-clk-meson-switch-gxbb-cts-amclk-div-to-the-generic-d.patch @@ -0,0 +1,44 @@ +From 0cecf963b9d815699fe50b7a7ee4a93ece3ed834 Mon Sep 17 00:00:00 2001 +From: Jerome Brunet +Date: Tue, 19 Jun 2018 18:14:49 +0200 +Subject: [PATCH] clk: meson: switch gxbb cts-amclk div to the generic divider + +clk-audio-divider was a (poor) attempt to use CCF rate propagation +while making sure the PLL rate would be high enough to work with +audio use cases. The result is far from optimal. We can do better +by carefully choosing the PLL rates for the audio use cases. +Doing so, we don't need to use clk-audio-divider anymore. The +generic will do + +Signed-off-by: Jerome Brunet +--- + drivers/clk/meson/gxbb.c | 12 +++++------- + 1 file changed, 5 insertions(+), 7 deletions(-) + +diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c +index 177fffb..69a58cb 100644 +--- a/drivers/clk/meson/gxbb.c ++++ b/drivers/clk/meson/gxbb.c +@@ -982,17 +982,15 @@ static struct clk_regmap gxbb_cts_amclk_sel = { + }; + + static struct clk_regmap gxbb_cts_amclk_div = { +- .data = &(struct meson_clk_audio_div_data){ +- .div = { +- .reg_off = HHI_AUD_CLK_CNTL, +- .shift = 0, +- .width = 8, +- }, ++ .data = &(struct clk_regmap_div_data) { ++ .offset = HHI_AUD_CLK_CNTL, ++ .shift = 0, ++ .width = 8, + .flags = CLK_DIVIDER_ROUND_CLOSEST, + }, + .hw.init = &(struct clk_init_data){ + .name = "cts_amclk_div", +- .ops = &meson_clk_audio_divider_ops, ++ .ops = &clk_regmap_divider_ops, + .parent_names = (const char *[]){ "cts_amclk_sel" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/022_linux-4.18-yocto-meson64-0005-clk-meson-remove-unused-clk-audio-divider-driver.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/022_linux-4.18-yocto-meson64-0005-clk-meson-remove-unused-clk-audio-divider-driver.patch new file mode 100644 index 000000000..cd6da8cf5 --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/022_linux-4.18-yocto-meson64-0005-clk-meson-remove-unused-clk-audio-divider-driver.patch @@ -0,0 +1,48 @@ +From e87dd7b11611e4ac5279ba4ad4f1fea4d0900273 Mon Sep 17 00:00:00 2001 +From: Jerome Brunet +Date: Tue, 19 Jun 2018 18:23:28 +0200 +Subject: [PATCH] clk: meson: remove unused clk-audio-divider driver + +Signed-off-by: Jerome Brunet +--- + drivers/clk/meson/Makefile | 2 +- + drivers/clk/meson/clkc.h | 7 ------- + 2 files changed, 1 insertion(+), 8 deletions(-) + +diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile +index d0d13ae..e40fea9 100644 +--- a/drivers/clk/meson/Makefile ++++ b/drivers/clk/meson/Makefile +@@ -2,7 +2,7 @@ + # Makefile for Meson specific clk + # + +-obj-$(CONFIG_COMMON_CLK_AMLOGIC) += clk-pll.o clk-mpll.o clk-audio-divider.o ++obj-$(CONFIG_COMMON_CLK_AMLOGIC) += clk-pll.o clk-mpll.o + obj-$(CONFIG_COMMON_CLK_MESON_AO) += meson-aoclk.o + obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b.o + obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o gxbb-aoclk-32k.o +diff --git a/drivers/clk/meson/clkc.h b/drivers/clk/meson/clkc.h +index 2fb0843..48db024 100644 +--- a/drivers/clk/meson/clkc.h ++++ b/drivers/clk/meson/clkc.h +@@ -91,11 +91,6 @@ struct meson_clk_mpll_data { + + #define CLK_MESON_MPLL_ROUND_CLOSEST BIT(0) + +-struct meson_clk_audio_div_data { +- struct parm div; +- u8 flags; +-}; +- + #define MESON_GATE(_name, _reg, _bit) \ + struct clk_regmap _name = { \ + .data = &(struct clk_regmap_gate_data){ \ +@@ -117,7 +112,5 @@ extern const struct clk_ops meson_clk_pll_ops; + extern const struct clk_ops meson_clk_cpu_ops; + extern const struct clk_ops meson_clk_mpll_ro_ops; + extern const struct clk_ops meson_clk_mpll_ops; +-extern const struct clk_ops meson_clk_audio_divider_ro_ops; +-extern const struct clk_ops meson_clk_audio_divider_ops; + + #endif /* __CLKC_H */ diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/023_linux-4.18-yocto-meson64-0006-ASoC-meson-add-meson-audio-core-driver.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/023_linux-4.18-yocto-meson64-0006-ASoC-meson-add-meson-audio-core-driver.patch new file mode 100644 index 000000000..69c0ab299 --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/023_linux-4.18-yocto-meson64-0006-ASoC-meson-add-meson-audio-core-driver.patch @@ -0,0 +1,308 @@ +From 878d41be386f0bcbe1475f65acd8b9fb304529a0 Mon Sep 17 00:00:00 2001 +From: Jerome Brunet +Date: Thu, 30 Mar 2017 11:49:55 +0200 +Subject: [PATCH] ASoC: meson: add meson audio core driver + +This patch adds support for the audio core driver for the Amlogic Meson SoC +family. The purpose of this driver is to properly reset the audio block and +provide register access for the different devices scattered in this address +space. This includes output and input DMAs, pcm, i2s and spdif dai, card +level routing, internal codec for the gxl variant + +For more information, please refer to the section 5 of the public datasheet +of the S905 (gxbb). This datasheet is available here: [0]. + +[0]: http://dn.odroid.com/S905/DataSheet/S905_Public_Datasheet_V1.1.4.pdf + +Signed-off-by: Jerome Brunet +--- + sound/soc/Kconfig | 1 + + sound/soc/Makefile | 1 + + sound/soc/meson/Kconfig | 9 ++ + sound/soc/meson/Makefile | 3 + + sound/soc/meson/audio-core.c | 190 +++++++++++++++++++++++++++++++++++++++++++ + sound/soc/meson/audio-core.h | 28 +++++++ + 6 files changed, 232 insertions(+) + create mode 100644 sound/soc/meson/Kconfig + create mode 100644 sound/soc/meson/Makefile + create mode 100644 sound/soc/meson/audio-core.c + create mode 100644 sound/soc/meson/audio-core.h + +diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig +index 41af6b9..1cf11cf 100644 +--- a/sound/soc/Kconfig ++++ b/sound/soc/Kconfig +@@ -57,6 +57,7 @@ source "sound/soc/kirkwood/Kconfig" + source "sound/soc/img/Kconfig" + source "sound/soc/intel/Kconfig" + source "sound/soc/mediatek/Kconfig" ++source "sound/soc/meson/Kconfig" + source "sound/soc/mxs/Kconfig" + source "sound/soc/pxa/Kconfig" + source "sound/soc/qcom/Kconfig" +diff --git a/sound/soc/Makefile b/sound/soc/Makefile +index 06389a5..62a5f87 100644 +--- a/sound/soc/Makefile ++++ b/sound/soc/Makefile +@@ -38,6 +38,7 @@ obj-$(CONFIG_SND_SOC) += jz4740/ + obj-$(CONFIG_SND_SOC) += img/ + obj-$(CONFIG_SND_SOC) += intel/ + obj-$(CONFIG_SND_SOC) += mediatek/ ++obj-$(CONFIG_SND_SOC) += meson/ + obj-$(CONFIG_SND_SOC) += mxs/ + obj-$(CONFIG_SND_SOC) += nuc900/ + obj-$(CONFIG_SND_SOC) += omap/ +diff --git a/sound/soc/meson/Kconfig b/sound/soc/meson/Kconfig +new file mode 100644 +index 0000000..ca0e3e9 +--- /dev/null ++++ b/sound/soc/meson/Kconfig +@@ -0,0 +1,9 @@ ++menuconfig SND_SOC_MESON ++ tristate "ASoC support for Amlogic Meson SoCs" ++ depends on ARCH_MESON ++ select MFD_CORE ++ select REGMAP_MMIO ++ help ++ Say Y or M if you want to add support for codecs attached to ++ the Amlogic Meson SoCs Audio interfaces. You will also need to ++ select the audio interfaces to support below. +diff --git a/sound/soc/meson/Makefile b/sound/soc/meson/Makefile +new file mode 100644 +index 0000000..22028ab +--- /dev/null ++++ b/sound/soc/meson/Makefile +@@ -0,0 +1,3 @@ ++snd-soc-meson-audio-core-objs := audio-core.o ++ ++obj-$(CONFIG_SND_SOC_MESON) += snd-soc-meson-audio-core.o +diff --git a/sound/soc/meson/audio-core.c b/sound/soc/meson/audio-core.c +new file mode 100644 +index 0000000..99993ec +--- /dev/null ++++ b/sound/soc/meson/audio-core.c +@@ -0,0 +1,190 @@ ++/* ++ * Copyright (C) 2017 BayLibre, SAS ++ * Author: Jerome Brunet ++ * Copyright (C) 2017 Amlogic, Inc. All rights reserved. ++ * ++ * 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. ++ * ++ * 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. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, see . ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "audio-core.h" ++ ++#define DRV_NAME "meson-audio-core" ++ ++static const char * const acore_clock_names[] = { "aiu_top", ++ "aiu_glue", ++ "audin" }; ++ ++static int meson_acore_init_clocks(struct device *dev) ++{ ++ struct clk *clock; ++ int i, ret; ++ ++ for (i = 0; i < ARRAY_SIZE(acore_clock_names); i++) { ++ clock = devm_clk_get(dev, acore_clock_names[i]); ++ if (IS_ERR(clock)) { ++ if (PTR_ERR(clock) != -EPROBE_DEFER) ++ dev_err(dev, "Failed to get %s clock\n", ++ acore_clock_names[i]); ++ return PTR_ERR(clock); ++ } ++ ++ ret = clk_prepare_enable(clock); ++ if (ret) { ++ dev_err(dev, "Failed to enable %s clock\n", ++ acore_clock_names[i]); ++ return ret; ++ } ++ ++ ret = devm_add_action_or_reset(dev, ++ (void(*)(void *))clk_disable_unprepare, ++ clock); ++ if (ret) ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static const char * const acore_reset_names[] = { "aiu", ++ "audin" }; ++ ++static int meson_acore_init_resets(struct device *dev) ++{ ++ struct reset_control *reset; ++ int i, ret; ++ ++ for (i = 0; i < ARRAY_SIZE(acore_reset_names); i++) { ++ reset = devm_reset_control_get_exclusive(dev, ++ acore_reset_names[i]); ++ if (IS_ERR(reset)) { ++ if (PTR_ERR(reset) != -EPROBE_DEFER) ++ dev_err(dev, "Failed to get %s reset\n", ++ acore_reset_names[i]); ++ return PTR_ERR(reset); ++ } ++ ++ ret = reset_control_reset(reset); ++ if (ret) { ++ dev_err(dev, "Failed to pulse %s reset\n", ++ acore_reset_names[i]); ++ return ret; ++ } ++ } ++ ++ return 0; ++} ++ ++static const struct regmap_config meson_acore_regmap_config = { ++ .reg_bits = 32, ++ .val_bits = 32, ++ .reg_stride = 4, ++}; ++ ++static const struct mfd_cell meson_acore_devs[] = { ++ { ++ .name = "meson-i2s-dai", ++ .of_compatible = "amlogic,meson-i2s-dai", ++ }, ++ { ++ .name = "meson-spdif-dai", ++ .of_compatible = "amlogic,meson-spdif-dai", ++ }, ++ { ++ .name = "meson-aiu-i2s-dma", ++ .of_compatible = "amlogic,meson-aiu-i2s-dma", ++ }, ++ { ++ .name = "meson-aiu-spdif-dma", ++ .of_compatible = "amlogic,meson-aiu-spdif-dma", ++ }, ++}; ++ ++static int meson_acore_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct meson_audio_core_data *data; ++ struct resource *res; ++ void __iomem *regs; ++ int ret; ++ ++ data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); ++ if (!data) ++ return -ENOMEM; ++ platform_set_drvdata(pdev, data); ++ ++ ret = meson_acore_init_clocks(dev); ++ if (ret) ++ return ret; ++ ++ ret = meson_acore_init_resets(dev); ++ if (ret) ++ return ret; ++ ++ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "aiu"); ++ regs = devm_ioremap_resource(dev, res); ++ if (IS_ERR(regs)) ++ return PTR_ERR(regs); ++ ++ data->aiu = devm_regmap_init_mmio(dev, regs, ++ &meson_acore_regmap_config); ++ if (IS_ERR(data->aiu)) { ++ dev_err(dev, "Couldn't create the AIU regmap\n"); ++ return PTR_ERR(data->aiu); ++ } ++ ++ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "audin"); ++ regs = devm_ioremap_resource(dev, res); ++ if (IS_ERR(regs)) ++ return PTR_ERR(regs); ++ ++ data->audin = devm_regmap_init_mmio(dev, regs, ++ &meson_acore_regmap_config); ++ if (IS_ERR(data->audin)) { ++ dev_err(dev, "Couldn't create the AUDIN regmap\n"); ++ return PTR_ERR(data->audin); ++ } ++ ++ return devm_mfd_add_devices(dev, PLATFORM_DEVID_AUTO, meson_acore_devs, ++ ARRAY_SIZE(meson_acore_devs), NULL, 0, ++ NULL); ++} ++ ++static const struct of_device_id meson_acore_of_match[] = { ++ { .compatible = "amlogic,meson-audio-core", }, ++ { .compatible = "amlogic,meson-gxbb-audio-core", }, ++ { .compatible = "amlogic,meson-gxl-audio-core", }, ++ {} ++}; ++MODULE_DEVICE_TABLE(of, meson_acore_of_match); ++ ++static struct platform_driver meson_acore_pdrv = { ++ .probe = meson_acore_probe, ++ .driver = { ++ .name = DRV_NAME, ++ .of_match_table = meson_acore_of_match, ++ }, ++}; ++module_platform_driver(meson_acore_pdrv); ++ ++MODULE_DESCRIPTION("Meson Audio Core Driver"); ++MODULE_AUTHOR("Jerome Brunet "); ++MODULE_LICENSE("GPL v2"); +diff --git a/sound/soc/meson/audio-core.h b/sound/soc/meson/audio-core.h +new file mode 100644 +index 0000000..6e7a24c +--- /dev/null ++++ b/sound/soc/meson/audio-core.h +@@ -0,0 +1,28 @@ ++/* ++ * Copyright (C) 2017 BayLibre, SAS ++ * Author: Jerome Brunet ++ * Copyright (C) 2017 Amlogic, Inc. All rights reserved. ++ * ++ * 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. ++ * ++ * 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. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, see . ++ */ ++ ++#ifndef _MESON_AUDIO_CORE_H_ ++#define _MESON_AUDIO_CORE_H_ ++ ++struct meson_audio_core_data { ++ struct regmap *aiu; ++ struct regmap *audin; ++}; ++ ++#endif /* _MESON_AUDIO_CORE_H_ */ diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/024_linux-4.18-yocto-meson64-0007-ASoC-meson-add-register-definitions.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/024_linux-4.18-yocto-meson64-0007-ASoC-meson-add-register-definitions.patch new file mode 100644 index 000000000..0a13a427c --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/024_linux-4.18-yocto-meson64-0007-ASoC-meson-add-register-definitions.patch @@ -0,0 +1,357 @@ +From f6c0ce626b08f5ba85bd9bfe000044c4f9e7da24 Mon Sep 17 00:00:00 2001 +From: Jerome Brunet +Date: Thu, 30 Mar 2017 12:00:10 +0200 +Subject: [PATCH] ASoC: meson: add register definitions + +Add the register definition for the AIU and AUDIN blocks + +Signed-off-by: Jerome Brunet +--- + sound/soc/meson/aiu-regs.h | 182 +++++++++++++++++++++++++++++++++++++++++++ + sound/soc/meson/audin-regs.h | 148 +++++++++++++++++++++++++++++++++++ + 2 files changed, 330 insertions(+) + create mode 100644 sound/soc/meson/aiu-regs.h + create mode 100644 sound/soc/meson/audin-regs.h + +diff --git a/sound/soc/meson/aiu-regs.h b/sound/soc/meson/aiu-regs.h +new file mode 100644 +index 0000000..67391e6 +--- /dev/null ++++ b/sound/soc/meson/aiu-regs.h +@@ -0,0 +1,182 @@ ++/* ++ * Copyright (C) 2017 BayLibre, SAS ++ * Author: Jerome Brunet ++ * Copyright (C) 2017 Amlogic, Inc. All rights reserved. ++ * ++ * 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. ++ * ++ * 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. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, see . ++ */ ++ ++#ifndef _AIU_REGS_H_ ++#define _AIU_REGS_H_ ++ ++#define AIU_958_BPF 0x000 ++#define AIU_958_BRST 0x004 ++#define AIU_958_LENGTH 0x008 ++#define AIU_958_PADDSIZE 0x00C ++#define AIU_958_MISC 0x010 ++#define AIU_958_FORCE_LEFT 0x014 /* Unknown */ ++#define AIU_958_DISCARD_NUM 0x018 ++#define AIU_958_DCU_FF_CTRL 0x01C ++#define AIU_958_CHSTAT_L0 0x020 ++#define AIU_958_CHSTAT_L1 0x024 ++#define AIU_958_CTRL 0x028 ++#define AIU_958_RPT 0x02C ++#define AIU_I2S_MUTE_SWAP 0x030 ++#define AIU_I2S_SOURCE_DESC 0x034 ++#define AIU_I2S_MED_CTRL 0x038 ++#define AIU_I2S_MED_THRESH 0x03C ++#define AIU_I2S_DAC_CFG 0x040 ++#define AIU_I2S_SYNC 0x044 /* Unknown */ ++#define AIU_I2S_MISC 0x048 ++#define AIU_I2S_OUT_CFG 0x04C ++#define AIU_I2S_FF_CTRL 0x050 /* Unknown */ ++#define AIU_RST_SOFT 0x054 ++#define AIU_CLK_CTRL 0x058 ++#define AIU_MIX_ADCCFG 0x05C ++#define AIU_MIX_CTRL 0x060 ++#define AIU_CLK_CTRL_MORE 0x064 ++#define AIU_958_POP 0x068 ++#define AIU_MIX_GAIN 0x06C ++#define AIU_958_SYNWORD1 0x070 ++#define AIU_958_SYNWORD2 0x074 ++#define AIU_958_SYNWORD3 0x078 ++#define AIU_958_SYNWORD1_MASK 0x07C ++#define AIU_958_SYNWORD2_MASK 0x080 ++#define AIU_958_SYNWORD3_MASK 0x084 ++#define AIU_958_FFRDOUT_THD 0x088 ++#define AIU_958_LENGTH_PER_PAUSE 0x08C ++#define AIU_958_PAUSE_NUM 0x090 ++#define AIU_958_PAUSE_PAYLOAD 0x094 ++#define AIU_958_AUTO_PAUSE 0x098 ++#define AIU_958_PAUSE_PD_LENGTH 0x09C ++#define AIU_CODEC_DAC_LRCLK_CTRL 0x0A0 ++#define AIU_CODEC_ADC_LRCLK_CTRL 0x0A4 ++#define AIU_HDMI_CLK_DATA_CTRL 0x0A8 ++#define AIU_CODEC_CLK_DATA_CTRL 0x0AC ++#define AIU_ACODEC_CTRL 0x0B0 ++#define AIU_958_CHSTAT_R0 0x0C0 ++#define AIU_958_CHSTAT_R1 0x0C4 ++#define AIU_958_VALID_CTRL 0x0C8 ++#define AIU_AUDIO_AMP_REG0 0x0F0 /* Unknown */ ++#define AIU_AUDIO_AMP_REG1 0x0F4 /* Unknown */ ++#define AIU_AUDIO_AMP_REG2 0x0F8 /* Unknown */ ++#define AIU_AUDIO_AMP_REG3 0x0FC /* Unknown */ ++#define AIU_AIFIFO2_CTRL 0x100 ++#define AIU_AIFIFO2_STATUS 0x104 ++#define AIU_AIFIFO2_GBIT 0x108 ++#define AIU_AIFIFO2_CLB 0x10C ++#define AIU_CRC_CTRL 0x110 ++#define AIU_CRC_STATUS 0x114 ++#define AIU_CRC_SHIFT_REG 0x118 ++#define AIU_CRC_IREG 0x11C ++#define AIU_CRC_CAL_REG1 0x120 ++#define AIU_CRC_CAL_REG0 0x124 ++#define AIU_CRC_POLY_COEF1 0x128 ++#define AIU_CRC_POLY_COEF0 0x12C ++#define AIU_CRC_BIT_SIZE1 0x130 ++#define AIU_CRC_BIT_SIZE0 0x134 ++#define AIU_CRC_BIT_CNT1 0x138 ++#define AIU_CRC_BIT_CNT0 0x13C ++#define AIU_AMCLK_GATE_HI 0x140 ++#define AIU_AMCLK_GATE_LO 0x144 ++#define AIU_AMCLK_MSR 0x148 ++#define AIU_AUDAC_CTRL0 0x14C /* Unknown */ ++#define AIU_DELTA_SIGMA0 0x154 /* Unknown */ ++#define AIU_DELTA_SIGMA1 0x158 /* Unknown */ ++#define AIU_DELTA_SIGMA2 0x15C /* Unknown */ ++#define AIU_DELTA_SIGMA3 0x160 /* Unknown */ ++#define AIU_DELTA_SIGMA4 0x164 /* Unknown */ ++#define AIU_DELTA_SIGMA5 0x168 /* Unknown */ ++#define AIU_DELTA_SIGMA6 0x16C /* Unknown */ ++#define AIU_DELTA_SIGMA7 0x170 /* Unknown */ ++#define AIU_DELTA_SIGMA_LCNTS 0x174 /* Unknown */ ++#define AIU_DELTA_SIGMA_RCNTS 0x178 /* Unknown */ ++#define AIU_MEM_I2S_START_PTR 0x180 ++#define AIU_MEM_I2S_RD_PTR 0x184 ++#define AIU_MEM_I2S_END_PTR 0x188 ++#define AIU_MEM_I2S_MASKS 0x18C ++#define AIU_MEM_I2S_CONTROL 0x190 ++#define AIU_MEM_IEC958_START_PTR 0x194 ++#define AIU_MEM_IEC958_RD_PTR 0x198 ++#define AIU_MEM_IEC958_END_PTR 0x19C ++#define AIU_MEM_IEC958_MASKS 0x1A0 ++#define AIU_MEM_IEC958_CONTROL 0x1A4 ++#define AIU_MEM_AIFIFO2_START_PTR 0x1A8 ++#define AIU_MEM_AIFIFO2_CURR_PTR 0x1AC ++#define AIU_MEM_AIFIFO2_END_PTR 0x1B0 ++#define AIU_MEM_AIFIFO2_BYTES_AVAIL 0x1B4 ++#define AIU_MEM_AIFIFO2_CONTROL 0x1B8 ++#define AIU_MEM_AIFIFO2_MAN_WP 0x1BC ++#define AIU_MEM_AIFIFO2_MAN_RP 0x1C0 ++#define AIU_MEM_AIFIFO2_LEVEL 0x1C4 ++#define AIU_MEM_AIFIFO2_BUF_CNTL 0x1C8 ++#define AIU_MEM_I2S_MAN_WP 0x1CC ++#define AIU_MEM_I2S_MAN_RP 0x1D0 ++#define AIU_MEM_I2S_LEVEL 0x1D4 ++#define AIU_MEM_I2S_BUF_CNTL 0x1D8 ++#define AIU_MEM_I2S_BUF_WRAP_COUNT 0x1DC ++#define AIU_MEM_I2S_MEM_CTL 0x1E0 ++#define AIU_MEM_IEC958_MEM_CTL 0x1E4 ++#define AIU_MEM_IEC958_WRAP_COUNT 0x1E8 ++#define AIU_MEM_IEC958_IRQ_LEVEL 0x1EC ++#define AIU_MEM_IEC958_MAN_WP 0x1F0 ++#define AIU_MEM_IEC958_MAN_RP 0x1F4 ++#define AIU_MEM_IEC958_LEVEL 0x1F8 ++#define AIU_MEM_IEC958_BUF_CNTL 0x1FC ++#define AIU_AIFIFO_CTRL 0x200 ++#define AIU_AIFIFO_STATUS 0x204 ++#define AIU_AIFIFO_GBIT 0x208 ++#define AIU_AIFIFO_CLB 0x20C ++#define AIU_MEM_AIFIFO_START_PTR 0x210 ++#define AIU_MEM_AIFIFO_CURR_PTR 0x214 ++#define AIU_MEM_AIFIFO_END_PTR 0x218 ++#define AIU_MEM_AIFIFO_BYTES_AVAIL 0x21C ++#define AIU_MEM_AIFIFO_CONTROL 0x220 ++#define AIU_MEM_AIFIFO_MAN_WP 0x224 ++#define AIU_MEM_AIFIFO_MAN_RP 0x228 ++#define AIU_MEM_AIFIFO_LEVEL 0x22C ++#define AIU_MEM_AIFIFO_BUF_CNTL 0x230 ++#define AIU_MEM_AIFIFO_BUF_WRAP_COUNT 0x234 ++#define AIU_MEM_AIFIFO2_BUF_WRAP_COUNT 0x238 ++#define AIU_MEM_AIFIFO_MEM_CTL 0x23C ++#define AIFIFO_TIME_STAMP_CNTL 0x240 ++#define AIFIFO_TIME_STAMP_SYNC_0 0x244 ++#define AIFIFO_TIME_STAMP_SYNC_1 0x248 ++#define AIFIFO_TIME_STAMP_0 0x24C ++#define AIFIFO_TIME_STAMP_1 0x250 ++#define AIFIFO_TIME_STAMP_2 0x254 ++#define AIFIFO_TIME_STAMP_3 0x258 ++#define AIFIFO_TIME_STAMP_LENGTH 0x25C ++#define AIFIFO2_TIME_STAMP_CNTL 0x260 ++#define AIFIFO2_TIME_STAMP_SYNC_0 0x264 ++#define AIFIFO2_TIME_STAMP_SYNC_1 0x268 ++#define AIFIFO2_TIME_STAMP_0 0x26C ++#define AIFIFO2_TIME_STAMP_1 0x270 ++#define AIFIFO2_TIME_STAMP_2 0x274 ++#define AIFIFO2_TIME_STAMP_3 0x278 ++#define AIFIFO2_TIME_STAMP_LENGTH 0x27C ++#define IEC958_TIME_STAMP_CNTL 0x280 ++#define IEC958_TIME_STAMP_SYNC_0 0x284 ++#define IEC958_TIME_STAMP_SYNC_1 0x288 ++#define IEC958_TIME_STAMP_0 0x28C ++#define IEC958_TIME_STAMP_1 0x290 ++#define IEC958_TIME_STAMP_2 0x294 ++#define IEC958_TIME_STAMP_3 0x298 ++#define IEC958_TIME_STAMP_LENGTH 0x29C ++#define AIU_MEM_AIFIFO2_MEM_CTL 0x2A0 ++#define AIU_I2S_CBUS_DDR_CNTL 0x2A4 ++#define AIU_I2S_CBUS_DDR_WDATA 0x2A8 ++#define AIU_I2S_CBUS_DDR_ADDR 0x2AC ++ ++#endif /* _AIU_REGS_H_ */ +diff --git a/sound/soc/meson/audin-regs.h b/sound/soc/meson/audin-regs.h +new file mode 100644 +index 0000000..f224610 +--- /dev/null ++++ b/sound/soc/meson/audin-regs.h +@@ -0,0 +1,148 @@ ++/* ++ * Copyright (C) 2017 BayLibre, SAS ++ * Author: Jerome Brunet ++ * Copyright (C) 2017 Amlogic, Inc. All rights reserved. ++ * ++ * 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. ++ * ++ * 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. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, see . ++ */ ++ ++#ifndef _AUDIN_REGS_H_ ++#define _AUDIN_REGS_H_ ++ ++/* ++ * Note : ++ * Datasheet issue page 196 ++ * AUDIN_MUTE_VAL 0x35 => impossible: Already assigned to AUDIN_FIFO1_PTR ++ * AUDIN_FIFO1_PTR is more likely to be correct here since surrounding registers ++ * also deal with AUDIN_FIFO1 ++ * ++ * Clarification needed from Amlogic ++ */ ++ ++#define AUDIN_SPDIF_MODE 0x000 ++#define AUDIN_SPDIF_FS_CLK_RLTN 0x004 ++#define AUDIN_SPDIF_CHNL_STS_A 0x008 ++#define AUDIN_SPDIF_CHNL_STS_B 0x00C ++#define AUDIN_SPDIF_MISC 0x010 ++#define AUDIN_SPDIF_NPCM_PCPD 0x014 ++#define AUDIN_SPDIF_END 0x03C /* Unknown */ ++#define AUDIN_I2SIN_CTRL 0x040 ++#define AUDIN_SOURCE_SEL 0x044 ++#define AUDIN_DECODE_FORMAT 0x048 ++#define AUDIN_DECODE_CONTROL_STATUS 0x04C ++#define AUDIN_DECODE_CHANNEL_STATUS_A_0 0x050 ++#define AUDIN_DECODE_CHANNEL_STATUS_A_1 0x054 ++#define AUDIN_DECODE_CHANNEL_STATUS_A_2 0x058 ++#define AUDIN_DECODE_CHANNEL_STATUS_A_3 0x05C ++#define AUDIN_DECODE_CHANNEL_STATUS_A_4 0x060 ++#define AUDIN_DECODE_CHANNEL_STATUS_A_5 0x064 ++#define AUDIN_FIFO0_START 0x080 ++#define AUDIN_FIFO0_END 0x084 ++#define AUDIN_FIFO0_PTR 0x088 ++#define AUDIN_FIFO0_INTR 0x08C ++#define AUDIN_FIFO0_RDPTR 0x090 ++#define AUDIN_FIFO0_CTRL 0x094 ++#define AUDIN_FIFO0_CTRL1 0x098 ++#define AUDIN_FIFO0_LVL0 0x09C ++#define AUDIN_FIFO0_LVL1 0x0A0 ++#define AUDIN_FIFO0_LVL2 0x0A4 ++#define AUDIN_FIFO0_REQID 0x0C0 ++#define AUDIN_FIFO0_WRAP 0x0C4 ++#define AUDIN_FIFO1_START 0x0CC ++#define AUDIN_FIFO1_END 0x0D0 ++#define AUDIN_FIFO1_PTR 0x0D4 ++#define AUDIN_FIFO1_INTR 0x0D8 ++#define AUDIN_FIFO1_RDPTR 0x0DC ++#define AUDIN_FIFO1_CTRL 0x0E0 ++#define AUDIN_FIFO1_CTRL1 0x0E4 ++#define AUDIN_FIFO1_LVL0 0x100 ++#define AUDIN_FIFO1_LVL1 0x104 ++#define AUDIN_FIFO1_LVL2 0x108 ++#define AUDIN_FIFO1_REQID 0x10C ++#define AUDIN_FIFO1_WRAP 0x110 ++#define AUDIN_FIFO2_START 0x114 ++#define AUDIN_FIFO2_END 0x118 ++#define AUDIN_FIFO2_PTR 0x11C ++#define AUDIN_FIFO2_INTR 0x120 ++#define AUDIN_FIFO2_RDPTR 0x124 ++#define AUDIN_FIFO2_CTRL 0x128 ++#define AUDIN_FIFO2_CTRL1 0x12C ++#define AUDIN_FIFO2_LVL0 0x130 ++#define AUDIN_FIFO2_LVL1 0x134 ++#define AUDIN_FIFO2_LVL2 0x138 ++#define AUDIN_FIFO2_REQID 0x13C ++#define AUDIN_FIFO2_WRAP 0x140 ++#define AUDIN_INT_CTRL 0x144 ++#define AUDIN_FIFO_INT 0x148 ++#define PCMIN_CTRL0 0x180 ++#define PCMIN_CTRL1 0x184 ++#define PCMIN1_CTRL0 0x188 ++#define PCMIN1_CTRL1 0x18C ++#define PCMOUT_CTRL0 0x1C0 ++#define PCMOUT_CTRL1 0x1C4 ++#define PCMOUT_CTRL2 0x1C8 ++#define PCMOUT_CTRL3 0x1CC ++#define PCMOUT1_CTRL0 0x1D0 ++#define PCMOUT1_CTRL1 0x1D4 ++#define PCMOUT1_CTRL2 0x1D8 ++#define PCMOUT1_CTRL3 0x1DC ++#define AUDOUT_CTRL 0x200 ++#define AUDOUT_CTRL1 0x204 ++#define AUDOUT_BUF0_STA 0x208 ++#define AUDOUT_BUF0_EDA 0x20C ++#define AUDOUT_BUF0_WPTR 0x210 ++#define AUDOUT_BUF1_STA 0x214 ++#define AUDOUT_BUF1_EDA 0x218 ++#define AUDOUT_BUF1_WPTR 0x21C ++#define AUDOUT_FIFO_RPTR 0x220 ++#define AUDOUT_INTR_PTR 0x224 ++#define AUDOUT_FIFO_STS 0x228 ++#define AUDOUT1_CTRL 0x240 ++#define AUDOUT1_CTRL1 0x244 ++#define AUDOUT1_BUF0_STA 0x248 ++#define AUDOUT1_BUF0_EDA 0x24C ++#define AUDOUT1_BUF0_WPTR 0x250 ++#define AUDOUT1_BUF1_STA 0x254 ++#define AUDOUT1_BUF1_EDA 0x258 ++#define AUDOUT1_BUF1_WPTR 0x25C ++#define AUDOUT1_FIFO_RPTR 0x260 ++#define AUDOUT1_INTR_PTR 0x264 ++#define AUDOUT1_FIFO_STS 0x268 ++#define AUDIN_HDMI_MEAS_CTRL 0x280 ++#define AUDIN_HDMI_MEAS_CYCLES_M1 0x284 ++#define AUDIN_HDMI_MEAS_INTR_MASKN 0x288 ++#define AUDIN_HDMI_MEAS_INTR_STAT 0x28C ++#define AUDIN_HDMI_REF_CYCLES_STAT_0 0x290 ++#define AUDIN_HDMI_REF_CYCLES_STAT_1 0x294 ++#define AUDIN_HDMIRX_AFIFO_STAT 0x298 ++#define AUDIN_FIFO0_PIO_STS 0x2C0 ++#define AUDIN_FIFO0_PIO_RDL 0x2C4 ++#define AUDIN_FIFO0_PIO_RDH 0x2C8 ++#define AUDIN_FIFO1_PIO_STS 0x2CC ++#define AUDIN_FIFO1_PIO_RDL 0x2D0 ++#define AUDIN_FIFO1_PIO_RDH 0x2D4 ++#define AUDIN_FIFO2_PIO_STS 0x2D8 ++#define AUDIN_FIFO2_PIO_RDL 0x2DC ++#define AUDIN_FIFO2_PIO_RDH 0x2E0 ++#define AUDOUT_FIFO_PIO_STS 0x2E4 ++#define AUDOUT_FIFO_PIO_WRL 0x2E8 ++#define AUDOUT_FIFO_PIO_WRH 0x2EC ++#define AUDOUT1_FIFO_PIO_STS 0x2F0 /* Unknown */ ++#define AUDOUT1_FIFO_PIO_WRL 0x2F4 /* Unknown */ ++#define AUDOUT1_FIFO_PIO_WRH 0x2F8 /* Unknown */ ++#define AUD_RESAMPLE_CTRL0 0x2FC ++#define AUD_RESAMPLE_CTRL1 0x300 ++#define AUD_RESAMPLE_STATUS 0x304 ++ ++#endif /* _AUDIN_REGS_H_ */ diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/025_linux-4.18-yocto-meson64-0008-ASoC-meson-add-aiu-i2s-dma-support.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/025_linux-4.18-yocto-meson64-0008-ASoC-meson-add-aiu-i2s-dma-support.patch new file mode 100644 index 000000000..1de0e444a --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/025_linux-4.18-yocto-meson64-0008-ASoC-meson-add-aiu-i2s-dma-support.patch @@ -0,0 +1,416 @@ +From bb5102086db1579c1289440fa8aa184a70cb7c64 Mon Sep 17 00:00:00 2001 +From: Jerome Brunet +Date: Thu, 30 Mar 2017 12:14:40 +0200 +Subject: [PATCH] ASoC: meson: add aiu i2s dma support + +Add support for the i2s output dma which is part of the AIU block + +Signed-off-by: Jerome Brunet +--- + sound/soc/meson/Kconfig | 7 + + sound/soc/meson/Makefile | 2 + + sound/soc/meson/aiu-i2s-dma.c | 370 ++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 379 insertions(+) + create mode 100644 sound/soc/meson/aiu-i2s-dma.c + +diff --git a/sound/soc/meson/Kconfig b/sound/soc/meson/Kconfig +index ca0e3e9..88fbfc2 100644 +--- a/sound/soc/meson/Kconfig ++++ b/sound/soc/meson/Kconfig +@@ -7,3 +7,10 @@ menuconfig SND_SOC_MESON + Say Y or M if you want to add support for codecs attached to + the Amlogic Meson SoCs Audio interfaces. You will also need to + select the audio interfaces to support below. ++ ++config SND_SOC_MESON_I2S ++ tristate "Meson i2s interface" ++ depends on SND_SOC_MESON ++ help ++ Say Y or M if you want to add support for i2s dma driver for Amlogic ++ Meson SoCs. +diff --git a/sound/soc/meson/Makefile b/sound/soc/meson/Makefile +index 22028ab..273f275 100644 +--- a/sound/soc/meson/Makefile ++++ b/sound/soc/meson/Makefile +@@ -1,3 +1,5 @@ + snd-soc-meson-audio-core-objs := audio-core.o ++snd-soc-meson-aiu-i2s-dma-objs := aiu-i2s-dma.o + + obj-$(CONFIG_SND_SOC_MESON) += snd-soc-meson-audio-core.o ++obj-$(CONFIG_SND_SOC_MESON_I2S) += snd-soc-meson-aiu-i2s-dma.o +diff --git a/sound/soc/meson/aiu-i2s-dma.c b/sound/soc/meson/aiu-i2s-dma.c +new file mode 100644 +index 0000000..2684bd0 +--- /dev/null ++++ b/sound/soc/meson/aiu-i2s-dma.c +@@ -0,0 +1,370 @@ ++/* ++ * Copyright (C) 2017 BayLibre, SAS ++ * Author: Jerome Brunet ++ * Copyright (C) 2017 Amlogic, Inc. All rights reserved. ++ * ++ * 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. ++ * ++ * 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. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, see . ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#include "aiu-regs.h" ++#include "audio-core.h" ++ ++#define DRV_NAME "meson-aiu-i2s-dma" ++ ++struct aiu_i2s_dma { ++ struct meson_audio_core_data *core; ++ struct clk *fast; ++ int irq; ++}; ++ ++#define AIU_MEM_I2S_BUF_CNTL_INIT BIT(0) ++#define AIU_MEM_I2S_CONTROL_INIT BIT(0) ++#define AIU_MEM_I2S_CONTROL_FILL_EN BIT(1) ++#define AIU_MEM_I2S_CONTROL_EMPTY_EN BIT(2) ++#define AIU_MEM_I2S_CONTROL_MODE_16BIT BIT(6) ++#define AIU_MEM_I2S_CONTROL_BUSY BIT(7) ++#define AIU_MEM_I2S_CONTROL_DATA_READY BIT(8) ++#define AIU_MEM_I2S_CONTROL_LEVEL_CNTL BIT(9) ++#define AIU_MEM_I2S_MASKS_IRQ_BLOCK_MASK GENMASK(31, 16) ++#define AIU_MEM_I2S_MASKS_IRQ_BLOCK(n) ((n) << 16) ++#define AIU_MEM_I2S_MASKS_CH_MEM_MASK GENMASK(15, 8) ++#define AIU_MEM_I2S_MASKS_CH_MEM(ch) ((ch) << 8) ++#define AIU_MEM_I2S_MASKS_CH_RD_MASK GENMASK(7, 0) ++#define AIU_MEM_I2S_MASKS_CH_RD(ch) ((ch) << 0) ++#define AIU_RST_SOFT_I2S_FAST_DOMAIN BIT(0) ++#define AIU_RST_SOFT_I2S_SLOW_DOMAIN BIT(1) ++ ++/* ++ * The DMA works by i2s "blocks" (or DMA burst). The burst size and the memory ++ * layout expected depends on the mode of operation. ++ * ++ * - Normal mode: The channels are expected to be packed in 32 bytes groups ++ * interleaved the buffer. AIU_MEM_I2S_MASKS_CH_MEM is a bitfield representing ++ * the channels present in memory. AIU_MEM_I2S_MASKS_CH_MEM represents the ++ * channels read by the DMA. This is very flexible but the unsual memory layout ++ * makes it less easy to deal with. The burst size is 32 bytes times the number ++ * of channels read. ++ * ++ * - Split mode: ++ * Classical channel interleaved frame organisation. In this mode, ++ * AIU_MEM_I2S_MASKS_CH_MEM and AIU_MEM_I2S_MASKS_CH_MEM must be set to 0xff and ++ * the burst size is fixed to 256 bytes. The input can be either 2 or 8 ++ * channels. ++ * ++ * The following driver implements the split mode. ++ */ ++ ++#define AIU_I2S_DMA_BURST 256 ++ ++static struct snd_pcm_hardware aiu_i2s_dma_hw = { ++ .info = (SNDRV_PCM_INFO_INTERLEAVED | ++ SNDRV_PCM_INFO_MMAP | ++ SNDRV_PCM_INFO_MMAP_VALID | ++ SNDRV_PCM_INFO_PAUSE), ++ ++ .formats = (SNDRV_PCM_FMTBIT_S16_LE | ++ SNDRV_PCM_FMTBIT_S24_LE | ++ SNDRV_PCM_FMTBIT_S32_LE), ++ ++ /* ++ * TODO: The DMA can change the endianness, the msb position ++ * and deal with unsigned - support this later on ++ */ ++ ++ .rate_min = 8000, ++ .rate_max = 192000, ++ .channels_min = 2, ++ .channels_max = 8, ++ .period_bytes_min = AIU_I2S_DMA_BURST, ++ .period_bytes_max = AIU_I2S_DMA_BURST * 65535, ++ .periods_min = 2, ++ .periods_max = UINT_MAX, ++ .buffer_bytes_max = 1 * 1024 * 1024, ++ .fifo_size = 0, ++}; ++ ++static struct aiu_i2s_dma *aiu_i2s_dma_priv(struct snd_pcm_substream *s) ++{ ++ struct snd_soc_pcm_runtime *rtd = s->private_data; ++ struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME); ++ ++ return snd_soc_component_get_drvdata(component); ++} ++ ++static snd_pcm_uframes_t ++aiu_i2s_dma_pointer(struct snd_pcm_substream *substream) ++{ ++ struct snd_pcm_runtime *runtime = substream->runtime; ++ struct aiu_i2s_dma *priv = aiu_i2s_dma_priv(substream); ++ unsigned int addr; ++ int ret; ++ ++ ret = regmap_read(priv->core->aiu, AIU_MEM_I2S_RD_PTR, ++ &addr); ++ if (ret) ++ return 0; ++ ++ return bytes_to_frames(runtime, addr - (unsigned int)runtime->dma_addr); ++} ++ ++static void __dma_enable(struct aiu_i2s_dma *priv, bool enable) ++{ ++ unsigned int en_mask = (AIU_MEM_I2S_CONTROL_FILL_EN | ++ AIU_MEM_I2S_CONTROL_EMPTY_EN); ++ ++ regmap_update_bits(priv->core->aiu, AIU_MEM_I2S_CONTROL, en_mask, ++ enable ? en_mask : 0); ++ ++} ++ ++static int aiu_i2s_dma_trigger(struct snd_pcm_substream *substream, int cmd) ++{ ++ struct aiu_i2s_dma *priv = aiu_i2s_dma_priv(substream); ++ ++ switch (cmd) { ++ case SNDRV_PCM_TRIGGER_START: ++ case SNDRV_PCM_TRIGGER_RESUME: ++ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: ++ __dma_enable(priv, true); ++ break; ++ case SNDRV_PCM_TRIGGER_SUSPEND: ++ case SNDRV_PCM_TRIGGER_PAUSE_PUSH: ++ case SNDRV_PCM_TRIGGER_STOP: ++ __dma_enable(priv, false); ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static void __dma_init_mem(struct aiu_i2s_dma *priv) ++{ ++ regmap_update_bits(priv->core->aiu, AIU_MEM_I2S_CONTROL, ++ AIU_MEM_I2S_CONTROL_INIT, ++ AIU_MEM_I2S_CONTROL_INIT); ++ regmap_update_bits(priv->core->aiu, AIU_MEM_I2S_BUF_CNTL, ++ AIU_MEM_I2S_BUF_CNTL_INIT, ++ AIU_MEM_I2S_BUF_CNTL_INIT); ++ ++ regmap_update_bits(priv->core->aiu, AIU_MEM_I2S_CONTROL, ++ AIU_MEM_I2S_CONTROL_INIT, ++ 0); ++ regmap_update_bits(priv->core->aiu, AIU_MEM_I2S_BUF_CNTL, ++ AIU_MEM_I2S_BUF_CNTL_INIT, ++ 0); ++} ++ ++static int aiu_i2s_dma_prepare(struct snd_pcm_substream *substream) ++{ ++ struct aiu_i2s_dma *priv = aiu_i2s_dma_priv(substream); ++ ++ __dma_init_mem(priv); ++ ++ return 0; ++} ++ ++static int aiu_i2s_dma_hw_params(struct snd_pcm_substream *substream, ++ struct snd_pcm_hw_params *params) ++{ ++ struct snd_pcm_runtime *runtime = substream->runtime; ++ struct aiu_i2s_dma *priv = aiu_i2s_dma_priv(substream); ++ int ret; ++ u32 burst_num, mem_ctl; ++ dma_addr_t end_ptr; ++ ++ ret = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params)); ++ if (ret < 0) ++ return ret; ++ ++ /* Setup memory layout */ ++ if (params_physical_width(params) == 16) ++ mem_ctl = AIU_MEM_I2S_CONTROL_MODE_16BIT; ++ else ++ mem_ctl = 0; ++ ++ regmap_update_bits(priv->core->aiu, AIU_MEM_I2S_CONTROL, ++ AIU_MEM_I2S_CONTROL_MODE_16BIT, ++ mem_ctl); ++ ++ /* Initialize memory pointers */ ++ regmap_write(priv->core->aiu, AIU_MEM_I2S_START_PTR, runtime->dma_addr); ++ regmap_write(priv->core->aiu, AIU_MEM_I2S_RD_PTR, runtime->dma_addr); ++ ++ /* The end pointer is the address of the last valid block */ ++ end_ptr = runtime->dma_addr + runtime->dma_bytes - AIU_I2S_DMA_BURST; ++ regmap_write(priv->core->aiu, AIU_MEM_I2S_END_PTR, end_ptr); ++ ++ /* Memory masks */ ++ burst_num = params_period_bytes(params) / AIU_I2S_DMA_BURST; ++ regmap_write(priv->core->aiu, AIU_MEM_I2S_MASKS, ++ AIU_MEM_I2S_MASKS_CH_RD(0xff) | ++ AIU_MEM_I2S_MASKS_CH_MEM(0xff) | ++ AIU_MEM_I2S_MASKS_IRQ_BLOCK(burst_num)); ++ ++ return 0; ++} ++ ++static int aiu_i2s_dma_hw_free(struct snd_pcm_substream *substream) ++{ ++ return snd_pcm_lib_free_pages(substream); ++} ++ ++ ++static irqreturn_t aiu_i2s_dma_irq_block(int irq, void *dev_id) ++{ ++ struct snd_pcm_substream *playback = dev_id; ++ ++ snd_pcm_period_elapsed(playback); ++ ++ return IRQ_HANDLED; ++} ++ ++static int aiu_i2s_dma_open(struct snd_pcm_substream *substream) ++{ ++ struct aiu_i2s_dma *priv = aiu_i2s_dma_priv(substream); ++ int ret; ++ ++ snd_soc_set_runtime_hwparams(substream, &aiu_i2s_dma_hw); ++ ++ /* ++ * Make sure the buffer and period size are multiple of the DMA burst ++ * size ++ */ ++ ret = snd_pcm_hw_constraint_step(substream->runtime, 0, ++ SNDRV_PCM_HW_PARAM_BUFFER_BYTES, ++ AIU_I2S_DMA_BURST); ++ if (ret) ++ return ret; ++ ++ ret = snd_pcm_hw_constraint_step(substream->runtime, 0, ++ SNDRV_PCM_HW_PARAM_PERIOD_BYTES, ++ AIU_I2S_DMA_BURST); ++ if (ret) ++ return ret; ++ ++ /* Request the I2S DDR irq */ ++ ret = request_irq(priv->irq, aiu_i2s_dma_irq_block, 0, ++ DRV_NAME, substream); ++ if (ret) ++ return ret; ++ ++ /* Power up the i2s fast domain - can't write the registers w/o it */ ++ ret = clk_prepare_enable(priv->fast); ++ if (ret) ++ return ret; ++ ++ /* Make sure the dma is initially disabled */ ++ __dma_enable(priv, false); ++ ++ return 0; ++} ++ ++static int aiu_i2s_dma_close(struct snd_pcm_substream *substream) ++{ ++ struct aiu_i2s_dma *priv = aiu_i2s_dma_priv(substream); ++ ++ clk_disable_unprepare(priv->fast); ++ free_irq(priv->irq, substream); ++ ++ return 0; ++} ++ ++static const struct snd_pcm_ops aiu_i2s_dma_ops = { ++ .open = aiu_i2s_dma_open, ++ .close = aiu_i2s_dma_close, ++ .ioctl = snd_pcm_lib_ioctl, ++ .hw_params = aiu_i2s_dma_hw_params, ++ .hw_free = aiu_i2s_dma_hw_free, ++ .prepare = aiu_i2s_dma_prepare, ++ .pointer = aiu_i2s_dma_pointer, ++ .trigger = aiu_i2s_dma_trigger, ++}; ++ ++static int aiu_i2s_dma_new(struct snd_soc_pcm_runtime *rtd) ++{ ++ struct snd_card *card = rtd->card->snd_card; ++ size_t size = aiu_i2s_dma_hw.buffer_bytes_max; ++ ++ return snd_pcm_lib_preallocate_pages_for_all(rtd->pcm, ++ SNDRV_DMA_TYPE_DEV, ++ card->dev, size, size); ++} ++ ++static const struct snd_soc_component_driver aiu_i2s_platform = { ++ .ops = &aiu_i2s_dma_ops, ++ .pcm_new = aiu_i2s_dma_new, ++ .name = DRV_NAME, ++}; ++ ++static int aiu_i2s_dma_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct aiu_i2s_dma *priv; ++ ++ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); ++ if (!priv) ++ return -ENOMEM; ++ ++ platform_set_drvdata(pdev, priv); ++ priv->core = dev_get_drvdata(dev->parent); ++ ++ priv->fast = devm_clk_get(dev, "fast"); ++ if (IS_ERR(priv->fast)) { ++ if (PTR_ERR(priv->fast) != -EPROBE_DEFER) ++ dev_err(dev, "Can't get i2s fast domain clock\n"); ++ return PTR_ERR(priv->fast); ++ } ++ ++ priv->irq = platform_get_irq(pdev, 0); ++ if (priv->irq <= 0) { ++ dev_err(dev, "Can't get i2s ddr irq\n"); ++ return priv->irq; ++ } ++ ++ return devm_snd_soc_register_component(dev, &aiu_i2s_platform, ++ NULL, 0); ++} ++ ++static const struct of_device_id aiu_i2s_dma_of_match[] = { ++ { .compatible = "amlogic,meson-aiu-i2s-dma", }, ++ { .compatible = "amlogic,meson-gxbb-aiu-i2s-dma", }, ++ { .compatible = "amlogic,meson-gxl-aiu-i2s-dma", }, ++ {} ++}; ++MODULE_DEVICE_TABLE(of, aiu_i2s_dma_of_match); ++ ++static struct platform_driver aiu_i2s_dma_pdrv = { ++ .probe = aiu_i2s_dma_probe, ++ .driver = { ++ .name = DRV_NAME, ++ .of_match_table = aiu_i2s_dma_of_match, ++ }, ++}; ++module_platform_driver(aiu_i2s_dma_pdrv); ++ ++MODULE_DESCRIPTION("Meson AIU i2s DMA ASoC Driver"); ++MODULE_AUTHOR("Jerome Brunet "); ++MODULE_LICENSE("GPL v2"); diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/026_linux-4.18-yocto-meson64-0009-ASoC-meson-add-initial-i2s-dai-support.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/026_linux-4.18-yocto-meson64-0009-ASoC-meson-add-initial-i2s-dai-support.patch new file mode 100644 index 000000000..f3bac343f --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/026_linux-4.18-yocto-meson64-0009-ASoC-meson-add-initial-i2s-dai-support.patch @@ -0,0 +1,511 @@ +From 6a5036e9f7dbd99023c6f9482fed3a747868b1c2 Mon Sep 17 00:00:00 2001 +From: Jerome Brunet +Date: Thu, 30 Mar 2017 12:17:27 +0200 +Subject: [PATCH] ASoC: meson: add initial i2s dai support + +Add support for the i2s dai found on Amlogic Meson SoC family. +With this initial implementation, only playback is supported. +Capture will be part of furture work. + +Signed-off-by: Jerome Brunet +--- + sound/soc/meson/Kconfig | 2 +- + sound/soc/meson/Makefile | 2 + + sound/soc/meson/i2s-dai.c | 465 ++++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 468 insertions(+), 1 deletion(-) + create mode 100644 sound/soc/meson/i2s-dai.c + +diff --git a/sound/soc/meson/Kconfig b/sound/soc/meson/Kconfig +index 88fbfc2..478f29a 100644 +--- a/sound/soc/meson/Kconfig ++++ b/sound/soc/meson/Kconfig +@@ -12,5 +12,5 @@ config SND_SOC_MESON_I2S + tristate "Meson i2s interface" + depends on SND_SOC_MESON + help +- Say Y or M if you want to add support for i2s dma driver for Amlogic ++ Say Y or M if you want to add support for i2s driver for Amlogic + Meson SoCs. +diff --git a/sound/soc/meson/Makefile b/sound/soc/meson/Makefile +index 273f275..ea06dde 100644 +--- a/sound/soc/meson/Makefile ++++ b/sound/soc/meson/Makefile +@@ -1,5 +1,7 @@ + snd-soc-meson-audio-core-objs := audio-core.o + snd-soc-meson-aiu-i2s-dma-objs := aiu-i2s-dma.o ++snd-soc-meson-i2s-dai-objs := i2s-dai.o + + obj-$(CONFIG_SND_SOC_MESON) += snd-soc-meson-audio-core.o + obj-$(CONFIG_SND_SOC_MESON_I2S) += snd-soc-meson-aiu-i2s-dma.o ++obj-$(CONFIG_SND_SOC_MESON_I2S) += snd-soc-meson-i2s-dai.o +diff --git a/sound/soc/meson/i2s-dai.c b/sound/soc/meson/i2s-dai.c +new file mode 100644 +index 0000000..1008af8 +--- /dev/null ++++ b/sound/soc/meson/i2s-dai.c +@@ -0,0 +1,465 @@ ++/* ++ * Copyright (C) 2017 BayLibre, SAS ++ * Author: Jerome Brunet ++ * Copyright (C) 2017 Amlogic, Inc. All rights reserved. ++ * ++ * 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. ++ * ++ * 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. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, see . ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#include "aiu-regs.h" ++#include "audio-core.h" ++ ++#define DRV_NAME "meson-i2s-dai" ++ ++struct meson_i2s_dai { ++ struct meson_audio_core_data *core; ++ struct clk *mclk; ++ struct clk *bclks; ++ struct clk *iface; ++ struct clk *fast; ++ bool bclks_idle; ++}; ++ ++#define AIU_CLK_CTRL_I2S_DIV_EN BIT(0) ++#define AIU_CLK_CTRL_I2S_DIV_MASK GENMASK(3, 2) ++#define AIU_CLK_CTRL_AOCLK_POLARITY_MASK BIT(6) ++#define AIU_CLK_CTRL_AOCLK_POLARITY_NORMAL (0 << 6) ++#define AIU_CLK_CTRL_AOCLK_POLARITY_INVERTED (1 << 6) ++#define AIU_CLK_CTRL_ALRCLK_POLARITY_MASK BIT(7) ++#define AIU_CLK_CTRL_ALRCLK_POLARITY_NORMAL (0 << 7) ++#define AIU_CLK_CTRL_ALRCLK_POLARITY_INVERTED (1 << 7) ++#define AIU_CLK_CTRL_ALRCLK_SKEW_MASK GENMASK(9, 8) ++#define AIU_CLK_CTRL_ALRCLK_LEFT_J (0 << 8) ++#define AIU_CLK_CTRL_ALRCLK_I2S (1 << 8) ++#define AIU_CLK_CTRL_ALRCLK_RIGHT_J (2 << 8) ++#define AIU_CLK_CTRL_MORE_I2S_DIV_MASK GENMASK(5, 0) ++#define AIU_CLK_CTRL_MORE_I2S_DIV(div) (((div) - 1) << 0) ++#define AIU_CODEC_DAC_LRCLK_CTRL_DIV_MASK GENMASK(11, 0) ++#define AIU_CODEC_DAC_LRCLK_CTRL_DIV(div) (((div) - 1) << 0) ++#define AIU_I2S_DAC_CFG_PAYLOAD_SIZE_MASK GENMASK(1, 0) ++#define AIU_I2S_DAC_CFG_AOCLK_32 (0 << 0) ++#define AIU_I2S_DAC_CFG_AOCLK_48 (2 << 0) ++#define AIU_I2S_DAC_CFG_AOCLK_64 (3 << 0) ++#define AIU_I2S_MISC_HOLD_EN BIT(2) ++#define AIU_I2S_SOURCE_DESC_MODE_8CH BIT(0) ++#define AIU_I2S_SOURCE_DESC_MODE_24BIT BIT(5) ++#define AIU_I2S_SOURCE_DESC_MODE_32BIT BIT(9) ++#define AIU_I2S_SOURCE_DESC_MODE_SPLIT BIT(11) ++ ++static void __hold(struct meson_i2s_dai *priv, bool enable) ++{ ++ regmap_update_bits(priv->core->aiu, AIU_I2S_MISC, ++ AIU_I2S_MISC_HOLD_EN, ++ enable ? AIU_I2S_MISC_HOLD_EN : 0); ++} ++ ++static void __divider_enable(struct meson_i2s_dai *priv, bool enable) ++{ ++ regmap_update_bits(priv->core->aiu, AIU_CLK_CTRL, ++ AIU_CLK_CTRL_I2S_DIV_EN, ++ enable ? AIU_CLK_CTRL_I2S_DIV_EN : 0); ++} ++ ++static void __playback_start(struct meson_i2s_dai *priv) ++{ ++ __divider_enable(priv, true); ++ __hold(priv, false); ++} ++ ++static void __playback_stop(struct meson_i2s_dai *priv, bool clk_force) ++{ ++ __hold(priv, true); ++ /* Disable the bit clks if necessary */ ++ if (clk_force || !priv->bclks_idle) ++ __divider_enable(priv, false); ++} ++ ++static int meson_i2s_dai_trigger(struct snd_pcm_substream *substream, int cmd, ++ struct snd_soc_dai *dai) ++{ ++ struct meson_i2s_dai *priv = snd_soc_dai_get_drvdata(dai); ++ bool clk_force_stop = false; ++ ++ switch (cmd) { ++ case SNDRV_PCM_TRIGGER_START: ++ case SNDRV_PCM_TRIGGER_RESUME: ++ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: ++ __playback_start(priv); ++ return 0; ++ ++ case SNDRV_PCM_TRIGGER_STOP: ++ case SNDRV_PCM_TRIGGER_SUSPEND: ++ clk_force_stop = true; ++ case SNDRV_PCM_TRIGGER_PAUSE_PUSH: ++ __playback_stop(priv, clk_force_stop); ++ return 0; ++ ++ default: ++ return -EINVAL; ++ } ++} ++ ++static int __bclks_set_rate(struct meson_i2s_dai *priv, unsigned int srate, ++ unsigned int width) ++{ ++ unsigned int fs; ++ ++ /* Get the oversampling factor */ ++ fs = DIV_ROUND_CLOSEST(clk_get_rate(priv->mclk), srate); ++ ++ /* ++ * This DAI is usually connected to the dw-hdmi which does not support ++ * bclk being 32 * lrclk or 48 * lrclk ++ * Restrict to blck = 64 * lrclk ++ */ ++ if (fs % 64) ++ return -EINVAL; ++ ++ /* Set the divider between lrclk and bclk */ ++ regmap_update_bits(priv->core->aiu, AIU_I2S_DAC_CFG, ++ AIU_I2S_DAC_CFG_PAYLOAD_SIZE_MASK, ++ AIU_I2S_DAC_CFG_AOCLK_64); ++ ++ regmap_update_bits(priv->core->aiu, AIU_CODEC_DAC_LRCLK_CTRL, ++ AIU_CODEC_DAC_LRCLK_CTRL_DIV_MASK, ++ AIU_CODEC_DAC_LRCLK_CTRL_DIV(64)); ++ ++ /* Use CLK_MORE for the i2s divider */ ++ regmap_update_bits(priv->core->aiu, AIU_CLK_CTRL, ++ AIU_CLK_CTRL_I2S_DIV_MASK, ++ 0); ++ ++ regmap_update_bits(priv->core->aiu, AIU_CLK_CTRL_MORE, ++ AIU_CLK_CTRL_MORE_I2S_DIV_MASK, ++ AIU_CLK_CTRL_MORE_I2S_DIV(fs / 64)); ++ ++ return 0; ++} ++ ++static int __setup_desc(struct meson_i2s_dai *priv, unsigned int width, ++ unsigned int channels) ++{ ++ u32 desc = 0; ++ ++ switch (width) { ++ case 24: ++ /* ++ * For some reason, 24 bits wide audio don't play well ++ * if the 32 bits mode is not set ++ */ ++ desc |= (AIU_I2S_SOURCE_DESC_MODE_24BIT | ++ AIU_I2S_SOURCE_DESC_MODE_32BIT); ++ break; ++ case 16: ++ break; ++ ++ default: ++ return -EINVAL; ++ } ++ ++ switch (channels) { ++ case 2: /* Nothing to do */ ++ break; ++ case 8: ++ /* TODO: Still requires testing ... */ ++ desc |= AIU_I2S_SOURCE_DESC_MODE_8CH; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ regmap_update_bits(priv->core->aiu, AIU_I2S_SOURCE_DESC, ++ AIU_I2S_SOURCE_DESC_MODE_8CH | ++ AIU_I2S_SOURCE_DESC_MODE_24BIT | ++ AIU_I2S_SOURCE_DESC_MODE_32BIT, ++ desc); ++ ++ return 0; ++} ++ ++static int meson_i2s_dai_hw_params(struct snd_pcm_substream *substream, ++ struct snd_pcm_hw_params *params, ++ struct snd_soc_dai *dai) ++{ ++ struct meson_i2s_dai *priv = snd_soc_dai_get_drvdata(dai); ++ unsigned int width = params_width(params); ++ unsigned int channels = params_channels(params); ++ unsigned int rate = params_rate(params); ++ int ret; ++ ++ ret = __setup_desc(priv, width, channels); ++ if (ret) { ++ dev_err(dai->dev, "Unable set to set i2s description\n"); ++ return ret; ++ } ++ ++ ret = __bclks_set_rate(priv, rate, width); ++ if (ret) { ++ dev_err(dai->dev, "Unable set to the i2s clock rates\n"); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static int meson_i2s_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) ++{ ++ struct meson_i2s_dai *priv = snd_soc_dai_get_drvdata(dai); ++ u32 val; ++ ++ if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS) ++ return -EINVAL; ++ ++ /* DAI output mode */ ++ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { ++ case SND_SOC_DAIFMT_I2S: ++ val = AIU_CLK_CTRL_ALRCLK_I2S; ++ break; ++ case SND_SOC_DAIFMT_LEFT_J: ++ val = AIU_CLK_CTRL_ALRCLK_LEFT_J; ++ break; ++ case SND_SOC_DAIFMT_RIGHT_J: ++ val = AIU_CLK_CTRL_ALRCLK_RIGHT_J; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ regmap_update_bits(priv->core->aiu, AIU_CLK_CTRL, ++ AIU_CLK_CTRL_ALRCLK_SKEW_MASK, ++ val); ++ ++ /* DAI clock polarity */ ++ switch (fmt & SND_SOC_DAIFMT_INV_MASK) { ++ case SND_SOC_DAIFMT_IB_IF: ++ /* Invert both clocks */ ++ val = AIU_CLK_CTRL_ALRCLK_POLARITY_INVERTED | ++ AIU_CLK_CTRL_AOCLK_POLARITY_INVERTED; ++ break; ++ case SND_SOC_DAIFMT_IB_NF: ++ /* Invert bit clock */ ++ val = AIU_CLK_CTRL_ALRCLK_POLARITY_NORMAL | ++ AIU_CLK_CTRL_AOCLK_POLARITY_INVERTED; ++ break; ++ case SND_SOC_DAIFMT_NB_IF: ++ /* Invert frame clock */ ++ val = AIU_CLK_CTRL_ALRCLK_POLARITY_INVERTED | ++ AIU_CLK_CTRL_AOCLK_POLARITY_NORMAL; ++ break; ++ case SND_SOC_DAIFMT_NB_NF: ++ /* Normal clocks */ ++ val = AIU_CLK_CTRL_ALRCLK_POLARITY_NORMAL | ++ AIU_CLK_CTRL_AOCLK_POLARITY_NORMAL; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ regmap_update_bits(priv->core->aiu, AIU_CLK_CTRL, ++ AIU_CLK_CTRL_ALRCLK_POLARITY_MASK | ++ AIU_CLK_CTRL_AOCLK_POLARITY_MASK, ++ val); ++ ++ switch (fmt & SND_SOC_DAIFMT_CLOCK_MASK) { ++ case SND_SOC_DAIFMT_CONT: ++ priv->bclks_idle = true; ++ break; ++ case SND_SOC_DAIFMT_GATED: ++ priv->bclks_idle = false; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static int meson_i2s_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id, ++ unsigned int freq, int dir) ++{ ++ struct meson_i2s_dai *priv = snd_soc_dai_get_drvdata(dai); ++ int ret; ++ ++ if (WARN_ON(clk_id != 0)) ++ return -EINVAL; ++ ++ if (dir == SND_SOC_CLOCK_IN) ++ return 0; ++ ++ ret = clk_set_rate(priv->mclk, freq); ++ if (ret) { ++ dev_err(dai->dev, "Failed to set sysclk to %uHz", freq); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static int meson_i2s_dai_startup(struct snd_pcm_substream *substream, ++ struct snd_soc_dai *dai) ++{ ++ struct meson_i2s_dai *priv = snd_soc_dai_get_drvdata(dai); ++ int ret; ++ ++ /* Power up the i2s fast domain - can't write the registers w/o it */ ++ ret = clk_prepare_enable(priv->fast); ++ if (ret) ++ goto out_clk_fast; ++ ++ /* Make sure nothing gets out of the DAI yet */ ++ __hold(priv, true); ++ ++ /* I2S encoder needs the mixer interface gate */ ++ ret = clk_prepare_enable(priv->iface); ++ if (ret) ++ goto out_clk_iface; ++ ++ /* Enable the i2s master clock */ ++ ret = clk_prepare_enable(priv->mclk); ++ if (ret) ++ goto out_mclk; ++ ++ /* Enable the bit clock gate */ ++ ret = clk_prepare_enable(priv->bclks); ++ if (ret) ++ goto out_bclks; ++ ++ /* Make sure the interface expect a memory layout we can work with */ ++ regmap_update_bits(priv->core->aiu, AIU_I2S_SOURCE_DESC, ++ AIU_I2S_SOURCE_DESC_MODE_SPLIT, ++ AIU_I2S_SOURCE_DESC_MODE_SPLIT); ++ ++ return 0; ++ ++out_bclks: ++ clk_disable_unprepare(priv->mclk); ++out_mclk: ++ clk_disable_unprepare(priv->iface); ++out_clk_iface: ++ clk_disable_unprepare(priv->fast); ++out_clk_fast: ++ return ret; ++} ++ ++static void meson_i2s_dai_shutdown(struct snd_pcm_substream *substream, ++ struct snd_soc_dai *dai) ++{ ++ struct meson_i2s_dai *priv = snd_soc_dai_get_drvdata(dai); ++ ++ clk_disable_unprepare(priv->bclks); ++ clk_disable_unprepare(priv->mclk); ++ clk_disable_unprepare(priv->iface); ++ clk_disable_unprepare(priv->fast); ++} ++ ++static const struct snd_soc_dai_ops meson_i2s_dai_ops = { ++ .startup = meson_i2s_dai_startup, ++ .shutdown = meson_i2s_dai_shutdown, ++ .trigger = meson_i2s_dai_trigger, ++ .hw_params = meson_i2s_dai_hw_params, ++ .set_fmt = meson_i2s_dai_set_fmt, ++ .set_sysclk = meson_i2s_dai_set_sysclk, ++}; ++ ++static struct snd_soc_dai_driver meson_i2s_dai = { ++ .playback = { ++ .stream_name = "Playback", ++ .channels_min = 2, ++ .channels_max = 8, ++ .rates = SNDRV_PCM_RATE_8000_192000, ++ .formats = (SNDRV_PCM_FMTBIT_S16_LE | ++ SNDRV_PCM_FMTBIT_S24_LE) ++ }, ++ .ops = &meson_i2s_dai_ops, ++}; ++ ++static const struct snd_soc_component_driver meson_i2s_dai_component = { ++ .name = DRV_NAME, ++}; ++ ++static int meson_i2s_dai_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct meson_i2s_dai *priv; ++ ++ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); ++ if (!priv) ++ return -ENOMEM; ++ ++ platform_set_drvdata(pdev, priv); ++ priv->core = dev_get_drvdata(dev->parent); ++ ++ priv->fast = devm_clk_get(dev, "fast"); ++ if (IS_ERR(priv->fast)) { ++ if (PTR_ERR(priv->fast) != -EPROBE_DEFER) ++ dev_err(dev, "Can't get the i2s fast domain clock\n"); ++ return PTR_ERR(priv->fast); ++ } ++ ++ priv->iface = devm_clk_get(dev, "iface"); ++ if (IS_ERR(priv->iface)) { ++ if (PTR_ERR(priv->iface) != -EPROBE_DEFER) ++ dev_err(dev, "Can't get i2s dai clock gate\n"); ++ return PTR_ERR(priv->iface); ++ } ++ ++ priv->bclks = devm_clk_get(dev, "bclks"); ++ if (IS_ERR(priv->bclks)) { ++ if (PTR_ERR(priv->bclks) != -EPROBE_DEFER) ++ dev_err(dev, "Can't get bit clocks gate\n"); ++ return PTR_ERR(priv->bclks); ++ } ++ ++ priv->mclk = devm_clk_get(dev, "mclk"); ++ if (IS_ERR(priv->mclk)) { ++ if (PTR_ERR(priv->mclk) != -EPROBE_DEFER) ++ dev_err(dev, "failed to get the i2s master clock\n"); ++ return PTR_ERR(priv->mclk); ++ } ++ ++ return devm_snd_soc_register_component(dev, &meson_i2s_dai_component, ++ &meson_i2s_dai, 1); ++} ++ ++static const struct of_device_id meson_i2s_dai_of_match[] = { ++ { .compatible = "amlogic,meson-i2s-dai", }, ++ { .compatible = "amlogic,meson-gxbb-i2s-dai", }, ++ { .compatible = "amlogic,meson-gxl-i2s-dai", }, ++ {} ++}; ++MODULE_DEVICE_TABLE(of, meson_i2s_dai_of_match); ++ ++static struct platform_driver meson_i2s_dai_pdrv = { ++ .probe = meson_i2s_dai_probe, ++ .driver = { ++ .name = DRV_NAME, ++ .of_match_table = meson_i2s_dai_of_match, ++ }, ++}; ++module_platform_driver(meson_i2s_dai_pdrv); ++ ++MODULE_DESCRIPTION("Meson i2s DAI ASoC Driver"); ++MODULE_AUTHOR("Jerome Brunet "); ++MODULE_LICENSE("GPL v2"); diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/027_linux-4.18-yocto-meson64-0010-ASoC-meson-add-aiu-spdif-dma-support.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/027_linux-4.18-yocto-meson64-0010-ASoC-meson-add-aiu-spdif-dma-support.patch new file mode 100644 index 000000000..380f5d5b2 --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/027_linux-4.18-yocto-meson64-0010-ASoC-meson-add-aiu-spdif-dma-support.patch @@ -0,0 +1,438 @@ +From 8dd5edaf984e4c8d6f7ca1e7709b3109cf7dd780 Mon Sep 17 00:00:00 2001 +From: Jerome Brunet +Date: Thu, 30 Mar 2017 13:43:52 +0200 +Subject: [PATCH] ASoC: meson: add aiu spdif dma support + +Add support for the spdif output dma which is part of the AIU block + +Signed-off-by: Jerome Brunet +--- + sound/soc/meson/Kconfig | 7 + + sound/soc/meson/Makefile | 2 + + sound/soc/meson/aiu-spdif-dma.c | 388 ++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 397 insertions(+) + create mode 100644 sound/soc/meson/aiu-spdif-dma.c + +diff --git a/sound/soc/meson/Kconfig b/sound/soc/meson/Kconfig +index 478f29a..3fb93b9 100644 +--- a/sound/soc/meson/Kconfig ++++ b/sound/soc/meson/Kconfig +@@ -14,3 +14,10 @@ config SND_SOC_MESON_I2S + help + Say Y or M if you want to add support for i2s driver for Amlogic + Meson SoCs. ++ ++config SND_SOC_MESON_SPDIF ++ tristate "Meson spdif interface" ++ depends on SND_SOC_MESON ++ help ++ Say Y or M if you want to add support for spdif dma driver for Amlogic ++ Meson SoCs. +diff --git a/sound/soc/meson/Makefile b/sound/soc/meson/Makefile +index ea06dde..cef9a9d 100644 +--- a/sound/soc/meson/Makefile ++++ b/sound/soc/meson/Makefile +@@ -1,7 +1,9 @@ + snd-soc-meson-audio-core-objs := audio-core.o + snd-soc-meson-aiu-i2s-dma-objs := aiu-i2s-dma.o ++snd-soc-meson-aiu-spdif-dma-objs := aiu-spdif-dma.o + snd-soc-meson-i2s-dai-objs := i2s-dai.o + + obj-$(CONFIG_SND_SOC_MESON) += snd-soc-meson-audio-core.o + obj-$(CONFIG_SND_SOC_MESON_I2S) += snd-soc-meson-aiu-i2s-dma.o + obj-$(CONFIG_SND_SOC_MESON_I2S) += snd-soc-meson-i2s-dai.o ++obj-$(CONFIG_SND_SOC_MESON_SPDIF) += snd-soc-meson-aiu-spdif-dma.o +diff --git a/sound/soc/meson/aiu-spdif-dma.c b/sound/soc/meson/aiu-spdif-dma.c +new file mode 100644 +index 0000000..81c3b85 +--- /dev/null ++++ b/sound/soc/meson/aiu-spdif-dma.c +@@ -0,0 +1,388 @@ ++/* ++ * Copyright (C) 2017 BayLibre, SAS ++ * Author: Jerome Brunet ++ * Copyright (C) 2017 Amlogic, Inc. All rights reserved. ++ * ++ * 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. ++ * ++ * 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. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, see . ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#include "aiu-regs.h" ++#include "audio-core.h" ++ ++#define DRV_NAME "meson-aiu-spdif-dma" ++ ++struct aiu_spdif_dma { ++ struct meson_audio_core_data *core; ++ struct clk *fast; ++ int irq; ++}; ++ ++#define AIU_958_DCU_FF_CTRL_EN BIT(0) ++#define AIU_958_DCU_FF_CTRL_AUTO_DISABLE BIT(1) ++#define AIU_958_DCU_FF_CTRL_IRQ_MODE_MASK GENMASK(3, 2) ++#define AIU_958_DCU_FF_CTRL_IRQ_OUT_THD BIT(2) ++#define AIU_958_DCU_FF_CTRL_IRQ_FRAME_READ BIT(3) ++#define AIU_958_DCU_FF_CTRL_SYNC_HEAD_EN BIT(4) ++#define AIU_958_DCU_FF_CTRL_BYTE_SEEK BIT(5) ++#define AIU_958_DCU_FF_CTRL_CONTINUE BIT(6) ++#define AIU_MEM_IEC958_BUF_CNTL_INIT BIT(0) ++#define AIU_MEM_IEC958_CONTROL_INIT BIT(0) ++#define AIU_MEM_IEC958_CONTROL_FILL_EN BIT(1) ++#define AIU_MEM_IEC958_CONTROL_EMPTY_EN BIT(2) ++#define AIU_MEM_IEC958_CONTROL_ENDIAN_MASK GENMASK(5, 3) ++#define AIU_MEM_IEC958_CONTROL_RD_DDR BIT(6) ++#define AIU_MEM_IEC958_CONTROL_MODE_16BIT BIT(7) ++#define AIU_MEM_IEC958_MASKS_CH_MEM_MASK GENMASK(15, 8) ++#define AIU_MEM_IEC958_MASKS_CH_MEM(ch) ((ch) << 8) ++#define AIU_MEM_IEC958_MASKS_CH_RD_MASK GENMASK(7, 0) ++#define AIU_MEM_IEC958_MASKS_CH_RD(ch) ((ch) << 0) ++ ++#define AIU_SPDIF_DMA_BURST 8 ++#define AIU_SPDIF_BPF_MAX USHRT_MAX ++ ++static struct snd_pcm_hardware aiu_spdif_dma_hw = { ++ .info = (SNDRV_PCM_INFO_INTERLEAVED | ++ SNDRV_PCM_INFO_MMAP | ++ SNDRV_PCM_INFO_MMAP_VALID | ++ SNDRV_PCM_INFO_PAUSE), ++ ++ .formats = (SNDRV_PCM_FMTBIT_S16_LE | ++ SNDRV_PCM_FMTBIT_S24_LE | ++ SNDRV_PCM_FMTBIT_S32_LE), ++ ++ .rates = (SNDRV_PCM_RATE_32000 | ++ SNDRV_PCM_RATE_44100 | ++ SNDRV_PCM_RATE_48000 | ++ SNDRV_PCM_RATE_96000 | ++ SNDRV_PCM_RATE_192000), ++ /* ++ * TODO: The DMA can change the endianness, the msb position ++ * and deal with unsigned - support this later on ++ */ ++ ++ .channels_min = 2, ++ .channels_max = 2, ++ .period_bytes_min = AIU_SPDIF_DMA_BURST, ++ .period_bytes_max = AIU_SPDIF_BPF_MAX, ++ .periods_min = 2, ++ .periods_max = UINT_MAX, ++ .buffer_bytes_max = 1 * 1024 * 1024, ++ .fifo_size = 0, ++}; ++ ++static struct aiu_spdif_dma *aiu_spdif_dma_priv(struct snd_pcm_substream *s) ++{ ++ struct snd_soc_pcm_runtime *rtd = s->private_data; ++ struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME); ++ ++ return snd_soc_component_get_drvdata(component); ++} ++ ++static snd_pcm_uframes_t ++aiu_spdif_dma_pointer(struct snd_pcm_substream *substream) ++{ ++ struct snd_pcm_runtime *runtime = substream->runtime; ++ struct aiu_spdif_dma *priv = aiu_spdif_dma_priv(substream); ++ unsigned int addr; ++ int ret; ++ ++ ret = regmap_read(priv->core->aiu, AIU_MEM_IEC958_RD_PTR, ++ &addr); ++ if (ret) ++ return 0; ++ ++ return bytes_to_frames(runtime, addr - (unsigned int)runtime->dma_addr); ++} ++ ++static void __dma_enable(struct aiu_spdif_dma *priv, bool enable) ++{ ++ unsigned int en_mask = (AIU_MEM_IEC958_CONTROL_FILL_EN | ++ AIU_MEM_IEC958_CONTROL_EMPTY_EN); ++ ++ regmap_update_bits(priv->core->aiu, AIU_MEM_IEC958_CONTROL, en_mask, ++ enable ? en_mask : 0); ++} ++ ++static void __dcu_fifo_enable(struct aiu_spdif_dma *priv, bool enable) ++{ ++ regmap_update_bits(priv->core->aiu, AIU_958_DCU_FF_CTRL, ++ AIU_958_DCU_FF_CTRL_EN, ++ enable ? AIU_958_DCU_FF_CTRL_EN : 0); ++} ++ ++static int aiu_spdif_dma_trigger(struct snd_pcm_substream *substream, int cmd) ++{ ++ struct aiu_spdif_dma *priv = aiu_spdif_dma_priv(substream); ++ ++ switch (cmd) { ++ case SNDRV_PCM_TRIGGER_START: ++ case SNDRV_PCM_TRIGGER_RESUME: ++ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: ++ __dcu_fifo_enable(priv, true); ++ __dma_enable(priv, true); ++ break; ++ case SNDRV_PCM_TRIGGER_SUSPEND: ++ case SNDRV_PCM_TRIGGER_PAUSE_PUSH: ++ case SNDRV_PCM_TRIGGER_STOP: ++ __dma_enable(priv, false); ++ __dcu_fifo_enable(priv, false); ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static void __dma_init_mem(struct aiu_spdif_dma *priv) ++{ ++ regmap_update_bits(priv->core->aiu, AIU_MEM_IEC958_CONTROL, ++ AIU_MEM_IEC958_CONTROL_INIT, ++ AIU_MEM_IEC958_CONTROL_INIT); ++ regmap_update_bits(priv->core->aiu, AIU_MEM_IEC958_BUF_CNTL, ++ AIU_MEM_IEC958_BUF_CNTL_INIT, ++ AIU_MEM_IEC958_BUF_CNTL_INIT); ++ ++ regmap_update_bits(priv->core->aiu, AIU_MEM_IEC958_CONTROL, ++ AIU_MEM_IEC958_CONTROL_INIT, ++ 0); ++ regmap_update_bits(priv->core->aiu, AIU_MEM_IEC958_BUF_CNTL, ++ AIU_MEM_IEC958_BUF_CNTL_INIT, ++ 0); ++} ++ ++static int aiu_spdif_dma_prepare(struct snd_pcm_substream *substream) ++{ ++ struct aiu_spdif_dma *priv = aiu_spdif_dma_priv(substream); ++ ++ __dma_init_mem(priv); ++ ++ return 0; ++} ++ ++static int __setup_memory_layout(struct aiu_spdif_dma *priv, ++ unsigned int width) ++{ ++ u32 mem_ctl = AIU_MEM_IEC958_CONTROL_RD_DDR; ++ ++ if (width == 16) ++ mem_ctl |= AIU_MEM_IEC958_CONTROL_MODE_16BIT; ++ ++ regmap_update_bits(priv->core->aiu, AIU_MEM_IEC958_CONTROL, ++ AIU_MEM_IEC958_CONTROL_ENDIAN_MASK | ++ AIU_MEM_IEC958_CONTROL_MODE_16BIT | ++ AIU_MEM_IEC958_CONTROL_RD_DDR, ++ mem_ctl); ++ ++ return 0; ++} ++ ++static int aiu_spdif_dma_hw_params(struct snd_pcm_substream *substream, ++ struct snd_pcm_hw_params *params) ++{ ++ struct snd_pcm_runtime *runtime = substream->runtime; ++ struct aiu_spdif_dma *priv = aiu_spdif_dma_priv(substream); ++ int ret; ++ dma_addr_t end_ptr; ++ ++ ret = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params)); ++ if (ret < 0) ++ return ret; ++ ++ ret = __setup_memory_layout(priv, params_physical_width(params)); ++ if (ret) ++ return ret; ++ ++ /* Initialize memory pointers */ ++ regmap_write(priv->core->aiu, ++ AIU_MEM_IEC958_START_PTR, runtime->dma_addr); ++ regmap_write(priv->core->aiu, ++ AIU_MEM_IEC958_RD_PTR, runtime->dma_addr); ++ ++ /* The end pointer is the address of the last valid block */ ++ end_ptr = runtime->dma_addr + runtime->dma_bytes - AIU_SPDIF_DMA_BURST; ++ regmap_write(priv->core->aiu, AIU_MEM_IEC958_END_PTR, end_ptr); ++ ++ /* Memory masks */ ++ regmap_write(priv->core->aiu, AIU_MEM_IEC958_MASKS, ++ AIU_MEM_IEC958_MASKS_CH_RD(0xff) | ++ AIU_MEM_IEC958_MASKS_CH_MEM(0xff)); ++ ++ /* Setup the number bytes read by the FIFO between each IRQ */ ++ regmap_write(priv->core->aiu, AIU_958_BPF, params_period_bytes(params)); ++ ++ /* ++ * AUTO_DISABLE and SYNC_HEAD are enabled by default but ++ * this should be disabled in PCM (uncompressed) mode ++ */ ++ regmap_update_bits(priv->core->aiu, AIU_958_DCU_FF_CTRL, ++ AIU_958_DCU_FF_CTRL_AUTO_DISABLE | ++ AIU_958_DCU_FF_CTRL_IRQ_MODE_MASK | ++ AIU_958_DCU_FF_CTRL_SYNC_HEAD_EN, ++ AIU_958_DCU_FF_CTRL_IRQ_FRAME_READ); ++ ++ return 0; ++} ++ ++static int aiu_spdif_dma_hw_free(struct snd_pcm_substream *substream) ++{ ++ return snd_pcm_lib_free_pages(substream); ++} ++ ++static irqreturn_t aiu_spdif_dma_irq(int irq, void *dev_id) ++{ ++ struct snd_pcm_substream *playback = dev_id; ++ ++ snd_pcm_period_elapsed(playback); ++ ++ return IRQ_HANDLED; ++} ++ ++static int aiu_spdif_dma_open(struct snd_pcm_substream *substream) ++{ ++ struct aiu_spdif_dma *priv = aiu_spdif_dma_priv(substream); ++ int ret; ++ ++ snd_soc_set_runtime_hwparams(substream, &aiu_spdif_dma_hw); ++ ++ /* ++ * Make sure the buffer and period size are multiple of the DMA burst ++ * size ++ */ ++ ret = snd_pcm_hw_constraint_step(substream->runtime, 0, ++ SNDRV_PCM_HW_PARAM_BUFFER_BYTES, ++ AIU_SPDIF_DMA_BURST); ++ if (ret) ++ return ret; ++ ++ ret = snd_pcm_hw_constraint_step(substream->runtime, 0, ++ SNDRV_PCM_HW_PARAM_PERIOD_BYTES, ++ AIU_SPDIF_DMA_BURST); ++ if (ret) ++ return ret; ++ ++ /* Request the SPDIF DDR irq */ ++ ret = request_irq(priv->irq, aiu_spdif_dma_irq, 0, ++ DRV_NAME, substream); ++ if (ret) ++ return ret; ++ ++ /* Power up the spdif fast domain - can't write the register w/o it */ ++ ret = clk_prepare_enable(priv->fast); ++ if (ret) ++ return ret; ++ ++ /* Make sure the dma is initially halted */ ++ __dma_enable(priv, false); ++ __dcu_fifo_enable(priv, false); ++ ++ return 0; ++} ++ ++static int aiu_spdif_dma_close(struct snd_pcm_substream *substream) ++{ ++ struct aiu_spdif_dma *priv = aiu_spdif_dma_priv(substream); ++ ++ clk_disable_unprepare(priv->fast); ++ free_irq(priv->irq, substream); ++ ++ return 0; ++} ++ ++static const struct snd_pcm_ops aiu_spdif_dma_ops = { ++ .open = aiu_spdif_dma_open, ++ .close = aiu_spdif_dma_close, ++ .ioctl = snd_pcm_lib_ioctl, ++ .hw_params = aiu_spdif_dma_hw_params, ++ .hw_free = aiu_spdif_dma_hw_free, ++ .prepare = aiu_spdif_dma_prepare, ++ .pointer = aiu_spdif_dma_pointer, ++ .trigger = aiu_spdif_dma_trigger, ++}; ++ ++static int aiu_spdif_dma_new(struct snd_soc_pcm_runtime *rtd) ++{ ++ struct snd_card *card = rtd->card->snd_card; ++ size_t size = aiu_spdif_dma_hw.buffer_bytes_max; ++ ++ return snd_pcm_lib_preallocate_pages_for_all(rtd->pcm, ++ SNDRV_DMA_TYPE_DEV, ++ card->dev, size, size); ++} ++ ++static const struct snd_soc_component_driver aiu_spdif_platform = { ++ .ops = &aiu_spdif_dma_ops, ++ .pcm_new = aiu_spdif_dma_new, ++ .name = DRV_NAME, ++}; ++ ++static int aiu_spdif_dma_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct aiu_spdif_dma *priv; ++ ++ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); ++ if (!priv) ++ return -ENOMEM; ++ ++ platform_set_drvdata(pdev, priv); ++ priv->core = dev_get_drvdata(dev->parent); ++ ++ priv->fast = devm_clk_get(dev, "fast"); ++ if (IS_ERR(priv->fast)) { ++ if (PTR_ERR(priv->fast) != -EPROBE_DEFER) ++ dev_err(dev, "Can't get spdif fast domain clock\n"); ++ return PTR_ERR(priv->fast); ++ } ++ ++ priv->irq = platform_get_irq(pdev, 0); ++ if (priv->irq <= 0) { ++ dev_err(dev, "Can't get spdif ddr irq\n"); ++ return priv->irq; ++ } ++ ++ return devm_snd_soc_register_component(dev, &aiu_spdif_platform, ++ NULL, 0); ++} ++ ++static const struct of_device_id aiu_spdif_dma_of_match[] = { ++ { .compatible = "amlogic,meson-aiu-spdif-dma", }, ++ { .compatible = "amlogic,meson-gxbb-aiu-spdif-dma", }, ++ { .compatible = "amlogic,meson-gxl-aiu-spdif-dma", }, ++ {} ++}; ++MODULE_DEVICE_TABLE(of, aiu_spdif_dma_of_match); ++ ++static struct platform_driver aiu_spdif_dma_pdrv = { ++ .probe = aiu_spdif_dma_probe, ++ .driver = { ++ .name = DRV_NAME, ++ .of_match_table = aiu_spdif_dma_of_match, ++ }, ++}; ++module_platform_driver(aiu_spdif_dma_pdrv); ++ ++MODULE_DESCRIPTION("Meson AIU spdif DMA ASoC Driver"); ++MODULE_AUTHOR("Jerome Brunet "); ++MODULE_LICENSE("GPL"); diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/028_linux-4.18-yocto-meson64-0011-ASoC-meson-add-initial-spdif-dai-support.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/028_linux-4.18-yocto-meson64-0011-ASoC-meson-add-initial-spdif-dai-support.patch new file mode 100644 index 000000000..3d36f4b06 --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/028_linux-4.18-yocto-meson64-0011-ASoC-meson-add-initial-spdif-dai-support.patch @@ -0,0 +1,426 @@ +From e635299f76dc27b97a768f2a044d04c1917b9ad1 Mon Sep 17 00:00:00 2001 +From: Jerome Brunet +Date: Thu, 30 Mar 2017 13:46:03 +0200 +Subject: [PATCH] ASoC: meson: add initial spdif dai support + +Add support for the spdif dai found on Amlogic Meson SoC family. +With this initial implementation, only uncompressed pcm playback +from the spdif dma is supported. Future work will add compressed +support, pcm playback from i2s dma and capture. + +Signed-off-by: Jerome Brunet +--- + sound/soc/meson/Kconfig | 3 +- + sound/soc/meson/Makefile | 2 + + sound/soc/meson/spdif-dai.c | 374 ++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 378 insertions(+), 1 deletion(-) + create mode 100644 sound/soc/meson/spdif-dai.c + +diff --git a/sound/soc/meson/Kconfig b/sound/soc/meson/Kconfig +index 3fb93b9..301d3a3 100644 +--- a/sound/soc/meson/Kconfig ++++ b/sound/soc/meson/Kconfig +@@ -18,6 +18,7 @@ config SND_SOC_MESON_I2S + config SND_SOC_MESON_SPDIF + tristate "Meson spdif interface" + depends on SND_SOC_MESON ++ select SND_PCM_IEC958 + help +- Say Y or M if you want to add support for spdif dma driver for Amlogic ++ Say Y or M if you want to add support for spdif driver for Amlogic + Meson SoCs. +diff --git a/sound/soc/meson/Makefile b/sound/soc/meson/Makefile +index cef9a9d..bc4391c 100644 +--- a/sound/soc/meson/Makefile ++++ b/sound/soc/meson/Makefile +@@ -2,8 +2,10 @@ snd-soc-meson-audio-core-objs := audio-core.o + snd-soc-meson-aiu-i2s-dma-objs := aiu-i2s-dma.o + snd-soc-meson-aiu-spdif-dma-objs := aiu-spdif-dma.o + snd-soc-meson-i2s-dai-objs := i2s-dai.o ++snd-soc-meson-spdif-dai-objs := spdif-dai.o + + obj-$(CONFIG_SND_SOC_MESON) += snd-soc-meson-audio-core.o + obj-$(CONFIG_SND_SOC_MESON_I2S) += snd-soc-meson-aiu-i2s-dma.o + obj-$(CONFIG_SND_SOC_MESON_I2S) += snd-soc-meson-i2s-dai.o + obj-$(CONFIG_SND_SOC_MESON_SPDIF) += snd-soc-meson-aiu-spdif-dma.o ++obj-$(CONFIG_SND_SOC_MESON_SPDIF) += snd-soc-meson-spdif-dai.o +diff --git a/sound/soc/meson/spdif-dai.c b/sound/soc/meson/spdif-dai.c +new file mode 100644 +index 0000000..e763000 +--- /dev/null ++++ b/sound/soc/meson/spdif-dai.c +@@ -0,0 +1,374 @@ ++/* ++ * Copyright (C) 2017 BayLibre, SAS ++ * Author: Jerome Brunet ++ * Copyright (C) 2017 Amlogic, Inc. All rights reserved. ++ * ++ * 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. ++ * ++ * 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. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, see . ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++#include "aiu-regs.h" ++#include "audio-core.h" ++ ++#define DRV_NAME "meson-spdif-dai" ++ ++struct meson_spdif_dai { ++ struct meson_audio_core_data *core; ++ struct clk *iface; ++ struct clk *fast; ++ struct clk *mclk_i958; ++ struct clk *mclk; ++}; ++ ++#define AIU_CLK_CTRL_958_DIV_EN BIT(1) ++#define AIU_CLK_CTRL_958_DIV_MASK GENMASK(5, 4) ++#define AIU_CLK_CTRL_958_DIV_MORE BIT(12) ++#define AIU_MEM_IEC958_CONTROL_MODE_LINEAR BIT(8) ++#define AIU_958_CTRL_HOLD_EN BIT(0) ++#define AIU_958_MISC_NON_PCM BIT(0) ++#define AIU_958_MISC_MODE_16BITS BIT(1) ++#define AIU_958_MISC_16BITS_ALIGN_MASK GENMASK(6, 5) ++#define AIU_958_MISC_16BITS_ALIGN(val) ((val) << 5) ++#define AIU_958_MISC_MODE_32BITS BIT(7) ++#define AIU_958_MISC_32BITS_SHIFT_MASK GENMASK(10, 8) ++#define AIU_958_MISC_32BITS_SHIFT(val) ((val) << 8) ++#define AIU_958_MISC_U_FROM_STREAM BIT(12) ++#define AIU_958_MISC_FORCE_LR BIT(13) ++ ++#define AIU_CS_WORD_LEN 4 ++ ++static void __hold(struct meson_spdif_dai *priv, bool enable) ++{ ++ regmap_update_bits(priv->core->aiu, AIU_958_CTRL, ++ AIU_958_CTRL_HOLD_EN, ++ enable ? AIU_958_CTRL_HOLD_EN : 0); ++} ++ ++static void __divider_enable(struct meson_spdif_dai *priv, bool enable) ++{ ++ regmap_update_bits(priv->core->aiu, AIU_CLK_CTRL, ++ AIU_CLK_CTRL_958_DIV_EN, ++ enable ? AIU_CLK_CTRL_958_DIV_EN : 0); ++} ++ ++static void __playback_start(struct meson_spdif_dai *priv) ++{ ++ __divider_enable(priv, true); ++ __hold(priv, false); ++} ++ ++static void __playback_stop(struct meson_spdif_dai *priv) ++{ ++ __hold(priv, true); ++ __divider_enable(priv, false); ++} ++ ++static int meson_spdif_dai_trigger(struct snd_pcm_substream *substream, int cmd, ++ struct snd_soc_dai *dai) ++{ ++ struct meson_spdif_dai *priv = snd_soc_dai_get_drvdata(dai); ++ ++ switch (cmd) { ++ case SNDRV_PCM_TRIGGER_START: ++ case SNDRV_PCM_TRIGGER_RESUME: ++ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: ++ __playback_start(priv); ++ return 0; ++ ++ case SNDRV_PCM_TRIGGER_STOP: ++ case SNDRV_PCM_TRIGGER_SUSPEND: ++ case SNDRV_PCM_TRIGGER_PAUSE_PUSH: ++ __playback_stop(priv); ++ return 0; ++ ++ default: ++ return -EINVAL; ++ } ++} ++ ++static int __setup_spdif_clk(struct meson_spdif_dai *priv, unsigned int rate) ++{ ++ unsigned int mrate; ++ ++ /* Leave the internal divisor alone */ ++ regmap_update_bits(priv->core->aiu, AIU_CLK_CTRL, ++ AIU_CLK_CTRL_958_DIV_MASK | ++ AIU_CLK_CTRL_958_DIV_MORE, ++ 0); ++ ++ /* 2 * 32bits per subframe * 2 channels = 128 */ ++ mrate = rate * 128; ++ return clk_set_rate(priv->mclk, mrate); ++} ++ ++static int __setup_cs_word(struct meson_spdif_dai *priv, ++ struct snd_pcm_hw_params *params) ++{ ++ u8 cs[AIU_CS_WORD_LEN]; ++ u32 val; ++ int ret; ++ ++ ret = snd_pcm_create_iec958_consumer_hw_params(params, cs, ++ AIU_CS_WORD_LEN); ++ if (ret < 0) ++ return -EINVAL; ++ ++ /* Write the 1st half word */ ++ val = cs[1] | cs[0] << 8; ++ regmap_write(priv->core->aiu, AIU_958_CHSTAT_L0, val); ++ regmap_write(priv->core->aiu, AIU_958_CHSTAT_R0, val); ++ ++ /* Write the 2nd half word */ ++ val = cs[3] | cs[2] << 8; ++ regmap_write(priv->core->aiu, AIU_958_CHSTAT_L1, val); ++ regmap_write(priv->core->aiu, AIU_958_CHSTAT_R1, val); ++ ++ return 0; ++} ++ ++static int __setup_pcm_fmt(struct meson_spdif_dai *priv, ++ unsigned int width) ++{ ++ u32 val = 0; ++ ++ switch (width) { ++ case 16: ++ val |= AIU_958_MISC_MODE_16BITS; ++ val |= AIU_958_MISC_16BITS_ALIGN(2); ++ break; ++ case 32: ++ case 24: ++ /* ++ * Looks like this should only be set for 32bits mode, but the ++ * vendor kernel sets it like this for 24bits as well, let's ++ * try and see ++ */ ++ val |= AIU_958_MISC_MODE_32BITS; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ /* No idea what this actually does, copying the vendor kernel for now */ ++ val |= AIU_958_MISC_FORCE_LR; ++ val |= AIU_958_MISC_U_FROM_STREAM; ++ ++ regmap_update_bits(priv->core->aiu, AIU_958_MISC, ++ AIU_958_MISC_NON_PCM | ++ AIU_958_MISC_MODE_16BITS | ++ AIU_958_MISC_16BITS_ALIGN_MASK | ++ AIU_958_MISC_MODE_32BITS | ++ AIU_958_MISC_FORCE_LR, ++ val); ++ ++ return 0; ++} ++ ++static int meson_spdif_dai_hw_params(struct snd_pcm_substream *substream, ++ struct snd_pcm_hw_params *params, ++ struct snd_soc_dai *dai) ++{ ++ struct meson_spdif_dai *priv = snd_soc_dai_get_drvdata(dai); ++ int ret; ++ ++ ret = __setup_spdif_clk(priv, params_rate(params)); ++ if (ret) { ++ dev_err(dai->dev, "Unable to set the spdif clock\n"); ++ return ret; ++ } ++ ++ ret = __setup_cs_word(priv, params); ++ if (ret) { ++ dev_err(dai->dev, "Unable to set the channel status word\n"); ++ return ret; ++ } ++ ++ ret = __setup_pcm_fmt(priv, params_width(params)); ++ if (ret) { ++ dev_err(dai->dev, "Unable to set the pcm format\n"); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static int meson_spdif_dai_startup(struct snd_pcm_substream *substream, ++ struct snd_soc_dai *dai) ++{ ++ struct meson_spdif_dai *priv = snd_soc_dai_get_drvdata(dai); ++ int ret; ++ ++ /* Power up the spdif fast domain - can't write the registers w/o it */ ++ ret = clk_prepare_enable(priv->fast); ++ if (ret) ++ goto out_clk_fast; ++ ++ /* Make sure nothing gets out of the DAI yet*/ ++ __hold(priv, true); ++ ++ ret = clk_set_parent(priv->mclk, priv->mclk_i958); ++ if (ret) ++ return ret; ++ ++ /* Enable the clock gate */ ++ ret = clk_prepare_enable(priv->iface); ++ if (ret) ++ goto out_clk_iface; ++ ++ /* Enable the spdif clock */ ++ ret = clk_prepare_enable(priv->mclk); ++ if (ret) ++ goto out_mclk; ++ ++ /* ++ * Make sure the interface expect a memory layout we can work with ++ * MEM prefixed register usually belong to the DMA, but when the spdif ++ * DAI takes data from the i2s buffer, we need to make sure it works in ++ * split mode and not the "normal mode" (channel samples packed in ++ * 32 bytes groups) ++ */ ++ regmap_update_bits(priv->core->aiu, AIU_MEM_IEC958_CONTROL, ++ AIU_MEM_IEC958_CONTROL_MODE_LINEAR, ++ AIU_MEM_IEC958_CONTROL_MODE_LINEAR); ++ ++ return 0; ++ ++out_mclk: ++ clk_disable_unprepare(priv->iface); ++out_clk_iface: ++ clk_disable_unprepare(priv->fast); ++out_clk_fast: ++ return ret; ++} ++ ++static void meson_spdif_dai_shutdown(struct snd_pcm_substream *substream, ++ struct snd_soc_dai *dai) ++{ ++ struct meson_spdif_dai *priv = snd_soc_dai_get_drvdata(dai); ++ ++ clk_disable_unprepare(priv->iface); ++ clk_disable_unprepare(priv->mclk); ++ clk_disable_unprepare(priv->fast); ++} ++ ++static const struct snd_soc_dai_ops meson_spdif_dai_ops = { ++ .startup = meson_spdif_dai_startup, ++ .shutdown = meson_spdif_dai_shutdown, ++ .trigger = meson_spdif_dai_trigger, ++ .hw_params = meson_spdif_dai_hw_params, ++}; ++ ++static struct snd_soc_dai_driver meson_spdif_dai = { ++ .playback = { ++ .stream_name = "Playback", ++ .channels_min = 2, ++ .channels_max = 2, ++ .rates = (SNDRV_PCM_RATE_32000 | ++ SNDRV_PCM_RATE_44100 | ++ SNDRV_PCM_RATE_48000 | ++ SNDRV_PCM_RATE_96000 | ++ SNDRV_PCM_RATE_192000), ++ .formats = (SNDRV_PCM_FMTBIT_S16_LE | ++ SNDRV_PCM_FMTBIT_S24_LE) ++ }, ++ .ops = &meson_spdif_dai_ops, ++}; ++ ++static const struct snd_soc_component_driver meson_spdif_dai_component = { ++ .name = DRV_NAME, ++}; ++ ++static int meson_spdif_dai_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct meson_spdif_dai *priv; ++ ++ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); ++ if (!priv) ++ return -ENOMEM; ++ ++ platform_set_drvdata(pdev, priv); ++ priv->core = dev_get_drvdata(dev->parent); ++ ++ priv->fast = devm_clk_get(dev, "fast"); ++ if (IS_ERR(priv->fast)) { ++ if (PTR_ERR(priv->fast) != -EPROBE_DEFER) ++ dev_err(dev, "Can't get spdif fast domain clockt\n"); ++ return PTR_ERR(priv->fast); ++ } ++ ++ priv->iface = devm_clk_get(dev, "iface"); ++ if (IS_ERR(priv->iface)) { ++ if (PTR_ERR(priv->iface) != -EPROBE_DEFER) ++ dev_err(dev, ++ "Can't get the dai clock gate\n"); ++ return PTR_ERR(priv->iface); ++ } ++ ++ priv->mclk_i958 = devm_clk_get(dev, "mclk_i958"); ++ if (IS_ERR(priv->mclk_i958)) { ++ if (PTR_ERR(priv->mclk_i958) != -EPROBE_DEFER) ++ dev_err(dev, "Can't get the spdif master clock\n"); ++ return PTR_ERR(priv->mclk_i958); ++ } ++ ++ /* ++ * TODO: the spdif dai can also get its data from the i2s fifo. ++ * For this use-case, the DAI driver will need to get the i2s master ++ * clock in order to reparent the spdif clock from cts_mclk_i958 to ++ * cts_amclk ++ */ ++ ++ priv->mclk = devm_clk_get(dev, "mclk"); ++ if (IS_ERR(priv->mclk)) { ++ if (PTR_ERR(priv->mclk) != -EPROBE_DEFER) ++ dev_err(dev, "Can't get the spdif input mux clock\n"); ++ return PTR_ERR(priv->mclk); ++ } ++ ++ return devm_snd_soc_register_component(dev, &meson_spdif_dai_component, ++ &meson_spdif_dai, 1); ++} ++ ++static const struct of_device_id meson_spdif_dai_of_match[] = { ++ { .compatible = "amlogic,meson-spdif-dai", }, ++ { .compatible = "amlogic,meson-gxbb-spdif-dai", }, ++ { .compatible = "amlogic,meson-gxl-spdif-dai", }, ++ {} ++}; ++MODULE_DEVICE_TABLE(of, meson_spdif_dai_of_match); ++ ++static struct platform_driver meson_spdif_dai_pdrv = { ++ .probe = meson_spdif_dai_probe, ++ .driver = { ++ .name = DRV_NAME, ++ .of_match_table = meson_spdif_dai_of_match, ++ }, ++}; ++module_platform_driver(meson_spdif_dai_pdrv); ++ ++MODULE_DESCRIPTION("Meson spdif DAI ASoC Driver"); ++MODULE_AUTHOR("Jerome Brunet "); ++MODULE_LICENSE("GPL v2"); diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/029_linux-4.18-yocto-meson64-0012-ARM64-defconfig-enable-audio-support-for-meson-SoCs-.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/029_linux-4.18-yocto-meson64-0012-ARM64-defconfig-enable-audio-support-for-meson-SoCs-.patch new file mode 100644 index 000000000..ff2035ecc --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/029_linux-4.18-yocto-meson64-0012-ARM64-defconfig-enable-audio-support-for-meson-SoCs-.patch @@ -0,0 +1,29 @@ +From 5ddca63ac5c5d81c6d6a6745670a3f136970eaef Mon Sep 17 00:00:00 2001 +From: Jerome Brunet +Date: Fri, 31 Mar 2017 15:55:03 +0200 +Subject: [PATCH] ARM64: defconfig: enable audio support for meson SoCs as + module + +Add audio support for meson SoCs. This includes the audio core +driver and the i2s and spdif output interfaces + +Signed-off-by: Jerome Brunet +--- + arch/arm64/configs/defconfig | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig +index 2584605..ae1f774 100644 +--- a/arch/arm64/configs/defconfig ++++ b/arch/arm64/configs/defconfig +@@ -451,6 +451,10 @@ CONFIG_SOUND=y + CONFIG_SND=y + CONFIG_SND_SOC=y + CONFIG_SND_BCM2835_SOC_I2S=m ++CONFIG_SND_SOC_MESON=m ++CONFIG_SND_SOC_MESON_I2S=m ++CONFIG_SND_SOC_MESON_SPDIF=m ++CONFIG_SND_SOC_RCAR=y + CONFIG_SND_SOC_SAMSUNG=y + CONFIG_SND_SOC_RCAR=m + CONFIG_SND_SOC_AK4613=m diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/030_linux-4.18-yocto-meson64-0013-ARM64-dts-meson-gx-add-audio-controller-nodes.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/030_linux-4.18-yocto-meson64-0013-ARM64-dts-meson-gx-add-audio-controller-nodes.patch new file mode 100644 index 000000000..f58d3ef3c --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/030_linux-4.18-yocto-meson64-0013-ARM64-dts-meson-gx-add-audio-controller-nodes.patch @@ -0,0 +1,186 @@ +From f4d7ad156ad2253d5ec3e79ea36309e27b8fabc7 Mon Sep 17 00:00:00 2001 +From: Jerome Brunet +Date: Thu, 30 Mar 2017 15:19:04 +0200 +Subject: [PATCH] ARM64: dts: meson-gx: add audio controller nodes + +Add audio controller nodes for Amlogic meson gxbb and gxl. +This includes the audio-core node, the i2s and spdif DAIs, i2s and spdif +aiu DMAs. + +Audio on this SoC family is still a work in progress. More nodes are likely +to be added later on (pcm DAIs, input DMAs, etc ...) + +Signed-off-by: Jerome Brunet +--- + arch/arm64/boot/dts/amlogic/meson-gx.dtsi | 35 ++++++++++++++++++++++++++ + arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi | 39 +++++++++++++++++++++++++++++ + arch/arm64/boot/dts/amlogic/meson-gxl.dtsi | 38 ++++++++++++++++++++++++++++ + 3 files changed, 112 insertions(+) + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi +index b8dc4db..6b64b63 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi +@@ -203,6 +203,41 @@ + #reset-cells = <1>; + }; + ++ audio: audio@5400 { ++ compatible = "amlogic,meson-audio-core"; ++ reg = <0x0 0x5400 0x0 0x2ac>, ++ <0x0 0xa000 0x0 0x304>; ++ reg-names = "aiu", "audin"; ++ status = "disabled"; ++ ++ aiu_i2s_dma: aiu_i2s_dma { ++ #sound-dai-cells = <0>; ++ compatible = "amlogic,meson-aiu-i2s-dma"; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ ++ aiu_spdif_dma: aiu_spdif_dma { ++ #sound-dai-cells = <0>; ++ compatible = "amlogic,meson-aiu-spdif-dma"; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ ++ i2s_dai: i2s_dai { ++ #sound-dai-cells = <0>; ++ compatible = "amlogic,meson-i2s-dai"; ++ status = "disabled"; ++ }; ++ ++ spdif_dai: spdif_dai { ++ #sound-dai-cells = <0>; ++ compatible = "amlogic,meson-spdif-dai"; ++ status = "disabled"; ++ }; ++ ++ }; ++ + uart_A: serial@84c0 { + compatible = "amlogic,meson-gx-uart"; + reg = <0x0 0x84c0 0x0 0x18>; +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi +index 98cbba6..7913249 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi +@@ -659,6 +659,35 @@ + }; + }; + ++&audio { ++ clocks = <&clkc CLKID_AIU>, ++ <&clkc CLKID_AIU_GLUE>, ++ <&clkc CLKID_I2S_SPDIF>; ++ clock-names = "aiu_top", "aiu_glue", "audin"; ++ resets = <&reset RESET_AIU>, ++ <&reset RESET_AUDIN>; ++ reset-names = "aiu", "audin"; ++}; ++ ++&aiu_i2s_dma { ++ clocks = <&clkc CLKID_I2S_OUT>; ++ clock-names = "fast"; ++}; ++ ++&aiu_spdif_dma { ++ clocks = <&clkc CLKID_IEC958>; ++ clock-names = "fast"; ++ ++}; ++ ++&i2s_dai { ++ clocks = <&clkc CLKID_I2S_OUT>, ++ <&clkc CLKID_MIXER_IFACE>, ++ <&clkc CLKID_AOCLK_GATE>, ++ <&clkc CLKID_CTS_AMCLK>; ++ clock-names = "fast", "iface", "bclks", "mclk"; ++}; ++ + &pwrc_vpu { + resets = <&reset RESET_VIU>, + <&reset RESET_VENC>, +@@ -741,6 +770,15 @@ + num-cs = <1>; + }; + ++&spdif_dai { ++ clocks = <&clkc CLKID_IEC958>, ++ <&clkc CLKID_IEC958_GATE>, ++ <&clkc CLKID_CTS_MCLK_I958>, ++ <&clkc CLKID_CTS_AMCLK>, ++ <&clkc CLKID_CTS_I958>; ++ clock-names = "fast", "iface", "mclk_i958", "mclk_i2s", "mclk"; ++}; ++ + &spifc { + clocks = <&clkc CLKID_SPI>; + }; +@@ -774,3 +812,4 @@ + compatible = "amlogic,meson-gxbb-vpu", "amlogic,meson-gx-vpu"; + power-domains = <&pwrc_vpu>; + }; ++ +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi +index c87a80e..20922cd 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi +@@ -660,6 +660,34 @@ + }; + }; + ++&audio { ++ clocks = <&clkc CLKID_AIU>, ++ <&clkc CLKID_AIU_GLUE>, ++ <&clkc CLKID_I2S_SPDIF>; ++ clock-names = "aiu_top", "aiu_glue", "audin"; ++ resets = <&reset RESET_AIU>, ++ <&reset RESET_AUDIN>; ++ reset-names = "aiu", "audin"; ++}; ++ ++&aiu_i2s_dma { ++ clocks = <&clkc CLKID_I2S_OUT>; ++ clock-names = "fast"; ++}; ++ ++&aiu_spdif_dma { ++ clocks = <&clkc CLKID_IEC958>; ++ clock-names = "fast"; ++}; ++ ++&i2s_dai { ++ clocks = <&clkc CLKID_I2S_OUT>, ++ <&clkc CLKID_MIXER_IFACE>, ++ <&clkc CLKID_AOCLK_GATE>, ++ <&clkc CLKID_CTS_AMCLK>; ++ clock-names = "fast", "iface", "bclks", "mclk"; ++}; ++ + &pwrc_vpu { + resets = <&reset RESET_VIU>, + <&reset RESET_VENC>, +@@ -742,6 +770,15 @@ + num-cs = <1>; + }; + ++&spdif_dai { ++ clocks = <&clkc CLKID_IEC958>, ++ <&clkc CLKID_IEC958_GATE>, ++ <&clkc CLKID_CTS_MCLK_I958>, ++ <&clkc CLKID_CTS_AMCLK>, ++ <&clkc CLKID_CTS_I958>; ++ clock-names = "fast", "iface", "mclk_i958", "mclk_i2s", "mclk"; ++}; ++ + &spifc { + clocks = <&clkc CLKID_SPI>; + }; +@@ -775,3 +812,4 @@ + compatible = "amlogic,meson-gxl-vpu", "amlogic,meson-gx-vpu"; + power-domains = <&pwrc_vpu>; + }; ++ diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/031_linux-4.18-yocto-meson64-0014-snd-meson-activate-HDMI-audio-path.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/031_linux-4.18-yocto-meson64-0014-snd-meson-activate-HDMI-audio-path.patch new file mode 100644 index 000000000..26dedf3d2 --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/031_linux-4.18-yocto-meson64-0014-snd-meson-activate-HDMI-audio-path.patch @@ -0,0 +1,52 @@ +From 69d2f200d91fbd48e2388a8c5346f10d889a2928 Mon Sep 17 00:00:00 2001 +From: Jerome Brunet +Date: Fri, 7 Jul 2017 17:39:21 +0200 +Subject: [PATCH] snd: meson: activate HDMI audio path + +Signed-off-by: Neil Armstrong +--- + sound/soc/meson/i2s-dai.c | 22 ++++++++++++++++++++++ + 1 file changed, 22 insertions(+) + +diff --git a/sound/soc/meson/i2s-dai.c b/sound/soc/meson/i2s-dai.c +index 1008af8..63fe098 100644 +--- a/sound/soc/meson/i2s-dai.c ++++ b/sound/soc/meson/i2s-dai.c +@@ -56,8 +56,19 @@ struct meson_i2s_dai { + #define AIU_CLK_CTRL_ALRCLK_RIGHT_J (2 << 8) + #define AIU_CLK_CTRL_MORE_I2S_DIV_MASK GENMASK(5, 0) + #define AIU_CLK_CTRL_MORE_I2S_DIV(div) (((div) - 1) << 0) ++#define AIU_CLK_CTRL_MORE_HDMI_TX_SEL_MASK BIT(6) ++#define AIU_CLK_CTRL_MORE_HDMI_TX_I958_CLK (0 << 6) ++#define AIU_CLK_CTRL_MORE_HDMI_TX_INT_CLK (1 << 6) + #define AIU_CODEC_DAC_LRCLK_CTRL_DIV_MASK GENMASK(11, 0) + #define AIU_CODEC_DAC_LRCLK_CTRL_DIV(div) (((div) - 1) << 0) ++#define AIU_HDMI_CLK_DATA_CTRL_CLK_SEL_MASK GENMASK(1, 0) ++#define AIU_HDMI_CLK_DATA_CTRL_CLK_DISABLE (0 << 0) ++#define AIU_HDMI_CLK_DATA_CTRL_CLK_PCM (1 << 0) ++#define AIU_HDMI_CLK_DATA_CTRL_CLK_I2S (2 << 0) ++#define AIU_HDMI_CLK_DATA_CTRL_DATA_SEL_MASK GENMASK(5, 4) ++#define AIU_HDMI_CLK_DATA_CTRL_DATA_MUTE (0 << 4) ++#define AIU_HDMI_CLK_DATA_CTRL_DATA_PCM (1 << 4) ++#define AIU_HDMI_CLK_DATA_CTRL_DATA_I2S (2 << 4) + #define AIU_I2S_DAC_CFG_PAYLOAD_SIZE_MASK GENMASK(1, 0) + #define AIU_I2S_DAC_CFG_AOCLK_32 (0 << 0) + #define AIU_I2S_DAC_CFG_AOCLK_48 (2 << 0) +@@ -221,6 +232,17 @@ static int meson_i2s_dai_hw_params(struct snd_pcm_substream *substream, + return ret; + } + ++ /* Quick and dirty hack for HDMI */ ++ regmap_update_bits(priv->core->aiu, AIU_HDMI_CLK_DATA_CTRL, ++ AIU_HDMI_CLK_DATA_CTRL_CLK_SEL_MASK | ++ AIU_HDMI_CLK_DATA_CTRL_DATA_SEL_MASK, ++ AIU_HDMI_CLK_DATA_CTRL_CLK_I2S | ++ AIU_HDMI_CLK_DATA_CTRL_DATA_I2S); ++ ++ regmap_update_bits(priv->core->aiu, AIU_CLK_CTRL_MORE, ++ AIU_CLK_CTRL_MORE_HDMI_TX_SEL_MASK, ++ AIU_CLK_CTRL_MORE_HDMI_TX_INT_CLK); ++ + return 0; + } + diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/032_linux-4.18-yocto-meson64-0015-drm-meson-select-dw-hdmi-i2s-audio-for-meson-hdmi.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/032_linux-4.18-yocto-meson64-0015-drm-meson-select-dw-hdmi-i2s-audio-for-meson-hdmi.patch new file mode 100644 index 000000000..cb88ebaf1 --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/032_linux-4.18-yocto-meson64-0015-drm-meson-select-dw-hdmi-i2s-audio-for-meson-hdmi.patch @@ -0,0 +1,19 @@ +From 223d7ef1a49981c597094e8519e150108cba9ef9 Mon Sep 17 00:00:00 2001 +From: Jerome Brunet +Date: Tue, 14 Feb 2017 19:18:04 +0100 +Subject: [PATCH] drm/meson: select dw-hdmi i2s audio for meson hdmi + +Signed-off-by: Jerome Brunet +--- + drivers/gpu/drm/meson/Kconfig | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/gpu/drm/meson/Kconfig b/drivers/gpu/drm/meson/Kconfig +index 3ce51d8..02d400b 100644 +--- a/drivers/gpu/drm/meson/Kconfig ++++ b/drivers/gpu/drm/meson/Kconfig +@@ -13,3 +13,4 @@ config DRM_MESON_DW_HDMI + depends on DRM_MESON + default y if DRM_MESON + select DRM_DW_HDMI ++ select DRM_DW_HDMI_I2S_AUDIO diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/033_linux-4.18-yocto-meson64-0016-ARM64-dts-meson-gx-add-sound-dai-cells-to-HDMI-node.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/033_linux-4.18-yocto-meson64-0016-ARM64-dts-meson-gx-add-sound-dai-cells-to-HDMI-node.patch new file mode 100644 index 000000000..a5e4fab7a --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/033_linux-4.18-yocto-meson64-0016-ARM64-dts-meson-gx-add-sound-dai-cells-to-HDMI-node.patch @@ -0,0 +1,35 @@ +From 00ce6fbb804c6aaecd3bde8f2978d091fbc0546c Mon Sep 17 00:00:00 2001 +From: Jerome Brunet +Date: Wed, 20 Sep 2017 18:01:26 +0200 +Subject: [PATCH] ARM64: dts: meson-gx: add sound-dai-cells to HDMI node + +Signed-off-by: Jerome Brunet +--- + arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi | 1 + + arch/arm64/boot/dts/amlogic/meson-gxl.dtsi | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi +index 7913249..2a4d506 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi +@@ -305,6 +305,7 @@ + <&clkc CLKID_CLK81>, + <&clkc CLKID_GCLK_VENCI_INT0>; + clock-names = "isfr", "iahb", "venci"; ++ #sound-dai-cells = <0>; + }; + + &sysctrl { +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi +index 20922cd..9f4b618 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi +@@ -257,6 +257,7 @@ + <&clkc CLKID_CLK81>, + <&clkc CLKID_GCLK_VENCI_INT0>; + clock-names = "isfr", "iahb", "venci"; ++ #sound-dai-cells = <0>; + }; + + &sysctrl { diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/034_linux-4.18-yocto-meson64-0017-ARM64-dts-meson-activate-hdmi-audio-HDMI-enabled-boa.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/034_linux-4.18-yocto-meson64-0017-ARM64-dts-meson-activate-hdmi-audio-HDMI-enabled-boa.patch new file mode 100644 index 000000000..e02abbfe2 --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/034_linux-4.18-yocto-meson64-0017-ARM64-dts-meson-activate-hdmi-audio-HDMI-enabled-boa.patch @@ -0,0 +1,860 @@ +From 2df1a3a93bc1ce2d04fa0f0743c9c30195c7057a Mon Sep 17 00:00:00 2001 +From: Jerome Brunet +Date: Wed, 20 Sep 2017 18:10:08 +0200 +Subject: [PATCH] ARM64: dts: meson: activate hdmi audio HDMI enabled boards + +This patch activate audio over HDMI on selected boards + +Please note that this audio support is based on WIP changes +This should be considered as preview and it does not reflect +the audio I expect to see merged + +Signed-off-by: Jerome Brunet +Signed-off-by: Neil Armstrong +--- + .../arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi | 45 ++++++++++++++++++++++ + .../boot/dts/amlogic/meson-gxbb-nanopi-k2.dts | 45 ++++++++++++++++++++++ + .../boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts | 45 ++++++++++++++++++++++ + .../arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts | 45 ++++++++++++++++++++++ + arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi | 45 ++++++++++++++++++++++ + arch/arm64/boot/dts/amlogic/meson-gxbb-wetek.dtsi | 45 ++++++++++++++++++++++ + .../dts/amlogic/meson-gxl-s905x-khadas-vim.dts | 45 ++++++++++++++++++++++ + .../dts/amlogic/meson-gxl-s905x-libretech-cc.dts | 45 ++++++++++++++++++++++ + .../dts/amlogic/meson-gxl-s905x-nexbox-a95x.dts | 45 ++++++++++++++++++++++ + .../boot/dts/amlogic/meson-gxl-s905x-p212.dts | 45 ++++++++++++++++++++++ + .../boot/dts/amlogic/meson-gxm-khadas-vim2.dts | 45 ++++++++++++++++++++++ + .../arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts | 45 ++++++++++++++++++++++ + 12 files changed, 540 insertions(+) + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi +index 88e712e..319512e 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi +@@ -95,6 +95,39 @@ + }; + }; + }; ++ ++ sound { ++ compatible = "simple-audio-card"; ++ simple-audio-card,name = "meson-gx-audio"; ++ ++ assigned-clocks = <&clkc CLKID_MPLL2>, ++ <&clkc CLKID_MPLL0>, ++ <&clkc CLKID_MPLL1>; ++ assigned-clock-parents = <0>, <0>, <0>; ++ assigned-clock-rates = <294912000>, ++ <270950400>, ++ <393216000>; ++ ++ simple-audio-card,dai-link@0 { ++ /* HDMI Output */ ++ format = "i2s"; ++ mclk-fs = <256>; ++ bitclock-master = <&i2s_dai>; ++ frame-master = <&i2s_dai>; ++ ++ plat { ++ sound-dai = <&aiu_i2s_dma>; ++ }; ++ ++ cpu { ++ sound-dai = <&i2s_dai>; ++ }; ++ ++ codec { ++ sound-dai = <&hdmi_tx>; ++ }; ++ }; ++ }; + }; + + &cec_AO { +@@ -104,6 +137,14 @@ + hdmi-phandle = <&hdmi_tx>; + }; + ++&audio { ++ status = "okay"; ++}; ++ ++&aiu_i2s_dma { ++ status = "okay"; ++}; ++ + &cvbs_vdac_port { + cvbs_vdac_out: endpoint { + remote-endpoint = <&cvbs_connector_in>; +@@ -126,6 +167,10 @@ + }; + }; + ++&i2s_dai { ++ status = "okay"; ++}; ++ + &ir { + status = "okay"; + pinctrl-0 = <&remote_input_ao_pins>; +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts +index cbe99bd..5b10de9 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts +@@ -88,6 +88,39 @@ + clock-names = "ext_clock"; + }; + ++ sound { ++ compatible = "simple-audio-card"; ++ simple-audio-card,name = "meson-gx-audio"; ++ ++ assigned-clocks = <&clkc CLKID_MPLL2>, ++ <&clkc CLKID_MPLL0>, ++ <&clkc CLKID_MPLL1>; ++ assigned-clock-parents = <0>, <0>, <0>; ++ assigned-clock-rates = <294912000>, ++ <270950400>, ++ <393216000>; ++ ++ simple-audio-card,dai-link@0 { ++ /* HDMI Output */ ++ format = "i2s"; ++ mclk-fs = <256>; ++ bitclock-master = <&i2s_dai>; ++ frame-master = <&i2s_dai>; ++ ++ plat { ++ sound-dai = <&aiu_i2s_dma>; ++ }; ++ ++ cpu { ++ sound-dai = <&i2s_dai>; ++ }; ++ ++ codec { ++ sound-dai = <&hdmi_tx>; ++ }; ++ }; ++ }; ++ + vcc1v8: regulator-vcc1v8 { + compatible = "regulator-fixed"; + regulator-name = "VCC1.8V"; +@@ -131,6 +164,14 @@ + }; + }; + ++&audio { ++ status = "okay"; ++}; ++ ++&aiu_i2s_dma { ++ status = "okay"; ++}; ++ + &cec_AO { + status = "okay"; + pinctrl-0 = <&ao_cec_pins>; +@@ -185,6 +226,10 @@ + }; + }; + ++&i2s_dai { ++ status = "okay"; ++}; ++ + &ir { + status = "okay"; + pinctrl-0 = <&remote_input_ao_pins>; +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts +index 4cf7f6e..ff87bdc 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts +@@ -119,6 +119,39 @@ + clock-names = "ext_clock"; + }; + ++ sound { ++ compatible = "simple-audio-card"; ++ simple-audio-card,name = "meson-gx-audio"; ++ ++ assigned-clocks = <&clkc CLKID_MPLL2>, ++ <&clkc CLKID_MPLL0>, ++ <&clkc CLKID_MPLL1>; ++ assigned-clock-parents = <0>, <0>, <0>; ++ assigned-clock-rates = <294912000>, ++ <270950400>, ++ <393216000>; ++ ++ simple-audio-card,dai-link@0 { ++ /* HDMI Output */ ++ format = "i2s"; ++ mclk-fs = <256>; ++ bitclock-master = <&i2s_dai>; ++ frame-master = <&i2s_dai>; ++ ++ plat { ++ sound-dai = <&aiu_i2s_dma>; ++ }; ++ ++ cpu { ++ sound-dai = <&i2s_dai>; ++ }; ++ ++ codec { ++ sound-dai = <&hdmi_tx>; ++ }; ++ }; ++ }; ++ + cvbs-connector { + compatible = "composite-video-connector"; + +@@ -154,6 +187,14 @@ + hdmi-phandle = <&hdmi_tx>; + }; + ++&audio { ++ status = "okay"; ++}; ++ ++&aiu_i2s_dma { ++ status = "okay"; ++}; ++ + ðmac { + status = "okay"; + pinctrl-0 = <ð_rmii_pins>; +@@ -190,6 +231,10 @@ + }; + }; + ++&i2s_dai { ++ status = "okay"; ++}; ++ + &ir { + status = "okay"; + pinctrl-0 = <&remote_input_ao_pins>; +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts +index 54954b3..3da3309 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts +@@ -110,6 +110,39 @@ + }; + }; + }; ++ ++ sound { ++ compatible = "simple-audio-card"; ++ simple-audio-card,name = "meson-gx-audio"; ++ ++ assigned-clocks = <&clkc CLKID_MPLL2>, ++ <&clkc CLKID_MPLL0>, ++ <&clkc CLKID_MPLL1>; ++ assigned-clock-parents = <0>, <0>, <0>; ++ assigned-clock-rates = <294912000>, ++ <270950400>, ++ <393216000>; ++ ++ simple-audio-card,dai-link@0 { ++ /* HDMI Output */ ++ format = "i2s"; ++ mclk-fs = <256>; ++ bitclock-master = <&i2s_dai>; ++ frame-master = <&i2s_dai>; ++ ++ plat { ++ sound-dai = <&aiu_i2s_dma>; ++ }; ++ ++ cpu { ++ sound-dai = <&i2s_dai>; ++ }; ++ ++ codec { ++ sound-dai = <&hdmi_tx>; ++ }; ++ }; ++ }; + }; + + &cec_AO { +@@ -119,6 +152,14 @@ + hdmi-phandle = <&hdmi_tx>; + }; + ++&audio { ++ status = "okay"; ++}; ++ ++&aiu_i2s_dma { ++ status = "okay"; ++}; ++ + ðmac { + status = "okay"; + pinctrl-0 = <ð_rgmii_pins>; +@@ -181,6 +222,10 @@ + pinctrl-names = "default"; + }; + ++&i2s_dai { ++ status = "okay"; ++}; ++ + &ir { + status = "okay"; + pinctrl-0 = <&remote_input_ao_pins>; +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi +index ce86226..84eb93b 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi +@@ -113,6 +113,39 @@ + }; + }; + }; ++ ++ sound { ++ compatible = "simple-audio-card"; ++ simple-audio-card,name = "meson-gx-audio"; ++ ++ assigned-clocks = <&clkc CLKID_MPLL2>, ++ <&clkc CLKID_MPLL0>, ++ <&clkc CLKID_MPLL1>; ++ assigned-clock-parents = <0>, <0>, <0>; ++ assigned-clock-rates = <294912000>, ++ <270950400>, ++ <393216000>; ++ ++ simple-audio-card,dai-link@0 { ++ /* HDMI Output */ ++ format = "i2s"; ++ mclk-fs = <256>; ++ bitclock-master = <&i2s_dai>; ++ frame-master = <&i2s_dai>; ++ ++ plat { ++ sound-dai = <&aiu_i2s_dma>; ++ }; ++ ++ cpu { ++ sound-dai = <&i2s_dai>; ++ }; ++ ++ codec { ++ sound-dai = <&hdmi_tx>; ++ }; ++ }; ++ }; + }; + + &cec_AO { +@@ -122,6 +155,14 @@ + hdmi-phandle = <&hdmi_tx>; + }; + ++&audio { ++ status = "okay"; ++}; ++ ++&aiu_i2s_dma { ++ status = "okay"; ++}; ++ + &cvbs_vdac_port { + cvbs_vdac_out: endpoint { + remote-endpoint = <&cvbs_connector_in>; +@@ -140,6 +181,10 @@ + }; + }; + ++&i2s_dai { ++ status = "okay"; ++}; ++ + &ir { + status = "okay"; + pinctrl-0 = <&remote_input_ao_pins>; +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek.dtsi +index 70325b2..7d1f172 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek.dtsi +@@ -105,6 +105,47 @@ + }; + }; + }; ++ ++ sound { ++ compatible = "simple-audio-card"; ++ simple-audio-card,name = "meson-gx-audio"; ++ ++ assigned-clocks = <&clkc CLKID_MPLL2>, ++ <&clkc CLKID_MPLL0>, ++ <&clkc CLKID_MPLL1>; ++ assigned-clock-parents = <0>, <0>, <0>; ++ assigned-clock-rates = <294912000>, ++ <270950400>, ++ <393216000>; ++ ++ simple-audio-card,dai-link@0 { ++ /* HDMI Output */ ++ format = "i2s"; ++ mclk-fs = <256>; ++ bitclock-master = <&i2s_dai>; ++ frame-master = <&i2s_dai>; ++ ++ plat { ++ sound-dai = <&aiu_i2s_dma>; ++ }; ++ ++ cpu { ++ sound-dai = <&i2s_dai>; ++ }; ++ ++ codec { ++ sound-dai = <&hdmi_tx>; ++ }; ++ }; ++ }; ++}; ++ ++&audio { ++ status = "okay"; ++}; ++ ++&aiu_i2s_dma { ++ status = "okay"; + }; + + &cec_AO { +@@ -159,6 +200,10 @@ + }; + }; + ++&i2s_dai { ++ status = "okay"; ++}; ++ + &ir { + status = "okay"; + pinctrl-0 = <&remote_input_ao_pins>; +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts +index d32cf38..f053595 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts +@@ -65,6 +65,39 @@ + }; + }; + }; ++ ++ sound { ++ compatible = "simple-audio-card"; ++ simple-audio-card,name = "meson-gx-audio"; ++ ++ assigned-clocks = <&clkc CLKID_MPLL2>, ++ <&clkc CLKID_MPLL0>, ++ <&clkc CLKID_MPLL1>; ++ assigned-clock-parents = <0>, <0>, <0>; ++ assigned-clock-rates = <294912000>, ++ <270950400>, ++ <393216000>; ++ ++ simple-audio-card,dai-link@0 { ++ /* HDMI Output */ ++ format = "i2s"; ++ mclk-fs = <256>; ++ bitclock-master = <&i2s_dai>; ++ frame-master = <&i2s_dai>; ++ ++ plat { ++ sound-dai = <&aiu_i2s_dma>; ++ }; ++ ++ cpu { ++ sound-dai = <&i2s_dai>; ++ }; ++ ++ codec { ++ sound-dai = <&hdmi_tx>; ++ }; ++ }; ++ }; + }; + + &cec_AO { +@@ -74,6 +107,14 @@ + hdmi-phandle = <&hdmi_tx>; + }; + ++&audio { ++ status = "okay"; ++}; ++ ++&aiu_i2s_dma { ++ status = "okay"; ++}; ++ + &hdmi_tx { + status = "okay"; + pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>; +@@ -86,6 +127,10 @@ + }; + }; + ++&i2s_dai { ++ status = "okay"; ++}; ++ + &i2c_A { + status = "okay"; + pinctrl-0 = <&i2c_a_pins>; +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts +index f63bceb..f56969e 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts +@@ -84,6 +84,39 @@ + regulator-always-on; + }; + ++ sound { ++ compatible = "simple-audio-card"; ++ simple-audio-card,name = "meson-gx-audio"; ++ ++ assigned-clocks = <&clkc CLKID_MPLL2>, ++ <&clkc CLKID_MPLL0>, ++ <&clkc CLKID_MPLL1>; ++ assigned-clock-parents = <0>, <0>, <0>; ++ assigned-clock-rates = <294912000>, ++ <270950400>, ++ <393216000>; ++ ++ simple-audio-card,dai-link@0 { ++ /* HDMI Output */ ++ format = "i2s"; ++ mclk-fs = <256>; ++ bitclock-master = <&i2s_dai>; ++ frame-master = <&i2s_dai>; ++ ++ plat { ++ sound-dai = <&aiu_i2s_dma>; ++ }; ++ ++ cpu { ++ sound-dai = <&i2s_dai>; ++ }; ++ ++ codec { ++ sound-dai = <&hdmi_tx>; ++ }; ++ }; ++ }; ++ + vcc_3v3: regulator-vcc_3v3 { + compatible = "regulator-fixed"; + regulator-name = "VCC_3V3"; +@@ -130,6 +163,14 @@ + hdmi-phandle = <&hdmi_tx>; + }; + ++&audio { ++ status = "okay"; ++}; ++ ++&aiu_i2s_dma { ++ status = "okay"; ++}; ++ + &cvbs_vdac_port { + cvbs_vdac_out: endpoint { + remote-endpoint = <&cvbs_connector_in>; +@@ -151,6 +192,10 @@ + pinctrl-names = "default"; + }; + ++&i2s_dai { ++ status = "okay"; ++}; ++ + &hdmi_tx { + status = "okay"; + pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>; +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-nexbox-a95x.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-nexbox-a95x.dts +index 6739697..e3e777f 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-nexbox-a95x.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-nexbox-a95x.dts +@@ -102,6 +102,39 @@ + }; + }; + }; ++ ++ sound { ++ compatible = "simple-audio-card"; ++ simple-audio-card,name = "meson-gx-audio"; ++ ++ assigned-clocks = <&clkc CLKID_MPLL2>, ++ <&clkc CLKID_MPLL0>, ++ <&clkc CLKID_MPLL1>; ++ assigned-clock-parents = <0>, <0>, <0>; ++ assigned-clock-rates = <294912000>, ++ <270950400>, ++ <393216000>; ++ ++ simple-audio-card,dai-link@0 { ++ /* HDMI Output */ ++ format = "i2s"; ++ mclk-fs = <256>; ++ bitclock-master = <&i2s_dai>; ++ frame-master = <&i2s_dai>; ++ ++ plat { ++ sound-dai = <&aiu_i2s_dma>; ++ }; ++ ++ cpu { ++ sound-dai = <&i2s_dai>; ++ }; ++ ++ codec { ++ sound-dai = <&hdmi_tx>; ++ }; ++ }; ++ }; + }; + + &cec_AO { +@@ -111,6 +144,14 @@ + hdmi-phandle = <&hdmi_tx>; + }; + ++&audio { ++ status = "okay"; ++}; ++ ++&aiu_i2s_dma { ++ status = "okay"; ++}; ++ + &cvbs_vdac_port { + cvbs_vdac_out: endpoint { + remote-endpoint = <&cvbs_connector_in>; +@@ -135,6 +176,10 @@ + }; + }; + ++&i2s_dai { ++ status = "okay"; ++}; ++ + &ir { + status = "okay"; + pinctrl-0 = <&remote_input_ao_pins>; +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dts +index 5896e8a..f8c66a7 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dts +@@ -32,6 +32,39 @@ + }; + }; + }; ++ ++ sound { ++ compatible = "simple-audio-card"; ++ simple-audio-card,name = "meson-gx-audio"; ++ ++ assigned-clocks = <&clkc CLKID_MPLL2>, ++ <&clkc CLKID_MPLL0>, ++ <&clkc CLKID_MPLL1>; ++ assigned-clock-parents = <0>, <0>, <0>; ++ assigned-clock-rates = <294912000>, ++ <270950400>, ++ <393216000>; ++ ++ simple-audio-card,dai-link@0 { ++ /* HDMI Output */ ++ format = "i2s"; ++ mclk-fs = <256>; ++ bitclock-master = <&i2s_dai>; ++ frame-master = <&i2s_dai>; ++ ++ plat { ++ sound-dai = <&aiu_i2s_dma>; ++ }; ++ ++ cpu { ++ sound-dai = <&i2s_dai>; ++ }; ++ ++ codec { ++ sound-dai = <&hdmi_tx>; ++ }; ++ }; ++ }; + }; + + &cec_AO { +@@ -41,12 +74,24 @@ + hdmi-phandle = <&hdmi_tx>; + }; + ++&audio { ++ status = "okay"; ++}; ++ ++&aiu_i2s_dma { ++ status = "okay"; ++}; ++ + &cvbs_vdac_port { + cvbs_vdac_out: endpoint { + remote-endpoint = <&cvbs_connector_in>; + }; + }; + ++&i2s_dai { ++ status = "okay"; ++}; ++ + &hdmi_tx { + status = "okay"; + pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>; +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts b/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts +index 0868da4..ea71261 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts +@@ -85,6 +85,39 @@ + }; + }; + ++ sound { ++ compatible = "simple-audio-card"; ++ simple-audio-card,name = "meson-gx-audio"; ++ ++ assigned-clocks = <&clkc CLKID_MPLL2>, ++ <&clkc CLKID_MPLL0>, ++ <&clkc CLKID_MPLL1>; ++ assigned-clock-parents = <0>, <0>, <0>; ++ assigned-clock-rates = <294912000>, ++ <270950400>, ++ <393216000>; ++ ++ simple-audio-card,dai-link@0 { ++ /* HDMI Output */ ++ format = "i2s"; ++ mclk-fs = <256>; ++ bitclock-master = <&i2s_dai>; ++ frame-master = <&i2s_dai>; ++ ++ plat { ++ sound-dai = <&aiu_i2s_dma>; ++ }; ++ ++ cpu { ++ sound-dai = <&i2s_dai>; ++ }; ++ ++ codec { ++ sound-dai = <&hdmi_tx>; ++ }; ++ }; ++ }; ++ + pwmleds { + compatible = "pwm-leds"; + +@@ -205,6 +238,14 @@ + hdmi-phandle = <&hdmi_tx>; + }; + ++&audio { ++ status = "okay"; ++}; ++ ++&aiu_i2s_dma { ++ status = "okay"; ++}; ++ + &cpu0 { + #cooling-cells = <2>; + }; +@@ -255,6 +296,10 @@ + }; + }; + ++&i2s_dai { ++ status = "okay"; ++}; ++ + &i2c_A { + status = "okay"; + pinctrl-0 = <&i2c_a_pins>; +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts b/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts +index f7a1cff..b9c5e64 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts +@@ -75,6 +75,39 @@ + }; + }; + }; ++ ++ sound { ++ compatible = "simple-audio-card"; ++ simple-audio-card,name = "meson-gx-audio"; ++ ++ assigned-clocks = <&clkc CLKID_MPLL2>, ++ <&clkc CLKID_MPLL0>, ++ <&clkc CLKID_MPLL1>; ++ assigned-clock-parents = <0>, <0>, <0>; ++ assigned-clock-rates = <294912000>, ++ <270950400>, ++ <393216000>; ++ ++ simple-audio-card,dai-link@0 { ++ /* HDMI Output */ ++ format = "i2s"; ++ mclk-fs = <256>; ++ bitclock-master = <&i2s_dai>; ++ frame-master = <&i2s_dai>; ++ ++ plat { ++ sound-dai = <&aiu_i2s_dma>; ++ }; ++ ++ cpu { ++ sound-dai = <&i2s_dai>; ++ }; ++ ++ codec { ++ sound-dai = <&hdmi_tx>; ++ }; ++ }; ++ }; + }; + + &cec_AO { +@@ -84,6 +117,14 @@ + hdmi-phandle = <&hdmi_tx>; + }; + ++&audio { ++ status = "okay"; ++}; ++ ++&aiu_i2s_dma { ++ status = "okay"; ++}; ++ + &cvbs_vdac_port { + cvbs_vdac_out: endpoint { + remote-endpoint = <&cvbs_connector_in>; +@@ -129,6 +170,10 @@ + }; + }; + ++&i2s_dai { ++ status = "okay"; ++}; ++ + &ir { + status = "okay"; + pinctrl-0 = <&remote_input_ao_pins>; diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/035_linux-4.18-yocto-meson64-0018-drm-bridge-dw-hdmi-Use-AUTO-CTS-setup-mode-when-non-.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/035_linux-4.18-yocto-meson64-0018-drm-bridge-dw-hdmi-Use-AUTO-CTS-setup-mode-when-non-.patch new file mode 100644 index 000000000..fbff6c8d8 --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/035_linux-4.18-yocto-meson64-0018-drm-bridge-dw-hdmi-Use-AUTO-CTS-setup-mode-when-non-.patch @@ -0,0 +1,75 @@ +From e282ad866be628951a95d297207c9a5580f4101d Mon Sep 17 00:00:00 2001 +From: Neil Armstrong +Date: Mon, 2 Jul 2018 12:21:55 +0200 +Subject: [PATCH] drm: bridge: dw-hdmi: Use AUTO CTS setup mode when non-AHB + audio + +Signed-off-by: Neil Armstrong +--- + drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 41 ++++++++++++++++++++----------- + 1 file changed, 26 insertions(+), 15 deletions(-) + +diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +index 3c136f2b..a68ffbb 100644 +--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c ++++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +@@ -430,8 +430,12 @@ static void hdmi_set_cts_n(struct dw_hdmi *hdmi, unsigned int cts, + /* 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) ++ 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); + +@@ -501,24 +505,31 @@ 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_compute_n(sample_rate, pixel_clk); + +- /* +- * 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/buildroot-external/board/hardkernel/odroid-c2/patches/linux/036_linux-4.18-yocto-meson64-0019-drm-meson-Call-drm_crtc_vblank_on-drm_crtc_vblank_of.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/036_linux-4.18-yocto-meson64-0019-drm-meson-Call-drm_crtc_vblank_on-drm_crtc_vblank_of.patch new file mode 100644 index 000000000..314ff482b --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/036_linux-4.18-yocto-meson64-0019-drm-meson-Call-drm_crtc_vblank_on-drm_crtc_vblank_of.patch @@ -0,0 +1,36 @@ +From 4a3a6d04d4996ff0a0acc8405fdd0b0347a62138 Mon Sep 17 00:00:00 2001 +From: Neil Armstrong +Date: Wed, 28 Feb 2018 16:07:18 +0100 +Subject: [PATCH] drm/meson: Call drm_crtc_vblank_on / drm_crtc_vblank_off + +Make sure that the CRTC code will call the enable/disable_vblank hooks. + +Signed-off-by: Neil Armstrong +--- + drivers/gpu/drm/meson/meson_crtc.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/drivers/gpu/drm/meson/meson_crtc.c b/drivers/gpu/drm/meson/meson_crtc.c +index 0552020..4dd0df0 100644 +--- a/drivers/gpu/drm/meson/meson_crtc.c ++++ b/drivers/gpu/drm/meson/meson_crtc.c +@@ -102,6 +102,8 @@ static void meson_crtc_atomic_enable(struct drm_crtc *crtc, + priv->io_base + _REG(VPP_MISC)); + + priv->viu.osd1_enabled = true; ++ ++ drm_crtc_vblank_on(crtc); + } + + static void meson_crtc_atomic_disable(struct drm_crtc *crtc, +@@ -110,6 +112,10 @@ static void meson_crtc_atomic_disable(struct drm_crtc *crtc, + struct meson_crtc *meson_crtc = to_meson_crtc(crtc); + struct meson_drm *priv = meson_crtc->priv; + ++ DRM_DEBUG_DRIVER("\n"); ++ ++ drm_crtc_vblank_off(crtc); ++ + priv->viu.osd1_enabled = false; + priv->viu.osd1_commit = false; + diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/037_linux-4.18-yocto-meson64-0020-media-platform-meson-ao-cec-make-busy-TX-warning-sil.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/037_linux-4.18-yocto-meson64-0020-media-platform-meson-ao-cec-make-busy-TX-warning-sil.patch new file mode 100644 index 000000000..81569fc4d --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/037_linux-4.18-yocto-meson64-0020-media-platform-meson-ao-cec-make-busy-TX-warning-sil.patch @@ -0,0 +1,32 @@ +From 830bb1ab9ee8999566a4d98086590ac824cdeb4e Mon Sep 17 00:00:00 2001 +From: Neil Armstrong +Date: Tue, 10 Jul 2018 15:00:45 +0200 +Subject: [PATCH] media: platform: meson-ao-cec: make busy TX warning silent + +Switch to dev_dbg for the busy TX message to avoid having a flood of: +[ 228.064570] meson-ao-cec c8100100.cec: meson_ao_cec_transmit: busy TX: aborting +[ 230.368489] meson-ao-cec c8100100.cec: meson_ao_cec_transmit: busy TX: aborting +[ 234.208655] meson-ao-cec c8100100.cec: meson_ao_cec_transmit: busy TX: aborting +[ 236.512558] meson-ao-cec c8100100.cec: meson_ao_cec_transmit: busy TX: aborting + +This message is only a debug hint and not an error. + +Fixes: 7ec2c0f72cb1 ("media: platform: Add Amlogic Meson AO CEC Controller driver") +Signed-off-by: Neil Armstrong +--- + drivers/media/platform/meson/ao-cec.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/media/platform/meson/ao-cec.c b/drivers/media/platform/meson/ao-cec.c +index 8040a62..cd4be38 100644 +--- a/drivers/media/platform/meson/ao-cec.c ++++ b/drivers/media/platform/meson/ao-cec.c +@@ -524,7 +524,7 @@ static int meson_ao_cec_transmit(struct cec_adapter *adap, u8 attempts, + return ret; + + if (reg == TX_BUSY) { +- dev_err(&ao_cec->pdev->dev, "%s: busy TX: aborting\n", ++ dev_dbg(&ao_cec->pdev->dev, "%s: busy TX: aborting\n", + __func__); + meson_ao_cec_write(ao_cec, CEC_TX_MSG_CMD, TX_ABORT, &ret); + } diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/045_linux-4.18-yocto-meson64-0001-libretech-cc-disable-CVBS-connector.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/045_linux-4.18-yocto-meson64-0001-libretech-cc-disable-CVBS-connector.patch new file mode 100644 index 000000000..7f8298118 --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/045_linux-4.18-yocto-meson64-0001-libretech-cc-disable-CVBS-connector.patch @@ -0,0 +1,24 @@ +From baa0a8ee8b8a0a14ddab6b14c37846dfed261007 Mon Sep 17 00:00:00 2001 +From: Koen Kooi +Date: Fri, 11 May 2018 13:51:20 +0200 +Subject: [PATCH] libretech-cc: disable CVBS connector + +Signed-off-by: Koen Kooi +--- + arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts +index f56969e..ac3a150 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts +@@ -24,7 +24,8 @@ + stdout-path = "serial0:115200n8"; + }; + +- cvbs-connector { ++ cvbs_connector: cvbs-connector { ++ status = "disabled"; + compatible = "composite-video-connector"; + + port { diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/048_linux-4.18.y-jeromebrunet-0001-clk-qcom-drop_clk_set_rate_gate_from_sdc_clocks.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/048_linux-4.18.y-jeromebrunet-0001-clk-qcom-drop_clk_set_rate_gate_from_sdc_clocks.patch new file mode 100644 index 000000000..0cd5bcd06 --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/048_linux-4.18.y-jeromebrunet-0001-clk-qcom-drop_clk_set_rate_gate_from_sdc_clocks.patch @@ -0,0 +1,161 @@ +From e18fe49cfa5a989d0e8aca1b95a989f71c1916e7 Mon Sep 17 00:00:00 2001 +From: Jerome Brunet +Date: Tue, 19 Jun 2018 11:03:03 +0200 +Subject: [PATCH] clk: qcom: drop CLK_SET_RATE_GATE from sdc clocks + +the mmci driver (drivers/mmc/host/mmci.c) does the following sequence: +* clk_prepare_enable() +* clk_set_rate() + +on SDCx_clk which is a children of SDCx_src. SDCx_src has +CLK_SET_RATE_GATE so this sequence should not be allowed but this was not +enforced. IOW, the flag is ignored. Dropping the flag won't change +anything to the current behaviour of the platform. + +CLK_SET_RATE_GATE is being fixed and enforced now. If the flag was kept, +the mmci driver would receive -EBUSY when calling clk_set_rate() + +Signed-off-by: Jerome Brunet +--- + drivers/clk/qcom/gcc-ipq806x.c | 3 --- + drivers/clk/qcom/gcc-mdm9615.c | 2 -- + drivers/clk/qcom/gcc-msm8660.c | 5 ----- + drivers/clk/qcom/gcc-msm8960.c | 5 ----- + 4 files changed, 15 deletions(-) + +diff --git a/drivers/clk/qcom/gcc-ipq806x.c b/drivers/clk/qcom/gcc-ipq806x.c +index 28eb200d0f1ee..5f61225657abb 100644 +--- a/drivers/clk/qcom/gcc-ipq806x.c ++++ b/drivers/clk/qcom/gcc-ipq806x.c +@@ -1220,7 +1220,6 @@ static struct clk_rcg sdc1_src = { + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, +- .flags = CLK_SET_RATE_GATE, + }, + } + }; +@@ -1269,7 +1268,6 @@ static struct clk_rcg sdc3_src = { + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, +- .flags = CLK_SET_RATE_GATE, + }, + } + }; +@@ -1353,7 +1351,6 @@ static struct clk_rcg tsif_ref_src = { + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, +- .flags = CLK_SET_RATE_GATE, + }, + } + }; +diff --git a/drivers/clk/qcom/gcc-mdm9615.c b/drivers/clk/qcom/gcc-mdm9615.c +index b99dd406e9071..849046fbed6d4 100644 +--- a/drivers/clk/qcom/gcc-mdm9615.c ++++ b/drivers/clk/qcom/gcc-mdm9615.c +@@ -947,7 +947,6 @@ static struct clk_rcg sdc1_src = { + .parent_names = gcc_cxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, +- .flags = CLK_SET_RATE_GATE, + }, + } + }; +@@ -996,7 +995,6 @@ static struct clk_rcg sdc2_src = { + .parent_names = gcc_cxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, +- .flags = CLK_SET_RATE_GATE, + }, + } + }; +diff --git a/drivers/clk/qcom/gcc-msm8660.c b/drivers/clk/qcom/gcc-msm8660.c +index c347a0d44bc8b..7e930e25c79f1 100644 +--- a/drivers/clk/qcom/gcc-msm8660.c ++++ b/drivers/clk/qcom/gcc-msm8660.c +@@ -1558,7 +1558,6 @@ static struct clk_rcg sdc1_src = { + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, +- .flags = CLK_SET_RATE_GATE, + }, + } + }; +@@ -1607,7 +1606,6 @@ static struct clk_rcg sdc2_src = { + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, +- .flags = CLK_SET_RATE_GATE, + }, + } + }; +@@ -1656,7 +1654,6 @@ static struct clk_rcg sdc3_src = { + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, +- .flags = CLK_SET_RATE_GATE, + }, + } + }; +@@ -1705,7 +1702,6 @@ static struct clk_rcg sdc4_src = { + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, +- .flags = CLK_SET_RATE_GATE, + }, + } + }; +@@ -1754,7 +1750,6 @@ static struct clk_rcg sdc5_src = { + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, +- .flags = CLK_SET_RATE_GATE, + }, + } + }; +diff --git a/drivers/clk/qcom/gcc-msm8960.c b/drivers/clk/qcom/gcc-msm8960.c +index eb551c75fba6a..fd495e0471bb4 100644 +--- a/drivers/clk/qcom/gcc-msm8960.c ++++ b/drivers/clk/qcom/gcc-msm8960.c +@@ -1628,7 +1628,6 @@ static struct clk_rcg sdc1_src = { + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, +- .flags = CLK_SET_RATE_GATE, + }, + } + }; +@@ -1677,7 +1676,6 @@ static struct clk_rcg sdc2_src = { + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, +- .flags = CLK_SET_RATE_GATE, + }, + } + }; +@@ -1726,7 +1724,6 @@ static struct clk_rcg sdc3_src = { + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, +- .flags = CLK_SET_RATE_GATE, + }, + } + }; +@@ -1775,7 +1772,6 @@ static struct clk_rcg sdc4_src = { + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, +- .flags = CLK_SET_RATE_GATE, + }, + } + }; +@@ -1824,7 +1820,6 @@ static struct clk_rcg sdc5_src = { + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, +- .flags = CLK_SET_RATE_GATE, + }, + } + }; diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/049_linux-4.18.y-jeromebrunet-0002-clk-fix_clk_set_rate_gate_with_clock_rate_protection.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/049_linux-4.18.y-jeromebrunet-0002-clk-fix_clk_set_rate_gate_with_clock_rate_protection.patch new file mode 100644 index 000000000..daba9ee1b --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/049_linux-4.18.y-jeromebrunet-0002-clk-fix_clk_set_rate_gate_with_clock_rate_protection.patch @@ -0,0 +1,70 @@ +From b2ae7fbfe34642d87aeac299d9cec8f1e01ed0b2 Mon Sep 17 00:00:00 2001 +From: Jerome Brunet +Date: Fri, 1 Dec 2017 22:51:58 +0100 +Subject: [PATCH] clk: fix CLK_SET_RATE_GATE with clock rate protection + +CLK_SET_RATE_GATE should prevent any operation which may result in a rate +change or glitch while the clock is prepared/enabled. + +IOW, the following sequence is not allowed anymore with CLK_SET_RATE_GATE: +* clk_get() +* clk_prepare_enable() +* clk_get_rate() +* clk_set_rate() + +At the moment this is enforced on the leaf clock of the operation, not +along the tree. This problematic because, if a PLL has the CLK_RATE_GATE, +it won't be enforced if the clk_set_rate() is called on its child clocks. + +Using clock rate protection, we can now enforce CLK_SET_RATE_GATE along the +clock tree + +Acked-by: Linus Walleij +Tested-by: Quentin Schulz +Tested-by: Maxime Ripard +Signed-off-by: Jerome Brunet +--- + drivers/clk/clk.c | 16 +++++++++++++--- + 1 file changed, 13 insertions(+), 3 deletions(-) + +diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c +index 9760b526ca31d..97c09243fb21c 100644 +--- a/drivers/clk/clk.c ++++ b/drivers/clk/clk.c +@@ -691,6 +691,9 @@ static void clk_core_unprepare(struct clk_core *core) + "Unpreparing critical %s\n", core->name)) + return; + ++ if (core->flags & CLK_SET_RATE_GATE) ++ clk_core_rate_unprotect(core); ++ + if (--core->prepare_count > 0) + return; + +@@ -765,6 +768,16 @@ static int clk_core_prepare(struct clk_core *core) + + core->prepare_count++; + ++ /* ++ * CLK_SET_RATE_GATE is a special case of clock protection ++ * Instead of a consumer claiming exclusive rate control, it is ++ * actually the provider which prevents any consumer from making any ++ * operation which could result in a rate change or rate glitch while ++ * the clock is prepared. ++ */ ++ if (core->flags & CLK_SET_RATE_GATE) ++ clk_core_rate_protect(core); ++ + return 0; + unprepare: + clk_core_unprepare(core->parent); +@@ -1888,9 +1901,6 @@ static int clk_core_set_rate_nolock(struct clk_core *core, + if (clk_core_rate_is_protected(core)) + return -EBUSY; + +- if ((core->flags & CLK_SET_RATE_GATE) && core->prepare_count) +- return -EBUSY; +- + /* calculate new rates and get the topmost changed clock */ + top = clk_calc_new_rates(core, req_rate); + if (!top) diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/050_linux-4.18.y-jeromebrunet-0003-media-rc-meson-rc_rc0-two_consecutive_events_of_type.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/050_linux-4.18.y-jeromebrunet-0003-media-rc-meson-rc_rc0-two_consecutive_events_of_type.patch new file mode 100644 index 000000000..4cd4c3aa4 --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/050_linux-4.18.y-jeromebrunet-0003-media-rc-meson-rc_rc0-two_consecutive_events_of_type.patch @@ -0,0 +1,29 @@ +From df17d1808dd4899a9469e4e7f2d9b1120b7fc208 Mon Sep 17 00:00:00 2001 +From: Sean Young +Date: Tue, 19 Jun 2018 13:50:36 +0100 +Subject: [PATCH] media: rc: meson: rc rc0: two consecutive events of type + space + +The meson generates one edge per interrupt. The duration is encoded in 12 +bits of 10 microseconds, so it can only encoding a maximum of 40 +milliseconds. As a result, it can produce multiple space events. + +Signed-off-by: Sean Young +--- + drivers/media/rc/meson-ir.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/media/rc/meson-ir.c b/drivers/media/rc/meson-ir.c +index f449b35d25e73..9747426719b29 100644 +--- a/drivers/media/rc/meson-ir.c ++++ b/drivers/media/rc/meson-ir.c +@@ -97,7 +97,8 @@ static irqreturn_t meson_ir_irq(int irqno, void *dev_id) + status = readl_relaxed(ir->reg + IR_DEC_STATUS); + rawir.pulse = !!(status & STATUS_IR_DEC_IN); + +- ir_raw_event_store_with_timeout(ir->rc, &rawir); ++ if (ir_raw_event_store_with_filter(ir->rc, &rawir)) ++ ir_raw_event_handle(ir->rc); + + spin_unlock(&ir->lock); + diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/051_linux-4.18.y-jeromebrunet-0004-clk-add_duty_cycle_support.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/051_linux-4.18.y-jeromebrunet-0004-clk-add_duty_cycle_support.patch new file mode 100644 index 000000000..9547c408c --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/051_linux-4.18.y-jeromebrunet-0004-clk-add_duty_cycle_support.patch @@ -0,0 +1,461 @@ +From 28d675fabd5e66be0ccc3cba655de36c7625f4a5 Mon Sep 17 00:00:00 2001 +From: Jerome Brunet +Date: Fri, 20 Apr 2018 23:11:41 +0200 +Subject: [PATCH] clk: add duty cycle support + +Add the possibility to apply and query the clock signal duty cycle ratio. + +This is useful when the duty cycle of the clock signal depends on some +other parameters controlled by the clock framework. + +For example, the duty cycle of a divider may depends on the raw divider +setting (ratio = N / div) , which is controlled by the CCF. In such case, +going through the pwm framework to control the duty cycle ratio of this +clock would be a burden. + +A clock provider is not required to implement the operation to set and get +the duty cycle. If it does not implement .get_duty_cycle(), the ratio is +assumed to be 50%. + +This change also adds a new flag, CLK_DUTY_CYCLE_PARENT. This flag should +be used to indicate that a clock, such as gates and muxes, may inherit +the duty cycle ratio of its parent clock. If a clock does not provide a +get_duty_cycle() callback and has CLK_DUTY_CYCLE_PARENT, then the call +will be directly forwarded to its parent clock, if any. For +set_duty_cycle(), the clock should also have CLK_SET_RATE_PARENT for the +call to be forwarded + +Signed-off-by: Jerome Brunet +--- + drivers/clk/clk.c | 199 ++++++++++++++++++++++++++++++++++- + include/linux/clk-provider.h | 26 +++++ + include/linux/clk.h | 33 ++++++ + include/trace/events/clk.h | 36 +++++++ + 4 files changed, 289 insertions(+), 5 deletions(-) + +diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c +index 97c09243fb21c..e108f591d84a9 100644 +--- a/drivers/clk/clk.c ++++ b/drivers/clk/clk.c +@@ -68,6 +68,7 @@ struct clk_core { + unsigned long max_rate; + unsigned long accuracy; + int phase; ++ struct clk_duty duty; + struct hlist_head children; + struct hlist_node child_node; + struct hlist_head clks; +@@ -2412,6 +2413,172 @@ int clk_get_phase(struct clk *clk) + } + EXPORT_SYMBOL_GPL(clk_get_phase); + ++static void clk_core_reset_duty_cycle_nolock(struct clk_core *core) ++{ ++ /* Assume a default value of 50% */ ++ core->duty.num = 1; ++ core->duty.den = 2; ++} ++ ++static int clk_core_update_duty_cycle_parent_nolock(struct clk_core *core); ++ ++static int clk_core_update_duty_cycle_nolock(struct clk_core *core) ++{ ++ struct clk_duty *duty = &core->duty; ++ int ret = 0; ++ ++ if (!core->ops->get_duty_cycle) ++ return clk_core_update_duty_cycle_parent_nolock(core); ++ ++ ret = core->ops->get_duty_cycle(core->hw, duty); ++ if (ret) ++ goto reset; ++ ++ /* Don't trust the clock provider too much */ ++ if (duty->den == 0 || duty->num > duty->den) { ++ ret = -EINVAL; ++ goto reset; ++ } ++ ++ return 0; ++ ++reset: ++ clk_core_reset_duty_cycle_nolock(core); ++ return ret; ++} ++ ++static int clk_core_update_duty_cycle_parent_nolock(struct clk_core *core) ++{ ++ int ret = 0; ++ ++ if (core->parent && ++ core->flags & CLK_DUTY_CYCLE_PARENT) { ++ ret = clk_core_update_duty_cycle_nolock(core->parent); ++ memcpy(&core->duty, &core->parent->duty, sizeof(core->duty)); ++ } else { ++ clk_core_reset_duty_cycle_nolock(core); ++ } ++ ++ return ret; ++} ++ ++static int clk_core_set_duty_cycle_parent_nolock(struct clk_core *core, ++ struct clk_duty *duty); ++ ++static int clk_core_set_duty_cycle_nolock(struct clk_core *core, ++ struct clk_duty *duty) ++{ ++ int ret; ++ ++ lockdep_assert_held(&prepare_lock); ++ ++ if (clk_core_rate_is_protected(core)) ++ return -EBUSY; ++ ++ trace_clk_set_duty_cycle(core, duty); ++ ++ if (!core->ops->set_duty_cycle) ++ return clk_core_set_duty_cycle_parent_nolock(core, duty); ++ ++ ret = core->ops->set_duty_cycle(core->hw, duty); ++ if (!ret) ++ memcpy(&core->duty, duty, sizeof(*duty)); ++ ++ trace_clk_set_duty_cycle_complete(core, duty); ++ ++ return ret; ++} ++ ++static int clk_core_set_duty_cycle_parent_nolock(struct clk_core *core, ++ struct clk_duty *duty) ++{ ++ int ret = 0; ++ ++ if (core->parent && ++ core->flags & (CLK_DUTY_CYCLE_PARENT | CLK_SET_RATE_PARENT)) { ++ ret = clk_core_set_duty_cycle_nolock(core->parent, duty); ++ memcpy(&core->duty, &core->parent->duty, sizeof(core->duty)); ++ } ++ ++ return ret; ++} ++ ++/** ++ * clk_set_duty_cycle - adjust the duty cycle ratio of a clock signal ++ * @clk: clock signal source ++ * @num: numerator of the duty cycle ratio to be applied ++ * @den: denominator of the duty cycle ratio to be applied ++ * ++ * Apply the duty cycle ratio if the ratio is valid and the clock can ++ * perform this operation ++ * ++ * Returns (0) on success, a negative errno otherwise. ++ */ ++int clk_set_duty_cycle(struct clk *clk, unsigned int num, unsigned int den) ++{ ++ int ret; ++ struct clk_duty duty; ++ ++ if (!clk) ++ return 0; ++ ++ /* sanity check the ratio */ ++ if (den == 0 || num > den) ++ return -EINVAL; ++ ++ duty.num = num; ++ duty.den = den; ++ ++ clk_prepare_lock(); ++ ++ if (clk->exclusive_count) ++ clk_core_rate_unprotect(clk->core); ++ ++ ret = clk_core_set_duty_cycle_nolock(clk->core, &duty); ++ ++ if (clk->exclusive_count) ++ clk_core_rate_protect(clk->core); ++ ++ clk_prepare_unlock(); ++ ++ return ret; ++} ++EXPORT_SYMBOL_GPL(clk_set_duty_cycle); ++ ++static int clk_core_get_scaled_duty_cycle(struct clk_core *core, ++ unsigned int scale) ++{ ++ struct clk_duty *duty = &core->duty; ++ int ret; ++ ++ clk_prepare_lock(); ++ ++ ret = clk_core_update_duty_cycle_nolock(core); ++ if (!ret) ++ ret = mult_frac(scale, duty->num, duty->den); ++ ++ clk_prepare_unlock(); ++ ++ return ret; ++} ++ ++/** ++ * clk_get_scaled_duty_cycle - return the duty cycle ratio of a clock signal ++ * @clk: clock signal source ++ * @scale: scaling factor to be applied to represent the ratio as an integer ++ * ++ * Returns the duty cycle ratio of a clock node multiplied by the provided ++ * scaling factor, or negative errno on error. ++ */ ++int clk_get_scaled_duty_cycle(struct clk *clk, unsigned int scale) ++{ ++ if (!clk) ++ return 0; ++ ++ return clk_core_get_scaled_duty_cycle(clk->core, scale); ++} ++EXPORT_SYMBOL_GPL(clk_get_scaled_duty_cycle); ++ + /** + * clk_is_match - check if two clk's point to the same hardware clock + * @p: clk compared against q +@@ -2465,12 +2632,13 @@ static void clk_summary_show_one(struct seq_file *s, struct clk_core *c, + if (!c) + return; + +- seq_printf(s, "%*s%-*s %7d %8d %8d %11lu %10lu %-3d\n", ++ seq_printf(s, "%*s%-*s %7d %8d %8d %11lu %10lu %5d %6d\n", + level * 3 + 1, "", + 30 - level * 3, c->name, + c->enable_count, c->prepare_count, c->protect_count, + clk_core_get_rate(c), clk_core_get_accuracy(c), +- clk_core_get_phase(c)); ++ clk_core_get_phase(c), ++ clk_core_get_scaled_duty_cycle(c, 100000)); + } + + static void clk_summary_show_subtree(struct seq_file *s, struct clk_core *c, +@@ -2492,9 +2660,9 @@ static int clk_summary_show(struct seq_file *s, void *data) + struct clk_core *c; + struct hlist_head **lists = (struct hlist_head **)s->private; + +- seq_puts(s, " enable prepare protect \n"); +- seq_puts(s, " clock count count count rate accuracy phase\n"); +- seq_puts(s, "----------------------------------------------------------------------------------------\n"); ++ seq_puts(s, " enable prepare protect duty\n"); ++ seq_puts(s, " clock count count count rate accuracy phase cycle\n"); ++ seq_puts(s, "---------------------------------------------------------------------------------------------\n"); + + clk_prepare_lock(); + +@@ -2521,6 +2689,8 @@ static void clk_dump_one(struct seq_file *s, struct clk_core *c, int level) + seq_printf(s, "\"rate\": %lu,", clk_core_get_rate(c)); + seq_printf(s, "\"accuracy\": %lu,", clk_core_get_accuracy(c)); + seq_printf(s, "\"phase\": %d", clk_core_get_phase(c)); ++ seq_printf(s, "\"duty_cycle\": %u", ++ clk_core_get_scaled_duty_cycle(c, 100000)); + } + + static void clk_dump_subtree(struct seq_file *s, struct clk_core *c, int level) +@@ -2582,6 +2752,7 @@ static const struct { + ENTRY(CLK_SET_RATE_UNGATE), + ENTRY(CLK_IS_CRITICAL), + ENTRY(CLK_OPS_PARENT_ENABLE), ++ ENTRY(CLK_DUTY_CYCLE_PARENT), + #undef ENTRY + }; + +@@ -2620,6 +2791,17 @@ static int possible_parents_show(struct seq_file *s, void *data) + } + DEFINE_SHOW_ATTRIBUTE(possible_parents); + ++static int clk_duty_cycle_show(struct seq_file *s, void *data) ++{ ++ struct clk_core *core = s->private; ++ struct clk_duty *duty = &core->duty; ++ ++ seq_printf(s, "%u/%u\n", duty->num, duty->den); ++ ++ return 0; ++} ++DEFINE_SHOW_ATTRIBUTE(clk_duty_cycle); ++ + static void clk_debug_create_one(struct clk_core *core, struct dentry *pdentry) + { + struct dentry *root; +@@ -2638,6 +2820,8 @@ static void clk_debug_create_one(struct clk_core *core, struct dentry *pdentry) + debugfs_create_u32("clk_enable_count", 0444, root, &core->enable_count); + debugfs_create_u32("clk_protect_count", 0444, root, &core->protect_count); + debugfs_create_u32("clk_notifier_count", 0444, root, &core->notifier_count); ++ debugfs_create_file("clk_duty_cycle", 0444, root, core, ++ &clk_duty_cycle_fops); + + if (core->num_parents > 1) + debugfs_create_file("clk_possible_parents", 0444, root, core, +@@ -2855,6 +3039,11 @@ static int __clk_core_init(struct clk_core *core) + else + core->phase = 0; + ++ /* ++ * Set clk's duty cycle. ++ */ ++ clk_core_update_duty_cycle_nolock(core); ++ + /* + * Set clk's rate. The preferred method is to use .recalc_rate. For + * simple clocks and lazy developers the default fallback is to use the +diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h +index b7cfa037e593e..08b1aa70a38d3 100644 +--- a/include/linux/clk-provider.h ++++ b/include/linux/clk-provider.h +@@ -38,6 +38,8 @@ + #define CLK_IS_CRITICAL BIT(11) /* do not gate, ever */ + /* parents need enable during gate/ungate, set rate and re-parent */ + #define CLK_OPS_PARENT_ENABLE BIT(12) ++/* duty cycle call may be forwarded to the parent clock */ ++#define CLK_DUTY_CYCLE_PARENT BIT(13) + + struct clk; + struct clk_hw; +@@ -66,6 +68,17 @@ struct clk_rate_request { + struct clk_hw *best_parent_hw; + }; + ++/** ++ * struct clk_duty - Struture encoding the duty cycle ratio of a clock ++ * ++ * @num: Numerator of the duty cycle ratio ++ * @den: Denominator of the duty cycle ratio ++ */ ++struct clk_duty { ++ unsigned int num; ++ unsigned int den; ++}; ++ + /** + * struct clk_ops - Callback operations for hardware clocks; these are to + * be provided by the clock implementation, and will be called by drivers +@@ -169,6 +182,15 @@ struct clk_rate_request { + * by the second argument. Valid values for degrees are + * 0-359. Return 0 on success, otherwise -EERROR. + * ++ * @get_duty_cycle: Queries the hardware to get the current duty cycle ratio ++ * of a clock. Returned values denominator cannot be 0 and must be ++ * superior or equal to the numerator. ++ * ++ * @set_duty_cycle: Apply the duty cycle ratio to this clock signal specified by ++ * the numerator (2nd argurment) and denominator (3rd argument). ++ * Argument must be a valid ratio (denominator > 0 ++ * and >= numerator) Return 0 on success, otherwise -EERROR. ++ * + * @init: Perform platform-specific initialization magic. + * This is not not used by any of the basic clock types. + * Please consider other ways of solving initialization problems +@@ -218,6 +240,10 @@ struct clk_ops { + unsigned long parent_accuracy); + int (*get_phase)(struct clk_hw *hw); + int (*set_phase)(struct clk_hw *hw, int degrees); ++ int (*get_duty_cycle)(struct clk_hw *hw, ++ struct clk_duty *duty); ++ int (*set_duty_cycle)(struct clk_hw *hw, ++ struct clk_duty *duty); + void (*init)(struct clk_hw *hw); + void (*debug_init)(struct clk_hw *hw, struct dentry *dentry); + }; +diff --git a/include/linux/clk.h b/include/linux/clk.h +index 0dbd0885b2c23..4f750c481b82b 100644 +--- a/include/linux/clk.h ++++ b/include/linux/clk.h +@@ -141,6 +141,27 @@ int clk_set_phase(struct clk *clk, int degrees); + */ + int clk_get_phase(struct clk *clk); + ++/** ++ * clk_set_duty_cycle - adjust the duty cycle ratio of a clock signal ++ * @clk: clock signal source ++ * @num: numerator of the duty cycle ratio to be applied ++ * @den: denominator of the duty cycle ratio to be applied ++ * ++ * Adjust the duty cycle of a clock signal by the specified ratio. Returns 0 on ++ * success, -EERROR otherwise. ++ */ ++int clk_set_duty_cycle(struct clk *clk, unsigned int num, unsigned int den); ++ ++/** ++ * clk_get_duty_cycle - return the duty cycle ratio of a clock signal ++ * @clk: clock signal source ++ * @scale: scaling factor to be applied to represent the ratio as an integer ++ * ++ * Returns the duty cycle ratio multiplied by the scale provided, otherwise ++ * returns -EERROR. ++ */ ++int clk_get_scaled_duty_cycle(struct clk *clk, unsigned int scale); ++ + /** + * clk_is_match - check if two clk's point to the same hardware clock + * @p: clk compared against q +@@ -183,6 +204,18 @@ static inline long clk_get_phase(struct clk *clk) + return -ENOTSUPP; + } + ++static inline int clk_set_duty_cycle(struct clk *clk, unsigned int num, ++ unsigned int den) ++{ ++ return -ENOTSUPP; ++} ++ ++static inline unsigned int clk_get_scaled_duty_cycle(struct clk *clk, ++ unsigned int scale) ++{ ++ return 0; ++} ++ + static inline bool clk_is_match(const struct clk *p, const struct clk *q) + { + return p == q; +diff --git a/include/trace/events/clk.h b/include/trace/events/clk.h +index 2cd449328aee3..9004ffff7f326 100644 +--- a/include/trace/events/clk.h ++++ b/include/trace/events/clk.h +@@ -192,6 +192,42 @@ DEFINE_EVENT(clk_phase, clk_set_phase_complete, + TP_ARGS(core, phase) + ); + ++DECLARE_EVENT_CLASS(clk_duty_cycle, ++ ++ TP_PROTO(struct clk_core *core, struct clk_duty *duty), ++ ++ TP_ARGS(core, duty), ++ ++ TP_STRUCT__entry( ++ __string( name, core->name ) ++ __field( unsigned int, num ) ++ __field( unsigned int, den ) ++ ), ++ ++ TP_fast_assign( ++ __assign_str(name, core->name); ++ __entry->num = duty->num; ++ __entry->den = duty->den; ++ ), ++ ++ TP_printk("%s %u/%u", __get_str(name), (unsigned int)__entry->num, ++ (unsigned int)__entry->den) ++); ++ ++DEFINE_EVENT(clk_duty_cycle, clk_set_duty_cycle, ++ ++ TP_PROTO(struct clk_core *core, struct clk_duty *duty), ++ ++ TP_ARGS(core, duty) ++); ++ ++DEFINE_EVENT(clk_duty_cycle, clk_set_duty_cycle_complete, ++ ++ TP_PROTO(struct clk_core *core, struct clk_duty *duty), ++ ++ TP_ARGS(core, duty) ++); ++ + #endif /* _TRACE_CLK_H */ + + /* This part must be outside protection */ diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/053_linux-4.18.y-jeromebrunet-0006-clk-meson-remove_obsolete_register_access.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/053_linux-4.18.y-jeromebrunet-0006-clk-meson-remove_obsolete_register_access.patch new file mode 100644 index 000000000..0472a46df --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/053_linux-4.18.y-jeromebrunet-0006-clk-meson-remove_obsolete_register_access.patch @@ -0,0 +1,142 @@ +From c46829185836ce19b9b14ee301d891e3f67fbe3d Mon Sep 17 00:00:00 2001 +From: Jerome Brunet +Date: Wed, 10 Jan 2018 17:05:57 +0100 +Subject: [PATCH] clk: meson: remove obsolete register access + +The legacy method to access the hhi register space is not longer used. +We can safely drop it now. + +Signed-off-by: Jerome Brunet +--- + drivers/clk/meson/axg.c | 37 ++----------------------------------- + drivers/clk/meson/gxbb.c | 36 ++---------------------------------- + 2 files changed, 4 insertions(+), 69 deletions(-) + +diff --git a/drivers/clk/meson/axg.c b/drivers/clk/meson/axg.c +index bd4dbc696b88f..3fb884db1b10f 100644 +--- a/drivers/clk/meson/axg.c ++++ b/drivers/clk/meson/axg.c +@@ -12,7 +12,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -995,49 +994,17 @@ static const struct of_device_id clkc_match_table[] = { + {} + }; + +-static const struct regmap_config clkc_regmap_config = { +- .reg_bits = 32, +- .val_bits = 32, +- .reg_stride = 4, +-}; +- + static int axg_clkc_probe(struct platform_device *pdev) + { + struct device *dev = &pdev->dev; +- struct resource *res; +- void __iomem *clk_base = NULL; + struct regmap *map; + int ret, i; + + /* Get the hhi system controller node if available */ + map = syscon_node_to_regmap(of_get_parent(dev->of_node)); + if (IS_ERR(map)) { +- dev_err(dev, +- "failed to get HHI regmap - Trying obsolete regs\n"); +- +- /* +- * FIXME: HHI registers should be accessed through +- * the appropriate system controller. This is required because +- * there is more than just clocks in this register space +- * +- * This fallback method is only provided temporarily until +- * all the platform DTs are properly using the syscon node +- */ +- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +- if (!res) +- return -EINVAL; +- +- +- clk_base = devm_ioremap(dev, res->start, resource_size(res)); +- if (!clk_base) { +- dev_err(dev, "Unable to map clk base\n"); +- return -ENXIO; +- } +- +- map = devm_regmap_init_mmio(dev, clk_base, +- &clkc_regmap_config); +- if (IS_ERR(map)) +- return PTR_ERR(map); ++ dev_err(dev, "failed to get HHI regmap\n"); ++ return PTR_ERR(map); + } + + /* Populate regmap for the regmap backed clocks */ +diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c +index 177fffb9ebefe..297ebc3914750 100644 +--- a/drivers/clk/meson/gxbb.c ++++ b/drivers/clk/meson/gxbb.c +@@ -7,7 +7,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -2228,17 +2227,9 @@ static const struct of_device_id clkc_match_table[] = { + {}, + }; + +-static const struct regmap_config clkc_regmap_config = { +- .reg_bits = 32, +- .val_bits = 32, +- .reg_stride = 4, +-}; +- + static int gxbb_clkc_probe(struct platform_device *pdev) + { + const struct clkc_data *clkc_data; +- struct resource *res; +- void __iomem *clk_base; + struct regmap *map; + int ret, i; + struct device *dev = &pdev->dev; +@@ -2250,31 +2241,8 @@ static int gxbb_clkc_probe(struct platform_device *pdev) + /* Get the hhi system controller node if available */ + map = syscon_node_to_regmap(of_get_parent(dev->of_node)); + if (IS_ERR(map)) { +- dev_err(dev, +- "failed to get HHI regmap - Trying obsolete regs\n"); +- +- /* +- * FIXME: HHI registers should be accessed through +- * the appropriate system controller. This is required because +- * there is more than just clocks in this register space +- * +- * This fallback method is only provided temporarily until +- * all the platform DTs are properly using the syscon node +- */ +- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +- if (!res) +- return -EINVAL; +- +- clk_base = devm_ioremap(dev, res->start, resource_size(res)); +- if (!clk_base) { +- dev_err(dev, "Unable to map clk base\n"); +- return -ENXIO; +- } +- +- map = devm_regmap_init_mmio(dev, clk_base, +- &clkc_regmap_config); +- if (IS_ERR(map)) +- return PTR_ERR(map); ++ dev_err(dev, "failed to get HHI regmap\n"); ++ return PTR_ERR(map); + } + + /* Populate regmap for the common regmap backed clocks */ diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/054_linux-4.18.y-jeromebrunet-0007-clk-meson-stop_rate_propagation_for_audio_clocks.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/054_linux-4.18.y-jeromebrunet-0007-clk-meson-stop_rate_propagation_for_audio_clocks.patch new file mode 100644 index 000000000..45c1f85e8 --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/054_linux-4.18.y-jeromebrunet-0007-clk-meson-stop_rate_propagation_for_audio_clocks.patch @@ -0,0 +1,51 @@ +From baa2bf58a7e8c243b89fe2de4a20784ddcbd6403 Mon Sep 17 00:00:00 2001 +From: Jerome Brunet +Date: Tue, 19 Jun 2018 18:06:30 +0200 +Subject: [PATCH] clk: meson: stop rate propagation for audio clocks + +It is actually a lot easier and precise to setup the PLL with +carefully chosen rates than relying on CCF clock propagation for +this use case. + +For this, we stop the rate propagation at the mux picking the +PLL and let it round to the closest matching PLL + +Signed-off-by: Jerome Brunet +--- + drivers/clk/meson/gxbb.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c +index 297ebc3914750..7d4a4e597385c 100644 +--- a/drivers/clk/meson/gxbb.c ++++ b/drivers/clk/meson/gxbb.c +@@ -970,13 +970,13 @@ static struct clk_regmap gxbb_cts_amclk_sel = { + .mask = 0x3, + .shift = 9, + .table = (u32[]){ 1, 2, 3 }, ++ .flags = CLK_MUX_ROUND_CLOSEST, + }, + .hw.init = &(struct clk_init_data){ + .name = "cts_amclk_sel", + .ops = &clk_regmap_mux_ops, + .parent_names = (const char *[]){ "mpll0", "mpll1", "mpll2" }, + .num_parents = 3, +- .flags = CLK_SET_RATE_PARENT, + }, + }; + +@@ -1018,13 +1018,13 @@ static struct clk_regmap gxbb_cts_mclk_i958_sel = { + .mask = 0x3, + .shift = 25, + .table = (u32[]){ 1, 2, 3 }, ++ .flags = CLK_MUX_ROUND_CLOSEST, + }, + .hw.init = &(struct clk_init_data) { + .name = "cts_mclk_i958_sel", + .ops = &clk_regmap_mux_ops, + .parent_names = (const char *[]){ "mpll0", "mpll1", "mpll2" }, + .num_parents = 3, +- .flags = CLK_SET_RATE_PARENT, + }, + }; + diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/055_linux-4.18.y-jeromebrunet-2008-asoc-codecs-force-enable-pcm5102a.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/055_linux-4.18.y-jeromebrunet-2008-asoc-codecs-force-enable-pcm5102a.patch new file mode 100644 index 000000000..8c47826ac --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/055_linux-4.18.y-jeromebrunet-2008-asoc-codecs-force-enable-pcm5102a.patch @@ -0,0 +1,13 @@ +--- a/sound/soc/codecs/Kconfig 2018-09-25 02:40:11.206734417 +0200 ++++ b/sound/soc/codecs/Kconfig 2018-09-25 03:32:51.395650591 +0200 +@@ -747,7 +747,9 @@ + select REGMAP_SPI + + config SND_SOC_PCM5102A +- tristate ++ tristate "PCM5102A Simple driver" ++ default m if SND_SOC_MESON=m ++ default y if SND_SOC_MESON=y + + config SND_SOC_PCM512x + tristate diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/056_linux-4.18.y-jeromebrunet-2009-arm64-dts-meson-gxbb-odroidc2-add-testing-i2s-entries.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/056_linux-4.18.y-jeromebrunet-2009-arm64-dts-meson-gxbb-odroidc2-add-testing-i2s-entries.patch new file mode 100644 index 000000000..72f6b624c --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/056_linux-4.18.y-jeromebrunet-2009-arm64-dts-meson-gxbb-odroidc2-add-testing-i2s-entries.patch @@ -0,0 +1,68 @@ +--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts 2018-09-25 02:40:03.744549370 +0200 ++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts 2018-09-25 03:42:03.505596966 +0200 +@@ -147,10 +147,27 @@ + }; + }; + ++ i2s_codec: external-codec { ++ #sound-dai-cells = <0>; ++ compatible = "ti,pcm5102a"; ++ status = "okay"; ++ }; ++ + sound { + compatible = "simple-audio-card"; + simple-audio-card,name = "meson-gx-audio"; + ++ simple-audio-card,widgets = ++ "Line", "Analog Left Output", ++ "Line", "Analog Right Output"; ++ simple-audio-card,routing = ++ "Analog Left Output", "OUTL", ++ "Analog Right Output", "OUTR", ++ "INL", "AOUTL", ++ "INR", "AOUTR"; ++ ++ status = "okay"; ++ + assigned-clocks = <&clkc CLKID_MPLL2>, + <&clkc CLKID_MPLL0>, + <&clkc CLKID_MPLL1>; +@@ -178,6 +195,27 @@ + sound-dai = <&hdmi_tx>; + }; + }; ++ ++ simple-audio-card,dai-link@1 { ++ /* I2C external codec Output */ ++ format = "i2s"; ++ bitclock-inversion; ++ mclk-fs = <256>; ++ bitclock-master = <&i2s_dai>; ++ frame-master = <&i2s_dai>; ++ ++ plat { ++ sound-dai = <&aiu_i2s_dma>; ++ }; ++ ++ cpu { ++ sound-dai = <&i2s_dai>; ++ }; ++ ++ codec { ++ sound-dai = <&i2s_codec>; ++ }; ++ }; + }; + }; + +@@ -264,6 +302,9 @@ + + &i2s_dai { + status = "okay"; ++ pinctrl-0 = <&i2s_am_clk_pins>, <&i2s_out_ao_clk_pins>, ++ <&i2s_out_lr_clk_pins>, <&i2s_out_ch01_ao_pins>; ++ pinctrl-names = "default"; + }; + + &ir { diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/058_linux-4.16-le-amlogic-gx-1001-usb-enable-otg-as-host.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/058_linux-4.16-le-amlogic-gx-1001-usb-enable-otg-as-host.patch new file mode 100644 index 000000000..8f9c1cd27 --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/058_linux-4.16-le-amlogic-gx-1001-usb-enable-otg-as-host.patch @@ -0,0 +1,51 @@ + +--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts 2018-04-28 19:24:56.090524456 +0200 ++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts 2018-04-29 23:09:48.559371108 +0200 +@@ -409,6 +409,7 @@ + &usb0_phy { + status = "okay"; + phy-supply = <&usb_otg_pwr>; ++ dr_mode = "otg"; + }; + + &usb1_phy { +@@ -418,6 +419,7 @@ + + &usb0 { + status = "okay"; ++ dr_mode = "host"; + }; + + &usb1 { + +--- a/drivers/phy/amlogic/phy-meson8b-usb2.c 2018-04-28 19:22:57.420144229 +0200 ++++ b/drivers/phy/amlogic/phy-meson8b-usb2.c 2018-04-29 23:13:57.136515043 +0200 +@@ -113,6 +113,7 @@ + struct phy_meson8b_usb2_priv { + void __iomem *regs; + enum usb_dr_mode dr_mode; ++ enum usb_dr_mode phy_mode; + struct clk *clk_usb_general; + struct clk *clk_usb; + struct reset_control *reset; +@@ -181,7 +182,7 @@ + phy_meson8b_usb2_mask_bits(priv, REG_CTRL, REG_CTRL_SOF_TOGGLE_OUT, + REG_CTRL_SOF_TOGGLE_OUT); + +- if (priv->dr_mode == USB_DR_MODE_HOST) { ++ if (priv->phy_mode == USB_DR_MODE_HOST) { + phy_meson8b_usb2_mask_bits(priv, REG_ADP_BC, + REG_ADP_BC_ACA_ENABLE, + REG_ADP_BC_ACA_ENABLE); +@@ -251,6 +252,11 @@ + return -EINVAL; + } + ++ priv->phy_mode = usb_get_dr_mode(&pdev->dev); ++ if (priv->phy_mode == USB_DR_MODE_UNKNOWN) { ++ priv->phy_mode = priv->dr_mode; ++ } ++ + phy = devm_phy_create(&pdev->dev, NULL, &phy_meson8b_usb2_ops); + if (IS_ERR(phy)) { + dev_err(&pdev->dev, "failed to create PHY\n"); diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/064_linux-4.14.y-le-amlogic-gx-scpi-1004-mailbox-revert_switch_to_hrtimer_for_tx_complete_polling.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/064_linux-4.14.y-le-amlogic-gx-scpi-1004-mailbox-revert_switch_to_hrtimer_for_tx_complete_polling.patch new file mode 100644 index 000000000..2dd8b1c9c --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/064_linux-4.14.y-le-amlogic-gx-scpi-1004-mailbox-revert_switch_to_hrtimer_for_tx_complete_polling.patch @@ -0,0 +1,103 @@ +diff --git a/drivers/mailbox/mailbox.c b/drivers/mailbox/mailbox.c +index 674b35f40..3497cabda 100644 +--- a/drivers/mailbox/mailbox.c ++++ b/drivers/mailbox/mailbox.c +@@ -26,6 +26,8 @@ + static LIST_HEAD(mbox_cons); + static DEFINE_MUTEX(con_mutex); + ++static void poll_txdone(struct timer_list *t); ++ + static int add_to_rbuf(struct mbox_chan *chan, void *mssg) + { + int idx; +@@ -86,8 +88,7 @@ static void msg_submit(struct mbox_chan *chan) + spin_unlock_irqrestore(&chan->lock, flags); + + if (!err && (chan->txdone_method & TXDONE_BY_POLL)) +- /* kick start the timer immediately to avoid delays */ +- hrtimer_start(&chan->mbox->poll_hrt, 0, HRTIMER_MODE_REL); ++ poll_txdone(&chan->mbox->poll); + } + + static void tx_tick(struct mbox_chan *chan, int r) +@@ -114,10 +115,9 @@ static void tx_tick(struct mbox_chan *chan, int r) + complete(&chan->tx_complete); + } + +-static enum hrtimer_restart txdone_hrtimer(struct hrtimer *hrtimer) ++static void poll_txdone(struct timer_list *t) + { +- struct mbox_controller *mbox = +- container_of(hrtimer, struct mbox_controller, poll_hrt); ++ struct mbox_controller *mbox = from_timer(mbox, t, poll); + bool txdone, resched = false; + int i; + +@@ -133,11 +133,9 @@ static enum hrtimer_restart txdone_hrtimer(struct hrtimer *hrtimer) + } + } + +- if (resched) { +- hrtimer_forward_now(hrtimer, ms_to_ktime(mbox->txpoll_period)); +- return HRTIMER_RESTART; +- } +- return HRTIMER_NORESTART; ++ if (resched) ++ mod_timer(&mbox->poll, jiffies + ++ msecs_to_jiffies(mbox->txpoll_period)); + } + + /** +@@ -466,9 +464,7 @@ int mbox_controller_register(struct mbox_controller *mbox) + return -EINVAL; + } + +- hrtimer_init(&mbox->poll_hrt, CLOCK_MONOTONIC, +- HRTIMER_MODE_REL); +- mbox->poll_hrt.function = txdone_hrtimer; ++ timer_setup(&mbox->poll, &poll_txdone, 0); + } + + for (i = 0; i < mbox->num_chans; i++) { +@@ -510,7 +506,7 @@ void mbox_controller_unregister(struct mbox_controller *mbox) + mbox_free_channel(&mbox->chans[i]); + + if (mbox->txdone_poll) +- hrtimer_cancel(&mbox->poll_hrt); ++ del_timer_sync(&mbox->poll); + + mutex_unlock(&con_mutex); + } +diff --git a/include/linux/mailbox_controller.h b/include/linux/mailbox_controller.h +index 74deadb42..68c424544 100644 +--- a/include/linux/mailbox_controller.h ++++ b/include/linux/mailbox_controller.h +@@ -9,7 +9,7 @@ + + #include + #include +-#include ++#include + #include + #include + +@@ -67,8 +67,7 @@ struct mbox_chan_ops { + * @txpoll_period: If 'txdone_poll' is in effect, the API polls for + * last TX's status after these many millisecs + * @of_xlate: Controller driver specific mapping of channel via DT +- * @poll_hrt: API private. hrtimer used to poll for TXDONE on all +- * channels. ++ * @poll: API private. Used to poll for TXDONE on all channels. + * @node: API private. To hook into list of controllers. + */ + struct mbox_controller { +@@ -82,7 +81,7 @@ struct mbox_controller { + struct mbox_chan *(*of_xlate)(struct mbox_controller *mbox, + const struct of_phandle_args *sp); + /* Internal to API */ +- struct hrtimer poll_hrt; ++ struct timer_list poll; + struct list_head node; + }; + diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/068_linux-4.17-amlogic-dmt-extended-0001-make_dmt_timings_parameter_generic_and_add_more_frequencies.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/068_linux-4.17-amlogic-dmt-extended-0001-make_dmt_timings_parameter_generic_and_add_more_frequencies.patch new file mode 100644 index 000000000..c0859bcf3 --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/068_linux-4.17-amlogic-dmt-extended-0001-make_dmt_timings_parameter_generic_and_add_more_frequencies.patch @@ -0,0 +1,714 @@ +From 2d49cff77c34c63ae5aa32537cc5fef1ea2e165d Mon Sep 17 00:00:00 2001 +From: Neil Armstrong +Date: Fri, 27 Apr 2018 17:19:46 +0200 +Subject: [PATCH] drm/meson: Make DMT timings parameter generic and add more + frequencies + +Add more frequencies to support more timings with the generic timings +parameters calculation. + +Signed-off-by: Neil Armstrong +--- + drivers/gpu/drm/meson/meson_dw_hdmi.c | 10 +- + drivers/gpu/drm/meson/meson_vclk.c | 184 ++++++++++++++++++- + drivers/gpu/drm/meson/meson_venc.c | 330 +++++----------------------------- + drivers/gpu/drm/meson/meson_venc.h | 3 +- + 4 files changed, 231 insertions(+), 296 deletions(-) + +diff --git a/drivers/gpu/drm/meson/meson_dw_hdmi.c b/drivers/gpu/drm/meson/meson_dw_hdmi.c +index a393095aac1a6..7ebfef86383fe 100644 +--- a/drivers/gpu/drm/meson/meson_dw_hdmi.c ++++ b/drivers/gpu/drm/meson/meson_dw_hdmi.c +@@ -546,6 +546,7 @@ dw_hdmi_mode_valid(struct drm_connector *connector, + unsigned int venc_freq; + unsigned int hdmi_freq; + int vic = drm_match_cea_mode(mode); ++ enum drm_mode_status status; + + DRM_DEBUG_DRIVER("Modeline %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x\n", + mode->base.id, mode->name, mode->vrefresh, mode->clock, +@@ -556,8 +557,9 @@ dw_hdmi_mode_valid(struct drm_connector *connector, + + /* Check against non-VIC supported modes */ + if (!vic) { +- if (!meson_venc_hdmi_supported_mode(mode)) +- return MODE_BAD; ++ status = meson_venc_hdmi_supported_mode(mode); ++ if (status != MODE_OK) ++ return status; + /* Check against supported VIC modes */ + } else if (!meson_venc_hdmi_supported_vic(vic)) + return MODE_BAD; +@@ -587,6 +589,10 @@ dw_hdmi_mode_valid(struct drm_connector *connector, + switch (vclk_freq) { + case 25175: + case 40000: ++ case 32000: ++ case 36000: ++ case 33750: ++ case 33900: + case 54000: + case 65000: + case 74250: +diff --git a/drivers/gpu/drm/meson/meson_vclk.c b/drivers/gpu/drm/meson/meson_vclk.c +index f0511220317f9..86975f245c361 100644 +--- a/drivers/gpu/drm/meson/meson_vclk.c ++++ b/drivers/gpu/drm/meson/meson_vclk.c +@@ -330,22 +330,30 @@ static void meson_venci_cvbs_clock_config(struct meson_drm *priv) + #define MESON_VCLK_HDMI_DDR_148500 3 + /* 4028 /4 /4 /1 /5 /2 => /1 /1 */ + #define MESON_VCLK_HDMI_25175 4 ++/* 2560 /4 /2 /1 /5 /2 => /1 /1 */ ++#define MESON_VCLK_HDMI_32000 5 ++/* 2700 /4 /2 /1 /5 /2 => /1 /1 */ ++#define MESON_VCLK_HDMI_33750 6 ++/* 2712 /4 /2 /1 /5 /2 => /1 /1 */ ++#define MESON_VCLK_HDMI_33900 7 ++/* 2880 /4 /2 /1 /5 /2 => /1 /1 */ ++#define MESON_VCLK_HDMI_36000 8 + /* 3200 /4 /2 /1 /5 /2 => /1 /1 */ +-#define MESON_VCLK_HDMI_40000 5 ++#define MESON_VCLK_HDMI_40000 9 + /* 5200 /4 /2 /1 /5 /2 => /1 /1 */ +-#define MESON_VCLK_HDMI_65000 6 ++#define MESON_VCLK_HDMI_65000 10 + /* 2970 /2 /2 /2 /5 /1 => /1 /1 */ +-#define MESON_VCLK_HDMI_74250 7 ++#define MESON_VCLK_HDMI_74250 11 + /* 4320 /4 /1 /1 /5 /2 => /1 /1 */ +-#define MESON_VCLK_HDMI_108000 8 ++#define MESON_VCLK_HDMI_108000 12 + /* 2970 /1 /2 /2 /5 /1 => /1 /1 */ +-#define MESON_VCLK_HDMI_148500 9 ++#define MESON_VCLK_HDMI_148500 13 + /* 3240 /2 /1 /1 /5 /2 => /1 /1 */ +-#define MESON_VCLK_HDMI_162000 10 ++#define MESON_VCLK_HDMI_162000 14 + /* 2970 /1 /1 /1 /5 /2 => /1 /1 */ +-#define MESON_VCLK_HDMI_297000 11 ++#define MESON_VCLK_HDMI_297000 15 + /* 5940 /1 /1 /2 /5 /1 => /1 /1 */ +-#define MESON_VCLK_HDMI_594000 12 ++#define MESON_VCLK_HDMI_594000 16 + + struct meson_vclk_params { + unsigned int pll_base_freq; +@@ -419,6 +427,38 @@ struct meson_vclk_params { + .vid_pll_div = VID_PLL_DIV_5, + .vclk_div = 2, + }, ++ [MESON_VCLK_HDMI_32000] = { ++ .pll_base_freq = 2560000, ++ .pll_od1 = 4, ++ .pll_od2 = 2, ++ .pll_od3 = 1, ++ .vid_pll_div = VID_PLL_DIV_5, ++ .vclk_div = 2, ++ }, ++ [MESON_VCLK_HDMI_33750] = { ++ .pll_base_freq = 2700000, ++ .pll_od1 = 4, ++ .pll_od2 = 2, ++ .pll_od3 = 1, ++ .vid_pll_div = VID_PLL_DIV_5, ++ .vclk_div = 2, ++ }, ++ [MESON_VCLK_HDMI_33900] = { ++ .pll_base_freq = 2712000, ++ .pll_od1 = 4, ++ .pll_od2 = 2, ++ .pll_od3 = 1, ++ .vid_pll_div = VID_PLL_DIV_5, ++ .vclk_div = 2, ++ }, ++ [MESON_VCLK_HDMI_36000] = { ++ .pll_base_freq = 2880000, ++ .pll_od1 = 4, ++ .pll_od2 = 2, ++ .pll_od3 = 1, ++ .vid_pll_div = VID_PLL_DIV_5, ++ .vclk_div = 2, ++ }, + [MESON_VCLK_HDMI_40000] = { + .pll_base_freq = 3200000, + .pll_od1 = 4, +@@ -480,6 +520,86 @@ void meson_hdmi_pll_set(struct meson_drm *priv, + + if (meson_vpu_is_compatible(priv, "amlogic,meson-gxbb-vpu")) { + switch (base) { ++ case 2560000: ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x58000235); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x00000000); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x0d5c5091); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x801da72c); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x71486980); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x00000e55); ++ ++ /* Enable and unreset */ ++ regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL, ++ 0x7 << 28, 0x4 << 28); ++ ++ /* Poll for lock bit */ ++ regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL, ++ val, (val & HDMI_PLL_LOCK), 10, 0); ++ ++ /* div_frac */ ++ regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2, ++ 0xFFFF, 0x4555); ++ break; ++ ++ case 2700000: ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x58000238); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x00000000); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x0d5c5091); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x801da72c); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x71486980); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x00000e55); ++ ++ /* Enable and unreset */ ++ regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL, ++ 0x7 << 28, 0x4 << 28); ++ ++ /* Poll for lock bit */ ++ regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL, ++ val, (val & HDMI_PLL_LOCK), 10, 0); ++ ++ /* div_frac */ ++ regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2, ++ 0xFFFF, 0x4400); ++ break; ++ ++ case 2712000: ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x58000238); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x00000000); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x0d5c5091); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x801da72c); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x71486980); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x00000e55); ++ ++ /* Enable and unreset */ ++ regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL, ++ 0x7 << 28, 0x4 << 28); ++ ++ /* Poll for lock bit */ ++ regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL, ++ val, (val & HDMI_PLL_LOCK), 10, 0); ++ ++ /* div_frac */ ++ regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2, ++ 0xFFFF, 0x4800); ++ break; ++ ++ case 2880000: ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x5800023c); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x00000000); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x0d5c5091); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x801da72c); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x71486980); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x00000e55); ++ ++ /* Enable and unreset */ ++ regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL, ++ 0x7 << 28, 0x4 << 28); ++ ++ /* Poll for lock bit */ ++ regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL, ++ val, (val & HDMI_PLL_LOCK), 10, 0); ++ break; ++ + case 2970000: + regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x5800023d); + regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x00000000); +@@ -640,6 +760,42 @@ void meson_hdmi_pll_set(struct meson_drm *priv, + } else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu") || + meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu")) { + switch (base) { ++ case 2560000: ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x4000026a); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb2ab); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x860f30c4); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x0c8e0000); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x001fa729); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500); ++ break; ++ ++ case 2700000: ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x40000270); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb200); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x860f30c4); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x0c8e0000); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x001fa729); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500); ++ break; ++ ++ case 2712000: ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x40000271); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb000); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x860f30c4); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x0c8e0000); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x001fa729); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500); ++ break; ++ ++ case 2880000: ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x40000278); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb000); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x860f30c4); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x0c8e0000); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x001fa729); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500); ++ break; ++ + case 2970000: + regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x4000027b); + regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb300); +@@ -789,6 +945,18 @@ void meson_vclk_setup(struct meson_drm *priv, unsigned int target, + case 25175: + freq = MESON_VCLK_HDMI_25175; + break; ++ case 32000: ++ freq = MESON_VCLK_HDMI_32000; ++ break; ++ case 33750: ++ freq = MESON_VCLK_HDMI_33750; ++ break; ++ case 33900: ++ freq = MESON_VCLK_HDMI_33900; ++ break; ++ case 36000: ++ freq = MESON_VCLK_HDMI_36000; ++ break; + case 40000: + freq = MESON_VCLK_HDMI_40000; + break; +diff --git a/drivers/gpu/drm/meson/meson_venc.c b/drivers/gpu/drm/meson/meson_venc.c +index 6e27013898013..ea178151399c5 100644 +--- a/drivers/gpu/drm/meson/meson_venc.c ++++ b/drivers/gpu/drm/meson/meson_venc.c +@@ -697,258 +697,6 @@ union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080p60 = { + }, + }; + +-union meson_hdmi_venc_mode meson_hdmi_encp_mode_640x480_60 = { +- .encp = { +- .dvi_settings = 0x21, +- .video_mode = 0x4040, +- .video_mode_adv = 0x18, +- /* video_prog_mode */ +- /* video_sync_mode */ +- /* video_yc_dly */ +- /* video_rgb_ctrl */ +- /* video_filt_ctrl */ +- /* video_ofld_voav_ofst */ +- /* yfp1_htime */ +- /* yfp2_htime */ +- .max_pxcnt = 0x31f, +- /* hspuls_begin */ +- /* hspuls_end */ +- /* hspuls_switch */ +- /* vspuls_begin */ +- /* vspuls_end */ +- /* vspuls_bline */ +- /* vspuls_eline */ +- .havon_begin = 0x90, +- .havon_end = 0x30f, +- .vavon_bline = 0x23, +- .vavon_eline = 0x202, +- /* eqpuls_begin */ +- /* eqpuls_end */ +- /* eqpuls_bline */ +- /* eqpuls_eline */ +- .hso_begin = 0, +- .hso_end = 0x60, +- .vso_begin = 0x1e, +- .vso_end = 0x32, +- .vso_bline = 0, +- .vso_eline = 2, +- .vso_eline_present = true, +- /* sy_val */ +- /* sy2_val */ +- .max_lncnt = 0x20c, +- }, +-}; +- +-union meson_hdmi_venc_mode meson_hdmi_encp_mode_800x600_60 = { +- .encp = { +- .dvi_settings = 0x21, +- .video_mode = 0x4040, +- .video_mode_adv = 0x18, +- /* video_prog_mode */ +- /* video_sync_mode */ +- /* video_yc_dly */ +- /* video_rgb_ctrl */ +- /* video_filt_ctrl */ +- /* video_ofld_voav_ofst */ +- /* yfp1_htime */ +- /* yfp2_htime */ +- .max_pxcnt = 0x41f, +- /* hspuls_begin */ +- /* hspuls_end */ +- /* hspuls_switch */ +- /* vspuls_begin */ +- /* vspuls_end */ +- /* vspuls_bline */ +- /* vspuls_eline */ +- .havon_begin = 0xD8, +- .havon_end = 0x3f7, +- .vavon_bline = 0x1b, +- .vavon_eline = 0x272, +- /* eqpuls_begin */ +- /* eqpuls_end */ +- /* eqpuls_bline */ +- /* eqpuls_eline */ +- .hso_begin = 0, +- .hso_end = 0x80, +- .vso_begin = 0x1e, +- .vso_end = 0x32, +- .vso_bline = 0, +- .vso_eline = 4, +- .vso_eline_present = true, +- /* sy_val */ +- /* sy2_val */ +- .max_lncnt = 0x273, +- }, +-}; +- +-union meson_hdmi_venc_mode meson_hdmi_encp_mode_1024x768_60 = { +- .encp = { +- .dvi_settings = 0x21, +- .video_mode = 0x4040, +- .video_mode_adv = 0x18, +- /* video_prog_mode */ +- /* video_sync_mode */ +- /* video_yc_dly */ +- /* video_rgb_ctrl */ +- /* video_filt_ctrl */ +- /* video_ofld_voav_ofst */ +- /* yfp1_htime */ +- /* yfp2_htime */ +- .max_pxcnt = 1343, +- /* hspuls_begin */ +- /* hspuls_end */ +- /* hspuls_switch */ +- /* vspuls_begin */ +- /* vspuls_end */ +- /* vspuls_bline */ +- /* vspuls_eline */ +- .havon_begin = 296, +- .havon_end = 1319, +- .vavon_bline = 35, +- .vavon_eline = 802, +- /* eqpuls_begin */ +- /* eqpuls_end */ +- /* eqpuls_bline */ +- /* eqpuls_eline */ +- .hso_begin = 0, +- .hso_end = 136, +- .vso_begin = 30, +- .vso_end = 50, +- .vso_bline = 0, +- .vso_eline = 6, +- .vso_eline_present = true, +- /* sy_val */ +- /* sy2_val */ +- .max_lncnt = 805, +- }, +-}; +- +-union meson_hdmi_venc_mode meson_hdmi_encp_mode_1152x864_75 = { +- .encp = { +- .dvi_settings = 0x21, +- .video_mode = 0x4040, +- .video_mode_adv = 0x18, +- /* video_prog_mode */ +- /* video_sync_mode */ +- /* video_yc_dly */ +- /* video_rgb_ctrl */ +- /* video_filt_ctrl */ +- /* video_ofld_voav_ofst */ +- /* yfp1_htime */ +- /* yfp2_htime */ +- .max_pxcnt = 0x63f, +- /* hspuls_begin */ +- /* hspuls_end */ +- /* hspuls_switch */ +- /* vspuls_begin */ +- /* vspuls_end */ +- /* vspuls_bline */ +- /* vspuls_eline */ +- .havon_begin = 0x180, +- .havon_end = 0x5ff, +- .vavon_bline = 0x23, +- .vavon_eline = 0x382, +- /* eqpuls_begin */ +- /* eqpuls_end */ +- /* eqpuls_bline */ +- /* eqpuls_eline */ +- .hso_begin = 0, +- .hso_end = 0x80, +- .vso_begin = 0x1e, +- .vso_end = 0x32, +- .vso_bline = 0, +- .vso_eline = 3, +- .vso_eline_present = true, +- /* sy_val */ +- /* sy2_val */ +- .max_lncnt = 0x383, +- }, +-}; +- +-union meson_hdmi_venc_mode meson_hdmi_encp_mode_1280x1024_60 = { +- .encp = { +- .dvi_settings = 0x21, +- .video_mode = 0x4040, +- .video_mode_adv = 0x18, +- /* video_prog_mode */ +- /* video_sync_mode */ +- /* video_yc_dly */ +- /* video_rgb_ctrl */ +- /* video_filt_ctrl */ +- /* video_ofld_voav_ofst */ +- /* yfp1_htime */ +- /* yfp2_htime */ +- .max_pxcnt = 0x697, +- /* hspuls_begin */ +- /* hspuls_end */ +- /* hspuls_switch */ +- /* vspuls_begin */ +- /* vspuls_end */ +- /* vspuls_bline */ +- /* vspuls_eline */ +- .havon_begin = 0x168, +- .havon_end = 0x667, +- .vavon_bline = 0x29, +- .vavon_eline = 0x428, +- /* eqpuls_begin */ +- /* eqpuls_end */ +- /* eqpuls_bline */ +- /* eqpuls_eline */ +- .hso_begin = 0, +- .hso_end = 0x70, +- .vso_begin = 0x1e, +- .vso_end = 0x32, +- .vso_bline = 0, +- .vso_eline = 3, +- .vso_eline_present = true, +- /* sy_val */ +- /* sy2_val */ +- .max_lncnt = 0x429, +- }, +-}; +- +-union meson_hdmi_venc_mode meson_hdmi_encp_mode_1600x1200_60 = { +- .encp = { +- .dvi_settings = 0x21, +- .video_mode = 0x4040, +- .video_mode_adv = 0x18, +- /* video_prog_mode */ +- /* video_sync_mode */ +- /* video_yc_dly */ +- /* video_rgb_ctrl */ +- /* video_filt_ctrl */ +- /* video_ofld_voav_ofst */ +- /* yfp1_htime */ +- /* yfp2_htime */ +- .max_pxcnt = 0x86f, +- /* hspuls_begin */ +- /* hspuls_end */ +- /* hspuls_switch */ +- /* vspuls_begin */ +- /* vspuls_end */ +- /* vspuls_bline */ +- /* vspuls_eline */ +- .havon_begin = 0x1f0, +- .havon_end = 0x82f, +- .vavon_bline = 0x31, +- .vavon_eline = 0x4e0, +- /* eqpuls_begin */ +- /* eqpuls_end */ +- /* eqpuls_bline */ +- /* eqpuls_eline */ +- .hso_begin = 0, +- .hso_end = 0xc0, +- .vso_begin = 0x1e, +- .vso_end = 0x32, +- .vso_bline = 0, +- .vso_eline = 3, +- .vso_eline_present = true, +- /* sy_val */ +- /* sy2_val */ +- .max_lncnt = 0x4e1, +- }, +-}; +- + struct meson_hdmi_venc_dmt_mode { + struct drm_display_mode drm_mode; + union meson_hdmi_venc_mode *mode; +@@ -958,49 +706,42 @@ struct meson_hdmi_venc_dmt_mode { + { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25175, 640, 656, + 752, 800, 0, 480, 490, 492, 525, 0, + DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, +- &meson_hdmi_encp_mode_640x480_60, + }, + /* 800x600@60Hz */ + { + { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 40000, 800, 840, + 968, 1056, 0, 600, 601, 605, 628, 0, + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, +- &meson_hdmi_encp_mode_800x600_60, + }, + /* 1024x768@60Hz */ + { + { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 65000, 1024, + 1048, 1184, 1344, 0, 768, 771, 777, 806, 0, + DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, +- &meson_hdmi_encp_mode_1024x768_60, + }, + /* 1152x864@75Hz */ + { + { DRM_MODE("1152x864", DRM_MODE_TYPE_DRIVER, 108000, 1152, + 1216, 1344, 1600, 0, 864, 865, 868, 900, 0, + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, +- &meson_hdmi_encp_mode_1152x864_75, + }, + /* 1280x1024@60Hz */ + { + { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 108000, 1280, + 1328, 1440, 1688, 0, 1024, 1025, 1028, 1066, 0, + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, +- &meson_hdmi_encp_mode_1280x1024_60, + }, + /* 1600x1200@60Hz */ + { + { DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 162000, 1600, + 1664, 1856, 2160, 0, 1200, 1201, 1204, 1250, 0, + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, +- &meson_hdmi_encp_mode_1600x1200_60, + }, + /* 1920x1080@60Hz */ + { + { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, + 2008, 2052, 2200, 0, 1080, 1084, 1089, 1125, 0, + DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, +- &meson_hdmi_encp_mode_1080p60 + }, + { }, /* sentinel */ + }; +@@ -1044,17 +785,20 @@ static unsigned long modulo(unsigned long a, unsigned long b) + return a; + } + +-bool meson_venc_hdmi_supported_mode(const struct drm_display_mode *mode) ++enum drm_mode_status ++meson_venc_hdmi_supported_mode(const struct drm_display_mode *mode) + { +- struct meson_hdmi_venc_dmt_mode *vmode = meson_hdmi_venc_dmt_modes; ++ if (mode->flags & ~(DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NHSYNC | ++ DRM_MODE_FLAG_PVSYNC | DRM_MODE_FLAG_NVSYNC)) ++ return MODE_BAD; + +- while (vmode->mode) { +- if (drm_mode_equal(&vmode->drm_mode, mode)) +- return true; +- vmode++; +- } ++ if (mode->hdisplay < 640 || mode->hdisplay > 1920) ++ return MODE_BAD_HVALUE; + +- return false; ++ if (mode->vdisplay < 480 || mode->vdisplay > 1200) ++ return MODE_BAD_VVALUE; ++ ++ return MODE_OK; + } + EXPORT_SYMBOL_GPL(meson_venc_hdmi_supported_mode); + +@@ -1072,18 +816,29 @@ bool meson_venc_hdmi_supported_vic(int vic) + } + EXPORT_SYMBOL_GPL(meson_venc_hdmi_supported_vic); + +-static union meson_hdmi_venc_mode +-*meson_venc_hdmi_get_dmt_vmode(const struct drm_display_mode *mode) ++void meson_venc_hdmi_get_dmt_vmode(const struct drm_display_mode *mode, ++ union meson_hdmi_venc_mode *dmt_mode) + { +- struct meson_hdmi_venc_dmt_mode *vmode = meson_hdmi_venc_dmt_modes; +- +- while (vmode->mode) { +- if (drm_mode_equal(&vmode->drm_mode, mode)) +- return vmode->mode; +- vmode++; +- } +- +- return NULL; ++ memset(dmt_mode, 0, sizeof(*dmt_mode)); ++ ++ dmt_mode->encp.dvi_settings = 0x21; ++ dmt_mode->encp.video_mode = 0x4040; ++ dmt_mode->encp.video_mode_adv = 0x18; ++ dmt_mode->encp.max_pxcnt = mode->htotal - 1; ++ dmt_mode->encp.havon_begin = mode->htotal - mode->hsync_start; ++ dmt_mode->encp.havon_end = dmt_mode->encp.havon_begin + ++ mode->hdisplay - 1; ++ dmt_mode->encp.vavon_bline = mode->vtotal - mode->vsync_start; ++ dmt_mode->encp.vavon_eline = dmt_mode->encp.vavon_bline + ++ mode->vdisplay - 1; ++ dmt_mode->encp.hso_begin = 0; ++ dmt_mode->encp.hso_end = mode->hsync_end - mode->hsync_start; ++ dmt_mode->encp.vso_begin = 30; ++ dmt_mode->encp.vso_end = 50; ++ dmt_mode->encp.vso_bline = 0; ++ dmt_mode->encp.vso_eline = mode->vsync_end - mode->vsync_start; ++ dmt_mode->encp.vso_eline_present = true; ++ dmt_mode->encp.max_lncnt = mode->vtotal - 1; + } + + static union meson_hdmi_venc_mode *meson_venc_hdmi_get_vic_vmode(int vic) +@@ -1120,6 +875,7 @@ void meson_venc_hdmi_mode_set(struct meson_drm *priv, int vic, + struct drm_display_mode *mode) + { + union meson_hdmi_venc_mode *vmode = NULL; ++ union meson_hdmi_venc_mode vmode_dmt; + bool use_enci = false; + bool venc_repeat = false; + bool hdmi_repeat = false; +@@ -1147,14 +903,18 @@ void meson_venc_hdmi_mode_set(struct meson_drm *priv, int vic, + unsigned int sof_lines; + unsigned int vsync_lines; + +- if (meson_venc_hdmi_supported_vic(vic)) ++ if (meson_venc_hdmi_supported_vic(vic)) { + vmode = meson_venc_hdmi_get_vic_vmode(vic); +- else +- vmode = meson_venc_hdmi_get_dmt_vmode(mode); +- if (!vmode) { +- dev_err(priv->dev, "%s: Fatal Error, unsupported mode " +- DRM_MODE_FMT "\n", __func__, DRM_MODE_ARG(mode)); +- return; ++ if (!vmode) { ++ dev_err(priv->dev, "%s: Fatal Error, unsupported mode " ++ DRM_MODE_FMT "\n", __func__, ++ DRM_MODE_ARG(mode)); ++ return; ++ } ++ } ++ else { ++ meson_venc_hdmi_get_dmt_vmode(mode, &vmode_dmt); ++ vmode = &vmode_dmt; + } + + /* Use VENCI for 480i and 576i and double HDMI pixels */ +diff --git a/drivers/gpu/drm/meson/meson_venc.h b/drivers/gpu/drm/meson/meson_venc.h +index 7c18a36a0dd0c..97eaebbfa0c4a 100644 +--- a/drivers/gpu/drm/meson/meson_venc.h ++++ b/drivers/gpu/drm/meson/meson_venc.h +@@ -58,7 +58,8 @@ struct meson_cvbs_enci_mode { + }; + + /* HDMI Clock parameters */ +-bool meson_venc_hdmi_supported_mode(const struct drm_display_mode *mode); ++enum drm_mode_status ++meson_venc_hdmi_supported_mode(const struct drm_display_mode *mode); + bool meson_venc_hdmi_supported_vic(int vic); + bool meson_venc_hdmi_venc_repeat(int vic); + diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/069_linux-4.17-amlogic-dmt-extended-1001-fix-32000khz.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/069_linux-4.17-amlogic-dmt-extended-1001-fix-32000khz.patch new file mode 100644 index 000000000..a359376a7 --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/069_linux-4.17-amlogic-dmt-extended-1001-fix-32000khz.patch @@ -0,0 +1,119 @@ +diff -ur a/drivers/gpu/drm/meson/meson_vclk.c b/drivers/gpu/drm/meson/meson_vclk.c +--- a/drivers/gpu/drm/meson/meson_vclk.c 2018-06-02 20:21:48.000000000 +0200 ++++ b/drivers/gpu/drm/meson/meson_vclk.c 2018-06-02 20:16:44.008061996 +0200 +@@ -428,9 +428,9 @@ + .vclk_div = 2, + }, + [MESON_VCLK_HDMI_32000] = { +- .pll_base_freq = 2560000, ++ .pll_base_freq = 5120000, + .pll_od1 = 4, +- .pll_od2 = 2, ++ .pll_od2 = 4, + .pll_od3 = 1, + .vid_pll_div = VID_PLL_DIV_5, + .vclk_div = 2, +@@ -520,27 +520,6 @@ + + if (meson_vpu_is_compatible(priv, "amlogic,meson-gxbb-vpu")) { + switch (base) { +- case 2560000: +- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x58000235); +- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x00000000); +- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x0d5c5091); +- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x801da72c); +- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x71486980); +- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x00000e55); +- +- /* Enable and unreset */ +- regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL, +- 0x7 << 28, 0x4 << 28); +- +- /* Poll for lock bit */ +- regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL, +- val, (val & HDMI_PLL_LOCK), 10, 0); +- +- /* div_frac */ +- regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2, +- 0xFFFF, 0x4555); +- break; +- + case 2700000: + regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x58000238); + regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x00000000); +@@ -722,6 +701,27 @@ + val, (val & HDMI_PLL_LOCK), 10, 0); + break; + ++ case 5120000: ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x5800026a); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x00000000); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x135c5091); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x801da72c); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x71486980); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x00000e55); ++ ++ /* unreset */ ++ regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL, ++ BIT(28), 0); ++ ++ /* Poll for lock bit */ ++ regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL, ++ val, (val & HDMI_PLL_LOCK), 10, 0); ++ ++ /* div_frac */ ++ regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2, ++ 0xFFFF, 0x4aab); ++ break; ++ + case 5940000: + regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x5800027b); + regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2, +@@ -760,15 +760,6 @@ + } else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu") || + meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu")) { + switch (base) { +- case 2560000: +- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x4000026a); +- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb2ab); +- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x860f30c4); +- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x0c8e0000); +- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x001fa729); +- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500); +- break; +- + case 2700000: + regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x40000270); + regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb200); +@@ -847,6 +838,15 @@ + regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x860f30c4); + regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x0c8e0000); + regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x001fa729); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500); ++ break; ++ ++ case 5120000: ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x400002d5); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb155); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x860f30c4); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x0c8e0000); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x001fa729); + regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500); + break; + +diff -ur a/drivers/gpu/drm/meson/meson_venc.c b/drivers/gpu/drm/meson/meson_venc.c +--- a/drivers/gpu/drm/meson/meson_venc.c 2018-06-02 16:39:27.777402009 +0200 ++++ b/drivers/gpu/drm/meson/meson_venc.c 2018-06-02 20:23:23.744646670 +0200 +@@ -713,6 +713,12 @@ + 968, 1056, 0, 600, 601, 605, 628, 0, + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, + }, ++ /* 1024x600@43Hz */ ++ { ++ { DRM_MODE("1024x600", DRM_MODE_TYPE_DRIVER, 32000, 1024, ++ 1064, 1112, 1152, 0, 600, 613, 616, 645, 0, ++ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, ++ }, + /* 1024x768@60Hz */ + { + { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 65000, 1024, diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/070_linux-4.17-amlogic-dmt-extended-1002-custom-mode.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/070_linux-4.17-amlogic-dmt-extended-1002-custom-mode.patch new file mode 100644 index 000000000..97136bd0c --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/070_linux-4.17-amlogic-dmt-extended-1002-custom-mode.patch @@ -0,0 +1,547 @@ +diff -ur a/drivers/gpu/drm/meson/meson_dw_hdmi.c b/drivers/gpu/drm/meson/meson_dw_hdmi.c +--- a/drivers/gpu/drm/meson/meson_dw_hdmi.c 2018-06-02 16:39:27.777402009 +0200 ++++ b/drivers/gpu/drm/meson/meson_dw_hdmi.c 2018-06-02 17:25:33.803332054 +0200 +@@ -588,22 +588,28 @@ + /* Finally filter by configurable vclk frequencies */ + switch (vclk_freq) { + case 25175: +- case 40000: ++ case 29750: + case 32000: + case 36000: + case 33750: + case 33900: ++ case 40000: + case 54000: + case 65000: + case 74250: ++ case 106500: + case 108000: + case 148500: + case 162000: ++ case 193250: + case 297000: + case 594000: + return MODE_OK; + } + ++ if (meson_vclk_supported(vclk_freq)) ++ return MODE_OK; ++ + return MODE_CLOCK_RANGE; + } + +diff -ur a/drivers/gpu/drm/meson/meson_vclk.c b/drivers/gpu/drm/meson/meson_vclk.c +--- a/drivers/gpu/drm/meson/meson_vclk.c 2018-06-02 20:16:44.008061996 +0200 ++++ b/drivers/gpu/drm/meson/meson_vclk.c 2018-06-04 03:26:22.092619417 +0200 +@@ -321,39 +321,49 @@ + } + + +-/* PLL O1 O2 O3 VP DV EN TX */ +-/* 4320 /4 /4 /1 /5 /1 => /2 /2 */ +-#define MESON_VCLK_HDMI_ENCI_54000 1 +-/* 4320 /4 /4 /1 /5 /1 => /1 /2 */ +-#define MESON_VCLK_HDMI_DDR_54000 2 +-/* 2970 /4 /1 /1 /5 /1 => /1 /2 */ +-#define MESON_VCLK_HDMI_DDR_148500 3 +-/* 4028 /4 /4 /1 /5 /2 => /1 /1 */ +-#define MESON_VCLK_HDMI_25175 4 +-/* 2560 /4 /2 /1 /5 /2 => /1 /1 */ +-#define MESON_VCLK_HDMI_32000 5 +-/* 2700 /4 /2 /1 /5 /2 => /1 /1 */ +-#define MESON_VCLK_HDMI_33750 6 +-/* 2712 /4 /2 /1 /5 /2 => /1 /1 */ +-#define MESON_VCLK_HDMI_33900 7 +-/* 2880 /4 /2 /1 /5 /2 => /1 /1 */ +-#define MESON_VCLK_HDMI_36000 8 +-/* 3200 /4 /2 /1 /5 /2 => /1 /1 */ +-#define MESON_VCLK_HDMI_40000 9 +-/* 5200 /4 /2 /1 /5 /2 => /1 /1 */ +-#define MESON_VCLK_HDMI_65000 10 +-/* 2970 /2 /2 /2 /5 /1 => /1 /1 */ +-#define MESON_VCLK_HDMI_74250 11 +-/* 4320 /4 /1 /1 /5 /2 => /1 /1 */ +-#define MESON_VCLK_HDMI_108000 12 +-/* 2970 /1 /2 /2 /5 /1 => /1 /1 */ +-#define MESON_VCLK_HDMI_148500 13 +-/* 3240 /2 /1 /1 /5 /2 => /1 /1 */ +-#define MESON_VCLK_HDMI_162000 14 +-/* 2970 /1 /1 /1 /5 /2 => /1 /1 */ +-#define MESON_VCLK_HDMI_297000 15 +-/* 5940 /1 /1 /2 /5 /1 => /1 /1 */ +-#define MESON_VCLK_HDMI_594000 16 ++enum { ++ /* PLL O1 O2 O3 VP DV EN TX */ ++ /* 4320 /4 /4 /1 /5 /1 => /2 /2 */ ++ MESON_VCLK_HDMI_ENCI_54000 = 1, ++ /* 4320 /4 /4 /1 /5 /1 => /1 /2 */ ++ MESON_VCLK_HDMI_DDR_54000, ++ /* 2970 /4 /1 /1 /5 /1 => /1 /2 */ ++ MESON_VCLK_HDMI_DDR_148500, ++ /* 4028 /4 /4 /1 /5 /2 => /1 /1 */ ++ MESON_VCLK_HDMI_25175, ++ /* 4760 /4 /4 /1 /5 /2 => /1 /1 */ ++ MESON_VCLK_HDMI_29750, ++ /* 2560 /4 /2 /1 /5 /2 => /1 /1 */ ++ MESON_VCLK_HDMI_32000, ++ /* 2700 /4 /2 /1 /5 /2 => /1 /1 */ ++ MESON_VCLK_HDMI_33750, ++ /* 2712 /4 /2 /1 /5 /2 => /1 /1 */ ++ MESON_VCLK_HDMI_33900, ++ /* 2880 /4 /2 /1 /5 /2 => /1 /1 */ ++ MESON_VCLK_HDMI_36000, ++ /* 3200 /4 /2 /1 /5 /2 => /1 /1 */ ++ MESON_VCLK_HDMI_40000, ++ /* 5200 /4 /2 /1 /5 /2 => /1 /1 */ ++ MESON_VCLK_HDMI_65000, ++ /* 2970 /2 /2 /2 /5 /1 => /1 /1 */ ++ MESON_VCLK_HDMI_74250, ++ /* 4260 /4 /1 /1 /5 /2 => /1 /1 */ ++ MESON_VCLK_HDMI_106500, ++ /* 4320 /4 /1 /1 /5 /2 => /1 /1 */ ++ MESON_VCLK_HDMI_108000, ++ /* 2970 /1 /2 /2 /5 /1 => /1 /1 */ ++ MESON_VCLK_HDMI_148500, ++ /* 3240 /2 /1 /1 /5 /2 => /1 /1 */ ++ MESON_VCLK_HDMI_162000, ++ /* 3865 /2 /1 /1 /5 /2 => /1 /1 */ ++ MESON_VCLK_HDMI_193250, ++ /* 2970 /1 /1 /1 /5 /2 => /1 /1 */ ++ MESON_VCLK_HDMI_297000, ++ /* 5940 /1 /1 /2 /5 /1 => /1 /1 */ ++ MESON_VCLK_HDMI_594000, ++ /* custom calculated mode */ ++ MESON_VCLK_HDMI_CUSTOM, ++}; + + struct meson_vclk_params { + unsigned int pll_base_freq; +@@ -427,6 +437,14 @@ + .vid_pll_div = VID_PLL_DIV_5, + .vclk_div = 2, + }, ++ [MESON_VCLK_HDMI_29750] = { ++ .pll_base_freq = 4760000, ++ .pll_od1 = 4, ++ .pll_od2 = 4, ++ .pll_od3 = 1, ++ .vid_pll_div = VID_PLL_DIV_5, ++ .vclk_div = 2, ++ }, + [MESON_VCLK_HDMI_32000] = { + .pll_base_freq = 5120000, + .pll_od1 = 4, +@@ -475,6 +493,14 @@ + .vid_pll_div = VID_PLL_DIV_5, + .vclk_div = 2, + }, ++ [MESON_VCLK_HDMI_106500] = { ++ .pll_base_freq = 4260000, ++ .pll_od1 = 4, ++ .pll_od2 = 1, ++ .pll_od3 = 1, ++ .vid_pll_div = VID_PLL_DIV_5, ++ .vclk_div = 2, ++ }, + [MESON_VCLK_HDMI_108000] = { + .pll_base_freq = 4320000, + .pll_od1 = 4, +@@ -491,6 +517,14 @@ + .vid_pll_div = VID_PLL_DIV_5, + .vclk_div = 2, + }, ++ [MESON_VCLK_HDMI_193250] = { ++ .pll_base_freq = 3865000, ++ .pll_od1 = 2, ++ .pll_od2 = 1, ++ .pll_od3 = 1, ++ .vid_pll_div = VID_PLL_DIV_5, ++ .vclk_div = 2, ++ }, + }; + + static inline unsigned int pll_od_to_reg(unsigned int od) +@@ -519,6 +553,18 @@ + unsigned int val; + + if (meson_vpu_is_compatible(priv, "amlogic,meson-gxbb-vpu")) { ++ unsigned int step = 48000; ++ unsigned int range = 0x1000; ++ unsigned int round = step / range / 2; ++ unsigned int frac = base % step; ++ unsigned int m = (base - frac) / step; ++ ++ frac = (frac + round) * range / step; ++ if (frac >= range) ++ frac = range-1; ++ ++ dev_info(priv->dev, "%s: base=%d, m=0x%.2x, frac=0x%.3x\n", __func__, base, m, frac); ++ + switch (base) { + case 2700000: + regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x58000238); +@@ -755,10 +801,49 @@ + /* Poll for lock bit */ + regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL, + val, (val & HDMI_PLL_LOCK), 10, 0); ++ ++ /* div_frac */ ++ regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2, ++ 0xFFFF, 0x4555); ++ break; ++ ++ default: ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x58000200 | m); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x00000000); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x135c5091); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x801da72c); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x71486980); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x00000e55); ++ ++ /* unreset */ ++ regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL, ++ BIT(28), 0); ++ ++ /* Poll for lock bit */ ++ regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL, ++ val, (val & HDMI_PLL_LOCK), 10, 0); ++ ++ /* div_frac */ ++ if (frac) ++ regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2, ++ 0xFFFF, 0x4000 | frac); + break; ++ + }; + } else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu") || + meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu")) { ++ unsigned int step = 24000; ++ unsigned int range = 0x400; ++ unsigned int round = step / range / 2; ++ unsigned int frac = base % step; ++ unsigned int m = (base - frac) / step; ++ ++ frac = (frac + round) * range / step; ++ if (frac >= range) ++ frac = range-1; ++ ++ pr_info("%s: base=%d, m=0x%.2x, frac=0x%.3x", __func__, base, m, frac); ++ + switch (base) { + case 2700000: + regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x40000270); +@@ -868,6 +953,14 @@ + regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500); + break; + ++ default: ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x40000200 | m); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb000 | frac); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x860f30c4); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x0c8e0000); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x001fa729); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500); ++ break; + }; + + /* Reset PLL */ +@@ -906,6 +999,151 @@ + 3 << 19, pll_od_to_reg(od3) << 19); + } + ++unsigned int meson_vclk_freq_from_params(struct meson_vclk_params* vclk_params) ++{ ++ unsigned int vclk_freq = vclk_params->pll_base_freq / ++ vclk_params->pll_od1 / vclk_params->pll_od2 / ++ vclk_params->pll_od3 / vclk_params->vclk_div; ++ ++ switch (vclk_params->vid_pll_div) { ++ case VID_PLL_DIV_2: ++ vclk_freq /= 2; ++ break; ++ case VID_PLL_DIV_2p5: ++ vclk_freq *= 4; ++ vclk_freq /= 10; ++ break; ++ case VID_PLL_DIV_3: ++ vclk_freq /= 3; ++ break; ++ case VID_PLL_DIV_3p5: ++ vclk_freq *= 2; ++ vclk_freq /= 7; ++ break; ++ case VID_PLL_DIV_3p75: ++ vclk_freq *= 4; ++ vclk_freq /= 15; ++ break; ++ case VID_PLL_DIV_4: ++ vclk_freq /= 4; ++ break; ++ case VID_PLL_DIV_5: ++ vclk_freq /= 5; ++ break; ++ case VID_PLL_DIV_6: ++ vclk_freq /= 6; ++ break; ++ case VID_PLL_DIV_6p25: ++ vclk_freq *= 8; ++ vclk_freq /= 50; ++ break; ++ case VID_PLL_DIV_7: ++ vclk_freq /= 7; ++ break; ++ case VID_PLL_DIV_7p5: ++ vclk_freq *= 4; ++ vclk_freq /= 30; ++ break; ++ case VID_PLL_DIV_12: ++ vclk_freq /= 12; ++ break; ++ case VID_PLL_DIV_14: ++ vclk_freq /= 14; ++ break; ++ case VID_PLL_DIV_15: ++ vclk_freq /= 15; ++ break; ++ default: ++ return 0; ++ } ++ ++ return vclk_freq; ++} ++ ++static bool meson_get_vclk_params(unsigned int freq, ++ struct meson_vclk_params* vclk_params) ++{ ++ unsigned int vclk_freq = freq; ++ unsigned int base_freq, od1_od2, od3_vpll_vclk; ++ int p, jit; ++ bool found = false; ++ ++ if ((vclk_freq < 13500) || (vclk_freq > 594000)) ++ return false; ++ ++ if (vclk_freq % 25 > 12) ++ vclk_freq += 25; ++ vclk_freq -= vclk_freq % 25; ++ ++ for (p = 1; p < sizeof(params) / sizeof(struct meson_vclk_params); p++) { ++ if (params[p].vid_pll_div != VID_PLL_DIV_5) ++ continue; ++ ++ od1_od2 = params[p].pll_od1 * params[p].pll_od2; ++ od3_vpll_vclk = params[p].pll_od3 * 5 * params[p].vclk_div; ++ ++ if ((od3_vpll_vclk != 10) && (vclk_freq > 54000 + 175)) ++ continue; ++ ++ base_freq = vclk_freq * od1_od2 * od3_vpll_vclk; ++ ++ if ((base_freq < 2700000) || (base_freq > 5940000)) ++ continue; ++ ++ vclk_params->pll_base_freq = base_freq; ++ vclk_params->pll_od1 = params[p].pll_od1; ++ vclk_params->pll_od2 = params[p].pll_od2; ++ vclk_params->pll_od3 = params[p].pll_od3; ++ vclk_params->vid_pll_div = params[p].vid_pll_div; ++ vclk_params->vclk_div = params[p].vclk_div; ++ ++ found = true; ++ ++ if (params[p].pll_base_freq > vclk_params->pll_base_freq) ++ jit = params[p].pll_base_freq - vclk_params->pll_base_freq; ++ else ++ jit = vclk_params->pll_base_freq - params[p].pll_base_freq; ++ ++ if (jit < 175 * od1_od2 * od3_vpll_vclk) { ++ vclk_params->pll_base_freq = params[p].pll_base_freq; ++ vclk_freq = vclk_params->pll_base_freq / od1_od2 / od3_vpll_vclk; ++ } ++ ++ if (jit < 40000) ++ break; ++ } ++ ++ return found; ++} ++ ++static void meson_print_vclk_params(struct meson_drm *priv, unsigned int freq, ++ struct meson_vclk_params* vclk_params) ++{ ++ unsigned int vclk_freq = meson_vclk_freq_from_params(vclk_params); ++ ++ if (vclk_params->vid_pll_div != VID_PLL_DIV_5) ++ return; ++ ++ if (vclk_freq != freq) ++ dev_info(priv->dev, "adjusted %d -> %d", freq, vclk_freq); ++ ++ dev_info(priv->dev, "params %d / %d / %d / %d / %d / %d = %d\n", ++ vclk_params->pll_base_freq, ++ vclk_params->pll_od1, ++ vclk_params->pll_od2, ++ vclk_params->pll_od3, ++ 5, vclk_params->vclk_div, ++ vclk_freq); ++} ++ ++bool meson_vclk_supported(unsigned int vclk_freq) ++{ ++ struct meson_vclk_params custom_params; ++ ++ return (meson_get_vclk_params(vclk_freq, &custom_params)); ++} ++EXPORT_SYMBOL_GPL(meson_vclk_supported); ++ + void meson_vclk_setup(struct meson_drm *priv, unsigned int target, + unsigned int vclk_freq, unsigned int venc_freq, + unsigned int dac_freq, bool hdmi_use_enci) +@@ -913,6 +1151,8 @@ + unsigned int freq; + unsigned int hdmi_tx_div; + unsigned int venc_div; ++ struct meson_vclk_params custom_params; ++ struct meson_vclk_params* vclk_params; + + if (target == MESON_VCLK_TARGET_CVBS) { + meson_venci_cvbs_clock_config(priv); +@@ -945,6 +1185,9 @@ + case 25175: + freq = MESON_VCLK_HDMI_25175; + break; ++ case 29750: ++ freq = MESON_VCLK_HDMI_29750; ++ break; + case 32000: + freq = MESON_VCLK_HDMI_32000; + break; +@@ -966,6 +1209,9 @@ + case 74250: + freq = MESON_VCLK_HDMI_74250; + break; ++ case 106500: ++ freq = MESON_VCLK_HDMI_106500; ++ break; + case 108000: + freq = MESON_VCLK_HDMI_108000; + break; +@@ -978,6 +1224,9 @@ + case 162000: + freq = MESON_VCLK_HDMI_162000; + break; ++ case 193250: ++ freq = MESON_VCLK_HDMI_193250; ++ break; + case 297000: + freq = MESON_VCLK_HDMI_297000; + break; +@@ -985,9 +1234,8 @@ + freq = MESON_VCLK_HDMI_594000; + break; + default: +- pr_err("Fatal Error, invalid HDMI vclk freq %d\n", +- vclk_freq); +- return; ++ freq = MESON_VCLK_HDMI_CUSTOM; ++ break; + } + + /* Set HDMI-TX sys clock */ +@@ -998,20 +1246,35 @@ + regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL, + CTS_HDMI_SYS_EN, CTS_HDMI_SYS_EN); + ++ vclk_params = NULL; ++ ++ if (freq != MESON_VCLK_HDMI_CUSTOM) ++ vclk_params = ¶ms[freq]; ++ else if (meson_get_vclk_params(vclk_freq, &custom_params)) ++ vclk_params = &custom_params; ++ ++ if (!vclk_params) { ++ pr_err("Fatal Error, invalid HDMI vclk freq %d\n", ++ vclk_freq); ++ return; ++ } ++ ++ meson_print_vclk_params(priv, vclk_freq, vclk_params); ++ + /* Set HDMI PLL rate */ +- meson_hdmi_pll_set(priv, params[freq].pll_base_freq, +- params[freq].pll_od1, +- params[freq].pll_od2, +- params[freq].pll_od3); ++ meson_hdmi_pll_set(priv, vclk_params->pll_base_freq, ++ vclk_params->pll_od1, ++ vclk_params->pll_od2, ++ vclk_params->pll_od3); + + /* Setup vid_pll divider */ +- meson_vid_pll_set(priv, params[freq].vid_pll_div); ++ meson_vid_pll_set(priv, vclk_params->vid_pll_div); + + /* Set VCLK div */ + regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL, + VCLK_SEL_MASK, 0); + regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV, +- VCLK_DIV_MASK, params[freq].vclk_div - 1); ++ VCLK_DIV_MASK, vclk_params->vclk_div - 1); + + /* Set HDMI-TX source */ + switch (hdmi_tx_div) { +diff -ur a/drivers/gpu/drm/meson/meson_vclk.h b/drivers/gpu/drm/meson/meson_vclk.h +--- a/drivers/gpu/drm/meson/meson_vclk.h 2018-05-26 22:29:37.112948771 +0200 ++++ b/drivers/gpu/drm/meson/meson_vclk.h 2018-05-31 05:15:53.342134304 +0200 +@@ -29,6 +29,8 @@ + /* 27MHz is the CVBS Pixel Clock */ + #define MESON_VCLK_CVBS 27000 + ++bool meson_vclk_supported(unsigned int vclk_freq); ++ + void meson_vclk_setup(struct meson_drm *priv, unsigned int target, + unsigned int vclk_freq, unsigned int venc_freq, + unsigned int dac_freq, bool hdmi_use_enci); +diff -ur a/drivers/gpu/drm/meson/meson_venc.c b/drivers/gpu/drm/meson/meson_venc.c +--- a/drivers/gpu/drm/meson/meson_venc.c 2018-06-02 20:23:23.744646670 +0200 ++++ b/drivers/gpu/drm/meson/meson_venc.c 2018-06-02 17:25:33.807332121 +0200 +@@ -707,6 +707,12 @@ + 752, 800, 0, 480, 490, 492, 525, 0, + DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, + }, ++ /* 800x480@60Hz */ ++ { ++ { DRM_MODE("800x480", DRM_MODE_TYPE_DRIVER, 29750, 800, 824, ++ 896, 992, 0, 480, 483, 490, 500, 0, ++ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, ++ }, + /* 800x600@60Hz */ + { + { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 40000, 800, 840, +@@ -737,6 +743,12 @@ + 1328, 1440, 1688, 0, 1024, 1025, 1028, 1066, 0, + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, + }, ++ /* 1440x900@60Hz */ ++ { ++ { DRM_MODE("1440x900", DRM_MODE_TYPE_DRIVER, 106500, 1440, ++ 1520, 1672, 1904, 0, 900, 903, 909, 934, 0, ++ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, ++ }, + /* 1600x1200@60Hz */ + { + { DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 162000, 1600, +@@ -749,6 +761,12 @@ + 2008, 2052, 2200, 0, 1080, 1084, 1089, 1125, 0, + DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, + }, ++ /* 1920x1200@60Hz */ ++ { ++ { DRM_MODE("1920x1200", DRM_MODE_TYPE_DRIVER, 193250, 1920, ++ 2056, 2256, 2592, 0, 1200, 1203, 1209, 1245, 0, ++ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, ++ }, + { }, /* sentinel */ + }; + diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/071_linux-4.17-amlogic-dmt-extended-1003-calculate-clock-dividers.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/071_linux-4.17-amlogic-dmt-extended-1003-calculate-clock-dividers.patch new file mode 100644 index 000000000..5dfcace64 --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/071_linux-4.17-amlogic-dmt-extended-1003-calculate-clock-dividers.patch @@ -0,0 +1,115 @@ +diff -u a/drivers/gpu/drm/meson/meson_vclk.c b/drivers/gpu/drm/meson/meson_vclk.c +--- a/drivers/gpu/drm/meson/meson_vclk.c 2018-06-10 06:10:59.071504595 +0200 ++++ b/drivers/gpu/drm/meson/meson_vclk.c 2018-06-10 05:33:51.347202114 +0200 +@@ -842,7 +842,7 @@ + if (frac >= range) + frac = range-1; + +- pr_info("%s: base=%d, m=0x%.2x, frac=0x%.3x", __func__, base, m, frac); ++ dev_info(priv->dev, "%s: base=%d, m=0x%.2x, frac=0x%.3x\n", __func__, base, m, frac); + + switch (base) { + case 2700000: +@@ -1065,25 +1065,36 @@ + { + unsigned int vclk_freq = freq; + unsigned int base_freq, od1_od2, od3_vpll_vclk; +- int p, jit; ++ int od1, od2, od3, p, jit; + bool found = false; + +- if ((vclk_freq < 13500) || (vclk_freq > 594000)) ++ if ((vclk_freq < 12000) || (vclk_freq > 594000)) + return false; + + if (vclk_freq % 25 > 12) + vclk_freq += 25; + vclk_freq -= vclk_freq % 25; + +- for (p = 1; p < sizeof(params) / sizeof(struct meson_vclk_params); p++) { +- if (params[p].vid_pll_div != VID_PLL_DIV_5) ++ for (p = 0; p < 6; p++) { ++ od1 = (1 << p); ++ od2 = 1; ++ od3 = 1; ++ ++ if ((vclk_freq > 18550) && (od1 > 16)) + continue; + +- od1_od2 = params[p].pll_od1 * params[p].pll_od2; +- od3_vpll_vclk = params[p].pll_od3 * 5 * params[p].vclk_div; ++ if (od1 > 16) { ++ od3 = od1 / 16; ++ od1 = 16; ++ } + +- if ((od3_vpll_vclk != 10) && (vclk_freq > 54000 + 175)) +- continue; ++ if (od1 > 4) { ++ od2 = od1 / 4; ++ od1 = 4; ++ } ++ ++ od1_od2 = od1 * od2; ++ od3_vpll_vclk = od3 * 5 * 2; + + base_freq = vclk_freq * od1_od2 * od3_vpll_vclk; + +@@ -1091,21 +1102,32 @@ + continue; + + vclk_params->pll_base_freq = base_freq; +- vclk_params->pll_od1 = params[p].pll_od1; +- vclk_params->pll_od2 = params[p].pll_od2; +- vclk_params->pll_od3 = params[p].pll_od3; +- vclk_params->vid_pll_div = params[p].vid_pll_div; +- vclk_params->vclk_div = params[p].vclk_div; ++ vclk_params->pll_od1 = od1; ++ vclk_params->pll_od2 = od2; ++ vclk_params->pll_od3 = od3; ++ vclk_params->vid_pll_div = VID_PLL_DIV_5; ++ vclk_params->vclk_div = 2; + + found = true; + +- if (params[p].pll_base_freq > vclk_params->pll_base_freq) +- jit = params[p].pll_base_freq - vclk_params->pll_base_freq; ++ jit = od1_od2 * od3_vpll_vclk * 125; ++ if (p < 3) ++ jit <<= (3-p); ++ ++ if ((base_freq % 24000) < (base_freq % jit)) ++ jit = 24000; ++ ++ if ((base_freq % jit) > (jit / 2)) ++ base_freq = base_freq+jit; ++ base_freq -= base_freq % jit; ++ ++ if (base_freq > vclk_params->pll_base_freq) ++ jit = base_freq - vclk_params->pll_base_freq; + else +- jit = vclk_params->pll_base_freq - params[p].pll_base_freq; ++ jit = vclk_params->pll_base_freq - base_freq; + + if (jit < 175 * od1_od2 * od3_vpll_vclk) { +- vclk_params->pll_base_freq = params[p].pll_base_freq; ++ vclk_params->pll_base_freq = base_freq; + vclk_freq = vclk_params->pll_base_freq / od1_od2 / od3_vpll_vclk; + } + +diff -u a/drivers/gpu/drm/meson/meson_venc.c b/drivers/gpu/drm/meson/meson_venc.c +--- a/drivers/gpu/drm/meson/meson_venc.c 2018-06-10 06:10:59.071504595 +0200 ++++ b/drivers/gpu/drm/meson/meson_venc.c 2018-06-10 05:26:59.995203463 +0200 +@@ -816,10 +816,10 @@ + DRM_MODE_FLAG_PVSYNC | DRM_MODE_FLAG_NVSYNC)) + return MODE_BAD; + +- if (mode->hdisplay < 640 || mode->hdisplay > 1920) ++ if (mode->hdisplay < 416 || mode->hdisplay > 1920) + return MODE_BAD_HVALUE; + +- if (mode->vdisplay < 480 || mode->vdisplay > 1200) ++ if (mode->vdisplay < 360 || mode->vdisplay > 1200) + return MODE_BAD_VVALUE; + + return MODE_OK; diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/072_linux-4.16.y-input_touchscreen-vu5-vu7plus.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/072_linux-4.16.y-input_touchscreen-vu5-vu7plus.patch new file mode 100644 index 000000000..3693d959d --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/072_linux-4.16.y-input_touchscreen-vu5-vu7plus.patch @@ -0,0 +1,1235 @@ +diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c +index e92b77fa5..53bdf9725 100644 +--- a/drivers/hid/hid-quirks.c ++++ b/drivers/hid/hid-quirks.c +@@ -869,6 +869,8 @@ static const struct hid_device_id hid_ignore_list[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_DPAD) }, + #endif + { HID_USB_DEVICE(USB_VENDOR_ID_YEALINK, USB_DEVICE_ID_YEALINK_P1K_P4K_B2K) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_ODROID, USB_DEVICE_ID_VU5) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_ODROID, USB_DEVICE_ID_VU7PLUS) }, + { } + }; + +diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h +index ff539c0b4..b09d5ea03 100644 +--- a/drivers/hid/hid-ids.h ++++ b/drivers/hid/hid-ids.h +@@ -1164,4 +1164,10 @@ + #define USB_VENDOR_ID_UGTIZER 0x2179 + #define USB_DEVICE_ID_UGTIZER_TABLET_GP0610 0x0053 + ++#define USB_DEVICE_ID_DWAV_MULTITOUCH 0x0005 ++ ++#define USB_VENDOR_ID_ODROID 0x16b4 ++#define USB_DEVICE_ID_VU5 0x0704 ++#define USB_DEVICE_ID_VU7PLUS 0x0705 ++ + #endif +diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig +index 64b30fe27..05e834eed 100644 +--- a/drivers/input/touchscreen/Kconfig ++++ b/drivers/input/touchscreen/Kconfig +@@ -1246,4 +1246,23 @@ config TOUCHSCREEN_ROHM_BU21023 + To compile this driver as a module, choose M here: the + module will be called bu21023_ts. + ++config TOUCHSCREEN_DWAV_USB_MT ++ tristate "D-WAV Scientific USB MultiTouch" ++ depends on USB_ARCH_HAS_HCD ++ select USB ++ help ++ Say Y here if you have a D-WAV Scientific USB(HID) based MultiTouch ++ controller. ++ ++ If unsure, say N. ++ ++ To compile this driver as a module, choose M here: the ++ module will be called dwav-usb-mt. ++ ++config TOUCHSCREEN_SX865X ++ tristate "Semtech multitouch resistive touchscreen" ++ depends on I2C ++ help ++ This enables support for Semtech multitouch resistive touchscreen. ++ + endif +diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile +index 850c15625..bc3f0e1d5 100644 +--- a/drivers/input/touchscreen/Makefile ++++ b/drivers/input/touchscreen/Makefile +@@ -104,3 +104,5 @@ obj-$(CONFIG_TOUCHSCREEN_ZET6223) += zet6223.o + obj-$(CONFIG_TOUCHSCREEN_ZFORCE) += zforce_ts.o + obj-$(CONFIG_TOUCHSCREEN_COLIBRI_VF50) += colibri-vf50-ts.o + obj-$(CONFIG_TOUCHSCREEN_ROHM_BU21023) += rohm_bu21023.o ++obj-$(CONFIG_TOUCHSCREEN_DWAV_USB_MT) += dwav-usb-mt.o ++obj-$(CONFIG_TOUCHSCREEN_SX865X) += sx865x.o +diff -urN a/drivers/input/touchscreen/dwav-usb-mt.c b/drivers/input/touchscreen/dwav-usb-mt.c +--- a/drivers/input/touchscreen/dwav-usb-mt.c 1970-01-01 01:00:00.000000000 +0100 ++++ b/drivers/input/touchscreen/dwav-usb-mt.c 2018-05-06 10:03:40.485939294 +0200 +@@ -0,0 +1,577 @@ ++/*------------------------------------------------------------------------- ++ ++ D-WAV Scientific USB(HID) MultiTouch Screen Driver(Based on usbtouchscreen.c) ++ Hardkernel : 2015/09/17 ++ ++-------------------------------------------------------------------------*/ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++/*-------------------------------------------------------------------------*/ ++#define USB_VENDOR_ID_DWAV 0x0eef /* 800 x 480, 7" DWAV touch */ ++#define USB_DEVICE_ID_VU7 0x0005 ++ ++#define USB_VENDOR_ID_ODROID 0x16b4 ++#define USB_DEVICE_ID_VU5 0x0704 ++#define USB_DEVICE_ID_VU7PLUS 0x0705 ++ ++enum { ++ ODROID_VU7 = 0, /* 800 x 480, 7" Touch */ ++ ODROID_VU5, /* 800 x 480, 5" Touch */ ++ ODROID_VU7PLUS, /* 1024 x 600, 7" Touch */ ++}; ++ ++/*-------------------------------------------------------------------------*/ ++struct usbtouch_device_info { ++ char name[64]; ++ int max_x; ++ int max_y; ++ int max_press; ++ int max_finger; ++}; ++ ++/*-------------------------------------------------------------------------*/ ++const struct usbtouch_device_info DEV_INFO[] = { ++ [ODROID_VU7] = { ++ .name = "ODROID VU7 MultiTouch(800x480)", ++ .max_x = 800, ++ .max_y = 480, ++ .max_press = 255, ++ .max_finger = 5, ++ }, ++ [ODROID_VU5] = { ++ .name = "ODROID VU5 MultiTouch(800x480)", ++ .max_x = 800, ++ .max_y = 480, ++ .max_press = 255, ++ .max_finger = 5, ++ }, ++ [ODROID_VU7PLUS] = { ++ .name = "ODROID VU7 Plus MultiTouch(1024x600)", ++ .max_x = 1024, ++ .max_y = 600, ++ .max_press = 255, ++ .max_finger = 5, ++ }, ++}; ++ ++/*-------------------------------------------------------------------------*/ ++static const struct usb_device_id dwav_usb_mt_devices[] = { ++ {USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_VU7), ++ .driver_info = ODROID_VU7}, ++ {USB_DEVICE(USB_VENDOR_ID_ODROID, USB_DEVICE_ID_VU5), ++ .driver_info = ODROID_VU5}, ++ {USB_DEVICE(USB_VENDOR_ID_ODROID, USB_DEVICE_ID_VU7PLUS), ++ .driver_info = ODROID_VU7PLUS}, ++ {} ++}; ++ ++/*-------------------------------------------------------------------------*/ ++struct dwav_raw { /* Total 25 bytes */ ++ unsigned char header; /* frame header 0xAA*/ ++ unsigned char press; ++ /* Touch flag (1:valid touch data, 0:touch finished) */ ++ unsigned short x1; /* 1st x */ ++ unsigned short y1; /* 1st y */ ++ unsigned char end; ++ /* 1st touch finish flags 0xBB, RPI only uses the first 7 bytes */ ++ unsigned char ids; /* touch ID(bit field) */ ++ unsigned short y2; ++ unsigned short x2; ++ unsigned short y3; ++ unsigned short x3; ++ unsigned short y4; ++ unsigned short x4; ++ unsigned short y5; ++ unsigned short x5; ++ unsigned char tail; /* frame end 0xCC */ ++}; ++ ++/*------------------------------------------------------------------------- ++ Touch Event type define ++-------------------------------------------------------------------------*/ ++#define TS_EVENT_UNKNOWN 0x00 ++#define TS_EVENT_PRESS 0x01 ++#define TS_EVENT_RELEASE 0x02 ++ ++struct finger_t { ++ unsigned int status; /* ts event type */ ++ unsigned int x; /* ts data x */ ++ unsigned int y; /* ts data y */ ++} __packed; ++ ++struct dwav_usb_mt { ++ char name[128], phys[64]; ++ ++ int dev_id; ++ /* for URB Data DMA */ ++ dma_addr_t data_dma; ++ unsigned char *data; ++ int data_size; ++ ++ struct urb *irq; ++ struct usb_interface *interface; ++ struct input_dev *input; ++ ++ struct finger_t *finger; ++}; ++ ++/*-------------------------------------------------------------------------*/ ++static void dwav_usb_mt_report(struct dwav_usb_mt *dwav_usb_mt) ++{ ++ int id, max_x, max_y, max_press, max_finger; ++ ++ max_x = DEV_INFO[dwav_usb_mt->dev_id].max_x; ++ max_y = DEV_INFO[dwav_usb_mt->dev_id].max_y; ++ max_press = DEV_INFO[dwav_usb_mt->dev_id].max_press; ++ max_finger = DEV_INFO[dwav_usb_mt->dev_id].max_finger; ++ ++ for (id = 0; id < max_finger; id++) { ++ ++ if (dwav_usb_mt->finger[id].status == TS_EVENT_UNKNOWN) ++ continue; ++ ++ if (dwav_usb_mt->finger[id].x >= max_x || ++ dwav_usb_mt->finger[id].y >= max_y) ++ continue; ++ ++ input_mt_slot(dwav_usb_mt->input, id); ++ ++ if (dwav_usb_mt->finger[id].status != TS_EVENT_RELEASE) { ++ input_mt_report_slot_state(dwav_usb_mt->input, ++ MT_TOOL_FINGER, true); ++ input_report_abs(dwav_usb_mt->input, ++ ABS_MT_POSITION_X, ++ dwav_usb_mt->finger[id].x); ++ input_report_abs(dwav_usb_mt->input, ++ ABS_MT_POSITION_Y, ++ dwav_usb_mt->finger[id].y); ++ input_report_abs(dwav_usb_mt->input, ++ ABS_MT_PRESSURE, ++ max_press); ++ } else { ++ input_mt_report_slot_state(dwav_usb_mt->input, ++ MT_TOOL_FINGER, false); ++ dwav_usb_mt->finger[id].status = TS_EVENT_UNKNOWN; ++ } ++ input_mt_report_pointer_emulation(dwav_usb_mt->input, true); ++ input_sync(dwav_usb_mt->input); ++ } ++} ++ ++/*-------------------------------------------------------------------------*/ ++static void dwav_usb_mt_process(struct dwav_usb_mt *dwav_usb_mt, ++ unsigned char *pkt, int len) ++{ ++ struct dwav_raw *dwav_raw = (struct dwav_raw *)pkt; ++ unsigned char bit_mask, cnt; ++ ++ for (cnt = 0, bit_mask = 0x01; ++ cnt < DEV_INFO[dwav_usb_mt->dev_id].max_finger; ++ cnt++, bit_mask <<= 1) { ++ if ((dwav_raw->ids & bit_mask) && dwav_raw->press) { ++ dwav_usb_mt->finger[cnt].status = TS_EVENT_PRESS; ++ switch (cnt) { ++ case 0: ++ dwav_usb_mt->finger[cnt].x ++ = cpu_to_be16(dwav_raw->x1); ++ dwav_usb_mt->finger[cnt].y ++ = cpu_to_be16(dwav_raw->y1); ++ break; ++ case 1: ++ dwav_usb_mt->finger[cnt].x ++ = cpu_to_be16(dwav_raw->x2); ++ dwav_usb_mt->finger[cnt].y ++ = cpu_to_be16(dwav_raw->y2); ++ break; ++ case 2: ++ dwav_usb_mt->finger[cnt].x ++ = cpu_to_be16(dwav_raw->x3); ++ dwav_usb_mt->finger[cnt].y ++ = cpu_to_be16(dwav_raw->y3); ++ break; ++ case 3: ++ dwav_usb_mt->finger[cnt].x ++ = cpu_to_be16(dwav_raw->x4); ++ dwav_usb_mt->finger[cnt].y ++ = cpu_to_be16(dwav_raw->y4); ++ break; ++ case 4: ++ dwav_usb_mt->finger[cnt].x ++ = cpu_to_be16(dwav_raw->x5); ++ dwav_usb_mt->finger[cnt].y ++ = cpu_to_be16(dwav_raw->y5); ++ break; ++ default: ++ break; ++ } ++ } else { ++ if (dwav_usb_mt->finger[cnt].status == TS_EVENT_PRESS) ++ dwav_usb_mt->finger[cnt].status ++ = TS_EVENT_RELEASE; ++ else ++ dwav_usb_mt->finger[cnt].status ++ = TS_EVENT_UNKNOWN; ++ } ++ } ++ dwav_usb_mt_report(dwav_usb_mt); ++} ++ ++/*-------------------------------------------------------------------------*/ ++static void dwav_usb_mt_irq(struct urb *urb) ++{ ++ struct dwav_usb_mt *dwav_usb_mt = urb->context; ++ struct device *dev = &dwav_usb_mt->interface->dev; ++ int retval; ++ ++ switch (urb->status) { ++ case 0: ++ /* success */ ++ break; ++ case -ETIME: ++ /* this urb is timing out */ ++ dev_dbg(dev, "%s - urb timed out - was the device unplugged?\n", ++ __func__); ++ return; ++ case -ECONNRESET: ++ case -ENOENT: ++ case -ESHUTDOWN: ++ case -EPIPE: ++ /* this urb is terminated, clean up */ ++ dev_dbg(dev, "%s - urb shutting down with status: %d\n", ++ __func__, urb->status); ++ return; ++ default: ++ dev_dbg(dev, "%s - nonzero urb status received: %d\n", ++ __func__, urb->status); ++ goto exit; ++ } ++ ++ dwav_usb_mt_process(dwav_usb_mt, dwav_usb_mt->data, urb->actual_length); ++ ++exit: ++ usb_mark_last_busy(interface_to_usbdev(dwav_usb_mt->interface)); ++ retval = usb_submit_urb(urb, GFP_ATOMIC); ++ if (retval) { ++ dev_err(dev, "%s - usb_submit_urb failed with result: %d\n", ++ __func__, retval); ++ } ++} ++ ++/*-------------------------------------------------------------------------*/ ++static int dwav_usb_mt_open(struct input_dev *input) ++{ ++ struct dwav_usb_mt *dwav_usb_mt = input_get_drvdata(input); ++ int r; ++ ++ dwav_usb_mt->irq->dev = interface_to_usbdev(dwav_usb_mt->interface); ++ ++ r = usb_autopm_get_interface(dwav_usb_mt->interface) ? -EIO : 0; ++ if (r < 0) ++ goto out; ++ ++ if (usb_submit_urb(dwav_usb_mt->irq, GFP_KERNEL)) { ++ r = -EIO; ++ goto out_put; ++ } ++ ++ dwav_usb_mt->interface->needs_remote_wakeup = 1; ++out_put: ++ usb_autopm_put_interface(dwav_usb_mt->interface); ++out: ++ return r; ++} ++ ++/*-------------------------------------------------------------------------*/ ++static void dwav_usb_mt_close(struct input_dev *input) ++{ ++ struct dwav_usb_mt *dwav_usb_mt = input_get_drvdata(input); ++ int r; ++ ++ usb_kill_urb(dwav_usb_mt->irq); ++ ++ r = usb_autopm_get_interface(dwav_usb_mt->interface); ++ ++ dwav_usb_mt->interface->needs_remote_wakeup = 0; ++ if (!r) ++ usb_autopm_put_interface(dwav_usb_mt->interface); ++} ++ ++/*-------------------------------------------------------------------------*/ ++static int dwav_usb_mt_suspend(struct usb_interface *intf, pm_message_t message) ++{ ++ struct dwav_usb_mt *dwav_usb_mt = usb_get_intfdata(intf); ++ ++ usb_kill_urb(dwav_usb_mt->irq); ++ ++ return 0; ++} ++ ++/*-------------------------------------------------------------------------*/ ++static int dwav_usb_mt_resume(struct usb_interface *intf) ++{ ++ struct dwav_usb_mt *dwav_usb_mt = usb_get_intfdata(intf); ++ struct input_dev *input = dwav_usb_mt->input; ++ int result = 0; ++ ++ mutex_lock(&input->mutex); ++ if (input->users) ++ result = usb_submit_urb(dwav_usb_mt->irq, GFP_NOIO); ++ mutex_unlock(&input->mutex); ++ ++ return result; ++} ++ ++/*-------------------------------------------------------------------------*/ ++static int dwav_usb_mt_reset_resume(struct usb_interface *intf) ++{ ++ struct dwav_usb_mt *dwav_usb_mt = usb_get_intfdata(intf); ++ struct input_dev *input = dwav_usb_mt->input; ++ int err = 0; ++ ++ /* restart IO if needed */ ++ mutex_lock(&input->mutex); ++ if (input->users) ++ err = usb_submit_urb(dwav_usb_mt->irq, GFP_NOIO); ++ mutex_unlock(&input->mutex); ++ ++ return err; ++} ++ ++/*-------------------------------------------------------------------------*/ ++static void dwav_usb_mt_free_buffers(struct usb_device *udev, ++ struct dwav_usb_mt *dwav_usb_mt) ++{ ++ usb_free_coherent(udev, dwav_usb_mt->data_size, ++ dwav_usb_mt->data, dwav_usb_mt->data_dma); ++} ++ ++/*-------------------------------------------------------------------------*/ ++static struct usb_endpoint_descriptor *dwav_usb_mt_get_input_endpoint( ++ struct usb_host_interface *interface) ++{ ++ int i; ++ ++ for (i = 0; i < interface->desc.bNumEndpoints; i++) { ++ if (usb_endpoint_dir_in(&interface->endpoint[i].desc)) ++ return &interface->endpoint[i].desc; ++ } ++ ++ return NULL; ++} ++ ++/*-------------------------------------------------------------------------*/ ++static int dwav_usb_mt_init(struct dwav_usb_mt *dwav_usb_mt, void *dev) ++{ ++ int err; ++ struct input_dev *input_dev = (struct input_dev *)dev; ++ ++ input_dev->name = dwav_usb_mt->name; ++ input_dev->phys = dwav_usb_mt->phys; ++ ++ input_set_drvdata(input_dev, dwav_usb_mt); ++ ++ input_dev->open = dwav_usb_mt_open; ++ input_dev->close = dwav_usb_mt_close; ++ ++ input_dev->id.bustype = BUS_USB; ++ ++ /* single touch */ ++ input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); ++ input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); ++ ++ input_set_abs_params(input_dev, ABS_X, 0, ++ DEV_INFO[dwav_usb_mt->dev_id].max_x, 0, 0); ++ input_set_abs_params(input_dev, ABS_Y, 0, ++ DEV_INFO[dwav_usb_mt->dev_id].max_y, 0, 0); ++ ++ /* multi touch */ ++ input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0, ++ DEV_INFO[dwav_usb_mt->dev_id].max_x, 0, 0); ++ input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, ++ DEV_INFO[dwav_usb_mt->dev_id].max_y, 0, 0); ++ input_mt_init_slots(input_dev, ++ DEV_INFO[dwav_usb_mt->dev_id].max_finger, 0); ++ ++ err = input_register_device(input_dev); ++ if (err) { ++ pr_err("%s - input_register_device failed, err: %d\n", ++ __func__, err); ++ return err; ++ } ++ ++ dwav_usb_mt->input = input_dev; ++ ++ return 0; ++} ++ ++/*-------------------------------------------------------------------------*/ ++static int dwav_usb_mt_probe(struct usb_interface *intf, ++ const struct usb_device_id *id) ++{ ++ struct dwav_usb_mt *dwav_usb_mt = NULL; ++ struct input_dev *input_dev = NULL; ++ struct usb_endpoint_descriptor *endpoint; ++ struct usb_device *udev = interface_to_usbdev(intf); ++ ++ int err = 0; ++ ++ endpoint = dwav_usb_mt_get_input_endpoint(intf->cur_altsetting); ++ if (!endpoint) ++ return -ENXIO; ++ ++ dwav_usb_mt = kzalloc(sizeof(struct dwav_usb_mt), GFP_KERNEL); ++ if (!dwav_usb_mt) ++ return -ENOMEM; ++ ++ dwav_usb_mt->dev_id = id->driver_info; ++ ++ dwav_usb_mt->finger = kzalloc(sizeof(struct finger_t) * ++ DEV_INFO[dwav_usb_mt->dev_id].max_finger, ++ GFP_KERNEL); ++ ++ if (!dwav_usb_mt->finger) ++ goto err_free_mem; ++ ++ input_dev = input_allocate_device(); ++ if (!input_dev) ++ goto err_free_mem; ++ ++ dwav_usb_mt->data_size = sizeof(struct dwav_raw); ++ dwav_usb_mt->data = usb_alloc_coherent(udev, dwav_usb_mt->data_size, ++ GFP_KERNEL, &dwav_usb_mt->data_dma); ++ if (!dwav_usb_mt->data) ++ goto err_free_mem; ++ ++ dwav_usb_mt->irq = usb_alloc_urb(0, GFP_KERNEL); ++ if (!dwav_usb_mt->irq) { ++ dev_dbg(&intf->dev, ++ "%s - usb_alloc_urb failed: usbtouch->irq\n", ++ __func__); ++ goto err_free_buffers; ++ } ++ ++ if (usb_endpoint_type(endpoint) == USB_ENDPOINT_XFER_INT) { ++ usb_fill_int_urb(dwav_usb_mt->irq, udev, ++ usb_rcvintpipe(udev, endpoint->bEndpointAddress), ++ dwav_usb_mt->data, dwav_usb_mt->data_size, ++ dwav_usb_mt_irq, dwav_usb_mt, endpoint->bInterval); ++ } else { ++ usb_fill_bulk_urb(dwav_usb_mt->irq, udev, ++ usb_rcvbulkpipe(udev, endpoint->bEndpointAddress), ++ dwav_usb_mt->data, dwav_usb_mt->data_size, ++ dwav_usb_mt_irq, dwav_usb_mt); ++ } ++ ++ dwav_usb_mt->irq->dev = udev; ++ dwav_usb_mt->irq->transfer_dma = dwav_usb_mt->data_dma; ++ dwav_usb_mt->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; ++ ++ dwav_usb_mt->interface = intf; ++ ++ if (udev->manufacturer) ++ strlcpy(dwav_usb_mt->name, ++ udev->manufacturer, sizeof(dwav_usb_mt->name)); ++ ++ if (udev->product) { ++ if (udev->manufacturer) ++ strlcat(dwav_usb_mt->name, ++ " ", sizeof(dwav_usb_mt->name)); ++ ++ strlcat(dwav_usb_mt->name, ++ udev->product, sizeof(dwav_usb_mt->name)); ++ } ++ ++ if (!strlen(dwav_usb_mt->name)) { ++ snprintf(dwav_usb_mt->name, sizeof(dwav_usb_mt->name), ++ "D-WAV Scientific MultiTouch %04x:%04x", ++ le16_to_cpu(udev->descriptor.idVendor), ++ le16_to_cpu(udev->descriptor.idProduct)); ++ } ++ ++ usb_make_path(udev, dwav_usb_mt->phys, sizeof(dwav_usb_mt->phys)); ++ strlcat(dwav_usb_mt->phys, "/input0", sizeof(dwav_usb_mt->phys)); ++ ++ usb_to_input_id(udev, &input_dev->id); ++ ++ input_dev->dev.parent = &intf->dev; ++ ++ err = dwav_usb_mt_init(dwav_usb_mt, (void *)input_dev); ++ if (err) ++ goto err_free_urb; ++ ++ usb_set_intfdata(intf, dwav_usb_mt); ++ ++ dev_info(&intf->dev, "%s\n", DEV_INFO[dwav_usb_mt->dev_id].name); ++ ++ return 0; ++ ++err_free_urb: ++ usb_free_urb(dwav_usb_mt->irq); ++ ++err_free_buffers: ++ dwav_usb_mt_free_buffers(udev, dwav_usb_mt); ++ ++err_free_mem: ++ if (input_dev) ++ input_free_device(input_dev); ++ kfree(dwav_usb_mt); ++ ++ return err; ++} ++ ++/*-------------------------------------------------------------------------*/ ++static void dwav_usb_mt_disconnect(struct usb_interface *intf) ++{ ++ struct dwav_usb_mt *dwav_usb_mt = usb_get_intfdata(intf); ++ ++ if (!dwav_usb_mt) ++ return; ++ ++ dev_dbg(&intf->dev, ++ "%s - dwav_usb_mt is initialized, cleaning up\n", ++ __func__); ++ ++ usb_set_intfdata(intf, NULL); ++ ++ /* this will stop IO via close */ ++ input_unregister_device(dwav_usb_mt->input); ++ ++ usb_free_urb(dwav_usb_mt->irq); ++ ++ dwav_usb_mt_free_buffers(interface_to_usbdev(intf), dwav_usb_mt); ++ ++ kfree(dwav_usb_mt); ++} ++ ++/*-------------------------------------------------------------------------*/ ++MODULE_DEVICE_TABLE(usb, dwav_usb_mt_devices); ++ ++static struct usb_driver dwav_usb_mt_driver = { ++ .name = "dwav_usb_mt", ++ .probe = dwav_usb_mt_probe, ++ .disconnect = dwav_usb_mt_disconnect, ++ .suspend = dwav_usb_mt_suspend, ++ .resume = dwav_usb_mt_resume, ++ .reset_resume = dwav_usb_mt_reset_resume, ++ .id_table = dwav_usb_mt_devices, ++ .supports_autosuspend = 1, ++}; ++ ++module_usb_driver(dwav_usb_mt_driver); ++ ++/*-------------------------------------------------------------------------*/ ++MODULE_AUTHOR("Hardkernel Co.,Ltd"); ++MODULE_DESCRIPTION("D-WAV USB(HID) MultiTouch Driver"); ++MODULE_LICENSE("GPL"); ++ ++MODULE_ALIAS("dwav_usb_mt"); ++/*-------------------------------------------------------------------------*/ +diff -urN a/drivers/input/touchscreen/sx865x.c b/drivers/input/touchscreen/sx865x.c +--- a/drivers/input/touchscreen/sx865x.c 1970-01-01 01:00:00.000000000 +0100 ++++ b/drivers/input/touchscreen/sx865x.c 2018-05-06 10:03:40.553940699 +0200 +@@ -0,0 +1,584 @@ ++/* ++ * drivers/input/touchscreen/sx865x.c ++ * ++ * Copyright (c) 2013 U-MoBo Srl ++ * Pierluigi Passaro ++ * ++ * Using code from: ++ * - sx8650.c ++ * Copyright (c) 2009 Wayne Roberts ++ * - tsc2007.c ++ * Copyright (c) 2008 Kwangwoo Lee ++ * - ads7846.c ++ * Copyright (c) 2005 David Brownell ++ * Copyright (c) 2006 Nokia Corporation ++ * - corgi_ts.c ++ * Copyright (C) 2004-2005 Richard Purdie ++ * - omap_ts.[hc], ads7846.h, ts_osk.c ++ * Copyright (C) 2002 MontaVista Software ++ * Copyright (C) 2004 Texas Instruments ++ * Copyright (C) 2005 Dirk Behme ++ * ++ * 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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#if defined(CONFIG_ARCH_MESON64_ODROIDC2) ++ ++#include ++#include ++ ++#define AMLGPIO_IRQ_BASE 96 ++ ++#endif ++ ++/* timeout expires after pen is lifted, no more PENIRQs comming */ ++/* adjust with POWDLY setting */ ++#define TS_TIMEOUT (8 * 1000000) ++ ++/* analog channels */ ++#define CH_X 0 ++#define CH_Y 1 ++#define CH_Z1 2 ++#define CH_Z2 3 ++#define CH_AUX 4 ++#define CH_RX 5 ++#define CH_RY 6 ++#define CH_SEQ 7 ++ ++/* commands */ ++#define SX865X_WRITE_REGISTER 0x00 ++#define SX865X_READ_REGISTER 0x40 ++#define SX865X_SELECT_CH(ch) (0x80 | ch) ++#define SX865X_CONVERT_CH(ch) (0x90 | ch) ++#define SX865X_POWDWN 0xb0 /* power down, ignore pen */ ++#define SX865X_PENDET 0xc0 /* " " with pen sensitivity */ ++#define SX865X_PENTRG 0xe0 /* " " " " and sample channels */ ++ ++/* register addresses */ ++#define I2C_REG_CTRL0 0x00 ++#define I2C_REG_CTRL1 0x01 ++#define I2C_REG_CTRL2 0x02 ++#define I2C_REG_CTRL3 0x03 ++#define I2C_REG_CHANMASK 0x04 ++#define I2C_REG_STAT 0x05 ++#define I2C_REG_SOFTRESET 0x1f ++ ++#define I2C_EXTENDED_REG_STAT 0x24 ++#define I2C_EXTENDED_REG_SOFTRESET 0x3f ++ ++#define SOFTRESET_VALUE 0xde ++ ++/* bits for I2C_REG_STAT */ ++/* I2C_REG_STAT: end of conversion flag */ ++#define STATUS_CONVIRQ 0x80 ++/* I2C_REG_STAT: pen detected */ ++#define STATUS_PENIRQ 0x40 ++ ++/* bits for I2C_EXTENDED_REG_STAT */ ++/* I2C_EXTENDED_REG_STAT: end of conversion flag */ ++#define EXTENDED_STATUS_CONVIRQ 0x08 ++/* I2C_EXTENDED_REG_STAT: pen detected */ ++#define EXTENDED_STATUS_PENIRQ 0x04 ++ ++/* sx865x bits for RegCtrl1 */ ++#define CONDIRQ 0x20 ++/* no averaging */ ++#define FILT_NONE 0x00 ++/* 3 sample averaging */ ++#define FILT_3SA 0x01 ++/* 5 sample averaging */ ++#define FILT_5SA 0x02 ++/* 7 samples, sort, then average of 3 middle samples */ ++#define FILT_7SA 0x03 ++ ++/* bits for register 2, I2CRegChanMsk */ ++#define CONV_X 0x80 ++#define CONV_Y 0x40 ++#define CONV_Z1 0x20 ++#define CONV_Z2 0x10 ++#define CONV_AUX 0x08 ++#define CONV_RX 0x04 ++#define CONV_RY 0x02 ++ ++/* power delay: lower nibble of CTRL0 register */ ++#define POWDLY_IMMEDIATE 0x00 ++#define POWDLY_1_1US 0x01 ++#define POWDLY_2_2US 0x02 ++#define POWDLY_4_4US 0x03 ++#define POWDLY_8_9US 0x04 ++#define POWDLY_17_8US 0x05 ++#define POWDLY_35_5US 0x06 ++#define POWDLY_71US 0x07 ++#define POWDLY_140US 0x08 ++#define POWDLY_280US 0x09 ++#define POWDLY_570US 0x0a ++#define POWDLY_1_1MS 0x0b ++#define POWDLY_2_3MS 0x0c ++#define POWDLY_4_6MS 0x0d ++#define POWDLY_9MS 0x0e ++#define POWDLY_18MS 0x0f ++ ++#define MAX_12BIT ((1 << 12) - 1) ++ ++/* when changing the channel mask, also change the read length appropriately */ ++#define CHAN_MASK (CONV_X | CONV_Y | CONV_Z1 | CONV_RX | CONV_RY) ++#define NUM_CHANNELS_SEQ 5 ++#define CHAN_READ_LENGTH (NUM_CHANNELS_SEQ * 2) ++ ++#define SX_MULTITOUCH 0x01 ++#define SX_PROXIMITY_SENSING 0x02 ++#define SX_HAPTICS_GENERIC 0x04 ++#define SX_HAPTICS_IMMERSION 0x08 ++#define SX_EXTENDED_REGS (SX_PROXIMITY_SENSING | SX_HAPTICS_GENERIC | SX_HAPTICS_IMMERSION) ++ ++#define SX865X_UP_SCANTIME_MS (100) ++#define SX865X_DOWN_SCANTIME_MS (20) ++ ++struct ts_event { ++ u16 x, y; ++ u16 z1; ++ u16 rx, ry; ++}; ++ ++struct sx865x { ++ struct input_dev *input; ++ struct ts_event tc; ++ ++ struct i2c_client *client; ++ ++ u32 invert_x; ++ u32 invert_y; ++ u32 swap_xy; ++ u32 gpio_pendown; ++ u32 gpio_reset; ++ ++#if defined(CONFIG_ARCH_MESON64_ODROIDC2) ++ int irq_bank; ++#endif ++ unsigned pendown; ++ int irq; ++}; ++ ++static struct i2c_device_id sx865x_idtable[] = { ++ { "sx8650", 0 }, ++ { } ++}; ++ ++MODULE_DEVICE_TABLE(i2c, sx865x_idtable); ++ ++static const struct of_device_id sx865x_of_match[] = { ++ { .compatible = "semtech,sx8650", .data = (void *)0 }, ++ {} ++}; ++ ++MODULE_DEVICE_TABLE(of, sx865x_of_match); ++ ++static void sx865x_send_event(struct sx865x *ts) ++{ ++ u32 rt; ++ u16 x, y, z1; ++ ++ x = ts->tc.x; ++ y = ts->tc.y; ++ z1 = ts->tc.z1; ++ ++ /* range filtering */ ++ if (y == MAX_12BIT) ++ y = 0; ++ ++ /* compute touch pressure resistance */ ++ if (likely(y && z1)) ++ rt = z1; ++ else ++ rt = 0; ++ ++ /* Sample found inconsistent by debouncing or pressure is beyond ++ * the maximum. Don't report it to user space, repeat at least ++ * once more the measurement ++ */ ++ if (rt > MAX_12BIT) { ++ dev_dbg(&ts->client->dev, "ignored pressure %d\n", rt); ++ return; ++ } ++ ++ /* NOTE: We can't rely on the pressure to determine the pen down ++ * state, even this controller has a pressure sensor. The pressure ++ * value can fluctuate for quite a while after lifting the pen and ++ * in some cases may not even settle at the expected value. ++ * ++ * The only safe way to check for the pen up condition is in the ++ * timer by reading the pen signal state (it's a GPIO _and_ IRQ). ++ */ ++ if (rt) { ++ struct input_dev *input = ts->input; ++ ++ if (ts->invert_x) x = (~x) & MAX_12BIT; ++ ++ if (ts->invert_y) y = (~y) & MAX_12BIT; ++ ++ if (ts->swap_xy) swap(x, y); ++ ++ if (!ts->pendown) { ++ dev_dbg(&ts->client->dev, "DOWN\n"); ++ ts->pendown = 1; ++ input_report_key(input, BTN_TOUCH, 1); ++ } ++ ++ input_report_abs(input, ABS_X, x); ++ input_report_abs(input, ABS_Y, y); ++ input_report_abs(input, ABS_PRESSURE, rt); ++ input_sync(input); ++ ++ dev_dbg(&ts->client->dev, "point(%4d,%4d), pressure (%4u)\n", ++ x, y, rt); ++ } ++} ++ ++static int sx865x_read_values(struct sx865x *ts) ++{ ++ s32 data; ++ u16 vals[NUM_CHANNELS_SEQ+1]; /* +1 for last dummy read */ ++ int length; ++ int i; ++ ++ memset(&(ts->tc), 0, sizeof(ts->tc)); ++ /* The protocol and raw data format from i2c interface: ++ * S Addr R A [DataLow] A [DataHigh] A (repeat) NA P ++ * Where DataLow has (channel | [D11-D8]), DataHigh has [D7-D0]. ++ */ ++ length = i2c_master_recv(ts->client, (char *)vals, CHAN_READ_LENGTH); ++ ++ if (likely(length == CHAN_READ_LENGTH)) { ++ length >>= 1; ++ for (i = 0; i < length; i++) { ++ u16 ch; ++ data = swab16(vals[i]); ++ if (unlikely(data & 0x8000)) { ++ dev_dbg(&ts->client->dev, ++ "hibit @ %d [0x%04x]\n", i, data); ++ continue; ++ } ++ ch = data >> 12; ++ if (ch == CH_X) { ++ ts->tc.x = data & 0xfff; ++ } else if (ch == CH_Y) { ++ ts->tc.y = data & 0xfff; ++ } else if (ch == CH_Z1) { ++ ts->tc.z1 = data & 0xfff; ++ } else if (ch == CH_RX) { ++ ts->tc.rx = data & 0xfff; ++ } else if (ch == CH_RY) { ++ ts->tc.ry = data & 0xfff; ++ } else { ++ dev_err(&ts->client->dev, "? CH%d %x\n", ++ ch, data & 0xfff); ++ } ++ } ++ } else { ++ dev_err(&ts->client->dev, "%d = recv()\n", length); ++ } ++ ++ dev_dbg(&ts->client->dev, "X:%03x Y:%03x Z1:%03x RX:%03x RY:%03x\n", ++ ts->tc.x, ts->tc.y, ts->tc.z1, ts->tc.rx, ts->tc.ry); ++ ++ return !ts->tc.z1; /* return 0 only if pressure not 0 */ ++} ++ ++static void sx865x_pen_up(struct sx865x *ts) ++{ ++ struct input_dev *input = ts->input; ++ ++ /* This timer expires after PENIRQs havent been coming in for some time. ++ * It means that the pen is now UP. */ ++ input_report_key(input, BTN_TOUCH, 0); ++ input_report_abs(input, ABS_PRESSURE, 0); ++ input_sync(input); ++ ++ ts->pendown = 0; ++ dev_dbg(&ts->client->dev, "UP\n"); ++} ++ ++static int sx865x_data_available(struct sx865x *ts) ++{ ++ u8 status; ++ ++ status = i2c_smbus_read_byte_data(ts->client, ++ (SX865X_READ_REGISTER | I2C_REG_STAT)); ++ return status & STATUS_CONVIRQ; ++} ++ ++static int get_pendown_status(struct sx865x *ts) ++{ ++ return gpio_get_value(ts->gpio_pendown) ? 0 : 1; ++} ++ ++static irqreturn_t sx865x_hw_irq(int irq, void *handle) ++{ ++ struct sx865x *ts = handle; ++ ++ return get_pendown_status(ts) ? IRQ_WAKE_THREAD : IRQ_HANDLED; ++} ++ ++static irqreturn_t sx865x_irq(int irq, void *handle) ++{ ++ struct sx865x *ts = handle; ++ ++ while (sx865x_data_available(ts)) { ++ /* valid data was read in */ ++ if (likely(sx865x_read_values(ts) == 0)) ++ sx865x_send_event(ts); ++ else ++ dev_dbg(&ts->client->dev, "data error!\n"); ++ ++ msleep(SX865X_DOWN_SCANTIME_MS); ++ } ++ ++ if (ts->pendown) ++ sx865x_pen_up(ts); ++ ++ return IRQ_HANDLED; ++} ++ ++static void sx865x_hw_reset(struct sx865x *ts) ++{ ++ gpio_direction_output(ts->gpio_reset, 0); ++ udelay(1000); ++ gpio_direction_output(ts->gpio_reset, 1); ++ udelay(1000); ++} ++ ++static int sx865x_dt_probe(struct i2c_client *client, struct sx865x *ts) ++{ ++ struct device_node *node = client->dev.of_node; ++ const struct of_device_id *match; ++ ++ if (!node) { ++ dev_err(&client->dev, ++ "Device dost not have associated DT data\n"); ++ return -EINVAL; ++ } ++ ++ match = of_match_device(sx865x_of_match, &client->dev); ++ if (!match) { ++ dev_err(&client->dev, ++ "Unknown device model\n"); ++ return -EINVAL; ++ } ++ ++ of_property_read_u32(node, "swap-xy", &ts->swap_xy); ++ of_property_read_u32(node, "invert-x", &ts->invert_x); ++ of_property_read_u32(node, "invert-y", &ts->invert_y); ++ ++ ts->gpio_pendown = of_get_named_gpio(node, "gpio-pendown", 0); ++ ts->gpio_reset = of_get_named_gpio(node, "gpio-reset", 0); ++ ++ if (gpio_request(ts->gpio_pendown, "ts-pendown")) ++ dev_err(&client->dev, ++ "gpio request fail (%d)!\n", ts->gpio_pendown); ++ else ++ gpio_direction_input(ts->gpio_pendown); ++ ++ if (gpio_request(ts->gpio_reset, "ts-reset")) ++ dev_err(&client->dev, ++ "gpio request fail (%d)!\n", ts->gpio_reset); ++ else ++ sx865x_hw_reset(ts); ++ ++#if defined(CONFIG_ARCH_MESON64_ODROIDC2) ++ /* irq setup */ ++ ts->irq_bank = meson_fix_irqbank(ts->irq_bank); ++ if (ts->irq_bank < 0) { ++ dev_err(&client->dev, ++ "Could not find irq bank!\n"); ++ return -EINVAL; ++ } ++ ++ { ++ int ret; ++ /* AMLogic gpio irq setup */ ++ ret = gpio_for_irq(ts->gpio_pendown, ++ AML_GPIO_IRQ(ts->irq_bank, FILTER_NUM7, GPIO_IRQ_FALLING)); ++ ++ if (ret) { ++ dev_err(&client->dev, ++ "AML_GPIO_IRQ setup fail!\n"); ++ return -EINVAL; ++ } ++ /* Amlogic gpio based irq setup */ ++ ts->irq = AMLGPIO_IRQ_BASE + ts->irq_bank; ++ } ++#else ++ ts->irq = gpio_to_irq(ts->gpio_pendown); ++ if (ts->irq < 0) ++ return -EINVAL; ++#endif ++ ++ /* platform data info display */ ++ dev_info(&client->dev, "swap_xy (%d)\n", ts->swap_xy); ++ dev_info(&client->dev, "invert_x (%d)\n", ts->invert_x); ++ dev_info(&client->dev, "invert_y (%d)\n", ts->invert_y); ++ dev_info(&client->dev, "gpio pendown (%d)\n", ts->gpio_pendown); ++ dev_info(&client->dev, "gpio reset (%d)\n", ts->gpio_reset); ++ dev_info(&client->dev, "gpio irq (%d)\n", ts->irq); ++ ++ return 0; ++} ++ ++#if defined(CONFIG_ARCH_MESON64_ODROIDC2) ++static void sx865x_irq_free(struct i2c_client *client, struct sx865x *ts) ++{ ++ int irq_banks[2]; ++ ++ meson_free_irq(gpio_to_irq(ts->gpio_pendown), &irq_banks[0]); ++ ++ /* rising irq bank */ ++ if (irq_banks[0] != -1) ++ free_irq(irq_banks[0] + AMLGPIO_IRQ_BASE, ts); ++ ++ /* falling irq bank */ ++ if (irq_banks[1] != -1) ++ free_irq(irq_banks[1] + AMLGPIO_IRQ_BASE, ts); ++} ++#endif ++ ++static int sx865x_probe(struct i2c_client *client, ++ const struct i2c_device_id *id) ++{ ++ struct sx865x *ts; ++ struct input_dev *input_dev; ++ int err = 0; ++ ++ dev_info(&client->dev, "sx865x_probe()\n"); ++ ++ if (!i2c_check_functionality(client->adapter, ++ I2C_FUNC_SMBUS_READ_WORD_DATA)) ++ return -EIO; ++ ++ ts = devm_kzalloc(&client->dev, sizeof(struct sx865x), GFP_KERNEL); ++ input_dev = devm_input_allocate_device(&client->dev); ++ if (!ts || !input_dev) ++ return -ENOMEM; ++ ++ if (sx865x_dt_probe(client, ts) != 0) ++ return -EIO; ++ ++ i2c_set_clientdata(client, ts); ++ ++ input_dev->name = "SX865X Touchscreen"; ++ input_dev->id.bustype = BUS_I2C; ++ input_dev->dev.parent = &client->dev; ++ input_set_drvdata(input_dev, ts); ++ ++ input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); ++ input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); ++ ++ input_set_abs_params(input_dev, ABS_X, 0, MAX_12BIT, 0, 0); ++ input_set_abs_params(input_dev, ABS_Y, 0, MAX_12BIT, 0, 0); ++ input_set_abs_params(input_dev, ABS_PRESSURE, 0, MAX_12BIT, 0, 0); ++ ++ /* soft reset: SX8650 fails to nak at the end, ignore return value */ ++ i2c_smbus_write_byte_data(client, I2C_REG_SOFTRESET, SOFTRESET_VALUE); ++ ++ /* set mask to convert X, Y, Z1, RX, RY for CH_SEQ */ ++ err = i2c_smbus_write_byte_data(client, I2C_REG_CHANMASK, CHAN_MASK); ++ if (err != 0) return -EIO; ++ ++ err = i2c_smbus_write_byte_data(client, I2C_REG_CTRL1, ++ CONDIRQ | FILT_7SA); ++ if (err != 0) return -EIO; ++ ++ /* set POWDLY settling time -- adjust TS_TIMEOUT accordingly */ ++ err = i2c_smbus_write_byte_data(client, I2C_REG_CTRL0, POWDLY_1_1MS); ++ if (err != 0) return -EIO; ++ ++ /* enter pen-trigger mode */ ++ err = i2c_smbus_write_byte(client, SX865X_PENTRG); ++ if (err != 0) return -EIO; ++ ++ err = request_threaded_irq(ts->irq, sx865x_hw_irq, sx865x_irq, ++ IRQF_ONESHOT, ++ client->dev.driver->name, ts); ++ ++ if (err < 0) { ++ dev_err(&client->dev, "irq %d busy?\n", ts->irq); ++ return -EIO; ++ } ++ ++ err = input_register_device(input_dev); ++ if (err) ++ goto err_free_irq; ++ ++ ts->client = client; ++ ts->input = input_dev; ++ ++ dev_info(&client->dev, "probe ok! registered with irq (%d)\n", ts->irq); ++ ++ return 0; ++ ++err_free_irq: ++ if (ts->gpio_pendown) ++ gpio_free(ts->gpio_pendown); ++ if (ts->gpio_reset) ++ gpio_free(ts->gpio_reset); ++#if defined(CONFIG_ARCH_MESON64_ODROIDC2) ++ sx865x_irq_free(client, ts); ++#else ++ if (ts->irq) ++ free_irq(ts->irq, ts); ++#endif ++ return err; ++} ++ ++static int sx865x_remove(struct i2c_client *client) ++{ ++ struct sx865x *ts = i2c_get_clientdata(client); ++ struct sx865x_platform_data *pdata; ++ ++ pdata = client->dev.platform_data; ++ ++ if (ts->gpio_pendown) ++ gpio_free(ts->gpio_pendown); ++ if (ts->gpio_reset) ++ gpio_free(ts->gpio_reset); ++#if defined(CONFIG_ARCH_MESON64_ODROIDC2) ++ sx865x_irq_free(client, ts); ++#else ++ if (ts->irq) ++ free_irq(ts->irq, ts); ++#endif ++ input_unregister_device(ts->input); ++ ++ return 0; ++} ++ ++static struct i2c_driver sx865x_driver = { ++ .driver = { ++ .owner = THIS_MODULE, ++ .name = "sx865x", ++ .of_match_table = of_match_ptr(sx865x_of_match), ++ }, ++ .id_table = sx865x_idtable, ++ .probe = sx865x_probe, ++ .remove = sx865x_remove, ++}; ++ ++module_i2c_driver(sx865x_driver); ++ ++MODULE_AUTHOR("Pierluigi Passaro "); ++MODULE_DESCRIPTION("SX865X TouchScreen Driver"); ++MODULE_LICENSE("GPL"); diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/073_linux-4.18.y-drm-fb_helper-ump-ioctls.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/073_linux-4.18.y-drm-fb_helper-ump-ioctls.patch new file mode 100644 index 000000000..b4cd89375 --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/073_linux-4.18.y-drm-fb_helper-ump-ioctls.patch @@ -0,0 +1,151 @@ +diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c +index cab14f25..cafc60ea 100644 +--- a/drivers/gpu/drm/drm_fb_helper.c ++++ b/drivers/gpu/drm/drm_fb_helper.c +@@ -1544,6 +1544,14 @@ int drm_fb_helper_ioctl(struct fb_info *info, unsigned int cmd, + + ret = 0; + goto unlock; ++#if defined(CONFIG_UMP) ++ case GET_UMP_SECURE_ID_BUF1: ++ ret = drm_get_ump_secure_id(info, fb_helper, arg, 0); ++ goto unlock; ++ case GET_UMP_SECURE_ID_BUF2: ++ ret = drm_get_ump_secure_id(info, fb_helper, arg, 1); ++ goto unlock; ++#endif + default: + ret = -ENOTTY; + } +diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile +index 69c13517..55673ac6 100644 +--- a/drivers/gpu/drm/Makefile ++++ b/drivers/gpu/drm/Makefile +@@ -44,6 +44,7 @@ drm_kms_helper-$(CONFIG_DRM_DP_AUX_CHARDEV) += drm_dp_aux_dev.o + + obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o + obj-$(CONFIG_DRM_DEBUG_SELFTEST) += selftests/ ++obj-$(CONFIG_UMP) += drm_fb_ump.o + + obj-$(CONFIG_DRM) += drm.o + obj-$(CONFIG_DRM_MIPI_DSI) += drm_mipi_dsi.o +diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h +index b069433e..95657b76 100644 +--- a/include/drm/drm_fb_helper.h ++++ b/include/drm/drm_fb_helper.h +@@ -36,6 +36,10 @@ struct drm_fb_helper; + #include + #include + ++#if defined(CONFIG_UMP) ++#include ++#endif ++ + enum mode_set_atomic { + LEAVE_ATOMIC_MODE_SET, + ENTER_ATOMIC_MODE_SET, +@@ -131,6 +135,8 @@ struct drm_fb_helper_connector { + struct drm_connector *connector; + }; + ++#define DRM_FB_UMP_COUNT 1 /* only enable one FB UMP layer */ ++ + /** + * struct drm_fb_helper - main structure to emulate fbdev on top of KMS + * @fb: Scanout framebuffer object +@@ -232,6 +238,9 @@ struct drm_fb_helper { + * See also: @deferred_setup + */ + int preferred_bpp; ++#if defined(CONFIG_UMP) ++ ump_dd_handle ump_wrapped_buffer[DRM_FB_UMP_COUNT][2]; ++#endif + }; + + /** +@@ -577,4 +586,11 @@ drm_fb_helper_remove_conflicting_framebuffers(struct apertures_struct *a, + #endif + } + ++#if defined(CONFIG_UMP) ++extern int (*drm_get_ump_secure_id) (struct fb_info *info, ++ struct drm_fb_helper *g_fbi, unsigned long arg, int buf); ++#define GET_UMP_SECURE_ID_BUF1 _IOWR('m', 311, unsigned int) ++#define GET_UMP_SECURE_ID_BUF2 _IOWR('m', 312, unsigned int) ++#endif ++ + #endif +--- /dev/null 2018-07-12 16:39:19.544000000 +0200 ++++ b/drivers/gpu/drm/drm_fb_ump.c 2018-07-22 22:20:45.166145058 +0200 +@@ -0,0 +1,71 @@ ++/* ++ * Copyright (C) 2016 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. ++ * ++ * 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. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, ++ * MA 02111-1307 USA ++ */ ++ ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++int (*drm_get_ump_secure_id) (struct fb_info *info, ++ struct drm_fb_helper *g_fbi, unsigned long arg, int buf); ++EXPORT_SYMBOL(drm_get_ump_secure_id); ++ ++static int _drm_get_ump_secure_id(struct fb_info *info, ++ struct drm_fb_helper *g_fbi, unsigned long arg, int buf) ++{ ++ u32 __user *psecureid = (u32 __user *) arg; ++ ump_secure_id secure_id; ++ ++ if (!g_fbi->ump_wrapped_buffer[info->node][buf]) { ++ ump_dd_physical_block ump_memory_description; ++ printk("ump: create disp: %d\n", buf); ++ ++ ump_memory_description.addr = info->fix.smem_start; ++ ump_memory_description.size = info->fix.smem_len; ++ g_fbi->ump_wrapped_buffer[info->node][buf] = ++ ump_dd_handle_create_from_phys_blocks( ++ &ump_memory_description, 1); ++ } ++ secure_id = ump_dd_secure_id_get( ++ g_fbi->ump_wrapped_buffer[info->node][buf]); ++ ++ return put_user((unsigned int)secure_id, psecureid); ++} ++ ++static int __init drm_ump_module_init(void) ++{ ++ int ret = 0; ++ drm_get_ump_secure_id = _drm_get_ump_secure_id; ++ return ret; ++} ++ ++static void __exit drm_ump_module_exit(void) ++{ ++ drm_get_ump_secure_id = NULL; ++} ++ ++module_init(drm_ump_module_init); ++module_exit(drm_ump_module_exit); ++ ++MODULE_AUTHOR("Mauro Ribeiro "); ++MODULE_DESCRIPTION("UMP Glue for DRM Framebuffer"); ++MODULE_LICENSE("GPL"); diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/074_odroidc2-enable-scpi-dvfs.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/074_odroidc2-enable-scpi-dvfs.patch new file mode 100644 index 000000000..dbe1e637f --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/074_odroidc2-enable-scpi-dvfs.patch @@ -0,0 +1,14 @@ +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts +index d147c853a..dbde670ba 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts +@@ -246,7 +246,8 @@ + }; + + &scpi_clocks { +- status = "disabled"; ++ /* Works only with new blobs that have limited DVFS table */ ++ status = "okay"; + }; + + /* SD */ diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/075_odroidc2-enable-scpi-cpu-thermal.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/075_odroidc2-enable-scpi-cpu-thermal.patch new file mode 100644 index 000000000..e05b711aa --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/075_odroidc2-enable-scpi-cpu-thermal.patch @@ -0,0 +1,63 @@ +--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts 2018-04-29 05:46:55.636313674 +0200 ++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts 2018-04-29 00:07:14.412005049 +0200 +@@ -46,6 +46,7 @@ + + #include "meson-gxbb.dtsi" + #include ++#include + + / { + compatible = "hardkernel,odroid-c2", "amlogic,meson-gxbb"; +@@ -117,6 +118,41 @@ + 1800000 1>; + }; + ++ thermal-zones { ++ cpu-thermal { ++ polling-delay-passive = <250>; /* milliseconds */ ++ polling-delay = <1000>; /* milliseconds */ ++ ++ thermal-sensors = <&scpi_sensors 0>; ++ ++ trips { ++ cpu_alert0: cpu-alert0 { ++ temperature = <70000>; ++ hysteresis = <2000>; ++ type = "passive"; ++ }; ++ cpu_alert1: cpu-alert1 { ++ temperature = <85000>; ++ hysteresis = <2000>; ++ type = "passive"; ++ }; ++ cpu_crit: cpu_crit { ++ temperature = <95000>; ++ hysteresis = <2000>; ++ type = "critical"; ++ }; ++ }; ++ ++ cooling-maps { ++ map0 { ++ trip = <&cpu_alert1>; ++ cooling-device = ++ <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; ++ }; ++ }; ++ }; ++ }; ++ + vcc1v8: regulator-vcc1v8 { + compatible = "regulator-fixed"; + regulator-name = "VCC1V8"; +@@ -192,6 +228,10 @@ + status = "okay"; + }; + ++&cpu0 { ++ #cooling-cells = <2>; ++}; ++ + ðmac { + status = "okay"; + pinctrl-0 = <ð_rgmii_pins>; diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/000_linux-4.14.y-le-amlogic-gx-0000-net-before.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/000_linux-4.14.y-le-amlogic-gx-0000-net-before.patch new file mode 100644 index 000000000..5e07a33bc --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/000_linux-4.14.y-le-amlogic-gx-0000-net-before.patch @@ -0,0 +1,19 @@ + +--- b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c 2018-04-12 01:40:29.029325568 +0200 ++++ a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c 2018-04-14 01:12:07.301469106 +0200 +@@ -364,15 +364,9 @@ + bool stmmac_eee_init(struct stmmac_priv *priv) + { + struct net_device *ndev = priv->dev; +- int interface = priv->plat->interface; + unsigned long flags; + bool ret = false; + +- if ((interface != PHY_INTERFACE_MODE_MII) && +- (interface != PHY_INTERFACE_MODE_GMII) && +- !phy_interface_mode_is_rgmii(interface)) +- goto out; +- + /* Using PCS we cannot dial with the phy registers at this stage + * so we do not support extra feature like EEE. + */ diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/0002-ARM64-dts-meson-gxbb-allow-child-devices-on-the-USB-.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/001_linux-4.14.y-le-amlogic-gx-0002-arm64-dts-meson-gxbb-allow_child_devices_on_the_usb.patch similarity index 87% rename from buildroot-external/board/hardkernel/odroid-c2/patches/linux/0002-ARM64-dts-meson-gxbb-allow-child-devices-on-the-USB-.patch rename to buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/001_linux-4.14.y-le-amlogic-gx-0002-arm64-dts-meson-gxbb-allow_child_devices_on_the_usb.patch index bbabdbcbd..d46bc071b 100644 --- a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/0002-ARM64-dts-meson-gxbb-allow-child-devices-on-the-USB-.patch +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/001_linux-4.14.y-le-amlogic-gx-0002-arm64-dts-meson-gxbb-allow_child_devices_on_the_usb.patch @@ -1,7 +1,7 @@ -From 841ec7b8484dee021a15fdc187cdadc1c89220f2 Mon Sep 17 00:00:00 2001 +From 9724ee442cf7bf4da885433b28029ac559f1f26a Mon Sep 17 00:00:00 2001 From: Martin Blumenstingl Date: Thu, 12 Jan 2017 01:38:26 +0100 -Subject: [PATCH 02/39] ARM64: dts: meson-gxbb: allow child devices on the USB +Subject: [PATCH] ARM64: dts: meson-gxbb: allow child devices on the USB controller Add the size and adress cells to the USB controllers to allow specifying @@ -15,7 +15,7 @@ Signed-off-by: Neil Armstrong 1 file changed, 4 insertions(+) diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi -index af834cd..7d38d55 100644 +index af834cdbba791..7d38d55869c94 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi @@ -73,6 +73,8 @@ @@ -36,6 +36,3 @@ index af834cd..7d38d55 100644 reg = <0x0 0xc9100000 0x0 0x40000>; interrupts = ; clocks = <&clkc CLKID_USB1_DDR_BRIDGE>; --- -2.7.4 - diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/0003-ARM64-dts-meson-gxbb-odroidc2-take-USB-hub-out-of-re.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/002_linux-4.14.y-le-amlogic-gx-0003-arm64-dts-meson-gxbb-odroidc2-take_usb_hub_out_of_reset.patch similarity index 81% rename from buildroot-external/board/hardkernel/odroid-c2/patches/linux/0003-ARM64-dts-meson-gxbb-odroidc2-take-USB-hub-out-of-re.patch rename to buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/002_linux-4.14.y-le-amlogic-gx-0003-arm64-dts-meson-gxbb-odroidc2-take_usb_hub_out_of_reset.patch index c0b21cab9..233b4840f 100644 --- a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/0003-ARM64-dts-meson-gxbb-odroidc2-take-USB-hub-out-of-re.patch +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/002_linux-4.14.y-le-amlogic-gx-0003-arm64-dts-meson-gxbb-odroidc2-take_usb_hub_out_of_reset.patch @@ -1,8 +1,7 @@ -From 564bc89139a6bf0833cef64993dfe3fe2784c6a8 Mon Sep 17 00:00:00 2001 +From 53d19221222d8fe49aae75721a9547c7d104e9ed Mon Sep 17 00:00:00 2001 From: Martin Blumenstingl Date: Thu, 12 Jan 2017 01:39:20 +0100 -Subject: [PATCH 03/39] ARM64: dts: meson-gxbb-odroidc2: take USB hub out of - reset +Subject: [PATCH] ARM64: dts: meson-gxbb-odroidc2: take USB hub out of reset This takes the USB hub out of reset, otherwise the hub is not working. @@ -14,10 +13,10 @@ Signed-off-by: Neil Armstrong 1 file changed, 7 insertions(+) diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts -index 08b7bb7..c3a7b7f 100644 +index 1ffa1c238a725..b035c728a4821 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts -@@ -310,4 +310,11 @@ +@@ -309,4 +309,11 @@ &usb1 { status = "okay"; @@ -29,6 +28,3 @@ index 08b7bb7..c3a7b7f 100644 + reset-duration-us = <3000>; + }; }; --- -2.7.4 - diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/003_linux-4.14.y-le-amlogic-gx-0004-phy-meson-add_usb3_phy_support_for_meson_gxl.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/003_linux-4.14.y-le-amlogic-gx-0004-phy-meson-add_usb3_phy_support_for_meson_gxl.patch new file mode 100644 index 000000000..5cbaa9478 --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/003_linux-4.14.y-le-amlogic-gx-0004-phy-meson-add_usb3_phy_support_for_meson_gxl.patch @@ -0,0 +1,257 @@ +From 1b68976e2e05b3e10e4f3070ef5b9e08640ad7a0 Mon Sep 17 00:00:00 2001 +From: Martin Blumenstingl +Date: Sat, 26 Nov 2016 15:56:32 +0100 +Subject: [PATCH] phy: meson: add USB3 PHY support for Meson GXL + +This adds USB3 PHY driver found on Meson GXL and GXM SoCs. + +Unfortunately there are no datasheets available for any of these PHYs. +Both drivers were written by reading the reference drivers provided by +Amlogic and analyzing the registers on the kernel that was shipped with +my board. + +Signed-off-by: Martin Blumenstingl +Signed-off-by: Neil Armstrong +--- + drivers/phy/amlogic/Kconfig | 13 ++ + drivers/phy/amlogic/Makefile | 1 + + drivers/phy/amlogic/phy-meson-gxl-usb3.c | 198 +++++++++++++++++++++++++++++++ + 3 files changed, 212 insertions(+) + create mode 100644 drivers/phy/amlogic/phy-meson-gxl-usb3.c + +diff --git a/drivers/phy/amlogic/Kconfig b/drivers/phy/amlogic/Kconfig +index cb8f4501652b1..5d11a3e698d4a 100644 +--- a/drivers/phy/amlogic/Kconfig ++++ b/drivers/phy/amlogic/Kconfig +@@ -13,6 +13,19 @@ config PHY_MESON8B_USB2 + Meson8b and GXBB SoCs. + If unsure, say N. + ++config PHY_MESON_GXL_USB3 ++ tristate "Meson GXL and GXM USB3 PHY drivers" ++ default ARCH_MESON ++ depends on OF && (ARCH_MESON || COMPILE_TEST) ++ depends on USB_SUPPORT ++ select USB_COMMON ++ select GENERIC_PHY ++ select REGMAP_MMIO ++ help ++ Enable this to support the Meson USB3 PHY found in Meson ++ GXL and GXM SoCs. ++ If unsure, say N. ++ + config PHY_MESON_GXL_USB2 + tristate "Meson GXL and GXM USB2 PHY drivers" + default ARCH_MESON +diff --git a/drivers/phy/amlogic/Makefile b/drivers/phy/amlogic/Makefile +index cfdc98715c30a..4fd8848c194d6 100644 +--- a/drivers/phy/amlogic/Makefile ++++ b/drivers/phy/amlogic/Makefile +@@ -1,2 +1,3 @@ + obj-$(CONFIG_PHY_MESON8B_USB2) += phy-meson8b-usb2.o + obj-$(CONFIG_PHY_MESON_GXL_USB2) += phy-meson-gxl-usb2.o ++obj-$(CONFIG_PHY_MESON_GXL_USB3) += phy-meson-gxl-usb3.o +diff --git a/drivers/phy/amlogic/phy-meson-gxl-usb3.c b/drivers/phy/amlogic/phy-meson-gxl-usb3.c +new file mode 100644 +index 0000000000000..9af5222fe754f +--- /dev/null ++++ b/drivers/phy/amlogic/phy-meson-gxl-usb3.c +@@ -0,0 +1,198 @@ ++/* ++ * Meson GXL USB3 PHY driver ++ * ++ * Copyright (C) 2016 Martin Blumenstingl ++ * ++ * 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. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program. If not, see . ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define USB_R0 0x00 ++ #define USB_R0_P30_FSEL_SHIFT 0 ++ #define USB_R0_P30_FSEL_MASK GENMASK(5, 0) ++ #define USB_R0_P30_PHY_RESET BIT(6) ++ #define USB_R0_P30_TEST_POWERDOWN_HSP BIT(7) ++ #define USB_R0_P30_TEST_POWERDOWN_SSP BIT(8) ++ #define USB_R0_P30_ACJT_LEVEL_SHIFT 9 ++ #define USB_R0_P30_ACJT_LEVEL_MASK GENMASK(13, 9) ++ #define USB_R0_P30_TX_BOOST_LEVEL_SHIFT 14 ++ #define USB_R0_P30_TX_BOOST_LEVEL_MASK GENMASK(16, 14) ++ #define USB_R0_P30_LANE0_TX2RX_LOOPBACK BIT(17) ++ #define USB_R0_P30_LANE0_EXT_PCLK_REQ BIT(18) ++ #define USB_R0_P30_PCS_RX_LOS_MASK_VAL_SHIFT 19 ++ #define USB_R0_P30_PCS_RX_LOS_MASK_VAL_MASK GENMASK(28, 19) ++ #define USB_R0_U2D_SS_SCALEDOWN_MODE_SHIFT 29 ++ #define USB_R0_U2D_SS_SCALEDOWN_MODE_MASK GENMASK(30, 29) ++ #define USB_R0_U2D_ACT BIT(31) ++ ++#define USB_R1 0x04 ++ #define USB_R1_U3H_BIGENDIAN_GS BIT(0) ++ #define USB_R1_U3H_PME_ENABLE BIT(1) ++ #define USB_R1_U3H_HUB_PORT_OVERCURRENT_SHIFT 2 ++ #define USB_R1_U3H_HUB_PORT_OVERCURRENT_MASK GENMASK(6, 2) ++ #define USB_R1_U3H_HUB_PORT_PERM_ATTACH_SHIFT 7 ++ #define USB_R1_U3H_HUB_PORT_PERM_ATTACH_MASK GENMASK(11, 7) ++ #define USB_R1_U3H_HOST_U2_PORT_DISABLE_SHIFT 12 ++ #define USB_R1_U3H_HOST_U2_PORT_DISABLE_MASK GENMASK(15, 12) ++ #define USB_R1_U3H_HOST_U3_PORT_DISABLE BIT(16) ++ #define USB_R1_U3H_HOST_PORT_POWER_CONTROL_PRESENT BIT(17) ++ #define USB_R1_U3H_HOST_MSI_ENABLE BIT(18) ++ #define USB_R1_U3H_FLADJ_30MHZ_REG_SHIFT 19 ++ #define USB_R1_U3H_FLADJ_30MHZ_REG_MASK GENMASK(24, 19) ++ #define USB_R1_P30_PCS_TX_SWING_FULL_SHIFT 25 ++ #define USB_R1_P30_PCS_TX_SWING_FULL_MASK GENMASK(31, 25) ++ ++#define USB_R2 0x08 ++ #define USB_R2_P30_CR_DATA_IN_SHIFT 0 ++ #define USB_R2_P30_CR_DATA_IN_MASK GENMASK(15, 0) ++ #define USB_R2_P30_CR_READ BIT(16) ++ #define USB_R2_P30_CR_WRITE BIT(17) ++ #define USB_R2_P30_CR_CAP_ADDR BIT(18) ++ #define USB_R2_P30_CR_CAP_DATA BIT(19) ++ #define USB_R2_P30_PCS_TX_DEEMPH_3P5DB_SHIFT 20 ++ #define USB_R2_P30_PCS_TX_DEEMPH_3P5DB_MASK GENMASK(25, 20) ++ #define USB_R2_P30_PCS_TX_DEEMPH_6DB_SHIFT 26 ++ #define USB_R2_P30_PCS_TX_DEEMPH_6DB_MASK GENMASK(31, 26) ++ ++#define USB_R3 0x0c ++ #define USB_R3_P30_SSC_ENABLE BIT(0) ++ #define USB_R3_P30_SSC_RANGE_SHIFT 1 ++ #define USB_R3_P30_SSC_RANGE_MASK GENMASK(3, 1) ++ #define USB_R3_P30_SSC_REF_CLK_SEL_SHIFT 4 ++ #define USB_R3_P30_SSC_REF_CLK_SEL_MASK GENMASK(12, 4) ++ #define USB_R3_P30_REF_SSP_EN BIT(13) ++ #define USB_R3_P30_LOS_BIAS_SHIFT 16 ++ #define USB_R3_P30_LOS_BIAS_MASK GENMASK(18, 16) ++ #define USB_R3_P30_LOS_LEVEL_SHIFT 19 ++ #define USB_R3_P30_LOS_LEVEL_MASK GENMASK(23, 19) ++ #define USB_R3_P30_MPLL_MULTIPLIER_SHIFT 24 ++ #define USB_R3_P30_MPLL_MULTIPLIER_MASK GENMASK(30, 24) ++ ++#define USB_R4 0x10 ++ #define USB_R4_P21_PORT_RESET_0 BIT(0) ++ #define USB_R4_P21_SLEEP_M0 BIT(1) ++ #define USB_R4_MEM_PD_SHIFT 2 ++ #define USB_R4_MEM_PD_MASK GENMASK(3, 2) ++ #define USB_R4_P21_ONLY BIT(4) ++ ++#define USB_R5 0x14 ++ #define USB_R5_ID_DIG_SYNC BIT(0) ++ #define USB_R5_ID_DIG_REG BIT(1) ++ #define USB_R5_ID_DIG_CFG_SHIFT 2 ++ #define USB_R5_ID_DIG_CFG_MASK GENMASK(3, 2) ++ #define USB_R5_ID_DIG_EN_0 BIT(4) ++ #define USB_R5_ID_DIG_EN_1 BIT(5) ++ #define USB_R5_ID_DIG_CURR BIT(6) ++ #define USB_R5_ID_DIG_IRQ BIT(7) ++ #define USB_R5_ID_DIG_TH_SHIFT 8 ++ #define USB_R5_ID_DIG_TH_MASK GENMASK(15, 8) ++ #define USB_R5_ID_DIG_CNT_SHIFT 16 ++ #define USB_R5_ID_DIG_CNT_MASK GENMASK(23, 16) ++ ++/* read-only register */ ++#define USB_R6 0x18 ++ #define USB_R6_P30_CR_DATA_OUT_SHIFT 0 ++ #define USB_R6_P30_CR_DATA_OUT_MASK GENMASK(15, 0) ++ #define USB_R6_P30_CR_ACK BIT(16) ++ ++#define RESET_COMPLETE_TIME 500 ++ ++struct phy_meson_gxl_usb3_priv { ++ struct regmap *regmap; ++ struct phy *this_phy; ++}; ++ ++static const struct regmap_config phy_meson_gxl_usb3_regmap_conf = { ++ .reg_bits = 32, ++ .val_bits = 32, ++ .reg_stride = 4, ++ .max_register = USB_R6, ++}; ++ ++static int phy_meson_gxl_usb3_power_on(struct phy *phy) ++{ ++ struct phy_meson_gxl_usb3_priv *priv = phy_get_drvdata(phy); ++ ++ regmap_update_bits(priv->regmap, USB_R1, ++ USB_R1_U3H_FLADJ_30MHZ_REG_MASK, ++ 0x20 << USB_R1_U3H_FLADJ_30MHZ_REG_SHIFT); ++ ++ return 0; ++} ++ ++static const struct phy_ops phy_meson_gxl_usb3_ops = { ++ .power_on = phy_meson_gxl_usb3_power_on, ++ .owner = THIS_MODULE, ++}; ++ ++static int phy_meson_gxl_usb3_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct device_node *np = dev->of_node; ++ struct phy_meson_gxl_usb3_priv *priv; ++ struct resource *res; ++ struct phy *phy; ++ struct phy_provider *phy_provider; ++ void __iomem *base; ++ ++ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); ++ if (!priv) ++ return -ENOMEM; ++ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ base = devm_ioremap_resource(dev, res); ++ if (IS_ERR(base)) ++ return PTR_ERR(base); ++ ++ priv->regmap = devm_regmap_init_mmio(dev, base, ++ &phy_meson_gxl_usb3_regmap_conf); ++ if (IS_ERR(priv->regmap)) ++ return PTR_ERR(priv->regmap); ++ ++ phy = devm_phy_create(dev, np, &phy_meson_gxl_usb3_ops); ++ if (IS_ERR(phy)) { ++ dev_err(dev, "failed to create PHY\n"); ++ return PTR_ERR(phy); ++ } ++ ++ phy_set_drvdata(phy, priv); ++ ++ phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); ++ ++ return PTR_ERR_OR_ZERO(phy_provider); ++} ++ ++static const struct of_device_id phy_meson_gxl_usb3_of_match[] = { ++ { .compatible = "amlogic,meson-gxl-usb3-phy", }, ++ { }, ++}; ++MODULE_DEVICE_TABLE(of, phy_meson_gxl_usb3_of_match); ++ ++static struct platform_driver phy_meson_gxl_usb3_driver = { ++ .probe = phy_meson_gxl_usb3_probe, ++ .driver = { ++ .name = "phy-meson-gxl-usb3", ++ .of_match_table = phy_meson_gxl_usb3_of_match, ++ }, ++}; ++module_platform_driver(phy_meson_gxl_usb3_driver); ++ ++MODULE_AUTHOR("Martin Blumenstingl "); ++MODULE_DESCRIPTION("Meson GXL USB3 PHY driver"); ++MODULE_LICENSE("GPL"); diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/004_linux-4.14.y-le-amlogic-gx-0005-usb-host-add_a_generic_platform_usb_roothub_driver.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/004_linux-4.14.y-le-amlogic-gx-0005-usb-host-add_a_generic_platform_usb_roothub_driver.patch new file mode 100644 index 000000000..812471960 --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/004_linux-4.14.y-le-amlogic-gx-0005-usb-host-add_a_generic_platform_usb_roothub_driver.patch @@ -0,0 +1,290 @@ +From 0e1b7fc3afdff8b63a2ed34ae6222cc02b043d62 Mon Sep 17 00:00:00 2001 +From: Martin Blumenstingl +Date: Tue, 10 Jan 2017 18:59:43 +0100 +Subject: [PATCH] usb: host: add a generic platform USB roothub driver + +Many SoC platforms have separate devices for the USB PHY which are +registered through the generic PHY framework. These PHYs have to be +enabled to make the USB controller actually work. They also have to be +disabled again on shutdown/suspend. + +Currently (at least) the following HCI platform drivers are using custom +code to obtain all PHYs via devicetree for the roothub/controller and +disable/enable them when required: +- ehci-platform.c has ehci_platform_power_{on,off} +- xhci-mtk.c has xhci_mtk_phy_{init,exit,power_on,power_off} +- ohci-platform.c has ohci_platform_power_{on,off} + +These drivers are not using the generic devicetree USB device bindings +yet which were only introduced recently (documentation is available in +devicetree/bindings/usb/usb-device.txt). +With this new driver the usb2-phy and usb3-phy can be specified directly +in the child-node of the corresponding port of the roothub via +devicetree. This can be extended by not just parsing PHYs (some of the +other drivers listed above are for example also parsing a list of clocks +as well) when required. + +Signed-off-by: Martin Blumenstingl +Signed-off-by: Neil Armstrong +--- + .../devicetree/bindings/usb/usb-roothub.txt | 46 +++++++ + drivers/usb/host/Kconfig | 3 + + drivers/usb/host/Makefile | 2 + + drivers/usb/host/platform-roothub.c | 146 +++++++++++++++++++++ + drivers/usb/host/platform-roothub.h | 14 ++ + 5 files changed, 211 insertions(+) + create mode 100644 Documentation/devicetree/bindings/usb/usb-roothub.txt + create mode 100644 drivers/usb/host/platform-roothub.c + create mode 100644 drivers/usb/host/platform-roothub.h + +diff --git a/Documentation/devicetree/bindings/usb/usb-roothub.txt b/Documentation/devicetree/bindings/usb/usb-roothub.txt +new file mode 100644 +index 0000000000000..23b24b68d74df +--- /dev/null ++++ b/Documentation/devicetree/bindings/usb/usb-roothub.txt +@@ -0,0 +1,46 @@ ++Generic USB root-hub Properties ++ ++similar to the USB device bindings (documented in usb-device.txt from the ++current directory) this provides support for configuring the root-hub. ++ ++Required properties: ++- compatible: should be at least one of "usb1d6b,3", "usb1d6b,2" ++- reg: must be 0. ++- address-cells: must be 1 ++- size-cells: must be 0 ++ ++Required sub-nodes: ++a sub-node per actual USB port is required. each sub-node supports the ++following properties: ++ Required properties: ++ - reg: the port number on the root-hub (mandatory) ++ Optional properties: ++ - phys: optional, from the *Generic PHY* bindings (mandatory needed ++ when phy-names is given) ++ - phy-names: optional, from the *Generic PHY* bindings; supported names ++ are "usb2-phy" or "usb3-phy" ++ ++Example: ++ &usb1 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ roothub@0 { ++ compatible = "usb1d6b,3", "usb1d6b,2"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ reg = <0>; ++ ++ port@1 { ++ reg = <1>; ++ usb-phy = <&usb2_phy1>, <&usb3_phy1>; ++ phy-names = "usb2-phy", "usb3-phy"; ++ }; ++ ++ port@2 { ++ reg = <2>; ++ usb-phy = <&usb2_phy2>, <&usb3_phy2>; ++ phy-names = "usb2-phy", "usb3-phy"; ++ }; ++ }; ++ } +diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig +index fa5692dec8320..b8b05c786b2a2 100644 +--- a/drivers/usb/host/Kconfig ++++ b/drivers/usb/host/Kconfig +@@ -805,6 +805,9 @@ config USB_HCD_SSB + + If unsure, say N. + ++config USB_PLATFORM_ROOTHUB ++ bool ++ + config USB_HCD_TEST_MODE + bool "HCD test mode support" + ---help--- +diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile +index 4ab2689c8952b..873ebd9250d3b 100644 +--- a/drivers/usb/host/Makefile ++++ b/drivers/usb/host/Makefile +@@ -30,6 +30,8 @@ obj-$(CONFIG_USB_WHCI_HCD) += whci/ + + obj-$(CONFIG_USB_PCI) += pci-quirks.o + ++obj-$(CONFIG_USB_PLATFORM_ROOTHUB) += platform-roothub.o ++ + obj-$(CONFIG_USB_EHCI_HCD) += ehci-hcd.o + obj-$(CONFIG_USB_EHCI_PCI) += ehci-pci.o + obj-$(CONFIG_USB_EHCI_HCD_PLATFORM) += ehci-platform.o +diff --git a/drivers/usb/host/platform-roothub.c b/drivers/usb/host/platform-roothub.c +new file mode 100644 +index 0000000000000..84837e42b0063 +--- /dev/null ++++ b/drivers/usb/host/platform-roothub.c +@@ -0,0 +1,146 @@ ++/* ++ * platform roothub driver - a virtual PHY device which passes all phy_* ++ * function calls to multiple (actual) PHY devices. This is comes handy when ++ * initializing all PHYs on a root-hub (to keep them all in the same state). ++ * ++ * Copyright (C) 2017 Martin Blumenstingl ++ * ++ * 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. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program. If not, see . ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include "platform-roothub.h" ++ ++#define ROOTHUB_PORTNUM 0 ++ ++struct platform_roothub { ++ struct phy *phy; ++ struct list_head list; ++}; ++ ++static struct platform_roothub *platform_roothub_alloc(struct device *dev) ++{ ++ struct platform_roothub *roothub_entry; ++ ++ roothub_entry = devm_kzalloc(dev, sizeof(*roothub_entry), GFP_KERNEL); ++ if (!roothub_entry) ++ return ERR_PTR(-ENOMEM); ++ ++ INIT_LIST_HEAD(&roothub_entry->list); ++ ++ return roothub_entry; ++} ++ ++static int platform_roothub_add_phy(struct device *dev, ++ struct device_node *port_np, ++ const char *con_id, struct list_head *list) ++{ ++ struct platform_roothub *roothub_entry; ++ struct phy *phy = devm_of_phy_get(dev, port_np, con_id); ++ ++ if (IS_ERR_OR_NULL(phy)) { ++ if (!phy || PTR_ERR(phy) == -ENODEV) ++ return 0; ++ else ++ return PTR_ERR(phy); ++ } ++ ++ roothub_entry = platform_roothub_alloc(dev); ++ if (IS_ERR(roothub_entry)) ++ return PTR_ERR(roothub_entry); ++ ++ roothub_entry->phy = phy; ++ ++ list_add_tail(&roothub_entry->list, list); ++ ++ return 0; ++} ++ ++struct platform_roothub *platform_roothub_init(struct device *dev) ++{ ++ struct device_node *roothub_np, *port_np; ++ struct platform_roothub *plat_roothub; ++ int err; ++ ++ roothub_np = usb_of_get_child_node(dev->of_node, ROOTHUB_PORTNUM); ++ if (!of_device_is_available(roothub_np)) ++ return NULL; ++ ++ plat_roothub = platform_roothub_alloc(dev); ++ if (IS_ERR(plat_roothub)) ++ return plat_roothub; ++ ++ for_each_available_child_of_node(roothub_np, port_np) { ++ err = platform_roothub_add_phy(dev, port_np, "usb2-phy", ++ &plat_roothub->list); ++ if (err) ++ return ERR_PTR(err); ++ ++ err = platform_roothub_add_phy(dev, port_np, "usb3-phy", ++ &plat_roothub->list); ++ if (err) ++ return ERR_PTR(err); ++ } ++ ++ return plat_roothub; ++} ++EXPORT_SYMBOL_GPL(platform_roothub_init); ++ ++int platform_roothub_power_on(struct platform_roothub *plat_roothub) ++{ ++ struct platform_roothub *roothub_entry; ++ struct list_head *head; ++ int err; ++ ++ if (!plat_roothub) ++ return 0; ++ ++ head = &plat_roothub->list; ++ ++ list_for_each_entry(roothub_entry, head, list) { ++ err = phy_init(roothub_entry->phy); ++ if (err) ++ goto err_out; ++ ++ err = phy_power_on(roothub_entry->phy); ++ if (err) { ++ phy_exit(roothub_entry->phy); ++ goto err_out; ++ } ++ } ++ ++ return 0; ++ ++err_out: ++ list_for_each_entry_continue_reverse(roothub_entry, head, list) { ++ phy_power_off(roothub_entry->phy); ++ phy_exit(roothub_entry->phy); ++ } ++ ++ return err; ++} ++EXPORT_SYMBOL_GPL(platform_roothub_power_on); ++ ++void platform_roothub_power_off(struct platform_roothub *plat_roothub) ++{ ++ struct platform_roothub *roothub_entry; ++ ++ if (!plat_roothub) ++ return; ++ ++ list_for_each_entry_reverse(roothub_entry, &plat_roothub->list, list) { ++ phy_power_off(roothub_entry->phy); ++ phy_exit(roothub_entry->phy); ++ } ++} ++EXPORT_SYMBOL_GPL(platform_roothub_power_off); +diff --git a/drivers/usb/host/platform-roothub.h b/drivers/usb/host/platform-roothub.h +new file mode 100644 +index 0000000000000..bde0bf299e3b5 +--- /dev/null ++++ b/drivers/usb/host/platform-roothub.h +@@ -0,0 +1,14 @@ ++#ifndef USB_HOST_PLATFORM_ROOTHUB_H ++#define USB_HOST_PLATFORM_ROOTHUB_H ++ ++struct phy; ++struct device_node; ++ ++struct platform_roothub; ++ ++struct platform_roothub *platform_roothub_init(struct device *dev); ++ ++int platform_roothub_power_on(struct platform_roothub *plat_roothub); ++void platform_roothub_power_off(struct platform_roothub *plat_roothub); ++ ++#endif /* USB_HOST_PLATFORM_ROOTHUB_H */ diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/0014-clk-meson-gxbb-Add-VPU-and-VAPB-clockids.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/005_linux-4.14.y-le-amlogic-gx-0014-clk-meson-gxbb-add_vpu_and_vapb_clockids.patch similarity index 88% rename from buildroot-external/board/hardkernel/odroid-c2/patches/linux/0014-clk-meson-gxbb-Add-VPU-and-VAPB-clockids.patch rename to buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/005_linux-4.14.y-le-amlogic-gx-0014-clk-meson-gxbb-add_vpu_and_vapb_clockids.patch index 9d7354901..29648b755 100644 --- a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/0014-clk-meson-gxbb-Add-VPU-and-VAPB-clockids.patch +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/005_linux-4.14.y-le-amlogic-gx-0014-clk-meson-gxbb-add_vpu_and_vapb_clockids.patch @@ -1,7 +1,7 @@ -From 9bc414d9e18f8c9d39be44165b4926e2b2cdc1d9 Mon Sep 17 00:00:00 2001 +From 7a03fa7ed4d552f8e1397a18d9f0046f9c8a8076 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Mon, 16 Oct 2017 17:29:33 +0200 -Subject: [PATCH 14/39] clk: meson: gxbb: Add VPU and VAPB clockids +Subject: [PATCH] clk: meson: gxbb: Add VPU and VAPB clockids Add the clkids for the clocks feeding the Video Processing Unit. @@ -12,7 +12,7 @@ Signed-off-by: Neil Armstrong 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/drivers/clk/meson/gxbb.h b/drivers/clk/meson/gxbb.h -index 5b1d4b3..aee6fbb 100644 +index 5b1d4b374d1c2..aee6fbba20043 100644 --- a/drivers/clk/meson/gxbb.h +++ b/drivers/clk/meson/gxbb.h @@ -190,8 +190,12 @@ @@ -30,7 +30,7 @@ index 5b1d4b3..aee6fbb 100644 /* include the CLKIDs that have been made part of the DT binding */ #include diff --git a/include/dt-bindings/clock/gxbb-clkc.h b/include/dt-bindings/clock/gxbb-clkc.h -index 8c92528..8ba99a5 100644 +index 8c92528aa48ad..8ba99a5e3fd34 100644 --- a/include/dt-bindings/clock/gxbb-clkc.h +++ b/include/dt-bindings/clock/gxbb-clkc.h @@ -114,5 +114,16 @@ @@ -50,6 +50,3 @@ index 8c92528..8ba99a5 100644 +#define CLKID_VAPB 140 #endif /* __GXBB_CLKC_H */ --- -2.7.4 - diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/0015-clk-meson-gxbb-Add-VPU-and-VAPB-clocks-data.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/006_linux-4.14.y-le-amlogic-gx-0015-clk-meson-gxbb-add_vpu_and_vapb_clocks_data.patch similarity index 98% rename from buildroot-external/board/hardkernel/odroid-c2/patches/linux/0015-clk-meson-gxbb-Add-VPU-and-VAPB-clocks-data.patch rename to buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/006_linux-4.14.y-le-amlogic-gx-0015-clk-meson-gxbb-add_vpu_and_vapb_clocks_data.patch index 778c6ab64..1154fee31 100644 --- a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/0015-clk-meson-gxbb-Add-VPU-and-VAPB-clocks-data.patch +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/006_linux-4.14.y-le-amlogic-gx-0015-clk-meson-gxbb-add_vpu_and_vapb_clocks_data.patch @@ -1,7 +1,7 @@ -From a3b8b7bfd775fa521425c72856b4394fb6fec518 Mon Sep 17 00:00:00 2001 +From 89e3cdb01f2bf01810474984fd2c676a88973ac5 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Fri, 13 Oct 2017 14:38:37 +0200 -Subject: [PATCH 15/39] clk: meson: gxbb: Add VPU and VAPB clocks data +Subject: [PATCH] clk: meson: gxbb: Add VPU and VAPB clocks data The Amlogic Meson GX SoCs needs these two clocks to power up the VPU power domain. @@ -15,7 +15,7 @@ Signed-off-by: Neil Armstrong 1 file changed, 292 insertions(+) diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c -index 92168348..86cb5af 100644 +index b2d1e8ed7152b..a71374464c92d 100644 --- a/drivers/clk/meson/gxbb.c +++ b/drivers/clk/meson/gxbb.c @@ -1131,6 +1131,253 @@ static struct clk_gate gxbb_sd_emmc_c_clk0 = { @@ -352,6 +352,3 @@ index 92168348..86cb5af 100644 }; static struct meson_clk_audio_divider *const gxbb_audio_dividers[] = { --- -2.7.4 - diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/0018-reset-meson-add-level-reset-support-for-GX-SoC-famil.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/007_linux-4.14.y-le-amlogic-gx-0018-reset-meson-add_level_reset_support_for_gx_soc_family.patch similarity index 95% rename from buildroot-external/board/hardkernel/odroid-c2/patches/linux/0018-reset-meson-add-level-reset-support-for-GX-SoC-famil.patch rename to buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/007_linux-4.14.y-le-amlogic-gx-0018-reset-meson-add_level_reset_support_for_gx_soc_family.patch index 3ad7ba4fa..84ef1fb45 100644 --- a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/0018-reset-meson-add-level-reset-support-for-GX-SoC-famil.patch +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/007_linux-4.14.y-le-amlogic-gx-0018-reset-meson-add_level_reset_support_for_gx_soc_family.patch @@ -1,7 +1,7 @@ -From 0689a4eaecae2831fe2cb614e102bb4ef43484a4 Mon Sep 17 00:00:00 2001 +From 434a32bab28ccf277229338b33849b24ace9cc35 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Fri, 13 Oct 2017 14:05:01 +0200 -Subject: [PATCH 18/39] reset: meson: add level reset support for GX SoC family +Subject: [PATCH] reset: meson: add level reset support for GX SoC family The Amlogic GX SoC family embeds alternate registers to drive the reset levels next to the pulse registers. @@ -16,7 +16,7 @@ Signed-off-by: Neil Armstrong 1 file changed, 58 insertions(+), 4 deletions(-) diff --git a/drivers/reset/reset-meson.c b/drivers/reset/reset-meson.c -index a8b915e..f3b9d69 100644 +index a8b915eb8b581..f3b9d6989267e 100644 --- a/drivers/reset/reset-meson.c +++ b/drivers/reset/reset-meson.c @@ -62,13 +62,16 @@ @@ -127,6 +127,3 @@ index a8b915e..f3b9d69 100644 data->rcdev.of_node = pdev->dev.of_node; return devm_reset_controller_register(&pdev->dev, &data->rcdev); --- -2.7.4 - diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/0019-soc-amlogic-add-Meson-GX-VPU-Domains-driver.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/008_linux-4.14.y-le-amlogic-gx-0019-soc-amlogic-add_meson_gx_vpu_domains_driver.patch similarity index 96% rename from buildroot-external/board/hardkernel/odroid-c2/patches/linux/0019-soc-amlogic-add-Meson-GX-VPU-Domains-driver.patch rename to buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/008_linux-4.14.y-le-amlogic-gx-0019-soc-amlogic-add_meson_gx_vpu_domains_driver.patch index 99b3bea09..b0d638834 100644 --- a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/0019-soc-amlogic-add-Meson-GX-VPU-Domains-driver.patch +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/008_linux-4.14.y-le-amlogic-gx-0019-soc-amlogic-add_meson_gx_vpu_domains_driver.patch @@ -1,7 +1,7 @@ -From 58d5e73046ca5c28eb835c1a98f936193de5d4d0 Mon Sep 17 00:00:00 2001 +From 375dd688f29cc0e8da629b3896c86c7e263030ae Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Fri, 13 Oct 2017 17:05:00 +0200 -Subject: [PATCH 19/39] soc: amlogic: add Meson GX VPU Domains driver +Subject: [PATCH] soc: amlogic: add Meson GX VPU Domains driver The Video Processing Unit needs a specific Power Domain powering scheme this driver handles this as a PM Power Domain driver. @@ -15,7 +15,7 @@ Signed-off-by: Neil Armstrong create mode 100644 drivers/soc/amlogic/meson-gx-pwrc-vpu.c diff --git a/drivers/soc/amlogic/Kconfig b/drivers/soc/amlogic/Kconfig -index 22acf06..c2c0513 100644 +index 22acf064531ff..c2c0513b18ff5 100644 --- a/drivers/soc/amlogic/Kconfig +++ b/drivers/soc/amlogic/Kconfig @@ -8,5 +8,15 @@ config MESON_GX_SOCINFO @@ -35,7 +35,7 @@ index 22acf06..c2c0513 100644 endmenu diff --git a/drivers/soc/amlogic/Makefile b/drivers/soc/amlogic/Makefile -index 3e85fc4..3174e93 100644 +index 3e85fc462c213..3174e93e72e9c 100644 --- a/drivers/soc/amlogic/Makefile +++ b/drivers/soc/amlogic/Makefile @@ -1 +1,2 @@ @@ -43,7 +43,7 @@ index 3e85fc4..3174e93 100644 +obj-$(CONFIG_MESON_GX_PM_DOMAINS) += meson-gx-pwrc-vpu.o diff --git a/drivers/soc/amlogic/meson-gx-pwrc-vpu.c b/drivers/soc/amlogic/meson-gx-pwrc-vpu.c new file mode 100644 -index 0000000..bf5190b +index 0000000000000..bf5190b65ad9b --- /dev/null +++ b/drivers/soc/amlogic/meson-gx-pwrc-vpu.c @@ -0,0 +1,234 @@ @@ -281,6 +281,3 @@ index 0000000..bf5190b + }, +}; +builtin_platform_driver(meson_gx_pwrc_vpu_driver); --- -2.7.4 - diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/0020-soc-amlogic-meson-gx-pwrc-vpu-fix-power-off-when-pow.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/009_linux-4.14.y-le-amlogic-gx-0020-soc-amlogic-meson-gx-pwrc-vpu-fix_power-off_when_powered.patch similarity index 94% rename from buildroot-external/board/hardkernel/odroid-c2/patches/linux/0020-soc-amlogic-meson-gx-pwrc-vpu-fix-power-off-when-pow.patch rename to buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/009_linux-4.14.y-le-amlogic-gx-0020-soc-amlogic-meson-gx-pwrc-vpu-fix_power-off_when_powered.patch index aa13051f8..ac73f19b5 100644 --- a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/0020-soc-amlogic-meson-gx-pwrc-vpu-fix-power-off-when-pow.patch +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/009_linux-4.14.y-le-amlogic-gx-0020-soc-amlogic-meson-gx-pwrc-vpu-fix_power-off_when_powered.patch @@ -1,8 +1,8 @@ -From a2ae223bac1ad40a5bd7ee124b3af735ff445eb9 Mon Sep 17 00:00:00 2001 +From 6747193c223e945901f42d7e7bc1d3ddea663585 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Fri, 3 Nov 2017 16:43:24 +0100 -Subject: [PATCH 20/39] soc: amlogic: meson-gx-pwrc-vpu: fix power-off when - powered by bootloader +Subject: [PATCH] soc: amlogic: meson-gx-pwrc-vpu: fix power-off when powered + by bootloader In the case the VPU power domain has been powered on by the bootloader and no driver are attached to this power domain, the genpd will power it @@ -19,7 +19,7 @@ Tested-by: Kevin Hilman 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/drivers/soc/amlogic/meson-gx-pwrc-vpu.c b/drivers/soc/amlogic/meson-gx-pwrc-vpu.c -index bf5190b..2bdeebc 100644 +index bf5190b65ad9b..2bdeebc48901d 100644 --- a/drivers/soc/amlogic/meson-gx-pwrc-vpu.c +++ b/drivers/soc/amlogic/meson-gx-pwrc-vpu.c @@ -34,7 +34,6 @@ struct meson_gx_pwrc_vpu { @@ -100,6 +100,3 @@ index bf5190b..2bdeebc 100644 } static const struct of_device_id meson_gx_pwrc_vpu_match_table[] = { --- -2.7.4 - diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/010_linux-4.14.y-le-amlogic-gx-0037-net-phy-meson-gxl-detect_lpa_corruption.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/010_linux-4.14.y-le-amlogic-gx-0037-net-phy-meson-gxl-detect_lpa_corruption.patch new file mode 100644 index 000000000..f98fdef58 --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/010_linux-4.14.y-le-amlogic-gx-0037-net-phy-meson-gxl-detect_lpa_corruption.patch @@ -0,0 +1,128 @@ +From b940b2533f1bb3718ed50f4dc9091f8494e6f37a Mon Sep 17 00:00:00 2001 +From: Jerome Brunet +Date: Fri, 8 Dec 2017 12:08:11 +0100 +Subject: [PATCH] net: phy: meson-gxl: detect LPA corruption + +The purpose of this change is to fix the incorrect detection of the link +partner (LP) advertised capabilities which sometimes happens with this PHY +(roughly 1 time in a dozen) + +This issue may cause the link to be negotiated at 10Mbps/Full or +10Mbps/Half when 100MBps/Full is actually possible. In some case, the link +is even completely broken and no communication is possible. + +To detect the corruption, we must look for a magic undocumented bit in the +WOL bank (hint given by the SoC vendor kernel) but this is not enough to +cover all cases. We also have to look at the LPA ack. If the LP supports +Aneg but did not ack our base code when aneg is completed, we assume +something went wrong. + +The detection of a corrupted LPA triggers a restart of the aneg process. +This solves the problem but may take up to 6 retries to complete. + +Fixes: 7334b3e47aee ("net: phy: Add Meson GXL Internal PHY driver") +Signed-off-by: Jerome Brunet +Signed-off-by: David S. Miller +--- + drivers/net/phy/meson-gxl.c | 74 ++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 73 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/phy/meson-gxl.c b/drivers/net/phy/meson-gxl.c +index 1ea69b7585d9b..700007dd4be56 100644 +--- a/drivers/net/phy/meson-gxl.c ++++ b/drivers/net/phy/meson-gxl.c +@@ -22,6 +22,7 @@ + #include + #include + #include ++#include + + static int meson_gxl_config_init(struct phy_device *phydev) + { +@@ -50,6 +51,77 @@ static int meson_gxl_config_init(struct phy_device *phydev) + return 0; + } + ++/* This function is provided to cope with the possible failures of this phy ++ * during aneg process. When aneg fails, the PHY reports that aneg is done ++ * but the value found in MII_LPA is wrong: ++ * - Early failures: MII_LPA is just 0x0001. if MII_EXPANSION reports that ++ * the link partner (LP) supports aneg but the LP never acked our base ++ * code word, it is likely that we never sent it to begin with. ++ * - Late failures: MII_LPA is filled with a value which seems to make sense ++ * but it actually is not what the LP is advertising. It seems that we ++ * can detect this using a magic bit in the WOL bank (reg 12 - bit 12). ++ * If this particular bit is not set when aneg is reported being done, ++ * it means MII_LPA is likely to be wrong. ++ * ++ * In both case, forcing a restart of the aneg process solve the problem. ++ * When this failure happens, the first retry is usually successful but, ++ * in some cases, it may take up to 6 retries to get a decent result ++ */ ++int meson_gxl_read_status(struct phy_device *phydev) ++{ ++ int ret, wol, lpa, exp; ++ ++ if (phydev->autoneg == AUTONEG_ENABLE) { ++ ret = genphy_aneg_done(phydev); ++ if (ret < 0) ++ return ret; ++ else if (!ret) ++ goto read_status_continue; ++ ++ /* Need to access WOL bank, make sure the access is open */ ++ ret = phy_write(phydev, 0x14, 0x0000); ++ if (ret) ++ return ret; ++ ret = phy_write(phydev, 0x14, 0x0400); ++ if (ret) ++ return ret; ++ ret = phy_write(phydev, 0x14, 0x0000); ++ if (ret) ++ return ret; ++ ret = phy_write(phydev, 0x14, 0x0400); ++ if (ret) ++ return ret; ++ ++ /* Request LPI_STATUS WOL register */ ++ ret = phy_write(phydev, 0x14, 0x8D80); ++ if (ret) ++ return ret; ++ ++ /* Read LPI_STATUS value */ ++ wol = phy_read(phydev, 0x15); ++ if (wol < 0) ++ return wol; ++ ++ lpa = phy_read(phydev, MII_LPA); ++ if (lpa < 0) ++ return lpa; ++ ++ exp = phy_read(phydev, MII_EXPANSION); ++ if (exp < 0) ++ return exp; ++ ++ if (!(wol & BIT(12)) || ++ ((exp & EXPANSION_NWAY) && !(lpa & LPA_LPACK))) { ++ /* Looks like aneg failed after all */ ++ phydev_dbg(phydev, "LPA corruption - aneg restart\n"); ++ return genphy_restart_aneg(phydev); ++ } ++ } ++ ++read_status_continue: ++ return genphy_read_status(phydev); ++} ++ + static struct phy_driver meson_gxl_phy[] = { + { + .phy_id = 0x01814400, +@@ -60,7 +132,7 @@ static struct phy_driver meson_gxl_phy[] = { + .config_init = meson_gxl_config_init, + .config_aneg = genphy_config_aneg, + .aneg_done = genphy_aneg_done, +- .read_status = genphy_read_status, ++ .read_status = meson_gxl_read_status, + .suspend = genphy_suspend, + .resume = genphy_resume, + }, diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/011_linux-4.14.y-le-amlogic-gx-0038-net-stmmac-enable_eee_in_mii,_gmii_or_rgmii_only.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/011_linux-4.14.y-le-amlogic-gx-0038-net-stmmac-enable_eee_in_mii,_gmii_or_rgmii_only.patch new file mode 100644 index 000000000..d68652014 --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/011_linux-4.14.y-le-amlogic-gx-0038-net-stmmac-enable_eee_in_mii,_gmii_or_rgmii_only.patch @@ -0,0 +1,42 @@ +From 0b4f75b1bbf8c1bd22cf62b5100f930e75b9229e Mon Sep 17 00:00:00 2001 +From: Jerome Brunet +Date: Wed, 3 Jan 2018 16:46:29 +0100 +Subject: [PATCH] net: stmmac: enable EEE in MII, GMII or RGMII only + +Note in the databook - Section 4.4 - EEE : +" The EEE feature is not supported when the MAC is configured to use the +TBI, RTBI, SMII, RMII or SGMII single PHY interface. Even if the MAC +supports multiple PHY interfaces, you should activate the EEE mode only +when the MAC is operating with GMII, MII, or RGMII interface." + +Applying this restriction solves a stability issue observed on Amlogic +gxl platforms operating with RMII interface and the internal PHY. + +Fixes: 83bf79b6bb64 ("stmmac: disable at run-time the EEE if not supported") +Signed-off-by: Jerome Brunet +Tested-by: Arnaud Patard +Signed-off-by: David S. Miller +--- + drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +index 16bd509290844..294a19f0fc1be 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +@@ -364,9 +364,15 @@ static void stmmac_eee_ctrl_timer(unsigned long arg) + bool stmmac_eee_init(struct stmmac_priv *priv) + { + struct net_device *ndev = priv->dev; ++ int interface = priv->plat->interface; + unsigned long flags; + bool ret = false; + ++ if ((interface != PHY_INTERFACE_MODE_MII) && ++ (interface != PHY_INTERFACE_MODE_GMII) && ++ !phy_interface_mode_is_rgmii(interface)) ++ goto out; ++ + /* Using PCS we cannot dial with the phy registers at this stage + * so we do not support extra feature like EEE. + */ diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/020_linux-4.16.y-le-amlogic-gx-0037-media-rc-meson-ir-add_timeout_on_idle.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/020_linux-4.16.y-le-amlogic-gx-0037-media-rc-meson-ir-add_timeout_on_idle.patch new file mode 100644 index 000000000..e70ded913 --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/020_linux-4.16.y-le-amlogic-gx-0037-media-rc-meson-ir-add_timeout_on_idle.patch @@ -0,0 +1,82 @@ +From 20705cd911573220254947a6338b0804d1382720 Mon Sep 17 00:00:00 2001 +From: Matthias Reichl +Date: Tue, 23 Jan 2018 09:40:02 +0100 +Subject: [PATCH] media: rc: meson-ir: add timeout on idle + +Meson hardware doesn't generate timeout events, so install a +software timer to prevent "ghost keypresses". + +Signed-off-by: Matthias Reichl +--- + drivers/media/rc/meson-ir.c | 22 ++++++++++++++++++++++ + 1 file changed, 22 insertions(+) + +diff --git a/drivers/media/rc/meson-ir.c b/drivers/media/rc/meson-ir.c +index f2204eb77e2ab..f34c5836412be 100644 +--- a/drivers/media/rc/meson-ir.c ++++ b/drivers/media/rc/meson-ir.c +@@ -69,6 +69,7 @@ struct meson_ir { + void __iomem *reg; + struct rc_dev *rc; + spinlock_t lock; ++ struct timer_list timeout_timer; + }; + + static void meson_ir_set_mask(struct meson_ir *ir, unsigned int reg, +@@ -98,6 +99,10 @@ static irqreturn_t meson_ir_irq(int irqno, void *dev_id) + rawir.pulse = !!(status & STATUS_IR_DEC_IN); + + ir_raw_event_store(ir->rc, &rawir); ++ ++ mod_timer(&ir->timeout_timer, ++ jiffies + nsecs_to_jiffies(ir->rc->timeout)); ++ + ir_raw_event_handle(ir->rc); + + spin_unlock(&ir->lock); +@@ -105,6 +110,17 @@ static irqreturn_t meson_ir_irq(int irqno, void *dev_id) + return IRQ_HANDLED; + } + ++static void meson_ir_timeout_timer(struct timer_list *t) ++{ ++ struct meson_ir *ir = from_timer(ir, t, timeout_timer); ++ DEFINE_IR_RAW_EVENT(rawir); ++ ++ rawir.timeout = true; ++ rawir.duration = ir->rc->timeout; ++ ir_raw_event_store(ir->rc, &rawir); ++ ir_raw_event_handle(ir->rc); ++} ++ + static int meson_ir_probe(struct platform_device *pdev) + { + struct device *dev = &pdev->dev; +@@ -145,7 +161,9 @@ static int meson_ir_probe(struct platform_device *pdev) + ir->rc->map_name = map_name ? map_name : RC_MAP_EMPTY; + ir->rc->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER; + ir->rc->rx_resolution = US_TO_NS(MESON_TRATE); ++ ir->rc->min_timeout = 1; + ir->rc->timeout = MS_TO_NS(200); ++ ir->rc->max_timeout = 10 * IR_DEFAULT_TIMEOUT; + ir->rc->driver_name = DRIVER_NAME; + + spin_lock_init(&ir->lock); +@@ -157,6 +175,8 @@ static int meson_ir_probe(struct platform_device *pdev) + return ret; + } + ++ timer_setup(&ir->timeout_timer, meson_ir_timeout_timer, 0); ++ + ret = devm_request_irq(dev, irq, meson_ir_irq, 0, NULL, ir); + if (ret) { + dev_err(dev, "failed to request irq\n"); +@@ -198,6 +218,8 @@ static int meson_ir_remove(struct platform_device *pdev) + meson_ir_set_mask(ir, IR_DEC_REG1, REG1_ENABLE, 0); + spin_unlock_irqrestore(&ir->lock, flags); + ++ del_timer_sync(&ir->timeout_timer); ++ + return 0; + } + diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/021_linux-4.16-le-amlogic-gx-1001-usb-enable-otg-as-host.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/021_linux-4.16-le-amlogic-gx-1001-usb-enable-otg-as-host.patch new file mode 100644 index 000000000..8f9c1cd27 --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/021_linux-4.16-le-amlogic-gx-1001-usb-enable-otg-as-host.patch @@ -0,0 +1,51 @@ + +--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts 2018-04-28 19:24:56.090524456 +0200 ++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts 2018-04-29 23:09:48.559371108 +0200 +@@ -409,6 +409,7 @@ + &usb0_phy { + status = "okay"; + phy-supply = <&usb_otg_pwr>; ++ dr_mode = "otg"; + }; + + &usb1_phy { +@@ -418,6 +419,7 @@ + + &usb0 { + status = "okay"; ++ dr_mode = "host"; + }; + + &usb1 { + +--- a/drivers/phy/amlogic/phy-meson8b-usb2.c 2018-04-28 19:22:57.420144229 +0200 ++++ b/drivers/phy/amlogic/phy-meson8b-usb2.c 2018-04-29 23:13:57.136515043 +0200 +@@ -113,6 +113,7 @@ + struct phy_meson8b_usb2_priv { + void __iomem *regs; + enum usb_dr_mode dr_mode; ++ enum usb_dr_mode phy_mode; + struct clk *clk_usb_general; + struct clk *clk_usb; + struct reset_control *reset; +@@ -181,7 +182,7 @@ + phy_meson8b_usb2_mask_bits(priv, REG_CTRL, REG_CTRL_SOF_TOGGLE_OUT, + REG_CTRL_SOF_TOGGLE_OUT); + +- if (priv->dr_mode == USB_DR_MODE_HOST) { ++ if (priv->phy_mode == USB_DR_MODE_HOST) { + phy_meson8b_usb2_mask_bits(priv, REG_ADP_BC, + REG_ADP_BC_ACA_ENABLE, + REG_ADP_BC_ACA_ENABLE); +@@ -251,6 +252,11 @@ + return -EINVAL; + } + ++ priv->phy_mode = usb_get_dr_mode(&pdev->dev); ++ if (priv->phy_mode == USB_DR_MODE_UNKNOWN) { ++ priv->phy_mode = priv->dr_mode; ++ } ++ + phy = devm_phy_create(&pdev->dev, NULL, &phy_meson8b_usb2_ops); + if (IS_ERR(phy)) { + dev_err(&pdev->dev, "failed to create PHY\n"); diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/022_linux-4.14.y-le-amlogic-gx-scpi-1004-mailbox-revert_switch_to_hrtimer_for_tx_complete_polling.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/022_linux-4.14.y-le-amlogic-gx-scpi-1004-mailbox-revert_switch_to_hrtimer_for_tx_complete_polling.patch new file mode 100644 index 000000000..2dd8b1c9c --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/022_linux-4.14.y-le-amlogic-gx-scpi-1004-mailbox-revert_switch_to_hrtimer_for_tx_complete_polling.patch @@ -0,0 +1,103 @@ +diff --git a/drivers/mailbox/mailbox.c b/drivers/mailbox/mailbox.c +index 674b35f40..3497cabda 100644 +--- a/drivers/mailbox/mailbox.c ++++ b/drivers/mailbox/mailbox.c +@@ -26,6 +26,8 @@ + static LIST_HEAD(mbox_cons); + static DEFINE_MUTEX(con_mutex); + ++static void poll_txdone(struct timer_list *t); ++ + static int add_to_rbuf(struct mbox_chan *chan, void *mssg) + { + int idx; +@@ -86,8 +88,7 @@ static void msg_submit(struct mbox_chan *chan) + spin_unlock_irqrestore(&chan->lock, flags); + + if (!err && (chan->txdone_method & TXDONE_BY_POLL)) +- /* kick start the timer immediately to avoid delays */ +- hrtimer_start(&chan->mbox->poll_hrt, 0, HRTIMER_MODE_REL); ++ poll_txdone(&chan->mbox->poll); + } + + static void tx_tick(struct mbox_chan *chan, int r) +@@ -114,10 +115,9 @@ static void tx_tick(struct mbox_chan *chan, int r) + complete(&chan->tx_complete); + } + +-static enum hrtimer_restart txdone_hrtimer(struct hrtimer *hrtimer) ++static void poll_txdone(struct timer_list *t) + { +- struct mbox_controller *mbox = +- container_of(hrtimer, struct mbox_controller, poll_hrt); ++ struct mbox_controller *mbox = from_timer(mbox, t, poll); + bool txdone, resched = false; + int i; + +@@ -133,11 +133,9 @@ static enum hrtimer_restart txdone_hrtimer(struct hrtimer *hrtimer) + } + } + +- if (resched) { +- hrtimer_forward_now(hrtimer, ms_to_ktime(mbox->txpoll_period)); +- return HRTIMER_RESTART; +- } +- return HRTIMER_NORESTART; ++ if (resched) ++ mod_timer(&mbox->poll, jiffies + ++ msecs_to_jiffies(mbox->txpoll_period)); + } + + /** +@@ -466,9 +464,7 @@ int mbox_controller_register(struct mbox_controller *mbox) + return -EINVAL; + } + +- hrtimer_init(&mbox->poll_hrt, CLOCK_MONOTONIC, +- HRTIMER_MODE_REL); +- mbox->poll_hrt.function = txdone_hrtimer; ++ timer_setup(&mbox->poll, &poll_txdone, 0); + } + + for (i = 0; i < mbox->num_chans; i++) { +@@ -510,7 +506,7 @@ void mbox_controller_unregister(struct mbox_controller *mbox) + mbox_free_channel(&mbox->chans[i]); + + if (mbox->txdone_poll) +- hrtimer_cancel(&mbox->poll_hrt); ++ del_timer_sync(&mbox->poll); + + mutex_unlock(&con_mutex); + } +diff --git a/include/linux/mailbox_controller.h b/include/linux/mailbox_controller.h +index 74deadb42..68c424544 100644 +--- a/include/linux/mailbox_controller.h ++++ b/include/linux/mailbox_controller.h +@@ -9,7 +9,7 @@ + + #include + #include +-#include ++#include + #include + #include + +@@ -67,8 +67,7 @@ struct mbox_chan_ops { + * @txpoll_period: If 'txdone_poll' is in effect, the API polls for + * last TX's status after these many millisecs + * @of_xlate: Controller driver specific mapping of channel via DT +- * @poll_hrt: API private. hrtimer used to poll for TXDONE on all +- * channels. ++ * @poll: API private. Used to poll for TXDONE on all channels. + * @node: API private. To hook into list of controllers. + */ + struct mbox_controller { +@@ -82,7 +81,7 @@ struct mbox_controller { + struct mbox_chan *(*of_xlate)(struct mbox_controller *mbox, + const struct of_phandle_args *sp); + /* Internal to API */ +- struct hrtimer poll_hrt; ++ struct timer_list poll; + struct list_head node; + }; + diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/023_linux-4.14.y-backport-net-0001-drivers-net-stmmac-use_setup_timer_helper..patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/023_linux-4.14.y-backport-net-0001-drivers-net-stmmac-use_setup_timer_helper..patch new file mode 100644 index 000000000..fe0312b0b --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/023_linux-4.14.y-backport-net-0001-drivers-net-stmmac-use_setup_timer_helper..patch @@ -0,0 +1,30 @@ +From 997decfb6aeaa9be41ff557741845bb9fb4bf5bc Mon Sep 17 00:00:00 2001 +From: Allen Pais +Date: Thu, 21 Sep 2017 22:35:18 +0530 +Subject: [PATCH] drivers: net: stmmac: use setup_timer() helper. + +Use setup_timer function instead of initializing timer with the + function and data fields. + +Signed-off-by: Allen Pais +Signed-off-by: David S. Miller +--- + drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +index 1763e48c84e20..f41661a04f237 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +@@ -2217,10 +2217,8 @@ static void stmmac_init_tx_coalesce(struct stmmac_priv *priv) + { + priv->tx_coal_frames = STMMAC_TX_FRAMES; + priv->tx_coal_timer = STMMAC_COAL_TX_TIMER; +- init_timer(&priv->txtimer); ++ setup_timer(&priv->txtimer, stmmac_tx_timer, (unsigned long)priv); + priv->txtimer.expires = STMMAC_COAL_TIMER(priv->tx_coal_timer); +- priv->txtimer.data = (unsigned long)priv; +- priv->txtimer.function = stmmac_tx_timer; + add_timer(&priv->txtimer); + } + diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/024_linux-4.14.y-backport-net-0002-net-ethernet-stmmac-clean_up_dead_code.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/024_linux-4.14.y-backport-net-0002-net-ethernet-stmmac-clean_up_dead_code.patch new file mode 100644 index 000000000..ca015c02c --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/024_linux-4.14.y-backport-net-0002-net-ethernet-stmmac-clean_up_dead_code.patch @@ -0,0 +1,70 @@ +From c778c32118167adcfe6b40063c49bfeac6bc1cf1 Mon Sep 17 00:00:00 2001 +From: Christos Gkekas +Date: Sun, 8 Oct 2017 20:13:49 +0100 +Subject: [PATCH] net: ethernet: stmmac: Clean up dead code + +Many macros in dwmac-ipq806x are unused and should be removed. +Moreover gmac->id is an unsigned variable and therefore checking +whether it is less than zero is redundant. + +Signed-off-by: Christos Gkekas +Signed-off-by: David S. Miller +--- + drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c | 14 +------------- + 1 file changed, 1 insertion(+), 13 deletions(-) + +diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c +index 866444b6c82fa..2c6d7c69c8f74 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c ++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c +@@ -51,15 +51,11 @@ + #define NSS_COMMON_CLK_SRC_CTRL_RGMII(x) 1 + #define NSS_COMMON_CLK_SRC_CTRL_SGMII(x) ((x >= 2) ? 1 : 0) + +-#define NSS_COMMON_MACSEC_CTL 0x28 +-#define NSS_COMMON_MACSEC_CTL_EXT_BYPASS_EN(x) (1 << x) +- + #define NSS_COMMON_GMAC_CTL(x) (0x30 + (x * 4)) + #define NSS_COMMON_GMAC_CTL_CSYS_REQ BIT(19) + #define NSS_COMMON_GMAC_CTL_PHY_IFACE_SEL BIT(16) + #define NSS_COMMON_GMAC_CTL_IFG_LIMIT_OFFSET 8 + #define NSS_COMMON_GMAC_CTL_IFG_OFFSET 0 +-#define NSS_COMMON_GMAC_CTL_IFG_MASK 0x3f + + #define NSS_COMMON_CLK_DIV_RGMII_1000 1 + #define NSS_COMMON_CLK_DIV_RGMII_100 9 +@@ -68,9 +64,6 @@ + #define NSS_COMMON_CLK_DIV_SGMII_100 4 + #define NSS_COMMON_CLK_DIV_SGMII_10 49 + +-#define QSGMII_PCS_MODE_CTL 0x68 +-#define QSGMII_PCS_MODE_CTL_AUTONEG_EN(x) BIT((x * 8) + 7) +- + #define QSGMII_PCS_CAL_LCKDT_CTL 0x120 + #define QSGMII_PCS_CAL_LCKDT_CTL_RST BIT(19) + +@@ -83,15 +76,10 @@ + #define QSGMII_PHY_TX_DRIVER_EN BIT(3) + #define QSGMII_PHY_QSGMII_EN BIT(7) + #define QSGMII_PHY_PHASE_LOOP_GAIN_OFFSET 12 +-#define QSGMII_PHY_PHASE_LOOP_GAIN_MASK 0x7 + #define QSGMII_PHY_RX_DC_BIAS_OFFSET 18 +-#define QSGMII_PHY_RX_DC_BIAS_MASK 0x3 + #define QSGMII_PHY_RX_INPUT_EQU_OFFSET 20 +-#define QSGMII_PHY_RX_INPUT_EQU_MASK 0x3 + #define QSGMII_PHY_CDR_PI_SLEW_OFFSET 22 +-#define QSGMII_PHY_CDR_PI_SLEW_MASK 0x3 + #define QSGMII_PHY_TX_DRV_AMP_OFFSET 28 +-#define QSGMII_PHY_TX_DRV_AMP_MASK 0xf + + struct ipq806x_gmac { + struct platform_device *pdev; +@@ -217,7 +205,7 @@ static int ipq806x_gmac_of_parse(struct ipq806x_gmac *gmac) + * code and keep it consistent with the Linux convention, we'll number + * them from 0 to 3 here. + */ +- if (gmac->id < 0 || gmac->id > 3) { ++ if (gmac->id > 3) { + dev_err(dev, "invalid gmac id\n"); + return -EINVAL; + } diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/025_linux-4.14.y-backport-net-0003-net-stmmac-use_correct_values_in_tqs-rqs_fields.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/025_linux-4.14.y-backport-net-0003-net-stmmac-use_correct_values_in_tqs-rqs_fields.patch new file mode 100644 index 000000000..0f7210435 --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/025_linux-4.14.y-backport-net-0003-net-stmmac-use_correct_values_in_tqs-rqs_fields.patch @@ -0,0 +1,135 @@ +From 52a76235d0c4dd259cd0df503afed4757c04ba1d Mon Sep 17 00:00:00 2001 +From: Jose Abreu +Date: Fri, 13 Oct 2017 10:58:36 +0100 +Subject: [PATCH] net: stmmac: Use correct values in TQS/RQS fields + +Currently we are using all the available fifo size in RQS and +TQS fields. This will not work correctly in multi-queues IP's +because total fifo size must be splitted to the enabled queues. + +Correct this by computing the available fifo size per queue and +setting the right value in TQS and RQS fields. + +Signed-off-by: Jose Abreu +Cc: David S. Miller +Cc: Joao Pinto +Cc: Giuseppe Cavallaro +Cc: Alexandre Torgue +Signed-off-by: David S. Miller +--- + drivers/net/ethernet/stmicro/stmmac/common.h | 3 ++- + drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c | 15 +++++++++------ + drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 22 ++++++++++++++++++++-- + 3 files changed, 31 insertions(+), 9 deletions(-) + +diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h +index e82b4b70b7be3..c26c8a7f957f5 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/common.h ++++ b/drivers/net/ethernet/stmicro/stmmac/common.h +@@ -443,7 +443,8 @@ struct stmmac_dma_ops { + int rxfifosz); + void (*dma_rx_mode)(void __iomem *ioaddr, int mode, u32 channel, + int fifosz); +- void (*dma_tx_mode)(void __iomem *ioaddr, int mode, u32 channel); ++ void (*dma_tx_mode)(void __iomem *ioaddr, int mode, u32 channel, ++ int fifosz); + /* To track extra statistic (if supported) */ + void (*dma_diagnostic_fr) (void *data, struct stmmac_extra_stats *x, + void __iomem *ioaddr); +diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c +index e84831e1b63b3..898849bbc7d44 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c ++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c +@@ -271,9 +271,10 @@ static void dwmac4_dma_rx_chan_op_mode(void __iomem *ioaddr, int mode, + } + + static void dwmac4_dma_tx_chan_op_mode(void __iomem *ioaddr, int mode, +- u32 channel) ++ u32 channel, int fifosz) + { + u32 mtl_tx_op = readl(ioaddr + MTL_CHAN_TX_OP_MODE(channel)); ++ unsigned int tqs = fifosz / 256 - 1; + + if (mode == SF_DMA_MODE) { + pr_debug("GMAC: enable TX store and forward mode\n"); +@@ -306,12 +307,14 @@ static void dwmac4_dma_tx_chan_op_mode(void __iomem *ioaddr, int mode, + * For an IP with DWC_EQOS_NUM_TXQ > 1, the fields TXQEN and TQS are R/W + * with reset values: TXQEN off, TQS 256 bytes. + * +- * Write the bits in both cases, since it will have no effect when RO. +- * For DWC_EQOS_NUM_TXQ > 1, the top bits in MTL_OP_MODE_TQS_MASK might +- * be RO, however, writing the whole TQS field will result in a value +- * equal to DWC_EQOS_TXFIFO_SIZE, just like for DWC_EQOS_NUM_TXQ == 1. ++ * TXQEN must be written for multi-channel operation and TQS must ++ * reflect the available fifo size per queue (total fifo size / number ++ * of enabled queues). + */ +- mtl_tx_op |= MTL_OP_MODE_TXQEN | MTL_OP_MODE_TQS_MASK; ++ mtl_tx_op |= MTL_OP_MODE_TXQEN; ++ mtl_tx_op &= ~MTL_OP_MODE_TQS_MASK; ++ mtl_tx_op |= tqs << MTL_OP_MODE_TQS_SHIFT; ++ + writel(mtl_tx_op, ioaddr + MTL_CHAN_TX_OP_MODE(channel)); + } + +diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +index f41661a04f237..edf245b8bce32 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +@@ -1750,12 +1750,19 @@ static void stmmac_dma_operation_mode(struct stmmac_priv *priv) + u32 rx_channels_count = priv->plat->rx_queues_to_use; + u32 tx_channels_count = priv->plat->tx_queues_to_use; + int rxfifosz = priv->plat->rx_fifo_size; ++ int txfifosz = priv->plat->tx_fifo_size; + u32 txmode = 0; + u32 rxmode = 0; + u32 chan = 0; + + if (rxfifosz == 0) + rxfifosz = priv->dma_cap.rx_fifo_size; ++ if (txfifosz == 0) ++ txfifosz = priv->dma_cap.tx_fifo_size; ++ ++ /* Adjust for real per queue fifo size */ ++ rxfifosz /= rx_channels_count; ++ txfifosz /= tx_channels_count; + + if (priv->plat->force_thresh_dma_mode) { + txmode = tc; +@@ -1783,7 +1790,8 @@ static void stmmac_dma_operation_mode(struct stmmac_priv *priv) + rxfifosz); + + for (chan = 0; chan < tx_channels_count; chan++) +- priv->hw->dma->dma_tx_mode(priv->ioaddr, txmode, chan); ++ priv->hw->dma->dma_tx_mode(priv->ioaddr, txmode, chan, ++ txfifosz); + } else { + priv->hw->dma->dma_mode(priv->ioaddr, txmode, rxmode, + rxfifosz); +@@ -1946,15 +1954,25 @@ static void stmmac_tx_err(struct stmmac_priv *priv, u32 chan) + static void stmmac_set_dma_operation_mode(struct stmmac_priv *priv, u32 txmode, + u32 rxmode, u32 chan) + { ++ u32 rx_channels_count = priv->plat->rx_queues_to_use; ++ u32 tx_channels_count = priv->plat->tx_queues_to_use; + int rxfifosz = priv->plat->rx_fifo_size; ++ int txfifosz = priv->plat->tx_fifo_size; + + if (rxfifosz == 0) + rxfifosz = priv->dma_cap.rx_fifo_size; ++ if (txfifosz == 0) ++ txfifosz = priv->dma_cap.tx_fifo_size; ++ ++ /* Adjust for real per queue fifo size */ ++ rxfifosz /= rx_channels_count; ++ txfifosz /= tx_channels_count; + + if (priv->synopsys_id >= DWMAC_CORE_4_00) { + priv->hw->dma->dma_rx_mode(priv->ioaddr, rxmode, chan, + rxfifosz); +- priv->hw->dma->dma_tx_mode(priv->ioaddr, txmode, chan); ++ priv->hw->dma->dma_tx_mode(priv->ioaddr, txmode, chan, ++ txfifosz); + } else { + priv->hw->dma->dma_mode(priv->ioaddr, txmode, rxmode, + rxfifosz); diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/026_linux-4.14.y-backport-net-0004-net-stmmac-disable_flow_ctrl_for_rx_avb_queues_and_really.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/026_linux-4.14.y-backport-net-0004-net-stmmac-disable_flow_ctrl_for_rx_avb_queues_and_really.patch new file mode 100644 index 000000000..d000df779 --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/026_linux-4.14.y-backport-net-0004-net-stmmac-disable_flow_ctrl_for_rx_avb_queues_and_really.patch @@ -0,0 +1,160 @@ +From a0daae13776994cf90e9a7bc81cd8e4ad3959093 Mon Sep 17 00:00:00 2001 +From: Jose Abreu +Date: Fri, 13 Oct 2017 10:58:37 +0100 +Subject: [PATCH] net: stmmac: Disable flow ctrl for RX AVB queues and really + enable TX AVB queues + +Flow control must be disabled for AVB enabled queues and TX +AVB queues must be enabled by setting BIT(2) of TXQEN. + +Correct this by passing the queue mode to DMA callbacks +and by checking in these functions wether we are in AVB +performing the necessary adjustments. + +Signed-off-by: Jose Abreu +Cc: David S. Miller +Cc: Joao Pinto +Cc: Giuseppe Cavallaro +Cc: Alexandre Torgue +Signed-off-by: David S. Miller +--- + drivers/net/ethernet/stmicro/stmmac/common.h | 4 ++-- + drivers/net/ethernet/stmicro/stmmac/dwmac4.h | 2 ++ + drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c | 16 +++++++++++----- + drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 21 +++++++++++++++------ + 4 files changed, 30 insertions(+), 13 deletions(-) + +diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h +index c26c8a7f957f5..e1e5ac0537606 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/common.h ++++ b/drivers/net/ethernet/stmicro/stmmac/common.h +@@ -442,9 +442,9 @@ struct stmmac_dma_ops { + void (*dma_mode)(void __iomem *ioaddr, int txmode, int rxmode, + int rxfifosz); + void (*dma_rx_mode)(void __iomem *ioaddr, int mode, u32 channel, +- int fifosz); ++ int fifosz, u8 qmode); + void (*dma_tx_mode)(void __iomem *ioaddr, int mode, u32 channel, +- int fifosz); ++ int fifosz, u8 qmode); + /* To track extra statistic (if supported) */ + void (*dma_diagnostic_fr) (void *data, struct stmmac_extra_stats *x, + void __iomem *ioaddr); +diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4.h b/drivers/net/ethernet/stmicro/stmmac/dwmac4.h +index d74cedf2a3975..aeda3ab2d761c 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4.h ++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4.h +@@ -225,6 +225,8 @@ enum power_event { + #define MTL_CHAN_RX_DEBUG(x) (MTL_CHANX_BASE_ADDR(x) + 0x38) + + #define MTL_OP_MODE_RSF BIT(5) ++#define MTL_OP_MODE_TXQEN_MASK GENMASK(3, 2) ++#define MTL_OP_MODE_TXQEN_AV BIT(2) + #define MTL_OP_MODE_TXQEN BIT(3) + #define MTL_OP_MODE_TSF BIT(1) + +diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c +index 898849bbc7d44..c110f6850ffa3 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c ++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c +@@ -191,7 +191,7 @@ static void dwmac4_rx_watchdog(void __iomem *ioaddr, u32 riwt, u32 number_chan) + } + + static void dwmac4_dma_rx_chan_op_mode(void __iomem *ioaddr, int mode, +- u32 channel, int fifosz) ++ u32 channel, int fifosz, u8 qmode) + { + unsigned int rqs = fifosz / 256 - 1; + u32 mtl_rx_op, mtl_rx_int; +@@ -218,8 +218,10 @@ static void dwmac4_dma_rx_chan_op_mode(void __iomem *ioaddr, int mode, + mtl_rx_op &= ~MTL_OP_MODE_RQS_MASK; + mtl_rx_op |= rqs << MTL_OP_MODE_RQS_SHIFT; + +- /* enable flow control only if each channel gets 4 KiB or more FIFO */ +- if (fifosz >= 4096) { ++ /* Enable flow control only if each channel gets 4 KiB or more FIFO and ++ * only if channel is not an AVB channel. ++ */ ++ if ((fifosz >= 4096) && (qmode != MTL_QUEUE_AVB)) { + unsigned int rfd, rfa; + + mtl_rx_op |= MTL_OP_MODE_EHFC; +@@ -271,7 +273,7 @@ static void dwmac4_dma_rx_chan_op_mode(void __iomem *ioaddr, int mode, + } + + static void dwmac4_dma_tx_chan_op_mode(void __iomem *ioaddr, int mode, +- u32 channel, int fifosz) ++ u32 channel, int fifosz, u8 qmode) + { + u32 mtl_tx_op = readl(ioaddr + MTL_CHAN_TX_OP_MODE(channel)); + unsigned int tqs = fifosz / 256 - 1; +@@ -311,7 +313,11 @@ static void dwmac4_dma_tx_chan_op_mode(void __iomem *ioaddr, int mode, + * reflect the available fifo size per queue (total fifo size / number + * of enabled queues). + */ +- mtl_tx_op |= MTL_OP_MODE_TXQEN; ++ mtl_tx_op &= ~MTL_OP_MODE_TXQEN_MASK; ++ if (qmode != MTL_QUEUE_AVB) ++ mtl_tx_op |= MTL_OP_MODE_TXQEN; ++ else ++ mtl_tx_op |= MTL_OP_MODE_TXQEN_AV; + mtl_tx_op &= ~MTL_OP_MODE_TQS_MASK; + mtl_tx_op |= tqs << MTL_OP_MODE_TQS_SHIFT; + +diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +index edf245b8bce32..0e1b0a3d7b766 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +@@ -1754,6 +1754,7 @@ static void stmmac_dma_operation_mode(struct stmmac_priv *priv) + u32 txmode = 0; + u32 rxmode = 0; + u32 chan = 0; ++ u8 qmode = 0; + + if (rxfifosz == 0) + rxfifosz = priv->dma_cap.rx_fifo_size; +@@ -1785,13 +1786,19 @@ static void stmmac_dma_operation_mode(struct stmmac_priv *priv) + + /* configure all channels */ + if (priv->synopsys_id >= DWMAC_CORE_4_00) { +- for (chan = 0; chan < rx_channels_count; chan++) ++ for (chan = 0; chan < rx_channels_count; chan++) { ++ qmode = priv->plat->rx_queues_cfg[chan].mode_to_use; ++ + priv->hw->dma->dma_rx_mode(priv->ioaddr, rxmode, chan, +- rxfifosz); ++ rxfifosz, qmode); ++ } ++ ++ for (chan = 0; chan < tx_channels_count; chan++) { ++ qmode = priv->plat->tx_queues_cfg[chan].mode_to_use; + +- for (chan = 0; chan < tx_channels_count; chan++) + priv->hw->dma->dma_tx_mode(priv->ioaddr, txmode, chan, +- txfifosz); ++ txfifosz, qmode); ++ } + } else { + priv->hw->dma->dma_mode(priv->ioaddr, txmode, rxmode, + rxfifosz); +@@ -1954,6 +1961,8 @@ static void stmmac_tx_err(struct stmmac_priv *priv, u32 chan) + static void stmmac_set_dma_operation_mode(struct stmmac_priv *priv, u32 txmode, + u32 rxmode, u32 chan) + { ++ u8 rxqmode = priv->plat->rx_queues_cfg[chan].mode_to_use; ++ u8 txqmode = priv->plat->tx_queues_cfg[chan].mode_to_use; + u32 rx_channels_count = priv->plat->rx_queues_to_use; + u32 tx_channels_count = priv->plat->tx_queues_to_use; + int rxfifosz = priv->plat->rx_fifo_size; +@@ -1970,9 +1979,9 @@ static void stmmac_set_dma_operation_mode(struct stmmac_priv *priv, u32 txmode, + + if (priv->synopsys_id >= DWMAC_CORE_4_00) { + priv->hw->dma->dma_rx_mode(priv->ioaddr, rxmode, chan, +- rxfifosz); ++ rxfifosz, rxqmode); + priv->hw->dma->dma_tx_mode(priv->ioaddr, txmode, chan, +- txfifosz); ++ txfifosz, txqmode); + } else { + priv->hw->dma->dma_mode(priv->ioaddr, txmode, rxmode, + rxfifosz); diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/027_linux-4.14.y-backport-net-0005-net-ethernet-stmmac-convert_timers_to_use_timer_setup.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/027_linux-4.14.y-backport-net-0005-net-ethernet-stmmac-convert_timers_to_use_timer_setup.patch new file mode 100644 index 000000000..972bba081 --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/027_linux-4.14.y-backport-net-0005-net-ethernet-stmmac-convert_timers_to_use_timer_setup.patch @@ -0,0 +1,90 @@ +From abec4be3ee68c8572adb39da68fbfd86e63daa84 Mon Sep 17 00:00:00 2001 +From: Kees Cook +Date: Mon, 16 Oct 2017 17:29:00 -0700 +Subject: [PATCH] net: ethernet: stmmac: Convert timers to use timer_setup() + +In preparation for unconditionally passing the struct timer_list pointer to +all timer callbacks, switch to using the new timer_setup() and from_timer() +to pass the timer pointer explicitly. + +Cc: Giuseppe Cavallaro +Cc: Alexandre Torgue +Cc: netdev@vger.kernel.org +Signed-off-by: Kees Cook +Acked-by: Giuseppe Cavallaro +Signed-off-by: David S. Miller +--- + drivers/net/ethernet/stmicro/stmmac/altr_tse_pcs.c | 22 ++++++++++------------ + 1 file changed, 10 insertions(+), 12 deletions(-) + +diff --git a/drivers/net/ethernet/stmicro/stmmac/altr_tse_pcs.c b/drivers/net/ethernet/stmicro/stmmac/altr_tse_pcs.c +index 6a9c954492f22..8b50afcdb52df 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/altr_tse_pcs.c ++++ b/drivers/net/ethernet/stmicro/stmmac/altr_tse_pcs.c +@@ -118,10 +118,9 @@ int tse_pcs_init(void __iomem *base, struct tse_pcs *pcs) + return ret; + } + +-static void pcs_link_timer_callback(unsigned long data) ++static void pcs_link_timer_callback(struct tse_pcs *pcs) + { + u16 val = 0; +- struct tse_pcs *pcs = (struct tse_pcs *)data; + void __iomem *tse_pcs_base = pcs->tse_pcs_base; + void __iomem *sgmii_adapter_base = pcs->sgmii_adapter_base; + +@@ -138,12 +137,11 @@ static void pcs_link_timer_callback(unsigned long data) + } + } + +-static void auto_nego_timer_callback(unsigned long data) ++static void auto_nego_timer_callback(struct tse_pcs *pcs) + { + u16 val = 0; + u16 speed = 0; + u16 duplex = 0; +- struct tse_pcs *pcs = (struct tse_pcs *)data; + void __iomem *tse_pcs_base = pcs->tse_pcs_base; + void __iomem *sgmii_adapter_base = pcs->sgmii_adapter_base; + +@@ -201,14 +199,14 @@ static void auto_nego_timer_callback(unsigned long data) + } + } + +-static void aneg_link_timer_callback(unsigned long data) ++static void aneg_link_timer_callback(struct timer_list *t) + { +- struct tse_pcs *pcs = (struct tse_pcs *)data; ++ struct tse_pcs *pcs = from_timer(pcs, t, aneg_link_timer); + + if (pcs->autoneg == AUTONEG_ENABLE) +- auto_nego_timer_callback(data); ++ auto_nego_timer_callback(pcs); + else if (pcs->autoneg == AUTONEG_DISABLE) +- pcs_link_timer_callback(data); ++ pcs_link_timer_callback(pcs); + } + + void tse_pcs_fix_mac_speed(struct tse_pcs *pcs, struct phy_device *phy_dev, +@@ -237,8 +235,8 @@ void tse_pcs_fix_mac_speed(struct tse_pcs *pcs, struct phy_device *phy_dev, + + tse_pcs_reset(tse_pcs_base, pcs); + +- setup_timer(&pcs->aneg_link_timer, +- aneg_link_timer_callback, (unsigned long)pcs); ++ timer_setup(&pcs->aneg_link_timer, aneg_link_timer_callback, ++ 0); + mod_timer(&pcs->aneg_link_timer, jiffies + + msecs_to_jiffies(AUTONEGO_LINK_TIMER)); + } else if (phy_dev->autoneg == AUTONEG_DISABLE) { +@@ -270,8 +268,8 @@ void tse_pcs_fix_mac_speed(struct tse_pcs *pcs, struct phy_device *phy_dev, + + tse_pcs_reset(tse_pcs_base, pcs); + +- setup_timer(&pcs->aneg_link_timer, +- aneg_link_timer_callback, (unsigned long)pcs); ++ timer_setup(&pcs->aneg_link_timer, aneg_link_timer_callback, ++ 0); + mod_timer(&pcs->aneg_link_timer, jiffies + + msecs_to_jiffies(AUTONEGO_LINK_TIMER)); + } diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/028_linux-4.14.y-backport-net-0006-net-stmmac-snps,_dwmac-mdio_mdios_are_automatically.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/028_linux-4.14.y-backport-net-0006-net-stmmac-snps,_dwmac-mdio_mdios_are_automatically.patch new file mode 100644 index 000000000..2719bfd29 --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/028_linux-4.14.y-backport-net-0006-net-stmmac-snps,_dwmac-mdio_mdios_are_automatically.patch @@ -0,0 +1,35 @@ +From b5beecb580376cd8d959eb990abece6a748a3ce3 Mon Sep 17 00:00:00 2001 +From: Corentin Labbe +Date: Tue, 24 Oct 2017 19:57:12 +0200 +Subject: [PATCH] net: stmmac: snps, dwmac-mdio MDIOs are automatically + registered + +stmmac bindings docs said that its mdio node must have +compatible = "snps,dwmac-mdio"; +Since dwmac-sun8i does not have any good reasons to not doing it, all +their MDIO node must have it. + +Since these compatible is automatically registered, dwmac-sun8i compatible +does not need to be in need_mdio_ids. + +Signed-off-by: Corentin Labbe +Signed-off-by: David S. Miller +--- + drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +index 8a280b48e3a9f..9e616da0745d6 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +@@ -311,10 +311,6 @@ static int stmmac_dt_phy(struct plat_stmmacenet_data *plat, + bool mdio = true; + static const struct of_device_id need_mdio_ids[] = { + { .compatible = "snps,dwc-qos-ethernet-4.10" }, +- { .compatible = "allwinner,sun8i-a83t-emac" }, +- { .compatible = "allwinner,sun8i-h3-emac" }, +- { .compatible = "allwinner,sun8i-v3s-emac" }, +- { .compatible = "allwinner,sun50i-a64-emac" }, + {}, + }; + diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/029_linux-4.14.y-backport-net-0007-net-stmmac-dwmac-sun8i-handle_integrated-external_mdios.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/029_linux-4.14.y-backport-net-0007-net-stmmac-dwmac-sun8i-handle_integrated-external_mdios.patch new file mode 100644 index 000000000..841e83e8b --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/029_linux-4.14.y-backport-net-0007-net-stmmac-dwmac-sun8i-handle_integrated-external_mdios.patch @@ -0,0 +1,510 @@ +From 634db83b82658f4641d8026e340c6027cf74a6bb Mon Sep 17 00:00:00 2001 +From: Corentin Labbe +Date: Tue, 24 Oct 2017 19:57:13 +0200 +Subject: [PATCH] net: stmmac: dwmac-sun8i: Handle integrated/external MDIOs + +The Allwinner H3 SoC have two distinct MDIO bus, only one could be +active at the same time. +The selection of the active MDIO bus are done via some bits in the EMAC +register of the system controller. + +This patch implement this MDIO switch via a custom MDIO-mux. + +Signed-off-by: Corentin Labbe +Reviewed-by: Andrew Lunn +Signed-off-by: David S. Miller +--- + drivers/net/ethernet/stmicro/stmmac/Kconfig | 1 + + drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c | 353 ++++++++++++++-------- + 2 files changed, 224 insertions(+), 130 deletions(-) + +diff --git a/drivers/net/ethernet/stmicro/stmmac/Kconfig b/drivers/net/ethernet/stmicro/stmmac/Kconfig +index 97035766c291b..e28c0d2c58e91 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/Kconfig ++++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig +@@ -159,6 +159,7 @@ config DWMAC_SUN8I + tristate "Allwinner sun8i GMAC support" + default ARCH_SUNXI + depends on OF && (ARCH_SUNXI || COMPILE_TEST) ++ select MDIO_BUS_MUX + ---help--- + Support for Allwinner H3 A83T A64 EMAC ethernet controllers. + +diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c +index 39c2122a4f269..b3eb344bb158d 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c ++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c +@@ -17,6 +17,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -41,14 +42,14 @@ + * This value is used for disabling properly EMAC + * and used as a good starting value in case of the + * boot process(uboot) leave some stuff. +- * @internal_phy: Does the MAC embed an internal PHY ++ * @soc_has_internal_phy: Does the MAC embed an internal PHY + * @support_mii: Does the MAC handle MII + * @support_rmii: Does the MAC handle RMII + * @support_rgmii: Does the MAC handle RGMII + */ + struct emac_variant { + u32 default_syscon_value; +- int internal_phy; ++ bool soc_has_internal_phy; + bool support_mii; + bool support_rmii; + bool support_rgmii; +@@ -61,7 +62,8 @@ struct emac_variant { + * @rst_ephy: reference to the optional EPHY reset for the internal PHY + * @variant: reference to the current board variant + * @regmap: regmap for using the syscon +- * @use_internal_phy: Does the current PHY choice imply using the internal PHY ++ * @internal_phy_powered: Does the internal PHY is enabled ++ * @mux_handle: Internal pointer used by mdio-mux lib + */ + struct sunxi_priv_data { + struct clk *tx_clk; +@@ -70,12 +72,13 @@ struct sunxi_priv_data { + struct reset_control *rst_ephy; + const struct emac_variant *variant; + struct regmap *regmap; +- bool use_internal_phy; ++ bool internal_phy_powered; ++ void *mux_handle; + }; + + static const struct emac_variant emac_variant_h3 = { + .default_syscon_value = 0x58000, +- .internal_phy = PHY_INTERFACE_MODE_MII, ++ .soc_has_internal_phy = true, + .support_mii = true, + .support_rmii = true, + .support_rgmii = true +@@ -83,20 +86,20 @@ static const struct emac_variant emac_variant_h3 = { + + static const struct emac_variant emac_variant_v3s = { + .default_syscon_value = 0x38000, +- .internal_phy = PHY_INTERFACE_MODE_MII, ++ .soc_has_internal_phy = true, + .support_mii = true + }; + + static const struct emac_variant emac_variant_a83t = { + .default_syscon_value = 0, +- .internal_phy = 0, ++ .soc_has_internal_phy = false, + .support_mii = true, + .support_rgmii = true + }; + + static const struct emac_variant emac_variant_a64 = { + .default_syscon_value = 0, +- .internal_phy = 0, ++ .soc_has_internal_phy = false, + .support_mii = true, + .support_rmii = true, + .support_rgmii = true +@@ -195,6 +198,9 @@ static const struct emac_variant emac_variant_a64 = { + #define H3_EPHY_LED_POL BIT(17) /* 1: active low, 0: active high */ + #define H3_EPHY_SHUTDOWN BIT(16) /* 1: shutdown, 0: power up */ + #define H3_EPHY_SELECT BIT(15) /* 1: internal PHY, 0: external PHY */ ++#define H3_EPHY_MUX_MASK (H3_EPHY_SHUTDOWN | H3_EPHY_SELECT) ++#define DWMAC_SUN8I_MDIO_MUX_INTERNAL_ID 1 ++#define DWMAC_SUN8I_MDIO_MUX_EXTERNAL_ID 2 + + /* H3/A64 specific bits */ + #define SYSCON_RMII_EN BIT(13) /* 1: enable RMII (overrides EPIT) */ +@@ -634,6 +640,159 @@ static int sun8i_dwmac_reset(struct stmmac_priv *priv) + return 0; + } + ++/* Search in mdio-mux node for internal PHY node and get its clk/reset */ ++static int get_ephy_nodes(struct stmmac_priv *priv) ++{ ++ struct sunxi_priv_data *gmac = priv->plat->bsp_priv; ++ struct device_node *mdio_mux, *iphynode; ++ struct device_node *mdio_internal; ++ int ret; ++ ++ mdio_mux = of_get_child_by_name(priv->device->of_node, "mdio-mux"); ++ if (!mdio_mux) { ++ dev_err(priv->device, "Cannot get mdio-mux node\n"); ++ return -ENODEV; ++ } ++ ++ mdio_internal = of_find_compatible_node(mdio_mux, NULL, ++ "allwinner,sun8i-h3-mdio-internal"); ++ if (!mdio_internal) { ++ dev_err(priv->device, "Cannot get internal_mdio node\n"); ++ return -ENODEV; ++ } ++ ++ /* Seek for internal PHY */ ++ for_each_child_of_node(mdio_internal, iphynode) { ++ gmac->ephy_clk = of_clk_get(iphynode, 0); ++ if (IS_ERR(gmac->ephy_clk)) ++ continue; ++ gmac->rst_ephy = of_reset_control_get_exclusive(iphynode, NULL); ++ if (IS_ERR(gmac->rst_ephy)) { ++ ret = PTR_ERR(gmac->rst_ephy); ++ if (ret == -EPROBE_DEFER) ++ return ret; ++ continue; ++ } ++ dev_info(priv->device, "Found internal PHY node\n"); ++ return 0; ++ } ++ return -ENODEV; ++} ++ ++static int sun8i_dwmac_power_internal_phy(struct stmmac_priv *priv) ++{ ++ struct sunxi_priv_data *gmac = priv->plat->bsp_priv; ++ int ret; ++ ++ if (gmac->internal_phy_powered) { ++ dev_warn(priv->device, "Internal PHY already powered\n"); ++ return 0; ++ } ++ ++ dev_info(priv->device, "Powering internal PHY\n"); ++ ret = clk_prepare_enable(gmac->ephy_clk); ++ if (ret) { ++ dev_err(priv->device, "Cannot enable internal PHY\n"); ++ return ret; ++ } ++ ++ /* Make sure the EPHY is properly reseted, as U-Boot may leave ++ * it at deasserted state, and thus it may fail to reset EMAC. ++ */ ++ reset_control_assert(gmac->rst_ephy); ++ ++ ret = reset_control_deassert(gmac->rst_ephy); ++ if (ret) { ++ dev_err(priv->device, "Cannot deassert internal phy\n"); ++ clk_disable_unprepare(gmac->ephy_clk); ++ return ret; ++ } ++ ++ gmac->internal_phy_powered = true; ++ ++ return 0; ++} ++ ++static int sun8i_dwmac_unpower_internal_phy(struct sunxi_priv_data *gmac) ++{ ++ if (!gmac->internal_phy_powered) ++ return 0; ++ ++ clk_disable_unprepare(gmac->ephy_clk); ++ reset_control_assert(gmac->rst_ephy); ++ gmac->internal_phy_powered = false; ++ return 0; ++} ++ ++/* MDIO multiplexing switch function ++ * This function is called by the mdio-mux layer when it thinks the mdio bus ++ * multiplexer needs to switch. ++ * 'current_child' is the current value of the mux register ++ * 'desired_child' is the value of the 'reg' property of the target child MDIO ++ * node. ++ * The first time this function is called, current_child == -1. ++ * If current_child == desired_child, then the mux is already set to the ++ * correct bus. ++ */ ++static int mdio_mux_syscon_switch_fn(int current_child, int desired_child, ++ void *data) ++{ ++ struct stmmac_priv *priv = data; ++ struct sunxi_priv_data *gmac = priv->plat->bsp_priv; ++ u32 reg, val; ++ int ret = 0; ++ bool need_power_ephy = false; ++ ++ if (current_child ^ desired_child) { ++ regmap_read(gmac->regmap, SYSCON_EMAC_REG, ®); ++ switch (desired_child) { ++ case DWMAC_SUN8I_MDIO_MUX_INTERNAL_ID: ++ dev_info(priv->device, "Switch mux to internal PHY"); ++ val = (reg & ~H3_EPHY_MUX_MASK) | H3_EPHY_SELECT; ++ ++ need_power_ephy = true; ++ break; ++ case DWMAC_SUN8I_MDIO_MUX_EXTERNAL_ID: ++ dev_info(priv->device, "Switch mux to external PHY"); ++ val = (reg & ~H3_EPHY_MUX_MASK) | H3_EPHY_SHUTDOWN; ++ need_power_ephy = false; ++ break; ++ default: ++ dev_err(priv->device, "Invalid child ID %x\n", ++ desired_child); ++ return -EINVAL; ++ } ++ regmap_write(gmac->regmap, SYSCON_EMAC_REG, val); ++ if (need_power_ephy) { ++ ret = sun8i_dwmac_power_internal_phy(priv); ++ if (ret) ++ return ret; ++ } else { ++ sun8i_dwmac_unpower_internal_phy(gmac); ++ } ++ /* After changing syscon value, the MAC need reset or it will ++ * use the last value (and so the last PHY set). ++ */ ++ ret = sun8i_dwmac_reset(priv); ++ } ++ return ret; ++} ++ ++static int sun8i_dwmac_register_mdio_mux(struct stmmac_priv *priv) ++{ ++ int ret; ++ struct device_node *mdio_mux; ++ struct sunxi_priv_data *gmac = priv->plat->bsp_priv; ++ ++ mdio_mux = of_get_child_by_name(priv->device->of_node, "mdio-mux"); ++ if (!mdio_mux) ++ return -ENODEV; ++ ++ ret = mdio_mux_init(priv->device, mdio_mux, mdio_mux_syscon_switch_fn, ++ &gmac->mux_handle, priv, priv->mii); ++ return ret; ++} ++ + static int sun8i_dwmac_set_syscon(struct stmmac_priv *priv) + { + struct sunxi_priv_data *gmac = priv->plat->bsp_priv; +@@ -648,35 +807,25 @@ static int sun8i_dwmac_set_syscon(struct stmmac_priv *priv) + "Current syscon value is not the default %x (expect %x)\n", + val, reg); + +- if (gmac->variant->internal_phy) { +- if (!gmac->use_internal_phy) { +- /* switch to external PHY interface */ +- reg &= ~H3_EPHY_SELECT; +- } else { +- reg |= H3_EPHY_SELECT; +- reg &= ~H3_EPHY_SHUTDOWN; +- dev_dbg(priv->device, "Select internal_phy %x\n", reg); +- +- if (of_property_read_bool(priv->plat->phy_node, +- "allwinner,leds-active-low")) +- reg |= H3_EPHY_LED_POL; +- else +- reg &= ~H3_EPHY_LED_POL; +- +- /* Force EPHY xtal frequency to 24MHz. */ +- reg |= H3_EPHY_CLK_SEL; +- +- ret = of_mdio_parse_addr(priv->device, +- priv->plat->phy_node); +- if (ret < 0) { +- dev_err(priv->device, "Could not parse MDIO addr\n"); +- return ret; +- } +- /* of_mdio_parse_addr returns a valid (0 ~ 31) PHY +- * address. No need to mask it again. +- */ +- reg |= ret << H3_EPHY_ADDR_SHIFT; ++ if (gmac->variant->soc_has_internal_phy) { ++ if (of_property_read_bool(priv->plat->phy_node, ++ "allwinner,leds-active-low")) ++ reg |= H3_EPHY_LED_POL; ++ else ++ reg &= ~H3_EPHY_LED_POL; ++ ++ /* Force EPHY xtal frequency to 24MHz. */ ++ reg |= H3_EPHY_CLK_SEL; ++ ++ ret = of_mdio_parse_addr(priv->device, priv->plat->phy_node); ++ if (ret < 0) { ++ dev_err(priv->device, "Could not parse MDIO addr\n"); ++ return ret; + } ++ /* of_mdio_parse_addr returns a valid (0 ~ 31) PHY ++ * address. No need to mask it again. ++ */ ++ reg |= 1 << H3_EPHY_ADDR_SHIFT; + } + + if (!of_property_read_u32(node, "allwinner,tx-delay-ps", &val)) { +@@ -746,81 +895,21 @@ static void sun8i_dwmac_unset_syscon(struct sunxi_priv_data *gmac) + regmap_write(gmac->regmap, SYSCON_EMAC_REG, reg); + } + +-static int sun8i_dwmac_power_internal_phy(struct stmmac_priv *priv) ++static void sun8i_dwmac_exit(struct platform_device *pdev, void *priv) + { +- struct sunxi_priv_data *gmac = priv->plat->bsp_priv; +- int ret; +- +- if (!gmac->use_internal_phy) +- return 0; +- +- ret = clk_prepare_enable(gmac->ephy_clk); +- if (ret) { +- dev_err(priv->device, "Cannot enable ephy\n"); +- return ret; +- } +- +- /* Make sure the EPHY is properly reseted, as U-Boot may leave +- * it at deasserted state, and thus it may fail to reset EMAC. +- */ +- reset_control_assert(gmac->rst_ephy); ++ struct sunxi_priv_data *gmac = priv; + +- ret = reset_control_deassert(gmac->rst_ephy); +- if (ret) { +- dev_err(priv->device, "Cannot deassert ephy\n"); +- clk_disable_unprepare(gmac->ephy_clk); +- return ret; ++ if (gmac->variant->soc_has_internal_phy) { ++ /* sun8i_dwmac_exit could be called with mdiomux uninit */ ++ if (gmac->mux_handle) ++ mdio_mux_uninit(gmac->mux_handle); ++ if (gmac->internal_phy_powered) ++ sun8i_dwmac_unpower_internal_phy(gmac); + } + +- return 0; +-} +- +-static int sun8i_dwmac_unpower_internal_phy(struct sunxi_priv_data *gmac) +-{ +- if (!gmac->use_internal_phy) +- return 0; +- +- clk_disable_unprepare(gmac->ephy_clk); +- reset_control_assert(gmac->rst_ephy); +- return 0; +-} +- +-/* sun8i_power_phy() - Activate the PHY: +- * In case of error, no need to call sun8i_unpower_phy(), +- * it will be called anyway by sun8i_dwmac_exit() +- */ +-static int sun8i_power_phy(struct stmmac_priv *priv) +-{ +- int ret; +- +- ret = sun8i_dwmac_power_internal_phy(priv); +- if (ret) +- return ret; +- +- ret = sun8i_dwmac_set_syscon(priv); +- if (ret) +- return ret; +- +- /* After changing syscon value, the MAC need reset or it will use +- * the last value (and so the last PHY set. +- */ +- ret = sun8i_dwmac_reset(priv); +- if (ret) +- return ret; +- return 0; +-} +- +-static void sun8i_unpower_phy(struct sunxi_priv_data *gmac) +-{ + sun8i_dwmac_unset_syscon(gmac); +- sun8i_dwmac_unpower_internal_phy(gmac); +-} +- +-static void sun8i_dwmac_exit(struct platform_device *pdev, void *priv) +-{ +- struct sunxi_priv_data *gmac = priv; + +- sun8i_unpower_phy(gmac); ++ reset_control_put(gmac->rst_ephy); + + clk_disable_unprepare(gmac->tx_clk); + +@@ -849,7 +938,7 @@ static struct mac_device_info *sun8i_dwmac_setup(void *ppriv) + if (!mac) + return NULL; + +- ret = sun8i_power_phy(priv); ++ ret = sun8i_dwmac_set_syscon(priv); + if (ret) + return NULL; + +@@ -889,6 +978,8 @@ static int sun8i_dwmac_probe(struct platform_device *pdev) + struct sunxi_priv_data *gmac; + struct device *dev = &pdev->dev; + int ret; ++ struct stmmac_priv *priv; ++ struct net_device *ndev; + + ret = stmmac_get_platform_resources(pdev, &stmmac_res); + if (ret) +@@ -932,29 +1023,6 @@ static int sun8i_dwmac_probe(struct platform_device *pdev) + } + + plat_dat->interface = of_get_phy_mode(dev->of_node); +- if (plat_dat->interface == gmac->variant->internal_phy) { +- dev_info(&pdev->dev, "Will use internal PHY\n"); +- gmac->use_internal_phy = true; +- gmac->ephy_clk = of_clk_get(plat_dat->phy_node, 0); +- if (IS_ERR(gmac->ephy_clk)) { +- ret = PTR_ERR(gmac->ephy_clk); +- dev_err(&pdev->dev, "Cannot get EPHY clock: %d\n", ret); +- return -EINVAL; +- } +- +- gmac->rst_ephy = of_reset_control_get(plat_dat->phy_node, NULL); +- if (IS_ERR(gmac->rst_ephy)) { +- ret = PTR_ERR(gmac->rst_ephy); +- if (ret == -EPROBE_DEFER) +- return ret; +- dev_err(&pdev->dev, "No EPHY reset control found %d\n", +- ret); +- return -EINVAL; +- } +- } else { +- dev_info(&pdev->dev, "Will use external PHY\n"); +- gmac->use_internal_phy = false; +- } + + /* platform data specifying hardware features and callbacks. + * hardware features were copied from Allwinner drivers. +@@ -973,9 +1041,34 @@ static int sun8i_dwmac_probe(struct platform_device *pdev) + + ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res); + if (ret) +- sun8i_dwmac_exit(pdev, plat_dat->bsp_priv); ++ goto dwmac_exit; ++ ++ ndev = dev_get_drvdata(&pdev->dev); ++ priv = netdev_priv(ndev); ++ /* The mux must be registered after parent MDIO ++ * so after stmmac_dvr_probe() ++ */ ++ if (gmac->variant->soc_has_internal_phy) { ++ ret = get_ephy_nodes(priv); ++ if (ret) ++ goto dwmac_exit; ++ ret = sun8i_dwmac_register_mdio_mux(priv); ++ if (ret) { ++ dev_err(&pdev->dev, "Failed to register mux\n"); ++ goto dwmac_mux; ++ } ++ } else { ++ ret = sun8i_dwmac_reset(priv); ++ if (ret) ++ goto dwmac_exit; ++ } + + return ret; ++dwmac_mux: ++ sun8i_dwmac_unset_syscon(gmac); ++dwmac_exit: ++ sun8i_dwmac_exit(pdev, plat_dat->bsp_priv); ++return ret; + } + + static const struct of_device_id sun8i_dwmac_match[] = { diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/030_linux-4.14.y-backport-net-0008-net-stmmac-sun8i-restore_the_compatibles.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/030_linux-4.14.y-backport-net-0008-net-stmmac-sun8i-restore_the_compatibles.patch new file mode 100644 index 000000000..6cfb68188 --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/030_linux-4.14.y-backport-net-0008-net-stmmac-sun8i-restore_the_compatibles.patch @@ -0,0 +1,37 @@ +From a8ff8ccb45d37efa64476958fc5e9a8d9716b23b Mon Sep 17 00:00:00 2001 +From: Corentin Labbe +Date: Tue, 24 Oct 2017 19:57:14 +0200 +Subject: [PATCH] net: stmmac: sun8i: Restore the compatibles + +The original dwmac-sun8i DT bindings have some issue on how to handle +integrated PHY and was reverted in last RC of 4.13. +But now we have a solution so we need to get back that was reverted. + +This patch restore compatibles about dwmac-sun8i +This reverts commit ad4540cc5aa3 ("net: stmmac: sun8i: Remove the compatibles") + +Signed-off-by: Corentin Labbe +Signed-off-by: David S. Miller +--- + drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c +index b3eb344bb158d..e5ff734d4f9b2 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c ++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c +@@ -1072,6 +1072,14 @@ return ret; + } + + static const struct of_device_id sun8i_dwmac_match[] = { ++ { .compatible = "allwinner,sun8i-h3-emac", ++ .data = &emac_variant_h3 }, ++ { .compatible = "allwinner,sun8i-v3s-emac", ++ .data = &emac_variant_v3s }, ++ { .compatible = "allwinner,sun8i-a83t-emac", ++ .data = &emac_variant_a83t }, ++ { .compatible = "allwinner,sun50i-a64-emac", ++ .data = &emac_variant_a64 }, + { } + }; + MODULE_DEVICE_TABLE(of, sun8i_dwmac_match); diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/031_linux-4.14.y-backport-net-0009-net-stmmac-fix_lpi_transitioning_for_dwmac4.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/031_linux-4.14.y-backport-net-0009-net-stmmac-fix_lpi_transitioning_for_dwmac4.patch new file mode 100644 index 000000000..b31f8dae4 --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/031_linux-4.14.y-backport-net-0009-net-stmmac-fix_lpi_transitioning_for_dwmac4.patch @@ -0,0 +1,106 @@ +From 4497478c60c04d2bf37082e27fc98f4f835db96b Mon Sep 17 00:00:00 2001 +From: Niklas Cassel +Date: Tue, 14 Nov 2017 11:15:54 +0100 +Subject: [PATCH] net: stmmac: fix LPI transitioning for dwmac4 + +The LPI transitioning logic in stmmac_main uses +priv->tx_path_in_lpi_mode to enter/exit LPI. + +However, priv->tx_path_in_lpi_mode is assigned +using the return value from host_irq_status(). + +So for dwmac4, priv->tx_path_in_lpi_mode was always false, +so stmmac_tx_clean() would always try to put us in eee mode, +and stmmac_xmit() would never take us out of eee mode. + +To fix this, make host_irq_status() read and return the LPI +irq status also for dwmac4. + +This also increments the existing LPI counters, so that +ethtool --statistics shows LPI transitions also for dwmac4. + +For dwmac1000, irqs are enabled/disabled using the register +named "Interrupt Mask Register", and thus setting a bit disables +that specific irq. + +For dwmac4 the matching register is named "MAC_Interrupt_Enable", +and thus setting a bit enables that specific irq. + +Looking at dwmac1000_core.c, the irqs that are always enabled are: +LPI and PMT. + +Looking at dwmac4_core.c, the irqs that are always enabled are: +PMT. + +To be able to read the LPI irq status, we need to enable the LPI +irq also for dwmac4. + +Signed-off-by: Niklas Cassel +Signed-off-by: David S. Miller +--- + drivers/net/ethernet/stmicro/stmmac/dwmac4.h | 7 ++++++- + drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c | 19 +++++++++++++++++++ + 2 files changed, 25 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4.h b/drivers/net/ethernet/stmicro/stmmac/dwmac4.h +index aeda3ab2d761c..789dad8a07b5c 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4.h ++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4.h +@@ -98,7 +98,7 @@ + #define GMAC_PCS_IRQ_DEFAULT (GMAC_INT_RGSMIIS | GMAC_INT_PCS_LINK | \ + GMAC_INT_PCS_ANE) + +-#define GMAC_INT_DEFAULT_MASK GMAC_INT_PMT_EN ++#define GMAC_INT_DEFAULT_MASK (GMAC_INT_PMT_EN | GMAC_INT_LPI_EN) + + enum dwmac4_irq_status { + time_stamp_irq = 0x00001000, +@@ -106,6 +106,7 @@ enum dwmac4_irq_status { + mmc_tx_irq = 0x00000400, + mmc_rx_irq = 0x00000200, + mmc_irq = 0x00000100, ++ lpi_irq = 0x00000020, + pmt_irq = 0x00000010, + }; + +@@ -132,6 +133,10 @@ enum power_event { + #define GMAC4_LPI_CTRL_STATUS_LPITXA BIT(19) /* Enable LPI TX Automate */ + #define GMAC4_LPI_CTRL_STATUS_PLS BIT(17) /* PHY Link Status */ + #define GMAC4_LPI_CTRL_STATUS_LPIEN BIT(16) /* LPI Enable */ ++#define GMAC4_LPI_CTRL_STATUS_RLPIEX BIT(3) /* Receive LPI Exit */ ++#define GMAC4_LPI_CTRL_STATUS_RLPIEN BIT(2) /* Receive LPI Entry */ ++#define GMAC4_LPI_CTRL_STATUS_TLPIEX BIT(1) /* Transmit LPI Exit */ ++#define GMAC4_LPI_CTRL_STATUS_TLPIEN BIT(0) /* Transmit LPI Entry */ + + /* MAC Debug bitmap */ + #define GMAC_DEBUG_TFCSTS_MASK GENMASK(18, 17) +diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c +index 2f7d7ec59962a..f3ed8f7853eb4 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c ++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c +@@ -580,6 +580,25 @@ static int dwmac4_irq_status(struct mac_device_info *hw, + x->irq_receive_pmt_irq_n++; + } + ++ /* MAC tx/rx EEE LPI entry/exit interrupts */ ++ if (intr_status & lpi_irq) { ++ /* Clear LPI interrupt by reading MAC_LPI_Control_Status */ ++ u32 status = readl(ioaddr + GMAC4_LPI_CTRL_STATUS); ++ ++ if (status & GMAC4_LPI_CTRL_STATUS_TLPIEN) { ++ ret |= CORE_IRQ_TX_PATH_IN_LPI_MODE; ++ x->irq_tx_path_in_lpi_mode_n++; ++ } ++ if (status & GMAC4_LPI_CTRL_STATUS_TLPIEX) { ++ ret |= CORE_IRQ_TX_PATH_EXIT_LPI_MODE; ++ x->irq_tx_path_exit_lpi_mode_n++; ++ } ++ if (status & GMAC4_LPI_CTRL_STATUS_RLPIEN) ++ x->irq_rx_path_in_lpi_mode_n++; ++ if (status & GMAC4_LPI_CTRL_STATUS_RLPIEX) ++ x->irq_rx_path_exit_lpi_mode_n++; ++ } ++ + dwmac_pcs_isr(ioaddr, GMAC_PCS_BASE, intr_status, x); + if (intr_status & PCS_RGSMIIIS_IRQ) + dwmac4_phystatus(ioaddr, x); diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/032_linux-4.14.y-backport-net-0010-net-stmmac-dwmac-sun8i-fix_allwinner,leds-active-low.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/032_linux-4.14.y-backport-net-0010-net-stmmac-dwmac-sun8i-fix_allwinner,leds-active-low.patch new file mode 100644 index 000000000..7435b7af2 --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/032_linux-4.14.y-backport-net-0010-net-stmmac-dwmac-sun8i-fix_allwinner,leds-active-low.patch @@ -0,0 +1,32 @@ +From 1c08ac0c4bd8e9d66c4dde29bc496c3b430dd028 Mon Sep 17 00:00:00 2001 +From: Corentin Labbe +Date: Tue, 28 Nov 2017 17:48:22 +0100 +Subject: [PATCH] net: stmmac: dwmac-sun8i: fix allwinner,leds-active-low + handling + +The driver expect "allwinner,leds-active-low" to be in PHY node, but +the binding doc expect it to be in MAC node. + +Since all board DT use it also in MAC node, the driver need to search +allwinner,leds-active-low in MAC node. + +Signed-off-by: Corentin Labbe +Signed-off-by: David S. Miller +--- + drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c +index e5ff734d4f9b2..9eb7f65d8000d 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c ++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c +@@ -808,8 +808,7 @@ static int sun8i_dwmac_set_syscon(struct stmmac_priv *priv) + val, reg); + + if (gmac->variant->soc_has_internal_phy) { +- if (of_property_read_bool(priv->plat->phy_node, +- "allwinner,leds-active-low")) ++ if (of_property_read_bool(node, "allwinner,leds-active-low")) + reg |= H3_EPHY_LED_POL; + else + reg &= ~H3_EPHY_LED_POL; diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/033_linux-4.14.y-backport-net-0011-ethernet-dwmac-stm32-fix_copyright.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/033_linux-4.14.y-backport-net-0011-ethernet-dwmac-stm32-fix_copyright.patch new file mode 100644 index 000000000..ae376676a --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/033_linux-4.14.y-backport-net-0011-ethernet-dwmac-stm32-fix_copyright.patch @@ -0,0 +1,30 @@ +From f6454f80e8a965fca203dab28723f68ec78db608 Mon Sep 17 00:00:00 2001 +From: Benjamin Gaignard +Date: Wed, 29 Nov 2017 15:20:00 +0100 +Subject: [PATCH] ethernet: dwmac-stm32: Fix copyright + +Uniformize STMicroelectronics copyrights header + +Signed-off-by: Benjamin Gaignard +CC: Alexandre Torgue +Acked-by: Alexandre TORGUE +Signed-off-by: David S. Miller +--- + drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c +index 61cb24810d101..9e6db16af663b 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c ++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c +@@ -1,8 +1,8 @@ + /* + * dwmac-stm32.c - DWMAC Specific Glue layer for STM32 MCU + * +- * Copyright (C) Alexandre Torgue 2015 +- * Author: Alexandre Torgue ++ * Copyright (C) STMicroelectronics SA 2017 ++ * Author: Alexandre Torgue for STMicroelectronics. + * License terms: GNU General Public License (GPL), version 2 + * + */ diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/034_linux-4.14.y-backport-net-0012-net-stmmac-fix_broken_dma_interrupt_handling_for.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/034_linux-4.14.y-backport-net-0012-net-stmmac-fix_broken_dma_interrupt_handling_for.patch new file mode 100644 index 000000000..cf763e6da --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/034_linux-4.14.y-backport-net-0012-net-stmmac-fix_broken_dma_interrupt_handling_for.patch @@ -0,0 +1,128 @@ +From 5a6a0445d1edb28fc89fd12b49cda2d5114e2665 Mon Sep 17 00:00:00 2001 +From: Niklas Cassel +Date: Thu, 7 Dec 2017 23:56:10 +0100 +Subject: [PATCH] net: stmmac: fix broken dma_interrupt handling for + multi-queues + +There is nothing that says that number of TX queues == number of RX +queues. E.g. the ARTPEC-6 SoC has 2 TX queues and 1 RX queue. + +This code is obviously wrong: +for (chan = 0; chan < tx_channel_count; chan++) { + struct stmmac_rx_queue *rx_q = &priv->rx_queue[chan]; + +priv->rx_queue has size MTL_MAX_RX_QUEUES, so this will send an +uninitialized napi_struct to __napi_schedule(), causing us to +crash in net_rx_action(), because napi_struct->poll is zero. + +[12846.759880] Unable to handle kernel NULL pointer dereference at virtual address 00000000 +[12846.768014] pgd = (ptrval) +[12846.770742] [00000000] *pgd=39ec7831, *pte=00000000, *ppte=00000000 +[12846.777023] Internal error: Oops: 80000007 [#1] PREEMPT SMP ARM +[12846.782942] Modules linked in: +[12846.785998] CPU: 0 PID: 161 Comm: dropbear Not tainted 4.15.0-rc2-00285-gf5fb5f2f39a7 #36 +[12846.794177] Hardware name: Axis ARTPEC-6 Platform +[12846.798879] task: (ptrval) task.stack: (ptrval) +[12846.803407] PC is at 0x0 +[12846.805942] LR is at net_rx_action+0x274/0x43c +[12846.810383] pc : [<00000000>] lr : [<80bff064>] psr: 200e0113 +[12846.816648] sp : b90d9ae8 ip : b90d9ae8 fp : b90d9b44 +[12846.821871] r10: 00000008 r9 : 0013250e r8 : 00000100 +[12846.827094] r7 : 0000012c r6 : 00000000 r5 : 00000001 r4 : bac84900 +[12846.833619] r3 : 00000000 r2 : b90d9b08 r1 : 00000000 r0 : bac84900 + +Since each DMA channel can be used for rx and tx simultaneously, +the current code should probably be rewritten so that napi_struct is +embedded in a new struct stmmac_channel. +That way, stmmac_poll() can call stmmac_tx_clean() on just the tx queue +where we got the IRQ, instead of looping through all tx queues. +This is also how the xgbe driver does it (another driver for this IP). + +Fixes: c22a3f48ef99 ("net: stmmac: adding multiple napi mechanism") +Signed-off-by: Niklas Cassel +Signed-off-by: David S. Miller +--- + drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 54 +++++++++++++++++++---- + 1 file changed, 46 insertions(+), 8 deletions(-) + +diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +index d7250539d0bd0..c52a9963c19d5 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +@@ -1997,22 +1997,60 @@ static void stmmac_set_dma_operation_mode(struct stmmac_priv *priv, u32 txmode, + static void stmmac_dma_interrupt(struct stmmac_priv *priv) + { + u32 tx_channel_count = priv->plat->tx_queues_to_use; +- int status; ++ u32 rx_channel_count = priv->plat->rx_queues_to_use; ++ u32 channels_to_check = tx_channel_count > rx_channel_count ? ++ tx_channel_count : rx_channel_count; + u32 chan; ++ bool poll_scheduled = false; ++ int status[channels_to_check]; ++ ++ /* Each DMA channel can be used for rx and tx simultaneously, yet ++ * napi_struct is embedded in struct stmmac_rx_queue rather than in a ++ * stmmac_channel struct. ++ * Because of this, stmmac_poll currently checks (and possibly wakes) ++ * all tx queues rather than just a single tx queue. ++ */ ++ for (chan = 0; chan < channels_to_check; chan++) ++ status[chan] = priv->hw->dma->dma_interrupt(priv->ioaddr, ++ &priv->xstats, ++ chan); + +- for (chan = 0; chan < tx_channel_count; chan++) { +- struct stmmac_rx_queue *rx_q = &priv->rx_queue[chan]; ++ for (chan = 0; chan < rx_channel_count; chan++) { ++ if (likely(status[chan] & handle_rx)) { ++ struct stmmac_rx_queue *rx_q = &priv->rx_queue[chan]; + +- status = priv->hw->dma->dma_interrupt(priv->ioaddr, +- &priv->xstats, chan); +- if (likely((status & handle_rx)) || (status & handle_tx)) { + if (likely(napi_schedule_prep(&rx_q->napi))) { + stmmac_disable_dma_irq(priv, chan); + __napi_schedule(&rx_q->napi); ++ poll_scheduled = true; ++ } ++ } ++ } ++ ++ /* If we scheduled poll, we already know that tx queues will be checked. ++ * If we didn't schedule poll, see if any DMA channel (used by tx) has a ++ * completed transmission, if so, call stmmac_poll (once). ++ */ ++ if (!poll_scheduled) { ++ for (chan = 0; chan < tx_channel_count; chan++) { ++ if (status[chan] & handle_tx) { ++ /* It doesn't matter what rx queue we choose ++ * here. We use 0 since it always exists. ++ */ ++ struct stmmac_rx_queue *rx_q = ++ &priv->rx_queue[0]; ++ ++ if (likely(napi_schedule_prep(&rx_q->napi))) { ++ stmmac_disable_dma_irq(priv, chan); ++ __napi_schedule(&rx_q->napi); ++ } ++ break; + } + } ++ } + +- if (unlikely(status & tx_hard_error_bump_tc)) { ++ for (chan = 0; chan < tx_channel_count; chan++) { ++ if (unlikely(status[chan] & tx_hard_error_bump_tc)) { + /* Try to bump up the dma threshold on this failure */ + if (unlikely(priv->xstats.threshold != SF_DMA_MODE) && + (tc <= 256)) { +@@ -2029,7 +2067,7 @@ static void stmmac_dma_interrupt(struct stmmac_priv *priv) + chan); + priv->xstats.threshold = tc; + } +- } else if (unlikely(status == tx_hard_error)) { ++ } else if (unlikely(status[chan] == tx_hard_error)) { + stmmac_tx_err(priv, chan); + } + } diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/035_linux-4.14.y-backport-net-0013-net-stmmac-pad_ring_number_with_zeroes_in_display_ring.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/035_linux-4.14.y-backport-net-0013-net-stmmac-pad_ring_number_with_zeroes_in_display_ring.patch new file mode 100644 index 000000000..d6a39b820 --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/035_linux-4.14.y-backport-net-0013-net-stmmac-pad_ring_number_with_zeroes_in_display_ring.patch @@ -0,0 +1,56 @@ +From bdb421663d936eb9b29c743a668614276cf3b97d Mon Sep 17 00:00:00 2001 +From: Florian Fainelli +Date: Fri, 29 Dec 2017 19:56:32 -0800 +Subject: [PATCH] net: stmmac: Pad ring number with zeroes in display_ring() + +Make the printing of the ring number consistent and properly aligned by +padding the ring number with up to 3 zeroes, which covers the maximum +ring size. This makes it a lot easier to see outliers in debug prints. + +Signed-off-by: Florian Fainelli +Signed-off-by: David S. Miller +--- + drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c | 2 +- + drivers/net/ethernet/stmicro/stmmac/enh_desc.c | 2 +- + drivers/net/ethernet/stmicro/stmmac/norm_desc.c | 2 +- + 3 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c +index 7e089bf906b4f..2fd8456999f69 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c ++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c +@@ -406,7 +406,7 @@ static void dwmac4_display_ring(void *head, unsigned int size, bool rx) + pr_info("%s descriptor ring:\n", rx ? "RX" : "TX"); + + for (i = 0; i < size; i++) { +- pr_info("%d [0x%x]: 0x%x 0x%x 0x%x 0x%x\n", ++ pr_info("%03d [0x%x]: 0x%x 0x%x 0x%x 0x%x\n", + i, (unsigned int)virt_to_phys(p), + le32_to_cpu(p->des0), le32_to_cpu(p->des1), + le32_to_cpu(p->des2), le32_to_cpu(p->des3)); +diff --git a/drivers/net/ethernet/stmicro/stmmac/enh_desc.c b/drivers/net/ethernet/stmicro/stmmac/enh_desc.c +index 2a828a3128142..b47cb5c4da513 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/enh_desc.c ++++ b/drivers/net/ethernet/stmicro/stmmac/enh_desc.c +@@ -428,7 +428,7 @@ static void enh_desc_display_ring(void *head, unsigned int size, bool rx) + u64 x; + + x = *(u64 *)ep; +- pr_info("%d [0x%x]: 0x%x 0x%x 0x%x 0x%x\n", ++ pr_info("%03d [0x%x]: 0x%x 0x%x 0x%x 0x%x\n", + i, (unsigned int)virt_to_phys(ep), + (unsigned int)x, (unsigned int)(x >> 32), + ep->basic.des2, ep->basic.des3); +diff --git a/drivers/net/ethernet/stmicro/stmmac/norm_desc.c b/drivers/net/ethernet/stmicro/stmmac/norm_desc.c +index db4cee57bb246..ebd9e5e00f161 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/norm_desc.c ++++ b/drivers/net/ethernet/stmicro/stmmac/norm_desc.c +@@ -288,7 +288,7 @@ static void ndesc_display_ring(void *head, unsigned int size, bool rx) + u64 x; + + x = *(u64 *)p; +- pr_info("%d [0x%x]: 0x%x 0x%x 0x%x 0x%x", ++ pr_info("%03d [0x%x]: 0x%x 0x%x 0x%x 0x%x", + i, (unsigned int)virt_to_phys(p), + (unsigned int)x, (unsigned int)(x >> 32), + p->des2, p->des3); diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/036_linux-4.14.y-backport-net-0014-net-stmmac-dwmac-meson8b-only_configure_the_clocks_in.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/036_linux-4.14.y-backport-net-0014-net-stmmac-dwmac-meson8b-only_configure_the_clocks_in.patch new file mode 100644 index 000000000..c68200318 --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/036_linux-4.14.y-backport-net-0014-net-stmmac-dwmac-meson8b-only_configure_the_clocks_in.patch @@ -0,0 +1,133 @@ +From 37512b42f082d784a012c3734ef109f25d199786 Mon Sep 17 00:00:00 2001 +From: Martin Blumenstingl +Date: Mon, 15 Jan 2018 18:10:12 +0100 +Subject: [PATCH] net: stmmac: dwmac-meson8b: only configure the clocks in + RGMII mode + +Neither the m25_div_clk nor the m250_div_clk or m250_mux_clk are used in +RMII mode. The m25_div_clk output is routed to the RGMII PHY's "RGMII +clock". +This means that we don't need to configure the clocks in RMII mode. The +driver however did this - with no effect since the clocks are not routed +to the PHY in RMII mode. + +While here also rename meson8b_init_clk to meson8b_init_rgmii_tx_clk to +make it easier to understand the code. + +Fixes: 566e8251625304 ("net: stmmac: add a glue driver for the Amlogic Meson 8b / GXBB DWMAC") +Signed-off-by: Martin Blumenstingl +Tested-by: Jerome Brunet +Signed-off-by: David S. Miller +--- + .../net/ethernet/stmicro/stmmac/dwmac-meson8b.c | 46 ++++++++++------------ + 1 file changed, 21 insertions(+), 25 deletions(-) + +diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c +index 4404650b32c5e..c6f87e9c4ccb3 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c ++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c +@@ -81,7 +81,7 @@ static void meson8b_dwmac_mask_bits(struct meson8b_dwmac *dwmac, u32 reg, + writel(data, dwmac->regs + reg); + } + +-static int meson8b_init_clk(struct meson8b_dwmac *dwmac) ++static int meson8b_init_rgmii_tx_clk(struct meson8b_dwmac *dwmac) + { + struct clk_init_data init; + int i, ret; +@@ -176,7 +176,6 @@ static int meson8b_init_clk(struct meson8b_dwmac *dwmac) + static int meson8b_init_prg_eth(struct meson8b_dwmac *dwmac) + { + int ret; +- unsigned long clk_rate; + u8 tx_dly_val = 0; + + switch (dwmac->phy_mode) { +@@ -191,9 +190,6 @@ static int meson8b_init_prg_eth(struct meson8b_dwmac *dwmac) + + case PHY_INTERFACE_MODE_RGMII_ID: + case PHY_INTERFACE_MODE_RGMII_TXID: +- /* Generate a 25MHz clock for the PHY */ +- clk_rate = 25 * 1000 * 1000; +- + /* enable RGMII mode */ + meson8b_dwmac_mask_bits(dwmac, PRG_ETH0, PRG_ETH0_RGMII_MODE, + PRG_ETH0_RGMII_MODE); +@@ -204,12 +200,24 @@ static int meson8b_init_prg_eth(struct meson8b_dwmac *dwmac) + + meson8b_dwmac_mask_bits(dwmac, PRG_ETH0, PRG_ETH0_TXDLY_MASK, + tx_dly_val << PRG_ETH0_TXDLY_SHIFT); ++ ++ ret = clk_prepare_enable(dwmac->m25_div_clk); ++ if (ret) { ++ dev_err(&dwmac->pdev->dev, "failed to enable the PHY clock\n"); ++ return ret; ++ } ++ ++ /* Generate the 25MHz RGMII clock for the PHY */ ++ ret = clk_set_rate(dwmac->m25_div_clk, 25 * 1000 * 1000); ++ if (ret) { ++ clk_disable_unprepare(dwmac->m25_div_clk); ++ ++ dev_err(&dwmac->pdev->dev, "failed to set PHY clock\n"); ++ return ret; ++ } + break; + + case PHY_INTERFACE_MODE_RMII: +- /* Use the rate of the mux clock for the internal RMII PHY */ +- clk_rate = clk_get_rate(dwmac->m250_mux_clk); +- + /* disable RGMII mode -> enables RMII mode */ + meson8b_dwmac_mask_bits(dwmac, PRG_ETH0, PRG_ETH0_RGMII_MODE, + 0); +@@ -231,20 +239,6 @@ static int meson8b_init_prg_eth(struct meson8b_dwmac *dwmac) + return -EINVAL; + } + +- ret = clk_prepare_enable(dwmac->m25_div_clk); +- if (ret) { +- dev_err(&dwmac->pdev->dev, "failed to enable the PHY clock\n"); +- return ret; +- } +- +- ret = clk_set_rate(dwmac->m25_div_clk, clk_rate); +- if (ret) { +- clk_disable_unprepare(dwmac->m25_div_clk); +- +- dev_err(&dwmac->pdev->dev, "failed to set PHY clock\n"); +- return ret; +- } +- + /* enable TX_CLK and PHY_REF_CLK generator */ + meson8b_dwmac_mask_bits(dwmac, PRG_ETH0, PRG_ETH0_TX_AND_PHY_REF_CLK, + PRG_ETH0_TX_AND_PHY_REF_CLK); +@@ -294,7 +288,7 @@ static int meson8b_dwmac_probe(struct platform_device *pdev) + &dwmac->tx_delay_ns)) + dwmac->tx_delay_ns = 2; + +- ret = meson8b_init_clk(dwmac); ++ ret = meson8b_init_rgmii_tx_clk(dwmac); + if (ret) + goto err_remove_config_dt; + +@@ -311,7 +305,8 @@ static int meson8b_dwmac_probe(struct platform_device *pdev) + return 0; + + err_clk_disable: +- clk_disable_unprepare(dwmac->m25_div_clk); ++ if (phy_interface_mode_is_rgmii(dwmac->phy_mode)) ++ clk_disable_unprepare(dwmac->m25_div_clk); + err_remove_config_dt: + stmmac_remove_config_dt(pdev, plat_dat); + +@@ -322,7 +317,8 @@ static int meson8b_dwmac_remove(struct platform_device *pdev) + { + struct meson8b_dwmac *dwmac = get_stmmac_bsp_priv(&pdev->dev); + +- clk_disable_unprepare(dwmac->m25_div_clk); ++ if (phy_interface_mode_is_rgmii(dwmac->phy_mode)) ++ clk_disable_unprepare(dwmac->m25_div_clk); + + return stmmac_pltfr_remove(pdev); + } diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/037_linux-4.14.y-backport-net-0015-net-stmmac-dwmac-meson8b-fix_internal_rgmii_clock.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/037_linux-4.14.y-backport-net-0015-net-stmmac-dwmac-meson8b-fix_internal_rgmii_clock.patch new file mode 100644 index 000000000..31786ee28 --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/037_linux-4.14.y-backport-net-0015-net-stmmac-dwmac-meson8b-fix_internal_rgmii_clock.patch @@ -0,0 +1,215 @@ +From 4f6a71b84e1afdf13827741e7421a844203cf8d0 Mon Sep 17 00:00:00 2001 +From: Martin Blumenstingl +Date: Mon, 15 Jan 2018 18:10:13 +0100 +Subject: [PATCH] net: stmmac: dwmac-meson8b: fix internal RGMII clock + configuration +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Tests (using an oscilloscope and an Odroid-C1 board with a RTL8211F +RGMII PHY) have shown that the PRG_ETH0 register behaves as follows: +- bit 4 is a mux to choose between two parent clocks. according to the + public S805 datasheet the only supported parent clock is MPLL2 (this + was not verified using the oscilloscope). + The public S805/S905 datasheet claims that this bit is reserved. +- bits 9:7 control a one-based divider (register value 1 means "divide + by 1", etc.) for the input clock. we call this clock the "m250_div" + clock because it's value is always supposed to be (close to) 250MHz + (see below for an explanation). + The description in the public S805/S905 datasheet is a bit cryptic, + but it comes down to "input clock = 250MHz * value" (which could also + be expressed as "250MHz = input clock / value") +- there seems to be an internal fixed divide-by-2 clock which takes the + output from the m250_div and divides it by 2. This is not unusual on + Amlogic SoCs, since the SDIO (MMC) driver also uses an internal fixed + divide-by-2 clock. + This is not documented in the public S805/S905 datasheet +- bit 10 controls a gate clock which enables or disables the RGMII TX + clock (which is an output on the MAC/SoC and an input in the PHY). we + call this the "rgmii_tx_en" clock. if this bit is set to "0" the RGMII + TX clock output is close to 0 + The description for this bit in the public S805/S905 datasheet is + "Generate 25MHz clock for PHY". Based on these tests it's believed + that this is wrong, and should probably read "Generate the 125MHz + RGMII TX clock for the PHY" +- the RGMII TX clock has to be set to 125MHz - the IP block adjusts the + output (automatically) depending on the line speed (RGMII specifies + that Gbit connections use a 125MHz clock, 100Mbit/s connections use a + 25MHz clock and 10Mbit/s connections use a 2.5MHz clock. only Gbit and + 100Mbit/s were tested with an oscilloscope). Due to the requirement + that this clock always has to be set to 125MHz and due to the fixed + divide-by-2 parent clock this means that m250_div will always end up + with a rate of (close to) 250MHz. +- bits 6:5 are the TX delay, which is also named "clock phase" in some + of Amlogic's older GPL kernel sources. + +The PHY also has an XTAL_IN pin where a 25MHz clock has to be provided. +Tests with the oscilloscope have shown that this is routed to a crystal +right next to the RTL8211F PHY. The same seems to be true on the Khadas +VIM2 (which uses a GXM SoC) board - however the 25MHz crystal is on the +other side of the PCB there. + +This updates the clocks in the dwmac-meson8b driver by replacing the +"m25_div" with the "rgmii_tx_en" clock and additionally introducing a +fixed divide-by-2 clock between "m250_div" and "rgmii_tx_en". +Now we also need to set a frequency of 125MHz on the RGMII clock +(opposed to the 25MHz we set before, with that non-existing +divide-by-5-or-10 divider). + +Special thanks go to Linus Lüssing for testing the various bits and +checking the results with an oscilloscope on his Odroid-C1! + +Fixes: 566e8251625304 ("net: stmmac: add a glue driver for the Amlogic Meson 8b / GXBB DWMAC") +Reported-by: Emiliano Ingrassia +Signed-off-by: Martin Blumenstingl +Acked-by: Jerome Brunet +Tested-by: Jerome Brunet +Signed-off-by: David S. Miller +--- + .../net/ethernet/stmicro/stmmac/dwmac-meson8b.c | 79 +++++++++++++--------- + 1 file changed, 47 insertions(+), 32 deletions(-) + +diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c +index c6f87e9c4ccb3..7930a152dd634 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c ++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c +@@ -40,9 +40,7 @@ + #define PRG_ETH0_CLK_M250_DIV_SHIFT 7 + #define PRG_ETH0_CLK_M250_DIV_WIDTH 3 + +-/* divides the result of m25_sel by either 5 (bit unset) or 10 (bit set) */ +-#define PRG_ETH0_CLK_M25_DIV_SHIFT 10 +-#define PRG_ETH0_CLK_M25_DIV_WIDTH 1 ++#define PRG_ETH0_RGMII_TX_CLK_EN 10 + + #define PRG_ETH0_INVERTED_RMII_CLK BIT(11) + #define PRG_ETH0_TX_AND_PHY_REF_CLK BIT(12) +@@ -63,8 +61,11 @@ struct meson8b_dwmac { + struct clk_divider m250_div; + struct clk *m250_div_clk; + +- struct clk_divider m25_div; +- struct clk *m25_div_clk; ++ struct clk_fixed_factor fixed_div2; ++ struct clk *fixed_div2_clk; ++ ++ struct clk_gate rgmii_tx_en; ++ struct clk *rgmii_tx_en_clk; + + u32 tx_delay_ns; + }; +@@ -89,11 +90,6 @@ static int meson8b_init_rgmii_tx_clk(struct meson8b_dwmac *dwmac) + char clk_name[32]; + const char *clk_div_parents[1]; + const char *mux_parent_names[MUX_CLK_NUM_PARENTS]; +- static const struct clk_div_table clk_25m_div_table[] = { +- { .val = 0, .div = 5 }, +- { .val = 1, .div = 10 }, +- { /* sentinel */ }, +- }; + + /* get the mux parents from DT */ + for (i = 0; i < MUX_CLK_NUM_PARENTS; i++) { +@@ -150,25 +146,40 @@ static int meson8b_init_rgmii_tx_clk(struct meson8b_dwmac *dwmac) + if (WARN_ON(IS_ERR(dwmac->m250_div_clk))) + return PTR_ERR(dwmac->m250_div_clk); + +- /* create the m25_div */ +- snprintf(clk_name, sizeof(clk_name), "%s#m25_div", dev_name(dev)); ++ /* create the fixed_div2 */ ++ snprintf(clk_name, sizeof(clk_name), "%s#fixed_div2", dev_name(dev)); + init.name = devm_kstrdup(dev, clk_name, GFP_KERNEL); +- init.ops = &clk_divider_ops; +- init.flags = CLK_IS_BASIC | CLK_SET_RATE_PARENT; ++ init.ops = &clk_fixed_factor_ops; ++ init.flags = CLK_SET_RATE_PARENT; + clk_div_parents[0] = __clk_get_name(dwmac->m250_div_clk); + init.parent_names = clk_div_parents; + init.num_parents = ARRAY_SIZE(clk_div_parents); + +- dwmac->m25_div.reg = dwmac->regs + PRG_ETH0; +- dwmac->m25_div.shift = PRG_ETH0_CLK_M25_DIV_SHIFT; +- dwmac->m25_div.width = PRG_ETH0_CLK_M25_DIV_WIDTH; +- dwmac->m25_div.table = clk_25m_div_table; +- dwmac->m25_div.hw.init = &init; +- dwmac->m25_div.flags = CLK_DIVIDER_ALLOW_ZERO; ++ dwmac->fixed_div2.mult = 1; ++ dwmac->fixed_div2.div = 2; ++ dwmac->fixed_div2.hw.init = &init; + +- dwmac->m25_div_clk = devm_clk_register(dev, &dwmac->m25_div.hw); +- if (WARN_ON(IS_ERR(dwmac->m25_div_clk))) +- return PTR_ERR(dwmac->m25_div_clk); ++ dwmac->fixed_div2_clk = devm_clk_register(dev, &dwmac->fixed_div2.hw); ++ if (WARN_ON(IS_ERR(dwmac->fixed_div2_clk))) ++ return PTR_ERR(dwmac->fixed_div2_clk); ++ ++ /* create the rgmii_tx_en */ ++ init.name = devm_kasprintf(dev, GFP_KERNEL, "%s#rgmii_tx_en", ++ dev_name(dev)); ++ init.ops = &clk_gate_ops; ++ init.flags = CLK_SET_RATE_PARENT; ++ clk_div_parents[0] = __clk_get_name(dwmac->fixed_div2_clk); ++ init.parent_names = clk_div_parents; ++ init.num_parents = ARRAY_SIZE(clk_div_parents); ++ ++ dwmac->rgmii_tx_en.reg = dwmac->regs + PRG_ETH0; ++ dwmac->rgmii_tx_en.bit_idx = PRG_ETH0_RGMII_TX_CLK_EN; ++ dwmac->rgmii_tx_en.hw.init = &init; ++ ++ dwmac->rgmii_tx_en_clk = devm_clk_register(dev, ++ &dwmac->rgmii_tx_en.hw); ++ if (WARN_ON(IS_ERR(dwmac->rgmii_tx_en_clk))) ++ return PTR_ERR(dwmac->rgmii_tx_en_clk); + + return 0; + } +@@ -201,18 +212,22 @@ static int meson8b_init_prg_eth(struct meson8b_dwmac *dwmac) + meson8b_dwmac_mask_bits(dwmac, PRG_ETH0, PRG_ETH0_TXDLY_MASK, + tx_dly_val << PRG_ETH0_TXDLY_SHIFT); + +- ret = clk_prepare_enable(dwmac->m25_div_clk); ++ /* Configure the 125MHz RGMII TX clock, the IP block changes ++ * the output automatically (= without us having to configure ++ * a register) based on the line-speed (125MHz for Gbit speeds, ++ * 25MHz for 100Mbit/s and 2.5MHz for 10Mbit/s). ++ */ ++ ret = clk_set_rate(dwmac->rgmii_tx_en_clk, 125 * 1000 * 1000); + if (ret) { +- dev_err(&dwmac->pdev->dev, "failed to enable the PHY clock\n"); ++ dev_err(&dwmac->pdev->dev, ++ "failed to set RGMII TX clock\n"); + return ret; + } + +- /* Generate the 25MHz RGMII clock for the PHY */ +- ret = clk_set_rate(dwmac->m25_div_clk, 25 * 1000 * 1000); ++ ret = clk_prepare_enable(dwmac->rgmii_tx_en_clk); + if (ret) { +- clk_disable_unprepare(dwmac->m25_div_clk); +- +- dev_err(&dwmac->pdev->dev, "failed to set PHY clock\n"); ++ dev_err(&dwmac->pdev->dev, ++ "failed to enable the RGMII TX clock\n"); + return ret; + } + break; +@@ -306,7 +321,7 @@ static int meson8b_dwmac_probe(struct platform_device *pdev) + + err_clk_disable: + if (phy_interface_mode_is_rgmii(dwmac->phy_mode)) +- clk_disable_unprepare(dwmac->m25_div_clk); ++ clk_disable_unprepare(dwmac->rgmii_tx_en_clk); + err_remove_config_dt: + stmmac_remove_config_dt(pdev, plat_dat); + +@@ -318,7 +333,7 @@ static int meson8b_dwmac_remove(struct platform_device *pdev) + struct meson8b_dwmac *dwmac = get_stmmac_bsp_priv(&pdev->dev); + + if (phy_interface_mode_is_rgmii(dwmac->phy_mode)) +- clk_disable_unprepare(dwmac->m25_div_clk); ++ clk_disable_unprepare(dwmac->rgmii_tx_en_clk); + + return stmmac_pltfr_remove(pdev); + } diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/038_linux-4.14.y-backport-net-0018-net-stmmac-fix_reception_of_broadcom_switches_tags.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/038_linux-4.14.y-backport-net-0018-net-stmmac-fix_reception_of_broadcom_switches_tags.patch new file mode 100644 index 000000000..292b5a417 --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/038_linux-4.14.y-backport-net-0018-net-stmmac-fix_reception_of_broadcom_switches_tags.patch @@ -0,0 +1,168 @@ +From 8cad443eacf661796a740903a75cb8944c675b4e Mon Sep 17 00:00:00 2001 +From: Florian Fainelli +Date: Thu, 18 Jan 2018 15:12:21 -0800 +Subject: [PATCH] net: stmmac: Fix reception of Broadcom switches tags + +Broadcom tags inserted by Broadcom switches put a 4 byte header after +the MAC SA and before the EtherType, which may look like some sort of 0 +length LLC/SNAP packet (tcpdump and wireshark do think that way). With +ACS enabled in stmmac the packets were truncated to 8 bytes on +reception, whereas clearing this bit allowed normal reception to occur. + +In order to make that possible, we need to pass a net_device argument to +the different core_init() functions and we are dependent on the Broadcom +tagger padding packets correctly (which it now does). To be as little +invasive as possible, this is only done for gmac1000 when the network +device is DSA-enabled (netdev_uses_dsa() returns true). + +Signed-off-by: Florian Fainelli +Acked-by: Giuseppe Cavallaro +Signed-off-by: David S. Miller +--- + drivers/net/ethernet/stmicro/stmmac/common.h | 2 +- + drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c | 3 ++- + drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c | 12 +++++++++++- + drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c | 15 +++++++++++++-- + drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c | 12 +++++++++++- + drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 2 +- + 6 files changed, 39 insertions(+), 7 deletions(-) + +diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h +index ce2ea2d491aca..2ffe76c0ff742 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/common.h ++++ b/drivers/net/ethernet/stmicro/stmmac/common.h +@@ -474,7 +474,7 @@ struct mac_device_info; + /* Helpers to program the MAC core */ + struct stmmac_ops { + /* MAC core initialization */ +- void (*core_init)(struct mac_device_info *hw, int mtu); ++ void (*core_init)(struct mac_device_info *hw, struct net_device *dev); + /* Enable the MAC RX/TX */ + void (*set_mac)(void __iomem *ioaddr, bool enable); + /* Enable and verify that the IPC module is supported */ +diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c +index 9eb7f65d8000d..a3fa65b1ca8e5 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c ++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c +@@ -483,7 +483,8 @@ static int sun8i_dwmac_init(struct platform_device *pdev, void *priv) + return 0; + } + +-static void sun8i_dwmac_core_init(struct mac_device_info *hw, int mtu) ++static void sun8i_dwmac_core_init(struct mac_device_info *hw, ++ struct net_device *dev) + { + void __iomem *ioaddr = hw->pcsr; + u32 v; +diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c +index 8a86340ff2d34..540d21786a43b 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c ++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c +@@ -25,18 +25,28 @@ + #include + #include + #include ++#include + #include + #include "stmmac_pcs.h" + #include "dwmac1000.h" + +-static void dwmac1000_core_init(struct mac_device_info *hw, int mtu) ++static void dwmac1000_core_init(struct mac_device_info *hw, ++ struct net_device *dev) + { + void __iomem *ioaddr = hw->pcsr; + u32 value = readl(ioaddr + GMAC_CONTROL); ++ int mtu = dev->mtu; + + /* Configure GMAC core */ + value |= GMAC_CORE_INIT; + ++ /* Clear ACS bit because Ethernet switch tagging formats such as ++ * Broadcom tags can look like invalid LLC/SNAP packets and cause the ++ * hardware to truncate packets on reception. ++ */ ++ if (netdev_uses_dsa(dev)) ++ value &= ~GMAC_CONTROL_ACS; ++ + if (mtu > 1500) + value |= GMAC_CONTROL_2K; + if (mtu > 2000) +diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c +index 8ef5173563134..91b23f9db31ad 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c ++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c +@@ -25,15 +25,26 @@ + *******************************************************************************/ + + #include ++#include + #include + #include "dwmac100.h" + +-static void dwmac100_core_init(struct mac_device_info *hw, int mtu) ++static void dwmac100_core_init(struct mac_device_info *hw, ++ struct net_device *dev) + { + void __iomem *ioaddr = hw->pcsr; + u32 value = readl(ioaddr + MAC_CONTROL); + +- writel((value | MAC_CORE_INIT), ioaddr + MAC_CONTROL); ++ value |= MAC_CORE_INIT; ++ ++ /* Clear ASTP bit because Ethernet switch tagging formats such as ++ * Broadcom tags can look like invalid LLC/SNAP packets and cause the ++ * hardware to truncate packets on reception. ++ */ ++ if (netdev_uses_dsa(dev)) ++ value &= ~MAC_CONTROL_ASTP; ++ ++ writel(value, ioaddr + MAC_CONTROL); + + #ifdef STMMAC_VLAN_TAG_USED + writel(ETH_P_8021Q, ioaddr + MAC_VLAN1); +diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c +index f3ed8f7853eb4..ed222b20fcf19 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c ++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c +@@ -17,16 +17,26 @@ + #include + #include + #include ++#include + #include "stmmac_pcs.h" + #include "dwmac4.h" + +-static void dwmac4_core_init(struct mac_device_info *hw, int mtu) ++static void dwmac4_core_init(struct mac_device_info *hw, ++ struct net_device *dev) + { + void __iomem *ioaddr = hw->pcsr; + u32 value = readl(ioaddr + GMAC_CONFIG); ++ int mtu = dev->mtu; + + value |= GMAC_CORE_INIT; + ++ /* Clear ACS bit because Ethernet switch tagging formats such as ++ * Broadcom tags can look like invalid LLC/SNAP packets and cause the ++ * hardware to truncate packets on reception. ++ */ ++ if (netdev_uses_dsa(dev)) ++ value &= ~GMAC_CONFIG_ACS; ++ + if (mtu > 1500) + value |= GMAC_CONFIG_2K; + if (mtu > 2000) +diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +index f99f14c35063d..7ad841434ec8d 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +@@ -2527,7 +2527,7 @@ static int stmmac_hw_setup(struct net_device *dev, bool init_ptp) + } + + /* Initialize the MAC Core */ +- priv->hw->mac->core_init(priv->hw, dev->mtu); ++ priv->hw->mac->core_init(priv->hw, dev); + + /* Initialize MTL*/ + if (priv->synopsys_id >= DWMAC_CORE_4_00) diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/039_linux-4.14.y-backport-net-0019-net-stmmac-do_not_use_a_bitwise_and_operator_with_a_bool.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/039_linux-4.14.y-backport-net-0019-net-stmmac-do_not_use_a_bitwise_and_operator_with_a_bool.patch new file mode 100644 index 000000000..7ae271b9a --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/039_linux-4.14.y-backport-net-0019-net-stmmac-do_not_use_a_bitwise_and_operator_with_a_bool.patch @@ -0,0 +1,59 @@ +From d8f8b9542a4d8d560c0292a492f4edd922dd4ece Mon Sep 17 00:00:00 2001 +From: Niklas Cassel +Date: Mon, 22 Jan 2018 16:59:50 +0100 +Subject: [PATCH] net: stmmac: do not use a bitwise AND operator with a bool + operand + +Doing a bitwise AND between a bool and an int is generally not a good idea. +The bool will be promoted to an int with value 0 or 1, +the int is generally regarded as true with a non-zero value, +thus ANDing them has the potential to yield an undesired result. + +This commit fixes the following smatch warnings: + +drivers/net/ethernet/stmicro/stmmac/enh_desc.c:344 enh_desc_prepare_tx_desc() warn: maybe use && instead of & +drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c:337 dwmac4_rd_prepare_tx_desc() warn: maybe use && instead of & +drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c:380 dwmac4_rd_prepare_tso_tx_desc() warn: maybe use && instead of & + +Signed-off-by: Niklas Cassel +Signed-off-by: David S. Miller +--- + drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c | 4 ++-- + drivers/net/ethernet/stmicro/stmmac/enh_desc.c | 2 +- + 2 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c +index 2fd8456999f69..c728ffa095de0 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c ++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c +@@ -334,7 +334,7 @@ static void dwmac4_rd_prepare_tx_desc(struct dma_desc *p, int is_fs, int len, + if (tx_own) + tdes3 |= TDES3_OWN; + +- if (is_fs & tx_own) ++ if (is_fs && tx_own) + /* When the own bit, for the first frame, has to be set, all + * descriptors for the same frame has to be set before, to + * avoid race condition. +@@ -377,7 +377,7 @@ static void dwmac4_rd_prepare_tso_tx_desc(struct dma_desc *p, int is_fs, + if (tx_own) + tdes3 |= TDES3_OWN; + +- if (is_fs & tx_own) ++ if (is_fs && tx_own) + /* When the own bit, for the first frame, has to be set, all + * descriptors for the same frame has to be set before, to + * avoid race condition. +diff --git a/drivers/net/ethernet/stmicro/stmmac/enh_desc.c b/drivers/net/ethernet/stmicro/stmmac/enh_desc.c +index b47cb5c4da513..6768a25b6aa09 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/enh_desc.c ++++ b/drivers/net/ethernet/stmicro/stmmac/enh_desc.c +@@ -341,7 +341,7 @@ static void enh_desc_prepare_tx_desc(struct dma_desc *p, int is_fs, int len, + if (tx_own) + tdes0 |= ETDES0_OWN; + +- if (is_fs & tx_own) ++ if (is_fs && tx_own) + /* When the own bit, for the first frame, has to be set, all + * descriptors for the same frame has to be set before, to + * avoid race condition. diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/040_linux-4.14.y-backport-net-0020-net-stmmac-rename_gmac_int_default_mask_for_dwmac4.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/040_linux-4.14.y-backport-net-0020-net-stmmac-rename_gmac_int_default_mask_for_dwmac4.patch new file mode 100644 index 000000000..6eddc7a3b --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/040_linux-4.14.y-backport-net-0020-net-stmmac-rename_gmac_int_default_mask_for_dwmac4.patch @@ -0,0 +1,46 @@ +From e879b7ab3739d8f9990961fc7df2f63861bd780b Mon Sep 17 00:00:00 2001 +From: Niklas Cassel +Date: Fri, 9 Feb 2018 17:22:46 +0100 +Subject: [PATCH] net: stmmac: rename GMAC_INT_DEFAULT_MASK for dwmac4 + +GMAC_INT_DEFAULT_MASK is written to the interrupt enable register. +In previous versions of the IP (e.g. dwmac1000), this register was +instead an interrupt mask register. +To improve clarity and reflect reality, rename GMAC_INT_DEFAULT_MASK +to GMAC_INT_DEFAULT_ENABLE. + +Signed-off-by: Niklas Cassel +Signed-off-by: David S. Miller +--- + drivers/net/ethernet/stmicro/stmmac/dwmac4.h | 2 +- + drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c | 4 ++-- + 2 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4.h b/drivers/net/ethernet/stmicro/stmmac/dwmac4.h +index 789dad8a07b5c..7761a26ec9c56 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4.h ++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4.h +@@ -98,7 +98,7 @@ + #define GMAC_PCS_IRQ_DEFAULT (GMAC_INT_RGSMIIS | GMAC_INT_PCS_LINK | \ + GMAC_INT_PCS_ANE) + +-#define GMAC_INT_DEFAULT_MASK (GMAC_INT_PMT_EN | GMAC_INT_LPI_EN) ++#define GMAC_INT_DEFAULT_ENABLE (GMAC_INT_PMT_EN | GMAC_INT_LPI_EN) + + enum dwmac4_irq_status { + time_stamp_irq = 0x00001000, +diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c +index 1e0a7668b7529..6badc63d8e6d3 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c ++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c +@@ -61,8 +61,8 @@ static void dwmac4_core_init(struct mac_device_info *hw, + + writel(value, ioaddr + GMAC_CONFIG); + +- /* Mask GMAC interrupts */ +- value = GMAC_INT_DEFAULT_MASK; ++ /* Enable GMAC interrupts */ ++ value = GMAC_INT_DEFAULT_ENABLE; + if (hw->pmt) + value |= GMAC_INT_PMT_EN; + if (hw->pcs) diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/041_linux-4.14.y-backport-net-0021-net-stmmac-remove_redundant_enable_of_pmt_irq.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/041_linux-4.14.y-backport-net-0021-net-stmmac-remove_redundant_enable_of_pmt_irq.patch new file mode 100644 index 000000000..a50ae8011 --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/041_linux-4.14.y-backport-net-0021-net-stmmac-remove_redundant_enable_of_pmt_irq.patch @@ -0,0 +1,49 @@ +From 1029117127540fef4edcf4f0887dc3e1f7d5adb2 Mon Sep 17 00:00:00 2001 +From: Niklas Cassel +Date: Fri, 9 Feb 2018 17:22:47 +0100 +Subject: [PATCH] net: stmmac: remove redundant enable of PMT irq + +For dwmac4, GMAC_INT_DEFAULT_ENABLE already includes +GMAC_INT_PMT_EN, so it is redundant to check if hw->pmt +is set, and if so, setting the bit again. + +For dwmac1000, GMAC_INT_DEFAULT_MASK does not include +GMAC_INT_DISABLE_PMT, so it is redundant to check if +hw->pmt is set, and if so, clearing an already cleared bit. + +Improve code readability by removing this redundant code. + +Signed-off-by: Niklas Cassel +Signed-off-by: David S. Miller +--- + drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c | 2 -- + drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c | 3 +-- + 2 files changed, 1 insertion(+), 4 deletions(-) + +diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c +index 540d21786a43b..ef10baf141862 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c ++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c +@@ -74,8 +74,6 @@ static void dwmac1000_core_init(struct mac_device_info *hw, + /* Mask GMAC interrupts */ + value = GMAC_INT_DEFAULT_MASK; + +- if (hw->pmt) +- value &= ~GMAC_INT_DISABLE_PMT; + if (hw->pcs) + value &= ~GMAC_INT_DISABLE_PCS; + +diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c +index 6badc63d8e6d3..63795ecafc8dc 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c ++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c +@@ -63,8 +63,7 @@ static void dwmac4_core_init(struct mac_device_info *hw, + + /* Enable GMAC interrupts */ + value = GMAC_INT_DEFAULT_ENABLE; +- if (hw->pmt) +- value |= GMAC_INT_PMT_EN; ++ + if (hw->pcs) + value |= GMAC_PCS_IRQ_DEFAULT; + diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/042_linux-4.14.y-backport-net-1000-net-stmmac-setup_timer_-_timer_setup.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/042_linux-4.14.y-backport-net-1000-net-stmmac-setup_timer_-_timer_setup.patch new file mode 100644 index 000000000..7bff6097d --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/042_linux-4.14.y-backport-net-1000-net-stmmac-setup_timer_-_timer_setup.patch @@ -0,0 +1,60 @@ +From e99e88a9d2b067465adaa9c111ada99a041bef9a Mon Sep 17 00:00:00 2001 +From: Kees Cook +Date: Mon, 16 Oct 2017 14:43:17 -0700 +Subject: [PATCH] net: stmmac: setup_timer() -> timer_setup() + +This converts all remaining cases of the old setup_timer() API into using +timer_setup(), where the callback argument is the structure already +holding the struct timer_list. These should have no behavioral changes, +since they just change which pointer is passed into the callback with +the same available pointers after conversion. + +diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +index ff4fb5eae1af3..f63c2ddced3c9 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +@@ -345,9 +345,9 @@ void stmmac_disable_eee_mode(struct stmmac_priv *priv) + * if there is no data transfer and if we are not in LPI state, + * then MAC Transmitter can be moved to LPI state. + */ +-static void stmmac_eee_ctrl_timer(unsigned long arg) ++static void stmmac_eee_ctrl_timer(struct timer_list *t) + { +- struct stmmac_priv *priv = (struct stmmac_priv *)arg; ++ struct stmmac_priv *priv = from_timer(priv, t, eee_ctrl_timer); + + stmmac_enable_eee_mode(priv); + mod_timer(&priv->eee_ctrl_timer, STMMAC_LPI_T(eee_timer)); +@@ -401,9 +401,8 @@ bool stmmac_eee_init(struct stmmac_priv *priv) + spin_lock_irqsave(&priv->lock, flags); + if (!priv->eee_active) { + priv->eee_active = 1; +- setup_timer(&priv->eee_ctrl_timer, +- stmmac_eee_ctrl_timer, +- (unsigned long)priv); ++ timer_setup(&priv->eee_ctrl_timer, ++ stmmac_eee_ctrl_timer, 0); + mod_timer(&priv->eee_ctrl_timer, + STMMAC_LPI_T(eee_timer)); + +@@ -2221,9 +2220,9 @@ static int stmmac_init_dma_engine(struct stmmac_priv *priv) + * Description: + * This is the timer handler to directly invoke the stmmac_tx_clean. + */ +-static void stmmac_tx_timer(unsigned long data) ++static void stmmac_tx_timer(struct timer_list *t) + { +- struct stmmac_priv *priv = (struct stmmac_priv *)data; ++ struct stmmac_priv *priv = from_timer(priv, t, txtimer); + u32 tx_queues_count = priv->plat->tx_queues_to_use; + u32 queue; + +@@ -2244,7 +2243,7 @@ static void stmmac_init_tx_coalesce(struct stmmac_priv *priv) + { + priv->tx_coal_frames = STMMAC_TX_FRAMES; + priv->tx_coal_timer = STMMAC_COAL_TX_TIMER; +- setup_timer(&priv->txtimer, stmmac_tx_timer, (unsigned long)priv); ++ timer_setup(&priv->txtimer, stmmac_tx_timer, 0); + priv->txtimer.expires = STMMAC_COAL_TIMER(priv->tx_coal_timer); + add_timer(&priv->txtimer); + } diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/043_linux-4.14.y-backport-net-1001-net-stmmac-replace_all_pr_xxx_by_their_netdev_xxx.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/043_linux-4.14.y-backport-net-1001-net-stmmac-replace_all_pr_xxx_by_their_netdev_xxx.patch new file mode 100644 index 000000000..af1431118 --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/043_linux-4.14.y-backport-net-1001-net-stmmac-replace_all_pr_xxx_by_their_netdev_xxx.patch @@ -0,0 +1,15 @@ +diff -urN a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c 2018-05-01 18:26:12.093131654 +0200 ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c 2018-04-29 05:32:21.590669392 +0200 +@@ -3442,9 +3442,8 @@ + if (netif_msg_rx_status(priv)) { + netdev_dbg(priv->dev, "\tdesc: %p [entry %d] buff=0x%x\n", + p, entry, des); +- if (frame_len > ETH_FRAME_LEN) +- netdev_dbg(priv->dev, "frame size %d, COE: %d\n", +- frame_len, status); ++ netdev_dbg(priv->dev, "frame size %d, COE: %d\n", ++ frame_len, status); + } + + /* The zero-copy is always used for all the sizes diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/044_linux-4.14.y-bpo-dts-0001-arm64-dts-meson-gxl-libretech-cc-enable_saradc.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/044_linux-4.14.y-bpo-dts-0001-arm64-dts-meson-gxl-libretech-cc-enable_saradc.patch new file mode 100644 index 000000000..421ccc6ba --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/044_linux-4.14.y-bpo-dts-0001-arm64-dts-meson-gxl-libretech-cc-enable_saradc.patch @@ -0,0 +1,45 @@ +From dd47e4a36afd6c606f20e6d58e58f8e7e472c8fe Mon Sep 17 00:00:00 2001 +From: Jerome Brunet +Date: Tue, 5 Sep 2017 19:09:55 +0200 +Subject: [PATCH] ARM64: dts: meson-gxl-libretech-cc: enable saradc + +Enable saradc and add the reference 1.8v regulator required. +The libretech-cc has saradc channel 0 and 2 available on the 2 first +pins of 2J3 header + +Signed-off-by: Jerome Brunet +Signed-off-by: Kevin Hilman +--- + arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts +index 64c54c92e214d..a8aa9ce5f55e3 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts +@@ -96,6 +96,13 @@ + regulator-settling-time-down-us = <50000>; + }; + ++ vddio_ao18: regulator-vddio_ao18 { ++ compatible = "regulator-fixed"; ++ regulator-name = "VDDIO_AO18"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ }; ++ + vddio_boot: regulator-vddio_boot { + compatible = "regulator-fixed"; + regulator-name = "VDDIO_BOOT"; +@@ -196,6 +203,11 @@ + "7J1 Header Pin15"; + }; + ++&saradc { ++ status = "okay"; ++ vref-supply = <&vddio_ao18>; ++}; ++ + /* SD card */ + &sd_emmc_b { + status = "okay"; diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/045_linux-4.14.y-bpo-dts-0002-arm64-dts-meson-gxl-libretech-cc-enable_internal_phy_leds.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/045_linux-4.14.y-bpo-dts-0002-arm64-dts-meson-gxl-libretech-cc-enable_internal_phy_leds.patch new file mode 100644 index 000000000..440f4c98f --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/045_linux-4.14.y-bpo-dts-0002-arm64-dts-meson-gxl-libretech-cc-enable_internal_phy_leds.patch @@ -0,0 +1,29 @@ +From dac161871fb592816826ef11b742554fb3dc2fe3 Mon Sep 17 00:00:00 2001 +From: Jerome Brunet +Date: Wed, 6 Sep 2017 14:25:47 +0200 +Subject: [PATCH] ARM64: dts: meson-gxl-libretech-cc: enable internal phy leds + +Enable the internal phy ACT and LINK leds pinmux + +Signed-off-by: Jerome Brunet +Signed-off-by: Kevin Hilman +--- + arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts +index a8aa9ce5f55e3..6d023fa27067b 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts +@@ -128,6 +128,11 @@ + status = "okay"; + }; + ++&internal_phy { ++ pinctrl-0 = <ð_link_led_pins>, <ð_act_led_pins>; ++ pinctrl-names = "default"; ++}; ++ + &ir { + status = "okay"; + pinctrl-0 = <&remote_input_ao_pins>; diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/046_linux-4.14.y-bpo-dts-0003-arm64-dts-meson-gxbb-adjust_nanopi-k2_gpio-line-names.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/046_linux-4.14.y-bpo-dts-0003-arm64-dts-meson-gxbb-adjust_nanopi-k2_gpio-line-names.patch new file mode 100644 index 000000000..acdff4b8e --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/046_linux-4.14.y-bpo-dts-0003-arm64-dts-meson-gxbb-adjust_nanopi-k2_gpio-line-names.patch @@ -0,0 +1,43 @@ +From 1ce2c00878dbd4f8adfd2f0d64f01855072340a5 Mon Sep 17 00:00:00 2001 +From: Jerome Brunet +Date: Thu, 21 Sep 2017 19:14:47 +0200 +Subject: [PATCH] ARM64: dts: meson-gxbb: adjust nanopi-k2 gpio-line-names + +GPIOX22 is now declared properly and TEST_N has been moved so +the gpio-line-names of the nanopi-k2 must be adjusted accordingly + +Signed-off-by: Jerome Brunet +Signed-off-by: Kevin Hilman +--- + arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts +index 4b17a76959b2f..745d77f7cde13 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts +@@ -183,7 +183,9 @@ + "VCCK En", "CON1 Header Pin31", + "I2S Header Pin6", "IR In", "I2S Header Pin7", + "I2S Header Pin3", "I2S Header Pin4", +- "I2S Header Pin5", "HDMI CEC", "SYS LED"; ++ "I2S Header Pin5", "HDMI CEC", "SYS LED", ++ /* GPIO_TEST_N */ ++ ""; + }; + + &pinctrl_periphs { +@@ -229,11 +231,9 @@ + "Bluetooth UART TX", "Bluetooth UART RX", + "Bluetooth UART CTS", "Bluetooth UART RTS", + "", "", "", "WIFI 32K", "Bluetooth Enable", +- "Bluetooth WAKE HOST", ++ "Bluetooth WAKE HOST", "", + /* Bank GPIOCLK */ +- "", "CON1 Header Pin35", "", "", +- /* GPIO_TEST_N */ +- ""; ++ "", "CON1 Header Pin35", "", ""; + }; + + &pwm_ef { diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/047_linux-4.14.y-bpo-dts-0004-arm64-dts-meson-gxbb-adjust_odroid-c2_gpio-line-names.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/047_linux-4.14.y-bpo-dts-0004-arm64-dts-meson-gxbb-adjust_odroid-c2_gpio-line-names.patch new file mode 100644 index 000000000..aad3e9581 --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/047_linux-4.14.y-bpo-dts-0004-arm64-dts-meson-gxbb-adjust_odroid-c2_gpio-line-names.patch @@ -0,0 +1,43 @@ +From e43f20e844290655eecdd8a5038bc80964837889 Mon Sep 17 00:00:00 2001 +From: Jerome Brunet +Date: Thu, 21 Sep 2017 19:14:48 +0200 +Subject: [PATCH] ARM64: dts: meson-gxbb: adjust odroid-c2 gpio-line-names + +GPIOX22 is now declared properly and TEST_N has been moved so +the gpio-line-names of the odroid-c2 must be adjusted accordingly + +Signed-off-by: Jerome Brunet +Signed-off-by: Kevin Hilman +--- + arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts +index 1ffa1c238a725..a2f75194bc0cc 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts +@@ -194,7 +194,9 @@ + "USB HUB nRESET", "USB OTG Power En", + "J7 Header Pin2", "IR In", "J7 Header Pin4", + "J7 Header Pin6", "J7 Header Pin5", "J7 Header Pin7", +- "HDMI CEC", "SYS LED"; ++ "HDMI CEC", "SYS LED", ++ /* GPIO_TEST_N */ ++ ""; + }; + + &pinctrl_periphs { +@@ -233,11 +235,9 @@ + "J2 Header Pin12", "J2 Header Pin13", + "J2 Header Pin8", "J2 Header Pin10", + "", "", "", "", "", +- "J2 Header Pin11", "", "J2 Header Pin7", ++ "J2 Header Pin11", "", "J2 Header Pin7", "", + /* Bank GPIOCLK */ +- "", "", "", "", +- /* GPIO_TEST_N */ +- ""; ++ "", "", "", ""; + }; + + &saradc { diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/048_linux-4.14.y-bpo-dts-0005-arm64-dts-meson-gxl-adjust_kvim_gpio-line-names.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/048_linux-4.14.y-bpo-dts-0005-arm64-dts-meson-gxl-adjust_kvim_gpio-line-names.patch new file mode 100644 index 000000000..fc42dce94 --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/048_linux-4.14.y-bpo-dts-0005-arm64-dts-meson-gxl-adjust_kvim_gpio-line-names.patch @@ -0,0 +1,40 @@ +From c6496b47aeaef38fcd5a4fa5a90c82caebde538f Mon Sep 17 00:00:00 2001 +From: Jerome Brunet +Date: Thu, 21 Sep 2017 19:14:49 +0200 +Subject: [PATCH] ARM64: dts: meson-gxl: adjust kvim gpio-line-names + +TEST_N gpio has been moved so the gpio-line-names of the kvim +must be adjusted accordingly + +Signed-off-by: Jerome Brunet +Signed-off-by: Kevin Hilman +--- + arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts +index edc512ad0bac3..71a6e1ce7ad58 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts +@@ -122,7 +122,9 @@ + "J9 Header Pin33", + "IR In", + "HDMI CEC", +- "SYS LED"; ++ "SYS LED", ++ /* GPIO_TEST_N */ ++ ""; + }; + + &pinctrl_periphs { +@@ -163,9 +165,7 @@ + "WIFI 32K", "Bluetooth Enable", + "Bluetooth WAKE HOST", + /* Bank GPIOCLK */ +- "", "J9 Header Pin39", +- /* GPIO_TEST_N */ +- ""; ++ "", "J9 Header Pin39"; + }; + + &pwm_AO_ab { diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/049_linux-4.14.y-bpo-dts-0006-arm64-dts-meson-gxl-adjust_libretech-cc_gpio-line-names.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/049_linux-4.14.y-bpo-dts-0006-arm64-dts-meson-gxl-adjust_libretech-cc_gpio-line-names.patch new file mode 100644 index 000000000..5702f0861 --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/049_linux-4.14.y-bpo-dts-0006-arm64-dts-meson-gxl-adjust_libretech-cc_gpio-line-names.patch @@ -0,0 +1,40 @@ +From 1d70eaada70a355acd95a9022a84e476858ceba1 Mon Sep 17 00:00:00 2001 +From: Jerome Brunet +Date: Thu, 21 Sep 2017 19:16:04 +0200 +Subject: [PATCH] ARM64: dts: meson-gxl: adjust libretech-cc gpio-line-names + +TEST_N gpio has been moved so the gpio-line-names of the cc +must be adjusted accordingly + +Signed-off-by: Jerome Brunet +Signed-off-by: Kevin Hilman +--- + arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts +index 6d023fa27067b..c862540749384 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts +@@ -161,7 +161,9 @@ + "7J1 Header Pin12", + "IR In", + "9J3 Switch HDMI CEC/7J1 Header Pin11", +- "7J1 Header Pin13"; ++ "7J1 Header Pin13", ++ /* GPIO_TEST_N */ ++ "7J1 Header Pin15"; + }; + + &pinctrl_periphs { +@@ -203,9 +205,7 @@ + "7J1 Header Pin32", "7J1 Header Pin29", + "7J1 Header Pin31", + /* Bank GPIOCLK */ +- "7J1 Header Pin7", "", +- /* GPIO_TEST_N */ +- "7J1 Header Pin15"; ++ "7J1 Header Pin7", ""; + }; + + &saradc { diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/050_linux-4.14.y-bpo-dts-0007-arm64-dts-meson-gxl-take_emmc_data_strobe_out_of_emmc_pins.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/050_linux-4.14.y-bpo-dts-0007-arm64-dts-meson-gxl-take_emmc_data_strobe_out_of_emmc_pins.patch new file mode 100644 index 000000000..60e4e1a32 --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/050_linux-4.14.y-bpo-dts-0007-arm64-dts-meson-gxl-take_emmc_data_strobe_out_of_emmc_pins.patch @@ -0,0 +1,226 @@ +From ab36be660bad40133e1c6a028ba79e46c5d6f3c7 Mon Sep 17 00:00:00 2001 +From: Neil Armstrong +Date: Tue, 3 Oct 2017 17:24:42 +0200 +Subject: [PATCH] ARM64: dts: meson-gxl: Take eMMC data strobe out of eMMC pins + +Since the Data Strobe pin is optional, take it out of the default +eMMC pins and add a separate entry. + +Signed-off-by: Neil Armstrong +Tested-by: Jerome Brunet +Signed-off-by: Kevin Hilman +--- + arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi | 2 +- + arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts | 2 +- + arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts | 2 +- + arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts | 2 +- + arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi | 2 +- + arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi | 2 +- + arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi | 10 ++++++++-- + arch/arm64/boot/dts/amlogic/meson-gxl-s905x-hwacom-amazetv.dts | 2 +- + arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts | 2 +- + arch/arm64/boot/dts/amlogic/meson-gxl-s905x-nexbox-a95x.dts | 2 +- + arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi | 2 +- + arch/arm64/boot/dts/amlogic/meson-gxl.dtsi | 10 ++++++++-- + arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts | 2 +- + arch/arm64/boot/dts/amlogic/meson-gxm-rbox-pro.dts | 2 +- + 14 files changed, 28 insertions(+), 16 deletions(-) + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi +index 4157987f4a3d2..7d4b95e499935 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi +@@ -213,7 +213,7 @@ + /* eMMC */ + &sd_emmc_c { + status = "okay"; +- pinctrl-0 = <&emmc_pins>; ++ pinctrl-0 = <&emmc_pins>, <&emmc_ds_pins>; + pinctrl-1 = <&emmc_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts +index 745d77f7cde13..2e853c082a654 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts +@@ -302,7 +302,7 @@ + /* eMMC */ + &sd_emmc_c { + status = "disabled"; +- pinctrl-0 = <&emmc_pins>; ++ pinctrl-0 = <&emmc_pins>, <&emmc_ds_pins>; + pinctrl-1 = <&emmc_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts +index 38dfdde5c1473..9a773239dcef9 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts +@@ -272,7 +272,7 @@ + /* eMMC */ + &sd_emmc_c { + status = "okay"; +- pinctrl-0 = <&emmc_pins>; ++ pinctrl-0 = <&emmc_pins>, <&emmc_ds_pins>; + pinctrl-1 = <&emmc_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts +index a2f75194bc0cc..1deaa53c9fb56 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts +@@ -271,7 +271,7 @@ + /* eMMC */ + &sd_emmc_c { + status = "okay"; +- pinctrl-0 = <&emmc_pins>; ++ pinctrl-0 = <&emmc_pins>, <&emmc_ds_pins>; + pinctrl-1 = <&emmc_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi +index 23c08c3afd0ab..932158a778ef8 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi +@@ -242,7 +242,7 @@ + /* eMMC */ + &sd_emmc_c { + status = "okay"; +- pinctrl-0 = <&emmc_pins>; ++ pinctrl-0 = <&emmc_pins>, <&emmc_ds_pins>; + pinctrl-1 = <&emmc_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi +index f2bc6dea1fc62..1fe8e24cf675c 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi +@@ -199,7 +199,7 @@ + /* eMMC */ + &sd_emmc_c { + status = "okay"; +- pinctrl-0 = <&emmc_pins>; ++ pinctrl-0 = <&emmc_pins>, <&emmc_ds_pins>; + pinctrl-1 = <&emmc_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi +index 99ec6216c84a2..3d41db9c9d226 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi +@@ -386,8 +386,14 @@ + mux { + groups = "emmc_nand_d07", + "emmc_cmd", +- "emmc_clk", +- "emmc_ds"; ++ "emmc_clk"; ++ function = "emmc"; ++ }; ++ }; ++ ++ emmc_ds_pins: emmc-ds { ++ mux { ++ groups = "emmc_ds"; + function = "emmc"; + }; + }; +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-hwacom-amazetv.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-hwacom-amazetv.dts +index 977b4240f3c1b..e82582574160c 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-hwacom-amazetv.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-hwacom-amazetv.dts +@@ -141,7 +141,7 @@ + /* eMMC */ + &sd_emmc_c { + status = "okay"; +- pinctrl-0 = <&emmc_pins>; ++ pinctrl-0 = <&emmc_pins>, <&emmc_ds_pins>; + pinctrl-1 = <&emmc_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts +index c862540749384..dc9c3b8216c2b 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts +@@ -238,7 +238,7 @@ + /* eMMC */ + &sd_emmc_c { + status = "okay"; +- pinctrl-0 = <&emmc_pins>; ++ pinctrl-0 = <&emmc_pins>, <&emmc_ds_pins>; + pinctrl-1 = <&emmc_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-nexbox-a95x.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-nexbox-a95x.dts +index 1b8f32867aa10..271f142791808 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-nexbox-a95x.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-nexbox-a95x.dts +@@ -229,7 +229,7 @@ + /* eMMC */ + &sd_emmc_c { + status = "okay"; +- pinctrl-0 = <&emmc_pins>; ++ pinctrl-0 = <&emmc_pins>, <&emmc_ds_pins>; + pinctrl-1 = <&emmc_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi +index 129af9068814d..ff09df1fd5a32 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi +@@ -135,7 +135,7 @@ + /* eMMC */ + &sd_emmc_c { + status = "okay"; +- pinctrl-0 = <&emmc_pins>; ++ pinctrl-0 = <&emmc_pins>, <&emmc_ds_pins>; + pinctrl-1 = <&emmc_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi +index e7cfe87be3b44..19c001abb0c51 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi +@@ -275,8 +275,14 @@ + mux { + groups = "emmc_nand_d07", + "emmc_cmd", +- "emmc_clk", +- "emmc_ds"; ++ "emmc_clk"; ++ function = "emmc"; ++ }; ++ }; ++ ++ emmc_ds_pins: emmc-ds { ++ mux { ++ groups = "emmc_ds"; + function = "emmc"; + }; + }; +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts b/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts +index 22c697732f668..e7a228f6cc7e7 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts +@@ -193,7 +193,7 @@ + /* eMMC */ + &sd_emmc_c { + status = "okay"; +- pinctrl-0 = <&emmc_pins>; ++ pinctrl-0 = <&emmc_pins>, <&emmc_ds_pins>; + pinctrl-1 = <&emmc_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm-rbox-pro.dts b/arch/arm64/boot/dts/amlogic/meson-gxm-rbox-pro.dts +index 470f72bb863c5..a5e9b955d5ed3 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxm-rbox-pro.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxm-rbox-pro.dts +@@ -216,7 +216,7 @@ + /* eMMC */ + &sd_emmc_c { + status = "okay"; +- pinctrl-0 = <&emmc_pins>; ++ pinctrl-0 = <&emmc_pins>, <&emmc_ds_pins>; + pinctrl-names = "default"; + + bus-width = <8>; diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/051_linux-4.14.y-bpo-dts-0008-arm64-dts-meson-gxm-add_support_for_khadas_vim2.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/051_linux-4.14.y-bpo-dts-0008-arm64-dts-meson-gxm-add_support_for_khadas_vim2.patch new file mode 100644 index 000000000..ffb48af7c --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/051_linux-4.14.y-bpo-dts-0008-arm64-dts-meson-gxm-add_support_for_khadas_vim2.patch @@ -0,0 +1,454 @@ +From b8b74dda3908660f49a5d5cec28725e3950e00d5 Mon Sep 17 00:00:00 2001 +From: Neil Armstrong +Date: Tue, 3 Oct 2017 17:24:43 +0200 +Subject: [PATCH] ARM64: dts: meson-gxm: Add support for Khadas VIM2 + +The Khadas VIM2 is a Single Board Computer, respin of the origin +Khadas VIM board, using an Amlogic S912 SoC and more server oriented. + +It provides the same external connectors and header pinout, plus a SPI +NOR Flash, a reprogrammable STM8S003 MCU, FPC Connector, Cooling FAN header +and Pogo Pads Arrays. + +Cc: Gouwa +Acked-by: Martin Blumenstingl +Acked-by: Rob Herring +Signed-off-by: Neil Armstrong +Tested-by: Jerome Brunet +Signed-off-by: Kevin Hilman +--- + Documentation/devicetree/bindings/arm/amlogic.txt | 1 + + arch/arm64/boot/dts/amlogic/Makefile | 1 + + .../boot/dts/amlogic/meson-gxm-khadas-vim2.dts | 399 +++++++++++++++++++++ + 3 files changed, 401 insertions(+) + create mode 100644 arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts + +diff --git a/Documentation/devicetree/bindings/arm/amlogic.txt b/Documentation/devicetree/bindings/arm/amlogic.txt +index 4e4bc0bae597a..a44599739746b 100644 +--- a/Documentation/devicetree/bindings/arm/amlogic.txt ++++ b/Documentation/devicetree/bindings/arm/amlogic.txt +@@ -71,6 +71,7 @@ Board compatible values (alphabetically, grouped by SoC): + + - "amlogic,q200" (Meson gxm s912) + - "amlogic,q201" (Meson gxm s912) ++ - "khadas,vim2" (Meson gxm s912) + - "kingnovel,r-box-pro" (Meson gxm S912) + - "nexbox,a1" (Meson gxm s912) + +diff --git a/arch/arm64/boot/dts/amlogic/Makefile b/arch/arm64/boot/dts/amlogic/Makefile +index 7a9f48c27b1f5..70246e3ecd5c6 100644 +--- a/arch/arm64/boot/dts/amlogic/Makefile ++++ b/arch/arm64/boot/dts/amlogic/Makefile +@@ -15,6 +15,7 @@ dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905x-nexbox-a95x.dtb + dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905x-p212.dtb + dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905d-p230.dtb + dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905d-p231.dtb ++dtb-$(CONFIG_ARCH_MESON) += meson-gxm-khadas-vim2.dtb + dtb-$(CONFIG_ARCH_MESON) += meson-gxm-nexbox-a1.dtb + dtb-$(CONFIG_ARCH_MESON) += meson-gxm-q200.dtb + dtb-$(CONFIG_ARCH_MESON) += meson-gxm-q201.dtb +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts b/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts +new file mode 100644 +index 0000000000000..32c138ec0e587 +--- /dev/null ++++ b/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts +@@ -0,0 +1,399 @@ ++/* ++ * Copyright (c) 2017 Martin Blumenstingl . ++ * Copyright (c) 2017 BayLibre, SAS ++ * Author: Neil Armstrong ++ * ++ * SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++ */ ++ ++/dts-v1/; ++ ++#include ++#include ++ ++#include "meson-gxm.dtsi" ++ ++/ { ++ compatible = "khadas,vim2", "amlogic,s912", "amlogic,meson-gxm"; ++ model = "Khadas VIM2"; ++ ++ aliases { ++ serial0 = &uart_AO; ++ serial1 = &uart_A; ++ serial2 = &uart_AO_B; ++ }; ++ ++ chosen { ++ stdout-path = "serial0:115200n8"; ++ }; ++ ++ memory@0 { ++ device_type = "memory"; ++ reg = <0x0 0x0 0x0 0x80000000>; ++ }; ++ ++ adc-keys { ++ compatible = "adc-keys"; ++ io-channels = <&saradc 0>; ++ io-channel-names = "buttons"; ++ keyup-threshold-microvolt = <1710000>; ++ ++ button-function { ++ label = "Function"; ++ linux,code = ; ++ press-threshold-microvolt = <10000>; ++ }; ++ }; ++ ++ emmc_pwrseq: emmc-pwrseq { ++ compatible = "mmc-pwrseq-emmc"; ++ reset-gpios = <&gpio BOOT_9 GPIO_ACTIVE_LOW>; ++ }; ++ ++ gpio_fan: gpio-fan { ++ compatible = "gpio-fan"; ++ gpios = <&gpio GPIODV_14 GPIO_ACTIVE_HIGH ++ &gpio GPIODV_15 GPIO_ACTIVE_HIGH>; ++ /* Dummy RPM values since fan is optional */ ++ gpio-fan,speed-map = <0 0 ++ 1 1 ++ 2 2 ++ 3 3>; ++ cooling-min-level = <0>; ++ cooling-max-level = <3>; ++ #cooling-cells = <2>; ++ }; ++ ++ gpio-keys-polled { ++ compatible = "gpio-keys-polled"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ poll-interval = <100>; ++ ++ button@0 { ++ label = "power"; ++ linux,code = ; ++ gpios = <&gpio_ao GPIOAO_2 GPIO_ACTIVE_LOW>; ++ }; ++ }; ++ ++ hdmi-connector { ++ compatible = "hdmi-connector"; ++ type = "a"; ++ ++ port { ++ hdmi_connector_in: endpoint { ++ remote-endpoint = <&hdmi_tx_tmds_out>; ++ }; ++ }; ++ }; ++ ++ pwmleds { ++ compatible = "pwm-leds"; ++ ++ power { ++ label = "vim:red:power"; ++ pwms = <&pwm_AO_ab 1 7812500 0>; ++ max-brightness = <255>; ++ linux,default-trigger = "default-on"; ++ }; ++ }; ++ ++ sdio_pwrseq: sdio-pwrseq { ++ compatible = "mmc-pwrseq-simple"; ++ reset-gpios = <&gpio GPIOX_6 GPIO_ACTIVE_LOW>; ++ clocks = <&wifi32k>; ++ clock-names = "ext_clock"; ++ }; ++ ++ thermal-zones { ++ cpu-thermal { ++ polling-delay-passive = <250>; /* milliseconds */ ++ polling-delay = <1000>; /* milliseconds */ ++ ++ thermal-sensors = <&scpi_sensors 0>; ++ ++ trips { ++ cpu_alert0: cpu-alert0 { ++ temperature = <70000>; /* millicelsius */ ++ hysteresis = <2000>; /* millicelsius */ ++ type = "active"; ++ }; ++ ++ cpu_alert1: cpu-alert1 { ++ temperature = <80000>; /* millicelsius */ ++ hysteresis = <2000>; /* millicelsius */ ++ type = "passive"; ++ }; ++ }; ++ ++ cooling-maps { ++ map0 { ++ trip = <&cpu_alert0>; ++ cooling-device = <&gpio_fan THERMAL_NO_LIMIT 1>; ++ }; ++ ++ map1 { ++ trip = <&cpu_alert1>; ++ cooling-device = <&gpio_fan 2 THERMAL_NO_LIMIT>; ++ }; ++ ++ map2 { ++ trip = <&cpu_alert1>; ++ cooling-device = ++ <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; ++ }; ++ ++ map3 { ++ trip = <&cpu_alert1>; ++ cooling-device = ++ <&cpu4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; ++ }; ++ }; ++ }; ++ }; ++ ++ vcc_3v3: regulator-vcc_3v3 { ++ compatible = "regulator-fixed"; ++ regulator-name = "VCC_3V3"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ }; ++ ++ vddio_ao18: regulator-vddio_ao18 { ++ compatible = "regulator-fixed"; ++ regulator-name = "VDDIO_AO18"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ }; ++ ++ vddio_boot: regulator-vddio_boot { ++ compatible = "regulator-fixed"; ++ regulator-name = "VDDIO_BOOT"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ }; ++ ++ vddao_3v3: regulator-vddao_3v3 { ++ compatible = "regulator-fixed"; ++ regulator-name = "VDDAO_3V3"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ }; ++ ++ wifi32k: wifi32k { ++ compatible = "pwm-clock"; ++ #clock-cells = <0>; ++ clock-frequency = <32768>; ++ pwms = <&pwm_ef 0 30518 0>; /* PWM_E at 32.768KHz */ ++ }; ++}; ++ ++&cec_AO { ++ status = "okay"; ++ pinctrl-0 = <&ao_cec_pins>; ++ pinctrl-names = "default"; ++ hdmi-phandle = <&hdmi_tx>; ++}; ++ ++&cpu0 { ++ cooling-min-level = <0>; ++ cooling-max-level = <6>; ++ #cooling-cells = <2>; ++}; ++ ++&cpu4 { ++ cooling-min-level = <0>; ++ cooling-max-level = <4>; ++ #cooling-cells = <2>; ++}; ++ ++ðmac { ++ pinctrl-0 = <ð_pins>; ++ pinctrl-names = "default"; ++ ++ /* Select external PHY by default */ ++ phy-handle = <&external_phy>; ++ ++ amlogic,tx-delay-ns = <2>; ++ ++ /* External PHY reset is shared with internal PHY Led signals */ ++ snps,reset-gpio = <&gpio GPIOZ_14 0>; ++ snps,reset-delays-us = <0 10000 1000000>; ++ snps,reset-active-low; ++ ++ /* External PHY is in RGMII */ ++ phy-mode = "rgmii"; ++ ++ status = "okay"; ++}; ++ ++&external_mdio { ++ external_phy: ethernet-phy@0 { ++ /* Realtek RTL8211F (0x001cc916) */ ++ reg = <0>; ++ }; ++}; ++ ++&hdmi_tx { ++ status = "okay"; ++ pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>; ++ pinctrl-names = "default"; ++}; ++ ++&hdmi_tx_tmds_port { ++ hdmi_tx_tmds_out: endpoint { ++ remote-endpoint = <&hdmi_connector_in>; ++ }; ++}; ++ ++&i2c_A { ++ status = "okay"; ++ pinctrl-0 = <&i2c_a_pins>; ++ pinctrl-names = "default"; ++}; ++ ++&i2c_B { ++ status = "okay"; ++ pinctrl-0 = <&i2c_b_pins>; ++ pinctrl-names = "default"; ++ ++ rtc: rtc@51 { ++ /* has to be enabled manually when a battery is connected: */ ++ status = "disabled"; ++ compatible = "haoyu,hym8563"; ++ reg = <0x51>; ++ #clock-cells = <0>; ++ clock-frequency = <32768>; ++ clock-output-names = "xin32k"; ++ }; ++}; ++ ++&ir { ++ status = "okay"; ++ pinctrl-0 = <&remote_input_ao_pins>; ++ pinctrl-names = "default"; ++ linux,rc-map-name = "rc-geekbox"; ++}; ++ ++&pwm_AO_ab { ++ status = "okay"; ++ pinctrl-0 = <&pwm_ao_a_3_pins>, <&pwm_ao_b_pins>; ++ pinctrl-names = "default"; ++ clocks = <&clkc CLKID_FCLK_DIV4>; ++ clock-names = "clkin0"; ++}; ++ ++&pwm_ef { ++ status = "okay"; ++ pinctrl-0 = <&pwm_e_pins>, <&pwm_f_clk_pins>; ++ pinctrl-names = "default"; ++ clocks = <&clkc CLKID_FCLK_DIV4>; ++ clock-names = "clkin0"; ++}; ++ ++&sd_emmc_a { ++ status = "okay"; ++ pinctrl-0 = <&sdio_pins>; ++ pinctrl-names = "default"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ bus-width = <4>; ++ max-frequency = <100000000>; ++ ++ non-removable; ++ disable-wp; ++ ++ mmc-pwrseq = <&sdio_pwrseq>; ++ ++ vmmc-supply = <&vddao_3v3>; ++ vqmmc-supply = <&vddio_boot>; ++ ++ brcmf: wifi@1 { ++ reg = <1>; ++ compatible = "brcm,bcm4329-fmac"; ++ }; ++}; ++ ++/* SD card */ ++&sd_emmc_b { ++ status = "okay"; ++ pinctrl-0 = <&sdcard_pins>; ++ pinctrl-names = "default"; ++ ++ bus-width = <4>; ++ cap-sd-highspeed; ++ max-frequency = <100000000>; ++ disable-wp; ++ ++ cd-gpios = <&gpio CARD_6 GPIO_ACTIVE_HIGH>; ++ cd-inverted; ++ ++ vmmc-supply = <&vddao_3v3>; ++ vqmmc-supply = <&vddio_boot>; ++}; ++ ++/* eMMC */ ++&sd_emmc_c { ++ status = "okay"; ++ pinctrl-0 = <&emmc_pins>, <&emmc_ds_pins>; ++ pinctrl-names = "default"; ++ ++ bus-width = <8>; ++ cap-sd-highspeed; ++ cap-mmc-highspeed; ++ max-frequency = <200000000>; ++ non-removable; ++ disable-wp; ++ mmc-ddr-1_8v; ++ mmc-hs200-1_8v; ++ ++ mmc-pwrseq = <&emmc_pwrseq>; ++ vmmc-supply = <&vcc_3v3>; ++ vqmmc-supply = <&vddio_boot>; ++}; ++ ++/* ++ * EMMC_DS pin is shared between SPI NOR CS and eMMC Data Strobe ++ * Remove emmc_ds_pins from sd_emmc_c pinctrl-0 then spifc can be enabled ++ */ ++&spifc { ++ status = "disabled"; ++ pinctrl-0 = <&nor_pins>; ++ pinctrl-names = "default"; ++ ++ w25q32: spi-flash@0 { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "winbond,w25q16", "jedec,spi-nor"; ++ reg = <0>; ++ spi-max-frequency = <3000000>; ++ }; ++}; ++ ++/* This one is connected to the Bluetooth module */ ++&uart_A { ++ status = "okay"; ++ pinctrl-0 = <&uart_a_pins>; ++ pinctrl-names = "default"; ++}; ++ ++/* This is brought out on the Linux_RX (18) and Linux_TX (19) pins: */ ++&uart_AO { ++ status = "okay"; ++ pinctrl-0 = <&uart_ao_a_pins>; ++ pinctrl-names = "default"; ++}; ++ ++/* This is brought out on the UART_RX_AO_B (15) and UART_TX_AO_B (16) pins: */ ++&uart_AO_B { ++ status = "okay"; ++ pinctrl-0 = <&uart_ao_b_pins>; ++ pinctrl-names = "default"; ++}; ++ ++&saradc { ++ status = "okay"; ++ vref-supply = <&vddio_ao18>; ++}; diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/052_linux-4.14.y-bpo-dts-0009-arm64-dts-meson-gxbb-nexbox-a95x-enable_usb_nodes.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/052_linux-4.14.y-bpo-dts-0009-arm64-dts-meson-gxbb-nexbox-a95x-enable_usb_nodes.patch new file mode 100644 index 000000000..9ec860c2f --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/052_linux-4.14.y-bpo-dts-0009-arm64-dts-meson-gxbb-nexbox-a95x-enable_usb_nodes.patch @@ -0,0 +1,59 @@ +From e2f4d749e73a468902f2d2453b1575602427c069 Mon Sep 17 00:00:00 2001 +From: Peter Korsgaard +Date: Thu, 5 Oct 2017 15:21:18 +0200 +Subject: [PATCH] ARM64: dts: meson-gxbb-nexbox-a95x: Enable USB Nodes + +Enable both gxbb USB controllers and add a 5V regulator for the OTG port +VBUS, similar to p20x. + +Signed-off-by: Peter Korsgaard +Acked-by: Neil Armstrong +Signed-off-by: Kevin Hilman +--- + .../boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts | 29 ++++++++++++++++++++++ + 1 file changed, 29 insertions(+) + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts +index 9a773239dcef9..818954b1d57f8 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts +@@ -88,6 +88,18 @@ + }; + }; + ++ usb_pwr: regulator-usb-pwrs { ++ compatible = "regulator-fixed"; ++ ++ regulator-name = "USB_PWR"; ++ ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ ++ gpio = <&gpio GPIODV_24 GPIO_ACTIVE_HIGH>; ++ enable-active-high; ++ }; ++ + vddio_card: gpio-regulator { + compatible = "regulator-gpio"; + +@@ -294,3 +306,20 @@ + pinctrl-0 = <&uart_ao_a_pins>; + pinctrl-names = "default"; + }; ++ ++&usb0_phy { ++ status = "okay"; ++ phy-supply = <&usb_pwr>; ++}; ++ ++&usb1_phy { ++ status = "okay"; ++}; ++ ++&usb0 { ++ status = "okay"; ++}; ++ ++&usb1 { ++ status = "okay"; ++}; diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/053_linux-4.14.y-bpo-dts-0010-arm64-dts-meson-gxm-enable_hs400_on_the_vim2.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/053_linux-4.14.y-bpo-dts-0010-arm64-dts-meson-gxm-enable_hs400_on_the_vim2.patch new file mode 100644 index 000000000..0ce3c8a49 --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/053_linux-4.14.y-bpo-dts-0010-arm64-dts-meson-gxm-enable_hs400_on_the_vim2.patch @@ -0,0 +1,25 @@ +From a1d759cf528064e73c06d318cd03213c4eafbc35 Mon Sep 17 00:00:00 2001 +From: Jerome Brunet +Date: Tue, 10 Oct 2017 16:18:22 +0200 +Subject: [PATCH] ARM64: dts: meson-gxm: enable HS400 on the vim2 + +Enable HS400 high speed eMMC mode on the khadas vim2 + +Signed-off-by: Jerome Brunet +Signed-off-by: Kevin Hilman +--- + arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts b/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts +index 32c138ec0e587..34a41b26a4ed2 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts +@@ -348,6 +348,7 @@ + disable-wp; + mmc-ddr-1_8v; + mmc-hs200-1_8v; ++ mmc-hs400-1_8v; + + mmc-pwrseq = <&emmc_pwrseq>; + vmmc-supply = <&vcc_3v3>; diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/054_linux-4.14.y-bpo-dts-0011-arm64-dts-meson-gx-remove_unnecessary_clocks_properties.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/054_linux-4.14.y-bpo-dts-0011-arm64-dts-meson-gx-remove_unnecessary_clocks_properties.patch new file mode 100644 index 000000000..265485c24 --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/054_linux-4.14.y-bpo-dts-0011-arm64-dts-meson-gx-remove_unnecessary_clocks_properties.patch @@ -0,0 +1,44 @@ +From ab29891e953fd7c3410f3edeb50457812f7694d8 Mon Sep 17 00:00:00 2001 +From: Neil Armstrong +Date: Wed, 11 Oct 2017 17:39:39 +0200 +Subject: [PATCH] ARM64: dts: meson-gx: remove unnecessary clocks properties + +Since the switch to documented uart bindings, the clocks are +redefined in the SoC family dtsi file. + +This patch removes these unneeded properties. + +Signed-off-by: Neil Armstrong +Signed-off-by: Kevin Hilman +--- + arch/arm64/boot/dts/amlogic/meson-gx.dtsi | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi +index f175db8462861..2be981a547dfc 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi +@@ -228,7 +228,6 @@ + compatible = "amlogic,meson-gx-uart", "amlogic,meson-uart"; + reg = <0x0 0x84c0 0x0 0x14>; + interrupts = ; +- clocks = <&xtal>; + status = "disabled"; + }; + +@@ -236,7 +235,6 @@ + compatible = "amlogic,meson-gx-uart", "amlogic,meson-uart"; + reg = <0x0 0x84dc 0x0 0x14>; + interrupts = ; +- clocks = <&xtal>; + status = "disabled"; + }; + +@@ -282,7 +280,6 @@ + compatible = "amlogic,meson-gx-uart", "amlogic,meson-uart"; + reg = <0x0 0x8700 0x0 0x14>; + interrupts = ; +- clocks = <&xtal>; + status = "disabled"; + }; + diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/055_linux-4.14.y-bpo-dts-0012-arm64-dts-meson-gx-remove_unnecessary_uart_compatible.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/055_linux-4.14.y-bpo-dts-0012-arm64-dts-meson-gx-remove_unnecessary_uart_compatible.patch new file mode 100644 index 000000000..10514abf9 --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/055_linux-4.14.y-bpo-dts-0012-arm64-dts-meson-gx-remove_unnecessary_uart_compatible.patch @@ -0,0 +1,63 @@ +From a87f854ddcf7ff7e044d72db0aa6da82f26d69a6 Mon Sep 17 00:00:00 2001 +From: Neil Armstrong +Date: Wed, 11 Oct 2017 17:39:40 +0200 +Subject: [PATCH] ARM64: dts: meson-gx: remove unnecessary uart compatible + +Since the switch to documented uart bindings, the old undocumented +compatible binding was left for simplicity. + +This patch removes these unneeded compatible strings. + +Signed-off-by: Neil Armstrong +Signed-off-by: Kevin Hilman +--- + arch/arm64/boot/dts/amlogic/meson-gx.dtsi | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi +index 2be981a547dfc..b7723436a04b2 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi +@@ -225,14 +225,14 @@ + }; + + uart_A: serial@84c0 { +- compatible = "amlogic,meson-gx-uart", "amlogic,meson-uart"; ++ compatible = "amlogic,meson-gx-uart"; + reg = <0x0 0x84c0 0x0 0x14>; + interrupts = ; + status = "disabled"; + }; + + uart_B: serial@84dc { +- compatible = "amlogic,meson-gx-uart", "amlogic,meson-uart"; ++ compatible = "amlogic,meson-gx-uart"; + reg = <0x0 0x84dc 0x0 0x14>; + interrupts = ; + status = "disabled"; +@@ -277,7 +277,7 @@ + }; + + uart_C: serial@8700 { +- compatible = "amlogic,meson-gx-uart", "amlogic,meson-uart"; ++ compatible = "amlogic,meson-gx-uart"; + reg = <0x0 0x8700 0x0 0x14>; + interrupts = ; + status = "disabled"; +@@ -388,14 +388,14 @@ + }; + + uart_AO: serial@4c0 { +- compatible = "amlogic,meson-gx-uart", "amlogic,meson-ao-uart", "amlogic,meson-uart"; ++ compatible = "amlogic,meson-gx-uart", "amlogic,meson-ao-uart"; + reg = <0x0 0x004c0 0x0 0x14>; + interrupts = ; + status = "disabled"; + }; + + uart_AO_B: serial@4e0 { +- compatible = "amlogic,meson-gx-uart", "amlogic,meson-ao-uart", "amlogic,meson-uart"; ++ compatible = "amlogic,meson-gx-uart", "amlogic,meson-ao-uart"; + reg = <0x0 0x004e0 0x0 0x14>; + interrupts = ; + status = "disabled"; diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/056_linux-4.14.y-bpo-dts-0013-arm64-dts-meson-gx-add_gpio_interrupt_controller.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/056_linux-4.14.y-bpo-dts-0013-arm64-dts-meson-gx-add_gpio_interrupt_controller.patch new file mode 100644 index 000000000..5850e71ae --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/056_linux-4.14.y-bpo-dts-0013-arm64-dts-meson-gx-add_gpio_interrupt_controller.patch @@ -0,0 +1,70 @@ +From 9dbb56ea0917a036dc966663a09baf3d5a471f54 Mon Sep 17 00:00:00 2001 +From: Jerome Brunet +Date: Thu, 19 Oct 2017 14:01:42 +0200 +Subject: [PATCH] ARM64: dts: meson-gx: add gpio interrupt controller + +Add gpio interrupt controller to Amlogic GX family SoCs + +Signed-off-by: Jerome Brunet +Reviewed-by: Neil Armstrong +Signed-off-by: Kevin Hilman +--- + arch/arm64/boot/dts/amlogic/meson-gx.dtsi | 9 +++++++++ + arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi | 6 ++++++ + arch/arm64/boot/dts/amlogic/meson-gxl.dtsi | 6 ++++++ + 3 files changed, 21 insertions(+) + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi +index b7723436a04b2..ab7ce1644cdc5 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi +@@ -218,6 +218,15 @@ + #size-cells = <2>; + ranges = <0x0 0x0 0x0 0xc1100000 0x0 0x100000>; + ++ gpio_intc: interrupt-controller@9880 { ++ compatible = "amlogic,meson-gpio-intc"; ++ reg = <0x0 0x9880 0x0 0x10>; ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ amlogic,channel-interrupts = <64 65 66 67 68 69 70 71>; ++ status = "disabled"; ++ }; ++ + reset: reset-controller@4404 { + compatible = "amlogic,meson-gx-reset", "amlogic,meson-gxbb-reset"; + reg = <0x0 0x04404 0x0 0x20>; +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi +index 3d41db9c9d226..ead895a4e9a5c 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi +@@ -323,6 +323,12 @@ + clock-names = "stmmaceth", "clkin0", "clkin1"; + }; + ++&gpio_intc { ++ compatible = "amlogic,meson-gpio-intc", ++ "amlogic,meson-gxbb-gpio-intc"; ++ status = "okay"; ++}; ++ + &hdmi_tx { + compatible = "amlogic,meson-gxbb-dw-hdmi", "amlogic,meson-gx-dw-hdmi"; + resets = <&reset RESET_HDMITX_CAPB3>, +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi +index d3a51031a7111..0aa71a35ce64c 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi +@@ -225,6 +225,12 @@ + compatible = "amlogic,meson-gxl-aoclkc", "amlogic,meson-gx-aoclkc"; + }; + ++&gpio_intc { ++ compatible = "amlogic,meson-gpio-intc", ++ "amlogic,meson-gxl-gpio-intc"; ++ status = "okay"; ++}; ++ + &hdmi_tx { + compatible = "amlogic,meson-gxl-dw-hdmi", "amlogic,meson-gx-dw-hdmi"; + resets = <&reset RESET_HDMITX_CAPB3>, diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/057_linux-4.14.y-bpo-dts-0014-arm64-dts-meson-gx-add_external_phy_interrupt_on_some.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/057_linux-4.14.y-bpo-dts-0014-arm64-dts-meson-gx-add_external_phy_interrupt_on_some.patch new file mode 100644 index 000000000..ecbeff4d5 --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/057_linux-4.14.y-bpo-dts-0014-arm64-dts-meson-gx-add_external_phy_interrupt_on_some.patch @@ -0,0 +1,85 @@ +From b94d22d94ad226eeea3b6ec4579fb4bf8a199e5c Mon Sep 17 00:00:00 2001 +From: Jerome Brunet +Date: Thu, 19 Oct 2017 14:01:43 +0200 +Subject: [PATCH] ARM64: dts: meson-gx: add external PHY interrupt on some + platforms + +Add the external PHY interrupt on the nanopi-k2, odroid-c2, p200, p230 +and q200 + +Signed-off-by: Jerome Brunet +Reviewed-by: Neil Armstrong +Signed-off-by: Kevin Hilman +--- + arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts | 2 ++ + arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts | 2 ++ + arch/arm64/boot/dts/amlogic/meson-gxbb-p200.dts | 2 ++ + arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts | 2 ++ + arch/arm64/boot/dts/amlogic/meson-gxm-q200.dts | 2 ++ + 5 files changed, 10 insertions(+) + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts +index 2e853c082a654..4a4251001bfd5 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts +@@ -168,6 +168,8 @@ + eth_phy0: ethernet-phy@0 { + /* Realtek RTL8211F (0x001cc916) */ + reg = <0>; ++ interrupt-parent = <&gpio_intc>; ++ interrupts = <29 IRQ_TYPE_LEVEL_LOW>; + }; + }; + }; +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts +index 2e5ed59e697ed..f8d221463c60a 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts +@@ -157,6 +157,8 @@ + + eth_phy0: ethernet-phy@0 { + reg = <0>; ++ interrupt-parent = <&gpio_intc>; ++ interrupts = <29 IRQ_TYPE_LEVEL_LOW>; + eee-broken-1000t; + }; + }; +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-p200.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-p200.dts +index 2054a474e0a91..9bf16bb7c491b 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-p200.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-p200.dts +@@ -117,6 +117,8 @@ + eth_phy0: ethernet-phy@3 { + /* Micrel KSZ9031 (0x00221620) */ + reg = <3>; ++ interrupt-parent = <&gpio_intc>; ++ interrupts = <29 IRQ_TYPE_LEVEL_LOW>; + }; + }; + }; +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts +index 6827f235d7cfe..4f3f03fc31b0d 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts +@@ -128,6 +128,8 @@ + compatible = "ethernet-phy-id001c.c916", "ethernet-phy-ieee802.3-c22"; + reg = <0>; + max-speed = <1000>; ++ interrupt-parent = <&gpio_intc>; ++ interrupts = <29 IRQ_TYPE_LEVEL_LOW>; + }; + }; + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm-q200.dts b/arch/arm64/boot/dts/amlogic/meson-gxm-q200.dts +index b65776b019118..66c6da7e112cf 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxm-q200.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxm-q200.dts +@@ -110,6 +110,8 @@ + compatible = "ethernet-phy-id001c.c916", "ethernet-phy-ieee802.3-c22"; + reg = <0>; + max-speed = <1000>; ++ interrupt-parent = <&gpio_intc>; ++ interrupts = <29 IRQ_TYPE_LEVEL_LOW>; + }; + }; + diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/0031-ARM64-dts-meson-gx-add-VPU-power-domain.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/058_linux-4.14.y-bpo-dts-0015-arm64-dts-meson-gx-add_vpu_power_domain.patch similarity index 91% rename from buildroot-external/board/hardkernel/odroid-c2/patches/linux/0031-ARM64-dts-meson-gx-add-VPU-power-domain.patch rename to buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/058_linux-4.14.y-bpo-dts-0015-arm64-dts-meson-gx-add_vpu_power_domain.patch index 57f3cb118..b02d6c2b3 100644 --- a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/0031-ARM64-dts-meson-gx-add-VPU-power-domain.patch +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/058_linux-4.14.y-bpo-dts-0015-arm64-dts-meson-gx-add_vpu_power_domain.patch @@ -1,12 +1,13 @@ -From 107e323a199087cfb84c22b31d769f0b2e623e4a Mon Sep 17 00:00:00 2001 +From 74d1c6e9af69dc6aec07a1dd5c628ae184b15e41 Mon Sep 17 00:00:00 2001 From: Neil Armstrong -Date: Fri, 13 Oct 2017 14:47:23 +0200 -Subject: [PATCH 31/39] ARM64: dts: meson-gx: add VPU power domain +Date: Mon, 20 Nov 2017 15:19:54 +0100 +Subject: [PATCH] ARM64: dts: meson-gx: add VPU power domain This patch adds support for the VPU Power Domain nodes, and attaches the VPU power domain to the VPU node. Signed-off-by: Neil Armstrong +Signed-off-by: Kevin Hilman --- arch/arm64/boot/dts/amlogic/meson-gx.dtsi | 11 ++++++++ arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi | 43 +++++++++++++++++++++++++++++ @@ -14,10 +15,10 @@ Signed-off-by: Neil Armstrong 3 files changed, 97 insertions(+) diff --git a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi -index ff27ce0..ace0e4b 100644 +index ab7ce1644cdc5..668d891b23a0f 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi -@@ -393,6 +393,12 @@ +@@ -377,6 +377,12 @@ compatible = "amlogic,meson-gx-ao-sysctrl", "syscon", "simple-mfd"; reg = <0x0 0x0 0x0 0x100>; @@ -30,7 +31,7 @@ index ff27ce0..ace0e4b 100644 clkc_AO: clock-controller { compatible = "amlogic,meson-gx-aoclkc"; #clock-cells = <1>; -@@ -470,6 +476,11 @@ +@@ -454,6 +460,11 @@ #size-cells = <2>; ranges = <0x0 0x0 0x0 0xc883c000 0x0 0x2000>; @@ -43,10 +44,10 @@ index ff27ce0..ace0e4b 100644 compatible = "amlogic,meson-gx-mhu", "amlogic,meson-gxbb-mhu"; reg = <0 0x404 0 0x4c>; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi -index ef12d67..b5b6b33 100644 +index ead895a4e9a5c..6904872f08af5 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi -@@ -692,6 +692,48 @@ +@@ -694,6 +694,48 @@ }; }; @@ -95,18 +96,18 @@ index ef12d67..b5b6b33 100644 &saradc { compatible = "amlogic,meson-gxbb-saradc", "amlogic,meson-saradc"; clocks = <&xtal>, -@@ -761,4 +803,5 @@ +@@ -763,4 +805,5 @@ &vpu { compatible = "amlogic,meson-gxbb-vpu", "amlogic,meson-gx-vpu"; + power-domains = <&pwrc_vpu>; }; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi -index 02b52b6..d5c8952 100644 +index 8ed981f59e5ae..49b8ec159603c 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi -@@ -721,6 +721,48 @@ - clock-names = "fast", "iface", "bclks", "mclk"; +@@ -644,6 +644,48 @@ + }; }; +&pwrc_vpu { @@ -154,12 +155,9 @@ index 02b52b6..d5c8952 100644 &saradc { compatible = "amlogic,meson-gxl-saradc", "amlogic,meson-saradc"; clocks = <&xtal>, -@@ -790,4 +832,5 @@ +@@ -713,4 +755,5 @@ &vpu { compatible = "amlogic,meson-gxl-vpu", "amlogic,meson-gx-vpu"; + power-domains = <&pwrc_vpu>; }; --- -2.7.4 - diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/059_linux-4.14.y-bpo-dts-0016-arm64-dts-meson-drop_sana_clock_from_sar_adc.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/059_linux-4.14.y-bpo-dts-0016-arm64-dts-meson-drop_sana_clock_from_sar_adc.patch new file mode 100644 index 000000000..3823adf4a --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/059_linux-4.14.y-bpo-dts-0016-arm64-dts-meson-drop_sana_clock_from_sar_adc.patch @@ -0,0 +1,48 @@ +From e102da498ec3001009433d8d2d160eebbe6d1d69 Mon Sep 17 00:00:00 2001 +From: Xingyu Chen +Date: Thu, 16 Nov 2017 17:01:14 +0800 +Subject: [PATCH] ARM64: dts: meson: drop "sana" clock from SAR ADC + +The SAR ADC modules doesn't require The "sana" clock. + +Acked-by: Martin Blumenstingl +Singed-off-by: Xingyu Chen +Signed-off-by: Yixun Lan +Signed-off-by: Kevin Hilman +--- + arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi | 3 +-- + arch/arm64/boot/dts/amlogic/meson-gxl.dtsi | 3 +-- + 2 files changed, 2 insertions(+), 4 deletions(-) + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi +index 6904872f08af5..eeaf10c7ba74d 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi +@@ -740,10 +740,9 @@ + compatible = "amlogic,meson-gxbb-saradc", "amlogic,meson-saradc"; + clocks = <&xtal>, + <&clkc CLKID_SAR_ADC>, +- <&clkc CLKID_SANA>, + <&clkc CLKID_SAR_ADC_CLK>, + <&clkc CLKID_SAR_ADC_SEL>; +- clock-names = "clkin", "core", "sana", "adc_clk", "adc_sel"; ++ clock-names = "clkin", "core", "adc_clk", "adc_sel"; + }; + + &sd_emmc_a { +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi +index 49b8ec159603c..4a316a11a00e8 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi +@@ -690,10 +690,9 @@ + compatible = "amlogic,meson-gxl-saradc", "amlogic,meson-saradc"; + clocks = <&xtal>, + <&clkc CLKID_SAR_ADC>, +- <&clkc CLKID_SANA>, + <&clkc CLKID_SAR_ADC_CLK>, + <&clkc CLKID_SAR_ADC_SEL>; +- clock-names = "clkin", "core", "sana", "adc_clk", "adc_sel"; ++ clock-names = "clkin", "core", "adc_clk", "adc_sel"; + }; + + &sd_emmc_a { diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/060_linux-4.14.y-bpo-dts-0017-arm64-dts-meson-gx-add_hdmi_5v_regulator_on_selected.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/060_linux-4.14.y-bpo-dts-0017-arm64-dts-meson-gx-add_hdmi_5v_regulator_on_selected.patch new file mode 100644 index 000000000..ca1bb4dbe --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/060_linux-4.14.y-bpo-dts-0017-arm64-dts-meson-gx-add_hdmi_5v_regulator_on_selected.patch @@ -0,0 +1,111 @@ +From b409f625a6d55e0f0ebc570d1350c1813e65400a Mon Sep 17 00:00:00 2001 +From: Neil Armstrong +Date: Mon, 20 Nov 2017 15:19:55 +0100 +Subject: [PATCH] ARM64: dts: meson-gx: Add HDMI_5V regulator on selected + boards + +On reference boards and derivatives, the HDMI Logic is powered by an external +5V regulator. +This regulator was set by the Vendor U-Boot, add the regulator and set it always-on for now. + +Signed-off-by: Neil Armstrong +Signed-off-by: Kevin Hilman +--- + arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi | 12 ++++++++++++ + arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts | 12 ++++++++++++ + arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi | 12 ++++++++++++ + arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts | 12 ++++++++++++ + 4 files changed, 48 insertions(+) + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi +index 7d4b95e499935..aeb6d21a3beca 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi +@@ -59,6 +59,18 @@ + reg = <0x0 0x0 0x0 0x80000000>; + }; + ++ hdmi_5v: regulator-hdmi-5v { ++ compatible = "regulator-fixed"; ++ ++ regulator-name = "HDMI_5V"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ ++ gpio = <&gpio GPIOH_3 GPIO_ACTIVE_HIGH>; ++ enable-active-high; ++ regulator-always-on; ++ }; ++ + vddio_boot: regulator-vddio_boot { + compatible = "regulator-fixed"; + regulator-name = "VDDIO_BOOT"; +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts +index dc9c3b8216c2b..9671f1e3c74a9 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts +@@ -72,6 +72,18 @@ + reg = <0x0 0x0 0x0 0x80000000>; + }; + ++ hdmi_5v: regulator-hdmi-5v { ++ compatible = "regulator-fixed"; ++ ++ regulator-name = "HDMI_5V"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ ++ gpio = <&gpio GPIOH_3 GPIO_ACTIVE_HIGH>; ++ enable-active-high; ++ regulator-always-on; ++ }; ++ + vcc_3v3: regulator-vcc_3v3 { + compatible = "regulator-fixed"; + regulator-name = "VCC_3V3"; +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi +index ff09df1fd5a32..7005068346a09 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi +@@ -28,6 +28,18 @@ + reg = <0x0 0x0 0x0 0x80000000>; + }; + ++ hdmi_5v: regulator-hdmi-5v { ++ compatible = "regulator-fixed"; ++ ++ regulator-name = "HDMI_5V"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ ++ gpio = <&gpio GPIOH_3 GPIO_ACTIVE_HIGH>; ++ enable-active-high; ++ regulator-always-on; ++ }; ++ + vddio_boot: regulator-vddio_boot { + compatible = "regulator-fixed"; + regulator-name = "VDDIO_BOOT"; +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts b/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts +index 34a41b26a4ed2..d2595c08ebe7d 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts +@@ -153,6 +153,18 @@ + }; + }; + ++ hdmi_5v: regulator-hdmi-5v { ++ compatible = "regulator-fixed"; ++ ++ regulator-name = "HDMI_5V"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ ++ gpio = <&gpio GPIOH_3 GPIO_ACTIVE_HIGH>; ++ enable-active-high; ++ regulator-always-on; ++ }; ++ + vcc_3v3: regulator-vcc_3v3 { + compatible = "regulator-fixed"; + regulator-name = "VCC_3V3"; diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/0033-ARM64-dts-meson-gx-grow-reset-controller-memory-zone.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/061_linux-4.14.y-bpo-dts-0018-arm64-dts-meson-gx-grow_reset_controller_memory_zone.patch similarity index 72% rename from buildroot-external/board/hardkernel/odroid-c2/patches/linux/0033-ARM64-dts-meson-gx-grow-reset-controller-memory-zone.patch rename to buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/061_linux-4.14.y-bpo-dts-0018-arm64-dts-meson-gx-grow_reset_controller_memory_zone.patch index 9efc6c15f..07a02d6f9 100644 --- a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/0033-ARM64-dts-meson-gx-grow-reset-controller-memory-zone.patch +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/061_linux-4.14.y-bpo-dts-0018-arm64-dts-meson-gx-grow_reset_controller_memory_zone.patch @@ -1,21 +1,22 @@ -From 7c3d7dee433538e1450564582da535cac44a2361 Mon Sep 17 00:00:00 2001 +From 1eb0919836c76ed844d604f1d4a600bbfa9c9a02 Mon Sep 17 00:00:00 2001 From: Neil Armstrong -Date: Mon, 16 Oct 2017 17:00:59 +0200 -Subject: [PATCH 33/39] ARM64: dts: meson-gx: grow reset controller memory zone +Date: Mon, 20 Nov 2017 15:19:56 +0100 +Subject: [PATCH] ARM64: dts: meson-gx: grow reset controller memory zone Now the Amlogic Meson GX SoCs datasheet documents all the Reset registers, grow the memory in the node to allow usage of the level registers. Signed-off-by: Neil Armstrong +Signed-off-by: Kevin Hilman --- arch/arm64/boot/dts/amlogic/meson-gx.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi -index ace0e4b..2e0ee17 100644 +index 668d891b23a0f..7cdbf58a062f4 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi -@@ -220,7 +220,7 @@ +@@ -229,7 +229,7 @@ reset: reset-controller@4404 { compatible = "amlogic,meson-gx-reset", "amlogic,meson-gxbb-reset"; @@ -24,6 +25,3 @@ index ace0e4b..2e0ee17 100644 #reset-cells = <1>; }; --- -2.7.4 - diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/0034-ARM64-dts-odroid-c2-Add-HDMI-and-CEC-Nodes.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/062_linux-4.14.y-bpo-dts-0019-arm64-dts-odroid-c2-add_hdmi_and_cec_nodes.patch similarity index 82% rename from buildroot-external/board/hardkernel/odroid-c2/patches/linux/0034-ARM64-dts-odroid-c2-Add-HDMI-and-CEC-Nodes.patch rename to buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/062_linux-4.14.y-bpo-dts-0019-arm64-dts-odroid-c2-add_hdmi_and_cec_nodes.patch index d3bccda9e..738d115ba 100644 --- a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/0034-ARM64-dts-odroid-c2-Add-HDMI-and-CEC-Nodes.patch +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/062_linux-4.14.y-bpo-dts-0019-arm64-dts-odroid-c2-add_hdmi_and_cec_nodes.patch @@ -1,18 +1,19 @@ -From a0cd1597b6b505c8d72406d31cf408933b2993e9 Mon Sep 17 00:00:00 2001 +From fc19afa1b4aad3bcbf29bda4a52dcec10879ce15 Mon Sep 17 00:00:00 2001 From: Neil Armstrong -Date: Mon, 16 Oct 2017 17:00:26 +0200 -Subject: [PATCH 34/39] ARM64: dts: odroid-c2: Add HDMI and CEC Nodes +Date: Mon, 20 Nov 2017 15:19:57 +0100 +Subject: [PATCH] ARM64: dts: odroid-c2: Add HDMI and CEC Nodes Now the VPU Power Domain has been fixed while boothing from Mainline U-Boot, VPU and HDMI nodes can finally be added to the Odroid-C2 DTS. Signed-off-by: Neil Armstrong +Signed-off-by: Kevin Hilman --- .../arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts | 30 ++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts -index 4221e1f..dc3d1ba 100644 +index f8d221463c60a..d6d3af5eaf553 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts @@ -135,6 +135,24 @@ @@ -40,7 +41,7 @@ index 4221e1f..dc3d1ba 100644 }; ðmac { -@@ -177,6 +195,18 @@ +@@ -179,6 +197,18 @@ }; }; @@ -59,6 +60,3 @@ index 4221e1f..dc3d1ba 100644 &i2c_A { status = "okay"; pinctrl-0 = <&i2c_a_pins>; --- -2.7.4 - diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/063_linux-4.14.y-bpo-dts-0020-arm64-dts-meson-add_comments_with_the_gpio_for_the_phy.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/063_linux-4.14.y-bpo-dts-0020-arm64-dts-meson-add_comments_with_the_gpio_for_the_phy.patch new file mode 100644 index 000000000..4f898717b --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/063_linux-4.14.y-bpo-dts-0020-arm64-dts-meson-add_comments_with_the_gpio_for_the_phy.patch @@ -0,0 +1,75 @@ +From 50290cfe50bd94deb221731a25347d0ac12d9f40 Mon Sep 17 00:00:00 2001 +From: Martin Blumenstingl +Date: Sat, 2 Dec 2017 22:40:36 +0100 +Subject: [PATCH] ARM64: dts: meson: add comments with the GPIO for the PHY + interrupts + +Currently one has to look/calculate the GPIO for the PHY interrupts +manually. Add a comment for the existing PHY interrupt lines to make it +easier to find out which GPIO is used. +This is done using the following calculation: +- number of GPIO AO pins (14 on GXBB: GPIOAO_0..13) +- add the offset of the pin which is used for the interrupt (for example + GPIOZ_15 = 15 on Odroid-C2) + +Signed-off-by: Martin Blumenstingl +Reviewed-By: Jerome Brunet +Signed-off-by: Kevin Hilman +--- + arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts | 1 + + arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts | 2 ++ + arch/arm64/boot/dts/amlogic/meson-gxbb-p200.dts | 1 + + arch/arm64/boot/dts/amlogic/meson-gxm-q200.dts | 1 + + 4 files changed, 5 insertions(+) + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts +index 4a4251001bfd5..011e8e08e429b 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts +@@ -169,6 +169,7 @@ + /* Realtek RTL8211F (0x001cc916) */ + reg = <0>; + interrupt-parent = <&gpio_intc>; ++ /* MAC_INTR on GPIOZ_15 */ + interrupts = <29 IRQ_TYPE_LEVEL_LOW>; + }; + }; +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts +index d6d3af5eaf553..ee4ada61c59cf 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts +@@ -174,8 +174,10 @@ + #size-cells = <0>; + + eth_phy0: ethernet-phy@0 { ++ /* Realtek RTL8211F (0x001cc916) */ + reg = <0>; + interrupt-parent = <&gpio_intc>; ++ /* MAC_INTR on GPIOZ_15 */ + interrupts = <29 IRQ_TYPE_LEVEL_LOW>; + eee-broken-1000t; + }; +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-p200.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-p200.dts +index 9bf16bb7c491b..09f34f7ef0845 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-p200.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-p200.dts +@@ -118,6 +118,7 @@ + /* Micrel KSZ9031 (0x00221620) */ + reg = <3>; + interrupt-parent = <&gpio_intc>; ++ /* MAC_INTR on GPIOZ_15 */ + interrupts = <29 IRQ_TYPE_LEVEL_LOW>; + }; + }; +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm-q200.dts b/arch/arm64/boot/dts/amlogic/meson-gxm-q200.dts +index 66c6da7e112cf..9847fce443a85 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxm-q200.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxm-q200.dts +@@ -111,6 +111,7 @@ + reg = <0>; + max-speed = <1000>; + interrupt-parent = <&gpio_intc>; ++ /* MAC_INTR on GPIOH_3 */ + interrupts = <29 IRQ_TYPE_LEVEL_LOW>; + }; + }; diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/064_linux-4.14.y-bpo-dts-0021-arm64-dts-meson-gxm-add_the_phy_interrupt_line_on_khadas.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/064_linux-4.14.y-bpo-dts-0021-arm64-dts-meson-gxm-add_the_phy_interrupt_line_on_khadas.patch new file mode 100644 index 000000000..4ad7d2467 --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/064_linux-4.14.y-bpo-dts-0021-arm64-dts-meson-gxm-add_the_phy_interrupt_line_on_khadas.patch @@ -0,0 +1,32 @@ +From 45293920c62cc391ce0b601646d90b33e379ee96 Mon Sep 17 00:00:00 2001 +From: Martin Blumenstingl +Date: Sat, 2 Dec 2017 22:40:37 +0100 +Subject: [PATCH] ARM64: dts: meson-gxm: add the PHY interrupt line on Khadas + VIM2 + +The INTB/PMEB pin of the RTL8211F PHY on the Khadas VIM2 is routed to +GPIOZ_15. Add the corresponding interrupt using the GPIO interrupt +controller so the PHY framework doesn't have to poll the PHY for it's +status. + +Signed-off-by: Martin Blumenstingl +Reviewed-by: Jerome Brunet +Signed-off-by: Kevin Hilman +--- + arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts b/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts +index d2595c08ebe7d..1448c3dba08e8 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts +@@ -244,6 +244,9 @@ + external_phy: ethernet-phy@0 { + /* Realtek RTL8211F (0x001cc916) */ + reg = <0>; ++ interrupt-parent = <&gpio_intc>; ++ /* MAC_INTR on GPIOZ_15 */ ++ interrupts = <25 IRQ_TYPE_LEVEL_LOW>; + }; + }; + diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/065_linux-4.14.y-bpo-dts-0022-arm64-dts-meson-gx-fix_uart_pclk_clock_name.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/065_linux-4.14.y-bpo-dts-0022-arm64-dts-meson-gx-fix_uart_pclk_clock_name.patch new file mode 100644 index 000000000..4e2f0a492 --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/065_linux-4.14.y-bpo-dts-0022-arm64-dts-meson-gx-fix_uart_pclk_clock_name.patch @@ -0,0 +1,68 @@ +From 39005e562a88c61fa77acef1d2c0cb81ee6b0423 Mon Sep 17 00:00:00 2001 +From: Neil Armstrong +Date: Mon, 4 Dec 2017 10:04:53 +0100 +Subject: [PATCH] ARM64: dts: meson-gx: fix UART pclk clock name +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The clock-names for pclk was wrongly set to "core", but the bindings +specifies "pclk". +This was not cathed until the legacy non-documented bindings were removed. + +Reported-by: Andreas Färber +Fixes: f72d6f6037b7 ("ARM64: dts: meson-gx: use stable UART bindings with correct gate clock") +Signed-off-by: Neil Armstrong +Signed-off-by: Kevin Hilman +--- + arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi | 4 ++-- + arch/arm64/boot/dts/amlogic/meson-gxl.dtsi | 6 +++--- + 2 files changed, 5 insertions(+), 5 deletions(-) + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi +index ead895a4e9a5c..1fb8b9d6cb4ea 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi +@@ -753,12 +753,12 @@ + + &uart_B { + clocks = <&xtal>, <&clkc CLKID_UART1>, <&xtal>; +- clock-names = "xtal", "core", "baud"; ++ clock-names = "xtal", "pclk", "baud"; + }; + + &uart_C { + clocks = <&xtal>, <&clkc CLKID_UART2>, <&xtal>; +- clock-names = "xtal", "core", "baud"; ++ clock-names = "xtal", "pclk", "baud"; + }; + + &vpu { +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi +index 8ed981f59e5ae..6524b89e7115b 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi +@@ -688,7 +688,7 @@ + + &uart_A { + clocks = <&xtal>, <&clkc CLKID_UART0>, <&xtal>; +- clock-names = "xtal", "core", "baud"; ++ clock-names = "xtal", "pclk", "baud"; + }; + + &uart_AO { +@@ -703,12 +703,12 @@ + + &uart_B { + clocks = <&xtal>, <&clkc CLKID_UART1>, <&xtal>; +- clock-names = "xtal", "core", "baud"; ++ clock-names = "xtal", "pclk", "baud"; + }; + + &uart_C { + clocks = <&xtal>, <&clkc CLKID_UART2>, <&xtal>; +- clock-names = "xtal", "core", "baud"; ++ clock-names = "xtal", "pclk", "baud"; + }; + + &vpu { diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/066_linux-4.14.y-bpo-dts-0023-arm64-dts-meson-gxm-fix_q200_interrupt_number.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/066_linux-4.14.y-bpo-dts-0023-arm64-dts-meson-gxm-fix_q200_interrupt_number.patch new file mode 100644 index 000000000..c74b65300 --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/066_linux-4.14.y-bpo-dts-0023-arm64-dts-meson-gxm-fix_q200_interrupt_number.patch @@ -0,0 +1,30 @@ +From 3106507e1004dd398ef75d0caf048f97ba2dfd0b Mon Sep 17 00:00:00 2001 +From: Jerome Brunet +Date: Mon, 4 Dec 2017 11:05:04 +0100 +Subject: [PATCH] ARM64: dts: meson-gxm: fix q200 interrupt number + +Correct the interrupt number assigned to the Realtek PHY in the q200 + +Fixes: b94d22d94ad2 ("ARM64: dts: meson-gx: add external PHY interrupt on some platforms") +Reported-by: Martin Blumenstingl +Signed-off-by: Jerome Brunet +Signed-off-by: Kevin Hilman +--- + arch/arm64/boot/dts/amlogic/meson-gxm-q200.dts | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm-q200.dts b/arch/arm64/boot/dts/amlogic/meson-gxm-q200.dts +index 9847fce443a85..388fac4f2d977 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxm-q200.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxm-q200.dts +@@ -111,8 +111,8 @@ + reg = <0>; + max-speed = <1000>; + interrupt-parent = <&gpio_intc>; +- /* MAC_INTR on GPIOH_3 */ +- interrupts = <29 IRQ_TYPE_LEVEL_LOW>; ++ /* MAC_INTR on GPIOZ_15 */ ++ interrupts = <25 IRQ_TYPE_LEVEL_LOW>; + }; + }; + diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/067_linux-4.14.y-bpo-dts-0024-arm64-dts-amlogic-use_generic_bus_node_names.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/067_linux-4.14.y-bpo-dts-0024-arm64-dts-amlogic-use_generic_bus_node_names.patch new file mode 100644 index 000000000..d9e377d2e --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/067_linux-4.14.y-bpo-dts-0024-arm64-dts-amlogic-use_generic_bus_node_names.patch @@ -0,0 +1,47 @@ +From 0cb6c604232ccb6bbbd148c7451f99f9101b46d7 Mon Sep 17 00:00:00 2001 +From: Kevin Hilman +Date: Wed, 6 Dec 2017 11:30:05 -0800 +Subject: [PATCH] ARM64: dts: amlogic: use generic bus node names + +The DT spec recommends that node-names have generic names like "bus". +Fix that in the Amlogic DTs, while leaving the label names to have more +SoC-specific names that match with the HW documentation. + +Suggested-by: Stephen Boyd +Reviewed-by: Neil Armstrong +Signed-off-by: Kevin Hilman +--- + arch/arm64/boot/dts/amlogic/meson-gx.dtsi | 6 +++--- + 1 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi +index 7cdbf58a062f4..6cb3c2a52bafe 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi +@@ -211,7 +211,7 @@ + #size-cells = <2>; + ranges; + +- cbus: cbus@c1100000 { ++ cbus: bus@c1100000 { + compatible = "simple-bus"; + reg = <0x0 0xc1100000 0x0 0x100000>; + #address-cells = <2>; +@@ -366,7 +366,7 @@ + }; + }; + +- aobus: aobus@c8100000 { ++ aobus: bus@c8100000 { + compatible = "simple-bus"; + reg = <0x0 0xc8100000 0x0 0x100000>; + #address-cells = <2>; +@@ -453,7 +453,7 @@ + }; + }; + +- hiubus: hiubus@c883c000 { ++ hiubus: bus@c883c000 { + compatible = "simple-bus"; + reg = <0x0 0xc883c000 0x0 0x2000>; + #address-cells = <2>; diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/068_linux-4.14.y-bpo-dts-0025-arm64-dts-meson-uart-fix_address_space_range.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/068_linux-4.14.y-bpo-dts-0025-arm64-dts-meson-uart-fix_address_space_range.patch new file mode 100644 index 000000000..7505ed2d9 --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/068_linux-4.14.y-bpo-dts-0025-arm64-dts-meson-uart-fix_address_space_range.patch @@ -0,0 +1,61 @@ +From 77f5cdbd78ec5e17022725a5da476f4ca08b1dfa Mon Sep 17 00:00:00 2001 +From: Yixun Lan +Date: Thu, 11 Jan 2018 10:33:57 +0800 +Subject: [PATCH] ARM64: dts: meson: uart: fix address space range + +The address space range is actually 0x18, fixed here. + +Reviewed-by: Jerome Brunet +Signed-off-by: Yixun Lan +Signed-off-by: Kevin Hilman +--- + arch/arm64/boot/dts/amlogic/meson-gx.dtsi | 10 +++++----- + 1 files changed, 5 insertions(+), 5 deletions(-) + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi +index 6cb3c2a52bafe..4ee2e7951482f 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi +@@ -235,14 +235,14 @@ + + uart_A: serial@84c0 { + compatible = "amlogic,meson-gx-uart"; +- reg = <0x0 0x84c0 0x0 0x14>; ++ reg = <0x0 0x84c0 0x0 0x18>; + interrupts = ; + status = "disabled"; + }; + + uart_B: serial@84dc { + compatible = "amlogic,meson-gx-uart"; +- reg = <0x0 0x84dc 0x0 0x14>; ++ reg = <0x0 0x84dc 0x0 0x18>; + interrupts = ; + status = "disabled"; + }; +@@ -287,7 +287,7 @@ + + uart_C: serial@8700 { + compatible = "amlogic,meson-gx-uart"; +- reg = <0x0 0x8700 0x0 0x14>; ++ reg = <0x0 0x8700 0x0 0x18>; + interrupts = ; + status = "disabled"; + }; +@@ -404,14 +404,14 @@ + + uart_AO: serial@4c0 { + compatible = "amlogic,meson-gx-uart", "amlogic,meson-ao-uart"; +- reg = <0x0 0x004c0 0x0 0x14>; ++ reg = <0x0 0x004c0 0x0 0x18>; + interrupts = ; + status = "disabled"; + }; + + uart_AO_B: serial@4e0 { + compatible = "amlogic,meson-gx-uart", "amlogic,meson-ao-uart"; +- reg = <0x0 0x004e0 0x0 0x14>; ++ reg = <0x0 0x004e0 0x0 0x18>; + interrupts = ; + status = "disabled"; + }; diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/069_linux-4.14.y-bpo-dts-0026-arm64-dts-meson_s905x-accept_mac_addr_from_u-boot.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/069_linux-4.14.y-bpo-dts-0026-arm64-dts-meson_s905x-accept_mac_addr_from_u-boot.patch new file mode 100644 index 000000000..beae5faba --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/069_linux-4.14.y-bpo-dts-0026-arm64-dts-meson_s905x-accept_mac_addr_from_u-boot.patch @@ -0,0 +1,32 @@ +From f7c36209c46c4d162202b65eed2e66962ad8c3c1 Mon Sep 17 00:00:00 2001 +From: Jorge Ramirez-Ortiz +Date: Wed, 17 Jan 2018 11:55:43 +0100 +Subject: [PATCH] ARM64: dts: meson s905x: accept MAC addr from u-boot + environment + +With the adequate configuration settings, u-boot will loop through the +list of aliases looking for "ethernetX". + +By adding an ethernet alias, u-boot can fixup the local-mac-address +property in the kernel's device tree using a value held in its +environment variable ethaddr. + +Tested-by: Jorge Ramirez-Ortiz +Signed-off-by: Jorge Ramirez-Ortiz +Signed-off-by: Kevin Hilman +--- + arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts +index 9671f1e3c74a9..a011d51fec244 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts +@@ -18,6 +18,7 @@ + + aliases { + serial0 = &uart_AO; ++ ethernet0 = ðmac; + }; + + chosen { diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/070_linux-4.14.y-bpo-dts-0027-arm64-dts-meson-accept_mac_addr_from_u-boot_environment.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/070_linux-4.14.y-bpo-dts-0027-arm64-dts-meson-accept_mac_addr_from_u-boot_environment.patch new file mode 100644 index 000000000..cfc1aa40b --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/070_linux-4.14.y-bpo-dts-0027-arm64-dts-meson-accept_mac_addr_from_u-boot_environment.patch @@ -0,0 +1,171 @@ +From 059a58fcd53a78b898f26c26a1c37816ba306933 Mon Sep 17 00:00:00 2001 +From: Jorge Ramirez-Ortiz +Date: Wed, 17 Jan 2018 11:56:27 +0100 +Subject: [PATCH] ARM64: dts: meson: accept MAC addr from u-boot environment + +Extend configuring the MAC address from u-boot to all meson boards. + +I didn't test this changeset but having checked libretech's u-boot +tree I believe it should just work. + +Signed-off-by: Jorge Ramirez-Ortiz +Signed-off-by: Kevin Hilman +--- + arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi | 1 + + arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts | 1 + + arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts | 1 + + arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts | 1 + + arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi | 1 + + arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi | 1 + + arch/arm64/boot/dts/amlogic/meson-gxl-s905x-hwacom-amazetv.dts | 1 + + arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts | 1 + + arch/arm64/boot/dts/amlogic/meson-gxl-s905x-nexbox-a95x.dts | 1 + + arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi | 1 + + arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts | 1 + + arch/arm64/boot/dts/amlogic/meson-gxm-rbox-pro.dts | 1 + + 12 files changed, 12 insertions(+) + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi +index aeb6d21a3beca..4b28a6e31175b 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi +@@ -48,6 +48,7 @@ + / { + aliases { + serial0 = &uart_AO; ++ ethernet0 = ðmac; + }; + + chosen { +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts +index 011e8e08e429b..2ce7258a147bb 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts +@@ -52,6 +52,7 @@ + + aliases { + serial0 = &uart_AO; ++ ethernet0 = ðmac; + }; + + chosen { +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts +index 818954b1d57f8..855dd9ae07160 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts +@@ -54,6 +54,7 @@ + + aliases { + serial0 = &uart_AO; ++ ethernet0 = ðmac; + }; + + chosen { +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts +index ee4ada61c59cf..73a030a5ecf33 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts +@@ -53,6 +53,7 @@ + + aliases { + serial0 = &uart_AO; ++ ethernet0 = ðmac; + }; + + chosen { +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi +index 932158a778ef8..c6f7b51e2ec8f 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi +@@ -47,6 +47,7 @@ + / { + aliases { + serial0 = &uart_AO; ++ ethernet0 = ðmac; + }; + + chosen { +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi +index 1fe8e24cf675c..383f9de734c10 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi +@@ -47,6 +47,7 @@ + + aliases { + serial0 = &uart_AO; ++ ethernet0 = ðmac; + }; + + chosen { +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-hwacom-amazetv.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-hwacom-amazetv.dts +index e82582574160c..386fab4d1c8f3 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-hwacom-amazetv.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-hwacom-amazetv.dts +@@ -16,6 +16,7 @@ + + aliases { + serial0 = &uart_AO; ++ ethernet0 = ðmac; + }; + + chosen { +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts +index 71a6e1ce7ad58..94cddf59646ae 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts +@@ -29,6 +29,7 @@ + + aliases { + serial2 = &uart_AO_B; ++ ethernet0 = ðmac; + }; + + gpio-keys-polled { +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-nexbox-a95x.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-nexbox-a95x.dts +index 271f142791808..6b05c0e577248 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-nexbox-a95x.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-nexbox-a95x.dts +@@ -52,6 +52,7 @@ + + aliases { + serial0 = &uart_AO; ++ ethernet0 = ðmac; + }; + + chosen { +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi +index 7005068346a09..9cde3d2eef972 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi +@@ -17,6 +17,7 @@ + aliases { + serial0 = &uart_AO; + serial1 = &uart_A; ++ ethernet0 = ðmac; + }; + + chosen { +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts b/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts +index e7a228f6cc7e7..15cdd938f6a21 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts +@@ -54,6 +54,7 @@ + + aliases { + serial0 = &uart_AO; ++ ethernet0 = ðmac; + }; + + chosen { +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm-rbox-pro.dts b/arch/arm64/boot/dts/amlogic/meson-gxm-rbox-pro.dts +index a5e9b955d5ed3..67fadea68e075 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxm-rbox-pro.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxm-rbox-pro.dts +@@ -58,6 +58,7 @@ + + aliases { + serial0 = &uart_AO; ++ ethernet0 = ðmac; + }; + + chosen { diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/071_linux-4.14.y-bpo-dts-0028-arm64-dts-meson-remove_cooling-min_max-level_for_cpu.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/071_linux-4.14.y-bpo-dts-0028-arm64-dts-meson-remove_cooling-min_max-level_for_cpu.patch new file mode 100644 index 000000000..f55196cdf --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/071_linux-4.14.y-bpo-dts-0028-arm64-dts-meson-remove_cooling-min_max-level_for_cpu.patch @@ -0,0 +1,38 @@ +From f65f2df29d7b4e77318635ec33e95d801a9e40dd Mon Sep 17 00:00:00 2001 +From: Viresh Kumar +Date: Fri, 9 Feb 2018 14:28:06 +0530 +Subject: [PATCH] ARM64: dts: meson: Remove "cooling-{min|max}-level" for CPU + nodes + +The "cooling-min-level" and "cooling-max-level" properties are not +parsed by any part of the kernel currently and the max cooling state of +a CPU cooling device is found by referring to the cpufreq table instead. + +Remove the unused properties from the CPU nodes. + +Signed-off-by: Viresh Kumar +Acked-by: Neil Armstrong +Signed-off-by: Arnd Bergmann +--- + arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts b/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts +index 447b9e22cf8e3..f9a50f861cd38 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts +@@ -208,14 +208,10 @@ + }; + + &cpu0 { +- cooling-min-level = <0>; +- cooling-max-level = <6>; + #cooling-cells = <2>; + }; + + &cpu4 { +- cooling-min-level = <0>; +- cooling-max-level = <4>; + #cooling-cells = <2>; + }; + diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/072_linux-4.14.y-bpo-dts-0029-arm64-dts-meson-remove_cooling-min_max-level_for.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/072_linux-4.14.y-bpo-dts-0029-arm64-dts-meson-remove_cooling-min_max-level_for.patch new file mode 100644 index 000000000..d22f34de0 --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/072_linux-4.14.y-bpo-dts-0029-arm64-dts-meson-remove_cooling-min_max-level_for.patch @@ -0,0 +1,33 @@ +From b6f67b039c64572adced5d5c0f01dc944e251bc2 Mon Sep 17 00:00:00 2001 +From: Viresh Kumar +Date: Fri, 9 Feb 2018 14:28:08 +0530 +Subject: [PATCH] ARM64: dts: meson: Remove "cooling-{min|max}-level" for + gpio-fan node + +The "cooling-min-level" and "cooling-max-level" properties are not +parsed by any part of the kernel currently and the max cooling state of +gpio-fan cooling device is found by referring to the +"gpio-fan,speed-map" instead. + +Remove the unused properties from the gpio-fan node. + +Signed-off-by: Viresh Kumar +Acked-by: Neil Armstrong +Signed-off-by: Arnd Bergmann +--- + arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts b/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts +index f9a50f861cd38..4fd46c1546a7e 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts +@@ -58,8 +58,6 @@ + 1 1 + 2 2 + 3 3>; +- cooling-min-level = <0>; +- cooling-max-level = <3>; + #cooling-cells = <2>; + }; + diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/073_linux-4.14.y-bpo-dts-0030-arm64-dts-meson-gxbb-wetek-add_a_wetek_specific_dtsi_to.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/073_linux-4.14.y-bpo-dts-0030-arm64-dts-meson-gxbb-wetek-add_a_wetek_specific_dtsi_to.patch new file mode 100644 index 000000000..d20967415 --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/073_linux-4.14.y-bpo-dts-0030-arm64-dts-meson-gxbb-wetek-add_a_wetek_specific_dtsi_to.patch @@ -0,0 +1,454 @@ +From fb72c03e0e32068a0a2ff66c2787814142d9a211 Mon Sep 17 00:00:00 2001 +From: Neil Armstrong +Date: Tue, 6 Mar 2018 17:19:33 +0100 +Subject: [PATCH] ARM64: dts: meson-gxbb-wetek: add a wetek specific dtsi to + cleanup hub and play2 + +This patch adds a specific wetek dtsi to handle the specific Hub and Play2 +boards by no more depending on the p20x dtsi. +This simplifies the hub and play2 dts and will avoid breaking these +boards when adding p200 and p201 specific changes. + +Signed-off-by: Neil Armstrong +Signed-off-by: Kevin Hilman +--- + .../boot/dts/amlogic/meson-gxbb-wetek-hub.dts | 43 +--- + .../boot/dts/amlogic/meson-gxbb-wetek-play2.dts | 83 +------ + arch/arm64/boot/dts/amlogic/meson-gxbb-wetek.dtsi | 256 +++++++++++++++++++++ + 3 files changed, 262 insertions(+), 120 deletions(-) + create mode 100644 arch/arm64/boot/dts/amlogic/meson-gxbb-wetek.dtsi + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek-hub.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek-hub.dts +index ce80d5d0982c0..2bfe69902552e 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek-hub.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek-hub.dts +@@ -6,50 +6,9 @@ + + /dts-v1/; + +-#include "meson-gxbb-p20x.dtsi" ++#include "meson-gxbb-wetek.dtsi" + + / { + compatible = "wetek,hub", "amlogic,meson-gxbb"; + model = "WeTek Hub"; +- +- leds { +- compatible = "gpio-leds"; +- +- system { +- label = "wetek-play:system-status"; +- gpios = <&gpio_ao GPIOAO_13 GPIO_ACTIVE_HIGH>; +- default-state = "on"; +- panic-indicator; +- }; +- }; +-}; +- +-&cvbs_connector { +- status = "disabled"; +-}; +- +-ðmac { +- status = "okay"; +- pinctrl-0 = <ð_rgmii_pins>; +- pinctrl-names = "default"; +- +- phy-handle = <ð_phy0>; +- phy-mode = "rgmii"; +- +- amlogic,tx-delay-ns = <2>; +- +- snps,reset-gpio = <&gpio GPIOZ_14 0>; +- snps,reset-delays-us = <0 10000 1000000>; +- snps,reset-active-low; +- +- mdio { +- compatible = "snps,dwmac-mdio"; +- #address-cells = <1>; +- #size-cells = <0>; +- +- eth_phy0: ethernet-phy@0 { +- /* Realtek RTL8211F (0x001cc916) */ +- reg = <0>; +- }; +- }; + }; +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek-play2.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek-play2.dts +index 0d1f080cbb3e6..0038522315de7 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek-play2.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek-play2.dts +@@ -6,7 +6,7 @@ + + /dts-v1/; + +-#include "meson-gxbb-p20x.dtsi" ++#include "meson-gxbb-wetek.dtsi" + #include + + / { +@@ -14,15 +14,6 @@ + model = "WeTek Play 2"; + + leds { +- compatible = "gpio-leds"; +- +- system { +- label = "wetek-play:system-status"; +- gpios = <&gpio_ao GPIOAO_13 GPIO_ACTIVE_HIGH>; +- default-state = "on"; +- panic-indicator; +- }; +- + wifi { + label = "wetek-play:wifi-status"; + gpios = <&gpio GPIODV_26 GPIO_ACTIVE_HIGH>; +@@ -48,82 +39,18 @@ + gpios = <&gpio_ao GPIOAO_3 GPIO_ACTIVE_LOW>; + }; + }; +- +- cvbs-connector { +- compatible = "composite-video-connector"; +- +- port { +- cvbs_connector_in: endpoint { +- remote-endpoint = <&cvbs_vdac_out>; +- }; +- }; +- }; +- +- hdmi-connector { +- compatible = "hdmi-connector"; +- type = "a"; +- +- port { +- hdmi_connector_in: endpoint { +- remote-endpoint = <&hdmi_tx_tmds_out>; +- }; +- }; +- }; +-}; +- +-&cec_AO { +- status = "okay"; +- pinctrl-0 = <&ao_cec_pins>; +- pinctrl-names = "default"; +- hdmi-phandle = <&hdmi_tx>; +-}; +- +-&cvbs_vdac_port { +- cvbs_vdac_out: endpoint { +- remote-endpoint = <&cvbs_connector_in>; +- }; + }; + +-ðmac { ++&i2c_A { + status = "okay"; +- pinctrl-0 = <ð_rgmii_pins>; ++ pinctrl-0 = <&i2c_a_pins>; + pinctrl-names = "default"; +- +- phy-handle = <ð_phy0>; +- phy-mode = "rgmii"; +- +- amlogic,tx-delay-ns = <2>; +- +- snps,reset-gpio = <&gpio GPIOZ_14 0>; +- snps,reset-delays-us = <0 10000 1000000>; +- snps,reset-active-low; +- +- mdio { +- compatible = "snps,dwmac-mdio"; +- #address-cells = <1>; +- #size-cells = <0>; +- +- eth_phy0: ethernet-phy@0 { +- /* Realtek RTL8211F (0x001cc916) */ +- reg = <0>; +- }; +- }; + }; + +-&hdmi_tx { ++&usb1_phy { + status = "okay"; +- pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>; +- pinctrl-names = "default"; + }; + +-&hdmi_tx_tmds_port { +- hdmi_tx_tmds_out: endpoint { +- remote-endpoint = <&hdmi_connector_in>; +- }; +-}; +- +-&i2c_A { ++&usb1 { + status = "okay"; +- pinctrl-0 = <&i2c_a_pins>; +- pinctrl-names = "default"; + }; +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek.dtsi +new file mode 100644 +index 0000000000000..70325b273bd2b +--- /dev/null ++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek.dtsi +@@ -0,0 +1,256 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++/* ++ * Copyright (c) 2016 Andreas Färber ++ * Copyright (c) 2016 BayLibre, Inc. ++ * Author: Kevin Hilman ++ */ ++ ++#include "meson-gxbb.dtsi" ++ ++/ { ++ aliases { ++ serial0 = &uart_AO; ++ ethernet0 = ðmac; ++ }; ++ ++ chosen { ++ stdout-path = "serial0:115200n8"; ++ }; ++ ++ memory@0 { ++ device_type = "memory"; ++ reg = <0x0 0x0 0x0 0x40000000>; ++ }; ++ ++ leds { ++ compatible = "gpio-leds"; ++ ++ system { ++ label = "wetek-play:system-status"; ++ gpios = <&gpio_ao GPIOAO_13 GPIO_ACTIVE_HIGH>; ++ default-state = "on"; ++ panic-indicator; ++ }; ++ }; ++ ++ usb_pwr: regulator-usb-pwrs { ++ compatible = "regulator-fixed"; ++ ++ regulator-name = "USB_PWR"; ++ ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ ++ gpio = <&gpio GPIODV_24 GPIO_ACTIVE_HIGH>; ++ enable-active-high; ++ }; ++ ++ vddio_boot: regulator-vddio_boot { ++ compatible = "regulator-fixed"; ++ regulator-name = "VDDIO_BOOT"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ }; ++ ++ vddao_3v3: regulator-vddao_3v3 { ++ compatible = "regulator-fixed"; ++ regulator-name = "VDDAO_3V3"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ }; ++ ++ vcc_3v3: regulator-vcc_3v3 { ++ compatible = "regulator-fixed"; ++ regulator-name = "VCC_3V3"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ }; ++ ++ emmc_pwrseq: emmc-pwrseq { ++ compatible = "mmc-pwrseq-emmc"; ++ reset-gpios = <&gpio BOOT_9 GPIO_ACTIVE_LOW>; ++ }; ++ ++ wifi32k: wifi32k { ++ compatible = "pwm-clock"; ++ #clock-cells = <0>; ++ clock-frequency = <32768>; ++ pwms = <&pwm_ef 0 30518 0>; /* PWM_E at 32.768KHz */ ++ }; ++ ++ sdio_pwrseq: sdio-pwrseq { ++ compatible = "mmc-pwrseq-simple"; ++ reset-gpios = <&gpio GPIOX_6 GPIO_ACTIVE_LOW>; ++ clocks = <&wifi32k>; ++ clock-names = "ext_clock"; ++ }; ++ ++ cvbs-connector { ++ compatible = "composite-video-connector"; ++ ++ port { ++ cvbs_connector_in: endpoint { ++ remote-endpoint = <&cvbs_vdac_out>; ++ }; ++ }; ++ }; ++ ++ hdmi-connector { ++ compatible = "hdmi-connector"; ++ type = "a"; ++ ++ port { ++ hdmi_connector_in: endpoint { ++ remote-endpoint = <&hdmi_tx_tmds_out>; ++ }; ++ }; ++ }; ++}; ++ ++&cec_AO { ++ status = "okay"; ++ pinctrl-0 = <&ao_cec_pins>; ++ pinctrl-names = "default"; ++ hdmi-phandle = <&hdmi_tx>; ++}; ++ ++&cvbs_vdac_port { ++ cvbs_vdac_out: endpoint { ++ remote-endpoint = <&cvbs_connector_in>; ++ }; ++}; ++ ++ðmac { ++ status = "okay"; ++ pinctrl-0 = <ð_rgmii_pins>; ++ pinctrl-names = "default"; ++ ++ phy-handle = <ð_phy0>; ++ phy-mode = "rgmii"; ++ ++ amlogic,tx-delay-ns = <2>; ++ ++ snps,reset-gpio = <&gpio GPIOZ_14 0>; ++ snps,reset-delays-us = <0 10000 1000000>; ++ snps,reset-active-low; ++ ++ mdio { ++ compatible = "snps,dwmac-mdio"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ eth_phy0: ethernet-phy@0 { ++ /* Realtek RTL8211F (0x001cc916) */ ++ reg = <0>; ++ eee-broken-1000t; ++ }; ++ }; ++}; ++ ++&hdmi_tx { ++ status = "okay"; ++ pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>; ++ pinctrl-names = "default"; ++}; ++ ++&hdmi_tx_tmds_port { ++ hdmi_tx_tmds_out: endpoint { ++ remote-endpoint = <&hdmi_connector_in>; ++ }; ++}; ++ ++&ir { ++ status = "okay"; ++ pinctrl-0 = <&remote_input_ao_pins>; ++ pinctrl-names = "default"; ++}; ++ ++&pwm_ef { ++ status = "okay"; ++ pinctrl-0 = <&pwm_e_pins>; ++ pinctrl-names = "default"; ++ clocks = <&clkc CLKID_FCLK_DIV4>; ++ clock-names = "clkin0"; ++}; ++ ++/* Wireless SDIO Module */ ++&sd_emmc_a { ++ status = "okay"; ++ pinctrl-0 = <&sdio_pins>; ++ pinctrl-1 = <&sdio_clk_gate_pins>; ++ pinctrl-names = "default", "clk-gate"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ bus-width = <4>; ++ cap-sd-highspeed; ++ max-frequency = <100000000>; ++ ++ non-removable; ++ disable-wp; ++ ++ mmc-pwrseq = <&sdio_pwrseq>; ++ ++ vmmc-supply = <&vddao_3v3>; ++ vqmmc-supply = <&vddio_boot>; ++ ++ brcmf: wifi@1 { ++ reg = <1>; ++ compatible = "brcm,bcm4329-fmac"; ++ }; ++}; ++ ++/* SD card */ ++&sd_emmc_b { ++ status = "okay"; ++ pinctrl-0 = <&sdcard_pins>; ++ pinctrl-1 = <&sdcard_clk_gate_pins>; ++ pinctrl-names = "default", "clk-gate"; ++ ++ bus-width = <4>; ++ cap-sd-highspeed; ++ max-frequency = <100000000>; ++ disable-wp; ++ ++ cd-gpios = <&gpio CARD_6 GPIO_ACTIVE_HIGH>; ++ cd-inverted; ++ ++ vmmc-supply = <&vddao_3v3>; ++ vqmmc-supply = <&vcc_3v3>; ++}; ++ ++/* eMMC */ ++&sd_emmc_c { ++ status = "okay"; ++ pinctrl-0 = <&emmc_pins>, <&emmc_ds_pins>; ++ pinctrl-1 = <&emmc_clk_gate_pins>; ++ pinctrl-names = "default", "clk-gate"; ++ ++ bus-width = <8>; ++ cap-mmc-highspeed; ++ max-frequency = <200000000>; ++ non-removable; ++ disable-wp; ++ mmc-ddr-1_8v; ++ mmc-hs200-1_8v; ++ ++ mmc-pwrseq = <&emmc_pwrseq>; ++ vmmc-supply = <&vcc_3v3>; ++ vqmmc-supply = <&vddio_boot>; ++}; ++ ++/* This UART is brought out to the DB9 connector */ ++&uart_AO { ++ status = "okay"; ++ pinctrl-0 = <&uart_ao_a_pins>; ++ pinctrl-names = "default"; ++}; ++ ++&usb0_phy { ++ status = "okay"; ++ phy-supply = <&usb_pwr>; ++}; ++ ++&usb0 { ++ status = "okay"; ++}; diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/0038-ARM64-dts-meson-bump-mali450-clk-to-744MHz.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/074_linux-4.14.y-bpo-dts-0031-arm64-dts-meson-bump_mali450_clk_to_744mhz.patch similarity index 82% rename from buildroot-external/board/hardkernel/odroid-c2/patches/linux/0038-ARM64-dts-meson-bump-mali450-clk-to-744MHz.patch rename to buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/074_linux-4.14.y-bpo-dts-0031-arm64-dts-meson-bump_mali450_clk_to_744mhz.patch index ac9930839..ebdb54757 100644 --- a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/0038-ARM64-dts-meson-bump-mali450-clk-to-744MHz.patch +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/074_linux-4.14.y-bpo-dts-0031-arm64-dts-meson-bump_mali450_clk_to_744mhz.patch @@ -1,19 +1,24 @@ -From 63ffa5db0046106f6c3b8687e200e17599e14b9f Mon Sep 17 00:00:00 2001 +From 97ac00930970bc9e3982182891e350ae1764fbb5 Mon Sep 17 00:00:00 2001 From: Neil Armstrong -Date: Fri, 23 Feb 2018 11:18:11 +0100 -Subject: [PATCH 38/39] ARM64: dts: meson: bump mali450 clk to 744MHz +Date: Mon, 12 Mar 2018 12:10:21 +0100 +Subject: [PATCH] ARM64: dts: meson: bump mali450 clk to 744MHz +The Mali-450 IP can run up to 744MHz, bump the frequency using +the GP0 PLL clock. + +Cc: Michal Lazo Signed-off-by: Neil Armstrong +Signed-off-by: Kevin Hilman --- arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi | 11 +++++++---- arch/arm64/boot/dts/amlogic/meson-gxl-mali.dtsi | 11 +++++++---- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi -index b5b6b33..d00a9f2 100644 +index cac72acb85b1a..562c26a0ba333 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi -@@ -288,14 +288,17 @@ +@@ -247,14 +247,17 @@ * MALI_0 and MALI_1 muxed to a single clock by a glitch * free mux to safely change frequency while running. */ @@ -36,10 +41,10 @@ index b5b6b33..d00a9f2 100644 }; }; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-mali.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl-mali.dtsi -index f06cc234..972df67 100644 +index f825506cdf64f..eb327664a4d8c 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxl-mali.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-gxl-mali.dtsi -@@ -30,14 +30,17 @@ +@@ -29,14 +29,17 @@ * MALI_0 and MALI_1 muxed to a single clock by a glitch * free mux to safely change frequency while running. */ @@ -61,6 +66,3 @@ index f06cc234..972df67 100644 <0>; /* Do Nothing */ }; }; --- -2.7.4 - diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/075_linux-4.14.y-bpo-dts-0032-arm64-dts-meson-gx-make_efuse_read-only.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/075_linux-4.14.y-bpo-dts-0032-arm64-dts-meson-gx-make_efuse_read-only.patch new file mode 100644 index 000000000..aa603bf8c --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/075_linux-4.14.y-bpo-dts-0032-arm64-dts-meson-gx-make_efuse_read-only.patch @@ -0,0 +1,27 @@ +From c339f0e29ce9f9cd1cd2b6759a29a298bce1e948 Mon Sep 17 00:00:00 2001 +From: Jerome Brunet +Date: Fri, 16 Mar 2018 15:50:21 +0100 +Subject: [PATCH] ARM64: dts: meson-gx: make efuse read-only + +efuse is one time programmable, so it is safer to deny write request +to this memory, unless the user is savvy enough to remove the read-only +flag from DTB + +Signed-off-by: Jerome Brunet +Signed-off-by: Kevin Hilman +--- + arch/arm64/boot/dts/amlogic/meson-gx.dtsi | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi +index 2d51ccd60628e..3c31e21cbed7f 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi +@@ -132,6 +132,7 @@ + compatible = "amlogic,meson-gx-efuse", "amlogic,meson-gxbb-efuse"; + #address-cells = <1>; + #size-cells = <1>; ++ read-only; + + sn: sn@14 { + reg = <0x14 0x10>; diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/076_linux-4.14.y-bpo-dts-0033-arm64-dts-meson-gxl-s905x-p212-enable_the_usb_controller.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/076_linux-4.14.y-bpo-dts-0033-arm64-dts-meson-gxl-s905x-p212-enable_the_usb_controller.patch new file mode 100644 index 000000000..49cc0e2ae --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/076_linux-4.14.y-bpo-dts-0033-arm64-dts-meson-gxl-s905x-p212-enable_the_usb_controller.patch @@ -0,0 +1,30 @@ +From b9f07cb4f41fccbe7616482015d28e6e26aec3a3 Mon Sep 17 00:00:00 2001 +From: Martin Blumenstingl +Date: Mon, 26 Mar 2018 23:17:44 +0200 +Subject: [PATCH] ARM64: dts: meson-gxl-s905x-p212: enable the USB controller + +All boards based on the P212 reference design (the P212 reference board +itself and the Khadas VIM) have USB connectors (in case of the Khadas +VIM the first port is exposed through the USB Type-C connector, the +second port is connected to a 4-port USB hub). +This enables the USB controller on these boards to make the USB ports +actually usable. + +Signed-off-by: Martin Blumenstingl +Signed-off-by: Kevin Hilman +--- + arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi +index 0a0953fbc7d42..0cfd701809dec 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi +@@ -185,3 +185,7 @@ + pinctrl-0 = <&uart_ao_a_pins>; + pinctrl-names = "default"; + }; ++ ++&usb0 { ++ status = "okay"; ++}; diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/077_linux-4.14.y-bpo-dts-0034-arm64-dts-meson-gxl-s905x-libretech-cc-enable_the_usb.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/077_linux-4.14.y-bpo-dts-0034-arm64-dts-meson-gxl-s905x-libretech-cc-enable_the_usb.patch new file mode 100644 index 000000000..d89de01fc --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/077_linux-4.14.y-bpo-dts-0034-arm64-dts-meson-gxl-s905x-libretech-cc-enable_the_usb.patch @@ -0,0 +1,39 @@ +From b83687f359d9b4128073f06ab7a06489eb04aa7c Mon Sep 17 00:00:00 2001 +From: Martin Blumenstingl +Date: Mon, 26 Mar 2018 23:17:46 +0200 +Subject: [PATCH] ARM64: dts: meson-gxl-s905x-libretech-cc: enable the USB + controller + +The LibreTech CC ("Le Potato") board provides four USB connectors. +These are provided by a hub which is connected to the SoC's USB +controller. +Enable the SoC's USB controller to make the USB ports usable. Also turn +on the HDMI_5V regulator when powering on the PHY because (even though +it's not shown in the schematics) HDMI_5V also supplies the USB VBUS. + +Signed-off-by: Martin Blumenstingl +Signed-off-by: Kevin Hilman +--- + arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts +index 22bf37404ff1b..3e3eb31748a35 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts +@@ -271,3 +271,15 @@ + pinctrl-0 = <&uart_ao_a_pins>; + pinctrl-names = "default"; + }; ++ ++&usb0 { ++ status = "okay"; ++}; ++ ++&usb2_phy0 { ++ /* ++ * even though the schematics don't show it: ++ * HDMI_5V is also used as supply for the USB VBUS. ++ */ ++ phy-supply = <&hdmi_5v>; ++}; diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/078_linux-4.14.y-bpo-dts-0035-arm64-dts-meson-gxl-add_usb_host_support.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/078_linux-4.14.y-bpo-dts-0035-arm64-dts-meson-gxl-add_usb_host_support.patch new file mode 100644 index 000000000..e3e606887 --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/078_linux-4.14.y-bpo-dts-0035-arm64-dts-meson-gxl-add_usb_host_support.patch @@ -0,0 +1,105 @@ +From 8aec5fc1d4d881fe446addb94309efb39d4e5b23 Mon Sep 17 00:00:00 2001 +From: Martin Blumenstingl +Date: Mon, 26 Mar 2018 23:17:42 +0200 +Subject: [PATCH] ARM64: dts: meson-gxl: add USB host support + +This adds USB host support to the Meson GXL SoC. A dwc3 controller is +used for host-mode, while a dwc2 controller (not added in this patch +because I could not get it working) is used for device-mode only. + +The dwc3 controller's internal roothub has two USB2 ports enabled but no +USB3 port. Each of the ports is supplied by a separate PHY. The USB pins +are connected to the SoC's USBHOST_A and USBOTG_B pins. +Due to the way the roothub works internally the USB PHYs are left +enabled. When the dwc3 controller is disabled the PHY is never powered on +so it does not draw any extra power. However, when the dwc3 host +controller is enabled then all PHYs also have to be enabled, otherwise +USB devices will not be detected (regardless of whether they are plugged +into an enabled port or not). This means that only the dwc3 controller +has to be enabled on boards with USB support (instead of requiring all +boards to enable the PHYs additionally with the chance of forgetting to +enable one and breaking all other ports with that as well). + +This also adds the USB3 PHY which currently only does some basic +initialization. That however is required because without it high-speed +devices (like USB thumb drives) do not work on some devices (probably +because the bootloader does not configure the USB3 PHY registers). + +Signed-off-by: Martin Blumenstingl +Signed-off-by: Kevin Hilman +--- + arch/arm64/boot/dts/amlogic/meson-gxl.dtsi | 61 ++++++++++++++++++++++++++++++ + 1 file changed, 61 insertions(+) + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi +index e1a39cbed8c9c..dba365ed4bd5f 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi +@@ -20,6 +20,67 @@ + no-map; + }; + }; ++ ++ soc { ++ usb0: usb@c9000000 { ++ status = "disabled"; ++ compatible = "amlogic,meson-gxl-dwc3"; ++ #address-cells = <2>; ++ #size-cells = <2>; ++ ranges; ++ ++ clocks = <&clkc CLKID_USB>; ++ clock-names = "usb_general"; ++ resets = <&reset RESET_USB_OTG>; ++ reset-names = "usb_otg"; ++ ++ dwc3: dwc3@c9000000 { ++ compatible = "snps,dwc3"; ++ reg = <0x0 0xc9000000 0x0 0x100000>; ++ interrupts = ; ++ dr_mode = "host"; ++ maximum-speed = "high-speed"; ++ snps,dis_u2_susphy_quirk; ++ phys = <&usb3_phy>, <&usb2_phy0>, <&usb2_phy1>; ++ }; ++ }; ++ }; ++}; ++ ++&apb { ++ usb2_phy0: phy@78000 { ++ compatible = "amlogic,meson-gxl-usb2-phy"; ++ #phy-cells = <0>; ++ reg = <0x0 0x78000 0x0 0x20>; ++ clocks = <&clkc CLKID_USB>; ++ clock-names = "phy"; ++ resets = <&reset RESET_USB_OTG>; ++ reset-names = "phy"; ++ status = "okay"; ++ }; ++ ++ usb2_phy1: phy@78020 { ++ compatible = "amlogic,meson-gxl-usb2-phy"; ++ #phy-cells = <0>; ++ reg = <0x0 0x78020 0x0 0x20>; ++ clocks = <&clkc CLKID_USB>; ++ clock-names = "phy"; ++ resets = <&reset RESET_USB_OTG>; ++ reset-names = "phy"; ++ status = "okay"; ++ }; ++ ++ usb3_phy: phy@78080 { ++ compatible = "amlogic,meson-gxl-usb3-phy"; ++ #phy-cells = <0>; ++ reg = <0x0 0x78080 0x0 0x20>; ++ interrupts = ; ++ clocks = <&clkc CLKID_USB>, <&clkc_AO CLKID_AO_CEC_32K>; ++ clock-names = "phy", "peripheral"; ++ resets = <&reset RESET_USB_OTG>, <&reset RESET_USB_OTG>; ++ reset-names = "phy", "peripheral"; ++ status = "okay"; ++ }; + }; + + ðmac { diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/079_linux-4.14.y-bpo-dts-0036-arm64-dts-meson-gxm-add_gxm_specific_usb_host.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/079_linux-4.14.y-bpo-dts-0036-arm64-dts-meson-gxm-add_gxm_specific_usb_host.patch new file mode 100644 index 000000000..4820d9853 --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/079_linux-4.14.y-bpo-dts-0036-arm64-dts-meson-gxm-add_gxm_specific_usb_host.patch @@ -0,0 +1,53 @@ +From 458baa95c86406c81c6ebac0a98d1689075a3ec4 Mon Sep 17 00:00:00 2001 +From: Martin Blumenstingl +Date: Mon, 26 Mar 2018 23:17:43 +0200 +Subject: [PATCH] ARM64: dts: meson-gxm: add GXM specific USB host + configuration + +The USB configuration on GXM is slightly different than on GXL. The dwc3 +controller's internal hub has three USB2 ports (instead of 2 on GXL) +along with a dedicated USB2 PHY for this port. However, it seems that +there are no pins on GXM which would allow connecting the third port to +a physical USB port. +Passing the third PHY is required though, because without it none of the +other USB ports is working (this seems to be a limitation of how the +internal USB hub works, if one PHY is disabled then no USB port works). + +Signed-off-by: Martin Blumenstingl +Signed-off-by: Kevin Hilman +--- + arch/arm64/boot/dts/amlogic/meson-gxm.dtsi | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxm.dtsi +index d076a7c425ddd..247888d68a3aa 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxm.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gxm.dtsi +@@ -80,6 +80,19 @@ + }; + }; + ++&apb { ++ usb2_phy2: phy@78040 { ++ compatible = "amlogic,meson-gxl-usb2-phy"; ++ #phy-cells = <0>; ++ reg = <0x0 0x78040 0x0 0x20>; ++ clocks = <&clkc CLKID_USB>; ++ clock-names = "phy"; ++ resets = <&reset RESET_USB_OTG>; ++ reset-names = "phy"; ++ status = "okay"; ++ }; ++}; ++ + &clkc_AO { + compatible = "amlogic,meson-gxm-aoclkc", "amlogic,meson-gx-aoclkc"; + }; +@@ -100,3 +113,7 @@ + &hdmi_tx { + compatible = "amlogic,meson-gxm-dw-hdmi", "amlogic,meson-gx-dw-hdmi"; + }; ++ ++&dwc3 { ++ phys = <&usb3_phy>, <&usb2_phy0>, <&usb2_phy1>, <&usb2_phy2>; ++}; diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/080_linux-4.14.y-bpo-dts-0037-arm64-dts-meson-gx-p23x-q20x-enable_the_usb_controller.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/080_linux-4.14.y-bpo-dts-0037-arm64-dts-meson-gx-p23x-q20x-enable_the_usb_controller.patch new file mode 100644 index 000000000..aefbc6704 --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/080_linux-4.14.y-bpo-dts-0037-arm64-dts-meson-gx-p23x-q20x-enable_the_usb_controller.patch @@ -0,0 +1,28 @@ +From 972cd12a027256061c19c164021f2a771e860438 Mon Sep 17 00:00:00 2001 +From: Martin Blumenstingl +Date: Mon, 26 Mar 2018 23:17:45 +0200 +Subject: [PATCH] ARM64: dts: meson-gx-p23x-q20x: enable the USB controller + +All S905D (GXL) and S912 (GXM) reference boards (namely these are +P230, P231, Q200 and Q201) provide USB connectors. +This enables the USB controller on these boards to make the USB ports +actually usable. + +Signed-off-by: Martin Blumenstingl +Signed-off-by: Kevin Hilman +--- + arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi +index 4eef36b225386..88e712ea757a2 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi +@@ -212,3 +212,7 @@ + pinctrl-0 = <&uart_ao_a_pins>; + pinctrl-names = "default"; + }; ++ ++&usb0 { ++ status = "okay"; ++}; diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/081_linux-4.14.y-bpo-dts-0038-arm64-dts-meson-gxl-nexbox-a95x-enable_the_usb_controller.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/081_linux-4.14.y-bpo-dts-0038-arm64-dts-meson-gxl-nexbox-a95x-enable_the_usb_controller.patch new file mode 100644 index 000000000..9109f75e8 --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/081_linux-4.14.y-bpo-dts-0038-arm64-dts-meson-gxl-nexbox-a95x-enable_the_usb_controller.patch @@ -0,0 +1,26 @@ +From 55ef32249bb647c6b64adcf943918d302a0020a7 Mon Sep 17 00:00:00 2001 +From: Martin Blumenstingl +Date: Mon, 26 Mar 2018 23:17:47 +0200 +Subject: [PATCH] ARM64: dts: meson-gxl-nexbox-a95x: enable the USB controller + +The Nexbox A95X provides two USB ports. Enable the SoC's USB controller +on this board to make these USB ports usable. + +Signed-off-by: Martin Blumenstingl +Signed-off-by: Kevin Hilman +--- + arch/arm64/boot/dts/amlogic/meson-gxl-s905x-nexbox-a95x.dts | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-nexbox-a95x.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-nexbox-a95x.dts +index 69c721a70e44b..6739697be1def 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-nexbox-a95x.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-nexbox-a95x.dts +@@ -215,3 +215,7 @@ + pinctrl-0 = <&uart_ao_a_pins>; + pinctrl-names = "default"; + }; ++ ++&usb0 { ++ status = "okay"; ++}; diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/082_linux-4.14.y-bpo-dts-0039-arm64-dts-meson-gxm-khadas-vim2-enable_the_usb_controller.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/082_linux-4.14.y-bpo-dts-0039-arm64-dts-meson-gxm-khadas-vim2-enable_the_usb_controller.patch new file mode 100644 index 000000000..2d930e1b6 --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/082_linux-4.14.y-bpo-dts-0039-arm64-dts-meson-gxm-khadas-vim2-enable_the_usb_controller.patch @@ -0,0 +1,28 @@ +From 4b7b0d7b25538d2ad421a1041267d5208d3425bc Mon Sep 17 00:00:00 2001 +From: Martin Blumenstingl +Date: Mon, 26 Mar 2018 23:17:48 +0200 +Subject: [PATCH] ARM64: dts: meson-gxm-khadas-vim2: enable the USB controller + +The Khadas VIM2 board connects the dwc3 controller to an internal 4-port +USB hub which. Two of these ports are accessible directly soldered to +the board, while the other two are accessible through the 40-pin "GPIO" +header. + +Signed-off-by: Martin Blumenstingl +Signed-off-by: Kevin Hilman +--- + arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts b/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts +index 4fd46c1546a7e..0868da476e41f 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts +@@ -406,3 +406,7 @@ + status = "okay"; + vref-supply = <&vddio_ao18>; + }; ++ ++&usb0 { ++ status = "okay"; ++}; diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/083_linux-4.14.y-bpo-drm-0131-drm-bridge-synopsys-dw-hdmi-revert_fix_overflow_workaround_for_amlogic.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/083_linux-4.14.y-bpo-drm-0131-drm-bridge-synopsys-dw-hdmi-revert_fix_overflow_workaround_for_amlogic.patch new file mode 100644 index 000000000..bf1023a1c --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/083_linux-4.14.y-bpo-drm-0131-drm-bridge-synopsys-dw-hdmi-revert_fix_overflow_workaround_for_amlogic.patch @@ -0,0 +1,21 @@ +diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +index 4db31b895..bf14214fa 100644 +--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c ++++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +@@ -1634,8 +1634,6 @@ static void dw_hdmi_clear_overflow(struct dw_hdmi *hdmi) + * (and possibly on the platform). So far only i.MX6Q (v1.30a) and + * i.MX6DL (v1.31a) have been identified as needing the workaround, with + * 4 and 1 iterations respectively. +- * The Amlogic Meson GX SoCs (v2.01a) have been identified as needing +- * the workaround with a single iteration. + */ + + switch (hdmi->version) { +@@ -1643,7 +1641,6 @@ static void dw_hdmi_clear_overflow(struct dw_hdmi *hdmi) + count = 4; + break; + case 0x131a: +- case 0x201a: + count = 1; + break; + default: diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/084_linux-4.14.y-bpo-drm-0132-drm-bridge-synopsys-dw-hdmi-enable_cec_clock.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/084_linux-4.14.y-bpo-drm-0132-drm-bridge-synopsys-dw-hdmi-enable_cec_clock.patch new file mode 100644 index 000000000..07b93d4b4 --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/084_linux-4.14.y-bpo-drm-0132-drm-bridge-synopsys-dw-hdmi-enable_cec_clock.patch @@ -0,0 +1,87 @@ +From ebe32c3e282a62974b190b9d514864fc0d56716e Mon Sep 17 00:00:00 2001 +From: Pierre-Hugues Husson +Date: Sat, 25 Nov 2017 21:18:44 +0100 +Subject: [PATCH] drm/bridge: synopsys/dw-hdmi: Enable cec clock + +Support the "cec" optional clock. The documentation already mentions "cec" +optional clock and it is used by several boards, but currently the driver +doesn't enable it, thus preventing cec from working on those boards. + +And even worse: a /dev/cecX device will appear for those boards, but it +won't be functioning without configuring this clock. + +Changes: +v4: +- Change commit message to stress the importance of this patch + +v3: +- Drop useless braces + +v2: +- Separate ENOENT errors from others +- Propagate other errors (especially -EPROBE_DEFER) + +Signed-off-by: Pierre-Hugues Husson +Signed-off-by: Archit Taneja +Link: https://patchwork.freedesktop.org/patch/msgid/20171125201844.11353-1-phh@phh.me +--- + drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 25 +++++++++++++++++++++++++ + 1 file changed, 25 insertions(+) + +diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +index bf14214fa4640..b72259bf6e2fb 100644 +--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c ++++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +@@ -138,6 +138,7 @@ struct dw_hdmi { + struct device *dev; + struct clk *isfr_clk; + struct clk *iahb_clk; ++ struct clk *cec_clk; + struct dw_hdmi_i2c *i2c; + + struct hdmi_data_info hdmi_data; +@@ -2382,6 +2383,26 @@ __dw_hdmi_probe(struct platform_device *pdev, + goto err_isfr; + } + ++ hdmi->cec_clk = devm_clk_get(hdmi->dev, "cec"); ++ if (PTR_ERR(hdmi->cec_clk) == -ENOENT) { ++ hdmi->cec_clk = NULL; ++ } else if (IS_ERR(hdmi->cec_clk)) { ++ ret = PTR_ERR(hdmi->cec_clk); ++ if (ret != -EPROBE_DEFER) ++ dev_err(hdmi->dev, "Cannot get HDMI cec clock: %d\n", ++ ret); ++ ++ hdmi->cec_clk = NULL; ++ goto err_iahb; ++ } else { ++ ret = clk_prepare_enable(hdmi->cec_clk); ++ if (ret) { ++ dev_err(hdmi->dev, "Cannot enable HDMI cec clock: %d\n", ++ ret); ++ goto err_iahb; ++ } ++ } ++ + /* Product and revision IDs */ + hdmi->version = (hdmi_readb(hdmi, HDMI_DESIGN_ID) << 8) + | (hdmi_readb(hdmi, HDMI_REVISION_ID) << 0); +@@ -2518,6 +2539,8 @@ __dw_hdmi_probe(struct platform_device *pdev, + cec_notifier_put(hdmi->cec_notifier); + + clk_disable_unprepare(hdmi->iahb_clk); ++ if (hdmi->cec_clk) ++ clk_disable_unprepare(hdmi->cec_clk); + err_isfr: + clk_disable_unprepare(hdmi->isfr_clk); + err_res: +@@ -2541,6 +2564,8 @@ static void __dw_hdmi_remove(struct dw_hdmi *hdmi) + + clk_disable_unprepare(hdmi->iahb_clk); + clk_disable_unprepare(hdmi->isfr_clk); ++ if (hdmi->cec_clk) ++ clk_disable_unprepare(hdmi->cec_clk); + + if (hdmi->i2c) + i2c_del_adapter(&hdmi->i2c->adap); diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/085_linux-4.14.y-bpo-drm-0133-drm-bridge-synopsys-dw-hdmi-enable_workaround_for_v1.32a.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/085_linux-4.14.y-bpo-drm-0133-drm-bridge-synopsys-dw-hdmi-enable_workaround_for_v1.32a.patch new file mode 100644 index 000000000..abf433bf3 --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/085_linux-4.14.y-bpo-drm-0133-drm-bridge-synopsys-dw-hdmi-enable_workaround_for_v1.32a.patch @@ -0,0 +1,45 @@ +From 46d1b42bfac6ea085169a23b266178719b19a778 Mon Sep 17 00:00:00 2001 +From: Jernej Skrabec +Date: Wed, 14 Feb 2018 21:08:57 +0100 +Subject: [PATCH] drm/bridge/synopsys: dw-hdmi: Enable workaround for v1.32a + +Allwinner SoCs have dw hdmi controller v1.32a which exhibits same +magenta line issue as i.MX6Q and i.MX6DL. Enable workaround for it. + +Tests show that one iteration is enough. + +Acked-by: Laurent Pinchart +Reviewed-by: Archit Taneja +Signed-off-by: Jernej Skrabec +Signed-off-by: Maxime Ripard +Link: https://patchwork.freedesktop.org/patch/msgid/20180214200906.31509-4-jernej.skrabec@siol.net +--- + drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +index a38db40ce990d..7ca14d7325b51 100644 +--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c ++++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +@@ -1634,9 +1634,10 @@ static void dw_hdmi_clear_overflow(struct dw_hdmi *hdmi) + * then write one of the FC registers several times. + * + * The number of iterations matters and depends on the HDMI TX revision +- * (and possibly on the platform). So far only i.MX6Q (v1.30a) and +- * i.MX6DL (v1.31a) have been identified as needing the workaround, with +- * 4 and 1 iterations respectively. ++ * (and possibly on the platform). So far i.MX6Q (v1.30a), i.MX6DL ++ * (v1.31a) and multiple Allwinner SoCs (v1.32a) have been identified ++ * as needing the workaround, with 4 iterations for v1.30a and 1 ++ * iteration for others. + */ + + switch (hdmi->version) { +@@ -1644,6 +1645,7 @@ static void dw_hdmi_clear_overflow(struct dw_hdmi *hdmi) + count = 4; + break; + case 0x131a: ++ case 0x132a: + count = 1; + break; + default: diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/086_linux-4.14.y-bpo-drm-0134-drm-bridge-dw-hdmi-fix_overflow_workaround_for_amlogic.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/086_linux-4.14.y-bpo-drm-0134-drm-bridge-dw-hdmi-fix_overflow_workaround_for_amlogic.patch new file mode 100644 index 000000000..76e33dd49 --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/086_linux-4.14.y-bpo-drm-0134-drm-bridge-dw-hdmi-fix_overflow_workaround_for_amlogic.patch @@ -0,0 +1,41 @@ +From 9c305eb442f3b371fc722ade827bbf673514123e Mon Sep 17 00:00:00 2001 +From: Neil Armstrong +Date: Fri, 23 Feb 2018 12:44:37 +0100 +Subject: [PATCH] drm: bridge: dw-hdmi: Fix overflow workaround for Amlogic + Meson GX SoCs + +The Amlogic Meson GX SoCs, embedded the v2.01a controller, has been also +identified needing this workaround. +This patch adds the corresponding version to enable a single iteration for +this specific version. + +Fixes: be41fc55f1aa ("drm: bridge: dw-hdmi: Handle overflow workaround based on device version") +Acked-by: Archit Taneja +[narmstrong: s/identifies/identified and rebased against Jernej's change] +Signed-off-by: Neil Armstrong +Link: https://patchwork.freedesktop.org/patch/msgid/1519386277-25902-1-git-send-email-narmstrong@baylibre.com +--- + 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 f9802399cc0de..53ebbe2904b66 100644 +--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c ++++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +@@ -1654,6 +1654,8 @@ static void dw_hdmi_clear_overflow(struct dw_hdmi *hdmi) + * (v1.31a) and multiple Allwinner SoCs (v1.32a) have been identified + * as needing the workaround, with 4 iterations for v1.30a and 1 + * iteration for others. ++ * The Amlogic Meson GX SoCs (v2.01a) have been identified as needing ++ * the workaround with a single iteration. + */ + + switch (hdmi->version) { +@@ -1662,6 +1664,7 @@ static void dw_hdmi_clear_overflow(struct dw_hdmi *hdmi) + break; + case 0x131a: + case 0x132a: ++ case 0x201a: + count = 1; + break; + default: diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/087_linux-4.14.y-bpo-drm-0135-drm-bridge-synopsys-dw-hdmi-export_some_phy_related.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/087_linux-4.14.y-bpo-drm-0135-drm-bridge-synopsys-dw-hdmi-export_some_phy_related.patch new file mode 100644 index 000000000..d3b3332cb --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/087_linux-4.14.y-bpo-drm-0135-drm-bridge-synopsys-dw-hdmi-export_some_phy_related.patch @@ -0,0 +1,187 @@ +From 5765916afa4e859b92457a4a14f82ef2a9876758 Mon Sep 17 00:00:00 2001 +From: Jernej Skrabec +Date: Wed, 14 Feb 2018 21:08:58 +0100 +Subject: [PATCH] drm/bridge/synopsys: dw-hdmi: Export some PHY related + functions + +Parts of PHY code could be useful also for custom PHYs. For example, +Allwinner A83T has custom PHY which is probably Synopsys gen2 PHY +with few additional memory mapped registers, so most of the Synopsys PHY +related code could be reused. + +Functions exported here are actually not specific to Synopsys PHYs but +to DWC HDMI controller PHY interface. This means that even if the PHY is +completely custom, i.e. not designed by Synopsys, exported functions can +be useful. + +Reviewed-by: Archit Taneja +Reviewed-by: Neil Armstrong +Reviewed-by: Laurent Pinchart +Signed-off-by: Jernej Skrabec +Signed-off-by: Maxime Ripard +Link: https://patchwork.freedesktop.org/patch/msgid/20180214200906.31509-5-jernej.skrabec@siol.net +--- + drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 44 +++++++++++++++++++++---------- + drivers/gpu/drm/meson/meson_dw_hdmi.c | 8 +++--- + include/drm/bridge/dw_hdmi.h | 11 ++++++++ + 3 files changed, 45 insertions(+), 18 deletions(-) + +diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +index 7ca14d7325b51..7d80f4b566831 100644 +--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c ++++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +@@ -1037,19 +1037,21 @@ static void dw_hdmi_phy_enable_svsret(struct dw_hdmi *hdmi, u8 enable) + HDMI_PHY_CONF0_SVSRET_MASK); + } + +-static void dw_hdmi_phy_gen2_pddq(struct dw_hdmi *hdmi, u8 enable) ++void dw_hdmi_phy_gen2_pddq(struct dw_hdmi *hdmi, u8 enable) + { + hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0, + HDMI_PHY_CONF0_GEN2_PDDQ_OFFSET, + HDMI_PHY_CONF0_GEN2_PDDQ_MASK); + } ++EXPORT_SYMBOL_GPL(dw_hdmi_phy_gen2_pddq); + +-static void dw_hdmi_phy_gen2_txpwron(struct dw_hdmi *hdmi, u8 enable) ++void dw_hdmi_phy_gen2_txpwron(struct dw_hdmi *hdmi, u8 enable) + { + hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0, + HDMI_PHY_CONF0_GEN2_TXPWRON_OFFSET, + HDMI_PHY_CONF0_GEN2_TXPWRON_MASK); + } ++EXPORT_SYMBOL_GPL(dw_hdmi_phy_gen2_txpwron); + + static void dw_hdmi_phy_sel_data_en_pol(struct dw_hdmi *hdmi, u8 enable) + { +@@ -1065,6 +1067,22 @@ static void dw_hdmi_phy_sel_interface_control(struct dw_hdmi *hdmi, u8 enable) + HDMI_PHY_CONF0_SELDIPIF_MASK); + } + ++void dw_hdmi_phy_reset(struct dw_hdmi *hdmi) ++{ ++ /* PHY reset. The reset signal is active high on Gen2 PHYs. */ ++ hdmi_writeb(hdmi, HDMI_MC_PHYRSTZ_PHYRSTZ, HDMI_MC_PHYRSTZ); ++ hdmi_writeb(hdmi, 0, HDMI_MC_PHYRSTZ); ++} ++EXPORT_SYMBOL_GPL(dw_hdmi_phy_reset); ++ ++void dw_hdmi_phy_i2c_set_addr(struct dw_hdmi *hdmi, u8 address) ++{ ++ hdmi_phy_test_clear(hdmi, 1); ++ hdmi_writeb(hdmi, address, HDMI_PHY_I2CM_SLAVE_ADDR); ++ hdmi_phy_test_clear(hdmi, 0); ++} ++EXPORT_SYMBOL_GPL(dw_hdmi_phy_i2c_set_addr); ++ + static void dw_hdmi_phy_power_off(struct dw_hdmi *hdmi) + { + const struct dw_hdmi_phy_data *phy = hdmi->phy.data; +@@ -1203,16 +1221,11 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi) + if (phy->has_svsret) + dw_hdmi_phy_enable_svsret(hdmi, 1); + +- /* PHY reset. The reset signal is active high on Gen2 PHYs. */ +- hdmi_writeb(hdmi, HDMI_MC_PHYRSTZ_PHYRSTZ, HDMI_MC_PHYRSTZ); +- hdmi_writeb(hdmi, 0, HDMI_MC_PHYRSTZ); ++ dw_hdmi_phy_reset(hdmi); + + hdmi_writeb(hdmi, HDMI_MC_HEACPHY_RST_ASSERT, HDMI_MC_HEACPHY_RST); + +- hdmi_phy_test_clear(hdmi, 1); +- hdmi_writeb(hdmi, HDMI_PHY_I2CM_SLAVE_ADDR_PHY_GEN2, +- HDMI_PHY_I2CM_SLAVE_ADDR); +- hdmi_phy_test_clear(hdmi, 0); ++ dw_hdmi_phy_i2c_set_addr(hdmi, HDMI_PHY_I2CM_SLAVE_ADDR_PHY_GEN2); + + /* Write to the PHY as configured by the platform */ + if (pdata->configure_phy) +@@ -1251,15 +1264,16 @@ static void dw_hdmi_phy_disable(struct dw_hdmi *hdmi, void *data) + dw_hdmi_phy_power_off(hdmi); + } + +-static enum drm_connector_status dw_hdmi_phy_read_hpd(struct dw_hdmi *hdmi, +- void *data) ++enum drm_connector_status dw_hdmi_phy_read_hpd(struct dw_hdmi *hdmi, ++ void *data) + { + return hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_HPD ? + connector_status_connected : connector_status_disconnected; + } ++EXPORT_SYMBOL_GPL(dw_hdmi_phy_read_hpd); + +-static void dw_hdmi_phy_update_hpd(struct dw_hdmi *hdmi, void *data, +- bool force, bool disabled, bool rxsense) ++void dw_hdmi_phy_update_hpd(struct dw_hdmi *hdmi, void *data, ++ bool force, bool disabled, bool rxsense) + { + u8 old_mask = hdmi->phy_mask; + +@@ -1271,8 +1285,9 @@ static void dw_hdmi_phy_update_hpd(struct dw_hdmi *hdmi, void *data, + if (old_mask != hdmi->phy_mask) + hdmi_writeb(hdmi, hdmi->phy_mask, HDMI_PHY_MASK0); + } ++EXPORT_SYMBOL_GPL(dw_hdmi_phy_update_hpd); + +-static void dw_hdmi_phy_setup_hpd(struct dw_hdmi *hdmi, void *data) ++void dw_hdmi_phy_setup_hpd(struct dw_hdmi *hdmi, void *data) + { + /* + * Configure the PHY RX SENSE and HPD interrupts polarities and clear +@@ -1291,6 +1306,7 @@ static void dw_hdmi_phy_setup_hpd(struct dw_hdmi *hdmi, void *data) + hdmi_writeb(hdmi, ~(HDMI_IH_PHY_STAT0_HPD | HDMI_IH_PHY_STAT0_RX_SENSE), + HDMI_IH_MUTE_PHY_STAT0); + } ++EXPORT_SYMBOL_GPL(dw_hdmi_phy_setup_hpd); + + static const struct dw_hdmi_phy_ops dw_hdmi_synopsys_phy_ops = { + .init = dw_hdmi_phy_init, +diff --git a/drivers/gpu/drm/meson/meson_dw_hdmi.c b/drivers/gpu/drm/meson/meson_dw_hdmi.c +index 17de3afd98f6a..e8c3ef8a94ce3 100644 +--- a/drivers/gpu/drm/meson/meson_dw_hdmi.c ++++ b/drivers/gpu/drm/meson/meson_dw_hdmi.c +@@ -302,7 +302,7 @@ static void meson_hdmi_phy_setup_mode(struct meson_dw_hdmi *dw_hdmi, + } + } + +-static inline void dw_hdmi_phy_reset(struct meson_dw_hdmi *dw_hdmi) ++static inline void meson_dw_hdmi_phy_reset(struct meson_dw_hdmi *dw_hdmi) + { + struct meson_drm *priv = dw_hdmi->priv; + +@@ -409,9 +409,9 @@ static int dw_hdmi_phy_init(struct dw_hdmi *hdmi, void *data, + msleep(100); + + /* Reset PHY 3 times in a row */ +- dw_hdmi_phy_reset(dw_hdmi); +- dw_hdmi_phy_reset(dw_hdmi); +- dw_hdmi_phy_reset(dw_hdmi); ++ meson_dw_hdmi_phy_reset(dw_hdmi); ++ meson_dw_hdmi_phy_reset(dw_hdmi); ++ meson_dw_hdmi_phy_reset(dw_hdmi); + + /* Temporary Disable VENC video stream */ + if (priv->venc.hdmi_use_enci) +diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h +index 182f83283e247..f3f3f0e1b2d3a 100644 +--- a/include/drm/bridge/dw_hdmi.h ++++ b/include/drm/bridge/dw_hdmi.h +@@ -157,7 +157,18 @@ void dw_hdmi_audio_enable(struct dw_hdmi *hdmi); + void dw_hdmi_audio_disable(struct dw_hdmi *hdmi); + + /* PHY configuration */ ++void dw_hdmi_phy_i2c_set_addr(struct dw_hdmi *hdmi, u8 address); + void dw_hdmi_phy_i2c_write(struct dw_hdmi *hdmi, unsigned short data, + unsigned char addr); + ++void dw_hdmi_phy_gen2_pddq(struct dw_hdmi *hdmi, u8 enable); ++void dw_hdmi_phy_gen2_txpwron(struct dw_hdmi *hdmi, u8 enable); ++void dw_hdmi_phy_reset(struct dw_hdmi *hdmi); ++ ++enum drm_connector_status dw_hdmi_phy_read_hpd(struct dw_hdmi *hdmi, ++ void *data); ++void dw_hdmi_phy_update_hpd(struct dw_hdmi *hdmi, void *data, ++ bool force, bool disabled, bool rxsense); ++void dw_hdmi_phy_setup_hpd(struct dw_hdmi *hdmi, void *data); ++ + #endif /* __IMX_HDMI_H__ */ diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/088_linux-4.14.y-bpo-drm-0136-drm-bridge-synopsys-dw-hdmi-dont_clobber_drvdata.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/088_linux-4.14.y-bpo-drm-0136-drm-bridge-synopsys-dw-hdmi-dont_clobber_drvdata.patch new file mode 100644 index 000000000..d3b30c4c7 --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/088_linux-4.14.y-bpo-drm-0136-drm-bridge-synopsys-dw-hdmi-dont_clobber_drvdata.patch @@ -0,0 +1,294 @@ +From eea034af90c64802fd747a9dc534c26a7ebe7754 Mon Sep 17 00:00:00 2001 +From: Jernej Skrabec +Date: Wed, 14 Feb 2018 21:08:59 +0100 +Subject: [PATCH] drm/bridge/synopsys: dw-hdmi: don't clobber drvdata + +dw_hdmi shouldn't set drvdata since some drivers might need to store +it's own data there. Rework dw_hdmi in a way to return struct dw_hdmi +instead to store it in drvdata. This way drivers are responsible to +store and pass structure when needed. + +Idea was taken from the following commit: +8242ecbd597d ("drm/bridge/synopsys: stop clobbering drvdata") + +Cc: p.zabel@pengutronix.de +Cc: Laurent.pinchart@ideasonboard.com +Cc: hjc@rock-chips.com +Acked-by: Heiko Stuebner +Acked-by: Neil Armstrong +Reviewed-by: Archit Taneja +Tested-by: Heiko Stuebner +Signed-off-by: Jernej Skrabec +Signed-off-by: Maxime Ripard +Link: https://patchwork.freedesktop.org/patch/msgid/20180214200906.31509-6-jernej.skrabec@siol.net +--- + drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 31 ++++++++++++----------------- + drivers/gpu/drm/imx/dw_hdmi-imx.c | 13 +++++++++--- + drivers/gpu/drm/meson/meson_dw_hdmi.c | 14 +++++++++---- + drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c | 12 +++++++++-- + drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 13 +++++++++--- + include/drm/bridge/dw_hdmi.h | 13 ++++++------ + 6 files changed, 60 insertions(+), 36 deletions(-) + +diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +index 7d80f4b566831..f9802399cc0de 100644 +--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c ++++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +@@ -2543,8 +2543,6 @@ __dw_hdmi_probe(struct platform_device *pdev, + if (hdmi->i2c) + dw_hdmi_i2c_init(hdmi); + +- platform_set_drvdata(pdev, hdmi); +- + return hdmi; + + err_iahb: +@@ -2594,25 +2592,23 @@ static void __dw_hdmi_remove(struct dw_hdmi *hdmi) + /* ----------------------------------------------------------------------------- + * Probe/remove API, used from platforms based on the DRM bridge API. + */ +-int dw_hdmi_probe(struct platform_device *pdev, +- const struct dw_hdmi_plat_data *plat_data) ++struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev, ++ const struct dw_hdmi_plat_data *plat_data) + { + struct dw_hdmi *hdmi; + + hdmi = __dw_hdmi_probe(pdev, plat_data); + if (IS_ERR(hdmi)) +- return PTR_ERR(hdmi); ++ return hdmi; + + drm_bridge_add(&hdmi->bridge); + +- return 0; ++ return hdmi; + } + EXPORT_SYMBOL_GPL(dw_hdmi_probe); + +-void dw_hdmi_remove(struct platform_device *pdev) ++void dw_hdmi_remove(struct dw_hdmi *hdmi) + { +- struct dw_hdmi *hdmi = platform_get_drvdata(pdev); +- + drm_bridge_remove(&hdmi->bridge); + + __dw_hdmi_remove(hdmi); +@@ -2622,31 +2618,30 @@ EXPORT_SYMBOL_GPL(dw_hdmi_remove); + /* ----------------------------------------------------------------------------- + * Bind/unbind API, used from platforms based on the component framework. + */ +-int dw_hdmi_bind(struct platform_device *pdev, struct drm_encoder *encoder, +- const struct dw_hdmi_plat_data *plat_data) ++struct dw_hdmi *dw_hdmi_bind(struct platform_device *pdev, ++ struct drm_encoder *encoder, ++ const struct dw_hdmi_plat_data *plat_data) + { + struct dw_hdmi *hdmi; + int ret; + + hdmi = __dw_hdmi_probe(pdev, plat_data); + if (IS_ERR(hdmi)) +- return PTR_ERR(hdmi); ++ return hdmi; + + ret = drm_bridge_attach(encoder, &hdmi->bridge, NULL); + if (ret) { +- dw_hdmi_remove(pdev); ++ dw_hdmi_remove(hdmi); + DRM_ERROR("Failed to initialize bridge with drm\n"); +- return ret; ++ return ERR_PTR(ret); + } + +- return 0; ++ return hdmi; + } + EXPORT_SYMBOL_GPL(dw_hdmi_bind); + +-void dw_hdmi_unbind(struct device *dev) ++void dw_hdmi_unbind(struct dw_hdmi *hdmi) + { +- struct dw_hdmi *hdmi = dev_get_drvdata(dev); +- + __dw_hdmi_remove(hdmi); + } + EXPORT_SYMBOL_GPL(dw_hdmi_unbind); +diff --git a/drivers/gpu/drm/imx/dw_hdmi-imx.c b/drivers/gpu/drm/imx/dw_hdmi-imx.c +index b62763aa87069..fe6becdcc29ed 100644 +--- a/drivers/gpu/drm/imx/dw_hdmi-imx.c ++++ b/drivers/gpu/drm/imx/dw_hdmi-imx.c +@@ -25,6 +25,7 @@ + struct imx_hdmi { + struct device *dev; + struct drm_encoder encoder; ++ struct dw_hdmi *hdmi; + struct regmap *regmap; + }; + +@@ -239,14 +240,18 @@ static int dw_hdmi_imx_bind(struct device *dev, struct device *master, + drm_encoder_init(drm, encoder, &dw_hdmi_imx_encoder_funcs, + DRM_MODE_ENCODER_TMDS, NULL); + +- ret = dw_hdmi_bind(pdev, encoder, plat_data); ++ platform_set_drvdata(pdev, hdmi); ++ ++ hdmi->hdmi = dw_hdmi_bind(pdev, encoder, plat_data); + + /* + * If dw_hdmi_bind() fails we'll never call dw_hdmi_unbind(), + * which would have called the encoder cleanup. Do it manually. + */ +- if (ret) ++ if (IS_ERR(hdmi->hdmi)) { ++ ret = PTR_ERR(hdmi->hdmi); + drm_encoder_cleanup(encoder); ++ } + + return ret; + } +@@ -254,7 +259,9 @@ static int dw_hdmi_imx_bind(struct device *dev, struct device *master, + static void dw_hdmi_imx_unbind(struct device *dev, struct device *master, + void *data) + { +- return dw_hdmi_unbind(dev); ++ struct imx_hdmi *hdmi = dev_get_drvdata(dev); ++ ++ dw_hdmi_unbind(hdmi->hdmi); + } + + static const struct component_ops dw_hdmi_imx_ops = { +diff --git a/drivers/gpu/drm/meson/meson_dw_hdmi.c b/drivers/gpu/drm/meson/meson_dw_hdmi.c +index e8c3ef8a94ce3..d49af17310c99 100644 +--- a/drivers/gpu/drm/meson/meson_dw_hdmi.c ++++ b/drivers/gpu/drm/meson/meson_dw_hdmi.c +@@ -140,6 +140,7 @@ struct meson_dw_hdmi { + struct clk *venci_clk; + struct regulator *hdmi_supply; + u32 irq_stat; ++ struct dw_hdmi *hdmi; + }; + #define encoder_to_meson_dw_hdmi(x) \ + container_of(x, struct meson_dw_hdmi, encoder) +@@ -878,9 +879,12 @@ static int meson_dw_hdmi_bind(struct device *dev, struct device *master, + dw_plat_data->input_bus_format = MEDIA_BUS_FMT_YUV8_1X24; + dw_plat_data->input_bus_encoding = V4L2_YCBCR_ENC_709; + +- ret = dw_hdmi_bind(pdev, encoder, &meson_dw_hdmi->dw_plat_data); +- if (ret) +- return ret; ++ platform_set_drvdata(pdev, meson_dw_hdmi); ++ ++ meson_dw_hdmi->hdmi = dw_hdmi_bind(pdev, encoder, ++ &meson_dw_hdmi->dw_plat_data); ++ if (IS_ERR(meson_dw_hdmi->hdmi)) ++ return PTR_ERR(meson_dw_hdmi->hdmi); + + DRM_DEBUG_DRIVER("HDMI controller initialized\n"); + +@@ -890,7 +894,9 @@ static int meson_dw_hdmi_bind(struct device *dev, struct device *master, + static void meson_dw_hdmi_unbind(struct device *dev, struct device *master, + void *data) + { +- dw_hdmi_unbind(dev); ++ struct meson_dw_hdmi *meson_dw_hdmi = dev_get_drvdata(dev); ++ ++ dw_hdmi_unbind(meson_dw_hdmi->hdmi); + } + + static const struct component_ops meson_dw_hdmi_ops = { +diff --git a/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c b/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c +index dc85b53d58ef2..3bebc6821e9cc 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c ++++ b/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c +@@ -68,12 +68,20 @@ static const struct dw_hdmi_plat_data rcar_dw_hdmi_plat_data = { + + static int rcar_dw_hdmi_probe(struct platform_device *pdev) + { +- return dw_hdmi_probe(pdev, &rcar_dw_hdmi_plat_data); ++ struct dw_hdmi *hdmi; ++ ++ hdmi = dw_hdmi_probe(pdev, &rcar_dw_hdmi_plat_data); ++ if (IS_ERR(hdmi)) ++ return PTR_ERR(hdmi); ++ ++ platform_set_drvdata(pdev, hdmi); + } + + static int rcar_dw_hdmi_remove(struct platform_device *pdev) + { +- dw_hdmi_remove(pdev); ++ struct dw_hdmi *hdmi = platform_get_drvdata(dev); ++ ++ dw_hdmi_remove(hdmi); + + return 0; + } +diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +index 1eb02a82fd918..3574b0ae2ad19 100644 +--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c ++++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +@@ -48,6 +48,7 @@ struct rockchip_hdmi { + const struct rockchip_hdmi_chip_data *chip_data; + struct clk *vpll_clk; + struct clk *grf_clk; ++ struct dw_hdmi *hdmi; + }; + + #define to_rockchip_hdmi(x) container_of(x, struct rockchip_hdmi, x) +@@ -377,14 +378,18 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master, + drm_encoder_init(drm, encoder, &dw_hdmi_rockchip_encoder_funcs, + DRM_MODE_ENCODER_TMDS, NULL); + +- ret = dw_hdmi_bind(pdev, encoder, plat_data); ++ platform_set_drvdata(pdev, hdmi); ++ ++ hdmi->hdmi = dw_hdmi_bind(pdev, encoder, plat_data); + + /* + * If dw_hdmi_bind() fails we'll never call dw_hdmi_unbind(), + * which would have called the encoder cleanup. Do it manually. + */ +- if (ret) ++ if (IS_ERR(hdmi->hdmi)) { ++ ret = PTR_ERR(hdmi->hdmi); + drm_encoder_cleanup(encoder); ++ } + + return ret; + } +@@ -392,7 +397,9 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master, + static void dw_hdmi_rockchip_unbind(struct device *dev, struct device *master, + void *data) + { +- return dw_hdmi_unbind(dev); ++ struct rockchip_hdmi *hdmi = dev_get_drvdata(dev); ++ ++ dw_hdmi_unbind(hdmi->hdmi); + } + + static const struct component_ops dw_hdmi_rockchip_ops = { +diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h +index f3f3f0e1b2d3a..dd2a8cf7d20b8 100644 +--- a/include/drm/bridge/dw_hdmi.h ++++ b/include/drm/bridge/dw_hdmi.h +@@ -143,12 +143,13 @@ struct dw_hdmi_plat_data { + unsigned long mpixelclock); + }; + +-int dw_hdmi_probe(struct platform_device *pdev, +- const struct dw_hdmi_plat_data *plat_data); +-void dw_hdmi_remove(struct platform_device *pdev); +-void dw_hdmi_unbind(struct device *dev); +-int dw_hdmi_bind(struct platform_device *pdev, struct drm_encoder *encoder, +- const struct dw_hdmi_plat_data *plat_data); ++struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev, ++ const struct dw_hdmi_plat_data *plat_data); ++void dw_hdmi_remove(struct dw_hdmi *hdmi); ++void dw_hdmi_unbind(struct dw_hdmi *hdmi); ++struct dw_hdmi *dw_hdmi_bind(struct platform_device *pdev, ++ struct drm_encoder *encoder, ++ const struct dw_hdmi_plat_data *plat_data); + + void dw_hdmi_setup_rx_sense(struct device *dev, bool hpd, bool rx_sense); + diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/0026-drm-meson-select-dw-hdmi-i2s-audio-for-meson-hdmi.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/089_linux-4.17-yocto-meson64-0002-drm-meson-select-dw-hdmi-i2s-audio-for-meson-hdmi.patch similarity index 82% rename from buildroot-external/board/hardkernel/odroid-c2/patches/linux/0026-drm-meson-select-dw-hdmi-i2s-audio-for-meson-hdmi.patch rename to buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/089_linux-4.17-yocto-meson64-0002-drm-meson-select-dw-hdmi-i2s-audio-for-meson-hdmi.patch index 3aa2e2f74..6f1d3e25d 100644 --- a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/0026-drm-meson-select-dw-hdmi-i2s-audio-for-meson-hdmi.patch +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/089_linux-4.17-yocto-meson64-0002-drm-meson-select-dw-hdmi-i2s-audio-for-meson-hdmi.patch @@ -1,7 +1,7 @@ -From e5509c367852ca7a7b52c30fda3dfd2a763ee8f3 Mon Sep 17 00:00:00 2001 +From 13253828e625fad26802c497672d1ebc2588a61e Mon Sep 17 00:00:00 2001 From: Jerome Brunet Date: Tue, 14 Feb 2017 19:18:04 +0100 -Subject: [PATCH 26/39] drm/meson: select dw-hdmi i2s audio for meson hdmi +Subject: [PATCH 02/14] drm/meson: select dw-hdmi i2s audio for meson hdmi Signed-off-by: Jerome Brunet Signed-off-by: Neil Armstrong diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/0021-ASoC-meson-add-meson-audio-core-driver.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/090_linux-4.17-yocto-meson64-0003-ASoC-meson-add-meson-audio-core-driver.patch similarity index 96% rename from buildroot-external/board/hardkernel/odroid-c2/patches/linux/0021-ASoC-meson-add-meson-audio-core-driver.patch rename to buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/090_linux-4.17-yocto-meson64-0003-ASoC-meson-add-meson-audio-core-driver.patch index ff9a55e19..b7efebb87 100644 --- a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/0021-ASoC-meson-add-meson-audio-core-driver.patch +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/090_linux-4.17-yocto-meson64-0003-ASoC-meson-add-meson-audio-core-driver.patch @@ -1,7 +1,7 @@ -From f9b447452943415a12055c0fca279281cd28d923 Mon Sep 17 00:00:00 2001 +From 0d24a1c3cd2bc015eb3c22e7b1322ab39a5f8dda Mon Sep 17 00:00:00 2001 From: Jerome Brunet Date: Thu, 30 Mar 2017 11:49:55 +0200 -Subject: [PATCH 21/39] ASoC: meson: add meson audio core driver +Subject: [PATCH 03/14] ASoC: meson: add meson audio core driver This patch adds support for the audio core driver for the Amlogic Meson SoC family. The purpose of this driver is to properly reset the audio block and @@ -30,10 +30,10 @@ Signed-off-by: Neil Armstrong create mode 100644 sound/soc/meson/audio-core.h diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig -index c0abad2..7db316f 100644 +index 41af6b9..1cf11cf 100644 --- a/sound/soc/Kconfig +++ b/sound/soc/Kconfig -@@ -55,6 +55,7 @@ source "sound/soc/kirkwood/Kconfig" +@@ -57,6 +57,7 @@ source "sound/soc/kirkwood/Kconfig" source "sound/soc/img/Kconfig" source "sound/soc/intel/Kconfig" source "sound/soc/mediatek/Kconfig" @@ -42,10 +42,10 @@ index c0abad2..7db316f 100644 source "sound/soc/pxa/Kconfig" source "sound/soc/qcom/Kconfig" diff --git a/sound/soc/Makefile b/sound/soc/Makefile -index bf8c1e2..d4c0a51 100644 +index 8d92492..4d642ea 100644 --- a/sound/soc/Makefile +++ b/sound/soc/Makefile -@@ -33,6 +33,7 @@ obj-$(CONFIG_SND_SOC) += jz4740/ +@@ -38,6 +38,7 @@ obj-$(CONFIG_SND_SOC) += jz4740/ obj-$(CONFIG_SND_SOC) += img/ obj-$(CONFIG_SND_SOC) += intel/ obj-$(CONFIG_SND_SOC) += mediatek/ diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/0022-ASoC-meson-add-register-definitions.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/091_linux-4.17-yocto-meson64-0004-ASoC-meson-add-register-definitions.patch similarity index 99% rename from buildroot-external/board/hardkernel/odroid-c2/patches/linux/0022-ASoC-meson-add-register-definitions.patch rename to buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/091_linux-4.17-yocto-meson64-0004-ASoC-meson-add-register-definitions.patch index c040e9f9c..742e8b3df 100644 --- a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/0022-ASoC-meson-add-register-definitions.patch +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/091_linux-4.17-yocto-meson64-0004-ASoC-meson-add-register-definitions.patch @@ -1,7 +1,7 @@ -From 71e89b9513f114d45fd43233039a73f678702815 Mon Sep 17 00:00:00 2001 +From 04b110f288ec7436b0d714b090498562ab93c04b Mon Sep 17 00:00:00 2001 From: Jerome Brunet Date: Thu, 30 Mar 2017 12:00:10 +0200 -Subject: [PATCH 22/39] ASoC: meson: add register definitions +Subject: [PATCH 04/14] ASoC: meson: add register definitions Add the register definition for the AIU and AUDIN blocks diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/0023-ASoC-meson-add-aiu-i2s-dma-support.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/092_linux-4.17-yocto-meson64-0005-ASoC-meson-add-aiu-i2s-dma-support.patch similarity index 99% rename from buildroot-external/board/hardkernel/odroid-c2/patches/linux/0023-ASoC-meson-add-aiu-i2s-dma-support.patch rename to buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/092_linux-4.17-yocto-meson64-0005-ASoC-meson-add-aiu-i2s-dma-support.patch index edb19292b..fec22f4d9 100644 --- a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/0023-ASoC-meson-add-aiu-i2s-dma-support.patch +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/092_linux-4.17-yocto-meson64-0005-ASoC-meson-add-aiu-i2s-dma-support.patch @@ -1,7 +1,7 @@ -From 03285555d8cbb3eb1f4991b758e5804a3c19b4ce Mon Sep 17 00:00:00 2001 +From 298241f7155bfeed607b68840950c4d193cbaf55 Mon Sep 17 00:00:00 2001 From: Jerome Brunet Date: Thu, 30 Mar 2017 12:14:40 +0200 -Subject: [PATCH 23/39] ASoC: meson: add aiu i2s dma support +Subject: [PATCH 05/14] ASoC: meson: add aiu i2s dma support Add support for the i2s output dma which is part of the AIU block diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/0024-ASoC-meson-add-initial-i2s-dai-support.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/093_linux-4.17-yocto-meson64-0006-ASoC-meson-add-initial-i2s-dai-support.patch similarity index 99% rename from buildroot-external/board/hardkernel/odroid-c2/patches/linux/0024-ASoC-meson-add-initial-i2s-dai-support.patch rename to buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/093_linux-4.17-yocto-meson64-0006-ASoC-meson-add-initial-i2s-dai-support.patch index cfd5f78bd..c3cd903ee 100644 --- a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/0024-ASoC-meson-add-initial-i2s-dai-support.patch +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/093_linux-4.17-yocto-meson64-0006-ASoC-meson-add-initial-i2s-dai-support.patch @@ -1,7 +1,7 @@ -From e273b0687bfb891ca4962dfe96e174371853ae89 Mon Sep 17 00:00:00 2001 +From 583f1a4a1120f751a26f7c78218e54e449930308 Mon Sep 17 00:00:00 2001 From: Jerome Brunet Date: Thu, 30 Mar 2017 12:17:27 +0200 -Subject: [PATCH 24/39] ASoC: meson: add initial i2s dai support +Subject: [PATCH 06/14] ASoC: meson: add initial i2s dai support Add support for the i2s dai found on Amlogic Meson SoC family. With this initial implementation, only playback is supported. diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/0025-snd-meson-activate-HDMI-audio-path.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/094_linux-4.17-yocto-meson64-0007-snd-meson-activate-HDMI-audio-path.patch similarity index 94% rename from buildroot-external/board/hardkernel/odroid-c2/patches/linux/0025-snd-meson-activate-HDMI-audio-path.patch rename to buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/094_linux-4.17-yocto-meson64-0007-snd-meson-activate-HDMI-audio-path.patch index c3fadbccd..6ade016d4 100644 --- a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/0025-snd-meson-activate-HDMI-audio-path.patch +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/094_linux-4.17-yocto-meson64-0007-snd-meson-activate-HDMI-audio-path.patch @@ -1,7 +1,7 @@ -From f40a0d725ebdad433383010d1c5ef92eb99e41a7 Mon Sep 17 00:00:00 2001 +From 7833a66101aabad7f882fdf6dee62c7de9c3c71b Mon Sep 17 00:00:00 2001 From: Jerome Brunet Date: Fri, 7 Jul 2017 17:39:21 +0200 -Subject: [PATCH 25/39] snd: meson: activate HDMI audio path +Subject: [PATCH 07/14] snd: meson: activate HDMI audio path Signed-off-by: Neil Armstrong --- diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/0027-ARM64-defconfig-enable-audio-support-for-meson-SoCs-.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/095_linux-4.17-yocto-meson64-0010-ARM64-defconfig-enable-audio-support-for-meson-SoCs-.patch similarity index 79% rename from buildroot-external/board/hardkernel/odroid-c2/patches/linux/0027-ARM64-defconfig-enable-audio-support-for-meson-SoCs-.patch rename to buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/095_linux-4.17-yocto-meson64-0010-ARM64-defconfig-enable-audio-support-for-meson-SoCs-.patch index 6adccf110..7fd89f084 100644 --- a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/0027-ARM64-defconfig-enable-audio-support-for-meson-SoCs-.patch +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/095_linux-4.17-yocto-meson64-0010-ARM64-defconfig-enable-audio-support-for-meson-SoCs-.patch @@ -1,7 +1,7 @@ -From d74574d0836155eadde90e9ba12b8c4d18202d8e Mon Sep 17 00:00:00 2001 +From e3fec781d3684fa264dfd68877b59b70a30f8929 Mon Sep 17 00:00:00 2001 From: Jerome Brunet Date: Fri, 31 Mar 2017 15:55:03 +0200 -Subject: [PATCH 27/39] ARM64: defconfig: enable audio support for meson SoCs +Subject: [PATCH 10/14] ARM64: defconfig: enable audio support for meson SoCs as module Add audio support for meson SoCs. This includes the audio core @@ -14,10 +14,10 @@ Signed-off-by: Neil Armstrong 1 file changed, 2 insertions(+) diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig -index dcf1090..beb5774 100644 +index 43716e1..639cb12 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig -@@ -405,6 +405,8 @@ CONFIG_SOUND=y +@@ -440,6 +440,8 @@ CONFIG_SOUND=y CONFIG_SND=y CONFIG_SND_SOC=y CONFIG_SND_BCM2835_SOC_I2S=m diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/0028-ARM64-dts-meson-gx-add-audio-controller-nodes.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/096_linux-4.17-yocto-meson64-0011-ARM64-dts-meson-gx-add-audio-controller-nodes.patch similarity index 57% rename from buildroot-external/board/hardkernel/odroid-c2/patches/linux/0028-ARM64-dts-meson-gx-add-audio-controller-nodes.patch rename to buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/096_linux-4.17-yocto-meson64-0011-ARM64-dts-meson-gx-add-audio-controller-nodes.patch index 772a14095..c2fb3c5d8 100644 --- a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/0028-ARM64-dts-meson-gx-add-audio-controller-nodes.patch +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/096_linux-4.17-yocto-meson64-0011-ARM64-dts-meson-gx-add-audio-controller-nodes.patch @@ -1,7 +1,7 @@ -From 7bd8dcbb1f840fe6d4ae6a1f5f2d3708f09110f9 Mon Sep 17 00:00:00 2001 +From c9a242f21d67baf22cb113ba37e9f77b96ba1027 Mon Sep 17 00:00:00 2001 From: Jerome Brunet Date: Wed, 20 Sep 2017 17:22:47 +0200 -Subject: [PATCH 28/39] ARM64: dts: meson-gx: add audio controller nodes +Subject: [PATCH] ARM64: dts: meson-gx: add audio controller nodes Add audio controller nodes for Amlogic meson gxl. This includes the audio-core node, the i2s DAI and i2s @@ -13,15 +13,16 @@ to be added later on (pcm DAIs, input DMAs, SPDIF etc ...) Signed-off-by: Jerome Brunet Signed-off-by: Neil Armstrong --- - arch/arm64/boot/dts/amlogic/meson-gx.dtsi | 22 ++++++++++++++++++++++ - arch/arm64/boot/dts/amlogic/meson-gxl.dtsi | 23 +++++++++++++++++++++++ - 2 files changed, 45 insertions(+) + arch/arm64/boot/dts/amlogic/meson-gx.dtsi | 22 ++++++++++++++++++++++ + arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi | 23 +++++++++++++++++++++++ + arch/arm64/boot/dts/amlogic/meson-gxl.dtsi | 23 +++++++++++++++++++++++ + 3 files changed, 68 insertions(+) diff --git a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi -index f175db8..ff27ce0 100644 +index 3c31e21cbed7f..e4ebc8751fd27 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi -@@ -224,6 +224,28 @@ +@@ -197,6 +197,28 @@ #reset-cells = <1>; }; @@ -48,14 +49,48 @@ index f175db8..ff27ce0 100644 + }; + uart_A: serial@84c0 { - compatible = "amlogic,meson-gx-uart", "amlogic,meson-uart"; - reg = <0x0 0x84c0 0x0 0x14>; + compatible = "amlogic,meson-gx-uart"; + reg = <0x0 0x84c0 0x0 0x18>; +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi +index 562c26a0ba333..67d794bee9034 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi +@@ -702,6 +702,29 @@ + <0>; /* Do Nothing */ + }; + ++&audio { ++ clocks = <&clkc CLKID_AIU>, ++ <&clkc CLKID_AIU_GLUE>, ++ <&clkc CLKID_I2S_SPDIF>; ++ clock-names = "aiu_top", "aiu_glue", "audin"; ++ resets = <&reset RESET_AIU>, ++ <&reset RESET_AUDIN>; ++ reset-names = "aiu", "audin"; ++}; ++ ++&aiu_i2s_dma { ++ clocks = <&clkc CLKID_I2S_OUT>; ++ clock-names = "fast"; ++}; ++ ++&i2s_dai { ++ clocks = <&clkc CLKID_I2S_OUT>, ++ <&clkc CLKID_MIXER_IFACE>, ++ <&clkc CLKID_AOCLK_GATE>, ++ <&clkc CLKID_CTS_AMCLK>; ++ clock-names = "fast", "iface", "bclks", "mclk"; ++}; ++ + &saradc { + compatible = "amlogic,meson-gxbb-saradc", "amlogic,meson-saradc"; + clocks = <&xtal>, diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi -index 68ea67a..9d2fb46 100644 +index dba365ed4bd5f..0a41e2ed490bc 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi -@@ -691,6 +691,29 @@ - }; +@@ -711,6 +711,29 @@ + <0>; /* Do Nothing */ }; +&audio { @@ -84,6 +119,3 @@ index 68ea67a..9d2fb46 100644 &saradc { compatible = "amlogic,meson-gxl-saradc", "amlogic,meson-saradc"; clocks = <&xtal>, --- -2.7.4 - diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/097_linux-4.17-yocto-meson64-0012-ARM64-dts-meson-gxl-add-sound-dai-cells-to-HDMI-node.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/097_linux-4.17-yocto-meson64-0012-ARM64-dts-meson-gxl-add-sound-dai-cells-to-HDMI-node.patch new file mode 100644 index 000000000..466ed5a62 --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/097_linux-4.17-yocto-meson64-0012-ARM64-dts-meson-gxl-add-sound-dai-cells-to-HDMI-node.patch @@ -0,0 +1,23 @@ +From fb45bc4b076c17a3f9c1dab64e652dce752371c2 Mon Sep 17 00:00:00 2001 +From: Jerome Brunet +Date: Wed, 20 Sep 2017 18:01:26 +0200 +Subject: [PATCH] ARM64: dts: meson-gxl: add sound-dai-cells to HDMI node + +Signed-off-by: Jerome Brunet +Signed-off-by: Neil Armstrong +--- + arch/arm64/boot/dts/amlogic/meson-gxl.dtsi | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi +index 0a41e2ed490bc..a11ac158df7a1 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi +@@ -265,6 +265,7 @@ + <&clkc CLKID_CLK81>, + <&clkc CLKID_GCLK_VENCI_INT0>; + clock-names = "isfr", "iahb", "venci"; ++ #sound-dai-cells = <0>; + }; + + &hiubus { diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/0035-ARM64-dts-meson-activate-hdmi-audio-HDMI-enabled-boa.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/098_linux-4.17-yocto-meson64-0013-ARM64-dts-meson-activate-hdmi-audio-HDMI-enabled-boa.patch similarity index 83% rename from buildroot-external/board/hardkernel/odroid-c2/patches/linux/0035-ARM64-dts-meson-activate-hdmi-audio-HDMI-enabled-boa.patch rename to buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/098_linux-4.17-yocto-meson64-0013-ARM64-dts-meson-activate-hdmi-audio-HDMI-enabled-boa.patch index f06348b40..5cac91968 100644 --- a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/0035-ARM64-dts-meson-activate-hdmi-audio-HDMI-enabled-boa.patch +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/098_linux-4.17-yocto-meson64-0013-ARM64-dts-meson-activate-hdmi-audio-HDMI-enabled-boa.patch @@ -1,8 +1,7 @@ -From bc1416cbeb6fb588e8573c9904b691259d173093 Mon Sep 17 00:00:00 2001 +From e6794244bc4c59ffcf1ed4cbb452836dca10ad55 Mon Sep 17 00:00:00 2001 From: Jerome Brunet Date: Wed, 20 Sep 2017 18:10:08 +0200 -Subject: [PATCH 35/39] ARM64: dts: meson: activate hdmi audio HDMI enabled - boards +Subject: [PATCH] ARM64: dts: meson: activate hdmi audio HDMI enabled boards This patch activate audio over HDMI on selected boards @@ -17,7 +16,7 @@ Signed-off-by: Neil Armstrong .../boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts | 38 ++++++++++++++++++++++ .../arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts | 37 +++++++++++++++++++++ arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi | 37 +++++++++++++++++++++ - .../boot/dts/amlogic/meson-gxbb-wetek-play2.dts | 37 +++++++++++++++++++++ + arch/arm64/boot/dts/amlogic/meson-gxbb-wetek.dtsi | 37 +++++++++++++++++++++ .../dts/amlogic/meson-gxl-s905x-khadas-vim.dts | 37 +++++++++++++++++++++ .../dts/amlogic/meson-gxl-s905x-libretech-cc.dts | 37 +++++++++++++++++++++ .../dts/amlogic/meson-gxl-s905x-nexbox-a95x.dts | 37 +++++++++++++++++++++ @@ -27,10 +26,10 @@ Signed-off-by: Neil Armstrong 11 files changed, 408 insertions(+) diff --git a/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi -index 979abaf..91b7ac8 100644 +index 88e712ea757a2..7256912413e1a 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi -@@ -130,6 +130,31 @@ +@@ -95,6 +95,31 @@ }; }; }; @@ -62,7 +61,7 @@ index 979abaf..91b7ac8 100644 }; &cec_AO { -@@ -139,6 +164,18 @@ +@@ -104,6 +129,18 @@ hdmi-phandle = <&hdmi_tx>; }; @@ -82,10 +81,10 @@ index 979abaf..91b7ac8 100644 cvbs_vdac_out: endpoint { remote-endpoint = <&cvbs_connector_in>; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts -index 9a77323..2357a38 100644 +index 4cf7f6e80c6a0..43586e9099616 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts -@@ -143,6 +143,31 @@ +@@ -119,6 +119,31 @@ clock-names = "ext_clock"; }; @@ -117,7 +116,7 @@ index 9a77323..2357a38 100644 cvbs-connector { compatible = "composite-video-connector"; -@@ -178,6 +203,19 @@ +@@ -154,6 +179,19 @@ hdmi-phandle = <&hdmi_tx>; }; @@ -138,10 +137,10 @@ index 9a77323..2357a38 100644 status = "okay"; pinctrl-0 = <ð_rmii_pins>; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts -index dc3d1ba..4e0b3c7 100644 +index 54954b314a452..b24d2f79ccc34 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts -@@ -146,6 +146,31 @@ +@@ -110,6 +110,31 @@ }; }; }; @@ -173,7 +172,7 @@ index dc3d1ba..4e0b3c7 100644 }; &cec_AO { -@@ -155,6 +180,18 @@ +@@ -119,6 +144,18 @@ hdmi-phandle = <&hdmi_tx>; }; @@ -193,10 +192,10 @@ index dc3d1ba..4e0b3c7 100644 status = "okay"; pinctrl-0 = <ð_rgmii_pins>; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi -index 932158a..c9d4870 100644 +index ce862266b9aac..f89a094daf98d 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi -@@ -149,6 +149,31 @@ +@@ -113,6 +113,31 @@ }; }; }; @@ -228,7 +227,7 @@ index 932158a..c9d4870 100644 }; &cec_AO { -@@ -158,6 +183,18 @@ +@@ -122,6 +147,18 @@ hdmi-phandle = <&hdmi_tx>; }; @@ -247,11 +246,11 @@ index 932158a..c9d4870 100644 &cvbs_vdac_port { cvbs_vdac_out: endpoint { remote-endpoint = <&cvbs_connector_in>; -diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek-play2.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek-play2.dts -index f7144fd..58a0f51 100644 ---- a/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek-play2.dts -+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek-play2.dts -@@ -106,6 +106,31 @@ +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek.dtsi +index 70325b273bd2b..b3b6ce7e665b9 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek.dtsi +@@ -105,6 +105,43 @@ }; }; }; @@ -280,13 +279,8 @@ index f7144fd..58a0f51 100644 + }; + }; + }; - }; - - &cec_AO { -@@ -115,6 +140,18 @@ - hdmi-phandle = <&hdmi_tx>; - }; - ++}; ++ +&audio { + status = "okay"; +}; @@ -297,13 +291,11 @@ index f7144fd..58a0f51 100644 + +&i2s_dai { + status = "okay"; -+}; -+ - &cvbs_vdac_port { - cvbs_vdac_out: endpoint { - remote-endpoint = <&cvbs_connector_in>; + }; + + &cec_AO { diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts -index f7b37de..ce92ca5 100644 +index d32cf38463702..1b2171d76a7bb 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts +++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts @@ -65,6 +65,31 @@ @@ -358,11 +350,11 @@ index f7b37de..ce92ca5 100644 status = "okay"; pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts -index 0c4ed4e..29d8e01 100644 +index 3e3eb31748a35..9717c831a54f0 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts +++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts -@@ -83,6 +83,31 @@ - enable-active-high; +@@ -84,6 +84,31 @@ + regulator-always-on; }; + sound { @@ -393,7 +385,7 @@ index 0c4ed4e..29d8e01 100644 vcc_3v3: regulator-vcc_3v3 { compatible = "regulator-fixed"; regulator-name = "VCC_3V3"; -@@ -122,6 +147,18 @@ +@@ -130,6 +155,18 @@ hdmi-phandle = <&hdmi_tx>; }; @@ -413,10 +405,10 @@ index 0c4ed4e..29d8e01 100644 cvbs_vdac_out: endpoint { remote-endpoint = <&cvbs_connector_in>; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-nexbox-a95x.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-nexbox-a95x.dts -index 0fdebcc..dcb571a 100644 +index 6739697be1def..1c2f62984c8ad 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-nexbox-a95x.dts +++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-nexbox-a95x.dts -@@ -138,6 +138,31 @@ +@@ -102,6 +102,31 @@ }; }; }; @@ -448,7 +440,7 @@ index 0fdebcc..dcb571a 100644 }; &cec_AO { -@@ -147,6 +172,18 @@ +@@ -111,6 +136,18 @@ hdmi-phandle = <&hdmi_tx>; }; @@ -468,10 +460,10 @@ index 0fdebcc..dcb571a 100644 cvbs_vdac_out: endpoint { remote-endpoint = <&cvbs_connector_in>; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dts -index 4f6b1c9..f23f148 100644 +index 5896e8a5d86bc..02582371fa4e8 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dts +++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dts -@@ -69,6 +69,31 @@ +@@ -32,6 +32,31 @@ }; }; }; @@ -503,7 +495,7 @@ index 4f6b1c9..f23f148 100644 }; &cec_AO { -@@ -78,6 +103,18 @@ +@@ -41,6 +66,18 @@ hdmi-phandle = <&hdmi_tx>; }; @@ -522,11 +514,66 @@ index 4f6b1c9..f23f148 100644 &cvbs_vdac_port { cvbs_vdac_out: endpoint { remote-endpoint = <&cvbs_connector_in>; +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts b/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts +index 0868da476e41f..22707afa0b6d8 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts +@@ -85,6 +85,31 @@ + }; + }; + ++ sound { ++ compatible = "simple-audio-card"; ++ simple-audio-card,name = "meson-gx-preview"; ++ status = "okay"; ++ ++ simple-audio-card,dai-link@0 { ++ /* HDMI Output */ ++ format = "i2s"; ++ mclk-fs = <256>; ++ bitclock-master = <&i2s_dai>; ++ frame-master = <&i2s_dai>; ++ plat { ++ sound-dai = <&aiu_i2s_dma>; ++ }; ++ ++ cpu { ++ sound-dai = <&i2s_dai>; ++ }; ++ ++ codec { ++ sound-dai = <&hdmi_tx>; ++ }; ++ }; ++ }; ++ + pwmleds { + compatible = "pwm-leds"; + +@@ -205,6 +230,18 @@ + hdmi-phandle = <&hdmi_tx>; + }; + ++&audio { ++ status = "okay"; ++}; ++ ++&aiu_i2s_dma { ++ status = "okay"; ++}; ++ ++&i2s_dai { ++ status = "okay"; ++}; ++ + &cpu0 { + #cooling-cells = <2>; + }; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts b/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts -index e70b5e2..8444f79 100644 +index f7a1cffab4a88..1af4891bdb06b 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts +++ b/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts -@@ -111,6 +111,31 @@ +@@ -75,6 +75,31 @@ }; }; }; @@ -558,7 +605,7 @@ index e70b5e2..8444f79 100644 }; &cec_AO { -@@ -120,6 +145,18 @@ +@@ -84,6 +109,18 @@ hdmi-phandle = <&hdmi_tx>; }; @@ -577,6 +624,3 @@ index e70b5e2..8444f79 100644 &cvbs_vdac_port { cvbs_vdac_out: endpoint { remote-endpoint = <&cvbs_connector_in>; --- -2.7.4 - diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/0010-ARM64-defconfig-add-CONFIG_MESON_EFUSE.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/099_linux-4.14.y-le-amlogic-gx-0010-arm64-defconfig-add_config_meson_efuse.patch similarity index 72% rename from buildroot-external/board/hardkernel/odroid-c2/patches/linux/0010-ARM64-defconfig-add-CONFIG_MESON_EFUSE.patch rename to buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/099_linux-4.14.y-le-amlogic-gx-0010-arm64-defconfig-add_config_meson_efuse.patch index f80c0765b..02f2d5fae 100644 --- a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/0010-ARM64-defconfig-add-CONFIG_MESON_EFUSE.patch +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/099_linux-4.14.y-le-amlogic-gx-0010-arm64-defconfig-add_config_meson_efuse.patch @@ -1,18 +1,17 @@ -From eb29dbaf90e217978d8abfab1912b11020825e28 Mon Sep 17 00:00:00 2001 +From f1aaa72f808ab876ffe8c16820b5a4726b711933 Mon Sep 17 00:00:00 2001 From: Jerome Brunet Date: Mon, 13 Nov 2017 12:02:59 +0100 -Subject: [PATCH 10/39] ARM64: defconfig: add CONFIG_MESON_EFUSE +Subject: [PATCH] ARM64: defconfig: add CONFIG_MESON_EFUSE Turn on CONFIG_MESON_EFUSE as module Signed-off-by: Jerome Brunet -Signed-off-by: Neil Armstrong --- arch/arm64/configs/defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig -index 34480e9..3cdfc74 100644 +index 34480e9af2e71..3cdfc7490707b 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -541,6 +541,7 @@ CONFIG_PHY_XGENE=y @@ -23,6 +22,3 @@ index 34480e9..3cdfc74 100644 CONFIG_TEE=y CONFIG_OPTEE=y CONFIG_ARM_SCPI_PROTOCOL=y --- -2.7.4 - diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/0011-ARM64-defconfig-enable-CEC-support.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/100_linux-4.14.y-le-amlogic-gx-0011-arm64-defconfig-enable_cec_support.patch similarity index 80% rename from buildroot-external/board/hardkernel/odroid-c2/patches/linux/0011-ARM64-defconfig-enable-CEC-support.patch rename to buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/100_linux-4.14.y-le-amlogic-gx-0011-arm64-defconfig-enable_cec_support.patch index 54b58d493..143ac0634 100644 --- a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/0011-ARM64-defconfig-enable-CEC-support.patch +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/100_linux-4.14.y-le-amlogic-gx-0011-arm64-defconfig-enable_cec_support.patch @@ -1,18 +1,17 @@ -From 175366cb9e77fe54e6949f6599c0900cf0980b26 Mon Sep 17 00:00:00 2001 +From 6ea4d5e0afcdb84fc76cd5bfbc9b7d8f7009c512 Mon Sep 17 00:00:00 2001 From: Jerome Brunet Date: Mon, 13 Nov 2017 12:09:40 +0100 -Subject: [PATCH 11/39] ARM64: defconfig: enable CEC support +Subject: [PATCH] ARM64: defconfig: enable CEC support Turn on CONFIG_CEC_SUPPORT and CONFIG_CEC_PLATFORM_DRIVERS Signed-off-by: Jerome Brunet -Signed-off-by: Neil Armstrong --- arch/arm64/configs/defconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig -index 3cdfc74..944b93b 100644 +index 3cdfc7490707b..944b93b1c0268 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -350,6 +350,7 @@ CONFIG_MEDIA_SUPPORT=m @@ -31,6 +30,3 @@ index 3cdfc74..944b93b 100644 CONFIG_DRM=m CONFIG_DRM_NOUVEAU=m CONFIG_DRM_EXYNOS=m --- -2.7.4 - diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/0012-ARM64-defconfig-enable-CONFIG_VIDEO_MESON_AO_CEC.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/101_linux-4.14.y-le-amlogic-gx-0012-arm64-defconfig-enable_config_video_meson_ao_cec.patch similarity index 72% rename from buildroot-external/board/hardkernel/odroid-c2/patches/linux/0012-ARM64-defconfig-enable-CONFIG_VIDEO_MESON_AO_CEC.patch rename to buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/101_linux-4.14.y-le-amlogic-gx-0012-arm64-defconfig-enable_config_video_meson_ao_cec.patch index eb8910de8..a83f80069 100644 --- a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/0012-ARM64-defconfig-enable-CONFIG_VIDEO_MESON_AO_CEC.patch +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/101_linux-4.14.y-le-amlogic-gx-0012-arm64-defconfig-enable_config_video_meson_ao_cec.patch @@ -1,18 +1,17 @@ -From c71be51a7778a6aa6b784dd0edc57951acf63ef2 Mon Sep 17 00:00:00 2001 +From 0682a78ae935a272c73a281d6c320a6cd017ce28 Mon Sep 17 00:00:00 2001 From: Jerome Brunet Date: Mon, 13 Nov 2017 12:11:41 +0100 -Subject: [PATCH 12/39] ARM64: defconfig: enable CONFIG_VIDEO_MESON_AO_CEC +Subject: [PATCH] ARM64: defconfig: enable CONFIG_VIDEO_MESON_AO_CEC Turn on CONFIG_VIDEO_MESON_AO_CEC as module Signed-off-by: Jerome Brunet -Signed-off-by: Neil Armstrong --- arch/arm64/configs/defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig -index 944b93b..fdf94cb 100644 +index 944b93b1c0268..fdf94cbd56a28 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -366,6 +366,7 @@ CONFIG_VIDEO_SAMSUNG_EXYNOS_GSC=m @@ -23,6 +22,3 @@ index 944b93b..fdf94cb 100644 CONFIG_DRM=m CONFIG_DRM_NOUVEAU=m CONFIG_DRM_EXYNOS=m --- -2.7.4 - diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/0013-ARM64-defconfig-enable-CONFIG_DRM_DW_HDMI_CEC.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/102_linux-4.14.y-le-amlogic-gx-0013-arm64-defconfig-enable_config_drm_dw_hdmi_cec.patch similarity index 72% rename from buildroot-external/board/hardkernel/odroid-c2/patches/linux/0013-ARM64-defconfig-enable-CONFIG_DRM_DW_HDMI_CEC.patch rename to buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/102_linux-4.14.y-le-amlogic-gx-0013-arm64-defconfig-enable_config_drm_dw_hdmi_cec.patch index 8fda9646d..5e3622af2 100644 --- a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/0013-ARM64-defconfig-enable-CONFIG_DRM_DW_HDMI_CEC.patch +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/102_linux-4.14.y-le-amlogic-gx-0013-arm64-defconfig-enable_config_drm_dw_hdmi_cec.patch @@ -1,18 +1,17 @@ -From 94fb1910e76e39cc910fb5b5a528712f4135891e Mon Sep 17 00:00:00 2001 +From d537685003beb9f008c50075e66cb245e265dea2 Mon Sep 17 00:00:00 2001 From: Jerome Brunet Date: Mon, 13 Nov 2017 12:15:18 +0100 -Subject: [PATCH 13/39] ARM64: defconfig: enable CONFIG_DRM_DW_HDMI_CEC +Subject: [PATCH] ARM64: defconfig: enable CONFIG_DRM_DW_HDMI_CEC Turn on CONFIG_DRM_DW_HDMI_CEC as module Signed-off-by: Jerome Brunet -Signed-off-by: Neil Armstrong --- arch/arm64/configs/defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig -index fdf94cb..dcf1090 100644 +index fdf94cbd56a28..dcf10903f6340 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -388,6 +388,7 @@ CONFIG_DRM_RCAR_VSP=y @@ -23,6 +22,3 @@ index fdf94cb..dcf1090 100644 CONFIG_DRM_VC4=m CONFIG_DRM_HISI_KIRIN=m CONFIG_DRM_MESON=m --- -2.7.4 - diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/103_linux-4.14.y-le-amlogic-gx-1001-dts-meson-gxbb-add_sound-dai-cells_to_hdmi_node.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/103_linux-4.14.y-le-amlogic-gx-1001-dts-meson-gxbb-add_sound-dai-cells_to_hdmi_node.patch new file mode 100644 index 000000000..e2ea19c1a --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/103_linux-4.14.y-le-amlogic-gx-1001-dts-meson-gxbb-add_sound-dai-cells_to_hdmi_node.patch @@ -0,0 +1,10 @@ +--- a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi 2018-04-14 00:32:29.116806877 +0200 ++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi 2018-04-13 18:58:49.474094592 +0200 +@@ -343,6 +343,7 @@ + <&clkc CLKID_CLK81>, + <&clkc CLKID_GCLK_VENCI_INT0>; + clock-names = "isfr", "iahb", "venci"; ++ #sound-dai-cells = <0>; + }; + + &hiubus { diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/104_linux-4.14.y-le-amlogic-gx-1002-dts-meson-gxbb-rename_audio_card.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/104_linux-4.14.y-le-amlogic-gx-1002-dts-meson-gxbb-rename_audio_card.patch new file mode 100644 index 000000000..9480f4c72 --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/104_linux-4.14.y-le-amlogic-gx-1002-dts-meson-gxbb-rename_audio_card.patch @@ -0,0 +1,11 @@ +--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts 2018-05-01 01:15:01.378785083 +0200 ++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts 2018-05-02 00:16:22.834304176 +0200 +@@ -185,7 +185,7 @@ + + sound { + compatible = "simple-audio-card"; +- simple-audio-card,name = "meson-gx-preview"; ++ simple-audio-card,name = "meson-gxbb-audio"; + status = "okay"; + + simple-audio-card,dai-link@0 { diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/105_linux-4.17.y-amlogic-drm-0001-drm-meson-use_drm_gem_fb_create.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/105_linux-4.17.y-amlogic-drm-0001-drm-meson-use_drm_gem_fb_create.patch new file mode 100644 index 000000000..b59baebbd --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/105_linux-4.17.y-amlogic-drm-0001-drm-meson-use_drm_gem_fb_create.patch @@ -0,0 +1,40 @@ +From 24ef8157fcc092b5bd87cd1eb4dc0f540601d533 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= +Date: Sun, 24 Sep 2017 14:26:19 +0200 +Subject: [PATCH] drm/meson: Use drm_gem_fb_create() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +drm_fb_cma_create() is just a wrapper around drm_gem_fb_create() now, +so use the function directly. + +Cc: Neil Armstrong +Signed-off-by: Noralf Trønnes +Reviewed-by: Eric Anholt +Link: https://patchwork.freedesktop.org/patch/msgid/1506255985-61113-5-git-send-email-noralf@tronnes.org +--- + drivers/gpu/drm/meson/meson_drv.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c +index 7742c7d81ed8f..3b804fdaf7a05 100644 +--- a/drivers/gpu/drm/meson/meson_drv.c ++++ b/drivers/gpu/drm/meson/meson_drv.c +@@ -34,6 +34,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -78,7 +79,7 @@ static const struct drm_mode_config_funcs meson_mode_config_funcs = { + .output_poll_changed = meson_fb_output_poll_changed, + .atomic_check = drm_atomic_helper_check, + .atomic_commit = drm_atomic_helper_commit, +- .fb_create = drm_fb_cma_create, ++ .fb_create = drm_gem_fb_create, + }; + + static irqreturn_t meson_irq(int irq, void *arg) diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/0016-drm-meson-dw_hdmi-Add-support-for-an-optional-extern.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/106_linux-4.17.y-amlogic-drm-0004-drm-meson-dw_hdmi-add_support_for_an_optional_external_5v.patch similarity index 78% rename from buildroot-external/board/hardkernel/odroid-c2/patches/linux/0016-drm-meson-dw_hdmi-Add-support-for-an-optional-extern.patch rename to buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/106_linux-4.17.y-amlogic-drm-0004-drm-meson-dw_hdmi-add_support_for_an_optional_external_5v.patch index d23cd3f02..88e5f15c6 100644 --- a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/0016-drm-meson-dw_hdmi-Add-support-for-an-optional-extern.patch +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/106_linux-4.17.y-amlogic-drm-0004-drm-meson-dw_hdmi-add_support_for_an_optional_external_5v.patch @@ -1,20 +1,23 @@ -From fc742b3d9f1b79f9e3e695f0e4bfc6a35c7ed7e3 Mon Sep 17 00:00:00 2001 +From 161a803fe32d2b8c7a54d9819e3f2dc222f42e22 Mon Sep 17 00:00:00 2001 From: Neil Armstrong -Date: Mon, 16 Oct 2017 15:35:00 +0200 -Subject: [PATCH 16/39] drm/meson: dw_hdmi: Add support for an optional - external 5V regulator +Date: Wed, 6 Dec 2017 12:54:27 +0100 +Subject: [PATCH] drm/meson: dw_hdmi: Add support for an optional external 5V + regulator On reference boards and derivatives, the HDMI Logic is powered by an external 5V regulator. This regulator was set by the Vendor U-Boot, add optional support for it. Signed-off-by: Neil Armstrong +Tested-by: Jerome Brunet +Reviewed-by: Jerome Brunet +Link: https://patchwork.freedesktop.org/patch/msgid/1512561268-29806-4-git-send-email-narmstrong@baylibre.com --- drivers/gpu/drm/meson/meson_dw_hdmi.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/gpu/drm/meson/meson_dw_hdmi.c b/drivers/gpu/drm/meson/meson_dw_hdmi.c -index cef4144..17de3af 100644 +index cef414466f9fe..17de3afd98f6a 100644 --- a/drivers/gpu/drm/meson/meson_dw_hdmi.c +++ b/drivers/gpu/drm/meson/meson_dw_hdmi.c @@ -23,6 +23,7 @@ @@ -51,6 +54,3 @@ index cef4144..17de3af 100644 meson_dw_hdmi->hdmitx_apb = devm_reset_control_get_exclusive(dev, "hdmitx_apb"); if (IS_ERR(meson_dw_hdmi->hdmitx_apb)) { --- -2.7.4 - diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/0017-drm-meson-Add-missing-VPU-init.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/107_linux-4.17.y-amlogic-drm-0005-drm-meson-add_missing_vpu_init.patch similarity index 72% rename from buildroot-external/board/hardkernel/odroid-c2/patches/linux/0017-drm-meson-Add-missing-VPU-init.patch rename to buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/107_linux-4.17.y-amlogic-drm-0005-drm-meson-add_missing_vpu_init.patch index f3ab93118..ef68fc02c 100644 --- a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/0017-drm-meson-Add-missing-VPU-init.patch +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/107_linux-4.17.y-amlogic-drm-0005-drm-meson-add_missing_vpu_init.patch @@ -1,21 +1,25 @@ -From 253dbcb48f94e172873878262d19338bcc9aa108 Mon Sep 17 00:00:00 2001 +From 09762525d6eafb394a637e9ef8b602d3cd227939 Mon Sep 17 00:00:00 2001 From: Neil Armstrong -Date: Mon, 16 Oct 2017 15:34:21 +0200 -Subject: [PATCH 17/39] drm/meson: Add missing VPU init +Date: Wed, 6 Dec 2017 12:54:28 +0100 +Subject: [PATCH] drm/meson: Add missing VPU init The VPU init misses these configurations values. Signed-off-by: Neil Armstrong +Acked-by: Chris Wilson +Tested-by: Jerome Brunet +Reviewed-by: Jerome Brunet +Link: https://patchwork.freedesktop.org/patch/msgid/1512561268-29806-5-git-send-email-narmstrong@baylibre.com --- drivers/gpu/drm/meson/meson_drv.c | 9 +++++++++ drivers/gpu/drm/meson/meson_registers.h | 4 ++++ 2 files changed, 13 insertions(+) diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c -index 7742c7d..19a0d8d 100644 +index 3b804fdaf7a05..f9ad0e960263f 100644 --- a/drivers/gpu/drm/meson/meson_drv.c +++ b/drivers/gpu/drm/meson/meson_drv.c -@@ -150,6 +150,14 @@ static struct regmap_config meson_regmap_config = { +@@ -151,6 +151,14 @@ static struct regmap_config meson_regmap_config = { .max_register = 0x1000, }; @@ -30,7 +34,7 @@ index 7742c7d..19a0d8d 100644 static int meson_drv_bind_master(struct device *dev, bool has_components) { struct platform_device *pdev = to_platform_device(dev); -@@ -221,6 +229,7 @@ static int meson_drv_bind_master(struct device *dev, bool has_components) +@@ -222,6 +230,7 @@ static int meson_drv_bind_master(struct device *dev, bool has_components) /* Hardware Initialization */ @@ -39,7 +43,7 @@ index 7742c7d..19a0d8d 100644 meson_vpp_init(priv); meson_viu_init(priv); diff --git a/drivers/gpu/drm/meson/meson_registers.h b/drivers/gpu/drm/meson/meson_registers.h -index 2847381..bca8714 100644 +index 284738196af9c..bca87143e5488 100644 --- a/drivers/gpu/drm/meson/meson_registers.h +++ b/drivers/gpu/drm/meson/meson_registers.h @@ -1363,6 +1363,10 @@ @@ -53,6 +57,3 @@ index 2847381..bca8714 100644 /* osd super scale */ #define OSDSR_HV_SIZEIN 0x3130 --- -2.7.4 - diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/108_linux-4.17.y-amlogic-drm-0006-drm-meson-use_drm_mode_get_hv_timing_to_populate_plane.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/108_linux-4.17.y-amlogic-drm-0006-drm-meson-use_drm_mode_get_hv_timing_to_populate_plane.patch new file mode 100644 index 000000000..d619a85e4 --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/108_linux-4.17.y-amlogic-drm-0006-drm-meson-use_drm_mode_get_hv_timing_to_populate_plane.patch @@ -0,0 +1,44 @@ +From 13eff9ae5210b3858e462cc73c3133b41ac261dc Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Thu, 23 Nov 2017 21:04:55 +0200 +Subject: [PATCH] drm/meson: Use drm_mode_get_hv_timing() to populate plane + clip rectangle +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Use drm_mode_get_hv_timing() to fill out the plane clip rectangle. + +No functional changes as the code already uses crtc_state->mode +to populate the clip, which is also what drm_mode_get_hv_timing() +uses. + +Once everyone agrees on this we can move the clip handling into +drm_atomic_helper_check_plane_state(). + +Cc: Laurent Pinchart +Cc: Neil Armstrong +Cc: linux-amlogic@lists.infradead.org +Signed-off-by: Ville Syrjälä +Link: https://patchwork.freedesktop.org/patch/msgid/20171123190502.28449-9-ville.syrjala@linux.intel.com +Reviewed-by: Thierry Reding +--- + drivers/gpu/drm/meson/meson_plane.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/meson/meson_plane.c b/drivers/gpu/drm/meson/meson_plane.c +index d0a6ac8390f39..3801bee1f9e62 100644 +--- a/drivers/gpu/drm/meson/meson_plane.c ++++ b/drivers/gpu/drm/meson/meson_plane.c +@@ -58,8 +58,9 @@ static int meson_plane_atomic_check(struct drm_plane *plane, + if (IS_ERR(crtc_state)) + return PTR_ERR(crtc_state); + +- clip.x2 = crtc_state->mode.hdisplay; +- clip.y2 = crtc_state->mode.vdisplay; ++ if (crtc_state->enable) ++ drm_mode_get_hv_timing(&crtc_state->mode, ++ &clip.x2, &clip.y2); + + return drm_atomic_helper_check_plane_state(state, crtc_state, &clip, + DRM_PLANE_HELPER_NO_SCALING, diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/0039-drm-meson-Add-support-for-DMT-modes-on-HDMI.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/109_linux-4.17.y-amlogic-drm-0014-drm-meson-add_support_for_dmt_modes_on_hdmi.patch similarity index 95% rename from buildroot-external/board/hardkernel/odroid-c2/patches/linux/0039-drm-meson-Add-support-for-DMT-modes-on-HDMI.patch rename to buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/109_linux-4.17.y-amlogic-drm-0014-drm-meson-add_support_for_dmt_modes_on_hdmi.patch index 9cd2dbd1b..16b03f3f4 100644 --- a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/0039-drm-meson-Add-support-for-DMT-modes-on-HDMI.patch +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/109_linux-4.17.y-amlogic-drm-0014-drm-meson-add_support_for_dmt_modes_on_hdmi.patch @@ -1,7 +1,7 @@ -From 8da289631087c90a3b644cbdd124bee7f7b348f3 Mon Sep 17 00:00:00 2001 +From 9c936b12f15019b38edb5f8bae77bb5b0046d1b7 Mon Sep 17 00:00:00 2001 From: Neil Armstrong -Date: Thu, 8 Mar 2018 16:35:34 +0100 -Subject: [PATCH 39/39] drm/meson: Add support for DMT modes on HDMI +Date: Tue, 13 Mar 2018 11:07:50 +0100 +Subject: [PATCH] drm/meson: Add support for DMT modes on HDMI This patch adds support for DMT display modes over HDMI. The modes timings configurations are from the Amlogic Vendor linux tree @@ -19,7 +19,9 @@ Only these following modes are supported with these changes: The associated code to handle the clock rates is also added. +Acked-by: Jerome Brunet Signed-off-by: Neil Armstrong +Link: https://patchwork.freedesktop.org/patch/msgid/1520935670-14187-1-git-send-email-narmstrong@baylibre.com --- drivers/gpu/drm/meson/meson_dw_hdmi.c | 22 +-- drivers/gpu/drm/meson/meson_vclk.c | 219 ++++++++++++++++++++- @@ -28,10 +30,10 @@ Signed-off-by: Neil Armstrong 4 files changed, 570 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/meson/meson_dw_hdmi.c b/drivers/gpu/drm/meson/meson_dw_hdmi.c -index 17de3af..9d70ed6 100644 +index d49af17310c99..a393095aac1a6 100644 --- a/drivers/gpu/drm/meson/meson_dw_hdmi.c +++ b/drivers/gpu/drm/meson/meson_dw_hdmi.c -@@ -537,7 +537,6 @@ static irqreturn_t dw_hdmi_top_thread_irq(int irq, void *dev_id) +@@ -538,7 +538,6 @@ static irqreturn_t dw_hdmi_top_thread_irq(int irq, void *dev_id) return IRQ_HANDLED; } @@ -39,7 +41,7 @@ index 17de3af..9d70ed6 100644 static enum drm_mode_status dw_hdmi_mode_valid(struct drm_connector *connector, const struct drm_display_mode *mode) -@@ -554,12 +553,12 @@ dw_hdmi_mode_valid(struct drm_connector *connector, +@@ -555,12 +554,12 @@ dw_hdmi_mode_valid(struct drm_connector *connector, mode->vdisplay, mode->vsync_start, mode->vsync_end, mode->vtotal, mode->type, mode->flags); @@ -58,7 +60,7 @@ index 17de3af..9d70ed6 100644 return MODE_BAD; vclk_freq = mode->clock; -@@ -585,9 +584,14 @@ dw_hdmi_mode_valid(struct drm_connector *connector, +@@ -586,9 +585,14 @@ dw_hdmi_mode_valid(struct drm_connector *connector, /* Finally filter by configurable vclk frequencies */ switch (vclk_freq) { @@ -73,7 +75,7 @@ index 17de3af..9d70ed6 100644 case 297000: case 594000: return MODE_OK; -@@ -652,10 +656,6 @@ static void meson_venc_hdmi_encoder_mode_set(struct drm_encoder *encoder, +@@ -653,10 +657,6 @@ static void meson_venc_hdmi_encoder_mode_set(struct drm_encoder *encoder, DRM_DEBUG_DRIVER("%d:\"%s\" vic %d\n", mode->base.id, mode->name, vic); @@ -85,7 +87,7 @@ index 17de3af..9d70ed6 100644 meson_venc_hdmi_mode_set(priv, vic, mode); diff --git a/drivers/gpu/drm/meson/meson_vclk.c b/drivers/gpu/drm/meson/meson_vclk.c -index 4767704..f051122 100644 +index 47677047e42dd..f0511220317f9 100644 --- a/drivers/gpu/drm/meson/meson_vclk.c +++ b/drivers/gpu/drm/meson/meson_vclk.c @@ -328,14 +328,24 @@ static void meson_venci_cvbs_clock_config(struct meson_drm *priv) @@ -255,10 +257,18 @@ index 4767704..f051122 100644 case 4320000: regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x5800025a); regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x00000000); -@@ -485,6 +619,23 @@ void meson_hdmi_pll_set(struct meson_drm *priv, - regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL, - val, (val & HDMI_PLL_LOCK), 10, 0); - break; +@@ -477,6 +611,23 @@ void meson_hdmi_pll_set(struct meson_drm *priv, + regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x71486980); + regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x00000e55); + ++ /* unreset */ ++ regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL, ++ BIT(28), 0); ++ ++ /* Poll for lock bit */ ++ regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL, ++ val, (val & HDMI_PLL_LOCK), 10, 0); ++ break; + + case 5200000: + regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x5800026c); @@ -268,17 +278,9 @@ index 4767704..f051122 100644 + regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x71486980); + regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x00000e55); + -+ /* unreset */ -+ regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL, -+ BIT(28), 0); -+ -+ /* Poll for lock bit */ -+ regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL, -+ val, (val & HDMI_PLL_LOCK), 10, 0); -+ break; - }; - } else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu") || - meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu")) { + /* unreset */ + regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL, + BIT(28), 0); @@ -498,6 +649,42 @@ void meson_hdmi_pll_set(struct meson_drm *priv, regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500); break; @@ -370,7 +372,7 @@ index 4767704..f051122 100644 freq = MESON_VCLK_HDMI_297000; break; diff --git a/drivers/gpu/drm/meson/meson_venc.c b/drivers/gpu/drm/meson/meson_venc.c -index 9509017..6e27013 100644 +index 9509017dbded1..6e27013898013 100644 --- a/drivers/gpu/drm/meson/meson_venc.c +++ b/drivers/gpu/drm/meson/meson_venc.c @@ -697,6 +697,314 @@ union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080p60 = { @@ -757,7 +759,7 @@ index 9509017..6e27013 100644 writel_relaxed(0, priv->io_base + _REG(ENCI_VIDEO_EN)); diff --git a/drivers/gpu/drm/meson/meson_venc.h b/drivers/gpu/drm/meson/meson_venc.h -index a1b96e8..7c18a36 100644 +index a1b96e898c14e..7c18a36a0dd0c 100644 --- a/drivers/gpu/drm/meson/meson_venc.h +++ b/drivers/gpu/drm/meson/meson_venc.h @@ -58,6 +58,7 @@ struct meson_cvbs_enci_mode { @@ -768,6 +770,3 @@ index a1b96e8..7c18a36 100644 bool meson_venc_hdmi_supported_vic(int vic); bool meson_venc_hdmi_venc_repeat(int vic); --- -2.7.4 - diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/110_linux-4.17.y-amlogic-drm-0015-drm-meson-fix_potential_null_dereference_in.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/110_linux-4.17.y-amlogic-drm-0015-drm-meson-fix_potential_null_dereference_in.patch new file mode 100644 index 000000000..cdff10fe5 --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/110_linux-4.17.y-amlogic-drm-0015-drm-meson-fix_potential_null_dereference_in.patch @@ -0,0 +1,52 @@ +From acaa3f13b8dd77da3c6c0fe18cb1159eef7ea286 Mon Sep 17 00:00:00 2001 +From: Wei Yongjun +Date: Tue, 20 Mar 2018 14:20:30 +0000 +Subject: [PATCH] drm/meson: Fix potential NULL dereference in + meson_drv_bind_master() + +platform_get_resource_byname() may fail and return NULL, so we should +better check it's return value to avoid a NULL pointer dereference +a bit later in the code. + +This is detected by Coccinelle semantic patch. + +@@ +expression pdev, res, n, t, e, e1, e2; +@@ + +res = platform_get_resource_byname(pdev, t, n); ++ if (!res) ++ return -EINVAL; +... when != res == NULL +e = devm_ioremap(e1, res->start, e2); + +Signed-off-by: Wei Yongjun +Signed-off-by: Neil Armstrong +Acked-by: Neil Armstrong +Link: https://patchwork.freedesktop.org/patch/msgid/1521555630-29284-1-git-send-email-weiyongjun1@huawei.com +--- + drivers/gpu/drm/meson/meson_drv.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c +index 3baceb744beb8..32b1a6cdecfc0 100644 +--- a/drivers/gpu/drm/meson/meson_drv.c ++++ b/drivers/gpu/drm/meson/meson_drv.c +@@ -197,6 +197,8 @@ static int meson_drv_bind_master(struct device *dev, bool has_components) + priv->io_base = regs; + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hhi"); ++ if (!res) ++ return -EINVAL; + /* Simply ioremap since it may be a shared register zone */ + regs = devm_ioremap(dev, res->start, resource_size(res)); + if (!regs) { +@@ -213,6 +215,8 @@ static int meson_drv_bind_master(struct device *dev, bool has_components) + } + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dmc"); ++ if (!res) ++ return -EINVAL; + /* Simply ioremap since it may be a shared register zone */ + regs = devm_ioremap(dev, res->start, resource_size(res)); + if (!regs) { diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/111_linux-4.17-amlogic-dmt-extended-0001-make_dmt_timings_parameter_generic_and_add_more_frequencies.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/111_linux-4.17-amlogic-dmt-extended-0001-make_dmt_timings_parameter_generic_and_add_more_frequencies.patch new file mode 100644 index 000000000..c0859bcf3 --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/111_linux-4.17-amlogic-dmt-extended-0001-make_dmt_timings_parameter_generic_and_add_more_frequencies.patch @@ -0,0 +1,714 @@ +From 2d49cff77c34c63ae5aa32537cc5fef1ea2e165d Mon Sep 17 00:00:00 2001 +From: Neil Armstrong +Date: Fri, 27 Apr 2018 17:19:46 +0200 +Subject: [PATCH] drm/meson: Make DMT timings parameter generic and add more + frequencies + +Add more frequencies to support more timings with the generic timings +parameters calculation. + +Signed-off-by: Neil Armstrong +--- + drivers/gpu/drm/meson/meson_dw_hdmi.c | 10 +- + drivers/gpu/drm/meson/meson_vclk.c | 184 ++++++++++++++++++- + drivers/gpu/drm/meson/meson_venc.c | 330 +++++----------------------------- + drivers/gpu/drm/meson/meson_venc.h | 3 +- + 4 files changed, 231 insertions(+), 296 deletions(-) + +diff --git a/drivers/gpu/drm/meson/meson_dw_hdmi.c b/drivers/gpu/drm/meson/meson_dw_hdmi.c +index a393095aac1a6..7ebfef86383fe 100644 +--- a/drivers/gpu/drm/meson/meson_dw_hdmi.c ++++ b/drivers/gpu/drm/meson/meson_dw_hdmi.c +@@ -546,6 +546,7 @@ dw_hdmi_mode_valid(struct drm_connector *connector, + unsigned int venc_freq; + unsigned int hdmi_freq; + int vic = drm_match_cea_mode(mode); ++ enum drm_mode_status status; + + DRM_DEBUG_DRIVER("Modeline %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x\n", + mode->base.id, mode->name, mode->vrefresh, mode->clock, +@@ -556,8 +557,9 @@ dw_hdmi_mode_valid(struct drm_connector *connector, + + /* Check against non-VIC supported modes */ + if (!vic) { +- if (!meson_venc_hdmi_supported_mode(mode)) +- return MODE_BAD; ++ status = meson_venc_hdmi_supported_mode(mode); ++ if (status != MODE_OK) ++ return status; + /* Check against supported VIC modes */ + } else if (!meson_venc_hdmi_supported_vic(vic)) + return MODE_BAD; +@@ -587,6 +589,10 @@ dw_hdmi_mode_valid(struct drm_connector *connector, + switch (vclk_freq) { + case 25175: + case 40000: ++ case 32000: ++ case 36000: ++ case 33750: ++ case 33900: + case 54000: + case 65000: + case 74250: +diff --git a/drivers/gpu/drm/meson/meson_vclk.c b/drivers/gpu/drm/meson/meson_vclk.c +index f0511220317f9..86975f245c361 100644 +--- a/drivers/gpu/drm/meson/meson_vclk.c ++++ b/drivers/gpu/drm/meson/meson_vclk.c +@@ -330,22 +330,30 @@ static void meson_venci_cvbs_clock_config(struct meson_drm *priv) + #define MESON_VCLK_HDMI_DDR_148500 3 + /* 4028 /4 /4 /1 /5 /2 => /1 /1 */ + #define MESON_VCLK_HDMI_25175 4 ++/* 2560 /4 /2 /1 /5 /2 => /1 /1 */ ++#define MESON_VCLK_HDMI_32000 5 ++/* 2700 /4 /2 /1 /5 /2 => /1 /1 */ ++#define MESON_VCLK_HDMI_33750 6 ++/* 2712 /4 /2 /1 /5 /2 => /1 /1 */ ++#define MESON_VCLK_HDMI_33900 7 ++/* 2880 /4 /2 /1 /5 /2 => /1 /1 */ ++#define MESON_VCLK_HDMI_36000 8 + /* 3200 /4 /2 /1 /5 /2 => /1 /1 */ +-#define MESON_VCLK_HDMI_40000 5 ++#define MESON_VCLK_HDMI_40000 9 + /* 5200 /4 /2 /1 /5 /2 => /1 /1 */ +-#define MESON_VCLK_HDMI_65000 6 ++#define MESON_VCLK_HDMI_65000 10 + /* 2970 /2 /2 /2 /5 /1 => /1 /1 */ +-#define MESON_VCLK_HDMI_74250 7 ++#define MESON_VCLK_HDMI_74250 11 + /* 4320 /4 /1 /1 /5 /2 => /1 /1 */ +-#define MESON_VCLK_HDMI_108000 8 ++#define MESON_VCLK_HDMI_108000 12 + /* 2970 /1 /2 /2 /5 /1 => /1 /1 */ +-#define MESON_VCLK_HDMI_148500 9 ++#define MESON_VCLK_HDMI_148500 13 + /* 3240 /2 /1 /1 /5 /2 => /1 /1 */ +-#define MESON_VCLK_HDMI_162000 10 ++#define MESON_VCLK_HDMI_162000 14 + /* 2970 /1 /1 /1 /5 /2 => /1 /1 */ +-#define MESON_VCLK_HDMI_297000 11 ++#define MESON_VCLK_HDMI_297000 15 + /* 5940 /1 /1 /2 /5 /1 => /1 /1 */ +-#define MESON_VCLK_HDMI_594000 12 ++#define MESON_VCLK_HDMI_594000 16 + + struct meson_vclk_params { + unsigned int pll_base_freq; +@@ -419,6 +427,38 @@ struct meson_vclk_params { + .vid_pll_div = VID_PLL_DIV_5, + .vclk_div = 2, + }, ++ [MESON_VCLK_HDMI_32000] = { ++ .pll_base_freq = 2560000, ++ .pll_od1 = 4, ++ .pll_od2 = 2, ++ .pll_od3 = 1, ++ .vid_pll_div = VID_PLL_DIV_5, ++ .vclk_div = 2, ++ }, ++ [MESON_VCLK_HDMI_33750] = { ++ .pll_base_freq = 2700000, ++ .pll_od1 = 4, ++ .pll_od2 = 2, ++ .pll_od3 = 1, ++ .vid_pll_div = VID_PLL_DIV_5, ++ .vclk_div = 2, ++ }, ++ [MESON_VCLK_HDMI_33900] = { ++ .pll_base_freq = 2712000, ++ .pll_od1 = 4, ++ .pll_od2 = 2, ++ .pll_od3 = 1, ++ .vid_pll_div = VID_PLL_DIV_5, ++ .vclk_div = 2, ++ }, ++ [MESON_VCLK_HDMI_36000] = { ++ .pll_base_freq = 2880000, ++ .pll_od1 = 4, ++ .pll_od2 = 2, ++ .pll_od3 = 1, ++ .vid_pll_div = VID_PLL_DIV_5, ++ .vclk_div = 2, ++ }, + [MESON_VCLK_HDMI_40000] = { + .pll_base_freq = 3200000, + .pll_od1 = 4, +@@ -480,6 +520,86 @@ void meson_hdmi_pll_set(struct meson_drm *priv, + + if (meson_vpu_is_compatible(priv, "amlogic,meson-gxbb-vpu")) { + switch (base) { ++ case 2560000: ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x58000235); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x00000000); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x0d5c5091); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x801da72c); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x71486980); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x00000e55); ++ ++ /* Enable and unreset */ ++ regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL, ++ 0x7 << 28, 0x4 << 28); ++ ++ /* Poll for lock bit */ ++ regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL, ++ val, (val & HDMI_PLL_LOCK), 10, 0); ++ ++ /* div_frac */ ++ regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2, ++ 0xFFFF, 0x4555); ++ break; ++ ++ case 2700000: ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x58000238); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x00000000); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x0d5c5091); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x801da72c); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x71486980); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x00000e55); ++ ++ /* Enable and unreset */ ++ regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL, ++ 0x7 << 28, 0x4 << 28); ++ ++ /* Poll for lock bit */ ++ regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL, ++ val, (val & HDMI_PLL_LOCK), 10, 0); ++ ++ /* div_frac */ ++ regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2, ++ 0xFFFF, 0x4400); ++ break; ++ ++ case 2712000: ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x58000238); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x00000000); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x0d5c5091); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x801da72c); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x71486980); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x00000e55); ++ ++ /* Enable and unreset */ ++ regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL, ++ 0x7 << 28, 0x4 << 28); ++ ++ /* Poll for lock bit */ ++ regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL, ++ val, (val & HDMI_PLL_LOCK), 10, 0); ++ ++ /* div_frac */ ++ regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2, ++ 0xFFFF, 0x4800); ++ break; ++ ++ case 2880000: ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x5800023c); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x00000000); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x0d5c5091); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x801da72c); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x71486980); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x00000e55); ++ ++ /* Enable and unreset */ ++ regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL, ++ 0x7 << 28, 0x4 << 28); ++ ++ /* Poll for lock bit */ ++ regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL, ++ val, (val & HDMI_PLL_LOCK), 10, 0); ++ break; ++ + case 2970000: + regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x5800023d); + regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x00000000); +@@ -640,6 +760,42 @@ void meson_hdmi_pll_set(struct meson_drm *priv, + } else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu") || + meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu")) { + switch (base) { ++ case 2560000: ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x4000026a); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb2ab); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x860f30c4); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x0c8e0000); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x001fa729); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500); ++ break; ++ ++ case 2700000: ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x40000270); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb200); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x860f30c4); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x0c8e0000); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x001fa729); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500); ++ break; ++ ++ case 2712000: ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x40000271); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb000); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x860f30c4); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x0c8e0000); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x001fa729); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500); ++ break; ++ ++ case 2880000: ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x40000278); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb000); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x860f30c4); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x0c8e0000); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x001fa729); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500); ++ break; ++ + case 2970000: + regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x4000027b); + regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb300); +@@ -789,6 +945,18 @@ void meson_vclk_setup(struct meson_drm *priv, unsigned int target, + case 25175: + freq = MESON_VCLK_HDMI_25175; + break; ++ case 32000: ++ freq = MESON_VCLK_HDMI_32000; ++ break; ++ case 33750: ++ freq = MESON_VCLK_HDMI_33750; ++ break; ++ case 33900: ++ freq = MESON_VCLK_HDMI_33900; ++ break; ++ case 36000: ++ freq = MESON_VCLK_HDMI_36000; ++ break; + case 40000: + freq = MESON_VCLK_HDMI_40000; + break; +diff --git a/drivers/gpu/drm/meson/meson_venc.c b/drivers/gpu/drm/meson/meson_venc.c +index 6e27013898013..ea178151399c5 100644 +--- a/drivers/gpu/drm/meson/meson_venc.c ++++ b/drivers/gpu/drm/meson/meson_venc.c +@@ -697,258 +697,6 @@ union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080p60 = { + }, + }; + +-union meson_hdmi_venc_mode meson_hdmi_encp_mode_640x480_60 = { +- .encp = { +- .dvi_settings = 0x21, +- .video_mode = 0x4040, +- .video_mode_adv = 0x18, +- /* video_prog_mode */ +- /* video_sync_mode */ +- /* video_yc_dly */ +- /* video_rgb_ctrl */ +- /* video_filt_ctrl */ +- /* video_ofld_voav_ofst */ +- /* yfp1_htime */ +- /* yfp2_htime */ +- .max_pxcnt = 0x31f, +- /* hspuls_begin */ +- /* hspuls_end */ +- /* hspuls_switch */ +- /* vspuls_begin */ +- /* vspuls_end */ +- /* vspuls_bline */ +- /* vspuls_eline */ +- .havon_begin = 0x90, +- .havon_end = 0x30f, +- .vavon_bline = 0x23, +- .vavon_eline = 0x202, +- /* eqpuls_begin */ +- /* eqpuls_end */ +- /* eqpuls_bline */ +- /* eqpuls_eline */ +- .hso_begin = 0, +- .hso_end = 0x60, +- .vso_begin = 0x1e, +- .vso_end = 0x32, +- .vso_bline = 0, +- .vso_eline = 2, +- .vso_eline_present = true, +- /* sy_val */ +- /* sy2_val */ +- .max_lncnt = 0x20c, +- }, +-}; +- +-union meson_hdmi_venc_mode meson_hdmi_encp_mode_800x600_60 = { +- .encp = { +- .dvi_settings = 0x21, +- .video_mode = 0x4040, +- .video_mode_adv = 0x18, +- /* video_prog_mode */ +- /* video_sync_mode */ +- /* video_yc_dly */ +- /* video_rgb_ctrl */ +- /* video_filt_ctrl */ +- /* video_ofld_voav_ofst */ +- /* yfp1_htime */ +- /* yfp2_htime */ +- .max_pxcnt = 0x41f, +- /* hspuls_begin */ +- /* hspuls_end */ +- /* hspuls_switch */ +- /* vspuls_begin */ +- /* vspuls_end */ +- /* vspuls_bline */ +- /* vspuls_eline */ +- .havon_begin = 0xD8, +- .havon_end = 0x3f7, +- .vavon_bline = 0x1b, +- .vavon_eline = 0x272, +- /* eqpuls_begin */ +- /* eqpuls_end */ +- /* eqpuls_bline */ +- /* eqpuls_eline */ +- .hso_begin = 0, +- .hso_end = 0x80, +- .vso_begin = 0x1e, +- .vso_end = 0x32, +- .vso_bline = 0, +- .vso_eline = 4, +- .vso_eline_present = true, +- /* sy_val */ +- /* sy2_val */ +- .max_lncnt = 0x273, +- }, +-}; +- +-union meson_hdmi_venc_mode meson_hdmi_encp_mode_1024x768_60 = { +- .encp = { +- .dvi_settings = 0x21, +- .video_mode = 0x4040, +- .video_mode_adv = 0x18, +- /* video_prog_mode */ +- /* video_sync_mode */ +- /* video_yc_dly */ +- /* video_rgb_ctrl */ +- /* video_filt_ctrl */ +- /* video_ofld_voav_ofst */ +- /* yfp1_htime */ +- /* yfp2_htime */ +- .max_pxcnt = 1343, +- /* hspuls_begin */ +- /* hspuls_end */ +- /* hspuls_switch */ +- /* vspuls_begin */ +- /* vspuls_end */ +- /* vspuls_bline */ +- /* vspuls_eline */ +- .havon_begin = 296, +- .havon_end = 1319, +- .vavon_bline = 35, +- .vavon_eline = 802, +- /* eqpuls_begin */ +- /* eqpuls_end */ +- /* eqpuls_bline */ +- /* eqpuls_eline */ +- .hso_begin = 0, +- .hso_end = 136, +- .vso_begin = 30, +- .vso_end = 50, +- .vso_bline = 0, +- .vso_eline = 6, +- .vso_eline_present = true, +- /* sy_val */ +- /* sy2_val */ +- .max_lncnt = 805, +- }, +-}; +- +-union meson_hdmi_venc_mode meson_hdmi_encp_mode_1152x864_75 = { +- .encp = { +- .dvi_settings = 0x21, +- .video_mode = 0x4040, +- .video_mode_adv = 0x18, +- /* video_prog_mode */ +- /* video_sync_mode */ +- /* video_yc_dly */ +- /* video_rgb_ctrl */ +- /* video_filt_ctrl */ +- /* video_ofld_voav_ofst */ +- /* yfp1_htime */ +- /* yfp2_htime */ +- .max_pxcnt = 0x63f, +- /* hspuls_begin */ +- /* hspuls_end */ +- /* hspuls_switch */ +- /* vspuls_begin */ +- /* vspuls_end */ +- /* vspuls_bline */ +- /* vspuls_eline */ +- .havon_begin = 0x180, +- .havon_end = 0x5ff, +- .vavon_bline = 0x23, +- .vavon_eline = 0x382, +- /* eqpuls_begin */ +- /* eqpuls_end */ +- /* eqpuls_bline */ +- /* eqpuls_eline */ +- .hso_begin = 0, +- .hso_end = 0x80, +- .vso_begin = 0x1e, +- .vso_end = 0x32, +- .vso_bline = 0, +- .vso_eline = 3, +- .vso_eline_present = true, +- /* sy_val */ +- /* sy2_val */ +- .max_lncnt = 0x383, +- }, +-}; +- +-union meson_hdmi_venc_mode meson_hdmi_encp_mode_1280x1024_60 = { +- .encp = { +- .dvi_settings = 0x21, +- .video_mode = 0x4040, +- .video_mode_adv = 0x18, +- /* video_prog_mode */ +- /* video_sync_mode */ +- /* video_yc_dly */ +- /* video_rgb_ctrl */ +- /* video_filt_ctrl */ +- /* video_ofld_voav_ofst */ +- /* yfp1_htime */ +- /* yfp2_htime */ +- .max_pxcnt = 0x697, +- /* hspuls_begin */ +- /* hspuls_end */ +- /* hspuls_switch */ +- /* vspuls_begin */ +- /* vspuls_end */ +- /* vspuls_bline */ +- /* vspuls_eline */ +- .havon_begin = 0x168, +- .havon_end = 0x667, +- .vavon_bline = 0x29, +- .vavon_eline = 0x428, +- /* eqpuls_begin */ +- /* eqpuls_end */ +- /* eqpuls_bline */ +- /* eqpuls_eline */ +- .hso_begin = 0, +- .hso_end = 0x70, +- .vso_begin = 0x1e, +- .vso_end = 0x32, +- .vso_bline = 0, +- .vso_eline = 3, +- .vso_eline_present = true, +- /* sy_val */ +- /* sy2_val */ +- .max_lncnt = 0x429, +- }, +-}; +- +-union meson_hdmi_venc_mode meson_hdmi_encp_mode_1600x1200_60 = { +- .encp = { +- .dvi_settings = 0x21, +- .video_mode = 0x4040, +- .video_mode_adv = 0x18, +- /* video_prog_mode */ +- /* video_sync_mode */ +- /* video_yc_dly */ +- /* video_rgb_ctrl */ +- /* video_filt_ctrl */ +- /* video_ofld_voav_ofst */ +- /* yfp1_htime */ +- /* yfp2_htime */ +- .max_pxcnt = 0x86f, +- /* hspuls_begin */ +- /* hspuls_end */ +- /* hspuls_switch */ +- /* vspuls_begin */ +- /* vspuls_end */ +- /* vspuls_bline */ +- /* vspuls_eline */ +- .havon_begin = 0x1f0, +- .havon_end = 0x82f, +- .vavon_bline = 0x31, +- .vavon_eline = 0x4e0, +- /* eqpuls_begin */ +- /* eqpuls_end */ +- /* eqpuls_bline */ +- /* eqpuls_eline */ +- .hso_begin = 0, +- .hso_end = 0xc0, +- .vso_begin = 0x1e, +- .vso_end = 0x32, +- .vso_bline = 0, +- .vso_eline = 3, +- .vso_eline_present = true, +- /* sy_val */ +- /* sy2_val */ +- .max_lncnt = 0x4e1, +- }, +-}; +- + struct meson_hdmi_venc_dmt_mode { + struct drm_display_mode drm_mode; + union meson_hdmi_venc_mode *mode; +@@ -958,49 +706,42 @@ struct meson_hdmi_venc_dmt_mode { + { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25175, 640, 656, + 752, 800, 0, 480, 490, 492, 525, 0, + DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, +- &meson_hdmi_encp_mode_640x480_60, + }, + /* 800x600@60Hz */ + { + { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 40000, 800, 840, + 968, 1056, 0, 600, 601, 605, 628, 0, + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, +- &meson_hdmi_encp_mode_800x600_60, + }, + /* 1024x768@60Hz */ + { + { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 65000, 1024, + 1048, 1184, 1344, 0, 768, 771, 777, 806, 0, + DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, +- &meson_hdmi_encp_mode_1024x768_60, + }, + /* 1152x864@75Hz */ + { + { DRM_MODE("1152x864", DRM_MODE_TYPE_DRIVER, 108000, 1152, + 1216, 1344, 1600, 0, 864, 865, 868, 900, 0, + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, +- &meson_hdmi_encp_mode_1152x864_75, + }, + /* 1280x1024@60Hz */ + { + { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 108000, 1280, + 1328, 1440, 1688, 0, 1024, 1025, 1028, 1066, 0, + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, +- &meson_hdmi_encp_mode_1280x1024_60, + }, + /* 1600x1200@60Hz */ + { + { DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 162000, 1600, + 1664, 1856, 2160, 0, 1200, 1201, 1204, 1250, 0, + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, +- &meson_hdmi_encp_mode_1600x1200_60, + }, + /* 1920x1080@60Hz */ + { + { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, + 2008, 2052, 2200, 0, 1080, 1084, 1089, 1125, 0, + DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, +- &meson_hdmi_encp_mode_1080p60 + }, + { }, /* sentinel */ + }; +@@ -1044,17 +785,20 @@ static unsigned long modulo(unsigned long a, unsigned long b) + return a; + } + +-bool meson_venc_hdmi_supported_mode(const struct drm_display_mode *mode) ++enum drm_mode_status ++meson_venc_hdmi_supported_mode(const struct drm_display_mode *mode) + { +- struct meson_hdmi_venc_dmt_mode *vmode = meson_hdmi_venc_dmt_modes; ++ if (mode->flags & ~(DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NHSYNC | ++ DRM_MODE_FLAG_PVSYNC | DRM_MODE_FLAG_NVSYNC)) ++ return MODE_BAD; + +- while (vmode->mode) { +- if (drm_mode_equal(&vmode->drm_mode, mode)) +- return true; +- vmode++; +- } ++ if (mode->hdisplay < 640 || mode->hdisplay > 1920) ++ return MODE_BAD_HVALUE; + +- return false; ++ if (mode->vdisplay < 480 || mode->vdisplay > 1200) ++ return MODE_BAD_VVALUE; ++ ++ return MODE_OK; + } + EXPORT_SYMBOL_GPL(meson_venc_hdmi_supported_mode); + +@@ -1072,18 +816,29 @@ bool meson_venc_hdmi_supported_vic(int vic) + } + EXPORT_SYMBOL_GPL(meson_venc_hdmi_supported_vic); + +-static union meson_hdmi_venc_mode +-*meson_venc_hdmi_get_dmt_vmode(const struct drm_display_mode *mode) ++void meson_venc_hdmi_get_dmt_vmode(const struct drm_display_mode *mode, ++ union meson_hdmi_venc_mode *dmt_mode) + { +- struct meson_hdmi_venc_dmt_mode *vmode = meson_hdmi_venc_dmt_modes; +- +- while (vmode->mode) { +- if (drm_mode_equal(&vmode->drm_mode, mode)) +- return vmode->mode; +- vmode++; +- } +- +- return NULL; ++ memset(dmt_mode, 0, sizeof(*dmt_mode)); ++ ++ dmt_mode->encp.dvi_settings = 0x21; ++ dmt_mode->encp.video_mode = 0x4040; ++ dmt_mode->encp.video_mode_adv = 0x18; ++ dmt_mode->encp.max_pxcnt = mode->htotal - 1; ++ dmt_mode->encp.havon_begin = mode->htotal - mode->hsync_start; ++ dmt_mode->encp.havon_end = dmt_mode->encp.havon_begin + ++ mode->hdisplay - 1; ++ dmt_mode->encp.vavon_bline = mode->vtotal - mode->vsync_start; ++ dmt_mode->encp.vavon_eline = dmt_mode->encp.vavon_bline + ++ mode->vdisplay - 1; ++ dmt_mode->encp.hso_begin = 0; ++ dmt_mode->encp.hso_end = mode->hsync_end - mode->hsync_start; ++ dmt_mode->encp.vso_begin = 30; ++ dmt_mode->encp.vso_end = 50; ++ dmt_mode->encp.vso_bline = 0; ++ dmt_mode->encp.vso_eline = mode->vsync_end - mode->vsync_start; ++ dmt_mode->encp.vso_eline_present = true; ++ dmt_mode->encp.max_lncnt = mode->vtotal - 1; + } + + static union meson_hdmi_venc_mode *meson_venc_hdmi_get_vic_vmode(int vic) +@@ -1120,6 +875,7 @@ void meson_venc_hdmi_mode_set(struct meson_drm *priv, int vic, + struct drm_display_mode *mode) + { + union meson_hdmi_venc_mode *vmode = NULL; ++ union meson_hdmi_venc_mode vmode_dmt; + bool use_enci = false; + bool venc_repeat = false; + bool hdmi_repeat = false; +@@ -1147,14 +903,18 @@ void meson_venc_hdmi_mode_set(struct meson_drm *priv, int vic, + unsigned int sof_lines; + unsigned int vsync_lines; + +- if (meson_venc_hdmi_supported_vic(vic)) ++ if (meson_venc_hdmi_supported_vic(vic)) { + vmode = meson_venc_hdmi_get_vic_vmode(vic); +- else +- vmode = meson_venc_hdmi_get_dmt_vmode(mode); +- if (!vmode) { +- dev_err(priv->dev, "%s: Fatal Error, unsupported mode " +- DRM_MODE_FMT "\n", __func__, DRM_MODE_ARG(mode)); +- return; ++ if (!vmode) { ++ dev_err(priv->dev, "%s: Fatal Error, unsupported mode " ++ DRM_MODE_FMT "\n", __func__, ++ DRM_MODE_ARG(mode)); ++ return; ++ } ++ } ++ else { ++ meson_venc_hdmi_get_dmt_vmode(mode, &vmode_dmt); ++ vmode = &vmode_dmt; + } + + /* Use VENCI for 480i and 576i and double HDMI pixels */ +diff --git a/drivers/gpu/drm/meson/meson_venc.h b/drivers/gpu/drm/meson/meson_venc.h +index 7c18a36a0dd0c..97eaebbfa0c4a 100644 +--- a/drivers/gpu/drm/meson/meson_venc.h ++++ b/drivers/gpu/drm/meson/meson_venc.h +@@ -58,7 +58,8 @@ struct meson_cvbs_enci_mode { + }; + + /* HDMI Clock parameters */ +-bool meson_venc_hdmi_supported_mode(const struct drm_display_mode *mode); ++enum drm_mode_status ++meson_venc_hdmi_supported_mode(const struct drm_display_mode *mode); + bool meson_venc_hdmi_supported_vic(int vic); + bool meson_venc_hdmi_venc_repeat(int vic); + diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/112_linux-4.17-amlogic-dmt-extended-1001-fix-32000khz.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/112_linux-4.17-amlogic-dmt-extended-1001-fix-32000khz.patch new file mode 100644 index 000000000..a359376a7 --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/112_linux-4.17-amlogic-dmt-extended-1001-fix-32000khz.patch @@ -0,0 +1,119 @@ +diff -ur a/drivers/gpu/drm/meson/meson_vclk.c b/drivers/gpu/drm/meson/meson_vclk.c +--- a/drivers/gpu/drm/meson/meson_vclk.c 2018-06-02 20:21:48.000000000 +0200 ++++ b/drivers/gpu/drm/meson/meson_vclk.c 2018-06-02 20:16:44.008061996 +0200 +@@ -428,9 +428,9 @@ + .vclk_div = 2, + }, + [MESON_VCLK_HDMI_32000] = { +- .pll_base_freq = 2560000, ++ .pll_base_freq = 5120000, + .pll_od1 = 4, +- .pll_od2 = 2, ++ .pll_od2 = 4, + .pll_od3 = 1, + .vid_pll_div = VID_PLL_DIV_5, + .vclk_div = 2, +@@ -520,27 +520,6 @@ + + if (meson_vpu_is_compatible(priv, "amlogic,meson-gxbb-vpu")) { + switch (base) { +- case 2560000: +- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x58000235); +- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x00000000); +- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x0d5c5091); +- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x801da72c); +- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x71486980); +- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x00000e55); +- +- /* Enable and unreset */ +- regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL, +- 0x7 << 28, 0x4 << 28); +- +- /* Poll for lock bit */ +- regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL, +- val, (val & HDMI_PLL_LOCK), 10, 0); +- +- /* div_frac */ +- regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2, +- 0xFFFF, 0x4555); +- break; +- + case 2700000: + regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x58000238); + regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x00000000); +@@ -722,6 +701,27 @@ + val, (val & HDMI_PLL_LOCK), 10, 0); + break; + ++ case 5120000: ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x5800026a); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x00000000); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x135c5091); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x801da72c); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x71486980); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x00000e55); ++ ++ /* unreset */ ++ regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL, ++ BIT(28), 0); ++ ++ /* Poll for lock bit */ ++ regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL, ++ val, (val & HDMI_PLL_LOCK), 10, 0); ++ ++ /* div_frac */ ++ regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2, ++ 0xFFFF, 0x4aab); ++ break; ++ + case 5940000: + regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x5800027b); + regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2, +@@ -760,15 +760,6 @@ + } else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu") || + meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu")) { + switch (base) { +- case 2560000: +- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x4000026a); +- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb2ab); +- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x860f30c4); +- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x0c8e0000); +- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x001fa729); +- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500); +- break; +- + case 2700000: + regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x40000270); + regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb200); +@@ -847,6 +838,15 @@ + regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x860f30c4); + regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x0c8e0000); + regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x001fa729); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500); ++ break; ++ ++ case 5120000: ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x400002d5); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb155); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x860f30c4); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x0c8e0000); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x001fa729); + regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500); + break; + +diff -ur a/drivers/gpu/drm/meson/meson_venc.c b/drivers/gpu/drm/meson/meson_venc.c +--- a/drivers/gpu/drm/meson/meson_venc.c 2018-06-02 16:39:27.777402009 +0200 ++++ b/drivers/gpu/drm/meson/meson_venc.c 2018-06-02 20:23:23.744646670 +0200 +@@ -713,6 +713,12 @@ + 968, 1056, 0, 600, 601, 605, 628, 0, + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, + }, ++ /* 1024x600@43Hz */ ++ { ++ { DRM_MODE("1024x600", DRM_MODE_TYPE_DRIVER, 32000, 1024, ++ 1064, 1112, 1152, 0, 600, 613, 616, 645, 0, ++ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, ++ }, + /* 1024x768@60Hz */ + { + { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 65000, 1024, diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/113_linux-4.17-amlogic-dmt-extended-1002-custom-mode.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/113_linux-4.17-amlogic-dmt-extended-1002-custom-mode.patch new file mode 100644 index 000000000..97136bd0c --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/113_linux-4.17-amlogic-dmt-extended-1002-custom-mode.patch @@ -0,0 +1,547 @@ +diff -ur a/drivers/gpu/drm/meson/meson_dw_hdmi.c b/drivers/gpu/drm/meson/meson_dw_hdmi.c +--- a/drivers/gpu/drm/meson/meson_dw_hdmi.c 2018-06-02 16:39:27.777402009 +0200 ++++ b/drivers/gpu/drm/meson/meson_dw_hdmi.c 2018-06-02 17:25:33.803332054 +0200 +@@ -588,22 +588,28 @@ + /* Finally filter by configurable vclk frequencies */ + switch (vclk_freq) { + case 25175: +- case 40000: ++ case 29750: + case 32000: + case 36000: + case 33750: + case 33900: ++ case 40000: + case 54000: + case 65000: + case 74250: ++ case 106500: + case 108000: + case 148500: + case 162000: ++ case 193250: + case 297000: + case 594000: + return MODE_OK; + } + ++ if (meson_vclk_supported(vclk_freq)) ++ return MODE_OK; ++ + return MODE_CLOCK_RANGE; + } + +diff -ur a/drivers/gpu/drm/meson/meson_vclk.c b/drivers/gpu/drm/meson/meson_vclk.c +--- a/drivers/gpu/drm/meson/meson_vclk.c 2018-06-02 20:16:44.008061996 +0200 ++++ b/drivers/gpu/drm/meson/meson_vclk.c 2018-06-04 03:26:22.092619417 +0200 +@@ -321,39 +321,49 @@ + } + + +-/* PLL O1 O2 O3 VP DV EN TX */ +-/* 4320 /4 /4 /1 /5 /1 => /2 /2 */ +-#define MESON_VCLK_HDMI_ENCI_54000 1 +-/* 4320 /4 /4 /1 /5 /1 => /1 /2 */ +-#define MESON_VCLK_HDMI_DDR_54000 2 +-/* 2970 /4 /1 /1 /5 /1 => /1 /2 */ +-#define MESON_VCLK_HDMI_DDR_148500 3 +-/* 4028 /4 /4 /1 /5 /2 => /1 /1 */ +-#define MESON_VCLK_HDMI_25175 4 +-/* 2560 /4 /2 /1 /5 /2 => /1 /1 */ +-#define MESON_VCLK_HDMI_32000 5 +-/* 2700 /4 /2 /1 /5 /2 => /1 /1 */ +-#define MESON_VCLK_HDMI_33750 6 +-/* 2712 /4 /2 /1 /5 /2 => /1 /1 */ +-#define MESON_VCLK_HDMI_33900 7 +-/* 2880 /4 /2 /1 /5 /2 => /1 /1 */ +-#define MESON_VCLK_HDMI_36000 8 +-/* 3200 /4 /2 /1 /5 /2 => /1 /1 */ +-#define MESON_VCLK_HDMI_40000 9 +-/* 5200 /4 /2 /1 /5 /2 => /1 /1 */ +-#define MESON_VCLK_HDMI_65000 10 +-/* 2970 /2 /2 /2 /5 /1 => /1 /1 */ +-#define MESON_VCLK_HDMI_74250 11 +-/* 4320 /4 /1 /1 /5 /2 => /1 /1 */ +-#define MESON_VCLK_HDMI_108000 12 +-/* 2970 /1 /2 /2 /5 /1 => /1 /1 */ +-#define MESON_VCLK_HDMI_148500 13 +-/* 3240 /2 /1 /1 /5 /2 => /1 /1 */ +-#define MESON_VCLK_HDMI_162000 14 +-/* 2970 /1 /1 /1 /5 /2 => /1 /1 */ +-#define MESON_VCLK_HDMI_297000 15 +-/* 5940 /1 /1 /2 /5 /1 => /1 /1 */ +-#define MESON_VCLK_HDMI_594000 16 ++enum { ++ /* PLL O1 O2 O3 VP DV EN TX */ ++ /* 4320 /4 /4 /1 /5 /1 => /2 /2 */ ++ MESON_VCLK_HDMI_ENCI_54000 = 1, ++ /* 4320 /4 /4 /1 /5 /1 => /1 /2 */ ++ MESON_VCLK_HDMI_DDR_54000, ++ /* 2970 /4 /1 /1 /5 /1 => /1 /2 */ ++ MESON_VCLK_HDMI_DDR_148500, ++ /* 4028 /4 /4 /1 /5 /2 => /1 /1 */ ++ MESON_VCLK_HDMI_25175, ++ /* 4760 /4 /4 /1 /5 /2 => /1 /1 */ ++ MESON_VCLK_HDMI_29750, ++ /* 2560 /4 /2 /1 /5 /2 => /1 /1 */ ++ MESON_VCLK_HDMI_32000, ++ /* 2700 /4 /2 /1 /5 /2 => /1 /1 */ ++ MESON_VCLK_HDMI_33750, ++ /* 2712 /4 /2 /1 /5 /2 => /1 /1 */ ++ MESON_VCLK_HDMI_33900, ++ /* 2880 /4 /2 /1 /5 /2 => /1 /1 */ ++ MESON_VCLK_HDMI_36000, ++ /* 3200 /4 /2 /1 /5 /2 => /1 /1 */ ++ MESON_VCLK_HDMI_40000, ++ /* 5200 /4 /2 /1 /5 /2 => /1 /1 */ ++ MESON_VCLK_HDMI_65000, ++ /* 2970 /2 /2 /2 /5 /1 => /1 /1 */ ++ MESON_VCLK_HDMI_74250, ++ /* 4260 /4 /1 /1 /5 /2 => /1 /1 */ ++ MESON_VCLK_HDMI_106500, ++ /* 4320 /4 /1 /1 /5 /2 => /1 /1 */ ++ MESON_VCLK_HDMI_108000, ++ /* 2970 /1 /2 /2 /5 /1 => /1 /1 */ ++ MESON_VCLK_HDMI_148500, ++ /* 3240 /2 /1 /1 /5 /2 => /1 /1 */ ++ MESON_VCLK_HDMI_162000, ++ /* 3865 /2 /1 /1 /5 /2 => /1 /1 */ ++ MESON_VCLK_HDMI_193250, ++ /* 2970 /1 /1 /1 /5 /2 => /1 /1 */ ++ MESON_VCLK_HDMI_297000, ++ /* 5940 /1 /1 /2 /5 /1 => /1 /1 */ ++ MESON_VCLK_HDMI_594000, ++ /* custom calculated mode */ ++ MESON_VCLK_HDMI_CUSTOM, ++}; + + struct meson_vclk_params { + unsigned int pll_base_freq; +@@ -427,6 +437,14 @@ + .vid_pll_div = VID_PLL_DIV_5, + .vclk_div = 2, + }, ++ [MESON_VCLK_HDMI_29750] = { ++ .pll_base_freq = 4760000, ++ .pll_od1 = 4, ++ .pll_od2 = 4, ++ .pll_od3 = 1, ++ .vid_pll_div = VID_PLL_DIV_5, ++ .vclk_div = 2, ++ }, + [MESON_VCLK_HDMI_32000] = { + .pll_base_freq = 5120000, + .pll_od1 = 4, +@@ -475,6 +493,14 @@ + .vid_pll_div = VID_PLL_DIV_5, + .vclk_div = 2, + }, ++ [MESON_VCLK_HDMI_106500] = { ++ .pll_base_freq = 4260000, ++ .pll_od1 = 4, ++ .pll_od2 = 1, ++ .pll_od3 = 1, ++ .vid_pll_div = VID_PLL_DIV_5, ++ .vclk_div = 2, ++ }, + [MESON_VCLK_HDMI_108000] = { + .pll_base_freq = 4320000, + .pll_od1 = 4, +@@ -491,6 +517,14 @@ + .vid_pll_div = VID_PLL_DIV_5, + .vclk_div = 2, + }, ++ [MESON_VCLK_HDMI_193250] = { ++ .pll_base_freq = 3865000, ++ .pll_od1 = 2, ++ .pll_od2 = 1, ++ .pll_od3 = 1, ++ .vid_pll_div = VID_PLL_DIV_5, ++ .vclk_div = 2, ++ }, + }; + + static inline unsigned int pll_od_to_reg(unsigned int od) +@@ -519,6 +553,18 @@ + unsigned int val; + + if (meson_vpu_is_compatible(priv, "amlogic,meson-gxbb-vpu")) { ++ unsigned int step = 48000; ++ unsigned int range = 0x1000; ++ unsigned int round = step / range / 2; ++ unsigned int frac = base % step; ++ unsigned int m = (base - frac) / step; ++ ++ frac = (frac + round) * range / step; ++ if (frac >= range) ++ frac = range-1; ++ ++ dev_info(priv->dev, "%s: base=%d, m=0x%.2x, frac=0x%.3x\n", __func__, base, m, frac); ++ + switch (base) { + case 2700000: + regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x58000238); +@@ -755,10 +801,49 @@ + /* Poll for lock bit */ + regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL, + val, (val & HDMI_PLL_LOCK), 10, 0); ++ ++ /* div_frac */ ++ regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2, ++ 0xFFFF, 0x4555); ++ break; ++ ++ default: ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x58000200 | m); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x00000000); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x135c5091); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x801da72c); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x71486980); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x00000e55); ++ ++ /* unreset */ ++ regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL, ++ BIT(28), 0); ++ ++ /* Poll for lock bit */ ++ regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL, ++ val, (val & HDMI_PLL_LOCK), 10, 0); ++ ++ /* div_frac */ ++ if (frac) ++ regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2, ++ 0xFFFF, 0x4000 | frac); + break; ++ + }; + } else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu") || + meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu")) { ++ unsigned int step = 24000; ++ unsigned int range = 0x400; ++ unsigned int round = step / range / 2; ++ unsigned int frac = base % step; ++ unsigned int m = (base - frac) / step; ++ ++ frac = (frac + round) * range / step; ++ if (frac >= range) ++ frac = range-1; ++ ++ pr_info("%s: base=%d, m=0x%.2x, frac=0x%.3x", __func__, base, m, frac); ++ + switch (base) { + case 2700000: + regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x40000270); +@@ -868,6 +953,14 @@ + regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500); + break; + ++ default: ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x40000200 | m); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb000 | frac); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x860f30c4); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x0c8e0000); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x001fa729); ++ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500); ++ break; + }; + + /* Reset PLL */ +@@ -906,6 +999,151 @@ + 3 << 19, pll_od_to_reg(od3) << 19); + } + ++unsigned int meson_vclk_freq_from_params(struct meson_vclk_params* vclk_params) ++{ ++ unsigned int vclk_freq = vclk_params->pll_base_freq / ++ vclk_params->pll_od1 / vclk_params->pll_od2 / ++ vclk_params->pll_od3 / vclk_params->vclk_div; ++ ++ switch (vclk_params->vid_pll_div) { ++ case VID_PLL_DIV_2: ++ vclk_freq /= 2; ++ break; ++ case VID_PLL_DIV_2p5: ++ vclk_freq *= 4; ++ vclk_freq /= 10; ++ break; ++ case VID_PLL_DIV_3: ++ vclk_freq /= 3; ++ break; ++ case VID_PLL_DIV_3p5: ++ vclk_freq *= 2; ++ vclk_freq /= 7; ++ break; ++ case VID_PLL_DIV_3p75: ++ vclk_freq *= 4; ++ vclk_freq /= 15; ++ break; ++ case VID_PLL_DIV_4: ++ vclk_freq /= 4; ++ break; ++ case VID_PLL_DIV_5: ++ vclk_freq /= 5; ++ break; ++ case VID_PLL_DIV_6: ++ vclk_freq /= 6; ++ break; ++ case VID_PLL_DIV_6p25: ++ vclk_freq *= 8; ++ vclk_freq /= 50; ++ break; ++ case VID_PLL_DIV_7: ++ vclk_freq /= 7; ++ break; ++ case VID_PLL_DIV_7p5: ++ vclk_freq *= 4; ++ vclk_freq /= 30; ++ break; ++ case VID_PLL_DIV_12: ++ vclk_freq /= 12; ++ break; ++ case VID_PLL_DIV_14: ++ vclk_freq /= 14; ++ break; ++ case VID_PLL_DIV_15: ++ vclk_freq /= 15; ++ break; ++ default: ++ return 0; ++ } ++ ++ return vclk_freq; ++} ++ ++static bool meson_get_vclk_params(unsigned int freq, ++ struct meson_vclk_params* vclk_params) ++{ ++ unsigned int vclk_freq = freq; ++ unsigned int base_freq, od1_od2, od3_vpll_vclk; ++ int p, jit; ++ bool found = false; ++ ++ if ((vclk_freq < 13500) || (vclk_freq > 594000)) ++ return false; ++ ++ if (vclk_freq % 25 > 12) ++ vclk_freq += 25; ++ vclk_freq -= vclk_freq % 25; ++ ++ for (p = 1; p < sizeof(params) / sizeof(struct meson_vclk_params); p++) { ++ if (params[p].vid_pll_div != VID_PLL_DIV_5) ++ continue; ++ ++ od1_od2 = params[p].pll_od1 * params[p].pll_od2; ++ od3_vpll_vclk = params[p].pll_od3 * 5 * params[p].vclk_div; ++ ++ if ((od3_vpll_vclk != 10) && (vclk_freq > 54000 + 175)) ++ continue; ++ ++ base_freq = vclk_freq * od1_od2 * od3_vpll_vclk; ++ ++ if ((base_freq < 2700000) || (base_freq > 5940000)) ++ continue; ++ ++ vclk_params->pll_base_freq = base_freq; ++ vclk_params->pll_od1 = params[p].pll_od1; ++ vclk_params->pll_od2 = params[p].pll_od2; ++ vclk_params->pll_od3 = params[p].pll_od3; ++ vclk_params->vid_pll_div = params[p].vid_pll_div; ++ vclk_params->vclk_div = params[p].vclk_div; ++ ++ found = true; ++ ++ if (params[p].pll_base_freq > vclk_params->pll_base_freq) ++ jit = params[p].pll_base_freq - vclk_params->pll_base_freq; ++ else ++ jit = vclk_params->pll_base_freq - params[p].pll_base_freq; ++ ++ if (jit < 175 * od1_od2 * od3_vpll_vclk) { ++ vclk_params->pll_base_freq = params[p].pll_base_freq; ++ vclk_freq = vclk_params->pll_base_freq / od1_od2 / od3_vpll_vclk; ++ } ++ ++ if (jit < 40000) ++ break; ++ } ++ ++ return found; ++} ++ ++static void meson_print_vclk_params(struct meson_drm *priv, unsigned int freq, ++ struct meson_vclk_params* vclk_params) ++{ ++ unsigned int vclk_freq = meson_vclk_freq_from_params(vclk_params); ++ ++ if (vclk_params->vid_pll_div != VID_PLL_DIV_5) ++ return; ++ ++ if (vclk_freq != freq) ++ dev_info(priv->dev, "adjusted %d -> %d", freq, vclk_freq); ++ ++ dev_info(priv->dev, "params %d / %d / %d / %d / %d / %d = %d\n", ++ vclk_params->pll_base_freq, ++ vclk_params->pll_od1, ++ vclk_params->pll_od2, ++ vclk_params->pll_od3, ++ 5, vclk_params->vclk_div, ++ vclk_freq); ++} ++ ++bool meson_vclk_supported(unsigned int vclk_freq) ++{ ++ struct meson_vclk_params custom_params; ++ ++ return (meson_get_vclk_params(vclk_freq, &custom_params)); ++} ++EXPORT_SYMBOL_GPL(meson_vclk_supported); ++ + void meson_vclk_setup(struct meson_drm *priv, unsigned int target, + unsigned int vclk_freq, unsigned int venc_freq, + unsigned int dac_freq, bool hdmi_use_enci) +@@ -913,6 +1151,8 @@ + unsigned int freq; + unsigned int hdmi_tx_div; + unsigned int venc_div; ++ struct meson_vclk_params custom_params; ++ struct meson_vclk_params* vclk_params; + + if (target == MESON_VCLK_TARGET_CVBS) { + meson_venci_cvbs_clock_config(priv); +@@ -945,6 +1185,9 @@ + case 25175: + freq = MESON_VCLK_HDMI_25175; + break; ++ case 29750: ++ freq = MESON_VCLK_HDMI_29750; ++ break; + case 32000: + freq = MESON_VCLK_HDMI_32000; + break; +@@ -966,6 +1209,9 @@ + case 74250: + freq = MESON_VCLK_HDMI_74250; + break; ++ case 106500: ++ freq = MESON_VCLK_HDMI_106500; ++ break; + case 108000: + freq = MESON_VCLK_HDMI_108000; + break; +@@ -978,6 +1224,9 @@ + case 162000: + freq = MESON_VCLK_HDMI_162000; + break; ++ case 193250: ++ freq = MESON_VCLK_HDMI_193250; ++ break; + case 297000: + freq = MESON_VCLK_HDMI_297000; + break; +@@ -985,9 +1234,8 @@ + freq = MESON_VCLK_HDMI_594000; + break; + default: +- pr_err("Fatal Error, invalid HDMI vclk freq %d\n", +- vclk_freq); +- return; ++ freq = MESON_VCLK_HDMI_CUSTOM; ++ break; + } + + /* Set HDMI-TX sys clock */ +@@ -998,20 +1246,35 @@ + regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL, + CTS_HDMI_SYS_EN, CTS_HDMI_SYS_EN); + ++ vclk_params = NULL; ++ ++ if (freq != MESON_VCLK_HDMI_CUSTOM) ++ vclk_params = ¶ms[freq]; ++ else if (meson_get_vclk_params(vclk_freq, &custom_params)) ++ vclk_params = &custom_params; ++ ++ if (!vclk_params) { ++ pr_err("Fatal Error, invalid HDMI vclk freq %d\n", ++ vclk_freq); ++ return; ++ } ++ ++ meson_print_vclk_params(priv, vclk_freq, vclk_params); ++ + /* Set HDMI PLL rate */ +- meson_hdmi_pll_set(priv, params[freq].pll_base_freq, +- params[freq].pll_od1, +- params[freq].pll_od2, +- params[freq].pll_od3); ++ meson_hdmi_pll_set(priv, vclk_params->pll_base_freq, ++ vclk_params->pll_od1, ++ vclk_params->pll_od2, ++ vclk_params->pll_od3); + + /* Setup vid_pll divider */ +- meson_vid_pll_set(priv, params[freq].vid_pll_div); ++ meson_vid_pll_set(priv, vclk_params->vid_pll_div); + + /* Set VCLK div */ + regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL, + VCLK_SEL_MASK, 0); + regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV, +- VCLK_DIV_MASK, params[freq].vclk_div - 1); ++ VCLK_DIV_MASK, vclk_params->vclk_div - 1); + + /* Set HDMI-TX source */ + switch (hdmi_tx_div) { +diff -ur a/drivers/gpu/drm/meson/meson_vclk.h b/drivers/gpu/drm/meson/meson_vclk.h +--- a/drivers/gpu/drm/meson/meson_vclk.h 2018-05-26 22:29:37.112948771 +0200 ++++ b/drivers/gpu/drm/meson/meson_vclk.h 2018-05-31 05:15:53.342134304 +0200 +@@ -29,6 +29,8 @@ + /* 27MHz is the CVBS Pixel Clock */ + #define MESON_VCLK_CVBS 27000 + ++bool meson_vclk_supported(unsigned int vclk_freq); ++ + void meson_vclk_setup(struct meson_drm *priv, unsigned int target, + unsigned int vclk_freq, unsigned int venc_freq, + unsigned int dac_freq, bool hdmi_use_enci); +diff -ur a/drivers/gpu/drm/meson/meson_venc.c b/drivers/gpu/drm/meson/meson_venc.c +--- a/drivers/gpu/drm/meson/meson_venc.c 2018-06-02 20:23:23.744646670 +0200 ++++ b/drivers/gpu/drm/meson/meson_venc.c 2018-06-02 17:25:33.807332121 +0200 +@@ -707,6 +707,12 @@ + 752, 800, 0, 480, 490, 492, 525, 0, + DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, + }, ++ /* 800x480@60Hz */ ++ { ++ { DRM_MODE("800x480", DRM_MODE_TYPE_DRIVER, 29750, 800, 824, ++ 896, 992, 0, 480, 483, 490, 500, 0, ++ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, ++ }, + /* 800x600@60Hz */ + { + { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 40000, 800, 840, +@@ -737,6 +743,12 @@ + 1328, 1440, 1688, 0, 1024, 1025, 1028, 1066, 0, + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, + }, ++ /* 1440x900@60Hz */ ++ { ++ { DRM_MODE("1440x900", DRM_MODE_TYPE_DRIVER, 106500, 1440, ++ 1520, 1672, 1904, 0, 900, 903, 909, 934, 0, ++ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, ++ }, + /* 1600x1200@60Hz */ + { + { DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 162000, 1600, +@@ -749,6 +761,12 @@ + 2008, 2052, 2200, 0, 1080, 1084, 1089, 1125, 0, + DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, + }, ++ /* 1920x1200@60Hz */ ++ { ++ { DRM_MODE("1920x1200", DRM_MODE_TYPE_DRIVER, 193250, 1920, ++ 2056, 2256, 2592, 0, 1200, 1203, 1209, 1245, 0, ++ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, ++ }, + { }, /* sentinel */ + }; + diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/114_linux-4.17-amlogic-dmt-extended-1003-calculate-clock-dividers.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/114_linux-4.17-amlogic-dmt-extended-1003-calculate-clock-dividers.patch new file mode 100644 index 000000000..5dfcace64 --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/114_linux-4.17-amlogic-dmt-extended-1003-calculate-clock-dividers.patch @@ -0,0 +1,115 @@ +diff -u a/drivers/gpu/drm/meson/meson_vclk.c b/drivers/gpu/drm/meson/meson_vclk.c +--- a/drivers/gpu/drm/meson/meson_vclk.c 2018-06-10 06:10:59.071504595 +0200 ++++ b/drivers/gpu/drm/meson/meson_vclk.c 2018-06-10 05:33:51.347202114 +0200 +@@ -842,7 +842,7 @@ + if (frac >= range) + frac = range-1; + +- pr_info("%s: base=%d, m=0x%.2x, frac=0x%.3x", __func__, base, m, frac); ++ dev_info(priv->dev, "%s: base=%d, m=0x%.2x, frac=0x%.3x\n", __func__, base, m, frac); + + switch (base) { + case 2700000: +@@ -1065,25 +1065,36 @@ + { + unsigned int vclk_freq = freq; + unsigned int base_freq, od1_od2, od3_vpll_vclk; +- int p, jit; ++ int od1, od2, od3, p, jit; + bool found = false; + +- if ((vclk_freq < 13500) || (vclk_freq > 594000)) ++ if ((vclk_freq < 12000) || (vclk_freq > 594000)) + return false; + + if (vclk_freq % 25 > 12) + vclk_freq += 25; + vclk_freq -= vclk_freq % 25; + +- for (p = 1; p < sizeof(params) / sizeof(struct meson_vclk_params); p++) { +- if (params[p].vid_pll_div != VID_PLL_DIV_5) ++ for (p = 0; p < 6; p++) { ++ od1 = (1 << p); ++ od2 = 1; ++ od3 = 1; ++ ++ if ((vclk_freq > 18550) && (od1 > 16)) + continue; + +- od1_od2 = params[p].pll_od1 * params[p].pll_od2; +- od3_vpll_vclk = params[p].pll_od3 * 5 * params[p].vclk_div; ++ if (od1 > 16) { ++ od3 = od1 / 16; ++ od1 = 16; ++ } + +- if ((od3_vpll_vclk != 10) && (vclk_freq > 54000 + 175)) +- continue; ++ if (od1 > 4) { ++ od2 = od1 / 4; ++ od1 = 4; ++ } ++ ++ od1_od2 = od1 * od2; ++ od3_vpll_vclk = od3 * 5 * 2; + + base_freq = vclk_freq * od1_od2 * od3_vpll_vclk; + +@@ -1091,21 +1102,32 @@ + continue; + + vclk_params->pll_base_freq = base_freq; +- vclk_params->pll_od1 = params[p].pll_od1; +- vclk_params->pll_od2 = params[p].pll_od2; +- vclk_params->pll_od3 = params[p].pll_od3; +- vclk_params->vid_pll_div = params[p].vid_pll_div; +- vclk_params->vclk_div = params[p].vclk_div; ++ vclk_params->pll_od1 = od1; ++ vclk_params->pll_od2 = od2; ++ vclk_params->pll_od3 = od3; ++ vclk_params->vid_pll_div = VID_PLL_DIV_5; ++ vclk_params->vclk_div = 2; + + found = true; + +- if (params[p].pll_base_freq > vclk_params->pll_base_freq) +- jit = params[p].pll_base_freq - vclk_params->pll_base_freq; ++ jit = od1_od2 * od3_vpll_vclk * 125; ++ if (p < 3) ++ jit <<= (3-p); ++ ++ if ((base_freq % 24000) < (base_freq % jit)) ++ jit = 24000; ++ ++ if ((base_freq % jit) > (jit / 2)) ++ base_freq = base_freq+jit; ++ base_freq -= base_freq % jit; ++ ++ if (base_freq > vclk_params->pll_base_freq) ++ jit = base_freq - vclk_params->pll_base_freq; + else +- jit = vclk_params->pll_base_freq - params[p].pll_base_freq; ++ jit = vclk_params->pll_base_freq - base_freq; + + if (jit < 175 * od1_od2 * od3_vpll_vclk) { +- vclk_params->pll_base_freq = params[p].pll_base_freq; ++ vclk_params->pll_base_freq = base_freq; + vclk_freq = vclk_params->pll_base_freq / od1_od2 / od3_vpll_vclk; + } + +diff -u a/drivers/gpu/drm/meson/meson_venc.c b/drivers/gpu/drm/meson/meson_venc.c +--- a/drivers/gpu/drm/meson/meson_venc.c 2018-06-10 06:10:59.071504595 +0200 ++++ b/drivers/gpu/drm/meson/meson_venc.c 2018-06-10 05:26:59.995203463 +0200 +@@ -816,10 +816,10 @@ + DRM_MODE_FLAG_PVSYNC | DRM_MODE_FLAG_NVSYNC)) + return MODE_BAD; + +- if (mode->hdisplay < 640 || mode->hdisplay > 1920) ++ if (mode->hdisplay < 416 || mode->hdisplay > 1920) + return MODE_BAD_HVALUE; + +- if (mode->vdisplay < 480 || mode->vdisplay > 1200) ++ if (mode->vdisplay < 360 || mode->vdisplay > 1200) + return MODE_BAD_VVALUE; + + return MODE_OK; diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/115_linux-4.14.y-input_touchscreen-vu5-vu7plus.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/115_linux-4.14.y-input_touchscreen-vu5-vu7plus.patch new file mode 100644 index 000000000..e1cb84e1b --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/115_linux-4.14.y-input_touchscreen-vu5-vu7plus.patch @@ -0,0 +1,1235 @@ +diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c +index 672b0be41..f46efab94 100644 +--- a/drivers/hid/hid-core.c ++++ b/drivers/hid/hid-core.c +@@ -2776,6 +2776,8 @@ static const struct hid_device_id hid_ignore_list[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_DPAD) }, + #endif + { HID_USB_DEVICE(USB_VENDOR_ID_YEALINK, USB_DEVICE_ID_YEALINK_P1K_P4K_B2K) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_ODROID, USB_DEVICE_ID_VU5) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_ODROID, USB_DEVICE_ID_VU7PLUS) }, + { } + }; + +diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h +index ff539c0b4..b09d5ea03 100644 +--- a/drivers/hid/hid-ids.h ++++ b/drivers/hid/hid-ids.h +@@ -1164,4 +1164,10 @@ + #define USB_VENDOR_ID_UGTIZER 0x2179 + #define USB_DEVICE_ID_UGTIZER_TABLET_GP0610 0x0053 + ++#define USB_DEVICE_ID_DWAV_MULTITOUCH 0x0005 ++ ++#define USB_VENDOR_ID_ODROID 0x16b4 ++#define USB_DEVICE_ID_VU5 0x0704 ++#define USB_DEVICE_ID_VU7PLUS 0x0705 ++ + #endif +diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig +index 64b30fe27..05e834eed 100644 +--- a/drivers/input/touchscreen/Kconfig ++++ b/drivers/input/touchscreen/Kconfig +@@ -1246,4 +1246,23 @@ config TOUCHSCREEN_ROHM_BU21023 + To compile this driver as a module, choose M here: the + module will be called bu21023_ts. + ++config TOUCHSCREEN_DWAV_USB_MT ++ tristate "D-WAV Scientific USB MultiTouch" ++ depends on USB_ARCH_HAS_HCD ++ select USB ++ help ++ Say Y here if you have a D-WAV Scientific USB(HID) based MultiTouch ++ controller. ++ ++ If unsure, say N. ++ ++ To compile this driver as a module, choose M here: the ++ module will be called dwav-usb-mt. ++ ++config TOUCHSCREEN_SX865X ++ tristate "Semtech multitouch resistive touchscreen" ++ depends on I2C ++ help ++ This enables support for Semtech multitouch resistive touchscreen. ++ + endif +diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile +index 850c15625..bc3f0e1d5 100644 +--- a/drivers/input/touchscreen/Makefile ++++ b/drivers/input/touchscreen/Makefile +@@ -104,3 +104,5 @@ obj-$(CONFIG_TOUCHSCREEN_ZET6223) += zet6223.o + obj-$(CONFIG_TOUCHSCREEN_ZFORCE) += zforce_ts.o + obj-$(CONFIG_TOUCHSCREEN_COLIBRI_VF50) += colibri-vf50-ts.o + obj-$(CONFIG_TOUCHSCREEN_ROHM_BU21023) += rohm_bu21023.o ++obj-$(CONFIG_TOUCHSCREEN_DWAV_USB_MT) += dwav-usb-mt.o ++obj-$(CONFIG_TOUCHSCREEN_SX865X) += sx865x.o +diff -urN a/drivers/input/touchscreen/dwav-usb-mt.c b/drivers/input/touchscreen/dwav-usb-mt.c +--- a/drivers/input/touchscreen/dwav-usb-mt.c 1970-01-01 01:00:00.000000000 +0100 ++++ b/drivers/input/touchscreen/dwav-usb-mt.c 2018-05-06 10:03:40.485939294 +0200 +@@ -0,0 +1,577 @@ ++/*------------------------------------------------------------------------- ++ ++ D-WAV Scientific USB(HID) MultiTouch Screen Driver(Based on usbtouchscreen.c) ++ Hardkernel : 2015/09/17 ++ ++-------------------------------------------------------------------------*/ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++/*-------------------------------------------------------------------------*/ ++#define USB_VENDOR_ID_DWAV 0x0eef /* 800 x 480, 7" DWAV touch */ ++#define USB_DEVICE_ID_VU7 0x0005 ++ ++#define USB_VENDOR_ID_ODROID 0x16b4 ++#define USB_DEVICE_ID_VU5 0x0704 ++#define USB_DEVICE_ID_VU7PLUS 0x0705 ++ ++enum { ++ ODROID_VU7 = 0, /* 800 x 480, 7" Touch */ ++ ODROID_VU5, /* 800 x 480, 5" Touch */ ++ ODROID_VU7PLUS, /* 1024 x 600, 7" Touch */ ++}; ++ ++/*-------------------------------------------------------------------------*/ ++struct usbtouch_device_info { ++ char name[64]; ++ int max_x; ++ int max_y; ++ int max_press; ++ int max_finger; ++}; ++ ++/*-------------------------------------------------------------------------*/ ++const struct usbtouch_device_info DEV_INFO[] = { ++ [ODROID_VU7] = { ++ .name = "ODROID VU7 MultiTouch(800x480)", ++ .max_x = 800, ++ .max_y = 480, ++ .max_press = 255, ++ .max_finger = 5, ++ }, ++ [ODROID_VU5] = { ++ .name = "ODROID VU5 MultiTouch(800x480)", ++ .max_x = 800, ++ .max_y = 480, ++ .max_press = 255, ++ .max_finger = 5, ++ }, ++ [ODROID_VU7PLUS] = { ++ .name = "ODROID VU7 Plus MultiTouch(1024x600)", ++ .max_x = 1024, ++ .max_y = 600, ++ .max_press = 255, ++ .max_finger = 5, ++ }, ++}; ++ ++/*-------------------------------------------------------------------------*/ ++static const struct usb_device_id dwav_usb_mt_devices[] = { ++ {USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_VU7), ++ .driver_info = ODROID_VU7}, ++ {USB_DEVICE(USB_VENDOR_ID_ODROID, USB_DEVICE_ID_VU5), ++ .driver_info = ODROID_VU5}, ++ {USB_DEVICE(USB_VENDOR_ID_ODROID, USB_DEVICE_ID_VU7PLUS), ++ .driver_info = ODROID_VU7PLUS}, ++ {} ++}; ++ ++/*-------------------------------------------------------------------------*/ ++struct dwav_raw { /* Total 25 bytes */ ++ unsigned char header; /* frame header 0xAA*/ ++ unsigned char press; ++ /* Touch flag (1:valid touch data, 0:touch finished) */ ++ unsigned short x1; /* 1st x */ ++ unsigned short y1; /* 1st y */ ++ unsigned char end; ++ /* 1st touch finish flags 0xBB, RPI only uses the first 7 bytes */ ++ unsigned char ids; /* touch ID(bit field) */ ++ unsigned short y2; ++ unsigned short x2; ++ unsigned short y3; ++ unsigned short x3; ++ unsigned short y4; ++ unsigned short x4; ++ unsigned short y5; ++ unsigned short x5; ++ unsigned char tail; /* frame end 0xCC */ ++}; ++ ++/*------------------------------------------------------------------------- ++ Touch Event type define ++-------------------------------------------------------------------------*/ ++#define TS_EVENT_UNKNOWN 0x00 ++#define TS_EVENT_PRESS 0x01 ++#define TS_EVENT_RELEASE 0x02 ++ ++struct finger_t { ++ unsigned int status; /* ts event type */ ++ unsigned int x; /* ts data x */ ++ unsigned int y; /* ts data y */ ++} __packed; ++ ++struct dwav_usb_mt { ++ char name[128], phys[64]; ++ ++ int dev_id; ++ /* for URB Data DMA */ ++ dma_addr_t data_dma; ++ unsigned char *data; ++ int data_size; ++ ++ struct urb *irq; ++ struct usb_interface *interface; ++ struct input_dev *input; ++ ++ struct finger_t *finger; ++}; ++ ++/*-------------------------------------------------------------------------*/ ++static void dwav_usb_mt_report(struct dwav_usb_mt *dwav_usb_mt) ++{ ++ int id, max_x, max_y, max_press, max_finger; ++ ++ max_x = DEV_INFO[dwav_usb_mt->dev_id].max_x; ++ max_y = DEV_INFO[dwav_usb_mt->dev_id].max_y; ++ max_press = DEV_INFO[dwav_usb_mt->dev_id].max_press; ++ max_finger = DEV_INFO[dwav_usb_mt->dev_id].max_finger; ++ ++ for (id = 0; id < max_finger; id++) { ++ ++ if (dwav_usb_mt->finger[id].status == TS_EVENT_UNKNOWN) ++ continue; ++ ++ if (dwav_usb_mt->finger[id].x >= max_x || ++ dwav_usb_mt->finger[id].y >= max_y) ++ continue; ++ ++ input_mt_slot(dwav_usb_mt->input, id); ++ ++ if (dwav_usb_mt->finger[id].status != TS_EVENT_RELEASE) { ++ input_mt_report_slot_state(dwav_usb_mt->input, ++ MT_TOOL_FINGER, true); ++ input_report_abs(dwav_usb_mt->input, ++ ABS_MT_POSITION_X, ++ dwav_usb_mt->finger[id].x); ++ input_report_abs(dwav_usb_mt->input, ++ ABS_MT_POSITION_Y, ++ dwav_usb_mt->finger[id].y); ++ input_report_abs(dwav_usb_mt->input, ++ ABS_MT_PRESSURE, ++ max_press); ++ } else { ++ input_mt_report_slot_state(dwav_usb_mt->input, ++ MT_TOOL_FINGER, false); ++ dwav_usb_mt->finger[id].status = TS_EVENT_UNKNOWN; ++ } ++ input_mt_report_pointer_emulation(dwav_usb_mt->input, true); ++ input_sync(dwav_usb_mt->input); ++ } ++} ++ ++/*-------------------------------------------------------------------------*/ ++static void dwav_usb_mt_process(struct dwav_usb_mt *dwav_usb_mt, ++ unsigned char *pkt, int len) ++{ ++ struct dwav_raw *dwav_raw = (struct dwav_raw *)pkt; ++ unsigned char bit_mask, cnt; ++ ++ for (cnt = 0, bit_mask = 0x01; ++ cnt < DEV_INFO[dwav_usb_mt->dev_id].max_finger; ++ cnt++, bit_mask <<= 1) { ++ if ((dwav_raw->ids & bit_mask) && dwav_raw->press) { ++ dwav_usb_mt->finger[cnt].status = TS_EVENT_PRESS; ++ switch (cnt) { ++ case 0: ++ dwav_usb_mt->finger[cnt].x ++ = cpu_to_be16(dwav_raw->x1); ++ dwav_usb_mt->finger[cnt].y ++ = cpu_to_be16(dwav_raw->y1); ++ break; ++ case 1: ++ dwav_usb_mt->finger[cnt].x ++ = cpu_to_be16(dwav_raw->x2); ++ dwav_usb_mt->finger[cnt].y ++ = cpu_to_be16(dwav_raw->y2); ++ break; ++ case 2: ++ dwav_usb_mt->finger[cnt].x ++ = cpu_to_be16(dwav_raw->x3); ++ dwav_usb_mt->finger[cnt].y ++ = cpu_to_be16(dwav_raw->y3); ++ break; ++ case 3: ++ dwav_usb_mt->finger[cnt].x ++ = cpu_to_be16(dwav_raw->x4); ++ dwav_usb_mt->finger[cnt].y ++ = cpu_to_be16(dwav_raw->y4); ++ break; ++ case 4: ++ dwav_usb_mt->finger[cnt].x ++ = cpu_to_be16(dwav_raw->x5); ++ dwav_usb_mt->finger[cnt].y ++ = cpu_to_be16(dwav_raw->y5); ++ break; ++ default: ++ break; ++ } ++ } else { ++ if (dwav_usb_mt->finger[cnt].status == TS_EVENT_PRESS) ++ dwav_usb_mt->finger[cnt].status ++ = TS_EVENT_RELEASE; ++ else ++ dwav_usb_mt->finger[cnt].status ++ = TS_EVENT_UNKNOWN; ++ } ++ } ++ dwav_usb_mt_report(dwav_usb_mt); ++} ++ ++/*-------------------------------------------------------------------------*/ ++static void dwav_usb_mt_irq(struct urb *urb) ++{ ++ struct dwav_usb_mt *dwav_usb_mt = urb->context; ++ struct device *dev = &dwav_usb_mt->interface->dev; ++ int retval; ++ ++ switch (urb->status) { ++ case 0: ++ /* success */ ++ break; ++ case -ETIME: ++ /* this urb is timing out */ ++ dev_dbg(dev, "%s - urb timed out - was the device unplugged?\n", ++ __func__); ++ return; ++ case -ECONNRESET: ++ case -ENOENT: ++ case -ESHUTDOWN: ++ case -EPIPE: ++ /* this urb is terminated, clean up */ ++ dev_dbg(dev, "%s - urb shutting down with status: %d\n", ++ __func__, urb->status); ++ return; ++ default: ++ dev_dbg(dev, "%s - nonzero urb status received: %d\n", ++ __func__, urb->status); ++ goto exit; ++ } ++ ++ dwav_usb_mt_process(dwav_usb_mt, dwav_usb_mt->data, urb->actual_length); ++ ++exit: ++ usb_mark_last_busy(interface_to_usbdev(dwav_usb_mt->interface)); ++ retval = usb_submit_urb(urb, GFP_ATOMIC); ++ if (retval) { ++ dev_err(dev, "%s - usb_submit_urb failed with result: %d\n", ++ __func__, retval); ++ } ++} ++ ++/*-------------------------------------------------------------------------*/ ++static int dwav_usb_mt_open(struct input_dev *input) ++{ ++ struct dwav_usb_mt *dwav_usb_mt = input_get_drvdata(input); ++ int r; ++ ++ dwav_usb_mt->irq->dev = interface_to_usbdev(dwav_usb_mt->interface); ++ ++ r = usb_autopm_get_interface(dwav_usb_mt->interface) ? -EIO : 0; ++ if (r < 0) ++ goto out; ++ ++ if (usb_submit_urb(dwav_usb_mt->irq, GFP_KERNEL)) { ++ r = -EIO; ++ goto out_put; ++ } ++ ++ dwav_usb_mt->interface->needs_remote_wakeup = 1; ++out_put: ++ usb_autopm_put_interface(dwav_usb_mt->interface); ++out: ++ return r; ++} ++ ++/*-------------------------------------------------------------------------*/ ++static void dwav_usb_mt_close(struct input_dev *input) ++{ ++ struct dwav_usb_mt *dwav_usb_mt = input_get_drvdata(input); ++ int r; ++ ++ usb_kill_urb(dwav_usb_mt->irq); ++ ++ r = usb_autopm_get_interface(dwav_usb_mt->interface); ++ ++ dwav_usb_mt->interface->needs_remote_wakeup = 0; ++ if (!r) ++ usb_autopm_put_interface(dwav_usb_mt->interface); ++} ++ ++/*-------------------------------------------------------------------------*/ ++static int dwav_usb_mt_suspend(struct usb_interface *intf, pm_message_t message) ++{ ++ struct dwav_usb_mt *dwav_usb_mt = usb_get_intfdata(intf); ++ ++ usb_kill_urb(dwav_usb_mt->irq); ++ ++ return 0; ++} ++ ++/*-------------------------------------------------------------------------*/ ++static int dwav_usb_mt_resume(struct usb_interface *intf) ++{ ++ struct dwav_usb_mt *dwav_usb_mt = usb_get_intfdata(intf); ++ struct input_dev *input = dwav_usb_mt->input; ++ int result = 0; ++ ++ mutex_lock(&input->mutex); ++ if (input->users) ++ result = usb_submit_urb(dwav_usb_mt->irq, GFP_NOIO); ++ mutex_unlock(&input->mutex); ++ ++ return result; ++} ++ ++/*-------------------------------------------------------------------------*/ ++static int dwav_usb_mt_reset_resume(struct usb_interface *intf) ++{ ++ struct dwav_usb_mt *dwav_usb_mt = usb_get_intfdata(intf); ++ struct input_dev *input = dwav_usb_mt->input; ++ int err = 0; ++ ++ /* restart IO if needed */ ++ mutex_lock(&input->mutex); ++ if (input->users) ++ err = usb_submit_urb(dwav_usb_mt->irq, GFP_NOIO); ++ mutex_unlock(&input->mutex); ++ ++ return err; ++} ++ ++/*-------------------------------------------------------------------------*/ ++static void dwav_usb_mt_free_buffers(struct usb_device *udev, ++ struct dwav_usb_mt *dwav_usb_mt) ++{ ++ usb_free_coherent(udev, dwav_usb_mt->data_size, ++ dwav_usb_mt->data, dwav_usb_mt->data_dma); ++} ++ ++/*-------------------------------------------------------------------------*/ ++static struct usb_endpoint_descriptor *dwav_usb_mt_get_input_endpoint( ++ struct usb_host_interface *interface) ++{ ++ int i; ++ ++ for (i = 0; i < interface->desc.bNumEndpoints; i++) { ++ if (usb_endpoint_dir_in(&interface->endpoint[i].desc)) ++ return &interface->endpoint[i].desc; ++ } ++ ++ return NULL; ++} ++ ++/*-------------------------------------------------------------------------*/ ++static int dwav_usb_mt_init(struct dwav_usb_mt *dwav_usb_mt, void *dev) ++{ ++ int err; ++ struct input_dev *input_dev = (struct input_dev *)dev; ++ ++ input_dev->name = dwav_usb_mt->name; ++ input_dev->phys = dwav_usb_mt->phys; ++ ++ input_set_drvdata(input_dev, dwav_usb_mt); ++ ++ input_dev->open = dwav_usb_mt_open; ++ input_dev->close = dwav_usb_mt_close; ++ ++ input_dev->id.bustype = BUS_USB; ++ ++ /* single touch */ ++ input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); ++ input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); ++ ++ input_set_abs_params(input_dev, ABS_X, 0, ++ DEV_INFO[dwav_usb_mt->dev_id].max_x, 0, 0); ++ input_set_abs_params(input_dev, ABS_Y, 0, ++ DEV_INFO[dwav_usb_mt->dev_id].max_y, 0, 0); ++ ++ /* multi touch */ ++ input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0, ++ DEV_INFO[dwav_usb_mt->dev_id].max_x, 0, 0); ++ input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, ++ DEV_INFO[dwav_usb_mt->dev_id].max_y, 0, 0); ++ input_mt_init_slots(input_dev, ++ DEV_INFO[dwav_usb_mt->dev_id].max_finger, 0); ++ ++ err = input_register_device(input_dev); ++ if (err) { ++ pr_err("%s - input_register_device failed, err: %d\n", ++ __func__, err); ++ return err; ++ } ++ ++ dwav_usb_mt->input = input_dev; ++ ++ return 0; ++} ++ ++/*-------------------------------------------------------------------------*/ ++static int dwav_usb_mt_probe(struct usb_interface *intf, ++ const struct usb_device_id *id) ++{ ++ struct dwav_usb_mt *dwav_usb_mt = NULL; ++ struct input_dev *input_dev = NULL; ++ struct usb_endpoint_descriptor *endpoint; ++ struct usb_device *udev = interface_to_usbdev(intf); ++ ++ int err = 0; ++ ++ endpoint = dwav_usb_mt_get_input_endpoint(intf->cur_altsetting); ++ if (!endpoint) ++ return -ENXIO; ++ ++ dwav_usb_mt = kzalloc(sizeof(struct dwav_usb_mt), GFP_KERNEL); ++ if (!dwav_usb_mt) ++ return -ENOMEM; ++ ++ dwav_usb_mt->dev_id = id->driver_info; ++ ++ dwav_usb_mt->finger = kzalloc(sizeof(struct finger_t) * ++ DEV_INFO[dwav_usb_mt->dev_id].max_finger, ++ GFP_KERNEL); ++ ++ if (!dwav_usb_mt->finger) ++ goto err_free_mem; ++ ++ input_dev = input_allocate_device(); ++ if (!input_dev) ++ goto err_free_mem; ++ ++ dwav_usb_mt->data_size = sizeof(struct dwav_raw); ++ dwav_usb_mt->data = usb_alloc_coherent(udev, dwav_usb_mt->data_size, ++ GFP_KERNEL, &dwav_usb_mt->data_dma); ++ if (!dwav_usb_mt->data) ++ goto err_free_mem; ++ ++ dwav_usb_mt->irq = usb_alloc_urb(0, GFP_KERNEL); ++ if (!dwav_usb_mt->irq) { ++ dev_dbg(&intf->dev, ++ "%s - usb_alloc_urb failed: usbtouch->irq\n", ++ __func__); ++ goto err_free_buffers; ++ } ++ ++ if (usb_endpoint_type(endpoint) == USB_ENDPOINT_XFER_INT) { ++ usb_fill_int_urb(dwav_usb_mt->irq, udev, ++ usb_rcvintpipe(udev, endpoint->bEndpointAddress), ++ dwav_usb_mt->data, dwav_usb_mt->data_size, ++ dwav_usb_mt_irq, dwav_usb_mt, endpoint->bInterval); ++ } else { ++ usb_fill_bulk_urb(dwav_usb_mt->irq, udev, ++ usb_rcvbulkpipe(udev, endpoint->bEndpointAddress), ++ dwav_usb_mt->data, dwav_usb_mt->data_size, ++ dwav_usb_mt_irq, dwav_usb_mt); ++ } ++ ++ dwav_usb_mt->irq->dev = udev; ++ dwav_usb_mt->irq->transfer_dma = dwav_usb_mt->data_dma; ++ dwav_usb_mt->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; ++ ++ dwav_usb_mt->interface = intf; ++ ++ if (udev->manufacturer) ++ strlcpy(dwav_usb_mt->name, ++ udev->manufacturer, sizeof(dwav_usb_mt->name)); ++ ++ if (udev->product) { ++ if (udev->manufacturer) ++ strlcat(dwav_usb_mt->name, ++ " ", sizeof(dwav_usb_mt->name)); ++ ++ strlcat(dwav_usb_mt->name, ++ udev->product, sizeof(dwav_usb_mt->name)); ++ } ++ ++ if (!strlen(dwav_usb_mt->name)) { ++ snprintf(dwav_usb_mt->name, sizeof(dwav_usb_mt->name), ++ "D-WAV Scientific MultiTouch %04x:%04x", ++ le16_to_cpu(udev->descriptor.idVendor), ++ le16_to_cpu(udev->descriptor.idProduct)); ++ } ++ ++ usb_make_path(udev, dwav_usb_mt->phys, sizeof(dwav_usb_mt->phys)); ++ strlcat(dwav_usb_mt->phys, "/input0", sizeof(dwav_usb_mt->phys)); ++ ++ usb_to_input_id(udev, &input_dev->id); ++ ++ input_dev->dev.parent = &intf->dev; ++ ++ err = dwav_usb_mt_init(dwav_usb_mt, (void *)input_dev); ++ if (err) ++ goto err_free_urb; ++ ++ usb_set_intfdata(intf, dwav_usb_mt); ++ ++ dev_info(&intf->dev, "%s\n", DEV_INFO[dwav_usb_mt->dev_id].name); ++ ++ return 0; ++ ++err_free_urb: ++ usb_free_urb(dwav_usb_mt->irq); ++ ++err_free_buffers: ++ dwav_usb_mt_free_buffers(udev, dwav_usb_mt); ++ ++err_free_mem: ++ if (input_dev) ++ input_free_device(input_dev); ++ kfree(dwav_usb_mt); ++ ++ return err; ++} ++ ++/*-------------------------------------------------------------------------*/ ++static void dwav_usb_mt_disconnect(struct usb_interface *intf) ++{ ++ struct dwav_usb_mt *dwav_usb_mt = usb_get_intfdata(intf); ++ ++ if (!dwav_usb_mt) ++ return; ++ ++ dev_dbg(&intf->dev, ++ "%s - dwav_usb_mt is initialized, cleaning up\n", ++ __func__); ++ ++ usb_set_intfdata(intf, NULL); ++ ++ /* this will stop IO via close */ ++ input_unregister_device(dwav_usb_mt->input); ++ ++ usb_free_urb(dwav_usb_mt->irq); ++ ++ dwav_usb_mt_free_buffers(interface_to_usbdev(intf), dwav_usb_mt); ++ ++ kfree(dwav_usb_mt); ++} ++ ++/*-------------------------------------------------------------------------*/ ++MODULE_DEVICE_TABLE(usb, dwav_usb_mt_devices); ++ ++static struct usb_driver dwav_usb_mt_driver = { ++ .name = "dwav_usb_mt", ++ .probe = dwav_usb_mt_probe, ++ .disconnect = dwav_usb_mt_disconnect, ++ .suspend = dwav_usb_mt_suspend, ++ .resume = dwav_usb_mt_resume, ++ .reset_resume = dwav_usb_mt_reset_resume, ++ .id_table = dwav_usb_mt_devices, ++ .supports_autosuspend = 1, ++}; ++ ++module_usb_driver(dwav_usb_mt_driver); ++ ++/*-------------------------------------------------------------------------*/ ++MODULE_AUTHOR("Hardkernel Co.,Ltd"); ++MODULE_DESCRIPTION("D-WAV USB(HID) MultiTouch Driver"); ++MODULE_LICENSE("GPL"); ++ ++MODULE_ALIAS("dwav_usb_mt"); ++/*-------------------------------------------------------------------------*/ +diff -urN a/drivers/input/touchscreen/sx865x.c b/drivers/input/touchscreen/sx865x.c +--- a/drivers/input/touchscreen/sx865x.c 1970-01-01 01:00:00.000000000 +0100 ++++ b/drivers/input/touchscreen/sx865x.c 2018-05-06 10:03:40.553940699 +0200 +@@ -0,0 +1,584 @@ ++/* ++ * drivers/input/touchscreen/sx865x.c ++ * ++ * Copyright (c) 2013 U-MoBo Srl ++ * Pierluigi Passaro ++ * ++ * Using code from: ++ * - sx8650.c ++ * Copyright (c) 2009 Wayne Roberts ++ * - tsc2007.c ++ * Copyright (c) 2008 Kwangwoo Lee ++ * - ads7846.c ++ * Copyright (c) 2005 David Brownell ++ * Copyright (c) 2006 Nokia Corporation ++ * - corgi_ts.c ++ * Copyright (C) 2004-2005 Richard Purdie ++ * - omap_ts.[hc], ads7846.h, ts_osk.c ++ * Copyright (C) 2002 MontaVista Software ++ * Copyright (C) 2004 Texas Instruments ++ * Copyright (C) 2005 Dirk Behme ++ * ++ * 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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#if defined(CONFIG_ARCH_MESON64_ODROIDC2) ++ ++#include ++#include ++ ++#define AMLGPIO_IRQ_BASE 96 ++ ++#endif ++ ++/* timeout expires after pen is lifted, no more PENIRQs comming */ ++/* adjust with POWDLY setting */ ++#define TS_TIMEOUT (8 * 1000000) ++ ++/* analog channels */ ++#define CH_X 0 ++#define CH_Y 1 ++#define CH_Z1 2 ++#define CH_Z2 3 ++#define CH_AUX 4 ++#define CH_RX 5 ++#define CH_RY 6 ++#define CH_SEQ 7 ++ ++/* commands */ ++#define SX865X_WRITE_REGISTER 0x00 ++#define SX865X_READ_REGISTER 0x40 ++#define SX865X_SELECT_CH(ch) (0x80 | ch) ++#define SX865X_CONVERT_CH(ch) (0x90 | ch) ++#define SX865X_POWDWN 0xb0 /* power down, ignore pen */ ++#define SX865X_PENDET 0xc0 /* " " with pen sensitivity */ ++#define SX865X_PENTRG 0xe0 /* " " " " and sample channels */ ++ ++/* register addresses */ ++#define I2C_REG_CTRL0 0x00 ++#define I2C_REG_CTRL1 0x01 ++#define I2C_REG_CTRL2 0x02 ++#define I2C_REG_CTRL3 0x03 ++#define I2C_REG_CHANMASK 0x04 ++#define I2C_REG_STAT 0x05 ++#define I2C_REG_SOFTRESET 0x1f ++ ++#define I2C_EXTENDED_REG_STAT 0x24 ++#define I2C_EXTENDED_REG_SOFTRESET 0x3f ++ ++#define SOFTRESET_VALUE 0xde ++ ++/* bits for I2C_REG_STAT */ ++/* I2C_REG_STAT: end of conversion flag */ ++#define STATUS_CONVIRQ 0x80 ++/* I2C_REG_STAT: pen detected */ ++#define STATUS_PENIRQ 0x40 ++ ++/* bits for I2C_EXTENDED_REG_STAT */ ++/* I2C_EXTENDED_REG_STAT: end of conversion flag */ ++#define EXTENDED_STATUS_CONVIRQ 0x08 ++/* I2C_EXTENDED_REG_STAT: pen detected */ ++#define EXTENDED_STATUS_PENIRQ 0x04 ++ ++/* sx865x bits for RegCtrl1 */ ++#define CONDIRQ 0x20 ++/* no averaging */ ++#define FILT_NONE 0x00 ++/* 3 sample averaging */ ++#define FILT_3SA 0x01 ++/* 5 sample averaging */ ++#define FILT_5SA 0x02 ++/* 7 samples, sort, then average of 3 middle samples */ ++#define FILT_7SA 0x03 ++ ++/* bits for register 2, I2CRegChanMsk */ ++#define CONV_X 0x80 ++#define CONV_Y 0x40 ++#define CONV_Z1 0x20 ++#define CONV_Z2 0x10 ++#define CONV_AUX 0x08 ++#define CONV_RX 0x04 ++#define CONV_RY 0x02 ++ ++/* power delay: lower nibble of CTRL0 register */ ++#define POWDLY_IMMEDIATE 0x00 ++#define POWDLY_1_1US 0x01 ++#define POWDLY_2_2US 0x02 ++#define POWDLY_4_4US 0x03 ++#define POWDLY_8_9US 0x04 ++#define POWDLY_17_8US 0x05 ++#define POWDLY_35_5US 0x06 ++#define POWDLY_71US 0x07 ++#define POWDLY_140US 0x08 ++#define POWDLY_280US 0x09 ++#define POWDLY_570US 0x0a ++#define POWDLY_1_1MS 0x0b ++#define POWDLY_2_3MS 0x0c ++#define POWDLY_4_6MS 0x0d ++#define POWDLY_9MS 0x0e ++#define POWDLY_18MS 0x0f ++ ++#define MAX_12BIT ((1 << 12) - 1) ++ ++/* when changing the channel mask, also change the read length appropriately */ ++#define CHAN_MASK (CONV_X | CONV_Y | CONV_Z1 | CONV_RX | CONV_RY) ++#define NUM_CHANNELS_SEQ 5 ++#define CHAN_READ_LENGTH (NUM_CHANNELS_SEQ * 2) ++ ++#define SX_MULTITOUCH 0x01 ++#define SX_PROXIMITY_SENSING 0x02 ++#define SX_HAPTICS_GENERIC 0x04 ++#define SX_HAPTICS_IMMERSION 0x08 ++#define SX_EXTENDED_REGS (SX_PROXIMITY_SENSING | SX_HAPTICS_GENERIC | SX_HAPTICS_IMMERSION) ++ ++#define SX865X_UP_SCANTIME_MS (100) ++#define SX865X_DOWN_SCANTIME_MS (20) ++ ++struct ts_event { ++ u16 x, y; ++ u16 z1; ++ u16 rx, ry; ++}; ++ ++struct sx865x { ++ struct input_dev *input; ++ struct ts_event tc; ++ ++ struct i2c_client *client; ++ ++ u32 invert_x; ++ u32 invert_y; ++ u32 swap_xy; ++ u32 gpio_pendown; ++ u32 gpio_reset; ++ ++#if defined(CONFIG_ARCH_MESON64_ODROIDC2) ++ int irq_bank; ++#endif ++ unsigned pendown; ++ int irq; ++}; ++ ++static struct i2c_device_id sx865x_idtable[] = { ++ { "sx8650", 0 }, ++ { } ++}; ++ ++MODULE_DEVICE_TABLE(i2c, sx865x_idtable); ++ ++static const struct of_device_id sx865x_of_match[] = { ++ { .compatible = "semtech,sx8650", .data = (void *)0 }, ++ {} ++}; ++ ++MODULE_DEVICE_TABLE(of, sx865x_of_match); ++ ++static void sx865x_send_event(struct sx865x *ts) ++{ ++ u32 rt; ++ u16 x, y, z1; ++ ++ x = ts->tc.x; ++ y = ts->tc.y; ++ z1 = ts->tc.z1; ++ ++ /* range filtering */ ++ if (y == MAX_12BIT) ++ y = 0; ++ ++ /* compute touch pressure resistance */ ++ if (likely(y && z1)) ++ rt = z1; ++ else ++ rt = 0; ++ ++ /* Sample found inconsistent by debouncing or pressure is beyond ++ * the maximum. Don't report it to user space, repeat at least ++ * once more the measurement ++ */ ++ if (rt > MAX_12BIT) { ++ dev_dbg(&ts->client->dev, "ignored pressure %d\n", rt); ++ return; ++ } ++ ++ /* NOTE: We can't rely on the pressure to determine the pen down ++ * state, even this controller has a pressure sensor. The pressure ++ * value can fluctuate for quite a while after lifting the pen and ++ * in some cases may not even settle at the expected value. ++ * ++ * The only safe way to check for the pen up condition is in the ++ * timer by reading the pen signal state (it's a GPIO _and_ IRQ). ++ */ ++ if (rt) { ++ struct input_dev *input = ts->input; ++ ++ if (ts->invert_x) x = (~x) & MAX_12BIT; ++ ++ if (ts->invert_y) y = (~y) & MAX_12BIT; ++ ++ if (ts->swap_xy) swap(x, y); ++ ++ if (!ts->pendown) { ++ dev_dbg(&ts->client->dev, "DOWN\n"); ++ ts->pendown = 1; ++ input_report_key(input, BTN_TOUCH, 1); ++ } ++ ++ input_report_abs(input, ABS_X, x); ++ input_report_abs(input, ABS_Y, y); ++ input_report_abs(input, ABS_PRESSURE, rt); ++ input_sync(input); ++ ++ dev_dbg(&ts->client->dev, "point(%4d,%4d), pressure (%4u)\n", ++ x, y, rt); ++ } ++} ++ ++static int sx865x_read_values(struct sx865x *ts) ++{ ++ s32 data; ++ u16 vals[NUM_CHANNELS_SEQ+1]; /* +1 for last dummy read */ ++ int length; ++ int i; ++ ++ memset(&(ts->tc), 0, sizeof(ts->tc)); ++ /* The protocol and raw data format from i2c interface: ++ * S Addr R A [DataLow] A [DataHigh] A (repeat) NA P ++ * Where DataLow has (channel | [D11-D8]), DataHigh has [D7-D0]. ++ */ ++ length = i2c_master_recv(ts->client, (char *)vals, CHAN_READ_LENGTH); ++ ++ if (likely(length == CHAN_READ_LENGTH)) { ++ length >>= 1; ++ for (i = 0; i < length; i++) { ++ u16 ch; ++ data = swab16(vals[i]); ++ if (unlikely(data & 0x8000)) { ++ dev_dbg(&ts->client->dev, ++ "hibit @ %d [0x%04x]\n", i, data); ++ continue; ++ } ++ ch = data >> 12; ++ if (ch == CH_X) { ++ ts->tc.x = data & 0xfff; ++ } else if (ch == CH_Y) { ++ ts->tc.y = data & 0xfff; ++ } else if (ch == CH_Z1) { ++ ts->tc.z1 = data & 0xfff; ++ } else if (ch == CH_RX) { ++ ts->tc.rx = data & 0xfff; ++ } else if (ch == CH_RY) { ++ ts->tc.ry = data & 0xfff; ++ } else { ++ dev_err(&ts->client->dev, "? CH%d %x\n", ++ ch, data & 0xfff); ++ } ++ } ++ } else { ++ dev_err(&ts->client->dev, "%d = recv()\n", length); ++ } ++ ++ dev_dbg(&ts->client->dev, "X:%03x Y:%03x Z1:%03x RX:%03x RY:%03x\n", ++ ts->tc.x, ts->tc.y, ts->tc.z1, ts->tc.rx, ts->tc.ry); ++ ++ return !ts->tc.z1; /* return 0 only if pressure not 0 */ ++} ++ ++static void sx865x_pen_up(struct sx865x *ts) ++{ ++ struct input_dev *input = ts->input; ++ ++ /* This timer expires after PENIRQs havent been coming in for some time. ++ * It means that the pen is now UP. */ ++ input_report_key(input, BTN_TOUCH, 0); ++ input_report_abs(input, ABS_PRESSURE, 0); ++ input_sync(input); ++ ++ ts->pendown = 0; ++ dev_dbg(&ts->client->dev, "UP\n"); ++} ++ ++static int sx865x_data_available(struct sx865x *ts) ++{ ++ u8 status; ++ ++ status = i2c_smbus_read_byte_data(ts->client, ++ (SX865X_READ_REGISTER | I2C_REG_STAT)); ++ return status & STATUS_CONVIRQ; ++} ++ ++static int get_pendown_status(struct sx865x *ts) ++{ ++ return gpio_get_value(ts->gpio_pendown) ? 0 : 1; ++} ++ ++static irqreturn_t sx865x_hw_irq(int irq, void *handle) ++{ ++ struct sx865x *ts = handle; ++ ++ return get_pendown_status(ts) ? IRQ_WAKE_THREAD : IRQ_HANDLED; ++} ++ ++static irqreturn_t sx865x_irq(int irq, void *handle) ++{ ++ struct sx865x *ts = handle; ++ ++ while (sx865x_data_available(ts)) { ++ /* valid data was read in */ ++ if (likely(sx865x_read_values(ts) == 0)) ++ sx865x_send_event(ts); ++ else ++ dev_dbg(&ts->client->dev, "data error!\n"); ++ ++ msleep(SX865X_DOWN_SCANTIME_MS); ++ } ++ ++ if (ts->pendown) ++ sx865x_pen_up(ts); ++ ++ return IRQ_HANDLED; ++} ++ ++static void sx865x_hw_reset(struct sx865x *ts) ++{ ++ gpio_direction_output(ts->gpio_reset, 0); ++ udelay(1000); ++ gpio_direction_output(ts->gpio_reset, 1); ++ udelay(1000); ++} ++ ++static int sx865x_dt_probe(struct i2c_client *client, struct sx865x *ts) ++{ ++ struct device_node *node = client->dev.of_node; ++ const struct of_device_id *match; ++ ++ if (!node) { ++ dev_err(&client->dev, ++ "Device dost not have associated DT data\n"); ++ return -EINVAL; ++ } ++ ++ match = of_match_device(sx865x_of_match, &client->dev); ++ if (!match) { ++ dev_err(&client->dev, ++ "Unknown device model\n"); ++ return -EINVAL; ++ } ++ ++ of_property_read_u32(node, "swap-xy", &ts->swap_xy); ++ of_property_read_u32(node, "invert-x", &ts->invert_x); ++ of_property_read_u32(node, "invert-y", &ts->invert_y); ++ ++ ts->gpio_pendown = of_get_named_gpio(node, "gpio-pendown", 0); ++ ts->gpio_reset = of_get_named_gpio(node, "gpio-reset", 0); ++ ++ if (gpio_request(ts->gpio_pendown, "ts-pendown")) ++ dev_err(&client->dev, ++ "gpio request fail (%d)!\n", ts->gpio_pendown); ++ else ++ gpio_direction_input(ts->gpio_pendown); ++ ++ if (gpio_request(ts->gpio_reset, "ts-reset")) ++ dev_err(&client->dev, ++ "gpio request fail (%d)!\n", ts->gpio_reset); ++ else ++ sx865x_hw_reset(ts); ++ ++#if defined(CONFIG_ARCH_MESON64_ODROIDC2) ++ /* irq setup */ ++ ts->irq_bank = meson_fix_irqbank(ts->irq_bank); ++ if (ts->irq_bank < 0) { ++ dev_err(&client->dev, ++ "Could not find irq bank!\n"); ++ return -EINVAL; ++ } ++ ++ { ++ int ret; ++ /* AMLogic gpio irq setup */ ++ ret = gpio_for_irq(ts->gpio_pendown, ++ AML_GPIO_IRQ(ts->irq_bank, FILTER_NUM7, GPIO_IRQ_FALLING)); ++ ++ if (ret) { ++ dev_err(&client->dev, ++ "AML_GPIO_IRQ setup fail!\n"); ++ return -EINVAL; ++ } ++ /* Amlogic gpio based irq setup */ ++ ts->irq = AMLGPIO_IRQ_BASE + ts->irq_bank; ++ } ++#else ++ ts->irq = gpio_to_irq(ts->gpio_pendown); ++ if (ts->irq < 0) ++ return -EINVAL; ++#endif ++ ++ /* platform data info display */ ++ dev_info(&client->dev, "swap_xy (%d)\n", ts->swap_xy); ++ dev_info(&client->dev, "invert_x (%d)\n", ts->invert_x); ++ dev_info(&client->dev, "invert_y (%d)\n", ts->invert_y); ++ dev_info(&client->dev, "gpio pendown (%d)\n", ts->gpio_pendown); ++ dev_info(&client->dev, "gpio reset (%d)\n", ts->gpio_reset); ++ dev_info(&client->dev, "gpio irq (%d)\n", ts->irq); ++ ++ return 0; ++} ++ ++#if defined(CONFIG_ARCH_MESON64_ODROIDC2) ++static void sx865x_irq_free(struct i2c_client *client, struct sx865x *ts) ++{ ++ int irq_banks[2]; ++ ++ meson_free_irq(gpio_to_irq(ts->gpio_pendown), &irq_banks[0]); ++ ++ /* rising irq bank */ ++ if (irq_banks[0] != -1) ++ free_irq(irq_banks[0] + AMLGPIO_IRQ_BASE, ts); ++ ++ /* falling irq bank */ ++ if (irq_banks[1] != -1) ++ free_irq(irq_banks[1] + AMLGPIO_IRQ_BASE, ts); ++} ++#endif ++ ++static int sx865x_probe(struct i2c_client *client, ++ const struct i2c_device_id *id) ++{ ++ struct sx865x *ts; ++ struct input_dev *input_dev; ++ int err = 0; ++ ++ dev_info(&client->dev, "sx865x_probe()\n"); ++ ++ if (!i2c_check_functionality(client->adapter, ++ I2C_FUNC_SMBUS_READ_WORD_DATA)) ++ return -EIO; ++ ++ ts = devm_kzalloc(&client->dev, sizeof(struct sx865x), GFP_KERNEL); ++ input_dev = devm_input_allocate_device(&client->dev); ++ if (!ts || !input_dev) ++ return -ENOMEM; ++ ++ if (sx865x_dt_probe(client, ts) != 0) ++ return -EIO; ++ ++ i2c_set_clientdata(client, ts); ++ ++ input_dev->name = "SX865X Touchscreen"; ++ input_dev->id.bustype = BUS_I2C; ++ input_dev->dev.parent = &client->dev; ++ input_set_drvdata(input_dev, ts); ++ ++ input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); ++ input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); ++ ++ input_set_abs_params(input_dev, ABS_X, 0, MAX_12BIT, 0, 0); ++ input_set_abs_params(input_dev, ABS_Y, 0, MAX_12BIT, 0, 0); ++ input_set_abs_params(input_dev, ABS_PRESSURE, 0, MAX_12BIT, 0, 0); ++ ++ /* soft reset: SX8650 fails to nak at the end, ignore return value */ ++ i2c_smbus_write_byte_data(client, I2C_REG_SOFTRESET, SOFTRESET_VALUE); ++ ++ /* set mask to convert X, Y, Z1, RX, RY for CH_SEQ */ ++ err = i2c_smbus_write_byte_data(client, I2C_REG_CHANMASK, CHAN_MASK); ++ if (err != 0) return -EIO; ++ ++ err = i2c_smbus_write_byte_data(client, I2C_REG_CTRL1, ++ CONDIRQ | FILT_7SA); ++ if (err != 0) return -EIO; ++ ++ /* set POWDLY settling time -- adjust TS_TIMEOUT accordingly */ ++ err = i2c_smbus_write_byte_data(client, I2C_REG_CTRL0, POWDLY_1_1MS); ++ if (err != 0) return -EIO; ++ ++ /* enter pen-trigger mode */ ++ err = i2c_smbus_write_byte(client, SX865X_PENTRG); ++ if (err != 0) return -EIO; ++ ++ err = request_threaded_irq(ts->irq, sx865x_hw_irq, sx865x_irq, ++ IRQF_ONESHOT, ++ client->dev.driver->name, ts); ++ ++ if (err < 0) { ++ dev_err(&client->dev, "irq %d busy?\n", ts->irq); ++ return -EIO; ++ } ++ ++ err = input_register_device(input_dev); ++ if (err) ++ goto err_free_irq; ++ ++ ts->client = client; ++ ts->input = input_dev; ++ ++ dev_info(&client->dev, "probe ok! registered with irq (%d)\n", ts->irq); ++ ++ return 0; ++ ++err_free_irq: ++ if (ts->gpio_pendown) ++ gpio_free(ts->gpio_pendown); ++ if (ts->gpio_reset) ++ gpio_free(ts->gpio_reset); ++#if defined(CONFIG_ARCH_MESON64_ODROIDC2) ++ sx865x_irq_free(client, ts); ++#else ++ if (ts->irq) ++ free_irq(ts->irq, ts); ++#endif ++ return err; ++} ++ ++static int sx865x_remove(struct i2c_client *client) ++{ ++ struct sx865x *ts = i2c_get_clientdata(client); ++ struct sx865x_platform_data *pdata; ++ ++ pdata = client->dev.platform_data; ++ ++ if (ts->gpio_pendown) ++ gpio_free(ts->gpio_pendown); ++ if (ts->gpio_reset) ++ gpio_free(ts->gpio_reset); ++#if defined(CONFIG_ARCH_MESON64_ODROIDC2) ++ sx865x_irq_free(client, ts); ++#else ++ if (ts->irq) ++ free_irq(ts->irq, ts); ++#endif ++ input_unregister_device(ts->input); ++ ++ return 0; ++} ++ ++static struct i2c_driver sx865x_driver = { ++ .driver = { ++ .owner = THIS_MODULE, ++ .name = "sx865x", ++ .of_match_table = of_match_ptr(sx865x_of_match), ++ }, ++ .id_table = sx865x_idtable, ++ .probe = sx865x_probe, ++ .remove = sx865x_remove, ++}; ++ ++module_i2c_driver(sx865x_driver); ++ ++MODULE_AUTHOR("Pierluigi Passaro "); ++MODULE_DESCRIPTION("SX865X TouchScreen Driver"); ++MODULE_LICENSE("GPL"); diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/116_linux-4.14.y-drm-fb_helper-ump-ioctls.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/116_linux-4.14.y-drm-fb_helper-ump-ioctls.patch new file mode 100644 index 000000000..81a727526 --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/116_linux-4.14.y-drm-fb_helper-ump-ioctls.patch @@ -0,0 +1,151 @@ +diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c +index cab14f25..cafc60ea 100644 +--- a/drivers/gpu/drm/drm_fb_helper.c ++++ b/drivers/gpu/drm/drm_fb_helper.c +@@ -1544,6 +1544,14 @@ int drm_fb_helper_ioctl(struct fb_info *info, unsigned int cmd, + + ret = 0; + goto unlock; ++#if defined(CONFIG_UMP) ++ case GET_UMP_SECURE_ID_BUF1: ++ ret = drm_get_ump_secure_id(info, fb_helper, arg, 0); ++ goto unlock; ++ case GET_UMP_SECURE_ID_BUF2: ++ ret = drm_get_ump_secure_id(info, fb_helper, arg, 1); ++ goto unlock; ++#endif + default: + ret = -ENOTTY; + } +diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile +index 8ce07039b..fdf946be3 100644 +--- a/drivers/gpu/drm/Makefile ++++ b/drivers/gpu/drm/Makefile +@@ -44,6 +44,7 @@ drm_kms_helper-$(CONFIG_DRM_DP_AUX_CHARDEV) += drm_dp_aux_dev.o + + obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o + obj-$(CONFIG_DRM_DEBUG_MM_SELFTEST) += selftests/ ++obj-$(CONFIG_UMP) += drm_fb_ump.o + + CFLAGS_drm_trace_points.o := -I$(src) + +diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h +index b069433e..95657b76 100644 +--- a/include/drm/drm_fb_helper.h ++++ b/include/drm/drm_fb_helper.h +@@ -36,6 +36,10 @@ struct drm_fb_helper; + #include + #include + ++#if defined(CONFIG_UMP) ++#include ++#endif ++ + enum mode_set_atomic { + LEAVE_ATOMIC_MODE_SET, + ENTER_ATOMIC_MODE_SET, +@@ -131,6 +135,8 @@ struct drm_fb_helper_connector { + struct drm_connector *connector; + }; + ++#define DRM_FB_UMP_COUNT 1 /* only enable one FB UMP layer */ ++ + /** + * struct drm_fb_helper - main structure to emulate fbdev on top of KMS + * @fb: Scanout framebuffer object +@@ -232,6 +238,9 @@ struct drm_fb_helper { + * See also: @deferred_setup + */ + int preferred_bpp; ++#if defined(CONFIG_UMP) ++ ump_dd_handle ump_wrapped_buffer[DRM_FB_UMP_COUNT][2]; ++#endif + }; + + /** +@@ -577,4 +586,11 @@ drm_fb_helper_remove_conflicting_framebuffers(struct apertures_struct *a, + #endif + } + ++#if defined(CONFIG_UMP) ++extern int (*drm_get_ump_secure_id) (struct fb_info *info, ++ struct drm_fb_helper *g_fbi, unsigned long arg, int buf); ++#define GET_UMP_SECURE_ID_BUF1 _IOWR('m', 311, unsigned int) ++#define GET_UMP_SECURE_ID_BUF2 _IOWR('m', 312, unsigned int) ++#endif ++ + #endif +--- /dev/null 2018-07-12 16:39:19.544000000 +0200 ++++ b/drivers/gpu/drm/drm_fb_ump.c 2018-07-22 22:20:45.166145058 +0200 +@@ -0,0 +1,71 @@ ++/* ++ * Copyright (C) 2016 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. ++ * ++ * 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. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, ++ * MA 02111-1307 USA ++ */ ++ ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++int (*drm_get_ump_secure_id) (struct fb_info *info, ++ struct drm_fb_helper *g_fbi, unsigned long arg, int buf); ++EXPORT_SYMBOL(drm_get_ump_secure_id); ++ ++static int _drm_get_ump_secure_id(struct fb_info *info, ++ struct drm_fb_helper *g_fbi, unsigned long arg, int buf) ++{ ++ u32 __user *psecureid = (u32 __user *) arg; ++ ump_secure_id secure_id; ++ ++ if (!g_fbi->ump_wrapped_buffer[info->node][buf]) { ++ ump_dd_physical_block ump_memory_description; ++ printk("ump: create disp: %d\n", buf); ++ ++ ump_memory_description.addr = info->fix.smem_start; ++ ump_memory_description.size = info->fix.smem_len; ++ g_fbi->ump_wrapped_buffer[info->node][buf] = ++ ump_dd_handle_create_from_phys_blocks( ++ &ump_memory_description, 1); ++ } ++ secure_id = ump_dd_secure_id_get( ++ g_fbi->ump_wrapped_buffer[info->node][buf]); ++ ++ return put_user((unsigned int)secure_id, psecureid); ++} ++ ++static int __init drm_ump_module_init(void) ++{ ++ int ret = 0; ++ drm_get_ump_secure_id = _drm_get_ump_secure_id; ++ return ret; ++} ++ ++static void __exit drm_ump_module_exit(void) ++{ ++ drm_get_ump_secure_id = NULL; ++} ++ ++module_init(drm_ump_module_init); ++module_exit(drm_ump_module_exit); ++ ++MODULE_AUTHOR("Mauro Ribeiro "); ++MODULE_DESCRIPTION("UMP Glue for DRM Framebuffer"); ++MODULE_LICENSE("GPL"); diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/117_arm64_increasing_DMA_block_memory_allocation_to_2048.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/117_arm64_increasing_DMA_block_memory_allocation_to_2048.patch new file mode 100644 index 000000000..a848ed52e --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/117_arm64_increasing_DMA_block_memory_allocation_to_2048.patch @@ -0,0 +1,13 @@ +diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c +index 614af886b7ef..632d32109755 100644 +--- a/arch/arm64/mm/dma-mapping.c ++++ b/arch/arm64/mm/dma-mapping.c +@@ -44,7 +44,7 @@ static pgprot_t __get_dma_pgprot(unsigned long attrs, pgprot_t prot, + + static struct gen_pool *atomic_pool __ro_after_init; + +-#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) diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/118_arm64-set-default-target-to-Image.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/118_arm64-set-default-target-to-Image.patch new file mode 100644 index 000000000..51bf570c2 --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/118_arm64-set-default-target-to-Image.patch @@ -0,0 +1,13 @@ +diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile +index f839ecd9..cd276162 100644 +--- a/arch/arm64/Makefile ++++ b/arch/arm64/Makefile +@@ -103,7 +103,7 @@ core-$(CONFIG_EFI_STUB) += $(objtree)/drivers/firmware/efi/libstub/lib.a + + # Default target when executing plain make + boot := arch/arm64/boot +-KBUILD_IMAGE := $(boot)/Image.gz ++KBUILD_IMAGE := $(boot)/Image + KBUILD_DTBS := dtbs + + all: Image.gz $(KBUILD_DTBS) diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/119_odroidc2-enable-scpi-dvfs.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/119_odroidc2-enable-scpi-dvfs.patch new file mode 100644 index 000000000..dbe1e637f --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/119_odroidc2-enable-scpi-dvfs.patch @@ -0,0 +1,14 @@ +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts +index d147c853a..dbde670ba 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts +@@ -246,7 +246,8 @@ + }; + + &scpi_clocks { +- status = "disabled"; ++ /* Works only with new blobs that have limited DVFS table */ ++ status = "okay"; + }; + + /* SD */ diff --git a/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/120_odroidc2-enable-scpi-cpu-thermal.patch b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/120_odroidc2-enable-scpi-cpu-thermal.patch new file mode 100644 index 000000000..e05b711aa --- /dev/null +++ b/buildroot-external/board/hardkernel/odroid-c2/patches/linux/aside/120_odroidc2-enable-scpi-cpu-thermal.patch @@ -0,0 +1,63 @@ +--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts 2018-04-29 05:46:55.636313674 +0200 ++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts 2018-04-29 00:07:14.412005049 +0200 +@@ -46,6 +46,7 @@ + + #include "meson-gxbb.dtsi" + #include ++#include + + / { + compatible = "hardkernel,odroid-c2", "amlogic,meson-gxbb"; +@@ -117,6 +118,41 @@ + 1800000 1>; + }; + ++ thermal-zones { ++ cpu-thermal { ++ polling-delay-passive = <250>; /* milliseconds */ ++ polling-delay = <1000>; /* milliseconds */ ++ ++ thermal-sensors = <&scpi_sensors 0>; ++ ++ trips { ++ cpu_alert0: cpu-alert0 { ++ temperature = <70000>; ++ hysteresis = <2000>; ++ type = "passive"; ++ }; ++ cpu_alert1: cpu-alert1 { ++ temperature = <85000>; ++ hysteresis = <2000>; ++ type = "passive"; ++ }; ++ cpu_crit: cpu_crit { ++ temperature = <95000>; ++ hysteresis = <2000>; ++ type = "critical"; ++ }; ++ }; ++ ++ cooling-maps { ++ map0 { ++ trip = <&cpu_alert1>; ++ cooling-device = ++ <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; ++ }; ++ }; ++ }; ++ }; ++ + vcc1v8: regulator-vcc1v8 { + compatible = "regulator-fixed"; + regulator-name = "VCC1V8"; +@@ -192,6 +228,10 @@ + status = "okay"; + }; + ++&cpu0 { ++ #cooling-cells = <2>; ++}; ++ + ðmac { + status = "okay"; + pinctrl-0 = <ð_rgmii_pins>; diff --git a/buildroot-external/configs/odroid_c2_defconfig b/buildroot-external/configs/odroid_c2_defconfig index f7e9cc250..8622dde17 100644 --- a/buildroot-external/configs/odroid_c2_defconfig +++ b/buildroot-external/configs/odroid_c2_defconfig @@ -4,7 +4,7 @@ BR2_CCACHE=y BR2_CCACHE_DIR="/cache/cc" BR2_GLOBAL_PATCH_DIR="$(BR2_EXTERNAL_HASSOS_PATH)/patches $(BR2_EXTERNAL_HASSOS_PATH)/board/hardkernel/odroid-c2/patches" BR2_TOOLCHAIN_BUILDROOT_GLIBC=y -BR2_KERNEL_HEADERS_4_14=y +BR2_KERNEL_HEADERS_4_18=y BR2_GCC_VERSION_7_X=y BR2_TOOLCHAIN_BUILDROOT_CXX=y BR2_TARGET_GENERIC_HOSTNAME="hassio" @@ -18,7 +18,7 @@ BR2_ROOTFS_POST_IMAGE_SCRIPT="$(BR2_EXTERNAL_HASSOS_PATH)/scripts/post-image.sh" BR2_ROOTFS_POST_SCRIPT_ARGS="$(BR2_EXTERNAL_HASSOS_PATH)/board/hardkernel/odroid-c2 $(BR2_EXTERNAL_HASSOS_PATH)/board/hardkernel/odroid-c2/hassos-hook.sh" BR2_LINUX_KERNEL=y BR2_LINUX_KERNEL_CUSTOM_VERSION=y -BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="4.14.67" +BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="4.18.20" BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="$(BR2_EXTERNAL_HASSOS_PATH)/board/hardkernel/odroid-c2/kernel.config" BR2_LINUX_KERNEL_CONFIG_FRAGMENT_FILES="$(BR2_EXTERNAL_HASSOS_PATH)/kernel/hassos-4_14.config $(BR2_EXTERNAL_HASSOS_PATH)/kernel/device-support.config" diff --git a/buildroot-external/scripts/hdd-image.sh b/buildroot-external/scripts/hdd-image.sh index c9d4ad93d..acce0bb6f 100755 --- a/buildroot-external/scripts/hdd-image.sh +++ b/buildroot-external/scripts/hdd-image.sh @@ -19,10 +19,10 @@ DATA_SIZE=1G function size2sectors() { - s=0 + local f=0 for v in "${@}" do - ((s+=$(echo "$v" | awk \ + local p=$(echo "$v" | awk \ 'BEGIN{IGNORECASE = 1} function printsectors(n,b,p) {printf "%u\n", n*b^p/512} /B$/{ printsectors($1, 1, 0)}; @@ -34,9 +34,13 @@ function size2sectors() { /MB$/{ printsectors($1, 10, 6)}; /GB$/{ printsectors($1, 10, 9)}; /TB$/{ printsectors($1, 10, 12)}') - )) + for s in $p + do + f=$((f+s)) done - echo $s + + done + echo $f } @@ -196,14 +200,14 @@ function _create_disk_mbr() { local disk_layout="${BINARIES_DIR}/disk.layout" local boot_start=16384 - local boot_size=$(($(size2sectors BOOT_SIZE)+2)) - local kernel0_size=$(($(size2sectors KERNEL_SIZE)+2)) - local system0_size=$(($(size2sectors SYSTEM_SIZE)+2)) - local kernel1_size=$(($(size2sectors KERNEL_SIZE)+2)) - local system1_size=$(($(size2sectors SYSTEM_SIZE)+2)) - local bootstate_size=$(($(size2sectors BOOTSTATE_SIZE)+2)) - local overlay_size=$(($(size2sectors OVERLAY_SIZE)+2)) - local data_size=$(($(size2sectors DATA_SIZE)+2)) + local boot_size=$(($(size2sectors "$(get_boot_size)")+2)) + local kernel0_size=$(($(size2sectors "$KERNEL_SIZE")+2)) + local system0_size=$(($(size2sectors "$SYSTEM_SIZE")+2)) + local kernel1_size=$(($(size2sectors "$KERNEL_SIZE")+2)) + local system1_size=$(($(size2sectors "$SYSTEM_SIZE")+2)) + local bootstate_size=$(($(size2sectors "$BOOTSTATE_SIZE")+2)) + local overlay_size=$(($(size2sectors "$OVERLAY_SIZE")+2)) + local data_size=$(($(size2sectors "$DATA_SIZE")+2)) local extended_size=$((kernel0_size+system0_size+kernel1_size+system1_size+bootstate_size+2)) # we add one here for the extended header.